fix(workbench): keep active notices after reading
This commit is contained in:
@@ -3,6 +3,7 @@ import type { OperationalTask } from "../api/operational-task-client";
|
||||
import type { WorkbenchEvent } from "../api/workbench-sync-client";
|
||||
import {
|
||||
collectOperationalTaskEventChanges,
|
||||
selectHeaderNotifications,
|
||||
toOperationalTaskCondition
|
||||
} from "./use-operational-tasks";
|
||||
|
||||
@@ -123,6 +124,37 @@ describe("operational task event invalidation", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("operational notification visibility", () => {
|
||||
it("keeps a read notification visible until its business lifecycle is resolved", () => {
|
||||
const notification = {
|
||||
notification_id: "66666666-6666-4666-8666-666666666666",
|
||||
task_id: "22222222-2222-4222-8222-222222222222",
|
||||
kind: "action_approval_pending" as const,
|
||||
title: "待审批工单",
|
||||
description: "请审核派单内容",
|
||||
required_permission: null,
|
||||
lifecycle_status: "active" as const,
|
||||
subject_type: "action" as const,
|
||||
subject_id: "77777777-7777-4777-8777-777777777777",
|
||||
resolved_at: null,
|
||||
resolution_reason: null,
|
||||
status: "read" as const,
|
||||
version: 2,
|
||||
created_at: "2026-09-24T00:00:00Z",
|
||||
read_at: "2026-09-24T00:01:00Z",
|
||||
read_by: "principal:11111111-1111-4111-8111-111111111111"
|
||||
};
|
||||
|
||||
expect(selectHeaderNotifications([notification])).toEqual([notification]);
|
||||
expect(selectHeaderNotifications([{
|
||||
...notification,
|
||||
lifecycle_status: "resolved",
|
||||
resolved_at: "2026-09-24T00:02:00Z",
|
||||
resolution_reason: "action_approved"
|
||||
}])).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
function event(
|
||||
eventSequence: number,
|
||||
taskId: string,
|
||||
|
||||
@@ -59,6 +59,10 @@ export function collectOperationalTaskEventChanges(events: WorkbenchEvent[]) {
|
||||
return { taskIds, deletedTaskIds, notificationsChanged };
|
||||
}
|
||||
|
||||
export function selectHeaderNotifications(items: OperationalTaskNotification[]) {
|
||||
return items.filter((item) => item.lifecycle_status === "active");
|
||||
}
|
||||
|
||||
export function useOperationalTasks(
|
||||
getAccessToken: AccessTokenProvider | undefined,
|
||||
sync: WorkbenchSyncState
|
||||
@@ -106,9 +110,7 @@ export function useOperationalTasks(
|
||||
forceRefreshRef.current = false;
|
||||
detailResetGenerationRef.current = sync.detailResetGeneration;
|
||||
setTasks(nextTasks);
|
||||
setNotifications((sync.snapshot?.notifications ?? []).filter(
|
||||
(item) => item.lifecycle_status === "active" && item.status === "unread"
|
||||
));
|
||||
setNotifications(selectHeaderNotifications(sync.snapshot?.notifications ?? []));
|
||||
setAvailable(true);
|
||||
activatedRef.current = true;
|
||||
setError(null);
|
||||
@@ -283,13 +285,15 @@ export function useOperationalTasks(
|
||||
}, [getAccessToken, refresh]);
|
||||
|
||||
const acknowledgeNotification = useCallback(async (notificationId: string, version: number) => {
|
||||
await acknowledgeOperationalTaskNotification(
|
||||
const updated = await acknowledgeOperationalTaskNotification(
|
||||
notificationId,
|
||||
version,
|
||||
createOperationalRequestId(),
|
||||
getAccessToken
|
||||
);
|
||||
setNotifications((current) => current.filter((item) => item.notification_id !== notificationId));
|
||||
setNotifications((current) => selectHeaderNotifications(current.map((item) =>
|
||||
item.notification_id === notificationId ? updated : item
|
||||
)));
|
||||
}, [getAccessToken]);
|
||||
|
||||
const loadEvidenceSnapshot = useCallback((taskId: string, evidenceId: string) =>
|
||||
|
||||
Reference in New Issue
Block a user