@ai-matrx/records-ui 0.85.6 → 0.85.7
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 +32 -3
- package/dist/index.cjs +370 -72
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +38 -3
- package/dist/index.d.ts +38 -3
- package/dist/index.js +324 -26
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3102,6 +3102,7 @@ import {
|
|
|
3102
3102
|
useRecordsClient as useRecordsClient9,
|
|
3103
3103
|
useTable as useTable2
|
|
3104
3104
|
} from "@ai-matrx/records/react";
|
|
3105
|
+
import { asPermissionLevel } from "@ai-matrx/records";
|
|
3105
3106
|
import { MatrxDataTable, tableStyleIsEmpty as tableStyleIsEmpty2 } from "@ai-matrx/design-system/data-table";
|
|
3106
3107
|
|
|
3107
3108
|
// src/presentation.ts
|
|
@@ -5501,7 +5502,12 @@ function Grid({
|
|
|
5501
5502
|
recordId: row.id,
|
|
5502
5503
|
title: recordNameIn(table.data, row.document ?? {}),
|
|
5503
5504
|
action: action.name,
|
|
5504
|
-
prompt: action.prompt ?? action.name
|
|
5505
|
+
prompt: action.prompt ?? action.name,
|
|
5506
|
+
// No second read: what the grid holds travels with the press.
|
|
5507
|
+
tableName: table.data ? tableName(table.data) : "",
|
|
5508
|
+
fields: fields.data ?? [],
|
|
5509
|
+
document: row.document ?? {},
|
|
5510
|
+
level: asPermissionLevel(row.level)
|
|
5505
5511
|
})
|
|
5506
5512
|
},
|
|
5507
5513
|
action.id
|
|
@@ -12423,9 +12429,18 @@ function useMyChecklistSteps(limit = 25) {
|
|
|
12423
12429
|
}, [refresh]);
|
|
12424
12430
|
return { steps, loading, error, refresh };
|
|
12425
12431
|
}
|
|
12426
|
-
function MyChecklistSteps({
|
|
12432
|
+
function MyChecklistSteps({
|
|
12433
|
+
className,
|
|
12434
|
+
onlyIds,
|
|
12435
|
+
onSteps,
|
|
12436
|
+
actions
|
|
12437
|
+
}) {
|
|
12427
12438
|
const client = useRecordsClient26();
|
|
12428
|
-
const { steps, loading, error, refresh } = useMyChecklistSteps();
|
|
12439
|
+
const { steps: held, loading, error, refresh } = useMyChecklistSteps();
|
|
12440
|
+
useEffect25(() => {
|
|
12441
|
+
onSteps?.(held.map((s) => s.step_id));
|
|
12442
|
+
}, [held, onSteps]);
|
|
12443
|
+
const steps = onlyIds ? held.filter((s) => onlyIds.has(s.step_id)) : held;
|
|
12429
12444
|
const [busy, setBusy] = useState37(null);
|
|
12430
12445
|
const [refusal2, setRefusal] = useState37(null);
|
|
12431
12446
|
const complete = useCallback18(
|
|
@@ -12451,15 +12466,20 @@ function MyChecklistSteps({ className }) {
|
|
|
12451
12466
|
] }),
|
|
12452
12467
|
error ? /* @__PURE__ */ jsx42(RefusalNotice, { error }) : null,
|
|
12453
12468
|
refusal2 ? /* @__PURE__ */ jsx42(RefusalNotice, { error: refusal2 }) : null,
|
|
12454
|
-
/* @__PURE__ */ jsx42("ol", { className: "flex flex-col gap-1.5", children: steps.map(
|
|
12455
|
-
|
|
12456
|
-
|
|
12457
|
-
|
|
12458
|
-
|
|
12459
|
-
|
|
12460
|
-
|
|
12461
|
-
|
|
12462
|
-
|
|
12469
|
+
/* @__PURE__ */ jsx42("ol", { className: "flex flex-col gap-1.5", children: steps.map(
|
|
12470
|
+
(step2) => actions ? /* @__PURE__ */ jsxs37("div", { className: "flex flex-col gap-0.5", "data-step-row": step2.step_id, children: [
|
|
12471
|
+
/* @__PURE__ */ jsx42(StepRow, { step: step2, busy: busy === step2.step_id, onComplete: (evidence) => void complete(step2, evidence) }),
|
|
12472
|
+
/* @__PURE__ */ jsx42("div", { className: "flex items-center justify-end gap-1", children: actions(step2.step_id) })
|
|
12473
|
+
] }, step2.step_id) : /* @__PURE__ */ jsx42(
|
|
12474
|
+
StepRow,
|
|
12475
|
+
{
|
|
12476
|
+
step: step2,
|
|
12477
|
+
busy: busy === step2.step_id,
|
|
12478
|
+
onComplete: (evidence) => void complete(step2, evidence)
|
|
12479
|
+
},
|
|
12480
|
+
step2.step_id
|
|
12481
|
+
)
|
|
12482
|
+
) })
|
|
12463
12483
|
] });
|
|
12464
12484
|
}
|
|
12465
12485
|
function ChecklistsPanel({ tableId, onOpenRecord, className }) {
|
|
@@ -12839,6 +12859,24 @@ var DUE_WORD2 = DUE_STATE_LABEL;
|
|
|
12839
12859
|
var INBOX_GROUPINGS = ["kind", "table", "none"];
|
|
12840
12860
|
var GROUPING_WORD = { kind: "Kind", table: "Table", none: "None" };
|
|
12841
12861
|
var KIND_ORDER = { approval: 0, proposal: 1, assignment: 2 };
|
|
12862
|
+
var INBOX_VIEWS = ["inbox", "snoozed", "done"];
|
|
12863
|
+
var VIEW_WORD = { inbox: "Inbox", snoozed: "Snoozed", done: "Done" };
|
|
12864
|
+
function snoozeChoices(now = /* @__PURE__ */ new Date()) {
|
|
12865
|
+
const at8 = (d) => {
|
|
12866
|
+
const x = new Date(d);
|
|
12867
|
+
x.setHours(8, 0, 0, 0);
|
|
12868
|
+
return x;
|
|
12869
|
+
};
|
|
12870
|
+
const later = new Date(now.getTime() + 3 * 36e5);
|
|
12871
|
+
const tomorrow = at8(new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1));
|
|
12872
|
+
const daysToMonday = (8 - now.getDay()) % 7 || 7;
|
|
12873
|
+
const monday = at8(new Date(now.getFullYear(), now.getMonth(), now.getDate() + daysToMonday));
|
|
12874
|
+
return [
|
|
12875
|
+
{ key: "1", label: "Later today", until: later },
|
|
12876
|
+
{ key: "2", label: "Tomorrow, 8 AM", until: tomorrow },
|
|
12877
|
+
{ key: "3", label: "Next Monday, 8 AM", until: monday }
|
|
12878
|
+
];
|
|
12879
|
+
}
|
|
12842
12880
|
function groupInbox(items, by) {
|
|
12843
12881
|
if (by === "none") return [{ key: "all", label: null, items: [...items] }];
|
|
12844
12882
|
const groups = /* @__PURE__ */ new Map();
|
|
@@ -12880,8 +12918,19 @@ function ActionInbox({
|
|
|
12880
12918
|
const anchor = useRef10(null);
|
|
12881
12919
|
const [deciding, setDeciding] = useState38(false);
|
|
12882
12920
|
const [batchSaid, setBatchSaid] = useState38(null);
|
|
12921
|
+
const [view, setView] = useState38("inbox");
|
|
12922
|
+
const [counts, setCounts] = useState38(null);
|
|
12923
|
+
const [snoozing, setSnoozing] = useState38(null);
|
|
12924
|
+
const [pickAt, setPickAt] = useState38("");
|
|
12925
|
+
const [said, setSaid] = useState38(null);
|
|
12926
|
+
const [stepIds, setStepIds] = useState38(/* @__PURE__ */ new Set());
|
|
12927
|
+
const onSteps = useCallback19((ids) => setStepIds(new Set(ids)), []);
|
|
12883
12928
|
const load = useCallback19(async () => {
|
|
12884
|
-
const result = await
|
|
12929
|
+
const [result, counted] = await Promise.all([
|
|
12930
|
+
client.workInbox({ limit: 200, includeDecided: view === "inbox" && showDecided, view }),
|
|
12931
|
+
client.inboxCounts()
|
|
12932
|
+
]);
|
|
12933
|
+
setCounts(counted.ok ? counted.data[0] ?? null : null);
|
|
12885
12934
|
if (!result.ok) {
|
|
12886
12935
|
setError(result.error);
|
|
12887
12936
|
setItems([]);
|
|
@@ -12889,15 +12938,19 @@ function ActionInbox({
|
|
|
12889
12938
|
}
|
|
12890
12939
|
setError(null);
|
|
12891
12940
|
setItems(result.data);
|
|
12892
|
-
}, [client, showDecided]);
|
|
12941
|
+
}, [client, showDecided, view]);
|
|
12893
12942
|
useEffect26(() => {
|
|
12894
12943
|
void load();
|
|
12895
12944
|
}, [load]);
|
|
12896
12945
|
const narrowed = useMemo26(() => {
|
|
12897
|
-
const all = items ?? [];
|
|
12946
|
+
const all = (items ?? []).filter((i) => !(view === "inbox" && i.kind === "assignment" && stepIds.has(i.item_id)));
|
|
12898
12947
|
if (!tableId || everyTable) return all;
|
|
12899
12948
|
return all.filter((i) => i.table_id === tableId);
|
|
12900
|
-
}, [items, tableId, everyTable]);
|
|
12949
|
+
}, [items, tableId, everyTable, view, stepIds]);
|
|
12950
|
+
const waitingIds = useMemo26(
|
|
12951
|
+
() => new Set((items ?? []).filter((i) => i.kind === "assignment").map((i) => i.item_id)),
|
|
12952
|
+
[items]
|
|
12953
|
+
);
|
|
12901
12954
|
const groups = useMemo26(() => groupInbox(narrowed, groupBy), [narrowed, groupBy]);
|
|
12902
12955
|
const shown3 = useMemo26(() => groups.flatMap((g) => g.items), [groups]);
|
|
12903
12956
|
const elsewhere = (items?.length ?? 0) - narrowed.length;
|
|
@@ -12956,9 +13009,9 @@ function ActionInbox({
|
|
|
12956
13009
|
setError(result.error);
|
|
12957
13010
|
return;
|
|
12958
13011
|
}
|
|
12959
|
-
const
|
|
12960
|
-
for (const r of result.data.results)
|
|
12961
|
-
setOutcome((o) => ({ ...o, ...
|
|
13012
|
+
const said2 = {};
|
|
13013
|
+
for (const r of result.data.results) said2[r.item] = r.sentence;
|
|
13014
|
+
setOutcome((o) => ({ ...o, ...said2 }));
|
|
12962
13015
|
const { approved, declined, not_decided } = result.data;
|
|
12963
13016
|
setBatchSaid(
|
|
12964
13017
|
[
|
|
@@ -12972,6 +13025,79 @@ function ActionInbox({
|
|
|
12972
13025
|
},
|
|
12973
13026
|
[client, shown3, selected, decidable, load]
|
|
12974
13027
|
);
|
|
13028
|
+
const snooze = useCallback19(
|
|
13029
|
+
async (itemId, title, until) => {
|
|
13030
|
+
setSnoozing(null);
|
|
13031
|
+
const result = await client.inboxSnooze({ item_id: itemId, until: until.toISOString() });
|
|
13032
|
+
if (!result.ok) {
|
|
13033
|
+
setError(result.error);
|
|
13034
|
+
return;
|
|
13035
|
+
}
|
|
13036
|
+
setSaid({
|
|
13037
|
+
text: `Snoozed until ${whenWords2(until.toISOString())}: ${title}`,
|
|
13038
|
+
undo: async () => {
|
|
13039
|
+
const back = await client.inboxUnsnooze({ item_id: itemId });
|
|
13040
|
+
if (!back.ok) setError(back.error);
|
|
13041
|
+
else setSaid({ text: back.data.sentence, undo: null });
|
|
13042
|
+
await load();
|
|
13043
|
+
}
|
|
13044
|
+
});
|
|
13045
|
+
await load();
|
|
13046
|
+
},
|
|
13047
|
+
[client, load]
|
|
13048
|
+
);
|
|
13049
|
+
const unsnooze = useCallback19(
|
|
13050
|
+
async (itemId) => {
|
|
13051
|
+
const result = await client.inboxUnsnooze({ item_id: itemId });
|
|
13052
|
+
if (!result.ok) {
|
|
13053
|
+
setError(result.error);
|
|
13054
|
+
return;
|
|
13055
|
+
}
|
|
13056
|
+
setSaid({ text: result.data.sentence, undo: null });
|
|
13057
|
+
await load();
|
|
13058
|
+
},
|
|
13059
|
+
[client, load]
|
|
13060
|
+
);
|
|
13061
|
+
const clearItem = useCallback19(
|
|
13062
|
+
async (itemId) => {
|
|
13063
|
+
const result = await client.inboxClear({ item_id: itemId });
|
|
13064
|
+
if (!result.ok) {
|
|
13065
|
+
setError(result.error);
|
|
13066
|
+
return;
|
|
13067
|
+
}
|
|
13068
|
+
setSaid({
|
|
13069
|
+
text: result.data.sentence,
|
|
13070
|
+
undo: async () => {
|
|
13071
|
+
const back = await client.inboxUnclear({ item_id: itemId });
|
|
13072
|
+
if (!back.ok) setError(back.error);
|
|
13073
|
+
else setSaid({ text: back.data.sentence, undo: null });
|
|
13074
|
+
await load();
|
|
13075
|
+
}
|
|
13076
|
+
});
|
|
13077
|
+
await load();
|
|
13078
|
+
},
|
|
13079
|
+
[client, load]
|
|
13080
|
+
);
|
|
13081
|
+
const unclear = useCallback19(
|
|
13082
|
+
async (itemId) => {
|
|
13083
|
+
const result = await client.inboxUnclear({ item_id: itemId });
|
|
13084
|
+
if (!result.ok) {
|
|
13085
|
+
setError(result.error);
|
|
13086
|
+
return;
|
|
13087
|
+
}
|
|
13088
|
+
setSaid({ text: result.data.sentence, undo: null });
|
|
13089
|
+
await load();
|
|
13090
|
+
},
|
|
13091
|
+
[client, load]
|
|
13092
|
+
);
|
|
13093
|
+
const clearable = useCallback19(
|
|
13094
|
+
(item) => item.kind === "assignment" && view === "inbox",
|
|
13095
|
+
[view]
|
|
13096
|
+
);
|
|
13097
|
+
const snoozable = useCallback19(
|
|
13098
|
+
(item) => view === "inbox" && (item.kind === "assignment" || item.state === "pending") && !outcome[item.item_id],
|
|
13099
|
+
[view, outcome]
|
|
13100
|
+
);
|
|
12975
13101
|
const open = useCallback19(
|
|
12976
13102
|
(item) => {
|
|
12977
13103
|
if (!onOpenRecord || !item.subject_id) return;
|
|
@@ -12983,6 +13109,47 @@ function ActionInbox({
|
|
|
12983
13109
|
(event) => {
|
|
12984
13110
|
const item = shown3[cursor];
|
|
12985
13111
|
const key = event.key;
|
|
13112
|
+
if (event.target?.tagName === "INPUT") return;
|
|
13113
|
+
if (snoozing) {
|
|
13114
|
+
const choice = snoozeChoices().find((c) => c.key === key);
|
|
13115
|
+
const row = shown3.find((i) => i.item_id === snoozing);
|
|
13116
|
+
if (choice && row) {
|
|
13117
|
+
event.preventDefault();
|
|
13118
|
+
void snooze(row.item_id, row.title, choice.until);
|
|
13119
|
+
return;
|
|
13120
|
+
}
|
|
13121
|
+
if (key === "Escape") {
|
|
13122
|
+
event.preventDefault();
|
|
13123
|
+
setSnoozing(null);
|
|
13124
|
+
return;
|
|
13125
|
+
}
|
|
13126
|
+
}
|
|
13127
|
+
if (key === "s" && item && snoozable(item)) {
|
|
13128
|
+
event.preventDefault();
|
|
13129
|
+
setSnoozing((open2) => open2 === item.item_id ? null : item.item_id);
|
|
13130
|
+
return;
|
|
13131
|
+
}
|
|
13132
|
+
if (key === "e" && item && clearable(item)) {
|
|
13133
|
+
event.preventDefault();
|
|
13134
|
+
void clearItem(item.item_id);
|
|
13135
|
+
return;
|
|
13136
|
+
}
|
|
13137
|
+
if (key === "u" && item && view !== "inbox") {
|
|
13138
|
+
event.preventDefault();
|
|
13139
|
+
void (view === "snoozed" ? unsnooze(item.item_id) : unclear(item.item_id));
|
|
13140
|
+
return;
|
|
13141
|
+
}
|
|
13142
|
+
if (key === "z" && said?.undo) {
|
|
13143
|
+
event.preventDefault();
|
|
13144
|
+
void said.undo();
|
|
13145
|
+
return;
|
|
13146
|
+
}
|
|
13147
|
+
if (key === "v") {
|
|
13148
|
+
event.preventDefault();
|
|
13149
|
+
setView((v) => INBOX_VIEWS[(INBOX_VIEWS.indexOf(v) + 1) % INBOX_VIEWS.length]);
|
|
13150
|
+
setSelected(/* @__PURE__ */ new Set());
|
|
13151
|
+
return;
|
|
13152
|
+
}
|
|
12986
13153
|
if (key === "j" || key === "ArrowDown") {
|
|
12987
13154
|
event.preventDefault();
|
|
12988
13155
|
setCursor((c) => Math.min(shown3.length - 1, c + 1));
|
|
@@ -13016,7 +13183,7 @@ function ActionInbox({
|
|
|
13016
13183
|
void decide(item, key === "a");
|
|
13017
13184
|
}
|
|
13018
13185
|
},
|
|
13019
|
-
[shown3, cursor, decide, open, load, decidable, select, selected, decideSelected]
|
|
13186
|
+
[shown3, cursor, decide, open, load, decidable, select, selected, decideSelected, snoozing, snooze, clearItem, unsnooze, unclear, said, view, snoozable, clearable]
|
|
13020
13187
|
);
|
|
13021
13188
|
const renderRow = (item, index) => {
|
|
13022
13189
|
const settled = outcome[item.item_id];
|
|
@@ -13068,9 +13235,84 @@ function ActionInbox({
|
|
|
13068
13235
|
children: DUE_WORD2[item.due_state] ?? item.due_state
|
|
13069
13236
|
}
|
|
13070
13237
|
) : null,
|
|
13238
|
+
view === "snoozed" && item.snoozed_until ? /* @__PURE__ */ jsxs38("span", { className: "shrink-0 text-[11px] text-muted-foreground", "data-testid": "inbox-back-at", children: [
|
|
13239
|
+
"Back ",
|
|
13240
|
+
/* @__PURE__ */ jsx43("time", { dateTime: item.snoozed_until, children: whenWords2(item.snoozed_until) })
|
|
13241
|
+
] }) : null,
|
|
13242
|
+
view === "done" && item.cleared_at ? /* @__PURE__ */ jsxs38("span", { className: "shrink-0 text-[11px] text-muted-foreground", children: [
|
|
13243
|
+
"Cleared ",
|
|
13244
|
+
/* @__PURE__ */ jsx43("time", { dateTime: item.cleared_at, children: whenWords2(item.cleared_at) })
|
|
13245
|
+
] }) : null,
|
|
13246
|
+
snoozable(item) ? /* @__PURE__ */ jsx43(
|
|
13247
|
+
Button34,
|
|
13248
|
+
{
|
|
13249
|
+
size: "sm",
|
|
13250
|
+
variant: "ghost",
|
|
13251
|
+
className: "h-5 px-1 text-[11px]",
|
|
13252
|
+
"aria-expanded": snoozing === item.item_id,
|
|
13253
|
+
onClick: () => setSnoozing((o) => o === item.item_id ? null : item.item_id),
|
|
13254
|
+
children: "Snooze"
|
|
13255
|
+
}
|
|
13256
|
+
) : null,
|
|
13257
|
+
clearable(item) ? /* @__PURE__ */ jsx43(Button34, { size: "sm", variant: "ghost", className: "h-5 px-1 text-[11px]", onClick: () => void clearItem(item.item_id), children: "Done" }) : null,
|
|
13258
|
+
view === "snoozed" ? /* @__PURE__ */ jsx43(Button34, { size: "sm", variant: "ghost", className: "h-5 px-1 text-[11px]", onClick: () => void unsnooze(item.item_id), children: "Unsnooze" }) : null,
|
|
13259
|
+
view === "done" ? /* @__PURE__ */ jsx43(Button34, { size: "sm", variant: "ghost", className: "h-5 px-1 text-[11px]", onClick: () => void unclear(item.item_id), children: "Put back" }) : null,
|
|
13071
13260
|
item.subject_id && onOpenRecord ? /* @__PURE__ */ jsx43(Button34, { size: "sm", variant: "ghost", className: "h-5 px-1 text-[11px]", onClick: () => open(item), children: "Open" }) : null
|
|
13072
13261
|
] }),
|
|
13073
13262
|
item.summary ? /* @__PURE__ */ jsx43("p", { className: "text-xs text-muted-foreground", children: item.summary }) : null,
|
|
13263
|
+
snoozing === item.item_id ? (
|
|
13264
|
+
// SUPERHUMAN'S CHOICES, then any moment the person names. The picked time's own Snooze is
|
|
13265
|
+
// absent until a time is picked — never a greyed button that does nothing.
|
|
13266
|
+
/* @__PURE__ */ jsxs38(
|
|
13267
|
+
"div",
|
|
13268
|
+
{
|
|
13269
|
+
role: "group",
|
|
13270
|
+
"aria-label": `Snooze ${item.title} until`,
|
|
13271
|
+
"data-testid": "inbox-snooze-choices",
|
|
13272
|
+
className: "flex flex-wrap items-center gap-1 rounded border border-border bg-muted/40 p-1.5",
|
|
13273
|
+
children: [
|
|
13274
|
+
snoozeChoices().map((c) => /* @__PURE__ */ jsxs38(
|
|
13275
|
+
Button34,
|
|
13276
|
+
{
|
|
13277
|
+
size: "sm",
|
|
13278
|
+
variant: "ghost",
|
|
13279
|
+
className: "h-6 px-2 text-[11px]",
|
|
13280
|
+
title: c.until.toLocaleString(),
|
|
13281
|
+
onClick: () => void snooze(item.item_id, item.title, c.until),
|
|
13282
|
+
children: [
|
|
13283
|
+
c.label,
|
|
13284
|
+
/* @__PURE__ */ jsx43("span", { className: "ml-1 text-muted-foreground", children: c.key })
|
|
13285
|
+
]
|
|
13286
|
+
},
|
|
13287
|
+
c.key
|
|
13288
|
+
)),
|
|
13289
|
+
/* @__PURE__ */ jsx43(
|
|
13290
|
+
"input",
|
|
13291
|
+
{
|
|
13292
|
+
type: "datetime-local",
|
|
13293
|
+
"aria-label": "Pick a time",
|
|
13294
|
+
value: pickAt,
|
|
13295
|
+
onChange: (e) => setPickAt(e.target.value),
|
|
13296
|
+
className: "h-6 rounded border border-border bg-background px-1 text-[11px]"
|
|
13297
|
+
}
|
|
13298
|
+
),
|
|
13299
|
+
pickAt ? /* @__PURE__ */ jsx43(
|
|
13300
|
+
Button34,
|
|
13301
|
+
{
|
|
13302
|
+
size: "sm",
|
|
13303
|
+
className: "h-6 px-2 text-[11px]",
|
|
13304
|
+
onClick: () => {
|
|
13305
|
+
const until = new Date(pickAt);
|
|
13306
|
+
setPickAt("");
|
|
13307
|
+
void snooze(item.item_id, item.title, until);
|
|
13308
|
+
},
|
|
13309
|
+
children: "Snooze until then"
|
|
13310
|
+
}
|
|
13311
|
+
) : null
|
|
13312
|
+
]
|
|
13313
|
+
}
|
|
13314
|
+
)
|
|
13315
|
+
) : null,
|
|
13074
13316
|
settled ? /* @__PURE__ */ jsx43("p", { className: "text-xs", children: settled }) : item.kind === "assignment" ? /* @__PURE__ */ jsx43("p", { className: "text-[11px] text-muted-foreground", children: item.state === "open" ? "Waiting on you." : `${item.state}.` }) : closed ? (
|
|
13075
13317
|
// A CLOSED ITEM SAYS WHO AND WHEN, and then what happened, in the store's own sentence.
|
|
13076
13318
|
/* @__PURE__ */ jsxs38("div", { className: "flex flex-col gap-0.5", "data-testid": "inbox-closed", children: [
|
|
@@ -13110,9 +13352,34 @@ function ActionInbox({
|
|
|
13110
13352
|
"aria-label": "Inbox",
|
|
13111
13353
|
children: [
|
|
13112
13354
|
/* @__PURE__ */ jsxs38("div", { className: "flex items-center gap-2", children: [
|
|
13113
|
-
/* @__PURE__ */ jsx43("h3", { className: "
|
|
13114
|
-
/* @__PURE__ */ jsx43("
|
|
13115
|
-
|
|
13355
|
+
/* @__PURE__ */ jsx43("h3", { className: "sr-only", children: "Inbox" }),
|
|
13356
|
+
/* @__PURE__ */ jsx43("div", { role: "tablist", "aria-label": "Inbox views", className: "flex items-center gap-0.5", children: INBOX_VIEWS.map((v) => {
|
|
13357
|
+
const n = counts === null ? v === view ? shown3.length : null : v === "inbox" ? counts.waiting : v === "snoozed" ? counts.snoozed : counts.cleared;
|
|
13358
|
+
return /* @__PURE__ */ jsxs38(
|
|
13359
|
+
"button",
|
|
13360
|
+
{
|
|
13361
|
+
type: "button",
|
|
13362
|
+
role: "tab",
|
|
13363
|
+
"aria-selected": view === v,
|
|
13364
|
+
"data-inbox-view": v,
|
|
13365
|
+
onClick: () => {
|
|
13366
|
+
setView(v);
|
|
13367
|
+
setSelected(/* @__PURE__ */ new Set());
|
|
13368
|
+
setSnoozing(null);
|
|
13369
|
+
},
|
|
13370
|
+
className: cn34(
|
|
13371
|
+
"flex items-baseline gap-1 rounded px-1.5 py-0.5 text-xs",
|
|
13372
|
+
view === v ? "bg-accent font-medium text-foreground" : "text-muted-foreground"
|
|
13373
|
+
),
|
|
13374
|
+
children: [
|
|
13375
|
+
/* @__PURE__ */ jsx43("span", { children: VIEW_WORD[v] }),
|
|
13376
|
+
n !== null ? /* @__PURE__ */ jsx43("span", { className: "tabular-nums text-[11px] text-muted-foreground", children: n }) : null
|
|
13377
|
+
]
|
|
13378
|
+
},
|
|
13379
|
+
v
|
|
13380
|
+
);
|
|
13381
|
+
}) }),
|
|
13382
|
+
/* @__PURE__ */ jsx43("span", { className: "ml-auto hidden text-[10px] text-muted-foreground lg:inline", children: view === "inbox" ? "j/k move \xB7 x select \xB7 a approve \xB7 d decline \xB7 s snooze \xB7 e done \xB7 z undo \xB7 o open \xB7 v view \xB7 g group \xB7 h decided" : "j/k move \xB7 u put back \xB7 z undo \xB7 o open \xB7 v view \xB7 g group" }),
|
|
13116
13383
|
/* @__PURE__ */ jsx43(
|
|
13117
13384
|
"div",
|
|
13118
13385
|
{
|
|
@@ -13135,7 +13402,7 @@ function ActionInbox({
|
|
|
13135
13402
|
))
|
|
13136
13403
|
}
|
|
13137
13404
|
),
|
|
13138
|
-
/* @__PURE__ */ jsx43(Button34, { size: "sm", variant: "ghost", className: "h-7 px-2 text-xs", onClick: () => setShowDecided((s) => !s), children: showDecided ? "Hide decided" : "Show decided" }),
|
|
13405
|
+
view === "inbox" ? /* @__PURE__ */ jsx43(Button34, { size: "sm", variant: "ghost", className: "h-7 px-2 text-xs", onClick: () => setShowDecided((s) => !s), children: showDecided ? "Hide decided" : "Show decided" }) : null,
|
|
13139
13406
|
/* @__PURE__ */ jsx43(Button34, { size: "sm", variant: "ghost", className: "h-7 px-2 text-xs", onClick: () => void load(), children: "Refresh" })
|
|
13140
13407
|
] }),
|
|
13141
13408
|
error ? /* @__PURE__ */ jsx43(RefusalNotice, { error }) : null,
|
|
@@ -13180,7 +13447,12 @@ function ActionInbox({
|
|
|
13180
13447
|
/* @__PURE__ */ jsx43("span", { children: batchSaid }),
|
|
13181
13448
|
/* @__PURE__ */ jsx43(Button34, { size: "sm", variant: "ghost", className: "h-6 px-2", onClick: () => setBatchSaid(null), children: "Close" })
|
|
13182
13449
|
] }) : null,
|
|
13183
|
-
|
|
13450
|
+
said ? /* @__PURE__ */ jsxs38("p", { className: "flex items-center gap-2 text-xs", role: "status", "data-testid": "inbox-said", children: [
|
|
13451
|
+
/* @__PURE__ */ jsx43("span", { children: said.text }),
|
|
13452
|
+
said.undo ? /* @__PURE__ */ jsx43(Button34, { size: "sm", variant: "ghost", className: "h-6 px-2", onClick: () => void said.undo?.(), children: "Undo" }) : null,
|
|
13453
|
+
/* @__PURE__ */ jsx43(Button34, { size: "sm", variant: "ghost", className: "h-6 px-2", onClick: () => setSaid(null), children: "Close" })
|
|
13454
|
+
] }) : null,
|
|
13455
|
+
shown3.length === 0 && view === "snoozed" && !error ? /* @__PURE__ */ jsx43("p", { className: "text-xs text-muted-foreground", "data-testid": "inbox-empty", children: "Nothing is snoozed. Press s on a row to put it off until a time; it comes back to the top of your inbox then, and only your inbox changes." }) : shown3.length === 0 && view === "done" && !error ? /* @__PURE__ */ jsx43("p", { className: "text-xs text-muted-foreground", "data-testid": "inbox-empty", children: "Nothing is cleared. Press e on a piece of work you have seen to take it out of your inbox; it comes back if somebody else changes it." }) : shown3.length === 0 ? (
|
|
13184
13456
|
// AN EMPTY INBOX SAYS WHY — and never under a refusal, where "nothing is waiting" would be
|
|
13185
13457
|
// a guess dressed as an answer.
|
|
13186
13458
|
error ? null : tableId && !everyTable && elsewhere > 0 ? /* @__PURE__ */ jsxs38("p", { className: "flex flex-wrap items-center gap-2 text-xs text-muted-foreground", "data-testid": "inbox-empty", children: [
|
|
@@ -13210,7 +13482,31 @@ function ActionInbox({
|
|
|
13210
13482
|
) : null,
|
|
13211
13483
|
/* @__PURE__ */ jsx43("ol", { className: "flex flex-col gap-1", children: group.items.map((item) => renderRow(item, shown3.indexOf(item))) })
|
|
13212
13484
|
] }, group.key)) }),
|
|
13213
|
-
/* @__PURE__ */ jsx43(
|
|
13485
|
+
view === "inbox" ? /* @__PURE__ */ jsx43(
|
|
13486
|
+
MyChecklistSteps,
|
|
13487
|
+
{
|
|
13488
|
+
className: "border-t pt-2",
|
|
13489
|
+
onlyIds: waitingIds,
|
|
13490
|
+
onSteps,
|
|
13491
|
+
actions: (stepId) => {
|
|
13492
|
+
const title = items?.find((i) => i.item_id === stepId)?.title ?? "this step";
|
|
13493
|
+
return /* @__PURE__ */ jsxs38(Fragment18, { children: [
|
|
13494
|
+
snoozing === stepId ? snoozeChoices().map((c) => /* @__PURE__ */ jsx43(
|
|
13495
|
+
Button34,
|
|
13496
|
+
{
|
|
13497
|
+
size: "sm",
|
|
13498
|
+
variant: "ghost",
|
|
13499
|
+
className: "h-5 px-1 text-[11px]",
|
|
13500
|
+
onClick: () => void snooze(stepId, title, c.until),
|
|
13501
|
+
children: c.label
|
|
13502
|
+
},
|
|
13503
|
+
c.key
|
|
13504
|
+
)) : /* @__PURE__ */ jsx43(Button34, { size: "sm", variant: "ghost", className: "h-5 px-1 text-[11px]", onClick: () => setSnoozing(stepId), children: "Snooze" }),
|
|
13505
|
+
/* @__PURE__ */ jsx43(Button34, { size: "sm", variant: "ghost", className: "h-5 px-1 text-[11px]", onClick: () => void clearItem(stepId), children: "Done" })
|
|
13506
|
+
] });
|
|
13507
|
+
}
|
|
13508
|
+
}
|
|
13509
|
+
) : null
|
|
13214
13510
|
]
|
|
13215
13511
|
}
|
|
13216
13512
|
);
|
|
@@ -22074,6 +22370,7 @@ export {
|
|
|
22074
22370
|
GridCell,
|
|
22075
22371
|
HistoryPanel,
|
|
22076
22372
|
INBOX_GROUPINGS,
|
|
22373
|
+
INBOX_VIEWS,
|
|
22077
22374
|
IN_MEMORY_QUEUE_REASON,
|
|
22078
22375
|
ImportWizard,
|
|
22079
22376
|
KERNEL_REASON,
|
|
@@ -22284,6 +22581,7 @@ export {
|
|
|
22284
22581
|
scalarText,
|
|
22285
22582
|
seedIsSatisfied,
|
|
22286
22583
|
shareUnavailableReason,
|
|
22584
|
+
snoozeChoices,
|
|
22287
22585
|
specFromBlock,
|
|
22288
22586
|
storeDecidesRights,
|
|
22289
22587
|
styleFromDecorations,
|