feat(v2.7): 接入协作治理前端体验
This commit is contained in:
32
apps/web/lib/notification.ts
Normal file
32
apps/web/lib/notification.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
export type NotificationType = 'assignment' | 'mention' | 'risk_alert' | 'overdue_item';
|
||||
|
||||
export interface NotificationRecord {
|
||||
id: string;
|
||||
recipientId: string;
|
||||
actorId?: string | null;
|
||||
type: NotificationType;
|
||||
title: string;
|
||||
body?: string;
|
||||
resourceType: string;
|
||||
resourceId: string;
|
||||
resourceVersionId?: string | null;
|
||||
productId?: string | null;
|
||||
projectId?: string | null;
|
||||
versionId?: string | null;
|
||||
metadata?: Record<string, unknown>;
|
||||
readAt?: string | null;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
export function countUnreadNotifications(items: Pick<NotificationRecord, 'readAt'>[]): number {
|
||||
return items.filter((item) => !item.readAt).length;
|
||||
}
|
||||
|
||||
export function sortNotificationsNewestFirst<T extends Pick<NotificationRecord, 'createdAt'>>(items: T[]): T[] {
|
||||
return [...items].sort((a, b) => dateValue(b.createdAt) - dateValue(a.createdAt));
|
||||
}
|
||||
|
||||
function dateValue(value: string): number {
|
||||
const time = new Date(value).getTime();
|
||||
return Number.isFinite(time) ? time : 0;
|
||||
}
|
||||
Reference in New Issue
Block a user