@parhelia/core 0.1.12241 → 0.1.12259

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. package/dist/agents-view/AgentsWorkspaceView.js +9 -1
  2. package/dist/agents-view/AgentsWorkspaceView.js.map +1 -1
  3. package/dist/components/MarkdownDisplay.d.ts +10 -0
  4. package/dist/components/MarkdownDisplay.js +197 -0
  5. package/dist/components/MarkdownDisplay.js.map +1 -0
  6. package/dist/config/config.js +4 -1
  7. package/dist/config/config.js.map +1 -1
  8. package/dist/config/notificationRoutes.d.ts +2 -0
  9. package/dist/config/notificationRoutes.js +195 -0
  10. package/dist/config/notificationRoutes.js.map +1 -0
  11. package/dist/config/types.d.ts +7 -0
  12. package/dist/config/types.js.map +1 -1
  13. package/dist/editor/ContentTree.d.ts +2 -1
  14. package/dist/editor/ContentTree.js +11 -3
  15. package/dist/editor/ContentTree.js.map +1 -1
  16. package/dist/editor/Editor.js +12 -3
  17. package/dist/editor/Editor.js.map +1 -1
  18. package/dist/editor/GlobalMenuBar.js +29 -1
  19. package/dist/editor/GlobalMenuBar.js.map +1 -1
  20. package/dist/editor/ai/AgentTerminal.d.ts +9 -1
  21. package/dist/editor/ai/AgentTerminal.js +233 -53
  22. package/dist/editor/ai/AgentTerminal.js.map +1 -1
  23. package/dist/editor/ai/dialogs/AgentDialogHandler.js +5 -0
  24. package/dist/editor/ai/dialogs/AgentDialogHandler.js.map +1 -1
  25. package/dist/editor/ai/dialogs/QuestionnaireInline.d.ts +3 -1
  26. package/dist/editor/ai/dialogs/QuestionnaireInline.js +5 -5
  27. package/dist/editor/ai/dialogs/QuestionnaireInline.js.map +1 -1
  28. package/dist/editor/client/EditorShell.js +5 -1
  29. package/dist/editor/client/EditorShell.js.map +1 -1
  30. package/dist/editor/client/editContext.d.ts +4 -1
  31. package/dist/editor/client/editContext.js.map +1 -1
  32. package/dist/editor/client/hooks/useEditorWebSocket.js +36 -4
  33. package/dist/editor/client/hooks/useEditorWebSocket.js.map +1 -1
  34. package/dist/editor/client/hooks/useSocketMessageHandler.js +2 -0
  35. package/dist/editor/client/hooks/useSocketMessageHandler.js.map +1 -1
  36. package/dist/editor/client/operations.d.ts +2 -1
  37. package/dist/editor/client/operations.js +8 -0
  38. package/dist/editor/client/operations.js.map +1 -1
  39. package/dist/editor/commands/itemCommands.d.ts +1 -0
  40. package/dist/editor/commands/itemCommands.js +23 -1
  41. package/dist/editor/commands/itemCommands.js.map +1 -1
  42. package/dist/editor/menubar/toolbar-sections/ManualBrowser.js +2 -134
  43. package/dist/editor/menubar/toolbar-sections/ManualBrowser.js.map +1 -1
  44. package/dist/editor/notifications/NotificationCenter.d.ts +1 -0
  45. package/dist/editor/notifications/NotificationCenter.js +69 -0
  46. package/dist/editor/notifications/NotificationCenter.js.map +1 -0
  47. package/dist/editor/notifications/NotificationItem.d.ts +14 -0
  48. package/dist/editor/notifications/NotificationItem.js +40 -0
  49. package/dist/editor/notifications/NotificationItem.js.map +1 -0
  50. package/dist/editor/notifications/WatchButton.d.ts +7 -0
  51. package/dist/editor/notifications/WatchButton.js +191 -0
  52. package/dist/editor/notifications/WatchButton.js.map +1 -0
  53. package/dist/editor/notifications/notificationListState.d.ts +25 -0
  54. package/dist/editor/notifications/notificationListState.js +38 -0
  55. package/dist/editor/notifications/notificationListState.js.map +1 -0
  56. package/dist/editor/notifications/notificationRoutes.d.ts +15 -0
  57. package/dist/editor/notifications/notificationRoutes.js +58 -0
  58. package/dist/editor/notifications/notificationRoutes.js.map +1 -0
  59. package/dist/editor/notifications/useNotificationSubscriptions.d.ts +14 -0
  60. package/dist/editor/notifications/useNotificationSubscriptions.js +88 -0
  61. package/dist/editor/notifications/useNotificationSubscriptions.js.map +1 -0
  62. package/dist/editor/notifications/useNotifications.d.ts +28 -0
  63. package/dist/editor/notifications/useNotifications.js +166 -0
  64. package/dist/editor/notifications/useNotifications.js.map +1 -0
  65. package/dist/editor/page-viewer/MiniMap.js.map +1 -1
  66. package/dist/editor/reviews/CreateReviewConfirmStep.d.ts +2 -1
  67. package/dist/editor/reviews/CreateReviewConfirmStep.js +3 -3
  68. package/dist/editor/reviews/CreateReviewConfirmStep.js.map +1 -1
  69. package/dist/editor/reviews/CreateReviewDialog.js +24 -9
  70. package/dist/editor/reviews/CreateReviewDialog.js.map +1 -1
  71. package/dist/editor/reviews/ReviewDetail.js +2 -1
  72. package/dist/editor/reviews/ReviewDetail.js.map +1 -1
  73. package/dist/editor/services/agentService.d.ts +6 -0
  74. package/dist/editor/services/agentService.js +32 -10
  75. package/dist/editor/services/agentService.js.map +1 -1
  76. package/dist/editor/services/contentService.d.ts +1 -0
  77. package/dist/editor/services/contentService.js +3 -0
  78. package/dist/editor/services/contentService.js.map +1 -1
  79. package/dist/editor/services/notificationService.d.ts +73 -0
  80. package/dist/editor/services/notificationService.js +72 -0
  81. package/dist/editor/services/notificationService.js.map +1 -0
  82. package/dist/editor/ui/PublishItemDialog.d.ts +8 -0
  83. package/dist/editor/ui/PublishItemDialog.js +193 -0
  84. package/dist/editor/ui/PublishItemDialog.js.map +1 -0
  85. package/dist/editor/ui/PublishRestrictionsDialog.js +165 -75
  86. package/dist/editor/ui/PublishRestrictionsDialog.js.map +1 -1
  87. package/dist/editor/ui/TreeListSelector.d.ts +2 -1
  88. package/dist/editor/ui/TreeListSelector.js +2 -2
  89. package/dist/editor/ui/TreeListSelector.js.map +1 -1
  90. package/dist/revision.d.ts +2 -2
  91. package/dist/revision.js +2 -2
  92. package/dist/splash-screen/ParheliaAssistantChat.js +9 -9
  93. package/dist/splash-screen/ParheliaAssistantChat.js.map +1 -1
  94. package/dist/task-board/TaskBoardWorkspace.js +716 -402
  95. package/dist/task-board/TaskBoardWorkspace.js.map +1 -1
  96. package/dist/task-board/components/AssignAgentDialog.js +2 -3
  97. package/dist/task-board/components/AssignAgentDialog.js.map +1 -1
  98. package/dist/task-board/components/CreateProjectDialog.d.ts +4 -1
  99. package/dist/task-board/components/CreateProjectDialog.js +23 -8
  100. package/dist/task-board/components/CreateProjectDialog.js.map +1 -1
  101. package/dist/task-board/components/TaskAgentPanel.js +10 -6
  102. package/dist/task-board/components/TaskAgentPanel.js.map +1 -1
  103. package/dist/task-board/components/TaskBoardMyTasksSidebar.js +48 -2
  104. package/dist/task-board/components/TaskBoardMyTasksSidebar.js.map +1 -1
  105. package/dist/task-board/components/TaskBoardTitlebar.js +4 -4
  106. package/dist/task-board/components/TaskBoardTitlebar.js.map +1 -1
  107. package/dist/task-board/components/TaskDetailPanel.js +2 -1
  108. package/dist/task-board/components/TaskDetailPanel.js.map +1 -1
  109. package/dist/task-board/components/TaskReviewActions.d.ts +8 -0
  110. package/dist/task-board/components/TaskReviewActions.js +110 -0
  111. package/dist/task-board/components/TaskReviewActions.js.map +1 -0
  112. package/dist/task-board/components/TaskRow.js +1 -1
  113. package/dist/task-board/components/TaskRow.js.map +1 -1
  114. package/dist/task-board/components/WizardCommunicationCenter.d.ts +30 -0
  115. package/dist/task-board/components/WizardCommunicationCenter.js +185 -0
  116. package/dist/task-board/components/WizardCommunicationCenter.js.map +1 -0
  117. package/dist/task-board/taskAgentConfig.d.ts +1 -3
  118. package/dist/task-board/taskAgentConfig.js +5 -15
  119. package/dist/task-board/taskAgentConfig.js.map +1 -1
  120. package/dist/task-board/taskAgentLink.js +4 -2
  121. package/dist/task-board/taskAgentLink.js.map +1 -1
  122. package/dist/task-board/taskBoardNavStore.d.ts +0 -1
  123. package/dist/task-board/taskBoardNavStore.js +0 -1
  124. package/dist/task-board/taskBoardNavStore.js.map +1 -1
  125. package/dist/task-board/taskExecutionStatus.js +13 -3
  126. package/dist/task-board/taskExecutionStatus.js.map +1 -1
  127. package/dist/task-board/types.d.ts +2 -0
  128. package/dist/task-board/views/KanbanView.js +3 -0
  129. package/dist/task-board/views/KanbanView.js.map +1 -1
  130. package/dist/task-board/views/ListView.js +3 -0
  131. package/dist/task-board/views/ListView.js.map +1 -1
  132. package/dist/task-board/views/WizardView.d.ts +9 -7
  133. package/dist/task-board/views/WizardView.js +164 -39
  134. package/dist/task-board/views/WizardView.js.map +1 -1
  135. package/dist/types.d.ts +19 -1
  136. package/package.json +1 -2
  137. package/styles.css +6 -10
