@ai-matrx/records-ui 0.102.4 → 0.102.5
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 +9 -0
- package/dist/index.cjs +585 -511
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -3
- package/dist/index.d.ts +9 -3
- package/dist/index.js +575 -501
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -13452,7 +13452,12 @@ function useMergedGridControls(args) {
|
|
|
13452
13452
|
}
|
|
13453
13453
|
} : {},
|
|
13454
13454
|
// v7 item 5: Rename opens the record's name cell in place — the grid's own editor.
|
|
13455
|
-
...table?.title_field && fields.some((f) => f.key === table.title_field) && editable ? {
|
|
13455
|
+
...table?.title_field && fields.some((f) => f.key === table.title_field) && editable ? {
|
|
13456
|
+
renameRow: (rowId) => {
|
|
13457
|
+
editing.begin({ rowId, key: table.title_field });
|
|
13458
|
+
selectOpenCellText();
|
|
13459
|
+
}
|
|
13460
|
+
} : {},
|
|
13456
13461
|
...hrefForRecord && table ? {
|
|
13457
13462
|
copyRecordLink: (rowId) => {
|
|
13458
13463
|
const href = hrefForRecord({ table, recordId: rowId });
|
|
@@ -13831,6 +13836,17 @@ function backLinkSentence(column, readers = [], tableName2 = null) {
|
|
|
13831
13836
|
if (readers.length === 0) return base;
|
|
13832
13837
|
return `${readersSentence(readers.length, tableName2)} ${base}`;
|
|
13833
13838
|
}
|
|
13839
|
+
function selectOpenCellText() {
|
|
13840
|
+
if (typeof window === "undefined") return;
|
|
13841
|
+
requestAnimationFrame(
|
|
13842
|
+
() => requestAnimationFrame(() => {
|
|
13843
|
+
const box = document.querySelector(
|
|
13844
|
+
"[data-matrx-cell-editor] input, [data-matrx-cell-editor] textarea"
|
|
13845
|
+
);
|
|
13846
|
+
box?.select();
|
|
13847
|
+
})
|
|
13848
|
+
);
|
|
13849
|
+
}
|
|
13834
13850
|
|
|
13835
13851
|
// src/Grid.tsx
|
|
13836
13852
|
var import_design_system58 = require("@ai-matrx/design-system");
|
|
@@ -29368,15 +29384,162 @@ var import_design_system92 = require("@ai-matrx/design-system");
|
|
|
29368
29384
|
var import_data_table19 = require("@ai-matrx/design-system/data-table");
|
|
29369
29385
|
var import_format6 = require("@ai-matrx/kit/format");
|
|
29370
29386
|
|
|
29387
|
+
// src/recordMoves.tsx
|
|
29388
|
+
var import_react165 = require("react");
|
|
29389
|
+
var import_react166 = require("@ai-matrx/records/react");
|
|
29390
|
+
var import_design_system85 = require("@ai-matrx/design-system");
|
|
29391
|
+
var import_jsx_runtime96 = require("react/jsx-runtime");
|
|
29392
|
+
async function moveRecordValue(client, recordId, patch, expectedVersion) {
|
|
29393
|
+
const written = await updateRecordAt(client, { record_id: recordId, patch, version: expectedVersion });
|
|
29394
|
+
return written.ok ? { ok: true, version: typeof written.data === "number" ? written.data : null } : { ok: false, error: written.error };
|
|
29395
|
+
}
|
|
29396
|
+
function useRecordMoves({
|
|
29397
|
+
tableId,
|
|
29398
|
+
rows,
|
|
29399
|
+
onMoved
|
|
29400
|
+
}) {
|
|
29401
|
+
const client = (0, import_react166.useRecordsClient)();
|
|
29402
|
+
const [refused, setRefused] = (0, import_react165.useState)(null);
|
|
29403
|
+
const versions = useRecordVersions(client, rows);
|
|
29404
|
+
const [stale, setStale] = (0, import_react165.useState)(null);
|
|
29405
|
+
const reload = (0, import_react165.useCallback)(() => onMoved?.(), [onMoved]);
|
|
29406
|
+
const forget = (0, import_react165.useCallback)(() => void 0, []);
|
|
29407
|
+
const undo = useGridUndo({
|
|
29408
|
+
tableId,
|
|
29409
|
+
reload,
|
|
29410
|
+
forget,
|
|
29411
|
+
onVersions: (written) => {
|
|
29412
|
+
for (const v of written) versions.wrote(v.id, v.version);
|
|
29413
|
+
}
|
|
29414
|
+
});
|
|
29415
|
+
const move = (0, import_react165.useCallback)(
|
|
29416
|
+
async ({ recordId, patch, before, label }) => {
|
|
29417
|
+
setRefused(null);
|
|
29418
|
+
setStale(null);
|
|
29419
|
+
const written = await moveRecordValue(client, recordId, patch, await versions.seen(recordId));
|
|
29420
|
+
if (!written.ok) {
|
|
29421
|
+
const changedElsewhere = isChangedElsewhere(written.error);
|
|
29422
|
+
const unread = isVersionUnread(written.error);
|
|
29423
|
+
setRefused({ recordId, error: written.error, changedElsewhere, unread });
|
|
29424
|
+
if (changedElsewhere || unread) {
|
|
29425
|
+
undo.dismiss();
|
|
29426
|
+
setStale({ id: recordId, unread });
|
|
29427
|
+
} else {
|
|
29428
|
+
undo.say(`Not moved. ${refusalSentence(written.error)}`, true);
|
|
29429
|
+
}
|
|
29430
|
+
if (changedElsewhere) {
|
|
29431
|
+
versions.refresh([recordId]);
|
|
29432
|
+
onMoved?.();
|
|
29433
|
+
}
|
|
29434
|
+
return false;
|
|
29435
|
+
}
|
|
29436
|
+
if (written.version !== null) versions.wrote(recordId, written.version);
|
|
29437
|
+
undo.push({
|
|
29438
|
+
label,
|
|
29439
|
+
cells: Object.keys(patch).map((key) => ({
|
|
29440
|
+
rowId: recordId,
|
|
29441
|
+
key,
|
|
29442
|
+
before: before[key] ?? null,
|
|
29443
|
+
after: patch[key],
|
|
29444
|
+
...written.version !== null ? { version: written.version } : {}
|
|
29445
|
+
}))
|
|
29446
|
+
});
|
|
29447
|
+
onMoved?.();
|
|
29448
|
+
return true;
|
|
29449
|
+
},
|
|
29450
|
+
[client, undo, onMoved, versions]
|
|
29451
|
+
);
|
|
29452
|
+
const create = (0, import_react165.useCallback)(
|
|
29453
|
+
async ({ tableId: table, data, label }) => {
|
|
29454
|
+
setRefused(null);
|
|
29455
|
+
const written = await client.recordWrite({ table_id: table, data });
|
|
29456
|
+
if (!written.ok) {
|
|
29457
|
+
undo.say(`Nothing was added. ${refusalSentence(written.error)}`, true);
|
|
29458
|
+
return null;
|
|
29459
|
+
}
|
|
29460
|
+
undo.push({ label, cells: [], created: [written.data] });
|
|
29461
|
+
onMoved?.();
|
|
29462
|
+
return written.data;
|
|
29463
|
+
},
|
|
29464
|
+
[client, undo, onMoved]
|
|
29465
|
+
);
|
|
29466
|
+
const offering = Boolean(undo.notice);
|
|
29467
|
+
const undoRef = (0, import_react165.useRef)(undo);
|
|
29468
|
+
undoRef.current = undo;
|
|
29469
|
+
(0, import_react165.useEffect)(() => {
|
|
29470
|
+
if (!offering || typeof document === "undefined") return;
|
|
29471
|
+
const onKey = (event) => {
|
|
29472
|
+
const which = undoKey(event);
|
|
29473
|
+
if (!which) return;
|
|
29474
|
+
event.preventDefault();
|
|
29475
|
+
void (which === "undo" ? undoRef.current.undo() : undoRef.current.redo());
|
|
29476
|
+
};
|
|
29477
|
+
document.addEventListener("keydown", onKey);
|
|
29478
|
+
return () => document.removeEventListener("keydown", onKey);
|
|
29479
|
+
}, [offering]);
|
|
29480
|
+
const onKeyDown = (0, import_react165.useCallback)(
|
|
29481
|
+
(event) => {
|
|
29482
|
+
if (offering) return;
|
|
29483
|
+
const which = undoKey(event);
|
|
29484
|
+
if (!which) return;
|
|
29485
|
+
event.preventDefault();
|
|
29486
|
+
void (which === "undo" ? undo.undo() : undo.redo());
|
|
29487
|
+
},
|
|
29488
|
+
[undo, offering]
|
|
29489
|
+
);
|
|
29490
|
+
const reloadStale = (0, import_react165.useCallback)(async () => {
|
|
29491
|
+
const id = stale?.id ?? null;
|
|
29492
|
+
setStale(null);
|
|
29493
|
+
setRefused(null);
|
|
29494
|
+
if (!id) return;
|
|
29495
|
+
versions.refresh([id]);
|
|
29496
|
+
onMoved?.();
|
|
29497
|
+
}, [versions, stale, onMoved]);
|
|
29498
|
+
const notice = /* @__PURE__ */ (0, import_jsx_runtime96.jsxs)(import_jsx_runtime96.Fragment, { children: [
|
|
29499
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsx)(UndoNotice, { undo }),
|
|
29500
|
+
stale ? /* @__PURE__ */ (0, import_jsx_runtime96.jsxs)(
|
|
29501
|
+
"p",
|
|
29502
|
+
{
|
|
29503
|
+
role: "status",
|
|
29504
|
+
"data-records-undo-notice": "refused",
|
|
29505
|
+
"data-move-stale": stale.id,
|
|
29506
|
+
"data-move-unread": stale.unread ? "" : void 0,
|
|
29507
|
+
className: "pointer-events-auto absolute bottom-3 left-1/2 z-30 flex max-w-[min(36rem,calc(100%-2rem))] -translate-x-1/2 items-center gap-2 rounded-md border border-border bg-popover px-3 py-1.5 text-xs text-popover-foreground shadow-lg",
|
|
29508
|
+
children: [
|
|
29509
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsx)("span", { children: stale.unread ? VERSION_UNREAD_LABEL : STALE_MOVE_LABEL }),
|
|
29510
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsx)(import_design_system85.Button, { size: "sm", variant: "outline", className: "ml-auto h-6", "data-move-reload": "", onClick: () => void reloadStale(), children: "Reload" }),
|
|
29511
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsx)(import_design_system85.Button, { size: "sm", variant: "ghost", className: "h-6", onClick: () => setStale(null), children: "Dismiss" })
|
|
29512
|
+
]
|
|
29513
|
+
}
|
|
29514
|
+
) : null
|
|
29515
|
+
] });
|
|
29516
|
+
return (0, import_react165.useMemo)(
|
|
29517
|
+
() => ({ move, create, refused, say: (says, sticky) => undo.say(says, sticky), undo, onKeyDown, notice }),
|
|
29518
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
29519
|
+
[move, create, refused, undo, onKeyDown, stale, reloadStale]
|
|
29520
|
+
);
|
|
29521
|
+
}
|
|
29522
|
+
function MoveRefusedBadge({ refused }) {
|
|
29523
|
+
return /* @__PURE__ */ (0, import_jsx_runtime96.jsx)(
|
|
29524
|
+
"span",
|
|
29525
|
+
{
|
|
29526
|
+
"data-move-refused": refused.changedElsewhere ? "changed-elsewhere" : refused.unread ? "unread" : "refused",
|
|
29527
|
+
title: refused.changedElsewhere ? STALE_MOVE_LABEL : refused.unread ? VERSION_UNREAD_LABEL : refusalSentence(refused.error),
|
|
29528
|
+
className: "mt-0.5 inline-block rounded bg-destructive/10 px-1 text-[10px] font-medium text-destructive",
|
|
29529
|
+
children: refused.changedElsewhere ? STALE_MOVE_LABEL : refused.unread ? VERSION_UNREAD_LABEL : "Not moved"
|
|
29530
|
+
}
|
|
29531
|
+
);
|
|
29532
|
+
}
|
|
29533
|
+
|
|
29371
29534
|
// src/Pipeline.tsx
|
|
29372
|
-
var
|
|
29373
|
-
var
|
|
29535
|
+
var import_react169 = require("react");
|
|
29536
|
+
var import_react170 = require("@ai-matrx/records/react");
|
|
29374
29537
|
var import_records46 = require("@ai-matrx/records");
|
|
29375
|
-
var
|
|
29538
|
+
var import_design_system87 = require("@ai-matrx/design-system");
|
|
29376
29539
|
var import_data_table14 = require("@ai-matrx/design-system/data-table");
|
|
29377
29540
|
|
|
29378
29541
|
// src/CardDates.tsx
|
|
29379
|
-
var
|
|
29542
|
+
var import_jsx_runtime97 = require("react/jsx-runtime");
|
|
29380
29543
|
function cardDateFields(all, titleField, hiddenFields) {
|
|
29381
29544
|
const hidden = new Set(hiddenFields ?? []);
|
|
29382
29545
|
return all.filter(
|
|
@@ -29391,14 +29554,14 @@ function CardDates({ record, fields }) {
|
|
|
29391
29554
|
return value !== null && value !== void 0 && value !== "";
|
|
29392
29555
|
});
|
|
29393
29556
|
if (held.length === 0) return null;
|
|
29394
|
-
return /* @__PURE__ */ (0,
|
|
29557
|
+
return /* @__PURE__ */ (0, import_jsx_runtime97.jsx)(import_jsx_runtime97.Fragment, { children: held.map((field2) => /* @__PURE__ */ (0, import_jsx_runtime97.jsxs)(
|
|
29395
29558
|
"span",
|
|
29396
29559
|
{
|
|
29397
29560
|
className: "mt-0.5 flex min-w-0 items-baseline gap-1 text-[11px] text-muted-foreground",
|
|
29398
29561
|
"data-card-date": field2.key,
|
|
29399
29562
|
children: [
|
|
29400
|
-
/* @__PURE__ */ (0,
|
|
29401
|
-
/* @__PURE__ */ (0,
|
|
29563
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)("span", { className: "shrink-0", children: fieldName(field2) }),
|
|
29564
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)("span", { className: "min-w-0 truncate text-foreground/80", children: /* @__PURE__ */ (0, import_jsx_runtime97.jsx)(
|
|
29402
29565
|
RecordValue,
|
|
29403
29566
|
{
|
|
29404
29567
|
field: field2,
|
|
@@ -29415,9 +29578,9 @@ function CardDates({ record, fields }) {
|
|
|
29415
29578
|
|
|
29416
29579
|
// src/RecordActionMenu.tsx
|
|
29417
29580
|
var import_clipboard6 = require("@ai-matrx/kit/clipboard");
|
|
29418
|
-
var
|
|
29419
|
-
var
|
|
29420
|
-
var
|
|
29581
|
+
var import_react167 = require("react");
|
|
29582
|
+
var import_react168 = require("@ai-matrx/records/react");
|
|
29583
|
+
var import_design_system86 = require("@ai-matrx/design-system");
|
|
29421
29584
|
|
|
29422
29585
|
// src/recordActions.ts
|
|
29423
29586
|
function recordLink(tableId, recordId, origin = DEFAULT_ACTION_ORIGIN) {
|
|
@@ -29477,7 +29640,7 @@ function recordActions(input) {
|
|
|
29477
29640
|
}
|
|
29478
29641
|
|
|
29479
29642
|
// src/RecordActionMenu.tsx
|
|
29480
|
-
var
|
|
29643
|
+
var import_jsx_runtime98 = require("react/jsx-runtime");
|
|
29481
29644
|
function duplicateValues(fields, document2) {
|
|
29482
29645
|
const data = {};
|
|
29483
29646
|
for (const field2 of fields) {
|
|
@@ -29488,15 +29651,15 @@ function duplicateValues(fields, document2) {
|
|
|
29488
29651
|
return data;
|
|
29489
29652
|
}
|
|
29490
29653
|
function useRecordActionHost({ tableId, row, onOpenRecord, onChanged, onMerge }) {
|
|
29491
|
-
const client = (0,
|
|
29654
|
+
const client = (0, import_react168.useRecordsClient)();
|
|
29492
29655
|
const host = useRecordsUi();
|
|
29493
|
-
const fields = (0,
|
|
29494
|
-
const table = (0,
|
|
29656
|
+
const fields = (0, import_react168.useFields)(tableId);
|
|
29657
|
+
const table = (0, import_react168.useTable)(tableId);
|
|
29495
29658
|
const notify = host.notify;
|
|
29496
29659
|
const linkRecord = host.linkRecord;
|
|
29497
29660
|
const href = host.hrefForRecord && table.data ? host.hrefForRecord({ table: table.data, recordId: row.id }) : void 0;
|
|
29498
29661
|
const fieldList = fields.data;
|
|
29499
|
-
return (0,
|
|
29662
|
+
return (0, import_react167.useMemo)(() => {
|
|
29500
29663
|
const said = (sentence2) => notify?.success(sentence2);
|
|
29501
29664
|
return {
|
|
29502
29665
|
...typeof window !== "undefined" ? { origin: window.location.origin } : {},
|
|
@@ -29559,8 +29722,8 @@ function useRecordActionHost({ tableId, row, onOpenRecord, onChanged, onMerge })
|
|
|
29559
29722
|
}
|
|
29560
29723
|
function ContextActionItem({ action: action3 }) {
|
|
29561
29724
|
const disabled = action3.disabledReason !== void 0;
|
|
29562
|
-
return /* @__PURE__ */ (0,
|
|
29563
|
-
|
|
29725
|
+
return /* @__PURE__ */ (0, import_jsx_runtime98.jsxs)(
|
|
29726
|
+
import_design_system86.ContextMenuItem,
|
|
29564
29727
|
{
|
|
29565
29728
|
disabled,
|
|
29566
29729
|
onSelect: () => {
|
|
@@ -29570,43 +29733,43 @@ function ContextActionItem({ action: action3 }) {
|
|
|
29570
29733
|
"data-object-action": action3.id,
|
|
29571
29734
|
className: action3.destructive ? "text-destructive focus:text-destructive" : void 0,
|
|
29572
29735
|
children: [
|
|
29573
|
-
/* @__PURE__ */ (0,
|
|
29574
|
-
/* @__PURE__ */ (0,
|
|
29575
|
-
/* @__PURE__ */ (0,
|
|
29576
|
-
disabled ? /* @__PURE__ */ (0,
|
|
29736
|
+
/* @__PURE__ */ (0, import_jsx_runtime98.jsx)(ObjectActionGlyph, { name: action3.icon, className: "mr-2 h-4 w-4 shrink-0" }),
|
|
29737
|
+
/* @__PURE__ */ (0, import_jsx_runtime98.jsxs)("span", { className: "flex min-w-0 flex-col", children: [
|
|
29738
|
+
/* @__PURE__ */ (0, import_jsx_runtime98.jsx)("span", { children: action3.label }),
|
|
29739
|
+
disabled ? /* @__PURE__ */ (0, import_jsx_runtime98.jsx)("span", { className: "truncate text-xs text-muted-foreground", "data-object-action-reason": "", children: action3.disabledReason }) : null
|
|
29577
29740
|
] }),
|
|
29578
|
-
action3.shortcut ? /* @__PURE__ */ (0,
|
|
29741
|
+
action3.shortcut ? /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(import_design_system86.ContextMenuShortcut, { children: action3.shortcut }) : null
|
|
29579
29742
|
]
|
|
29580
29743
|
}
|
|
29581
29744
|
);
|
|
29582
29745
|
}
|
|
29583
29746
|
function ObjectActionContextMenuItems({ actions }) {
|
|
29584
|
-
return /* @__PURE__ */ (0,
|
|
29585
|
-
if (entry.kind === "separator") return /* @__PURE__ */ (0,
|
|
29586
|
-
if (entry.kind === "item") return /* @__PURE__ */ (0,
|
|
29587
|
-
return /* @__PURE__ */ (0,
|
|
29588
|
-
/* @__PURE__ */ (0,
|
|
29589
|
-
entry.icon ? /* @__PURE__ */ (0,
|
|
29747
|
+
return /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(import_jsx_runtime98.Fragment, { children: toDropdownEntries(actions).map((entry) => {
|
|
29748
|
+
if (entry.kind === "separator") return /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(import_design_system86.ContextMenuSeparator, {}, entry.id);
|
|
29749
|
+
if (entry.kind === "item") return /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(ContextActionItem, { action: entry.action }, entry.action.id);
|
|
29750
|
+
return /* @__PURE__ */ (0, import_jsx_runtime98.jsxs)(import_design_system86.ContextMenuSub, { children: [
|
|
29751
|
+
/* @__PURE__ */ (0, import_jsx_runtime98.jsxs)(import_design_system86.ContextMenuSubTrigger, { "data-object-action-group": entry.id, children: [
|
|
29752
|
+
entry.icon ? /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(ObjectActionGlyph, { name: entry.icon, className: "mr-2 h-4 w-4 shrink-0" }) : null,
|
|
29590
29753
|
entry.label
|
|
29591
29754
|
] }),
|
|
29592
|
-
/* @__PURE__ */ (0,
|
|
29755
|
+
/* @__PURE__ */ (0, import_jsx_runtime98.jsx)(import_design_system86.ContextMenuSubContent, { children: entry.actions.map((a) => /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(ContextActionItem, { action: a }, a.id)) })
|
|
29593
29756
|
] }, entry.id);
|
|
29594
29757
|
}) });
|
|
29595
29758
|
}
|
|
29596
29759
|
function RecordActionMenu({ tableId, row, name, onOpenRecord, onChanged, children, className }) {
|
|
29597
|
-
const [merging, setMerging] = (0,
|
|
29598
|
-
const openMerge = (0,
|
|
29760
|
+
const [merging, setMerging] = (0, import_react167.useState)(false);
|
|
29761
|
+
const openMerge = (0, import_react167.useCallback)(() => setMerging(true), []);
|
|
29599
29762
|
const actionHost = useRecordActionHost({ tableId, row, onOpenRecord, onChanged, onMerge: openMerge });
|
|
29600
|
-
const rights = (0,
|
|
29601
|
-
const actions = (0,
|
|
29763
|
+
const rights = (0, import_react167.useMemo)(() => whatYouMayDo(row.level || null, true), [row.level]);
|
|
29764
|
+
const actions = (0, import_react167.useMemo)(
|
|
29602
29765
|
() => recordActions({ record: { id: row.id, tableId, name }, rights, host: actionHost }),
|
|
29603
29766
|
[row.id, tableId, name, rights, actionHost]
|
|
29604
29767
|
);
|
|
29605
|
-
return /* @__PURE__ */ (0,
|
|
29606
|
-
/* @__PURE__ */ (0,
|
|
29768
|
+
return /* @__PURE__ */ (0, import_jsx_runtime98.jsxs)(import_design_system86.ContextMenu, { children: [
|
|
29769
|
+
/* @__PURE__ */ (0, import_jsx_runtime98.jsx)(import_design_system86.ContextMenuTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime98.jsxs)("div", { className: (0, import_design_system86.cn)("group/record-card relative", className), "data-record-actions": row.id, children: [
|
|
29607
29770
|
children,
|
|
29608
|
-
/* @__PURE__ */ (0,
|
|
29609
|
-
/* @__PURE__ */ (0,
|
|
29771
|
+
/* @__PURE__ */ (0, import_jsx_runtime98.jsxs)(import_design_system86.DropdownMenu, { children: [
|
|
29772
|
+
/* @__PURE__ */ (0, import_jsx_runtime98.jsx)(import_design_system86.DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(
|
|
29610
29773
|
"button",
|
|
29611
29774
|
{
|
|
29612
29775
|
type: "button",
|
|
@@ -29614,18 +29777,18 @@ function RecordActionMenu({ tableId, row, name, onOpenRecord, onChanged, childre
|
|
|
29614
29777
|
title: "More",
|
|
29615
29778
|
"data-record-actions-trigger": row.id,
|
|
29616
29779
|
className: "absolute right-0.5 top-0.5 flex h-6 w-6 items-center justify-center rounded bg-background/90 text-muted-foreground opacity-0 hover:bg-muted hover:text-foreground focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring group-hover/record-card:opacity-100 data-[state=open]:opacity-100 [@media(hover:none)]:opacity-100",
|
|
29617
|
-
children: /* @__PURE__ */ (0,
|
|
29618
|
-
/* @__PURE__ */ (0,
|
|
29619
|
-
/* @__PURE__ */ (0,
|
|
29620
|
-
/* @__PURE__ */ (0,
|
|
29780
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime98.jsxs)("svg", { viewBox: "0 0 24 24", className: "h-4 w-4", fill: "currentColor", "aria-hidden": "true", children: [
|
|
29781
|
+
/* @__PURE__ */ (0, import_jsx_runtime98.jsx)("circle", { cx: "5", cy: "12", r: "1.75" }),
|
|
29782
|
+
/* @__PURE__ */ (0, import_jsx_runtime98.jsx)("circle", { cx: "12", cy: "12", r: "1.75" }),
|
|
29783
|
+
/* @__PURE__ */ (0, import_jsx_runtime98.jsx)("circle", { cx: "19", cy: "12", r: "1.75" })
|
|
29621
29784
|
] })
|
|
29622
29785
|
}
|
|
29623
29786
|
) }),
|
|
29624
|
-
/* @__PURE__ */ (0,
|
|
29787
|
+
/* @__PURE__ */ (0, import_jsx_runtime98.jsx)(import_design_system86.DropdownMenuContent, { align: "end", className: "w-56", children: /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(ObjectActionMenuItems, { actions }) })
|
|
29625
29788
|
] })
|
|
29626
29789
|
] }) }),
|
|
29627
|
-
/* @__PURE__ */ (0,
|
|
29628
|
-
merging ? /* @__PURE__ */ (0,
|
|
29790
|
+
/* @__PURE__ */ (0, import_jsx_runtime98.jsx)(import_design_system86.ContextMenuContent, { className: "w-56", children: /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(ObjectActionContextMenuItems, { actions }) }),
|
|
29791
|
+
merging ? /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(
|
|
29629
29792
|
MergeRecordDialog,
|
|
29630
29793
|
{
|
|
29631
29794
|
tableId,
|
|
@@ -29639,7 +29802,7 @@ function RecordActionMenu({ tableId, row, name, onOpenRecord, onChanged, childre
|
|
|
29639
29802
|
}
|
|
29640
29803
|
|
|
29641
29804
|
// src/Pipeline.tsx
|
|
29642
|
-
var
|
|
29805
|
+
var import_jsx_runtime99 = require("react/jsx-runtime");
|
|
29643
29806
|
var UNPLACED = "\0unplaced";
|
|
29644
29807
|
function stageOfCard(row, stageKey, stages) {
|
|
29645
29808
|
const document2 = row.document ?? {};
|
|
@@ -29673,38 +29836,39 @@ function PipelineBoard({
|
|
|
29673
29836
|
onChanged,
|
|
29674
29837
|
style,
|
|
29675
29838
|
dateFields,
|
|
29839
|
+
canAdd = false,
|
|
29676
29840
|
className
|
|
29677
29841
|
}) {
|
|
29678
|
-
const client = (0,
|
|
29679
|
-
const fields = (0,
|
|
29842
|
+
const client = (0, import_react170.useRecordsClient)();
|
|
29843
|
+
const fields = (0, import_react170.useFields)(tableId);
|
|
29680
29844
|
const ownDecorations = useTableDecorations(style ? null : tableId);
|
|
29681
|
-
const cardStyle = (0,
|
|
29845
|
+
const cardStyle = (0, import_react169.useMemo)(
|
|
29682
29846
|
() => style ?? resolveTableStyle(ownDecorations.data, fields.data ?? [], void 0),
|
|
29683
29847
|
[style, ownDecorations.data, fields.data]
|
|
29684
29848
|
);
|
|
29685
|
-
const [definition, setDefinition] = (0,
|
|
29686
|
-
const [columns, setColumns] = (0,
|
|
29687
|
-
const [error, setError] = (0,
|
|
29688
|
-
const [loading, setLoading] = (0,
|
|
29689
|
-
const [pending, setPending] = (0,
|
|
29690
|
-
const [waiting, setWaiting] = (0,
|
|
29691
|
-
const [dragging, setDragging] = (0,
|
|
29692
|
-
const [over, setOver] = (0,
|
|
29693
|
-
const alive = (0,
|
|
29694
|
-
const [selected, setSelected] = (0,
|
|
29695
|
-
const anchor = (0,
|
|
29696
|
-
const [batch, setBatch] = (0,
|
|
29697
|
-
const [batchSaid, setBatchSaid] = (0,
|
|
29698
|
-
const [batchError, setBatchError] = (0,
|
|
29699
|
-
const [moving, setMoving] = (0,
|
|
29700
|
-
(0,
|
|
29849
|
+
const [definition, setDefinition] = (0, import_react169.useState)(null);
|
|
29850
|
+
const [columns, setColumns] = (0, import_react169.useState)([]);
|
|
29851
|
+
const [error, setError] = (0, import_react169.useState)(null);
|
|
29852
|
+
const [loading, setLoading] = (0, import_react169.useState)(true);
|
|
29853
|
+
const [pending, setPending] = (0, import_react169.useState)({ kind: "none" });
|
|
29854
|
+
const [waiting, setWaiting] = (0, import_react169.useState)(/* @__PURE__ */ new Map());
|
|
29855
|
+
const [dragging, setDragging] = (0, import_react169.useState)(null);
|
|
29856
|
+
const [over, setOver] = (0, import_react169.useState)(null);
|
|
29857
|
+
const alive = (0, import_react169.useRef)(true);
|
|
29858
|
+
const [selected, setSelected] = (0, import_react169.useState)(/* @__PURE__ */ new Set());
|
|
29859
|
+
const anchor = (0, import_react169.useRef)(null);
|
|
29860
|
+
const [batch, setBatch] = (0, import_react169.useState)(/* @__PURE__ */ new Map());
|
|
29861
|
+
const [batchSaid, setBatchSaid] = (0, import_react169.useState)(null);
|
|
29862
|
+
const [batchError, setBatchError] = (0, import_react169.useState)(null);
|
|
29863
|
+
const [moving, setMoving] = (0, import_react169.useState)(false);
|
|
29864
|
+
(0, import_react169.useEffect)(() => {
|
|
29701
29865
|
alive.current = true;
|
|
29702
29866
|
return () => {
|
|
29703
29867
|
alive.current = false;
|
|
29704
29868
|
};
|
|
29705
29869
|
}, []);
|
|
29706
29870
|
const filterKey = (0, import_records46.stableFilterKey)(filter);
|
|
29707
|
-
const reload = (0,
|
|
29871
|
+
const reload = (0, import_react169.useCallback)(async () => {
|
|
29708
29872
|
setLoading(true);
|
|
29709
29873
|
const [read, board, held] = await Promise.all([
|
|
29710
29874
|
client.pipelineRead({ table_id: tableId }),
|
|
@@ -29722,15 +29886,23 @@ function PipelineBoard({
|
|
|
29722
29886
|
setWaiting(held.ok ? new Map((held.data ?? []).map((p) => [p.record_id, p])) : /* @__PURE__ */ new Map());
|
|
29723
29887
|
setColumns(board.ok ? board.data ?? [] : []);
|
|
29724
29888
|
}, [client, tableId, measure, filterKey]);
|
|
29725
|
-
(0,
|
|
29889
|
+
(0, import_react169.useEffect)(() => {
|
|
29726
29890
|
void reload();
|
|
29727
29891
|
}, [reload]);
|
|
29728
|
-
const versions = useRecordVersions(client, rows, (r) => (0,
|
|
29729
|
-
const versionsRef = (0,
|
|
29892
|
+
const versions = useRecordVersions(client, rows, (r) => (0, import_react170.mayDrag)(r.level));
|
|
29893
|
+
const versionsRef = (0, import_react169.useRef)(versions);
|
|
29730
29894
|
versionsRef.current = versions;
|
|
29731
29895
|
const drawnVersion = (id) => versionsRef.current.seen(id);
|
|
29732
29896
|
const stageKey = definition?.stage_field ?? null;
|
|
29733
|
-
const
|
|
29897
|
+
const adds = useRecordMoves({ tableId, rows, ...onMoved ? { onMoved } : {} });
|
|
29898
|
+
const addInStage = async (key, label) => {
|
|
29899
|
+
if (!stageKey) return;
|
|
29900
|
+
const made = await adds.create({ tableId, data: { [stageKey]: key }, label: `New record in ${label}` });
|
|
29901
|
+
if (!made) return;
|
|
29902
|
+
onChanged?.();
|
|
29903
|
+
onOpenRecord?.(made);
|
|
29904
|
+
};
|
|
29905
|
+
const cardsByStage = (0, import_react169.useMemo)(() => {
|
|
29734
29906
|
const map = /* @__PURE__ */ new Map();
|
|
29735
29907
|
if (!stageKey) return map;
|
|
29736
29908
|
for (const row of rows) {
|
|
@@ -29741,16 +29913,16 @@ function PipelineBoard({
|
|
|
29741
29913
|
}, [rows, stageKey, definition?.stages]);
|
|
29742
29914
|
const unplaced = cardsByStage.get(UNPLACED) ?? [];
|
|
29743
29915
|
const all = fields.data ?? [];
|
|
29744
|
-
const titleField = (0,
|
|
29916
|
+
const titleField = (0, import_react169.useMemo)(
|
|
29745
29917
|
() => cardTitleField(all, titleKey ?? null, [stageKey]),
|
|
29746
29918
|
[all, stageKey, titleKey]
|
|
29747
29919
|
);
|
|
29748
29920
|
const unplacedLabels = useRecordLabels(titleField ? [titleField] : []);
|
|
29749
|
-
const measurable = (0,
|
|
29921
|
+
const measurable = (0, import_react169.useMemo)(
|
|
29750
29922
|
() => all.filter((f) => ["number", "currency", "percentage"].includes(String(f.type ?? ""))),
|
|
29751
29923
|
[all]
|
|
29752
29924
|
);
|
|
29753
|
-
const drop = (0,
|
|
29925
|
+
const drop = (0, import_react169.useCallback)(
|
|
29754
29926
|
async (recordId, to) => {
|
|
29755
29927
|
setOver(null);
|
|
29756
29928
|
setDragging(null);
|
|
@@ -29790,7 +29962,7 @@ function PipelineBoard({
|
|
|
29790
29962
|
},
|
|
29791
29963
|
[client, onMoved, reload]
|
|
29792
29964
|
);
|
|
29793
|
-
const askForApproval = (0,
|
|
29965
|
+
const askForApproval = (0, import_react169.useCallback)(
|
|
29794
29966
|
async (recordId, to) => {
|
|
29795
29967
|
const moved = await movePipelineCardAt(client, { record_id: recordId, to, version: await drawnVersion(recordId) });
|
|
29796
29968
|
if (!alive.current) return;
|
|
@@ -29805,7 +29977,7 @@ function PipelineBoard({
|
|
|
29805
29977
|
},
|
|
29806
29978
|
[client, onMoved, reload]
|
|
29807
29979
|
);
|
|
29808
|
-
const moveWith = (0,
|
|
29980
|
+
const moveWith = (0, import_react169.useCallback)(
|
|
29809
29981
|
async (recordId, to, also) => {
|
|
29810
29982
|
const moved = await movePipelineCardAt(client, { record_id: recordId, to, also, version: await drawnVersion(recordId) });
|
|
29811
29983
|
if (!alive.current) return;
|
|
@@ -29831,7 +30003,7 @@ function PipelineBoard({
|
|
|
29831
30003
|
index,
|
|
29832
30004
|
anchor: anchor.current,
|
|
29833
30005
|
shiftKey: how.shift,
|
|
29834
|
-
isSelectable: (r) => (0,
|
|
30006
|
+
isSelectable: (r) => (0, import_react170.mayDrag)(r.level)
|
|
29835
30007
|
});
|
|
29836
30008
|
anchor.current = at;
|
|
29837
30009
|
setSelected(next);
|
|
@@ -29869,18 +30041,18 @@ function PipelineBoard({
|
|
|
29869
30041
|
onMoved?.();
|
|
29870
30042
|
void reload();
|
|
29871
30043
|
};
|
|
29872
|
-
if (fields.error) return /* @__PURE__ */ (0,
|
|
29873
|
-
if (error) return /* @__PURE__ */ (0,
|
|
29874
|
-
if (loading || fields.loading && !fields.data) return /* @__PURE__ */ (0,
|
|
30044
|
+
if (fields.error) return /* @__PURE__ */ (0, import_jsx_runtime99.jsx)(RefusalNotice, { error: fields.error });
|
|
30045
|
+
if (error) return /* @__PURE__ */ (0, import_jsx_runtime99.jsx)(RefusalNotice, { error });
|
|
30046
|
+
if (loading || fields.loading && !fields.data) return /* @__PURE__ */ (0, import_jsx_runtime99.jsx)(import_design_system87.Skeleton, { className: "h-40 w-full" });
|
|
29875
30047
|
if (!definition?.is_pipeline) {
|
|
29876
|
-
return /* @__PURE__ */ (0,
|
|
30048
|
+
return /* @__PURE__ */ (0, import_jsx_runtime99.jsx)("p", { className: "rounded border border-dashed p-4 text-xs text-muted-foreground", children: definition?.why ?? "This table has no stage column yet, so there is no board to draw." });
|
|
29877
30049
|
}
|
|
29878
30050
|
const stages = definition.stages ?? [];
|
|
29879
30051
|
const numbers = new Map(columns.map((c) => [c.stage_key, c]));
|
|
29880
|
-
return /* @__PURE__ */ (0,
|
|
30052
|
+
return /* @__PURE__ */ (0, import_jsx_runtime99.jsxs)(
|
|
29881
30053
|
"div",
|
|
29882
30054
|
{
|
|
29883
|
-
className: (0,
|
|
30055
|
+
className: (0, import_design_system87.cn)("flex min-h-0 flex-col gap-2", className),
|
|
29884
30056
|
onKeyDown: (e) => {
|
|
29885
30057
|
if (e.key === "Escape" && selected.size > 0) {
|
|
29886
30058
|
e.preventDefault();
|
|
@@ -29888,7 +30060,7 @@ function PipelineBoard({
|
|
|
29888
30060
|
}
|
|
29889
30061
|
},
|
|
29890
30062
|
children: [
|
|
29891
|
-
selectedInOrder.length > 0 ? /* @__PURE__ */ (0,
|
|
30063
|
+
selectedInOrder.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime99.jsxs)(
|
|
29892
30064
|
"div",
|
|
29893
30065
|
{
|
|
29894
30066
|
"data-records-bulk-bar": true,
|
|
@@ -29896,40 +30068,40 @@ function PipelineBoard({
|
|
|
29896
30068
|
"aria-label": "Selected cards",
|
|
29897
30069
|
className: "flex shrink-0 flex-wrap items-center gap-2 rounded-md border border-primary/30 bg-primary/5 px-2 py-1.5 text-xs",
|
|
29898
30070
|
children: [
|
|
29899
|
-
/* @__PURE__ */ (0,
|
|
30071
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsxs)("span", { className: "font-medium", children: [
|
|
29900
30072
|
selectedInOrder.length,
|
|
29901
30073
|
" ",
|
|
29902
30074
|
selectedInOrder.length === 1 ? "card" : "cards",
|
|
29903
30075
|
" selected"
|
|
29904
30076
|
] }),
|
|
29905
|
-
/* @__PURE__ */ (0,
|
|
29906
|
-
/* @__PURE__ */ (0,
|
|
29907
|
-
/* @__PURE__ */ (0,
|
|
29908
|
-
/* @__PURE__ */ (0,
|
|
30077
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)(import_design_system87.Button, { size: "sm", variant: "ghost", className: "h-7 px-2 text-xs", onClick: clearSelection, children: "Clear" }),
|
|
30078
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsxs)(import_design_system87.DropdownMenu, { children: [
|
|
30079
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)(import_design_system87.DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime99.jsx)(import_design_system87.Button, { size: "sm", className: "h-7 px-2 text-xs", disabled: moving, children: moving ? `Moving ${selectedInOrder.length}\u2026` : `Move ${selectedInOrder.length} to\u2026` }) }),
|
|
30080
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)(import_design_system87.DropdownMenuContent, { align: "start", children: stages.map((stage) => /* @__PURE__ */ (0, import_jsx_runtime99.jsxs)(import_design_system87.DropdownMenuItem, { onSelect: () => void moveSelected(stage.key, stage.label), children: [
|
|
29909
30081
|
"Move ",
|
|
29910
30082
|
selectedInOrder.length,
|
|
29911
30083
|
" to ",
|
|
29912
30084
|
stage.label
|
|
29913
30085
|
] }, stage.key)) })
|
|
29914
30086
|
] }),
|
|
29915
|
-
/* @__PURE__ */ (0,
|
|
30087
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)("span", { className: "ml-auto hidden text-[10px] text-muted-foreground sm:inline", children: "shift-click takes a run \xB7 x takes one \xB7 Esc clears" })
|
|
29916
30088
|
]
|
|
29917
30089
|
}
|
|
29918
30090
|
) : null,
|
|
29919
|
-
batchError ? /* @__PURE__ */ (0,
|
|
30091
|
+
batchError ? /* @__PURE__ */ (0, import_jsx_runtime99.jsx)(
|
|
29920
30092
|
RefusalNotice,
|
|
29921
30093
|
{
|
|
29922
30094
|
error: batchError,
|
|
29923
|
-
actions: /* @__PURE__ */ (0,
|
|
30095
|
+
actions: /* @__PURE__ */ (0, import_jsx_runtime99.jsx)(import_design_system87.Button, { size: "sm", variant: "ghost", className: "mt-1 h-6", onClick: () => setBatchError(null), children: "Close" })
|
|
29924
30096
|
}
|
|
29925
30097
|
) : null,
|
|
29926
|
-
batchSaid ? /* @__PURE__ */ (0,
|
|
29927
|
-
/* @__PURE__ */ (0,
|
|
29928
|
-
/* @__PURE__ */ (0,
|
|
30098
|
+
batchSaid ? /* @__PURE__ */ (0, import_jsx_runtime99.jsxs)("p", { className: "flex items-center gap-2 text-xs", role: "status", "data-testid": "pipeline-batch-said", children: [
|
|
30099
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)("span", { children: batchSaid }),
|
|
30100
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)(import_design_system87.Button, { size: "sm", variant: "ghost", className: "h-6 px-2", onClick: () => setBatchSaid(null), children: "Close" })
|
|
29929
30101
|
] }) : null,
|
|
29930
|
-
measurable.length > 0 && onMeasureChange ? /* @__PURE__ */ (0,
|
|
29931
|
-
/* @__PURE__ */ (0,
|
|
29932
|
-
/* @__PURE__ */ (0,
|
|
30102
|
+
measurable.length > 0 && onMeasureChange ? /* @__PURE__ */ (0, import_jsx_runtime99.jsxs)("div", { className: "flex items-center gap-1.5 text-xs", children: [
|
|
30103
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)("label", { className: "text-muted-foreground", htmlFor: "pipeline-measure", children: "Total" }),
|
|
30104
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)(
|
|
29933
30105
|
PickOne,
|
|
29934
30106
|
{
|
|
29935
30107
|
id: "pipeline-measure",
|
|
@@ -29940,10 +30112,10 @@ function PipelineBoard({
|
|
|
29940
30112
|
}
|
|
29941
30113
|
)
|
|
29942
30114
|
] }) : null,
|
|
29943
|
-
/* @__PURE__ */ (0,
|
|
30115
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)("div", { className: "flex min-h-0 gap-2 overflow-x-auto pb-2", "data-records-board": true, children: stages.map((stage) => {
|
|
29944
30116
|
const n = numbers.get(stage.key);
|
|
29945
30117
|
const cards = cardsByStage.get(stage.key) ?? [];
|
|
29946
|
-
return /* @__PURE__ */ (0,
|
|
30118
|
+
return /* @__PURE__ */ (0, import_jsx_runtime99.jsxs)(
|
|
29947
30119
|
"section",
|
|
29948
30120
|
{
|
|
29949
30121
|
onDragOver: (e) => {
|
|
@@ -29956,29 +30128,29 @@ function PipelineBoard({
|
|
|
29956
30128
|
const id = e.dataTransfer.getData("text/plain");
|
|
29957
30129
|
if (id) void drop(id, stage.key);
|
|
29958
30130
|
},
|
|
29959
|
-
className: (0,
|
|
30131
|
+
className: (0, import_design_system87.cn)(
|
|
29960
30132
|
"flex w-64 shrink-0 flex-col rounded border bg-muted/30",
|
|
29961
30133
|
over === stage.key ? "ring-2 ring-primary" : "",
|
|
29962
30134
|
n?.over_limit ? "border-destructive" : ""
|
|
29963
30135
|
),
|
|
29964
30136
|
children: [
|
|
29965
|
-
/* @__PURE__ */ (0,
|
|
29966
|
-
/* @__PURE__ */ (0,
|
|
29967
|
-
/* @__PURE__ */ (0,
|
|
30137
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsxs)("header", { className: "flex items-baseline gap-2 border-b px-2 py-1 text-xs font-medium", children: [
|
|
30138
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)("span", { className: "truncate", children: stage.label }),
|
|
30139
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsxs)("span", { className: "ml-auto shrink-0 tabular-nums text-muted-foreground", children: [
|
|
29968
30140
|
n ? n.cards : cards.length,
|
|
29969
30141
|
n?.wip_limit != null ? ` / ${n.wip_limit}` : "",
|
|
29970
30142
|
n?.total != null ? ` \xB7 ${formatTotal(n.total)}` : ""
|
|
29971
30143
|
] })
|
|
29972
30144
|
] }),
|
|
29973
|
-
n?.over_limit ? /* @__PURE__ */ (0,
|
|
30145
|
+
n?.over_limit ? /* @__PURE__ */ (0, import_jsx_runtime99.jsxs)("p", { className: "border-b px-2 py-1 text-xs text-destructive", children: [
|
|
29974
30146
|
"This column takes ",
|
|
29975
30147
|
n.wip_limit,
|
|
29976
30148
|
" at a time and holds ",
|
|
29977
30149
|
n.cards,
|
|
29978
30150
|
"."
|
|
29979
30151
|
] }) : null,
|
|
29980
|
-
/* @__PURE__ */ (0,
|
|
29981
|
-
/* @__PURE__ */ (0,
|
|
30152
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)("ul", { className: "flex flex-col gap-1 p-1", children: cards.map((card) => /* @__PURE__ */ (0, import_jsx_runtime99.jsxs)("li", { children: [
|
|
30153
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)(
|
|
29982
30154
|
RecordActionMenu,
|
|
29983
30155
|
{
|
|
29984
30156
|
tableId,
|
|
@@ -29989,7 +30161,7 @@ function PipelineBoard({
|
|
|
29989
30161
|
onChanged?.();
|
|
29990
30162
|
void reload();
|
|
29991
30163
|
},
|
|
29992
|
-
children: /* @__PURE__ */ (0,
|
|
30164
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime99.jsx)(
|
|
29993
30165
|
PipelineCard,
|
|
29994
30166
|
{
|
|
29995
30167
|
record: card,
|
|
@@ -30012,7 +30184,7 @@ function PipelineBoard({
|
|
|
30012
30184
|
)
|
|
30013
30185
|
}
|
|
30014
30186
|
),
|
|
30015
|
-
pending.kind !== "none" && pending.recordId === card.id ? /* @__PURE__ */ (0,
|
|
30187
|
+
pending.kind !== "none" && pending.recordId === card.id ? /* @__PURE__ */ (0, import_jsx_runtime99.jsx)(
|
|
30016
30188
|
Held,
|
|
30017
30189
|
{
|
|
30018
30190
|
pending,
|
|
@@ -30024,7 +30196,7 @@ function PipelineBoard({
|
|
|
30024
30196
|
) : batch.get(card.id) ? (
|
|
30025
30197
|
// WHAT THIS CARD'S PART OF THE BATCH CAME TO, on the card — the store's
|
|
30026
30198
|
// own sentence, and for a stage that asked for columns, the columns.
|
|
30027
|
-
/* @__PURE__ */ (0,
|
|
30199
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)(
|
|
30028
30200
|
Held,
|
|
30029
30201
|
{
|
|
30030
30202
|
pending: batch.get(card.id),
|
|
@@ -30050,13 +30222,23 @@ function PipelineBoard({
|
|
|
30050
30222
|
}
|
|
30051
30223
|
)
|
|
30052
30224
|
) : null
|
|
30053
|
-
] }, card.id)) })
|
|
30225
|
+
] }, card.id)) }),
|
|
30226
|
+
canAdd && stageKey ? /* @__PURE__ */ (0, import_jsx_runtime99.jsx)(
|
|
30227
|
+
"button",
|
|
30228
|
+
{
|
|
30229
|
+
type: "button",
|
|
30230
|
+
"data-board-add": stage.label,
|
|
30231
|
+
className: "mx-1 mb-1 self-start rounded px-1 py-0.5 text-xs text-muted-foreground hover:bg-muted hover:text-foreground",
|
|
30232
|
+
onClick: () => void addInStage(stage.key, stage.label),
|
|
30233
|
+
children: "+ New"
|
|
30234
|
+
}
|
|
30235
|
+
) : null
|
|
30054
30236
|
]
|
|
30055
30237
|
},
|
|
30056
30238
|
stage.key
|
|
30057
30239
|
);
|
|
30058
30240
|
}) }),
|
|
30059
|
-
unplaced.length > 0 ? /* @__PURE__ */ (0,
|
|
30241
|
+
unplaced.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime99.jsxs)("p", { className: "text-xs text-muted-foreground", "data-testid": "pipeline-unplaced", children: [
|
|
30060
30242
|
unplaced.length === 1 ? "One record is" : `${unplaced.length} records are`,
|
|
30061
30243
|
" not in any of these columns \u2014 ",
|
|
30062
30244
|
unplaced.slice(0, 3).map((r) => unplacedName(r, titleField, unplacedLabels)).join(", "),
|
|
@@ -30077,17 +30259,17 @@ function Held({
|
|
|
30077
30259
|
onFill,
|
|
30078
30260
|
onAsk
|
|
30079
30261
|
}) {
|
|
30080
|
-
const [draft, setDraft] = (0,
|
|
30262
|
+
const [draft, setDraft] = (0, import_react169.useState)({});
|
|
30081
30263
|
if (pending.kind === "asking") {
|
|
30082
|
-
return /* @__PURE__ */ (0,
|
|
30264
|
+
return /* @__PURE__ */ (0, import_jsx_runtime99.jsx)("p", { className: "px-2 py-1 text-xs text-muted-foreground", children: "Asking\u2026" });
|
|
30083
30265
|
}
|
|
30084
30266
|
if (pending.kind === "clash") {
|
|
30085
|
-
return /* @__PURE__ */ (0,
|
|
30267
|
+
return /* @__PURE__ */ (0, import_jsx_runtime99.jsx)(
|
|
30086
30268
|
RefusalNotice,
|
|
30087
30269
|
{
|
|
30088
30270
|
className: "mt-1",
|
|
30089
30271
|
error: pending.error,
|
|
30090
|
-
actions: /* @__PURE__ */ (0,
|
|
30272
|
+
actions: /* @__PURE__ */ (0, import_jsx_runtime99.jsx)("div", { className: "mt-1", children: /* @__PURE__ */ (0, import_jsx_runtime99.jsx)(import_design_system87.Button, { size: "sm", variant: "ghost", className: "h-6", onClick: onCancel, children: "Close" }) })
|
|
30091
30273
|
}
|
|
30092
30274
|
);
|
|
30093
30275
|
}
|
|
@@ -30095,7 +30277,7 @@ function Held({
|
|
|
30095
30277
|
return (
|
|
30096
30278
|
// THE STAGE GATE SAID NO: the one refusal surface, heading and remedy both,
|
|
30097
30279
|
// never its sentence alone in a red box (lane REFUSAL-SWEEP).
|
|
30098
|
-
/* @__PURE__ */ (0,
|
|
30280
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)(
|
|
30099
30281
|
RefusalNotice,
|
|
30100
30282
|
{
|
|
30101
30283
|
className: "mt-1",
|
|
@@ -30104,50 +30286,50 @@ function Held({
|
|
|
30104
30286
|
pending.verdict.why,
|
|
30105
30287
|
"The card stays where it was. Fill in what this stage asks for, then move it again."
|
|
30106
30288
|
),
|
|
30107
|
-
actions: /* @__PURE__ */ (0,
|
|
30289
|
+
actions: /* @__PURE__ */ (0, import_jsx_runtime99.jsx)(import_design_system87.Button, { size: "sm", variant: "ghost", className: "mt-1 h-6", onClick: onCancel, children: "Close" })
|
|
30108
30290
|
}
|
|
30109
30291
|
)
|
|
30110
30292
|
);
|
|
30111
30293
|
}
|
|
30112
30294
|
if (pending.kind === "approval") {
|
|
30113
|
-
return /* @__PURE__ */ (0,
|
|
30114
|
-
/* @__PURE__ */ (0,
|
|
30115
|
-
pending.verdict.what_happens ? /* @__PURE__ */ (0,
|
|
30116
|
-
/* @__PURE__ */ (0,
|
|
30117
|
-
/* @__PURE__ */ (0,
|
|
30118
|
-
/* @__PURE__ */ (0,
|
|
30295
|
+
return /* @__PURE__ */ (0, import_jsx_runtime99.jsxs)("div", { className: "mt-1 flex flex-col gap-1 rounded border p-2 text-xs", children: [
|
|
30296
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)("p", { children: pending.verdict.why }),
|
|
30297
|
+
pending.verdict.what_happens ? /* @__PURE__ */ (0, import_jsx_runtime99.jsx)("p", { className: "text-muted-foreground", children: pending.verdict.what_happens }) : null,
|
|
30298
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
30299
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)(import_design_system87.Button, { size: "sm", className: "h-6", onClick: onAsk, children: "Ask for approval" }),
|
|
30300
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)(import_design_system87.Button, { size: "sm", variant: "ghost", className: "h-6", onClick: onCancel, children: "Leave it where it was" })
|
|
30119
30301
|
] })
|
|
30120
30302
|
] });
|
|
30121
30303
|
}
|
|
30122
30304
|
if (pending.kind === "filed") {
|
|
30123
|
-
return /* @__PURE__ */ (0,
|
|
30124
|
-
/* @__PURE__ */ (0,
|
|
30125
|
-
(pending.result.approvers ?? []).length > 0 ? /* @__PURE__ */ (0,
|
|
30305
|
+
return /* @__PURE__ */ (0, import_jsx_runtime99.jsxs)("div", { className: "mt-1 rounded border p-2 text-xs", children: [
|
|
30306
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)("p", { children: pending.result.what_happens ?? "This is waiting for somebody who can approve it. It has not moved." }),
|
|
30307
|
+
(pending.result.approvers ?? []).length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime99.jsxs)("p", { className: "text-muted-foreground", children: [
|
|
30126
30308
|
"With",
|
|
30127
30309
|
" ",
|
|
30128
30310
|
(pending.result.approvers ?? []).map((a) => a.name ?? "somebody who can approve it").join(", "),
|
|
30129
30311
|
"."
|
|
30130
30312
|
] }) : null,
|
|
30131
|
-
/* @__PURE__ */ (0,
|
|
30313
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)(import_design_system87.Button, { size: "sm", variant: "ghost", className: "mt-1 h-6", onClick: onCancel, children: "Close" })
|
|
30132
30314
|
] });
|
|
30133
30315
|
}
|
|
30134
30316
|
if (pending.kind === "warned") {
|
|
30135
|
-
return /* @__PURE__ */ (0,
|
|
30136
|
-
pending.warnings.map((w) => /* @__PURE__ */ (0,
|
|
30137
|
-
/* @__PURE__ */ (0,
|
|
30138
|
-
/* @__PURE__ */ (0,
|
|
30317
|
+
return /* @__PURE__ */ (0, import_jsx_runtime99.jsxs)("div", { className: "mt-1 flex flex-col gap-1 rounded border border-amber-500/50 bg-amber-500/5 p-2 text-xs", children: [
|
|
30318
|
+
pending.warnings.map((w) => /* @__PURE__ */ (0, import_jsx_runtime99.jsxs)("div", { children: [
|
|
30319
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)("p", { children: w.why }),
|
|
30320
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)("p", { className: "text-muted-foreground", children: w.what_to_do })
|
|
30139
30321
|
] }, w.rule_id)),
|
|
30140
|
-
/* @__PURE__ */ (0,
|
|
30322
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)(import_design_system87.Button, { size: "sm", variant: "ghost", className: "h-6 self-start", onClick: onCancel, children: "Close" })
|
|
30141
30323
|
] });
|
|
30142
30324
|
}
|
|
30143
30325
|
if (pending.kind !== "needs") return null;
|
|
30144
30326
|
const missing = pending.verdict.missing ?? [];
|
|
30145
30327
|
const ready = missing.every((m) => (draft[m.key] ?? "").trim() !== "");
|
|
30146
|
-
return /* @__PURE__ */ (0,
|
|
30147
|
-
/* @__PURE__ */ (0,
|
|
30148
|
-
missing.map((m) => /* @__PURE__ */ (0,
|
|
30149
|
-
/* @__PURE__ */ (0,
|
|
30150
|
-
/* @__PURE__ */ (0,
|
|
30328
|
+
return /* @__PURE__ */ (0, import_jsx_runtime99.jsxs)("div", { className: "mt-1 flex flex-col gap-1 rounded border p-2 text-xs", children: [
|
|
30329
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)("p", { children: pending.verdict.why }),
|
|
30330
|
+
missing.map((m) => /* @__PURE__ */ (0, import_jsx_runtime99.jsxs)("label", { className: "flex flex-col gap-0.5", children: [
|
|
30331
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)("span", { className: "text-muted-foreground", children: m.label }),
|
|
30332
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)(
|
|
30151
30333
|
"input",
|
|
30152
30334
|
{
|
|
30153
30335
|
className: "h-7 rounded border bg-background px-1",
|
|
@@ -30156,21 +30338,21 @@ function Held({
|
|
|
30156
30338
|
}
|
|
30157
30339
|
)
|
|
30158
30340
|
] }, m.key)),
|
|
30159
|
-
/* @__PURE__ */ (0,
|
|
30160
|
-
ready ? /* @__PURE__ */ (0,
|
|
30161
|
-
|
|
30341
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
30342
|
+
ready ? /* @__PURE__ */ (0, import_jsx_runtime99.jsx)(
|
|
30343
|
+
import_design_system87.Button,
|
|
30162
30344
|
{
|
|
30163
30345
|
size: "sm",
|
|
30164
30346
|
className: "h-6",
|
|
30165
30347
|
onClick: () => onFill(Object.fromEntries(missing.map((m) => [m.key, draft[m.key]]))),
|
|
30166
30348
|
children: "Fill in and move"
|
|
30167
30349
|
}
|
|
30168
|
-
) : /* @__PURE__ */ (0,
|
|
30350
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime99.jsxs)("span", { className: "text-muted-foreground", children: [
|
|
30169
30351
|
"Fill ",
|
|
30170
30352
|
missing.length === 1 ? "it" : "them",
|
|
30171
30353
|
" in and the move goes through."
|
|
30172
30354
|
] }),
|
|
30173
|
-
/* @__PURE__ */ (0,
|
|
30355
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)(import_design_system87.Button, { size: "sm", variant: "ghost", className: "h-6", onClick: onCancel, children: "Leave it where it was" })
|
|
30174
30356
|
] }),
|
|
30175
30357
|
fields.length === 0 ? null : null
|
|
30176
30358
|
] });
|
|
@@ -30192,9 +30374,9 @@ function PipelineCard({
|
|
|
30192
30374
|
}) {
|
|
30193
30375
|
const labels = useRecordLabels(field2 ? [field2] : []);
|
|
30194
30376
|
const color = style ? (0, import_data_table14.resolveRowColor)(style, { id: record.id, data: record.document ?? {} }, colorFromTheValue) : null;
|
|
30195
|
-
const draggable = (0,
|
|
30377
|
+
const draggable = (0, import_react170.mayDrag)(record.level);
|
|
30196
30378
|
const { text: label, withheld } = cardWords(record, field2, labels);
|
|
30197
|
-
return /* @__PURE__ */ (0,
|
|
30379
|
+
return /* @__PURE__ */ (0, import_jsx_runtime99.jsxs)(
|
|
30198
30380
|
"button",
|
|
30199
30381
|
{
|
|
30200
30382
|
type: "button",
|
|
@@ -30204,7 +30386,7 @@ function PipelineCard({
|
|
|
30204
30386
|
"data-card-index": index,
|
|
30205
30387
|
"data-selected": selected ? "true" : void 0,
|
|
30206
30388
|
"aria-pressed": draggable ? selected : void 0,
|
|
30207
|
-
className: (0,
|
|
30389
|
+
className: (0, import_design_system87.cn)(
|
|
30208
30390
|
"w-full truncate rounded border bg-background py-1 pl-2 pr-7 text-left text-xs hover:bg-muted",
|
|
30209
30391
|
draggable ? "cursor-grab active:cursor-grabbing" : "",
|
|
30210
30392
|
dragging ? "opacity-50" : "",
|
|
@@ -30235,9 +30417,9 @@ function PipelineCard({
|
|
|
30235
30417
|
title: `${withheld ?? label}${draggable ? "" : " \u2014 you can look at this, but not move it."}`,
|
|
30236
30418
|
...withheld && field2 ? { "data-records-withheld": field2.key } : {},
|
|
30237
30419
|
children: [
|
|
30238
|
-
/* @__PURE__ */ (0,
|
|
30239
|
-
dates && dates.length > 0 ? /* @__PURE__ */ (0,
|
|
30240
|
-
waiting ? /* @__PURE__ */ (0,
|
|
30420
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)("span", { className: "block truncate", children: label }),
|
|
30421
|
+
dates && dates.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime99.jsx)(CardDates, { record, fields: dates }) : null,
|
|
30422
|
+
waiting ? /* @__PURE__ */ (0, import_jsx_runtime99.jsxs)(
|
|
30241
30423
|
"span",
|
|
30242
30424
|
{
|
|
30243
30425
|
className: "mt-0.5 block truncate text-[10px] font-medium text-amber-600 dark:text-amber-400",
|
|
@@ -30314,159 +30496,61 @@ function batchSentence(moved, waiting, notMoved, label) {
|
|
|
30314
30496
|
return said;
|
|
30315
30497
|
}
|
|
30316
30498
|
|
|
30317
|
-
// src/
|
|
30318
|
-
var
|
|
30319
|
-
|
|
30320
|
-
|
|
30321
|
-
var import_data_table16 = require("@ai-matrx/design-system/data-table");
|
|
30322
|
-
|
|
30323
|
-
// src/recordMoves.tsx
|
|
30324
|
-
var import_react169 = require("react");
|
|
30325
|
-
var import_react170 = require("@ai-matrx/records/react");
|
|
30326
|
-
var import_design_system87 = require("@ai-matrx/design-system");
|
|
30327
|
-
var import_jsx_runtime99 = require("react/jsx-runtime");
|
|
30328
|
-
async function moveRecordValue(client, recordId, patch, expectedVersion) {
|
|
30329
|
-
const written = await updateRecordAt(client, { record_id: recordId, patch, version: expectedVersion });
|
|
30330
|
-
return written.ok ? { ok: true, version: typeof written.data === "number" ? written.data : null } : { ok: false, error: written.error };
|
|
30499
|
+
// src/cardFields.tsx
|
|
30500
|
+
var import_jsx_runtime100 = require("react/jsx-runtime");
|
|
30501
|
+
function isEmptyOnCard(value) {
|
|
30502
|
+
return value === null || value === void 0 || value === "" || Array.isArray(value) && value.length === 0;
|
|
30331
30503
|
}
|
|
30332
|
-
function
|
|
30333
|
-
|
|
30334
|
-
|
|
30335
|
-
|
|
30504
|
+
function cardFieldsShown(fields, hiddenFields, exclude) {
|
|
30505
|
+
const hidden = new Set(hiddenFields ?? []);
|
|
30506
|
+
const out = new Set(exclude.filter((k) => Boolean(k)));
|
|
30507
|
+
return fields.filter((field2) => !hidden.has(field2.key) && !out.has(field2.key));
|
|
30508
|
+
}
|
|
30509
|
+
function CardFieldsPicker({
|
|
30510
|
+
fields,
|
|
30511
|
+
hiddenFields,
|
|
30512
|
+
summary,
|
|
30513
|
+
onChange,
|
|
30514
|
+
remembered,
|
|
30515
|
+
layout
|
|
30336
30516
|
}) {
|
|
30337
|
-
const
|
|
30338
|
-
|
|
30339
|
-
|
|
30340
|
-
|
|
30341
|
-
|
|
30342
|
-
|
|
30343
|
-
|
|
30344
|
-
|
|
30345
|
-
|
|
30346
|
-
|
|
30347
|
-
|
|
30348
|
-
|
|
30349
|
-
|
|
30350
|
-
|
|
30351
|
-
|
|
30352
|
-
|
|
30353
|
-
setRefused(null);
|
|
30354
|
-
setStale(null);
|
|
30355
|
-
const written = await moveRecordValue(client, recordId, patch, await versions.seen(recordId));
|
|
30356
|
-
if (!written.ok) {
|
|
30357
|
-
const changedElsewhere = isChangedElsewhere(written.error);
|
|
30358
|
-
const unread = isVersionUnread(written.error);
|
|
30359
|
-
setRefused({ recordId, error: written.error, changedElsewhere, unread });
|
|
30360
|
-
if (changedElsewhere || unread) {
|
|
30361
|
-
undo.dismiss();
|
|
30362
|
-
setStale({ id: recordId, unread });
|
|
30363
|
-
} else {
|
|
30364
|
-
undo.say(`Not moved. ${refusalSentence(written.error)}`, true);
|
|
30365
|
-
}
|
|
30366
|
-
if (changedElsewhere) {
|
|
30367
|
-
versions.refresh([recordId]);
|
|
30368
|
-
onMoved?.();
|
|
30517
|
+
const hidden = new Set(hiddenFields ?? []);
|
|
30518
|
+
return /* @__PURE__ */ (0, import_jsx_runtime100.jsxs)("details", { className: "text-xs text-muted-foreground", "data-records-card-fields": layout, children: [
|
|
30519
|
+
/* @__PURE__ */ (0, import_jsx_runtime100.jsx)("summary", { className: "cursor-pointer select-none", children: summary }),
|
|
30520
|
+
/* @__PURE__ */ (0, import_jsx_runtime100.jsx)("div", { className: "mt-1 flex flex-wrap gap-2", children: fields.map((field2) => /* @__PURE__ */ (0, import_jsx_runtime100.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
30521
|
+
/* @__PURE__ */ (0, import_jsx_runtime100.jsx)(
|
|
30522
|
+
"input",
|
|
30523
|
+
{
|
|
30524
|
+
type: "checkbox",
|
|
30525
|
+
checked: !hidden.has(field2.key),
|
|
30526
|
+
"data-records-card-field": field2.key,
|
|
30527
|
+
onChange: (event) => {
|
|
30528
|
+
const next = new Set(hidden);
|
|
30529
|
+
if (event.target.checked) next.delete(field2.key);
|
|
30530
|
+
else next.add(field2.key);
|
|
30531
|
+
onChange([...next]);
|
|
30532
|
+
}
|
|
30369
30533
|
}
|
|
30370
|
-
|
|
30371
|
-
|
|
30372
|
-
|
|
30373
|
-
|
|
30374
|
-
label,
|
|
30375
|
-
cells: Object.keys(patch).map((key) => ({
|
|
30376
|
-
rowId: recordId,
|
|
30377
|
-
key,
|
|
30378
|
-
before: before[key] ?? null,
|
|
30379
|
-
after: patch[key],
|
|
30380
|
-
...written.version !== null ? { version: written.version } : {}
|
|
30381
|
-
}))
|
|
30382
|
-
});
|
|
30383
|
-
onMoved?.();
|
|
30384
|
-
return true;
|
|
30385
|
-
},
|
|
30386
|
-
[client, undo, onMoved, versions]
|
|
30387
|
-
);
|
|
30388
|
-
const create = (0, import_react169.useCallback)(
|
|
30389
|
-
async ({ tableId: table, data, label }) => {
|
|
30390
|
-
setRefused(null);
|
|
30391
|
-
const written = await client.recordWrite({ table_id: table, data });
|
|
30392
|
-
if (!written.ok) {
|
|
30393
|
-
undo.say(`Nothing was added. ${refusalSentence(written.error)}`, true);
|
|
30394
|
-
return null;
|
|
30395
|
-
}
|
|
30396
|
-
undo.push({ label, cells: [], created: [written.data] });
|
|
30397
|
-
onMoved?.();
|
|
30398
|
-
return written.data;
|
|
30399
|
-
},
|
|
30400
|
-
[client, undo, onMoved]
|
|
30401
|
-
);
|
|
30402
|
-
const offering = Boolean(undo.notice);
|
|
30403
|
-
const undoRef = (0, import_react169.useRef)(undo);
|
|
30404
|
-
undoRef.current = undo;
|
|
30405
|
-
(0, import_react169.useEffect)(() => {
|
|
30406
|
-
if (!offering || typeof document === "undefined") return;
|
|
30407
|
-
const onKey = (event) => {
|
|
30408
|
-
const which = undoKey(event);
|
|
30409
|
-
if (!which) return;
|
|
30410
|
-
event.preventDefault();
|
|
30411
|
-
void (which === "undo" ? undoRef.current.undo() : undoRef.current.redo());
|
|
30412
|
-
};
|
|
30413
|
-
document.addEventListener("keydown", onKey);
|
|
30414
|
-
return () => document.removeEventListener("keydown", onKey);
|
|
30415
|
-
}, [offering]);
|
|
30416
|
-
const onKeyDown = (0, import_react169.useCallback)(
|
|
30417
|
-
(event) => {
|
|
30418
|
-
if (offering) return;
|
|
30419
|
-
const which = undoKey(event);
|
|
30420
|
-
if (!which) return;
|
|
30421
|
-
event.preventDefault();
|
|
30422
|
-
void (which === "undo" ? undo.undo() : undo.redo());
|
|
30423
|
-
},
|
|
30424
|
-
[undo, offering]
|
|
30425
|
-
);
|
|
30426
|
-
const reloadStale = (0, import_react169.useCallback)(async () => {
|
|
30427
|
-
const id = stale?.id ?? null;
|
|
30428
|
-
setStale(null);
|
|
30429
|
-
setRefused(null);
|
|
30430
|
-
if (!id) return;
|
|
30431
|
-
versions.refresh([id]);
|
|
30432
|
-
onMoved?.();
|
|
30433
|
-
}, [versions, stale, onMoved]);
|
|
30434
|
-
const notice = /* @__PURE__ */ (0, import_jsx_runtime99.jsxs)(import_jsx_runtime99.Fragment, { children: [
|
|
30435
|
-
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)(UndoNotice, { undo }),
|
|
30436
|
-
stale ? /* @__PURE__ */ (0, import_jsx_runtime99.jsxs)(
|
|
30437
|
-
"p",
|
|
30438
|
-
{
|
|
30439
|
-
role: "status",
|
|
30440
|
-
"data-records-undo-notice": "refused",
|
|
30441
|
-
"data-move-stale": stale.id,
|
|
30442
|
-
"data-move-unread": stale.unread ? "" : void 0,
|
|
30443
|
-
className: "pointer-events-auto absolute bottom-3 left-1/2 z-30 flex max-w-[min(36rem,calc(100%-2rem))] -translate-x-1/2 items-center gap-2 rounded-md border border-border bg-popover px-3 py-1.5 text-xs text-popover-foreground shadow-lg",
|
|
30444
|
-
children: [
|
|
30445
|
-
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)("span", { children: stale.unread ? VERSION_UNREAD_LABEL : STALE_MOVE_LABEL }),
|
|
30446
|
-
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)(import_design_system87.Button, { size: "sm", variant: "outline", className: "ml-auto h-6", "data-move-reload": "", onClick: () => void reloadStale(), children: "Reload" }),
|
|
30447
|
-
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)(import_design_system87.Button, { size: "sm", variant: "ghost", className: "h-6", onClick: () => setStale(null), children: "Dismiss" })
|
|
30448
|
-
]
|
|
30449
|
-
}
|
|
30450
|
-
) : null
|
|
30534
|
+
),
|
|
30535
|
+
fieldName(field2)
|
|
30536
|
+
] }, field2.key)) }),
|
|
30537
|
+
remembered ? null : /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("p", { className: "mt-1", children: "Kept for this visit only \u2014 this screen has nowhere to save it onto the view." })
|
|
30451
30538
|
] });
|
|
30452
|
-
return (0, import_react169.useMemo)(
|
|
30453
|
-
() => ({ move, create, refused, say: (says, sticky) => undo.say(says, sticky), undo, onKeyDown, notice }),
|
|
30454
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
30455
|
-
[move, create, refused, undo, onKeyDown, stale, reloadStale]
|
|
30456
|
-
);
|
|
30457
30539
|
}
|
|
30458
|
-
function
|
|
30459
|
-
|
|
30460
|
-
|
|
30461
|
-
|
|
30462
|
-
|
|
30463
|
-
|
|
30464
|
-
className: "mt-0.5 inline-block rounded bg-destructive/10 px-1 text-[10px] font-medium text-destructive",
|
|
30465
|
-
children: refused.changedElsewhere ? STALE_MOVE_LABEL : refused.unread ? VERSION_UNREAD_LABEL : "Not moved"
|
|
30466
|
-
}
|
|
30467
|
-
);
|
|
30540
|
+
function CardFieldsInline({ row, fields }) {
|
|
30541
|
+
if (!fields || fields.length === 0) return null;
|
|
30542
|
+
const doc = row.document ?? {};
|
|
30543
|
+
const parts = fields.filter((f) => !isEmptyOnCard(doc[f.key])).map((f) => scalarText(f, doc[f.key]));
|
|
30544
|
+
if (parts.length === 0) return null;
|
|
30545
|
+
return /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("span", { className: "min-w-0 shrink truncate opacity-75", "data-card-fields-inline": "", children: parts.map((p) => ` \xB7 ${p}`).join("") });
|
|
30468
30546
|
}
|
|
30469
30547
|
|
|
30548
|
+
// src/CalendarView.tsx
|
|
30549
|
+
var import_react172 = require("react");
|
|
30550
|
+
var import_react173 = require("@ai-matrx/records/react");
|
|
30551
|
+
var import_design_system88 = require("@ai-matrx/design-system");
|
|
30552
|
+
var import_data_table16 = require("@ai-matrx/design-system/data-table");
|
|
30553
|
+
|
|
30470
30554
|
// src/rowColorBy.tsx
|
|
30471
30555
|
var import_react171 = require("react");
|
|
30472
30556
|
var import_data_table15 = require("@ai-matrx/design-system/data-table");
|
|
@@ -30646,7 +30730,7 @@ function lookupTargets(all) {
|
|
|
30646
30730
|
}
|
|
30647
30731
|
|
|
30648
30732
|
// src/CalendarView.tsx
|
|
30649
|
-
var
|
|
30733
|
+
var import_jsx_runtime101 = require("react/jsx-runtime");
|
|
30650
30734
|
var DRAG_TYPE = "application/x-records-card";
|
|
30651
30735
|
var NONE = "__none__";
|
|
30652
30736
|
var HOUR_PX = 44;
|
|
@@ -30757,12 +30841,13 @@ function byTime(a, b) {
|
|
|
30757
30841
|
return Number(!allDayOn(a)) - Number(!allDayOn(b)) || (a.at && b.at && !allDayOn(a) && !allDayOn(b) ? a.at.getTime() - b.at.getTime() : 0) || a.firstDay.localeCompare(b.firstDay);
|
|
30758
30842
|
}
|
|
30759
30843
|
function LockIcon() {
|
|
30760
|
-
return /* @__PURE__ */ (0,
|
|
30761
|
-
/* @__PURE__ */ (0,
|
|
30762
|
-
/* @__PURE__ */ (0,
|
|
30844
|
+
return /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)("svg", { "aria-hidden": "true", viewBox: "0 0 16 16", className: "h-3 w-3 shrink-0 opacity-70", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: [
|
|
30845
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)("rect", { x: "3.5", y: "7", width: "9", height: "6.5", rx: "1" }),
|
|
30846
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)("path", { d: "M5.5 7V5a2.5 2.5 0 0 1 5 0v2" })
|
|
30763
30847
|
] });
|
|
30764
30848
|
}
|
|
30765
30849
|
function CalendarView({
|
|
30850
|
+
cardFields,
|
|
30766
30851
|
tableId,
|
|
30767
30852
|
rows,
|
|
30768
30853
|
dateField,
|
|
@@ -31066,7 +31151,7 @@ function CalendarView({
|
|
|
31066
31151
|
const lockWords = (0, import_react173.mayDrag)(row.level) ? WORKED_OUT_DATE_LOCK : "View only";
|
|
31067
31152
|
const color = colorOf(row);
|
|
31068
31153
|
const title = titleOf(row);
|
|
31069
|
-
return /* @__PURE__ */ (0,
|
|
31154
|
+
return /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)(
|
|
31070
31155
|
"button",
|
|
31071
31156
|
{
|
|
31072
31157
|
type: "button",
|
|
@@ -31082,19 +31167,20 @@ function CalendarView({
|
|
|
31082
31167
|
...color ? { "data-calendar-color": color } : {},
|
|
31083
31168
|
...may ? { "aria-keyshortcuts": "Alt+ArrowLeft Alt+ArrowRight Alt+ArrowUp Alt+ArrowDown" } : { "data-calendar-locked": "" },
|
|
31084
31169
|
children: [
|
|
31085
|
-
may ? null : /* @__PURE__ */ (0,
|
|
31170
|
+
may ? null : /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("span", { title: lockWords, "aria-label": lockWords, className: "inline-flex", ...(0, import_react173.mayDrag)(row.level) ? { "data-calendar-worked-out": "" } : {}, children: /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(LockIcon, {}) }),
|
|
31086
31171
|
extra,
|
|
31087
|
-
/* @__PURE__ */ (0,
|
|
31172
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)("span", { className: "min-w-0 truncate", children: title }),
|
|
31173
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)(CardFieldsInline, { row, fields: cardFields })
|
|
31088
31174
|
]
|
|
31089
31175
|
}
|
|
31090
31176
|
);
|
|
31091
31177
|
};
|
|
31092
|
-
const refusalOn = (row) => moves.refused?.recordId === row.id ? /* @__PURE__ */ (0,
|
|
31178
|
+
const refusalOn = (row) => moves.refused?.recordId === row.id ? /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(MoveRefusedBadge, { refused: moves.refused }) : null;
|
|
31093
31179
|
const timeOn = (row) => {
|
|
31094
31180
|
const words2 = timeOfDayWords(startOf(row));
|
|
31095
|
-
return words2 ? /* @__PURE__ */ (0,
|
|
31181
|
+
return words2 ? /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("span", { className: "shrink-0 tabular-nums text-[10px] opacity-75", "data-calendar-time": "", children: words2 }) : null;
|
|
31096
31182
|
};
|
|
31097
|
-
const listCard = (p, key) => /* @__PURE__ */ (0,
|
|
31183
|
+
const listCard = (p, key) => /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)("li", { ...dragSource(p.row), children: [
|
|
31098
31184
|
cardFace(p.row, timeOn(p.row)),
|
|
31099
31185
|
refusalOn(p.row)
|
|
31100
31186
|
] }, key);
|
|
@@ -31106,18 +31192,18 @@ function CalendarView({
|
|
|
31106
31192
|
else if (mode === "day") setAnchor(addDays2(anchor, dir));
|
|
31107
31193
|
else setAnchor(dayKey(new Date(anchorDate.getFullYear(), anchorDate.getMonth() + dir, 1)));
|
|
31108
31194
|
};
|
|
31109
|
-
const picker = (label, value, candidates, onPick, kept, unusual) => /* @__PURE__ */ (0,
|
|
31110
|
-
/* @__PURE__ */ (0,
|
|
31111
|
-
/* @__PURE__ */ (0,
|
|
31112
|
-
/* @__PURE__ */ (0,
|
|
31113
|
-
/* @__PURE__ */ (0,
|
|
31114
|
-
/* @__PURE__ */ (0,
|
|
31115
|
-
candidates.map((f) => /* @__PURE__ */ (0,
|
|
31116
|
-
unusual ? /* @__PURE__ */ (0,
|
|
31195
|
+
const picker = (label, value, candidates, onPick, kept, unusual) => /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)("div", { className: "flex items-center gap-1.5 whitespace-nowrap text-xs", "data-calendar-setting": label, children: [
|
|
31196
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)("span", { className: "text-muted-foreground", children: label }),
|
|
31197
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsxs)(import_design_system88.Select, { value: value ?? NONE, onValueChange: (v) => onPick(v === NONE ? null : v), children: [
|
|
31198
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_design_system88.SelectTrigger, { size: "sm", className: "h-7 min-w-24 text-xs", "aria-label": `${label} column`, ...kept ? {} : { title: "Kept for this visit only" }, children: /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_design_system88.SelectValue, { placeholder: "Choose" }) }),
|
|
31199
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsxs)(import_design_system88.SelectContent, { children: [
|
|
31200
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_design_system88.SelectItem, { value: NONE, children: "None" }),
|
|
31201
|
+
candidates.map((f) => /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_design_system88.SelectItem, { value: f.key, children: fieldName(f) }, f.key)),
|
|
31202
|
+
unusual ? /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_design_system88.SelectItem, { value: unusual.key, "data-calendar-unusual": "", children: `${fieldName(unusual)} \u2014 ${UNUSUAL_FIELD_NOTE}` }, unusual.key) : null
|
|
31117
31203
|
] })
|
|
31118
31204
|
] })
|
|
31119
31205
|
] });
|
|
31120
|
-
const pickers = all.length > 0 ? /* @__PURE__ */ (0,
|
|
31206
|
+
const pickers = all.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)(import_jsx_runtime101.Fragment, { children: [
|
|
31121
31207
|
otherDates.length > 0 || endUnusual ? picker("End", endField?.key ?? null, otherDates, (key) => {
|
|
31122
31208
|
setEndPick(key);
|
|
31123
31209
|
onEndFieldChange?.(key);
|
|
@@ -31127,35 +31213,35 @@ function CalendarView({
|
|
|
31127
31213
|
onColorFieldChange?.(key);
|
|
31128
31214
|
}, true) : null
|
|
31129
31215
|
] }) : null;
|
|
31130
|
-
const toolbar = /* @__PURE__ */ (0,
|
|
31131
|
-
/* @__PURE__ */ (0,
|
|
31132
|
-
mode !== "list" ? /* @__PURE__ */ (0,
|
|
31133
|
-
/* @__PURE__ */ (0,
|
|
31134
|
-
/* @__PURE__ */ (0,
|
|
31135
|
-
/* @__PURE__ */ (0,
|
|
31216
|
+
const toolbar = /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
31217
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_design_system88.Button, { size: "sm", variant: "outline", onClick: () => setAnchor(today), children: "Today" }),
|
|
31218
|
+
mode !== "list" ? /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)(import_jsx_runtime101.Fragment, { children: [
|
|
31219
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_design_system88.Button, { size: "sm", variant: "ghost", "aria-label": "Previous", onClick: () => step2(-1), children: "\u2039" }),
|
|
31220
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_design_system88.Button, { size: "sm", variant: "ghost", "aria-label": "Next", onClick: () => step2(1), children: "\u203A" }),
|
|
31221
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)("h3", { className: "text-sm font-medium", "data-calendar-heading": "", children: heading })
|
|
31136
31222
|
] }) : null,
|
|
31137
|
-
/* @__PURE__ */ (0,
|
|
31223
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsxs)("div", { className: "ml-auto flex flex-wrap items-center gap-2", children: [
|
|
31138
31224
|
pickers,
|
|
31139
|
-
/* @__PURE__ */ (0,
|
|
31225
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)("div", { className: "flex items-center gap-0.5", role: "group", "aria-label": "Calendar layout", children: ["month", "week", "day", "list"].map((m) => /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_design_system88.Button, { size: "sm", variant: m === mode ? "secondary" : "ghost", "aria-pressed": m === mode, onClick: () => setMode(m), children: m === "month" ? "Month" : m === "week" ? "Week" : m === "day" ? "Day" : "List" }, m)) })
|
|
31140
31226
|
] })
|
|
31141
31227
|
] });
|
|
31142
31228
|
const tray = undated.length > 0 ? (
|
|
31143
31229
|
// Nothing fails silently: a record with no date waits here and drags onto a day.
|
|
31144
|
-
/* @__PURE__ */ (0,
|
|
31145
|
-
/* @__PURE__ */ (0,
|
|
31230
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsxs)("aside", { className: "flex min-w-0 flex-col gap-1 sm:w-56 sm:shrink-0", "data-calendar-undated": "", children: [
|
|
31231
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsxs)("h4", { className: "text-xs font-medium", children: [
|
|
31146
31232
|
"Unscheduled \xB7 ",
|
|
31147
31233
|
undated.length
|
|
31148
31234
|
] }),
|
|
31149
|
-
/* @__PURE__ */ (0,
|
|
31235
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)("ul", { className: "flex flex-col gap-1 overflow-y-auto", children: undated.map((row) => listCard({ row }, `tray:${row.id}`)) })
|
|
31150
31236
|
] })
|
|
31151
31237
|
) : null;
|
|
31152
31238
|
let body;
|
|
31153
31239
|
if (mode === "month") {
|
|
31154
31240
|
const first = startOfWeek(dayKey(new Date(anchorDate.getFullYear(), anchorDate.getMonth(), 1)));
|
|
31155
31241
|
const weeks = Array.from({ length: 6 }, (_, w) => addDays2(first, w * 7));
|
|
31156
|
-
body = /* @__PURE__ */ (0,
|
|
31157
|
-
/* @__PURE__ */ (0,
|
|
31158
|
-
weeks.map((ws) => /* @__PURE__ */ (0,
|
|
31242
|
+
body = /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("div", { className: "min-w-0 flex-1 overflow-x-auto", children: /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)("div", { className: "min-w-[560px] border-l border-t", role: "grid", "aria-label": heading, "data-calendar-month": "", children: [
|
|
31243
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)("div", { className: "grid grid-cols-7", role: "row", children: Array.from({ length: 7 }, (_, i) => addDays2(first, i)).map((d) => /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("div", { role: "columnheader", className: "border-b border-r px-1 py-0.5 text-center text-xs text-muted-foreground", children: dayDate(d).toLocaleDateString(void 0, { weekday: "short" }) }, `h${d}`)) }),
|
|
31244
|
+
weeks.map((ws) => /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(
|
|
31159
31245
|
MonthWeek,
|
|
31160
31246
|
{
|
|
31161
31247
|
weekStart: ws,
|
|
@@ -31170,11 +31256,11 @@ function CalendarView({
|
|
|
31170
31256
|
canCreate: creates,
|
|
31171
31257
|
onCreate: (d) => void createAt(rescheduledValue(null, d, null, moments), null, calendarDayLabel(d)),
|
|
31172
31258
|
card: (p, key) => listCard(p, key),
|
|
31173
|
-
bar: (p, key) => /* @__PURE__ */ (0,
|
|
31259
|
+
bar: (p, key) => /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)("div", { ...dragSource(p.row), className: "relative h-full", children: [
|
|
31174
31260
|
cardFace(p.row, null, "h-full"),
|
|
31175
|
-
endField && canMove(p.row) ? /* @__PURE__ */ (0,
|
|
31176
|
-
/* @__PURE__ */ (0,
|
|
31177
|
-
/* @__PURE__ */ (0,
|
|
31261
|
+
endField && canMove(p.row) ? /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)(import_jsx_runtime101.Fragment, { children: [
|
|
31262
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)("span", { role: "separator", "aria-label": "Drag to change the start", "data-calendar-edge": "start", className: "absolute inset-y-0 left-0 w-1.5 cursor-ew-resize", onPointerDown: beginStretch(p.row, p, "start") }),
|
|
31263
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)("span", { role: "separator", "aria-label": "Drag to change the end", "data-calendar-edge": "end", className: "absolute inset-y-0 right-0 w-1.5 cursor-ew-resize", onPointerDown: beginStretch(p.row, p, "end") })
|
|
31178
31264
|
] }) : null
|
|
31179
31265
|
] }, key),
|
|
31180
31266
|
refusalOn
|
|
@@ -31194,14 +31280,14 @@ function CalendarView({
|
|
|
31194
31280
|
})
|
|
31195
31281
|
);
|
|
31196
31282
|
const columns = `3.5rem repeat(${days.length}, minmax(0, 1fr))`;
|
|
31197
|
-
body = /* @__PURE__ */ (0,
|
|
31198
|
-
/* @__PURE__ */ (0,
|
|
31199
|
-
/* @__PURE__ */ (0,
|
|
31200
|
-
days.map((d) => /* @__PURE__ */ (0,
|
|
31201
|
-
/* @__PURE__ */ (0,
|
|
31202
|
-
days.map((d) => /* @__PURE__ */ (0,
|
|
31283
|
+
body = /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("div", { className: "min-w-0 flex-1 overflow-x-auto", children: /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)("div", { className: (0, import_design_system88.cn)("border-l border-t", days.length > 1 ? "min-w-[640px]" : ""), "data-calendar-week": "", "data-calendar-days": days.length, children: [
|
|
31284
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsxs)("div", { className: "grid", style: { gridTemplateColumns: columns }, children: [
|
|
31285
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)("div", { className: "border-b border-r" }),
|
|
31286
|
+
days.map((d) => /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("div", { className: (0, import_design_system88.cn)("border-b border-r px-1 py-0.5 text-center text-xs", d === today ? "font-semibold text-primary" : "text-muted-foreground"), children: dayDate(d).toLocaleDateString(void 0, { weekday: "short", day: "numeric" }) }, `h${d}`)),
|
|
31287
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)("div", { className: "border-b border-r px-1 py-0.5 text-[10px] text-muted-foreground", children: "All day" }),
|
|
31288
|
+
days.map((d) => /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("div", { "data-calendar-day": d, className: (0, import_design_system88.cn)("min-h-8 border-b border-r p-0.5", ghost?.day === d && ghost.minute === null ? "bg-primary/10" : void 0), ...dayDrop(d), children: /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("ul", { className: "flex flex-col gap-0.5", children: allDay(d).map((p) => listCard(p, `${p.row.id}:${d}`)) }) }, `a${d}`))
|
|
31203
31289
|
] }),
|
|
31204
|
-
/* @__PURE__ */ (0,
|
|
31290
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)(
|
|
31205
31291
|
WeekHours,
|
|
31206
31292
|
{
|
|
31207
31293
|
days,
|
|
@@ -31209,8 +31295,8 @@ function CalendarView({
|
|
|
31209
31295
|
today,
|
|
31210
31296
|
timeDrop,
|
|
31211
31297
|
onSlotPointerDown: creates ? beginSelect : void 0,
|
|
31212
|
-
overlay: (d) => /* @__PURE__ */ (0,
|
|
31213
|
-
ghost && ghost.day === d && ghost.minute !== null ? /* @__PURE__ */ (0,
|
|
31298
|
+
overlay: (d) => /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)(import_jsx_runtime101.Fragment, { children: [
|
|
31299
|
+
ghost && ghost.day === d && ghost.minute !== null ? /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(
|
|
31214
31300
|
"div",
|
|
31215
31301
|
{
|
|
31216
31302
|
"aria-hidden": "true",
|
|
@@ -31220,7 +31306,7 @@ function CalendarView({
|
|
|
31220
31306
|
children: `${dayDate(d).toLocaleDateString(void 0, { weekday: "short" })} ${timeLabel(ghost.minute)}`
|
|
31221
31307
|
}
|
|
31222
31308
|
) : null,
|
|
31223
|
-
selecting && selecting.day === d ? /* @__PURE__ */ (0,
|
|
31309
|
+
selecting && selecting.day === d ? /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(
|
|
31224
31310
|
"div",
|
|
31225
31311
|
{
|
|
31226
31312
|
"aria-hidden": "true",
|
|
@@ -31233,7 +31319,7 @@ function CalendarView({
|
|
|
31233
31319
|
] }),
|
|
31234
31320
|
render: (d) => timed(d).map(({ p, start, end, col, cols }) => {
|
|
31235
31321
|
const tight = cols > 1 && end - start < 45;
|
|
31236
|
-
return /* @__PURE__ */ (0,
|
|
31322
|
+
return /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)(
|
|
31237
31323
|
"div",
|
|
31238
31324
|
{
|
|
31239
31325
|
...dragSource(p.row),
|
|
@@ -31243,11 +31329,11 @@ function CalendarView({
|
|
|
31243
31329
|
children: [
|
|
31244
31330
|
cardFace(
|
|
31245
31331
|
p.row,
|
|
31246
|
-
tight ? null : /* @__PURE__ */ (0,
|
|
31332
|
+
tight ? null : /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("span", { className: "shrink-0 tabular-nums text-[10px] opacity-75", "data-calendar-time": "", children: timeLabel(start) }),
|
|
31247
31333
|
// Taller blocks sharing the width stack the time over the name.
|
|
31248
31334
|
(0, import_design_system88.cn)("h-full items-start", !tight && end - start >= 45 && cols > 1 ? "flex-col gap-0" : void 0)
|
|
31249
31335
|
),
|
|
31250
|
-
endField && !endWorkedOut && canMove(p.row) ? /* @__PURE__ */ (0,
|
|
31336
|
+
endField && !endWorkedOut && canMove(p.row) ? /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(
|
|
31251
31337
|
"div",
|
|
31252
31338
|
{
|
|
31253
31339
|
role: "separator",
|
|
@@ -31259,7 +31345,7 @@ function CalendarView({
|
|
|
31259
31345
|
) : null,
|
|
31260
31346
|
moves.refused?.recordId === p.row.id ? (
|
|
31261
31347
|
// Above the block, never inside it where a neighbour covers it; the full sentence floats.
|
|
31262
|
-
/* @__PURE__ */ (0,
|
|
31348
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)("div", { className: "absolute left-0 top-full z-30", children: refusalOn(p.row) })
|
|
31263
31349
|
) : null
|
|
31264
31350
|
]
|
|
31265
31351
|
},
|
|
@@ -31273,12 +31359,12 @@ function CalendarView({
|
|
|
31273
31359
|
const byDay = /* @__PURE__ */ new Map();
|
|
31274
31360
|
for (const p of placed) for (let d = p.firstDay; d <= p.lastDay; d = addDays2(d, 1)) byDay.set(d, [...byDay.get(d) ?? [], p]);
|
|
31275
31361
|
const listed = [...byDay.entries()].sort((a, b) => a[0].localeCompare(b[0])).map(([d, cards]) => [d, [...cards].sort(byTime)]);
|
|
31276
|
-
body = /* @__PURE__ */ (0,
|
|
31277
|
-
/* @__PURE__ */ (0,
|
|
31278
|
-
/* @__PURE__ */ (0,
|
|
31362
|
+
body = /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("ol", { className: "flex min-h-0 min-w-0 flex-1 flex-col divide-y overflow-y-auto rounded border", "data-calendar-list": "", children: listed.map(([d, cards]) => /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)("li", { className: "flex gap-3 p-2", "data-calendar-day": d, ...dayDrop(d), children: [
|
|
31363
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)("span", { className: (0, import_design_system88.cn)("w-24 shrink-0 text-xs font-medium tabular-nums", d === today ? "text-primary" : ""), children: calendarDayLabel(d) }),
|
|
31364
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)("ul", { className: "flex min-w-0 flex-1 flex-col gap-1", children: cards.map((p) => listCard(p, `${p.row.id}:${d}`)) })
|
|
31279
31365
|
] }, d)) });
|
|
31280
31366
|
}
|
|
31281
|
-
return /* @__PURE__ */ (0,
|
|
31367
|
+
return /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)(
|
|
31282
31368
|
"div",
|
|
31283
31369
|
{
|
|
31284
31370
|
ref: frame,
|
|
@@ -31289,9 +31375,9 @@ function CalendarView({
|
|
|
31289
31375
|
if (!frame.current?.contains(e.relatedTarget)) setGhost(null);
|
|
31290
31376
|
},
|
|
31291
31377
|
children: [
|
|
31292
|
-
note ? /* @__PURE__ */ (0,
|
|
31378
|
+
note ? /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("p", { className: "text-xs text-muted-foreground", children: note }) : null,
|
|
31293
31379
|
toolbar,
|
|
31294
|
-
/* @__PURE__ */ (0,
|
|
31380
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsxs)("div", { className: "flex min-h-0 flex-col gap-3 sm:flex-row", children: [
|
|
31295
31381
|
body,
|
|
31296
31382
|
tray
|
|
31297
31383
|
] }),
|
|
@@ -31328,7 +31414,7 @@ function MonthWeek({
|
|
|
31328
31414
|
});
|
|
31329
31415
|
const lanesShown = Math.min(laneEnds.length, MONTH_ROWS - 1);
|
|
31330
31416
|
const singlesFit = MONTH_ROWS - lanesShown;
|
|
31331
|
-
return /* @__PURE__ */ (0,
|
|
31417
|
+
return /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)("div", { className: "relative grid grid-cols-7", role: "row", "data-calendar-week-row": weekStart, children: [
|
|
31332
31418
|
days.map((d) => {
|
|
31333
31419
|
const inMonth = dayDate(d).getMonth() === month;
|
|
31334
31420
|
const singles = placed.filter((p) => p.lastDay === p.firstDay && p.firstDay === d).sort(byTime);
|
|
@@ -31340,7 +31426,7 @@ function MonthWeek({
|
|
|
31340
31426
|
if (e.target.closest("button, [data-calendar-card], [role=dialog]")) return;
|
|
31341
31427
|
onCreate(d);
|
|
31342
31428
|
};
|
|
31343
|
-
return /* @__PURE__ */ (0,
|
|
31429
|
+
return /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)(
|
|
31344
31430
|
"div",
|
|
31345
31431
|
{
|
|
31346
31432
|
role: "gridcell",
|
|
@@ -31355,8 +31441,8 @@ function MonthWeek({
|
|
|
31355
31441
|
...dayDrop(d),
|
|
31356
31442
|
...canCreate ? { onClick: create } : {},
|
|
31357
31443
|
children: [
|
|
31358
|
-
/* @__PURE__ */ (0,
|
|
31359
|
-
canCreate ? /* @__PURE__ */ (0,
|
|
31444
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsxs)("div", { className: "flex items-center", children: [
|
|
31445
|
+
canCreate ? /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(
|
|
31360
31446
|
"button",
|
|
31361
31447
|
{
|
|
31362
31448
|
type: "button",
|
|
@@ -31367,7 +31453,7 @@ function MonthWeek({
|
|
|
31367
31453
|
children: "+"
|
|
31368
31454
|
}
|
|
31369
31455
|
) : null,
|
|
31370
|
-
/* @__PURE__ */ (0,
|
|
31456
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)(
|
|
31371
31457
|
"span",
|
|
31372
31458
|
{
|
|
31373
31459
|
className: (0, import_design_system88.cn)(
|
|
@@ -31378,14 +31464,14 @@ function MonthWeek({
|
|
|
31378
31464
|
}
|
|
31379
31465
|
)
|
|
31380
31466
|
] }),
|
|
31381
|
-
/* @__PURE__ */ (0,
|
|
31382
|
-
/* @__PURE__ */ (0,
|
|
31383
|
-
more > 0 ? /* @__PURE__ */ (0,
|
|
31467
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)("div", { style: { height: lanesShown * BAR_PX }, "aria-hidden": "true" }),
|
|
31468
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)("ul", { className: "flex flex-col gap-0.5", children: shown4.map((p) => card(p, `${p.row.id}:${d}`)) }),
|
|
31469
|
+
more > 0 ? /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)("button", { type: "button", className: "self-start px-1 text-xs text-muted-foreground hover:text-foreground", "data-calendar-more": d, onClick: () => onOpenDay(d), children: [
|
|
31384
31470
|
"+",
|
|
31385
31471
|
more,
|
|
31386
31472
|
" more"
|
|
31387
31473
|
] }) : null,
|
|
31388
|
-
openDay === d ? /* @__PURE__ */ (0,
|
|
31474
|
+
openDay === d ? /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)(
|
|
31389
31475
|
"div",
|
|
31390
31476
|
{
|
|
31391
31477
|
role: "dialog",
|
|
@@ -31396,11 +31482,11 @@ function MonthWeek({
|
|
|
31396
31482
|
if (e.key === "Escape") onOpenDay(null);
|
|
31397
31483
|
},
|
|
31398
31484
|
children: [
|
|
31399
|
-
/* @__PURE__ */ (0,
|
|
31400
|
-
/* @__PURE__ */ (0,
|
|
31401
|
-
/* @__PURE__ */ (0,
|
|
31485
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsxs)("div", { className: "flex items-center", children: [
|
|
31486
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)("span", { className: "text-xs font-medium", children: calendarDayLabel(d) }),
|
|
31487
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_design_system88.Button, { size: "sm", variant: "ghost", className: "ml-auto h-6", "aria-label": "Close", onClick: () => onOpenDay(null), children: "\xD7" })
|
|
31402
31488
|
] }),
|
|
31403
|
-
/* @__PURE__ */ (0,
|
|
31489
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)("ul", { className: "flex flex-col gap-0.5", children: everything.map((p) => card(p, `open:${p.row.id}:${d}`)) })
|
|
31404
31490
|
]
|
|
31405
31491
|
}
|
|
31406
31492
|
) : null
|
|
@@ -31412,7 +31498,7 @@ function MonthWeek({
|
|
|
31412
31498
|
bars.filter((b) => b.lane < lanesShown).map((b) => {
|
|
31413
31499
|
const col = daysBetween2(weekStart, b.from);
|
|
31414
31500
|
const span = daysBetween2(b.from, b.to) + 1;
|
|
31415
|
-
return /* @__PURE__ */ (0,
|
|
31501
|
+
return /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)(
|
|
31416
31502
|
"div",
|
|
31417
31503
|
{
|
|
31418
31504
|
"data-calendar-bar": `${b.from}..${b.to}`,
|
|
@@ -31448,9 +31534,9 @@ function WeekHours({
|
|
|
31448
31534
|
return () => clearInterval(timer);
|
|
31449
31535
|
}, []);
|
|
31450
31536
|
const hours = Array.from({ length: 24 }, (_, h) => h);
|
|
31451
|
-
return /* @__PURE__ */ (0,
|
|
31452
|
-
/* @__PURE__ */ (0,
|
|
31453
|
-
days.map((d) => /* @__PURE__ */ (0,
|
|
31537
|
+
return /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("div", { ref: frame, className: "max-h-[36rem] overflow-y-auto", children: /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)("div", { className: "grid", style: { gridTemplateColumns: columns }, children: [
|
|
31538
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)("div", { className: "border-r", children: hours.map((h) => /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("div", { className: "border-b px-1 text-right text-[10px] tabular-nums text-muted-foreground", style: { height: HOUR_PX }, children: h === 0 ? "" : new Date(2026, 0, 1, h).toLocaleTimeString(void 0, { hour: "numeric" }) }, h)) }),
|
|
31539
|
+
days.map((d) => /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)(
|
|
31454
31540
|
"div",
|
|
31455
31541
|
{
|
|
31456
31542
|
className: (0, import_design_system88.cn)("relative border-r", onSlotPointerDown ? "cursor-cell" : void 0),
|
|
@@ -31458,10 +31544,10 @@ function WeekHours({
|
|
|
31458
31544
|
...timeDrop(d),
|
|
31459
31545
|
...onSlotPointerDown ? { onPointerDown: onSlotPointerDown(d) } : {},
|
|
31460
31546
|
children: [
|
|
31461
|
-
hours.map((h) => /* @__PURE__ */ (0,
|
|
31547
|
+
hours.map((h) => /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("div", { "data-calendar-slot": `${d}T${pad3(h)}`, className: "border-b", style: { height: HOUR_PX } }, h)),
|
|
31462
31548
|
render(d),
|
|
31463
31549
|
overlay(d),
|
|
31464
|
-
d === today ? /* @__PURE__ */ (0,
|
|
31550
|
+
d === today ? /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(
|
|
31465
31551
|
"div",
|
|
31466
31552
|
{
|
|
31467
31553
|
"aria-hidden": "true",
|
|
@@ -31489,7 +31575,7 @@ var import_react174 = require("react");
|
|
|
31489
31575
|
var import_react175 = require("@ai-matrx/records/react");
|
|
31490
31576
|
var import_design_system89 = require("@ai-matrx/design-system");
|
|
31491
31577
|
var import_data_table17 = require("@ai-matrx/design-system/data-table");
|
|
31492
|
-
var
|
|
31578
|
+
var import_jsx_runtime102 = require("react/jsx-runtime");
|
|
31493
31579
|
var TIMELINE_ZOOMS = ["day", "week", "month", "quarter"];
|
|
31494
31580
|
var ZOOM_LABEL = { day: "Day", week: "Week", month: "Month", quarter: "Quarter" };
|
|
31495
31581
|
var PX_PER_DAY = { day: 96, week: 32, month: 10, quarter: 4 };
|
|
@@ -31576,12 +31662,13 @@ function scaleOf(start, days, zoom) {
|
|
|
31576
31662
|
};
|
|
31577
31663
|
}
|
|
31578
31664
|
function LockIcon2() {
|
|
31579
|
-
return /* @__PURE__ */ (0,
|
|
31580
|
-
/* @__PURE__ */ (0,
|
|
31581
|
-
/* @__PURE__ */ (0,
|
|
31665
|
+
return /* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("svg", { "aria-hidden": "true", viewBox: "0 0 16 16", className: "h-3 w-3 shrink-0 opacity-70", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: [
|
|
31666
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)("rect", { x: "3.5", y: "7", width: "9", height: "6.5", rx: "1" }),
|
|
31667
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)("path", { d: "M5.5 7V5a2.5 2.5 0 0 1 5 0v2" })
|
|
31582
31668
|
] });
|
|
31583
31669
|
}
|
|
31584
31670
|
function TimelineView({
|
|
31671
|
+
cardFields,
|
|
31585
31672
|
tableId,
|
|
31586
31673
|
rows,
|
|
31587
31674
|
fields,
|
|
@@ -31903,7 +31990,7 @@ function TimelineView({
|
|
|
31903
31990
|
const edges = may && Boolean(endField);
|
|
31904
31991
|
const outside = wordsOutside(p, span);
|
|
31905
31992
|
const inset = outside ? 0 : Math.min(Math.max(0, scrollX - left), Math.max(0, span - 48));
|
|
31906
|
-
return /* @__PURE__ */ (0,
|
|
31993
|
+
return /* @__PURE__ */ (0, import_jsx_runtime102.jsxs)(
|
|
31907
31994
|
"div",
|
|
31908
31995
|
{
|
|
31909
31996
|
role: "button",
|
|
@@ -31935,7 +32022,7 @@ function TimelineView({
|
|
|
31935
32022
|
onPointerDown: beginDrag(p, "move", { lane, top }),
|
|
31936
32023
|
onKeyDown: barKeys(p),
|
|
31937
32024
|
children: [
|
|
31938
|
-
edges && !p.marker ? /* @__PURE__ */ (0,
|
|
32025
|
+
edges && !p.marker ? /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
31939
32026
|
"span",
|
|
31940
32027
|
{
|
|
31941
32028
|
role: "separator",
|
|
@@ -31945,20 +32032,21 @@ function TimelineView({
|
|
|
31945
32032
|
onPointerDown: beginDrag(p, "start")
|
|
31946
32033
|
}
|
|
31947
32034
|
) : null,
|
|
31948
|
-
inset > 0 ? /* @__PURE__ */ (0,
|
|
31949
|
-
may ? null : /* @__PURE__ */ (0,
|
|
31950
|
-
p.marker ? /* @__PURE__ */ (0,
|
|
32035
|
+
inset > 0 ? /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("span", { "aria-hidden": "true", className: "shrink-0", style: { width: inset } }) : null,
|
|
32036
|
+
may ? null : /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(LockIcon2, {}),
|
|
32037
|
+
p.marker ? /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("span", { "aria-hidden": "true", className: "h-2 w-2 shrink-0 rotate-45 rounded-[1px] bg-current opacity-70" }) : null,
|
|
31951
32038
|
outside ? (
|
|
31952
32039
|
// Too short for its words: they sit just after the bar, the way Airtable labels a short bar.
|
|
31953
|
-
/* @__PURE__ */ (0,
|
|
31954
|
-
startTime ? /* @__PURE__ */ (0,
|
|
32040
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("span", { className: "pointer-events-none absolute left-full top-1/2 ml-1.5 -translate-y-1/2 whitespace-nowrap text-foreground", children: [
|
|
32041
|
+
startTime ? /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("span", { className: "mr-1 tabular-nums text-[10px] opacity-75", "data-timeline-time": "", children: startTime }) : null,
|
|
31955
32042
|
title
|
|
31956
32043
|
] })
|
|
31957
|
-
) : /* @__PURE__ */ (0,
|
|
31958
|
-
startTime ? /* @__PURE__ */ (0,
|
|
31959
|
-
/* @__PURE__ */ (0,
|
|
32044
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime102.jsxs)(import_jsx_runtime102.Fragment, { children: [
|
|
32045
|
+
startTime ? /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("span", { className: "shrink-0 tabular-nums text-[10px] opacity-75", "data-timeline-time": "", children: startTime }) : null,
|
|
32046
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)("span", { className: "min-w-0 truncate", children: title }),
|
|
32047
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)(CardFieldsInline, { row: p.row, fields: cardFields })
|
|
31960
32048
|
] }),
|
|
31961
|
-
edges && !endWorkedOut ? /* @__PURE__ */ (0,
|
|
32049
|
+
edges && !endWorkedOut ? /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
31962
32050
|
"span",
|
|
31963
32051
|
{
|
|
31964
32052
|
role: "separator",
|
|
@@ -31973,39 +32061,39 @@ function TimelineView({
|
|
|
31973
32061
|
`${lane}:${p.row.id}`
|
|
31974
32062
|
);
|
|
31975
32063
|
};
|
|
31976
|
-
const picker = (label, value, options, onPick, opts) => /* @__PURE__ */ (0,
|
|
31977
|
-
/* @__PURE__ */ (0,
|
|
31978
|
-
/* @__PURE__ */ (0,
|
|
31979
|
-
/* @__PURE__ */ (0,
|
|
31980
|
-
/* @__PURE__ */ (0,
|
|
31981
|
-
opts?.none !== false ? /* @__PURE__ */ (0,
|
|
31982
|
-
options.map((f) => /* @__PURE__ */ (0,
|
|
31983
|
-
value && !options.some((f) => f.key === value) && fields.some((f) => f.key === value) ? /* @__PURE__ */ (0,
|
|
32064
|
+
const picker = (label, value, options, onPick, opts) => /* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("div", { className: "flex items-center gap-1.5 whitespace-nowrap text-xs", "data-timeline-setting": label, children: [
|
|
32065
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)("span", { className: "text-muted-foreground", children: label }),
|
|
32066
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsxs)(import_design_system89.Select, { value: value ?? NONE2, onValueChange: (v) => onPick(v === NONE2 ? null : v), children: [
|
|
32067
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)(import_design_system89.SelectTrigger, { size: "sm", className: "h-7 min-w-24 text-xs", "aria-label": `${label} column`, ...opts?.kept === false ? { title: "Kept for this visit only" } : {}, children: /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(import_design_system89.SelectValue, { placeholder: "Choose" }) }),
|
|
32068
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsxs)(import_design_system89.SelectContent, { children: [
|
|
32069
|
+
opts?.none !== false ? /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(import_design_system89.SelectItem, { value: NONE2, children: "None" }) : null,
|
|
32070
|
+
options.map((f) => /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(import_design_system89.SelectItem, { value: f.key, children: fieldName(f) }, f.key)),
|
|
32071
|
+
value && !options.some((f) => f.key === value) && fields.some((f) => f.key === value) ? /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(import_design_system89.SelectItem, { value, "data-timeline-unusual": "", children: `${fieldName(fields.find((f) => f.key === value))} \u2014 ${UNUSUAL_FIELD_NOTE}` }, value) : null
|
|
31984
32072
|
] })
|
|
31985
32073
|
] })
|
|
31986
32074
|
] });
|
|
31987
|
-
const settings = /* @__PURE__ */ (0,
|
|
32075
|
+
const settings = /* @__PURE__ */ (0, import_jsx_runtime102.jsxs)(import_jsx_runtime102.Fragment, { children: [
|
|
31988
32076
|
dates.length > 1 || !startField || !dates.some((f) => f.key === startChosen) ? picker("Start", startChosen, dates, (key) => setting({ startKey: key }), { none: false }) : null,
|
|
31989
32077
|
endCandidates.length > 0 || endField && !endCandidates.includes(endField) ? picker("End", endChosen, endCandidates, (key) => setting({ endKey: key }), { kept: layoutKept }) : null,
|
|
31990
32078
|
groupCandidates.length > 0 ? picker("Group by", groupChosen, groupCandidates, (key) => setting({ groupKey: key })) : null,
|
|
31991
32079
|
choiceFields.length > 0 ? picker("Colour by", colorChosen, choiceFields, (key) => setting({ colorKey: key })) : null
|
|
31992
32080
|
] });
|
|
31993
32081
|
const heading = zoom === "quarter" ? `Q${Math.floor(dayAt(anchor).getMonth() / 3) + 1} ${dayAt(anchor).getFullYear()}` : dayAt(anchor).toLocaleDateString(void 0, { month: "long", year: "numeric" });
|
|
31994
|
-
const toolbar = /* @__PURE__ */ (0,
|
|
31995
|
-
/* @__PURE__ */ (0,
|
|
31996
|
-
/* @__PURE__ */ (0,
|
|
31997
|
-
/* @__PURE__ */ (0,
|
|
31998
|
-
/* @__PURE__ */ (0,
|
|
31999
|
-
layoutKept ? null : /* @__PURE__ */ (0,
|
|
32000
|
-
/* @__PURE__ */ (0,
|
|
32082
|
+
const toolbar = /* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
32083
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)(import_design_system89.Button, { size: "sm", variant: "outline", onClick: () => setAnchor(today), children: "Today" }),
|
|
32084
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)(import_design_system89.Button, { size: "sm", variant: "ghost", "aria-label": "Previous", onClick: () => setAnchor(addDays(anchor, -PAGE_DAYS[zoom])), children: "\u2039" }),
|
|
32085
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)(import_design_system89.Button, { size: "sm", variant: "ghost", "aria-label": "Next", onClick: () => setAnchor(addDays(anchor, PAGE_DAYS[zoom])), children: "\u203A" }),
|
|
32086
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)("h3", { className: "text-sm font-medium", "data-timeline-heading": "", children: heading }),
|
|
32087
|
+
layoutKept ? null : /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("span", { className: "text-xs text-muted-foreground", children: "Kept for this visit only" }),
|
|
32088
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("div", { className: "ml-auto flex flex-wrap items-center gap-2", children: [
|
|
32001
32089
|
settings,
|
|
32002
|
-
/* @__PURE__ */ (0,
|
|
32090
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)("div", { className: "flex items-center gap-0.5", role: "group", "aria-label": "Zoom", children: TIMELINE_ZOOMS.map((z) => /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(import_design_system89.Button, { size: "sm", variant: z === zoom ? "secondary" : "ghost", "aria-pressed": z === zoom, onClick: () => setZoom(z), children: ZOOM_LABEL[z] }, z)) })
|
|
32003
32091
|
] })
|
|
32004
32092
|
] });
|
|
32005
32093
|
if (!startField) {
|
|
32006
|
-
return /* @__PURE__ */ (0,
|
|
32007
|
-
/* @__PURE__ */ (0,
|
|
32008
|
-
dates.length > 0 ? /* @__PURE__ */ (0,
|
|
32094
|
+
return /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("div", { className: (0, import_design_system89.cn)("flex min-w-0 flex-col gap-2", className), "data-timeline-needs": "", children: /* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("div", { className: "flex flex-col gap-2 rounded border border-dashed p-4 text-xs text-muted-foreground", children: [
|
|
32095
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)("p", { children: dates.length > 0 ? VIEW_NEEDS.timeline?.pick : VIEW_NEEDS.timeline?.missing }),
|
|
32096
|
+
dates.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("div", { className: "flex flex-wrap gap-2", children: settings }) : null
|
|
32009
32097
|
] }) });
|
|
32010
32098
|
}
|
|
32011
32099
|
const todayX = today >= from && daysBetween(from, today) < days ? xOf(today) : null;
|
|
@@ -32027,15 +32115,15 @@ function TimelineView({
|
|
|
32027
32115
|
}) : [];
|
|
32028
32116
|
const tray = unscheduled.length > 0 ? (
|
|
32029
32117
|
// Nothing fails silently: a record with no Start waits here and drags onto the timeline.
|
|
32030
|
-
/* @__PURE__ */ (0,
|
|
32031
|
-
/* @__PURE__ */ (0,
|
|
32118
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("aside", { className: "flex min-w-0 flex-col gap-1 sm:w-56 sm:shrink-0", "data-timeline-unscheduled": "", children: [
|
|
32119
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("h4", { className: "text-xs font-medium", children: [
|
|
32032
32120
|
"Unscheduled \xB7 ",
|
|
32033
32121
|
unscheduled.length
|
|
32034
32122
|
] }),
|
|
32035
|
-
/* @__PURE__ */ (0,
|
|
32123
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)("ul", { className: "flex max-h-[28rem] flex-col gap-1 overflow-y-auto", children: unscheduled.map((row) => {
|
|
32036
32124
|
const may = canMove(row);
|
|
32037
32125
|
const color = colorOf(row);
|
|
32038
|
-
return /* @__PURE__ */ (0,
|
|
32126
|
+
return /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
32039
32127
|
"li",
|
|
32040
32128
|
{
|
|
32041
32129
|
"data-timeline-card": row.id,
|
|
@@ -32045,7 +32133,7 @@ function TimelineView({
|
|
|
32045
32133
|
e.dataTransfer.setData(DRAG_TYPE2, JSON.stringify({ id: row.id }));
|
|
32046
32134
|
e.dataTransfer.effectAllowed = "move";
|
|
32047
32135
|
},
|
|
32048
|
-
children: /* @__PURE__ */ (0,
|
|
32136
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime102.jsxs)(
|
|
32049
32137
|
"button",
|
|
32050
32138
|
{
|
|
32051
32139
|
type: "button",
|
|
@@ -32057,8 +32145,8 @@ function TimelineView({
|
|
|
32057
32145
|
title: may ? `${titleOf(row)} \xB7 drag onto a day` : (0, import_react175.mayDrag)(row.level) ? WORKED_OUT_DATE_LOCK : whatYouMayDo(row.level ?? null).why("write"),
|
|
32058
32146
|
onClick: () => onOpenRecord?.(row.id),
|
|
32059
32147
|
children: [
|
|
32060
|
-
may ? null : /* @__PURE__ */ (0,
|
|
32061
|
-
/* @__PURE__ */ (0,
|
|
32148
|
+
may ? null : /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(LockIcon2, {}),
|
|
32149
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)("span", { className: "min-w-0 truncate", children: titleOf(row) })
|
|
32062
32150
|
]
|
|
32063
32151
|
}
|
|
32064
32152
|
)
|
|
@@ -32069,7 +32157,7 @@ function TimelineView({
|
|
|
32069
32157
|
] })
|
|
32070
32158
|
) : null;
|
|
32071
32159
|
const LABEL_COLUMN = "sticky left-0 z-30 w-24 shrink-0 border-r bg-background sm:w-36";
|
|
32072
|
-
const todayLine = todayX !== null ? /* @__PURE__ */ (0,
|
|
32160
|
+
const todayLine = todayX !== null ? /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
32073
32161
|
"div",
|
|
32074
32162
|
{
|
|
32075
32163
|
"aria-hidden": "true",
|
|
@@ -32078,14 +32166,14 @@ function TimelineView({
|
|
|
32078
32166
|
style: { left: todayX + px / 2 - 1 }
|
|
32079
32167
|
}
|
|
32080
32168
|
) : null;
|
|
32081
|
-
const headerRow = (segments, className2, key) => /* @__PURE__ */ (0,
|
|
32082
|
-
grouped ? /* @__PURE__ */ (0,
|
|
32083
|
-
/* @__PURE__ */ (0,
|
|
32169
|
+
const headerRow = (segments, className2, key) => /* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("div", { className: "flex", "data-timeline-scale": key, children: [
|
|
32170
|
+
grouped ? /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("div", { className: (0, import_design_system89.cn)(LABEL_COLUMN, "border-b") }) : null,
|
|
32171
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("div", { className: "relative shrink-0", style: { width, height: 22 }, children: [
|
|
32084
32172
|
segments.map((s) => {
|
|
32085
32173
|
const left = xOf(s.day);
|
|
32086
32174
|
const w = s.days * px;
|
|
32087
32175
|
const inset = key === "top" ? Math.min(Math.max(0, scrollX - left), Math.max(0, w - 90)) : 0;
|
|
32088
|
-
return /* @__PURE__ */ (0,
|
|
32176
|
+
return /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
32089
32177
|
"div",
|
|
32090
32178
|
{
|
|
32091
32179
|
className: (0, import_design_system89.cn)("absolute top-0 h-full truncate border-b border-l px-1 text-[11px] leading-[22px]", className2, s.day === today && key === "bottom" ? "font-semibold text-primary" : void 0),
|
|
@@ -32098,14 +32186,14 @@ function TimelineView({
|
|
|
32098
32186
|
key === "bottom" ? todayLine : null
|
|
32099
32187
|
] })
|
|
32100
32188
|
] });
|
|
32101
|
-
const body = /* @__PURE__ */ (0,
|
|
32102
|
-
/* @__PURE__ */ (0,
|
|
32189
|
+
const body = /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("div", { ref: scroller, onScroll, className: "min-w-0 flex-1 overflow-x-auto overflow-y-auto rounded border", "data-timeline-scroll": "", style: { maxHeight: "36rem" }, children: /* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("div", { className: "relative w-max", "data-timeline-zoom": zoom, "data-timeline-from": from, children: [
|
|
32190
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("div", { className: "sticky top-0 z-30 bg-background", children: [
|
|
32103
32191
|
headerRow(scale.top, "font-medium", "top"),
|
|
32104
32192
|
headerRow(scale.bottom, "text-muted-foreground", "bottom")
|
|
32105
32193
|
] }),
|
|
32106
|
-
laneRows.map((lane) => /* @__PURE__ */ (0,
|
|
32107
|
-
grouped ? /* @__PURE__ */ (0,
|
|
32108
|
-
/* @__PURE__ */ (0,
|
|
32194
|
+
laneRows.map((lane) => /* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("div", { className: "flex border-b", "data-timeline-lane": groupField ? lane.key : "", children: [
|
|
32195
|
+
grouped ? /* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("div", { className: (0, import_design_system89.cn)(LABEL_COLUMN, "flex items-start p-1"), "data-timeline-label": "", children: [
|
|
32196
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
32109
32197
|
"span",
|
|
32110
32198
|
{
|
|
32111
32199
|
className: (0, import_design_system89.cn)("max-w-full truncate rounded px-1.5 py-0.5 text-xs font-medium", lane.color ? import_data_table17.CHOICE_CHIP_CLASS[lane.color] : void 0),
|
|
@@ -32114,19 +32202,19 @@ function TimelineView({
|
|
|
32114
32202
|
children: lane.label
|
|
32115
32203
|
}
|
|
32116
32204
|
),
|
|
32117
|
-
/* @__PURE__ */ (0,
|
|
32205
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)("span", { className: "ml-auto px-1 text-xs text-muted-foreground", children: lane.bars.length })
|
|
32118
32206
|
] }) : null,
|
|
32119
|
-
/* @__PURE__ */ (0,
|
|
32120
|
-
weekendBands.map((d) => /* @__PURE__ */ (0,
|
|
32207
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("div", { className: "relative shrink-0", style: { width, height: Math.max(lane.height, ROW_PX + LANE_PAD) }, "data-timeline-canvas": lane.key, ...laneDrop, children: [
|
|
32208
|
+
weekendBands.map((d) => /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("div", { "aria-hidden": "true", className: "absolute inset-y-0 bg-muted/40", style: { left: xOf(d), width: px } }, `we:${d}`)),
|
|
32121
32209
|
lane.packed.map((b) => bar(b.p, LANE_PAD / 2 + b.row * ROW_PX + (ROW_PX - BAR_PX2) / 2, lane.key)),
|
|
32122
32210
|
todayLine
|
|
32123
32211
|
] })
|
|
32124
32212
|
] }, lane.key))
|
|
32125
32213
|
] }) });
|
|
32126
|
-
return /* @__PURE__ */ (0,
|
|
32127
|
-
note ? /* @__PURE__ */ (0,
|
|
32214
|
+
return /* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("div", { className: (0, import_design_system89.cn)("relative flex min-h-0 min-w-0 max-w-full flex-col gap-2", className), "data-timeline": "", onKeyDown: moves.onKeyDown, children: [
|
|
32215
|
+
note ? /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("p", { className: "text-xs text-muted-foreground", children: note }) : null,
|
|
32128
32216
|
toolbar,
|
|
32129
|
-
/* @__PURE__ */ (0,
|
|
32217
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("div", { className: "flex min-h-0 min-w-0 flex-col gap-3 sm:flex-row", children: [
|
|
32130
32218
|
body,
|
|
32131
32219
|
tray
|
|
32132
32220
|
] }),
|
|
@@ -32138,7 +32226,7 @@ function TimelineView({
|
|
|
32138
32226
|
var import_react176 = require("react");
|
|
32139
32227
|
var import_react177 = require("@ai-matrx/records/react");
|
|
32140
32228
|
var import_design_system90 = require("@ai-matrx/design-system");
|
|
32141
|
-
var
|
|
32229
|
+
var import_jsx_runtime103 = require("react/jsx-runtime");
|
|
32142
32230
|
function viewNeedFor(layout) {
|
|
32143
32231
|
return VIEW_NEEDS[layout];
|
|
32144
32232
|
}
|
|
@@ -32199,10 +32287,10 @@ function ViewNeeds({ layout, tableId, fields, onMade, className }) {
|
|
|
32199
32287
|
setPendingId(null);
|
|
32200
32288
|
onMade(field2.key);
|
|
32201
32289
|
};
|
|
32202
|
-
const editor = /* @__PURE__ */ (0,
|
|
32203
|
-
/* @__PURE__ */ (0,
|
|
32204
|
-
/* @__PURE__ */ (0,
|
|
32205
|
-
/* @__PURE__ */ (0,
|
|
32290
|
+
const editor = /* @__PURE__ */ (0, import_jsx_runtime103.jsxs)("div", { className: "flex flex-col gap-2 text-xs", children: [
|
|
32291
|
+
/* @__PURE__ */ (0, import_jsx_runtime103.jsxs)("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
32292
|
+
/* @__PURE__ */ (0, import_jsx_runtime103.jsx)(import_design_system90.Label, { className: "text-xs text-muted-foreground", htmlFor: `view-needs-name-${layout}`, children: "Column name" }),
|
|
32293
|
+
/* @__PURE__ */ (0, import_jsx_runtime103.jsx)(
|
|
32206
32294
|
import_design_system90.BasicInput,
|
|
32207
32295
|
{
|
|
32208
32296
|
id: `view-needs-name-${layout}`,
|
|
@@ -32212,10 +32300,10 @@ function ViewNeeds({ layout, tableId, fields, onMade, className }) {
|
|
|
32212
32300
|
}
|
|
32213
32301
|
)
|
|
32214
32302
|
] }),
|
|
32215
|
-
need.starter.type === "select" ? /* @__PURE__ */ (0,
|
|
32216
|
-
/* @__PURE__ */ (0,
|
|
32217
|
-
options.map((option, index) => /* @__PURE__ */ (0,
|
|
32218
|
-
/* @__PURE__ */ (0,
|
|
32303
|
+
need.starter.type === "select" ? /* @__PURE__ */ (0, import_jsx_runtime103.jsxs)("div", { className: "flex flex-wrap items-center gap-1.5", role: "group", "aria-label": "Choices", children: [
|
|
32304
|
+
/* @__PURE__ */ (0, import_jsx_runtime103.jsx)("span", { className: "text-muted-foreground", children: "Choices" }),
|
|
32305
|
+
options.map((option, index) => /* @__PURE__ */ (0, import_jsx_runtime103.jsxs)("span", { className: "flex items-center gap-0.5", children: [
|
|
32306
|
+
/* @__PURE__ */ (0, import_jsx_runtime103.jsx)(
|
|
32219
32307
|
import_design_system90.BasicInput,
|
|
32220
32308
|
{
|
|
32221
32309
|
"aria-label": `Choice ${index + 1}`,
|
|
@@ -32224,7 +32312,7 @@ function ViewNeeds({ layout, tableId, fields, onMade, className }) {
|
|
|
32224
32312
|
onChange: (e) => setOptions((held) => held.map((o, i) => i === index ? e.target.value : o))
|
|
32225
32313
|
}
|
|
32226
32314
|
),
|
|
32227
|
-
/* @__PURE__ */ (0,
|
|
32315
|
+
/* @__PURE__ */ (0, import_jsx_runtime103.jsx)(
|
|
32228
32316
|
import_design_system90.Button,
|
|
32229
32317
|
{
|
|
32230
32318
|
type: "button",
|
|
@@ -32236,11 +32324,11 @@ function ViewNeeds({ layout, tableId, fields, onMade, className }) {
|
|
|
32236
32324
|
}
|
|
32237
32325
|
)
|
|
32238
32326
|
] }, index)),
|
|
32239
|
-
/* @__PURE__ */ (0,
|
|
32327
|
+
/* @__PURE__ */ (0, import_jsx_runtime103.jsx)(import_design_system90.Button, { type: "button", size: "sm", variant: "ghost", onClick: () => setOptions((held) => [...held, ""]), children: "Add a choice" })
|
|
32240
32328
|
] }) : null
|
|
32241
32329
|
] });
|
|
32242
|
-
return /* @__PURE__ */ (0,
|
|
32243
|
-
/* @__PURE__ */ (0,
|
|
32330
|
+
return /* @__PURE__ */ (0, import_jsx_runtime103.jsxs)("div", { className, children: [
|
|
32331
|
+
/* @__PURE__ */ (0, import_jsx_runtime103.jsx)(
|
|
32244
32332
|
BuildOrAsk,
|
|
32245
32333
|
{
|
|
32246
32334
|
mayBuild: rights.structure,
|
|
@@ -32261,16 +32349,16 @@ function ViewNeeds({ layout, tableId, fields, onMade, className }) {
|
|
|
32261
32349
|
children: rights.structure ? `${need.missing} ${need.does(name)}` : need.missing
|
|
32262
32350
|
}
|
|
32263
32351
|
),
|
|
32264
|
-
mutation.error ? /* @__PURE__ */ (0,
|
|
32265
|
-
refused ? /* @__PURE__ */ (0,
|
|
32266
|
-
pendingId ? /* @__PURE__ */ (0,
|
|
32352
|
+
mutation.error ? /* @__PURE__ */ (0, import_jsx_runtime103.jsx)(RefusalNotice, { error: mutation.error }) : null,
|
|
32353
|
+
refused ? /* @__PURE__ */ (0, import_jsx_runtime103.jsx)(RefusalNotice, { error: refused }) : null,
|
|
32354
|
+
pendingId ? /* @__PURE__ */ (0, import_jsx_runtime103.jsx)("p", { className: "mt-2 text-xs text-muted-foreground", children: "The store accepted the column and the table does not show it yet. Press Make it work again to look for it \u2014 it will not be added twice." }) : null
|
|
32267
32355
|
] });
|
|
32268
32356
|
}
|
|
32269
32357
|
|
|
32270
32358
|
// src/GalleryCover.tsx
|
|
32271
32359
|
var import_react178 = require("react");
|
|
32272
32360
|
var import_react179 = require("@ai-matrx/records/react");
|
|
32273
|
-
var
|
|
32361
|
+
var import_jsx_runtime104 = require("react/jsx-runtime");
|
|
32274
32362
|
function isImageAddress(value) {
|
|
32275
32363
|
return typeof value === "string" && /^(https?:\/\/|\/|data:image\/)/i.test(value.trim());
|
|
32276
32364
|
}
|
|
@@ -32279,10 +32367,10 @@ function GalleryCover({ field: field2, value }) {
|
|
|
32279
32367
|
const isFile = field2 ? editorKindFor(field2) === "attachment" : false;
|
|
32280
32368
|
if (isFile) {
|
|
32281
32369
|
const first = attachmentIdsOf(value)[0];
|
|
32282
|
-
return first ? /* @__PURE__ */ (0,
|
|
32370
|
+
return first ? /* @__PURE__ */ (0, import_jsx_runtime104.jsx)(FileCover, { recordId: first }) : null;
|
|
32283
32371
|
}
|
|
32284
32372
|
if (isImageAddress(value)) {
|
|
32285
|
-
return /* @__PURE__ */ (0,
|
|
32373
|
+
return /* @__PURE__ */ (0, import_jsx_runtime104.jsx)("img", { src: value, alt: "", loading: "lazy", className: "h-full w-full object-cover" });
|
|
32286
32374
|
}
|
|
32287
32375
|
return null;
|
|
32288
32376
|
}
|
|
@@ -32314,51 +32402,9 @@ function FileCover({ recordId }) {
|
|
|
32314
32402
|
}, [client, recordId]);
|
|
32315
32403
|
if (!read || !read.fileId) return null;
|
|
32316
32404
|
if (!host.fileImage) {
|
|
32317
|
-
return /* @__PURE__ */ (0,
|
|
32405
|
+
return /* @__PURE__ */ (0, import_jsx_runtime104.jsx)("span", { className: "flex h-full w-full items-center justify-center p-1 text-center text-[10px] text-muted-foreground", children: COVER_NOT_DRAWN });
|
|
32318
32406
|
}
|
|
32319
|
-
return /* @__PURE__ */ (0,
|
|
32320
|
-
}
|
|
32321
|
-
|
|
32322
|
-
// src/cardFields.tsx
|
|
32323
|
-
var import_jsx_runtime104 = require("react/jsx-runtime");
|
|
32324
|
-
function isEmptyOnCard(value) {
|
|
32325
|
-
return value === null || value === void 0 || value === "" || Array.isArray(value) && value.length === 0;
|
|
32326
|
-
}
|
|
32327
|
-
function cardFieldsShown(fields, hiddenFields, exclude) {
|
|
32328
|
-
const hidden = new Set(hiddenFields ?? []);
|
|
32329
|
-
const out = new Set(exclude.filter((k) => Boolean(k)));
|
|
32330
|
-
return fields.filter((field2) => !hidden.has(field2.key) && !out.has(field2.key));
|
|
32331
|
-
}
|
|
32332
|
-
function CardFieldsPicker({
|
|
32333
|
-
fields,
|
|
32334
|
-
hiddenFields,
|
|
32335
|
-
summary,
|
|
32336
|
-
onChange,
|
|
32337
|
-
remembered,
|
|
32338
|
-
layout
|
|
32339
|
-
}) {
|
|
32340
|
-
const hidden = new Set(hiddenFields ?? []);
|
|
32341
|
-
return /* @__PURE__ */ (0, import_jsx_runtime104.jsxs)("details", { className: "text-xs text-muted-foreground", "data-records-card-fields": layout, children: [
|
|
32342
|
-
/* @__PURE__ */ (0, import_jsx_runtime104.jsx)("summary", { className: "cursor-pointer select-none", children: summary }),
|
|
32343
|
-
/* @__PURE__ */ (0, import_jsx_runtime104.jsx)("div", { className: "mt-1 flex flex-wrap gap-2", children: fields.map((field2) => /* @__PURE__ */ (0, import_jsx_runtime104.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
32344
|
-
/* @__PURE__ */ (0, import_jsx_runtime104.jsx)(
|
|
32345
|
-
"input",
|
|
32346
|
-
{
|
|
32347
|
-
type: "checkbox",
|
|
32348
|
-
checked: !hidden.has(field2.key),
|
|
32349
|
-
"data-records-card-field": field2.key,
|
|
32350
|
-
onChange: (event) => {
|
|
32351
|
-
const next = new Set(hidden);
|
|
32352
|
-
if (event.target.checked) next.delete(field2.key);
|
|
32353
|
-
else next.add(field2.key);
|
|
32354
|
-
onChange([...next]);
|
|
32355
|
-
}
|
|
32356
|
-
}
|
|
32357
|
-
),
|
|
32358
|
-
fieldName(field2)
|
|
32359
|
-
] }, field2.key)) }),
|
|
32360
|
-
remembered ? null : /* @__PURE__ */ (0, import_jsx_runtime104.jsx)("p", { className: "mt-1", children: "Kept for this visit only \u2014 this screen has nowhere to save it onto the view." })
|
|
32361
|
-
] });
|
|
32407
|
+
return /* @__PURE__ */ (0, import_jsx_runtime104.jsx)(import_jsx_runtime104.Fragment, { children: host.fileImage({ fileId: read.fileId, alt: read.name }) });
|
|
32362
32408
|
}
|
|
32363
32409
|
|
|
32364
32410
|
// src/ListView.tsx
|
|
@@ -32507,17 +32553,22 @@ function ListRow({
|
|
|
32507
32553
|
const filled = fields.filter((field2) => !isEmptyOnCard(doc[field2.key]) || withheldNoticeOf(row.hidden, field2.key));
|
|
32508
32554
|
const onRow = chose ? filled : filled.slice(0, LIST_DEFAULT_FIELDS);
|
|
32509
32555
|
const color = style ? (0, import_data_table18.resolveRowColor)(style, { id: row.id, data: row.document ?? {} }, colorFromTheValue) : null;
|
|
32510
|
-
const values = onRow.map((field2) =>
|
|
32511
|
-
|
|
32512
|
-
|
|
32513
|
-
|
|
32514
|
-
|
|
32515
|
-
|
|
32516
|
-
|
|
32517
|
-
|
|
32518
|
-
|
|
32519
|
-
|
|
32520
|
-
|
|
32556
|
+
const values = onRow.map((field2) => (
|
|
32557
|
+
// ONE LINE PER VALUE (walk 2026-10-05): a multi-line caption drew as paragraphs, pushing the
|
|
32558
|
+
// title to the row's foot. A list row is one line, as Notion's is; the record page has the rest.
|
|
32559
|
+
/* @__PURE__ */ (0, import_jsx_runtime105.jsx)("span", { className: "flex h-5 min-w-0 max-w-[14rem] items-center gap-1 overflow-hidden whitespace-nowrap", "data-records-list-value": field2.key, title: fieldName(field2), children: /* @__PURE__ */ (0, import_jsx_runtime105.jsx)(
|
|
32560
|
+
RecordValue,
|
|
32561
|
+
{
|
|
32562
|
+
inCell: true,
|
|
32563
|
+
field: field2,
|
|
32564
|
+
value: doc[field2.key],
|
|
32565
|
+
document: row.document,
|
|
32566
|
+
recordId: row.id,
|
|
32567
|
+
withheld: withheldNoticeOf(row.hidden, field2.key),
|
|
32568
|
+
format: cellFormatFor(field2, formats?.[field2.key])
|
|
32569
|
+
}
|
|
32570
|
+
) }, field2.key)
|
|
32571
|
+
));
|
|
32521
32572
|
return /* @__PURE__ */ (0, import_jsx_runtime105.jsxs)(
|
|
32522
32573
|
"button",
|
|
32523
32574
|
{
|
|
@@ -32929,9 +32980,21 @@ function Board({
|
|
|
32929
32980
|
const titleField = cardTitleField(all, titleKey, [view.groupField]);
|
|
32930
32981
|
const cardHidden = cardHiddenOf(view.presentation);
|
|
32931
32982
|
const dateFields = cardDateFields(all, titleField, cardHidden);
|
|
32983
|
+
const timedCardFields = cardHidden !== void 0 ? cardFieldsShown(all, cardHidden, [titleField?.key]) : [];
|
|
32984
|
+
const timedCardPicker = (layout) => /* @__PURE__ */ (0, import_jsx_runtime106.jsx)(
|
|
32985
|
+
CardFieldsPicker,
|
|
32986
|
+
{
|
|
32987
|
+
layout,
|
|
32988
|
+
fields: all.filter((f) => f.key !== titleField?.key),
|
|
32989
|
+
hiddenFields: cardHidden ?? all.map((f) => f.key),
|
|
32990
|
+
summary: `Card fields (${timedCardFields.length})`,
|
|
32991
|
+
onChange: (next) => onChange({ presentation: { ...view.presentation, cardHidden: next } }),
|
|
32992
|
+
remembered
|
|
32993
|
+
}
|
|
32994
|
+
);
|
|
32932
32995
|
if (view.layout === "kanban") {
|
|
32933
32996
|
const choice = boardColumnChoice(all, view.groupField, stage);
|
|
32934
|
-
const groupField = byKey(choice.groupKey) ?? (choice.stillAsking ? void 0 : eligibleFieldFor("choice", all).
|
|
32997
|
+
const groupField = byKey(choice.groupKey) ?? (choice.stillAsking ? void 0 : boardDefaultGroupField(eligibleFieldFor("choice", all).eligible) ?? void 0);
|
|
32935
32998
|
const isPipeline = choice.isPipeline;
|
|
32936
32999
|
const boardChose = cardHidden !== void 0;
|
|
32937
33000
|
const boardCardFields = boardChose ? cardFieldsShown(all, cardHidden, [titleField?.key, groupField?.key, ...dateFields.map((f) => f.key)]) : [];
|
|
@@ -32967,7 +33030,8 @@ function Board({
|
|
|
32967
33030
|
...onMoved ? { onMoved } : {},
|
|
32968
33031
|
onChanged: () => records.reload(),
|
|
32969
33032
|
style,
|
|
32970
|
-
dateFields
|
|
33033
|
+
dateFields,
|
|
33034
|
+
canAdd: mayAdd
|
|
32971
33035
|
}
|
|
32972
33036
|
) : /* @__PURE__ */ (0, import_jsx_runtime106.jsx)(
|
|
32973
33037
|
Kanban,
|
|
@@ -33041,13 +33105,15 @@ function Board({
|
|
|
33041
33105
|
}
|
|
33042
33106
|
}),
|
|
33043
33107
|
titleField,
|
|
33108
|
+
cardFields: timedCardFields,
|
|
33044
33109
|
onOpenRecord,
|
|
33045
33110
|
...onMoved ? { onMoved } : {},
|
|
33046
33111
|
note: records.membership,
|
|
33047
33112
|
style
|
|
33048
33113
|
}
|
|
33049
33114
|
),
|
|
33050
|
-
pager
|
|
33115
|
+
pager,
|
|
33116
|
+
timedCardPicker("calendar")
|
|
33051
33117
|
] });
|
|
33052
33118
|
}
|
|
33053
33119
|
if (view.layout === "timeline") {
|
|
@@ -33058,6 +33124,7 @@ function Board({
|
|
|
33058
33124
|
noRows ?? /* @__PURE__ */ (0, import_jsx_runtime106.jsx)(
|
|
33059
33125
|
TimelineView,
|
|
33060
33126
|
{
|
|
33127
|
+
cardFields: timedCardFields,
|
|
33061
33128
|
tableId: view.subject,
|
|
33062
33129
|
rows: records.rows,
|
|
33063
33130
|
fields: all,
|
|
@@ -33089,7 +33156,8 @@ function Board({
|
|
|
33089
33156
|
style
|
|
33090
33157
|
}
|
|
33091
33158
|
),
|
|
33092
|
-
pager
|
|
33159
|
+
pager,
|
|
33160
|
+
timedCardPicker("timeline")
|
|
33093
33161
|
] });
|
|
33094
33162
|
}
|
|
33095
33163
|
if (view.layout === "list") {
|
|
@@ -33471,7 +33539,7 @@ function Gallery({
|
|
|
33471
33539
|
}) {
|
|
33472
33540
|
const hidden = (0, import_react181.useMemo)(() => new Set(hiddenFields ?? []), [hiddenFields]);
|
|
33473
33541
|
const imageField = imageKey ? fields.find((field2) => field2.key === imageKey) : void 0;
|
|
33474
|
-
const shown4 = fields.filter((field2) => !hidden.has(field2.key) && field2.key !== imageKey);
|
|
33542
|
+
const shown4 = fields.filter((field2) => !hidden.has(field2.key) && field2.key !== imageKey && field2.key !== titleKey);
|
|
33475
33543
|
const chose = hiddenFields !== void 0;
|
|
33476
33544
|
const dims = GALLERY_SIZE[size];
|
|
33477
33545
|
return /* @__PURE__ */ (0, import_jsx_runtime106.jsxs)("div", { className: "flex min-h-0 flex-col gap-2", children: [
|
|
@@ -33483,7 +33551,7 @@ function Gallery({
|
|
|
33483
33551
|
/* @__PURE__ */ (0, import_jsx_runtime106.jsxs)(
|
|
33484
33552
|
"ul",
|
|
33485
33553
|
{
|
|
33486
|
-
className: "grid gap-2 overflow-y-auto",
|
|
33554
|
+
className: "grid auto-rows-fr gap-2 overflow-y-auto",
|
|
33487
33555
|
style: { gridTemplateColumns: `repeat(auto-fill, ${dims.tile})` },
|
|
33488
33556
|
children: [
|
|
33489
33557
|
rows.map((row) => {
|
|
@@ -33492,7 +33560,7 @@ function Gallery({
|
|
|
33492
33560
|
const filled = shown4.filter((field2) => !isEmptyOnCard(doc[field2.key]) || withheldNoticeOf(row.hidden, field2.key));
|
|
33493
33561
|
const onCard = chose ? filled : filled.slice(0, GALLERY_DEFAULT_FIELDS);
|
|
33494
33562
|
const rowColor = style ? (0, import_data_table19.resolveRowColor)(style, { id: row.id, data: row.document ?? {} }, colorFromTheValue) : null;
|
|
33495
|
-
return /* @__PURE__ */ (0, import_jsx_runtime106.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime106.jsx)(
|
|
33563
|
+
return /* @__PURE__ */ (0, import_jsx_runtime106.jsx)("li", { className: "flex", children: /* @__PURE__ */ (0, import_jsx_runtime106.jsx)(
|
|
33496
33564
|
MaybeRecordActionMenu,
|
|
33497
33565
|
{
|
|
33498
33566
|
tableId,
|
|
@@ -33505,17 +33573,19 @@ function Gallery({
|
|
|
33505
33573
|
{
|
|
33506
33574
|
type: "button",
|
|
33507
33575
|
className: (0, import_design_system92.cn)(
|
|
33508
|
-
"flex w-full flex-col gap-1 rounded border p-2 pr-7 text-left hover:bg-muted",
|
|
33576
|
+
"flex h-full w-full flex-col gap-1 rounded border p-2 pr-7 text-left hover:bg-muted",
|
|
33509
33577
|
rowColor ? import_data_table19.ROW_TINT_CLASS[rowColor] : void 0
|
|
33510
33578
|
),
|
|
33511
33579
|
onClick: () => onOpenRecord?.(row.id),
|
|
33512
33580
|
children: [
|
|
33513
33581
|
imageField ? /* @__PURE__ */ (0, import_jsx_runtime106.jsx)("span", { className: (0, import_design_system92.cn)(dims.cover, "w-full shrink-0 overflow-hidden rounded bg-muted/50"), "data-records-gallery-cover": imageField.key, children: /* @__PURE__ */ (0, import_jsx_runtime106.jsx)(GalleryCover, { field: imageField, value: image }) }) : null,
|
|
33514
|
-
|
|
33582
|
+
/* @__PURE__ */ (0, import_jsx_runtime106.jsx)("span", { className: "truncate text-sm font-medium", "data-records-gallery-title": "", children: recordNameIn({ title_field: titleKey ?? null }, doc) || "Untitled" }),
|
|
33583
|
+
onCard.map((field2) => /* @__PURE__ */ (0, import_jsx_runtime106.jsxs)("span", { className: "flex h-5 min-w-0 items-center gap-1 overflow-hidden whitespace-nowrap text-xs", children: [
|
|
33515
33584
|
/* @__PURE__ */ (0, import_jsx_runtime106.jsx)("span", { className: "shrink-0 text-muted-foreground", children: fieldName(field2) }),
|
|
33516
33585
|
/* @__PURE__ */ (0, import_jsx_runtime106.jsx)("span", { className: "min-w-0 truncate", "data-records-gallery-value": field2.key, children: /* @__PURE__ */ (0, import_jsx_runtime106.jsx)(
|
|
33517
33586
|
RecordValue,
|
|
33518
33587
|
{
|
|
33588
|
+
inCell: true,
|
|
33519
33589
|
field: field2,
|
|
33520
33590
|
value: doc[field2.key],
|
|
33521
33591
|
document: row.document,
|
|
@@ -33610,6 +33680,10 @@ function cardHiddenOf(presentation) {
|
|
|
33610
33680
|
const held = presentation?.["cardHidden"];
|
|
33611
33681
|
return Array.isArray(held) ? held.filter((k) => typeof k === "string") : void 0;
|
|
33612
33682
|
}
|
|
33683
|
+
var STATUS_WORDS = /^(status|stage|state|progress|phase)$/i;
|
|
33684
|
+
function boardDefaultGroupField(eligible) {
|
|
33685
|
+
return eligible.find((f) => (0, import_records47.newerKindOf)(f) === "status") ?? eligible.find((f) => STATUS_WORDS.test(fieldName(f).trim()) || STATUS_WORDS.test(f.key)) ?? eligible[0] ?? null;
|
|
33686
|
+
}
|
|
33613
33687
|
|
|
33614
33688
|
// src/ArchivedView.tsx
|
|
33615
33689
|
var import_react183 = require("react");
|