pixelize-design-library 3.0.0 → 3.1.0
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.
- package/CHANGELOG.md +64 -1
- package/COMPONENT-GOTCHAS.md +37 -13
- package/DESIGN-GUIDE.md +4 -1
- package/dist/Components/NotificationBell/NotificationBellProps.d.ts +3 -3
- package/dist/Components/NotificationBell/NotificationItem.d.ts +1 -1
- package/dist/Components/NotificationBell/NotificationItem.js +1 -1
- package/dist/Components/NotificationBell/NotificationList.d.ts +1 -1
- package/dist/Components/NotificationBell/NotificationList.js +1 -1
- package/dist/Components/NotificationBell/NotificationPanel.d.ts +1 -1
- package/dist/Components/NotificationBell/NotificationPanel.js +1 -1
- package/dist/Components/NotificationCenter/center/CenterPanel.d.ts +15 -0
- package/dist/Components/NotificationCenter/center/CenterPanel.js +87 -0
- package/dist/Components/NotificationCenter/center/NotificationCenter.d.ts +4 -0
- package/dist/Components/NotificationCenter/center/NotificationCenter.js +130 -0
- package/dist/Components/NotificationCenter/center/NotificationCenterProps.d.ts +71 -0
- package/dist/Components/NotificationCenter/center/NotificationCenterProps.js +2 -0
- package/dist/Components/NotificationCenter/center/PanelRows.d.ts +10 -0
- package/dist/Components/NotificationCenter/center/PanelRows.js +35 -0
- package/dist/Components/NotificationCenter/center/PanelStates.d.ts +17 -0
- package/dist/Components/NotificationCenter/center/PanelStates.js +21 -0
- package/dist/Components/NotificationCenter/center/centerLabels.d.ts +4 -0
- package/dist/Components/NotificationCenter/center/centerLabels.js +38 -0
- package/dist/Components/NotificationCenter/center/useArrivals.d.ts +14 -0
- package/dist/Components/NotificationCenter/center/useArrivals.js +71 -0
- package/dist/Components/NotificationCenter/center/useIsSheet.d.ts +2 -0
- package/dist/Components/NotificationCenter/center/useIsSheet.js +20 -0
- package/dist/Components/NotificationCenter/core/NotificationCenterProvider.d.ts +17 -0
- package/dist/Components/NotificationCenter/core/NotificationCenterProvider.js +46 -0
- package/dist/Components/NotificationCenter/core/NotificationEngineProps.d.ts +182 -0
- package/dist/Components/NotificationCenter/core/NotificationEngineProps.js +2 -0
- package/dist/Components/NotificationCenter/core/NotificationSourceProps.d.ts +284 -0
- package/dist/Components/NotificationCenter/core/NotificationSourceProps.js +2 -0
- package/dist/Components/NotificationCenter/core/actionError.d.ts +4 -0
- package/dist/Components/NotificationCenter/core/actionError.js +45 -0
- package/dist/Components/NotificationCenter/core/format.d.ts +4 -0
- package/dist/Components/NotificationCenter/core/format.js +91 -0
- package/dist/Components/NotificationCenter/core/grouping.d.ts +14 -0
- package/dist/Components/NotificationCenter/core/grouping.js +102 -0
- package/dist/Components/NotificationCenter/core/labels.d.ts +6 -0
- package/dist/Components/NotificationCenter/core/labels.js +94 -0
- package/dist/Components/NotificationCenter/core/overlay.d.ts +109 -0
- package/dist/Components/NotificationCenter/core/overlay.js +281 -0
- package/dist/Components/NotificationCenter/core/useNotificationEngine.d.ts +13 -0
- package/dist/Components/NotificationCenter/core/useNotificationEngine.js +415 -0
- package/dist/Components/NotificationCenter/inbox/InboxList.d.ts +17 -0
- package/dist/Components/NotificationCenter/inbox/InboxList.js +25 -0
- package/dist/Components/NotificationCenter/inbox/InboxStates.d.ts +17 -0
- package/dist/Components/NotificationCenter/inbox/InboxStates.js +27 -0
- package/dist/Components/NotificationCenter/inbox/NotificationInbox.d.ts +4 -0
- package/dist/Components/NotificationCenter/inbox/NotificationInbox.js +434 -0
- package/dist/Components/NotificationCenter/inbox/NotificationInboxProps.d.ts +106 -0
- package/dist/Components/NotificationCenter/inbox/NotificationInboxProps.js +2 -0
- package/dist/Components/NotificationCenter/inbox/ShortcutsDialog.d.ts +8 -0
- package/dist/Components/NotificationCenter/inbox/ShortcutsDialog.js +63 -0
- package/dist/Components/NotificationCenter/inbox/inboxLabels.d.ts +4 -0
- package/dist/Components/NotificationCenter/inbox/inboxLabels.js +56 -0
- package/dist/Components/NotificationCenter/inbox/inboxModel.d.ts +17 -0
- package/dist/Components/NotificationCenter/inbox/inboxModel.js +47 -0
- package/dist/Components/NotificationCenter/inbox/useControllable.d.ts +1 -0
- package/dist/Components/NotificationCenter/inbox/useControllable.js +15 -0
- package/dist/Components/NotificationCenter/index.d.ts +8 -0
- package/dist/Components/NotificationCenter/index.js +26 -0
- package/dist/Components/NotificationCenter/preferences/NotificationPreferences.d.ts +4 -0
- package/dist/Components/NotificationCenter/preferences/NotificationPreferences.js +72 -0
- package/dist/Components/NotificationCenter/preferences/NotificationPreferencesProps.d.ts +111 -0
- package/dist/Components/NotificationCenter/preferences/NotificationPreferencesProps.js +2 -0
- package/dist/Components/NotificationCenter/preferences/PreferenceCells.d.ts +16 -0
- package/dist/Components/NotificationCenter/preferences/PreferenceCells.js +35 -0
- package/dist/Components/NotificationCenter/preferences/PreferenceGroups.d.ts +15 -0
- package/dist/Components/NotificationCenter/preferences/PreferenceGroups.js +26 -0
- package/dist/Components/NotificationCenter/preferences/preferencesLabels.d.ts +2 -0
- package/dist/Components/NotificationCenter/preferences/preferencesLabels.js +28 -0
- package/dist/Components/NotificationCenter/preferences/useAutosave.d.ts +8 -0
- package/dist/Components/NotificationCenter/preferences/useAutosave.js +41 -0
- package/dist/Components/NotificationCenter/row/NotificationDetail.d.ts +4 -0
- package/dist/Components/NotificationCenter/row/NotificationDetail.js +65 -0
- package/dist/Components/NotificationCenter/row/NotificationDetailProps.d.ts +15 -0
- package/dist/Components/NotificationCenter/row/NotificationDetailProps.js +2 -0
- package/dist/Components/NotificationCenter/row/NotificationRow.d.ts +3 -0
- package/dist/Components/NotificationCenter/row/NotificationRow.js +124 -0
- package/dist/Components/NotificationCenter/row/NotificationRowProps.d.ts +33 -0
- package/dist/Components/NotificationCenter/row/NotificationRowProps.js +2 -0
- package/dist/Components/NotificationCenter/row/ReasonForm.d.ts +14 -0
- package/dist/Components/NotificationCenter/row/ReasonForm.js +59 -0
- package/dist/Components/NotificationCenter/row/RowActions.d.ts +16 -0
- package/dist/Components/NotificationCenter/row/RowActions.js +36 -0
- package/dist/Components/NotificationCenter/row/RowQuickActions.d.ts +17 -0
- package/dist/Components/NotificationCenter/row/RowQuickActions.js +57 -0
- package/dist/Components/NotificationCenter/row/RowStatus.d.ts +10 -0
- package/dist/Components/NotificationCenter/row/RowStatus.js +42 -0
- package/dist/Components/NotificationCenter/row/category.d.ts +8 -0
- package/dist/Components/NotificationCenter/row/category.js +13 -0
- package/dist/Components/NotificationCenter/row/rowMenu.d.ts +14 -0
- package/dist/Components/NotificationCenter/row/rowMenu.js +37 -0
- package/dist/Components/NotificationCenter/row/rowParts.d.ts +40 -0
- package/dist/Components/NotificationCenter/row/rowParts.js +72 -0
- package/dist/Components/NotificationCenter/row/rowStyles.d.ts +11 -0
- package/dist/Components/NotificationCenter/row/rowStyles.js +25 -0
- package/dist/Components/SegmentedControl/segmentedInk.d.ts +4 -0
- package/dist/Components/SegmentedControl/segmentedInk.js +16 -2
- package/dist/Components/SideBar/SecondaryBar.js +2 -2
- package/dist/Components/SideBar/SideBar.js +18 -8
- package/dist/Components/SideBar/SideBarProps.d.ts +4 -2
- package/dist/Components/SideBar/components/MenuItemBox.d.ts +0 -2
- package/dist/Components/SideBar/components/MenuItemBox.js +2 -3
- package/dist/Components/SideBar/components/MenuItems.js +2 -2
- package/dist/Components/SideBar/components/PinnedSection.js +3 -4
- package/dist/Components/SideBar/sidebarScale.d.ts +0 -2
- package/dist/Components/SideBar/sidebarScale.js +0 -2
- package/dist/Components/Switch/Switch.d.ts +1 -1
- package/dist/Components/Switch/Switch.js +2 -2
- package/dist/Components/Switch/SwitchProps.d.ts +3 -0
- package/dist/Components/Toggle/TableToggle.js +4 -5
- package/dist/Components/Toggle/tableToggleInk.d.ts +7 -0
- package/dist/Components/Toggle/tableToggleInk.js +28 -0
- package/dist/esm/Components/NotificationBell/NotificationItem.js +1 -1
- package/dist/esm/Components/NotificationBell/NotificationList.js +1 -1
- package/dist/esm/Components/NotificationBell/NotificationPanel.js +1 -1
- package/dist/esm/Components/NotificationCenter/center/CenterPanel.js +81 -0
- package/dist/esm/Components/NotificationCenter/center/NotificationCenter.js +92 -0
- package/dist/esm/Components/NotificationCenter/center/NotificationCenterProps.js +1 -0
- package/dist/esm/Components/NotificationCenter/center/PanelRows.js +28 -0
- package/dist/esm/Components/NotificationCenter/center/PanelStates.js +11 -0
- package/dist/esm/Components/NotificationCenter/center/centerLabels.js +34 -0
- package/dist/esm/Components/NotificationCenter/center/useArrivals.js +67 -0
- package/dist/esm/Components/NotificationCenter/center/useIsSheet.js +16 -0
- package/dist/esm/Components/NotificationCenter/core/NotificationCenterProvider.js +35 -0
- package/dist/esm/Components/NotificationCenter/core/NotificationEngineProps.js +1 -0
- package/dist/esm/Components/NotificationCenter/core/NotificationSourceProps.js +1 -0
- package/dist/esm/Components/NotificationCenter/core/actionError.js +39 -0
- package/dist/esm/Components/NotificationCenter/core/format.js +87 -0
- package/dist/esm/Components/NotificationCenter/core/grouping.js +88 -0
- package/dist/esm/Components/NotificationCenter/core/labels.js +88 -0
- package/dist/esm/Components/NotificationCenter/core/overlay.js +274 -0
- package/dist/esm/Components/NotificationCenter/core/useNotificationEngine.js +408 -0
- package/dist/esm/Components/NotificationCenter/inbox/InboxList.js +18 -0
- package/dist/esm/Components/NotificationCenter/inbox/InboxStates.js +18 -0
- package/dist/esm/Components/NotificationCenter/inbox/NotificationInbox.js +396 -0
- package/dist/esm/Components/NotificationCenter/inbox/NotificationInboxProps.js +1 -0
- package/dist/esm/Components/NotificationCenter/inbox/ShortcutsDialog.js +23 -0
- package/dist/esm/Components/NotificationCenter/inbox/inboxLabels.js +52 -0
- package/dist/esm/Components/NotificationCenter/inbox/inboxModel.js +37 -0
- package/dist/esm/Components/NotificationCenter/inbox/useControllable.js +11 -0
- package/dist/esm/Components/NotificationCenter/index.js +8 -0
- package/dist/esm/Components/NotificationCenter/preferences/NotificationPreferences.js +67 -0
- package/dist/esm/Components/NotificationCenter/preferences/NotificationPreferencesProps.js +1 -0
- package/dist/esm/Components/NotificationCenter/preferences/PreferenceCells.js +27 -0
- package/dist/esm/Components/NotificationCenter/preferences/PreferenceGroups.js +21 -0
- package/dist/esm/Components/NotificationCenter/preferences/preferencesLabels.js +24 -0
- package/dist/esm/Components/NotificationCenter/preferences/useAutosave.js +37 -0
- package/dist/esm/Components/NotificationCenter/row/NotificationDetail.js +60 -0
- package/dist/esm/Components/NotificationCenter/row/NotificationDetailProps.js +1 -0
- package/dist/esm/Components/NotificationCenter/row/NotificationRow.js +119 -0
- package/dist/esm/Components/NotificationCenter/row/NotificationRowProps.js +1 -0
- package/dist/esm/Components/NotificationCenter/row/ReasonForm.js +52 -0
- package/dist/esm/Components/NotificationCenter/row/RowActions.js +28 -0
- package/dist/esm/Components/NotificationCenter/row/RowQuickActions.js +49 -0
- package/dist/esm/Components/NotificationCenter/row/RowStatus.js +35 -0
- package/dist/esm/Components/NotificationCenter/row/category.js +9 -0
- package/dist/esm/Components/NotificationCenter/row/rowMenu.js +30 -0
- package/dist/esm/Components/NotificationCenter/row/rowParts.js +59 -0
- package/dist/esm/Components/NotificationCenter/row/rowStyles.js +19 -0
- package/dist/esm/Components/SegmentedControl/segmentedInk.js +15 -2
- package/dist/esm/Components/SideBar/SecondaryBar.js +3 -3
- package/dist/esm/Components/SideBar/SideBar.js +18 -8
- package/dist/esm/Components/SideBar/components/MenuItemBox.js +2 -3
- package/dist/esm/Components/SideBar/components/MenuItems.js +2 -2
- package/dist/esm/Components/SideBar/components/PinnedSection.js +3 -4
- package/dist/esm/Components/SideBar/sidebarScale.js +0 -2
- package/dist/esm/Components/Switch/Switch.js +2 -2
- package/dist/esm/Components/Toggle/TableToggle.js +4 -5
- package/dist/esm/Components/Toggle/tableToggleInk.js +24 -0
- package/dist/esm/index.js +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +16 -3
- package/package.json +1 -1
|
@@ -0,0 +1,415 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.useNotificationEngine = exports.CLOCK_TICK_MS = exports.ARCHIVE_FOLD_MS = exports.DECISION_FOLD_MS = exports.UNDO_WINDOW_MS = void 0;
|
|
7
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
+
const react_1 = require("react");
|
|
9
|
+
const lucide_react_1 = require("lucide-react");
|
|
10
|
+
const Button_1 = __importDefault(require("../../Button/Button"));
|
|
11
|
+
const Toaster_1 = require("../../Toaster/Toaster");
|
|
12
|
+
const controlSizes_1 = require("../../../Theme/tokens/primitives/controlSizes");
|
|
13
|
+
const actionError_1 = require("./actionError");
|
|
14
|
+
const format_1 = require("./format");
|
|
15
|
+
const grouping_1 = require("./grouping");
|
|
16
|
+
const labels_1 = require("./labels");
|
|
17
|
+
const overlay_1 = require("./overlay");
|
|
18
|
+
exports.UNDO_WINDOW_MS = 6000;
|
|
19
|
+
exports.DECISION_FOLD_MS = 900;
|
|
20
|
+
exports.ARCHIVE_FOLD_MS = 220;
|
|
21
|
+
exports.CLOCK_TICK_MS = 60000;
|
|
22
|
+
const TOAST_POSITION = "bottom-right";
|
|
23
|
+
const ZERO_WIDTH_SPACE = String.fromCodePoint(0x200b);
|
|
24
|
+
const unique = (ids) => [...new Set(ids)];
|
|
25
|
+
const hasActionId = (entry, actionId) => Boolean(entry.actions && entry.actions.some((action) => action.id === actionId));
|
|
26
|
+
const isLive = (item) => item !== undefined;
|
|
27
|
+
const createEngineActions = (ctx) => {
|
|
28
|
+
const { latest, windows, undoOrder, mounted, batches, dispatch, announce } = ctx;
|
|
29
|
+
const nextBatch = () => {
|
|
30
|
+
batches.current += 1;
|
|
31
|
+
return `batch-${batches.current}`;
|
|
32
|
+
};
|
|
33
|
+
const toast = (props) => latest.current.toaster.showToast({ position: TOAST_POSITION, ...props });
|
|
34
|
+
const closeWindow = (win) => {
|
|
35
|
+
win.timers.forEach(clearTimeout);
|
|
36
|
+
if (win.toastId !== undefined)
|
|
37
|
+
latest.current.toaster.close(win.toastId);
|
|
38
|
+
windows.current.delete(win.batch);
|
|
39
|
+
undoOrder.current = undoOrder.current.filter((batch) => batch !== win.batch);
|
|
40
|
+
};
|
|
41
|
+
const sendWindow = (batch) => {
|
|
42
|
+
const win = windows.current.get(batch);
|
|
43
|
+
if (!win)
|
|
44
|
+
return;
|
|
45
|
+
closeWindow(win);
|
|
46
|
+
dispatch({ type: "fold", batch });
|
|
47
|
+
dispatch({ type: "send", batch });
|
|
48
|
+
win.send();
|
|
49
|
+
};
|
|
50
|
+
const undoWindow = (batch) => {
|
|
51
|
+
const win = windows.current.get(batch);
|
|
52
|
+
if (!win)
|
|
53
|
+
return false;
|
|
54
|
+
closeWindow(win);
|
|
55
|
+
dispatch({ type: "drop", batch });
|
|
56
|
+
const { labels } = latest.current;
|
|
57
|
+
announce(win.kind === "decision" ? labels.decisionUndone : labels.undone);
|
|
58
|
+
return true;
|
|
59
|
+
};
|
|
60
|
+
const openWindow = (win, foldAfter, props) => {
|
|
61
|
+
const timers = [];
|
|
62
|
+
if (foldAfter !== null)
|
|
63
|
+
timers.push(setTimeout(() => dispatch({ type: "fold", batch: win.batch }), foldAfter));
|
|
64
|
+
timers.push(setTimeout(() => sendWindow(win.batch), exports.UNDO_WINDOW_MS));
|
|
65
|
+
const record = { ...win, timers };
|
|
66
|
+
windows.current.set(win.batch, record);
|
|
67
|
+
undoOrder.current = [...undoOrder.current, win.batch];
|
|
68
|
+
const { labels } = latest.current;
|
|
69
|
+
record.toastId = toast({
|
|
70
|
+
...props,
|
|
71
|
+
duration: null,
|
|
72
|
+
actions: () => ((0, jsx_runtime_1.jsx)(Button_1.default, { size: "xs", variant: "outline", colorScheme: "gray", label: labels.undo, onClick: () => undoWindow(win.batch) })),
|
|
73
|
+
});
|
|
74
|
+
};
|
|
75
|
+
const sendThen = (batch, call, failTitle) => {
|
|
76
|
+
Promise.resolve()
|
|
77
|
+
.then(call)
|
|
78
|
+
.then(() => {
|
|
79
|
+
if (mounted.current)
|
|
80
|
+
dispatch({ type: "settle", batch });
|
|
81
|
+
}, () => {
|
|
82
|
+
if (!mounted.current)
|
|
83
|
+
return;
|
|
84
|
+
dispatch({ type: "drop", batch });
|
|
85
|
+
toast({ status: "error", title: failTitle });
|
|
86
|
+
});
|
|
87
|
+
};
|
|
88
|
+
const retryButton = (ids) => {
|
|
89
|
+
const renderRetry = (onClose) => ((0, jsx_runtime_1.jsx)(Button_1.default, { size: "xs", variant: "outline", colorScheme: "gray", leftIcon: (0, jsx_runtime_1.jsx)(lucide_react_1.RefreshCw, { size: controlSizes_1.BUTTON_SIZES.xs.iconSize, "aria-hidden": "true" }), label: latest.current.labels.retry, onClick: () => {
|
|
90
|
+
onClose();
|
|
91
|
+
retryMany(ids);
|
|
92
|
+
} }));
|
|
93
|
+
return renderRetry;
|
|
94
|
+
};
|
|
95
|
+
const finishDecisions = (batch, decision, results) => {
|
|
96
|
+
var _a, _b;
|
|
97
|
+
if (!mounted.current)
|
|
98
|
+
return;
|
|
99
|
+
const { labels } = latest.current;
|
|
100
|
+
const outcomes = {};
|
|
101
|
+
results.forEach((result) => {
|
|
102
|
+
outcomes[result.id] = { batch, error: result.error };
|
|
103
|
+
});
|
|
104
|
+
dispatch({ type: "settleDecisions", outcomes });
|
|
105
|
+
const ofKind = (kind) => results.filter((result) => { var _a; return ((_a = result.error) === null || _a === void 0 ? void 0 : _a.kind) === kind; });
|
|
106
|
+
const soleMessage = (list) => { var _a; return (list.length === 1 ? (_a = list[0].error) === null || _a === void 0 ? void 0 : _a.message : undefined); };
|
|
107
|
+
const failed = ofKind("failed");
|
|
108
|
+
const conflicts = ofKind("conflict");
|
|
109
|
+
const forbidden = ofKind("forbidden");
|
|
110
|
+
const needsReason = ofKind("reasonRequired");
|
|
111
|
+
if (failed.length) {
|
|
112
|
+
toast({
|
|
113
|
+
status: "error",
|
|
114
|
+
title: labels.decisionFailed(decision.label, failed.length),
|
|
115
|
+
description: (_a = soleMessage(failed)) !== null && _a !== void 0 ? _a : labels.failedMessage,
|
|
116
|
+
actions: retryButton(failed.map((result) => result.id)),
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
if (conflicts.length) {
|
|
120
|
+
const title = labels.conflicted(conflicts.length);
|
|
121
|
+
toast({ status: "info", title, description: soleMessage(conflicts) });
|
|
122
|
+
announce(title);
|
|
123
|
+
}
|
|
124
|
+
if (forbidden.length) {
|
|
125
|
+
toast({ status: "error", title: labels.forbidden(forbidden.length), description: soleMessage(forbidden) });
|
|
126
|
+
}
|
|
127
|
+
if (needsReason.length) {
|
|
128
|
+
const title = labels.reasonNeeded(decision.label);
|
|
129
|
+
toast({ status: "warning", title, description: (_b = soleMessage(needsReason)) !== null && _b !== void 0 ? _b : labels.reasonRequiredMessage });
|
|
130
|
+
announce(title);
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
const sendDecisions = (batch, targets, decision) => {
|
|
134
|
+
const { onAction } = latest.current.source;
|
|
135
|
+
if (!onAction || !targets.length)
|
|
136
|
+
return;
|
|
137
|
+
const sends = targets.map((entry) => {
|
|
138
|
+
const action = entry.actions && entry.actions.find((candidate) => candidate.id === decision.actionId);
|
|
139
|
+
if (!action)
|
|
140
|
+
return Promise.resolve({ id: entry.id, error: { kind: "conflict" } });
|
|
141
|
+
return Promise.resolve()
|
|
142
|
+
.then(() => onAction(entry, action, decision.reason))
|
|
143
|
+
.then(() => ({ id: entry.id }), (error) => ({ id: entry.id, error: (0, actionError_1.toNotificationActionError)(error) }));
|
|
144
|
+
});
|
|
145
|
+
Promise.all(sends).then((results) => finishDecisions(batch, decision, results));
|
|
146
|
+
};
|
|
147
|
+
const retryMany = (ids) => {
|
|
148
|
+
const { source, live } = latest.current;
|
|
149
|
+
if (source.isOffline)
|
|
150
|
+
return;
|
|
151
|
+
const byDecision = new Map();
|
|
152
|
+
unique(ids)
|
|
153
|
+
.map((id) => live.byId.get(id))
|
|
154
|
+
.filter(isLive)
|
|
155
|
+
.forEach(({ entry, state }) => {
|
|
156
|
+
if (state.status !== "failed" || !state.decision)
|
|
157
|
+
return;
|
|
158
|
+
const group = byDecision.get(state.decision);
|
|
159
|
+
if (group)
|
|
160
|
+
group.push(entry);
|
|
161
|
+
else
|
|
162
|
+
byDecision.set(state.decision, [entry]);
|
|
163
|
+
});
|
|
164
|
+
byDecision.forEach((group, decision) => {
|
|
165
|
+
const batch = nextBatch();
|
|
166
|
+
dispatch({ type: "retry", batch, ids: group.map((entry) => entry.id) });
|
|
167
|
+
sendDecisions(batch, group, decision);
|
|
168
|
+
});
|
|
169
|
+
};
|
|
170
|
+
const setRead = (ids, read) => {
|
|
171
|
+
const { source, live, labels } = latest.current;
|
|
172
|
+
const { onMarkRead } = source;
|
|
173
|
+
if (!onMarkRead || source.isOffline)
|
|
174
|
+
return;
|
|
175
|
+
const targets = unique(ids).filter((id) => {
|
|
176
|
+
const item = live.byId.get(id);
|
|
177
|
+
return item !== undefined && item.entry.isRead !== undefined && item.entry.isRead !== read;
|
|
178
|
+
});
|
|
179
|
+
if (!targets.length)
|
|
180
|
+
return;
|
|
181
|
+
const batch = nextBatch();
|
|
182
|
+
dispatch({ type: "flag", key: "read", batch, ids: targets, value: read, phase: "sending" });
|
|
183
|
+
sendThen(batch, () => onMarkRead(targets, read), labels.readFailed(read));
|
|
184
|
+
};
|
|
185
|
+
const actions = {
|
|
186
|
+
open: (entry, event, action) => {
|
|
187
|
+
const { source, live } = latest.current;
|
|
188
|
+
const item = live.byId.get(entry.id);
|
|
189
|
+
if (item && item.entry.isRead === false)
|
|
190
|
+
setRead([entry.id], true);
|
|
191
|
+
source.onOpen(action && action.href ? { ...entry, href: action.href } : entry, event, action);
|
|
192
|
+
},
|
|
193
|
+
decide: (ids, action, reason) => {
|
|
194
|
+
var _a, _b;
|
|
195
|
+
const { source, live, labels } = latest.current;
|
|
196
|
+
if (!source.onAction || source.isOffline)
|
|
197
|
+
return;
|
|
198
|
+
const items = unique(ids)
|
|
199
|
+
.map((id) => live.byId.get(id))
|
|
200
|
+
.filter(isLive)
|
|
201
|
+
.filter((item) => item.state.status === "open" && hasActionId(item.entry, action.id));
|
|
202
|
+
if (!items.length)
|
|
203
|
+
return;
|
|
204
|
+
const trimmed = reason === undefined ? "" : reason.trim();
|
|
205
|
+
const decision = {
|
|
206
|
+
actionId: action.id,
|
|
207
|
+
label: action.label,
|
|
208
|
+
doneLabel: (_a = action.doneLabel) !== null && _a !== void 0 ? _a : action.label,
|
|
209
|
+
intent: (_b = action.intent) !== null && _b !== void 0 ? _b : "neutral",
|
|
210
|
+
reason: trimmed ? trimmed : undefined,
|
|
211
|
+
};
|
|
212
|
+
const targetIds = items.map((item) => item.entry.id);
|
|
213
|
+
const batch = nextBatch();
|
|
214
|
+
dispatch({ type: "decide", batch, ids: targetIds, decision });
|
|
215
|
+
const subject = items.length > 1 ? labels.requests(items.length) : items[0].entry.subject;
|
|
216
|
+
announce(labels.decidedAnnouncement(decision.doneLabel, subject));
|
|
217
|
+
const decided = items.map((item) => item.entry);
|
|
218
|
+
openWindow({ batch, kind: "decision", ids: targetIds, send: () => sendDecisions(batch, decided, decision) }, exports.DECISION_FOLD_MS, {
|
|
219
|
+
status: decision.intent === "negative" ? "info" : "success",
|
|
220
|
+
title: labels.decided(decision.doneLabel, subject),
|
|
221
|
+
description: decision.reason ? labels.reasonQuote(decision.reason) : undefined,
|
|
222
|
+
});
|
|
223
|
+
},
|
|
224
|
+
undo: (id) => {
|
|
225
|
+
const hit = [...windows.current.values()].find((win) => win.ids.includes(id));
|
|
226
|
+
if (hit)
|
|
227
|
+
undoWindow(hit.batch);
|
|
228
|
+
},
|
|
229
|
+
undoLast: () => {
|
|
230
|
+
const batch = undoOrder.current[undoOrder.current.length - 1];
|
|
231
|
+
return batch === undefined ? false : undoWindow(batch);
|
|
232
|
+
},
|
|
233
|
+
retry: (id) => retryMany([id]),
|
|
234
|
+
dismiss: (id) => dispatch({ type: "dismiss", id }),
|
|
235
|
+
clearReasonRequest: (id) => dispatch({ type: "clearReasonRequest", id }),
|
|
236
|
+
setRead,
|
|
237
|
+
markAllRead: (scope) => {
|
|
238
|
+
const { source, live, labels, counts } = latest.current;
|
|
239
|
+
const { onMarkAllRead } = source;
|
|
240
|
+
if (!onMarkAllRead || source.isOffline)
|
|
241
|
+
return;
|
|
242
|
+
const query = scope.query ? scope.query.trim() : "";
|
|
243
|
+
const ids = live.lists[scope.zone]
|
|
244
|
+
.filter((item) => item.entry.isRead === false &&
|
|
245
|
+
!item.state.isHidden &&
|
|
246
|
+
(!scope.category || item.entry.category === scope.category) &&
|
|
247
|
+
(!query || (0, grouping_1.matchesNotificationQuery)(item.entry, query)))
|
|
248
|
+
.map((item) => item.entry.id);
|
|
249
|
+
const wholeActivity = scope.zone === "activity" && !scope.category && !query;
|
|
250
|
+
const count = wholeActivity ? Math.max(ids.length, counts.unread) : ids.length;
|
|
251
|
+
if (!count)
|
|
252
|
+
return;
|
|
253
|
+
const batch = nextBatch();
|
|
254
|
+
dispatch({ type: "markAll", batch, scope, ids });
|
|
255
|
+
const title = labels.markedRead(count);
|
|
256
|
+
announce(title);
|
|
257
|
+
openWindow({ batch, kind: "markAll", ids, send: () => sendThen(batch, () => onMarkAllRead(scope), labels.markAllFailed) }, null, { status: "success", title });
|
|
258
|
+
},
|
|
259
|
+
archive: (ids) => {
|
|
260
|
+
const { source, live, labels } = latest.current;
|
|
261
|
+
const { onArchive } = source;
|
|
262
|
+
if (!onArchive || source.isOffline)
|
|
263
|
+
return;
|
|
264
|
+
const items = unique(ids)
|
|
265
|
+
.map((id) => live.byId.get(id))
|
|
266
|
+
.filter(isLive)
|
|
267
|
+
.filter((item) => item.state.zone === "activity" && !item.state.isHidden);
|
|
268
|
+
if (!items.length)
|
|
269
|
+
return;
|
|
270
|
+
const targetIds = items.map((item) => item.entry.id);
|
|
271
|
+
const batch = nextBatch();
|
|
272
|
+
dispatch({ type: "flag", key: "archived", batch, ids: targetIds, value: true, phase: "undo" });
|
|
273
|
+
const title = labels.archived(targetIds.length);
|
|
274
|
+
announce(title);
|
|
275
|
+
openWindow({ batch, kind: "archive", ids: targetIds, send: () => sendThen(batch, () => onArchive(targetIds), labels.archiveFailed) }, exports.ARCHIVE_FOLD_MS, { status: "success", title, description: targetIds.length === 1 ? (0, grouping_1.plainTitle)(items[0].entry.title) : undefined });
|
|
276
|
+
},
|
|
277
|
+
restore: (ids) => {
|
|
278
|
+
const { source, live, labels } = latest.current;
|
|
279
|
+
const { onRestore } = source;
|
|
280
|
+
if (!onRestore || source.isOffline)
|
|
281
|
+
return;
|
|
282
|
+
const targets = unique(ids).filter((id) => {
|
|
283
|
+
const item = live.byId.get(id);
|
|
284
|
+
return item !== undefined && item.state.zone === "archived";
|
|
285
|
+
});
|
|
286
|
+
if (!targets.length)
|
|
287
|
+
return;
|
|
288
|
+
const batch = nextBatch();
|
|
289
|
+
dispatch({ type: "flag", key: "archived", batch, ids: targets, value: false, phase: "sending" });
|
|
290
|
+
toast({ status: "success", title: labels.restored });
|
|
291
|
+
announce(labels.restored);
|
|
292
|
+
sendThen(batch, () => onRestore(targets), labels.restoreFailed);
|
|
293
|
+
},
|
|
294
|
+
extraActionsFor: (entry) => {
|
|
295
|
+
const { extraActions } = latest.current.source;
|
|
296
|
+
return extraActions ? extraActions(entry) : [];
|
|
297
|
+
},
|
|
298
|
+
runExtraAction: (entry, extra) => {
|
|
299
|
+
const { labels } = latest.current;
|
|
300
|
+
Promise.resolve()
|
|
301
|
+
.then(() => extra.onSelect(entry))
|
|
302
|
+
.then(() => {
|
|
303
|
+
if (mounted.current && extra.doneLabel)
|
|
304
|
+
toast({ status: "success", title: extra.doneLabel });
|
|
305
|
+
}, () => {
|
|
306
|
+
if (mounted.current)
|
|
307
|
+
toast({ status: "error", title: labels.extraFailed(extra.label) });
|
|
308
|
+
});
|
|
309
|
+
},
|
|
310
|
+
loadMore: () => {
|
|
311
|
+
const { onLoadMore } = latest.current.source;
|
|
312
|
+
if (onLoadMore)
|
|
313
|
+
onLoadMore();
|
|
314
|
+
},
|
|
315
|
+
retryLoad: () => {
|
|
316
|
+
const { onRetry } = latest.current.source;
|
|
317
|
+
if (onRetry)
|
|
318
|
+
onRetry();
|
|
319
|
+
},
|
|
320
|
+
announce,
|
|
321
|
+
flush: () => {
|
|
322
|
+
[...windows.current.keys()].forEach(sendWindow);
|
|
323
|
+
},
|
|
324
|
+
};
|
|
325
|
+
return actions;
|
|
326
|
+
};
|
|
327
|
+
const useNotificationEngine = (source) => {
|
|
328
|
+
const { entries, counts, categories, locale = labels_1.DEFAULT_NOTIFICATION_LOCALE, labels: labelOverrides, status = "ready", isOffline = false, hasMore = false, isLoadingMore = false, loadedAt, appName, } = source;
|
|
329
|
+
const toaster = (0, Toaster_1.useToaster)();
|
|
330
|
+
const [overlay, dispatch] = (0, react_1.useReducer)(overlay_1.overlayReducer, overlay_1.EMPTY_OVERLAY);
|
|
331
|
+
const [announcement, setAnnouncement] = (0, react_1.useState)("");
|
|
332
|
+
const [now, setNow] = (0, react_1.useState)(() => Date.now());
|
|
333
|
+
const cache = (0, react_1.useRef)(new WeakMap());
|
|
334
|
+
const labels = (0, react_1.useMemo)(() => (0, labels_1.resolveNotificationLabels)(locale, labelOverrides), [locale, labelOverrides]);
|
|
335
|
+
const format = (0, react_1.useMemo)(() => (0, format_1.createNotificationFormatter)(locale, labels), [locale, labels]);
|
|
336
|
+
const live = (0, react_1.useMemo)(() => (0, overlay_1.buildLiveLists)(entries, overlay, categories, cache.current), [entries, overlay, categories]);
|
|
337
|
+
const { needsYou: serverNeedsYou, unread: serverUnread } = counts;
|
|
338
|
+
const liveCounts = (0, react_1.useMemo)(() => (0, overlay_1.optimisticCounts)(live, overlay, categories, { needsYou: serverNeedsYou, unread: serverUnread }), [live, overlay, categories, serverNeedsYou, serverUnread]);
|
|
339
|
+
const latest = (0, react_1.useRef)({ source, labels, live, counts: liveCounts, toaster });
|
|
340
|
+
(0, react_1.useLayoutEffect)(() => {
|
|
341
|
+
latest.current = { source, labels, live, counts: liveCounts, toaster };
|
|
342
|
+
});
|
|
343
|
+
const windows = (0, react_1.useRef)(new Map());
|
|
344
|
+
const undoOrder = (0, react_1.useRef)([]);
|
|
345
|
+
const mounted = (0, react_1.useRef)(true);
|
|
346
|
+
const batches = (0, react_1.useRef)(0);
|
|
347
|
+
const flip = (0, react_1.useRef)(false);
|
|
348
|
+
const announce = (0, react_1.useCallback)((message) => {
|
|
349
|
+
flip.current = !flip.current;
|
|
350
|
+
setAnnouncement(flip.current ? `${message}${ZERO_WIDTH_SPACE}` : message);
|
|
351
|
+
}, []);
|
|
352
|
+
const actions = (0, react_1.useMemo)(() => createEngineActions({ latest, windows, undoOrder, mounted, batches, dispatch, announce }), [announce]);
|
|
353
|
+
const find = (0, react_1.useCallback)((id) => live.byId.get(id), [live]);
|
|
354
|
+
(0, react_1.useEffect)(() => {
|
|
355
|
+
mounted.current = true;
|
|
356
|
+
return () => {
|
|
357
|
+
mounted.current = false;
|
|
358
|
+
actions.flush();
|
|
359
|
+
};
|
|
360
|
+
}, [actions]);
|
|
361
|
+
(0, react_1.useEffect)(() => {
|
|
362
|
+
const onPageHide = () => actions.flush();
|
|
363
|
+
const onVisibility = () => {
|
|
364
|
+
if (document.visibilityState === "hidden")
|
|
365
|
+
actions.flush();
|
|
366
|
+
};
|
|
367
|
+
window.addEventListener("pagehide", onPageHide);
|
|
368
|
+
document.addEventListener("visibilitychange", onVisibility);
|
|
369
|
+
return () => {
|
|
370
|
+
window.removeEventListener("pagehide", onPageHide);
|
|
371
|
+
document.removeEventListener("visibilitychange", onVisibility);
|
|
372
|
+
};
|
|
373
|
+
}, [actions]);
|
|
374
|
+
(0, react_1.useEffect)(() => {
|
|
375
|
+
const id = setInterval(() => setNow(Date.now()), exports.CLOCK_TICK_MS);
|
|
376
|
+
return () => clearInterval(id);
|
|
377
|
+
}, []);
|
|
378
|
+
const countsKey = `${serverNeedsYou}|${serverUnread}`;
|
|
379
|
+
const lastCounts = (0, react_1.useRef)(countsKey);
|
|
380
|
+
(0, react_1.useEffect)(() => {
|
|
381
|
+
if (lastCounts.current === countsKey)
|
|
382
|
+
return;
|
|
383
|
+
lastCounts.current = countsKey;
|
|
384
|
+
dispatch({ type: "countsChanged" });
|
|
385
|
+
}, [countsKey]);
|
|
386
|
+
(0, react_1.useEffect)(() => {
|
|
387
|
+
dispatch({ type: "reconcile", entries });
|
|
388
|
+
}, [entries]);
|
|
389
|
+
const seen = (0, react_1.useRef)(null);
|
|
390
|
+
(0, react_1.useEffect)(() => {
|
|
391
|
+
if (status !== "ready")
|
|
392
|
+
return;
|
|
393
|
+
const newest = entries.reduce((max, entry) => Math.max(max, entry.createdAt), 0);
|
|
394
|
+
const known = seen.current;
|
|
395
|
+
seen.current = { ids: new Set(entries.map((entry) => entry.id)), newest: Math.max(newest, known ? known.newest : 0) };
|
|
396
|
+
if (!known)
|
|
397
|
+
return;
|
|
398
|
+
const fresh = entries.filter((entry) => !known.ids.has(entry.id) && entry.createdAt > known.newest && !entry.archived);
|
|
399
|
+
if (fresh.length === 1)
|
|
400
|
+
announce(labels.arrivedOne((0, grouping_1.plainTitle)(fresh[0].title)));
|
|
401
|
+
else if (fresh.length > 1)
|
|
402
|
+
announce(labels.arrivedMany(fresh.length));
|
|
403
|
+
}, [entries, status, labels, announce]);
|
|
404
|
+
const decide = Boolean(source.onAction);
|
|
405
|
+
const markRead = Boolean(source.onMarkRead);
|
|
406
|
+
const markAllRead = Boolean(source.onMarkAllRead);
|
|
407
|
+
const archive = Boolean(source.onArchive);
|
|
408
|
+
const restore = Boolean(source.onRestore);
|
|
409
|
+
const loadMore = Boolean(source.onLoadMore);
|
|
410
|
+
const features = (0, react_1.useMemo)(() => ({ decide, markRead, markAllRead, archive, restore, loadMore }), [decide, markRead, markAllRead, archive, restore, loadMore]);
|
|
411
|
+
const shared = (0, react_1.useMemo)(() => ({ labels, format, now, categories, features, isOffline, appName, actions }), [labels, format, now, categories, features, isOffline, appName, actions]);
|
|
412
|
+
const value = (0, react_1.useMemo)(() => ({ ...shared, lists: live.lists, counts: liveCounts, status, loadedAt, hasMore, isLoadingMore, find }), [shared, live, liveCounts, status, loadedAt, hasMore, isLoadingMore, find]);
|
|
413
|
+
return { value, shared, announcement };
|
|
414
|
+
};
|
|
415
|
+
exports.useNotificationEngine = useNotificationEngine;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { RefCallback } from "react";
|
|
2
|
+
import type { LiveNotificationEntry, NotificationGroup, NotificationThread } from "../core/NotificationEngineProps";
|
|
3
|
+
import type { NotificationRowOpenEvent } from "../row/NotificationRowProps";
|
|
4
|
+
interface InboxListProps {
|
|
5
|
+
groups: NotificationGroup[];
|
|
6
|
+
isPhone: boolean;
|
|
7
|
+
selectedId: string | null;
|
|
8
|
+
checked: ReadonlySet<string>;
|
|
9
|
+
openThreads: ReadonlySet<string>;
|
|
10
|
+
idPrefix: string;
|
|
11
|
+
onOpenRow: (item: LiveNotificationEntry, event: NotificationRowOpenEvent) => void;
|
|
12
|
+
onCheckedChange?: (item: LiveNotificationEntry, checked: boolean) => void;
|
|
13
|
+
onThreadToggle: (thread: NotificationThread) => void;
|
|
14
|
+
linkRefFor: (id: string) => RefCallback<HTMLElement>;
|
|
15
|
+
}
|
|
16
|
+
export declare const InboxList: ({ groups, isPhone, selectedId, checked, openThreads, idPrefix, onOpenRow, onCheckedChange, onThreadToggle, linkRefFor, }: InboxListProps) => import("react/jsx-runtime").JSX.Element;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.InboxList = void 0;
|
|
7
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
+
const react_1 = require("@chakra-ui/react");
|
|
9
|
+
const Primitives_1 = require("../../Primitives/Primitives");
|
|
10
|
+
const useCustomTheme_1 = require("../../../Theme/useCustomTheme");
|
|
11
|
+
const NotificationRow_1 = __importDefault(require("../row/NotificationRow"));
|
|
12
|
+
const InboxList = ({ groups, isPhone, selectedId, checked, openThreads, idPrefix, onOpenRow, onCheckedChange, onThreadToggle, linkRefFor, }) => {
|
|
13
|
+
const { colors } = (0, useCustomTheme_1.useCustomTheme)();
|
|
14
|
+
const variant = isPhone ? "phone" : "inbox";
|
|
15
|
+
const rowFor = (item, extra) => ((0, jsx_runtime_1.jsx)(NotificationRow_1.default, { item: item, variant: variant, isSelected: !isPhone && selectedId === item.entry.id, isChecked: checked.has(item.entry.id), onCheckedChange: onCheckedChange, thread: extra.thread, isThreadOpen: extra.isOpen, onThreadToggle: extra.thread ? onThreadToggle : undefined, isThreadChild: extra.isChild, onOpen: onOpenRow, linkRef: linkRefFor(item.entry.id) }, item.entry.id));
|
|
16
|
+
return ((0, jsx_runtime_1.jsx)(Primitives_1.Box, { pb: 2, children: groups.map((group) => {
|
|
17
|
+
const headingId = `${idPrefix}-group-${group.key}`;
|
|
18
|
+
return ((0, jsx_runtime_1.jsxs)(react_1.chakra.section, { "aria-labelledby": group.label === null ? undefined : headingId, children: [group.label !== null && ((0, jsx_runtime_1.jsxs)(react_1.chakra.h2, { id: headingId, position: "sticky", top: 0, zIndex: "docked", display: "flex", alignItems: "center", gap: 1.5, m: 0, px: 4, pt: 3, pb: 1.5, bg: colors.surfaceRaised, color: colors.textMuted, fontSize: "xs-minus", fontWeight: 600, letterSpacing: "0.06em", textTransform: "uppercase", children: [(0, jsx_runtime_1.jsx)("span", { children: group.label }), group.count > 0 && (0, jsx_runtime_1.jsx)(react_1.chakra.span, { sx: { fontVariantNumeric: "tabular-nums" }, children: group.count })] })), (0, jsx_runtime_1.jsx)(react_1.chakra.ul, { listStyleType: "none", display: "grid", gap: "0.125rem", m: 0, px: 1.5, py: 0, children: group.threads.flatMap((thread) => {
|
|
19
|
+
const isOpen = openThreads.has(thread.key);
|
|
20
|
+
const lead = rowFor(thread.lead, { thread: thread.rest.length > 0 ? thread : undefined, isOpen });
|
|
21
|
+
return isOpen ? [lead, ...thread.rest.map((item) => rowFor(item, { isChild: true }))] : [lead];
|
|
22
|
+
}) })] }, group.key));
|
|
23
|
+
}) }));
|
|
24
|
+
};
|
|
25
|
+
exports.InboxList = InboxList;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { NotificationInboxLabels, NotificationInboxTab } from "./NotificationInboxProps";
|
|
2
|
+
export declare const InboxSkeleton: ({ isPhone, label }: {
|
|
3
|
+
isPhone: boolean;
|
|
4
|
+
label: string;
|
|
5
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
interface LoadFailureProps {
|
|
7
|
+
kind: "error" | "noAccess";
|
|
8
|
+
labels: NotificationInboxLabels;
|
|
9
|
+
appName?: string;
|
|
10
|
+
onRetry?: () => void;
|
|
11
|
+
}
|
|
12
|
+
export declare const InboxLoadFailure: ({ kind, labels, appName, onRetry }: LoadFailureProps) => import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
export declare const InboxEmpty: ({ tab, labels }: {
|
|
14
|
+
tab: NotificationInboxTab;
|
|
15
|
+
labels: NotificationInboxLabels;
|
|
16
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.InboxEmpty = exports.InboxLoadFailure = exports.InboxSkeleton = void 0;
|
|
7
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
+
const lucide_react_1 = require("lucide-react");
|
|
9
|
+
const Primitives_1 = require("../../Primitives/Primitives");
|
|
10
|
+
const Button_1 = __importDefault(require("../../Button/Button"));
|
|
11
|
+
const EmptyState_1 = __importDefault(require("../../EmptyState/EmptyState"));
|
|
12
|
+
const Skeletons_1 = __importDefault(require("../../Skeletons/Skeletons"));
|
|
13
|
+
const SKELETON_ROWS = 6;
|
|
14
|
+
const InboxSkeleton = ({ isPhone, label }) => ((0, jsx_runtime_1.jsx)(Primitives_1.Flex, { direction: "column", gap: 1, px: 2, py: 2, role: "status", "aria-busy": "true", "aria-label": label, children: Array.from({ length: SKELETON_ROWS }, (_, index) => ((0, jsx_runtime_1.jsxs)(Primitives_1.Flex, { gap: 3, px: 3, py: 2.5, "aria-hidden": "true", children: [(0, jsx_runtime_1.jsx)(Skeletons_1.default, { type: "circle", size: isPhone ? "10" : "8" }), (0, jsx_runtime_1.jsx)(Primitives_1.Box, { flex: 1, children: (0, jsx_runtime_1.jsx)(Skeletons_1.default, { type: "text", noOfLines: index % 2 === 0 ? 3 : 2, spacing: 2, skeletonHeight: 2 }) })] }, index))) }));
|
|
15
|
+
exports.InboxSkeleton = InboxSkeleton;
|
|
16
|
+
const InboxLoadFailure = ({ kind, labels, appName, onRetry }) => kind === "error" ? ((0, jsx_runtime_1.jsx)(EmptyState_1.default, { icon: lucide_react_1.CircleAlert, colorScheme: "error", title: labels.loadErrorTitle, description: labels.loadErrorBody, action: onRetry && (0, jsx_runtime_1.jsx)(Button_1.default, { size: "sm", variant: "outline", colorScheme: "gray", label: labels.retry, onClick: onRetry }) })) : ((0, jsx_runtime_1.jsx)(EmptyState_1.default, { icon: lucide_react_1.Lock, colorScheme: "gray", title: labels.noAccessTitle, description: labels.noAccessBody(appName) }));
|
|
17
|
+
exports.InboxLoadFailure = InboxLoadFailure;
|
|
18
|
+
const InboxEmpty = ({ tab, labels }) => {
|
|
19
|
+
if (tab === "needsYou") {
|
|
20
|
+
return (0, jsx_runtime_1.jsx)(EmptyState_1.default, { icon: lucide_react_1.CircleCheck, colorScheme: "success", title: labels.caughtUpTitle, description: labels.caughtUpBody });
|
|
21
|
+
}
|
|
22
|
+
if (tab === "archived") {
|
|
23
|
+
return (0, jsx_runtime_1.jsx)(EmptyState_1.default, { icon: lucide_react_1.Archive, colorScheme: "gray", title: labels.archivedEmptyTitle, description: labels.archivedEmptyBody });
|
|
24
|
+
}
|
|
25
|
+
return (0, jsx_runtime_1.jsx)(EmptyState_1.default, { icon: lucide_react_1.Bell, colorScheme: "gray", title: labels.activityEmptyTitle, description: labels.activityEmptyBody });
|
|
26
|
+
};
|
|
27
|
+
exports.InboxEmpty = InboxEmpty;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { NotificationInboxProps } from "./NotificationInboxProps";
|
|
2
|
+
/** Full-page inbox: Needs you, Activity and Archived tabs, search, a type filter, bulk actions and a reading pane. */
|
|
3
|
+
declare const NotificationInbox: (props: NotificationInboxProps) => import("react/jsx-runtime").JSX.Element;
|
|
4
|
+
export default NotificationInbox;
|