@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.js CHANGED
@@ -13048,7 +13048,12 @@ function useMergedGridControls(args) {
13048
13048
  }
13049
13049
  } : {},
13050
13050
  // v7 item 5: Rename opens the record's name cell in place — the grid's own editor.
13051
- ...table?.title_field && fields.some((f) => f.key === table.title_field) && editable ? { renameRow: (rowId) => editing.begin({ rowId, key: table.title_field }) } : {},
13051
+ ...table?.title_field && fields.some((f) => f.key === table.title_field) && editable ? {
13052
+ renameRow: (rowId) => {
13053
+ editing.begin({ rowId, key: table.title_field });
13054
+ selectOpenCellText();
13055
+ }
13056
+ } : {},
13052
13057
  ...hrefForRecord && table ? {
13053
13058
  copyRecordLink: (rowId) => {
13054
13059
  const href = hrefForRecord({ table, recordId: rowId });
@@ -13427,6 +13432,17 @@ function backLinkSentence(column, readers = [], tableName2 = null) {
13427
13432
  if (readers.length === 0) return base;
13428
13433
  return `${readersSentence(readers.length, tableName2)} ${base}`;
13429
13434
  }
13435
+ function selectOpenCellText() {
13436
+ if (typeof window === "undefined") return;
13437
+ requestAnimationFrame(
13438
+ () => requestAnimationFrame(() => {
13439
+ const box = document.querySelector(
13440
+ "[data-matrx-cell-editor] input, [data-matrx-cell-editor] textarea"
13441
+ );
13442
+ box?.select();
13443
+ })
13444
+ );
13445
+ }
13430
13446
 
13431
13447
  // src/Grid.tsx
13432
13448
  import { Button as Button41, ConfirmDialog as ConfirmDialog5, TapTargetSearchGroup, cn as cn34, useIsMobile } from "@ai-matrx/design-system";
@@ -29128,7 +29144,7 @@ function TablePageSkeleton({
29128
29144
  // src/ViewSwitcher.tsx
29129
29145
  import { useEffect as useEffect73, useMemo as useMemo54, useState as useState88 } from "react";
29130
29146
  import { mayDrag as mayDrag4, useFields as useFields18, useRecordPage as useRecordPage2, useRecordsClient as useRecordsClient62, useTable as useTable16 } from "@ai-matrx/records/react";
29131
- import { stableFilterKey as stableFilterKey4 } from "@ai-matrx/records";
29147
+ import { newerKindOf as newerKindOf6, stableFilterKey as stableFilterKey4 } from "@ai-matrx/records";
29132
29148
  import { Button as Button67, Select as Select16, SelectContent as SelectContent16, SelectItem as SelectItem16, SelectTrigger as SelectTrigger16, SelectValue as SelectValue16, cn as cn54 } from "@ai-matrx/design-system";
29133
29149
  import {
29134
29150
  CHOICE_CHIP_CLASS as CHOICE_CHIP_CLASS4,
@@ -29139,16 +29155,163 @@ import {
29139
29155
  } from "@ai-matrx/design-system/data-table";
29140
29156
  import { formatCount as formatCount3 } from "@ai-matrx/kit/format";
29141
29157
 
29158
+ // src/recordMoves.tsx
29159
+ import { useCallback as useCallback35, useEffect as useEffect67, useMemo as useMemo47, useRef as useRef37, useState as useState81 } from "react";
29160
+ import { useRecordsClient as useRecordsClient58 } from "@ai-matrx/records/react";
29161
+ import { Button as Button62 } from "@ai-matrx/design-system";
29162
+ import { Fragment as Fragment38, jsx as jsx96, jsxs as jsxs87 } from "react/jsx-runtime";
29163
+ async function moveRecordValue(client, recordId, patch, expectedVersion) {
29164
+ const written = await updateRecordAt(client, { record_id: recordId, patch, version: expectedVersion });
29165
+ return written.ok ? { ok: true, version: typeof written.data === "number" ? written.data : null } : { ok: false, error: written.error };
29166
+ }
29167
+ function useRecordMoves({
29168
+ tableId,
29169
+ rows,
29170
+ onMoved
29171
+ }) {
29172
+ const client = useRecordsClient58();
29173
+ const [refused, setRefused] = useState81(null);
29174
+ const versions = useRecordVersions(client, rows);
29175
+ const [stale, setStale] = useState81(null);
29176
+ const reload = useCallback35(() => onMoved?.(), [onMoved]);
29177
+ const forget = useCallback35(() => void 0, []);
29178
+ const undo = useGridUndo({
29179
+ tableId,
29180
+ reload,
29181
+ forget,
29182
+ onVersions: (written) => {
29183
+ for (const v of written) versions.wrote(v.id, v.version);
29184
+ }
29185
+ });
29186
+ const move = useCallback35(
29187
+ async ({ recordId, patch, before, label }) => {
29188
+ setRefused(null);
29189
+ setStale(null);
29190
+ const written = await moveRecordValue(client, recordId, patch, await versions.seen(recordId));
29191
+ if (!written.ok) {
29192
+ const changedElsewhere = isChangedElsewhere(written.error);
29193
+ const unread = isVersionUnread(written.error);
29194
+ setRefused({ recordId, error: written.error, changedElsewhere, unread });
29195
+ if (changedElsewhere || unread) {
29196
+ undo.dismiss();
29197
+ setStale({ id: recordId, unread });
29198
+ } else {
29199
+ undo.say(`Not moved. ${refusalSentence(written.error)}`, true);
29200
+ }
29201
+ if (changedElsewhere) {
29202
+ versions.refresh([recordId]);
29203
+ onMoved?.();
29204
+ }
29205
+ return false;
29206
+ }
29207
+ if (written.version !== null) versions.wrote(recordId, written.version);
29208
+ undo.push({
29209
+ label,
29210
+ cells: Object.keys(patch).map((key) => ({
29211
+ rowId: recordId,
29212
+ key,
29213
+ before: before[key] ?? null,
29214
+ after: patch[key],
29215
+ ...written.version !== null ? { version: written.version } : {}
29216
+ }))
29217
+ });
29218
+ onMoved?.();
29219
+ return true;
29220
+ },
29221
+ [client, undo, onMoved, versions]
29222
+ );
29223
+ const create = useCallback35(
29224
+ async ({ tableId: table, data, label }) => {
29225
+ setRefused(null);
29226
+ const written = await client.recordWrite({ table_id: table, data });
29227
+ if (!written.ok) {
29228
+ undo.say(`Nothing was added. ${refusalSentence(written.error)}`, true);
29229
+ return null;
29230
+ }
29231
+ undo.push({ label, cells: [], created: [written.data] });
29232
+ onMoved?.();
29233
+ return written.data;
29234
+ },
29235
+ [client, undo, onMoved]
29236
+ );
29237
+ const offering = Boolean(undo.notice);
29238
+ const undoRef = useRef37(undo);
29239
+ undoRef.current = undo;
29240
+ useEffect67(() => {
29241
+ if (!offering || typeof document === "undefined") return;
29242
+ const onKey = (event) => {
29243
+ const which = undoKey(event);
29244
+ if (!which) return;
29245
+ event.preventDefault();
29246
+ void (which === "undo" ? undoRef.current.undo() : undoRef.current.redo());
29247
+ };
29248
+ document.addEventListener("keydown", onKey);
29249
+ return () => document.removeEventListener("keydown", onKey);
29250
+ }, [offering]);
29251
+ const onKeyDown = useCallback35(
29252
+ (event) => {
29253
+ if (offering) return;
29254
+ const which = undoKey(event);
29255
+ if (!which) return;
29256
+ event.preventDefault();
29257
+ void (which === "undo" ? undo.undo() : undo.redo());
29258
+ },
29259
+ [undo, offering]
29260
+ );
29261
+ const reloadStale = useCallback35(async () => {
29262
+ const id = stale?.id ?? null;
29263
+ setStale(null);
29264
+ setRefused(null);
29265
+ if (!id) return;
29266
+ versions.refresh([id]);
29267
+ onMoved?.();
29268
+ }, [versions, stale, onMoved]);
29269
+ const notice = /* @__PURE__ */ jsxs87(Fragment38, { children: [
29270
+ /* @__PURE__ */ jsx96(UndoNotice, { undo }),
29271
+ stale ? /* @__PURE__ */ jsxs87(
29272
+ "p",
29273
+ {
29274
+ role: "status",
29275
+ "data-records-undo-notice": "refused",
29276
+ "data-move-stale": stale.id,
29277
+ "data-move-unread": stale.unread ? "" : void 0,
29278
+ 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",
29279
+ children: [
29280
+ /* @__PURE__ */ jsx96("span", { children: stale.unread ? VERSION_UNREAD_LABEL : STALE_MOVE_LABEL }),
29281
+ /* @__PURE__ */ jsx96(Button62, { size: "sm", variant: "outline", className: "ml-auto h-6", "data-move-reload": "", onClick: () => void reloadStale(), children: "Reload" }),
29282
+ /* @__PURE__ */ jsx96(Button62, { size: "sm", variant: "ghost", className: "h-6", onClick: () => setStale(null), children: "Dismiss" })
29283
+ ]
29284
+ }
29285
+ ) : null
29286
+ ] });
29287
+ return useMemo47(
29288
+ () => ({ move, create, refused, say: (says, sticky) => undo.say(says, sticky), undo, onKeyDown, notice }),
29289
+ // eslint-disable-next-line react-hooks/exhaustive-deps
29290
+ [move, create, refused, undo, onKeyDown, stale, reloadStale]
29291
+ );
29292
+ }
29293
+ function MoveRefusedBadge({ refused }) {
29294
+ return /* @__PURE__ */ jsx96(
29295
+ "span",
29296
+ {
29297
+ "data-move-refused": refused.changedElsewhere ? "changed-elsewhere" : refused.unread ? "unread" : "refused",
29298
+ title: refused.changedElsewhere ? STALE_MOVE_LABEL : refused.unread ? VERSION_UNREAD_LABEL : refusalSentence(refused.error),
29299
+ className: "mt-0.5 inline-block rounded bg-destructive/10 px-1 text-[10px] font-medium text-destructive",
29300
+ children: refused.changedElsewhere ? STALE_MOVE_LABEL : refused.unread ? VERSION_UNREAD_LABEL : "Not moved"
29301
+ }
29302
+ );
29303
+ }
29304
+
29142
29305
  // src/Pipeline.tsx
29143
- import { useCallback as useCallback36, useEffect as useEffect67, useMemo as useMemo48, useRef as useRef37, useState as useState82 } from "react";
29306
+ import { useCallback as useCallback37, useEffect as useEffect68, useMemo as useMemo49, useRef as useRef38, useState as useState83 } from "react";
29144
29307
  import {
29145
29308
  mayDrag,
29146
29309
  useFields as useFields17,
29147
- useRecordsClient as useRecordsClient59
29310
+ useRecordsClient as useRecordsClient60
29148
29311
  } from "@ai-matrx/records/react";
29149
29312
  import { stableFilterKey as stableFilterKey3 } from "@ai-matrx/records";
29150
29313
  import {
29151
- Button as Button62,
29314
+ Button as Button63,
29152
29315
  DropdownMenu as DropdownMenu8,
29153
29316
  DropdownMenuContent as DropdownMenuContent8,
29154
29317
  DropdownMenuItem as DropdownMenuItem7,
@@ -29163,7 +29326,7 @@ import {
29163
29326
  } from "@ai-matrx/design-system/data-table";
29164
29327
 
29165
29328
  // src/CardDates.tsx
29166
- import { Fragment as Fragment38, jsx as jsx96, jsxs as jsxs87 } from "react/jsx-runtime";
29329
+ import { Fragment as Fragment39, jsx as jsx97, jsxs as jsxs88 } from "react/jsx-runtime";
29167
29330
  function cardDateFields(all, titleField, hiddenFields) {
29168
29331
  const hidden = new Set(hiddenFields ?? []);
29169
29332
  return all.filter(
@@ -29178,14 +29341,14 @@ function CardDates({ record, fields }) {
29178
29341
  return value !== null && value !== void 0 && value !== "";
29179
29342
  });
29180
29343
  if (held.length === 0) return null;
29181
- return /* @__PURE__ */ jsx96(Fragment38, { children: held.map((field2) => /* @__PURE__ */ jsxs87(
29344
+ return /* @__PURE__ */ jsx97(Fragment39, { children: held.map((field2) => /* @__PURE__ */ jsxs88(
29182
29345
  "span",
29183
29346
  {
29184
29347
  className: "mt-0.5 flex min-w-0 items-baseline gap-1 text-[11px] text-muted-foreground",
29185
29348
  "data-card-date": field2.key,
29186
29349
  children: [
29187
- /* @__PURE__ */ jsx96("span", { className: "shrink-0", children: fieldName(field2) }),
29188
- /* @__PURE__ */ jsx96("span", { className: "min-w-0 truncate text-foreground/80", children: /* @__PURE__ */ jsx96(
29350
+ /* @__PURE__ */ jsx97("span", { className: "shrink-0", children: fieldName(field2) }),
29351
+ /* @__PURE__ */ jsx97("span", { className: "min-w-0 truncate text-foreground/80", children: /* @__PURE__ */ jsx97(
29189
29352
  RecordValue,
29190
29353
  {
29191
29354
  field: field2,
@@ -29202,8 +29365,8 @@ function CardDates({ record, fields }) {
29202
29365
 
29203
29366
  // src/RecordActionMenu.tsx
29204
29367
  import { copyText as copyText5 } from "@ai-matrx/kit/clipboard";
29205
- import { useCallback as useCallback35, useMemo as useMemo47, useState as useState81 } from "react";
29206
- import { useFields as useFields16, useRecordsClient as useRecordsClient58, useTable as useTable14 } from "@ai-matrx/records/react";
29368
+ import { useCallback as useCallback36, useMemo as useMemo48, useState as useState82 } from "react";
29369
+ import { useFields as useFields16, useRecordsClient as useRecordsClient59, useTable as useTable14 } from "@ai-matrx/records/react";
29207
29370
  import {
29208
29371
  ContextMenu,
29209
29372
  ContextMenuContent,
@@ -29278,7 +29441,7 @@ function recordActions(input) {
29278
29441
  }
29279
29442
 
29280
29443
  // src/RecordActionMenu.tsx
29281
- import { Fragment as Fragment39, jsx as jsx97, jsxs as jsxs88 } from "react/jsx-runtime";
29444
+ import { Fragment as Fragment40, jsx as jsx98, jsxs as jsxs89 } from "react/jsx-runtime";
29282
29445
  function duplicateValues(fields, document2) {
29283
29446
  const data = {};
29284
29447
  for (const field2 of fields) {
@@ -29289,7 +29452,7 @@ function duplicateValues(fields, document2) {
29289
29452
  return data;
29290
29453
  }
29291
29454
  function useRecordActionHost({ tableId, row, onOpenRecord, onChanged, onMerge }) {
29292
- const client = useRecordsClient58();
29455
+ const client = useRecordsClient59();
29293
29456
  const host = useRecordsUi();
29294
29457
  const fields = useFields16(tableId);
29295
29458
  const table = useTable14(tableId);
@@ -29297,7 +29460,7 @@ function useRecordActionHost({ tableId, row, onOpenRecord, onChanged, onMerge })
29297
29460
  const linkRecord = host.linkRecord;
29298
29461
  const href = host.hrefForRecord && table.data ? host.hrefForRecord({ table: table.data, recordId: row.id }) : void 0;
29299
29462
  const fieldList = fields.data;
29300
- return useMemo47(() => {
29463
+ return useMemo48(() => {
29301
29464
  const said = (sentence2) => notify?.success(sentence2);
29302
29465
  return {
29303
29466
  ...typeof window !== "undefined" ? { origin: window.location.origin } : {},
@@ -29360,7 +29523,7 @@ function useRecordActionHost({ tableId, row, onOpenRecord, onChanged, onMerge })
29360
29523
  }
29361
29524
  function ContextActionItem({ action: action3 }) {
29362
29525
  const disabled = action3.disabledReason !== void 0;
29363
- return /* @__PURE__ */ jsxs88(
29526
+ return /* @__PURE__ */ jsxs89(
29364
29527
  ContextMenuItem,
29365
29528
  {
29366
29529
  disabled,
@@ -29371,43 +29534,43 @@ function ContextActionItem({ action: action3 }) {
29371
29534
  "data-object-action": action3.id,
29372
29535
  className: action3.destructive ? "text-destructive focus:text-destructive" : void 0,
29373
29536
  children: [
29374
- /* @__PURE__ */ jsx97(ObjectActionGlyph, { name: action3.icon, className: "mr-2 h-4 w-4 shrink-0" }),
29375
- /* @__PURE__ */ jsxs88("span", { className: "flex min-w-0 flex-col", children: [
29376
- /* @__PURE__ */ jsx97("span", { children: action3.label }),
29377
- disabled ? /* @__PURE__ */ jsx97("span", { className: "truncate text-xs text-muted-foreground", "data-object-action-reason": "", children: action3.disabledReason }) : null
29537
+ /* @__PURE__ */ jsx98(ObjectActionGlyph, { name: action3.icon, className: "mr-2 h-4 w-4 shrink-0" }),
29538
+ /* @__PURE__ */ jsxs89("span", { className: "flex min-w-0 flex-col", children: [
29539
+ /* @__PURE__ */ jsx98("span", { children: action3.label }),
29540
+ disabled ? /* @__PURE__ */ jsx98("span", { className: "truncate text-xs text-muted-foreground", "data-object-action-reason": "", children: action3.disabledReason }) : null
29378
29541
  ] }),
29379
- action3.shortcut ? /* @__PURE__ */ jsx97(ContextMenuShortcut, { children: action3.shortcut }) : null
29542
+ action3.shortcut ? /* @__PURE__ */ jsx98(ContextMenuShortcut, { children: action3.shortcut }) : null
29380
29543
  ]
29381
29544
  }
29382
29545
  );
29383
29546
  }
29384
29547
  function ObjectActionContextMenuItems({ actions }) {
29385
- return /* @__PURE__ */ jsx97(Fragment39, { children: toDropdownEntries(actions).map((entry) => {
29386
- if (entry.kind === "separator") return /* @__PURE__ */ jsx97(ContextMenuSeparator, {}, entry.id);
29387
- if (entry.kind === "item") return /* @__PURE__ */ jsx97(ContextActionItem, { action: entry.action }, entry.action.id);
29388
- return /* @__PURE__ */ jsxs88(ContextMenuSub, { children: [
29389
- /* @__PURE__ */ jsxs88(ContextMenuSubTrigger, { "data-object-action-group": entry.id, children: [
29390
- entry.icon ? /* @__PURE__ */ jsx97(ObjectActionGlyph, { name: entry.icon, className: "mr-2 h-4 w-4 shrink-0" }) : null,
29548
+ return /* @__PURE__ */ jsx98(Fragment40, { children: toDropdownEntries(actions).map((entry) => {
29549
+ if (entry.kind === "separator") return /* @__PURE__ */ jsx98(ContextMenuSeparator, {}, entry.id);
29550
+ if (entry.kind === "item") return /* @__PURE__ */ jsx98(ContextActionItem, { action: entry.action }, entry.action.id);
29551
+ return /* @__PURE__ */ jsxs89(ContextMenuSub, { children: [
29552
+ /* @__PURE__ */ jsxs89(ContextMenuSubTrigger, { "data-object-action-group": entry.id, children: [
29553
+ entry.icon ? /* @__PURE__ */ jsx98(ObjectActionGlyph, { name: entry.icon, className: "mr-2 h-4 w-4 shrink-0" }) : null,
29391
29554
  entry.label
29392
29555
  ] }),
29393
- /* @__PURE__ */ jsx97(ContextMenuSubContent, { children: entry.actions.map((a) => /* @__PURE__ */ jsx97(ContextActionItem, { action: a }, a.id)) })
29556
+ /* @__PURE__ */ jsx98(ContextMenuSubContent, { children: entry.actions.map((a) => /* @__PURE__ */ jsx98(ContextActionItem, { action: a }, a.id)) })
29394
29557
  ] }, entry.id);
29395
29558
  }) });
29396
29559
  }
29397
29560
  function RecordActionMenu({ tableId, row, name, onOpenRecord, onChanged, children, className }) {
29398
- const [merging, setMerging] = useState81(false);
29399
- const openMerge = useCallback35(() => setMerging(true), []);
29561
+ const [merging, setMerging] = useState82(false);
29562
+ const openMerge = useCallback36(() => setMerging(true), []);
29400
29563
  const actionHost = useRecordActionHost({ tableId, row, onOpenRecord, onChanged, onMerge: openMerge });
29401
- const rights = useMemo47(() => whatYouMayDo(row.level || null, true), [row.level]);
29402
- const actions = useMemo47(
29564
+ const rights = useMemo48(() => whatYouMayDo(row.level || null, true), [row.level]);
29565
+ const actions = useMemo48(
29403
29566
  () => recordActions({ record: { id: row.id, tableId, name }, rights, host: actionHost }),
29404
29567
  [row.id, tableId, name, rights, actionHost]
29405
29568
  );
29406
- return /* @__PURE__ */ jsxs88(ContextMenu, { children: [
29407
- /* @__PURE__ */ jsx97(ContextMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs88("div", { className: cn49("group/record-card relative", className), "data-record-actions": row.id, children: [
29569
+ return /* @__PURE__ */ jsxs89(ContextMenu, { children: [
29570
+ /* @__PURE__ */ jsx98(ContextMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs89("div", { className: cn49("group/record-card relative", className), "data-record-actions": row.id, children: [
29408
29571
  children,
29409
- /* @__PURE__ */ jsxs88(DropdownMenu7, { children: [
29410
- /* @__PURE__ */ jsx97(DropdownMenuTrigger7, { asChild: true, children: /* @__PURE__ */ jsx97(
29572
+ /* @__PURE__ */ jsxs89(DropdownMenu7, { children: [
29573
+ /* @__PURE__ */ jsx98(DropdownMenuTrigger7, { asChild: true, children: /* @__PURE__ */ jsx98(
29411
29574
  "button",
29412
29575
  {
29413
29576
  type: "button",
@@ -29415,18 +29578,18 @@ function RecordActionMenu({ tableId, row, name, onOpenRecord, onChanged, childre
29415
29578
  title: "More",
29416
29579
  "data-record-actions-trigger": row.id,
29417
29580
  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",
29418
- children: /* @__PURE__ */ jsxs88("svg", { viewBox: "0 0 24 24", className: "h-4 w-4", fill: "currentColor", "aria-hidden": "true", children: [
29419
- /* @__PURE__ */ jsx97("circle", { cx: "5", cy: "12", r: "1.75" }),
29420
- /* @__PURE__ */ jsx97("circle", { cx: "12", cy: "12", r: "1.75" }),
29421
- /* @__PURE__ */ jsx97("circle", { cx: "19", cy: "12", r: "1.75" })
29581
+ children: /* @__PURE__ */ jsxs89("svg", { viewBox: "0 0 24 24", className: "h-4 w-4", fill: "currentColor", "aria-hidden": "true", children: [
29582
+ /* @__PURE__ */ jsx98("circle", { cx: "5", cy: "12", r: "1.75" }),
29583
+ /* @__PURE__ */ jsx98("circle", { cx: "12", cy: "12", r: "1.75" }),
29584
+ /* @__PURE__ */ jsx98("circle", { cx: "19", cy: "12", r: "1.75" })
29422
29585
  ] })
29423
29586
  }
29424
29587
  ) }),
29425
- /* @__PURE__ */ jsx97(DropdownMenuContent7, { align: "end", className: "w-56", children: /* @__PURE__ */ jsx97(ObjectActionMenuItems, { actions }) })
29588
+ /* @__PURE__ */ jsx98(DropdownMenuContent7, { align: "end", className: "w-56", children: /* @__PURE__ */ jsx98(ObjectActionMenuItems, { actions }) })
29426
29589
  ] })
29427
29590
  ] }) }),
29428
- /* @__PURE__ */ jsx97(ContextMenuContent, { className: "w-56", children: /* @__PURE__ */ jsx97(ObjectActionContextMenuItems, { actions }) }),
29429
- merging ? /* @__PURE__ */ jsx97(
29591
+ /* @__PURE__ */ jsx98(ContextMenuContent, { className: "w-56", children: /* @__PURE__ */ jsx98(ObjectActionContextMenuItems, { actions }) }),
29592
+ merging ? /* @__PURE__ */ jsx98(
29430
29593
  MergeRecordDialog,
29431
29594
  {
29432
29595
  tableId,
@@ -29440,7 +29603,7 @@ function RecordActionMenu({ tableId, row, name, onOpenRecord, onChanged, childre
29440
29603
  }
29441
29604
 
29442
29605
  // src/Pipeline.tsx
29443
- import { jsx as jsx98, jsxs as jsxs89 } from "react/jsx-runtime";
29606
+ import { jsx as jsx99, jsxs as jsxs90 } from "react/jsx-runtime";
29444
29607
  var UNPLACED = "\0unplaced";
29445
29608
  function stageOfCard(row, stageKey, stages) {
29446
29609
  const document2 = row.document ?? {};
@@ -29474,38 +29637,39 @@ function PipelineBoard({
29474
29637
  onChanged,
29475
29638
  style,
29476
29639
  dateFields,
29640
+ canAdd = false,
29477
29641
  className
29478
29642
  }) {
29479
- const client = useRecordsClient59();
29643
+ const client = useRecordsClient60();
29480
29644
  const fields = useFields17(tableId);
29481
29645
  const ownDecorations = useTableDecorations(style ? null : tableId);
29482
- const cardStyle = useMemo48(
29646
+ const cardStyle = useMemo49(
29483
29647
  () => style ?? resolveTableStyle(ownDecorations.data, fields.data ?? [], void 0),
29484
29648
  [style, ownDecorations.data, fields.data]
29485
29649
  );
29486
- const [definition, setDefinition] = useState82(null);
29487
- const [columns, setColumns] = useState82([]);
29488
- const [error, setError] = useState82(null);
29489
- const [loading, setLoading] = useState82(true);
29490
- const [pending, setPending] = useState82({ kind: "none" });
29491
- const [waiting, setWaiting] = useState82(/* @__PURE__ */ new Map());
29492
- const [dragging, setDragging] = useState82(null);
29493
- const [over, setOver] = useState82(null);
29494
- const alive = useRef37(true);
29495
- const [selected, setSelected] = useState82(/* @__PURE__ */ new Set());
29496
- const anchor = useRef37(null);
29497
- const [batch, setBatch] = useState82(/* @__PURE__ */ new Map());
29498
- const [batchSaid, setBatchSaid] = useState82(null);
29499
- const [batchError, setBatchError] = useState82(null);
29500
- const [moving, setMoving] = useState82(false);
29501
- useEffect67(() => {
29650
+ const [definition, setDefinition] = useState83(null);
29651
+ const [columns, setColumns] = useState83([]);
29652
+ const [error, setError] = useState83(null);
29653
+ const [loading, setLoading] = useState83(true);
29654
+ const [pending, setPending] = useState83({ kind: "none" });
29655
+ const [waiting, setWaiting] = useState83(/* @__PURE__ */ new Map());
29656
+ const [dragging, setDragging] = useState83(null);
29657
+ const [over, setOver] = useState83(null);
29658
+ const alive = useRef38(true);
29659
+ const [selected, setSelected] = useState83(/* @__PURE__ */ new Set());
29660
+ const anchor = useRef38(null);
29661
+ const [batch, setBatch] = useState83(/* @__PURE__ */ new Map());
29662
+ const [batchSaid, setBatchSaid] = useState83(null);
29663
+ const [batchError, setBatchError] = useState83(null);
29664
+ const [moving, setMoving] = useState83(false);
29665
+ useEffect68(() => {
29502
29666
  alive.current = true;
29503
29667
  return () => {
29504
29668
  alive.current = false;
29505
29669
  };
29506
29670
  }, []);
29507
29671
  const filterKey = stableFilterKey3(filter);
29508
- const reload = useCallback36(async () => {
29672
+ const reload = useCallback37(async () => {
29509
29673
  setLoading(true);
29510
29674
  const [read, board, held] = await Promise.all([
29511
29675
  client.pipelineRead({ table_id: tableId }),
@@ -29523,15 +29687,23 @@ function PipelineBoard({
29523
29687
  setWaiting(held.ok ? new Map((held.data ?? []).map((p) => [p.record_id, p])) : /* @__PURE__ */ new Map());
29524
29688
  setColumns(board.ok ? board.data ?? [] : []);
29525
29689
  }, [client, tableId, measure, filterKey]);
29526
- useEffect67(() => {
29690
+ useEffect68(() => {
29527
29691
  void reload();
29528
29692
  }, [reload]);
29529
29693
  const versions = useRecordVersions(client, rows, (r) => mayDrag(r.level));
29530
- const versionsRef = useRef37(versions);
29694
+ const versionsRef = useRef38(versions);
29531
29695
  versionsRef.current = versions;
29532
29696
  const drawnVersion = (id) => versionsRef.current.seen(id);
29533
29697
  const stageKey = definition?.stage_field ?? null;
29534
- const cardsByStage = useMemo48(() => {
29698
+ const adds = useRecordMoves({ tableId, rows, ...onMoved ? { onMoved } : {} });
29699
+ const addInStage = async (key, label) => {
29700
+ if (!stageKey) return;
29701
+ const made = await adds.create({ tableId, data: { [stageKey]: key }, label: `New record in ${label}` });
29702
+ if (!made) return;
29703
+ onChanged?.();
29704
+ onOpenRecord?.(made);
29705
+ };
29706
+ const cardsByStage = useMemo49(() => {
29535
29707
  const map = /* @__PURE__ */ new Map();
29536
29708
  if (!stageKey) return map;
29537
29709
  for (const row of rows) {
@@ -29542,16 +29714,16 @@ function PipelineBoard({
29542
29714
  }, [rows, stageKey, definition?.stages]);
29543
29715
  const unplaced = cardsByStage.get(UNPLACED) ?? [];
29544
29716
  const all = fields.data ?? [];
29545
- const titleField = useMemo48(
29717
+ const titleField = useMemo49(
29546
29718
  () => cardTitleField(all, titleKey ?? null, [stageKey]),
29547
29719
  [all, stageKey, titleKey]
29548
29720
  );
29549
29721
  const unplacedLabels = useRecordLabels(titleField ? [titleField] : []);
29550
- const measurable = useMemo48(
29722
+ const measurable = useMemo49(
29551
29723
  () => all.filter((f) => ["number", "currency", "percentage"].includes(String(f.type ?? ""))),
29552
29724
  [all]
29553
29725
  );
29554
- const drop = useCallback36(
29726
+ const drop = useCallback37(
29555
29727
  async (recordId, to) => {
29556
29728
  setOver(null);
29557
29729
  setDragging(null);
@@ -29591,7 +29763,7 @@ function PipelineBoard({
29591
29763
  },
29592
29764
  [client, onMoved, reload]
29593
29765
  );
29594
- const askForApproval = useCallback36(
29766
+ const askForApproval = useCallback37(
29595
29767
  async (recordId, to) => {
29596
29768
  const moved = await movePipelineCardAt(client, { record_id: recordId, to, version: await drawnVersion(recordId) });
29597
29769
  if (!alive.current) return;
@@ -29606,7 +29778,7 @@ function PipelineBoard({
29606
29778
  },
29607
29779
  [client, onMoved, reload]
29608
29780
  );
29609
- const moveWith = useCallback36(
29781
+ const moveWith = useCallback37(
29610
29782
  async (recordId, to, also) => {
29611
29783
  const moved = await movePipelineCardAt(client, { record_id: recordId, to, also, version: await drawnVersion(recordId) });
29612
29784
  if (!alive.current) return;
@@ -29670,15 +29842,15 @@ function PipelineBoard({
29670
29842
  onMoved?.();
29671
29843
  void reload();
29672
29844
  };
29673
- if (fields.error) return /* @__PURE__ */ jsx98(RefusalNotice, { error: fields.error });
29674
- if (error) return /* @__PURE__ */ jsx98(RefusalNotice, { error });
29675
- if (loading || fields.loading && !fields.data) return /* @__PURE__ */ jsx98(Skeleton11, { className: "h-40 w-full" });
29845
+ if (fields.error) return /* @__PURE__ */ jsx99(RefusalNotice, { error: fields.error });
29846
+ if (error) return /* @__PURE__ */ jsx99(RefusalNotice, { error });
29847
+ if (loading || fields.loading && !fields.data) return /* @__PURE__ */ jsx99(Skeleton11, { className: "h-40 w-full" });
29676
29848
  if (!definition?.is_pipeline) {
29677
- return /* @__PURE__ */ jsx98("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." });
29849
+ return /* @__PURE__ */ jsx99("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." });
29678
29850
  }
29679
29851
  const stages = definition.stages ?? [];
29680
29852
  const numbers = new Map(columns.map((c) => [c.stage_key, c]));
29681
- return /* @__PURE__ */ jsxs89(
29853
+ return /* @__PURE__ */ jsxs90(
29682
29854
  "div",
29683
29855
  {
29684
29856
  className: cn50("flex min-h-0 flex-col gap-2", className),
@@ -29689,7 +29861,7 @@ function PipelineBoard({
29689
29861
  }
29690
29862
  },
29691
29863
  children: [
29692
- selectedInOrder.length > 0 ? /* @__PURE__ */ jsxs89(
29864
+ selectedInOrder.length > 0 ? /* @__PURE__ */ jsxs90(
29693
29865
  "div",
29694
29866
  {
29695
29867
  "data-records-bulk-bar": true,
@@ -29697,40 +29869,40 @@ function PipelineBoard({
29697
29869
  "aria-label": "Selected cards",
29698
29870
  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",
29699
29871
  children: [
29700
- /* @__PURE__ */ jsxs89("span", { className: "font-medium", children: [
29872
+ /* @__PURE__ */ jsxs90("span", { className: "font-medium", children: [
29701
29873
  selectedInOrder.length,
29702
29874
  " ",
29703
29875
  selectedInOrder.length === 1 ? "card" : "cards",
29704
29876
  " selected"
29705
29877
  ] }),
29706
- /* @__PURE__ */ jsx98(Button62, { size: "sm", variant: "ghost", className: "h-7 px-2 text-xs", onClick: clearSelection, children: "Clear" }),
29707
- /* @__PURE__ */ jsxs89(DropdownMenu8, { children: [
29708
- /* @__PURE__ */ jsx98(DropdownMenuTrigger8, { asChild: true, children: /* @__PURE__ */ jsx98(Button62, { size: "sm", className: "h-7 px-2 text-xs", disabled: moving, children: moving ? `Moving ${selectedInOrder.length}\u2026` : `Move ${selectedInOrder.length} to\u2026` }) }),
29709
- /* @__PURE__ */ jsx98(DropdownMenuContent8, { align: "start", children: stages.map((stage) => /* @__PURE__ */ jsxs89(DropdownMenuItem7, { onSelect: () => void moveSelected(stage.key, stage.label), children: [
29878
+ /* @__PURE__ */ jsx99(Button63, { size: "sm", variant: "ghost", className: "h-7 px-2 text-xs", onClick: clearSelection, children: "Clear" }),
29879
+ /* @__PURE__ */ jsxs90(DropdownMenu8, { children: [
29880
+ /* @__PURE__ */ jsx99(DropdownMenuTrigger8, { asChild: true, children: /* @__PURE__ */ jsx99(Button63, { size: "sm", className: "h-7 px-2 text-xs", disabled: moving, children: moving ? `Moving ${selectedInOrder.length}\u2026` : `Move ${selectedInOrder.length} to\u2026` }) }),
29881
+ /* @__PURE__ */ jsx99(DropdownMenuContent8, { align: "start", children: stages.map((stage) => /* @__PURE__ */ jsxs90(DropdownMenuItem7, { onSelect: () => void moveSelected(stage.key, stage.label), children: [
29710
29882
  "Move ",
29711
29883
  selectedInOrder.length,
29712
29884
  " to ",
29713
29885
  stage.label
29714
29886
  ] }, stage.key)) })
29715
29887
  ] }),
29716
- /* @__PURE__ */ jsx98("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" })
29888
+ /* @__PURE__ */ jsx99("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" })
29717
29889
  ]
29718
29890
  }
29719
29891
  ) : null,
29720
- batchError ? /* @__PURE__ */ jsx98(
29892
+ batchError ? /* @__PURE__ */ jsx99(
29721
29893
  RefusalNotice,
29722
29894
  {
29723
29895
  error: batchError,
29724
- actions: /* @__PURE__ */ jsx98(Button62, { size: "sm", variant: "ghost", className: "mt-1 h-6", onClick: () => setBatchError(null), children: "Close" })
29896
+ actions: /* @__PURE__ */ jsx99(Button63, { size: "sm", variant: "ghost", className: "mt-1 h-6", onClick: () => setBatchError(null), children: "Close" })
29725
29897
  }
29726
29898
  ) : null,
29727
- batchSaid ? /* @__PURE__ */ jsxs89("p", { className: "flex items-center gap-2 text-xs", role: "status", "data-testid": "pipeline-batch-said", children: [
29728
- /* @__PURE__ */ jsx98("span", { children: batchSaid }),
29729
- /* @__PURE__ */ jsx98(Button62, { size: "sm", variant: "ghost", className: "h-6 px-2", onClick: () => setBatchSaid(null), children: "Close" })
29899
+ batchSaid ? /* @__PURE__ */ jsxs90("p", { className: "flex items-center gap-2 text-xs", role: "status", "data-testid": "pipeline-batch-said", children: [
29900
+ /* @__PURE__ */ jsx99("span", { children: batchSaid }),
29901
+ /* @__PURE__ */ jsx99(Button63, { size: "sm", variant: "ghost", className: "h-6 px-2", onClick: () => setBatchSaid(null), children: "Close" })
29730
29902
  ] }) : null,
29731
- measurable.length > 0 && onMeasureChange ? /* @__PURE__ */ jsxs89("div", { className: "flex items-center gap-1.5 text-xs", children: [
29732
- /* @__PURE__ */ jsx98("label", { className: "text-muted-foreground", htmlFor: "pipeline-measure", children: "Total" }),
29733
- /* @__PURE__ */ jsx98(
29903
+ measurable.length > 0 && onMeasureChange ? /* @__PURE__ */ jsxs90("div", { className: "flex items-center gap-1.5 text-xs", children: [
29904
+ /* @__PURE__ */ jsx99("label", { className: "text-muted-foreground", htmlFor: "pipeline-measure", children: "Total" }),
29905
+ /* @__PURE__ */ jsx99(
29734
29906
  PickOne,
29735
29907
  {
29736
29908
  id: "pipeline-measure",
@@ -29741,10 +29913,10 @@ function PipelineBoard({
29741
29913
  }
29742
29914
  )
29743
29915
  ] }) : null,
29744
- /* @__PURE__ */ jsx98("div", { className: "flex min-h-0 gap-2 overflow-x-auto pb-2", "data-records-board": true, children: stages.map((stage) => {
29916
+ /* @__PURE__ */ jsx99("div", { className: "flex min-h-0 gap-2 overflow-x-auto pb-2", "data-records-board": true, children: stages.map((stage) => {
29745
29917
  const n = numbers.get(stage.key);
29746
29918
  const cards = cardsByStage.get(stage.key) ?? [];
29747
- return /* @__PURE__ */ jsxs89(
29919
+ return /* @__PURE__ */ jsxs90(
29748
29920
  "section",
29749
29921
  {
29750
29922
  onDragOver: (e) => {
@@ -29763,23 +29935,23 @@ function PipelineBoard({
29763
29935
  n?.over_limit ? "border-destructive" : ""
29764
29936
  ),
29765
29937
  children: [
29766
- /* @__PURE__ */ jsxs89("header", { className: "flex items-baseline gap-2 border-b px-2 py-1 text-xs font-medium", children: [
29767
- /* @__PURE__ */ jsx98("span", { className: "truncate", children: stage.label }),
29768
- /* @__PURE__ */ jsxs89("span", { className: "ml-auto shrink-0 tabular-nums text-muted-foreground", children: [
29938
+ /* @__PURE__ */ jsxs90("header", { className: "flex items-baseline gap-2 border-b px-2 py-1 text-xs font-medium", children: [
29939
+ /* @__PURE__ */ jsx99("span", { className: "truncate", children: stage.label }),
29940
+ /* @__PURE__ */ jsxs90("span", { className: "ml-auto shrink-0 tabular-nums text-muted-foreground", children: [
29769
29941
  n ? n.cards : cards.length,
29770
29942
  n?.wip_limit != null ? ` / ${n.wip_limit}` : "",
29771
29943
  n?.total != null ? ` \xB7 ${formatTotal(n.total)}` : ""
29772
29944
  ] })
29773
29945
  ] }),
29774
- n?.over_limit ? /* @__PURE__ */ jsxs89("p", { className: "border-b px-2 py-1 text-xs text-destructive", children: [
29946
+ n?.over_limit ? /* @__PURE__ */ jsxs90("p", { className: "border-b px-2 py-1 text-xs text-destructive", children: [
29775
29947
  "This column takes ",
29776
29948
  n.wip_limit,
29777
29949
  " at a time and holds ",
29778
29950
  n.cards,
29779
29951
  "."
29780
29952
  ] }) : null,
29781
- /* @__PURE__ */ jsx98("ul", { className: "flex flex-col gap-1 p-1", children: cards.map((card) => /* @__PURE__ */ jsxs89("li", { children: [
29782
- /* @__PURE__ */ jsx98(
29953
+ /* @__PURE__ */ jsx99("ul", { className: "flex flex-col gap-1 p-1", children: cards.map((card) => /* @__PURE__ */ jsxs90("li", { children: [
29954
+ /* @__PURE__ */ jsx99(
29783
29955
  RecordActionMenu,
29784
29956
  {
29785
29957
  tableId,
@@ -29790,7 +29962,7 @@ function PipelineBoard({
29790
29962
  onChanged?.();
29791
29963
  void reload();
29792
29964
  },
29793
- children: /* @__PURE__ */ jsx98(
29965
+ children: /* @__PURE__ */ jsx99(
29794
29966
  PipelineCard,
29795
29967
  {
29796
29968
  record: card,
@@ -29813,7 +29985,7 @@ function PipelineBoard({
29813
29985
  )
29814
29986
  }
29815
29987
  ),
29816
- pending.kind !== "none" && pending.recordId === card.id ? /* @__PURE__ */ jsx98(
29988
+ pending.kind !== "none" && pending.recordId === card.id ? /* @__PURE__ */ jsx99(
29817
29989
  Held,
29818
29990
  {
29819
29991
  pending,
@@ -29825,7 +29997,7 @@ function PipelineBoard({
29825
29997
  ) : batch.get(card.id) ? (
29826
29998
  // WHAT THIS CARD'S PART OF THE BATCH CAME TO, on the card — the store's
29827
29999
  // own sentence, and for a stage that asked for columns, the columns.
29828
- /* @__PURE__ */ jsx98(
30000
+ /* @__PURE__ */ jsx99(
29829
30001
  Held,
29830
30002
  {
29831
30003
  pending: batch.get(card.id),
@@ -29851,13 +30023,23 @@ function PipelineBoard({
29851
30023
  }
29852
30024
  )
29853
30025
  ) : null
29854
- ] }, card.id)) })
30026
+ ] }, card.id)) }),
30027
+ canAdd && stageKey ? /* @__PURE__ */ jsx99(
30028
+ "button",
30029
+ {
30030
+ type: "button",
30031
+ "data-board-add": stage.label,
30032
+ className: "mx-1 mb-1 self-start rounded px-1 py-0.5 text-xs text-muted-foreground hover:bg-muted hover:text-foreground",
30033
+ onClick: () => void addInStage(stage.key, stage.label),
30034
+ children: "+ New"
30035
+ }
30036
+ ) : null
29855
30037
  ]
29856
30038
  },
29857
30039
  stage.key
29858
30040
  );
29859
30041
  }) }),
29860
- unplaced.length > 0 ? /* @__PURE__ */ jsxs89("p", { className: "text-xs text-muted-foreground", "data-testid": "pipeline-unplaced", children: [
30042
+ unplaced.length > 0 ? /* @__PURE__ */ jsxs90("p", { className: "text-xs text-muted-foreground", "data-testid": "pipeline-unplaced", children: [
29861
30043
  unplaced.length === 1 ? "One record is" : `${unplaced.length} records are`,
29862
30044
  " not in any of these columns \u2014 ",
29863
30045
  unplaced.slice(0, 3).map((r) => unplacedName(r, titleField, unplacedLabels)).join(", "),
@@ -29878,17 +30060,17 @@ function Held({
29878
30060
  onFill,
29879
30061
  onAsk
29880
30062
  }) {
29881
- const [draft, setDraft] = useState82({});
30063
+ const [draft, setDraft] = useState83({});
29882
30064
  if (pending.kind === "asking") {
29883
- return /* @__PURE__ */ jsx98("p", { className: "px-2 py-1 text-xs text-muted-foreground", children: "Asking\u2026" });
30065
+ return /* @__PURE__ */ jsx99("p", { className: "px-2 py-1 text-xs text-muted-foreground", children: "Asking\u2026" });
29884
30066
  }
29885
30067
  if (pending.kind === "clash") {
29886
- return /* @__PURE__ */ jsx98(
30068
+ return /* @__PURE__ */ jsx99(
29887
30069
  RefusalNotice,
29888
30070
  {
29889
30071
  className: "mt-1",
29890
30072
  error: pending.error,
29891
- actions: /* @__PURE__ */ jsx98("div", { className: "mt-1", children: /* @__PURE__ */ jsx98(Button62, { size: "sm", variant: "ghost", className: "h-6", onClick: onCancel, children: "Close" }) })
30073
+ actions: /* @__PURE__ */ jsx99("div", { className: "mt-1", children: /* @__PURE__ */ jsx99(Button63, { size: "sm", variant: "ghost", className: "h-6", onClick: onCancel, children: "Close" }) })
29892
30074
  }
29893
30075
  );
29894
30076
  }
@@ -29896,7 +30078,7 @@ function Held({
29896
30078
  return (
29897
30079
  // THE STAGE GATE SAID NO: the one refusal surface, heading and remedy both,
29898
30080
  // never its sentence alone in a red box (lane REFUSAL-SWEEP).
29899
- /* @__PURE__ */ jsx98(
30081
+ /* @__PURE__ */ jsx99(
29900
30082
  RefusalNotice,
29901
30083
  {
29902
30084
  className: "mt-1",
@@ -29905,50 +30087,50 @@ function Held({
29905
30087
  pending.verdict.why,
29906
30088
  "The card stays where it was. Fill in what this stage asks for, then move it again."
29907
30089
  ),
29908
- actions: /* @__PURE__ */ jsx98(Button62, { size: "sm", variant: "ghost", className: "mt-1 h-6", onClick: onCancel, children: "Close" })
30090
+ actions: /* @__PURE__ */ jsx99(Button63, { size: "sm", variant: "ghost", className: "mt-1 h-6", onClick: onCancel, children: "Close" })
29909
30091
  }
29910
30092
  )
29911
30093
  );
29912
30094
  }
29913
30095
  if (pending.kind === "approval") {
29914
- return /* @__PURE__ */ jsxs89("div", { className: "mt-1 flex flex-col gap-1 rounded border p-2 text-xs", children: [
29915
- /* @__PURE__ */ jsx98("p", { children: pending.verdict.why }),
29916
- pending.verdict.what_happens ? /* @__PURE__ */ jsx98("p", { className: "text-muted-foreground", children: pending.verdict.what_happens }) : null,
29917
- /* @__PURE__ */ jsxs89("div", { className: "flex items-center gap-1", children: [
29918
- /* @__PURE__ */ jsx98(Button62, { size: "sm", className: "h-6", onClick: onAsk, children: "Ask for approval" }),
29919
- /* @__PURE__ */ jsx98(Button62, { size: "sm", variant: "ghost", className: "h-6", onClick: onCancel, children: "Leave it where it was" })
30096
+ return /* @__PURE__ */ jsxs90("div", { className: "mt-1 flex flex-col gap-1 rounded border p-2 text-xs", children: [
30097
+ /* @__PURE__ */ jsx99("p", { children: pending.verdict.why }),
30098
+ pending.verdict.what_happens ? /* @__PURE__ */ jsx99("p", { className: "text-muted-foreground", children: pending.verdict.what_happens }) : null,
30099
+ /* @__PURE__ */ jsxs90("div", { className: "flex items-center gap-1", children: [
30100
+ /* @__PURE__ */ jsx99(Button63, { size: "sm", className: "h-6", onClick: onAsk, children: "Ask for approval" }),
30101
+ /* @__PURE__ */ jsx99(Button63, { size: "sm", variant: "ghost", className: "h-6", onClick: onCancel, children: "Leave it where it was" })
29920
30102
  ] })
29921
30103
  ] });
29922
30104
  }
29923
30105
  if (pending.kind === "filed") {
29924
- return /* @__PURE__ */ jsxs89("div", { className: "mt-1 rounded border p-2 text-xs", children: [
29925
- /* @__PURE__ */ jsx98("p", { children: pending.result.what_happens ?? "This is waiting for somebody who can approve it. It has not moved." }),
29926
- (pending.result.approvers ?? []).length > 0 ? /* @__PURE__ */ jsxs89("p", { className: "text-muted-foreground", children: [
30106
+ return /* @__PURE__ */ jsxs90("div", { className: "mt-1 rounded border p-2 text-xs", children: [
30107
+ /* @__PURE__ */ jsx99("p", { children: pending.result.what_happens ?? "This is waiting for somebody who can approve it. It has not moved." }),
30108
+ (pending.result.approvers ?? []).length > 0 ? /* @__PURE__ */ jsxs90("p", { className: "text-muted-foreground", children: [
29927
30109
  "With",
29928
30110
  " ",
29929
30111
  (pending.result.approvers ?? []).map((a) => a.name ?? "somebody who can approve it").join(", "),
29930
30112
  "."
29931
30113
  ] }) : null,
29932
- /* @__PURE__ */ jsx98(Button62, { size: "sm", variant: "ghost", className: "mt-1 h-6", onClick: onCancel, children: "Close" })
30114
+ /* @__PURE__ */ jsx99(Button63, { size: "sm", variant: "ghost", className: "mt-1 h-6", onClick: onCancel, children: "Close" })
29933
30115
  ] });
29934
30116
  }
29935
30117
  if (pending.kind === "warned") {
29936
- return /* @__PURE__ */ jsxs89("div", { className: "mt-1 flex flex-col gap-1 rounded border border-amber-500/50 bg-amber-500/5 p-2 text-xs", children: [
29937
- pending.warnings.map((w) => /* @__PURE__ */ jsxs89("div", { children: [
29938
- /* @__PURE__ */ jsx98("p", { children: w.why }),
29939
- /* @__PURE__ */ jsx98("p", { className: "text-muted-foreground", children: w.what_to_do })
30118
+ return /* @__PURE__ */ jsxs90("div", { className: "mt-1 flex flex-col gap-1 rounded border border-amber-500/50 bg-amber-500/5 p-2 text-xs", children: [
30119
+ pending.warnings.map((w) => /* @__PURE__ */ jsxs90("div", { children: [
30120
+ /* @__PURE__ */ jsx99("p", { children: w.why }),
30121
+ /* @__PURE__ */ jsx99("p", { className: "text-muted-foreground", children: w.what_to_do })
29940
30122
  ] }, w.rule_id)),
29941
- /* @__PURE__ */ jsx98(Button62, { size: "sm", variant: "ghost", className: "h-6 self-start", onClick: onCancel, children: "Close" })
30123
+ /* @__PURE__ */ jsx99(Button63, { size: "sm", variant: "ghost", className: "h-6 self-start", onClick: onCancel, children: "Close" })
29942
30124
  ] });
29943
30125
  }
29944
30126
  if (pending.kind !== "needs") return null;
29945
30127
  const missing = pending.verdict.missing ?? [];
29946
30128
  const ready = missing.every((m) => (draft[m.key] ?? "").trim() !== "");
29947
- return /* @__PURE__ */ jsxs89("div", { className: "mt-1 flex flex-col gap-1 rounded border p-2 text-xs", children: [
29948
- /* @__PURE__ */ jsx98("p", { children: pending.verdict.why }),
29949
- missing.map((m) => /* @__PURE__ */ jsxs89("label", { className: "flex flex-col gap-0.5", children: [
29950
- /* @__PURE__ */ jsx98("span", { className: "text-muted-foreground", children: m.label }),
29951
- /* @__PURE__ */ jsx98(
30129
+ return /* @__PURE__ */ jsxs90("div", { className: "mt-1 flex flex-col gap-1 rounded border p-2 text-xs", children: [
30130
+ /* @__PURE__ */ jsx99("p", { children: pending.verdict.why }),
30131
+ missing.map((m) => /* @__PURE__ */ jsxs90("label", { className: "flex flex-col gap-0.5", children: [
30132
+ /* @__PURE__ */ jsx99("span", { className: "text-muted-foreground", children: m.label }),
30133
+ /* @__PURE__ */ jsx99(
29952
30134
  "input",
29953
30135
  {
29954
30136
  className: "h-7 rounded border bg-background px-1",
@@ -29957,21 +30139,21 @@ function Held({
29957
30139
  }
29958
30140
  )
29959
30141
  ] }, m.key)),
29960
- /* @__PURE__ */ jsxs89("div", { className: "flex items-center gap-1", children: [
29961
- ready ? /* @__PURE__ */ jsx98(
29962
- Button62,
30142
+ /* @__PURE__ */ jsxs90("div", { className: "flex items-center gap-1", children: [
30143
+ ready ? /* @__PURE__ */ jsx99(
30144
+ Button63,
29963
30145
  {
29964
30146
  size: "sm",
29965
30147
  className: "h-6",
29966
30148
  onClick: () => onFill(Object.fromEntries(missing.map((m) => [m.key, draft[m.key]]))),
29967
30149
  children: "Fill in and move"
29968
30150
  }
29969
- ) : /* @__PURE__ */ jsxs89("span", { className: "text-muted-foreground", children: [
30151
+ ) : /* @__PURE__ */ jsxs90("span", { className: "text-muted-foreground", children: [
29970
30152
  "Fill ",
29971
30153
  missing.length === 1 ? "it" : "them",
29972
30154
  " in and the move goes through."
29973
30155
  ] }),
29974
- /* @__PURE__ */ jsx98(Button62, { size: "sm", variant: "ghost", className: "h-6", onClick: onCancel, children: "Leave it where it was" })
30156
+ /* @__PURE__ */ jsx99(Button63, { size: "sm", variant: "ghost", className: "h-6", onClick: onCancel, children: "Leave it where it was" })
29975
30157
  ] }),
29976
30158
  fields.length === 0 ? null : null
29977
30159
  ] });
@@ -29995,7 +30177,7 @@ function PipelineCard({
29995
30177
  const color = style ? resolveRowColor(style, { id: record.id, data: record.document ?? {} }, colorFromTheValue) : null;
29996
30178
  const draggable = mayDrag(record.level);
29997
30179
  const { text: label, withheld } = cardWords(record, field2, labels);
29998
- return /* @__PURE__ */ jsxs89(
30180
+ return /* @__PURE__ */ jsxs90(
29999
30181
  "button",
30000
30182
  {
30001
30183
  type: "button",
@@ -30036,9 +30218,9 @@ function PipelineCard({
30036
30218
  title: `${withheld ?? label}${draggable ? "" : " \u2014 you can look at this, but not move it."}`,
30037
30219
  ...withheld && field2 ? { "data-records-withheld": field2.key } : {},
30038
30220
  children: [
30039
- /* @__PURE__ */ jsx98("span", { className: "block truncate", children: label }),
30040
- dates && dates.length > 0 ? /* @__PURE__ */ jsx98(CardDates, { record, fields: dates }) : null,
30041
- waiting ? /* @__PURE__ */ jsxs89(
30221
+ /* @__PURE__ */ jsx99("span", { className: "block truncate", children: label }),
30222
+ dates && dates.length > 0 ? /* @__PURE__ */ jsx99(CardDates, { record, fields: dates }) : null,
30223
+ waiting ? /* @__PURE__ */ jsxs90(
30042
30224
  "span",
30043
30225
  {
30044
30226
  className: "mt-0.5 block truncate text-[10px] font-medium text-amber-600 dark:text-amber-400",
@@ -30115,159 +30297,61 @@ function batchSentence(moved, waiting, notMoved, label) {
30115
30297
  return said;
30116
30298
  }
30117
30299
 
30118
- // src/CalendarView.tsx
30119
- import { useEffect as useEffect69, useMemo as useMemo51, useRef as useRef39, useState as useState84 } from "react";
30120
- import { mayDrag as mayDrag2 } from "@ai-matrx/records/react";
30121
- import { Button as Button64, Select as Select13, SelectContent as SelectContent13, SelectItem as SelectItem13, SelectTrigger as SelectTrigger13, SelectValue as SelectValue13, cn as cn51 } from "@ai-matrx/design-system";
30122
- import { CHOICE_CHIP_CLASS as CHOICE_CHIP_CLASS2 } from "@ai-matrx/design-system/data-table";
30123
-
30124
- // src/recordMoves.tsx
30125
- import { useCallback as useCallback37, useEffect as useEffect68, useMemo as useMemo49, useRef as useRef38, useState as useState83 } from "react";
30126
- import { useRecordsClient as useRecordsClient60 } from "@ai-matrx/records/react";
30127
- import { Button as Button63 } from "@ai-matrx/design-system";
30128
- import { Fragment as Fragment40, jsx as jsx99, jsxs as jsxs90 } from "react/jsx-runtime";
30129
- async function moveRecordValue(client, recordId, patch, expectedVersion) {
30130
- const written = await updateRecordAt(client, { record_id: recordId, patch, version: expectedVersion });
30131
- return written.ok ? { ok: true, version: typeof written.data === "number" ? written.data : null } : { ok: false, error: written.error };
30300
+ // src/cardFields.tsx
30301
+ import { jsx as jsx100, jsxs as jsxs91 } from "react/jsx-runtime";
30302
+ function isEmptyOnCard(value) {
30303
+ return value === null || value === void 0 || value === "" || Array.isArray(value) && value.length === 0;
30132
30304
  }
30133
- function useRecordMoves({
30134
- tableId,
30135
- rows,
30136
- onMoved
30305
+ function cardFieldsShown(fields, hiddenFields, exclude) {
30306
+ const hidden = new Set(hiddenFields ?? []);
30307
+ const out = new Set(exclude.filter((k) => Boolean(k)));
30308
+ return fields.filter((field2) => !hidden.has(field2.key) && !out.has(field2.key));
30309
+ }
30310
+ function CardFieldsPicker({
30311
+ fields,
30312
+ hiddenFields,
30313
+ summary,
30314
+ onChange,
30315
+ remembered,
30316
+ layout
30137
30317
  }) {
30138
- const client = useRecordsClient60();
30139
- const [refused, setRefused] = useState83(null);
30140
- const versions = useRecordVersions(client, rows);
30141
- const [stale, setStale] = useState83(null);
30142
- const reload = useCallback37(() => onMoved?.(), [onMoved]);
30143
- const forget = useCallback37(() => void 0, []);
30144
- const undo = useGridUndo({
30145
- tableId,
30146
- reload,
30147
- forget,
30148
- onVersions: (written) => {
30149
- for (const v of written) versions.wrote(v.id, v.version);
30150
- }
30151
- });
30152
- const move = useCallback37(
30153
- async ({ recordId, patch, before, label }) => {
30154
- setRefused(null);
30155
- setStale(null);
30156
- const written = await moveRecordValue(client, recordId, patch, await versions.seen(recordId));
30157
- if (!written.ok) {
30158
- const changedElsewhere = isChangedElsewhere(written.error);
30159
- const unread = isVersionUnread(written.error);
30160
- setRefused({ recordId, error: written.error, changedElsewhere, unread });
30161
- if (changedElsewhere || unread) {
30162
- undo.dismiss();
30163
- setStale({ id: recordId, unread });
30164
- } else {
30165
- undo.say(`Not moved. ${refusalSentence(written.error)}`, true);
30166
- }
30167
- if (changedElsewhere) {
30168
- versions.refresh([recordId]);
30169
- onMoved?.();
30318
+ const hidden = new Set(hiddenFields ?? []);
30319
+ return /* @__PURE__ */ jsxs91("details", { className: "text-xs text-muted-foreground", "data-records-card-fields": layout, children: [
30320
+ /* @__PURE__ */ jsx100("summary", { className: "cursor-pointer select-none", children: summary }),
30321
+ /* @__PURE__ */ jsx100("div", { className: "mt-1 flex flex-wrap gap-2", children: fields.map((field2) => /* @__PURE__ */ jsxs91("label", { className: "flex items-center gap-1", children: [
30322
+ /* @__PURE__ */ jsx100(
30323
+ "input",
30324
+ {
30325
+ type: "checkbox",
30326
+ checked: !hidden.has(field2.key),
30327
+ "data-records-card-field": field2.key,
30328
+ onChange: (event) => {
30329
+ const next = new Set(hidden);
30330
+ if (event.target.checked) next.delete(field2.key);
30331
+ else next.add(field2.key);
30332
+ onChange([...next]);
30333
+ }
30170
30334
  }
30171
- return false;
30172
- }
30173
- if (written.version !== null) versions.wrote(recordId, written.version);
30174
- undo.push({
30175
- label,
30176
- cells: Object.keys(patch).map((key) => ({
30177
- rowId: recordId,
30178
- key,
30179
- before: before[key] ?? null,
30180
- after: patch[key],
30181
- ...written.version !== null ? { version: written.version } : {}
30182
- }))
30183
- });
30184
- onMoved?.();
30185
- return true;
30186
- },
30187
- [client, undo, onMoved, versions]
30188
- );
30189
- const create = useCallback37(
30190
- async ({ tableId: table, data, label }) => {
30191
- setRefused(null);
30192
- const written = await client.recordWrite({ table_id: table, data });
30193
- if (!written.ok) {
30194
- undo.say(`Nothing was added. ${refusalSentence(written.error)}`, true);
30195
- return null;
30196
- }
30197
- undo.push({ label, cells: [], created: [written.data] });
30198
- onMoved?.();
30199
- return written.data;
30200
- },
30201
- [client, undo, onMoved]
30202
- );
30203
- const offering = Boolean(undo.notice);
30204
- const undoRef = useRef38(undo);
30205
- undoRef.current = undo;
30206
- useEffect68(() => {
30207
- if (!offering || typeof document === "undefined") return;
30208
- const onKey = (event) => {
30209
- const which = undoKey(event);
30210
- if (!which) return;
30211
- event.preventDefault();
30212
- void (which === "undo" ? undoRef.current.undo() : undoRef.current.redo());
30213
- };
30214
- document.addEventListener("keydown", onKey);
30215
- return () => document.removeEventListener("keydown", onKey);
30216
- }, [offering]);
30217
- const onKeyDown = useCallback37(
30218
- (event) => {
30219
- if (offering) return;
30220
- const which = undoKey(event);
30221
- if (!which) return;
30222
- event.preventDefault();
30223
- void (which === "undo" ? undo.undo() : undo.redo());
30224
- },
30225
- [undo, offering]
30226
- );
30227
- const reloadStale = useCallback37(async () => {
30228
- const id = stale?.id ?? null;
30229
- setStale(null);
30230
- setRefused(null);
30231
- if (!id) return;
30232
- versions.refresh([id]);
30233
- onMoved?.();
30234
- }, [versions, stale, onMoved]);
30235
- const notice = /* @__PURE__ */ jsxs90(Fragment40, { children: [
30236
- /* @__PURE__ */ jsx99(UndoNotice, { undo }),
30237
- stale ? /* @__PURE__ */ jsxs90(
30238
- "p",
30239
- {
30240
- role: "status",
30241
- "data-records-undo-notice": "refused",
30242
- "data-move-stale": stale.id,
30243
- "data-move-unread": stale.unread ? "" : void 0,
30244
- 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",
30245
- children: [
30246
- /* @__PURE__ */ jsx99("span", { children: stale.unread ? VERSION_UNREAD_LABEL : STALE_MOVE_LABEL }),
30247
- /* @__PURE__ */ jsx99(Button63, { size: "sm", variant: "outline", className: "ml-auto h-6", "data-move-reload": "", onClick: () => void reloadStale(), children: "Reload" }),
30248
- /* @__PURE__ */ jsx99(Button63, { size: "sm", variant: "ghost", className: "h-6", onClick: () => setStale(null), children: "Dismiss" })
30249
- ]
30250
- }
30251
- ) : null
30335
+ ),
30336
+ fieldName(field2)
30337
+ ] }, field2.key)) }),
30338
+ remembered ? null : /* @__PURE__ */ jsx100("p", { className: "mt-1", children: "Kept for this visit only \u2014 this screen has nowhere to save it onto the view." })
30252
30339
  ] });
30253
- return useMemo49(
30254
- () => ({ move, create, refused, say: (says, sticky) => undo.say(says, sticky), undo, onKeyDown, notice }),
30255
- // eslint-disable-next-line react-hooks/exhaustive-deps
30256
- [move, create, refused, undo, onKeyDown, stale, reloadStale]
30257
- );
30258
30340
  }
30259
- function MoveRefusedBadge({ refused }) {
30260
- return /* @__PURE__ */ jsx99(
30261
- "span",
30262
- {
30263
- "data-move-refused": refused.changedElsewhere ? "changed-elsewhere" : refused.unread ? "unread" : "refused",
30264
- title: refused.changedElsewhere ? STALE_MOVE_LABEL : refused.unread ? VERSION_UNREAD_LABEL : refusalSentence(refused.error),
30265
- className: "mt-0.5 inline-block rounded bg-destructive/10 px-1 text-[10px] font-medium text-destructive",
30266
- children: refused.changedElsewhere ? STALE_MOVE_LABEL : refused.unread ? VERSION_UNREAD_LABEL : "Not moved"
30267
- }
30268
- );
30341
+ function CardFieldsInline({ row, fields }) {
30342
+ if (!fields || fields.length === 0) return null;
30343
+ const doc = row.document ?? {};
30344
+ const parts = fields.filter((f) => !isEmptyOnCard(doc[f.key])).map((f) => scalarText(f, doc[f.key]));
30345
+ if (parts.length === 0) return null;
30346
+ return /* @__PURE__ */ jsx100("span", { className: "min-w-0 shrink truncate opacity-75", "data-card-fields-inline": "", children: parts.map((p) => ` \xB7 ${p}`).join("") });
30269
30347
  }
30270
30348
 
30349
+ // src/CalendarView.tsx
30350
+ import { useEffect as useEffect69, useMemo as useMemo51, useRef as useRef39, useState as useState84 } from "react";
30351
+ import { mayDrag as mayDrag2 } from "@ai-matrx/records/react";
30352
+ import { Button as Button64, Select as Select13, SelectContent as SelectContent13, SelectItem as SelectItem13, SelectTrigger as SelectTrigger13, SelectValue as SelectValue13, cn as cn51 } from "@ai-matrx/design-system";
30353
+ import { CHOICE_CHIP_CLASS as CHOICE_CHIP_CLASS2 } from "@ai-matrx/design-system/data-table";
30354
+
30271
30355
  // src/rowColorBy.tsx
30272
30356
  import { useMemo as useMemo50 } from "react";
30273
30357
  import { EMPTY_TABLE_STYLE, resolveRowColor as resolveRowColor2 } from "@ai-matrx/design-system/data-table";
@@ -30447,7 +30531,7 @@ function lookupTargets(all) {
30447
30531
  }
30448
30532
 
30449
30533
  // src/CalendarView.tsx
30450
- import { Fragment as Fragment41, jsx as jsx100, jsxs as jsxs91 } from "react/jsx-runtime";
30534
+ import { Fragment as Fragment41, jsx as jsx101, jsxs as jsxs92 } from "react/jsx-runtime";
30451
30535
  var DRAG_TYPE = "application/x-records-card";
30452
30536
  var NONE = "__none__";
30453
30537
  var HOUR_PX = 44;
@@ -30558,12 +30642,13 @@ function byTime(a, b) {
30558
30642
  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);
30559
30643
  }
30560
30644
  function LockIcon() {
30561
- return /* @__PURE__ */ jsxs91("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: [
30562
- /* @__PURE__ */ jsx100("rect", { x: "3.5", y: "7", width: "9", height: "6.5", rx: "1" }),
30563
- /* @__PURE__ */ jsx100("path", { d: "M5.5 7V5a2.5 2.5 0 0 1 5 0v2" })
30645
+ return /* @__PURE__ */ jsxs92("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: [
30646
+ /* @__PURE__ */ jsx101("rect", { x: "3.5", y: "7", width: "9", height: "6.5", rx: "1" }),
30647
+ /* @__PURE__ */ jsx101("path", { d: "M5.5 7V5a2.5 2.5 0 0 1 5 0v2" })
30564
30648
  ] });
30565
30649
  }
30566
30650
  function CalendarView({
30651
+ cardFields,
30567
30652
  tableId,
30568
30653
  rows,
30569
30654
  dateField,
@@ -30867,7 +30952,7 @@ function CalendarView({
30867
30952
  const lockWords = mayDrag2(row.level) ? WORKED_OUT_DATE_LOCK : "View only";
30868
30953
  const color = colorOf(row);
30869
30954
  const title = titleOf(row);
30870
- return /* @__PURE__ */ jsxs91(
30955
+ return /* @__PURE__ */ jsxs92(
30871
30956
  "button",
30872
30957
  {
30873
30958
  type: "button",
@@ -30883,19 +30968,20 @@ function CalendarView({
30883
30968
  ...color ? { "data-calendar-color": color } : {},
30884
30969
  ...may ? { "aria-keyshortcuts": "Alt+ArrowLeft Alt+ArrowRight Alt+ArrowUp Alt+ArrowDown" } : { "data-calendar-locked": "" },
30885
30970
  children: [
30886
- may ? null : /* @__PURE__ */ jsx100("span", { title: lockWords, "aria-label": lockWords, className: "inline-flex", ...mayDrag2(row.level) ? { "data-calendar-worked-out": "" } : {}, children: /* @__PURE__ */ jsx100(LockIcon, {}) }),
30971
+ may ? null : /* @__PURE__ */ jsx101("span", { title: lockWords, "aria-label": lockWords, className: "inline-flex", ...mayDrag2(row.level) ? { "data-calendar-worked-out": "" } : {}, children: /* @__PURE__ */ jsx101(LockIcon, {}) }),
30887
30972
  extra,
30888
- /* @__PURE__ */ jsx100("span", { className: "min-w-0 truncate", children: title })
30973
+ /* @__PURE__ */ jsx101("span", { className: "min-w-0 truncate", children: title }),
30974
+ /* @__PURE__ */ jsx101(CardFieldsInline, { row, fields: cardFields })
30889
30975
  ]
30890
30976
  }
30891
30977
  );
30892
30978
  };
30893
- const refusalOn = (row) => moves.refused?.recordId === row.id ? /* @__PURE__ */ jsx100(MoveRefusedBadge, { refused: moves.refused }) : null;
30979
+ const refusalOn = (row) => moves.refused?.recordId === row.id ? /* @__PURE__ */ jsx101(MoveRefusedBadge, { refused: moves.refused }) : null;
30894
30980
  const timeOn = (row) => {
30895
30981
  const words2 = timeOfDayWords(startOf(row));
30896
- return words2 ? /* @__PURE__ */ jsx100("span", { className: "shrink-0 tabular-nums text-[10px] opacity-75", "data-calendar-time": "", children: words2 }) : null;
30982
+ return words2 ? /* @__PURE__ */ jsx101("span", { className: "shrink-0 tabular-nums text-[10px] opacity-75", "data-calendar-time": "", children: words2 }) : null;
30897
30983
  };
30898
- const listCard = (p, key) => /* @__PURE__ */ jsxs91("li", { ...dragSource(p.row), children: [
30984
+ const listCard = (p, key) => /* @__PURE__ */ jsxs92("li", { ...dragSource(p.row), children: [
30899
30985
  cardFace(p.row, timeOn(p.row)),
30900
30986
  refusalOn(p.row)
30901
30987
  ] }, key);
@@ -30907,18 +30993,18 @@ function CalendarView({
30907
30993
  else if (mode === "day") setAnchor(addDays2(anchor, dir));
30908
30994
  else setAnchor(dayKey(new Date(anchorDate.getFullYear(), anchorDate.getMonth() + dir, 1)));
30909
30995
  };
30910
- const picker = (label, value, candidates, onPick, kept, unusual) => /* @__PURE__ */ jsxs91("div", { className: "flex items-center gap-1.5 whitespace-nowrap text-xs", "data-calendar-setting": label, children: [
30911
- /* @__PURE__ */ jsx100("span", { className: "text-muted-foreground", children: label }),
30912
- /* @__PURE__ */ jsxs91(Select13, { value: value ?? NONE, onValueChange: (v) => onPick(v === NONE ? null : v), children: [
30913
- /* @__PURE__ */ jsx100(SelectTrigger13, { size: "sm", className: "h-7 min-w-24 text-xs", "aria-label": `${label} column`, ...kept ? {} : { title: "Kept for this visit only" }, children: /* @__PURE__ */ jsx100(SelectValue13, { placeholder: "Choose" }) }),
30914
- /* @__PURE__ */ jsxs91(SelectContent13, { children: [
30915
- /* @__PURE__ */ jsx100(SelectItem13, { value: NONE, children: "None" }),
30916
- candidates.map((f) => /* @__PURE__ */ jsx100(SelectItem13, { value: f.key, children: fieldName(f) }, f.key)),
30917
- unusual ? /* @__PURE__ */ jsx100(SelectItem13, { value: unusual.key, "data-calendar-unusual": "", children: `${fieldName(unusual)} \u2014 ${UNUSUAL_FIELD_NOTE}` }, unusual.key) : null
30996
+ const picker = (label, value, candidates, onPick, kept, unusual) => /* @__PURE__ */ jsxs92("div", { className: "flex items-center gap-1.5 whitespace-nowrap text-xs", "data-calendar-setting": label, children: [
30997
+ /* @__PURE__ */ jsx101("span", { className: "text-muted-foreground", children: label }),
30998
+ /* @__PURE__ */ jsxs92(Select13, { value: value ?? NONE, onValueChange: (v) => onPick(v === NONE ? null : v), children: [
30999
+ /* @__PURE__ */ jsx101(SelectTrigger13, { size: "sm", className: "h-7 min-w-24 text-xs", "aria-label": `${label} column`, ...kept ? {} : { title: "Kept for this visit only" }, children: /* @__PURE__ */ jsx101(SelectValue13, { placeholder: "Choose" }) }),
31000
+ /* @__PURE__ */ jsxs92(SelectContent13, { children: [
31001
+ /* @__PURE__ */ jsx101(SelectItem13, { value: NONE, children: "None" }),
31002
+ candidates.map((f) => /* @__PURE__ */ jsx101(SelectItem13, { value: f.key, children: fieldName(f) }, f.key)),
31003
+ unusual ? /* @__PURE__ */ jsx101(SelectItem13, { value: unusual.key, "data-calendar-unusual": "", children: `${fieldName(unusual)} \u2014 ${UNUSUAL_FIELD_NOTE}` }, unusual.key) : null
30918
31004
  ] })
30919
31005
  ] })
30920
31006
  ] });
30921
- const pickers = all.length > 0 ? /* @__PURE__ */ jsxs91(Fragment41, { children: [
31007
+ const pickers = all.length > 0 ? /* @__PURE__ */ jsxs92(Fragment41, { children: [
30922
31008
  otherDates.length > 0 || endUnusual ? picker("End", endField?.key ?? null, otherDates, (key) => {
30923
31009
  setEndPick(key);
30924
31010
  onEndFieldChange?.(key);
@@ -30928,35 +31014,35 @@ function CalendarView({
30928
31014
  onColorFieldChange?.(key);
30929
31015
  }, true) : null
30930
31016
  ] }) : null;
30931
- const toolbar = /* @__PURE__ */ jsxs91("div", { className: "flex flex-wrap items-center gap-2", children: [
30932
- /* @__PURE__ */ jsx100(Button64, { size: "sm", variant: "outline", onClick: () => setAnchor(today), children: "Today" }),
30933
- mode !== "list" ? /* @__PURE__ */ jsxs91(Fragment41, { children: [
30934
- /* @__PURE__ */ jsx100(Button64, { size: "sm", variant: "ghost", "aria-label": "Previous", onClick: () => step2(-1), children: "\u2039" }),
30935
- /* @__PURE__ */ jsx100(Button64, { size: "sm", variant: "ghost", "aria-label": "Next", onClick: () => step2(1), children: "\u203A" }),
30936
- /* @__PURE__ */ jsx100("h3", { className: "text-sm font-medium", "data-calendar-heading": "", children: heading })
31017
+ const toolbar = /* @__PURE__ */ jsxs92("div", { className: "flex flex-wrap items-center gap-2", children: [
31018
+ /* @__PURE__ */ jsx101(Button64, { size: "sm", variant: "outline", onClick: () => setAnchor(today), children: "Today" }),
31019
+ mode !== "list" ? /* @__PURE__ */ jsxs92(Fragment41, { children: [
31020
+ /* @__PURE__ */ jsx101(Button64, { size: "sm", variant: "ghost", "aria-label": "Previous", onClick: () => step2(-1), children: "\u2039" }),
31021
+ /* @__PURE__ */ jsx101(Button64, { size: "sm", variant: "ghost", "aria-label": "Next", onClick: () => step2(1), children: "\u203A" }),
31022
+ /* @__PURE__ */ jsx101("h3", { className: "text-sm font-medium", "data-calendar-heading": "", children: heading })
30937
31023
  ] }) : null,
30938
- /* @__PURE__ */ jsxs91("div", { className: "ml-auto flex flex-wrap items-center gap-2", children: [
31024
+ /* @__PURE__ */ jsxs92("div", { className: "ml-auto flex flex-wrap items-center gap-2", children: [
30939
31025
  pickers,
30940
- /* @__PURE__ */ jsx100("div", { className: "flex items-center gap-0.5", role: "group", "aria-label": "Calendar layout", children: ["month", "week", "day", "list"].map((m) => /* @__PURE__ */ jsx100(Button64, { 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)) })
31026
+ /* @__PURE__ */ jsx101("div", { className: "flex items-center gap-0.5", role: "group", "aria-label": "Calendar layout", children: ["month", "week", "day", "list"].map((m) => /* @__PURE__ */ jsx101(Button64, { 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)) })
30941
31027
  ] })
30942
31028
  ] });
30943
31029
  const tray = undated.length > 0 ? (
30944
31030
  // Nothing fails silently: a record with no date waits here and drags onto a day.
30945
- /* @__PURE__ */ jsxs91("aside", { className: "flex min-w-0 flex-col gap-1 sm:w-56 sm:shrink-0", "data-calendar-undated": "", children: [
30946
- /* @__PURE__ */ jsxs91("h4", { className: "text-xs font-medium", children: [
31031
+ /* @__PURE__ */ jsxs92("aside", { className: "flex min-w-0 flex-col gap-1 sm:w-56 sm:shrink-0", "data-calendar-undated": "", children: [
31032
+ /* @__PURE__ */ jsxs92("h4", { className: "text-xs font-medium", children: [
30947
31033
  "Unscheduled \xB7 ",
30948
31034
  undated.length
30949
31035
  ] }),
30950
- /* @__PURE__ */ jsx100("ul", { className: "flex flex-col gap-1 overflow-y-auto", children: undated.map((row) => listCard({ row }, `tray:${row.id}`)) })
31036
+ /* @__PURE__ */ jsx101("ul", { className: "flex flex-col gap-1 overflow-y-auto", children: undated.map((row) => listCard({ row }, `tray:${row.id}`)) })
30951
31037
  ] })
30952
31038
  ) : null;
30953
31039
  let body;
30954
31040
  if (mode === "month") {
30955
31041
  const first = startOfWeek(dayKey(new Date(anchorDate.getFullYear(), anchorDate.getMonth(), 1)));
30956
31042
  const weeks = Array.from({ length: 6 }, (_, w) => addDays2(first, w * 7));
30957
- body = /* @__PURE__ */ jsx100("div", { className: "min-w-0 flex-1 overflow-x-auto", children: /* @__PURE__ */ jsxs91("div", { className: "min-w-[560px] border-l border-t", role: "grid", "aria-label": heading, "data-calendar-month": "", children: [
30958
- /* @__PURE__ */ jsx100("div", { className: "grid grid-cols-7", role: "row", children: Array.from({ length: 7 }, (_, i) => addDays2(first, i)).map((d) => /* @__PURE__ */ jsx100("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}`)) }),
30959
- weeks.map((ws) => /* @__PURE__ */ jsx100(
31043
+ body = /* @__PURE__ */ jsx101("div", { className: "min-w-0 flex-1 overflow-x-auto", children: /* @__PURE__ */ jsxs92("div", { className: "min-w-[560px] border-l border-t", role: "grid", "aria-label": heading, "data-calendar-month": "", children: [
31044
+ /* @__PURE__ */ jsx101("div", { className: "grid grid-cols-7", role: "row", children: Array.from({ length: 7 }, (_, i) => addDays2(first, i)).map((d) => /* @__PURE__ */ jsx101("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}`)) }),
31045
+ weeks.map((ws) => /* @__PURE__ */ jsx101(
30960
31046
  MonthWeek,
30961
31047
  {
30962
31048
  weekStart: ws,
@@ -30971,11 +31057,11 @@ function CalendarView({
30971
31057
  canCreate: creates,
30972
31058
  onCreate: (d) => void createAt(rescheduledValue(null, d, null, moments), null, calendarDayLabel(d)),
30973
31059
  card: (p, key) => listCard(p, key),
30974
- bar: (p, key) => /* @__PURE__ */ jsxs91("div", { ...dragSource(p.row), className: "relative h-full", children: [
31060
+ bar: (p, key) => /* @__PURE__ */ jsxs92("div", { ...dragSource(p.row), className: "relative h-full", children: [
30975
31061
  cardFace(p.row, null, "h-full"),
30976
- endField && canMove(p.row) ? /* @__PURE__ */ jsxs91(Fragment41, { children: [
30977
- /* @__PURE__ */ jsx100("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") }),
30978
- /* @__PURE__ */ jsx100("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") })
31062
+ endField && canMove(p.row) ? /* @__PURE__ */ jsxs92(Fragment41, { children: [
31063
+ /* @__PURE__ */ jsx101("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") }),
31064
+ /* @__PURE__ */ jsx101("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") })
30979
31065
  ] }) : null
30980
31066
  ] }, key),
30981
31067
  refusalOn
@@ -30995,14 +31081,14 @@ function CalendarView({
30995
31081
  })
30996
31082
  );
30997
31083
  const columns = `3.5rem repeat(${days.length}, minmax(0, 1fr))`;
30998
- body = /* @__PURE__ */ jsx100("div", { className: "min-w-0 flex-1 overflow-x-auto", children: /* @__PURE__ */ jsxs91("div", { className: cn51("border-l border-t", days.length > 1 ? "min-w-[640px]" : ""), "data-calendar-week": "", "data-calendar-days": days.length, children: [
30999
- /* @__PURE__ */ jsxs91("div", { className: "grid", style: { gridTemplateColumns: columns }, children: [
31000
- /* @__PURE__ */ jsx100("div", { className: "border-b border-r" }),
31001
- days.map((d) => /* @__PURE__ */ jsx100("div", { className: cn51("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}`)),
31002
- /* @__PURE__ */ jsx100("div", { className: "border-b border-r px-1 py-0.5 text-[10px] text-muted-foreground", children: "All day" }),
31003
- days.map((d) => /* @__PURE__ */ jsx100("div", { "data-calendar-day": d, className: cn51("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__ */ jsx100("ul", { className: "flex flex-col gap-0.5", children: allDay(d).map((p) => listCard(p, `${p.row.id}:${d}`)) }) }, `a${d}`))
31084
+ body = /* @__PURE__ */ jsx101("div", { className: "min-w-0 flex-1 overflow-x-auto", children: /* @__PURE__ */ jsxs92("div", { className: cn51("border-l border-t", days.length > 1 ? "min-w-[640px]" : ""), "data-calendar-week": "", "data-calendar-days": days.length, children: [
31085
+ /* @__PURE__ */ jsxs92("div", { className: "grid", style: { gridTemplateColumns: columns }, children: [
31086
+ /* @__PURE__ */ jsx101("div", { className: "border-b border-r" }),
31087
+ days.map((d) => /* @__PURE__ */ jsx101("div", { className: cn51("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}`)),
31088
+ /* @__PURE__ */ jsx101("div", { className: "border-b border-r px-1 py-0.5 text-[10px] text-muted-foreground", children: "All day" }),
31089
+ days.map((d) => /* @__PURE__ */ jsx101("div", { "data-calendar-day": d, className: cn51("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__ */ jsx101("ul", { className: "flex flex-col gap-0.5", children: allDay(d).map((p) => listCard(p, `${p.row.id}:${d}`)) }) }, `a${d}`))
31004
31090
  ] }),
31005
- /* @__PURE__ */ jsx100(
31091
+ /* @__PURE__ */ jsx101(
31006
31092
  WeekHours,
31007
31093
  {
31008
31094
  days,
@@ -31010,8 +31096,8 @@ function CalendarView({
31010
31096
  today,
31011
31097
  timeDrop,
31012
31098
  onSlotPointerDown: creates ? beginSelect : void 0,
31013
- overlay: (d) => /* @__PURE__ */ jsxs91(Fragment41, { children: [
31014
- ghost && ghost.day === d && ghost.minute !== null ? /* @__PURE__ */ jsx100(
31099
+ overlay: (d) => /* @__PURE__ */ jsxs92(Fragment41, { children: [
31100
+ ghost && ghost.day === d && ghost.minute !== null ? /* @__PURE__ */ jsx101(
31015
31101
  "div",
31016
31102
  {
31017
31103
  "aria-hidden": "true",
@@ -31021,7 +31107,7 @@ function CalendarView({
31021
31107
  children: `${dayDate(d).toLocaleDateString(void 0, { weekday: "short" })} ${timeLabel(ghost.minute)}`
31022
31108
  }
31023
31109
  ) : null,
31024
- selecting && selecting.day === d ? /* @__PURE__ */ jsx100(
31110
+ selecting && selecting.day === d ? /* @__PURE__ */ jsx101(
31025
31111
  "div",
31026
31112
  {
31027
31113
  "aria-hidden": "true",
@@ -31034,7 +31120,7 @@ function CalendarView({
31034
31120
  ] }),
31035
31121
  render: (d) => timed(d).map(({ p, start, end, col, cols }) => {
31036
31122
  const tight = cols > 1 && end - start < 45;
31037
- return /* @__PURE__ */ jsxs91(
31123
+ return /* @__PURE__ */ jsxs92(
31038
31124
  "div",
31039
31125
  {
31040
31126
  ...dragSource(p.row),
@@ -31044,11 +31130,11 @@ function CalendarView({
31044
31130
  children: [
31045
31131
  cardFace(
31046
31132
  p.row,
31047
- tight ? null : /* @__PURE__ */ jsx100("span", { className: "shrink-0 tabular-nums text-[10px] opacity-75", "data-calendar-time": "", children: timeLabel(start) }),
31133
+ tight ? null : /* @__PURE__ */ jsx101("span", { className: "shrink-0 tabular-nums text-[10px] opacity-75", "data-calendar-time": "", children: timeLabel(start) }),
31048
31134
  // Taller blocks sharing the width stack the time over the name.
31049
31135
  cn51("h-full items-start", !tight && end - start >= 45 && cols > 1 ? "flex-col gap-0" : void 0)
31050
31136
  ),
31051
- endField && !endWorkedOut && canMove(p.row) ? /* @__PURE__ */ jsx100(
31137
+ endField && !endWorkedOut && canMove(p.row) ? /* @__PURE__ */ jsx101(
31052
31138
  "div",
31053
31139
  {
31054
31140
  role: "separator",
@@ -31060,7 +31146,7 @@ function CalendarView({
31060
31146
  ) : null,
31061
31147
  moves.refused?.recordId === p.row.id ? (
31062
31148
  // Above the block, never inside it where a neighbour covers it; the full sentence floats.
31063
- /* @__PURE__ */ jsx100("div", { className: "absolute left-0 top-full z-30", children: refusalOn(p.row) })
31149
+ /* @__PURE__ */ jsx101("div", { className: "absolute left-0 top-full z-30", children: refusalOn(p.row) })
31064
31150
  ) : null
31065
31151
  ]
31066
31152
  },
@@ -31074,12 +31160,12 @@ function CalendarView({
31074
31160
  const byDay = /* @__PURE__ */ new Map();
31075
31161
  for (const p of placed) for (let d = p.firstDay; d <= p.lastDay; d = addDays2(d, 1)) byDay.set(d, [...byDay.get(d) ?? [], p]);
31076
31162
  const listed = [...byDay.entries()].sort((a, b) => a[0].localeCompare(b[0])).map(([d, cards]) => [d, [...cards].sort(byTime)]);
31077
- body = /* @__PURE__ */ jsx100("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__ */ jsxs91("li", { className: "flex gap-3 p-2", "data-calendar-day": d, ...dayDrop(d), children: [
31078
- /* @__PURE__ */ jsx100("span", { className: cn51("w-24 shrink-0 text-xs font-medium tabular-nums", d === today ? "text-primary" : ""), children: calendarDayLabel(d) }),
31079
- /* @__PURE__ */ jsx100("ul", { className: "flex min-w-0 flex-1 flex-col gap-1", children: cards.map((p) => listCard(p, `${p.row.id}:${d}`)) })
31163
+ body = /* @__PURE__ */ jsx101("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__ */ jsxs92("li", { className: "flex gap-3 p-2", "data-calendar-day": d, ...dayDrop(d), children: [
31164
+ /* @__PURE__ */ jsx101("span", { className: cn51("w-24 shrink-0 text-xs font-medium tabular-nums", d === today ? "text-primary" : ""), children: calendarDayLabel(d) }),
31165
+ /* @__PURE__ */ jsx101("ul", { className: "flex min-w-0 flex-1 flex-col gap-1", children: cards.map((p) => listCard(p, `${p.row.id}:${d}`)) })
31080
31166
  ] }, d)) });
31081
31167
  }
31082
- return /* @__PURE__ */ jsxs91(
31168
+ return /* @__PURE__ */ jsxs92(
31083
31169
  "div",
31084
31170
  {
31085
31171
  ref: frame,
@@ -31090,9 +31176,9 @@ function CalendarView({
31090
31176
  if (!frame.current?.contains(e.relatedTarget)) setGhost(null);
31091
31177
  },
31092
31178
  children: [
31093
- note ? /* @__PURE__ */ jsx100("p", { className: "text-xs text-muted-foreground", children: note }) : null,
31179
+ note ? /* @__PURE__ */ jsx101("p", { className: "text-xs text-muted-foreground", children: note }) : null,
31094
31180
  toolbar,
31095
- /* @__PURE__ */ jsxs91("div", { className: "flex min-h-0 flex-col gap-3 sm:flex-row", children: [
31181
+ /* @__PURE__ */ jsxs92("div", { className: "flex min-h-0 flex-col gap-3 sm:flex-row", children: [
31096
31182
  body,
31097
31183
  tray
31098
31184
  ] }),
@@ -31129,7 +31215,7 @@ function MonthWeek({
31129
31215
  });
31130
31216
  const lanesShown = Math.min(laneEnds.length, MONTH_ROWS - 1);
31131
31217
  const singlesFit = MONTH_ROWS - lanesShown;
31132
- return /* @__PURE__ */ jsxs91("div", { className: "relative grid grid-cols-7", role: "row", "data-calendar-week-row": weekStart, children: [
31218
+ return /* @__PURE__ */ jsxs92("div", { className: "relative grid grid-cols-7", role: "row", "data-calendar-week-row": weekStart, children: [
31133
31219
  days.map((d) => {
31134
31220
  const inMonth = dayDate(d).getMonth() === month;
31135
31221
  const singles = placed.filter((p) => p.lastDay === p.firstDay && p.firstDay === d).sort(byTime);
@@ -31141,7 +31227,7 @@ function MonthWeek({
31141
31227
  if (e.target.closest("button, [data-calendar-card], [role=dialog]")) return;
31142
31228
  onCreate(d);
31143
31229
  };
31144
- return /* @__PURE__ */ jsxs91(
31230
+ return /* @__PURE__ */ jsxs92(
31145
31231
  "div",
31146
31232
  {
31147
31233
  role: "gridcell",
@@ -31156,8 +31242,8 @@ function MonthWeek({
31156
31242
  ...dayDrop(d),
31157
31243
  ...canCreate ? { onClick: create } : {},
31158
31244
  children: [
31159
- /* @__PURE__ */ jsxs91("div", { className: "flex items-center", children: [
31160
- canCreate ? /* @__PURE__ */ jsx100(
31245
+ /* @__PURE__ */ jsxs92("div", { className: "flex items-center", children: [
31246
+ canCreate ? /* @__PURE__ */ jsx101(
31161
31247
  "button",
31162
31248
  {
31163
31249
  type: "button",
@@ -31168,7 +31254,7 @@ function MonthWeek({
31168
31254
  children: "+"
31169
31255
  }
31170
31256
  ) : null,
31171
- /* @__PURE__ */ jsx100(
31257
+ /* @__PURE__ */ jsx101(
31172
31258
  "span",
31173
31259
  {
31174
31260
  className: cn51(
@@ -31179,14 +31265,14 @@ function MonthWeek({
31179
31265
  }
31180
31266
  )
31181
31267
  ] }),
31182
- /* @__PURE__ */ jsx100("div", { style: { height: lanesShown * BAR_PX }, "aria-hidden": "true" }),
31183
- /* @__PURE__ */ jsx100("ul", { className: "flex flex-col gap-0.5", children: shown4.map((p) => card(p, `${p.row.id}:${d}`)) }),
31184
- more > 0 ? /* @__PURE__ */ jsxs91("button", { type: "button", className: "self-start px-1 text-xs text-muted-foreground hover:text-foreground", "data-calendar-more": d, onClick: () => onOpenDay(d), children: [
31268
+ /* @__PURE__ */ jsx101("div", { style: { height: lanesShown * BAR_PX }, "aria-hidden": "true" }),
31269
+ /* @__PURE__ */ jsx101("ul", { className: "flex flex-col gap-0.5", children: shown4.map((p) => card(p, `${p.row.id}:${d}`)) }),
31270
+ more > 0 ? /* @__PURE__ */ jsxs92("button", { type: "button", className: "self-start px-1 text-xs text-muted-foreground hover:text-foreground", "data-calendar-more": d, onClick: () => onOpenDay(d), children: [
31185
31271
  "+",
31186
31272
  more,
31187
31273
  " more"
31188
31274
  ] }) : null,
31189
- openDay === d ? /* @__PURE__ */ jsxs91(
31275
+ openDay === d ? /* @__PURE__ */ jsxs92(
31190
31276
  "div",
31191
31277
  {
31192
31278
  role: "dialog",
@@ -31197,11 +31283,11 @@ function MonthWeek({
31197
31283
  if (e.key === "Escape") onOpenDay(null);
31198
31284
  },
31199
31285
  children: [
31200
- /* @__PURE__ */ jsxs91("div", { className: "flex items-center", children: [
31201
- /* @__PURE__ */ jsx100("span", { className: "text-xs font-medium", children: calendarDayLabel(d) }),
31202
- /* @__PURE__ */ jsx100(Button64, { size: "sm", variant: "ghost", className: "ml-auto h-6", "aria-label": "Close", onClick: () => onOpenDay(null), children: "\xD7" })
31286
+ /* @__PURE__ */ jsxs92("div", { className: "flex items-center", children: [
31287
+ /* @__PURE__ */ jsx101("span", { className: "text-xs font-medium", children: calendarDayLabel(d) }),
31288
+ /* @__PURE__ */ jsx101(Button64, { size: "sm", variant: "ghost", className: "ml-auto h-6", "aria-label": "Close", onClick: () => onOpenDay(null), children: "\xD7" })
31203
31289
  ] }),
31204
- /* @__PURE__ */ jsx100("ul", { className: "flex flex-col gap-0.5", children: everything.map((p) => card(p, `open:${p.row.id}:${d}`)) })
31290
+ /* @__PURE__ */ jsx101("ul", { className: "flex flex-col gap-0.5", children: everything.map((p) => card(p, `open:${p.row.id}:${d}`)) })
31205
31291
  ]
31206
31292
  }
31207
31293
  ) : null
@@ -31213,7 +31299,7 @@ function MonthWeek({
31213
31299
  bars.filter((b) => b.lane < lanesShown).map((b) => {
31214
31300
  const col = daysBetween2(weekStart, b.from);
31215
31301
  const span = daysBetween2(b.from, b.to) + 1;
31216
- return /* @__PURE__ */ jsxs91(
31302
+ return /* @__PURE__ */ jsxs92(
31217
31303
  "div",
31218
31304
  {
31219
31305
  "data-calendar-bar": `${b.from}..${b.to}`,
@@ -31249,9 +31335,9 @@ function WeekHours({
31249
31335
  return () => clearInterval(timer);
31250
31336
  }, []);
31251
31337
  const hours = Array.from({ length: 24 }, (_, h) => h);
31252
- return /* @__PURE__ */ jsx100("div", { ref: frame, className: "max-h-[36rem] overflow-y-auto", children: /* @__PURE__ */ jsxs91("div", { className: "grid", style: { gridTemplateColumns: columns }, children: [
31253
- /* @__PURE__ */ jsx100("div", { className: "border-r", children: hours.map((h) => /* @__PURE__ */ jsx100("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)) }),
31254
- days.map((d) => /* @__PURE__ */ jsxs91(
31338
+ return /* @__PURE__ */ jsx101("div", { ref: frame, className: "max-h-[36rem] overflow-y-auto", children: /* @__PURE__ */ jsxs92("div", { className: "grid", style: { gridTemplateColumns: columns }, children: [
31339
+ /* @__PURE__ */ jsx101("div", { className: "border-r", children: hours.map((h) => /* @__PURE__ */ jsx101("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)) }),
31340
+ days.map((d) => /* @__PURE__ */ jsxs92(
31255
31341
  "div",
31256
31342
  {
31257
31343
  className: cn51("relative border-r", onSlotPointerDown ? "cursor-cell" : void 0),
@@ -31259,10 +31345,10 @@ function WeekHours({
31259
31345
  ...timeDrop(d),
31260
31346
  ...onSlotPointerDown ? { onPointerDown: onSlotPointerDown(d) } : {},
31261
31347
  children: [
31262
- hours.map((h) => /* @__PURE__ */ jsx100("div", { "data-calendar-slot": `${d}T${pad3(h)}`, className: "border-b", style: { height: HOUR_PX } }, h)),
31348
+ hours.map((h) => /* @__PURE__ */ jsx101("div", { "data-calendar-slot": `${d}T${pad3(h)}`, className: "border-b", style: { height: HOUR_PX } }, h)),
31263
31349
  render(d),
31264
31350
  overlay(d),
31265
- d === today ? /* @__PURE__ */ jsx100(
31351
+ d === today ? /* @__PURE__ */ jsx101(
31266
31352
  "div",
31267
31353
  {
31268
31354
  "aria-hidden": "true",
@@ -31290,7 +31376,7 @@ import { useEffect as useEffect70, useMemo as useMemo52, useRef as useRef40, use
31290
31376
  import { mayDrag as mayDrag3 } from "@ai-matrx/records/react";
31291
31377
  import { Button as Button65, Select as Select14, SelectContent as SelectContent14, SelectItem as SelectItem14, SelectTrigger as SelectTrigger14, SelectValue as SelectValue14, cn as cn52 } from "@ai-matrx/design-system";
31292
31378
  import { CHOICE_CHIP_CLASS as CHOICE_CHIP_CLASS3 } from "@ai-matrx/design-system/data-table";
31293
- import { Fragment as Fragment42, jsx as jsx101, jsxs as jsxs92 } from "react/jsx-runtime";
31379
+ import { Fragment as Fragment42, jsx as jsx102, jsxs as jsxs93 } from "react/jsx-runtime";
31294
31380
  var TIMELINE_ZOOMS = ["day", "week", "month", "quarter"];
31295
31381
  var ZOOM_LABEL = { day: "Day", week: "Week", month: "Month", quarter: "Quarter" };
31296
31382
  var PX_PER_DAY = { day: 96, week: 32, month: 10, quarter: 4 };
@@ -31377,12 +31463,13 @@ function scaleOf(start, days, zoom) {
31377
31463
  };
31378
31464
  }
31379
31465
  function LockIcon2() {
31380
- return /* @__PURE__ */ jsxs92("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: [
31381
- /* @__PURE__ */ jsx101("rect", { x: "3.5", y: "7", width: "9", height: "6.5", rx: "1" }),
31382
- /* @__PURE__ */ jsx101("path", { d: "M5.5 7V5a2.5 2.5 0 0 1 5 0v2" })
31466
+ return /* @__PURE__ */ jsxs93("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: [
31467
+ /* @__PURE__ */ jsx102("rect", { x: "3.5", y: "7", width: "9", height: "6.5", rx: "1" }),
31468
+ /* @__PURE__ */ jsx102("path", { d: "M5.5 7V5a2.5 2.5 0 0 1 5 0v2" })
31383
31469
  ] });
31384
31470
  }
31385
31471
  function TimelineView({
31472
+ cardFields,
31386
31473
  tableId,
31387
31474
  rows,
31388
31475
  fields,
@@ -31704,7 +31791,7 @@ function TimelineView({
31704
31791
  const edges = may && Boolean(endField);
31705
31792
  const outside = wordsOutside(p, span);
31706
31793
  const inset = outside ? 0 : Math.min(Math.max(0, scrollX - left), Math.max(0, span - 48));
31707
- return /* @__PURE__ */ jsxs92(
31794
+ return /* @__PURE__ */ jsxs93(
31708
31795
  "div",
31709
31796
  {
31710
31797
  role: "button",
@@ -31736,7 +31823,7 @@ function TimelineView({
31736
31823
  onPointerDown: beginDrag(p, "move", { lane, top }),
31737
31824
  onKeyDown: barKeys(p),
31738
31825
  children: [
31739
- edges && !p.marker ? /* @__PURE__ */ jsx101(
31826
+ edges && !p.marker ? /* @__PURE__ */ jsx102(
31740
31827
  "span",
31741
31828
  {
31742
31829
  role: "separator",
@@ -31746,20 +31833,21 @@ function TimelineView({
31746
31833
  onPointerDown: beginDrag(p, "start")
31747
31834
  }
31748
31835
  ) : null,
31749
- inset > 0 ? /* @__PURE__ */ jsx101("span", { "aria-hidden": "true", className: "shrink-0", style: { width: inset } }) : null,
31750
- may ? null : /* @__PURE__ */ jsx101(LockIcon2, {}),
31751
- p.marker ? /* @__PURE__ */ jsx101("span", { "aria-hidden": "true", className: "h-2 w-2 shrink-0 rotate-45 rounded-[1px] bg-current opacity-70" }) : null,
31836
+ inset > 0 ? /* @__PURE__ */ jsx102("span", { "aria-hidden": "true", className: "shrink-0", style: { width: inset } }) : null,
31837
+ may ? null : /* @__PURE__ */ jsx102(LockIcon2, {}),
31838
+ p.marker ? /* @__PURE__ */ jsx102("span", { "aria-hidden": "true", className: "h-2 w-2 shrink-0 rotate-45 rounded-[1px] bg-current opacity-70" }) : null,
31752
31839
  outside ? (
31753
31840
  // Too short for its words: they sit just after the bar, the way Airtable labels a short bar.
31754
- /* @__PURE__ */ jsxs92("span", { className: "pointer-events-none absolute left-full top-1/2 ml-1.5 -translate-y-1/2 whitespace-nowrap text-foreground", children: [
31755
- startTime ? /* @__PURE__ */ jsx101("span", { className: "mr-1 tabular-nums text-[10px] opacity-75", "data-timeline-time": "", children: startTime }) : null,
31841
+ /* @__PURE__ */ jsxs93("span", { className: "pointer-events-none absolute left-full top-1/2 ml-1.5 -translate-y-1/2 whitespace-nowrap text-foreground", children: [
31842
+ startTime ? /* @__PURE__ */ jsx102("span", { className: "mr-1 tabular-nums text-[10px] opacity-75", "data-timeline-time": "", children: startTime }) : null,
31756
31843
  title
31757
31844
  ] })
31758
- ) : /* @__PURE__ */ jsxs92(Fragment42, { children: [
31759
- startTime ? /* @__PURE__ */ jsx101("span", { className: "shrink-0 tabular-nums text-[10px] opacity-75", "data-timeline-time": "", children: startTime }) : null,
31760
- /* @__PURE__ */ jsx101("span", { className: "min-w-0 truncate", children: title })
31845
+ ) : /* @__PURE__ */ jsxs93(Fragment42, { children: [
31846
+ startTime ? /* @__PURE__ */ jsx102("span", { className: "shrink-0 tabular-nums text-[10px] opacity-75", "data-timeline-time": "", children: startTime }) : null,
31847
+ /* @__PURE__ */ jsx102("span", { className: "min-w-0 truncate", children: title }),
31848
+ /* @__PURE__ */ jsx102(CardFieldsInline, { row: p.row, fields: cardFields })
31761
31849
  ] }),
31762
- edges && !endWorkedOut ? /* @__PURE__ */ jsx101(
31850
+ edges && !endWorkedOut ? /* @__PURE__ */ jsx102(
31763
31851
  "span",
31764
31852
  {
31765
31853
  role: "separator",
@@ -31774,39 +31862,39 @@ function TimelineView({
31774
31862
  `${lane}:${p.row.id}`
31775
31863
  );
31776
31864
  };
31777
- const picker = (label, value, options, onPick, opts) => /* @__PURE__ */ jsxs92("div", { className: "flex items-center gap-1.5 whitespace-nowrap text-xs", "data-timeline-setting": label, children: [
31778
- /* @__PURE__ */ jsx101("span", { className: "text-muted-foreground", children: label }),
31779
- /* @__PURE__ */ jsxs92(Select14, { value: value ?? NONE2, onValueChange: (v) => onPick(v === NONE2 ? null : v), children: [
31780
- /* @__PURE__ */ jsx101(SelectTrigger14, { 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__ */ jsx101(SelectValue14, { placeholder: "Choose" }) }),
31781
- /* @__PURE__ */ jsxs92(SelectContent14, { children: [
31782
- opts?.none !== false ? /* @__PURE__ */ jsx101(SelectItem14, { value: NONE2, children: "None" }) : null,
31783
- options.map((f) => /* @__PURE__ */ jsx101(SelectItem14, { value: f.key, children: fieldName(f) }, f.key)),
31784
- value && !options.some((f) => f.key === value) && fields.some((f) => f.key === value) ? /* @__PURE__ */ jsx101(SelectItem14, { value, "data-timeline-unusual": "", children: `${fieldName(fields.find((f) => f.key === value))} \u2014 ${UNUSUAL_FIELD_NOTE}` }, value) : null
31865
+ const picker = (label, value, options, onPick, opts) => /* @__PURE__ */ jsxs93("div", { className: "flex items-center gap-1.5 whitespace-nowrap text-xs", "data-timeline-setting": label, children: [
31866
+ /* @__PURE__ */ jsx102("span", { className: "text-muted-foreground", children: label }),
31867
+ /* @__PURE__ */ jsxs93(Select14, { value: value ?? NONE2, onValueChange: (v) => onPick(v === NONE2 ? null : v), children: [
31868
+ /* @__PURE__ */ jsx102(SelectTrigger14, { 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__ */ jsx102(SelectValue14, { placeholder: "Choose" }) }),
31869
+ /* @__PURE__ */ jsxs93(SelectContent14, { children: [
31870
+ opts?.none !== false ? /* @__PURE__ */ jsx102(SelectItem14, { value: NONE2, children: "None" }) : null,
31871
+ options.map((f) => /* @__PURE__ */ jsx102(SelectItem14, { value: f.key, children: fieldName(f) }, f.key)),
31872
+ value && !options.some((f) => f.key === value) && fields.some((f) => f.key === value) ? /* @__PURE__ */ jsx102(SelectItem14, { value, "data-timeline-unusual": "", children: `${fieldName(fields.find((f) => f.key === value))} \u2014 ${UNUSUAL_FIELD_NOTE}` }, value) : null
31785
31873
  ] })
31786
31874
  ] })
31787
31875
  ] });
31788
- const settings = /* @__PURE__ */ jsxs92(Fragment42, { children: [
31876
+ const settings = /* @__PURE__ */ jsxs93(Fragment42, { children: [
31789
31877
  dates.length > 1 || !startField || !dates.some((f) => f.key === startChosen) ? picker("Start", startChosen, dates, (key) => setting({ startKey: key }), { none: false }) : null,
31790
31878
  endCandidates.length > 0 || endField && !endCandidates.includes(endField) ? picker("End", endChosen, endCandidates, (key) => setting({ endKey: key }), { kept: layoutKept }) : null,
31791
31879
  groupCandidates.length > 0 ? picker("Group by", groupChosen, groupCandidates, (key) => setting({ groupKey: key })) : null,
31792
31880
  choiceFields.length > 0 ? picker("Colour by", colorChosen, choiceFields, (key) => setting({ colorKey: key })) : null
31793
31881
  ] });
31794
31882
  const heading = zoom === "quarter" ? `Q${Math.floor(dayAt(anchor).getMonth() / 3) + 1} ${dayAt(anchor).getFullYear()}` : dayAt(anchor).toLocaleDateString(void 0, { month: "long", year: "numeric" });
31795
- const toolbar = /* @__PURE__ */ jsxs92("div", { className: "flex flex-wrap items-center gap-2", children: [
31796
- /* @__PURE__ */ jsx101(Button65, { size: "sm", variant: "outline", onClick: () => setAnchor(today), children: "Today" }),
31797
- /* @__PURE__ */ jsx101(Button65, { size: "sm", variant: "ghost", "aria-label": "Previous", onClick: () => setAnchor(addDays(anchor, -PAGE_DAYS[zoom])), children: "\u2039" }),
31798
- /* @__PURE__ */ jsx101(Button65, { size: "sm", variant: "ghost", "aria-label": "Next", onClick: () => setAnchor(addDays(anchor, PAGE_DAYS[zoom])), children: "\u203A" }),
31799
- /* @__PURE__ */ jsx101("h3", { className: "text-sm font-medium", "data-timeline-heading": "", children: heading }),
31800
- layoutKept ? null : /* @__PURE__ */ jsx101("span", { className: "text-xs text-muted-foreground", children: "Kept for this visit only" }),
31801
- /* @__PURE__ */ jsxs92("div", { className: "ml-auto flex flex-wrap items-center gap-2", children: [
31883
+ const toolbar = /* @__PURE__ */ jsxs93("div", { className: "flex flex-wrap items-center gap-2", children: [
31884
+ /* @__PURE__ */ jsx102(Button65, { size: "sm", variant: "outline", onClick: () => setAnchor(today), children: "Today" }),
31885
+ /* @__PURE__ */ jsx102(Button65, { size: "sm", variant: "ghost", "aria-label": "Previous", onClick: () => setAnchor(addDays(anchor, -PAGE_DAYS[zoom])), children: "\u2039" }),
31886
+ /* @__PURE__ */ jsx102(Button65, { size: "sm", variant: "ghost", "aria-label": "Next", onClick: () => setAnchor(addDays(anchor, PAGE_DAYS[zoom])), children: "\u203A" }),
31887
+ /* @__PURE__ */ jsx102("h3", { className: "text-sm font-medium", "data-timeline-heading": "", children: heading }),
31888
+ layoutKept ? null : /* @__PURE__ */ jsx102("span", { className: "text-xs text-muted-foreground", children: "Kept for this visit only" }),
31889
+ /* @__PURE__ */ jsxs93("div", { className: "ml-auto flex flex-wrap items-center gap-2", children: [
31802
31890
  settings,
31803
- /* @__PURE__ */ jsx101("div", { className: "flex items-center gap-0.5", role: "group", "aria-label": "Zoom", children: TIMELINE_ZOOMS.map((z) => /* @__PURE__ */ jsx101(Button65, { size: "sm", variant: z === zoom ? "secondary" : "ghost", "aria-pressed": z === zoom, onClick: () => setZoom(z), children: ZOOM_LABEL[z] }, z)) })
31891
+ /* @__PURE__ */ jsx102("div", { className: "flex items-center gap-0.5", role: "group", "aria-label": "Zoom", children: TIMELINE_ZOOMS.map((z) => /* @__PURE__ */ jsx102(Button65, { size: "sm", variant: z === zoom ? "secondary" : "ghost", "aria-pressed": z === zoom, onClick: () => setZoom(z), children: ZOOM_LABEL[z] }, z)) })
31804
31892
  ] })
31805
31893
  ] });
31806
31894
  if (!startField) {
31807
- return /* @__PURE__ */ jsx101("div", { className: cn52("flex min-w-0 flex-col gap-2", className), "data-timeline-needs": "", children: /* @__PURE__ */ jsxs92("div", { className: "flex flex-col gap-2 rounded border border-dashed p-4 text-xs text-muted-foreground", children: [
31808
- /* @__PURE__ */ jsx101("p", { children: dates.length > 0 ? VIEW_NEEDS.timeline?.pick : VIEW_NEEDS.timeline?.missing }),
31809
- dates.length > 0 ? /* @__PURE__ */ jsx101("div", { className: "flex flex-wrap gap-2", children: settings }) : null
31895
+ return /* @__PURE__ */ jsx102("div", { className: cn52("flex min-w-0 flex-col gap-2", className), "data-timeline-needs": "", children: /* @__PURE__ */ jsxs93("div", { className: "flex flex-col gap-2 rounded border border-dashed p-4 text-xs text-muted-foreground", children: [
31896
+ /* @__PURE__ */ jsx102("p", { children: dates.length > 0 ? VIEW_NEEDS.timeline?.pick : VIEW_NEEDS.timeline?.missing }),
31897
+ dates.length > 0 ? /* @__PURE__ */ jsx102("div", { className: "flex flex-wrap gap-2", children: settings }) : null
31810
31898
  ] }) });
31811
31899
  }
31812
31900
  const todayX = today >= from && daysBetween(from, today) < days ? xOf(today) : null;
@@ -31828,15 +31916,15 @@ function TimelineView({
31828
31916
  }) : [];
31829
31917
  const tray = unscheduled.length > 0 ? (
31830
31918
  // Nothing fails silently: a record with no Start waits here and drags onto the timeline.
31831
- /* @__PURE__ */ jsxs92("aside", { className: "flex min-w-0 flex-col gap-1 sm:w-56 sm:shrink-0", "data-timeline-unscheduled": "", children: [
31832
- /* @__PURE__ */ jsxs92("h4", { className: "text-xs font-medium", children: [
31919
+ /* @__PURE__ */ jsxs93("aside", { className: "flex min-w-0 flex-col gap-1 sm:w-56 sm:shrink-0", "data-timeline-unscheduled": "", children: [
31920
+ /* @__PURE__ */ jsxs93("h4", { className: "text-xs font-medium", children: [
31833
31921
  "Unscheduled \xB7 ",
31834
31922
  unscheduled.length
31835
31923
  ] }),
31836
- /* @__PURE__ */ jsx101("ul", { className: "flex max-h-[28rem] flex-col gap-1 overflow-y-auto", children: unscheduled.map((row) => {
31924
+ /* @__PURE__ */ jsx102("ul", { className: "flex max-h-[28rem] flex-col gap-1 overflow-y-auto", children: unscheduled.map((row) => {
31837
31925
  const may = canMove(row);
31838
31926
  const color = colorOf(row);
31839
- return /* @__PURE__ */ jsx101(
31927
+ return /* @__PURE__ */ jsx102(
31840
31928
  "li",
31841
31929
  {
31842
31930
  "data-timeline-card": row.id,
@@ -31846,7 +31934,7 @@ function TimelineView({
31846
31934
  e.dataTransfer.setData(DRAG_TYPE2, JSON.stringify({ id: row.id }));
31847
31935
  e.dataTransfer.effectAllowed = "move";
31848
31936
  },
31849
- children: /* @__PURE__ */ jsxs92(
31937
+ children: /* @__PURE__ */ jsxs93(
31850
31938
  "button",
31851
31939
  {
31852
31940
  type: "button",
@@ -31858,8 +31946,8 @@ function TimelineView({
31858
31946
  title: may ? `${titleOf(row)} \xB7 drag onto a day` : mayDrag3(row.level) ? WORKED_OUT_DATE_LOCK : whatYouMayDo(row.level ?? null).why("write"),
31859
31947
  onClick: () => onOpenRecord?.(row.id),
31860
31948
  children: [
31861
- may ? null : /* @__PURE__ */ jsx101(LockIcon2, {}),
31862
- /* @__PURE__ */ jsx101("span", { className: "min-w-0 truncate", children: titleOf(row) })
31949
+ may ? null : /* @__PURE__ */ jsx102(LockIcon2, {}),
31950
+ /* @__PURE__ */ jsx102("span", { className: "min-w-0 truncate", children: titleOf(row) })
31863
31951
  ]
31864
31952
  }
31865
31953
  )
@@ -31870,7 +31958,7 @@ function TimelineView({
31870
31958
  ] })
31871
31959
  ) : null;
31872
31960
  const LABEL_COLUMN = "sticky left-0 z-30 w-24 shrink-0 border-r bg-background sm:w-36";
31873
- const todayLine = todayX !== null ? /* @__PURE__ */ jsx101(
31961
+ const todayLine = todayX !== null ? /* @__PURE__ */ jsx102(
31874
31962
  "div",
31875
31963
  {
31876
31964
  "aria-hidden": "true",
@@ -31879,14 +31967,14 @@ function TimelineView({
31879
31967
  style: { left: todayX + px / 2 - 1 }
31880
31968
  }
31881
31969
  ) : null;
31882
- const headerRow = (segments, className2, key) => /* @__PURE__ */ jsxs92("div", { className: "flex", "data-timeline-scale": key, children: [
31883
- grouped ? /* @__PURE__ */ jsx101("div", { className: cn52(LABEL_COLUMN, "border-b") }) : null,
31884
- /* @__PURE__ */ jsxs92("div", { className: "relative shrink-0", style: { width, height: 22 }, children: [
31970
+ const headerRow = (segments, className2, key) => /* @__PURE__ */ jsxs93("div", { className: "flex", "data-timeline-scale": key, children: [
31971
+ grouped ? /* @__PURE__ */ jsx102("div", { className: cn52(LABEL_COLUMN, "border-b") }) : null,
31972
+ /* @__PURE__ */ jsxs93("div", { className: "relative shrink-0", style: { width, height: 22 }, children: [
31885
31973
  segments.map((s) => {
31886
31974
  const left = xOf(s.day);
31887
31975
  const w = s.days * px;
31888
31976
  const inset = key === "top" ? Math.min(Math.max(0, scrollX - left), Math.max(0, w - 90)) : 0;
31889
- return /* @__PURE__ */ jsx101(
31977
+ return /* @__PURE__ */ jsx102(
31890
31978
  "div",
31891
31979
  {
31892
31980
  className: cn52("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),
@@ -31899,14 +31987,14 @@ function TimelineView({
31899
31987
  key === "bottom" ? todayLine : null
31900
31988
  ] })
31901
31989
  ] });
31902
- const body = /* @__PURE__ */ jsx101("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__ */ jsxs92("div", { className: "relative w-max", "data-timeline-zoom": zoom, "data-timeline-from": from, children: [
31903
- /* @__PURE__ */ jsxs92("div", { className: "sticky top-0 z-30 bg-background", children: [
31990
+ const body = /* @__PURE__ */ jsx102("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__ */ jsxs93("div", { className: "relative w-max", "data-timeline-zoom": zoom, "data-timeline-from": from, children: [
31991
+ /* @__PURE__ */ jsxs93("div", { className: "sticky top-0 z-30 bg-background", children: [
31904
31992
  headerRow(scale.top, "font-medium", "top"),
31905
31993
  headerRow(scale.bottom, "text-muted-foreground", "bottom")
31906
31994
  ] }),
31907
- laneRows.map((lane) => /* @__PURE__ */ jsxs92("div", { className: "flex border-b", "data-timeline-lane": groupField ? lane.key : "", children: [
31908
- grouped ? /* @__PURE__ */ jsxs92("div", { className: cn52(LABEL_COLUMN, "flex items-start p-1"), "data-timeline-label": "", children: [
31909
- /* @__PURE__ */ jsx101(
31995
+ laneRows.map((lane) => /* @__PURE__ */ jsxs93("div", { className: "flex border-b", "data-timeline-lane": groupField ? lane.key : "", children: [
31996
+ grouped ? /* @__PURE__ */ jsxs93("div", { className: cn52(LABEL_COLUMN, "flex items-start p-1"), "data-timeline-label": "", children: [
31997
+ /* @__PURE__ */ jsx102(
31910
31998
  "span",
31911
31999
  {
31912
32000
  className: cn52("max-w-full truncate rounded px-1.5 py-0.5 text-xs font-medium", lane.color ? CHOICE_CHIP_CLASS3[lane.color] : void 0),
@@ -31915,19 +32003,19 @@ function TimelineView({
31915
32003
  children: lane.label
31916
32004
  }
31917
32005
  ),
31918
- /* @__PURE__ */ jsx101("span", { className: "ml-auto px-1 text-xs text-muted-foreground", children: lane.bars.length })
32006
+ /* @__PURE__ */ jsx102("span", { className: "ml-auto px-1 text-xs text-muted-foreground", children: lane.bars.length })
31919
32007
  ] }) : null,
31920
- /* @__PURE__ */ jsxs92("div", { className: "relative shrink-0", style: { width, height: Math.max(lane.height, ROW_PX + LANE_PAD) }, "data-timeline-canvas": lane.key, ...laneDrop, children: [
31921
- weekendBands.map((d) => /* @__PURE__ */ jsx101("div", { "aria-hidden": "true", className: "absolute inset-y-0 bg-muted/40", style: { left: xOf(d), width: px } }, `we:${d}`)),
32008
+ /* @__PURE__ */ jsxs93("div", { className: "relative shrink-0", style: { width, height: Math.max(lane.height, ROW_PX + LANE_PAD) }, "data-timeline-canvas": lane.key, ...laneDrop, children: [
32009
+ weekendBands.map((d) => /* @__PURE__ */ jsx102("div", { "aria-hidden": "true", className: "absolute inset-y-0 bg-muted/40", style: { left: xOf(d), width: px } }, `we:${d}`)),
31922
32010
  lane.packed.map((b) => bar(b.p, LANE_PAD / 2 + b.row * ROW_PX + (ROW_PX - BAR_PX2) / 2, lane.key)),
31923
32011
  todayLine
31924
32012
  ] })
31925
32013
  ] }, lane.key))
31926
32014
  ] }) });
31927
- return /* @__PURE__ */ jsxs92("div", { className: cn52("relative flex min-h-0 min-w-0 max-w-full flex-col gap-2", className), "data-timeline": "", onKeyDown: moves.onKeyDown, children: [
31928
- note ? /* @__PURE__ */ jsx101("p", { className: "text-xs text-muted-foreground", children: note }) : null,
32015
+ return /* @__PURE__ */ jsxs93("div", { className: cn52("relative flex min-h-0 min-w-0 max-w-full flex-col gap-2", className), "data-timeline": "", onKeyDown: moves.onKeyDown, children: [
32016
+ note ? /* @__PURE__ */ jsx102("p", { className: "text-xs text-muted-foreground", children: note }) : null,
31929
32017
  toolbar,
31930
- /* @__PURE__ */ jsxs92("div", { className: "flex min-h-0 min-w-0 flex-col gap-3 sm:flex-row", children: [
32018
+ /* @__PURE__ */ jsxs93("div", { className: "flex min-h-0 min-w-0 flex-col gap-3 sm:flex-row", children: [
31931
32019
  body,
31932
32020
  tray
31933
32021
  ] }),
@@ -31939,7 +32027,7 @@ function TimelineView({
31939
32027
  import { useEffect as useEffect71, useState as useState86 } from "react";
31940
32028
  import { useFieldMutation as useFieldMutation6, useRecordsClient as useRecordsClient61, useTable as useTable15 } from "@ai-matrx/records/react";
31941
32029
  import { BasicInput as BasicInput19, Button as Button66, Label as Label17 } from "@ai-matrx/design-system";
31942
- import { jsx as jsx102, jsxs as jsxs93 } from "react/jsx-runtime";
32030
+ import { jsx as jsx103, jsxs as jsxs94 } from "react/jsx-runtime";
31943
32031
  function viewNeedFor(layout) {
31944
32032
  return VIEW_NEEDS[layout];
31945
32033
  }
@@ -32000,10 +32088,10 @@ function ViewNeeds({ layout, tableId, fields, onMade, className }) {
32000
32088
  setPendingId(null);
32001
32089
  onMade(field2.key);
32002
32090
  };
32003
- const editor = /* @__PURE__ */ jsxs93("div", { className: "flex flex-col gap-2 text-xs", children: [
32004
- /* @__PURE__ */ jsxs93("div", { className: "flex flex-wrap items-center gap-2", children: [
32005
- /* @__PURE__ */ jsx102(Label17, { className: "text-xs text-muted-foreground", htmlFor: `view-needs-name-${layout}`, children: "Column name" }),
32006
- /* @__PURE__ */ jsx102(
32091
+ const editor = /* @__PURE__ */ jsxs94("div", { className: "flex flex-col gap-2 text-xs", children: [
32092
+ /* @__PURE__ */ jsxs94("div", { className: "flex flex-wrap items-center gap-2", children: [
32093
+ /* @__PURE__ */ jsx103(Label17, { className: "text-xs text-muted-foreground", htmlFor: `view-needs-name-${layout}`, children: "Column name" }),
32094
+ /* @__PURE__ */ jsx103(
32007
32095
  BasicInput19,
32008
32096
  {
32009
32097
  id: `view-needs-name-${layout}`,
@@ -32013,10 +32101,10 @@ function ViewNeeds({ layout, tableId, fields, onMade, className }) {
32013
32101
  }
32014
32102
  )
32015
32103
  ] }),
32016
- need.starter.type === "select" ? /* @__PURE__ */ jsxs93("div", { className: "flex flex-wrap items-center gap-1.5", role: "group", "aria-label": "Choices", children: [
32017
- /* @__PURE__ */ jsx102("span", { className: "text-muted-foreground", children: "Choices" }),
32018
- options.map((option, index) => /* @__PURE__ */ jsxs93("span", { className: "flex items-center gap-0.5", children: [
32019
- /* @__PURE__ */ jsx102(
32104
+ need.starter.type === "select" ? /* @__PURE__ */ jsxs94("div", { className: "flex flex-wrap items-center gap-1.5", role: "group", "aria-label": "Choices", children: [
32105
+ /* @__PURE__ */ jsx103("span", { className: "text-muted-foreground", children: "Choices" }),
32106
+ options.map((option, index) => /* @__PURE__ */ jsxs94("span", { className: "flex items-center gap-0.5", children: [
32107
+ /* @__PURE__ */ jsx103(
32020
32108
  BasicInput19,
32021
32109
  {
32022
32110
  "aria-label": `Choice ${index + 1}`,
@@ -32025,7 +32113,7 @@ function ViewNeeds({ layout, tableId, fields, onMade, className }) {
32025
32113
  onChange: (e) => setOptions((held) => held.map((o, i) => i === index ? e.target.value : o))
32026
32114
  }
32027
32115
  ),
32028
- /* @__PURE__ */ jsx102(
32116
+ /* @__PURE__ */ jsx103(
32029
32117
  Button66,
32030
32118
  {
32031
32119
  type: "button",
@@ -32037,11 +32125,11 @@ function ViewNeeds({ layout, tableId, fields, onMade, className }) {
32037
32125
  }
32038
32126
  )
32039
32127
  ] }, index)),
32040
- /* @__PURE__ */ jsx102(Button66, { type: "button", size: "sm", variant: "ghost", onClick: () => setOptions((held) => [...held, ""]), children: "Add a choice" })
32128
+ /* @__PURE__ */ jsx103(Button66, { type: "button", size: "sm", variant: "ghost", onClick: () => setOptions((held) => [...held, ""]), children: "Add a choice" })
32041
32129
  ] }) : null
32042
32130
  ] });
32043
- return /* @__PURE__ */ jsxs93("div", { className, children: [
32044
- /* @__PURE__ */ jsx102(
32131
+ return /* @__PURE__ */ jsxs94("div", { className, children: [
32132
+ /* @__PURE__ */ jsx103(
32045
32133
  BuildOrAsk,
32046
32134
  {
32047
32135
  mayBuild: rights.structure,
@@ -32062,16 +32150,16 @@ function ViewNeeds({ layout, tableId, fields, onMade, className }) {
32062
32150
  children: rights.structure ? `${need.missing} ${need.does(name)}` : need.missing
32063
32151
  }
32064
32152
  ),
32065
- mutation.error ? /* @__PURE__ */ jsx102(RefusalNotice, { error: mutation.error }) : null,
32066
- refused ? /* @__PURE__ */ jsx102(RefusalNotice, { error: refused }) : null,
32067
- pendingId ? /* @__PURE__ */ jsx102("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
32153
+ mutation.error ? /* @__PURE__ */ jsx103(RefusalNotice, { error: mutation.error }) : null,
32154
+ refused ? /* @__PURE__ */ jsx103(RefusalNotice, { error: refused }) : null,
32155
+ pendingId ? /* @__PURE__ */ jsx103("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
32068
32156
  ] });
32069
32157
  }
32070
32158
 
32071
32159
  // src/GalleryCover.tsx
32072
32160
  import { useEffect as useEffect72, useState as useState87 } from "react";
32073
32161
  import { useOptionalRecordsClient as useOptionalRecordsClient10 } from "@ai-matrx/records/react";
32074
- import { Fragment as Fragment43, jsx as jsx103 } from "react/jsx-runtime";
32162
+ import { Fragment as Fragment43, jsx as jsx104 } from "react/jsx-runtime";
32075
32163
  function isImageAddress(value) {
32076
32164
  return typeof value === "string" && /^(https?:\/\/|\/|data:image\/)/i.test(value.trim());
32077
32165
  }
@@ -32080,10 +32168,10 @@ function GalleryCover({ field: field2, value }) {
32080
32168
  const isFile = field2 ? editorKindFor(field2) === "attachment" : false;
32081
32169
  if (isFile) {
32082
32170
  const first = attachmentIdsOf(value)[0];
32083
- return first ? /* @__PURE__ */ jsx103(FileCover, { recordId: first }) : null;
32171
+ return first ? /* @__PURE__ */ jsx104(FileCover, { recordId: first }) : null;
32084
32172
  }
32085
32173
  if (isImageAddress(value)) {
32086
- return /* @__PURE__ */ jsx103("img", { src: value, alt: "", loading: "lazy", className: "h-full w-full object-cover" });
32174
+ return /* @__PURE__ */ jsx104("img", { src: value, alt: "", loading: "lazy", className: "h-full w-full object-cover" });
32087
32175
  }
32088
32176
  return null;
32089
32177
  }
@@ -32115,51 +32203,9 @@ function FileCover({ recordId }) {
32115
32203
  }, [client, recordId]);
32116
32204
  if (!read || !read.fileId) return null;
32117
32205
  if (!host.fileImage) {
32118
- return /* @__PURE__ */ jsx103("span", { className: "flex h-full w-full items-center justify-center p-1 text-center text-[10px] text-muted-foreground", children: COVER_NOT_DRAWN });
32206
+ return /* @__PURE__ */ jsx104("span", { className: "flex h-full w-full items-center justify-center p-1 text-center text-[10px] text-muted-foreground", children: COVER_NOT_DRAWN });
32119
32207
  }
32120
- return /* @__PURE__ */ jsx103(Fragment43, { children: host.fileImage({ fileId: read.fileId, alt: read.name }) });
32121
- }
32122
-
32123
- // src/cardFields.tsx
32124
- import { jsx as jsx104, jsxs as jsxs94 } from "react/jsx-runtime";
32125
- function isEmptyOnCard(value) {
32126
- return value === null || value === void 0 || value === "" || Array.isArray(value) && value.length === 0;
32127
- }
32128
- function cardFieldsShown(fields, hiddenFields, exclude) {
32129
- const hidden = new Set(hiddenFields ?? []);
32130
- const out = new Set(exclude.filter((k) => Boolean(k)));
32131
- return fields.filter((field2) => !hidden.has(field2.key) && !out.has(field2.key));
32132
- }
32133
- function CardFieldsPicker({
32134
- fields,
32135
- hiddenFields,
32136
- summary,
32137
- onChange,
32138
- remembered,
32139
- layout
32140
- }) {
32141
- const hidden = new Set(hiddenFields ?? []);
32142
- return /* @__PURE__ */ jsxs94("details", { className: "text-xs text-muted-foreground", "data-records-card-fields": layout, children: [
32143
- /* @__PURE__ */ jsx104("summary", { className: "cursor-pointer select-none", children: summary }),
32144
- /* @__PURE__ */ jsx104("div", { className: "mt-1 flex flex-wrap gap-2", children: fields.map((field2) => /* @__PURE__ */ jsxs94("label", { className: "flex items-center gap-1", children: [
32145
- /* @__PURE__ */ jsx104(
32146
- "input",
32147
- {
32148
- type: "checkbox",
32149
- checked: !hidden.has(field2.key),
32150
- "data-records-card-field": field2.key,
32151
- onChange: (event) => {
32152
- const next = new Set(hidden);
32153
- if (event.target.checked) next.delete(field2.key);
32154
- else next.add(field2.key);
32155
- onChange([...next]);
32156
- }
32157
- }
32158
- ),
32159
- fieldName(field2)
32160
- ] }, field2.key)) }),
32161
- remembered ? null : /* @__PURE__ */ jsx104("p", { className: "mt-1", children: "Kept for this visit only \u2014 this screen has nowhere to save it onto the view." })
32162
- ] });
32208
+ return /* @__PURE__ */ jsx104(Fragment43, { children: host.fileImage({ fileId: read.fileId, alt: read.name }) });
32163
32209
  }
32164
32210
 
32165
32211
  // src/ListView.tsx
@@ -32308,17 +32354,22 @@ function ListRow({
32308
32354
  const filled = fields.filter((field2) => !isEmptyOnCard(doc[field2.key]) || withheldNoticeOf(row.hidden, field2.key));
32309
32355
  const onRow = chose ? filled : filled.slice(0, LIST_DEFAULT_FIELDS);
32310
32356
  const color = style ? resolveRowColor3(style, { id: row.id, data: row.document ?? {} }, colorFromTheValue) : null;
32311
- const values = onRow.map((field2) => /* @__PURE__ */ jsx105("span", { className: "flex min-w-0 max-w-[14rem] items-baseline gap-1", "data-records-list-value": field2.key, title: fieldName(field2), children: /* @__PURE__ */ jsx105(
32312
- RecordValue,
32313
- {
32314
- field: field2,
32315
- value: doc[field2.key],
32316
- document: row.document,
32317
- recordId: row.id,
32318
- withheld: withheldNoticeOf(row.hidden, field2.key),
32319
- format: cellFormatFor(field2, formats?.[field2.key])
32320
- }
32321
- ) }, field2.key));
32357
+ const values = onRow.map((field2) => (
32358
+ // ONE LINE PER VALUE (walk 2026-10-05): a multi-line caption drew as paragraphs, pushing the
32359
+ // title to the row's foot. A list row is one line, as Notion's is; the record page has the rest.
32360
+ /* @__PURE__ */ jsx105("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__ */ jsx105(
32361
+ RecordValue,
32362
+ {
32363
+ inCell: true,
32364
+ field: field2,
32365
+ value: doc[field2.key],
32366
+ document: row.document,
32367
+ recordId: row.id,
32368
+ withheld: withheldNoticeOf(row.hidden, field2.key),
32369
+ format: cellFormatFor(field2, formats?.[field2.key])
32370
+ }
32371
+ ) }, field2.key)
32372
+ ));
32322
32373
  return /* @__PURE__ */ jsxs95(
32323
32374
  "button",
32324
32375
  {
@@ -32730,9 +32781,21 @@ function Board({
32730
32781
  const titleField = cardTitleField(all, titleKey, [view.groupField]);
32731
32782
  const cardHidden = cardHiddenOf(view.presentation);
32732
32783
  const dateFields = cardDateFields(all, titleField, cardHidden);
32784
+ const timedCardFields = cardHidden !== void 0 ? cardFieldsShown(all, cardHidden, [titleField?.key]) : [];
32785
+ const timedCardPicker = (layout) => /* @__PURE__ */ jsx106(
32786
+ CardFieldsPicker,
32787
+ {
32788
+ layout,
32789
+ fields: all.filter((f) => f.key !== titleField?.key),
32790
+ hiddenFields: cardHidden ?? all.map((f) => f.key),
32791
+ summary: `Card fields (${timedCardFields.length})`,
32792
+ onChange: (next) => onChange({ presentation: { ...view.presentation, cardHidden: next } }),
32793
+ remembered
32794
+ }
32795
+ );
32733
32796
  if (view.layout === "kanban") {
32734
32797
  const choice = boardColumnChoice(all, view.groupField, stage);
32735
- const groupField = byKey(choice.groupKey) ?? (choice.stillAsking ? void 0 : eligibleFieldFor("choice", all).field ?? void 0);
32798
+ const groupField = byKey(choice.groupKey) ?? (choice.stillAsking ? void 0 : boardDefaultGroupField(eligibleFieldFor("choice", all).eligible) ?? void 0);
32736
32799
  const isPipeline = choice.isPipeline;
32737
32800
  const boardChose = cardHidden !== void 0;
32738
32801
  const boardCardFields = boardChose ? cardFieldsShown(all, cardHidden, [titleField?.key, groupField?.key, ...dateFields.map((f) => f.key)]) : [];
@@ -32768,7 +32831,8 @@ function Board({
32768
32831
  ...onMoved ? { onMoved } : {},
32769
32832
  onChanged: () => records.reload(),
32770
32833
  style,
32771
- dateFields
32834
+ dateFields,
32835
+ canAdd: mayAdd
32772
32836
  }
32773
32837
  ) : /* @__PURE__ */ jsx106(
32774
32838
  Kanban,
@@ -32842,13 +32906,15 @@ function Board({
32842
32906
  }
32843
32907
  }),
32844
32908
  titleField,
32909
+ cardFields: timedCardFields,
32845
32910
  onOpenRecord,
32846
32911
  ...onMoved ? { onMoved } : {},
32847
32912
  note: records.membership,
32848
32913
  style
32849
32914
  }
32850
32915
  ),
32851
- pager
32916
+ pager,
32917
+ timedCardPicker("calendar")
32852
32918
  ] });
32853
32919
  }
32854
32920
  if (view.layout === "timeline") {
@@ -32859,6 +32925,7 @@ function Board({
32859
32925
  noRows ?? /* @__PURE__ */ jsx106(
32860
32926
  TimelineView,
32861
32927
  {
32928
+ cardFields: timedCardFields,
32862
32929
  tableId: view.subject,
32863
32930
  rows: records.rows,
32864
32931
  fields: all,
@@ -32890,7 +32957,8 @@ function Board({
32890
32957
  style
32891
32958
  }
32892
32959
  ),
32893
- pager
32960
+ pager,
32961
+ timedCardPicker("timeline")
32894
32962
  ] });
32895
32963
  }
32896
32964
  if (view.layout === "list") {
@@ -33272,7 +33340,7 @@ function Gallery({
33272
33340
  }) {
33273
33341
  const hidden = useMemo54(() => new Set(hiddenFields ?? []), [hiddenFields]);
33274
33342
  const imageField = imageKey ? fields.find((field2) => field2.key === imageKey) : void 0;
33275
- const shown4 = fields.filter((field2) => !hidden.has(field2.key) && field2.key !== imageKey);
33343
+ const shown4 = fields.filter((field2) => !hidden.has(field2.key) && field2.key !== imageKey && field2.key !== titleKey);
33276
33344
  const chose = hiddenFields !== void 0;
33277
33345
  const dims = GALLERY_SIZE[size];
33278
33346
  return /* @__PURE__ */ jsxs96("div", { className: "flex min-h-0 flex-col gap-2", children: [
@@ -33284,7 +33352,7 @@ function Gallery({
33284
33352
  /* @__PURE__ */ jsxs96(
33285
33353
  "ul",
33286
33354
  {
33287
- className: "grid gap-2 overflow-y-auto",
33355
+ className: "grid auto-rows-fr gap-2 overflow-y-auto",
33288
33356
  style: { gridTemplateColumns: `repeat(auto-fill, ${dims.tile})` },
33289
33357
  children: [
33290
33358
  rows.map((row) => {
@@ -33293,7 +33361,7 @@ function Gallery({
33293
33361
  const filled = shown4.filter((field2) => !isEmptyOnCard(doc[field2.key]) || withheldNoticeOf(row.hidden, field2.key));
33294
33362
  const onCard = chose ? filled : filled.slice(0, GALLERY_DEFAULT_FIELDS);
33295
33363
  const rowColor = style ? resolveRowColor4(style, { id: row.id, data: row.document ?? {} }, colorFromTheValue) : null;
33296
- return /* @__PURE__ */ jsx106("li", { children: /* @__PURE__ */ jsx106(
33364
+ return /* @__PURE__ */ jsx106("li", { className: "flex", children: /* @__PURE__ */ jsx106(
33297
33365
  MaybeRecordActionMenu,
33298
33366
  {
33299
33367
  tableId,
@@ -33306,17 +33374,19 @@ function Gallery({
33306
33374
  {
33307
33375
  type: "button",
33308
33376
  className: cn54(
33309
- "flex w-full flex-col gap-1 rounded border p-2 pr-7 text-left hover:bg-muted",
33377
+ "flex h-full w-full flex-col gap-1 rounded border p-2 pr-7 text-left hover:bg-muted",
33310
33378
  rowColor ? ROW_TINT_CLASS3[rowColor] : void 0
33311
33379
  ),
33312
33380
  onClick: () => onOpenRecord?.(row.id),
33313
33381
  children: [
33314
33382
  imageField ? /* @__PURE__ */ jsx106("span", { className: cn54(dims.cover, "w-full shrink-0 overflow-hidden rounded bg-muted/50"), "data-records-gallery-cover": imageField.key, children: /* @__PURE__ */ jsx106(GalleryCover, { field: imageField, value: image }) }) : null,
33315
- onCard.map((field2) => /* @__PURE__ */ jsxs96("span", { className: "flex min-w-0 items-baseline gap-1 text-xs", children: [
33383
+ /* @__PURE__ */ jsx106("span", { className: "truncate text-sm font-medium", "data-records-gallery-title": "", children: recordNameIn({ title_field: titleKey ?? null }, doc) || "Untitled" }),
33384
+ onCard.map((field2) => /* @__PURE__ */ jsxs96("span", { className: "flex h-5 min-w-0 items-center gap-1 overflow-hidden whitespace-nowrap text-xs", children: [
33316
33385
  /* @__PURE__ */ jsx106("span", { className: "shrink-0 text-muted-foreground", children: fieldName(field2) }),
33317
33386
  /* @__PURE__ */ jsx106("span", { className: "min-w-0 truncate", "data-records-gallery-value": field2.key, children: /* @__PURE__ */ jsx106(
33318
33387
  RecordValue,
33319
33388
  {
33389
+ inCell: true,
33320
33390
  field: field2,
33321
33391
  value: doc[field2.key],
33322
33392
  document: row.document,
@@ -33411,6 +33481,10 @@ function cardHiddenOf(presentation) {
33411
33481
  const held = presentation?.["cardHidden"];
33412
33482
  return Array.isArray(held) ? held.filter((k) => typeof k === "string") : void 0;
33413
33483
  }
33484
+ var STATUS_WORDS = /^(status|stage|state|progress|phase)$/i;
33485
+ function boardDefaultGroupField(eligible) {
33486
+ return eligible.find((f) => newerKindOf6(f) === "status") ?? eligible.find((f) => STATUS_WORDS.test(fieldName(f).trim()) || STATUS_WORDS.test(f.key)) ?? eligible[0] ?? null;
33487
+ }
33414
33488
 
33415
33489
  // src/ArchivedView.tsx
33416
33490
  import { useCallback as useCallback38, useEffect as useEffect74, useState as useState89 } from "react";