Initial commit: notification-elements-ui library
Angular 19 component library for notifications & communication: - ntf-bell: notification bell with badge count and shake animation - ntf-feed / ntf-feed-item: real-time notification feed with grouping - ntf-center: full notification center with category filter tabs - ntf-inbox / ntf-inbox-item: two-column inbox with search and detail - ntf-comment / ntf-thread: comment threads with replies and reactions - ntf-mention-input: text input with @mention autocomplete - ntf-empty-state: empty state placeholder - ntf-item-def: custom template directive for notification items Includes signal-based services, SCSS design tokens with dark mode, utility functions, and full TypeScript type definitions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
56
src/services/notification.service.ts
Normal file
56
src/services/notification.service.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
import { Injectable, inject, signal, computed } from '@angular/core';
|
||||
import { NOTIFICATION_CONFIG } from '../providers/notification-config.provider';
|
||||
import type { NtfNotification, NtfGroup } from '../types/notification.types';
|
||||
import { groupByDate } from '../utils/time.utils';
|
||||
|
||||
@Injectable()
|
||||
export class NotificationService {
|
||||
private config = inject(NOTIFICATION_CONFIG);
|
||||
|
||||
readonly notifications = signal<NtfNotification[]>([]);
|
||||
|
||||
readonly unreadCount = computed(() =>
|
||||
this.notifications().filter((n) => n.status === 'unread').length,
|
||||
);
|
||||
|
||||
readonly grouped = computed<NtfGroup[]>(() => {
|
||||
const items = this.notifications().filter((n) => n.status !== 'archived');
|
||||
const dateGroups = groupByDate(items);
|
||||
|
||||
return dateGroups.map((g) => ({
|
||||
id: g.label.toLowerCase().replace(/\s+/g, '-'),
|
||||
label: g.label,
|
||||
notifications: g.items,
|
||||
}));
|
||||
});
|
||||
|
||||
add(notification: NtfNotification): void {
|
||||
this.notifications.update((list) => [notification, ...list]);
|
||||
}
|
||||
|
||||
markRead(notificationId: string): void {
|
||||
this.notifications.update((list) =>
|
||||
list.map((n) => (n.id === notificationId ? { ...n, status: 'read' as const } : n)),
|
||||
);
|
||||
}
|
||||
|
||||
markAllRead(): void {
|
||||
this.notifications.update((list) =>
|
||||
list.map((n) => (n.status === 'unread' ? { ...n, status: 'read' as const } : n)),
|
||||
);
|
||||
}
|
||||
|
||||
archive(notificationId: string): void {
|
||||
this.notifications.update((list) =>
|
||||
list.map((n) => (n.id === notificationId ? { ...n, status: 'archived' as const } : n)),
|
||||
);
|
||||
}
|
||||
|
||||
remove(notificationId: string): void {
|
||||
this.notifications.update((list) => list.filter((n) => n.id !== notificationId));
|
||||
}
|
||||
|
||||
clear(): void {
|
||||
this.notifications.set([]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user