@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/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 ? { renameRow: (rowId) => editing.begin({ rowId, key: table.title_field }) } : {},
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 import_react167 = require("react");
29373
- var import_react168 = require("@ai-matrx/records/react");
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 import_design_system86 = require("@ai-matrx/design-system");
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 import_jsx_runtime96 = require("react/jsx-runtime");
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, import_jsx_runtime96.jsx)(import_jsx_runtime96.Fragment, { children: held.map((field2) => /* @__PURE__ */ (0, import_jsx_runtime96.jsxs)(
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, import_jsx_runtime96.jsx)("span", { className: "shrink-0", children: fieldName(field2) }),
29401
- /* @__PURE__ */ (0, import_jsx_runtime96.jsx)("span", { className: "min-w-0 truncate text-foreground/80", children: /* @__PURE__ */ (0, import_jsx_runtime96.jsx)(
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 import_react165 = require("react");
29419
- var import_react166 = require("@ai-matrx/records/react");
29420
- var import_design_system85 = require("@ai-matrx/design-system");
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 import_jsx_runtime97 = require("react/jsx-runtime");
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, import_react166.useRecordsClient)();
29654
+ const client = (0, import_react168.useRecordsClient)();
29492
29655
  const host = useRecordsUi();
29493
- const fields = (0, import_react166.useFields)(tableId);
29494
- const table = (0, import_react166.useTable)(tableId);
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, import_react165.useMemo)(() => {
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, import_jsx_runtime97.jsxs)(
29563
- import_design_system85.ContextMenuItem,
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, import_jsx_runtime97.jsx)(ObjectActionGlyph, { name: action3.icon, className: "mr-2 h-4 w-4 shrink-0" }),
29574
- /* @__PURE__ */ (0, import_jsx_runtime97.jsxs)("span", { className: "flex min-w-0 flex-col", children: [
29575
- /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("span", { children: action3.label }),
29576
- disabled ? /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("span", { className: "truncate text-xs text-muted-foreground", "data-object-action-reason": "", children: action3.disabledReason }) : null
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, import_jsx_runtime97.jsx)(import_design_system85.ContextMenuShortcut, { children: action3.shortcut }) : null
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, import_jsx_runtime97.jsx)(import_jsx_runtime97.Fragment, { children: toDropdownEntries(actions).map((entry) => {
29585
- if (entry.kind === "separator") return /* @__PURE__ */ (0, import_jsx_runtime97.jsx)(import_design_system85.ContextMenuSeparator, {}, entry.id);
29586
- if (entry.kind === "item") return /* @__PURE__ */ (0, import_jsx_runtime97.jsx)(ContextActionItem, { action: entry.action }, entry.action.id);
29587
- return /* @__PURE__ */ (0, import_jsx_runtime97.jsxs)(import_design_system85.ContextMenuSub, { children: [
29588
- /* @__PURE__ */ (0, import_jsx_runtime97.jsxs)(import_design_system85.ContextMenuSubTrigger, { "data-object-action-group": entry.id, children: [
29589
- entry.icon ? /* @__PURE__ */ (0, import_jsx_runtime97.jsx)(ObjectActionGlyph, { name: entry.icon, className: "mr-2 h-4 w-4 shrink-0" }) : null,
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, import_jsx_runtime97.jsx)(import_design_system85.ContextMenuSubContent, { children: entry.actions.map((a) => /* @__PURE__ */ (0, import_jsx_runtime97.jsx)(ContextActionItem, { action: a }, a.id)) })
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, import_react165.useState)(false);
29598
- const openMerge = (0, import_react165.useCallback)(() => setMerging(true), []);
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, import_react165.useMemo)(() => whatYouMayDo(row.level || null, true), [row.level]);
29601
- const actions = (0, import_react165.useMemo)(
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, import_jsx_runtime97.jsxs)(import_design_system85.ContextMenu, { children: [
29606
- /* @__PURE__ */ (0, import_jsx_runtime97.jsx)(import_design_system85.ContextMenuTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime97.jsxs)("div", { className: (0, import_design_system85.cn)("group/record-card relative", className), "data-record-actions": row.id, children: [
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, import_jsx_runtime97.jsxs)(import_design_system85.DropdownMenu, { children: [
29609
- /* @__PURE__ */ (0, import_jsx_runtime97.jsx)(import_design_system85.DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime97.jsx)(
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, import_jsx_runtime97.jsxs)("svg", { viewBox: "0 0 24 24", className: "h-4 w-4", fill: "currentColor", "aria-hidden": "true", children: [
29618
- /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("circle", { cx: "5", cy: "12", r: "1.75" }),
29619
- /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("circle", { cx: "12", cy: "12", r: "1.75" }),
29620
- /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("circle", { cx: "19", cy: "12", r: "1.75" })
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, import_jsx_runtime97.jsx)(import_design_system85.DropdownMenuContent, { align: "end", className: "w-56", children: /* @__PURE__ */ (0, import_jsx_runtime97.jsx)(ObjectActionMenuItems, { actions }) })
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, import_jsx_runtime97.jsx)(import_design_system85.ContextMenuContent, { className: "w-56", children: /* @__PURE__ */ (0, import_jsx_runtime97.jsx)(ObjectActionContextMenuItems, { actions }) }),
29628
- merging ? /* @__PURE__ */ (0, import_jsx_runtime97.jsx)(
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 import_jsx_runtime98 = require("react/jsx-runtime");
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, import_react168.useRecordsClient)();
29679
- const fields = (0, import_react168.useFields)(tableId);
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, import_react167.useMemo)(
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, import_react167.useState)(null);
29686
- const [columns, setColumns] = (0, import_react167.useState)([]);
29687
- const [error, setError] = (0, import_react167.useState)(null);
29688
- const [loading, setLoading] = (0, import_react167.useState)(true);
29689
- const [pending, setPending] = (0, import_react167.useState)({ kind: "none" });
29690
- const [waiting, setWaiting] = (0, import_react167.useState)(/* @__PURE__ */ new Map());
29691
- const [dragging, setDragging] = (0, import_react167.useState)(null);
29692
- const [over, setOver] = (0, import_react167.useState)(null);
29693
- const alive = (0, import_react167.useRef)(true);
29694
- const [selected, setSelected] = (0, import_react167.useState)(/* @__PURE__ */ new Set());
29695
- const anchor = (0, import_react167.useRef)(null);
29696
- const [batch, setBatch] = (0, import_react167.useState)(/* @__PURE__ */ new Map());
29697
- const [batchSaid, setBatchSaid] = (0, import_react167.useState)(null);
29698
- const [batchError, setBatchError] = (0, import_react167.useState)(null);
29699
- const [moving, setMoving] = (0, import_react167.useState)(false);
29700
- (0, import_react167.useEffect)(() => {
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, import_react167.useCallback)(async () => {
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, import_react167.useEffect)(() => {
29889
+ (0, import_react169.useEffect)(() => {
29726
29890
  void reload();
29727
29891
  }, [reload]);
29728
- const versions = useRecordVersions(client, rows, (r) => (0, import_react168.mayDrag)(r.level));
29729
- const versionsRef = (0, import_react167.useRef)(versions);
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 cardsByStage = (0, import_react167.useMemo)(() => {
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, import_react167.useMemo)(
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, import_react167.useMemo)(
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, import_react167.useCallback)(
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, import_react167.useCallback)(
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, import_react167.useCallback)(
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, import_react168.mayDrag)(r.level)
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, import_jsx_runtime98.jsx)(RefusalNotice, { error: fields.error });
29873
- if (error) return /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(RefusalNotice, { error });
29874
- if (loading || fields.loading && !fields.data) return /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(import_design_system86.Skeleton, { className: "h-40 w-full" });
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, import_jsx_runtime98.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." });
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, import_jsx_runtime98.jsxs)(
30052
+ return /* @__PURE__ */ (0, import_jsx_runtime99.jsxs)(
29881
30053
  "div",
29882
30054
  {
29883
- className: (0, import_design_system86.cn)("flex min-h-0 flex-col gap-2", className),
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, import_jsx_runtime98.jsxs)(
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, import_jsx_runtime98.jsxs)("span", { className: "font-medium", children: [
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, import_jsx_runtime98.jsx)(import_design_system86.Button, { size: "sm", variant: "ghost", className: "h-7 px-2 text-xs", onClick: clearSelection, children: "Clear" }),
29906
- /* @__PURE__ */ (0, import_jsx_runtime98.jsxs)(import_design_system86.DropdownMenu, { children: [
29907
- /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(import_design_system86.DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(import_design_system86.Button, { size: "sm", className: "h-7 px-2 text-xs", disabled: moving, children: moving ? `Moving ${selectedInOrder.length}\u2026` : `Move ${selectedInOrder.length} to\u2026` }) }),
29908
- /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(import_design_system86.DropdownMenuContent, { align: "start", children: stages.map((stage) => /* @__PURE__ */ (0, import_jsx_runtime98.jsxs)(import_design_system86.DropdownMenuItem, { onSelect: () => void moveSelected(stage.key, stage.label), children: [
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, import_jsx_runtime98.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" })
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, import_jsx_runtime98.jsx)(
30091
+ batchError ? /* @__PURE__ */ (0, import_jsx_runtime99.jsx)(
29920
30092
  RefusalNotice,
29921
30093
  {
29922
30094
  error: batchError,
29923
- actions: /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(import_design_system86.Button, { size: "sm", variant: "ghost", className: "mt-1 h-6", onClick: () => setBatchError(null), children: "Close" })
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, import_jsx_runtime98.jsxs)("p", { className: "flex items-center gap-2 text-xs", role: "status", "data-testid": "pipeline-batch-said", children: [
29927
- /* @__PURE__ */ (0, import_jsx_runtime98.jsx)("span", { children: batchSaid }),
29928
- /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(import_design_system86.Button, { size: "sm", variant: "ghost", className: "h-6 px-2", onClick: () => setBatchSaid(null), children: "Close" })
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, import_jsx_runtime98.jsxs)("div", { className: "flex items-center gap-1.5 text-xs", children: [
29931
- /* @__PURE__ */ (0, import_jsx_runtime98.jsx)("label", { className: "text-muted-foreground", htmlFor: "pipeline-measure", children: "Total" }),
29932
- /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(
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, import_jsx_runtime98.jsx)("div", { className: "flex min-h-0 gap-2 overflow-x-auto pb-2", "data-records-board": true, children: stages.map((stage) => {
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, import_jsx_runtime98.jsxs)(
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, import_design_system86.cn)(
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, import_jsx_runtime98.jsxs)("header", { className: "flex items-baseline gap-2 border-b px-2 py-1 text-xs font-medium", children: [
29966
- /* @__PURE__ */ (0, import_jsx_runtime98.jsx)("span", { className: "truncate", children: stage.label }),
29967
- /* @__PURE__ */ (0, import_jsx_runtime98.jsxs)("span", { className: "ml-auto shrink-0 tabular-nums text-muted-foreground", children: [
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, import_jsx_runtime98.jsxs)("p", { className: "border-b px-2 py-1 text-xs text-destructive", children: [
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, import_jsx_runtime98.jsx)("ul", { className: "flex flex-col gap-1 p-1", children: cards.map((card) => /* @__PURE__ */ (0, import_jsx_runtime98.jsxs)("li", { children: [
29981
- /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(
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, import_jsx_runtime98.jsx)(
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, import_jsx_runtime98.jsx)(
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, import_jsx_runtime98.jsx)(
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, import_jsx_runtime98.jsxs)("p", { className: "text-xs text-muted-foreground", "data-testid": "pipeline-unplaced", children: [
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, import_react167.useState)({});
30262
+ const [draft, setDraft] = (0, import_react169.useState)({});
30081
30263
  if (pending.kind === "asking") {
30082
- return /* @__PURE__ */ (0, import_jsx_runtime98.jsx)("p", { className: "px-2 py-1 text-xs text-muted-foreground", children: "Asking\u2026" });
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, import_jsx_runtime98.jsx)(
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, import_jsx_runtime98.jsx)("div", { className: "mt-1", children: /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(import_design_system86.Button, { size: "sm", variant: "ghost", className: "h-6", onClick: onCancel, children: "Close" }) })
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, import_jsx_runtime98.jsx)(
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, import_jsx_runtime98.jsx)(import_design_system86.Button, { size: "sm", variant: "ghost", className: "mt-1 h-6", onClick: onCancel, children: "Close" })
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, import_jsx_runtime98.jsxs)("div", { className: "mt-1 flex flex-col gap-1 rounded border p-2 text-xs", children: [
30114
- /* @__PURE__ */ (0, import_jsx_runtime98.jsx)("p", { children: pending.verdict.why }),
30115
- pending.verdict.what_happens ? /* @__PURE__ */ (0, import_jsx_runtime98.jsx)("p", { className: "text-muted-foreground", children: pending.verdict.what_happens }) : null,
30116
- /* @__PURE__ */ (0, import_jsx_runtime98.jsxs)("div", { className: "flex items-center gap-1", children: [
30117
- /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(import_design_system86.Button, { size: "sm", className: "h-6", onClick: onAsk, children: "Ask for approval" }),
30118
- /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(import_design_system86.Button, { size: "sm", variant: "ghost", className: "h-6", onClick: onCancel, children: "Leave it where it was" })
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, import_jsx_runtime98.jsxs)("div", { className: "mt-1 rounded border p-2 text-xs", children: [
30124
- /* @__PURE__ */ (0, import_jsx_runtime98.jsx)("p", { children: pending.result.what_happens ?? "This is waiting for somebody who can approve it. It has not moved." }),
30125
- (pending.result.approvers ?? []).length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime98.jsxs)("p", { className: "text-muted-foreground", children: [
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, import_jsx_runtime98.jsx)(import_design_system86.Button, { size: "sm", variant: "ghost", className: "mt-1 h-6", onClick: onCancel, children: "Close" })
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, import_jsx_runtime98.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: [
30136
- pending.warnings.map((w) => /* @__PURE__ */ (0, import_jsx_runtime98.jsxs)("div", { children: [
30137
- /* @__PURE__ */ (0, import_jsx_runtime98.jsx)("p", { children: w.why }),
30138
- /* @__PURE__ */ (0, import_jsx_runtime98.jsx)("p", { className: "text-muted-foreground", children: w.what_to_do })
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, import_jsx_runtime98.jsx)(import_design_system86.Button, { size: "sm", variant: "ghost", className: "h-6 self-start", onClick: onCancel, children: "Close" })
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, import_jsx_runtime98.jsxs)("div", { className: "mt-1 flex flex-col gap-1 rounded border p-2 text-xs", children: [
30147
- /* @__PURE__ */ (0, import_jsx_runtime98.jsx)("p", { children: pending.verdict.why }),
30148
- missing.map((m) => /* @__PURE__ */ (0, import_jsx_runtime98.jsxs)("label", { className: "flex flex-col gap-0.5", children: [
30149
- /* @__PURE__ */ (0, import_jsx_runtime98.jsx)("span", { className: "text-muted-foreground", children: m.label }),
30150
- /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(
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, import_jsx_runtime98.jsxs)("div", { className: "flex items-center gap-1", children: [
30160
- ready ? /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(
30161
- import_design_system86.Button,
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, import_jsx_runtime98.jsxs)("span", { className: "text-muted-foreground", children: [
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, import_jsx_runtime98.jsx)(import_design_system86.Button, { size: "sm", variant: "ghost", className: "h-6", onClick: onCancel, children: "Leave it where it was" })
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, import_react168.mayDrag)(record.level);
30377
+ const draggable = (0, import_react170.mayDrag)(record.level);
30196
30378
  const { text: label, withheld } = cardWords(record, field2, labels);
30197
- return /* @__PURE__ */ (0, import_jsx_runtime98.jsxs)(
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, import_design_system86.cn)(
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, import_jsx_runtime98.jsx)("span", { className: "block truncate", children: label }),
30239
- dates && dates.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(CardDates, { record, fields: dates }) : null,
30240
- waiting ? /* @__PURE__ */ (0, import_jsx_runtime98.jsxs)(
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/CalendarView.tsx
30318
- var import_react172 = require("react");
30319
- var import_react173 = require("@ai-matrx/records/react");
30320
- var import_design_system88 = require("@ai-matrx/design-system");
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 useRecordMoves({
30333
- tableId,
30334
- rows,
30335
- onMoved
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 client = (0, import_react170.useRecordsClient)();
30338
- const [refused, setRefused] = (0, import_react169.useState)(null);
30339
- const versions = useRecordVersions(client, rows);
30340
- const [stale, setStale] = (0, import_react169.useState)(null);
30341
- const reload = (0, import_react169.useCallback)(() => onMoved?.(), [onMoved]);
30342
- const forget = (0, import_react169.useCallback)(() => void 0, []);
30343
- const undo = useGridUndo({
30344
- tableId,
30345
- reload,
30346
- forget,
30347
- onVersions: (written) => {
30348
- for (const v of written) versions.wrote(v.id, v.version);
30349
- }
30350
- });
30351
- const move = (0, import_react169.useCallback)(
30352
- async ({ recordId, patch, before, label }) => {
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
- return false;
30371
- }
30372
- if (written.version !== null) versions.wrote(recordId, written.version);
30373
- undo.push({
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 MoveRefusedBadge({ refused }) {
30459
- return /* @__PURE__ */ (0, import_jsx_runtime99.jsx)(
30460
- "span",
30461
- {
30462
- "data-move-refused": refused.changedElsewhere ? "changed-elsewhere" : refused.unread ? "unread" : "refused",
30463
- title: refused.changedElsewhere ? STALE_MOVE_LABEL : refused.unread ? VERSION_UNREAD_LABEL : refusalSentence(refused.error),
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 import_jsx_runtime100 = require("react/jsx-runtime");
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, import_jsx_runtime100.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: [
30761
- /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("rect", { x: "3.5", y: "7", width: "9", height: "6.5", rx: "1" }),
30762
- /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("path", { d: "M5.5 7V5a2.5 2.5 0 0 1 5 0v2" })
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, import_jsx_runtime100.jsxs)(
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, import_jsx_runtime100.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_runtime100.jsx)(LockIcon, {}) }),
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, import_jsx_runtime100.jsx)("span", { className: "min-w-0 truncate", children: title })
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, import_jsx_runtime100.jsx)(MoveRefusedBadge, { refused: moves.refused }) : null;
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, import_jsx_runtime100.jsx)("span", { className: "shrink-0 tabular-nums text-[10px] opacity-75", "data-calendar-time": "", children: words2 }) : null;
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, import_jsx_runtime100.jsxs)("li", { ...dragSource(p.row), children: [
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, import_jsx_runtime100.jsxs)("div", { className: "flex items-center gap-1.5 whitespace-nowrap text-xs", "data-calendar-setting": label, children: [
31110
- /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("span", { className: "text-muted-foreground", children: label }),
31111
- /* @__PURE__ */ (0, import_jsx_runtime100.jsxs)(import_design_system88.Select, { value: value ?? NONE, onValueChange: (v) => onPick(v === NONE ? null : v), children: [
31112
- /* @__PURE__ */ (0, import_jsx_runtime100.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_runtime100.jsx)(import_design_system88.SelectValue, { placeholder: "Choose" }) }),
31113
- /* @__PURE__ */ (0, import_jsx_runtime100.jsxs)(import_design_system88.SelectContent, { children: [
31114
- /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(import_design_system88.SelectItem, { value: NONE, children: "None" }),
31115
- candidates.map((f) => /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(import_design_system88.SelectItem, { value: f.key, children: fieldName(f) }, f.key)),
31116
- unusual ? /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(import_design_system88.SelectItem, { value: unusual.key, "data-calendar-unusual": "", children: `${fieldName(unusual)} \u2014 ${UNUSUAL_FIELD_NOTE}` }, unusual.key) : null
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, import_jsx_runtime100.jsxs)(import_jsx_runtime100.Fragment, { children: [
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, import_jsx_runtime100.jsxs)("div", { className: "flex flex-wrap items-center gap-2", children: [
31131
- /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(import_design_system88.Button, { size: "sm", variant: "outline", onClick: () => setAnchor(today), children: "Today" }),
31132
- mode !== "list" ? /* @__PURE__ */ (0, import_jsx_runtime100.jsxs)(import_jsx_runtime100.Fragment, { children: [
31133
- /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(import_design_system88.Button, { size: "sm", variant: "ghost", "aria-label": "Previous", onClick: () => step2(-1), children: "\u2039" }),
31134
- /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(import_design_system88.Button, { size: "sm", variant: "ghost", "aria-label": "Next", onClick: () => step2(1), children: "\u203A" }),
31135
- /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("h3", { className: "text-sm font-medium", "data-calendar-heading": "", children: heading })
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, import_jsx_runtime100.jsxs)("div", { className: "ml-auto flex flex-wrap items-center gap-2", children: [
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, import_jsx_runtime100.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_runtime100.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)) })
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, import_jsx_runtime100.jsxs)("aside", { className: "flex min-w-0 flex-col gap-1 sm:w-56 sm:shrink-0", "data-calendar-undated": "", children: [
31145
- /* @__PURE__ */ (0, import_jsx_runtime100.jsxs)("h4", { className: "text-xs font-medium", children: [
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, import_jsx_runtime100.jsx)("ul", { className: "flex flex-col gap-1 overflow-y-auto", children: undated.map((row) => listCard({ row }, `tray:${row.id}`)) })
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, import_jsx_runtime100.jsx)("div", { className: "min-w-0 flex-1 overflow-x-auto", children: /* @__PURE__ */ (0, import_jsx_runtime100.jsxs)("div", { className: "min-w-[560px] border-l border-t", role: "grid", "aria-label": heading, "data-calendar-month": "", children: [
31157
- /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("div", { className: "grid grid-cols-7", role: "row", children: Array.from({ length: 7 }, (_, i) => addDays2(first, i)).map((d) => /* @__PURE__ */ (0, import_jsx_runtime100.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}`)) }),
31158
- weeks.map((ws) => /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(
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, import_jsx_runtime100.jsxs)("div", { ...dragSource(p.row), className: "relative h-full", children: [
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, import_jsx_runtime100.jsxs)(import_jsx_runtime100.Fragment, { children: [
31176
- /* @__PURE__ */ (0, import_jsx_runtime100.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") }),
31177
- /* @__PURE__ */ (0, import_jsx_runtime100.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") })
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, import_jsx_runtime100.jsx)("div", { className: "min-w-0 flex-1 overflow-x-auto", children: /* @__PURE__ */ (0, import_jsx_runtime100.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: [
31198
- /* @__PURE__ */ (0, import_jsx_runtime100.jsxs)("div", { className: "grid", style: { gridTemplateColumns: columns }, children: [
31199
- /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("div", { className: "border-b border-r" }),
31200
- days.map((d) => /* @__PURE__ */ (0, import_jsx_runtime100.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}`)),
31201
- /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("div", { className: "border-b border-r px-1 py-0.5 text-[10px] text-muted-foreground", children: "All day" }),
31202
- days.map((d) => /* @__PURE__ */ (0, import_jsx_runtime100.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_runtime100.jsx)("ul", { className: "flex flex-col gap-0.5", children: allDay(d).map((p) => listCard(p, `${p.row.id}:${d}`)) }) }, `a${d}`))
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, import_jsx_runtime100.jsx)(
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, import_jsx_runtime100.jsxs)(import_jsx_runtime100.Fragment, { children: [
31213
- ghost && ghost.day === d && ghost.minute !== null ? /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(
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, import_jsx_runtime100.jsx)(
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, import_jsx_runtime100.jsxs)(
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, import_jsx_runtime100.jsx)("span", { className: "shrink-0 tabular-nums text-[10px] opacity-75", "data-calendar-time": "", children: timeLabel(start) }),
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, import_jsx_runtime100.jsx)(
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, import_jsx_runtime100.jsx)("div", { className: "absolute left-0 top-full z-30", children: refusalOn(p.row) })
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, import_jsx_runtime100.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_runtime100.jsxs)("li", { className: "flex gap-3 p-2", "data-calendar-day": d, ...dayDrop(d), children: [
31277
- /* @__PURE__ */ (0, import_jsx_runtime100.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) }),
31278
- /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("ul", { className: "flex min-w-0 flex-1 flex-col gap-1", children: cards.map((p) => listCard(p, `${p.row.id}:${d}`)) })
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, import_jsx_runtime100.jsxs)(
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, import_jsx_runtime100.jsx)("p", { className: "text-xs text-muted-foreground", children: note }) : null,
31378
+ note ? /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("p", { className: "text-xs text-muted-foreground", children: note }) : null,
31293
31379
  toolbar,
31294
- /* @__PURE__ */ (0, import_jsx_runtime100.jsxs)("div", { className: "flex min-h-0 flex-col gap-3 sm:flex-row", children: [
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, import_jsx_runtime100.jsxs)("div", { className: "relative grid grid-cols-7", role: "row", "data-calendar-week-row": weekStart, children: [
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, import_jsx_runtime100.jsxs)(
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, import_jsx_runtime100.jsxs)("div", { className: "flex items-center", children: [
31359
- canCreate ? /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(
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, import_jsx_runtime100.jsx)(
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, import_jsx_runtime100.jsx)("div", { style: { height: lanesShown * BAR_PX }, "aria-hidden": "true" }),
31382
- /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("ul", { className: "flex flex-col gap-0.5", children: shown4.map((p) => card(p, `${p.row.id}:${d}`)) }),
31383
- more > 0 ? /* @__PURE__ */ (0, import_jsx_runtime100.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: [
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, import_jsx_runtime100.jsxs)(
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, import_jsx_runtime100.jsxs)("div", { className: "flex items-center", children: [
31400
- /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("span", { className: "text-xs font-medium", children: calendarDayLabel(d) }),
31401
- /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(import_design_system88.Button, { size: "sm", variant: "ghost", className: "ml-auto h-6", "aria-label": "Close", onClick: () => onOpenDay(null), children: "\xD7" })
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, import_jsx_runtime100.jsx)("ul", { className: "flex flex-col gap-0.5", children: everything.map((p) => card(p, `open:${p.row.id}:${d}`)) })
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, import_jsx_runtime100.jsxs)(
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, import_jsx_runtime100.jsx)("div", { ref: frame, className: "max-h-[36rem] overflow-y-auto", children: /* @__PURE__ */ (0, import_jsx_runtime100.jsxs)("div", { className: "grid", style: { gridTemplateColumns: columns }, children: [
31452
- /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("div", { className: "border-r", children: hours.map((h) => /* @__PURE__ */ (0, import_jsx_runtime100.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)) }),
31453
- days.map((d) => /* @__PURE__ */ (0, import_jsx_runtime100.jsxs)(
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, import_jsx_runtime100.jsx)("div", { "data-calendar-slot": `${d}T${pad3(h)}`, className: "border-b", style: { height: HOUR_PX } }, h)),
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, import_jsx_runtime100.jsx)(
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 import_jsx_runtime101 = require("react/jsx-runtime");
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, 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: [
31580
- /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("rect", { x: "3.5", y: "7", width: "9", height: "6.5", rx: "1" }),
31581
- /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("path", { d: "M5.5 7V5a2.5 2.5 0 0 1 5 0v2" })
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, import_jsx_runtime101.jsxs)(
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, import_jsx_runtime101.jsx)(
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, import_jsx_runtime101.jsx)("span", { "aria-hidden": "true", className: "shrink-0", style: { width: inset } }) : null,
31949
- may ? null : /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(LockIcon2, {}),
31950
- p.marker ? /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("span", { "aria-hidden": "true", className: "h-2 w-2 shrink-0 rotate-45 rounded-[1px] bg-current opacity-70" }) : null,
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, import_jsx_runtime101.jsxs)("span", { className: "pointer-events-none absolute left-full top-1/2 ml-1.5 -translate-y-1/2 whitespace-nowrap text-foreground", children: [
31954
- startTime ? /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("span", { className: "mr-1 tabular-nums text-[10px] opacity-75", "data-timeline-time": "", children: startTime }) : null,
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, import_jsx_runtime101.jsxs)(import_jsx_runtime101.Fragment, { children: [
31958
- startTime ? /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("span", { className: "shrink-0 tabular-nums text-[10px] opacity-75", "data-timeline-time": "", children: startTime }) : null,
31959
- /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("span", { className: "min-w-0 truncate", children: title })
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, import_jsx_runtime101.jsx)(
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, import_jsx_runtime101.jsxs)("div", { className: "flex items-center gap-1.5 whitespace-nowrap text-xs", "data-timeline-setting": label, children: [
31977
- /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("span", { className: "text-muted-foreground", children: label }),
31978
- /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)(import_design_system89.Select, { value: value ?? NONE2, onValueChange: (v) => onPick(v === NONE2 ? null : v), children: [
31979
- /* @__PURE__ */ (0, import_jsx_runtime101.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_runtime101.jsx)(import_design_system89.SelectValue, { placeholder: "Choose" }) }),
31980
- /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)(import_design_system89.SelectContent, { children: [
31981
- opts?.none !== false ? /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_design_system89.SelectItem, { value: NONE2, children: "None" }) : null,
31982
- options.map((f) => /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_design_system89.SelectItem, { value: f.key, children: fieldName(f) }, f.key)),
31983
- value && !options.some((f) => f.key === value) && fields.some((f) => f.key === value) ? /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_design_system89.SelectItem, { value, "data-timeline-unusual": "", children: `${fieldName(fields.find((f) => f.key === value))} \u2014 ${UNUSUAL_FIELD_NOTE}` }, value) : null
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, import_jsx_runtime101.jsxs)(import_jsx_runtime101.Fragment, { children: [
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, import_jsx_runtime101.jsxs)("div", { className: "flex flex-wrap items-center gap-2", children: [
31995
- /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_design_system89.Button, { size: "sm", variant: "outline", onClick: () => setAnchor(today), children: "Today" }),
31996
- /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_design_system89.Button, { size: "sm", variant: "ghost", "aria-label": "Previous", onClick: () => setAnchor(addDays(anchor, -PAGE_DAYS[zoom])), children: "\u2039" }),
31997
- /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_design_system89.Button, { size: "sm", variant: "ghost", "aria-label": "Next", onClick: () => setAnchor(addDays(anchor, PAGE_DAYS[zoom])), children: "\u203A" }),
31998
- /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("h3", { className: "text-sm font-medium", "data-timeline-heading": "", children: heading }),
31999
- layoutKept ? null : /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("span", { className: "text-xs text-muted-foreground", children: "Kept for this visit only" }),
32000
- /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)("div", { className: "ml-auto flex flex-wrap items-center gap-2", children: [
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, import_jsx_runtime101.jsx)("div", { className: "flex items-center gap-0.5", role: "group", "aria-label": "Zoom", children: TIMELINE_ZOOMS.map((z) => /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_design_system89.Button, { size: "sm", variant: z === zoom ? "secondary" : "ghost", "aria-pressed": z === zoom, onClick: () => setZoom(z), children: ZOOM_LABEL[z] }, z)) })
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, import_jsx_runtime101.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_runtime101.jsxs)("div", { className: "flex flex-col gap-2 rounded border border-dashed p-4 text-xs text-muted-foreground", children: [
32007
- /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("p", { children: dates.length > 0 ? VIEW_NEEDS.timeline?.pick : VIEW_NEEDS.timeline?.missing }),
32008
- dates.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("div", { className: "flex flex-wrap gap-2", children: settings }) : null
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, import_jsx_runtime101.jsxs)("aside", { className: "flex min-w-0 flex-col gap-1 sm:w-56 sm:shrink-0", "data-timeline-unscheduled": "", children: [
32031
- /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)("h4", { className: "text-xs font-medium", children: [
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, import_jsx_runtime101.jsx)("ul", { className: "flex max-h-[28rem] flex-col gap-1 overflow-y-auto", children: unscheduled.map((row) => {
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, import_jsx_runtime101.jsx)(
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, import_jsx_runtime101.jsxs)(
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, import_jsx_runtime101.jsx)(LockIcon2, {}),
32061
- /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("span", { className: "min-w-0 truncate", children: titleOf(row) })
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, import_jsx_runtime101.jsx)(
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, import_jsx_runtime101.jsxs)("div", { className: "flex", "data-timeline-scale": key, children: [
32082
- grouped ? /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("div", { className: (0, import_design_system89.cn)(LABEL_COLUMN, "border-b") }) : null,
32083
- /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)("div", { className: "relative shrink-0", style: { width, height: 22 }, children: [
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, import_jsx_runtime101.jsx)(
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, import_jsx_runtime101.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_runtime101.jsxs)("div", { className: "relative w-max", "data-timeline-zoom": zoom, "data-timeline-from": from, children: [
32102
- /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)("div", { className: "sticky top-0 z-30 bg-background", children: [
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, import_jsx_runtime101.jsxs)("div", { className: "flex border-b", "data-timeline-lane": groupField ? lane.key : "", children: [
32107
- grouped ? /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)("div", { className: (0, import_design_system89.cn)(LABEL_COLUMN, "flex items-start p-1"), "data-timeline-label": "", children: [
32108
- /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(
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, import_jsx_runtime101.jsx)("span", { className: "ml-auto px-1 text-xs text-muted-foreground", children: lane.bars.length })
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, import_jsx_runtime101.jsxs)("div", { className: "relative shrink-0", style: { width, height: Math.max(lane.height, ROW_PX + LANE_PAD) }, "data-timeline-canvas": lane.key, ...laneDrop, children: [
32120
- weekendBands.map((d) => /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("div", { "aria-hidden": "true", className: "absolute inset-y-0 bg-muted/40", style: { left: xOf(d), width: px } }, `we:${d}`)),
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, import_jsx_runtime101.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: [
32127
- note ? /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("p", { className: "text-xs text-muted-foreground", children: note }) : null,
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, import_jsx_runtime101.jsxs)("div", { className: "flex min-h-0 min-w-0 flex-col gap-3 sm:flex-row", children: [
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 import_jsx_runtime102 = require("react/jsx-runtime");
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, import_jsx_runtime102.jsxs)("div", { className: "flex flex-col gap-2 text-xs", children: [
32203
- /* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("div", { className: "flex flex-wrap items-center gap-2", children: [
32204
- /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(import_design_system90.Label, { className: "text-xs text-muted-foreground", htmlFor: `view-needs-name-${layout}`, children: "Column name" }),
32205
- /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
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, import_jsx_runtime102.jsxs)("div", { className: "flex flex-wrap items-center gap-1.5", role: "group", "aria-label": "Choices", children: [
32216
- /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("span", { className: "text-muted-foreground", children: "Choices" }),
32217
- options.map((option, index) => /* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("span", { className: "flex items-center gap-0.5", children: [
32218
- /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
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, import_jsx_runtime102.jsx)(
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, import_jsx_runtime102.jsx)(import_design_system90.Button, { type: "button", size: "sm", variant: "ghost", onClick: () => setOptions((held) => [...held, ""]), children: "Add a choice" })
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, import_jsx_runtime102.jsxs)("div", { className, children: [
32243
- /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
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, import_jsx_runtime102.jsx)(RefusalNotice, { error: mutation.error }) : null,
32265
- refused ? /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(RefusalNotice, { error: refused }) : null,
32266
- pendingId ? /* @__PURE__ */ (0, import_jsx_runtime102.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
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 import_jsx_runtime103 = require("react/jsx-runtime");
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, import_jsx_runtime103.jsx)(FileCover, { recordId: first }) : null;
32370
+ return first ? /* @__PURE__ */ (0, import_jsx_runtime104.jsx)(FileCover, { recordId: first }) : null;
32283
32371
  }
32284
32372
  if (isImageAddress(value)) {
32285
- return /* @__PURE__ */ (0, import_jsx_runtime103.jsx)("img", { src: value, alt: "", loading: "lazy", className: "h-full w-full object-cover" });
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, import_jsx_runtime103.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 });
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, import_jsx_runtime103.jsx)(import_jsx_runtime103.Fragment, { children: host.fileImage({ fileId: read.fileId, alt: read.name }) });
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) => /* @__PURE__ */ (0, import_jsx_runtime105.jsx)("span", { className: "flex min-w-0 max-w-[14rem] items-baseline gap-1", "data-records-list-value": field2.key, title: fieldName(field2), children: /* @__PURE__ */ (0, import_jsx_runtime105.jsx)(
32511
- RecordValue,
32512
- {
32513
- field: field2,
32514
- value: doc[field2.key],
32515
- document: row.document,
32516
- recordId: row.id,
32517
- withheld: withheldNoticeOf(row.hidden, field2.key),
32518
- format: cellFormatFor(field2, formats?.[field2.key])
32519
- }
32520
- ) }, field2.key));
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).field ?? void 0);
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
- onCard.map((field2) => /* @__PURE__ */ (0, import_jsx_runtime106.jsxs)("span", { className: "flex min-w-0 items-baseline gap-1 text-xs", children: [
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");