@@ -0,0 +1,191 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { Check, ChevronDown, Eye, Flag, FolderTree, MessageSquare, PenLine, X, } from "lucide-react";
3
+ import { useCallback, useEffect, useMemo, useState } from "react";
4
+ import { Button } from "../../components/ui/button";
5
+ import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, } from "../../components/ui/dropdown-menu";
6
+ import { Tooltip, TooltipContent, TooltipTrigger, } from "../../components/ui/tooltip";
7
+ import { cn } from "../../lib/utils";
8
+ import { useEditContext } from "../client/editContext";
9
+ import { getDefaultNotificationEventTypes, notificationEventTypes, } from "../services/notificationService";
10
+ import { subscribeToNotificationTarget, unsubscribeFromNotificationTarget, useNotificationSubscriptions, } from "./useNotificationSubscriptions";
11
+ const itemWatchEventOptions = [
12
+ {
13
+ eventType: notificationEventTypes.itemChanged,
14
+ label: "Modifications",
15
+ icon: PenLine,
16
+ },
17
+ {
18
+ eventType: notificationEventTypes.feedback,
19
+ label: "Feedback",
20
+ icon: MessageSquare,
21
+ },
22
+ ];
23
+ const projectWatchEventOptions = [
24
+ {
25
+ eventType: notificationEventTypes.projectAttentionRequired,
26
+ label: "Attention required",
27
+ icon: Flag,
28
+ },
29
+ {
30
+ eventType: notificationEventTypes.projectTaskCompleted,
31
+ label: "Task completed",
32
+ icon: Check,
33
+ },
34
+ {
35
+ eventType: notificationEventTypes.projectFinished,
36
+ label: "Project finished",
37
+ icon: FolderTree,
38
+ },
39
+ ];
40
+ function getWatchEventOptions(targetType) {
41
+ if (targetType === "item")
42
+ return itemWatchEventOptions;
43
+ if (targetType === "project")
44
+ return projectWatchEventOptions;
45
+ return [];
46
+ }
47
+ function orderEventTypes(eventTypes, targetType) {
48
+ const eventOrder = getWatchEventOptions(targetType).map((option) => option.eventType);
49
+ return [...eventTypes].sort((left, right) => {
50
+ const leftIndex = eventOrder.indexOf(left);
51
+ const rightIndex = eventOrder.indexOf(right);
52
+ const normalizedLeft = leftIndex === -1 ? Number.MAX_SAFE_INTEGER : leftIndex;
53
+ const normalizedRight = rightIndex === -1 ? Number.MAX_SAFE_INTEGER : rightIndex;
54
+ return normalizedLeft - normalizedRight || left.localeCompare(right);
55
+ });
56
+ }
57
+ export function WatchButton(props) {
58
+ const { targetType, targetId, className } = props;
59
+ const editContext = useEditContext();
60
+ const [loading, setLoading] = useState(false);
61
+ const [currentLanguageOnly, setCurrentLanguageOnly] = useState(false);
62
+ const defaultEventTypes = useMemo(() => getDefaultNotificationEventTypes(targetType), [targetType]);
63
+ const [selectedEventTypes, setSelectedEventTypes] = useState(() => getDefaultNotificationEventTypes(props.targetType));
64
+ const { subscriptions } = useNotificationSubscriptions();
65
+ const current = useMemo(() => {
66
+ return subscriptions.find((s) => s.targetType.toLowerCase() === targetType && s.targetId === targetId);
67
+ }, [subscriptions, targetType, targetId]);
68
+ const isWatching = Boolean(current && !current.isMuted);
69
+ const isSubtree = Boolean(current?.includeDescendants);
70
+ const disabled = loading || !targetId;
71
+ const currentEventTypes = current?.eventTypes?.length && Array.isArray(current.eventTypes)
72
+ ? current.eventTypes
73
+ : defaultEventTypes;
74
+ const currentLanguage = targetType === "item"
75
+ ? editContext?.currentItemDescriptor?.language
76
+ : undefined;
77
+ const languageOnlyLabel = current?.language && current?.language !== currentLanguage
78
+ ? `Current language only (${current.language})`
79
+ : "Current language only";
80
+ const watchEventOptions = useMemo(() => getWatchEventOptions(targetType), [targetType]);
81
+ useEffect(() => {
82
+ setCurrentLanguageOnly(Boolean(current?.language));
83
+ }, [current?.language]);
84
+ useEffect(() => {
85
+ setSelectedEventTypes(orderEventTypes(currentEventTypes, targetType));
86
+ }, [current?.eventTypes, currentEventTypes, targetType]);
87
+ const doSubscribe = useCallback(async (descendants, options) => {
88
+ if (disabled)
89
+ return;
90
+ setLoading(true);
91
+ try {
92
+ const eventTypes = orderEventTypes(options?.eventTypes ?? selectedEventTypes, targetType);
93
+ const applyCurrentLanguageOnly = options?.currentLanguageOnly ?? currentLanguageOnly;
94
+ await subscribeToNotificationTarget({
95
+ targetType,
96
+ targetId,
97
+ includeDescendants: targetType === "item" ? descendants : false,
98
+ language: targetType === "item" && applyCurrentLanguageOnly
99
+ ? currentLanguage
100
+ : undefined,
101
+ eventTypes,
102
+ });
103
+ }
104
+ finally {
105
+ setLoading(false);
106
+ }
107
+ }, [
108
+ currentLanguage,
109
+ currentLanguageOnly,
110
+ disabled,
111
+ selectedEventTypes,
112
+ targetId,
113
+ targetType,
114
+ ]);
115
+ const doUnsubscribe = useCallback(async () => {
116
+ if (disabled)
117
+ return;
118
+ setLoading(true);
119
+ try {
120
+ await unsubscribeFromNotificationTarget({ targetType, targetId });
121
+ }
122
+ finally {
123
+ setLoading(false);
124
+ }
125
+ }, [disabled, targetId, targetType]);
126
+ const toggleSimple = useCallback(async () => {
127
+ if (disabled)
128
+ return;
129
+ if (!current) {
130
+ await doSubscribe(false);
131
+ }
132
+ else {
133
+ await doUnsubscribe();
134
+ }
135
+ }, [current, disabled, doSubscribe, doUnsubscribe]);
136
+ const iconCls = "size-3.5";
137
+ const stateIcon = isSubtree ? (_jsx(FolderTree, { className: iconCls })) : (_jsx(Eye, { className: iconCls }));
138
+ const toggleTooltip = isWatching
139
+ ? isSubtree
140
+ ? "Watching subtree (click to unwatch)"
141
+ : "Watching (click to unwatch)"
142
+ : "Watch";
143
+ const menuTooltip = "Watch options";
144
+ const activeButtonClass = isWatching
145
+ ? "bg-theme-secondary-light text-accent-foreground hover:bg-theme-secondary-light/90"
146
+ : undefined;
147
+ const toggleEventType = useCallback((eventType) => {
148
+ const nextEventTypes = (() => {
149
+ if (selectedEventTypes.includes(eventType)) {
150
+ if (selectedEventTypes.length === 1)
151
+ return selectedEventTypes;
152
+ return selectedEventTypes.filter((value) => value !== eventType);
153
+ }
154
+ return orderEventTypes([...selectedEventTypes, eventType], targetType);
155
+ })();
156
+ setSelectedEventTypes(nextEventTypes);
157
+ if (isWatching) {
158
+ void doSubscribe(isSubtree, { eventTypes: nextEventTypes });
159
+ }
160
+ }, [doSubscribe, isSubtree, isWatching, selectedEventTypes, targetType]);
161
+ const toggleCurrentLanguageOnly = useCallback(() => {
162
+ const nextCurrentLanguageOnly = !currentLanguageOnly;
163
+ setCurrentLanguageOnly(nextCurrentLanguageOnly);
164
+ if (isWatching) {
165
+ void doSubscribe(isSubtree, {
166
+ currentLanguageOnly: nextCurrentLanguageOnly,
167
+ });
168
+ }
169
+ }, [currentLanguageOnly, doSubscribe, isSubtree, isWatching]);
170
+ if (targetType === "item" || targetType === "project") {
171
+ const watchActionLabel = targetType === "item" ? "Watch item" : "Watch project";
172
+ const watchActionTestId = targetType === "item"
173
+ ? `watch-button-${targetType}-${targetId}-watch-item`
174
+ : `watch-button-${targetType}-${targetId}-watch-project`;
175
+ return (_jsxs("div", { className: cn("inline-flex items-center", className), "data-testid": targetType === "item" ? `watch-button-${targetType}-${targetId}` : undefined, children: [_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", size: "iconSm", className: cn("rounded-r-none border-r-0", activeButtonClass), disabled: disabled, onClick: () => void toggleSimple(), "data-testid": targetType === "item"
176
+ ? `watch-button-${targetType}-${targetId}-toggle`
177
+ : `watch-button-${targetType}-${targetId}`, "aria-label": toggleTooltip, children: stateIcon }) }), _jsx(TooltipContent, { children: toggleTooltip })] }), _jsxs(DropdownMenu, { children: [_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", size: "iconSm", className: cn("w-5 min-w-0 rounded-l-none px-0", activeButtonClass), disabled: disabled, "data-testid": `watch-button-${targetType}-${targetId}-menu-trigger`, "aria-label": menuTooltip, children: _jsx(ChevronDown, { className: "size-3" }) }) }) }), _jsx(TooltipContent, { children: menuTooltip })] }), _jsxs(DropdownMenuContent, { align: "end", className: "min-w-[160px]", children: [_jsxs(DropdownMenuItem, { onClick: () => void doSubscribe(false), "data-testid": watchActionTestId, className: cn("gap-2", isWatching &&
178
+ !isSubtree &&
179
+ "bg-theme-secondary-light text-accent-foreground hover:bg-theme-secondary-light/90"), children: [_jsx(Eye, { className: "size-3.5" }), watchActionLabel, isWatching && !isSubtree && (_jsx(Check, { className: "ml-auto size-3.5 text-green-600" }))] }), targetType === "item" && (_jsxs(_Fragment, { children: [_jsxs(DropdownMenuItem, { onClick: () => void doSubscribe(true), "data-testid": `watch-button-${targetType}-${targetId}-watch-subtree`, className: cn("gap-2", isWatching &&
180
+ isSubtree &&
181
+ "bg-theme-secondary-light text-accent-foreground hover:bg-theme-secondary-light/90"), children: [_jsx(FolderTree, { className: "size-3.5" }), "Watch subtree", isWatching && isSubtree && (_jsx(Check, { className: "ml-auto size-3.5 text-green-600" }))] }), _jsxs(DropdownMenuItem, { disabled: !currentLanguage, onClick: () => toggleCurrentLanguageOnly(), onSelect: (event) => event.preventDefault(), "data-testid": `watch-button-${targetType}-${targetId}-current-language-only`, className: cn("gap-2 text-xs", currentLanguageOnly &&
182
+ "bg-theme-secondary-light text-accent-foreground hover:bg-theme-secondary-light/90"), children: [_jsx(Flag, { className: "size-3.5" }), languageOnlyLabel, currentLanguageOnly && (_jsx(Check, { className: "ml-auto size-3.5 text-green-600" }))] })] })), _jsx(DropdownMenuSeparator, {}), watchEventOptions.map((option) => {
183
+ const selected = selectedEventTypes.includes(option.eventType);
184
+ const Icon = option.icon;
185
+ return (_jsxs(DropdownMenuItem, { onClick: () => toggleEventType(option.eventType), onSelect: (event) => event.preventDefault(), "data-testid": `watch-button-${targetType}-${targetId}-event-${option.eventType}`, className: cn("gap-2 text-xs", selected &&
186
+ "bg-theme-secondary-light text-accent-foreground hover:bg-theme-secondary-light/90"), children: [_jsx(Icon, { className: "size-3.5" }), option.label, selected && (_jsx(Check, { className: "ml-auto size-3.5 text-green-600" }))] }, option.eventType));
187
+ }), isWatching && (_jsxs(_Fragment, { children: [_jsx(DropdownMenuSeparator, {}), _jsxs(DropdownMenuItem, { onClick: () => void doUnsubscribe(), className: "gap-2", variant: "destructive", "data-testid": `watch-button-${targetType}-${targetId}-unwatch`, children: [_jsx(X, { className: "size-3.5" }), "Unwatch"] })] }))] })] })] }));
188
+ }
189
+ return (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", size: "iconSm", className: cn(className, activeButtonClass), disabled: disabled, onClick: () => void toggleSimple(), "data-testid": `watch-button-${targetType}-${targetId}`, "aria-label": toggleTooltip, children: stateIcon }) }), _jsx(TooltipContent, { children: toggleTooltip })] }));
190
+ }
191
+ //# sourceMappingURL=WatchButton.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WatchButton.js","sourceRoot":"","sources":["../../../src/editor/notifications/WatchButton.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import type { NotificationRecord } from "../services/notificationService";
2
+ export declare function mergeNotificationLists(primary: NotificationRecord[], secondary: NotificationRecord[]): NotificationRecord[];
3
+ export declare function buildNotificationQuery(options: {
4
+ showAll: boolean;
5
+ skip: number;
6
+ take: number;
7
+ }): {
8
+ skip: number;
9
+ take: number;
10
+ unreadOnly: boolean | undefined;
11
+ };
12
+ export declare function getNextOffsetAfterRealtime(currentOffset: number): number;
13
+ export declare function getNextOffsetAfterMarkRead(currentOffset: number, showAll: boolean): number;
14
+ export declare function applyMarkReadToNotifications(notifications: NotificationRecord[], id: string, showAll: boolean): NotificationRecord[];
15
+ export declare function applyMarkAllReadToNotifications(notifications: NotificationRecord[], showAll: boolean): {
16
+ isRead: boolean;
17
+ id: string;
18
+ userId: string;
19
+ type: string;
20
+ priority?: string;
21
+ title: string;
22
+ message: string;
23
+ contextJson?: string | null;
24
+ createdAt: string;
25
+ }[];
@@ -0,0 +1,38 @@
1
+ export function mergeNotificationLists(primary, secondary) {
2
+ const seen = new Set();
3
+ const merged = [];
4
+ for (const notification of [...primary, ...secondary]) {
5
+ if (seen.has(notification.id))
6
+ continue;
7
+ seen.add(notification.id);
8
+ merged.push(notification);
9
+ }
10
+ return merged;
11
+ }
12
+ export function buildNotificationQuery(options) {
13
+ return {
14
+ skip: options.skip,
15
+ take: options.take,
16
+ unreadOnly: options.showAll ? undefined : true,
17
+ };
18
+ }
19
+ export function getNextOffsetAfterRealtime(currentOffset) {
20
+ return currentOffset + 1;
21
+ }
22
+ export function getNextOffsetAfterMarkRead(currentOffset, showAll) {
23
+ if (showAll)
24
+ return currentOffset;
25
+ return Math.max(0, currentOffset - 1);
26
+ }
27
+ export function applyMarkReadToNotifications(notifications, id, showAll) {
28
+ if (!showAll) {
29
+ return notifications.filter((notification) => notification.id !== id);
30
+ }
31
+ return notifications.map((notification) => notification.id === id ? { ...notification, isRead: true } : notification);
32
+ }
33
+ export function applyMarkAllReadToNotifications(notifications, showAll) {
34
+ if (!showAll)
35
+ return [];
36
+ return notifications.map((notification) => ({ ...notification, isRead: true }));
37
+ }
38
+ //# sourceMappingURL=notificationListState.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notificationListState.js","sourceRoot":"","sources":["../../../src/editor/notifications/notificationListState.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,sBAAsB,CACpC,OAA6B,EAC7B,SAA+B;IAE/B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,MAAM,GAAyB,EAAE,CAAC;IAExC,KAAK,MAAM,YAAY,IAAI,CAAC,GAAG,OAAO,EAAE,GAAG,SAAS,CAAC,EAAE,CAAC;QACtD,IAAI,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;YAAE,SAAS;QACxC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;QAC1B,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC5B,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,OAItC;IACC,OAAO;QACL,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,UAAU,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI;KAC/C,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,aAAqB;IAC9D,OAAO,aAAa,GAAG,CAAC,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,aAAqB,EAAE,OAAgB;IAChF,IAAI,OAAO;QAAE,OAAO,aAAa,CAAC;IAClC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,aAAa,GAAG,CAAC,CAAC,CAAC;AACxC,CAAC;AAED,MAAM,UAAU,4BAA4B,CAC1C,aAAmC,EACnC,EAAU,EACV,OAAgB;IAEhB,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,aAAa,CAAC,MAAM,CAAC,CAAC,YAAY,EAAE,EAAE,CAAC,YAAY,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;IACxE,CAAC;IAED,OAAO,aAAa,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,EAAE,CACxC,YAAY,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,YAAY,CAC1E,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,+BAA+B,CAC7C,aAAmC,EACnC,OAAgB;IAEhB,IAAI,CAAC,OAAO;QAAE,OAAO,EAAE,CAAC;IACxB,OAAO,aAAa,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AAClF,CAAC"}
@@ -0,0 +1,15 @@
1
+ import type { EditContextType } from "../client/editContext";
2
+ import type { NotificationRecord } from "../services/notificationService";
3
+ export type NotificationWithContext = NotificationRecord & {
4
+ context?: unknown;
5
+ };
6
+ export type NotificationSubscriptionTarget = {
7
+ targetType: string;
8
+ targetId: string;
9
+ };
10
+ type NotificationAction = {
11
+ open: () => Promise<boolean>;
12
+ };
13
+ export declare function resolveNotificationSubscriptionTarget(notification: NotificationWithContext): NotificationSubscriptionTarget | null;
14
+ export declare function resolveNotificationAction(editContext: EditContextType | null | undefined, notification: NotificationWithContext): NotificationAction | null;
15
+ export {};
@@ -0,0 +1,58 @@
1
+ function asNotificationRecord(value) {
2
+ if (!value || typeof value !== "object" || Array.isArray(value))
3
+ return null;
4
+ return value;
5
+ }
6
+ function getNotificationStringField(record, key) {
7
+ if (!record)
8
+ return null;
9
+ const value = record[key];
10
+ if (typeof value !== "string")
11
+ return null;
12
+ const trimmed = value.trim();
13
+ return trimmed.length > 0 ? trimmed : null;
14
+ }
15
+ export function resolveNotificationSubscriptionTarget(notification) {
16
+ const context = asNotificationRecord(notification.context);
17
+ const explicitTargetType = getNotificationStringField(context, "targetType");
18
+ const explicitTargetId = getNotificationStringField(context, "targetId");
19
+ if (explicitTargetType && explicitTargetId) {
20
+ return {
21
+ targetType: explicitTargetType.toLowerCase(),
22
+ targetId: explicitTargetId,
23
+ };
24
+ }
25
+ switch (notification.type) {
26
+ case "item-changed":
27
+ case "feedback": {
28
+ const itemId = getNotificationStringField(context, "itemId");
29
+ return itemId ? { targetType: "item", targetId: itemId } : null;
30
+ }
31
+ case "review-invitation":
32
+ case "review-completed":
33
+ case "review-rejected": {
34
+ const reviewId = getNotificationStringField(context, "reviewId");
35
+ return reviewId ? { targetType: "review", targetId: reviewId } : null;
36
+ }
37
+ case "task-status-changed": {
38
+ const projectId = getNotificationStringField(context, "projectId");
39
+ return projectId ? { targetType: "project", targetId: projectId } : null;
40
+ }
41
+ default:
42
+ return null;
43
+ }
44
+ }
45
+ export function resolveNotificationAction(editContext, notification) {
46
+ if (!editContext)
47
+ return null;
48
+ const route = editContext.configuration?.editor?.notificationRoutes?.[notification.type];
49
+ if (!route)
50
+ return null;
51
+ const parsedContext = route.parseContext(notification.context);
52
+ if (!parsedContext)
53
+ return null;
54
+ return {
55
+ open: async () => Boolean(await route.open(editContext, parsedContext)),
56
+ };
57
+ }
58
+ //# sourceMappingURL=notificationRoutes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notificationRoutes.js","sourceRoot":"","sources":["../../../src/editor/notifications/notificationRoutes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { type NotificationSubscription, type NotificationTargetRequest, type SubscribeNotificationRequest } from "../services/notificationService";
2
+ export declare function refreshNotificationSubscriptions(): Promise<void>;
3
+ export declare function subscribeToNotificationTarget(request: SubscribeNotificationRequest): Promise<import("../..").ExecutionResult<NotificationSubscription>>;
4
+ export declare function unsubscribeFromNotificationTarget(request: NotificationTargetRequest): Promise<import("../..").ExecutionResult<{
5
+ success: boolean;
6
+ }>>;
7
+ export declare function useNotificationSubscriptions(): {
8
+ subscriptions: NotificationSubscription[];
9
+ initialized: boolean;
10
+ refreshing: boolean;
11
+ refreshSubscriptions: typeof refreshNotificationSubscriptions;
12
+ subscribeToTarget: typeof subscribeToNotificationTarget;
13
+ unsubscribeFromTarget: typeof unsubscribeFromNotificationTarget;
14
+ };
@@ -0,0 +1,88 @@
1
+ import { useEffect, useSyncExternalStore } from "react";
2
+ import { getNotificationSubscriptions, subscribeToNotifications, unsubscribeFromNotifications, } from "../services/notificationService";
3
+ let snapshot = {
4
+ subscriptions: [],
5
+ initialized: false,
6
+ refreshing: false,
7
+ };
8
+ let refreshPromise = null;
9
+ const listeners = new Set();
10
+ function emitChange() {
11
+ listeners.forEach((listener) => listener());
12
+ }
13
+ function setSnapshot(next) {
14
+ snapshot = typeof next === "function" ? next(snapshot) : next;
15
+ emitChange();
16
+ }
17
+ function getSnapshot() {
18
+ return snapshot;
19
+ }
20
+ function subscribe(listener) {
21
+ listeners.add(listener);
22
+ return () => {
23
+ listeners.delete(listener);
24
+ };
25
+ }
26
+ function matchesTarget(subscription, target) {
27
+ return (subscription.targetType.toLowerCase() === target.targetType.toLowerCase() &&
28
+ subscription.targetId === target.targetId);
29
+ }
30
+ function upsertSubscription(nextSubscription) {
31
+ setSnapshot((current) => ({
32
+ ...current,
33
+ subscriptions: [
34
+ nextSubscription,
35
+ ...current.subscriptions.filter((subscription) => !matchesTarget(subscription, nextSubscription)),
36
+ ],
37
+ }));
38
+ }
39
+ export async function refreshNotificationSubscriptions() {
40
+ if (refreshPromise)
41
+ return refreshPromise;
42
+ setSnapshot((current) => ({ ...current, refreshing: true }));
43
+ refreshPromise = (async () => {
44
+ const result = await getNotificationSubscriptions();
45
+ setSnapshot((current) => ({
46
+ subscriptions: result.type === "success" ? (result.data ?? []) : current.subscriptions,
47
+ initialized: true,
48
+ refreshing: false,
49
+ }));
50
+ })().finally(() => {
51
+ refreshPromise = null;
52
+ });
53
+ return refreshPromise;
54
+ }
55
+ export async function subscribeToNotificationTarget(request) {
56
+ const result = await subscribeToNotifications(request);
57
+ if (result.type === "success" && result.data) {
58
+ upsertSubscription(result.data);
59
+ }
60
+ return result;
61
+ }
62
+ export async function unsubscribeFromNotificationTarget(request) {
63
+ const result = await unsubscribeFromNotifications(request);
64
+ if (result.type === "success") {
65
+ setSnapshot((current) => ({
66
+ ...current,
67
+ subscriptions: current.subscriptions.filter((subscription) => !matchesTarget(subscription, request)),
68
+ }));
69
+ }
70
+ return result;
71
+ }
72
+ export function useNotificationSubscriptions() {
73
+ const state = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
74
+ useEffect(() => {
75
+ if (!state.initialized && !state.refreshing) {
76
+ void refreshNotificationSubscriptions();
77
+ }
78
+ }, [state.initialized, state.refreshing]);
79
+ return {
80
+ subscriptions: state.subscriptions,
81
+ initialized: state.initialized,
82
+ refreshing: state.refreshing,
83
+ refreshSubscriptions: refreshNotificationSubscriptions,
84
+ subscribeToTarget: subscribeToNotificationTarget,
85
+ unsubscribeFromTarget: unsubscribeFromNotificationTarget,
86
+ };
87
+ }
88
+ //# sourceMappingURL=useNotificationSubscriptions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useNotificationSubscriptions.js","sourceRoot":"","sources":["../../../src/editor/notifications/useNotificationSubscriptions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import type { EditContextType } from "../client/editContext";
2
+ export declare function useNotifications(editContext?: EditContextType | null, options?: {
3
+ showAll?: boolean;
4
+ pageSize?: number;
5
+ }): {
6
+ notifications: {
7
+ context: unknown;
8
+ id: string;
9
+ userId: string;
10
+ type: string;
11
+ priority?: string;
12
+ title: string;
13
+ message: string;
14
+ contextJson?: string | null;
15
+ isRead: boolean;
16
+ createdAt: string;
17
+ }[];
18
+ subscriptions: import("../services/notificationService").NotificationSubscription[];
19
+ unreadCount: number;
20
+ loading: boolean;
21
+ loadingMore: boolean;
22
+ hasMore: boolean;
23
+ refresh: () => Promise<void>;
24
+ loadMore: () => Promise<void>;
25
+ markRead: (id: string) => Promise<boolean>;
26
+ markAllRead: () => Promise<boolean>;
27
+ unsubscribe: (targetType: string, targetId: string) => Promise<boolean>;
28
+ };