import { Notification } from './notification'; /** * Repository for managing user notifications. * * {@link NotificationRepository} provides methods to load, manage, and interact with * notifications for the current user. Notifications inform users about: * - Task assignments ({@link NotificationType.assignment}) * - Object follows ({@link NotificationType.follow}) * - Mentions in comments ({@link NotificationType.mention}) * * Each {@link Notification} contains: * - A unique ID * - Type indicating what triggered the notification * - Timestamp of creation * - Associated {@link LimeObject} (the object being notified about) * - Creator information (who triggered the notification) * - Optional custom data * - Read status * * @example Display notification list * ```ts * import { PlatformServiceName } from '@limetech/lime-web-components'; * * const repository = platform.get(PlatformServiceName.NotificationRepository); * * const response = await repository.loadAll({ * filter: { read: false }, * limit: 20, * }); * * const notifications = response.items; * const unreadCount = response.count.unread; * ``` * * The repository methods are generic in `T` so callers can supply the * expected shape of {@link Notification.data} on a per-call basis. The * default is `unknown` — narrow it at the call site when you know what * payload to expect, e.g. `repo.get(id)`. * * @beta * @group NotificationRepository * @see {@link Notification} for notification structure * @see {@link NotificationType} for notification types * @see {@link NotificationLoadOptions} for loading options */ export interface NotificationRepository { /** * Load notifications for the current user. * * Fetches notifications from the server with optional filtering and pagination. * Returns both the notification items and count information (total and unread). * * Use {@link NotificationLoadOptions} to: * - Filter by read/unread status * - Paginate with limit and offset * - Load only recent notifications (newerThan, olderThan) * * @param options - Configuration for loading notifications * @returns Promise resolving to {@link NotificationResponse} with items and counts * * @example Load with pagination * ```ts * import { PlatformServiceName } from '@limetech/lime-web-components'; * * const repository = platform.get(PlatformServiceName.NotificationRepository); * const pageSize = 20; * const pageNumber = 2; * * const response = await repository.loadAll({ * limit: pageSize, * offset: pageNumber * pageSize, * }); * * const totalPages = Math.ceil(response.count.total / pageSize); * ``` * * @example Load only recent notifications since last check * ```ts * import { PlatformServiceName } from '@limetech/lime-web-components'; * * const repository = platform.get(PlatformServiceName.NotificationRepository); * * const seen = await repository.loadAll({ limit: 1 }); * const lastNotificationId = seen.items[0]?.id; * * const response = await repository.loadAll({ * newerThan: lastNotificationId, * limit: 100, * }); * * if (response.items.length > 0) { * console.log(`${response.items.length} new notifications`); * } * ``` * * @example Load older notifications for infinite scroll * ```ts * import { PlatformServiceName } from '@limetech/lime-web-components'; * * const repository = platform.get(PlatformServiceName.NotificationRepository); * * const firstPage = await repository.loadAll({ limit: 25 }); * let notifications = firstPage.items; * const oldestId = notifications.at(-1)?.id; * * const response = await repository.loadAll({ * olderThan: oldestId, * limit: 25, * }); * * notifications = [...notifications, ...response.items]; * ``` * * @see {@link NotificationLoadOptions} for filtering and pagination * @see {@link NotificationResponse} for response structure * @see {@link get} to retrieve a specific notification from cache */ loadAll(options?: NotificationLoadOptions): Promise>; /** * Get a cached notification by ID. * * Retrieves a notification from the repository cache without making a network request. * Returns `undefined` if the notification has not been loaded or doesn't exist. * * Use this to access notifications that were previously loaded via {@link loadAll}. * * @param notificationId - ID of the notification to retrieve * @returns The cached {@link Notification}, or `undefined` if not found * * @example Check if notification is already loaded * ```ts * import { PlatformServiceName } from '@limetech/lime-web-components'; * * const repository = platform.get(PlatformServiceName.NotificationRepository); * const notificationId = 1001; * * const notification = repository.get(notificationId); * * if (notification) { * console.log('Type:', notification.type); * console.log('Read:', notification.read !== undefined); * } else { * console.log('Notification not in cache'); * } * ``` * * @see {@link loadAll} to load notifications from the server * @see {@link Notification} for notification structure */ get(notificationId: number): Notification | undefined; /** * Delete a notification. * * Permanently removes the notification for the current user. This operation * cannot be undone. The notification will be removed from: * - The database * - The repository cache * - Any notification lists in the UI * * @param notification - The {@link Notification} to delete * @returns Promise that resolves when deletion is complete * @throws Error if deletion fails * * @example Delete a notification * ```ts * import { PlatformServiceName } from '@limetech/lime-web-components'; * * const repository = platform.get(PlatformServiceName.NotificationRepository); * * const response = await repository.loadAll({ limit: 1 }); * const [notification] = response.items; * * if (notification) { * try { * await repository.delete(notification); * } catch (error) { * console.error('Failed to delete:', error); * } * } * ``` * * @example Clear all read notifications * ```ts * import { PlatformServiceName } from '@limetech/lime-web-components'; * * const repository = platform.get(PlatformServiceName.NotificationRepository); * * const response = await repository.loadAll({ filter: { read: true } }); * * for (const notification of response.items) { * await repository.delete(notification); * } * * console.log(`Cleared ${response.items.length} read notifications`); * ``` * * @see {@link Notification} for notification structure * @see {@link markAsRead} to mark as read without deleting */ delete(notification: Notification): Promise; /** * Mark a notification as read or unread. * * Updates the read status of a notification. When marked as read, the notification's * `read` property is set to the current timestamp. When marked as unread, the `read` * property is cleared. * * Marking as read is typically done when: * - User clicks on the notification * - User views the related object * - Notification panel is opened * * @param notification - The {@link Notification} to update * @param read - Whether to mark as read (`true`) or unread (`false`). Defaults to `true` * @returns Promise resolving to the updated {@link Notification} * @throws Error if update fails * * @example Mark notification as read when clicked * ```ts * import { PlatformServiceName } from '@limetech/lime-web-components'; * * const repository = platform.get(PlatformServiceName.NotificationRepository); * const navigatorService = platform.get(PlatformServiceName.Navigator); * * const response = await repository.loadAll({ limit: 1 }); * const [notification] = response.items; * * if (notification && !notification.read) { * try { * await repository.markAsRead(notification); * * const limeobject = notification.limeobject; * if (limeobject) { * navigatorService.navigate( * `/object/${limeobject.getLimetype().name}/${limeobject.id}` * ); * } * } catch (error) { * console.error('Failed to mark as read:', error); * } * } * ``` * * @example Toggle read/unread status * ```ts * import { PlatformServiceName } from '@limetech/lime-web-components'; * * const repository = platform.get(PlatformServiceName.NotificationRepository); * * const response = await repository.loadAll({ limit: 1 }); * const [notification] = response.items; * * if (notification) { * const shouldBeRead = !notification.read; * * await repository.markAsRead(notification, shouldBeRead); * console.log(`Marked as ${shouldBeRead ? 'read' : 'unread'}`); * } * ``` * * @example Mark all as read * ```ts * import { PlatformServiceName } from '@limetech/lime-web-components'; * * const repository = platform.get(PlatformServiceName.NotificationRepository); * * const response = await repository.loadAll({ filter: { read: false } }); * * for (const notification of response.items) { * await repository.markAsRead(notification, true); * } * * console.log(`Marked ${response.items.length} notifications as read`); * ``` * * @see {@link Notification} for notification structure * @see {@link delete} to permanently remove a notification */ markAsRead(notification: Notification, read?: boolean): Promise>; } /** * The count response of loaded notifications * * @beta * @group NotificationRepository */ export type NotificationCount = { total: number; unread: number; }; /** * The response of loaded notifications * * @beta * @group NotificationRepository */ export type NotificationResponse = { items: Notification[]; count: NotificationCount; }; /** * The options to load notifications with * * @beta * @group NotificationRepository */ export interface NotificationLoadOptions { /** * Maximum number of notifications to load */ limit?: number; /** * Offset to start loading notifications from */ offset?: number; /** * Only return notifications newer than the notification with this ID */ newerThan?: number; /** * Only return notifications older than the notification with this ID */ olderThan?: number; /** * The properties to filter notifications by */ filter?: { read?: boolean; }; }