@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/dist/index.js CHANGED
@@ -347,6 +347,10 @@ function realPlural(table) {
347
347
  }
348
348
  return plural3;
349
349
  }
350
+ function singularNoun(table, fallback = "record") {
351
+ const word = (table?.label_singular ?? "").trim() || (table?.name ?? "").trim() || fallback;
352
+ return word.split(/\s+/).map((w) => /^[A-Z][a-z'’-]*$/.test(w) ? w.toLowerCase() : w).join(" ");
353
+ }
350
354
  function pluralNoun(table, fallback = "record") {
351
355
  const real = table ? realPlural(table) : null;
352
356
  if (real) return real;
@@ -2436,7 +2440,7 @@ function NumberInFormat({ format, value, onChange, disabled, id }) {
2436
2440
  function formatControl(args) {
2437
2441
  const def = getFieldFormat3(args.format.id);
2438
2442
  if (!def) return null;
2439
- const { format, value, onChange, disabled, id, label } = args;
2443
+ const { format, value, onChange, disabled, id, label, ownDetails } = args;
2440
2444
  const text = value === null || value === void 0 ? "" : String(value);
2441
2445
  const commit = (raw) => onChange(raw === "" ? null : parseFieldInput(raw, format));
2442
2446
  if (def.id === "rating") {
@@ -2459,7 +2463,17 @@ function formatControl(args) {
2459
2463
  case "email":
2460
2464
  case "url":
2461
2465
  case "tel":
2462
- return /* @__PURE__ */ jsx11(BasicInput4, { id, type: def.editor, value: text, disabled, onChange: (e) => commit(e.target.value) });
2466
+ return /* @__PURE__ */ jsx11(
2467
+ BasicInput4,
2468
+ {
2469
+ id,
2470
+ type: def.editor,
2471
+ ...ownDetails && def.editor !== "url" ? { autoComplete: def.editor === "email" ? "email" : "tel" } : {},
2472
+ value: text,
2473
+ disabled,
2474
+ onChange: (e) => commit(e.target.value)
2475
+ }
2476
+ );
2463
2477
  case "color":
2464
2478
  return /* @__PURE__ */ jsxs9("span", { className: "flex items-center gap-2", children: [
2465
2479
  /* @__PURE__ */ jsx11(
@@ -2713,14 +2727,19 @@ function TypedTextControl({ field: field2, value, onChange, disabled, id, onComm
2713
2727
  ] })
2714
2728
  ] });
2715
2729
  }
2730
+ function isPersonsName(field2) {
2731
+ const words2 = `${field2.key} ${field2.label ?? ""}`.toLowerCase();
2732
+ return /(^|[\s_])(full[\s_]?)?name(\s|$)/.test(words2) && !/(therapist|doctor|physician|company|business|pet|room)/.test(words2);
2733
+ }
2716
2734
  function FieldControl({ field: field2, value, onChange, disabled, id, autoOpen, onClose, onCommit, onCancel, addsChoices, initialSearch }) {
2717
2735
  const host = useRecordsUi();
2718
2736
  const kind = editorKindFor(field2);
2719
2737
  const inputId = id ?? `field-${field2.key}`;
2738
+ const ownDetails = useOptionalRecordsClient5() === null;
2720
2739
  if (isTypedDraft(value)) return /* @__PURE__ */ jsx12(TypedTextControl, { field: field2, value, onChange, disabled, id: inputId, onCommit, onCancel });
2721
2740
  const format = formatForField(field2);
2722
2741
  if (format && !FORMAT_BLIND_KINDS.has(String(kind))) {
2723
- const own2 = formatControl({ format, value, onChange, disabled, id: inputId, label: fieldName(field2) });
2742
+ const own2 = formatControl({ format, value, onChange, disabled, id: inputId, label: fieldName(field2), ownDetails });
2724
2743
  if (own2) return own2;
2725
2744
  }
2726
2745
  switch (kind) {
@@ -2781,6 +2800,7 @@ function FieldControl({ field: field2, value, onChange, disabled, id, autoOpen,
2781
2800
  {
2782
2801
  id: inputId,
2783
2802
  type: kind === "email" ? "email" : kind === "phone" ? "tel" : "url",
2803
+ ...ownDetails && kind !== "url" ? { autoComplete: kind === "email" ? "email" : "tel" } : {},
2784
2804
  value: value === null || value === void 0 ? "" : String(value),
2785
2805
  disabled,
2786
2806
  onChange: (e) => onChange(e.target.value === "" ? null : e.target.value)
@@ -2818,6 +2838,7 @@ function FieldControl({ field: field2, value, onChange, disabled, id, autoOpen,
2818
2838
  BasicInput5,
2819
2839
  {
2820
2840
  id: inputId,
2841
+ ...ownDetails && isPersonsName(field2) ? { autoComplete: "name" } : {},
2821
2842
  value: value === null || value === void 0 ? "" : String(value),
2822
2843
  disabled,
2823
2844
  onChange: (e) => onChange(e.target.value === "" ? null : e.target.value)
@@ -5234,6 +5255,22 @@ function archiveConfirmSentence(what) {
5234
5255
  const subject = what.trim() || "it";
5235
5256
  return `This archives ${subject}. It leaves this list, and you can restore it from Trash.`;
5236
5257
  }
5258
+ var recordsWord = (n) => `${n.toLocaleString()} record${n === 1 ? "" : "s"}`;
5259
+ function tableArchiveSentence(s) {
5260
+ const p = s.progress;
5261
+ if (!p) return "Every record in it goes with it.";
5262
+ const done = p.total - p.remaining;
5263
+ const sofar = `${done.toLocaleString()} of ${recordsWord(p.total)} ${done === 1 ? "is" : "are"} put away`;
5264
+ if (s.running) {
5265
+ 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." : ""}`;
5266
+ }
5267
+ if (p.in_progress && !s.failed && !(s.passesHere ?? 0)) {
5268
+ return `Archiving this table was started and not finished: ${sofar}. Carry on and it picks up where it stopped.`;
5269
+ }
5270
+ 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.`;
5271
+ if (s.interrupted) return `Stopped: ${sofar}. Carry on whenever you like; it picks up where it stopped.`;
5272
+ return `Its ${recordsWord(p.remaining)} ${p.remaining === 1 ? "goes" : "go"} with it.`;
5273
+ }
5237
5274
 
5238
5275
  // src/tableDecorations.ts
5239
5276
  import { useCallback as useCallback7, useEffect as useEffect12, useState as useState15 } from "react";
@@ -16190,8 +16227,9 @@ function Clause({
16190
16227
  }
16191
16228
 
16192
16229
  // src/TableSettings.tsx
16193
- import { useState as useState45 } from "react";
16230
+ import { useEffect as useEffect36, useState as useState45 } from "react";
16194
16231
  import {
16232
+ useRecordsClient as useRecordsClient28,
16195
16233
  useFieldMutation as useFieldMutation3,
16196
16234
  useFields as useFields9,
16197
16235
  useTable as useTable6,
@@ -16212,6 +16250,17 @@ function TableSettings({
16212
16250
  const rights = useTableRights(table.data);
16213
16251
  const shape = useFieldMutation3();
16214
16252
  const archive = useTableArchive(tableId);
16253
+ const client = useRecordsClient28();
16254
+ const ui = useRecordsUi();
16255
+ useEffect36(() => {
16256
+ let live = true;
16257
+ void archive.preview().then((answer) => {
16258
+ if (live && answer?.in_progress) setAskingToDelete(true);
16259
+ });
16260
+ return () => {
16261
+ live = false;
16262
+ };
16263
+ }, [tableId]);
16215
16264
  const [editing, setEditing] = useState45(null);
16216
16265
  const [askingToDelete, setAskingToDelete] = useState45(false);
16217
16266
  const [askingToRemove, setAskingToRemove] = useState45(null);
@@ -16240,6 +16289,16 @@ function TableSettings({
16240
16289
  const finished = await archive.start();
16241
16290
  if (finished?.done && finished.table_archived) {
16242
16291
  setAskingToDelete(false);
16292
+ const name = finished.table_name || "The table";
16293
+ ui.notify?.success(`\u201C${name}\u201D is archived. You can restore it from Trash.`, {
16294
+ label: "Undo",
16295
+ run: () => {
16296
+ void client.recordRestore({ record_id: tableId }).then((back) => {
16297
+ if (back.ok) ui.notify?.success(`\u201C${name}\u201D is back, with everything in it.`);
16298
+ else ui.notify?.error(back.error.message);
16299
+ });
16300
+ }
16301
+ });
16243
16302
  onDeleted?.();
16244
16303
  }
16245
16304
  };
@@ -16371,31 +16430,20 @@ function TableSettings({
16371
16430
  /* @__PURE__ */ jsxs47("div", { className: "flex flex-col gap-1", children: [
16372
16431
  /* @__PURE__ */ jsx54("span", { className: "font-medium", children: "This table" }),
16373
16432
  askingToDelete ? /* @__PURE__ */ jsxs47(Fragment21, { children: [
16374
- /* @__PURE__ */ jsxs47("p", { className: "text-muted-foreground", "data-archive-confirm": "table", children: [
16375
- archiveConfirmSentence(table.data ? `the table \u201C${tableName(table.data)}\u201D` : "this table"),
16376
- " ",
16377
- "Its ",
16378
- rows.length,
16379
- " field",
16380
- rows.length === 1 ? "" : "s",
16381
- " and",
16382
- " ",
16383
- archive.progress ? `its ${archive.progress.remaining.toLocaleString()} record${archive.progress.remaining === 1 ? "" : "s"}` : "every record in it",
16384
- " ",
16385
- "go with it",
16386
- table.data?.retention_days ? `, kept for ${table.data.retention_days} days` : "",
16387
- "."
16388
- ] }),
16389
- archive.progress && (archive.running || archive.passes > 0) ? /* @__PURE__ */ jsxs47("p", { className: archive.error ? "text-destructive" : "text-muted-foreground", children: [
16390
- 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.`,
16391
- archive.slowedDown ? " The store is busy, so it is taking smaller passes \u2014 it will still finish." : ""
16392
- ] }) : null,
16393
- archive.interrupted && archive.progress ? /* @__PURE__ */ jsx54("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,
16433
+ /* @__PURE__ */ jsx54("p", { className: "text-muted-foreground", "data-archive-confirm": "table", children: archiveConfirmSentence(table.data ? `the table \u201C${tableName(table.data)}\u201D` : "this table") }),
16434
+ /* @__PURE__ */ jsx54("p", { className: "text-muted-foreground", "data-archive-state": "", children: tableArchiveSentence({
16435
+ progress: archive.progress,
16436
+ running: archive.running,
16437
+ interrupted: archive.interrupted,
16438
+ failed: Boolean(archive.error),
16439
+ slowedDown: archive.slowedDown,
16440
+ passesHere: archive.passes
16441
+ }) }),
16394
16442
  /* @__PURE__ */ jsx54("div", { className: "flex gap-1", children: archive.running ? /* @__PURE__ */ jsxs47(Fragment21, { children: [
16395
16443
  /* @__PURE__ */ jsx54(Button38, { size: "sm", variant: "destructive", disabled: true, children: "Archiving\u2026" }),
16396
16444
  /* @__PURE__ */ jsx54(Button38, { size: "sm", variant: "ghost", onClick: () => archive.stop(), children: "Stop" })
16397
16445
  ] }) : /* @__PURE__ */ jsxs47(Fragment21, { children: [
16398
- /* @__PURE__ */ jsx54(Button38, { size: "sm", variant: "destructive", onClick: () => void startArchive(), children: archive.interrupted ? "Carry on archiving" : "Archive this table" }),
16446
+ /* @__PURE__ */ jsx54(Button38, { size: "sm", variant: "destructive", onClick: () => void startArchive(), children: archive.interrupted || archive.progress?.in_progress ? "Carry on archiving" : "Archive this table" }),
16399
16447
  /* @__PURE__ */ jsx54(Button38, { size: "sm", variant: "ghost", onClick: () => setAskingToDelete(false), children: "Keep it" })
16400
16448
  ] }) })
16401
16449
  ] }) : /* @__PURE__ */ jsx54("div", { children: /* @__PURE__ */ jsx54(Button38, { size: "sm", variant: "outline", onClick: () => void askToArchive(), children: "Archive this table" }) }),
@@ -16406,21 +16454,21 @@ function TableSettings({
16406
16454
 
16407
16455
  // src/Peek.tsx
16408
16456
  import { useState as useState50 } from "react";
16409
- import { useFields as useFields11, useRecord as useRecord2, useRecordsClient as useRecordsClient31, useTable as useTable7 } from "@ai-matrx/records/react";
16457
+ import { useFields as useFields11, useRecord as useRecord2, useRecordsClient as useRecordsClient32, useTable as useTable7 } from "@ai-matrx/records/react";
16410
16458
  import { AlchemyMenu as AlchemyMenu2 } from "@ai-matrx/alchemy/react";
16411
16459
 
16412
16460
  // src/RecordChat.tsx
16413
- import { useEffect as useEffect36, useMemo as useMemo27, useState as useState46 } from "react";
16414
- import { useRecordsClient as useRecordsClient28 } from "@ai-matrx/records/react";
16461
+ import { useEffect as useEffect37, useMemo as useMemo27, useState as useState46 } from "react";
16462
+ import { useRecordsClient as useRecordsClient29 } from "@ai-matrx/records/react";
16415
16463
  import { Skeleton as Skeleton4, cn as cn29 } from "@ai-matrx/design-system";
16416
16464
  import { jsx as jsx55, jsxs as jsxs48 } from "react/jsx-runtime";
16417
16465
  var NO_CHAT_REASON = "Chatting about this record is not switched on here yet, so this panel is empty rather than showing a box that goes nowhere. It is on our list, not yours.";
16418
16466
  function RecordChat({ tableId, recordId, className }) {
16419
- const client = useRecordsClient28();
16467
+ const client = useRecordsClient29();
16420
16468
  const host = useRecordsUi();
16421
16469
  const [scope, setScope] = useState46(null);
16422
16470
  const [error, setError] = useState46(null);
16423
- useEffect36(() => {
16471
+ useEffect37(() => {
16424
16472
  let cancelled = false;
16425
16473
  setScope(null);
16426
16474
  setError(null);
@@ -16537,12 +16585,12 @@ function entriesFor(scope) {
16537
16585
  import { Button as Button41, Separator as Separator8, Skeleton as Skeleton5, cn as cn31 } from "@ai-matrx/design-system";
16538
16586
 
16539
16587
  // src/RecordForm.tsx
16540
- import { useEffect as useEffect38, useMemo as useMemo29, useRef as useRef18, useState as useState48 } from "react";
16588
+ import { useEffect as useEffect39, useMemo as useMemo29, useRef as useRef18, useState as useState48 } from "react";
16541
16589
  import {
16542
16590
  useFields as useFields10,
16543
16591
  useRecord,
16544
16592
  useRecordMutation,
16545
- useRecordsClient as useRecordsClient30
16593
+ useRecordsClient as useRecordsClient31
16546
16594
  } from "@ai-matrx/records/react";
16547
16595
  import { asWriteConflict as asWriteConflict3, predictWriteRefusals, wholeValueOf as wholeValueOf5 } from "@ai-matrx/records/core";
16548
16596
 
@@ -16580,8 +16628,8 @@ async function updateOnTheWinningVersion(client, recordId, patch, expectedVersio
16580
16628
  import { Button as Button39, Separator as Separator7, cn as cn30 } from "@ai-matrx/design-system";
16581
16629
 
16582
16630
  // src/systemTable.ts
16583
- import { useEffect as useEffect37, useMemo as useMemo28, useState as useState47 } from "react";
16584
- import { useRecordsClient as useRecordsClient29 } from "@ai-matrx/records/react";
16631
+ import { useEffect as useEffect38, useMemo as useMemo28, useState as useState47 } from "react";
16632
+ import { useRecordsClient as useRecordsClient30 } from "@ai-matrx/records/react";
16585
16633
  var inFlight = /* @__PURE__ */ new Map();
16586
16634
  async function ensureSystemTable(client, spec) {
16587
16635
  const cacheKey = `${client.config.organizationId}:${spec.slug}`;
@@ -16709,11 +16757,11 @@ async function declare(client, spec) {
16709
16757
  return { ok: true, data: table.data };
16710
16758
  }
16711
16759
  function useSystemTable(spec) {
16712
- const client = useRecordsClient29();
16760
+ const client = useRecordsClient30();
16713
16761
  const [state, setState] = useState47({ tableId: null, loading: true, error: null });
16714
16762
  const slug = spec.slug;
16715
16763
  const stable = useMemo28(() => spec, [slug]);
16716
- useEffect37(() => {
16764
+ useEffect38(() => {
16717
16765
  let cancelled = false;
16718
16766
  setState({ tableId: null, loading: true, error: null });
16719
16767
  void ensureSystemTable(client, stable).then((result) => {
@@ -16729,9 +16777,9 @@ function useSystemTable(spec) {
16729
16777
  return state;
16730
16778
  }
16731
16779
  function useRecordVersion(recordId) {
16732
- const client = useRecordsClient29();
16780
+ const client = useRecordsClient30();
16733
16781
  const [version, setVersion] = useState47(null);
16734
- useEffect37(() => {
16782
+ useEffect38(() => {
16735
16783
  let cancelled = false;
16736
16784
  setVersion(null);
16737
16785
  if (!recordId) return;
@@ -16764,7 +16812,7 @@ function RecordForm({
16764
16812
  const fields = useFields10(tableId, recordType);
16765
16813
  const existing = useRecord(recordId ?? null);
16766
16814
  const mutation = useRecordMutation();
16767
- const client = useRecordsClient30();
16815
+ const client = useRecordsClient31();
16768
16816
  const [edit, setEdit] = useState48({
16769
16817
  saving: false,
16770
16818
  error: null,
@@ -16787,7 +16835,7 @@ function RecordForm({
16787
16835
  const loadedVersion = loaded.version;
16788
16836
  const changedRef = useRef18({});
16789
16837
  changedRef.current = changed;
16790
- useEffect38(() => {
16838
+ useEffect39(() => {
16791
16839
  const document3 = existing.data?.document;
16792
16840
  if (!document3) return;
16793
16841
  const mine = changedRef.current;
@@ -16988,7 +17036,7 @@ function asWords(value) {
16988
17036
  }
16989
17037
 
16990
17038
  // src/ShareControl.tsx
16991
- import { useEffect as useEffect39, useState as useState49 } from "react";
17039
+ import { useEffect as useEffect40, useState as useState49 } from "react";
16992
17040
  import { Button as Button40 } from "@ai-matrx/design-system";
16993
17041
  import { Fragment as Fragment22, jsx as jsx57, jsxs as jsxs50 } from "react/jsx-runtime";
16994
17042
  function useCanShare() {
@@ -17010,7 +17058,7 @@ function ShareControl({
17010
17058
  }) {
17011
17059
  const host = useRecordsUi();
17012
17060
  const [open, setOpen] = useState49(initiallyOpen);
17013
- useEffect39(() => {
17061
+ useEffect40(() => {
17014
17062
  if (initiallyOpen) setOpen(true);
17015
17063
  }, [initiallyOpen]);
17016
17064
  const asked2 = useRecordRights(may === void 0 ? subjectId : null);
@@ -17049,7 +17097,7 @@ function Peek({ tableId, recordId, onClose, className }) {
17049
17097
  const record = useRecord2(recordId, true);
17050
17098
  const may = useRecordRights(recordId);
17051
17099
  const host = useRecordsUi();
17052
- const organizationId = useRecordsClient31().config.organizationId;
17100
+ const organizationId = useRecordsClient32().config.organizationId;
17053
17101
  const [editing, setEditing] = useState50(false);
17054
17102
  const [talking, setTalking] = useState50(false);
17055
17103
  if (record.error) return /* @__PURE__ */ jsx58(RefusalNotice, { error: record.error, className });
@@ -17226,8 +17274,8 @@ var LOOK_WORDS = {
17226
17274
  };
17227
17275
 
17228
17276
  // src/ViewSwitcher.tsx
17229
- import { useEffect as useEffect42, useMemo as useMemo31, useState as useState54 } from "react";
17230
- import { useFields as useFields13, useRecords as useRecords6, useRecordsClient as useRecordsClient34 } from "@ai-matrx/records/react";
17277
+ import { useEffect as useEffect44, useMemo as useMemo31, useState as useState54 } from "react";
17278
+ import { useFields as useFields13, useRecords as useRecords6, useRecordsClient as useRecordsClient35 } from "@ai-matrx/records/react";
17231
17279
  import { stableFilterKey as stableFilterKey4 } from "@ai-matrx/records";
17232
17280
  import { Button as Button45, Skeleton as Skeleton7, cn as cn34 } from "@ai-matrx/design-system";
17233
17281
  import {
@@ -17236,11 +17284,11 @@ import {
17236
17284
  } from "@ai-matrx/design-system/data-table";
17237
17285
 
17238
17286
  // src/Pipeline.tsx
17239
- import { useCallback as useCallback21, useEffect as useEffect40, useMemo as useMemo30, useRef as useRef19, useState as useState51 } from "react";
17287
+ import { useCallback as useCallback21, useEffect as useEffect41, useMemo as useMemo30, useRef as useRef19, useState as useState51 } from "react";
17240
17288
  import {
17241
17289
  mayDrag,
17242
17290
  useFields as useFields12,
17243
- useRecordsClient as useRecordsClient32
17291
+ useRecordsClient as useRecordsClient33
17244
17292
  } from "@ai-matrx/records/react";
17245
17293
  import { stableFilterKey as stableFilterKey3 } from "@ai-matrx/records";
17246
17294
  import {
@@ -17332,7 +17380,7 @@ function PipelineBoard({
17332
17380
  dateFields,
17333
17381
  className
17334
17382
  }) {
17335
- const client = useRecordsClient32();
17383
+ const client = useRecordsClient33();
17336
17384
  const fields = useFields12(tableId);
17337
17385
  const ownDecorations = useTableDecorations(style ? null : tableId);
17338
17386
  const cardStyle = useMemo30(
@@ -17355,7 +17403,7 @@ function PipelineBoard({
17355
17403
  const [batchSaid, setBatchSaid] = useState51(null);
17356
17404
  const [batchError, setBatchError] = useState51(null);
17357
17405
  const [moving, setMoving] = useState51(false);
17358
- useEffect40(() => {
17406
+ useEffect41(() => {
17359
17407
  alive.current = true;
17360
17408
  return () => {
17361
17409
  alive.current = false;
@@ -17380,10 +17428,10 @@ function PipelineBoard({
17380
17428
  setWaiting(held.ok ? new Map((held.data ?? []).map((p) => [p.record_id, p])) : /* @__PURE__ */ new Map());
17381
17429
  setColumns(board.ok ? board.data ?? [] : []);
17382
17430
  }, [client, tableId, measure, filterKey]);
17383
- useEffect40(() => {
17431
+ useEffect41(() => {
17384
17432
  void reload();
17385
17433
  }, [reload]);
17386
- useEffect40(() => {
17434
+ useEffect41(() => {
17387
17435
  const ids = rows.filter((r) => mayDrag(r.level)).map((r) => r.id);
17388
17436
  if (ids.length === 0) {
17389
17437
  setVersions({ ok: true, map: /* @__PURE__ */ new Map() });
@@ -17980,8 +18028,8 @@ function batchSentence(moved, waiting, notMoved, label) {
17980
18028
  }
17981
18029
 
17982
18030
  // src/ViewNeeds.tsx
17983
- import { useState as useState52 } from "react";
17984
- import { useFieldMutation as useFieldMutation4, useRecordsClient as useRecordsClient33, useTable as useTable8 } from "@ai-matrx/records/react";
18031
+ import { useEffect as useEffect42, useState as useState52 } from "react";
18032
+ import { useFieldMutation as useFieldMutation4, useRecordsClient as useRecordsClient34, useTable as useTable8 } from "@ai-matrx/records/react";
17985
18033
  import { BasicInput as BasicInput15, Button as Button44, Label as Label13 } from "@ai-matrx/design-system";
17986
18034
 
17987
18035
  // src/BuildOrAsk.tsx
@@ -18031,6 +18079,18 @@ function columnDeclarationFor(need, label, options, fields) {
18031
18079
  if (need.starter.type === "datetime") return { ...base, parity_type: "datetime", kind: "date" };
18032
18080
  return { ...base, parity_type: "attachment" };
18033
18081
  }
18082
+ var askedFor = /* @__PURE__ */ new Map();
18083
+ var askKey = (tableId, layout) => `${tableId}:${layout}`;
18084
+ function useAskedColumnLands(layout, tableId, fields, chosen, offerable, onMade) {
18085
+ const wanted = askedFor.get(askKey(tableId, layout));
18086
+ const landed = wanted && !chosen ? offerable(fields).find((f) => fieldName(f).trim().toLowerCase() === wanted.trim().toLowerCase()) : void 0;
18087
+ const key = landed?.key ?? null;
18088
+ useEffect42(() => {
18089
+ if (!key) return;
18090
+ askedFor.delete(askKey(tableId, layout));
18091
+ onMade(key);
18092
+ }, [key, tableId, layout]);
18093
+ }
18034
18094
  var NO_ASSISTANT = "Asking in words needs the AI assistant, which this screen is not connected to.";
18035
18095
  function ViewNeeds({ layout, tableId, fields, onMade, className }) {
18036
18096
  const need = viewNeedFor(layout);
@@ -18038,7 +18098,7 @@ function ViewNeeds({ layout, tableId, fields, onMade, className }) {
18038
18098
  const rights = useTableRights(table.data);
18039
18099
  const host = useRecordsUi();
18040
18100
  const mutation = useFieldMutation4();
18041
- const client = useRecordsClient33();
18101
+ const client = useRecordsClient34();
18042
18102
  const taken = fields.map((f) => fieldName(f));
18043
18103
  const [label, setLabel] = useState52(() => freeColumnName(need?.starter.label ?? "", taken));
18044
18104
  const [options, setOptions] = useState52(() => [...need?.starter.options ?? []]);
@@ -18121,7 +18181,12 @@ function ViewNeeds({ layout, tableId, fields, onMade, className }) {
18121
18181
  editor,
18122
18182
  noAgentSentence: NO_ASSISTANT,
18123
18183
  suggestion,
18124
- ...host.onAskForOne ? { onAsk: () => host.onAskForOne?.({ kind: "column", tableId, suggestion }) } : {},
18184
+ ...host.onAskForOne ? {
18185
+ onAsk: () => {
18186
+ askedFor.set(askKey(tableId, layout), name);
18187
+ host.onAskForOne?.({ kind: "column", tableId, suggestion });
18188
+ }
18189
+ } : {},
18125
18190
  children: rights.structure ? `${need.missing} ${need.does(name)}` : need.missing
18126
18191
  }
18127
18192
  ),
@@ -18132,7 +18197,7 @@ function ViewNeeds({ layout, tableId, fields, onMade, className }) {
18132
18197
  }
18133
18198
 
18134
18199
  // src/GalleryCover.tsx
18135
- import { useEffect as useEffect41, useState as useState53 } from "react";
18200
+ import { useEffect as useEffect43, useState as useState53 } from "react";
18136
18201
  import { useOptionalRecordsClient as useOptionalRecordsClient7 } from "@ai-matrx/records/react";
18137
18202
  import { Fragment as Fragment25, jsx as jsx63 } from "react/jsx-runtime";
18138
18203
  function isImageAddress(value) {
@@ -18154,7 +18219,7 @@ function FileCover({ recordId }) {
18154
18219
  const client = useOptionalRecordsClient7();
18155
18220
  const host = useRecordsUi();
18156
18221
  const [read, setRead] = useState53(null);
18157
- useEffect41(() => {
18222
+ useEffect43(() => {
18158
18223
  let cancelled = false;
18159
18224
  if (!client) {
18160
18225
  setRead({ fileId: recordId, name: "" });
@@ -18187,7 +18252,7 @@ function FileCover({ recordId }) {
18187
18252
  import { Fragment as Fragment26, jsx as jsx64, jsxs as jsxs56 } from "react/jsx-runtime";
18188
18253
  var NO_FIELDS = [];
18189
18254
  function useViewRecords(view, pageSize = 200, filter, viewId) {
18190
- const client = useRecordsClient34();
18255
+ const client = useRecordsClient35();
18191
18256
  const table = useRecords6(view.ruleId ? null : view.subject, {
18192
18257
  pageSize,
18193
18258
  ...filter ? { filter } : {}
@@ -18198,7 +18263,7 @@ function useViewRecords(view, pageSize = 200, filter, viewId) {
18198
18263
  error: null
18199
18264
  });
18200
18265
  const ruleId = view.ruleId ?? null;
18201
- useEffect42(() => {
18266
+ useEffect44(() => {
18202
18267
  if (!ruleId) return;
18203
18268
  let cancelled = false;
18204
18269
  setRuled({ rows: [], loading: true, error: null });
@@ -18285,7 +18350,7 @@ function ViewSwitcher({
18285
18350
  const hostLayouts = useRecordsUi().layouts ?? [];
18286
18351
  const drawnByHost = hostLayout ? hostLayouts.find((h) => h.id === hostLayout) ?? null : null;
18287
18352
  const [local, setLocal] = useState54({});
18288
- useEffect42(() => {
18353
+ useEffect44(() => {
18289
18354
  setLayout(view.layout);
18290
18355
  setLocal({});
18291
18356
  }, [view.layout, view.name, view.subject]);
@@ -18393,12 +18458,12 @@ function offerableFields(all, want) {
18393
18458
  });
18394
18459
  }
18395
18460
  function useStageField(tableId) {
18396
- const client = useRecordsClient34();
18461
+ const client = useRecordsClient35();
18397
18462
  const [stage, setStage] = useState54({
18398
18463
  asked: false,
18399
18464
  key: null
18400
18465
  });
18401
- useEffect42(() => {
18466
+ useEffect44(() => {
18402
18467
  let cancelled = false;
18403
18468
  setStage({ asked: false, key: null });
18404
18469
  void client.tableStageField({ table_id: tableId }).then((r) => {
@@ -18441,6 +18506,17 @@ function Board({
18441
18506
  () => resolveTableStyle(decorations.data, fields.data ?? [], view.presentation?.style),
18442
18507
  [decorations.data, fields.data, view.presentation?.style]
18443
18508
  );
18509
+ const askedLayout = view.layout === "grid" ? "kanban" : view.layout;
18510
+ const askedKind = askedLayout === "kanban" ? "choice" : askedLayout === "calendar" ? "date" : "file";
18511
+ const askedChosen = askedLayout === "kanban" ? view.groupField : askedLayout === "calendar" ? view.dateField : view.imageField;
18512
+ useAskedColumnLands(
18513
+ askedLayout,
18514
+ view.subject,
18515
+ fields.data ?? NO_FIELDS,
18516
+ askedChosen,
18517
+ (all2) => offerableFields(all2, askedKind),
18518
+ (key) => onChange(askedLayout === "kanban" ? { groupField: key } : askedLayout === "calendar" ? { dateField: key } : { imageField: key })
18519
+ );
18444
18520
  if (fields.error) return /* @__PURE__ */ jsx64(RefusalNotice, { error: fields.error });
18445
18521
  if (records.error) return /* @__PURE__ */ jsx64(RefusalNotice, { error: records.error });
18446
18522
  if (fields.loading && !fields.data || records.loading && records.rows.length === 0) return /* @__PURE__ */ jsx64(Skeleton7, { className: "h-40 w-full" });
@@ -18821,7 +18897,7 @@ function Card2({
18821
18897
  }
18822
18898
 
18823
18899
  // src/ArchivedView.tsx
18824
- import { useCallback as useCallback22, useEffect as useEffect43, useState as useState55 } from "react";
18900
+ import { useCallback as useCallback22, useEffect as useEffect45, useState as useState55 } from "react";
18825
18901
  import {
18826
18902
  ARCHIVE_LANES,
18827
18903
  ARCHIVE_LANE_LABEL,
@@ -18830,7 +18906,7 @@ import {
18830
18906
  archivedByLine,
18831
18907
  emptyArchiveLine
18832
18908
  } from "@ai-matrx/records";
18833
- import { useFields as useFields14, useRecordsClient as useRecordsClient35, useTable as useTable9 } from "@ai-matrx/records/react";
18909
+ import { useFields as useFields14, useRecordsClient as useRecordsClient36, useTable as useTable9 } from "@ai-matrx/records/react";
18834
18910
  import { Button as Button46, Skeleton as Skeleton8, cn as cn35 } from "@ai-matrx/design-system";
18835
18911
  import { jsx as jsx65, jsxs as jsxs57 } from "react/jsx-runtime";
18836
18912
  var ARCHIVE_MEANS = "Archiving never destroys anything. A record you remove from the grid waits here until somebody brings it back.";
@@ -18849,7 +18925,7 @@ function ArchivedView({
18849
18925
  onRestored,
18850
18926
  className
18851
18927
  }) {
18852
- const client = useRecordsClient35();
18928
+ const client = useRecordsClient36();
18853
18929
  const table = useTable9(tableId);
18854
18930
  const rights = useTableRights(table.data);
18855
18931
  const fields = useFields14(tableId);
@@ -18859,7 +18935,7 @@ function ArchivedView({
18859
18935
  const [error, setError] = useState55(null);
18860
18936
  const [restoring, setRestoring] = useState55(null);
18861
18937
  const [refusal2, setRefusal] = useState55(null);
18862
- useEffect43(() => {
18938
+ useEffect45(() => {
18863
18939
  if (laneFromHost) setLane(laneFromHost);
18864
18940
  }, [laneFromHost]);
18865
18941
  const read = useCallback22(async () => {
@@ -18874,7 +18950,7 @@ function ArchivedView({
18874
18950
  }
18875
18951
  setLoading(false);
18876
18952
  }, [client, tableId, lane, pageSize]);
18877
- useEffect43(() => {
18953
+ useEffect45(() => {
18878
18954
  void read();
18879
18955
  }, [read]);
18880
18956
  const pick = (next) => {
@@ -18956,13 +19032,13 @@ function ArchivedView({
18956
19032
  }
18957
19033
 
18958
19034
  // src/ArchivedDisclosure.tsx
18959
- import { useCallback as useCallback23, useEffect as useEffect44, useState as useState56 } from "react";
19035
+ import { useCallback as useCallback23, useEffect as useEffect46, useState as useState56 } from "react";
18960
19036
  import {
18961
19037
  emptyPortalArchiveLine,
18962
19038
  portalConfirmLine,
18963
19039
  portalTitleTypedBack
18964
19040
  } from "@ai-matrx/records";
18965
- import { useRecordsClient as useRecordsClient36 } from "@ai-matrx/records/react";
19041
+ import { useRecordsClient as useRecordsClient37 } from "@ai-matrx/records/react";
18966
19042
  import { BasicInput as BasicInput16, Button as Button47, Skeleton as Skeleton9, cn as cn36 } from "@ai-matrx/design-system";
18967
19043
  import { jsx as jsx66, jsxs as jsxs58 } from "react/jsx-runtime";
18968
19044
  var ARCHIVED_NEVER_DESTROYED = "Archiving never destroys anything. What you put away waits here until somebody brings it back.";
@@ -19007,7 +19083,7 @@ function ArchivedPortals({
19007
19083
  defaultOpen,
19008
19084
  className
19009
19085
  }) {
19010
- const client = useRecordsClient36();
19086
+ const client = useRecordsClient37();
19011
19087
  const [rows, setRows] = useState56(null);
19012
19088
  const [error, setError] = useState56(null);
19013
19089
  const [confirming, setConfirming] = useState56(null);
@@ -19025,7 +19101,7 @@ function ArchivedPortals({
19025
19101
  setError(answered.error);
19026
19102
  }
19027
19103
  }, [client]);
19028
- useEffect44(() => {
19104
+ useEffect46(() => {
19029
19105
  void read();
19030
19106
  }, [read, refreshToken]);
19031
19107
  const restore = async (portal) => {
@@ -19141,8 +19217,8 @@ function ArchivedPortals({
19141
19217
  }
19142
19218
 
19143
19219
  // src/ViewBar.tsx
19144
- import { useCallback as useCallback25, useEffect as useEffect45, useState as useState57 } from "react";
19145
- import { useRecordsClient as useRecordsClient37 } from "@ai-matrx/records/react";
19220
+ import { useCallback as useCallback25, useEffect as useEffect47, useState as useState57 } from "react";
19221
+ import { useRecordsClient as useRecordsClient38 } from "@ai-matrx/records/react";
19146
19222
  import { Badge as Badge12, Button as Button48, Input as Input2, Popover as Popover5, PopoverContent as PopoverContent5, PopoverTrigger as PopoverTrigger5, Skeleton as Skeleton10, cn as cn37 } from "@ai-matrx/design-system";
19147
19223
 
19148
19224
  // src/seedOnce.ts
@@ -19165,7 +19241,7 @@ function seedIsSatisfied(seed, views) {
19165
19241
  return seed.isDefault === true && views.some((v) => v.isDefault);
19166
19242
  }
19167
19243
  function ViewBar({ tableId, activeViewId, onActiveView, seed, settings, onViews, className }) {
19168
- const client = useRecordsClient37();
19244
+ const client = useRecordsClient38();
19169
19245
  const claimSeed = useSeedGuard();
19170
19246
  const table = useTable10(tableId);
19171
19247
  const rights = useTableRights(table.data);
@@ -19217,10 +19293,10 @@ function ViewBar({ tableId, activeViewId, onActiveView, seed, settings, onViews,
19217
19293
  setViews(mine);
19218
19294
  onViews?.(mine);
19219
19295
  }, [client, readViews, tableId, seedKey]);
19220
- useEffect45(() => {
19296
+ useEffect47(() => {
19221
19297
  void load();
19222
19298
  }, [load]);
19223
- useEffect45(() => {
19299
+ useEffect47(() => {
19224
19300
  if (!views || views.length === 0) return;
19225
19301
  const chosen = views.find((v) => v.id === (activeViewId ?? active)) ?? defaultViewOf(views) ?? views[0];
19226
19302
  if (chosen.id !== active) setActive(chosen.id);
@@ -19324,7 +19400,7 @@ function ViewBar({ tableId, activeViewId, onActiveView, seed, settings, onViews,
19324
19400
 
19325
19401
  // src/ProposalRow.tsx
19326
19402
  import { useState as useState58 } from "react";
19327
- import { useRecordsClient as useRecordsClient38 } from "@ai-matrx/records/react";
19403
+ import { useRecordsClient as useRecordsClient39 } from "@ai-matrx/records/react";
19328
19404
  import { Badge as Badge13, Button as Button49, cn as cn38 } from "@ai-matrx/design-system";
19329
19405
  import { jsx as jsx68, jsxs as jsxs60 } from "react/jsx-runtime";
19330
19406
  var ACT_WORD = PROPOSED_CHANGE_ACT_LABEL;
@@ -19337,7 +19413,7 @@ function ProposalRow({
19337
19413
  onSettled,
19338
19414
  className
19339
19415
  }) {
19340
- const client = useRecordsClient38();
19416
+ const client = useRecordsClient39();
19341
19417
  const [settled, setSettled] = useState58(outcome ?? null);
19342
19418
  const [busy, setBusy] = useState58(false);
19343
19419
  const [confirming, setConfirming] = useState58(false);
@@ -19425,14 +19501,14 @@ function ProposalRow({
19425
19501
  }
19426
19502
 
19427
19503
  // src/ActionInbox.tsx
19428
- import { useCallback as useCallback27, useEffect as useEffect47, useMemo as useMemo33, useRef as useRef21, useState as useState60 } from "react";
19429
- import { useRecordsClient as useRecordsClient40 } from "@ai-matrx/records/react";
19504
+ import { useCallback as useCallback27, useEffect as useEffect49, useMemo as useMemo33, useRef as useRef21, useState as useState60 } from "react";
19505
+ import { useRecordsClient as useRecordsClient41 } from "@ai-matrx/records/react";
19430
19506
  import { Badge as Badge15, Button as Button51, Checkbox as Checkbox7, Skeleton as Skeleton12, cn as cn40 } from "@ai-matrx/design-system";
19431
19507
  import { toggleSelection as toggleSelection2 } from "@ai-matrx/design-system/data-table";
19432
19508
 
19433
19509
  // src/ChecklistRunner.tsx
19434
- import { useCallback as useCallback26, useEffect as useEffect46, useMemo as useMemo32, useState as useState59 } from "react";
19435
- import { useRecordsClient as useRecordsClient39, useTable as useTable11 } from "@ai-matrx/records/react";
19510
+ import { useCallback as useCallback26, useEffect as useEffect48, useMemo as useMemo32, useState as useState59 } from "react";
19511
+ import { useRecordsClient as useRecordsClient40, useTable as useTable11 } from "@ai-matrx/records/react";
19436
19512
  import { Badge as Badge14, BasicInput as BasicInput17, BasicTextarea as BasicTextarea9, Button as Button50, Skeleton as Skeleton11, cn as cn39 } from "@ai-matrx/design-system";
19437
19513
  import { Fragment as Fragment27, jsx as jsx69, jsxs as jsxs61 } from "react/jsx-runtime";
19438
19514
  var DUE_WORD = DUE_STATE_LABEL;
@@ -19446,7 +19522,7 @@ function ChecklistRunner({
19446
19522
  offerToStart,
19447
19523
  className
19448
19524
  }) {
19449
- const client = useRecordsClient39();
19525
+ const client = useRecordsClient40();
19450
19526
  const table = useTable11(tableId ?? null);
19451
19527
  const rights = useTableRights(table.data);
19452
19528
  const [runs, setRuns] = useState59(null);
@@ -19479,10 +19555,10 @@ function ChecklistRunner({
19479
19555
  (held) => held && answered.data.some((r) => r.run_id === held) ? held : answered.data[0]?.run_id ?? null
19480
19556
  );
19481
19557
  }, [client, includeClosed, recordId, runId, tableId]);
19482
- useEffect46(() => {
19558
+ useEffect48(() => {
19483
19559
  void loadRuns();
19484
19560
  }, [loadRuns]);
19485
- useEffect46(() => {
19561
+ useEffect48(() => {
19486
19562
  if (runId) setActiveId(runId);
19487
19563
  }, [runId]);
19488
19564
  const loadSteps = useCallback26(async () => {
@@ -19499,10 +19575,10 @@ function ChecklistRunner({
19499
19575
  setError(null);
19500
19576
  setSteps(answered.data);
19501
19577
  }, [client, activeId]);
19502
- useEffect46(() => {
19578
+ useEffect48(() => {
19503
19579
  void loadSteps();
19504
19580
  }, [loadSteps]);
19505
- useEffect46(() => {
19581
+ useEffect48(() => {
19506
19582
  if (!mayStart || !tableId) return;
19507
19583
  let cancelled = false;
19508
19584
  void client.checklistTemplates({ about_table_id: tableId, limit: 50 }).then((answered) => {
@@ -19639,7 +19715,7 @@ function StepRow({
19639
19715
  const host = useRecordsUi();
19640
19716
  const [members, setMembers] = useState59(null);
19641
19717
  const unassigned = !step2.finished && !step2.assignee_user_id && Boolean(step2.role);
19642
- useEffect46(() => {
19718
+ useEffect48(() => {
19643
19719
  if (!unassigned || !onAssign || !host.members || members !== null) return;
19644
19720
  let alive = true;
19645
19721
  void host.members().then((roster) => {
@@ -19741,7 +19817,7 @@ function StepRow({
19741
19817
  );
19742
19818
  }
19743
19819
  function useMyChecklistSteps(limit = 25) {
19744
- const client = useRecordsClient39();
19820
+ const client = useRecordsClient40();
19745
19821
  const me = client.config.actor.user_id ?? null;
19746
19822
  const [steps, setSteps] = useState59([]);
19747
19823
  const [loading, setLoading] = useState59(true);
@@ -19774,7 +19850,7 @@ function useMyChecklistSteps(limit = 25) {
19774
19850
  setSteps(held);
19775
19851
  setLoading(false);
19776
19852
  }, [client, limit, me]);
19777
- useEffect46(() => {
19853
+ useEffect48(() => {
19778
19854
  void refresh();
19779
19855
  }, [refresh]);
19780
19856
  return { steps, loading, error, refresh };
@@ -19785,9 +19861,9 @@ function MyChecklistSteps({
19785
19861
  onSteps,
19786
19862
  actions
19787
19863
  }) {
19788
- const client = useRecordsClient39();
19864
+ const client = useRecordsClient40();
19789
19865
  const { steps: held, loading, error, refresh } = useMyChecklistSteps();
19790
- useEffect46(() => {
19866
+ useEffect48(() => {
19791
19867
  onSteps?.(held.map((s) => s.step_id));
19792
19868
  }, [held, onSteps]);
19793
19869
  const steps = onlyIds ? held.filter((s) => onlyIds.has(s.step_id)) : held;
@@ -19833,7 +19909,7 @@ function MyChecklistSteps({
19833
19909
  ] });
19834
19910
  }
19835
19911
  function ChecklistsPanel({ tableId, onOpenRecord, className }) {
19836
- const client = useRecordsClient39();
19912
+ const client = useRecordsClient40();
19837
19913
  const table = useTable11(tableId);
19838
19914
  const rights = useTableRights(table.data);
19839
19915
  const [templates, setTemplates] = useState59(null);
@@ -19855,7 +19931,7 @@ function ChecklistsPanel({ tableId, onOpenRecord, className }) {
19855
19931
  if (!r.ok) setRuns([]);
19856
19932
  else setRuns(r.data);
19857
19933
  }, [client, tableId]);
19858
- useEffect46(() => {
19934
+ useEffect48(() => {
19859
19935
  void load();
19860
19936
  }, [load]);
19861
19937
  if (templates === null) return /* @__PURE__ */ jsx69(Skeleton11, { className: cn39("h-40 w-full", className) });
@@ -19994,14 +20070,14 @@ function ChecklistTemplateEditor({
19994
20070
  onDone,
19995
20071
  className
19996
20072
  }) {
19997
- const client = useRecordsClient39();
20073
+ const client = useRecordsClient40();
19998
20074
  const [name, setName] = useState59("");
19999
20075
  const [rows, setRows] = useState59([{ ...EMPTY_ROW }]);
20000
20076
  const [refusal2, setRefusal] = useState59(null);
20001
20077
  const [error, setError] = useState59(null);
20002
20078
  const [busy, setBusy] = useState59(false);
20003
20079
  const [loading, setLoading] = useState59(Boolean(templateId));
20004
- useEffect46(() => {
20080
+ useEffect48(() => {
20005
20081
  if (!templateId) return;
20006
20082
  let cancelled = false;
20007
20083
  void client.checklistTemplateShape({ template_id: templateId }).then((answered) => {
@@ -20038,7 +20114,7 @@ function ChecklistTemplateEditor({
20038
20114
  }),
20039
20115
  [aboutTableId, name, rows]
20040
20116
  );
20041
- useEffect46(() => {
20117
+ useEffect48(() => {
20042
20118
  if (spec.steps.length === 0 || spec.name.length === 0) {
20043
20119
  setRefusal(null);
20044
20120
  return;
@@ -20285,7 +20361,7 @@ function ActionInbox({
20285
20361
  onOpenRecord,
20286
20362
  className
20287
20363
  }) {
20288
- const client = useRecordsClient40();
20364
+ const client = useRecordsClient41();
20289
20365
  const [showDecided, setShowDecided] = useState60(includeSettled);
20290
20366
  const [groupBy, setGroupBy] = useState60(defaultGroupBy);
20291
20367
  const [everyTable, setEveryTable] = useState60(false);
@@ -20320,7 +20396,7 @@ function ActionInbox({
20320
20396
  setError(null);
20321
20397
  setItems(result.data);
20322
20398
  }, [client, showDecided, view]);
20323
- useEffect47(() => {
20399
+ useEffect49(() => {
20324
20400
  void load();
20325
20401
  }, [load]);
20326
20402
  const narrowed = useMemo33(() => {
@@ -20335,10 +20411,10 @@ function ActionInbox({
20335
20411
  const groups = useMemo33(() => groupInbox(narrowed, groupBy), [narrowed, groupBy]);
20336
20412
  const shown3 = useMemo33(() => groups.flatMap((g) => g.items), [groups]);
20337
20413
  const elsewhere = (items?.length ?? 0) - narrowed.length;
20338
- useEffect47(() => {
20414
+ useEffect49(() => {
20339
20415
  if (cursor >= shown3.length) setCursor(Math.max(0, shown3.length - 1));
20340
20416
  }, [shown3.length, cursor]);
20341
- useEffect47(() => {
20417
+ useEffect49(() => {
20342
20418
  const el = listRef.current?.querySelector(`[data-row="${cursor}"]`);
20343
20419
  el?.scrollIntoView({ block: "nearest" });
20344
20420
  }, [cursor, shown3.length]);
@@ -20363,7 +20439,7 @@ function ActionInbox({
20363
20439
  const lastHold = useRef21(null);
20364
20440
  const holdSeq = useRef21(0);
20365
20441
  const [, tick] = useState60(0);
20366
- useEffect47(() => {
20442
+ useEffect49(() => {
20367
20443
  if (Object.keys(held).length === 0) return;
20368
20444
  const t = setInterval(() => tick((n) => n + 1), 250);
20369
20445
  return () => clearInterval(t);
@@ -20408,7 +20484,7 @@ function ActionInbox({
20408
20484
  });
20409
20485
  setSaid({ text: entry.ids.length === 1 ? "Undone. It is waiting on you again, exactly as it was." : `Undone. All ${entry.ids.length} are waiting on you again, exactly as they were.`, undo: null });
20410
20486
  }, []);
20411
- useEffect47(() => {
20487
+ useEffect49(() => {
20412
20488
  const flush = () => {
20413
20489
  for (const entry of [...holds2.current.values()]) entry.commit();
20414
20490
  };
@@ -20419,7 +20495,7 @@ function ActionInbox({
20419
20495
  };
20420
20496
  }, []);
20421
20497
  const resumed = useRef21(false);
20422
- useEffect47(() => {
20498
+ useEffect49(() => {
20423
20499
  if (resumed.current || items === null || view !== "inbox") return;
20424
20500
  resumed.current = true;
20425
20501
  const kept = readHolds();
@@ -21022,17 +21098,17 @@ function ActionInbox({
21022
21098
  }
21023
21099
 
21024
21100
  // src/HistoryPanel.tsx
21025
- import { useCallback as useCallback28, useEffect as useEffect48, useRef as useRef22, useState as useState61 } from "react";
21101
+ import { useCallback as useCallback28, useEffect as useEffect50, useRef as useRef22, useState as useState61 } from "react";
21026
21102
  import {
21027
21103
  useFields as useFields15,
21028
21104
  useRecordChangeRevision,
21029
- useRecordsClient as useRecordsClient41,
21105
+ useRecordsClient as useRecordsClient42,
21030
21106
  useTable as useTable12
21031
21107
  } from "@ai-matrx/records/react";
21032
21108
  import { Badge as Badge16, Button as Button52, Skeleton as Skeleton13, cn as cn41 } from "@ai-matrx/design-system";
21033
21109
  import { jsx as jsx71, jsxs as jsxs63 } from "react/jsx-runtime";
21034
21110
  function HistoryPanel({ tableId, recordId, onAskAboutField, className }) {
21035
- const client = useRecordsClient41();
21111
+ const client = useRecordsClient42();
21036
21112
  const table = useTable12(tableId);
21037
21113
  const fields = useFields15(tableId);
21038
21114
  const rights = useTableRights(table.data);
@@ -21052,7 +21128,7 @@ function HistoryPanel({ tableId, recordId, onAskAboutField, className }) {
21052
21128
  setError(null);
21053
21129
  setEntries(answered.data);
21054
21130
  }, [client, recordId, changed]);
21055
- useEffect48(() => {
21131
+ useEffect50(() => {
21056
21132
  void load();
21057
21133
  }, [load]);
21058
21134
  if (error) return /* @__PURE__ */ jsx71(RefusalNotice, { error, className });
@@ -21333,16 +21409,16 @@ function say(value, field2) {
21333
21409
  }
21334
21410
 
21335
21411
  // src/CommentThread.tsx
21336
- import { useCallback as useCallback29, useEffect as useEffect49, useMemo as useMemo34, useRef as useRef23, useState as useState62 } from "react";
21412
+ import { useCallback as useCallback29, useEffect as useEffect51, useMemo as useMemo34, useRef as useRef23, useState as useState62 } from "react";
21337
21413
  import {
21338
21414
  useFields as useFields16,
21339
- useRecordsClient as useRecordsClient42,
21415
+ useRecordsClient as useRecordsClient43,
21340
21416
  useTable as useTable13
21341
21417
  } from "@ai-matrx/records/react";
21342
21418
  import { Badge as Badge17, Button as Button53, Skeleton as Skeleton14, Textarea, cn as cn42 } from "@ai-matrx/design-system";
21343
21419
  import { jsx as jsx72, jsxs as jsxs64 } from "react/jsx-runtime";
21344
21420
  function CommentThread({ tableId, recordId, fieldKey, className }) {
21345
- const client = useRecordsClient42();
21421
+ const client = useRecordsClient43();
21346
21422
  const table = useTable13(tableId);
21347
21423
  const fields = useFields16(tableId);
21348
21424
  const host = useRecordsUi();
@@ -21370,10 +21446,10 @@ function CommentThread({ tableId, recordId, fieldKey, className }) {
21370
21446
  mayResolve: answered.data.may_resolve
21371
21447
  });
21372
21448
  }, [client, recordId, showResolved]);
21373
- useEffect49(() => {
21449
+ useEffect51(() => {
21374
21450
  void load();
21375
21451
  }, [load]);
21376
- useEffect49(() => {
21452
+ useEffect51(() => {
21377
21453
  let alive = true;
21378
21454
  if (!host.members) return;
21379
21455
  void host.members().then((roster) => {
@@ -21576,10 +21652,10 @@ function Line({
21576
21652
  }
21577
21653
 
21578
21654
  // src/FieldHistoryPanel.tsx
21579
- import { useCallback as useCallback30, useEffect as useEffect50, useState as useState63 } from "react";
21655
+ import { useCallback as useCallback30, useEffect as useEffect52, useState as useState63 } from "react";
21580
21656
  import {
21581
21657
  useFields as useFields17,
21582
- useRecordsClient as useRecordsClient43,
21658
+ useRecordsClient as useRecordsClient44,
21583
21659
  useTable as useTable14
21584
21660
  } from "@ai-matrx/records/react";
21585
21661
  import { Badge as Badge18, Button as Button54, Skeleton as Skeleton15, cn as cn43 } from "@ai-matrx/design-system";
@@ -21592,7 +21668,7 @@ function FieldHistoryPanel({
21592
21668
  onOpenRecord,
21593
21669
  className
21594
21670
  }) {
21595
- const client = useRecordsClient43();
21671
+ const client = useRecordsClient44();
21596
21672
  const table = useTable14(tableId);
21597
21673
  const fields = useFields17(tableId);
21598
21674
  const rights = useTableRights(table.data);
@@ -21611,7 +21687,7 @@ function FieldHistoryPanel({
21611
21687
  setError(null);
21612
21688
  setRows(answered.data);
21613
21689
  }, [client, tableId, fieldKey, recordId]);
21614
- useEffect50(() => {
21690
+ useEffect52(() => {
21615
21691
  void load();
21616
21692
  }, [load]);
21617
21693
  const label = (fields.data ?? []).find((f) => f.key === fieldKey)?.label || humanize(fieldKey);
@@ -21823,20 +21899,20 @@ function submissionStamp(args) {
21823
21899
  }
21824
21900
 
21825
21901
  // src/PortalBuilder.tsx
21826
- import { useCallback as useCallback34, useEffect as useEffect57, useMemo as useMemo37, useState as useState70 } from "react";
21827
- import { useRecordsClient as useRecordsClient50, useTables as useTables4 } from "@ai-matrx/records/react";
21902
+ import { useCallback as useCallback34, useEffect as useEffect59, useMemo as useMemo37, useState as useState70 } from "react";
21903
+ import { useRecordsClient as useRecordsClient51, useTables as useTables4 } from "@ai-matrx/records/react";
21828
21904
  import { BasicInput as BasicInput21, Button as Button60, Checkbox as Checkbox9, Label as Label16, Separator as Separator9, Skeleton as Skeleton20, cn as cn48 } from "@ai-matrx/design-system";
21829
21905
 
21830
21906
  // src/TablesHome.tsx
21831
- import { useCallback as useCallback33, useEffect as useEffect56, useState as useState69 } from "react";
21832
- import { useRecordsClient as useRecordsClient49, useTables as useTables3 } from "@ai-matrx/records/react";
21907
+ import { useCallback as useCallback33, useEffect as useEffect58, useState as useState69 } from "react";
21908
+ import { useRecordsClient as useRecordsClient50, useTables as useTables3 } from "@ai-matrx/records/react";
21833
21909
  import { withTableFacts } from "@ai-matrx/records/core";
21834
21910
  import { withTablePlacement } from "@ai-matrx/records";
21835
21911
  import { BasicInput as BasicInput20, Button as Button59, Skeleton as Skeleton19, cn as cn47 } from "@ai-matrx/design-system";
21836
21912
 
21837
21913
  // src/ExampleTables.tsx
21838
- import { useEffect as useEffect51, useState as useState64 } from "react";
21839
- import { useRecordsClient as useRecordsClient44 } from "@ai-matrx/records/react";
21914
+ import { useEffect as useEffect53, useState as useState64 } from "react";
21915
+ import { useRecordsClient as useRecordsClient45 } from "@ai-matrx/records/react";
21840
21916
  import { loadUseCase, summarize as summarize2, useCaseIds } from "@ai-matrx/records/use-cases";
21841
21917
  import { Button as Button55, Skeleton as Skeleton16, cn as cn44 } from "@ai-matrx/design-system";
21842
21918
  import { jsx as jsx74, jsxs as jsxs66 } from "react/jsx-runtime";
@@ -21845,12 +21921,12 @@ function ExampleTables({
21845
21921
  onClose,
21846
21922
  className
21847
21923
  }) {
21848
- const client = useRecordsClient44();
21924
+ const client = useRecordsClient45();
21849
21925
  const [summaries, setSummaries] = useState64(null);
21850
21926
  const [busy, setBusy] = useState64(null);
21851
21927
  const [error, setError] = useState64(null);
21852
21928
  const [built, setBuilt] = useState64(null);
21853
- useEffect51(() => {
21929
+ useEffect53(() => {
21854
21930
  let alive = true;
21855
21931
  void Promise.all(useCaseIds().map(async (id) => summarize2(await loadUseCase(id)))).then((rows) => {
21856
21932
  if (alive) setSummaries(rows);
@@ -21925,23 +22001,23 @@ function ExampleTables({
21925
22001
  }
21926
22002
 
21927
22003
  // src/BookingSlots.tsx
21928
- import { useCallback as useCallback32, useEffect as useEffect54, useMemo as useMemo36, useState as useState67 } from "react";
21929
- import { useRecordsClient as useRecordsClient47, useMyLevels as useMyLevels2 } from "@ai-matrx/records/react";
22004
+ import { useCallback as useCallback32, useEffect as useEffect56, useMemo as useMemo36, useState as useState67 } from "react";
22005
+ import { useRecordsClient as useRecordsClient48, useMyLevels as useMyLevels2 } from "@ai-matrx/records/react";
21930
22006
  import { bookingPath as bookingPath2 } from "@ai-matrx/records";
21931
22007
  import { Badge as Badge19, Button as Button57, Skeleton as Skeleton18, cn as cn46 } from "@ai-matrx/design-system";
21932
22008
 
21933
22009
  // src/BookingBuilder.tsx
21934
- import { useCallback as useCallback31, useEffect as useEffect53, useMemo as useMemo35, useState as useState66 } from "react";
21935
- import { useFields as useFields18, useRecordsClient as useRecordsClient46, useTable as useTable15 } from "@ai-matrx/records/react";
22010
+ import { useCallback as useCallback31, useEffect as useEffect55, useMemo as useMemo35, useState as useState66 } from "react";
22011
+ import { useFields as useFields18, useRecordsClient as useRecordsClient47, useTable as useTable15 } from "@ai-matrx/records/react";
21936
22012
 
21937
22013
  // src/publish-gate.ts
21938
- import { useEffect as useEffect52, useState as useState65 } from "react";
21939
- import { useRecordsClient as useRecordsClient45 } from "@ai-matrx/records/react";
22014
+ import { useEffect as useEffect54, useState as useState65 } from "react";
22015
+ import { useRecordsClient as useRecordsClient46 } from "@ai-matrx/records/react";
21940
22016
  var PUBLISH_NEEDS_THE_STORE_ON = "This organization has its record store switched off, so publishing would hand you a link that opens nothing. An owner or an administrator turns it on under Database settings, on the unified data screen \u2014 everything you have already built here is kept and starts working the moment they do.";
21941
22017
  function usePublishGate() {
21942
- const client = useRecordsClient45();
22018
+ const client = useRecordsClient46();
21943
22019
  const [storeOpen, setStoreOpen] = useState65(null);
21944
- useEffect52(() => {
22020
+ useEffect54(() => {
21945
22021
  let alive = true;
21946
22022
  void (async () => {
21947
22023
  const answered = await client.storeIsOpen();
@@ -22054,7 +22130,7 @@ function draftWindows(availability) {
22054
22130
  });
22055
22131
  }
22056
22132
  function BookingBuilder({ tableId, bookingId, onSaved, onClose, className }) {
22057
- const client = useRecordsClient46();
22133
+ const client = useRecordsClient47();
22058
22134
  const publishGate = usePublishGate();
22059
22135
  const host = useRecordsUi();
22060
22136
  const table = useTable15(tableId);
@@ -22099,19 +22175,19 @@ function BookingBuilder({ tableId, bookingId, onSaved, onClose, className }) {
22099
22175
  setLoaded(true);
22100
22176
  if (mine) setFormId(mine.form_id);
22101
22177
  }, [client, tableId, bookingId]);
22102
- useEffect53(() => {
22178
+ useEffect55(() => {
22103
22179
  void load();
22104
22180
  }, [load]);
22105
- useEffect53(() => {
22181
+ useEffect55(() => {
22106
22182
  if (title !== "" || !table.data) return;
22107
- setTitle(existing?.title ?? `Book a ${minutes}-minute ${table.data.name} appointment`);
22183
+ setTitle(existing?.title ?? `Book a ${minutes}-minute ${singularNoun(table.data, "appointment")}`);
22108
22184
  }, [table.data, existing]);
22109
- useEffect53(() => {
22185
+ useEffect55(() => {
22110
22186
  if (!existing) return;
22111
22187
  setMinutes(existing.slot_minutes);
22112
22188
  if (existing.timezone && existing.timezone !== "UTC") setTimezone(existing.timezone);
22113
22189
  }, [existing]);
22114
- useEffect53(() => {
22190
+ useEffect55(() => {
22115
22191
  if (!offer) return;
22116
22192
  setWindows(draftWindows(offer));
22117
22193
  setMinutes(offer.slot_minutes);
@@ -22153,7 +22229,7 @@ function BookingBuilder({ tableId, bookingId, onSaved, onClose, className }) {
22153
22229
  setWhoAdded(true);
22154
22230
  }
22155
22231
  const [whoAdded, setWhoAdded] = useState66(false);
22156
- useEffect53(() => {
22232
+ useEffect55(() => {
22157
22233
  if (!whoAdded) return;
22158
22234
  const who = askable.filter((f) => isWhoField(f)).map((f) => f.key);
22159
22235
  if (who.length === 0) return;
@@ -22427,7 +22503,7 @@ function bookingSuggestion(tableName2) {
22427
22503
  var NO_ADMIN = "Opening a booking page lets people with no account take time in your calendar, so it needs the admin level on the table the appointments land in.";
22428
22504
  var STATE_WORDS = BOOKING_PAGE_STATE_LABEL;
22429
22505
  function BookingSlots({ tableId, activeBookingId, className }) {
22430
- const client = useRecordsClient47();
22506
+ const client = useRecordsClient48();
22431
22507
  const host = useRecordsUi();
22432
22508
  const [pages, setPages] = useState67(null);
22433
22509
  const [error, setError] = useState67(null);
@@ -22435,6 +22511,7 @@ function BookingSlots({ tableId, activeBookingId, className }) {
22435
22511
  const [copied, setCopied] = useState67(null);
22436
22512
  const [shown3, setShown] = useState67(null);
22437
22513
  const [building, setBuilding] = useState67(false);
22514
+ const [changing, setChanging] = useState67(null);
22438
22515
  const load = useCallback32(async () => {
22439
22516
  const answered = await client.bookings(tableId ? { table_id: tableId } : {});
22440
22517
  if (!answered.ok) {
@@ -22445,7 +22522,7 @@ function BookingSlots({ tableId, activeBookingId, className }) {
22445
22522
  setError(null);
22446
22523
  setPages(answered.data);
22447
22524
  }, [client, tableId]);
22448
- useEffect54(() => {
22525
+ useEffect56(() => {
22449
22526
  void load();
22450
22527
  }, [load]);
22451
22528
  const subjectIds = useMemo36(
@@ -22500,6 +22577,17 @@ function BookingSlots({ tableId, activeBookingId, className }) {
22500
22577
  ] }),
22501
22578
  error ? /* @__PURE__ */ jsx77(RefusalNotice, { error }) : null,
22502
22579
  activeBookingId && !pages.some((p) => p.form_id === activeBookingId) ? /* @__PURE__ */ jsx77("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,
22580
+ changing ? /* @__PURE__ */ jsx77(
22581
+ BookingBuilder,
22582
+ {
22583
+ tableId: changing.tableId,
22584
+ bookingId: changing.formId,
22585
+ onSaved: () => {
22586
+ void load();
22587
+ },
22588
+ onClose: () => setChanging(null)
22589
+ }
22590
+ ) : null,
22503
22591
  building && tableId ? /* @__PURE__ */ jsx77(
22504
22592
  BookingBuilder,
22505
22593
  {
@@ -22576,6 +22664,15 @@ function BookingSlots({ tableId, activeBookingId, className }) {
22576
22664
  /* @__PURE__ */ jsx77("p", { className: "mt-1 text-xs text-muted-foreground", children: nextInWords(page) }),
22577
22665
  /* @__PURE__ */ jsxs69("div", { className: "mt-2 flex flex-wrap items-center gap-1.5", children: [
22578
22666
  /* @__PURE__ */ jsx77(Button57, { size: "sm", variant: "outline", onClick: () => void copy(url, page.form_id), children: copied === page.form_id ? "Copied" : "Copy link" }),
22667
+ mayOpen ? /* @__PURE__ */ jsx77(
22668
+ Button57,
22669
+ {
22670
+ size: "sm",
22671
+ variant: "ghost",
22672
+ onClick: () => setChanging({ formId: page.form_id, tableId: page.table_id }),
22673
+ children: "Change it"
22674
+ }
22675
+ ) : null,
22579
22676
  mayOpen ? /* @__PURE__ */ jsx77(
22580
22677
  Button57,
22581
22678
  {
@@ -22637,13 +22734,13 @@ import {
22637
22734
  } from "@ai-matrx/records/core";
22638
22735
 
22639
22736
  // src/WhereItLives.tsx
22640
- import { useEffect as useEffect55, useState as useState68 } from "react";
22737
+ import { useEffect as useEffect57, useState as useState68 } from "react";
22641
22738
  import { moveConsequence } from "@ai-matrx/records";
22642
- import { useRecordsClient as useRecordsClient48 } from "@ai-matrx/records/react";
22739
+ import { useRecordsClient as useRecordsClient49 } from "@ai-matrx/records/react";
22643
22740
  import { Button as Button58, ErrorBox as ErrorBox2, Popover as Popover6, PopoverContent as PopoverContent6, PopoverTrigger as PopoverTrigger6 } from "@ai-matrx/design-system";
22644
22741
  import { jsx as jsx78, jsxs as jsxs70 } from "react/jsx-runtime";
22645
22742
  function WhereItLives({ tableId, knownOrganizationName, onMoved, variant = "header" }) {
22646
- const client = useRecordsClient48();
22743
+ const client = useRecordsClient49();
22647
22744
  const host = useRecordsUi();
22648
22745
  const [answer, setAnswer] = useState68(null);
22649
22746
  const [attempt, setAttempt] = useState68(0);
@@ -22652,7 +22749,7 @@ function WhereItLives({ tableId, knownOrganizationName, onMoved, variant = "head
22652
22749
  const [choosing, setChoosing] = useState68(null);
22653
22750
  const [moving, setMoving] = useState68(false);
22654
22751
  const [said, setSaid] = useState68(null);
22655
- useEffect55(() => {
22752
+ useEffect57(() => {
22656
22753
  if (!armed) return;
22657
22754
  let alive = true;
22658
22755
  setAnswer(null);
@@ -22898,11 +22995,11 @@ function visibilityLaneFor(table) {
22898
22995
  return "organization";
22899
22996
  }
22900
22997
  function TablesHome({ onOpenTable, organizationName, makingOnly = false, askedBy, className }) {
22901
- const client = useRecordsClient49();
22998
+ const client = useRecordsClient50();
22902
22999
  const tables = useTables3();
22903
23000
  const me = client.config.actor.user_id ?? null;
22904
23001
  const [facts, setFacts] = useState69({ phase: "reading" });
22905
- useEffect56(() => {
23002
+ useEffect58(() => {
22906
23003
  let alive = true;
22907
23004
  void client.tableFacts().then((answered) => {
22908
23005
  if (!alive) return;
@@ -22920,7 +23017,7 @@ function TablesHome({ onOpenTable, organizationName, makingOnly = false, askedBy
22920
23017
  const keptCount = listed.filter((t) => laneFor(t) === "app").length;
22921
23018
  const [askedName, setAskedName] = useState69(null);
22922
23019
  const firstTableId = listed[0]?.id ?? null;
22923
- useEffect56(() => {
23020
+ useEffect58(() => {
22924
23021
  if (organizationName || !firstTableId) return;
22925
23022
  let alive = true;
22926
23023
  void client.tableHome({ table_id: firstTableId }).then((answered) => {
@@ -22941,15 +23038,15 @@ function TablesHome({ onOpenTable, organizationName, makingOnly = false, askedBy
22941
23038
  const [examples, setExamples] = useState69(false);
22942
23039
  const createAsked = askedBy?.create ?? 0;
22943
23040
  const examplesAsked = askedBy?.examples ?? 0;
22944
- useEffect56(() => {
23041
+ useEffect58(() => {
22945
23042
  if (createAsked > 0) setCreating(true);
22946
23043
  }, [createAsked]);
22947
- useEffect56(() => {
23044
+ useEffect58(() => {
22948
23045
  if (examplesAsked > 0) setExamples(true);
22949
23046
  }, [examplesAsked]);
22950
23047
  const hostButtons = askedBy !== void 0;
22951
23048
  const [boards, setBoards] = useState69(null);
22952
- useEffect56(() => {
23049
+ useEffect58(() => {
22953
23050
  if (makingOnly) return;
22954
23051
  let cancelled = false;
22955
23052
  void client.dashboards({}).then((result) => {
@@ -23128,7 +23225,7 @@ function TablesHome({ onOpenTable, organizationName, makingOnly = false, askedBy
23128
23225
  import { Fragment as Fragment33, jsx as jsx80, jsxs as jsxs72 } from "react/jsx-runtime";
23129
23226
  var RESTATING_REPLACES = "Saving replaces what this portal shows: a table you untick stops being visible to every client the moment you save. Who is invited is not touched.";
23130
23227
  function PortalBuilder({ tableId, portalId, onSaved, onClose, className }) {
23131
- const client = useRecordsClient50();
23228
+ const client = useRecordsClient51();
23132
23229
  const tables = useTables4();
23133
23230
  const [title, setTitle] = useState70("");
23134
23231
  const [clientTableId, setClientTableId] = useState70(null);
@@ -23155,7 +23252,7 @@ function PortalBuilder({ tableId, portalId, onSaved, onClose, className }) {
23155
23252
  },
23156
23253
  [client, fieldsByTable]
23157
23254
  );
23158
- useEffect57(() => {
23255
+ useEffect59(() => {
23159
23256
  if (!portalId) return;
23160
23257
  void (async () => {
23161
23258
  const answered = await client.portalCard({ portal_id: portalId });
@@ -23169,7 +23266,7 @@ function PortalBuilder({ tableId, portalId, onSaved, onClose, className }) {
23169
23266
  setClientTableId(answered.data.client_table_id);
23170
23267
  })();
23171
23268
  }, [client, portalId]);
23172
- useEffect57(() => {
23269
+ useEffect59(() => {
23173
23270
  if (!tableId) return;
23174
23271
  setExposures(
23175
23272
  (prev) => prev[tableId] ? prev : {
@@ -23182,7 +23279,7 @@ function PortalBuilder({ tableId, portalId, onSaved, onClose, className }) {
23182
23279
  const cameFromPeople = Boolean(
23183
23280
  tableId && (fieldsByTable[tableId] ?? []).some((f) => editorKindFor(f) === "email")
23184
23281
  );
23185
- useEffect57(() => {
23282
+ useEffect59(() => {
23186
23283
  if (!tableId || portalId || clientTableId !== null || !cameFromPeople) return;
23187
23284
  setClientTableId(tableId);
23188
23285
  setExposures((prev) => {
@@ -23430,8 +23527,8 @@ function PortalBuilder({ tableId, portalId, onSaved, onClose, className }) {
23430
23527
  }
23431
23528
 
23432
23529
  // src/PortalsPanel.tsx
23433
- import { useCallback as useCallback35, useEffect as useEffect59, useMemo as useMemo39, useState as useState72 } from "react";
23434
- import { useRecordsClient as useRecordsClient52 } from "@ai-matrx/records/react";
23530
+ import { useCallback as useCallback35, useEffect as useEffect61, useMemo as useMemo39, useState as useState72 } from "react";
23531
+ import { useRecordsClient as useRecordsClient53 } from "@ai-matrx/records/react";
23435
23532
  import {
23436
23533
  portalArchiveConsequence,
23437
23534
  portalConfirmLine as portalConfirmLine2,
@@ -23441,8 +23538,8 @@ import {
23441
23538
  import { Badge as Badge20, BasicInput as BasicInput23, Button as Button62, Separator as Separator10, Skeleton as Skeleton21, cn as cn50 } from "@ai-matrx/design-system";
23442
23539
 
23443
23540
  // src/PortalLookEditor.tsx
23444
- import { useEffect as useEffect58, useMemo as useMemo38, useState as useState71 } from "react";
23445
- import { useRecordsClient as useRecordsClient51 } from "@ai-matrx/records/react";
23541
+ import { useEffect as useEffect60, useMemo as useMemo38, useState as useState71 } from "react";
23542
+ import { useRecordsClient as useRecordsClient52 } from "@ai-matrx/records/react";
23446
23543
  import { BasicInput as BasicInput22, Button as Button61, cn as cn49 } from "@ai-matrx/design-system";
23447
23544
  import { STYLE_COLOR_LABELS as STYLE_COLOR_LABELS3, SWATCH_CLASS as SWATCH_CLASS2 } from "@ai-matrx/design-system/data-table";
23448
23545
  import { jsx as jsx81, jsxs as jsxs73 } from "react/jsx-runtime";
@@ -23470,7 +23567,7 @@ function candidateRows(card, available) {
23470
23567
  return rows;
23471
23568
  }
23472
23569
  function PortalLookEditor({ card, onSaved, className }) {
23473
- const client = useRecordsClient51();
23570
+ const client = useRecordsClient52();
23474
23571
  const stored = card.config?.style ?? {};
23475
23572
  const [name, setName] = useState71(stored.display_name ?? "");
23476
23573
  const [welcome, setWelcome] = useState71(stored.welcome ?? "");
@@ -23483,7 +23580,7 @@ function PortalLookEditor({ card, onSaved, className }) {
23483
23580
  const [said, setSaid] = useState71(null);
23484
23581
  const [formsError, setFormsError] = useState71(null);
23485
23582
  const [formsUnread, setFormsUnread] = useState71(false);
23486
- useEffect58(() => {
23583
+ useEffect60(() => {
23487
23584
  let cancelled = false;
23488
23585
  void (async () => {
23489
23586
  try {
@@ -23765,13 +23862,13 @@ function stateWords(person) {
23765
23862
  }
23766
23863
  var PORTAL_SUGGESTION = "Let each of my customers sign in and see their own jobs and invoices, and nothing else.";
23767
23864
  function PortalsPanel({ tableId, activePortalId, className }) {
23768
- const client = useRecordsClient52();
23865
+ const client = useRecordsClient53();
23769
23866
  const host = useRecordsUi();
23770
23867
  const [portals, setPortals] = useState72(null);
23771
23868
  const [exposures, setExposures] = useState72([]);
23772
23869
  const [listError, setListError] = useState72(null);
23773
23870
  const [openId, setOpenId] = useState72(activePortalId ?? null);
23774
- useEffect59(() => {
23871
+ useEffect61(() => {
23775
23872
  if (activePortalId) setOpenId(activePortalId);
23776
23873
  }, [activePortalId]);
23777
23874
  const [building, setBuilding] = useState72(false);
@@ -23789,7 +23886,7 @@ function PortalsPanel({ tableId, activePortalId, className }) {
23789
23886
  setPortals(answered.data);
23790
23887
  setExposures(mapped.ok ? mapped.data : []);
23791
23888
  }, [client]);
23792
- useEffect59(() => {
23889
+ useEffect61(() => {
23793
23890
  void load();
23794
23891
  }, [load]);
23795
23892
  if (portals === null) return /* @__PURE__ */ jsx82(Skeleton21, { className: cn50("h-32 w-full", className) });
@@ -23945,7 +24042,7 @@ function ArchivePortalControl({
23945
24042
  portal,
23946
24043
  onArchived
23947
24044
  }) {
23948
- const client = useRecordsClient52();
24045
+ const client = useRecordsClient53();
23949
24046
  const [asking, setAsking] = useState72(false);
23950
24047
  const [typed, setTyped] = useState72("");
23951
24048
  const [busy, setBusy] = useState72(false);
@@ -24052,7 +24149,7 @@ function PortalDetail({
24052
24149
  origin,
24053
24150
  onChanged
24054
24151
  }) {
24055
- const client = useRecordsClient52();
24152
+ const client = useRecordsClient53();
24056
24153
  const [card, setCard] = useState72(null);
24057
24154
  const [error, setError] = useState72(null);
24058
24155
  const load = useCallback35(async () => {
@@ -24065,7 +24162,7 @@ function PortalDetail({
24065
24162
  setError(null);
24066
24163
  setCard(answered.data);
24067
24164
  }, [client, portalId]);
24068
- useEffect59(() => {
24165
+ useEffect61(() => {
24069
24166
  void load();
24070
24167
  }, [load]);
24071
24168
  const revoke = useCallback35(
@@ -24273,7 +24370,7 @@ function Preview({
24273
24370
  const [which, setWhich] = useState72(first?.table_id ?? null);
24274
24371
  const [rows, setRows] = useState72(null);
24275
24372
  const [error, setError] = useState72(null);
24276
- useEffect59(() => {
24373
+ useEffect61(() => {
24277
24374
  if (!which) return;
24278
24375
  let cancelled = false;
24279
24376
  setRows(null);
@@ -24310,7 +24407,7 @@ function Preview({
24310
24407
  ] });
24311
24408
  }
24312
24409
  function Invite({ card, onInvited }) {
24313
- const client = useRecordsClient52();
24410
+ const client = useRecordsClient53();
24314
24411
  const [rows, setRows] = useState72(null);
24315
24412
  const [clientTable, setClientTable] = useState72(null);
24316
24413
  const [search, setSearch] = useState72("");
@@ -24319,7 +24416,7 @@ function Invite({ card, onInvited }) {
24319
24416
  const [busy, setBusy] = useState72(false);
24320
24417
  const [said, setSaid] = useState72(null);
24321
24418
  const [error, setError] = useState72(null);
24322
- useEffect59(() => {
24419
+ useEffect61(() => {
24323
24420
  let cancelled = false;
24324
24421
  void client.list({ table_id: card.client_table_id, limit: 200 }).then((answered) => {
24325
24422
  if (cancelled) return;
@@ -24421,8 +24518,9 @@ function Invite({ card, onInvited }) {
24421
24518
  }
24422
24519
 
24423
24520
  // src/DigestScheduler.tsx
24424
- import { useCallback as useCallback36, useEffect as useEffect60, useMemo as useMemo40, useState as useState73 } from "react";
24425
- import { useRecordsClient as useRecordsClient53, useTable as useTable16 } from "@ai-matrx/records/react";
24521
+ import { useCallback as useCallback36, useEffect as useEffect62, useMemo as useMemo40, useState as useState73 } from "react";
24522
+ import { useRecordsClient as useRecordsClient54, useTable as useTable16 } from "@ai-matrx/records/react";
24523
+ import { hasQuietHours } from "@ai-matrx/records";
24426
24524
  import { BasicInput as BasicInput24, Button as Button63, Checkbox as Checkbox10, Label as Label17, Separator as Separator11, Skeleton as Skeleton22, cn as cn51 } from "@ai-matrx/design-system";
24427
24525
 
24428
24526
  // src/scheduleWords.ts
@@ -24465,6 +24563,12 @@ var CHANNEL_WORDS = {
24465
24563
  email: "by email \u2014 only if an address is on their account",
24466
24564
  sms: "by text \u2014 only if a number is on their account"
24467
24565
  };
24566
+ function scheduleParts(schedule) {
24567
+ const words2 = (schedule ?? "").trim().toLowerCase().split(/\s+/);
24568
+ const time = words2.find((w) => /^\d{1,2}:\d{2}$/.test(w)) ?? null;
24569
+ const day = WEEKDAYS.find((d) => words2.some((w) => w.slice(0, 3) === d.slice(0, 3))) ?? null;
24570
+ return { day, time: time ? time.padStart(5, "0") : null };
24571
+ }
24468
24572
  function DigestScheduler({
24469
24573
  tableId,
24470
24574
  savedViewId,
@@ -24472,27 +24576,42 @@ function DigestScheduler({
24472
24576
  filters,
24473
24577
  onScheduled,
24474
24578
  onClose,
24475
- className
24579
+ className,
24580
+ existing
24476
24581
  }) {
24477
- const client = useRecordsClient53();
24582
+ const client = useRecordsClient54();
24478
24583
  const host = useRecordsUi();
24479
24584
  const [views, setViews] = useState73(null);
24480
24585
  const [cadences, setCadences] = useState73([]);
24481
24586
  const [members, setMembers] = useState73(null);
24482
24587
  const [error, setError] = useState73(null);
24483
- const [viewId, setViewId] = useState73(savedViewId ?? "");
24484
- const [name, setName] = useState73(subjectName?.trim() ? `${subjectName.trim()} summary` : "");
24485
- const [cadence, setCadence] = useState73("weekly");
24486
- const [weekday, setWeekday] = useState73("monday");
24487
- const [time, setTime] = useState73("08:00");
24488
- const [timezone, setTimezone] = useState73(() => ownTimeZone());
24588
+ const was = scheduleParts(existing?.schedule);
24589
+ const [viewId, setViewId] = useState73(
24590
+ existing?.saved_view_id ?? savedViewId ?? ""
24591
+ );
24592
+ const [name, setName] = useState73(
24593
+ existing?.name ?? (subjectName?.trim() ? `${subjectName.trim()} summary` : "")
24594
+ );
24595
+ const [cadence, setCadence] = useState73(
24596
+ ["hourly", "daily", "weekly"].includes(existing?.cadence ?? "") ? existing.cadence : "weekly"
24597
+ );
24598
+ const [weekday, setWeekday] = useState73(was.day ?? "monday");
24599
+ const [time, setTime] = useState73(was.time ?? "08:00");
24600
+ const [timezone, setTimezone] = useState73(() => {
24601
+ const kept = existing?.quiet_hours?.tz?.trim();
24602
+ return kept && kept.toUpperCase() !== "UTC" ? kept : ownTimeZone();
24603
+ });
24489
24604
  const table = useTable16(tableId);
24490
24605
  const tableName2 = table.data?.name?.trim() || null;
24491
- const [channel, setChannel] = useState73("in_app");
24492
- const [quiet, setQuiet] = useState73(false);
24493
- const [quietFrom, setQuietFrom] = useState73("22:00");
24494
- const [quietTo, setQuietTo] = useState73("07:00");
24495
- const [recipients, setRecipients] = useState73([]);
24606
+ const [channel, setChannel] = useState73(
24607
+ existing?.channel === "email" || existing?.channel === "sms" ? existing.channel : "in_app"
24608
+ );
24609
+ const [quiet, setQuiet] = useState73(hasQuietHours(existing?.quiet_hours));
24610
+ const [quietFrom, setQuietFrom] = useState73(existing?.quiet_hours?.start ?? "22:00");
24611
+ const [quietTo, setQuietTo] = useState73(existing?.quiet_hours?.end ?? "07:00");
24612
+ const [recipients, setRecipients] = useState73(
24613
+ existing?.recipient_user_id ? [existing.recipient_user_id] : []
24614
+ );
24496
24615
  const [saving, setSaving] = useState73(false);
24497
24616
  const [outcomes, setOutcomes] = useState73(null);
24498
24617
  const [preview, setPreview] = useState73(null);
@@ -24516,7 +24635,7 @@ function DigestScheduler({
24516
24635
  setMembers([]);
24517
24636
  }
24518
24637
  }, [client, tableId, host]);
24519
- useEffect60(() => {
24638
+ useEffect62(() => {
24520
24639
  void load();
24521
24640
  }, [load]);
24522
24641
  const schedule = useMemo40(() => {
@@ -24563,7 +24682,8 @@ function DigestScheduler({
24563
24682
  schedule,
24564
24683
  channel,
24565
24684
  quiet_hours: quietHours,
24566
- ...userId === "" ? {} : { recipient_user_id: userId }
24685
+ ...userId === "" ? {} : { recipient_user_id: userId },
24686
+ ...existing ? { rule_id: existing.rule_id } : {}
24567
24687
  }
24568
24688
  });
24569
24689
  if (written.ok) done.push({ userId, who: label, ruleId: written.data });
@@ -24586,9 +24706,9 @@ function DigestScheduler({
24586
24706
  if (views === null && !error) return /* @__PURE__ */ jsx83(Skeleton22, { className: cn51("h-56 w-full", className) });
24587
24707
  return /* @__PURE__ */ jsxs75("section", { className: cn51("@container flex flex-col gap-3", className), children: [
24588
24708
  /* @__PURE__ */ jsxs75("header", { className: "flex items-center gap-2", children: [
24589
- /* @__PURE__ */ jsx83("h3", { className: "text-sm font-medium", children: "Send this on a schedule" }),
24709
+ /* @__PURE__ */ jsx83("h3", { className: "text-sm font-medium", children: existing ? "Change this summary" : "Send this on a schedule" }),
24590
24710
  /* @__PURE__ */ jsx83("div", { className: "flex-1" }),
24591
- /* @__PURE__ */ jsx83(Button63, { size: "sm", disabled: saving, onClick: () => void scheduleIt(), children: saving ? "Scheduling\u2026" : "Schedule it" }),
24711
+ /* @__PURE__ */ jsx83(Button63, { size: "sm", disabled: saving, onClick: () => void scheduleIt(), children: saving ? "Scheduling\u2026" : existing ? "Save the change" : "Schedule it" }),
24592
24712
  onClose ? /* @__PURE__ */ jsx83(Button63, { size: "sm", variant: "ghost", onClick: onClose, children: "Close" }) : null
24593
24713
  ] }),
24594
24714
  error ? /* @__PURE__ */ jsx83(RefusalNotice, { error }) : null,
@@ -24770,14 +24890,14 @@ function DigestScheduler({
24770
24890
  }
24771
24891
 
24772
24892
  // src/SubscriptionsPanel.tsx
24773
- import { useCallback as useCallback38, useEffect as useEffect62, useState as useState75 } from "react";
24774
- import { useRecordsClient as useRecordsClient55 } from "@ai-matrx/records/react";
24775
- import { hasQuietHours } from "@ai-matrx/records";
24893
+ import { useCallback as useCallback38, useEffect as useEffect64, useState as useState75 } from "react";
24894
+ import { useRecordsClient as useRecordsClient56 } from "@ai-matrx/records/react";
24895
+ import { hasQuietHours as hasQuietHours2 } from "@ai-matrx/records";
24776
24896
  import { Badge as Badge21, Button as Button65, Skeleton as Skeleton24, Switch as Switch2, cn as cn53 } from "@ai-matrx/design-system";
24777
24897
 
24778
24898
  // src/WebhooksPanel.tsx
24779
- import { useCallback as useCallback37, useEffect as useEffect61, useState as useState74 } from "react";
24780
- import { useRecordsClient as useRecordsClient54, useTable as useTable17 } from "@ai-matrx/records/react";
24899
+ import { useCallback as useCallback37, useEffect as useEffect63, useState as useState74 } from "react";
24900
+ import { useRecordsClient as useRecordsClient55, useTable as useTable17 } from "@ai-matrx/records/react";
24781
24901
  import { BasicInput as BasicInput25, Button as Button64, Checkbox as Checkbox11, ConfirmDialog as ConfirmDialog6, Label as Label18, Skeleton as Skeleton23, cn as cn52 } from "@ai-matrx/design-system";
24782
24902
  import { jsx as jsx84, jsxs as jsxs76 } from "react/jsx-runtime";
24783
24903
  var WEBHOOK_EVENT_LABEL = {
@@ -24797,7 +24917,7 @@ function health(hook) {
24797
24917
  return "Nothing has changed since it was set up, so nothing has been sent yet.";
24798
24918
  }
24799
24919
  function WebhooksPanel({ tableId, className }) {
24800
- const client = useRecordsClient54();
24920
+ const client = useRecordsClient55();
24801
24921
  const table = useTable17(tableId);
24802
24922
  const rights = useTableRights(table.data);
24803
24923
  const [hooks, setHooks] = useState74(null);
@@ -24809,17 +24929,20 @@ function WebhooksPanel({ tableId, className }) {
24809
24929
  const [busy, setBusy] = useState74(false);
24810
24930
  const [declared2, setDeclared] = useState74(null);
24811
24931
  const [stopping, setStopping] = useState74(null);
24932
+ const [readRefused, setReadRefused] = useState74(null);
24812
24933
  const load = useCallback37(async () => {
24813
24934
  const answered = await client.tableWebhooks({ table_id: tableId });
24814
24935
  if (!answered.ok) {
24936
+ setReadRefused(answered.error);
24815
24937
  setError(answered.error);
24816
24938
  setHooks([]);
24817
24939
  return;
24818
24940
  }
24941
+ setReadRefused(null);
24819
24942
  setError(null);
24820
24943
  setHooks(answered.data ?? []);
24821
24944
  }, [client, tableId]);
24822
- useEffect61(() => {
24945
+ useEffect63(() => {
24823
24946
  void load();
24824
24947
  }, [load]);
24825
24948
  const declare2 = async () => {
@@ -24844,6 +24967,17 @@ function WebhooksPanel({ tableId, className }) {
24844
24967
  await load();
24845
24968
  };
24846
24969
  if (hooks === null) return /* @__PURE__ */ jsx84(Skeleton23, { className: cn52("h-16 w-full", className) });
24970
+ const notHers = readRefused?.sqlstate === "42501" && rights.known && !rights.structure;
24971
+ if (notHers) {
24972
+ return /* @__PURE__ */ jsxs76("section", { "data-records-webhooks": "", className: cn52("flex flex-col gap-2 border-t pt-3", className), children: [
24973
+ /* @__PURE__ */ jsx84("header", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsx84("h3", { className: "text-sm font-medium", children: "Webhooks" }) }),
24974
+ /* @__PURE__ */ jsxs76("p", { className: "text-xs text-muted-foreground", children: [
24975
+ "Which other systems are told about these records is for this table's admins.",
24976
+ " ",
24977
+ rights.why("structure")
24978
+ ] })
24979
+ ] });
24980
+ }
24847
24981
  const mayChange = rights.structure;
24848
24982
  const live = hooks.filter((h) => h.is_active);
24849
24983
  return /* @__PURE__ */ jsxs76("section", { "data-records-webhooks": "", className: cn52("flex flex-col gap-2 border-t pt-3", className), children: [
@@ -24978,12 +25112,13 @@ function nextSummaryAt(subscription, now) {
24978
25112
  var CHANNEL_WORDS2 = SUBSCRIPTION_CHANNEL_LABEL;
24979
25113
  var DIGEST_SUGGESTION = "Email me a summary of this every Monday at 8 in the morning.";
24980
25114
  function SubscriptionsPanel({ tableId, activeRuleId, className }) {
24981
- const client = useRecordsClient55();
25115
+ const client = useRecordsClient56();
24982
25116
  const [rows, setRows] = useState75(null);
24983
25117
  const [error, setError] = useState75(null);
24984
25118
  const [busy, setBusy] = useState75(null);
24985
25119
  const [preview, setPreview] = useState75(null);
24986
25120
  const [scheduling, setScheduling] = useState75(false);
25121
+ const [changing, setChanging] = useState75(null);
24987
25122
  const host = useRecordsUi();
24988
25123
  const load = useCallback38(async () => {
24989
25124
  const answered = await client.subscriptions({ table_id: tableId });
@@ -24995,7 +25130,7 @@ function SubscriptionsPanel({ tableId, activeRuleId, className }) {
24995
25130
  setError(null);
24996
25131
  setRows(answered.data);
24997
25132
  }, [client, tableId]);
24998
- useEffect62(() => {
25133
+ useEffect64(() => {
24999
25134
  void load();
25000
25135
  }, [load]);
25001
25136
  const flip = useCallback38(
@@ -25055,6 +25190,18 @@ function SubscriptionsPanel({ tableId, activeRuleId, className }) {
25055
25190
  onClose: () => setScheduling(false)
25056
25191
  }
25057
25192
  ) : null,
25193
+ changing ? /* @__PURE__ */ jsx85(
25194
+ DigestScheduler,
25195
+ {
25196
+ tableId,
25197
+ existing: changing,
25198
+ onScheduled: () => {
25199
+ void load();
25200
+ },
25201
+ onClose: () => setChanging(null)
25202
+ },
25203
+ changing.rule_id
25204
+ ) : null,
25058
25205
  rows.length === 0 && !scheduling ? /* @__PURE__ */ jsx85(
25059
25206
  BuildOrAsk,
25060
25207
  {
@@ -25108,7 +25255,7 @@ function SubscriptionsPanel({ tableId, activeRuleId, className }) {
25108
25255
  "Last told you ",
25109
25256
  new Date(subscription.last_sent_at).toLocaleString()
25110
25257
  ] }) : /* @__PURE__ */ jsx85("span", { children: "It has not told you anything yet." }),
25111
- hasQuietHours(subscription.quiet_hours) ? /* @__PURE__ */ jsxs77("span", { children: [
25258
+ hasQuietHours2(subscription.quiet_hours) ? /* @__PURE__ */ jsxs77("span", { children: [
25112
25259
  "Not between ",
25113
25260
  subscription.quiet_hours.start,
25114
25261
  " and ",
@@ -25124,7 +25271,8 @@ function SubscriptionsPanel({ tableId, activeRuleId, className }) {
25124
25271
  onClick: () => void showOne(subscription),
25125
25272
  children: "Send me a preview now"
25126
25273
  }
25127
- )
25274
+ ),
25275
+ subscription.mine && subscription.cadence !== "instant" ? /* @__PURE__ */ jsx85(Button65, { size: "sm", variant: "ghost", onClick: () => setChanging(subscription), children: "Change it" }) : null
25128
25276
  ] }),
25129
25277
  preview && preview.rule_id === subscription.rule_id ? /* @__PURE__ */ jsxs77("div", { className: "mt-2 rounded-md border bg-muted/40 p-2.5 text-xs", children: [
25130
25278
  /* @__PURE__ */ jsx85("p", { className: "font-medium", children: preview.subject }),
@@ -25171,8 +25319,8 @@ function SubscriptionsPanel({ tableId, activeRuleId, className }) {
25171
25319
  }
25172
25320
 
25173
25321
  // src/FormBuilder.tsx
25174
- import { useCallback as useCallback41, useEffect as useEffect65, useMemo as useMemo42, useState as useState78 } from "react";
25175
- import { useFields as useFields20, useRecordsClient as useRecordsClient57, useTable as useTable19 } from "@ai-matrx/records/react";
25322
+ import { useCallback as useCallback41, useEffect as useEffect67, useMemo as useMemo42, useState as useState78 } from "react";
25323
+ import { useFields as useFields20, useRecordsClient as useRecordsClient58, useTable as useTable19 } from "@ai-matrx/records/react";
25176
25324
  import { publicFormPath } from "@ai-matrx/records";
25177
25325
  import {
25178
25326
  BasicInput as BasicInput26,
@@ -25185,7 +25333,7 @@ import {
25185
25333
  } from "@ai-matrx/design-system";
25186
25334
 
25187
25335
  // src/FormRunner.tsx
25188
- import { useCallback as useCallback39, useEffect as useEffect63, useMemo as useMemo41, useRef as useRef24, useState as useState76 } from "react";
25336
+ import { useCallback as useCallback39, useEffect as useEffect65, useMemo as useMemo41, useRef as useRef24, useState as useState76 } from "react";
25189
25337
  import { useFields as useFields19, useOptionalRecordsClient as useOptionalRecordsClient8 } from "@ai-matrx/records/react";
25190
25338
  import { Button as Button66, Progress, Skeleton as Skeleton25, cn as cn54 } from "@ai-matrx/design-system";
25191
25339
  import { Fragment as Fragment36, jsx as jsx86, jsxs as jsxs78 } from "react/jsx-runtime";
@@ -25301,7 +25449,7 @@ function FormStage({
25301
25449
  };
25302
25450
  });
25303
25451
  }, [fields, form.questions]);
25304
- useEffect63(() => {
25452
+ useEffect65(() => {
25305
25453
  if (!whichAsked) return;
25306
25454
  if (!questions.some((q) => q.showIf)) return;
25307
25455
  let cancelled = false;
@@ -25345,7 +25493,7 @@ function FormStage({
25345
25493
  }, [whichAsked, questions, answers]);
25346
25494
  const live = questions.filter((q) => !hidden[q.key]);
25347
25495
  const told = useRef24(answers);
25348
- useEffect63(() => {
25496
+ useEffect65(() => {
25349
25497
  if (told.current === answers) return;
25350
25498
  told.current = answers;
25351
25499
  onAnswersChange?.(answers);
@@ -25356,7 +25504,7 @@ function FormStage({
25356
25504
  return v === void 0 || v === null || v === "";
25357
25505
  })?.key ?? null : null
25358
25506
  );
25359
- useEffect63(() => {
25507
+ useEffect65(() => {
25360
25508
  const key = resumeAt.current;
25361
25509
  if (!key) return;
25362
25510
  const i = live.findIndex((q) => q.key === key);
@@ -25422,7 +25570,7 @@ function FormStage({
25422
25570
  if (event.shiftKey) retreat();
25423
25571
  else advance();
25424
25572
  }
25425
- useEffect63(() => {
25573
+ useEffect65(() => {
25426
25574
  const input = stage.current?.querySelector(
25427
25575
  "input:not([tabindex='-1']), textarea, select, [role='combobox']"
25428
25576
  );
@@ -25533,7 +25681,7 @@ function ThankYou({ form, done, className }) {
25533
25681
  const host = useRecordsUi();
25534
25682
  const redirect = form.thankYou?.redirectUrl?.trim() || null;
25535
25683
  const going = redirect !== null && done !== "preview";
25536
- useEffect63(() => {
25684
+ useEffect65(() => {
25537
25685
  if (!going || !redirect) return;
25538
25686
  const timer = window.setTimeout(() => window.location.assign(redirect), REDIRECT_AFTER_MS);
25539
25687
  return () => window.clearTimeout(timer);
@@ -25546,7 +25694,12 @@ function ThankYou({ form, done, className }) {
25546
25694
  " ",
25547
25695
  /* @__PURE__ */ jsx86("a", { href: redirect, className: "underline underline-offset-2", children: "Go now" })
25548
25696
  ] }) : null,
25549
- /* @__PURE__ */ jsx86("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 })
25697
+ /* @__PURE__ */ jsx86("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" ? (
25698
+ // SAID TO THE PERSON WHO ANSWERED (lane HANDOVER, 2026-09-29): "Saved to Form 1, with
25699
+ // this form stamped on it" was the owner's bookkeeping read out to a front-desk member
25700
+ // and to strangers. Where it landed is the owner's to see on the table.
25701
+ "Your answers were received."
25702
+ ) : done })
25550
25703
  ] });
25551
25704
  }
25552
25705
  function Question({
@@ -25592,15 +25745,15 @@ function Question({
25592
25745
  }
25593
25746
 
25594
25747
  // src/NotifyRuleEditor.tsx
25595
- import { useCallback as useCallback40, useEffect as useEffect64, useState as useState77 } from "react";
25596
- import { useRecordsClient as useRecordsClient56, useTable as useTable18 } from "@ai-matrx/records/react";
25597
- import { hasQuietHours as hasQuietHours2 } from "@ai-matrx/records";
25748
+ import { useCallback as useCallback40, useEffect as useEffect66, useState as useState77 } from "react";
25749
+ import { useRecordsClient as useRecordsClient57, useTable as useTable18 } from "@ai-matrx/records/react";
25750
+ import { hasQuietHours as hasQuietHours3 } from "@ai-matrx/records";
25598
25751
  import { Button as Button67, Skeleton as Skeleton26, cn as cn55 } from "@ai-matrx/design-system";
25599
25752
  import { jsx as jsx87, jsxs as jsxs79 } from "react/jsx-runtime";
25600
25753
  var CADENCE_WORDS2 = SUBSCRIPTION_CADENCE_LABEL;
25601
25754
  var CHANNEL_WORDS3 = SUBSCRIPTION_CHANNEL_LABEL;
25602
25755
  function NotifyRuleEditor({ tableId, seed, chosenRuleId, onChoose, className }) {
25603
- const client = useRecordsClient56();
25756
+ const client = useRecordsClient57();
25604
25757
  const host = useRecordsUi();
25605
25758
  const table = useTable18(tableId);
25606
25759
  const rights = useTableRights(table.data);
@@ -25638,7 +25791,7 @@ function NotifyRuleEditor({ tableId, seed, chosenRuleId, onChoose, className })
25638
25791
  }
25639
25792
  setViews(listed.data.map((v) => ({ id: v.view_id, name: v.name })));
25640
25793
  }, [client, host, tableId]);
25641
- useEffect64(() => {
25794
+ useEffect66(() => {
25642
25795
  void load();
25643
25796
  }, [load]);
25644
25797
  const write = useCallback40(
@@ -25666,7 +25819,7 @@ function NotifyRuleEditor({ tableId, seed, chosenRuleId, onChoose, className })
25666
25819
  },
25667
25820
  [client, tableId]
25668
25821
  );
25669
- useEffect64(() => {
25822
+ useEffect66(() => {
25670
25823
  if (!subscriptions || !seed || seed.length === 0) return;
25671
25824
  const missing = seed.filter((s) => !subscriptions.some((held) => held.name === s.name));
25672
25825
  if (missing.length === 0) return;
@@ -25745,7 +25898,7 @@ function NotifyRuleEditor({ tableId, seed, chosenRuleId, onChoose, className })
25745
25898
  "next ",
25746
25899
  new Date(held.next_digest_at).toLocaleString()
25747
25900
  ] }) : null,
25748
- hasQuietHours2(held.quiet_hours) ? /* @__PURE__ */ jsxs79("span", { className: "text-muted-foreground", children: [
25901
+ hasQuietHours3(held.quiet_hours) ? /* @__PURE__ */ jsxs79("span", { className: "text-muted-foreground", children: [
25749
25902
  "quiet ",
25750
25903
  held.quiet_hours.start,
25751
25904
  "\u2013",
@@ -25849,7 +26002,7 @@ function NotifyRuleEditor({ tableId, seed, chosenRuleId, onChoose, className })
25849
26002
  // src/FormBuilder.tsx
25850
26003
  import { Fragment as Fragment37, jsx as jsx88, jsxs as jsxs80 } from "react/jsx-runtime";
25851
26004
  function FormBuilder({ tableId, seed, activeFormId, onActiveForm, startWithOne, className }) {
25852
- const client = useRecordsClient57();
26005
+ const client = useRecordsClient58();
25853
26006
  const publishGate = usePublishGate();
25854
26007
  const host = useRecordsUi();
25855
26008
  const claimSeed = useSeedGuard();
@@ -25894,10 +26047,10 @@ function FormBuilder({ tableId, seed, activeFormId, onActiveForm, startWithOne,
25894
26047
  setError(null);
25895
26048
  setForms(mine);
25896
26049
  }, [client, tableId, seed, claimSeed]);
25897
- useEffect65(() => {
26050
+ useEffect67(() => {
25898
26051
  void load();
25899
26052
  }, [load]);
25900
- useEffect65(() => {
26053
+ useEffect67(() => {
25901
26054
  if (!forms || forms.length === 0) return;
25902
26055
  const chosen = forms.find((f) => f.id === (activeFormId ?? activeId)) ?? forms[0];
25903
26056
  if (chosen.id !== activeId) setActiveId(chosen.id);
@@ -25982,12 +26135,13 @@ function FormBuilder({ tableId, seed, activeFormId, onActiveForm, startWithOne,
25982
26135
  await load();
25983
26136
  }
25984
26137
  const [started, setStarted] = useState78(false);
25985
- useEffect65(() => {
26138
+ useEffect67(() => {
25986
26139
  if (!startWithOne || started || forms === null || forms.length > 0) return;
25987
26140
  if (askableFields(fields.data ?? []).length === 0) return;
26141
+ if (!table.data && !table.error) return;
25988
26142
  setStarted(true);
25989
26143
  void create(table.data?.name?.trim() ? `${table.data.name.trim()} form` : "Form 1");
25990
- }, [startWithOne, started, forms, fields.data, create, table.data?.name]);
26144
+ }, [startWithOne, started, forms, fields.data, create, table.data, table.error]);
25991
26145
  if (fields.error) return /* @__PURE__ */ jsx88(RefusalNotice, { error: fields.error, className });
25992
26146
  if (error) {
25993
26147
  return /* @__PURE__ */ jsx88(
@@ -26481,7 +26635,7 @@ function bucketWindow(groupKey, value) {
26481
26635
 
26482
26636
  // src/chartFrame.tsx
26483
26637
  import {
26484
- useEffect as useEffect66,
26638
+ useEffect as useEffect68,
26485
26639
  useId as useId3,
26486
26640
  useRef as useRef25,
26487
26641
  useState as useState79
@@ -26491,7 +26645,7 @@ import { jsx as jsx89, jsxs as jsxs81 } from "react/jsx-runtime";
26491
26645
  function useMeasuredWidth(fallback = 480) {
26492
26646
  const ref = useRef25(null);
26493
26647
  const [width, setWidth] = useState79(fallback);
26494
- useEffect66(() => {
26648
+ useEffect68(() => {
26495
26649
  const node = ref.current;
26496
26650
  if (!node) return;
26497
26651
  const apply = () => {
@@ -26615,12 +26769,12 @@ function isSignatureField(field2) {
26615
26769
  }
26616
26770
 
26617
26771
  // src/DocTemplate.tsx
26618
- import { useCallback as useCallback42, useEffect as useEffect67, useState as useState80 } from "react";
26619
- import { useFields as useFields21, useRecordsClient as useRecordsClient58, useTable as useTable20 } from "@ai-matrx/records/react";
26772
+ import { useCallback as useCallback42, useEffect as useEffect69, useState as useState80 } from "react";
26773
+ import { useFields as useFields21, useRecordsClient as useRecordsClient59, useTable as useTable20 } from "@ai-matrx/records/react";
26620
26774
  import { BasicInput as BasicInput27, BasicTextarea as BasicTextarea12, Button as Button69, Label as Label20, Skeleton as Skeleton28, cn as cn58 } from "@ai-matrx/design-system";
26621
26775
  import { jsx as jsx90, jsxs as jsxs82 } from "react/jsx-runtime";
26622
26776
  function DocTemplate({ tableId, seed, activeTemplateId, onActiveTemplate, className }) {
26623
- const client = useRecordsClient58();
26777
+ const client = useRecordsClient59();
26624
26778
  const claimSeed = useSeedGuard();
26625
26779
  const table = useTable20(tableId);
26626
26780
  const rights = useTableRights(table.data);
@@ -26663,10 +26817,10 @@ function DocTemplate({ tableId, seed, activeTemplateId, onActiveTemplate, classN
26663
26817
  setError(null);
26664
26818
  setTemplates(rows);
26665
26819
  }, [client, tableId, seed, fields.data]);
26666
- useEffect67(() => {
26820
+ useEffect69(() => {
26667
26821
  void load();
26668
26822
  }, [load]);
26669
- useEffect67(() => {
26823
+ useEffect69(() => {
26670
26824
  if (!templates || templates.length === 0) return;
26671
26825
  const chosen = templates.find((t) => t.id === (activeTemplateId ?? activeId)) ?? templates[0];
26672
26826
  if (chosen.id !== activeId) setActiveId(chosen.id);
@@ -26674,7 +26828,7 @@ function DocTemplate({ tableId, seed, activeTemplateId, onActiveTemplate, classN
26674
26828
  setDraftBody(chosen.body);
26675
26829
  onActiveTemplate?.(chosen);
26676
26830
  }, [templates, activeTemplateId]);
26677
- useEffect67(() => {
26831
+ useEffect69(() => {
26678
26832
  let cancelled = false;
26679
26833
  if (draftBody.trim() === "") {
26680
26834
  setUnresolved([]);
@@ -26799,12 +26953,12 @@ function DocTemplate({ tableId, seed, activeTemplateId, onActiveTemplate, classN
26799
26953
  }
26800
26954
 
26801
26955
  // src/DocRender.tsx
26802
- import { useCallback as useCallback43, useEffect as useEffect68, useRef as useRef26, useState as useState81 } from "react";
26803
- import { useRecordsClient as useRecordsClient59 } from "@ai-matrx/records/react";
26956
+ import { useCallback as useCallback43, useEffect as useEffect70, useRef as useRef26, useState as useState81 } from "react";
26957
+ import { useRecordsClient as useRecordsClient60 } from "@ai-matrx/records/react";
26804
26958
  import { Button as Button70, Skeleton as Skeleton29, cn as cn59 } from "@ai-matrx/design-system";
26805
26959
  import { jsx as jsx91, jsxs as jsxs83 } from "react/jsx-runtime";
26806
26960
  function DocRender({ templateId, recordId, filename, onRendered, className }) {
26807
- const client = useRecordsClient59();
26961
+ const client = useRecordsClient60();
26808
26962
  const [preview, setPreview] = useState81(null);
26809
26963
  const [renders, setRenders] = useState81(null);
26810
26964
  const [showing, setShowing] = useState81(null);
@@ -26828,7 +26982,7 @@ function DocRender({ templateId, recordId, filename, onRendered, className }) {
26828
26982
  setPreview(body.data);
26829
26983
  setRenders(held.data.filter((r) => r.template_id === templateId));
26830
26984
  }, [client, templateId, recordId]);
26831
- useEffect68(() => {
26985
+ useEffect70(() => {
26832
26986
  void load();
26833
26987
  }, [load]);
26834
26988
  async function freeze() {
@@ -26912,13 +27066,13 @@ function DocRender({ templateId, recordId, filename, onRendered, className }) {
26912
27066
  }
26913
27067
 
26914
27068
  // src/SignBlock.tsx
26915
- import { useCallback as useCallback44, useEffect as useEffect69, useState as useState82 } from "react";
26916
- import { useFields as useFields22, useRecordsClient as useRecordsClient60 } from "@ai-matrx/records/react";
27069
+ import { useCallback as useCallback44, useEffect as useEffect71, useState as useState82 } from "react";
27070
+ import { useFields as useFields22, useRecordsClient as useRecordsClient61 } from "@ai-matrx/records/react";
26917
27071
  import { BasicInput as BasicInput28, Button as Button71, Skeleton as Skeleton30, cn as cn60 } from "@ai-matrx/design-system";
26918
27072
  import { useTable as useTable21 } from "@ai-matrx/records/react";
26919
27073
  import { jsx as jsx92, jsxs as jsxs84 } from "react/jsx-runtime";
26920
27074
  function SignBlock({ tableId, recordId, render, className }) {
26921
- const client = useRecordsClient60();
27075
+ const client = useRecordsClient61();
26922
27076
  const table = useTable21(tableId);
26923
27077
  const rights = useTableRights(table.data);
26924
27078
  const fields = useFields22(tableId);
@@ -26942,7 +27096,7 @@ function SignBlock({ tableId, recordId, render, className }) {
26942
27096
  }
26943
27097
  setVerdicts(answers);
26944
27098
  }, [client, recordId]);
26945
- useEffect69(() => {
27099
+ useEffect71(() => {
26946
27100
  void load();
26947
27101
  }, [load]);
26948
27102
  async function sign(field2) {
@@ -27515,8 +27669,8 @@ function onlyWholeNumbers(rows) {
27515
27669
  }
27516
27670
 
27517
27671
  // src/DashboardCanvas.tsx
27518
- import { useCallback as useCallback45, useEffect as useEffect70, useMemo as useMemo44, useState as useState83 } from "react";
27519
- import { useFields as useFields23, useRecordsClient as useRecordsClient61, useTable as useTable22 } from "@ai-matrx/records/react";
27672
+ import { useCallback as useCallback45, useEffect as useEffect72, useMemo as useMemo44, useState as useState83 } from "react";
27673
+ import { useFields as useFields23, useRecordsClient as useRecordsClient62, useTable as useTable22 } from "@ai-matrx/records/react";
27520
27674
  import {
27521
27675
  BasicInput as BasicInput29,
27522
27676
  Button as Button72,
@@ -27530,7 +27684,7 @@ import {
27530
27684
  } from "@ai-matrx/design-system";
27531
27685
  import { Fragment as Fragment39, jsx as jsx94, jsxs as jsxs86 } from "react/jsx-runtime";
27532
27686
  function DashboardCanvas({ tableId, activeDashboardId, filter, className }) {
27533
- const client = useRecordsClient61();
27687
+ const client = useRecordsClient62();
27534
27688
  const host = useRecordsUi();
27535
27689
  const table = useTable22(tableId);
27536
27690
  const rights = useTableRights(table.data);
@@ -27562,17 +27716,17 @@ function DashboardCanvas({ tableId, activeDashboardId, filter, className }) {
27562
27716
  return read;
27563
27717
  }, [client, tableId]);
27564
27718
  const [notKept, setNotKept] = useState83(null);
27565
- useEffect70(() => {
27719
+ useEffect72(() => {
27566
27720
  void load();
27567
27721
  }, [load]);
27568
- useEffect70(() => {
27722
+ useEffect72(() => {
27569
27723
  if (!boards || boards.length === 0) return;
27570
27724
  const chosen = boards.find((d) => d.id === (activeDashboardId ?? activeId)) ?? boards[0];
27571
27725
  if (chosen.id !== activeId) setActiveId(chosen.id);
27572
27726
  }, [boards, activeDashboardId]);
27573
27727
  const board = useMemo44(() => boards?.find((d) => d.id === activeId) ?? null, [boards, activeId]);
27574
27728
  const filterKey = JSON.stringify(filter ?? {});
27575
- useEffect70(() => {
27729
+ useEffect72(() => {
27576
27730
  if (!activeId) {
27577
27731
  setRun(null);
27578
27732
  return;
@@ -28030,7 +28184,7 @@ function TargetControl({
28030
28184
  const [mode, setMode] = useState83(saved);
28031
28185
  const savedValue = block.target && "value" in block.target && typeof block.target.value === "number" ? block.target.value : null;
28032
28186
  const [draft, setDraft] = useState83(savedValue === null ? "" : String(savedValue));
28033
- useEffect70(() => {
28187
+ useEffect72(() => {
28034
28188
  setMode(saved);
28035
28189
  setDraft(savedValue === null ? "" : String(savedValue));
28036
28190
  }, [saved, savedValue]);
@@ -28097,8 +28251,8 @@ function TargetControl({
28097
28251
  }
28098
28252
 
28099
28253
  // src/FormsPanel.tsx
28100
- import { useCallback as useCallback46, useEffect as useEffect71, useState as useState84 } from "react";
28101
- import { useRecordsClient as useRecordsClient62, useTable as useTable23 } from "@ai-matrx/records/react";
28254
+ import { useCallback as useCallback46, useEffect as useEffect73, useState as useState84 } from "react";
28255
+ import { useRecordsClient as useRecordsClient63, useTable as useTable23 } from "@ai-matrx/records/react";
28102
28256
  import { publicFormPath as publicFormPath2 } from "@ai-matrx/records";
28103
28257
  import { Badge as Badge22, Button as Button73, Skeleton as Skeleton32, cn as cn63 } from "@ai-matrx/design-system";
28104
28258
  import { Fragment as Fragment40, jsx as jsx95, jsxs as jsxs87 } from "react/jsx-runtime";
@@ -28110,7 +28264,7 @@ function formSuggestion(tableName2) {
28110
28264
  return `Make me a form that collects new ${subject} entries and tells me when somebody answers.`;
28111
28265
  }
28112
28266
  function FormsPanel({ tableId, activeFormId, className }) {
28113
- const client = useRecordsClient62();
28267
+ const client = useRecordsClient63();
28114
28268
  const publishGate = usePublishGate();
28115
28269
  const host = useRecordsUi();
28116
28270
  const table = useTable23(tableId);
@@ -28122,7 +28276,7 @@ function FormsPanel({ tableId, activeFormId, className }) {
28122
28276
  const [building, setBuilding] = useState84(false);
28123
28277
  const linked = activeFormId && forms !== null ? forms.find((f) => f.form_id === activeFormId) ?? null : null;
28124
28278
  const linkedMissing = Boolean(activeFormId) && forms !== null && linked === null;
28125
- useEffect71(() => {
28279
+ useEffect73(() => {
28126
28280
  if (linked && rights.structure) setBuilding(true);
28127
28281
  }, [linked, rights.structure]);
28128
28282
  const load = useCallback46(async () => {
@@ -28135,7 +28289,7 @@ function FormsPanel({ tableId, activeFormId, className }) {
28135
28289
  setError(null);
28136
28290
  setForms(answered.data);
28137
28291
  }, [client, tableId]);
28138
- useEffect71(() => {
28292
+ useEffect73(() => {
28139
28293
  void load();
28140
28294
  }, [load]);
28141
28295
  const toggle = useCallback46(
@@ -28267,18 +28421,18 @@ function FormsPanel({ tableId, activeFormId, className }) {
28267
28421
  }
28268
28422
 
28269
28423
  // src/CaptureSheet.tsx
28270
- import { useCallback as useCallback48, useEffect as useEffect73, useRef as useRef28, useState as useState86 } from "react";
28271
- import { useFields as useFields24, useRecordsClient as useRecordsClient64, useTable as useTable24 } from "@ai-matrx/records/react";
28424
+ import { useCallback as useCallback48, useEffect as useEffect75, useRef as useRef28, useState as useState86 } from "react";
28425
+ import { useFields as useFields24, useRecordsClient as useRecordsClient65, useTable as useTable24 } from "@ai-matrx/records/react";
28272
28426
  import { Button as Button75, Input as Input4, Skeleton as Skeleton34, Textarea as Textarea3, cn as cn65 } from "@ai-matrx/design-system";
28273
28427
 
28274
28428
  // src/CaptureRun.tsx
28275
- import { useCallback as useCallback47, useEffect as useEffect72, useMemo as useMemo45, useRef as useRef27, useState as useState85 } from "react";
28429
+ import { useCallback as useCallback47, useEffect as useEffect74, useMemo as useMemo45, useRef as useRef27, useState as useState85 } from "react";
28276
28430
  import {
28277
28431
  coerceTypedAnswer as coerceTypedAnswer3,
28278
28432
  coercionLabel,
28279
28433
  openCaptureQueue
28280
28434
  } from "@ai-matrx/records";
28281
- import { useRecordsClient as useRecordsClient63 } from "@ai-matrx/records/react";
28435
+ import { useRecordsClient as useRecordsClient64 } from "@ai-matrx/records/react";
28282
28436
  import { Button as Button74, Input as Input3, Skeleton as Skeleton33, Textarea as Textarea2, cn as cn64 } from "@ai-matrx/design-system";
28283
28437
  import { jsx as jsx96, jsxs as jsxs88 } from "react/jsx-runtime";
28284
28438
  function controlFor(field2) {
@@ -28317,7 +28471,7 @@ function whereWeAre(timeoutMs = 4e3) {
28317
28471
  });
28318
28472
  }
28319
28473
  function CaptureRun({ sheetId, face: given, className }) {
28320
- const client = useRecordsClient63();
28474
+ const client = useRecordsClient64();
28321
28475
  const host = useRecordsUi();
28322
28476
  const [face, setFace] = useState85(given);
28323
28477
  const [loadFailed, setLoadFailed] = useState85(null);
@@ -28331,7 +28485,7 @@ function CaptureRun({ sheetId, face: given, className }) {
28331
28485
  const [lastSynced, setLastSynced] = useState85(null);
28332
28486
  const [sending, setSending] = useState85(false);
28333
28487
  const queueRef = useRef27(null);
28334
- useEffect72(() => {
28488
+ useEffect74(() => {
28335
28489
  const q2 = openCaptureQueue({
28336
28490
  onChange: (c, all) => {
28337
28491
  setCounts(c);
@@ -28369,7 +28523,7 @@ function CaptureRun({ sheetId, face: given, className }) {
28369
28523
  void q2.sync().then(() => void q2.lastSyncedAt().then(setLastSynced));
28370
28524
  return () => q2.dispose();
28371
28525
  }, [client, host]);
28372
- useEffect72(() => {
28526
+ useEffect74(() => {
28373
28527
  if (given !== void 0) return;
28374
28528
  let cancelled = false;
28375
28529
  void client.captureOpen({ sheet_id: sheetId }).then((res) => {
@@ -28697,7 +28851,7 @@ function AdHocCaptureSheet({
28697
28851
  attachmentField,
28698
28852
  className
28699
28853
  }) {
28700
- const client = useRecordsClient64();
28854
+ const client = useRecordsClient65();
28701
28855
  const host = useRecordsUi();
28702
28856
  const table = useTable24(tableId);
28703
28857
  const fields = useFields24(tableId);
@@ -28719,7 +28873,7 @@ function AdHocCaptureSheet({
28719
28873
  },
28720
28874
  [host]
28721
28875
  );
28722
- useEffect73(() => {
28876
+ useEffect75(() => {
28723
28877
  let cancelled = false;
28724
28878
  void (async () => {
28725
28879
  const held = host.captureQueue ? await host.captureQueue.load() : [];
@@ -28898,12 +29052,12 @@ function AdHocCaptureSheet({
28898
29052
  }
28899
29053
 
28900
29054
  // src/PortalShell.tsx
28901
- import { useCallback as useCallback49, useEffect as useEffect74, useState as useState87 } from "react";
28902
- import { useRecordsClient as useRecordsClient65 } from "@ai-matrx/records/react";
29055
+ import { useCallback as useCallback49, useEffect as useEffect76, useState as useState87 } from "react";
29056
+ import { useRecordsClient as useRecordsClient66 } from "@ai-matrx/records/react";
28903
29057
  import { Button as Button76, Skeleton as Skeleton35, cn as cn66 } from "@ai-matrx/design-system";
28904
29058
  import { jsx as jsx98, jsxs as jsxs90 } from "react/jsx-runtime";
28905
29059
  function PortalShell({ tableId, form, resourceType = "record", className }) {
28906
- const client = useRecordsClient65();
29060
+ const client = useRecordsClient66();
28907
29061
  const [card, setCard] = useState87(null);
28908
29062
  const [reach, setReach] = useState87(null);
28909
29063
  const [error, setError] = useState87(null);
@@ -28924,7 +29078,7 @@ function PortalShell({ tableId, form, resourceType = "record", className }) {
28924
29078
  }
28925
29079
  setReach(reached.data.map((row) => row.resource_id));
28926
29080
  }, [client, resourceType]);
28927
- useEffect74(() => {
29081
+ useEffect76(() => {
28928
29082
  void load();
28929
29083
  }, [load]);
28930
29084
  if (error) {
@@ -28982,9 +29136,9 @@ function PortalShell({ tableId, form, resourceType = "record", className }) {
28982
29136
  ] });
28983
29137
  }
28984
29138
  function PortalRow({ tableId, recordId }) {
28985
- const client = useRecordsClient65();
29139
+ const client = useRecordsClient66();
28986
29140
  const [title, setTitle] = useState87(null);
28987
- useEffect74(() => {
29141
+ useEffect76(() => {
28988
29142
  let cancelled = false;
28989
29143
  void client.recordRead({ record_id: recordId }).then((answered) => {
28990
29144
  if (cancelled) return;
@@ -29004,12 +29158,12 @@ function PortalRow({ tableId, recordId }) {
29004
29158
  }
29005
29159
 
29006
29160
  // src/PublicViewPage.tsx
29007
- import { useCallback as useCallback50, useEffect as useEffect75, useState as useState88 } from "react";
29008
- import { useRecordsClient as useRecordsClient66 } from "@ai-matrx/records/react";
29161
+ import { useCallback as useCallback50, useEffect as useEffect77, useState as useState88 } from "react";
29162
+ import { useRecordsClient as useRecordsClient67 } from "@ai-matrx/records/react";
29009
29163
  import { Skeleton as Skeleton36, cn as cn67 } from "@ai-matrx/design-system";
29010
29164
  import { jsx as jsx99, jsxs as jsxs91 } from "react/jsx-runtime";
29011
29165
  function PublicViewPage({ slug, className }) {
29012
- const client = useRecordsClient66();
29166
+ const client = useRecordsClient67();
29013
29167
  const [binding, setBinding] = useState88(null);
29014
29168
  const [rows, setRows] = useState88(null);
29015
29169
  const [fields, setFields] = useState88(null);
@@ -29048,7 +29202,7 @@ function PublicViewPage({ slug, className }) {
29048
29202
  }
29049
29203
  setRows([{ id: found.resource_id, document: read.data.document, level: "viewer", hidden: read.data.hidden }]);
29050
29204
  }, [client, slug]);
29051
- useEffect75(() => {
29205
+ useEffect77(() => {
29052
29206
  void load();
29053
29207
  }, [load]);
29054
29208
  if (error) return /* @__PURE__ */ jsx99(RefusalNotice, { error, className });
@@ -29085,8 +29239,8 @@ function PublicRow({ row, fields }) {
29085
29239
  }
29086
29240
 
29087
29241
  // src/EmbedFrame.tsx
29088
- import { useCallback as useCallback51, useEffect as useEffect76, useState as useState89 } from "react";
29089
- import { useRecordsClient as useRecordsClient67 } from "@ai-matrx/records/react";
29242
+ import { useCallback as useCallback51, useEffect as useEffect78, useState as useState89 } from "react";
29243
+ import { useRecordsClient as useRecordsClient68 } from "@ai-matrx/records/react";
29090
29244
  import { Button as Button77, Input as Input5, Skeleton as Skeleton37, Textarea as Textarea4, cn as cn68 } from "@ai-matrx/design-system";
29091
29245
  import { useTable as useTable25 } from "@ai-matrx/records/react";
29092
29246
  import { Fragment as Fragment42, jsx as jsx100, jsxs as jsxs92 } from "react/jsx-runtime";
@@ -29098,7 +29252,7 @@ function EmbedFrame({
29098
29252
  embedUrl,
29099
29253
  className
29100
29254
  }) {
29101
- const client = useRecordsClient67();
29255
+ const client = useRecordsClient68();
29102
29256
  const host = useRecordsUi();
29103
29257
  const table = useTable25(tableId);
29104
29258
  const rights = useTableRights(table.data);
@@ -29192,13 +29346,13 @@ function EmbedFrame({
29192
29346
  ] });
29193
29347
  }
29194
29348
  function useEmbedHandshake(args) {
29195
- const client = useRecordsClient67();
29349
+ const client = useRecordsClient68();
29196
29350
  const [binding, setBinding] = useState89(null);
29197
29351
  const [error, setError] = useState89(null);
29198
29352
  const [loading, setLoading] = useState89(true);
29199
29353
  const origin = args.origin ?? (typeof location === "undefined" ? "" : location.origin);
29200
29354
  const { secret, requiredMode } = args;
29201
- useEffect76(() => {
29355
+ useEffect78(() => {
29202
29356
  let cancelled = false;
29203
29357
  setLoading(true);
29204
29358
  setError(null);
@@ -29270,9 +29424,9 @@ function recordsDataSource(client, fallbackSchema = "custom") {
29270
29424
  }
29271
29425
 
29272
29426
  // src/TablePage.tsx
29273
- import { useCallback as useCallback52, useEffect as useEffect79, useRef as useRef30, useState as useState92 } from "react";
29427
+ import { useCallback as useCallback52, useEffect as useEffect81, useRef as useRef30, useState as useState92 } from "react";
29274
29428
  import { archivedByLine as archivedByLine2 } from "@ai-matrx/records";
29275
- import { useFields as useFields26, useRecordsClient as useRecordsClient68, useTable as useTable26 } from "@ai-matrx/records/react";
29429
+ import { useFields as useFields26, useRecordsClient as useRecordsClient69, useTable as useTable26 } from "@ai-matrx/records/react";
29276
29430
  import {
29277
29431
  BottomSheet,
29278
29432
  Button as Button79,
@@ -29293,7 +29447,7 @@ import {
29293
29447
  } from "@ai-matrx/design-system";
29294
29448
 
29295
29449
  // src/ViewFilter.tsx
29296
- import { useEffect as useEffect77, useMemo as useMemo46, useState as useState90 } from "react";
29450
+ import { useEffect as useEffect79, useMemo as useMemo46, useState as useState90 } from "react";
29297
29451
  import { Button as Button78, cn as cn69 } from "@ai-matrx/design-system";
29298
29452
  import { useFields as useFields25 } from "@ai-matrx/records/react";
29299
29453
  import { jsx as jsx102, jsxs as jsxs93 } from "react/jsx-runtime";
@@ -29311,7 +29465,7 @@ function ViewFilter({ tableId, view, onApply, className }) {
29311
29465
  const saved = view?.where ?? null;
29312
29466
  const [draft, setDraft] = useState90(saved);
29313
29467
  const savedKey = JSON.stringify(saved);
29314
- useEffect77(() => {
29468
+ useEffect79(() => {
29315
29469
  setDraft(saved);
29316
29470
  }, [view?.id, savedKey]);
29317
29471
  const conditionFields = useMemo46(
@@ -29394,7 +29548,7 @@ function ViewFilter({ tableId, view, onApply, className }) {
29394
29548
  }
29395
29549
 
29396
29550
  // src/toolbarFit.ts
29397
- import { useEffect as useEffect78, useState as useState91 } from "react";
29551
+ import { useEffect as useEffect80, useState as useState91 } from "react";
29398
29552
  var FOLDED_GUESS = { look: 104, chooser: 96, tools: 120 };
29399
29553
  function toolbarFold(input) {
29400
29554
  const { available, needsNow, gap, folded } = input;
@@ -29446,7 +29600,7 @@ function rowNeeds(row) {
29446
29600
  }
29447
29601
  function useToolbarFit(row) {
29448
29602
  const [fold, setFold] = useState91(0);
29449
- useEffect78(() => {
29603
+ useEffect80(() => {
29450
29604
  if (!row) return;
29451
29605
  const widths = {
29452
29606
  look: { full: null, folded: null },
@@ -29527,7 +29681,7 @@ function clippedEnds(scrollLeft, clientWidth, scrollWidth) {
29527
29681
  }
29528
29682
  function useSlotScroll(slot) {
29529
29683
  const [ends, setEnds] = useState91("none");
29530
- useEffect78(() => {
29684
+ useEffect80(() => {
29531
29685
  if (!slot) return;
29532
29686
  let pending = 0;
29533
29687
  const read = () => {
@@ -29643,11 +29797,11 @@ function TableNotHere({
29643
29797
  leaveLabel,
29644
29798
  className
29645
29799
  }) {
29646
- const client = useRecordsClient68();
29800
+ const client = useRecordsClient69();
29647
29801
  const [archived, setArchived] = useState92({ phase: "asking" });
29648
29802
  const [restoring, setRestoring] = useState92(false);
29649
29803
  const [refusal2, setRefusal] = useState92(null);
29650
- useEffect79(() => {
29804
+ useEffect81(() => {
29651
29805
  let alive = true;
29652
29806
  void client.tableArchived({ table_id: tableId }).then((answered) => {
29653
29807
  if (!alive) return;
@@ -29834,15 +29988,15 @@ function TablePage({
29834
29988
  onShownViewChange,
29835
29989
  className
29836
29990
  }) {
29837
- const client = useRecordsClient68();
29991
+ const client = useRecordsClient69();
29838
29992
  const table = useTable26(tableId);
29839
29993
  const rights = useTableRights(table.data);
29840
29994
  const pageFields = useFields26(filter ? tableId : null);
29841
29995
  const askedInWords = filter ? filterInWords(filter, pageFields.data ?? []) : null;
29842
- const organizationId = useRecordsClient68().config.organizationId;
29996
+ const organizationId = useRecordsClient69().config.organizationId;
29843
29997
  const [view, setView] = useState92(null);
29844
29998
  const [looks, setLooks] = useState92(void 0);
29845
- useEffect79(() => {
29999
+ useEffect81(() => {
29846
30000
  let live = true;
29847
30001
  setLooks(void 0);
29848
30002
  void readLooks(client, tableId).then((answered) => {
@@ -29894,7 +30048,7 @@ function TablePage({
29894
30048
  const chooserInline = !designated && !phone && toolbarFold2 < 2;
29895
30049
  const chooserCompact = !designated && !phone && toolbarFold2 >= 2;
29896
30050
  const controlsInSheet = phone && !designated;
29897
- useEffect79(() => {
30051
+ useEffect81(() => {
29898
30052
  if (face.kind !== "designated") return;
29899
30053
  if (hostFromLink || opened.layout || layoutChosen) return;
29900
30054
  setHostLayout(face.hostLayout);
@@ -29927,7 +30081,7 @@ function TablePage({
29927
30081
  const shownSignature = JSON.stringify(shownReport);
29928
30082
  const reportRef = useRef30(onShownViewChange);
29929
30083
  reportRef.current = onShownViewChange;
29930
- useEffect79(() => {
30084
+ useEffect81(() => {
29931
30085
  reportRef.current?.(JSON.parse(shownSignature));
29932
30086
  }, [shownSignature]);
29933
30087
  const pickLayout = (next) => {
@@ -29945,18 +30099,18 @@ function TablePage({
29945
30099
  onViewChanged?.(id);
29946
30100
  };
29947
30101
  const openedFromMenu = MENU.find((entry) => entry.press.main !== void 0 && entry.press.main === main) ?? MENU.find((entry) => entry.press.rail !== void 0 && entry.press.rail === rail) ?? null;
29948
- useEffect79(() => {
30102
+ useEffect81(() => {
29949
30103
  if (!activeRecordId) return;
29950
30104
  setOpenRecord(activeRecordId);
29951
30105
  setSurface((now) => ({ ...now, rail: "record" }));
29952
30106
  }, [activeRecordId]);
29953
- useEffect79(() => {
30107
+ useEffect81(() => {
29954
30108
  if (activeRecordId) return;
29955
30109
  const named = railFromParam(activeRail);
29956
30110
  if (named === null || named === "share") return;
29957
30111
  setSurface((now) => ({ ...now, rail: named }));
29958
30112
  }, [activeRail, activeRecordId]);
29959
- useEffect79(() => {
30113
+ useEffect81(() => {
29960
30114
  const host = hostLayoutFor(activeView);
29961
30115
  if (host) {
29962
30116
  setHostLayout(host);
@@ -30908,6 +31062,7 @@ export {
30908
31062
  scalarText,
30909
31063
  seedIsSatisfied,
30910
31064
  shareUnavailableReason,
31065
+ singularNoun,
30911
31066
  snoozeChoices,
30912
31067
  specFromBlock,
30913
31068
  storeDecidesRights,