@ai-matrx/records-ui 0.93.64 → 0.93.67

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # Changelog — @ai-matrx/records-ui
2
2
 
3
+ ## 0.93.67
4
+
5
+ Automatic changed-only republish (docs/metadata drift since the last tag — see
6
+ `git diff npm/records-ui/v0.93.64..npm/records-ui/v0.93.67 -- apps/shared/records-ui`).
7
+ No source changes intended and no consumer action required.
8
+
9
+ ## 0.93.66
10
+ ### Unreleased
11
+
12
+ - **A booking page or a summary that exists can be changed** (lane HANDOVER, 2026-09-29): a booking page's card offered "Copy link" and "Close" only, and a summary's card on/off and a preview only, so nothing on the screen could move a page saved with UTC hours, or a Monday summary kept in UTC, to the owner's clock. Each card now has "Change it": the booking builder opens on that page (re-stated by its id, starting in the owner's zone when the page was kept in UTC), and `DigestScheduler` takes `existing` — its words, day, time and clock — and saves the same rule (`rule_id`), never a second. Proof: `a-booking-page-that-exists-can-be-changed.test.tsx`, `a-summary-that-exists-can-be-changed.test.tsx`, each red on the old panel.
13
+
14
+ - **A person who answers is told it was received** (lane HANDOVER, 2026-09-29): a form's thank-you page read "Saved to Form 1, with this form stamped on it" — the owner's bookkeeping — to a front-desk member and to strangers. It now says "Your answers were received." Proof: `a-person-who-answers-is-told-it-was-received.test.tsx`, red on the old runner.
15
+
16
+ - **A booking page is titled for one visit** (lane HANDOVER, 2026-09-29): a new page on Visits was titled "Book a 30-minute Visits appointment" — the table's name where one record's noun goes. New `singularNoun(table, fallback)` (exported, beside the grid's plural) reads the table's own singular in sentence case ("visit"; acronyms kept, "MRI scan"); the title is "Book a 30-minute visit". Proof: `a-booking-page-is-titled-for-one-visit.test.tsx`, red on the old builder.
17
+
18
+ - **A stranger's own page fills her own details** (lane HANDOVER, 2026-09-29): with every booking question now drawn by `FieldControl`, the browser's offer of a person's saved name, email and phone moved into the shared control — on a page nobody is signed into (no records client) only, so a signed-in grid never offers the front desk's own email into a patient's cell. The format control (`formatControl`) carries it too (`ownDetails`). A therapist's name is not her name. Proof: `a-strangers-own-page-fills-her-own-details.test.tsx`, red on the old control.
19
+
20
+ ## 0.93.65
21
+ ### Unreleased
22
+
23
+ - **A form built in one press is named for its table** (lane HANDOVER, 2026-09-28): "Build the form" on Cedar Ridge's Treatment Rooms made "Form 1", because the builder named it before its own read of the table had answered. It now waits for the table's row. Proof: `build-the-form-makes-the-form.test.tsx` second clause (the builder mounted alone, the table answering last), red on the old builder ("Form 1").
24
+ - **A list that is not hers is said once, with no count** (lane HANDOVER, 2026-09-28): a member who is Viewer on a table opened Notifications, and the Webhooks section printed the read door's refusal in red ("…is not by itself permission to rewrite somebody else's row"), then "none" and "No other system is told when these records change" — a count the screen never had. A 42501 read refusal that the table's rights agree with is now one sentence ("Which other systems are told about these records is for this table's admins." plus her rights), with no count and no red line. Proof: `a-list-that-is-not-hers-is-said-once.test.tsx`, red on the old panel.
25
+
3
26
  ## 0.93.64
4
27
 
5
28
  Automatic changed-only republish (docs/metadata drift since the last tag — see
package/dist/index.cjs CHANGED
@@ -350,6 +350,7 @@ __export(src_exports, {
350
350
  scalarText: () => scalarText,
351
351
  seedIsSatisfied: () => seedIsSatisfied,
352
352
  shareUnavailableReason: () => shareUnavailableReason,
353
+ singularNoun: () => singularNoun,
353
354
  snoozeChoices: () => snoozeChoices,
354
355
  specFromBlock: () => specFromBlock,
355
356
  storeDecidesRights: () => storeDecidesRights,
@@ -749,6 +750,10 @@ function realPlural(table) {
749
750
  }
750
751
  return plural3;
751
752
  }
753
+ function singularNoun(table, fallback = "record") {
754
+ const word = (table?.label_singular ?? "").trim() || (table?.name ?? "").trim() || fallback;
755
+ return word.split(/\s+/).map((w) => /^[A-Z][a-z'’-]*$/.test(w) ? w.toLowerCase() : w).join(" ");
756
+ }
752
757
  function pluralNoun(table, fallback = "record") {
753
758
  const real = table ? realPlural(table) : null;
754
759
  if (real) return real;
@@ -2795,7 +2800,7 @@ function NumberInFormat({ format, value, onChange, disabled, id }) {
2795
2800
  function formatControl(args) {
2796
2801
  const def = (0, import_field_formats4.getFieldFormat)(args.format.id);
2797
2802
  if (!def) return null;
2798
- const { format, value, onChange, disabled, id, label } = args;
2803
+ const { format, value, onChange, disabled, id, label, ownDetails } = args;
2799
2804
  const text = value === null || value === void 0 ? "" : String(value);
2800
2805
  const commit = (raw) => onChange(raw === "" ? null : (0, import_field_formats4.parseFieldInput)(raw, format));
2801
2806
  if (def.id === "rating") {
@@ -2818,7 +2823,17 @@ function formatControl(args) {
2818
2823
  case "email":
2819
2824
  case "url":
2820
2825
  case "tel":
2821
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_design_system9.BasicInput, { id, type: def.editor, value: text, disabled, onChange: (e) => commit(e.target.value) });
2826
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2827
+ import_design_system9.BasicInput,
2828
+ {
2829
+ id,
2830
+ type: def.editor,
2831
+ ...ownDetails && def.editor !== "url" ? { autoComplete: def.editor === "email" ? "email" : "tel" } : {},
2832
+ value: text,
2833
+ disabled,
2834
+ onChange: (e) => commit(e.target.value)
2835
+ }
2836
+ );
2822
2837
  case "color":
2823
2838
  return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "flex items-center gap-2", children: [
2824
2839
  /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
@@ -3072,14 +3087,19 @@ function TypedTextControl({ field: field2, value, onChange, disabled, id, onComm
3072
3087
  ] })
3073
3088
  ] });
3074
3089
  }
3090
+ function isPersonsName(field2) {
3091
+ const words2 = `${field2.key} ${field2.label ?? ""}`.toLowerCase();
3092
+ return /(^|[\s_])(full[\s_]?)?name(\s|$)/.test(words2) && !/(therapist|doctor|physician|company|business|pet|room)/.test(words2);
3093
+ }
3075
3094
  function FieldControl({ field: field2, value, onChange, disabled, id, autoOpen, onClose, onCommit, onCancel, addsChoices, initialSearch }) {
3076
3095
  const host = useRecordsUi();
3077
3096
  const kind = editorKindFor(field2);
3078
3097
  const inputId = id ?? `field-${field2.key}`;
3098
+ const ownDetails = (0, import_react19.useOptionalRecordsClient)() === null;
3079
3099
  if (isTypedDraft(value)) return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(TypedTextControl, { field: field2, value, onChange, disabled, id: inputId, onCommit, onCancel });
3080
3100
  const format = formatForField(field2);
3081
3101
  if (format && !FORMAT_BLIND_KINDS.has(String(kind))) {
3082
- const own2 = formatControl({ format, value, onChange, disabled, id: inputId, label: fieldName(field2) });
3102
+ const own2 = formatControl({ format, value, onChange, disabled, id: inputId, label: fieldName(field2), ownDetails });
3083
3103
  if (own2) return own2;
3084
3104
  }
3085
3105
  switch (kind) {
@@ -3140,6 +3160,7 @@ function FieldControl({ field: field2, value, onChange, disabled, id, autoOpen,
3140
3160
  {
3141
3161
  id: inputId,
3142
3162
  type: kind === "email" ? "email" : kind === "phone" ? "tel" : "url",
3163
+ ...ownDetails && kind !== "url" ? { autoComplete: kind === "email" ? "email" : "tel" } : {},
3143
3164
  value: value === null || value === void 0 ? "" : String(value),
3144
3165
  disabled,
3145
3166
  onChange: (e) => onChange(e.target.value === "" ? null : e.target.value)
@@ -3177,6 +3198,7 @@ function FieldControl({ field: field2, value, onChange, disabled, id, autoOpen,
3177
3198
  import_design_system10.BasicInput,
3178
3199
  {
3179
3200
  id: inputId,
3201
+ ...ownDetails && isPersonsName(field2) ? { autoComplete: "name" } : {},
3180
3202
  value: value === null || value === void 0 ? "" : String(value),
3181
3203
  disabled,
3182
3204
  onChange: (e) => onChange(e.target.value === "" ? null : e.target.value)
@@ -5583,6 +5605,22 @@ function archiveConfirmSentence(what) {
5583
5605
  const subject = what.trim() || "it";
5584
5606
  return `This archives ${subject}. It leaves this list, and you can restore it from Trash.`;
5585
5607
  }
5608
+ var recordsWord = (n) => `${n.toLocaleString()} record${n === 1 ? "" : "s"}`;
5609
+ function tableArchiveSentence(s) {
5610
+ const p = s.progress;
5611
+ if (!p) return "Every record in it goes with it.";
5612
+ const done = p.total - p.remaining;
5613
+ const sofar = `${done.toLocaleString()} of ${recordsWord(p.total)} ${done === 1 ? "is" : "are"} put away`;
5614
+ if (s.running) {
5615
+ return `Archiving \u2014 ${done.toLocaleString()} of ${recordsWord(p.total)} put away.${s.slowedDown ? " The store is busy, so it is taking smaller passes; it will still finish." : ""}`;
5616
+ }
5617
+ if (p.in_progress && !s.failed && !(s.passesHere ?? 0)) {
5618
+ return `Archiving this table was started and not finished: ${sofar}. Carry on and it picks up where it stopped.`;
5619
+ }
5620
+ if (s.interrupted && s.failed) return `That pass did not finish: ${sofar} and nothing was lost. Carry on and it picks up where it stopped.`;
5621
+ if (s.interrupted) return `Stopped: ${sofar}. Carry on whenever you like; it picks up where it stopped.`;
5622
+ return `Its ${recordsWord(p.remaining)} ${p.remaining === 1 ? "goes" : "go"} with it.`;
5623
+ }
5586
5624
 
5587
5625
  // src/tableDecorations.ts
5588
5626
  var import_react27 = require("react");
@@ -16392,6 +16430,17 @@ function TableSettings({
16392
16430
  const rights = useTableRights(table.data);
16393
16431
  const shape = (0, import_react85.useFieldMutation)();
16394
16432
  const archive = (0, import_react85.useTableArchive)(tableId);
16433
+ const client = (0, import_react85.useRecordsClient)();
16434
+ const ui = useRecordsUi();
16435
+ (0, import_react84.useEffect)(() => {
16436
+ let live = true;
16437
+ void archive.preview().then((answer) => {
16438
+ if (live && answer?.in_progress) setAskingToDelete(true);
16439
+ });
16440
+ return () => {
16441
+ live = false;
16442
+ };
16443
+ }, [tableId]);
16395
16444
  const [editing, setEditing] = (0, import_react84.useState)(null);
16396
16445
  const [askingToDelete, setAskingToDelete] = (0, import_react84.useState)(false);
16397
16446
  const [askingToRemove, setAskingToRemove] = (0, import_react84.useState)(null);
@@ -16420,6 +16469,16 @@ function TableSettings({
16420
16469
  const finished = await archive.start();
16421
16470
  if (finished?.done && finished.table_archived) {
16422
16471
  setAskingToDelete(false);
16472
+ const name = finished.table_name || "The table";
16473
+ ui.notify?.success(`\u201C${name}\u201D is archived. You can restore it from Trash.`, {
16474
+ label: "Undo",
16475
+ run: () => {
16476
+ void client.recordRestore({ record_id: tableId }).then((back) => {
16477
+ if (back.ok) ui.notify?.success(`\u201C${name}\u201D is back, with everything in it.`);
16478
+ else ui.notify?.error(back.error.message);
16479
+ });
16480
+ }
16481
+ });
16423
16482
  onDeleted?.();
16424
16483
  }
16425
16484
  };
@@ -16551,31 +16610,20 @@ function TableSettings({
16551
16610
  /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: "flex flex-col gap-1", children: [
16552
16611
  /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("span", { className: "font-medium", children: "This table" }),
16553
16612
  askingToDelete ? /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(import_jsx_runtime54.Fragment, { children: [
16554
- /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("p", { className: "text-muted-foreground", "data-archive-confirm": "table", children: [
16555
- archiveConfirmSentence(table.data ? `the table \u201C${tableName(table.data)}\u201D` : "this table"),
16556
- " ",
16557
- "Its ",
16558
- rows.length,
16559
- " field",
16560
- rows.length === 1 ? "" : "s",
16561
- " and",
16562
- " ",
16563
- archive.progress ? `its ${archive.progress.remaining.toLocaleString()} record${archive.progress.remaining === 1 ? "" : "s"}` : "every record in it",
16564
- " ",
16565
- "go with it",
16566
- table.data?.retention_days ? `, kept for ${table.data.retention_days} days` : "",
16567
- "."
16568
- ] }),
16569
- archive.progress && (archive.running || archive.passes > 0) ? /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("p", { className: archive.error ? "text-destructive" : "text-muted-foreground", children: [
16570
- archive.progress.total - archive.progress.remaining === archive.progress.total ? `All ${archive.progress.total.toLocaleString()} record${archive.progress.total === 1 ? "" : "s"} are put away.` : `${(archive.progress.total - archive.progress.remaining).toLocaleString()} of ${archive.progress.total.toLocaleString()} record${archive.progress.total === 1 ? "" : "s"} put away so far.`,
16571
- archive.slowedDown ? " The store is busy, so it is taking smaller passes \u2014 it will still finish." : ""
16572
- ] }) : null,
16573
- archive.interrupted && archive.progress ? /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("p", { className: "text-muted-foreground", children: archive.error ? `That pass did not finish, so the rest is still here. ${archive.progress.archived_total.toLocaleString()} record${archive.progress.archived_total === 1 ? " is" : "s are"} already archived and ${archive.progress.remaining.toLocaleString()} ${archive.progress.remaining === 1 ? "is" : "are"} left. Nothing was lost \u2014 carry on and it picks up where it stopped.` : `Stopped. ${archive.progress.archived_total.toLocaleString()} record${archive.progress.archived_total === 1 ? " is" : "s are"} archived and ${archive.progress.remaining.toLocaleString()} ${archive.progress.remaining === 1 ? "is" : "are"} left. Carry on whenever you like \u2014 it picks up where it stopped.` }) : null,
16613
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("p", { className: "text-muted-foreground", "data-archive-confirm": "table", children: archiveConfirmSentence(table.data ? `the table \u201C${tableName(table.data)}\u201D` : "this table") }),
16614
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("p", { className: "text-muted-foreground", "data-archive-state": "", children: tableArchiveSentence({
16615
+ progress: archive.progress,
16616
+ running: archive.running,
16617
+ interrupted: archive.interrupted,
16618
+ failed: Boolean(archive.error),
16619
+ slowedDown: archive.slowedDown,
16620
+ passesHere: archive.passes
16621
+ }) }),
16574
16622
  /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { className: "flex gap-1", children: archive.running ? /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(import_jsx_runtime54.Fragment, { children: [
16575
16623
  /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_design_system47.Button, { size: "sm", variant: "destructive", disabled: true, children: "Archiving\u2026" }),
16576
16624
  /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_design_system47.Button, { size: "sm", variant: "ghost", onClick: () => archive.stop(), children: "Stop" })
16577
16625
  ] }) : /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(import_jsx_runtime54.Fragment, { children: [
16578
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_design_system47.Button, { size: "sm", variant: "destructive", onClick: () => void startArchive(), children: archive.interrupted ? "Carry on archiving" : "Archive this table" }),
16626
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_design_system47.Button, { size: "sm", variant: "destructive", onClick: () => void startArchive(), children: archive.interrupted || archive.progress?.in_progress ? "Carry on archiving" : "Archive this table" }),
16579
16627
  /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_design_system47.Button, { size: "sm", variant: "ghost", onClick: () => setAskingToDelete(false), children: "Keep it" })
16580
16628
  ] }) })
16581
16629
  ] }) : /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_design_system47.Button, { size: "sm", variant: "outline", onClick: () => void askToArchive(), children: "Archive this table" }) }),
@@ -18187,6 +18235,18 @@ function columnDeclarationFor(need, label, options, fields) {
18187
18235
  if (need.starter.type === "datetime") return { ...base, parity_type: "datetime", kind: "date" };
18188
18236
  return { ...base, parity_type: "attachment" };
18189
18237
  }
18238
+ var askedFor = /* @__PURE__ */ new Map();
18239
+ var askKey = (tableId, layout) => `${tableId}:${layout}`;
18240
+ function useAskedColumnLands(layout, tableId, fields, chosen, offerable, onMade) {
18241
+ const wanted = askedFor.get(askKey(tableId, layout));
18242
+ const landed = wanted && !chosen ? offerable(fields).find((f) => fieldName(f).trim().toLowerCase() === wanted.trim().toLowerCase()) : void 0;
18243
+ const key = landed?.key ?? null;
18244
+ (0, import_react98.useEffect)(() => {
18245
+ if (!key) return;
18246
+ askedFor.delete(askKey(tableId, layout));
18247
+ onMade(key);
18248
+ }, [key, tableId, layout]);
18249
+ }
18190
18250
  var NO_ASSISTANT = "Asking in words needs the AI assistant, which this screen is not connected to.";
18191
18251
  function ViewNeeds({ layout, tableId, fields, onMade, className }) {
18192
18252
  const need = viewNeedFor(layout);
@@ -18277,7 +18337,12 @@ function ViewNeeds({ layout, tableId, fields, onMade, className }) {
18277
18337
  editor,
18278
18338
  noAgentSentence: NO_ASSISTANT,
18279
18339
  suggestion,
18280
- ...host.onAskForOne ? { onAsk: () => host.onAskForOne?.({ kind: "column", tableId, suggestion }) } : {},
18340
+ ...host.onAskForOne ? {
18341
+ onAsk: () => {
18342
+ askedFor.set(askKey(tableId, layout), name);
18343
+ host.onAskForOne?.({ kind: "column", tableId, suggestion });
18344
+ }
18345
+ } : {},
18281
18346
  children: rights.structure ? `${need.missing} ${need.does(name)}` : need.missing
18282
18347
  }
18283
18348
  ),
@@ -18597,6 +18662,17 @@ function Board({
18597
18662
  () => resolveTableStyle(decorations.data, fields.data ?? [], view.presentation?.style),
18598
18663
  [decorations.data, fields.data, view.presentation?.style]
18599
18664
  );
18665
+ const askedLayout = view.layout === "grid" ? "kanban" : view.layout;
18666
+ const askedKind = askedLayout === "kanban" ? "choice" : askedLayout === "calendar" ? "date" : "file";
18667
+ const askedChosen = askedLayout === "kanban" ? view.groupField : askedLayout === "calendar" ? view.dateField : view.imageField;
18668
+ useAskedColumnLands(
18669
+ askedLayout,
18670
+ view.subject,
18671
+ fields.data ?? NO_FIELDS,
18672
+ askedChosen,
18673
+ (all2) => offerableFields(all2, askedKind),
18674
+ (key) => onChange(askedLayout === "kanban" ? { groupField: key } : askedLayout === "calendar" ? { dateField: key } : { imageField: key })
18675
+ );
18600
18676
  if (fields.error) return /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(RefusalNotice, { error: fields.error });
18601
18677
  if (records.error) return /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(RefusalNotice, { error: records.error });
18602
18678
  if (fields.loading && !fields.data || records.loading && records.rows.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(import_design_system55.Skeleton, { className: "h-40 w-full" });
@@ -22234,7 +22310,7 @@ function BookingBuilder({ tableId, bookingId, onSaved, onClose, className }) {
22234
22310
  }, [load]);
22235
22311
  (0, import_react129.useEffect)(() => {
22236
22312
  if (title !== "" || !table.data) return;
22237
- setTitle(existing?.title ?? `Book a ${minutes}-minute ${table.data.name} appointment`);
22313
+ setTitle(existing?.title ?? `Book a ${minutes}-minute ${singularNoun(table.data, "appointment")}`);
22238
22314
  }, [table.data, existing]);
22239
22315
  (0, import_react129.useEffect)(() => {
22240
22316
  if (!existing) return;
@@ -22565,6 +22641,7 @@ function BookingSlots({ tableId, activeBookingId, className }) {
22565
22641
  const [copied, setCopied] = (0, import_react131.useState)(null);
22566
22642
  const [shown3, setShown] = (0, import_react131.useState)(null);
22567
22643
  const [building, setBuilding] = (0, import_react131.useState)(false);
22644
+ const [changing, setChanging] = (0, import_react131.useState)(null);
22568
22645
  const load = (0, import_react131.useCallback)(async () => {
22569
22646
  const answered = await client.bookings(tableId ? { table_id: tableId } : {});
22570
22647
  if (!answered.ok) {
@@ -22630,6 +22707,17 @@ function BookingSlots({ tableId, activeBookingId, className }) {
22630
22707
  ] }),
22631
22708
  error ? /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(RefusalNotice, { error }) : null,
22632
22709
  activeBookingId && !pages.some((p) => p.form_id === activeBookingId) ? /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("p", { className: "rounded-md border border-amber-600/40 bg-amber-500/5 px-3 py-2 text-xs leading-relaxed text-amber-700 dark:border-amber-400/40 dark:text-amber-300", children: BOOKING_NOT_HERE_LINE }) : null,
22710
+ changing ? /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
22711
+ BookingBuilder,
22712
+ {
22713
+ tableId: changing.tableId,
22714
+ bookingId: changing.formId,
22715
+ onSaved: () => {
22716
+ void load();
22717
+ },
22718
+ onClose: () => setChanging(null)
22719
+ }
22720
+ ) : null,
22633
22721
  building && tableId ? /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
22634
22722
  BookingBuilder,
22635
22723
  {
@@ -22706,6 +22794,15 @@ function BookingSlots({ tableId, activeBookingId, className }) {
22706
22794
  /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("p", { className: "mt-1 text-xs text-muted-foreground", children: nextInWords(page) }),
22707
22795
  /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)("div", { className: "mt-2 flex flex-wrap items-center gap-1.5", children: [
22708
22796
  /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(import_design_system68.Button, { size: "sm", variant: "outline", onClick: () => void copy(url, page.form_id), children: copied === page.form_id ? "Copied" : "Copy link" }),
22797
+ mayOpen ? /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
22798
+ import_design_system68.Button,
22799
+ {
22800
+ size: "sm",
22801
+ variant: "ghost",
22802
+ onClick: () => setChanging({ formId: page.form_id, tableId: page.table_id }),
22803
+ children: "Change it"
22804
+ }
22805
+ ) : null,
22709
22806
  mayOpen ? /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
22710
22807
  import_design_system68.Button,
22711
22808
  {
@@ -24542,6 +24639,7 @@ function Invite({ card, onInvited }) {
24542
24639
  // src/DigestScheduler.tsx
24543
24640
  var import_react143 = require("react");
24544
24641
  var import_react144 = require("@ai-matrx/records/react");
24642
+ var import_records29 = require("@ai-matrx/records");
24545
24643
  var import_design_system74 = require("@ai-matrx/design-system");
24546
24644
 
24547
24645
  // src/scheduleWords.ts
@@ -24584,6 +24682,12 @@ var CHANNEL_WORDS = {
24584
24682
  email: "by email \u2014 only if an address is on their account",
24585
24683
  sms: "by text \u2014 only if a number is on their account"
24586
24684
  };
24685
+ function scheduleParts(schedule) {
24686
+ const words2 = (schedule ?? "").trim().toLowerCase().split(/\s+/);
24687
+ const time = words2.find((w) => /^\d{1,2}:\d{2}$/.test(w)) ?? null;
24688
+ const day = WEEKDAYS.find((d) => words2.some((w) => w.slice(0, 3) === d.slice(0, 3))) ?? null;
24689
+ return { day, time: time ? time.padStart(5, "0") : null };
24690
+ }
24587
24691
  function DigestScheduler({
24588
24692
  tableId,
24589
24693
  savedViewId,
@@ -24591,7 +24695,8 @@ function DigestScheduler({
24591
24695
  filters,
24592
24696
  onScheduled,
24593
24697
  onClose,
24594
- className
24698
+ className,
24699
+ existing
24595
24700
  }) {
24596
24701
  const client = (0, import_react144.useRecordsClient)();
24597
24702
  const host = useRecordsUi();
@@ -24599,19 +24704,33 @@ function DigestScheduler({
24599
24704
  const [cadences, setCadences] = (0, import_react143.useState)([]);
24600
24705
  const [members, setMembers] = (0, import_react143.useState)(null);
24601
24706
  const [error, setError] = (0, import_react143.useState)(null);
24602
- const [viewId, setViewId] = (0, import_react143.useState)(savedViewId ?? "");
24603
- const [name, setName] = (0, import_react143.useState)(subjectName?.trim() ? `${subjectName.trim()} summary` : "");
24604
- const [cadence, setCadence] = (0, import_react143.useState)("weekly");
24605
- const [weekday, setWeekday] = (0, import_react143.useState)("monday");
24606
- const [time, setTime] = (0, import_react143.useState)("08:00");
24607
- const [timezone, setTimezone] = (0, import_react143.useState)(() => ownTimeZone());
24707
+ const was = scheduleParts(existing?.schedule);
24708
+ const [viewId, setViewId] = (0, import_react143.useState)(
24709
+ existing?.saved_view_id ?? savedViewId ?? ""
24710
+ );
24711
+ const [name, setName] = (0, import_react143.useState)(
24712
+ existing?.name ?? (subjectName?.trim() ? `${subjectName.trim()} summary` : "")
24713
+ );
24714
+ const [cadence, setCadence] = (0, import_react143.useState)(
24715
+ ["hourly", "daily", "weekly"].includes(existing?.cadence ?? "") ? existing.cadence : "weekly"
24716
+ );
24717
+ const [weekday, setWeekday] = (0, import_react143.useState)(was.day ?? "monday");
24718
+ const [time, setTime] = (0, import_react143.useState)(was.time ?? "08:00");
24719
+ const [timezone, setTimezone] = (0, import_react143.useState)(() => {
24720
+ const kept = existing?.quiet_hours?.tz?.trim();
24721
+ return kept && kept.toUpperCase() !== "UTC" ? kept : ownTimeZone();
24722
+ });
24608
24723
  const table = (0, import_react144.useTable)(tableId);
24609
24724
  const tableName2 = table.data?.name?.trim() || null;
24610
- const [channel, setChannel] = (0, import_react143.useState)("in_app");
24611
- const [quiet, setQuiet] = (0, import_react143.useState)(false);
24612
- const [quietFrom, setQuietFrom] = (0, import_react143.useState)("22:00");
24613
- const [quietTo, setQuietTo] = (0, import_react143.useState)("07:00");
24614
- const [recipients, setRecipients] = (0, import_react143.useState)([]);
24725
+ const [channel, setChannel] = (0, import_react143.useState)(
24726
+ existing?.channel === "email" || existing?.channel === "sms" ? existing.channel : "in_app"
24727
+ );
24728
+ const [quiet, setQuiet] = (0, import_react143.useState)((0, import_records29.hasQuietHours)(existing?.quiet_hours));
24729
+ const [quietFrom, setQuietFrom] = (0, import_react143.useState)(existing?.quiet_hours?.start ?? "22:00");
24730
+ const [quietTo, setQuietTo] = (0, import_react143.useState)(existing?.quiet_hours?.end ?? "07:00");
24731
+ const [recipients, setRecipients] = (0, import_react143.useState)(
24732
+ existing?.recipient_user_id ? [existing.recipient_user_id] : []
24733
+ );
24615
24734
  const [saving, setSaving] = (0, import_react143.useState)(false);
24616
24735
  const [outcomes, setOutcomes] = (0, import_react143.useState)(null);
24617
24736
  const [preview, setPreview] = (0, import_react143.useState)(null);
@@ -24682,7 +24801,8 @@ function DigestScheduler({
24682
24801
  schedule,
24683
24802
  channel,
24684
24803
  quiet_hours: quietHours,
24685
- ...userId === "" ? {} : { recipient_user_id: userId }
24804
+ ...userId === "" ? {} : { recipient_user_id: userId },
24805
+ ...existing ? { rule_id: existing.rule_id } : {}
24686
24806
  }
24687
24807
  });
24688
24808
  if (written.ok) done.push({ userId, who: label, ruleId: written.data });
@@ -24705,9 +24825,9 @@ function DigestScheduler({
24705
24825
  if (views === null && !error) return /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(import_design_system74.Skeleton, { className: (0, import_design_system74.cn)("h-56 w-full", className) });
24706
24826
  return /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("section", { className: (0, import_design_system74.cn)("@container flex flex-col gap-3", className), children: [
24707
24827
  /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("header", { className: "flex items-center gap-2", children: [
24708
- /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("h3", { className: "text-sm font-medium", children: "Send this on a schedule" }),
24828
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("h3", { className: "text-sm font-medium", children: existing ? "Change this summary" : "Send this on a schedule" }),
24709
24829
  /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("div", { className: "flex-1" }),
24710
- /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(import_design_system74.Button, { size: "sm", disabled: saving, onClick: () => void scheduleIt(), children: saving ? "Scheduling\u2026" : "Schedule it" }),
24830
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(import_design_system74.Button, { size: "sm", disabled: saving, onClick: () => void scheduleIt(), children: saving ? "Scheduling\u2026" : existing ? "Save the change" : "Schedule it" }),
24711
24831
  onClose ? /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(import_design_system74.Button, { size: "sm", variant: "ghost", onClick: onClose, children: "Close" }) : null
24712
24832
  ] }),
24713
24833
  error ? /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(RefusalNotice, { error }) : null,
@@ -24891,7 +25011,7 @@ function DigestScheduler({
24891
25011
  // src/SubscriptionsPanel.tsx
24892
25012
  var import_react147 = require("react");
24893
25013
  var import_react148 = require("@ai-matrx/records/react");
24894
- var import_records29 = require("@ai-matrx/records");
25014
+ var import_records30 = require("@ai-matrx/records");
24895
25015
  var import_design_system76 = require("@ai-matrx/design-system");
24896
25016
 
24897
25017
  // src/WebhooksPanel.tsx
@@ -24928,13 +25048,16 @@ function WebhooksPanel({ tableId, className }) {
24928
25048
  const [busy, setBusy] = (0, import_react145.useState)(false);
24929
25049
  const [declared2, setDeclared] = (0, import_react145.useState)(null);
24930
25050
  const [stopping, setStopping] = (0, import_react145.useState)(null);
25051
+ const [readRefused, setReadRefused] = (0, import_react145.useState)(null);
24931
25052
  const load = (0, import_react145.useCallback)(async () => {
24932
25053
  const answered = await client.tableWebhooks({ table_id: tableId });
24933
25054
  if (!answered.ok) {
25055
+ setReadRefused(answered.error);
24934
25056
  setError(answered.error);
24935
25057
  setHooks([]);
24936
25058
  return;
24937
25059
  }
25060
+ setReadRefused(null);
24938
25061
  setError(null);
24939
25062
  setHooks(answered.data ?? []);
24940
25063
  }, [client, tableId]);
@@ -24963,6 +25086,17 @@ function WebhooksPanel({ tableId, className }) {
24963
25086
  await load();
24964
25087
  };
24965
25088
  if (hooks === null) return /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(import_design_system75.Skeleton, { className: (0, import_design_system75.cn)("h-16 w-full", className) });
25089
+ const notHers = readRefused?.sqlstate === "42501" && rights.known && !rights.structure;
25090
+ if (notHers) {
25091
+ return /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("section", { "data-records-webhooks": "", className: (0, import_design_system75.cn)("flex flex-col gap-2 border-t pt-3", className), children: [
25092
+ /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("header", { className: "flex items-center gap-2", children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("h3", { className: "text-sm font-medium", children: "Webhooks" }) }),
25093
+ /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("p", { className: "text-xs text-muted-foreground", children: [
25094
+ "Which other systems are told about these records is for this table's admins.",
25095
+ " ",
25096
+ rights.why("structure")
25097
+ ] })
25098
+ ] });
25099
+ }
24966
25100
  const mayChange = rights.structure;
24967
25101
  const live = hooks.filter((h) => h.is_active);
24968
25102
  return /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("section", { "data-records-webhooks": "", className: (0, import_design_system75.cn)("flex flex-col gap-2 border-t pt-3", className), children: [
@@ -25103,6 +25237,7 @@ function SubscriptionsPanel({ tableId, activeRuleId, className }) {
25103
25237
  const [busy, setBusy] = (0, import_react147.useState)(null);
25104
25238
  const [preview, setPreview] = (0, import_react147.useState)(null);
25105
25239
  const [scheduling, setScheduling] = (0, import_react147.useState)(false);
25240
+ const [changing, setChanging] = (0, import_react147.useState)(null);
25106
25241
  const host = useRecordsUi();
25107
25242
  const load = (0, import_react147.useCallback)(async () => {
25108
25243
  const answered = await client.subscriptions({ table_id: tableId });
@@ -25174,6 +25309,18 @@ function SubscriptionsPanel({ tableId, activeRuleId, className }) {
25174
25309
  onClose: () => setScheduling(false)
25175
25310
  }
25176
25311
  ) : null,
25312
+ changing ? /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
25313
+ DigestScheduler,
25314
+ {
25315
+ tableId,
25316
+ existing: changing,
25317
+ onScheduled: () => {
25318
+ void load();
25319
+ },
25320
+ onClose: () => setChanging(null)
25321
+ },
25322
+ changing.rule_id
25323
+ ) : null,
25177
25324
  rows.length === 0 && !scheduling ? /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
25178
25325
  BuildOrAsk,
25179
25326
  {
@@ -25227,7 +25374,7 @@ function SubscriptionsPanel({ tableId, activeRuleId, className }) {
25227
25374
  "Last told you ",
25228
25375
  new Date(subscription.last_sent_at).toLocaleString()
25229
25376
  ] }) : /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { children: "It has not told you anything yet." }),
25230
- (0, import_records29.hasQuietHours)(subscription.quiet_hours) ? /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("span", { children: [
25377
+ (0, import_records30.hasQuietHours)(subscription.quiet_hours) ? /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("span", { children: [
25231
25378
  "Not between ",
25232
25379
  subscription.quiet_hours.start,
25233
25380
  " and ",
@@ -25243,7 +25390,8 @@ function SubscriptionsPanel({ tableId, activeRuleId, className }) {
25243
25390
  onClick: () => void showOne(subscription),
25244
25391
  children: "Send me a preview now"
25245
25392
  }
25246
- )
25393
+ ),
25394
+ subscription.mine && subscription.cadence !== "instant" ? /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(import_design_system76.Button, { size: "sm", variant: "ghost", onClick: () => setChanging(subscription), children: "Change it" }) : null
25247
25395
  ] }),
25248
25396
  preview && preview.rule_id === subscription.rule_id ? /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("div", { className: "mt-2 rounded-md border bg-muted/40 p-2.5 text-xs", children: [
25249
25397
  /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("p", { className: "font-medium", children: preview.subject }),
@@ -25292,7 +25440,7 @@ function SubscriptionsPanel({ tableId, activeRuleId, className }) {
25292
25440
  // src/FormBuilder.tsx
25293
25441
  var import_react153 = require("react");
25294
25442
  var import_react154 = require("@ai-matrx/records/react");
25295
- var import_records31 = require("@ai-matrx/records");
25443
+ var import_records32 = require("@ai-matrx/records");
25296
25444
  var import_design_system79 = require("@ai-matrx/design-system");
25297
25445
 
25298
25446
  // src/FormRunner.tsx
@@ -25657,7 +25805,12 @@ function ThankYou({ form, done, className }) {
25657
25805
  " ",
25658
25806
  /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("a", { href: redirect, className: "underline underline-offset-2", children: "Go now" })
25659
25807
  ] }) : null,
25660
- /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("p", { className: "mt-3 text-xs text-muted-foreground", children: done === "preview" ? redirect ? `This was a preview, so nothing was written. The live form goes on to ${redirect}.` : "This was a preview, so nothing was written." : done === "sent" ? `Saved to ${form.name}, with this form stamped on it.` : done })
25808
+ /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("p", { className: "mt-3 text-xs text-muted-foreground", children: done === "preview" ? redirect ? `This was a preview, so nothing was written. The live form goes on to ${redirect}.` : "This was a preview, so nothing was written." : done === "sent" ? (
25809
+ // SAID TO THE PERSON WHO ANSWERED (lane HANDOVER, 2026-09-29): "Saved to Form 1, with
25810
+ // this form stamped on it" was the owner's bookkeeping read out to a front-desk member
25811
+ // and to strangers. Where it landed is the owner's to see on the table.
25812
+ "Your answers were received."
25813
+ ) : done })
25661
25814
  ] });
25662
25815
  }
25663
25816
  function Question({
@@ -25705,7 +25858,7 @@ function Question({
25705
25858
  // src/NotifyRuleEditor.tsx
25706
25859
  var import_react151 = require("react");
25707
25860
  var import_react152 = require("@ai-matrx/records/react");
25708
- var import_records30 = require("@ai-matrx/records");
25861
+ var import_records31 = require("@ai-matrx/records");
25709
25862
  var import_design_system78 = require("@ai-matrx/design-system");
25710
25863
  var import_jsx_runtime87 = require("react/jsx-runtime");
25711
25864
  var CADENCE_WORDS2 = SUBSCRIPTION_CADENCE_LABEL;
@@ -25856,7 +26009,7 @@ function NotifyRuleEditor({ tableId, seed, chosenRuleId, onChoose, className })
25856
26009
  "next ",
25857
26010
  new Date(held.next_digest_at).toLocaleString()
25858
26011
  ] }) : null,
25859
- (0, import_records30.hasQuietHours)(held.quiet_hours) ? /* @__PURE__ */ (0, import_jsx_runtime87.jsxs)("span", { className: "text-muted-foreground", children: [
26012
+ (0, import_records31.hasQuietHours)(held.quiet_hours) ? /* @__PURE__ */ (0, import_jsx_runtime87.jsxs)("span", { className: "text-muted-foreground", children: [
25860
26013
  "quiet ",
25861
26014
  held.quiet_hours.start,
25862
26015
  "\u2013",
@@ -26096,9 +26249,10 @@ function FormBuilder({ tableId, seed, activeFormId, onActiveForm, startWithOne,
26096
26249
  (0, import_react153.useEffect)(() => {
26097
26250
  if (!startWithOne || started || forms === null || forms.length > 0) return;
26098
26251
  if (askableFields(fields.data ?? []).length === 0) return;
26252
+ if (!table.data && !table.error) return;
26099
26253
  setStarted(true);
26100
26254
  void create(table.data?.name?.trim() ? `${table.data.name.trim()} form` : "Form 1");
26101
- }, [startWithOne, started, forms, fields.data, create, table.data?.name]);
26255
+ }, [startWithOne, started, forms, fields.data, create, table.data, table.error]);
26102
26256
  if (fields.error) return /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(RefusalNotice, { error: fields.error, className });
26103
26257
  if (error) {
26104
26258
  return /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(
@@ -26154,7 +26308,7 @@ function FormBuilder({ tableId, seed, activeFormId, onActiveForm, startWithOne,
26154
26308
  /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(
26155
26309
  PublishRow,
26156
26310
  {
26157
- url: `${publicOrigin}${(0, import_records31.publicFormPath)(draft.id)}`,
26311
+ url: `${publicOrigin}${(0, import_records32.publicFormPath)(draft.id)}`,
26158
26312
  state: draft.state,
26159
26313
  mayPublish: rights.structure && !publishGate.blocked,
26160
26314
  why: publishGate.why ?? rights.why("structure"),
@@ -27171,7 +27325,7 @@ function SignBlock({ tableId, recordId, render, className }) {
27171
27325
  // src/ChartBlock.tsx
27172
27326
  var import_react163 = require("react");
27173
27327
  var import_recharts = require("recharts");
27174
- var import_records32 = require("@ai-matrx/records");
27328
+ var import_records33 = require("@ai-matrx/records");
27175
27329
  var import_core17 = require("@ai-matrx/records/core");
27176
27330
  var import_design_system84 = require("@ai-matrx/design-system");
27177
27331
  var import_jsx_runtime93 = require("react/jsx-runtime");
@@ -27242,7 +27396,7 @@ function ChartBlock({ block, subject, className }) {
27242
27396
  const kind = block.kind;
27243
27397
  const tableId = block.table_id ?? subject;
27244
27398
  const measures = block.measures && block.measures.length > 0 ? block.measures : [{ op: "count" }];
27245
- const primary = (0, import_records32.measureKey)(measures[0]);
27399
+ const primary = (0, import_records33.measureKey)(measures[0]);
27246
27400
  const windows = kind === "stuck" ? null : block.compare ?? null;
27247
27401
  const compared = !!windows;
27248
27402
  const grain = block.bucket?.by ?? null;
@@ -28179,7 +28333,7 @@ function TargetControl({
28179
28333
  // src/FormsPanel.tsx
28180
28334
  var import_react166 = require("react");
28181
28335
  var import_react167 = require("@ai-matrx/records/react");
28182
- var import_records33 = require("@ai-matrx/records");
28336
+ var import_records34 = require("@ai-matrx/records");
28183
28337
  var import_design_system86 = require("@ai-matrx/design-system");
28184
28338
  var import_jsx_runtime95 = require("react/jsx-runtime");
28185
28339
  var FORM_NOT_HERE_LINE = "The link named a form this table does not have \u2014 it may have been removed, or it belongs to another table. The forms this table does have are listed here.";
@@ -28284,7 +28438,7 @@ function FormsPanel({ tableId, activeFormId, className }) {
28284
28438
  }
28285
28439
  ) : null,
28286
28440
  /* @__PURE__ */ (0, import_jsx_runtime95.jsx)("ul", { className: "flex flex-col gap-2", children: forms.map((form) => {
28287
- const url = `${origin}${(0, import_records33.publicFormPath)(form.form_id)}`;
28441
+ const url = `${origin}${(0, import_records34.publicFormPath)(form.form_id)}`;
28288
28442
  return /* @__PURE__ */ (0, import_jsx_runtime95.jsxs)(
28289
28443
  "li",
28290
28444
  {
@@ -28353,7 +28507,7 @@ var import_design_system88 = require("@ai-matrx/design-system");
28353
28507
 
28354
28508
  // src/CaptureRun.tsx
28355
28509
  var import_react168 = require("react");
28356
- var import_records34 = require("@ai-matrx/records");
28510
+ var import_records35 = require("@ai-matrx/records");
28357
28511
  var import_react169 = require("@ai-matrx/records/react");
28358
28512
  var import_design_system87 = require("@ai-matrx/design-system");
28359
28513
  var import_jsx_runtime96 = require("react/jsx-runtime");
@@ -28408,7 +28562,7 @@ function CaptureRun({ sheetId, face: given, className }) {
28408
28562
  const [sending, setSending] = (0, import_react168.useState)(false);
28409
28563
  const queueRef = (0, import_react168.useRef)(null);
28410
28564
  (0, import_react168.useEffect)(() => {
28411
- const q2 = (0, import_records34.openCaptureQueue)({
28565
+ const q2 = (0, import_records35.openCaptureQueue)({
28412
28566
  onChange: (c, all) => {
28413
28567
  setCounts(c);
28414
28568
  setItems(all);
@@ -28675,7 +28829,7 @@ function CaptureRun({ sheetId, face: given, className }) {
28675
28829
  value: String(answers[q.field] ?? ""),
28676
28830
  onChange: (e) => {
28677
28831
  const raw = e.target.value;
28678
- const answered2 = field2 ? (0, import_records34.coerceTypedAnswer)(field2, raw, { label: q.ask ?? (0, import_records34.coercionLabel)(field2) }) : { value: raw };
28832
+ const answered2 = field2 ? (0, import_records35.coerceTypedAnswer)(field2, raw, { label: q.ask ?? (0, import_records35.coercionLabel)(field2) }) : { value: raw };
28679
28833
  setAnswers((held) => ({
28680
28834
  ...held,
28681
28835
  [q.field]: raw === "" ? "" : "refusal" in answered2 ? raw : answered2.value
@@ -29347,7 +29501,7 @@ function recordsDataSource(client, fallbackSchema = "custom") {
29347
29501
 
29348
29502
  // src/TablePage.tsx
29349
29503
  var import_react184 = require("react");
29350
- var import_records35 = require("@ai-matrx/records");
29504
+ var import_records36 = require("@ai-matrx/records");
29351
29505
  var import_react185 = require("@ai-matrx/records/react");
29352
29506
  var import_design_system93 = require("@ai-matrx/design-system");
29353
29507
 
@@ -29722,7 +29876,7 @@ function TableNotHere({
29722
29876
  return /* @__PURE__ */ (0, import_jsx_runtime103.jsxs)("div", { className: (0, import_design_system93.cn)("flex flex-col items-start gap-2 rounded-md border border-dashed p-6", className), children: [
29723
29877
  /* @__PURE__ */ (0, import_jsx_runtime103.jsx)("p", { className: "text-sm font-medium", children: "This table is archived" }),
29724
29878
  /* @__PURE__ */ (0, import_jsx_runtime103.jsx)("p", { className: "max-w-prose text-xs text-muted-foreground", children: TABLE_IS_ARCHIVED }),
29725
- /* @__PURE__ */ (0, import_jsx_runtime103.jsx)("p", { className: "text-xs text-muted-foreground", children: (0, import_records35.archivedByLine)(row) }),
29879
+ /* @__PURE__ */ (0, import_jsx_runtime103.jsx)("p", { className: "text-xs text-muted-foreground", children: (0, import_records36.archivedByLine)(row) }),
29726
29880
  refusal2 ? /* @__PURE__ */ (0, import_jsx_runtime103.jsx)(RefusalNotice, { error: refusal2 }) : null,
29727
29881
  /* @__PURE__ */ (0, import_jsx_runtime103.jsxs)("div", { className: "flex gap-2", children: [
29728
29882
  /* @__PURE__ */ (0, import_jsx_runtime103.jsx)(