${filteredEntries.length > 0
? html`
Live Updates
`
: ''}
${filteredEntries.length === 0
? html`
No activity entries
`
: groupedEntries.map(
(group) => html`
${group.label}
${group.entries.map((entry) => this.renderActivityEntry(entry))}
`
)}
`;
}
private renderActivityEntry(entry: IActivityEntry): TemplateResult {
const timestamp = entry.timestamp || new Date();
const timeStr = this.formatTime(timestamp);
const iconName = entry.iconName || this.getIconForType(entry.type);
return html`
this.handleContextMenu(e, entry)}
>
${timeStr}
${entry.user} ${entry.message}
`;
}
// API METHODS
public add(entry: IActivityEntry): void {
const newEntry: IActivityEntry = {
...entry,
id: entry.id || this.generateId(),
timestamp: entry.timestamp || new Date(),
};
this.entries = [newEntry, ...this.entries];
this.entries$.next(this.entries);
}
public addMany(entries: IActivityEntry[]): void {
const newEntries = entries.map((entry) => ({
...entry,
id: entry.id || this.generateId(),
timestamp: entry.timestamp || new Date(),
}));
this.entries = [...newEntries.reverse(), ...this.entries];
this.entries$.next(this.entries);
}
public clear(): void {
this.entries = [];
this.entries$.next(this.entries);
}
public getEntries(): IActivityEntry[] {
return [...this.entries];
}
public filter(criteria: { user?: string; type?: IActivityEntry['type'] }): IActivityEntry[] {
return this.entries.filter((entry) => {
if (criteria.user && entry.user !== criteria.user) return false;
if (criteria.type && entry.type !== criteria.type) return false;
return true;
});
}
public search(query: string): IActivityEntry[] {
const lowerQuery = query.toLowerCase();
return this.entries.filter(
(entry) =>
entry.message.toLowerCase().includes(lowerQuery) ||
entry.user.toLowerCase().includes(lowerQuery)
);
}
// PRIVATE HELPERS
private generateId(): string {
return `activity-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
}
private getFilteredEntries(): IActivityEntry[] {
let result = this.entries;
if (this.searchQuery) {
const lowerQuery = this.searchQuery.toLowerCase();
result = result.filter(
(entry) =>
entry.message.toLowerCase().includes(lowerQuery) ||
entry.user.toLowerCase().includes(lowerQuery)
);
}
if (this.filterCriteria.user || this.filterCriteria.type) {
result = result.filter((entry) => {
if (this.filterCriteria.user && entry.user !== this.filterCriteria.user) return false;
if (this.filterCriteria.type && entry.type !== this.filterCriteria.type) return false;
return true;
});
}
return result;
}
private groupEntriesByDate(
entries: IActivityEntry[]
): Array<{ label: string; entries: IActivityEntry[] }> {
const groups: Map