@ai-matrx/records-ui 0.93.63 → 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" });
@@ -18617,15 +18693,19 @@ function Kanban({
18617
18693
  }) {
18618
18694
  const groupFields = useMemo31(() => [groupField], [groupField]);
18619
18695
  const labels = useRecordLabels(groupFields);
18696
+ const options = useChoiceOptions(groupFields, isChoiceField(groupField) ? [groupField.key] : []).get(groupField.key);
18620
18697
  const columns = useMemo31(() => {
18621
18698
  const map = /* @__PURE__ */ new Map();
18699
+ const order = (options ?? []).map((o) => o.label);
18700
+ for (const label of order) map.set(label, []);
18622
18701
  for (const row of rows) {
18623
18702
  const raw = (row.document ?? {})[groupField.key];
18624
18703
  const key = raw === null || raw === void 0 || raw === "" ? "No value" : scalarText(groupField, raw, labels);
18625
18704
  map.set(key, [...map.get(key) ?? [], row]);
18626
18705
  }
18627
- return [...map.entries()].sort((a, b) => a[0] === "No value" ? 1 : b[0] === "No value" ? -1 : a[0].localeCompare(b[0]));
18628
- }, [rows, groupField, labels]);
18706
+ const rank = (name) => name === "No value" ? Number.MAX_SAFE_INTEGER : order.includes(name) ? order.indexOf(name) : order.length;
18707
+ return [...map.entries()].sort((a, b) => rank(a[0]) - rank(b[0]) || a[0].localeCompare(b[0]));
18708
+ }, [rows, groupField, labels, options]);
18629
18709
  return /* @__PURE__ */ jsxs56("div", { className: "flex min-h-0 flex-col gap-2", children: [
18630
18710
  /* @__PURE__ */ jsx64(Note, { children: note }),
18631
18711
  /* @__PURE__ */ jsx64("div", { className: "flex min-h-0 gap-2 overflow-x-auto pb-2", children: columns.map(([name, cards]) => /* @__PURE__ */ jsxs56("section", { className: "flex w-64 shrink-0 flex-col rounded border bg-muted/30", children: [
@@ -18817,7 +18897,7 @@ function Card2({
18817
18897
  }
18818
18898
 
18819
18899
  // src/ArchivedView.tsx
18820
- 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";
18821
18901
  import {
18822
18902
  ARCHIVE_LANES,
18823
18903
  ARCHIVE_LANE_LABEL,
@@ -18826,7 +18906,7 @@ import {
18826
18906
  archivedByLine,
18827
18907
  emptyArchiveLine
18828
18908
  } from "@ai-matrx/records";
18829
- 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";
18830
18910
  import { Button as Button46, Skeleton as Skeleton8, cn as cn35 } from "@ai-matrx/design-system";
18831
18911
  import { jsx as jsx65, jsxs as jsxs57 } from "react/jsx-runtime";
18832
18912
  var ARCHIVE_MEANS = "Archiving never destroys anything. A record you remove from the grid waits here until somebody brings it back.";
@@ -18845,7 +18925,7 @@ function ArchivedView({
18845
18925
  onRestored,
18846
18926
  className
18847
18927
  }) {
18848
- const client = useRecordsClient35();
18928
+ const client = useRecordsClient36();
18849
18929
  const table = useTable9(tableId);
18850
18930
  const rights = useTableRights(table.data);
18851
18931
  const fields = useFields14(tableId);
@@ -18855,7 +18935,7 @@ function ArchivedView({
18855
18935
  const [error, setError] = useState55(null);
18856
18936
  const [restoring, setRestoring] = useState55(null);
18857
18937
  const [refusal2, setRefusal] = useState55(null);
18858
- useEffect43(() => {
18938
+ useEffect45(() => {
18859
18939
  if (laneFromHost) setLane(laneFromHost);
18860
18940
  }, [laneFromHost]);
18861
18941
  const read = useCallback22(async () => {
@@ -18870,7 +18950,7 @@ function ArchivedView({
18870
18950
  }
18871
18951
  setLoading(false);
18872
18952
  }, [client, tableId, lane, pageSize]);
18873
- useEffect43(() => {
18953
+ useEffect45(() => {
18874
18954
  void read();
18875
18955
  }, [read]);
18876
18956
  const pick = (next) => {
@@ -18952,13 +19032,13 @@ function ArchivedView({
18952
19032
  }
18953
19033
 
18954
19034
  // src/ArchivedDisclosure.tsx
18955
- 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";
18956
19036
  import {
18957
19037
  emptyPortalArchiveLine,
18958
19038
  portalConfirmLine,
18959
19039
  portalTitleTypedBack
18960
19040
  } from "@ai-matrx/records";
18961
- import { useRecordsClient as useRecordsClient36 } from "@ai-matrx/records/react";
19041
+ import { useRecordsClient as useRecordsClient37 } from "@ai-matrx/records/react";
18962
19042
  import { BasicInput as BasicInput16, Button as Button47, Skeleton as Skeleton9, cn as cn36 } from "@ai-matrx/design-system";
18963
19043
  import { jsx as jsx66, jsxs as jsxs58 } from "react/jsx-runtime";
18964
19044
  var ARCHIVED_NEVER_DESTROYED = "Archiving never destroys anything. What you put away waits here until somebody brings it back.";
@@ -19003,7 +19083,7 @@ function ArchivedPortals({
19003
19083
  defaultOpen,
19004
19084
  className
19005
19085
  }) {
19006
- const client = useRecordsClient36();
19086
+ const client = useRecordsClient37();
19007
19087
  const [rows, setRows] = useState56(null);
19008
19088
  const [error, setError] = useState56(null);
19009
19089
  const [confirming, setConfirming] = useState56(null);
@@ -19021,7 +19101,7 @@ function ArchivedPortals({
19021
19101
  setError(answered.error);
19022
19102
  }
19023
19103
  }, [client]);
19024
- useEffect44(() => {
19104
+ useEffect46(() => {
19025
19105
  void read();
19026
19106
  }, [read, refreshToken]);
19027
19107
  const restore = async (portal) => {
@@ -19137,8 +19217,8 @@ function ArchivedPortals({
19137
19217
  }
19138
19218
 
19139
19219
  // src/ViewBar.tsx
19140
- import { useCallback as useCallback25, useEffect as useEffect45, useState as useState57 } from "react";
19141
- 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";
19142
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";
19143
19223
 
19144
19224
  // src/seedOnce.ts
@@ -19161,7 +19241,7 @@ function seedIsSatisfied(seed, views) {
19161
19241
  return seed.isDefault === true && views.some((v) => v.isDefault);
19162
19242
  }
19163
19243
  function ViewBar({ tableId, activeViewId, onActiveView, seed, settings, onViews, className }) {
19164
- const client = useRecordsClient37();
19244
+ const client = useRecordsClient38();
19165
19245
  const claimSeed = useSeedGuard();
19166
19246
  const table = useTable10(tableId);
19167
19247
  const rights = useTableRights(table.data);
@@ -19213,10 +19293,10 @@ function ViewBar({ tableId, activeViewId, onActiveView, seed, settings, onViews,
19213
19293
  setViews(mine);
19214
19294
  onViews?.(mine);
19215
19295
  }, [client, readViews, tableId, seedKey]);
19216
- useEffect45(() => {
19296
+ useEffect47(() => {
19217
19297
  void load();
19218
19298
  }, [load]);
19219
- useEffect45(() => {
19299
+ useEffect47(() => {
19220
19300
  if (!views || views.length === 0) return;
19221
19301
  const chosen = views.find((v) => v.id === (activeViewId ?? active)) ?? defaultViewOf(views) ?? views[0];
19222
19302
  if (chosen.id !== active) setActive(chosen.id);
@@ -19320,7 +19400,7 @@ function ViewBar({ tableId, activeViewId, onActiveView, seed, settings, onViews,
19320
19400
 
19321
19401
  // src/ProposalRow.tsx
19322
19402
  import { useState as useState58 } from "react";
19323
- import { useRecordsClient as useRecordsClient38 } from "@ai-matrx/records/react";
19403
+ import { useRecordsClient as useRecordsClient39 } from "@ai-matrx/records/react";
19324
19404
  import { Badge as Badge13, Button as Button49, cn as cn38 } from "@ai-matrx/design-system";
19325
19405
  import { jsx as jsx68, jsxs as jsxs60 } from "react/jsx-runtime";
19326
19406
  var ACT_WORD = PROPOSED_CHANGE_ACT_LABEL;
@@ -19333,7 +19413,7 @@ function ProposalRow({
19333
19413
  onSettled,
19334
19414
  className
19335
19415
  }) {
19336
- const client = useRecordsClient38();
19416
+ const client = useRecordsClient39();
19337
19417
  const [settled, setSettled] = useState58(outcome ?? null);
19338
19418
  const [busy, setBusy] = useState58(false);
19339
19419
  const [confirming, setConfirming] = useState58(false);
@@ -19421,14 +19501,14 @@ function ProposalRow({
19421
19501
  }
19422
19502
 
19423
19503
  // src/ActionInbox.tsx
19424
- import { useCallback as useCallback27, useEffect as useEffect47, useMemo as useMemo33, useRef as useRef21, useState as useState60 } from "react";
19425
- 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";
19426
19506
  import { Badge as Badge15, Button as Button51, Checkbox as Checkbox7, Skeleton as Skeleton12, cn as cn40 } from "@ai-matrx/design-system";
19427
19507
  import { toggleSelection as toggleSelection2 } from "@ai-matrx/design-system/data-table";
19428
19508
 
19429
19509
  // src/ChecklistRunner.tsx
19430
- import { useCallback as useCallback26, useEffect as useEffect46, useMemo as useMemo32, useState as useState59 } from "react";
19431
- 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";
19432
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";
19433
19513
  import { Fragment as Fragment27, jsx as jsx69, jsxs as jsxs61 } from "react/jsx-runtime";
19434
19514
  var DUE_WORD = DUE_STATE_LABEL;
@@ -19442,7 +19522,7 @@ function ChecklistRunner({
19442
19522
  offerToStart,
19443
19523
  className
19444
19524
  }) {
19445
- const client = useRecordsClient39();
19525
+ const client = useRecordsClient40();
19446
19526
  const table = useTable11(tableId ?? null);
19447
19527
  const rights = useTableRights(table.data);
19448
19528
  const [runs, setRuns] = useState59(null);
@@ -19475,10 +19555,10 @@ function ChecklistRunner({
19475
19555
  (held) => held && answered.data.some((r) => r.run_id === held) ? held : answered.data[0]?.run_id ?? null
19476
19556
  );
19477
19557
  }, [client, includeClosed, recordId, runId, tableId]);
19478
- useEffect46(() => {
19558
+ useEffect48(() => {
19479
19559
  void loadRuns();
19480
19560
  }, [loadRuns]);
19481
- useEffect46(() => {
19561
+ useEffect48(() => {
19482
19562
  if (runId) setActiveId(runId);
19483
19563
  }, [runId]);
19484
19564
  const loadSteps = useCallback26(async () => {
@@ -19495,10 +19575,10 @@ function ChecklistRunner({
19495
19575
  setError(null);
19496
19576
  setSteps(answered.data);
19497
19577
  }, [client, activeId]);
19498
- useEffect46(() => {
19578
+ useEffect48(() => {
19499
19579
  void loadSteps();
19500
19580
  }, [loadSteps]);
19501
- useEffect46(() => {
19581
+ useEffect48(() => {
19502
19582
  if (!mayStart || !tableId) return;
19503
19583
  let cancelled = false;
19504
19584
  void client.checklistTemplates({ about_table_id: tableId, limit: 50 }).then((answered) => {
@@ -19635,7 +19715,7 @@ function StepRow({
19635
19715
  const host = useRecordsUi();
19636
19716
  const [members, setMembers] = useState59(null);
19637
19717
  const unassigned = !step2.finished && !step2.assignee_user_id && Boolean(step2.role);
19638
- useEffect46(() => {
19718
+ useEffect48(() => {
19639
19719
  if (!unassigned || !onAssign || !host.members || members !== null) return;
19640
19720
  let alive = true;
19641
19721
  void host.members().then((roster) => {
@@ -19737,7 +19817,7 @@ function StepRow({
19737
19817
  );
19738
19818
  }
19739
19819
  function useMyChecklistSteps(limit = 25) {
19740
- const client = useRecordsClient39();
19820
+ const client = useRecordsClient40();
19741
19821
  const me = client.config.actor.user_id ?? null;
19742
19822
  const [steps, setSteps] = useState59([]);
19743
19823
  const [loading, setLoading] = useState59(true);
@@ -19770,7 +19850,7 @@ function useMyChecklistSteps(limit = 25) {
19770
19850
  setSteps(held);
19771
19851
  setLoading(false);
19772
19852
  }, [client, limit, me]);
19773
- useEffect46(() => {
19853
+ useEffect48(() => {
19774
19854
  void refresh();
19775
19855
  }, [refresh]);
19776
19856
  return { steps, loading, error, refresh };
@@ -19781,9 +19861,9 @@ function MyChecklistSteps({
19781
19861
  onSteps,
19782
19862
  actions
19783
19863
  }) {
19784
- const client = useRecordsClient39();
19864
+ const client = useRecordsClient40();
19785
19865
  const { steps: held, loading, error, refresh } = useMyChecklistSteps();
19786
- useEffect46(() => {
19866
+ useEffect48(() => {
19787
19867
  onSteps?.(held.map((s) => s.step_id));
19788
19868
  }, [held, onSteps]);
19789
19869
  const steps = onlyIds ? held.filter((s) => onlyIds.has(s.step_id)) : held;
@@ -19829,7 +19909,7 @@ function MyChecklistSteps({
19829
19909
  ] });
19830
19910
  }
19831
19911
  function ChecklistsPanel({ tableId, onOpenRecord, className }) {
19832
- const client = useRecordsClient39();
19912
+ const client = useRecordsClient40();
19833
19913
  const table = useTable11(tableId);
19834
19914
  const rights = useTableRights(table.data);
19835
19915
  const [templates, setTemplates] = useState59(null);
@@ -19851,7 +19931,7 @@ function ChecklistsPanel({ tableId, onOpenRecord, className }) {
19851
19931
  if (!r.ok) setRuns([]);
19852
19932
  else setRuns(r.data);
19853
19933
  }, [client, tableId]);
19854
- useEffect46(() => {
19934
+ useEffect48(() => {
19855
19935
  void load();
19856
19936
  }, [load]);
19857
19937
  if (templates === null) return /* @__PURE__ */ jsx69(Skeleton11, { className: cn39("h-40 w-full", className) });
@@ -19990,14 +20070,14 @@ function ChecklistTemplateEditor({
19990
20070
  onDone,
19991
20071
  className
19992
20072
  }) {
19993
- const client = useRecordsClient39();
20073
+ const client = useRecordsClient40();
19994
20074
  const [name, setName] = useState59("");
19995
20075
  const [rows, setRows] = useState59([{ ...EMPTY_ROW }]);
19996
20076
  const [refusal2, setRefusal] = useState59(null);
19997
20077
  const [error, setError] = useState59(null);
19998
20078
  const [busy, setBusy] = useState59(false);
19999
20079
  const [loading, setLoading] = useState59(Boolean(templateId));
20000
- useEffect46(() => {
20080
+ useEffect48(() => {
20001
20081
  if (!templateId) return;
20002
20082
  let cancelled = false;
20003
20083
  void client.checklistTemplateShape({ template_id: templateId }).then((answered) => {
@@ -20034,7 +20114,7 @@ function ChecklistTemplateEditor({
20034
20114
  }),
20035
20115
  [aboutTableId, name, rows]
20036
20116
  );
20037
- useEffect46(() => {
20117
+ useEffect48(() => {
20038
20118
  if (spec.steps.length === 0 || spec.name.length === 0) {
20039
20119
  setRefusal(null);
20040
20120
  return;
@@ -20281,7 +20361,7 @@ function ActionInbox({
20281
20361
  onOpenRecord,
20282
20362
  className
20283
20363
  }) {
20284
- const client = useRecordsClient40();
20364
+ const client = useRecordsClient41();
20285
20365
  const [showDecided, setShowDecided] = useState60(includeSettled);
20286
20366
  const [groupBy, setGroupBy] = useState60(defaultGroupBy);
20287
20367
  const [everyTable, setEveryTable] = useState60(false);
@@ -20316,7 +20396,7 @@ function ActionInbox({
20316
20396
  setError(null);
20317
20397
  setItems(result.data);
20318
20398
  }, [client, showDecided, view]);
20319
- useEffect47(() => {
20399
+ useEffect49(() => {
20320
20400
  void load();
20321
20401
  }, [load]);
20322
20402
  const narrowed = useMemo33(() => {
@@ -20331,10 +20411,10 @@ function ActionInbox({
20331
20411
  const groups = useMemo33(() => groupInbox(narrowed, groupBy), [narrowed, groupBy]);
20332
20412
  const shown3 = useMemo33(() => groups.flatMap((g) => g.items), [groups]);
20333
20413
  const elsewhere = (items?.length ?? 0) - narrowed.length;
20334
- useEffect47(() => {
20414
+ useEffect49(() => {
20335
20415
  if (cursor >= shown3.length) setCursor(Math.max(0, shown3.length - 1));
20336
20416
  }, [shown3.length, cursor]);
20337
- useEffect47(() => {
20417
+ useEffect49(() => {
20338
20418
  const el = listRef.current?.querySelector(`[data-row="${cursor}"]`);
20339
20419
  el?.scrollIntoView({ block: "nearest" });
20340
20420
  }, [cursor, shown3.length]);
@@ -20359,7 +20439,7 @@ function ActionInbox({
20359
20439
  const lastHold = useRef21(null);
20360
20440
  const holdSeq = useRef21(0);
20361
20441
  const [, tick] = useState60(0);
20362
- useEffect47(() => {
20442
+ useEffect49(() => {
20363
20443
  if (Object.keys(held).length === 0) return;
20364
20444
  const t = setInterval(() => tick((n) => n + 1), 250);
20365
20445
  return () => clearInterval(t);
@@ -20404,7 +20484,7 @@ function ActionInbox({
20404
20484
  });
20405
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 });
20406
20486
  }, []);
20407
- useEffect47(() => {
20487
+ useEffect49(() => {
20408
20488
  const flush = () => {
20409
20489
  for (const entry of [...holds2.current.values()]) entry.commit();
20410
20490
  };
@@ -20415,7 +20495,7 @@ function ActionInbox({
20415
20495
  };
20416
20496
  }, []);
20417
20497
  const resumed = useRef21(false);
20418
- useEffect47(() => {
20498
+ useEffect49(() => {
20419
20499
  if (resumed.current || items === null || view !== "inbox") return;
20420
20500
  resumed.current = true;
20421
20501
  const kept = readHolds();
@@ -21018,17 +21098,17 @@ function ActionInbox({
21018
21098
  }
21019
21099
 
21020
21100
  // src/HistoryPanel.tsx
21021
- 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";
21022
21102
  import {
21023
21103
  useFields as useFields15,
21024
21104
  useRecordChangeRevision,
21025
- useRecordsClient as useRecordsClient41,
21105
+ useRecordsClient as useRecordsClient42,
21026
21106
  useTable as useTable12
21027
21107
  } from "@ai-matrx/records/react";
21028
21108
  import { Badge as Badge16, Button as Button52, Skeleton as Skeleton13, cn as cn41 } from "@ai-matrx/design-system";
21029
21109
  import { jsx as jsx71, jsxs as jsxs63 } from "react/jsx-runtime";
21030
21110
  function HistoryPanel({ tableId, recordId, onAskAboutField, className }) {
21031
- const client = useRecordsClient41();
21111
+ const client = useRecordsClient42();
21032
21112
  const table = useTable12(tableId);
21033
21113
  const fields = useFields15(tableId);
21034
21114
  const rights = useTableRights(table.data);
@@ -21048,7 +21128,7 @@ function HistoryPanel({ tableId, recordId, onAskAboutField, className }) {
21048
21128
  setError(null);
21049
21129
  setEntries(answered.data);
21050
21130
  }, [client, recordId, changed]);
21051
- useEffect48(() => {
21131
+ useEffect50(() => {
21052
21132
  void load();
21053
21133
  }, [load]);
21054
21134
  if (error) return /* @__PURE__ */ jsx71(RefusalNotice, { error, className });
@@ -21329,16 +21409,16 @@ function say(value, field2) {
21329
21409
  }
21330
21410
 
21331
21411
  // src/CommentThread.tsx
21332
- 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";
21333
21413
  import {
21334
21414
  useFields as useFields16,
21335
- useRecordsClient as useRecordsClient42,
21415
+ useRecordsClient as useRecordsClient43,
21336
21416
  useTable as useTable13
21337
21417
  } from "@ai-matrx/records/react";
21338
21418
  import { Badge as Badge17, Button as Button53, Skeleton as Skeleton14, Textarea, cn as cn42 } from "@ai-matrx/design-system";
21339
21419
  import { jsx as jsx72, jsxs as jsxs64 } from "react/jsx-runtime";
21340
21420
  function CommentThread({ tableId, recordId, fieldKey, className }) {
21341
- const client = useRecordsClient42();
21421
+ const client = useRecordsClient43();
21342
21422
  const table = useTable13(tableId);
21343
21423
  const fields = useFields16(tableId);
21344
21424
  const host = useRecordsUi();
@@ -21366,10 +21446,10 @@ function CommentThread({ tableId, recordId, fieldKey, className }) {
21366
21446
  mayResolve: answered.data.may_resolve
21367
21447
  });
21368
21448
  }, [client, recordId, showResolved]);
21369
- useEffect49(() => {
21449
+ useEffect51(() => {
21370
21450
  void load();
21371
21451
  }, [load]);
21372
- useEffect49(() => {
21452
+ useEffect51(() => {
21373
21453
  let alive = true;
21374
21454
  if (!host.members) return;
21375
21455
  void host.members().then((roster) => {
@@ -21572,10 +21652,10 @@ function Line({
21572
21652
  }
21573
21653
 
21574
21654
  // src/FieldHistoryPanel.tsx
21575
- 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";
21576
21656
  import {
21577
21657
  useFields as useFields17,
21578
- useRecordsClient as useRecordsClient43,
21658
+ useRecordsClient as useRecordsClient44,
21579
21659
  useTable as useTable14
21580
21660
  } from "@ai-matrx/records/react";
21581
21661
  import { Badge as Badge18, Button as Button54, Skeleton as Skeleton15, cn as cn43 } from "@ai-matrx/design-system";
@@ -21588,7 +21668,7 @@ function FieldHistoryPanel({
21588
21668
  onOpenRecord,
21589
21669
  className
21590
21670
  }) {
21591
- const client = useRecordsClient43();
21671
+ const client = useRecordsClient44();
21592
21672
  const table = useTable14(tableId);
21593
21673
  const fields = useFields17(tableId);
21594
21674
  const rights = useTableRights(table.data);
@@ -21607,7 +21687,7 @@ function FieldHistoryPanel({
21607
21687
  setError(null);
21608
21688
  setRows(answered.data);
21609
21689
  }, [client, tableId, fieldKey, recordId]);
21610
- useEffect50(() => {
21690
+ useEffect52(() => {
21611
21691
  void load();
21612
21692
  }, [load]);
21613
21693
  const label = (fields.data ?? []).find((f) => f.key === fieldKey)?.label || humanize(fieldKey);
@@ -21819,20 +21899,20 @@ function submissionStamp(args) {
21819
21899
  }
21820
21900
 
21821
21901
  // src/PortalBuilder.tsx
21822
- import { useCallback as useCallback34, useEffect as useEffect57, useMemo as useMemo37, useState as useState70 } from "react";
21823
- 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";
21824
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";
21825
21905
 
21826
21906
  // src/TablesHome.tsx
21827
- import { useCallback as useCallback33, useEffect as useEffect56, useState as useState69 } from "react";
21828
- 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";
21829
21909
  import { withTableFacts } from "@ai-matrx/records/core";
21830
21910
  import { withTablePlacement } from "@ai-matrx/records";
21831
21911
  import { BasicInput as BasicInput20, Button as Button59, Skeleton as Skeleton19, cn as cn47 } from "@ai-matrx/design-system";
21832
21912
 
21833
21913
  // src/ExampleTables.tsx
21834
- import { useEffect as useEffect51, useState as useState64 } from "react";
21835
- 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";
21836
21916
  import { loadUseCase, summarize as summarize2, useCaseIds } from "@ai-matrx/records/use-cases";
21837
21917
  import { Button as Button55, Skeleton as Skeleton16, cn as cn44 } from "@ai-matrx/design-system";
21838
21918
  import { jsx as jsx74, jsxs as jsxs66 } from "react/jsx-runtime";
@@ -21841,12 +21921,12 @@ function ExampleTables({
21841
21921
  onClose,
21842
21922
  className
21843
21923
  }) {
21844
- const client = useRecordsClient44();
21924
+ const client = useRecordsClient45();
21845
21925
  const [summaries, setSummaries] = useState64(null);
21846
21926
  const [busy, setBusy] = useState64(null);
21847
21927
  const [error, setError] = useState64(null);
21848
21928
  const [built, setBuilt] = useState64(null);
21849
- useEffect51(() => {
21929
+ useEffect53(() => {
21850
21930
  let alive = true;
21851
21931
  void Promise.all(useCaseIds().map(async (id) => summarize2(await loadUseCase(id)))).then((rows) => {
21852
21932
  if (alive) setSummaries(rows);
@@ -21921,23 +22001,23 @@ function ExampleTables({
21921
22001
  }
21922
22002
 
21923
22003
  // src/BookingSlots.tsx
21924
- import { useCallback as useCallback32, useEffect as useEffect54, useMemo as useMemo36, useState as useState67 } from "react";
21925
- 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";
21926
22006
  import { bookingPath as bookingPath2 } from "@ai-matrx/records";
21927
22007
  import { Badge as Badge19, Button as Button57, Skeleton as Skeleton18, cn as cn46 } from "@ai-matrx/design-system";
21928
22008
 
21929
22009
  // src/BookingBuilder.tsx
21930
- import { useCallback as useCallback31, useEffect as useEffect53, useMemo as useMemo35, useState as useState66 } from "react";
21931
- 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";
21932
22012
 
21933
22013
  // src/publish-gate.ts
21934
- import { useEffect as useEffect52, useState as useState65 } from "react";
21935
- 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";
21936
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.";
21937
22017
  function usePublishGate() {
21938
- const client = useRecordsClient45();
22018
+ const client = useRecordsClient46();
21939
22019
  const [storeOpen, setStoreOpen] = useState65(null);
21940
- useEffect52(() => {
22020
+ useEffect54(() => {
21941
22021
  let alive = true;
21942
22022
  void (async () => {
21943
22023
  const answered = await client.storeIsOpen();
@@ -22050,7 +22130,7 @@ function draftWindows(availability) {
22050
22130
  });
22051
22131
  }
22052
22132
  function BookingBuilder({ tableId, bookingId, onSaved, onClose, className }) {
22053
- const client = useRecordsClient46();
22133
+ const client = useRecordsClient47();
22054
22134
  const publishGate = usePublishGate();
22055
22135
  const host = useRecordsUi();
22056
22136
  const table = useTable15(tableId);
@@ -22095,19 +22175,19 @@ function BookingBuilder({ tableId, bookingId, onSaved, onClose, className }) {
22095
22175
  setLoaded(true);
22096
22176
  if (mine) setFormId(mine.form_id);
22097
22177
  }, [client, tableId, bookingId]);
22098
- useEffect53(() => {
22178
+ useEffect55(() => {
22099
22179
  void load();
22100
22180
  }, [load]);
22101
- useEffect53(() => {
22181
+ useEffect55(() => {
22102
22182
  if (title !== "" || !table.data) return;
22103
- setTitle(existing?.title ?? `Book a ${minutes}-minute ${table.data.name} appointment`);
22183
+ setTitle(existing?.title ?? `Book a ${minutes}-minute ${singularNoun(table.data, "appointment")}`);
22104
22184
  }, [table.data, existing]);
22105
- useEffect53(() => {
22185
+ useEffect55(() => {
22106
22186
  if (!existing) return;
22107
22187
  setMinutes(existing.slot_minutes);
22108
22188
  if (existing.timezone && existing.timezone !== "UTC") setTimezone(existing.timezone);
22109
22189
  }, [existing]);
22110
- useEffect53(() => {
22190
+ useEffect55(() => {
22111
22191
  if (!offer) return;
22112
22192
  setWindows(draftWindows(offer));
22113
22193
  setMinutes(offer.slot_minutes);
@@ -22149,7 +22229,7 @@ function BookingBuilder({ tableId, bookingId, onSaved, onClose, className }) {
22149
22229
  setWhoAdded(true);
22150
22230
  }
22151
22231
  const [whoAdded, setWhoAdded] = useState66(false);
22152
- useEffect53(() => {
22232
+ useEffect55(() => {
22153
22233
  if (!whoAdded) return;
22154
22234
  const who = askable.filter((f) => isWhoField(f)).map((f) => f.key);
22155
22235
  if (who.length === 0) return;
@@ -22423,7 +22503,7 @@ function bookingSuggestion(tableName2) {
22423
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.";
22424
22504
  var STATE_WORDS = BOOKING_PAGE_STATE_LABEL;
22425
22505
  function BookingSlots({ tableId, activeBookingId, className }) {
22426
- const client = useRecordsClient47();
22506
+ const client = useRecordsClient48();
22427
22507
  const host = useRecordsUi();
22428
22508
  const [pages, setPages] = useState67(null);
22429
22509
  const [error, setError] = useState67(null);
@@ -22431,6 +22511,7 @@ function BookingSlots({ tableId, activeBookingId, className }) {
22431
22511
  const [copied, setCopied] = useState67(null);
22432
22512
  const [shown3, setShown] = useState67(null);
22433
22513
  const [building, setBuilding] = useState67(false);
22514
+ const [changing, setChanging] = useState67(null);
22434
22515
  const load = useCallback32(async () => {
22435
22516
  const answered = await client.bookings(tableId ? { table_id: tableId } : {});
22436
22517
  if (!answered.ok) {
@@ -22441,7 +22522,7 @@ function BookingSlots({ tableId, activeBookingId, className }) {
22441
22522
  setError(null);
22442
22523
  setPages(answered.data);
22443
22524
  }, [client, tableId]);
22444
- useEffect54(() => {
22525
+ useEffect56(() => {
22445
22526
  void load();
22446
22527
  }, [load]);
22447
22528
  const subjectIds = useMemo36(
@@ -22496,6 +22577,17 @@ function BookingSlots({ tableId, activeBookingId, className }) {
22496
22577
  ] }),
22497
22578
  error ? /* @__PURE__ */ jsx77(RefusalNotice, { error }) : null,
22498
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,
22499
22591
  building && tableId ? /* @__PURE__ */ jsx77(
22500
22592
  BookingBuilder,
22501
22593
  {
@@ -22572,6 +22664,15 @@ function BookingSlots({ tableId, activeBookingId, className }) {
22572
22664
  /* @__PURE__ */ jsx77("p", { className: "mt-1 text-xs text-muted-foreground", children: nextInWords(page) }),
22573
22665
  /* @__PURE__ */ jsxs69("div", { className: "mt-2 flex flex-wrap items-center gap-1.5", children: [
22574
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,
22575
22676
  mayOpen ? /* @__PURE__ */ jsx77(
22576
22677
  Button57,
22577
22678
  {
@@ -22633,13 +22734,13 @@ import {
22633
22734
  } from "@ai-matrx/records/core";
22634
22735
 
22635
22736
  // src/WhereItLives.tsx
22636
- import { useEffect as useEffect55, useState as useState68 } from "react";
22737
+ import { useEffect as useEffect57, useState as useState68 } from "react";
22637
22738
  import { moveConsequence } from "@ai-matrx/records";
22638
- import { useRecordsClient as useRecordsClient48 } from "@ai-matrx/records/react";
22739
+ import { useRecordsClient as useRecordsClient49 } from "@ai-matrx/records/react";
22639
22740
  import { Button as Button58, ErrorBox as ErrorBox2, Popover as Popover6, PopoverContent as PopoverContent6, PopoverTrigger as PopoverTrigger6 } from "@ai-matrx/design-system";
22640
22741
  import { jsx as jsx78, jsxs as jsxs70 } from "react/jsx-runtime";
22641
22742
  function WhereItLives({ tableId, knownOrganizationName, onMoved, variant = "header" }) {
22642
- const client = useRecordsClient48();
22743
+ const client = useRecordsClient49();
22643
22744
  const host = useRecordsUi();
22644
22745
  const [answer, setAnswer] = useState68(null);
22645
22746
  const [attempt, setAttempt] = useState68(0);
@@ -22648,7 +22749,7 @@ function WhereItLives({ tableId, knownOrganizationName, onMoved, variant = "head
22648
22749
  const [choosing, setChoosing] = useState68(null);
22649
22750
  const [moving, setMoving] = useState68(false);
22650
22751
  const [said, setSaid] = useState68(null);
22651
- useEffect55(() => {
22752
+ useEffect57(() => {
22652
22753
  if (!armed) return;
22653
22754
  let alive = true;
22654
22755
  setAnswer(null);
@@ -22894,11 +22995,11 @@ function visibilityLaneFor(table) {
22894
22995
  return "organization";
22895
22996
  }
22896
22997
  function TablesHome({ onOpenTable, organizationName, makingOnly = false, askedBy, className }) {
22897
- const client = useRecordsClient49();
22998
+ const client = useRecordsClient50();
22898
22999
  const tables = useTables3();
22899
23000
  const me = client.config.actor.user_id ?? null;
22900
23001
  const [facts, setFacts] = useState69({ phase: "reading" });
22901
- useEffect56(() => {
23002
+ useEffect58(() => {
22902
23003
  let alive = true;
22903
23004
  void client.tableFacts().then((answered) => {
22904
23005
  if (!alive) return;
@@ -22916,7 +23017,7 @@ function TablesHome({ onOpenTable, organizationName, makingOnly = false, askedBy
22916
23017
  const keptCount = listed.filter((t) => laneFor(t) === "app").length;
22917
23018
  const [askedName, setAskedName] = useState69(null);
22918
23019
  const firstTableId = listed[0]?.id ?? null;
22919
- useEffect56(() => {
23020
+ useEffect58(() => {
22920
23021
  if (organizationName || !firstTableId) return;
22921
23022
  let alive = true;
22922
23023
  void client.tableHome({ table_id: firstTableId }).then((answered) => {
@@ -22937,15 +23038,15 @@ function TablesHome({ onOpenTable, organizationName, makingOnly = false, askedBy
22937
23038
  const [examples, setExamples] = useState69(false);
22938
23039
  const createAsked = askedBy?.create ?? 0;
22939
23040
  const examplesAsked = askedBy?.examples ?? 0;
22940
- useEffect56(() => {
23041
+ useEffect58(() => {
22941
23042
  if (createAsked > 0) setCreating(true);
22942
23043
  }, [createAsked]);
22943
- useEffect56(() => {
23044
+ useEffect58(() => {
22944
23045
  if (examplesAsked > 0) setExamples(true);
22945
23046
  }, [examplesAsked]);
22946
23047
  const hostButtons = askedBy !== void 0;
22947
23048
  const [boards, setBoards] = useState69(null);
22948
- useEffect56(() => {
23049
+ useEffect58(() => {
22949
23050
  if (makingOnly) return;
22950
23051
  let cancelled = false;
22951
23052
  void client.dashboards({}).then((result) => {
@@ -23124,7 +23225,7 @@ function TablesHome({ onOpenTable, organizationName, makingOnly = false, askedBy
23124
23225
  import { Fragment as Fragment33, jsx as jsx80, jsxs as jsxs72 } from "react/jsx-runtime";
23125
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.";
23126
23227
  function PortalBuilder({ tableId, portalId, onSaved, onClose, className }) {
23127
- const client = useRecordsClient50();
23228
+ const client = useRecordsClient51();
23128
23229
  const tables = useTables4();
23129
23230
  const [title, setTitle] = useState70("");
23130
23231
  const [clientTableId, setClientTableId] = useState70(null);
@@ -23151,7 +23252,7 @@ function PortalBuilder({ tableId, portalId, onSaved, onClose, className }) {
23151
23252
  },
23152
23253
  [client, fieldsByTable]
23153
23254
  );
23154
- useEffect57(() => {
23255
+ useEffect59(() => {
23155
23256
  if (!portalId) return;
23156
23257
  void (async () => {
23157
23258
  const answered = await client.portalCard({ portal_id: portalId });
@@ -23165,7 +23266,7 @@ function PortalBuilder({ tableId, portalId, onSaved, onClose, className }) {
23165
23266
  setClientTableId(answered.data.client_table_id);
23166
23267
  })();
23167
23268
  }, [client, portalId]);
23168
- useEffect57(() => {
23269
+ useEffect59(() => {
23169
23270
  if (!tableId) return;
23170
23271
  setExposures(
23171
23272
  (prev) => prev[tableId] ? prev : {
@@ -23178,7 +23279,7 @@ function PortalBuilder({ tableId, portalId, onSaved, onClose, className }) {
23178
23279
  const cameFromPeople = Boolean(
23179
23280
  tableId && (fieldsByTable[tableId] ?? []).some((f) => editorKindFor(f) === "email")
23180
23281
  );
23181
- useEffect57(() => {
23282
+ useEffect59(() => {
23182
23283
  if (!tableId || portalId || clientTableId !== null || !cameFromPeople) return;
23183
23284
  setClientTableId(tableId);
23184
23285
  setExposures((prev) => {
@@ -23426,8 +23527,8 @@ function PortalBuilder({ tableId, portalId, onSaved, onClose, className }) {
23426
23527
  }
23427
23528
 
23428
23529
  // src/PortalsPanel.tsx
23429
- import { useCallback as useCallback35, useEffect as useEffect59, useMemo as useMemo39, useState as useState72 } from "react";
23430
- 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";
23431
23532
  import {
23432
23533
  portalArchiveConsequence,
23433
23534
  portalConfirmLine as portalConfirmLine2,
@@ -23437,8 +23538,8 @@ import {
23437
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";
23438
23539
 
23439
23540
  // src/PortalLookEditor.tsx
23440
- import { useEffect as useEffect58, useMemo as useMemo38, useState as useState71 } from "react";
23441
- 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";
23442
23543
  import { BasicInput as BasicInput22, Button as Button61, cn as cn49 } from "@ai-matrx/design-system";
23443
23544
  import { STYLE_COLOR_LABELS as STYLE_COLOR_LABELS3, SWATCH_CLASS as SWATCH_CLASS2 } from "@ai-matrx/design-system/data-table";
23444
23545
  import { jsx as jsx81, jsxs as jsxs73 } from "react/jsx-runtime";
@@ -23466,7 +23567,7 @@ function candidateRows(card, available) {
23466
23567
  return rows;
23467
23568
  }
23468
23569
  function PortalLookEditor({ card, onSaved, className }) {
23469
- const client = useRecordsClient51();
23570
+ const client = useRecordsClient52();
23470
23571
  const stored = card.config?.style ?? {};
23471
23572
  const [name, setName] = useState71(stored.display_name ?? "");
23472
23573
  const [welcome, setWelcome] = useState71(stored.welcome ?? "");
@@ -23479,7 +23580,7 @@ function PortalLookEditor({ card, onSaved, className }) {
23479
23580
  const [said, setSaid] = useState71(null);
23480
23581
  const [formsError, setFormsError] = useState71(null);
23481
23582
  const [formsUnread, setFormsUnread] = useState71(false);
23482
- useEffect58(() => {
23583
+ useEffect60(() => {
23483
23584
  let cancelled = false;
23484
23585
  void (async () => {
23485
23586
  try {
@@ -23761,13 +23862,13 @@ function stateWords(person) {
23761
23862
  }
23762
23863
  var PORTAL_SUGGESTION = "Let each of my customers sign in and see their own jobs and invoices, and nothing else.";
23763
23864
  function PortalsPanel({ tableId, activePortalId, className }) {
23764
- const client = useRecordsClient52();
23865
+ const client = useRecordsClient53();
23765
23866
  const host = useRecordsUi();
23766
23867
  const [portals, setPortals] = useState72(null);
23767
23868
  const [exposures, setExposures] = useState72([]);
23768
23869
  const [listError, setListError] = useState72(null);
23769
23870
  const [openId, setOpenId] = useState72(activePortalId ?? null);
23770
- useEffect59(() => {
23871
+ useEffect61(() => {
23771
23872
  if (activePortalId) setOpenId(activePortalId);
23772
23873
  }, [activePortalId]);
23773
23874
  const [building, setBuilding] = useState72(false);
@@ -23785,7 +23886,7 @@ function PortalsPanel({ tableId, activePortalId, className }) {
23785
23886
  setPortals(answered.data);
23786
23887
  setExposures(mapped.ok ? mapped.data : []);
23787
23888
  }, [client]);
23788
- useEffect59(() => {
23889
+ useEffect61(() => {
23789
23890
  void load();
23790
23891
  }, [load]);
23791
23892
  if (portals === null) return /* @__PURE__ */ jsx82(Skeleton21, { className: cn50("h-32 w-full", className) });
@@ -23941,7 +24042,7 @@ function ArchivePortalControl({
23941
24042
  portal,
23942
24043
  onArchived
23943
24044
  }) {
23944
- const client = useRecordsClient52();
24045
+ const client = useRecordsClient53();
23945
24046
  const [asking, setAsking] = useState72(false);
23946
24047
  const [typed, setTyped] = useState72("");
23947
24048
  const [busy, setBusy] = useState72(false);
@@ -24048,7 +24149,7 @@ function PortalDetail({
24048
24149
  origin,
24049
24150
  onChanged
24050
24151
  }) {
24051
- const client = useRecordsClient52();
24152
+ const client = useRecordsClient53();
24052
24153
  const [card, setCard] = useState72(null);
24053
24154
  const [error, setError] = useState72(null);
24054
24155
  const load = useCallback35(async () => {
@@ -24061,7 +24162,7 @@ function PortalDetail({
24061
24162
  setError(null);
24062
24163
  setCard(answered.data);
24063
24164
  }, [client, portalId]);
24064
- useEffect59(() => {
24165
+ useEffect61(() => {
24065
24166
  void load();
24066
24167
  }, [load]);
24067
24168
  const revoke = useCallback35(
@@ -24269,7 +24370,7 @@ function Preview({
24269
24370
  const [which, setWhich] = useState72(first?.table_id ?? null);
24270
24371
  const [rows, setRows] = useState72(null);
24271
24372
  const [error, setError] = useState72(null);
24272
- useEffect59(() => {
24373
+ useEffect61(() => {
24273
24374
  if (!which) return;
24274
24375
  let cancelled = false;
24275
24376
  setRows(null);
@@ -24306,7 +24407,7 @@ function Preview({
24306
24407
  ] });
24307
24408
  }
24308
24409
  function Invite({ card, onInvited }) {
24309
- const client = useRecordsClient52();
24410
+ const client = useRecordsClient53();
24310
24411
  const [rows, setRows] = useState72(null);
24311
24412
  const [clientTable, setClientTable] = useState72(null);
24312
24413
  const [search, setSearch] = useState72("");
@@ -24315,7 +24416,7 @@ function Invite({ card, onInvited }) {
24315
24416
  const [busy, setBusy] = useState72(false);
24316
24417
  const [said, setSaid] = useState72(null);
24317
24418
  const [error, setError] = useState72(null);
24318
- useEffect59(() => {
24419
+ useEffect61(() => {
24319
24420
  let cancelled = false;
24320
24421
  void client.list({ table_id: card.client_table_id, limit: 200 }).then((answered) => {
24321
24422
  if (cancelled) return;
@@ -24417,8 +24518,9 @@ function Invite({ card, onInvited }) {
24417
24518
  }
24418
24519
 
24419
24520
  // src/DigestScheduler.tsx
24420
- import { useCallback as useCallback36, useEffect as useEffect60, useMemo as useMemo40, useState as useState73 } from "react";
24421
- 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";
24422
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";
24423
24525
 
24424
24526
  // src/scheduleWords.ts
@@ -24461,6 +24563,12 @@ var CHANNEL_WORDS = {
24461
24563
  email: "by email \u2014 only if an address is on their account",
24462
24564
  sms: "by text \u2014 only if a number is on their account"
24463
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
+ }
24464
24572
  function DigestScheduler({
24465
24573
  tableId,
24466
24574
  savedViewId,
@@ -24468,27 +24576,42 @@ function DigestScheduler({
24468
24576
  filters,
24469
24577
  onScheduled,
24470
24578
  onClose,
24471
- className
24579
+ className,
24580
+ existing
24472
24581
  }) {
24473
- const client = useRecordsClient53();
24582
+ const client = useRecordsClient54();
24474
24583
  const host = useRecordsUi();
24475
24584
  const [views, setViews] = useState73(null);
24476
24585
  const [cadences, setCadences] = useState73([]);
24477
24586
  const [members, setMembers] = useState73(null);
24478
24587
  const [error, setError] = useState73(null);
24479
- const [viewId, setViewId] = useState73(savedViewId ?? "");
24480
- const [name, setName] = useState73(subjectName?.trim() ? `${subjectName.trim()} summary` : "");
24481
- const [cadence, setCadence] = useState73("weekly");
24482
- const [weekday, setWeekday] = useState73("monday");
24483
- const [time, setTime] = useState73("08:00");
24484
- 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
+ });
24485
24604
  const table = useTable16(tableId);
24486
24605
  const tableName2 = table.data?.name?.trim() || null;
24487
- const [channel, setChannel] = useState73("in_app");
24488
- const [quiet, setQuiet] = useState73(false);
24489
- const [quietFrom, setQuietFrom] = useState73("22:00");
24490
- const [quietTo, setQuietTo] = useState73("07:00");
24491
- 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
+ );
24492
24615
  const [saving, setSaving] = useState73(false);
24493
24616
  const [outcomes, setOutcomes] = useState73(null);
24494
24617
  const [preview, setPreview] = useState73(null);
@@ -24512,7 +24635,7 @@ function DigestScheduler({
24512
24635
  setMembers([]);
24513
24636
  }
24514
24637
  }, [client, tableId, host]);
24515
- useEffect60(() => {
24638
+ useEffect62(() => {
24516
24639
  void load();
24517
24640
  }, [load]);
24518
24641
  const schedule = useMemo40(() => {
@@ -24559,7 +24682,8 @@ function DigestScheduler({
24559
24682
  schedule,
24560
24683
  channel,
24561
24684
  quiet_hours: quietHours,
24562
- ...userId === "" ? {} : { recipient_user_id: userId }
24685
+ ...userId === "" ? {} : { recipient_user_id: userId },
24686
+ ...existing ? { rule_id: existing.rule_id } : {}
24563
24687
  }
24564
24688
  });
24565
24689
  if (written.ok) done.push({ userId, who: label, ruleId: written.data });
@@ -24582,9 +24706,9 @@ function DigestScheduler({
24582
24706
  if (views === null && !error) return /* @__PURE__ */ jsx83(Skeleton22, { className: cn51("h-56 w-full", className) });
24583
24707
  return /* @__PURE__ */ jsxs75("section", { className: cn51("@container flex flex-col gap-3", className), children: [
24584
24708
  /* @__PURE__ */ jsxs75("header", { className: "flex items-center gap-2", children: [
24585
- /* @__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" }),
24586
24710
  /* @__PURE__ */ jsx83("div", { className: "flex-1" }),
24587
- /* @__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" }),
24588
24712
  onClose ? /* @__PURE__ */ jsx83(Button63, { size: "sm", variant: "ghost", onClick: onClose, children: "Close" }) : null
24589
24713
  ] }),
24590
24714
  error ? /* @__PURE__ */ jsx83(RefusalNotice, { error }) : null,
@@ -24766,14 +24890,14 @@ function DigestScheduler({
24766
24890
  }
24767
24891
 
24768
24892
  // src/SubscriptionsPanel.tsx
24769
- import { useCallback as useCallback38, useEffect as useEffect62, useState as useState75 } from "react";
24770
- import { useRecordsClient as useRecordsClient55 } from "@ai-matrx/records/react";
24771
- 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";
24772
24896
  import { Badge as Badge21, Button as Button65, Skeleton as Skeleton24, Switch as Switch2, cn as cn53 } from "@ai-matrx/design-system";
24773
24897
 
24774
24898
  // src/WebhooksPanel.tsx
24775
- import { useCallback as useCallback37, useEffect as useEffect61, useState as useState74 } from "react";
24776
- 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";
24777
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";
24778
24902
  import { jsx as jsx84, jsxs as jsxs76 } from "react/jsx-runtime";
24779
24903
  var WEBHOOK_EVENT_LABEL = {
@@ -24793,7 +24917,7 @@ function health(hook) {
24793
24917
  return "Nothing has changed since it was set up, so nothing has been sent yet.";
24794
24918
  }
24795
24919
  function WebhooksPanel({ tableId, className }) {
24796
- const client = useRecordsClient54();
24920
+ const client = useRecordsClient55();
24797
24921
  const table = useTable17(tableId);
24798
24922
  const rights = useTableRights(table.data);
24799
24923
  const [hooks, setHooks] = useState74(null);
@@ -24805,17 +24929,20 @@ function WebhooksPanel({ tableId, className }) {
24805
24929
  const [busy, setBusy] = useState74(false);
24806
24930
  const [declared2, setDeclared] = useState74(null);
24807
24931
  const [stopping, setStopping] = useState74(null);
24932
+ const [readRefused, setReadRefused] = useState74(null);
24808
24933
  const load = useCallback37(async () => {
24809
24934
  const answered = await client.tableWebhooks({ table_id: tableId });
24810
24935
  if (!answered.ok) {
24936
+ setReadRefused(answered.error);
24811
24937
  setError(answered.error);
24812
24938
  setHooks([]);
24813
24939
  return;
24814
24940
  }
24941
+ setReadRefused(null);
24815
24942
  setError(null);
24816
24943
  setHooks(answered.data ?? []);
24817
24944
  }, [client, tableId]);
24818
- useEffect61(() => {
24945
+ useEffect63(() => {
24819
24946
  void load();
24820
24947
  }, [load]);
24821
24948
  const declare2 = async () => {
@@ -24840,6 +24967,17 @@ function WebhooksPanel({ tableId, className }) {
24840
24967
  await load();
24841
24968
  };
24842
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
+ }
24843
24981
  const mayChange = rights.structure;
24844
24982
  const live = hooks.filter((h) => h.is_active);
24845
24983
  return /* @__PURE__ */ jsxs76("section", { "data-records-webhooks": "", className: cn52("flex flex-col gap-2 border-t pt-3", className), children: [
@@ -24974,12 +25112,13 @@ function nextSummaryAt(subscription, now) {
24974
25112
  var CHANNEL_WORDS2 = SUBSCRIPTION_CHANNEL_LABEL;
24975
25113
  var DIGEST_SUGGESTION = "Email me a summary of this every Monday at 8 in the morning.";
24976
25114
  function SubscriptionsPanel({ tableId, activeRuleId, className }) {
24977
- const client = useRecordsClient55();
25115
+ const client = useRecordsClient56();
24978
25116
  const [rows, setRows] = useState75(null);
24979
25117
  const [error, setError] = useState75(null);
24980
25118
  const [busy, setBusy] = useState75(null);
24981
25119
  const [preview, setPreview] = useState75(null);
24982
25120
  const [scheduling, setScheduling] = useState75(false);
25121
+ const [changing, setChanging] = useState75(null);
24983
25122
  const host = useRecordsUi();
24984
25123
  const load = useCallback38(async () => {
24985
25124
  const answered = await client.subscriptions({ table_id: tableId });
@@ -24991,7 +25130,7 @@ function SubscriptionsPanel({ tableId, activeRuleId, className }) {
24991
25130
  setError(null);
24992
25131
  setRows(answered.data);
24993
25132
  }, [client, tableId]);
24994
- useEffect62(() => {
25133
+ useEffect64(() => {
24995
25134
  void load();
24996
25135
  }, [load]);
24997
25136
  const flip = useCallback38(
@@ -25051,6 +25190,18 @@ function SubscriptionsPanel({ tableId, activeRuleId, className }) {
25051
25190
  onClose: () => setScheduling(false)
25052
25191
  }
25053
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,
25054
25205
  rows.length === 0 && !scheduling ? /* @__PURE__ */ jsx85(
25055
25206
  BuildOrAsk,
25056
25207
  {
@@ -25104,7 +25255,7 @@ function SubscriptionsPanel({ tableId, activeRuleId, className }) {
25104
25255
  "Last told you ",
25105
25256
  new Date(subscription.last_sent_at).toLocaleString()
25106
25257
  ] }) : /* @__PURE__ */ jsx85("span", { children: "It has not told you anything yet." }),
25107
- hasQuietHours(subscription.quiet_hours) ? /* @__PURE__ */ jsxs77("span", { children: [
25258
+ hasQuietHours2(subscription.quiet_hours) ? /* @__PURE__ */ jsxs77("span", { children: [
25108
25259
  "Not between ",
25109
25260
  subscription.quiet_hours.start,
25110
25261
  " and ",
@@ -25120,7 +25271,8 @@ function SubscriptionsPanel({ tableId, activeRuleId, className }) {
25120
25271
  onClick: () => void showOne(subscription),
25121
25272
  children: "Send me a preview now"
25122
25273
  }
25123
- )
25274
+ ),
25275
+ subscription.mine && subscription.cadence !== "instant" ? /* @__PURE__ */ jsx85(Button65, { size: "sm", variant: "ghost", onClick: () => setChanging(subscription), children: "Change it" }) : null
25124
25276
  ] }),
25125
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: [
25126
25278
  /* @__PURE__ */ jsx85("p", { className: "font-medium", children: preview.subject }),
@@ -25167,8 +25319,8 @@ function SubscriptionsPanel({ tableId, activeRuleId, className }) {
25167
25319
  }
25168
25320
 
25169
25321
  // src/FormBuilder.tsx
25170
- import { useCallback as useCallback41, useEffect as useEffect65, useMemo as useMemo42, useState as useState78 } from "react";
25171
- 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";
25172
25324
  import { publicFormPath } from "@ai-matrx/records";
25173
25325
  import {
25174
25326
  BasicInput as BasicInput26,
@@ -25181,7 +25333,7 @@ import {
25181
25333
  } from "@ai-matrx/design-system";
25182
25334
 
25183
25335
  // src/FormRunner.tsx
25184
- 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";
25185
25337
  import { useFields as useFields19, useOptionalRecordsClient as useOptionalRecordsClient8 } from "@ai-matrx/records/react";
25186
25338
  import { Button as Button66, Progress, Skeleton as Skeleton25, cn as cn54 } from "@ai-matrx/design-system";
25187
25339
  import { Fragment as Fragment36, jsx as jsx86, jsxs as jsxs78 } from "react/jsx-runtime";
@@ -25297,7 +25449,7 @@ function FormStage({
25297
25449
  };
25298
25450
  });
25299
25451
  }, [fields, form.questions]);
25300
- useEffect63(() => {
25452
+ useEffect65(() => {
25301
25453
  if (!whichAsked) return;
25302
25454
  if (!questions.some((q) => q.showIf)) return;
25303
25455
  let cancelled = false;
@@ -25341,7 +25493,7 @@ function FormStage({
25341
25493
  }, [whichAsked, questions, answers]);
25342
25494
  const live = questions.filter((q) => !hidden[q.key]);
25343
25495
  const told = useRef24(answers);
25344
- useEffect63(() => {
25496
+ useEffect65(() => {
25345
25497
  if (told.current === answers) return;
25346
25498
  told.current = answers;
25347
25499
  onAnswersChange?.(answers);
@@ -25352,7 +25504,7 @@ function FormStage({
25352
25504
  return v === void 0 || v === null || v === "";
25353
25505
  })?.key ?? null : null
25354
25506
  );
25355
- useEffect63(() => {
25507
+ useEffect65(() => {
25356
25508
  const key = resumeAt.current;
25357
25509
  if (!key) return;
25358
25510
  const i = live.findIndex((q) => q.key === key);
@@ -25418,7 +25570,7 @@ function FormStage({
25418
25570
  if (event.shiftKey) retreat();
25419
25571
  else advance();
25420
25572
  }
25421
- useEffect63(() => {
25573
+ useEffect65(() => {
25422
25574
  const input = stage.current?.querySelector(
25423
25575
  "input:not([tabindex='-1']), textarea, select, [role='combobox']"
25424
25576
  );
@@ -25529,7 +25681,7 @@ function ThankYou({ form, done, className }) {
25529
25681
  const host = useRecordsUi();
25530
25682
  const redirect = form.thankYou?.redirectUrl?.trim() || null;
25531
25683
  const going = redirect !== null && done !== "preview";
25532
- useEffect63(() => {
25684
+ useEffect65(() => {
25533
25685
  if (!going || !redirect) return;
25534
25686
  const timer = window.setTimeout(() => window.location.assign(redirect), REDIRECT_AFTER_MS);
25535
25687
  return () => window.clearTimeout(timer);
@@ -25542,7 +25694,12 @@ function ThankYou({ form, done, className }) {
25542
25694
  " ",
25543
25695
  /* @__PURE__ */ jsx86("a", { href: redirect, className: "underline underline-offset-2", children: "Go now" })
25544
25696
  ] }) : null,
25545
- /* @__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 })
25546
25703
  ] });
25547
25704
  }
25548
25705
  function Question({
@@ -25588,15 +25745,15 @@ function Question({
25588
25745
  }
25589
25746
 
25590
25747
  // src/NotifyRuleEditor.tsx
25591
- import { useCallback as useCallback40, useEffect as useEffect64, useState as useState77 } from "react";
25592
- import { useRecordsClient as useRecordsClient56, useTable as useTable18 } from "@ai-matrx/records/react";
25593
- 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";
25594
25751
  import { Button as Button67, Skeleton as Skeleton26, cn as cn55 } from "@ai-matrx/design-system";
25595
25752
  import { jsx as jsx87, jsxs as jsxs79 } from "react/jsx-runtime";
25596
25753
  var CADENCE_WORDS2 = SUBSCRIPTION_CADENCE_LABEL;
25597
25754
  var CHANNEL_WORDS3 = SUBSCRIPTION_CHANNEL_LABEL;
25598
25755
  function NotifyRuleEditor({ tableId, seed, chosenRuleId, onChoose, className }) {
25599
- const client = useRecordsClient56();
25756
+ const client = useRecordsClient57();
25600
25757
  const host = useRecordsUi();
25601
25758
  const table = useTable18(tableId);
25602
25759
  const rights = useTableRights(table.data);
@@ -25634,7 +25791,7 @@ function NotifyRuleEditor({ tableId, seed, chosenRuleId, onChoose, className })
25634
25791
  }
25635
25792
  setViews(listed.data.map((v) => ({ id: v.view_id, name: v.name })));
25636
25793
  }, [client, host, tableId]);
25637
- useEffect64(() => {
25794
+ useEffect66(() => {
25638
25795
  void load();
25639
25796
  }, [load]);
25640
25797
  const write = useCallback40(
@@ -25662,7 +25819,7 @@ function NotifyRuleEditor({ tableId, seed, chosenRuleId, onChoose, className })
25662
25819
  },
25663
25820
  [client, tableId]
25664
25821
  );
25665
- useEffect64(() => {
25822
+ useEffect66(() => {
25666
25823
  if (!subscriptions || !seed || seed.length === 0) return;
25667
25824
  const missing = seed.filter((s) => !subscriptions.some((held) => held.name === s.name));
25668
25825
  if (missing.length === 0) return;
@@ -25741,7 +25898,7 @@ function NotifyRuleEditor({ tableId, seed, chosenRuleId, onChoose, className })
25741
25898
  "next ",
25742
25899
  new Date(held.next_digest_at).toLocaleString()
25743
25900
  ] }) : null,
25744
- 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: [
25745
25902
  "quiet ",
25746
25903
  held.quiet_hours.start,
25747
25904
  "\u2013",
@@ -25845,7 +26002,7 @@ function NotifyRuleEditor({ tableId, seed, chosenRuleId, onChoose, className })
25845
26002
  // src/FormBuilder.tsx
25846
26003
  import { Fragment as Fragment37, jsx as jsx88, jsxs as jsxs80 } from "react/jsx-runtime";
25847
26004
  function FormBuilder({ tableId, seed, activeFormId, onActiveForm, startWithOne, className }) {
25848
- const client = useRecordsClient57();
26005
+ const client = useRecordsClient58();
25849
26006
  const publishGate = usePublishGate();
25850
26007
  const host = useRecordsUi();
25851
26008
  const claimSeed = useSeedGuard();
@@ -25890,10 +26047,10 @@ function FormBuilder({ tableId, seed, activeFormId, onActiveForm, startWithOne,
25890
26047
  setError(null);
25891
26048
  setForms(mine);
25892
26049
  }, [client, tableId, seed, claimSeed]);
25893
- useEffect65(() => {
26050
+ useEffect67(() => {
25894
26051
  void load();
25895
26052
  }, [load]);
25896
- useEffect65(() => {
26053
+ useEffect67(() => {
25897
26054
  if (!forms || forms.length === 0) return;
25898
26055
  const chosen = forms.find((f) => f.id === (activeFormId ?? activeId)) ?? forms[0];
25899
26056
  if (chosen.id !== activeId) setActiveId(chosen.id);
@@ -25978,12 +26135,13 @@ function FormBuilder({ tableId, seed, activeFormId, onActiveForm, startWithOne,
25978
26135
  await load();
25979
26136
  }
25980
26137
  const [started, setStarted] = useState78(false);
25981
- useEffect65(() => {
26138
+ useEffect67(() => {
25982
26139
  if (!startWithOne || started || forms === null || forms.length > 0) return;
25983
26140
  if (askableFields(fields.data ?? []).length === 0) return;
26141
+ if (!table.data && !table.error) return;
25984
26142
  setStarted(true);
25985
26143
  void create(table.data?.name?.trim() ? `${table.data.name.trim()} form` : "Form 1");
25986
- }, [startWithOne, started, forms, fields.data, create, table.data?.name]);
26144
+ }, [startWithOne, started, forms, fields.data, create, table.data, table.error]);
25987
26145
  if (fields.error) return /* @__PURE__ */ jsx88(RefusalNotice, { error: fields.error, className });
25988
26146
  if (error) {
25989
26147
  return /* @__PURE__ */ jsx88(
@@ -26477,7 +26635,7 @@ function bucketWindow(groupKey, value) {
26477
26635
 
26478
26636
  // src/chartFrame.tsx
26479
26637
  import {
26480
- useEffect as useEffect66,
26638
+ useEffect as useEffect68,
26481
26639
  useId as useId3,
26482
26640
  useRef as useRef25,
26483
26641
  useState as useState79
@@ -26487,7 +26645,7 @@ import { jsx as jsx89, jsxs as jsxs81 } from "react/jsx-runtime";
26487
26645
  function useMeasuredWidth(fallback = 480) {
26488
26646
  const ref = useRef25(null);
26489
26647
  const [width, setWidth] = useState79(fallback);
26490
- useEffect66(() => {
26648
+ useEffect68(() => {
26491
26649
  const node = ref.current;
26492
26650
  if (!node) return;
26493
26651
  const apply = () => {
@@ -26611,12 +26769,12 @@ function isSignatureField(field2) {
26611
26769
  }
26612
26770
 
26613
26771
  // src/DocTemplate.tsx
26614
- import { useCallback as useCallback42, useEffect as useEffect67, useState as useState80 } from "react";
26615
- 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";
26616
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";
26617
26775
  import { jsx as jsx90, jsxs as jsxs82 } from "react/jsx-runtime";
26618
26776
  function DocTemplate({ tableId, seed, activeTemplateId, onActiveTemplate, className }) {
26619
- const client = useRecordsClient58();
26777
+ const client = useRecordsClient59();
26620
26778
  const claimSeed = useSeedGuard();
26621
26779
  const table = useTable20(tableId);
26622
26780
  const rights = useTableRights(table.data);
@@ -26659,10 +26817,10 @@ function DocTemplate({ tableId, seed, activeTemplateId, onActiveTemplate, classN
26659
26817
  setError(null);
26660
26818
  setTemplates(rows);
26661
26819
  }, [client, tableId, seed, fields.data]);
26662
- useEffect67(() => {
26820
+ useEffect69(() => {
26663
26821
  void load();
26664
26822
  }, [load]);
26665
- useEffect67(() => {
26823
+ useEffect69(() => {
26666
26824
  if (!templates || templates.length === 0) return;
26667
26825
  const chosen = templates.find((t) => t.id === (activeTemplateId ?? activeId)) ?? templates[0];
26668
26826
  if (chosen.id !== activeId) setActiveId(chosen.id);
@@ -26670,7 +26828,7 @@ function DocTemplate({ tableId, seed, activeTemplateId, onActiveTemplate, classN
26670
26828
  setDraftBody(chosen.body);
26671
26829
  onActiveTemplate?.(chosen);
26672
26830
  }, [templates, activeTemplateId]);
26673
- useEffect67(() => {
26831
+ useEffect69(() => {
26674
26832
  let cancelled = false;
26675
26833
  if (draftBody.trim() === "") {
26676
26834
  setUnresolved([]);
@@ -26795,12 +26953,12 @@ function DocTemplate({ tableId, seed, activeTemplateId, onActiveTemplate, classN
26795
26953
  }
26796
26954
 
26797
26955
  // src/DocRender.tsx
26798
- import { useCallback as useCallback43, useEffect as useEffect68, useRef as useRef26, useState as useState81 } from "react";
26799
- 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";
26800
26958
  import { Button as Button70, Skeleton as Skeleton29, cn as cn59 } from "@ai-matrx/design-system";
26801
26959
  import { jsx as jsx91, jsxs as jsxs83 } from "react/jsx-runtime";
26802
26960
  function DocRender({ templateId, recordId, filename, onRendered, className }) {
26803
- const client = useRecordsClient59();
26961
+ const client = useRecordsClient60();
26804
26962
  const [preview, setPreview] = useState81(null);
26805
26963
  const [renders, setRenders] = useState81(null);
26806
26964
  const [showing, setShowing] = useState81(null);
@@ -26824,7 +26982,7 @@ function DocRender({ templateId, recordId, filename, onRendered, className }) {
26824
26982
  setPreview(body.data);
26825
26983
  setRenders(held.data.filter((r) => r.template_id === templateId));
26826
26984
  }, [client, templateId, recordId]);
26827
- useEffect68(() => {
26985
+ useEffect70(() => {
26828
26986
  void load();
26829
26987
  }, [load]);
26830
26988
  async function freeze() {
@@ -26908,13 +27066,13 @@ function DocRender({ templateId, recordId, filename, onRendered, className }) {
26908
27066
  }
26909
27067
 
26910
27068
  // src/SignBlock.tsx
26911
- import { useCallback as useCallback44, useEffect as useEffect69, useState as useState82 } from "react";
26912
- 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";
26913
27071
  import { BasicInput as BasicInput28, Button as Button71, Skeleton as Skeleton30, cn as cn60 } from "@ai-matrx/design-system";
26914
27072
  import { useTable as useTable21 } from "@ai-matrx/records/react";
26915
27073
  import { jsx as jsx92, jsxs as jsxs84 } from "react/jsx-runtime";
26916
27074
  function SignBlock({ tableId, recordId, render, className }) {
26917
- const client = useRecordsClient60();
27075
+ const client = useRecordsClient61();
26918
27076
  const table = useTable21(tableId);
26919
27077
  const rights = useTableRights(table.data);
26920
27078
  const fields = useFields22(tableId);
@@ -26938,7 +27096,7 @@ function SignBlock({ tableId, recordId, render, className }) {
26938
27096
  }
26939
27097
  setVerdicts(answers);
26940
27098
  }, [client, recordId]);
26941
- useEffect69(() => {
27099
+ useEffect71(() => {
26942
27100
  void load();
26943
27101
  }, [load]);
26944
27102
  async function sign(field2) {
@@ -27511,8 +27669,8 @@ function onlyWholeNumbers(rows) {
27511
27669
  }
27512
27670
 
27513
27671
  // src/DashboardCanvas.tsx
27514
- import { useCallback as useCallback45, useEffect as useEffect70, useMemo as useMemo44, useState as useState83 } from "react";
27515
- 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";
27516
27674
  import {
27517
27675
  BasicInput as BasicInput29,
27518
27676
  Button as Button72,
@@ -27526,7 +27684,7 @@ import {
27526
27684
  } from "@ai-matrx/design-system";
27527
27685
  import { Fragment as Fragment39, jsx as jsx94, jsxs as jsxs86 } from "react/jsx-runtime";
27528
27686
  function DashboardCanvas({ tableId, activeDashboardId, filter, className }) {
27529
- const client = useRecordsClient61();
27687
+ const client = useRecordsClient62();
27530
27688
  const host = useRecordsUi();
27531
27689
  const table = useTable22(tableId);
27532
27690
  const rights = useTableRights(table.data);
@@ -27558,17 +27716,17 @@ function DashboardCanvas({ tableId, activeDashboardId, filter, className }) {
27558
27716
  return read;
27559
27717
  }, [client, tableId]);
27560
27718
  const [notKept, setNotKept] = useState83(null);
27561
- useEffect70(() => {
27719
+ useEffect72(() => {
27562
27720
  void load();
27563
27721
  }, [load]);
27564
- useEffect70(() => {
27722
+ useEffect72(() => {
27565
27723
  if (!boards || boards.length === 0) return;
27566
27724
  const chosen = boards.find((d) => d.id === (activeDashboardId ?? activeId)) ?? boards[0];
27567
27725
  if (chosen.id !== activeId) setActiveId(chosen.id);
27568
27726
  }, [boards, activeDashboardId]);
27569
27727
  const board = useMemo44(() => boards?.find((d) => d.id === activeId) ?? null, [boards, activeId]);
27570
27728
  const filterKey = JSON.stringify(filter ?? {});
27571
- useEffect70(() => {
27729
+ useEffect72(() => {
27572
27730
  if (!activeId) {
27573
27731
  setRun(null);
27574
27732
  return;
@@ -28026,7 +28184,7 @@ function TargetControl({
28026
28184
  const [mode, setMode] = useState83(saved);
28027
28185
  const savedValue = block.target && "value" in block.target && typeof block.target.value === "number" ? block.target.value : null;
28028
28186
  const [draft, setDraft] = useState83(savedValue === null ? "" : String(savedValue));
28029
- useEffect70(() => {
28187
+ useEffect72(() => {
28030
28188
  setMode(saved);
28031
28189
  setDraft(savedValue === null ? "" : String(savedValue));
28032
28190
  }, [saved, savedValue]);
@@ -28093,8 +28251,8 @@ function TargetControl({
28093
28251
  }
28094
28252
 
28095
28253
  // src/FormsPanel.tsx
28096
- import { useCallback as useCallback46, useEffect as useEffect71, useState as useState84 } from "react";
28097
- 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";
28098
28256
  import { publicFormPath as publicFormPath2 } from "@ai-matrx/records";
28099
28257
  import { Badge as Badge22, Button as Button73, Skeleton as Skeleton32, cn as cn63 } from "@ai-matrx/design-system";
28100
28258
  import { Fragment as Fragment40, jsx as jsx95, jsxs as jsxs87 } from "react/jsx-runtime";
@@ -28106,7 +28264,7 @@ function formSuggestion(tableName2) {
28106
28264
  return `Make me a form that collects new ${subject} entries and tells me when somebody answers.`;
28107
28265
  }
28108
28266
  function FormsPanel({ tableId, activeFormId, className }) {
28109
- const client = useRecordsClient62();
28267
+ const client = useRecordsClient63();
28110
28268
  const publishGate = usePublishGate();
28111
28269
  const host = useRecordsUi();
28112
28270
  const table = useTable23(tableId);
@@ -28118,7 +28276,7 @@ function FormsPanel({ tableId, activeFormId, className }) {
28118
28276
  const [building, setBuilding] = useState84(false);
28119
28277
  const linked = activeFormId && forms !== null ? forms.find((f) => f.form_id === activeFormId) ?? null : null;
28120
28278
  const linkedMissing = Boolean(activeFormId) && forms !== null && linked === null;
28121
- useEffect71(() => {
28279
+ useEffect73(() => {
28122
28280
  if (linked && rights.structure) setBuilding(true);
28123
28281
  }, [linked, rights.structure]);
28124
28282
  const load = useCallback46(async () => {
@@ -28131,7 +28289,7 @@ function FormsPanel({ tableId, activeFormId, className }) {
28131
28289
  setError(null);
28132
28290
  setForms(answered.data);
28133
28291
  }, [client, tableId]);
28134
- useEffect71(() => {
28292
+ useEffect73(() => {
28135
28293
  void load();
28136
28294
  }, [load]);
28137
28295
  const toggle = useCallback46(
@@ -28263,18 +28421,18 @@ function FormsPanel({ tableId, activeFormId, className }) {
28263
28421
  }
28264
28422
 
28265
28423
  // src/CaptureSheet.tsx
28266
- import { useCallback as useCallback48, useEffect as useEffect73, useRef as useRef28, useState as useState86 } from "react";
28267
- 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";
28268
28426
  import { Button as Button75, Input as Input4, Skeleton as Skeleton34, Textarea as Textarea3, cn as cn65 } from "@ai-matrx/design-system";
28269
28427
 
28270
28428
  // src/CaptureRun.tsx
28271
- 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";
28272
28430
  import {
28273
28431
  coerceTypedAnswer as coerceTypedAnswer3,
28274
28432
  coercionLabel,
28275
28433
  openCaptureQueue
28276
28434
  } from "@ai-matrx/records";
28277
- import { useRecordsClient as useRecordsClient63 } from "@ai-matrx/records/react";
28435
+ import { useRecordsClient as useRecordsClient64 } from "@ai-matrx/records/react";
28278
28436
  import { Button as Button74, Input as Input3, Skeleton as Skeleton33, Textarea as Textarea2, cn as cn64 } from "@ai-matrx/design-system";
28279
28437
  import { jsx as jsx96, jsxs as jsxs88 } from "react/jsx-runtime";
28280
28438
  function controlFor(field2) {
@@ -28313,7 +28471,7 @@ function whereWeAre(timeoutMs = 4e3) {
28313
28471
  });
28314
28472
  }
28315
28473
  function CaptureRun({ sheetId, face: given, className }) {
28316
- const client = useRecordsClient63();
28474
+ const client = useRecordsClient64();
28317
28475
  const host = useRecordsUi();
28318
28476
  const [face, setFace] = useState85(given);
28319
28477
  const [loadFailed, setLoadFailed] = useState85(null);
@@ -28327,7 +28485,7 @@ function CaptureRun({ sheetId, face: given, className }) {
28327
28485
  const [lastSynced, setLastSynced] = useState85(null);
28328
28486
  const [sending, setSending] = useState85(false);
28329
28487
  const queueRef = useRef27(null);
28330
- useEffect72(() => {
28488
+ useEffect74(() => {
28331
28489
  const q2 = openCaptureQueue({
28332
28490
  onChange: (c, all) => {
28333
28491
  setCounts(c);
@@ -28365,7 +28523,7 @@ function CaptureRun({ sheetId, face: given, className }) {
28365
28523
  void q2.sync().then(() => void q2.lastSyncedAt().then(setLastSynced));
28366
28524
  return () => q2.dispose();
28367
28525
  }, [client, host]);
28368
- useEffect72(() => {
28526
+ useEffect74(() => {
28369
28527
  if (given !== void 0) return;
28370
28528
  let cancelled = false;
28371
28529
  void client.captureOpen({ sheet_id: sheetId }).then((res) => {
@@ -28693,7 +28851,7 @@ function AdHocCaptureSheet({
28693
28851
  attachmentField,
28694
28852
  className
28695
28853
  }) {
28696
- const client = useRecordsClient64();
28854
+ const client = useRecordsClient65();
28697
28855
  const host = useRecordsUi();
28698
28856
  const table = useTable24(tableId);
28699
28857
  const fields = useFields24(tableId);
@@ -28715,7 +28873,7 @@ function AdHocCaptureSheet({
28715
28873
  },
28716
28874
  [host]
28717
28875
  );
28718
- useEffect73(() => {
28876
+ useEffect75(() => {
28719
28877
  let cancelled = false;
28720
28878
  void (async () => {
28721
28879
  const held = host.captureQueue ? await host.captureQueue.load() : [];
@@ -28894,12 +29052,12 @@ function AdHocCaptureSheet({
28894
29052
  }
28895
29053
 
28896
29054
  // src/PortalShell.tsx
28897
- import { useCallback as useCallback49, useEffect as useEffect74, useState as useState87 } from "react";
28898
- 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";
28899
29057
  import { Button as Button76, Skeleton as Skeleton35, cn as cn66 } from "@ai-matrx/design-system";
28900
29058
  import { jsx as jsx98, jsxs as jsxs90 } from "react/jsx-runtime";
28901
29059
  function PortalShell({ tableId, form, resourceType = "record", className }) {
28902
- const client = useRecordsClient65();
29060
+ const client = useRecordsClient66();
28903
29061
  const [card, setCard] = useState87(null);
28904
29062
  const [reach, setReach] = useState87(null);
28905
29063
  const [error, setError] = useState87(null);
@@ -28920,7 +29078,7 @@ function PortalShell({ tableId, form, resourceType = "record", className }) {
28920
29078
  }
28921
29079
  setReach(reached.data.map((row) => row.resource_id));
28922
29080
  }, [client, resourceType]);
28923
- useEffect74(() => {
29081
+ useEffect76(() => {
28924
29082
  void load();
28925
29083
  }, [load]);
28926
29084
  if (error) {
@@ -28978,9 +29136,9 @@ function PortalShell({ tableId, form, resourceType = "record", className }) {
28978
29136
  ] });
28979
29137
  }
28980
29138
  function PortalRow({ tableId, recordId }) {
28981
- const client = useRecordsClient65();
29139
+ const client = useRecordsClient66();
28982
29140
  const [title, setTitle] = useState87(null);
28983
- useEffect74(() => {
29141
+ useEffect76(() => {
28984
29142
  let cancelled = false;
28985
29143
  void client.recordRead({ record_id: recordId }).then((answered) => {
28986
29144
  if (cancelled) return;
@@ -29000,12 +29158,12 @@ function PortalRow({ tableId, recordId }) {
29000
29158
  }
29001
29159
 
29002
29160
  // src/PublicViewPage.tsx
29003
- import { useCallback as useCallback50, useEffect as useEffect75, useState as useState88 } from "react";
29004
- 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";
29005
29163
  import { Skeleton as Skeleton36, cn as cn67 } from "@ai-matrx/design-system";
29006
29164
  import { jsx as jsx99, jsxs as jsxs91 } from "react/jsx-runtime";
29007
29165
  function PublicViewPage({ slug, className }) {
29008
- const client = useRecordsClient66();
29166
+ const client = useRecordsClient67();
29009
29167
  const [binding, setBinding] = useState88(null);
29010
29168
  const [rows, setRows] = useState88(null);
29011
29169
  const [fields, setFields] = useState88(null);
@@ -29044,7 +29202,7 @@ function PublicViewPage({ slug, className }) {
29044
29202
  }
29045
29203
  setRows([{ id: found.resource_id, document: read.data.document, level: "viewer", hidden: read.data.hidden }]);
29046
29204
  }, [client, slug]);
29047
- useEffect75(() => {
29205
+ useEffect77(() => {
29048
29206
  void load();
29049
29207
  }, [load]);
29050
29208
  if (error) return /* @__PURE__ */ jsx99(RefusalNotice, { error, className });
@@ -29081,8 +29239,8 @@ function PublicRow({ row, fields }) {
29081
29239
  }
29082
29240
 
29083
29241
  // src/EmbedFrame.tsx
29084
- import { useCallback as useCallback51, useEffect as useEffect76, useState as useState89 } from "react";
29085
- 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";
29086
29244
  import { Button as Button77, Input as Input5, Skeleton as Skeleton37, Textarea as Textarea4, cn as cn68 } from "@ai-matrx/design-system";
29087
29245
  import { useTable as useTable25 } from "@ai-matrx/records/react";
29088
29246
  import { Fragment as Fragment42, jsx as jsx100, jsxs as jsxs92 } from "react/jsx-runtime";
@@ -29094,7 +29252,7 @@ function EmbedFrame({
29094
29252
  embedUrl,
29095
29253
  className
29096
29254
  }) {
29097
- const client = useRecordsClient67();
29255
+ const client = useRecordsClient68();
29098
29256
  const host = useRecordsUi();
29099
29257
  const table = useTable25(tableId);
29100
29258
  const rights = useTableRights(table.data);
@@ -29188,13 +29346,13 @@ function EmbedFrame({
29188
29346
  ] });
29189
29347
  }
29190
29348
  function useEmbedHandshake(args) {
29191
- const client = useRecordsClient67();
29349
+ const client = useRecordsClient68();
29192
29350
  const [binding, setBinding] = useState89(null);
29193
29351
  const [error, setError] = useState89(null);
29194
29352
  const [loading, setLoading] = useState89(true);
29195
29353
  const origin = args.origin ?? (typeof location === "undefined" ? "" : location.origin);
29196
29354
  const { secret, requiredMode } = args;
29197
- useEffect76(() => {
29355
+ useEffect78(() => {
29198
29356
  let cancelled = false;
29199
29357
  setLoading(true);
29200
29358
  setError(null);
@@ -29266,9 +29424,9 @@ function recordsDataSource(client, fallbackSchema = "custom") {
29266
29424
  }
29267
29425
 
29268
29426
  // src/TablePage.tsx
29269
- 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";
29270
29428
  import { archivedByLine as archivedByLine2 } from "@ai-matrx/records";
29271
- 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";
29272
29430
  import {
29273
29431
  BottomSheet,
29274
29432
  Button as Button79,
@@ -29289,7 +29447,7 @@ import {
29289
29447
  } from "@ai-matrx/design-system";
29290
29448
 
29291
29449
  // src/ViewFilter.tsx
29292
- 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";
29293
29451
  import { Button as Button78, cn as cn69 } from "@ai-matrx/design-system";
29294
29452
  import { useFields as useFields25 } from "@ai-matrx/records/react";
29295
29453
  import { jsx as jsx102, jsxs as jsxs93 } from "react/jsx-runtime";
@@ -29307,7 +29465,7 @@ function ViewFilter({ tableId, view, onApply, className }) {
29307
29465
  const saved = view?.where ?? null;
29308
29466
  const [draft, setDraft] = useState90(saved);
29309
29467
  const savedKey = JSON.stringify(saved);
29310
- useEffect77(() => {
29468
+ useEffect79(() => {
29311
29469
  setDraft(saved);
29312
29470
  }, [view?.id, savedKey]);
29313
29471
  const conditionFields = useMemo46(
@@ -29390,7 +29548,7 @@ function ViewFilter({ tableId, view, onApply, className }) {
29390
29548
  }
29391
29549
 
29392
29550
  // src/toolbarFit.ts
29393
- import { useEffect as useEffect78, useState as useState91 } from "react";
29551
+ import { useEffect as useEffect80, useState as useState91 } from "react";
29394
29552
  var FOLDED_GUESS = { look: 104, chooser: 96, tools: 120 };
29395
29553
  function toolbarFold(input) {
29396
29554
  const { available, needsNow, gap, folded } = input;
@@ -29442,7 +29600,7 @@ function rowNeeds(row) {
29442
29600
  }
29443
29601
  function useToolbarFit(row) {
29444
29602
  const [fold, setFold] = useState91(0);
29445
- useEffect78(() => {
29603
+ useEffect80(() => {
29446
29604
  if (!row) return;
29447
29605
  const widths = {
29448
29606
  look: { full: null, folded: null },
@@ -29523,7 +29681,7 @@ function clippedEnds(scrollLeft, clientWidth, scrollWidth) {
29523
29681
  }
29524
29682
  function useSlotScroll(slot) {
29525
29683
  const [ends, setEnds] = useState91("none");
29526
- useEffect78(() => {
29684
+ useEffect80(() => {
29527
29685
  if (!slot) return;
29528
29686
  let pending = 0;
29529
29687
  const read = () => {
@@ -29639,11 +29797,11 @@ function TableNotHere({
29639
29797
  leaveLabel,
29640
29798
  className
29641
29799
  }) {
29642
- const client = useRecordsClient68();
29800
+ const client = useRecordsClient69();
29643
29801
  const [archived, setArchived] = useState92({ phase: "asking" });
29644
29802
  const [restoring, setRestoring] = useState92(false);
29645
29803
  const [refusal2, setRefusal] = useState92(null);
29646
- useEffect79(() => {
29804
+ useEffect81(() => {
29647
29805
  let alive = true;
29648
29806
  void client.tableArchived({ table_id: tableId }).then((answered) => {
29649
29807
  if (!alive) return;
@@ -29830,15 +29988,15 @@ function TablePage({
29830
29988
  onShownViewChange,
29831
29989
  className
29832
29990
  }) {
29833
- const client = useRecordsClient68();
29991
+ const client = useRecordsClient69();
29834
29992
  const table = useTable26(tableId);
29835
29993
  const rights = useTableRights(table.data);
29836
29994
  const pageFields = useFields26(filter ? tableId : null);
29837
29995
  const askedInWords = filter ? filterInWords(filter, pageFields.data ?? []) : null;
29838
- const organizationId = useRecordsClient68().config.organizationId;
29996
+ const organizationId = useRecordsClient69().config.organizationId;
29839
29997
  const [view, setView] = useState92(null);
29840
29998
  const [looks, setLooks] = useState92(void 0);
29841
- useEffect79(() => {
29999
+ useEffect81(() => {
29842
30000
  let live = true;
29843
30001
  setLooks(void 0);
29844
30002
  void readLooks(client, tableId).then((answered) => {
@@ -29890,7 +30048,7 @@ function TablePage({
29890
30048
  const chooserInline = !designated && !phone && toolbarFold2 < 2;
29891
30049
  const chooserCompact = !designated && !phone && toolbarFold2 >= 2;
29892
30050
  const controlsInSheet = phone && !designated;
29893
- useEffect79(() => {
30051
+ useEffect81(() => {
29894
30052
  if (face.kind !== "designated") return;
29895
30053
  if (hostFromLink || opened.layout || layoutChosen) return;
29896
30054
  setHostLayout(face.hostLayout);
@@ -29923,7 +30081,7 @@ function TablePage({
29923
30081
  const shownSignature = JSON.stringify(shownReport);
29924
30082
  const reportRef = useRef30(onShownViewChange);
29925
30083
  reportRef.current = onShownViewChange;
29926
- useEffect79(() => {
30084
+ useEffect81(() => {
29927
30085
  reportRef.current?.(JSON.parse(shownSignature));
29928
30086
  }, [shownSignature]);
29929
30087
  const pickLayout = (next) => {
@@ -29941,18 +30099,18 @@ function TablePage({
29941
30099
  onViewChanged?.(id);
29942
30100
  };
29943
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;
29944
- useEffect79(() => {
30102
+ useEffect81(() => {
29945
30103
  if (!activeRecordId) return;
29946
30104
  setOpenRecord(activeRecordId);
29947
30105
  setSurface((now) => ({ ...now, rail: "record" }));
29948
30106
  }, [activeRecordId]);
29949
- useEffect79(() => {
30107
+ useEffect81(() => {
29950
30108
  if (activeRecordId) return;
29951
30109
  const named = railFromParam(activeRail);
29952
30110
  if (named === null || named === "share") return;
29953
30111
  setSurface((now) => ({ ...now, rail: named }));
29954
30112
  }, [activeRail, activeRecordId]);
29955
- useEffect79(() => {
30113
+ useEffect81(() => {
29956
30114
  const host = hostLayoutFor(activeView);
29957
30115
  if (host) {
29958
30116
  setHostLayout(host);
@@ -30904,6 +31062,7 @@ export {
30904
31062
  scalarText,
30905
31063
  seedIsSatisfied,
30906
31064
  shareUnavailableReason,
31065
+ singularNoun,
30907
31066
  snoozeChoices,
30908
31067
  specFromBlock,
30909
31068
  storeDecidesRights,