@ai-matrx/records-ui 0.93.64 → 0.93.69

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;
@@ -2092,12 +2096,33 @@ function parseGrouping(raw) {
2092
2096
  const sub = level["field"];
2093
2097
  if (typeof sub !== "string" || sub.trim() === "") continue;
2094
2098
  const subOrder = level["order"];
2095
- then.push(
2096
- typeof subOrder === "string" && GROUP_ORDERS.includes(subOrder) ? { field: sub, order: subOrder } : { field: sub }
2097
- );
2099
+ const subGrain = level["grain"];
2100
+ then.push({
2101
+ field: sub,
2102
+ ...typeof subOrder === "string" && GROUP_ORDERS.includes(subOrder) ? { order: subOrder } : {},
2103
+ ...typeof subGrain === "string" && subGrain !== "" ? { grain: subGrain } : {}
2104
+ });
2098
2105
  }
2099
2106
  if (then.length > 0) out.then = then.slice(0, 2);
2100
2107
  }
2108
+ const grain = raw["grain"];
2109
+ if (typeof grain === "string" && grain !== "") out.grain = grain;
2110
+ const across = raw["across"];
2111
+ if (typeof across === "string" && across.trim() !== "") out.across = across;
2112
+ if (Array.isArray(raw["show"])) {
2113
+ const show = raw["show"].filter((k) => typeof k === "string" && k !== "");
2114
+ if (show.length > 0) out.show = show;
2115
+ }
2116
+ if (Array.isArray(raw["trail"])) {
2117
+ const trail = [];
2118
+ for (const step2 of raw["trail"]) {
2119
+ if (!isRecord(step2) || typeof step2["dim"] !== "string" || step2["dim"] === "") continue;
2120
+ const value = step2["value"];
2121
+ if (value !== null && typeof value !== "string") continue;
2122
+ trail.push({ dim: step2["dim"], value });
2123
+ }
2124
+ if (trail.length > 0) out.trail = trail;
2125
+ }
2101
2126
  return out;
2102
2127
  }
2103
2128
  function presentationIsEmpty(p) {
@@ -2436,7 +2461,7 @@ function NumberInFormat({ format, value, onChange, disabled, id }) {
2436
2461
  function formatControl(args) {
2437
2462
  const def = getFieldFormat3(args.format.id);
2438
2463
  if (!def) return null;
2439
- const { format, value, onChange, disabled, id, label } = args;
2464
+ const { format, value, onChange, disabled, id, label, ownDetails } = args;
2440
2465
  const text = value === null || value === void 0 ? "" : String(value);
2441
2466
  const commit = (raw) => onChange(raw === "" ? null : parseFieldInput(raw, format));
2442
2467
  if (def.id === "rating") {
@@ -2459,7 +2484,17 @@ function formatControl(args) {
2459
2484
  case "email":
2460
2485
  case "url":
2461
2486
  case "tel":
2462
- return /* @__PURE__ */ jsx11(BasicInput4, { id, type: def.editor, value: text, disabled, onChange: (e) => commit(e.target.value) });
2487
+ return /* @__PURE__ */ jsx11(
2488
+ BasicInput4,
2489
+ {
2490
+ id,
2491
+ type: def.editor,
2492
+ ...ownDetails && def.editor !== "url" ? { autoComplete: def.editor === "email" ? "email" : "tel" } : {},
2493
+ value: text,
2494
+ disabled,
2495
+ onChange: (e) => commit(e.target.value)
2496
+ }
2497
+ );
2463
2498
  case "color":
2464
2499
  return /* @__PURE__ */ jsxs9("span", { className: "flex items-center gap-2", children: [
2465
2500
  /* @__PURE__ */ jsx11(
@@ -2713,14 +2748,19 @@ function TypedTextControl({ field: field2, value, onChange, disabled, id, onComm
2713
2748
  ] })
2714
2749
  ] });
2715
2750
  }
2751
+ function isPersonsName(field2) {
2752
+ const words2 = `${field2.key} ${field2.label ?? ""}`.toLowerCase();
2753
+ return /(^|[\s_])(full[\s_]?)?name(\s|$)/.test(words2) && !/(therapist|doctor|physician|company|business|pet|room)/.test(words2);
2754
+ }
2716
2755
  function FieldControl({ field: field2, value, onChange, disabled, id, autoOpen, onClose, onCommit, onCancel, addsChoices, initialSearch }) {
2717
2756
  const host = useRecordsUi();
2718
2757
  const kind = editorKindFor(field2);
2719
2758
  const inputId = id ?? `field-${field2.key}`;
2759
+ const ownDetails = useOptionalRecordsClient5() === null;
2720
2760
  if (isTypedDraft(value)) return /* @__PURE__ */ jsx12(TypedTextControl, { field: field2, value, onChange, disabled, id: inputId, onCommit, onCancel });
2721
2761
  const format = formatForField(field2);
2722
2762
  if (format && !FORMAT_BLIND_KINDS.has(String(kind))) {
2723
- const own2 = formatControl({ format, value, onChange, disabled, id: inputId, label: fieldName(field2) });
2763
+ const own2 = formatControl({ format, value, onChange, disabled, id: inputId, label: fieldName(field2), ownDetails });
2724
2764
  if (own2) return own2;
2725
2765
  }
2726
2766
  switch (kind) {
@@ -2781,6 +2821,7 @@ function FieldControl({ field: field2, value, onChange, disabled, id, autoOpen,
2781
2821
  {
2782
2822
  id: inputId,
2783
2823
  type: kind === "email" ? "email" : kind === "phone" ? "tel" : "url",
2824
+ ...ownDetails && kind !== "url" ? { autoComplete: kind === "email" ? "email" : "tel" } : {},
2784
2825
  value: value === null || value === void 0 ? "" : String(value),
2785
2826
  disabled,
2786
2827
  onChange: (e) => onChange(e.target.value === "" ? null : e.target.value)
@@ -2818,6 +2859,7 @@ function FieldControl({ field: field2, value, onChange, disabled, id, autoOpen,
2818
2859
  BasicInput5,
2819
2860
  {
2820
2861
  id: inputId,
2862
+ ...ownDetails && isPersonsName(field2) ? { autoComplete: "name" } : {},
2821
2863
  value: value === null || value === void 0 ? "" : String(value),
2822
2864
  disabled,
2823
2865
  onChange: (e) => onChange(e.target.value === "" ? null : e.target.value)
@@ -5217,12 +5259,12 @@ function OpenCell({
5217
5259
  }
5218
5260
 
5219
5261
  // src/Grid.tsx
5220
- import { useCallback as useCallback18, useEffect as useEffect32, useMemo as useMemo23, useRef as useRef16, useState as useState39 } from "react";
5262
+ import { useCallback as useCallback18, useEffect as useEffect33, useMemo as useMemo24, useRef as useRef16, useState as useState40 } from "react";
5221
5263
  import {
5222
5264
  useFields as useFields5,
5223
5265
  useRecordPage,
5224
5266
  useRecords as useRecords4,
5225
- useRecordsClient as useRecordsClient23,
5267
+ useRecordsClient as useRecordsClient24,
5226
5268
  useTable as useTable3
5227
5269
  } from "@ai-matrx/records/react";
5228
5270
  import { asPermissionLevel } from "@ai-matrx/records";
@@ -5234,6 +5276,22 @@ function archiveConfirmSentence(what) {
5234
5276
  const subject = what.trim() || "it";
5235
5277
  return `This archives ${subject}. It leaves this list, and you can restore it from Trash.`;
5236
5278
  }
5279
+ var recordsWord = (n) => `${n.toLocaleString()} record${n === 1 ? "" : "s"}`;
5280
+ function tableArchiveSentence(s) {
5281
+ const p = s.progress;
5282
+ if (!p) return "Every record in it goes with it.";
5283
+ const done = p.total - p.remaining;
5284
+ const sofar = `${done.toLocaleString()} of ${recordsWord(p.total)} ${done === 1 ? "is" : "are"} put away`;
5285
+ if (s.running) {
5286
+ 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." : ""}`;
5287
+ }
5288
+ if (p.in_progress && !s.failed && !(s.passesHere ?? 0)) {
5289
+ return `Archiving this table was started and not finished: ${sofar}. Carry on and it picks up where it stopped.`;
5290
+ }
5291
+ 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.`;
5292
+ if (s.interrupted) return `Stopped: ${sofar}. Carry on whenever you like; it picks up where it stopped.`;
5293
+ return `Its ${recordsWord(p.remaining)} ${p.remaining === 1 ? "goes" : "go"} with it.`;
5294
+ }
5237
5295
 
5238
5296
  // src/tableDecorations.ts
5239
5297
  import { useCallback as useCallback7, useEffect as useEffect12, useState as useState15 } from "react";
@@ -9235,11 +9293,236 @@ function AddFirstRowButton({ onAdd, busy }) {
9235
9293
  return /* @__PURE__ */ jsx32(Button20, { size: "sm", "data-records-add-first-row": "", disabled: busy, onClick: onAdd, children: busy ? "Adding\u2026" : "Add the first row" });
9236
9294
  }
9237
9295
 
9296
+ // src/gridDrill.tsx
9297
+ import { useEffect as useEffect23, useMemo as useMemo16, useState as useState27 } from "react";
9298
+ import { useRecordsClient as useRecordsClient15 } from "@ai-matrx/records/react";
9299
+ import { isRuleFilter as isRuleFilter2 } from "@ai-matrx/records";
9300
+ import {
9301
+ bucketWindow,
9302
+ drillRequests,
9303
+ parseDimensionRef,
9304
+ useDrillUrlState
9305
+ } from "@ai-matrx/design-system/data-table";
9306
+ var MEASURE_OPS = [
9307
+ { op: "sum", word: "Sum of", additive: true },
9308
+ { op: "avg", word: "Average", additive: false },
9309
+ { op: "min", word: "Lowest", additive: false },
9310
+ { op: "max", word: "Highest", additive: false },
9311
+ { op: "median", word: "Median", additive: false }
9312
+ ];
9313
+ var DIMENSION_KINDS = {
9314
+ select: "choice",
9315
+ checkbox: "boolean",
9316
+ text: "text",
9317
+ datetime: "time"
9318
+ };
9319
+ function drillDimensionsFor(fields, options) {
9320
+ const out = [];
9321
+ for (const field2 of fields) {
9322
+ const kind = DIMENSION_KINDS[String(editorKindFor(field2))];
9323
+ if (!kind) continue;
9324
+ if (field2.multi) continue;
9325
+ const dim = { key: field2.key, label: fieldName(field2), kind };
9326
+ if (kind === "text") dim.cardinality = "high";
9327
+ if (kind === "choice" && isChoiceField(field2)) {
9328
+ dim.labelFor = (value) => {
9329
+ if (value === null || value === "") return "No value";
9330
+ return optionFor(options.get(field2.key), value)?.label ?? value;
9331
+ };
9332
+ }
9333
+ out.push(dim);
9334
+ }
9335
+ return out;
9336
+ }
9337
+ function drillMeasuresFor(fields) {
9338
+ const out = [{ key: "count", label: "Count", additive: true }];
9339
+ for (const field2 of fields) {
9340
+ const kind = String(editorKindFor(field2));
9341
+ if (kind !== "number" && kind !== "currency" && kind !== "percent") continue;
9342
+ for (const m of MEASURE_OPS) {
9343
+ out.push({ key: `${m.op}_${field2.key}`, label: `${m.word} ${fieldName(field2)}`, additive: m.additive });
9344
+ }
9345
+ }
9346
+ return out;
9347
+ }
9348
+ function measureFor(key) {
9349
+ if (key === "count") return { op: "count" };
9350
+ const at = key.indexOf("_");
9351
+ if (at <= 0) return null;
9352
+ const op2 = key.slice(0, at);
9353
+ if (!MEASURE_OPS.some((m) => m.op === op2)) return null;
9354
+ return { op: op2, key: key.slice(at + 1) };
9355
+ }
9356
+ function questionFromGrouping(grouping) {
9357
+ if (!grouping) return { by: [], across: null, show: ["count"], where: [] };
9358
+ const ref = (field2, grain) => grain ? `${field2}:${grain}` : field2;
9359
+ const by = [ref(grouping.field, grouping.grain), ...(grouping.then ?? []).map((t) => ref(t.field, t.grain))];
9360
+ return {
9361
+ by,
9362
+ across: grouping.across ?? null,
9363
+ show: grouping.show && grouping.show.length > 0 ? grouping.show : ["count"],
9364
+ where: grouping.trail ?? []
9365
+ };
9366
+ }
9367
+ function groupingFromQuestion(question, held) {
9368
+ const [first, ...rest] = question.by.map(parseDimensionRef);
9369
+ if (!first) return void 0;
9370
+ const sameFirst = held?.field === first.key;
9371
+ return {
9372
+ field: first.key,
9373
+ ...first.grain ? { grain: first.grain } : {},
9374
+ ...sameFirst && held?.aggregates ? { aggregates: held.aggregates } : {},
9375
+ ...sameFirst && held?.order ? { order: held.order } : {},
9376
+ ...rest.length > 0 ? { then: rest.map((level) => ({ field: level.key, ...level.grain ? { grain: level.grain } : {} })) } : {},
9377
+ ...question.across ? { across: question.across } : {},
9378
+ ...question.show.length > 0 && !(question.show.length === 1 && question.show[0] === "count") ? { show: question.show } : {},
9379
+ ...question.where.length > 0 ? { trail: question.where } : {}
9380
+ };
9381
+ }
9382
+ function trailClause(fields, w) {
9383
+ const { key, grain } = parseDimensionRef(w.dim);
9384
+ const field2 = fields.find((f) => f.key === key);
9385
+ if (grain && w.value !== null) return { key, value: bucketWindow(w.value, grain), field: field2 };
9386
+ if (field2 && String(editorKindFor(field2)) === "checkbox" && (w.value === "true" || w.value === "false")) {
9387
+ return { key, value: w.value === "true", field: field2 };
9388
+ }
9389
+ return { key, value: w.value, field: field2 };
9390
+ }
9391
+ function filterWithTrail(fields, base, trail) {
9392
+ if (trail.length === 0) return base;
9393
+ if (!base || !isRuleFilter2(base)) {
9394
+ const flat = { ...base ?? {} };
9395
+ for (const w of trail) {
9396
+ const clause = trailClause(fields, w);
9397
+ flat[clause.key] = clause.value;
9398
+ }
9399
+ return flat;
9400
+ }
9401
+ const args = [base];
9402
+ for (const w of trail) {
9403
+ const clause = trailClause(fields, w);
9404
+ if (!clause.field) continue;
9405
+ const ref = { field: clause.field.id };
9406
+ const v = clause.value;
9407
+ if (v === null) args.push({ op: "not", args: [{ op: "present", args: [ref] }] });
9408
+ else if (typeof v === "object") {
9409
+ if (v.from) args.push({ op: "gte", args: [ref, { const: v.from }] });
9410
+ if (v.to) args.push({ op: "lt", args: [ref, { const: v.to }] });
9411
+ } else args.push({ op: "eq", args: [ref, { const: v }] });
9412
+ }
9413
+ return { op: "and", args };
9414
+ }
9415
+ function useDrillAnswers(args) {
9416
+ const client = useRecordsClient15();
9417
+ const { tableId, question, enabled, version } = args;
9418
+ const [answers, setAnswers] = useState27({});
9419
+ const [error, setError] = useState27(null);
9420
+ const askKey2 = JSON.stringify({ by: question.by, across: question.across ?? null, show: question.show, filter: args.filter ?? null });
9421
+ useEffect23(() => {
9422
+ if (!enabled || question.by.length === 0) return;
9423
+ const asked2 = JSON.parse(askKey2);
9424
+ const measures = asked2.show.map(measureFor).filter((m) => m !== null);
9425
+ if (!measures.some((m) => m.op === "count")) measures.unshift({ op: "count" });
9426
+ let cancelled = false;
9427
+ setAnswers({});
9428
+ setError(null);
9429
+ const requests = drillRequests({ by: asked2.by, across: asked2.across, show: asked2.show, where: [] });
9430
+ void Promise.all(
9431
+ requests.map(async (request) => {
9432
+ const time = request.by.find((ref) => parseDimensionRef(ref).grain !== null) ?? null;
9433
+ const plain = request.by.filter((ref) => ref !== time);
9434
+ const grain = time ? parseDimensionRef(time) : null;
9435
+ const got = await client.recordAggregate({
9436
+ table_id: tableId,
9437
+ groupBy: plain,
9438
+ measures,
9439
+ bucket: grain && grain.grain ? { key: grain.key, by: grain.grain } : null,
9440
+ ...asked2.filter ? { filter: asked2.filter } : {},
9441
+ limit: 200
9442
+ });
9443
+ if (!got.ok) return { request, error: got.error.message || "The groups could not be read." };
9444
+ const rows = (got.data ?? []).map((row) => {
9445
+ const groups = {};
9446
+ for (const ref of plain) groups[ref] = row.groups[ref] ?? null;
9447
+ if (time && grain) groups[time] = row.groups[grain.key] ?? null;
9448
+ return { groups, measures: row.measures, row_count: row.row_count };
9449
+ });
9450
+ return { request, rows };
9451
+ })
9452
+ ).then((results) => {
9453
+ if (cancelled) return;
9454
+ const failed = results.find((r) => "error" in r);
9455
+ if (failed) {
9456
+ setError(failed.error);
9457
+ return;
9458
+ }
9459
+ const out = {};
9460
+ for (const r of results) if ("rows" in r) out[r.request.key] = r.rows;
9461
+ setAnswers(out);
9462
+ });
9463
+ return () => {
9464
+ cancelled = true;
9465
+ };
9466
+ }, [client, tableId, askKey2, enabled, version, question.by.length]);
9467
+ return { answers, error };
9468
+ }
9469
+ function useGridDrillQuestion(args) {
9470
+ const { fields, presentation, filter } = args;
9471
+ const choiceKeys = useMemo16(() => fields.filter((f) => isChoiceField(f) && !f.multi).map((f) => f.key), [fields]);
9472
+ const options = useChoiceOptions(fields, args.enabled ? choiceKeys : []);
9473
+ const dimensions = useMemo16(() => drillDimensionsFor(fields, options), [fields, options]);
9474
+ const measures = useMemo16(() => drillMeasuresFor(fields), [fields]);
9475
+ const saved = useMemo16(() => questionFromGrouping(presentation.grouping), [presentation.grouping]);
9476
+ const url = useDrillUrlState({ fallback: saved });
9477
+ const question = useMemo16(() => {
9478
+ const known = (ref) => dimensions.some((d) => d.key === parseDimensionRef(ref).key);
9479
+ const show = url.question.show.filter((key) => measures.some((m) => m.key === key));
9480
+ return {
9481
+ ...url.question,
9482
+ by: url.question.by.filter(known),
9483
+ across: url.question.across && known(url.question.across) ? url.question.across : null,
9484
+ show: show.length > 0 ? show : ["count"],
9485
+ where: url.question.where.filter((w) => known(w.dim))
9486
+ };
9487
+ }, [url.question, dimensions, measures]);
9488
+ const enabled = args.enabled && dimensions.length > 0;
9489
+ const trailFilter = useMemo16(
9490
+ () => enabled ? filterWithTrail(fields, filter, question.where) : filter,
9491
+ [enabled, fields, filter, question.where]
9492
+ );
9493
+ return { enabled, dimensions, measures, question, setQuestion: url.setQuestion, trailFilter };
9494
+ }
9495
+ function useGridDrillConfig(args) {
9496
+ const { tableId, state, presentation, onPresentationChange, version } = args;
9497
+ const { enabled, dimensions, measures, question, setQuestion, trailFilter } = state;
9498
+ const { answers, error } = useDrillAnswers({ tableId, question, filter: trailFilter, version, enabled });
9499
+ return useMemo16(() => {
9500
+ if (!enabled) return null;
9501
+ return {
9502
+ dimensions,
9503
+ measures,
9504
+ question,
9505
+ answers,
9506
+ error,
9507
+ rootLabel: "All records",
9508
+ rowNoun: "record",
9509
+ onQuestionChange: (next) => {
9510
+ setQuestion(next);
9511
+ if (onPresentationChange) {
9512
+ const grouping = groupingFromQuestion(next, presentation.grouping);
9513
+ const { grouping: _dropped, ...rest } = presentation;
9514
+ onPresentationChange(grouping ? { ...rest, grouping } : rest);
9515
+ }
9516
+ }
9517
+ };
9518
+ }, [enabled, dimensions, measures, question, answers, error, setQuestion, onPresentationChange, presentation]);
9519
+ }
9520
+
9238
9521
  // src/Enrich.tsx
9239
- import { useCallback as useCallback12, useEffect as useEffect23, useMemo as useMemo16, useState as useState27 } from "react";
9522
+ import { useCallback as useCallback12, useEffect as useEffect24, useMemo as useMemo17, useState as useState28 } from "react";
9240
9523
  import {
9241
9524
  useFields as useFields3,
9242
- useRecordsClient as useRecordsClient15,
9525
+ useRecordsClient as useRecordsClient16,
9243
9526
  useTable as useTable2
9244
9527
  } from "@ai-matrx/records/react";
9245
9528
  import {
@@ -9336,9 +9619,9 @@ function EnrichBadge({ cell, onPin, className }) {
9336
9619
  ] });
9337
9620
  }
9338
9621
  function useEnrichCells(tableId, recordIds) {
9339
- const client = useRecordsClient15();
9340
- const [cells, setCells] = useState27(/* @__PURE__ */ new Map());
9341
- const [error, setError] = useState27(null);
9622
+ const client = useRecordsClient16();
9623
+ const [cells, setCells] = useState28(/* @__PURE__ */ new Map());
9624
+ const [error, setError] = useState28(null);
9342
9625
  const key = (recordIds ?? []).join(",");
9343
9626
  const refresh = useCallback12(async () => {
9344
9627
  if (!tableId || !recordIds || recordIds.length === 0) {
@@ -9355,24 +9638,24 @@ function useEnrichCells(tableId, recordIds) {
9355
9638
  for (const cell of answered.data) next.set(`${cell.record_id}:${cell.field_key}`, cell);
9356
9639
  setCells(next);
9357
9640
  }, [client, tableId, key]);
9358
- useEffect23(() => {
9641
+ useEffect24(() => {
9359
9642
  void refresh();
9360
9643
  }, [refresh]);
9361
9644
  return { cells, refresh, error };
9362
9645
  }
9363
9646
  var NEVER = "Fill it in once and leave it alone";
9364
9647
  function EnrichPanel({ tableId, fieldId, className }) {
9365
- const client = useRecordsClient15();
9648
+ const client = useRecordsClient16();
9366
9649
  const host = useRecordsUi();
9367
9650
  const table = useTable2(tableId);
9368
9651
  const fields = useFields3(tableId);
9369
9652
  const rights = useTableRights(table.data);
9370
- const [rows, setRows] = useState27(null);
9371
- const [error, setError] = useState27(null);
9372
- const [busy, setBusy] = useState27(null);
9373
- const [outcome, setOutcome] = useState27(null);
9374
- const [preview, setPreview] = useState27(null);
9375
- const [draft, setDraft] = useState27({});
9653
+ const [rows, setRows] = useState28(null);
9654
+ const [error, setError] = useState28(null);
9655
+ const [busy, setBusy] = useState28(null);
9656
+ const [outcome, setOutcome] = useState28(null);
9657
+ const [preview, setPreview] = useState28(null);
9658
+ const [draft, setDraft] = useState28({});
9376
9659
  const load = useCallback12(async () => {
9377
9660
  const answered = await client.enrichments({ table_id: tableId });
9378
9661
  if (!answered.ok) {
@@ -9382,14 +9665,14 @@ function EnrichPanel({ tableId, fieldId, className }) {
9382
9665
  setError(null);
9383
9666
  setRows(answered.data);
9384
9667
  }, [client, tableId]);
9385
- useEffect23(() => {
9668
+ useEffect24(() => {
9386
9669
  void load();
9387
9670
  }, [load]);
9388
- const shown3 = useMemo16(
9671
+ const shown3 = useMemo17(
9389
9672
  () => fieldId ? (rows ?? []).filter((r) => r.field_id === fieldId) : rows ?? [],
9390
9673
  [rows, fieldId]
9391
9674
  );
9392
- const fieldByKey = useMemo16(() => {
9675
+ const fieldByKey = useMemo17(() => {
9393
9676
  const map = /* @__PURE__ */ new Map();
9394
9677
  for (const f of fields.data ?? []) map.set(f.key, f);
9395
9678
  return map;
@@ -9859,7 +10142,7 @@ function columnForField(field2, editing, mayWriteRow, whyNotRow, look, onAskWhoC
9859
10142
  }
9860
10143
 
9861
10144
  // src/PastePreview.tsx
9862
- import { useState as useState28 } from "react";
10145
+ import { useState as useState29 } from "react";
9863
10146
  import { Badge as Badge8, Button as Button23, Separator as Separator2 } from "@ai-matrx/design-system";
9864
10147
  import { Fragment as Fragment12, jsx as jsx35, jsxs as jsxs30 } from "react/jsx-runtime";
9865
10148
  function PastePreview({
@@ -9870,10 +10153,10 @@ function PastePreview({
9870
10153
  onCancel,
9871
10154
  onAddOptions
9872
10155
  }) {
9873
- const [busy, setBusy] = useState28(false);
9874
- const [outcome, setOutcome] = useState28(null);
9875
- const [adding, setAdding] = useState28(null);
9876
- const [addFailed, setAddFailed] = useState28(null);
10156
+ const [busy, setBusy] = useState29(false);
10157
+ const [outcome, setOutcome] = useState29(null);
10158
+ const [adding, setAdding] = useState29(null);
10159
+ const [addFailed, setAddFailed] = useState29(null);
9877
10160
  const nothingToDo = plan.cells === 0;
9878
10161
  return /* @__PURE__ */ jsx35(
9879
10162
  "div",
@@ -10056,8 +10339,8 @@ function confirmLabel(plan, noun, nounPlural) {
10056
10339
  }
10057
10340
 
10058
10341
  // src/gridActions.tsx
10059
- import { useCallback as useCallback13, useEffect as useEffect24, useMemo as useMemo17, useState as useState29 } from "react";
10060
- import { useRecordsClient as useRecordsClient16 } from "@ai-matrx/records/react";
10342
+ import { useCallback as useCallback13, useEffect as useEffect25, useMemo as useMemo18, useState as useState30 } from "react";
10343
+ import { useRecordsClient as useRecordsClient17 } from "@ai-matrx/records/react";
10061
10344
  import { actionRefusals } from "@ai-matrx/records";
10062
10345
  import { Button as Button24, ConfirmDialog as ConfirmDialog2, cn as cn19 } from "@ai-matrx/design-system";
10063
10346
  import { jsx as jsx36, jsxs as jsxs31 } from "react/jsx-runtime";
@@ -10066,10 +10349,10 @@ function rowActionsChanged(tableId) {
10066
10349
  for (const listener of actionListeners.get(tableId) ?? []) listener();
10067
10350
  }
10068
10351
  function useTableActions(tableId, enabled) {
10069
- const client = useRecordsClient16();
10070
- const [actions, setActions] = useState29([]);
10071
- const [error, setError] = useState29(null);
10072
- const [loaded, setLoaded] = useState29(false);
10352
+ const client = useRecordsClient17();
10353
+ const [actions, setActions] = useState30([]);
10354
+ const [error, setError] = useState30(null);
10355
+ const [loaded, setLoaded] = useState30(false);
10073
10356
  const reload = useCallback13(async () => {
10074
10357
  if (!enabled) return;
10075
10358
  const answered = await client.rowActions({ table_id: tableId });
@@ -10082,10 +10365,10 @@ function useTableActions(tableId, enabled) {
10082
10365
  setError(null);
10083
10366
  setActions(answered.data?.actions ?? []);
10084
10367
  }, [client, tableId, enabled]);
10085
- useEffect24(() => {
10368
+ useEffect25(() => {
10086
10369
  void reload();
10087
10370
  }, [reload]);
10088
- useEffect24(() => {
10371
+ useEffect25(() => {
10089
10372
  if (!enabled) return;
10090
10373
  const listener = () => void reload();
10091
10374
  const set = actionListeners.get(tableId) ?? /* @__PURE__ */ new Set();
@@ -10095,7 +10378,7 @@ function useTableActions(tableId, enabled) {
10095
10378
  set.delete(listener);
10096
10379
  };
10097
10380
  }, [tableId, enabled, reload]);
10098
- return useMemo17(() => {
10381
+ return useMemo18(() => {
10099
10382
  const isAgent = (a) => a.kind === "agent";
10100
10383
  return {
10101
10384
  runnable: actions.filter((a) => !isAgent(a) && a.runnable !== false && a.id),
@@ -10137,12 +10420,12 @@ function plural2(n, one, many) {
10137
10420
  return `${n} ${n === 1 ? one : many}`;
10138
10421
  }
10139
10422
  function useActionRunner(args) {
10140
- const client = useRecordsClient16();
10423
+ const client = useRecordsClient17();
10141
10424
  const { rows, fields, reload, noun, nounPlural } = args;
10142
10425
  const onRan = args.onRan;
10143
- const [asking, setAsking] = useState29(null);
10144
- const [busy, setBusy] = useState29(null);
10145
- const [outcome, setOutcome] = useState29(null);
10426
+ const [asking, setAsking] = useState30(null);
10427
+ const [busy, setBusy] = useState30(null);
10428
+ const [outcome, setOutcome] = useState30(null);
10146
10429
  const perform = useCallback13(
10147
10430
  async (action, ids) => {
10148
10431
  if (!action.id || ids.length === 0) return;
@@ -10411,8 +10694,8 @@ function useTableToolbarSheetExtras() {
10411
10694
  }
10412
10695
 
10413
10696
  // src/GridLayoutMenu.tsx
10414
- import { useEffect as useEffect25, useState as useState30 } from "react";
10415
- import { useRecordsClient as useRecordsClient17 } from "@ai-matrx/records/react";
10697
+ import { useEffect as useEffect26, useState as useState31 } from "react";
10698
+ import { useRecordsClient as useRecordsClient18 } from "@ai-matrx/records/react";
10416
10699
  import {
10417
10700
  Button as Button25,
10418
10701
  DropdownMenu as DropdownMenu2,
@@ -10427,12 +10710,12 @@ import {
10427
10710
  } from "@ai-matrx/design-system";
10428
10711
  import { Fragment as Fragment14, jsx as jsx39, jsxs as jsxs33 } from "react/jsx-runtime";
10429
10712
  function useStoreGridLayout(tableId) {
10430
- const client = useRecordsClient17();
10431
- const [answer, setAnswer] = useState30({
10713
+ const client = useRecordsClient18();
10714
+ const [answer, setAnswer] = useState31({
10432
10715
  layout: null,
10433
10716
  error: null
10434
10717
  });
10435
- useEffect25(() => {
10718
+ useEffect26(() => {
10436
10719
  let alive = true;
10437
10720
  void client.gridLayout({ table_id: tableId, view_id: null }).then((answered) => {
10438
10721
  if (!alive) return;
@@ -10530,7 +10813,7 @@ function GridLayoutMenu({
10530
10813
  }
10531
10814
 
10532
10815
  // src/gridActionsHeader.tsx
10533
- import { useState as useState33 } from "react";
10816
+ import { useState as useState34 } from "react";
10534
10817
  import {
10535
10818
  Button as Button27,
10536
10819
  Dialog as Dialog4,
@@ -10547,8 +10830,8 @@ import {
10547
10830
  } from "@ai-matrx/design-system";
10548
10831
 
10549
10832
  // src/RowActionsEditor.tsx
10550
- import { useCallback as useCallback14, useEffect as useEffect27, useMemo as useMemo18, useState as useState32 } from "react";
10551
- import { useFields as useFields4, useRecords as useRecords3, useRecordsClient as useRecordsClient19 } from "@ai-matrx/records/react";
10833
+ import { useCallback as useCallback14, useEffect as useEffect28, useMemo as useMemo19, useState as useState33 } from "react";
10834
+ import { useFields as useFields4, useRecords as useRecords3, useRecordsClient as useRecordsClient20 } from "@ai-matrx/records/react";
10552
10835
  import {
10553
10836
  Badge as Badge9,
10554
10837
  BasicInput as BasicInput11,
@@ -10565,8 +10848,8 @@ import {
10565
10848
  } from "@ai-matrx/design-system";
10566
10849
 
10567
10850
  // src/rowActionPreview.tsx
10568
- import { useEffect as useEffect26, useState as useState31 } from "react";
10569
- import { useRecordsClient as useRecordsClient18 } from "@ai-matrx/records/react";
10851
+ import { useEffect as useEffect27, useState as useState32 } from "react";
10852
+ import { useRecordsClient as useRecordsClient19 } from "@ai-matrx/records/react";
10570
10853
  import { cn as cn20 } from "@ai-matrx/design-system";
10571
10854
  import { jsx as jsx40, jsxs as jsxs34 } from "react/jsx-runtime";
10572
10855
  function isComputed(field2) {
@@ -10617,10 +10900,10 @@ var RESULT_WORDS = {
10617
10900
  unknown: "a value"
10618
10901
  };
10619
10902
  function useFormulaReadings(tableId, formulas) {
10620
- const client = useRecordsClient18();
10621
- const [readings, setReadings] = useState31({});
10903
+ const client = useRecordsClient19();
10904
+ const [readings, setReadings] = useState32({});
10622
10905
  const key = formulas.join("\0");
10623
- useEffect26(() => {
10906
+ useEffect27(() => {
10624
10907
  if (!tableId) return;
10625
10908
  let live = true;
10626
10909
  for (const text of formulas) {
@@ -10780,20 +11063,20 @@ function RowActionsSection({
10780
11063
  className,
10781
11064
  startAdding = false
10782
11065
  }) {
10783
- const client = useRecordsClient19();
11066
+ const client = useRecordsClient20();
10784
11067
  const fields = useFields4(tableId);
10785
11068
  const records = useRecords3(tableId, { pageSize: 20 });
10786
- const [actions, setActions] = useState32([]);
10787
- const [stale, setStale] = useState32(0);
10788
- const [loaded, setLoaded] = useState32(false);
10789
- const [readError, setReadError] = useState32(null);
10790
- const [saveError, setSaveError] = useState32(null);
10791
- const [saving, setSaving] = useState32(false);
10792
- const [editing, setEditing] = useState32(null);
10793
- const [retiring, setRetiring] = useState32(null);
10794
- const [retired, setRetired] = useState32(null);
10795
- const [colors, setColors] = useState32([]);
10796
- const [addStarted, setAddStarted] = useState32(false);
11069
+ const [actions, setActions] = useState33([]);
11070
+ const [stale, setStale] = useState33(0);
11071
+ const [loaded, setLoaded] = useState33(false);
11072
+ const [readError, setReadError] = useState33(null);
11073
+ const [saveError, setSaveError] = useState33(null);
11074
+ const [saving, setSaving] = useState33(false);
11075
+ const [editing, setEditing] = useState33(null);
11076
+ const [retiring, setRetiring] = useState33(null);
11077
+ const [retired, setRetired] = useState33(null);
11078
+ const [colors, setColors] = useState33([]);
11079
+ const [addStarted, setAddStarted] = useState33(false);
10797
11080
  const reload = useCallback14(async () => {
10798
11081
  const answered = await client.rowActions({ table_id: tableId });
10799
11082
  setLoaded(true);
@@ -10805,10 +11088,10 @@ function RowActionsSection({
10805
11088
  setActions(answered.data?.actions ?? []);
10806
11089
  setStale((answered.data?.stale ?? []).length);
10807
11090
  }, [client, tableId]);
10808
- useEffect27(() => {
11091
+ useEffect28(() => {
10809
11092
  void reload();
10810
11093
  }, [reload]);
10811
- useEffect27(() => {
11094
+ useEffect28(() => {
10812
11095
  let live = true;
10813
11096
  void client.tableDecorations({ table_id: tableId }).then((answered) => {
10814
11097
  if (live && answered.ok) setColors(answered.data?.colors ?? []);
@@ -10853,7 +11136,7 @@ function RowActionsSection({
10853
11136
  if (await declare2(next)) setRetired(null);
10854
11137
  };
10855
11138
  const allFields = fields.data ?? [];
10856
- useEffect27(() => {
11139
+ useEffect28(() => {
10857
11140
  if (!startAdding || addStarted || !loaded || readError) return;
10858
11141
  setAddStarted(true);
10859
11142
  setEditing("new");
@@ -11000,10 +11283,10 @@ function ActionForm({
11000
11283
  onSave,
11001
11284
  className
11002
11285
  }) {
11003
- const [draft, setDraft] = useState32(() => draftOf(original));
11286
+ const [draft, setDraft] = useState33(() => draftOf(original));
11004
11287
  const host = useRecordsUi();
11005
- const [previewId, setPreviewId] = useState32(rows[0]?.id ?? "");
11006
- const settable = useMemo18(() => settableFields(fields), [fields]);
11288
+ const [previewId, setPreviewId] = useState33(rows[0]?.id ?? "");
11289
+ const settable = useMemo19(() => settableFields(fields), [fields]);
11007
11290
  const previewRow = rows.find((r) => r.id === previewId) ?? rows[0] ?? null;
11008
11291
  const candidate = actionOf(draft, original);
11009
11292
  const complete = draft.steps.every((s) => s.field !== "");
@@ -11232,7 +11515,7 @@ function ActionsHeaderControls({
11232
11515
  mayManage,
11233
11516
  whyNotManage
11234
11517
  }) {
11235
- const [open, setOpen] = useState33(null);
11518
+ const [open, setOpen] = useState34(null);
11236
11519
  return /* @__PURE__ */ jsxs36(Fragment15, { children: [
11237
11520
  mayManage ? /* @__PURE__ */ jsx42(
11238
11521
  Button27,
@@ -11295,8 +11578,8 @@ function ActionsHeaderControls({
11295
11578
  }
11296
11579
 
11297
11580
  // src/gridUndo.tsx
11298
- import { useCallback as useCallback15, useEffect as useEffect28, useLayoutEffect, useMemo as useMemo19, useRef as useRef13, useState as useState34, useSyncExternalStore } from "react";
11299
- import { useRecordsClient as useRecordsClient20 } from "@ai-matrx/records/react";
11581
+ import { useCallback as useCallback15, useEffect as useEffect29, useLayoutEffect, useMemo as useMemo20, useRef as useRef13, useState as useState35, useSyncExternalStore } from "react";
11582
+ import { useRecordsClient as useRecordsClient21 } from "@ai-matrx/records/react";
11300
11583
  import { announceRecordChanged as announceRecordChanged2 } from "@ai-matrx/records/core";
11301
11584
  import { Button as Button28 } from "@ai-matrx/design-system";
11302
11585
  import { createUndoStack, popRedo, popUndo, pushUndo } from "@ai-matrx/design-system/data-table";
@@ -11316,13 +11599,13 @@ function changesFor(step2, direction) {
11316
11599
  return changes;
11317
11600
  }
11318
11601
  function useGridUndo(args) {
11319
- const client = useRecordsClient20();
11602
+ const client = useRecordsClient21();
11320
11603
  const { tableId, reload, forget } = args;
11321
- const [held, setHeld] = useState34(() => ({ stack: createUndoStack(args.depth ?? 100), steps: /* @__PURE__ */ new Map() }));
11604
+ const [held, setHeld] = useState35(() => ({ stack: createUndoStack(args.depth ?? 100), steps: /* @__PURE__ */ new Map() }));
11322
11605
  const heldRef = useRef13(held);
11323
11606
  heldRef.current = held;
11324
- const [busy, setBusy] = useState34(false);
11325
- const [notice, setNotice] = useState34(null);
11607
+ const [busy, setBusy] = useState35(false);
11608
+ const [notice, setNotice] = useState35(null);
11326
11609
  const counter = useRef13(0);
11327
11610
  const dismiss = useCallback15(() => setNotice(null), []);
11328
11611
  const push = useCallback15((step2) => {
@@ -11390,7 +11673,7 @@ function useGridUndo(args) {
11390
11673
  );
11391
11674
  const undo = useCallback15(() => apply("undo"), [apply]);
11392
11675
  const redo = useCallback15(() => apply("redo"), [apply]);
11393
- return useMemo19(
11676
+ return useMemo20(
11394
11677
  () => ({
11395
11678
  push,
11396
11679
  undo,
@@ -11413,7 +11696,7 @@ function useUndoSource(undo) {
11413
11696
  listeners: /* @__PURE__ */ new Set()
11414
11697
  });
11415
11698
  box.current.undo = undo;
11416
- const source = useMemo19(
11699
+ const source = useMemo20(
11417
11700
  () => ({
11418
11701
  face: () => box.current.face,
11419
11702
  subscribe: (listener) => {
@@ -11482,7 +11765,7 @@ function UndoRedoPair({ face, onUndo, onRedo }) {
11482
11765
  function UndoNotice({ undo }) {
11483
11766
  const notice = undo.notice;
11484
11767
  const dismiss = undo.dismiss;
11485
- useEffect28(() => {
11768
+ useEffect29(() => {
11486
11769
  if (!notice || notice.refusal) return;
11487
11770
  const timer = setTimeout(dismiss, 8e3);
11488
11771
  return () => clearTimeout(timer);
@@ -11514,7 +11797,7 @@ function undoKey(event) {
11514
11797
  }
11515
11798
 
11516
11799
  // src/gridAssist.tsx
11517
- import { useCallback as useCallback16, useEffect as useEffect30, useMemo as useMemo20, useRef as useRef14, useState as useState36 } from "react";
11800
+ import { useCallback as useCallback16, useEffect as useEffect31, useMemo as useMemo21, useRef as useRef14, useState as useState37 } from "react";
11518
11801
  import { wholeValueOf as wholeValueOf3 } from "@ai-matrx/records/core";
11519
11802
  import { useContentTransferCapabilities } from "@ai-matrx/design-system/content-transfer";
11520
11803
 
@@ -11584,7 +11867,7 @@ function gridContextKey(snapshot) {
11584
11867
  }
11585
11868
 
11586
11869
  // src/gridLongText.tsx
11587
- import { useEffect as useEffect29, useState as useState35 } from "react";
11870
+ import { useEffect as useEffect30, useState as useState36 } from "react";
11588
11871
  import {
11589
11872
  BasicTextarea as BasicTextarea7,
11590
11873
  Button as Button29,
@@ -11622,16 +11905,16 @@ function WholeTextDialog({
11622
11905
  onClose
11623
11906
  }) {
11624
11907
  const whole = useWholeText(target?.pointer ?? null);
11625
- const [draft, setDraft] = useState35(null);
11626
- const [cleanNote, setCleanNote] = useState35(null);
11908
+ const [draft, setDraft] = useState36(null);
11909
+ const [cleanNote, setCleanNote] = useState36(null);
11627
11910
  const renderText = useRecordsUi().renderText;
11628
- const [reading, setReading] = useState35(false);
11911
+ const [reading, setReading] = useState36(false);
11629
11912
  const startingText = target === null ? null : target.pointer ? whole.state === "ready" ? whole.text : null : typeof target.value === "string" ? target.value : target.value === null || target.value === void 0 ? "" : String(target.value);
11630
- useEffect29(() => {
11913
+ useEffect30(() => {
11631
11914
  setDraft(startingText);
11632
11915
  setCleanNote(null);
11633
11916
  }, [target?.rowId, target?.key, startingText]);
11634
- useEffect29(() => {
11917
+ useEffect30(() => {
11635
11918
  setReading(!mayWrite && Boolean(renderText));
11636
11919
  }, [target?.rowId, target?.key, mayWrite, renderText]);
11637
11920
  const open = target !== null;
@@ -11703,8 +11986,8 @@ import { jsx as jsx45 } from "react/jsx-runtime";
11703
11986
  function useGridAssist(args) {
11704
11987
  const { enabled, host, tableId, table, fields, rows, editing } = args;
11705
11988
  const reference = useContentTransferCapabilities().reference;
11706
- const [cursor, setCursor] = useState36(null);
11707
- const [whole, setWhole] = useState36(null);
11989
+ const [cursor, setCursor] = useState37(null);
11990
+ const [whole, setWhole] = useState37(null);
11708
11991
  const say2 = useCallback16(
11709
11992
  (ok, message) => ok ? host.notify?.success(message) : host.notify?.error(message),
11710
11993
  [host.notify]
@@ -11719,7 +12002,7 @@ function useGridAssist(args) {
11719
12002
  const lastKey = useRef14("");
11720
12003
  const editingAt = editing.editing;
11721
12004
  const draft = editing.draft;
11722
- useEffect30(() => {
12005
+ useEffect31(() => {
11723
12006
  if (!enabled || !onGridContext) return;
11724
12007
  const snapshot = gridContextSnapshot({
11725
12008
  tableId,
@@ -11758,7 +12041,7 @@ function useGridAssist(args) {
11758
12041
  [reference, say2]
11759
12042
  );
11760
12043
  const name = table ? tableName(table) : "";
11761
- const refFor = useMemo20(
12044
+ const refFor = useMemo21(
11762
12045
  () => ({
11763
12046
  table: () => ({
11764
12047
  id: `table:${tableId}`,
@@ -11894,8 +12177,8 @@ function useGridAssist(args) {
11894
12177
  }
11895
12178
 
11896
12179
  // src/gridBulk.tsx
11897
- import { useCallback as useCallback17, useMemo as useMemo21, useState as useState37 } from "react";
11898
- import { useRecordsClient as useRecordsClient21 } from "@ai-matrx/records/react";
12180
+ import { useCallback as useCallback17, useMemo as useMemo22, useState as useState38 } from "react";
12181
+ import { useRecordsClient as useRecordsClient22 } from "@ai-matrx/records/react";
11899
12182
  import { announceRecordChanged as announceRecordChanged3 } from "@ai-matrx/records/core";
11900
12183
  import {
11901
12184
  Button as Button30,
@@ -11949,10 +12232,10 @@ function planDuplicates(ids, rows, fields) {
11949
12232
  });
11950
12233
  }
11951
12234
  function useGridBulk(args) {
11952
- const client = useRecordsClient21();
12235
+ const client = useRecordsClient22();
11953
12236
  const { tableId, rows, fields, noun, nounPlural, reload, forget, pushUndo: pushUndo2 } = args;
11954
- const [busy, setBusy] = useState37(false);
11955
- const [refusal2, setRefusal] = useState37(null);
12237
+ const [busy, setBusy] = useState38(false);
12238
+ const [refusal2, setRefusal] = useState38(null);
11956
12239
  const send = useCallback17(
11957
12240
  async (changes) => {
11958
12241
  setBusy(true);
@@ -12017,11 +12300,11 @@ function BulkActions({
12017
12300
  nounPlural,
12018
12301
  onDone
12019
12302
  }) {
12020
- const typeable = useMemo21(() => fields.filter(fieldIsEditable), [fields]);
12021
- const [asking, setAsking] = useState37(null);
12022
- const [key, setKey] = useState37("");
12023
- const [value, setValue] = useState37(null);
12024
- const [confirmDelete, setConfirmDelete] = useState37(false);
12303
+ const typeable = useMemo22(() => fields.filter(fieldIsEditable), [fields]);
12304
+ const [asking, setAsking] = useState38(null);
12305
+ const [key, setKey] = useState38("");
12306
+ const [value, setValue] = useState38(null);
12307
+ const [confirmDelete, setConfirmDelete] = useState38(false);
12025
12308
  const field2 = typeable.find((f) => f.key === key) ?? typeable[0];
12026
12309
  const many = countOf(ids.length, noun, nounPlural);
12027
12310
  const open = (kind) => {
@@ -12122,8 +12405,8 @@ function BulkActions({
12122
12405
  }
12123
12406
 
12124
12407
  // src/handOrder.tsx
12125
- import { useEffect as useEffect31, useMemo as useMemo22, useRef as useRef15, useState as useState38 } from "react";
12126
- import { useRecordsClient as useRecordsClient22 } from "@ai-matrx/records/react";
12408
+ import { useEffect as useEffect32, useMemo as useMemo23, useRef as useRef15, useState as useState39 } from "react";
12409
+ import { useRecordsClient as useRecordsClient23 } from "@ai-matrx/records/react";
12127
12410
  import { stableFilterKey as stableFilterKey2 } from "@ai-matrx/records";
12128
12411
  import { Button as Button31, ConfirmDialog as ConfirmDialog4, Popover as Popover4, PopoverContent as PopoverContent4, PopoverTrigger as PopoverTrigger4, cn as cn22 } from "@ai-matrx/design-system";
12129
12412
 
@@ -12497,7 +12780,7 @@ function SortGlyph() {
12497
12780
  ] });
12498
12781
  }
12499
12782
  function SortStateControl({ label, line, attention = false, actions = [], mode }) {
12500
- const [open, setOpen] = useState38(false);
12783
+ const [open, setOpen] = useState39(false);
12501
12784
  return /* @__PURE__ */ jsxs40(Popover4, { open, onOpenChange: setOpen, children: [
12502
12785
  /* @__PURE__ */ jsx47(PopoverTrigger4, { asChild: true, children: /* @__PURE__ */ jsxs40(
12503
12786
  Button31,
@@ -12585,18 +12868,18 @@ function moveRow(list, from, to) {
12585
12868
  }
12586
12869
  var DOOR_PAGE_MAX = 500;
12587
12870
  function useHandOrderRows(args) {
12588
- const client = useRecordsClient22();
12871
+ const client = useRecordsClient23();
12589
12872
  const { viewId, active, page, pageSize } = args;
12590
12873
  const filter = args.filter && Object.keys(args.filter).length > 0 ? args.filter : null;
12591
12874
  const filterKey = filter ? stableFilterKey2(filter) : "";
12592
12875
  const filterNow = useRef15(filter);
12593
12876
  filterNow.current = filter;
12594
- const [answer, setAnswer] = useState38(null);
12595
- const [tick, setTick] = useState38(0);
12877
+ const [answer, setAnswer] = useState39(null);
12878
+ const [tick, setTick] = useState39(0);
12596
12879
  const limit = Math.max(1, Math.min(pageSize, DOOR_PAGE_MAX));
12597
12880
  const offset = Math.max(0, page) * limit;
12598
12881
  const key = `${viewId ?? ""}:${limit}:${offset}:${filterKey}`;
12599
- useEffect31(() => {
12882
+ useEffect32(() => {
12600
12883
  if (!active || !viewId) return;
12601
12884
  let cancelled = false;
12602
12885
  void client.readInViewOrder({ view_id: viewId, filter: filterNow.current, limit, offset }).then((result) => {
@@ -12609,7 +12892,7 @@ function useHandOrderRows(args) {
12609
12892
  cancelled = true;
12610
12893
  };
12611
12894
  }, [client, viewId, active, limit, offset, key, filterKey, args.version, tick]);
12612
- const rows = useMemo22(() => {
12895
+ const rows = useMemo23(() => {
12613
12896
  if (!active || !viewId || !answer || answer.key !== key) return null;
12614
12897
  if (answer.error) return null;
12615
12898
  return answer.rows;
@@ -12630,12 +12913,12 @@ function HandOrderDialog({
12630
12913
  more,
12631
12914
  onSaved
12632
12915
  }) {
12633
- const client = useRecordsClient22();
12634
- const [list, setList] = useState38([...items]);
12635
- const [dragging, setDragging] = useState38(null);
12636
- const [busy, setBusy] = useState38(false);
12637
- const [refused, setRefused] = useState38(null);
12638
- useEffect31(() => {
12916
+ const client = useRecordsClient23();
12917
+ const [list, setList] = useState39([...items]);
12918
+ const [dragging, setDragging] = useState39(null);
12919
+ const [busy, setBusy] = useState39(false);
12920
+ const [refused, setRefused] = useState39(null);
12921
+ useEffect32(() => {
12639
12922
  if (open) {
12640
12923
  setList([...items]);
12641
12924
  setRefused(null);
@@ -12711,6 +12994,7 @@ import { Fragment as Fragment18, jsx as jsx48, jsxs as jsxs41 } from "react/jsx-
12711
12994
  var NO_COLUMNS_YET = "This table has no columns yet";
12712
12995
  var NO_COLUMNS_WHY = "A column is what a record holds \u2014 a name, a date, an amount, a person. Add the first one and the grid appears with it; everything else on this page works the moment it exists.";
12713
12996
  var NO_SUMMARIES = Object.freeze({});
12997
+ var NO_DRILL_FIELDS = Object.freeze([]);
12714
12998
  var rowIdOf = (row) => row.id;
12715
12999
  function Grid({
12716
13000
  tableId,
@@ -12733,16 +13017,16 @@ function Grid({
12733
13017
  const toolbarSlot = useTableToolbarSlot();
12734
13018
  const fills = footer === "sticky";
12735
13019
  const host = useRecordsUi();
12736
- const client = useRecordsClient23();
13020
+ const client = useRecordsClient24();
12737
13021
  const table = useTable3(tableId);
12738
13022
  const fields = useFields5(tableId);
12739
13023
  const decorations = useTableDecorations(tableId, fields.data);
12740
- const mergedStyle = useMemo23(
13024
+ const mergedStyle = useMemo24(
12741
13025
  () => resolveTableStyle(decorations.data, fields.data ?? [], presentation.style),
12742
13026
  [decorations.data, fields.data, presentation.style]
12743
13027
  );
12744
13028
  const paintedChoices = useChoiceOptions(fields.data ?? [], choiceKeysIn(mergedStyle, fields.data ?? []));
12745
- const paint = useMemo23(
13029
+ const paint = useMemo24(
12746
13030
  () => paintByOption(mergedStyle, fields.data ?? [], paintedChoices, storedChoiceColorLookup(fields.data ?? [], colorFromTheValue)),
12747
13031
  [mergedStyle, fields.data, paintedChoices]
12748
13032
  );
@@ -12751,24 +13035,24 @@ function Grid({
12751
13035
  const toolbarFold2 = useTableToolbarFold();
12752
13036
  const sheetExtras = useTableToolbarSheetExtras();
12753
13037
  const rights = useTableRights(table.data);
12754
- const [heldOrder, setHeldOrder] = useState39(null);
13038
+ const [heldOrder, setHeldOrder] = useState40(null);
12755
13039
  const sortsKey = JSON.stringify(viewOrder?.sorts ?? []);
12756
- useEffect32(() => {
13040
+ useEffect33(() => {
12757
13041
  setHeldOrder(null);
12758
13042
  }, [viewOrder?.viewId, viewOrder?.order, sortsKey]);
12759
13043
  const viewId = viewOrder?.viewId ?? null;
12760
13044
  const order = heldOrder?.order ?? viewOrder?.order ?? null;
12761
13045
  const viewSorts = heldOrder?.sorts ?? viewOrder?.sorts ?? [];
12762
13046
  const manual = order === "manual" && viewId !== null;
12763
- const defaultSort = useMemo23(() => defaultSortOf(table.data, fields.data ?? []), [table.data, fields.data]);
12764
- const viewSort = useMemo23(() => {
13047
+ const defaultSort = useMemo24(() => defaultSortOf(table.data, fields.data ?? []), [table.data, fields.data]);
13048
+ const viewSort = useMemo24(() => {
12765
13049
  const first = viewSorts[0];
12766
13050
  if (!first) return null;
12767
13051
  return (fields.data ?? []).some((f) => f.key === first.field) ? { id: first.field, direction: first.direction } : null;
12768
13052
  }, [viewSorts, fields.data]);
12769
13053
  const openingSort = manual ? null : viewSort ?? defaultSort;
12770
13054
  const openingKey = openingSort ? `${openingSort.id}:${openingSort.direction}` : "none";
12771
- const [query, setQuery] = useState39(() => ({
13055
+ const [query, setQuery] = useState40(() => ({
12772
13056
  page: 1,
12773
13057
  pageSize,
12774
13058
  search: "",
@@ -12776,25 +13060,32 @@ function Grid({
12776
13060
  columnFilters: {},
12777
13061
  sort: openingSort
12778
13062
  }));
12779
- useEffect32(() => {
13063
+ useEffect33(() => {
12780
13064
  setQuery((held) => ({ ...held, sort: openingSort, page: 1 }));
12781
13065
  }, [openingKey]);
12782
13066
  const columnSort = query.sort;
12783
- const [page, setPage] = useState39(0);
12784
- const [searchTerm, setSearchTerm] = useState39("");
12785
- useEffect32(() => {
13067
+ const [page, setPage] = useState40(0);
13068
+ const [searchTerm, setSearchTerm] = useState40("");
13069
+ useEffect33(() => {
12786
13070
  if (!merged) return;
12787
13071
  const wanted = query.search.trim();
12788
13072
  if (wanted === searchTerm) return;
12789
13073
  const timer = setTimeout(() => setSearchTerm(wanted), 250);
12790
13074
  return () => clearTimeout(timer);
12791
13075
  }, [merged, query.search, searchTerm]);
12792
- const question = useMemo23(
13076
+ const question = useMemo24(
12793
13077
  () => merged ? storeQuestion(fields.data ?? [], filter, query.columnFilters) : { filter, refused: [] },
12794
13078
  [merged, fields.data, filter, query.columnFilters]
12795
13079
  );
13080
+ const drillState = useGridDrillQuestion({
13081
+ fields: fields.data ?? NO_DRILL_FIELDS,
13082
+ presentation,
13083
+ filter: question.filter,
13084
+ enabled: merged
13085
+ });
13086
+ const readFilter = drillState.enabled ? drillState.trailFilter : question.filter;
12796
13087
  const localQuestion = query.search.trim() !== "" || Object.values(query.columnFilters).some((value) => value !== void 0 && value !== null);
12797
- const clearQuestion = useMemo23(() => {
13088
+ const clearQuestion = useMemo24(() => {
12798
13089
  const external = Boolean(filter) && Boolean(onClearFilter);
12799
13090
  if (!localQuestion && !external) return void 0;
12800
13091
  return () => {
@@ -12802,18 +13093,18 @@ function Grid({
12802
13093
  if (external) onClearFilter?.();
12803
13094
  };
12804
13095
  }, [localQuestion, filter, onClearFilter]);
12805
- const pageSort = useMemo23(() => merged ? pageSortFor(fields.data ?? [], query.sort) : [], [merged, fields.data, query.sort]);
13096
+ const pageSort = useMemo24(() => merged ? pageSortFor(fields.data ?? [], query.sort) : [], [merged, fields.data, query.sort]);
12806
13097
  const classicRead = useRecords4(merged ? null : tableId, { pageSize, page, ...filter ? { filter } : {} });
12807
13098
  const serverRead = useRecordPage(merged && fields.data ? tableId : null, {
12808
13099
  pageSize: query.pageSize,
12809
13100
  page: Math.max(0, query.page - 1),
12810
- ...question.filter ? { filter: question.filter } : {},
13101
+ ...readFilter ? { filter: readFilter } : {},
12811
13102
  search: searchTerm,
12812
13103
  sort: pageSort,
12813
13104
  viewId: manual && pageSort.length === 0 ? viewId : null
12814
13105
  });
12815
13106
  const records = merged ? serverRead : classicRead;
12816
- const storeRows = useMemo23(() => records.data?.rows ?? [], [records.data]);
13107
+ const storeRows = useMemo24(() => records.data?.rows ?? [], [records.data]);
12817
13108
  const hand = useHandOrderRows({
12818
13109
  viewId,
12819
13110
  active: manual && !merged,
@@ -12822,15 +13113,15 @@ function Grid({
12822
13113
  filter: filter ?? null,
12823
13114
  version: records.data
12824
13115
  });
12825
- const pageRows = useMemo23(() => manual && !merged ? hand.rows ?? [] : storeRows, [manual, merged, hand.rows, storeRows]);
13116
+ const pageRows = useMemo24(() => manual && !merged ? hand.rows ?? [] : storeRows, [manual, merged, hand.rows, storeRows]);
12826
13117
  const added = useAddedRows({
12827
13118
  tableId,
12828
13119
  enabled: merged,
12829
13120
  pageRows,
12830
- pageKey: JSON.stringify([query.page, query.pageSize, searchTerm, pageSort, question.filter ?? null])
13121
+ pageKey: JSON.stringify([query.page, query.pageSize, searchTerm, pageSort, readFilter ?? null])
12831
13122
  });
12832
13123
  const rows = added.rows;
12833
- const rowIds = useMemo23(() => rows.map((row) => row.id), [rows]);
13124
+ const rowIds = useMemo24(() => rows.map((row) => row.id), [rows]);
12834
13125
  const askPerRow = Boolean(editable) && !host.rights && rights.known && !rights.write && rows.length > 0;
12835
13126
  const rowRights = useRowRights(rowIds, askPerRow);
12836
13127
  const mayWriteRow = useCallback18(
@@ -12864,7 +13155,7 @@ function Grid({
12864
13155
  });
12865
13156
  const editingNow = useRef16(editing);
12866
13157
  editingNow.current = editing;
12867
- const editingHandle = useMemo23(
13158
+ const editingHandle = useMemo24(
12868
13159
  () => new Proxy({}, {
12869
13160
  get: (_target, key) => editingNow.current[key]
12870
13161
  }),
@@ -12882,14 +13173,14 @@ function Grid({
12882
13173
  });
12883
13174
  };
12884
13175
  const storeLayout = useStoreGridLayout(tableId);
12885
- const [localLook, setLocalLook] = useState39(null);
12886
- const [localSummaries, setLocalSummaries] = useState39(null);
13176
+ const [localLook, setLocalLook] = useState40(null);
13177
+ const [localSummaries, setLocalSummaries] = useState40(null);
12887
13178
  const titleKey = table.data?.title_field ?? null;
12888
- const sortedKeys = useMemo23(
13179
+ const sortedKeys = useMemo24(
12889
13180
  () => lookColumnKeys([...fields.data ?? []].sort(compareFieldOrder).map((f) => f.key), titleKey),
12890
13181
  [fields.data, titleKey]
12891
13182
  );
12892
- const look = useMemo23(() => {
13183
+ const look = useMemo24(() => {
12893
13184
  const own2 = {
12894
13185
  rowHeight: presentation.rowHeight,
12895
13186
  frozen: presentation.frozen,
@@ -12901,8 +13192,8 @@ function Grid({
12901
13192
  return resolveLook(storeLayout.layout, own2, sortedKeys);
12902
13193
  }, [presentation, localLook, storeLayout.layout, sortedKeys]);
12903
13194
  const frozenList = look.frozen;
12904
- const frozenKeys = useMemo23(() => new Set(frozenList), [frozenList]);
12905
- const ordered = useMemo23(() => {
13195
+ const frozenKeys = useMemo24(() => new Set(frozenList), [frozenList]);
13196
+ const ordered = useMemo24(() => {
12906
13197
  const all = [...fields.data ?? []].sort(compareFieldOrder);
12907
13198
  if (frozenKeys.size === 0) return all;
12908
13199
  const pinned = frozenList.map((key) => all.find((f) => f.key === key)).filter((f) => f !== void 0);
@@ -12940,12 +13231,13 @@ function Grid({
12940
13231
  forget: editing.forget,
12941
13232
  pushUndo: undo.push
12942
13233
  });
12943
- const [selectedIds, setSelectedIds] = useState39([]);
13234
+ const [selectedIds, setSelectedIds] = useState40([]);
12944
13235
  const offerSelection = !readOnly && canWrite && (merged || tableActions.runnable.length > 0);
12945
- const [reordering, setReordering] = useState39(false);
13236
+ const [reordering, setReordering] = useState40(false);
12946
13237
  const chosenSummaries = localSummaries ?? presentation.summaries ?? NO_SUMMARIES;
12947
- const summaries = useColumnSummaries({ tableId, chosen: chosenSummaries, filter: question.filter, version: records.data });
12948
- const [duplicated, setDuplicated] = useState39(null);
13238
+ const summaries = useColumnSummaries({ tableId, chosen: chosenSummaries, filter: readFilter, version: records.data });
13239
+ const drillConfig = useGridDrillConfig({ tableId, state: drillState, presentation, onPresentationChange, version: records.data });
13240
+ const [duplicated, setDuplicated] = useState40(null);
12949
13241
  const duplicate = useCallback18(
12950
13242
  async (row) => {
12951
13243
  const document2 = row.document ?? {};
@@ -12984,7 +13276,7 @@ function Grid({
12984
13276
  },
12985
13277
  [client, fields.data, host, records, table.data, tableId, merged, added, manual, viewId, rows, viewOrder, hand, undo]
12986
13278
  );
12987
- const recordIds = useMemo23(() => rows.map((r) => r.id), [rows]);
13279
+ const recordIds = useMemo24(() => rows.map((r) => r.id), [rows]);
12988
13280
  const { cells: enrichCells, refresh: refreshEnrich } = useEnrichCells(tableId, recordIds);
12989
13281
  const pinCell = useCallback18(
12990
13282
  async (recordId, fieldKey, pinned) => {
@@ -12998,10 +13290,10 @@ function Grid({
12998
13290
  },
12999
13291
  [client, host, refreshEnrich]
13000
13292
  );
13001
- const [pastePlan, setPastePlan] = useState39(null);
13002
- const [deleting, setDeleting] = useState39(null);
13003
- const [deleteBusy, setDeleteBusy] = useState39(false);
13004
- const [archived, setArchived] = useState39(null);
13293
+ const [pastePlan, setPastePlan] = useState40(null);
13294
+ const [deleting, setDeleting] = useState40(null);
13295
+ const [deleteBusy, setDeleteBusy] = useState40(false);
13296
+ const [archived, setArchived] = useState40(null);
13005
13297
  const choiceOptions = useRef16(/* @__PURE__ */ new Map());
13006
13298
  const loadChoiceOptions = useCallback18(
13007
13299
  async (fieldList) => {
@@ -13017,7 +13309,7 @@ function Grid({
13017
13309
  },
13018
13310
  [client]
13019
13311
  );
13020
- const pasteableKeys = useMemo23(
13312
+ const pasteableKeys = useMemo24(
13021
13313
  () => ordered.filter((f) => fieldIsEditable(f)).map((f) => f.key),
13022
13314
  [ordered]
13023
13315
  );
@@ -13269,7 +13561,7 @@ function Grid({
13269
13561
  records.reload();
13270
13562
  return { written, readBack, missing, refusals };
13271
13563
  }, [pastePlan, client, tableId, records, merged, applyPasteAsOne]);
13272
- const columnIds = useMemo23(() => ordered.map((field2) => field2.key), [ordered]);
13564
+ const columnIds = useMemo24(() => ordered.map((field2) => field2.key), [ordered]);
13273
13565
  const writeLook = useCallback18(
13274
13566
  (next) => onPresentationChange?.(next),
13275
13567
  [onPresentationChange]
@@ -13301,7 +13593,7 @@ function Grid({
13301
13593
  [host, tableId, table.data, fields.data]
13302
13594
  );
13303
13595
  const hiddenKeys = presentation.hiddenFields;
13304
- const shownKeys = useMemo23(
13596
+ const shownKeys = useMemo24(
13305
13597
  () => hiddenKeys && hiddenKeys.length > 0 ? columnIds.filter((k) => !hiddenKeys.includes(k)) : columnIds,
13306
13598
  [columnIds, hiddenKeys]
13307
13599
  );
@@ -13374,7 +13666,7 @@ function Grid({
13374
13666
  choose: chooseSummary
13375
13667
  }
13376
13668
  });
13377
- const [addRefused, setAddRefused] = useState39(null);
13669
+ const [addRefused, setAddRefused] = useState40(null);
13378
13670
  const mayAddRow = merged && !readOnly && rights.write;
13379
13671
  const addRowHere = useCallback18(async () => {
13380
13672
  setAddRefused(null);
@@ -13393,13 +13685,13 @@ function Grid({
13393
13685
  const labelsNow = useRef16(labels);
13394
13686
  labelsNow.current = labels;
13395
13687
  const labelFor = useCallback18((field2, id) => labelsNow.current(field2, id), []);
13396
- useEffect32(() => {
13688
+ useEffect33(() => {
13397
13689
  for (const field2 of ordered) {
13398
13690
  if (!pointsAtRecords(field2)) continue;
13399
13691
  for (const row of rows) for (const id of idsOf(row.document?.[field2.key])) labels(field2, id);
13400
13692
  }
13401
13693
  }, [ordered, rows, labels]);
13402
- const fieldColumns = useMemo23(
13694
+ const fieldColumns = useMemo24(
13403
13695
  () => ordered.map((field2) => ({
13404
13696
  ...columnForField(
13405
13697
  // A formula's hover text names its columns as they are called NOW (review 2, C3).
@@ -13467,7 +13759,7 @@ function Grid({
13467
13759
  };
13468
13760
  const addColumnNow = useRef16(controls.addColumn);
13469
13761
  addColumnNow.current = controls.addColumn;
13470
- const bodyColumns = useMemo23(
13762
+ const bodyColumns = useMemo24(
13471
13763
  () => withAddRowCells(
13472
13764
  withSummaryCells(
13473
13765
  // THE ONE WAY A ROW OPENS ITS RECORD (VERIFIER-17): an Open control on the first cell,
@@ -13486,7 +13778,7 @@ function Grid({
13486
13778
  [fieldColumns, onOpenRecord, table.data, merged, mayAddRow]
13487
13779
  );
13488
13780
  const isRowSelectable = useCallback18((row) => row.id !== SUMMARY_ROW.id && mayWriteRow(row.id), [mayWriteRow]);
13489
- const copyConfig = useMemo23(
13781
+ const copyConfig = useMemo24(
13490
13782
  () => table.data ? gridCopyConfig({
13491
13783
  tableId,
13492
13784
  tableName: tableName(table.data),
@@ -13496,7 +13788,7 @@ function Grid({
13496
13788
  }) : null,
13497
13789
  [tableId, table.data, ordered, labelFor]
13498
13790
  );
13499
- const tableStyleProp = useMemo23(
13791
+ const tableStyleProp = useMemo24(
13500
13792
  () => tableStyleIsEmpty2(paint.style) ? null : {
13501
13793
  style: paint.style,
13502
13794
  // A choice is read as its OPTION (`paintByOption`): the rule, the value and the
@@ -13513,13 +13805,13 @@ function Grid({
13513
13805
  const offersRowActions = canWrite || Boolean(host.talkToRecord) || Boolean(!readOnly && host.runAgentAction && tableActions.agent.length > 0);
13514
13806
  const hasTalk = Boolean(host.talkToRecord);
13515
13807
  const hasAgent = Boolean(host.runAgentAction);
13516
- const headerActionList = useMemo23(
13808
+ const headerActionList = useMemo24(
13517
13809
  () => [...tableActions.runnable, ...tableActions.agent, ...tableActions.notRunnable],
13518
13810
  [tableActions.runnable, tableActions.agent, tableActions.notRunnable]
13519
13811
  );
13520
13812
  const mayManageActions = !readOnly && rights.structure;
13521
13813
  const whyNotManageActions = rights.why("structure");
13522
- const actionsHeader = useMemo23(
13814
+ const actionsHeader = useMemo24(
13523
13815
  () => /* @__PURE__ */ jsx48(
13524
13816
  ActionsHeaderControls,
13525
13817
  {
@@ -13599,8 +13891,8 @@ function Grid({
13599
13891
  );
13600
13892
  const headerHeld = useRef16(/* @__PURE__ */ new Map());
13601
13893
  const menuLatest = useRef16(/* @__PURE__ */ new Map());
13602
- const addColumnDef = useMemo23(() => addColumnColumn(() => addColumnNow.current()), []);
13603
- const drawnColumns = useMemo23(
13894
+ const addColumnDef = useMemo24(() => addColumnColumn(() => addColumnNow.current()), []);
13895
+ const drawnColumns = useMemo24(
13604
13896
  () => {
13605
13897
  const filterFor = controls.filterFor;
13606
13898
  const drawn = withHeaderMenus(
@@ -13615,10 +13907,10 @@ function Grid({
13615
13907
  const columnsHeld = useRef16(null);
13616
13908
  const columns = columnsHeld.current !== null && sameColumns(columnsHeld.current, drawnColumns) ? columnsHeld.current : drawnColumns;
13617
13909
  columnsHeld.current = columns;
13618
- const [localColumns, setLocalColumns] = useState39(
13910
+ const [localColumns, setLocalColumns] = useState40(
13619
13911
  null
13620
13912
  );
13621
- const [localWidths, setLocalWidths] = useState39(null);
13913
+ const [localWidths, setLocalWidths] = useState40(null);
13622
13914
  const changeLayout = useCallback18(
13623
13915
  (patch) => {
13624
13916
  setLocalLook((held) => ({ ...held ?? {}, ...patch }));
@@ -13632,7 +13924,7 @@ function Grid({
13632
13924
  [presentation, writeLook]
13633
13925
  );
13634
13926
  const widths = localWidths ?? presentation.widths;
13635
- const columnState = useMemo23(
13927
+ const columnState = useMemo24(
13636
13928
  () => ({
13637
13929
  order: controls.columns?.order ?? localColumns?.order ?? columnIds,
13638
13930
  hidden: controls.columns?.hidden ?? localColumns?.hidden ?? [],
@@ -13652,7 +13944,7 @@ function Grid({
13652
13944
  }),
13653
13945
  [columnIds, localColumns, widths, presentation, writeLook, controls.columns, fields.data]
13654
13946
  );
13655
- const groupingConfig = useMemo23(() => {
13947
+ const groupingConfig = useMemo24(() => {
13656
13948
  const view = presentation.grouping;
13657
13949
  const field2 = view?.field ?? null;
13658
13950
  if (field2 === null && !onPresentationChange) return null;
@@ -13688,7 +13980,7 @@ function Grid({
13688
13980
  };
13689
13981
  }, [presentation, onPresentationChange, writeLook, merged, phone]);
13690
13982
  const queryTotal = records.data?.total ?? rows.length;
13691
- const tableQuery = useMemo23(
13983
+ const tableQuery = useMemo24(
13692
13984
  () => merged ? {
13693
13985
  // THE STORE ANSWERS THE QUERY (tranche 6k): `data` is already the page.
13694
13986
  mode: "controlled",
@@ -13705,14 +13997,14 @@ function Grid({
13705
13997
  showAddLine ? added.busy : null,
13706
13998
  showSummaryLine ? [chosenSummaries, summaries.values, summaries.rowCount, summaries.loading] : null
13707
13999
  ]);
13708
- const footerRows = useMemo23(
14000
+ const footerRows = useMemo24(
13709
14001
  () => [...showAddLine ? [ADD_ROW] : [], ...showSummaryLine ? [SUMMARY_ROW] : []],
13710
14002
  // `footerFace`, `ordered` and the summaries' operations are what the footer's cells draw.
13711
14003
  // eslint-disable-next-line react-hooks/exhaustive-deps
13712
14004
  [showAddLine, showSummaryLine, footerFace, ordered, summaries.operations, summaries.askOperations]
13713
14005
  );
13714
14006
  const coverageTotal = typeof records.data?.total === "number" ? records.data.total : null;
13715
- const tableCoverage = useMemo23(
14007
+ const tableCoverage = useMemo24(
13716
14008
  () => ({
13717
14009
  answeredBy: merged ? "source" : "client",
13718
14010
  ...merged && coverageTotal !== null ? { matched: coverageTotal } : {},
@@ -13725,7 +14017,7 @@ function Grid({
13725
14017
  sheetNow.current = { merged, writeRange, editing, fields: fields.data ?? [], rows, mayWriteRow, notify: host.notify };
13726
14018
  const hasNotify = Boolean(host.notify);
13727
14019
  const readOnlyReason = !editable || !rights.known || rights.write ? "Editing is off here, so this table can be copied but not changed." : rights.why("write");
13728
- const spreadsheetConfig = useMemo23(
14020
+ const spreadsheetConfig = useMemo24(
13729
14021
  () => canWrite && editable ? {
13730
14022
  enabled: true,
13731
14023
  writableColumnIds: pasteableKeys,
@@ -13799,7 +14091,7 @@ function Grid({
13799
14091
  const editingBusy = editing.busy;
13800
14092
  const addRecord = editing.addRecord;
13801
14093
  const phoneSheetTools = merged && phone ? controls.sheetTools : null;
13802
- const tableToolbar = useMemo23(
14094
+ const tableToolbar = useMemo24(
13803
14095
  () => ({
13804
14096
  search: true,
13805
14097
  searchPlaceholder: "Search records",
@@ -14189,7 +14481,7 @@ function Grid({
14189
14481
  window: WINDOW_OFF,
14190
14482
  ...controls.contextMenu ? { contextMenu: controls.contextMenu } : {},
14191
14483
  spreadsheet: spreadsheetConfig,
14192
- ...groupingConfig ? { grouping: groupingConfig } : {},
14484
+ ...drillConfig ? { drill: drillConfig } : groupingConfig ? { grouping: groupingConfig } : {},
14193
14485
  columnState,
14194
14486
  ...look.rowHeight ? { rowHeight: look.rowHeight } : {},
14195
14487
  fitToWidth: look.fit === "fit",
@@ -14371,8 +14663,8 @@ function withHeaderMenus(columns, menuFor, filterFor) {
14371
14663
  }
14372
14664
 
14373
14665
  // src/ExportMenu.tsx
14374
- import { useState as useState40 } from "react";
14375
- import { useFields as useFields6, useRecords as useRecords5, useRecordsClient as useRecordsClient24 } from "@ai-matrx/records/react";
14666
+ import { useState as useState41 } from "react";
14667
+ import { useFields as useFields6, useRecords as useRecords5, useRecordsClient as useRecordsClient25 } from "@ai-matrx/records/react";
14376
14668
  import { exportCsv, exportXlsx, wholeValueOf as wholeValueOf4, withWholeValues } from "@ai-matrx/records/core";
14377
14669
  import { AlchemyMenu } from "@ai-matrx/alchemy/react";
14378
14670
  import { Button as Button33, cn as cn24 } from "@ai-matrx/design-system";
@@ -14407,11 +14699,11 @@ function download(name, mime, bytes) {
14407
14699
  URL.revokeObjectURL(url);
14408
14700
  }
14409
14701
  function ExportMenu({ tableId, rows, label, className }) {
14410
- const client = useRecordsClient24();
14702
+ const client = useRecordsClient25();
14411
14703
  const host = useRecordsUi();
14412
14704
  const fields = useFields6(tableId);
14413
14705
  const page = useRecords5(tableId, { pageSize: 500 });
14414
- const [failure, setFailure] = useState40(null);
14706
+ const [failure, setFailure] = useState41(null);
14415
14707
  const labels = useRecordLabels(fields.data ?? void 0);
14416
14708
  const records = rows ?? page.data?.rows ?? [];
14417
14709
  const name = label ?? "records";
@@ -14497,8 +14789,8 @@ function ExportMenu({ tableId, rows, label, className }) {
14497
14789
  }
14498
14790
 
14499
14791
  // src/ImportWizard.tsx
14500
- import { useCallback as useCallback19, useEffect as useEffect33, useMemo as useMemo24, useState as useState41 } from "react";
14501
- import { useFields as useFields7, useRecordsClient as useRecordsClient25, useTable as useTable4 } from "@ai-matrx/records/react";
14792
+ import { useCallback as useCallback19, useEffect as useEffect34, useMemo as useMemo25, useState as useState42 } from "react";
14793
+ import { useFields as useFields7, useRecordsClient as useRecordsClient26, useTable as useTable4 } from "@ai-matrx/records/react";
14502
14794
  import {
14503
14795
  importCsv,
14504
14796
  importXlsx
@@ -14579,36 +14871,36 @@ function lineInYourFile(dataRow) {
14579
14871
  return dataRow + 1;
14580
14872
  }
14581
14873
  function ImportWizard({ tableId, onDone, onWrote, className }) {
14582
- const client = useRecordsClient25();
14874
+ const client = useRecordsClient26();
14583
14875
  const table = useTable4(tableId);
14584
14876
  const fields = useFields7(tableId);
14585
14877
  const rights = useTableRights(table.data);
14586
- const [phase, setPhase] = useState41("waiting");
14587
- const [problem, setProblem] = useState41(null);
14588
- const [parsed, setParsed] = useState41(null);
14589
- const [rows, setRows] = useState41([]);
14590
- const [plan, setPlan] = useState41(null);
14591
- const [mapping, setMapping] = useState41({});
14592
- const [dedupeKey, setDedupeKey] = useState41("");
14593
- const [onDuplicate, setOnDuplicate] = useState41("skip");
14594
- const [unmapped, setUnmapped] = useState41("propose");
14595
- const [fileName, setFileName] = useState41("");
14596
- const [fileHash, setFileHash] = useState41(null);
14597
- const [fileBytes, setFileBytes] = useState41(null);
14598
- const [format, setFormat] = useState41("csv");
14599
- const [outcomes, setOutcomes] = useState41([]);
14600
- const [progress, setProgress] = useState41(0);
14601
- const [summary, setSummary] = useState41(null);
14602
- const [proposals, setProposals] = useState41([]);
14603
- const [alreadyRan, setAlreadyRan] = useState41(null);
14604
- const [columnsAdded, setColumnsAdded] = useState41(null);
14605
- const [show, setShow] = useState41("all");
14606
- const [ledger, setLedger] = useState41(null);
14607
- const [runs, setRuns] = useState41(null);
14608
- const [openRun, setOpenRun] = useState41(null);
14609
- const [runRows, setRunRows] = useState41(null);
14610
- const [runProblem, setRunProblem] = useState41(null);
14611
- const [runsProblem, setRunsProblem] = useState41(null);
14878
+ const [phase, setPhase] = useState42("waiting");
14879
+ const [problem, setProblem] = useState42(null);
14880
+ const [parsed, setParsed] = useState42(null);
14881
+ const [rows, setRows] = useState42([]);
14882
+ const [plan, setPlan] = useState42(null);
14883
+ const [mapping, setMapping] = useState42({});
14884
+ const [dedupeKey, setDedupeKey] = useState42("");
14885
+ const [onDuplicate, setOnDuplicate] = useState42("skip");
14886
+ const [unmapped, setUnmapped] = useState42("propose");
14887
+ const [fileName, setFileName] = useState42("");
14888
+ const [fileHash, setFileHash] = useState42(null);
14889
+ const [fileBytes, setFileBytes] = useState42(null);
14890
+ const [format, setFormat] = useState42("csv");
14891
+ const [outcomes, setOutcomes] = useState42([]);
14892
+ const [progress, setProgress] = useState42(0);
14893
+ const [summary, setSummary] = useState42(null);
14894
+ const [proposals, setProposals] = useState42([]);
14895
+ const [alreadyRan, setAlreadyRan] = useState42(null);
14896
+ const [columnsAdded, setColumnsAdded] = useState42(null);
14897
+ const [show, setShow] = useState42("all");
14898
+ const [ledger, setLedger] = useState42(null);
14899
+ const [runs, setRuns] = useState42(null);
14900
+ const [openRun, setOpenRun] = useState42(null);
14901
+ const [runRows, setRunRows] = useState42(null);
14902
+ const [runProblem, setRunProblem] = useState42(null);
14903
+ const [runsProblem, setRunsProblem] = useState42(null);
14612
14904
  const loadRuns = useCallback19(async () => {
14613
14905
  const answered = await client.imports({ table_id: tableId, limit: 10 });
14614
14906
  if (answered.ok) {
@@ -14616,7 +14908,7 @@ function ImportWizard({ tableId, onDone, onWrote, className }) {
14616
14908
  setRunsProblem(null);
14617
14909
  } else setRunsProblem(answered.error);
14618
14910
  }, [client, tableId]);
14619
- useEffect33(() => {
14911
+ useEffect34(() => {
14620
14912
  void loadRuns();
14621
14913
  }, [loadRuns]);
14622
14914
  const openRefusals = useCallback19(
@@ -14791,7 +15083,7 @@ function ImportWizard({ tableId, onDone, onWrote, className }) {
14791
15083
  onWrote?.(finished.data.rows_written);
14792
15084
  void loadRuns();
14793
15085
  }, [client, dedupeKey, fileBytes, fileHash, fileName, format, loadRuns, mapping, onDuplicate, onWrote, plan, rows, tableId, unmapped]);
14794
- const counts = useMemo24(() => {
15086
+ const counts = useMemo25(() => {
14795
15087
  let landed = 0;
14796
15088
  let duplicate = 0;
14797
15089
  let refused = 0;
@@ -14802,7 +15094,7 @@ function ImportWizard({ tableId, onDone, onWrote, className }) {
14802
15094
  }
14803
15095
  return { landed, duplicate, refused };
14804
15096
  }, [outcomes]);
14805
- const interesting = useMemo24(
15097
+ const interesting = useMemo25(
14806
15098
  () => outcomes.filter((o) => show === "all" ? o.outcome !== "landed" : o.outcome === show),
14807
15099
  [outcomes, show]
14808
15100
  );
@@ -14812,11 +15104,11 @@ function ImportWizard({ tableId, onDone, onWrote, className }) {
14812
15104
  const titleMissing = Boolean(titleKey) && titleMappedTo === null;
14813
15105
  const titleFieldLabel = (titleKey ? plan?.fields.find((f) => f.key === titleKey)?.label : null) || (titleKey ? declared2.find((f) => f.key === titleKey)?.label : null) || "the name column";
14814
15106
  const busy = phase === "reading" || phase === "planning" || phase === "declaring" || phase === "writing";
14815
- const ruleVerdicts = useMemo24(() => checkImportRules(declared2, rows, mapping), [declared2, rows, mapping]);
14816
- const ruleVerdictOf = useMemo24(() => new Map(ruleVerdicts.map((v) => [v.header, v])), [ruleVerdicts]);
15107
+ const ruleVerdicts = useMemo25(() => checkImportRules(declared2, rows, mapping), [declared2, rows, mapping]);
15108
+ const ruleVerdictOf = useMemo25(() => new Map(ruleVerdicts.map((v) => [v.header, v])), [ruleVerdicts]);
14817
15109
  const refusedByRules = ruleVerdicts.reduce((n, v) => n + v.refused, 0);
14818
- const [goAheadAnyway, setGoAheadAnyway] = useState41(false);
14819
- useEffect33(() => setGoAheadAnyway(false), [ruleVerdicts]);
15110
+ const [goAheadAnyway, setGoAheadAnyway] = useState42(false);
15111
+ useEffect34(() => setGoAheadAnyway(false), [ruleVerdicts]);
14820
15112
  const afterWrite = !busy && (phase === "done" || alreadyRan !== null || ledger !== null && ledger.seen > 0);
14821
15113
  return /* @__PURE__ */ jsxs43("div", { className: cn25("flex min-w-0 flex-col gap-2 text-xs", className), children: [
14822
15114
  /* @__PURE__ */ jsxs43("div", { className: "flex items-center gap-2", children: [
@@ -15210,12 +15502,12 @@ function ImportWizard({ tableId, onDone, onWrote, className }) {
15210
15502
  }
15211
15503
 
15212
15504
  // src/CustomFieldsSection.tsx
15213
- import { useEffect as useEffect34, useMemo as useMemo25, useRef as useRef17, useState as useState42 } from "react";
15505
+ import { useEffect as useEffect35, useMemo as useMemo26, useRef as useRef17, useState as useState43 } from "react";
15214
15506
  import {
15215
15507
  useEntityFieldMutation,
15216
15508
  useEntityFieldRights,
15217
15509
  useEntityRecord,
15218
- useRecordsClient as useRecordsClient26
15510
+ useRecordsClient as useRecordsClient27
15219
15511
  } from "@ai-matrx/records/react";
15220
15512
  import {
15221
15513
  BasicInput as BasicInput12,
@@ -15295,23 +15587,23 @@ function CustomFieldsSection({
15295
15587
  className,
15296
15588
  agentDoor
15297
15589
  }) {
15298
- const client = useRecordsClient26();
15590
+ const client = useRecordsClient27();
15299
15591
  const read = useEntityRecord(entityToken, recordId);
15300
15592
  const rights = useEntityFieldRights(entityToken);
15301
15593
  const mutation = useEntityFieldMutation();
15302
- const [editing, setEditing] = useState42(false);
15303
- const [adding, setAdding] = useState42(false);
15304
- const [newLabel, setNewLabel] = useState42("");
15305
- const [newType, setNewType] = useState42("text");
15306
- const [draft, setDraft] = useState42({});
15307
- const [removing, setRemoving] = useState42(null);
15308
- const fields = useMemo25(() => read.data?.fields ?? [], [read.data]);
15594
+ const [editing, setEditing] = useState43(false);
15595
+ const [adding, setAdding] = useState43(false);
15596
+ const [newLabel, setNewLabel] = useState43("");
15597
+ const [newType, setNewType] = useState43("text");
15598
+ const [draft, setDraft] = useState43({});
15599
+ const [removing, setRemoving] = useState43(null);
15600
+ const fields = useMemo26(() => read.data?.fields ?? [], [read.data]);
15309
15601
  const mayAdd = rights.data?.may_declare === true;
15310
15602
  const live = useRef17({ fields, rights: rights.data, loading: rights.loading, reload: read.reload, values: read.data?.custom ?? {} });
15311
- useEffect34(() => {
15603
+ useEffect35(() => {
15312
15604
  live.current = { fields, rights: rights.data, loading: rights.loading, reload: read.reload, values: read.data?.custom ?? {} };
15313
15605
  });
15314
- useEffect34(() => {
15606
+ useEffect35(() => {
15315
15607
  if (!agentDoor) return;
15316
15608
  const state = () => {
15317
15609
  const now = live.current;
@@ -15558,12 +15850,12 @@ function CustomFieldsSection({
15558
15850
  }
15559
15851
 
15560
15852
  // src/StageRules.tsx
15561
- import { useCallback as useCallback20, useEffect as useEffect35, useMemo as useMemo26, useState as useState44 } from "react";
15562
- import { useFields as useFields8, useRecordsClient as useRecordsClient27, useTable as useTable5 } from "@ai-matrx/records/react";
15853
+ import { useCallback as useCallback20, useEffect as useEffect36, useMemo as useMemo27, useState as useState45 } from "react";
15854
+ import { useFields as useFields8, useRecordsClient as useRecordsClient28, useTable as useTable5 } from "@ai-matrx/records/react";
15563
15855
  import { BasicInput as BasicInput14, BasicTextarea as BasicTextarea8, Button as Button37, Separator as Separator5, Skeleton as Skeleton3, cn as cn27 } from "@ai-matrx/design-system";
15564
15856
 
15565
15857
  // src/Condition.tsx
15566
- import { useState as useState43 } from "react";
15858
+ import { useState as useState44 } from "react";
15567
15859
  import { BasicInput as BasicInput13, Button as Button36 } from "@ai-matrx/design-system";
15568
15860
  import { Fragment as Fragment20, jsx as jsx52, jsxs as jsxs45 } from "react/jsx-runtime";
15569
15861
  var CONDITION_OPS = [
@@ -15781,7 +16073,7 @@ function ConditionGroup({
15781
16073
  className
15782
16074
  }) {
15783
16075
  const { joiner, args } = clausesOf(expr);
15784
- const [drafting, setDrafting] = useState43(null);
16076
+ const [drafting, setDrafting] = useState44(null);
15785
16077
  const nested = depth > 0;
15786
16078
  const replaceAt = (index, next) => {
15787
16079
  const nextArgs = args.slice();
@@ -15937,19 +16229,19 @@ function draftOf2(rule) {
15937
16229
  };
15938
16230
  }
15939
16231
  function StageRulesSection({ tableId, stage, className }) {
15940
- const client = useRecordsClient27();
16232
+ const client = useRecordsClient28();
15941
16233
  const table = useTable5(tableId);
15942
16234
  const rights = useTableRights(table.data);
15943
16235
  const fields = useFields8(tableId);
15944
- const [pipeline, setPipeline] = useState44(null);
15945
- const [enforcement, setEnforcement] = useState44(null);
15946
- const [asked2, setAsked] = useState44(false);
15947
- const [error, setError] = useState44(null);
15948
- const [chosen, setChosen] = useState44(stage ?? null);
15949
- const [draft, setDraft] = useState44(null);
15950
- const [preview, setPreview] = useState44(null);
15951
- const [previewError, setPreviewError] = useState44(null);
15952
- const [saving, setSaving] = useState44(false);
16236
+ const [pipeline, setPipeline] = useState45(null);
16237
+ const [enforcement, setEnforcement] = useState45(null);
16238
+ const [asked2, setAsked] = useState45(false);
16239
+ const [error, setError] = useState45(null);
16240
+ const [chosen, setChosen] = useState45(stage ?? null);
16241
+ const [draft, setDraft] = useState45(null);
16242
+ const [preview, setPreview] = useState45(null);
16243
+ const [previewError, setPreviewError] = useState45(null);
16244
+ const [saving, setSaving] = useState45(false);
15953
16245
  const load = useCallback20(async () => {
15954
16246
  const [read, mode] = await Promise.all([client.pipelineRead({ table_id: tableId }), client.stageRuleEnforcement()]);
15955
16247
  if (!read.ok) setError(read.error);
@@ -15957,18 +16249,18 @@ function StageRulesSection({ tableId, stage, className }) {
15957
16249
  if (mode.ok) setEnforcement(mode.data);
15958
16250
  setAsked(true);
15959
16251
  }, [client, tableId]);
15960
- useEffect35(() => {
16252
+ useEffect36(() => {
15961
16253
  void load();
15962
16254
  }, [load]);
15963
16255
  const stages = pipeline?.stages ?? [];
15964
16256
  const stageKey = chosen ?? stages.find((s) => !s.retired)?.key ?? null;
15965
16257
  const stageLabel = stages.find((s) => s.key === stageKey)?.label ?? stageKey ?? "";
15966
- const gates = useMemo26(() => stageKey ? gatesOf(pipeline, stageKey) : [], [pipeline, stageKey]);
15967
- const conditionFields = useMemo26(
16258
+ const gates = useMemo27(() => stageKey ? gatesOf(pipeline, stageKey) : [], [pipeline, stageKey]);
16259
+ const conditionFields = useMemo27(
15968
16260
  () => (fields.data ?? []).map((f) => ({ id: String(f.id), key: f.key, label: fieldName(f), field: f })),
15969
16261
  [fields.data]
15970
16262
  );
15971
- useEffect35(() => {
16263
+ useEffect36(() => {
15972
16264
  if (!draft || !stageKey || !draft.demands || Object.keys(draft.demands).length === 0) {
15973
16265
  setPreview(null);
15974
16266
  setPreviewError(null);
@@ -16151,7 +16443,7 @@ function Clause({
16151
16443
  fields,
16152
16444
  onChange
16153
16445
  }) {
16154
- const [replacing, setReplacing] = useState44(false);
16446
+ const [replacing, setReplacing] = useState45(false);
16155
16447
  const drawable = conditionIsDrawable(expr) || replacing;
16156
16448
  if (drawable) {
16157
16449
  return /* @__PURE__ */ jsx53(
@@ -16190,8 +16482,9 @@ function Clause({
16190
16482
  }
16191
16483
 
16192
16484
  // src/TableSettings.tsx
16193
- import { useState as useState45 } from "react";
16485
+ import { useEffect as useEffect37, useState as useState46 } from "react";
16194
16486
  import {
16487
+ useRecordsClient as useRecordsClient29,
16195
16488
  useFieldMutation as useFieldMutation3,
16196
16489
  useFields as useFields9,
16197
16490
  useTable as useTable6,
@@ -16212,10 +16505,21 @@ function TableSettings({
16212
16505
  const rights = useTableRights(table.data);
16213
16506
  const shape = useFieldMutation3();
16214
16507
  const archive = useTableArchive(tableId);
16215
- const [editing, setEditing] = useState45(null);
16216
- const [askingToDelete, setAskingToDelete] = useState45(false);
16217
- const [askingToRemove, setAskingToRemove] = useState45(null);
16218
- const [enriching, setEnriching] = useState45(null);
16508
+ const client = useRecordsClient29();
16509
+ const ui = useRecordsUi();
16510
+ useEffect37(() => {
16511
+ let live = true;
16512
+ void archive.preview().then((answer) => {
16513
+ if (live && answer?.in_progress) setAskingToDelete(true);
16514
+ });
16515
+ return () => {
16516
+ live = false;
16517
+ };
16518
+ }, [tableId]);
16519
+ const [editing, setEditing] = useState46(null);
16520
+ const [askingToDelete, setAskingToDelete] = useState46(false);
16521
+ const [askingToRemove, setAskingToRemove] = useState46(null);
16522
+ const [enriching, setEnriching] = useState46(null);
16219
16523
  if (table.error) return /* @__PURE__ */ jsx54(RefusalNotice, { error: table.error, className });
16220
16524
  if (fields.error) return /* @__PURE__ */ jsx54(RefusalNotice, { error: fields.error, className });
16221
16525
  if (!rights.structure) return /* @__PURE__ */ jsx54("p", { className: cn28("text-xs text-muted-foreground", className), children: rights.why("structure") });
@@ -16240,6 +16544,16 @@ function TableSettings({
16240
16544
  const finished = await archive.start();
16241
16545
  if (finished?.done && finished.table_archived) {
16242
16546
  setAskingToDelete(false);
16547
+ const name = finished.table_name || "The table";
16548
+ ui.notify?.success(`\u201C${name}\u201D is archived. You can restore it from Trash.`, {
16549
+ label: "Undo",
16550
+ run: () => {
16551
+ void client.recordRestore({ record_id: tableId }).then((back) => {
16552
+ if (back.ok) ui.notify?.success(`\u201C${name}\u201D is back, with everything in it.`);
16553
+ else ui.notify?.error(back.error.message);
16554
+ });
16555
+ }
16556
+ });
16243
16557
  onDeleted?.();
16244
16558
  }
16245
16559
  };
@@ -16371,31 +16685,20 @@ function TableSettings({
16371
16685
  /* @__PURE__ */ jsxs47("div", { className: "flex flex-col gap-1", children: [
16372
16686
  /* @__PURE__ */ jsx54("span", { className: "font-medium", children: "This table" }),
16373
16687
  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,
16688
+ /* @__PURE__ */ jsx54("p", { className: "text-muted-foreground", "data-archive-confirm": "table", children: archiveConfirmSentence(table.data ? `the table \u201C${tableName(table.data)}\u201D` : "this table") }),
16689
+ /* @__PURE__ */ jsx54("p", { className: "text-muted-foreground", "data-archive-state": "", children: tableArchiveSentence({
16690
+ progress: archive.progress,
16691
+ running: archive.running,
16692
+ interrupted: archive.interrupted,
16693
+ failed: Boolean(archive.error),
16694
+ slowedDown: archive.slowedDown,
16695
+ passesHere: archive.passes
16696
+ }) }),
16394
16697
  /* @__PURE__ */ jsx54("div", { className: "flex gap-1", children: archive.running ? /* @__PURE__ */ jsxs47(Fragment21, { children: [
16395
16698
  /* @__PURE__ */ jsx54(Button38, { size: "sm", variant: "destructive", disabled: true, children: "Archiving\u2026" }),
16396
16699
  /* @__PURE__ */ jsx54(Button38, { size: "sm", variant: "ghost", onClick: () => archive.stop(), children: "Stop" })
16397
16700
  ] }) : /* @__PURE__ */ jsxs47(Fragment21, { children: [
16398
- /* @__PURE__ */ jsx54(Button38, { size: "sm", variant: "destructive", onClick: () => void startArchive(), children: archive.interrupted ? "Carry on archiving" : "Archive this table" }),
16701
+ /* @__PURE__ */ jsx54(Button38, { size: "sm", variant: "destructive", onClick: () => void startArchive(), children: archive.interrupted || archive.progress?.in_progress ? "Carry on archiving" : "Archive this table" }),
16399
16702
  /* @__PURE__ */ jsx54(Button38, { size: "sm", variant: "ghost", onClick: () => setAskingToDelete(false), children: "Keep it" })
16400
16703
  ] }) })
16401
16704
  ] }) : /* @__PURE__ */ jsx54("div", { children: /* @__PURE__ */ jsx54(Button38, { size: "sm", variant: "outline", onClick: () => void askToArchive(), children: "Archive this table" }) }),
@@ -16405,22 +16708,22 @@ function TableSettings({
16405
16708
  }
16406
16709
 
16407
16710
  // src/Peek.tsx
16408
- 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";
16711
+ import { useState as useState51 } from "react";
16712
+ import { useFields as useFields11, useRecord as useRecord2, useRecordsClient as useRecordsClient33, useTable as useTable7 } from "@ai-matrx/records/react";
16410
16713
  import { AlchemyMenu as AlchemyMenu2 } from "@ai-matrx/alchemy/react";
16411
16714
 
16412
16715
  // 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";
16716
+ import { useEffect as useEffect38, useMemo as useMemo28, useState as useState47 } from "react";
16717
+ import { useRecordsClient as useRecordsClient30 } from "@ai-matrx/records/react";
16415
16718
  import { Skeleton as Skeleton4, cn as cn29 } from "@ai-matrx/design-system";
16416
16719
  import { jsx as jsx55, jsxs as jsxs48 } from "react/jsx-runtime";
16417
16720
  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
16721
  function RecordChat({ tableId, recordId, className }) {
16419
- const client = useRecordsClient28();
16722
+ const client = useRecordsClient30();
16420
16723
  const host = useRecordsUi();
16421
- const [scope, setScope] = useState46(null);
16422
- const [error, setError] = useState46(null);
16423
- useEffect36(() => {
16724
+ const [scope, setScope] = useState47(null);
16725
+ const [error, setError] = useState47(null);
16726
+ useEffect38(() => {
16424
16727
  let cancelled = false;
16425
16728
  setScope(null);
16426
16729
  setError(null);
@@ -16436,7 +16739,7 @@ function RecordChat({ tableId, recordId, className }) {
16436
16739
  cancelled = true;
16437
16740
  };
16438
16741
  }, [client, recordId]);
16439
- const context = useMemo27(() => {
16742
+ const context = useMemo28(() => {
16440
16743
  if (!scope) return null;
16441
16744
  return {
16442
16745
  surfaceKey: `records-ui:record-chat:${recordId}`,
@@ -16537,12 +16840,12 @@ function entriesFor(scope) {
16537
16840
  import { Button as Button41, Separator as Separator8, Skeleton as Skeleton5, cn as cn31 } from "@ai-matrx/design-system";
16538
16841
 
16539
16842
  // src/RecordForm.tsx
16540
- import { useEffect as useEffect38, useMemo as useMemo29, useRef as useRef18, useState as useState48 } from "react";
16843
+ import { useEffect as useEffect40, useMemo as useMemo30, useRef as useRef18, useState as useState49 } from "react";
16541
16844
  import {
16542
16845
  useFields as useFields10,
16543
16846
  useRecord,
16544
16847
  useRecordMutation,
16545
- useRecordsClient as useRecordsClient30
16848
+ useRecordsClient as useRecordsClient32
16546
16849
  } from "@ai-matrx/records/react";
16547
16850
  import { asWriteConflict as asWriteConflict3, predictWriteRefusals, wholeValueOf as wholeValueOf5 } from "@ai-matrx/records/core";
16548
16851
 
@@ -16580,8 +16883,8 @@ async function updateOnTheWinningVersion(client, recordId, patch, expectedVersio
16580
16883
  import { Button as Button39, Separator as Separator7, cn as cn30 } from "@ai-matrx/design-system";
16581
16884
 
16582
16885
  // 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";
16886
+ import { useEffect as useEffect39, useMemo as useMemo29, useState as useState48 } from "react";
16887
+ import { useRecordsClient as useRecordsClient31 } from "@ai-matrx/records/react";
16585
16888
  var inFlight = /* @__PURE__ */ new Map();
16586
16889
  async function ensureSystemTable(client, spec) {
16587
16890
  const cacheKey = `${client.config.organizationId}:${spec.slug}`;
@@ -16709,11 +17012,11 @@ async function declare(client, spec) {
16709
17012
  return { ok: true, data: table.data };
16710
17013
  }
16711
17014
  function useSystemTable(spec) {
16712
- const client = useRecordsClient29();
16713
- const [state, setState] = useState47({ tableId: null, loading: true, error: null });
17015
+ const client = useRecordsClient31();
17016
+ const [state, setState] = useState48({ tableId: null, loading: true, error: null });
16714
17017
  const slug = spec.slug;
16715
- const stable = useMemo28(() => spec, [slug]);
16716
- useEffect37(() => {
17018
+ const stable = useMemo29(() => spec, [slug]);
17019
+ useEffect39(() => {
16717
17020
  let cancelled = false;
16718
17021
  setState({ tableId: null, loading: true, error: null });
16719
17022
  void ensureSystemTable(client, stable).then((result) => {
@@ -16729,9 +17032,9 @@ function useSystemTable(spec) {
16729
17032
  return state;
16730
17033
  }
16731
17034
  function useRecordVersion(recordId) {
16732
- const client = useRecordsClient29();
16733
- const [version, setVersion] = useState47(null);
16734
- useEffect37(() => {
17035
+ const client = useRecordsClient31();
17036
+ const [version, setVersion] = useState48(null);
17037
+ useEffect39(() => {
16735
17038
  let cancelled = false;
16736
17039
  setVersion(null);
16737
17040
  if (!recordId) return;
@@ -16764,8 +17067,8 @@ function RecordForm({
16764
17067
  const fields = useFields10(tableId, recordType);
16765
17068
  const existing = useRecord(recordId ?? null);
16766
17069
  const mutation = useRecordMutation();
16767
- const client = useRecordsClient30();
16768
- const [edit, setEdit] = useState48({
17070
+ const client = useRecordsClient32();
17071
+ const [edit, setEdit] = useState49({
16769
17072
  saving: false,
16770
17073
  error: null,
16771
17074
  conflict: null
@@ -16779,15 +17082,15 @@ function RecordForm({
16779
17082
  setEdit((e) => ({ ...e, conflict: null }));
16780
17083
  }
16781
17084
  };
16782
- const [draft, setDraft] = useState48({});
16783
- const [touched, setTouched] = useState48(false);
16784
- const [changed, setChanged] = useState48({});
16785
- const [answered, setAnswered] = useState48(null);
17085
+ const [draft, setDraft] = useState49({});
17086
+ const [touched, setTouched] = useState49(false);
17087
+ const [changed, setChanged] = useState49({});
17088
+ const [answered, setAnswered] = useState49(null);
16786
17089
  const loaded = useRecordVersion(recordId ?? null);
16787
17090
  const loadedVersion = loaded.version;
16788
17091
  const changedRef = useRef18({});
16789
17092
  changedRef.current = changed;
16790
- useEffect38(() => {
17093
+ useEffect40(() => {
16791
17094
  const document3 = existing.data?.document;
16792
17095
  if (!document3) return;
16793
17096
  const mine = changedRef.current;
@@ -16797,7 +17100,7 @@ function RecordForm({
16797
17100
  return next;
16798
17101
  });
16799
17102
  }, [existing.data?.record_id, loadedVersion]);
16800
- const document2 = useMemo29(() => {
17103
+ const document2 = useMemo30(() => {
16801
17104
  const out = {};
16802
17105
  for (const [key, value] of Object.entries(draft)) {
16803
17106
  if (key.startsWith("_")) continue;
@@ -16805,7 +17108,7 @@ function RecordForm({
16805
17108
  }
16806
17109
  return out;
16807
17110
  }, [draft]);
16808
- const predicted = useMemo29(
17111
+ const predicted = useMemo30(
16809
17112
  () => fields.data ? predictWriteRefusals({ fields: fields.data, document: document2, ...recordType ? { recordType } : {} }) : [],
16810
17113
  [fields.data, document2, recordType]
16811
17114
  );
@@ -16988,7 +17291,7 @@ function asWords(value) {
16988
17291
  }
16989
17292
 
16990
17293
  // src/ShareControl.tsx
16991
- import { useEffect as useEffect39, useState as useState49 } from "react";
17294
+ import { useEffect as useEffect41, useState as useState50 } from "react";
16992
17295
  import { Button as Button40 } from "@ai-matrx/design-system";
16993
17296
  import { Fragment as Fragment22, jsx as jsx57, jsxs as jsxs50 } from "react/jsx-runtime";
16994
17297
  function useCanShare() {
@@ -17009,8 +17312,8 @@ function ShareControl({
17009
17312
  className
17010
17313
  }) {
17011
17314
  const host = useRecordsUi();
17012
- const [open, setOpen] = useState49(initiallyOpen);
17013
- useEffect39(() => {
17315
+ const [open, setOpen] = useState50(initiallyOpen);
17316
+ useEffect41(() => {
17014
17317
  if (initiallyOpen) setOpen(true);
17015
17318
  }, [initiallyOpen]);
17016
17319
  const asked2 = useRecordRights(may === void 0 ? subjectId : null);
@@ -17049,9 +17352,9 @@ function Peek({ tableId, recordId, onClose, className }) {
17049
17352
  const record = useRecord2(recordId, true);
17050
17353
  const may = useRecordRights(recordId);
17051
17354
  const host = useRecordsUi();
17052
- const organizationId = useRecordsClient31().config.organizationId;
17053
- const [editing, setEditing] = useState50(false);
17054
- const [talking, setTalking] = useState50(false);
17355
+ const organizationId = useRecordsClient33().config.organizationId;
17356
+ const [editing, setEditing] = useState51(false);
17357
+ const [talking, setTalking] = useState51(false);
17055
17358
  if (record.error) return /* @__PURE__ */ jsx58(RefusalNotice, { error: record.error, className });
17056
17359
  if (fields.error) return /* @__PURE__ */ jsx58(RefusalNotice, { error: fields.error, className });
17057
17360
  const document2 = record.data?.document;
@@ -17226,8 +17529,8 @@ var LOOK_WORDS = {
17226
17529
  };
17227
17530
 
17228
17531
  // 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";
17532
+ import { useEffect as useEffect45, useMemo as useMemo32, useState as useState55 } from "react";
17533
+ import { useFields as useFields13, useRecords as useRecords6, useRecordsClient as useRecordsClient36 } from "@ai-matrx/records/react";
17231
17534
  import { stableFilterKey as stableFilterKey4 } from "@ai-matrx/records";
17232
17535
  import { Button as Button45, Skeleton as Skeleton7, cn as cn34 } from "@ai-matrx/design-system";
17233
17536
  import {
@@ -17236,11 +17539,11 @@ import {
17236
17539
  } from "@ai-matrx/design-system/data-table";
17237
17540
 
17238
17541
  // src/Pipeline.tsx
17239
- import { useCallback as useCallback21, useEffect as useEffect40, useMemo as useMemo30, useRef as useRef19, useState as useState51 } from "react";
17542
+ import { useCallback as useCallback21, useEffect as useEffect42, useMemo as useMemo31, useRef as useRef19, useState as useState52 } from "react";
17240
17543
  import {
17241
17544
  mayDrag,
17242
17545
  useFields as useFields12,
17243
- useRecordsClient as useRecordsClient32
17546
+ useRecordsClient as useRecordsClient34
17244
17547
  } from "@ai-matrx/records/react";
17245
17548
  import { stableFilterKey as stableFilterKey3 } from "@ai-matrx/records";
17246
17549
  import {
@@ -17332,30 +17635,30 @@ function PipelineBoard({
17332
17635
  dateFields,
17333
17636
  className
17334
17637
  }) {
17335
- const client = useRecordsClient32();
17638
+ const client = useRecordsClient34();
17336
17639
  const fields = useFields12(tableId);
17337
17640
  const ownDecorations = useTableDecorations(style ? null : tableId);
17338
- const cardStyle = useMemo30(
17641
+ const cardStyle = useMemo31(
17339
17642
  () => style ?? resolveTableStyle(ownDecorations.data, fields.data ?? [], void 0),
17340
17643
  [style, ownDecorations.data, fields.data]
17341
17644
  );
17342
- const [definition, setDefinition] = useState51(null);
17343
- const [columns, setColumns] = useState51([]);
17344
- const [error, setError] = useState51(null);
17345
- const [loading, setLoading] = useState51(true);
17346
- const [pending, setPending] = useState51({ kind: "none" });
17347
- const [waiting, setWaiting] = useState51(/* @__PURE__ */ new Map());
17348
- const [dragging, setDragging] = useState51(null);
17349
- const [over, setOver] = useState51(null);
17645
+ const [definition, setDefinition] = useState52(null);
17646
+ const [columns, setColumns] = useState52([]);
17647
+ const [error, setError] = useState52(null);
17648
+ const [loading, setLoading] = useState52(true);
17649
+ const [pending, setPending] = useState52({ kind: "none" });
17650
+ const [waiting, setWaiting] = useState52(/* @__PURE__ */ new Map());
17651
+ const [dragging, setDragging] = useState52(null);
17652
+ const [over, setOver] = useState52(null);
17350
17653
  const alive = useRef19(true);
17351
- const [selected, setSelected] = useState51(/* @__PURE__ */ new Set());
17654
+ const [selected, setSelected] = useState52(/* @__PURE__ */ new Set());
17352
17655
  const anchor = useRef19(null);
17353
- const [versions, setVersions] = useState51(null);
17354
- const [batch, setBatch] = useState51(/* @__PURE__ */ new Map());
17355
- const [batchSaid, setBatchSaid] = useState51(null);
17356
- const [batchError, setBatchError] = useState51(null);
17357
- const [moving, setMoving] = useState51(false);
17358
- useEffect40(() => {
17656
+ const [versions, setVersions] = useState52(null);
17657
+ const [batch, setBatch] = useState52(/* @__PURE__ */ new Map());
17658
+ const [batchSaid, setBatchSaid] = useState52(null);
17659
+ const [batchError, setBatchError] = useState52(null);
17660
+ const [moving, setMoving] = useState52(false);
17661
+ useEffect42(() => {
17359
17662
  alive.current = true;
17360
17663
  return () => {
17361
17664
  alive.current = false;
@@ -17380,10 +17683,10 @@ function PipelineBoard({
17380
17683
  setWaiting(held.ok ? new Map((held.data ?? []).map((p) => [p.record_id, p])) : /* @__PURE__ */ new Map());
17381
17684
  setColumns(board.ok ? board.data ?? [] : []);
17382
17685
  }, [client, tableId, measure, filterKey]);
17383
- useEffect40(() => {
17686
+ useEffect42(() => {
17384
17687
  void reload();
17385
17688
  }, [reload]);
17386
- useEffect40(() => {
17689
+ useEffect42(() => {
17387
17690
  const ids = rows.filter((r) => mayDrag(r.level)).map((r) => r.id);
17388
17691
  if (ids.length === 0) {
17389
17692
  setVersions({ ok: true, map: /* @__PURE__ */ new Map() });
@@ -17401,7 +17704,7 @@ function PipelineBoard({
17401
17704
  };
17402
17705
  }, [client, rows]);
17403
17706
  const stageKey = definition?.stage_field ?? null;
17404
- const cardsByStage = useMemo30(() => {
17707
+ const cardsByStage = useMemo31(() => {
17405
17708
  const map = /* @__PURE__ */ new Map();
17406
17709
  if (!stageKey) return map;
17407
17710
  for (const row of rows) {
@@ -17412,12 +17715,12 @@ function PipelineBoard({
17412
17715
  }, [rows, stageKey, definition?.stages]);
17413
17716
  const unplaced = cardsByStage.get(UNPLACED) ?? [];
17414
17717
  const all = fields.data ?? [];
17415
- const titleField = useMemo30(
17718
+ const titleField = useMemo31(
17416
17719
  () => cardTitleField(all, titleKey ?? null, [stageKey]),
17417
17720
  [all, stageKey, titleKey]
17418
17721
  );
17419
17722
  const unplacedLabels = useRecordLabels(titleField ? [titleField] : []);
17420
- const measurable = useMemo30(
17723
+ const measurable = useMemo31(
17421
17724
  () => all.filter((f) => ["number", "currency", "percentage"].includes(String(f.type ?? ""))),
17422
17725
  [all]
17423
17726
  );
@@ -17742,7 +18045,7 @@ function Held({
17742
18045
  onFill,
17743
18046
  onAsk
17744
18047
  }) {
17745
- const [draft, setDraft] = useState51({});
18048
+ const [draft, setDraft] = useState52({});
17746
18049
  if (pending.kind === "asking") {
17747
18050
  return /* @__PURE__ */ jsx60("p", { className: "px-2 py-1 text-xs text-muted-foreground", children: "Asking\u2026" });
17748
18051
  }
@@ -17980,8 +18283,8 @@ function batchSentence(moved, waiting, notMoved, label) {
17980
18283
  }
17981
18284
 
17982
18285
  // 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";
18286
+ import { useEffect as useEffect43, useState as useState53 } from "react";
18287
+ import { useFieldMutation as useFieldMutation4, useRecordsClient as useRecordsClient35, useTable as useTable8 } from "@ai-matrx/records/react";
17985
18288
  import { BasicInput as BasicInput15, Button as Button44, Label as Label13 } from "@ai-matrx/design-system";
17986
18289
 
17987
18290
  // src/BuildOrAsk.tsx
@@ -18031,6 +18334,18 @@ function columnDeclarationFor(need, label, options, fields) {
18031
18334
  if (need.starter.type === "datetime") return { ...base, parity_type: "datetime", kind: "date" };
18032
18335
  return { ...base, parity_type: "attachment" };
18033
18336
  }
18337
+ var askedFor = /* @__PURE__ */ new Map();
18338
+ var askKey = (tableId, layout) => `${tableId}:${layout}`;
18339
+ function useAskedColumnLands(layout, tableId, fields, chosen, offerable, onMade) {
18340
+ const wanted = askedFor.get(askKey(tableId, layout));
18341
+ const landed = wanted && !chosen ? offerable(fields).find((f) => fieldName(f).trim().toLowerCase() === wanted.trim().toLowerCase()) : void 0;
18342
+ const key = landed?.key ?? null;
18343
+ useEffect43(() => {
18344
+ if (!key) return;
18345
+ askedFor.delete(askKey(tableId, layout));
18346
+ onMade(key);
18347
+ }, [key, tableId, layout]);
18348
+ }
18034
18349
  var NO_ASSISTANT = "Asking in words needs the AI assistant, which this screen is not connected to.";
18035
18350
  function ViewNeeds({ layout, tableId, fields, onMade, className }) {
18036
18351
  const need = viewNeedFor(layout);
@@ -18038,12 +18353,12 @@ function ViewNeeds({ layout, tableId, fields, onMade, className }) {
18038
18353
  const rights = useTableRights(table.data);
18039
18354
  const host = useRecordsUi();
18040
18355
  const mutation = useFieldMutation4();
18041
- const client = useRecordsClient33();
18356
+ const client = useRecordsClient35();
18042
18357
  const taken = fields.map((f) => fieldName(f));
18043
- const [label, setLabel] = useState52(() => freeColumnName(need?.starter.label ?? "", taken));
18044
- const [options, setOptions] = useState52(() => [...need?.starter.options ?? []]);
18045
- const [refused, setRefused] = useState52(null);
18046
- const [pendingId, setPendingId] = useState52(null);
18358
+ const [label, setLabel] = useState53(() => freeColumnName(need?.starter.label ?? "", taken));
18359
+ const [options, setOptions] = useState53(() => [...need?.starter.options ?? []]);
18360
+ const [refused, setRefused] = useState53(null);
18361
+ const [pendingId, setPendingId] = useState53(null);
18047
18362
  if (!need) return null;
18048
18363
  const name = label.trim() === "" ? need.starter.label : label.trim();
18049
18364
  const choices = options.map((o) => o.trim()).filter((o) => o !== "");
@@ -18121,7 +18436,12 @@ function ViewNeeds({ layout, tableId, fields, onMade, className }) {
18121
18436
  editor,
18122
18437
  noAgentSentence: NO_ASSISTANT,
18123
18438
  suggestion,
18124
- ...host.onAskForOne ? { onAsk: () => host.onAskForOne?.({ kind: "column", tableId, suggestion }) } : {},
18439
+ ...host.onAskForOne ? {
18440
+ onAsk: () => {
18441
+ askedFor.set(askKey(tableId, layout), name);
18442
+ host.onAskForOne?.({ kind: "column", tableId, suggestion });
18443
+ }
18444
+ } : {},
18125
18445
  children: rights.structure ? `${need.missing} ${need.does(name)}` : need.missing
18126
18446
  }
18127
18447
  ),
@@ -18132,7 +18452,7 @@ function ViewNeeds({ layout, tableId, fields, onMade, className }) {
18132
18452
  }
18133
18453
 
18134
18454
  // src/GalleryCover.tsx
18135
- import { useEffect as useEffect41, useState as useState53 } from "react";
18455
+ import { useEffect as useEffect44, useState as useState54 } from "react";
18136
18456
  import { useOptionalRecordsClient as useOptionalRecordsClient7 } from "@ai-matrx/records/react";
18137
18457
  import { Fragment as Fragment25, jsx as jsx63 } from "react/jsx-runtime";
18138
18458
  function isImageAddress(value) {
@@ -18153,8 +18473,8 @@ function GalleryCover({ field: field2, value }) {
18153
18473
  function FileCover({ recordId }) {
18154
18474
  const client = useOptionalRecordsClient7();
18155
18475
  const host = useRecordsUi();
18156
- const [read, setRead] = useState53(null);
18157
- useEffect41(() => {
18476
+ const [read, setRead] = useState54(null);
18477
+ useEffect44(() => {
18158
18478
  let cancelled = false;
18159
18479
  if (!client) {
18160
18480
  setRead({ fileId: recordId, name: "" });
@@ -18187,18 +18507,18 @@ function FileCover({ recordId }) {
18187
18507
  import { Fragment as Fragment26, jsx as jsx64, jsxs as jsxs56 } from "react/jsx-runtime";
18188
18508
  var NO_FIELDS = [];
18189
18509
  function useViewRecords(view, pageSize = 200, filter, viewId) {
18190
- const client = useRecordsClient34();
18510
+ const client = useRecordsClient36();
18191
18511
  const table = useRecords6(view.ruleId ? null : view.subject, {
18192
18512
  pageSize,
18193
18513
  ...filter ? { filter } : {}
18194
18514
  });
18195
- const [ruled, setRuled] = useState54({
18515
+ const [ruled, setRuled] = useState55({
18196
18516
  rows: [],
18197
18517
  loading: Boolean(view.ruleId),
18198
18518
  error: null
18199
18519
  });
18200
18520
  const ruleId = view.ruleId ?? null;
18201
- useEffect42(() => {
18521
+ useEffect45(() => {
18202
18522
  if (!ruleId) return;
18203
18523
  let cancelled = false;
18204
18524
  setRuled({ rows: [], loading: true, error: null });
@@ -18214,7 +18534,7 @@ function useViewRecords(view, pageSize = 200, filter, viewId) {
18214
18534
  }, [client, ruleId, pageSize]);
18215
18535
  const asked2 = stableFilterKey4(filter ?? null);
18216
18536
  const fromView = asked2 !== "{}" && (asked2 === stableFilterKey4(view.where ?? null) || asked2 === stableFilterKey4(view.filters ?? null));
18217
- const tableRows = useMemo31(() => table.data?.rows ?? [], [table.data]);
18537
+ const tableRows = useMemo32(() => table.data?.rows ?? [], [table.data]);
18218
18538
  const manual = view.order === "manual" && Boolean(viewId) && !ruleId;
18219
18539
  const hand = useHandOrderRows({
18220
18540
  viewId: viewId ?? null,
@@ -18281,11 +18601,11 @@ function ViewSwitcher({
18281
18601
  className
18282
18602
  }) {
18283
18603
  const toolbarSlot = useTableToolbarSlot();
18284
- const [layout, setLayout] = useState54(view.layout);
18604
+ const [layout, setLayout] = useState55(view.layout);
18285
18605
  const hostLayouts = useRecordsUi().layouts ?? [];
18286
18606
  const drawnByHost = hostLayout ? hostLayouts.find((h) => h.id === hostLayout) ?? null : null;
18287
- const [local, setLocal] = useState54({});
18288
- useEffect42(() => {
18607
+ const [local, setLocal] = useState55({});
18608
+ useEffect45(() => {
18289
18609
  setLayout(view.layout);
18290
18610
  setLocal({});
18291
18611
  }, [view.layout, view.name, view.subject]);
@@ -18393,12 +18713,12 @@ function offerableFields(all, want) {
18393
18713
  });
18394
18714
  }
18395
18715
  function useStageField(tableId) {
18396
- const client = useRecordsClient34();
18397
- const [stage, setStage] = useState54({
18716
+ const client = useRecordsClient36();
18717
+ const [stage, setStage] = useState55({
18398
18718
  asked: false,
18399
18719
  key: null
18400
18720
  });
18401
- useEffect42(() => {
18721
+ useEffect45(() => {
18402
18722
  let cancelled = false;
18403
18723
  setStage({ asked: false, key: null });
18404
18724
  void client.tableStageField({ table_id: tableId }).then((r) => {
@@ -18437,10 +18757,21 @@ function Board({
18437
18757
  const records = useViewRecords(view, pageSize, filter, viewId ?? null);
18438
18758
  const stage = useStageField(view.subject);
18439
18759
  const decorations = useTableDecorations(view.subject);
18440
- const style = useMemo31(
18760
+ const style = useMemo32(
18441
18761
  () => resolveTableStyle(decorations.data, fields.data ?? [], view.presentation?.style),
18442
18762
  [decorations.data, fields.data, view.presentation?.style]
18443
18763
  );
18764
+ const askedLayout = view.layout === "grid" ? "kanban" : view.layout;
18765
+ const askedKind = askedLayout === "kanban" ? "choice" : askedLayout === "calendar" ? "date" : "file";
18766
+ const askedChosen = askedLayout === "kanban" ? view.groupField : askedLayout === "calendar" ? view.dateField : view.imageField;
18767
+ useAskedColumnLands(
18768
+ askedLayout,
18769
+ view.subject,
18770
+ fields.data ?? NO_FIELDS,
18771
+ askedChosen,
18772
+ (all2) => offerableFields(all2, askedKind),
18773
+ (key) => onChange(askedLayout === "kanban" ? { groupField: key } : askedLayout === "calendar" ? { dateField: key } : { imageField: key })
18774
+ );
18444
18775
  if (fields.error) return /* @__PURE__ */ jsx64(RefusalNotice, { error: fields.error });
18445
18776
  if (records.error) return /* @__PURE__ */ jsx64(RefusalNotice, { error: records.error });
18446
18777
  if (fields.loading && !fields.data || records.loading && records.rows.length === 0) return /* @__PURE__ */ jsx64(Skeleton7, { className: "h-40 w-full" });
@@ -18615,10 +18946,10 @@ function Kanban({
18615
18946
  note,
18616
18947
  style
18617
18948
  }) {
18618
- const groupFields = useMemo31(() => [groupField], [groupField]);
18949
+ const groupFields = useMemo32(() => [groupField], [groupField]);
18619
18950
  const labels = useRecordLabels(groupFields);
18620
18951
  const options = useChoiceOptions(groupFields, isChoiceField(groupField) ? [groupField.key] : []).get(groupField.key);
18621
- const columns = useMemo31(() => {
18952
+ const columns = useMemo32(() => {
18622
18953
  const map = /* @__PURE__ */ new Map();
18623
18954
  const order = (options ?? []).map((o) => o.label);
18624
18955
  for (const label of order) map.set(label, []);
@@ -18649,7 +18980,7 @@ function Calendar({
18649
18980
  note,
18650
18981
  style
18651
18982
  }) {
18652
- const { days, undated } = useMemo31(() => {
18983
+ const { days, undated } = useMemo32(() => {
18653
18984
  const byDay = /* @__PURE__ */ new Map();
18654
18985
  const without = [];
18655
18986
  for (const row of rows) {
@@ -18719,7 +19050,7 @@ function Gallery({
18719
19050
  onHiddenFieldsChange,
18720
19051
  remembered
18721
19052
  }) {
18722
- const hidden = useMemo31(() => new Set(hiddenFields ?? []), [hiddenFields]);
19053
+ const hidden = useMemo32(() => new Set(hiddenFields ?? []), [hiddenFields]);
18723
19054
  const shown3 = fields.filter((field2) => !hidden.has(field2.key));
18724
19055
  const imageField = imageKey ? fields.find((field2) => field2.key === imageKey) : void 0;
18725
19056
  const dims = GALLERY_SIZE[size];
@@ -18793,7 +19124,7 @@ function Card2({
18793
19124
  dates
18794
19125
  }) {
18795
19126
  const host = useRecordsUi();
18796
- const wanted = useMemo31(
19127
+ const wanted = useMemo32(
18797
19128
  () => field2 && pointsAtRecords(field2) ? [field2] : NO_FIELDS,
18798
19129
  [field2]
18799
19130
  );
@@ -18821,7 +19152,7 @@ function Card2({
18821
19152
  }
18822
19153
 
18823
19154
  // src/ArchivedView.tsx
18824
- import { useCallback as useCallback22, useEffect as useEffect43, useState as useState55 } from "react";
19155
+ import { useCallback as useCallback22, useEffect as useEffect46, useState as useState56 } from "react";
18825
19156
  import {
18826
19157
  ARCHIVE_LANES,
18827
19158
  ARCHIVE_LANE_LABEL,
@@ -18830,7 +19161,7 @@ import {
18830
19161
  archivedByLine,
18831
19162
  emptyArchiveLine
18832
19163
  } from "@ai-matrx/records";
18833
- import { useFields as useFields14, useRecordsClient as useRecordsClient35, useTable as useTable9 } from "@ai-matrx/records/react";
19164
+ import { useFields as useFields14, useRecordsClient as useRecordsClient37, useTable as useTable9 } from "@ai-matrx/records/react";
18834
19165
  import { Button as Button46, Skeleton as Skeleton8, cn as cn35 } from "@ai-matrx/design-system";
18835
19166
  import { jsx as jsx65, jsxs as jsxs57 } from "react/jsx-runtime";
18836
19167
  var ARCHIVE_MEANS = "Archiving never destroys anything. A record you remove from the grid waits here until somebody brings it back.";
@@ -18849,17 +19180,17 @@ function ArchivedView({
18849
19180
  onRestored,
18850
19181
  className
18851
19182
  }) {
18852
- const client = useRecordsClient35();
19183
+ const client = useRecordsClient37();
18853
19184
  const table = useTable9(tableId);
18854
19185
  const rights = useTableRights(table.data);
18855
19186
  const fields = useFields14(tableId);
18856
- const [lane, setLane] = useState55(laneFromHost ?? DEFAULT_ARCHIVE_LANE);
18857
- const [rows, setRows] = useState55([]);
18858
- const [loading, setLoading] = useState55(true);
18859
- const [error, setError] = useState55(null);
18860
- const [restoring, setRestoring] = useState55(null);
18861
- const [refusal2, setRefusal] = useState55(null);
18862
- useEffect43(() => {
19187
+ const [lane, setLane] = useState56(laneFromHost ?? DEFAULT_ARCHIVE_LANE);
19188
+ const [rows, setRows] = useState56([]);
19189
+ const [loading, setLoading] = useState56(true);
19190
+ const [error, setError] = useState56(null);
19191
+ const [restoring, setRestoring] = useState56(null);
19192
+ const [refusal2, setRefusal] = useState56(null);
19193
+ useEffect46(() => {
18863
19194
  if (laneFromHost) setLane(laneFromHost);
18864
19195
  }, [laneFromHost]);
18865
19196
  const read = useCallback22(async () => {
@@ -18874,7 +19205,7 @@ function ArchivedView({
18874
19205
  }
18875
19206
  setLoading(false);
18876
19207
  }, [client, tableId, lane, pageSize]);
18877
- useEffect43(() => {
19208
+ useEffect46(() => {
18878
19209
  void read();
18879
19210
  }, [read]);
18880
19211
  const pick = (next) => {
@@ -18956,13 +19287,13 @@ function ArchivedView({
18956
19287
  }
18957
19288
 
18958
19289
  // src/ArchivedDisclosure.tsx
18959
- import { useCallback as useCallback23, useEffect as useEffect44, useState as useState56 } from "react";
19290
+ import { useCallback as useCallback23, useEffect as useEffect47, useState as useState57 } from "react";
18960
19291
  import {
18961
19292
  emptyPortalArchiveLine,
18962
19293
  portalConfirmLine,
18963
19294
  portalTitleTypedBack
18964
19295
  } from "@ai-matrx/records";
18965
- import { useRecordsClient as useRecordsClient36 } from "@ai-matrx/records/react";
19296
+ import { useRecordsClient as useRecordsClient38 } from "@ai-matrx/records/react";
18966
19297
  import { BasicInput as BasicInput16, Button as Button47, Skeleton as Skeleton9, cn as cn36 } from "@ai-matrx/design-system";
18967
19298
  import { jsx as jsx66, jsxs as jsxs58 } from "react/jsx-runtime";
18968
19299
  var ARCHIVED_NEVER_DESTROYED = "Archiving never destroys anything. What you put away waits here until somebody brings it back.";
@@ -18974,7 +19305,7 @@ function ArchivedDisclosure({
18974
19305
  children,
18975
19306
  className
18976
19307
  }) {
18977
- const [open, setOpen] = useState56(defaultOpen);
19308
+ const [open, setOpen] = useState57(defaultOpen);
18978
19309
  const toggle = () => {
18979
19310
  const next = !open;
18980
19311
  setOpen(next);
@@ -19007,14 +19338,14 @@ function ArchivedPortals({
19007
19338
  defaultOpen,
19008
19339
  className
19009
19340
  }) {
19010
- const client = useRecordsClient36();
19011
- const [rows, setRows] = useState56(null);
19012
- const [error, setError] = useState56(null);
19013
- const [confirming, setConfirming] = useState56(null);
19014
- const [typed, setTyped] = useState56("");
19015
- const [restoring, setRestoring] = useState56(null);
19016
- const [refusal2, setRefusal] = useState56(null);
19017
- const [said, setSaid] = useState56(null);
19341
+ const client = useRecordsClient38();
19342
+ const [rows, setRows] = useState57(null);
19343
+ const [error, setError] = useState57(null);
19344
+ const [confirming, setConfirming] = useState57(null);
19345
+ const [typed, setTyped] = useState57("");
19346
+ const [restoring, setRestoring] = useState57(null);
19347
+ const [refusal2, setRefusal] = useState57(null);
19348
+ const [said, setSaid] = useState57(null);
19018
19349
  const read = useCallback23(async () => {
19019
19350
  const answered = await client.listPortals({ archived: "archived" });
19020
19351
  if (answered.ok) {
@@ -19025,7 +19356,7 @@ function ArchivedPortals({
19025
19356
  setError(answered.error);
19026
19357
  }
19027
19358
  }, [client]);
19028
- useEffect44(() => {
19359
+ useEffect47(() => {
19029
19360
  void read();
19030
19361
  }, [read, refreshToken]);
19031
19362
  const restore = async (portal) => {
@@ -19141,8 +19472,8 @@ function ArchivedPortals({
19141
19472
  }
19142
19473
 
19143
19474
  // src/ViewBar.tsx
19144
- import { useCallback as useCallback25, useEffect as useEffect45, useState as useState57 } from "react";
19145
- import { useRecordsClient as useRecordsClient37 } from "@ai-matrx/records/react";
19475
+ import { useCallback as useCallback25, useEffect as useEffect48, useState as useState58 } from "react";
19476
+ import { useRecordsClient as useRecordsClient39 } from "@ai-matrx/records/react";
19146
19477
  import { Badge as Badge12, Button as Button48, Input as Input2, Popover as Popover5, PopoverContent as PopoverContent5, PopoverTrigger as PopoverTrigger5, Skeleton as Skeleton10, cn as cn37 } from "@ai-matrx/design-system";
19147
19478
 
19148
19479
  // src/seedOnce.ts
@@ -19165,17 +19496,17 @@ function seedIsSatisfied(seed, views) {
19165
19496
  return seed.isDefault === true && views.some((v) => v.isDefault);
19166
19497
  }
19167
19498
  function ViewBar({ tableId, activeViewId, onActiveView, seed, settings, onViews, className }) {
19168
- const client = useRecordsClient37();
19499
+ const client = useRecordsClient39();
19169
19500
  const claimSeed = useSeedGuard();
19170
19501
  const table = useTable10(tableId);
19171
19502
  const rights = useTableRights(table.data);
19172
- const [views, setViews] = useState57(null);
19173
- const [error, setError] = useState57(null);
19174
- const [unavailable, setUnavailable] = useState57(false);
19175
- const [active, setActive] = useState57(activeViewId ?? null);
19176
- const [naming, setNaming] = useState57(false);
19177
- const [draftName, setDraftName] = useState57("");
19178
- const [open, setOpen] = useState57(false);
19503
+ const [views, setViews] = useState58(null);
19504
+ const [error, setError] = useState58(null);
19505
+ const [unavailable, setUnavailable] = useState58(false);
19506
+ const [active, setActive] = useState58(activeViewId ?? null);
19507
+ const [naming, setNaming] = useState58(false);
19508
+ const [draftName, setDraftName] = useState58("");
19509
+ const [open, setOpen] = useState58(false);
19179
19510
  const seedKey = JSON.stringify(seed ?? []);
19180
19511
  const readViews = useCallback25(async () => {
19181
19512
  const result = await client.views({ table_id: tableId });
@@ -19217,10 +19548,10 @@ function ViewBar({ tableId, activeViewId, onActiveView, seed, settings, onViews,
19217
19548
  setViews(mine);
19218
19549
  onViews?.(mine);
19219
19550
  }, [client, readViews, tableId, seedKey]);
19220
- useEffect45(() => {
19551
+ useEffect48(() => {
19221
19552
  void load();
19222
19553
  }, [load]);
19223
- useEffect45(() => {
19554
+ useEffect48(() => {
19224
19555
  if (!views || views.length === 0) return;
19225
19556
  const chosen = views.find((v) => v.id === (activeViewId ?? active)) ?? defaultViewOf(views) ?? views[0];
19226
19557
  if (chosen.id !== active) setActive(chosen.id);
@@ -19323,8 +19654,8 @@ function ViewBar({ tableId, activeViewId, onActiveView, seed, settings, onViews,
19323
19654
  }
19324
19655
 
19325
19656
  // src/ProposalRow.tsx
19326
- import { useState as useState58 } from "react";
19327
- import { useRecordsClient as useRecordsClient38 } from "@ai-matrx/records/react";
19657
+ import { useState as useState59 } from "react";
19658
+ import { useRecordsClient as useRecordsClient40 } from "@ai-matrx/records/react";
19328
19659
  import { Badge as Badge13, Button as Button49, cn as cn38 } from "@ai-matrx/design-system";
19329
19660
  import { jsx as jsx68, jsxs as jsxs60 } from "react/jsx-runtime";
19330
19661
  var ACT_WORD = PROPOSED_CHANGE_ACT_LABEL;
@@ -19337,10 +19668,10 @@ function ProposalRow({
19337
19668
  onSettled,
19338
19669
  className
19339
19670
  }) {
19340
- const client = useRecordsClient38();
19341
- const [settled, setSettled] = useState58(outcome ?? null);
19342
- const [busy, setBusy] = useState58(false);
19343
- const [confirming, setConfirming] = useState58(false);
19671
+ const client = useRecordsClient40();
19672
+ const [settled, setSettled] = useState59(outcome ?? null);
19673
+ const [busy, setBusy] = useState59(false);
19674
+ const [confirming, setConfirming] = useState59(false);
19344
19675
  async function applyThroughTheStore() {
19345
19676
  if (change.act === "add") {
19346
19677
  if (!change.table) {
@@ -19425,14 +19756,14 @@ function ProposalRow({
19425
19756
  }
19426
19757
 
19427
19758
  // src/ActionInbox.tsx
19428
- import { useCallback as useCallback27, useEffect as useEffect47, useMemo as useMemo33, useRef as useRef21, useState as useState60 } from "react";
19429
- import { useRecordsClient as useRecordsClient40 } from "@ai-matrx/records/react";
19759
+ import { useCallback as useCallback27, useEffect as useEffect50, useMemo as useMemo34, useRef as useRef21, useState as useState61 } from "react";
19760
+ import { useRecordsClient as useRecordsClient42 } from "@ai-matrx/records/react";
19430
19761
  import { Badge as Badge15, Button as Button51, Checkbox as Checkbox7, Skeleton as Skeleton12, cn as cn40 } from "@ai-matrx/design-system";
19431
19762
  import { toggleSelection as toggleSelection2 } from "@ai-matrx/design-system/data-table";
19432
19763
 
19433
19764
  // src/ChecklistRunner.tsx
19434
- import { useCallback as useCallback26, useEffect as useEffect46, useMemo as useMemo32, useState as useState59 } from "react";
19435
- import { useRecordsClient as useRecordsClient39, useTable as useTable11 } from "@ai-matrx/records/react";
19765
+ import { useCallback as useCallback26, useEffect as useEffect49, useMemo as useMemo33, useState as useState60 } from "react";
19766
+ import { useRecordsClient as useRecordsClient41, useTable as useTable11 } from "@ai-matrx/records/react";
19436
19767
  import { Badge as Badge14, BasicInput as BasicInput17, BasicTextarea as BasicTextarea9, Button as Button50, Skeleton as Skeleton11, cn as cn39 } from "@ai-matrx/design-system";
19437
19768
  import { Fragment as Fragment27, jsx as jsx69, jsxs as jsxs61 } from "react/jsx-runtime";
19438
19769
  var DUE_WORD = DUE_STATE_LABEL;
@@ -19446,16 +19777,16 @@ function ChecklistRunner({
19446
19777
  offerToStart,
19447
19778
  className
19448
19779
  }) {
19449
- const client = useRecordsClient39();
19780
+ const client = useRecordsClient41();
19450
19781
  const table = useTable11(tableId ?? null);
19451
19782
  const rights = useTableRights(table.data);
19452
- const [runs, setRuns] = useState59(null);
19453
- const [activeId, setActiveId] = useState59(runId ?? null);
19454
- const [steps, setSteps] = useState59(null);
19455
- const [templates, setTemplates] = useState59(null);
19456
- const [error, setError] = useState59(null);
19457
- const [busy, setBusy] = useState59(null);
19458
- const [said, setSaid] = useState59(null);
19783
+ const [runs, setRuns] = useState60(null);
19784
+ const [activeId, setActiveId] = useState60(runId ?? null);
19785
+ const [steps, setSteps] = useState60(null);
19786
+ const [templates, setTemplates] = useState60(null);
19787
+ const [error, setError] = useState60(null);
19788
+ const [busy, setBusy] = useState60(null);
19789
+ const [said, setSaid] = useState60(null);
19459
19790
  const mayStart = offerToStart ?? Boolean(recordId);
19460
19791
  const loadRuns = useCallback26(async () => {
19461
19792
  if (runId) {
@@ -19479,10 +19810,10 @@ function ChecklistRunner({
19479
19810
  (held) => held && answered.data.some((r) => r.run_id === held) ? held : answered.data[0]?.run_id ?? null
19480
19811
  );
19481
19812
  }, [client, includeClosed, recordId, runId, tableId]);
19482
- useEffect46(() => {
19813
+ useEffect49(() => {
19483
19814
  void loadRuns();
19484
19815
  }, [loadRuns]);
19485
- useEffect46(() => {
19816
+ useEffect49(() => {
19486
19817
  if (runId) setActiveId(runId);
19487
19818
  }, [runId]);
19488
19819
  const loadSteps = useCallback26(async () => {
@@ -19499,10 +19830,10 @@ function ChecklistRunner({
19499
19830
  setError(null);
19500
19831
  setSteps(answered.data);
19501
19832
  }, [client, activeId]);
19502
- useEffect46(() => {
19833
+ useEffect49(() => {
19503
19834
  void loadSteps();
19504
19835
  }, [loadSteps]);
19505
- useEffect46(() => {
19836
+ useEffect49(() => {
19506
19837
  if (!mayStart || !tableId) return;
19507
19838
  let cancelled = false;
19508
19839
  void client.checklistTemplates({ about_table_id: tableId, limit: 50 }).then((answered) => {
@@ -19564,7 +19895,7 @@ function ChecklistRunner({
19564
19895
  },
19565
19896
  [client, loadSteps]
19566
19897
  );
19567
- const active = useMemo32(
19898
+ const active = useMemo33(
19568
19899
  () => runs?.find((r) => r.run_id === activeId) ?? null,
19569
19900
  [runs, activeId]
19570
19901
  );
@@ -19637,9 +19968,9 @@ function StepRow({
19637
19968
  className
19638
19969
  }) {
19639
19970
  const host = useRecordsUi();
19640
- const [members, setMembers] = useState59(null);
19971
+ const [members, setMembers] = useState60(null);
19641
19972
  const unassigned = !step2.finished && !step2.assignee_user_id && Boolean(step2.role);
19642
- useEffect46(() => {
19973
+ useEffect49(() => {
19643
19974
  if (!unassigned || !onAssign || !host.members || members !== null) return;
19644
19975
  let alive = true;
19645
19976
  void host.members().then((roster) => {
@@ -19649,7 +19980,7 @@ function StepRow({
19649
19980
  alive = false;
19650
19981
  };
19651
19982
  }, [unassigned, onAssign, host, members]);
19652
- const [answer, setAnswer] = useState59("");
19983
+ const [answer, setAnswer] = useState60("");
19653
19984
  const key = step2.requires_key ?? (step2.requires === "note" ? "note" : null);
19654
19985
  const asksHere = step2.requires === "note" || step2.requires === "answer";
19655
19986
  const needsAnswer = asksHere && answer.trim().length === 0;
@@ -19741,11 +20072,11 @@ function StepRow({
19741
20072
  );
19742
20073
  }
19743
20074
  function useMyChecklistSteps(limit = 25) {
19744
- const client = useRecordsClient39();
20075
+ const client = useRecordsClient41();
19745
20076
  const me = client.config.actor.user_id ?? null;
19746
- const [steps, setSteps] = useState59([]);
19747
- const [loading, setLoading] = useState59(true);
19748
- const [error, setError] = useState59(null);
20077
+ const [steps, setSteps] = useState60([]);
20078
+ const [loading, setLoading] = useState60(true);
20079
+ const [error, setError] = useState60(null);
19749
20080
  const refresh = useCallback26(async () => {
19750
20081
  if (!me) {
19751
20082
  setSteps([]);
@@ -19774,7 +20105,7 @@ function useMyChecklistSteps(limit = 25) {
19774
20105
  setSteps(held);
19775
20106
  setLoading(false);
19776
20107
  }, [client, limit, me]);
19777
- useEffect46(() => {
20108
+ useEffect49(() => {
19778
20109
  void refresh();
19779
20110
  }, [refresh]);
19780
20111
  return { steps, loading, error, refresh };
@@ -19785,14 +20116,14 @@ function MyChecklistSteps({
19785
20116
  onSteps,
19786
20117
  actions
19787
20118
  }) {
19788
- const client = useRecordsClient39();
20119
+ const client = useRecordsClient41();
19789
20120
  const { steps: held, loading, error, refresh } = useMyChecklistSteps();
19790
- useEffect46(() => {
20121
+ useEffect49(() => {
19791
20122
  onSteps?.(held.map((s) => s.step_id));
19792
20123
  }, [held, onSteps]);
19793
20124
  const steps = onlyIds ? held.filter((s) => onlyIds.has(s.step_id)) : held;
19794
- const [busy, setBusy] = useState59(null);
19795
- const [refusal2, setRefusal] = useState59(null);
20125
+ const [busy, setBusy] = useState60(null);
20126
+ const [refusal2, setRefusal] = useState60(null);
19796
20127
  const complete = useCallback26(
19797
20128
  async (step2, evidence) => {
19798
20129
  setBusy(step2.step_id);
@@ -19833,14 +20164,14 @@ function MyChecklistSteps({
19833
20164
  ] });
19834
20165
  }
19835
20166
  function ChecklistsPanel({ tableId, onOpenRecord, className }) {
19836
- const client = useRecordsClient39();
20167
+ const client = useRecordsClient41();
19837
20168
  const table = useTable11(tableId);
19838
20169
  const rights = useTableRights(table.data);
19839
- const [templates, setTemplates] = useState59(null);
19840
- const [runs, setRuns] = useState59(null);
19841
- const [error, setError] = useState59(null);
19842
- const [editing, setEditing] = useState59(null);
19843
- const [openRun, setOpenRun] = useState59(null);
20170
+ const [templates, setTemplates] = useState60(null);
20171
+ const [runs, setRuns] = useState60(null);
20172
+ const [error, setError] = useState60(null);
20173
+ const [editing, setEditing] = useState60(null);
20174
+ const [openRun, setOpenRun] = useState60(null);
19844
20175
  const load = useCallback26(async () => {
19845
20176
  const [t, r] = await Promise.all([
19846
20177
  client.checklistTemplates({ about_table_id: tableId, limit: 100 }),
@@ -19855,7 +20186,7 @@ function ChecklistsPanel({ tableId, onOpenRecord, className }) {
19855
20186
  if (!r.ok) setRuns([]);
19856
20187
  else setRuns(r.data);
19857
20188
  }, [client, tableId]);
19858
- useEffect46(() => {
20189
+ useEffect49(() => {
19859
20190
  void load();
19860
20191
  }, [load]);
19861
20192
  if (templates === null) return /* @__PURE__ */ jsx69(Skeleton11, { className: cn39("h-40 w-full", className) });
@@ -19994,14 +20325,14 @@ function ChecklistTemplateEditor({
19994
20325
  onDone,
19995
20326
  className
19996
20327
  }) {
19997
- const client = useRecordsClient39();
19998
- const [name, setName] = useState59("");
19999
- const [rows, setRows] = useState59([{ ...EMPTY_ROW }]);
20000
- const [refusal2, setRefusal] = useState59(null);
20001
- const [error, setError] = useState59(null);
20002
- const [busy, setBusy] = useState59(false);
20003
- const [loading, setLoading] = useState59(Boolean(templateId));
20004
- useEffect46(() => {
20328
+ const client = useRecordsClient41();
20329
+ const [name, setName] = useState60("");
20330
+ const [rows, setRows] = useState60([{ ...EMPTY_ROW }]);
20331
+ const [refusal2, setRefusal] = useState60(null);
20332
+ const [error, setError] = useState60(null);
20333
+ const [busy, setBusy] = useState60(false);
20334
+ const [loading, setLoading] = useState60(Boolean(templateId));
20335
+ useEffect49(() => {
20005
20336
  if (!templateId) return;
20006
20337
  let cancelled = false;
20007
20338
  void client.checklistTemplateShape({ template_id: templateId }).then((answered) => {
@@ -20029,7 +20360,7 @@ function ChecklistTemplateEditor({
20029
20360
  cancelled = true;
20030
20361
  };
20031
20362
  }, [client, templateId]);
20032
- const spec = useMemo32(
20363
+ const spec = useMemo33(
20033
20364
  () => ({
20034
20365
  name: name.trim(),
20035
20366
  about_table_id: aboutTableId,
@@ -20038,7 +20369,7 @@ function ChecklistTemplateEditor({
20038
20369
  }),
20039
20370
  [aboutTableId, name, rows]
20040
20371
  );
20041
- useEffect46(() => {
20372
+ useEffect49(() => {
20042
20373
  if (spec.steps.length === 0 || spec.name.length === 0) {
20043
20374
  setRefusal(null);
20044
20375
  return;
@@ -20285,26 +20616,26 @@ function ActionInbox({
20285
20616
  onOpenRecord,
20286
20617
  className
20287
20618
  }) {
20288
- const client = useRecordsClient40();
20289
- const [showDecided, setShowDecided] = useState60(includeSettled);
20290
- const [groupBy, setGroupBy] = useState60(defaultGroupBy);
20291
- const [everyTable, setEveryTable] = useState60(false);
20292
- const [items, setItems] = useState60(null);
20293
- const [error, setError] = useState60(null);
20294
- const [outcome, setOutcome] = useState60({});
20295
- const [busy, setBusy] = useState60(null);
20296
- const [cursor, setCursor] = useState60(0);
20619
+ const client = useRecordsClient42();
20620
+ const [showDecided, setShowDecided] = useState61(includeSettled);
20621
+ const [groupBy, setGroupBy] = useState61(defaultGroupBy);
20622
+ const [everyTable, setEveryTable] = useState61(false);
20623
+ const [items, setItems] = useState61(null);
20624
+ const [error, setError] = useState61(null);
20625
+ const [outcome, setOutcome] = useState61({});
20626
+ const [busy, setBusy] = useState61(null);
20627
+ const [cursor, setCursor] = useState61(0);
20297
20628
  const listRef = useRef21(null);
20298
- const [selected, setSelected] = useState60(/* @__PURE__ */ new Set());
20629
+ const [selected, setSelected] = useState61(/* @__PURE__ */ new Set());
20299
20630
  const anchor = useRef21(null);
20300
- const [deciding, setDeciding] = useState60(false);
20301
- const [batchSaid, setBatchSaid] = useState60(null);
20302
- const [view, setView] = useState60("inbox");
20303
- const [counts, setCounts] = useState60(null);
20304
- const [snoozing, setSnoozing] = useState60(null);
20305
- const [pickAt, setPickAt] = useState60("");
20306
- const [said, setSaid] = useState60(null);
20307
- const [stepIds, setStepIds] = useState60(/* @__PURE__ */ new Set());
20631
+ const [deciding, setDeciding] = useState61(false);
20632
+ const [batchSaid, setBatchSaid] = useState61(null);
20633
+ const [view, setView] = useState61("inbox");
20634
+ const [counts, setCounts] = useState61(null);
20635
+ const [snoozing, setSnoozing] = useState61(null);
20636
+ const [pickAt, setPickAt] = useState61("");
20637
+ const [said, setSaid] = useState61(null);
20638
+ const [stepIds, setStepIds] = useState61(/* @__PURE__ */ new Set());
20308
20639
  const onSteps = useCallback27((ids) => setStepIds(new Set(ids)), []);
20309
20640
  const load = useCallback27(async () => {
20310
20641
  const [result, counted] = await Promise.all([
@@ -20320,25 +20651,25 @@ function ActionInbox({
20320
20651
  setError(null);
20321
20652
  setItems(result.data);
20322
20653
  }, [client, showDecided, view]);
20323
- useEffect47(() => {
20654
+ useEffect50(() => {
20324
20655
  void load();
20325
20656
  }, [load]);
20326
- const narrowed = useMemo33(() => {
20657
+ const narrowed = useMemo34(() => {
20327
20658
  const all = (items ?? []).filter((i) => !(view === "inbox" && i.kind === "assignment" && stepIds.has(i.item_id)));
20328
20659
  if (!tableId || everyTable) return all;
20329
20660
  return all.filter((i) => i.table_id === tableId);
20330
20661
  }, [items, tableId, everyTable, view, stepIds]);
20331
- const waitingIds = useMemo33(
20662
+ const waitingIds = useMemo34(
20332
20663
  () => new Set((items ?? []).filter((i) => i.kind === "assignment").map((i) => i.item_id)),
20333
20664
  [items]
20334
20665
  );
20335
- const groups = useMemo33(() => groupInbox(narrowed, groupBy), [narrowed, groupBy]);
20336
- const shown3 = useMemo33(() => groups.flatMap((g) => g.items), [groups]);
20666
+ const groups = useMemo34(() => groupInbox(narrowed, groupBy), [narrowed, groupBy]);
20667
+ const shown3 = useMemo34(() => groups.flatMap((g) => g.items), [groups]);
20337
20668
  const elsewhere = (items?.length ?? 0) - narrowed.length;
20338
- useEffect47(() => {
20669
+ useEffect50(() => {
20339
20670
  if (cursor >= shown3.length) setCursor(Math.max(0, shown3.length - 1));
20340
20671
  }, [shown3.length, cursor]);
20341
- useEffect47(() => {
20672
+ useEffect50(() => {
20342
20673
  const el = listRef.current?.querySelector(`[data-row="${cursor}"]`);
20343
20674
  el?.scrollIntoView({ block: "nearest" });
20344
20675
  }, [cursor, shown3.length]);
@@ -20358,12 +20689,12 @@ function ActionInbox({
20358
20689
  },
20359
20690
  [client, load]
20360
20691
  );
20361
- const [held, setHeld] = useState60({});
20692
+ const [held, setHeld] = useState61({});
20362
20693
  const holds2 = useRef21(/* @__PURE__ */ new Map());
20363
20694
  const lastHold = useRef21(null);
20364
20695
  const holdSeq = useRef21(0);
20365
- const [, tick] = useState60(0);
20366
- useEffect47(() => {
20696
+ const [, tick] = useState61(0);
20697
+ useEffect50(() => {
20367
20698
  if (Object.keys(held).length === 0) return;
20368
20699
  const t = setInterval(() => tick((n) => n + 1), 250);
20369
20700
  return () => clearInterval(t);
@@ -20408,7 +20739,7 @@ function ActionInbox({
20408
20739
  });
20409
20740
  setSaid({ text: entry.ids.length === 1 ? "Undone. It is waiting on you again, exactly as it was." : `Undone. All ${entry.ids.length} are waiting on you again, exactly as they were.`, undo: null });
20410
20741
  }, []);
20411
- useEffect47(() => {
20742
+ useEffect50(() => {
20412
20743
  const flush = () => {
20413
20744
  for (const entry of [...holds2.current.values()]) entry.commit();
20414
20745
  };
@@ -20419,7 +20750,7 @@ function ActionInbox({
20419
20750
  };
20420
20751
  }, []);
20421
20752
  const resumed = useRef21(false);
20422
- useEffect47(() => {
20753
+ useEffect50(() => {
20423
20754
  if (resumed.current || items === null || view !== "inbox") return;
20424
20755
  resumed.current = true;
20425
20756
  const kept = readHolds();
@@ -21022,25 +21353,25 @@ function ActionInbox({
21022
21353
  }
21023
21354
 
21024
21355
  // src/HistoryPanel.tsx
21025
- import { useCallback as useCallback28, useEffect as useEffect48, useRef as useRef22, useState as useState61 } from "react";
21356
+ import { useCallback as useCallback28, useEffect as useEffect51, useRef as useRef22, useState as useState62 } from "react";
21026
21357
  import {
21027
21358
  useFields as useFields15,
21028
21359
  useRecordChangeRevision,
21029
- useRecordsClient as useRecordsClient41,
21360
+ useRecordsClient as useRecordsClient43,
21030
21361
  useTable as useTable12
21031
21362
  } from "@ai-matrx/records/react";
21032
21363
  import { Badge as Badge16, Button as Button52, Skeleton as Skeleton13, cn as cn41 } from "@ai-matrx/design-system";
21033
21364
  import { jsx as jsx71, jsxs as jsxs63 } from "react/jsx-runtime";
21034
21365
  function HistoryPanel({ tableId, recordId, onAskAboutField, className }) {
21035
- const client = useRecordsClient41();
21366
+ const client = useRecordsClient43();
21036
21367
  const table = useTable12(tableId);
21037
21368
  const fields = useFields15(tableId);
21038
21369
  const rights = useTableRights(table.data);
21039
- const [entries, setEntries] = useState61(null);
21040
- const [error, setError] = useState61(null);
21041
- const [open, setOpen] = useState61(null);
21042
- const [pending, setPending] = useState61({ phase: "idle" });
21043
- const [said, setSaid] = useState61(null);
21370
+ const [entries, setEntries] = useState62(null);
21371
+ const [error, setError] = useState62(null);
21372
+ const [open, setOpen] = useState62(null);
21373
+ const [pending, setPending] = useState62({ phase: "idle" });
21374
+ const [said, setSaid] = useState62(null);
21044
21375
  const listRef = useRef22(null);
21045
21376
  const changed = useRecordChangeRevision(recordId);
21046
21377
  const load = useCallback28(async () => {
@@ -21052,7 +21383,7 @@ function HistoryPanel({ tableId, recordId, onAskAboutField, className }) {
21052
21383
  setError(null);
21053
21384
  setEntries(answered.data);
21054
21385
  }, [client, recordId, changed]);
21055
- useEffect48(() => {
21386
+ useEffect51(() => {
21056
21387
  void load();
21057
21388
  }, [load]);
21058
21389
  if (error) return /* @__PURE__ */ jsx71(RefusalNotice, { error, className });
@@ -21333,29 +21664,29 @@ function say(value, field2) {
21333
21664
  }
21334
21665
 
21335
21666
  // src/CommentThread.tsx
21336
- import { useCallback as useCallback29, useEffect as useEffect49, useMemo as useMemo34, useRef as useRef23, useState as useState62 } from "react";
21667
+ import { useCallback as useCallback29, useEffect as useEffect52, useMemo as useMemo35, useRef as useRef23, useState as useState63 } from "react";
21337
21668
  import {
21338
21669
  useFields as useFields16,
21339
- useRecordsClient as useRecordsClient42,
21670
+ useRecordsClient as useRecordsClient44,
21340
21671
  useTable as useTable13
21341
21672
  } from "@ai-matrx/records/react";
21342
21673
  import { Badge as Badge17, Button as Button53, Skeleton as Skeleton14, Textarea, cn as cn42 } from "@ai-matrx/design-system";
21343
21674
  import { jsx as jsx72, jsxs as jsxs64 } from "react/jsx-runtime";
21344
21675
  function CommentThread({ tableId, recordId, fieldKey, className }) {
21345
- const client = useRecordsClient42();
21676
+ const client = useRecordsClient44();
21346
21677
  const table = useTable13(tableId);
21347
21678
  const fields = useFields16(tableId);
21348
21679
  const host = useRecordsUi();
21349
- const [thread, setThread] = useState62(null);
21350
- const [error, setError] = useState62(null);
21351
- const [draft, setDraft] = useState62("");
21352
- const [replyTo, setReplyTo] = useState62(null);
21353
- const [busy, setBusy] = useState62(false);
21354
- const [said, setSaid] = useState62(null);
21355
- const [showResolved, setShowResolved] = useState62(false);
21356
- const [people, setPeople] = useState62([]);
21357
- const [mentionQuery, setMentionQuery] = useState62(null);
21358
- const [picked, setPicked] = useState62([]);
21680
+ const [thread, setThread] = useState63(null);
21681
+ const [error, setError] = useState63(null);
21682
+ const [draft, setDraft] = useState63("");
21683
+ const [replyTo, setReplyTo] = useState63(null);
21684
+ const [busy, setBusy] = useState63(false);
21685
+ const [said, setSaid] = useState63(null);
21686
+ const [showResolved, setShowResolved] = useState63(false);
21687
+ const [people, setPeople] = useState63([]);
21688
+ const [mentionQuery, setMentionQuery] = useState63(null);
21689
+ const [picked, setPicked] = useState63([]);
21359
21690
  const box = useRef23(null);
21360
21691
  const load = useCallback29(async () => {
21361
21692
  const answered = await client.commentThread({ record_id: recordId, include_resolved: showResolved });
@@ -21370,10 +21701,10 @@ function CommentThread({ tableId, recordId, fieldKey, className }) {
21370
21701
  mayResolve: answered.data.may_resolve
21371
21702
  });
21372
21703
  }, [client, recordId, showResolved]);
21373
- useEffect49(() => {
21704
+ useEffect52(() => {
21374
21705
  void load();
21375
21706
  }, [load]);
21376
- useEffect49(() => {
21707
+ useEffect52(() => {
21377
21708
  let alive = true;
21378
21709
  if (!host.members) return;
21379
21710
  void host.members().then((roster) => {
@@ -21390,7 +21721,7 @@ function CommentThread({ tableId, recordId, fieldKey, className }) {
21390
21721
  alive = false;
21391
21722
  };
21392
21723
  }, [host]);
21393
- const candidates = useMemo34(() => {
21724
+ const candidates = useMemo35(() => {
21394
21725
  if (mentionQuery === null) return [];
21395
21726
  const q = mentionQuery.trim().toLowerCase();
21396
21727
  return people.filter((p) => !picked.some((already) => already.userId === p.userId)).filter((p) => q === "" || (p.name ?? p.email ?? "").toLowerCase().includes(q)).slice(0, 6);
@@ -21576,10 +21907,10 @@ function Line({
21576
21907
  }
21577
21908
 
21578
21909
  // src/FieldHistoryPanel.tsx
21579
- import { useCallback as useCallback30, useEffect as useEffect50, useState as useState63 } from "react";
21910
+ import { useCallback as useCallback30, useEffect as useEffect53, useState as useState64 } from "react";
21580
21911
  import {
21581
21912
  useFields as useFields17,
21582
- useRecordsClient as useRecordsClient43,
21913
+ useRecordsClient as useRecordsClient45,
21583
21914
  useTable as useTable14
21584
21915
  } from "@ai-matrx/records/react";
21585
21916
  import { Badge as Badge18, Button as Button54, Skeleton as Skeleton15, cn as cn43 } from "@ai-matrx/design-system";
@@ -21592,14 +21923,14 @@ function FieldHistoryPanel({
21592
21923
  onOpenRecord,
21593
21924
  className
21594
21925
  }) {
21595
- const client = useRecordsClient43();
21926
+ const client = useRecordsClient45();
21596
21927
  const table = useTable14(tableId);
21597
21928
  const fields = useFields17(tableId);
21598
21929
  const rights = useTableRights(table.data);
21599
- const [rows, setRows] = useState63(null);
21600
- const [error, setError] = useState63(null);
21601
- const [pending, setPending] = useState63({ phase: "idle" });
21602
- const [said, setSaid] = useState63(null);
21930
+ const [rows, setRows] = useState64(null);
21931
+ const [error, setError] = useState64(null);
21932
+ const [pending, setPending] = useState64({ phase: "idle" });
21933
+ const [said, setSaid] = useState64(null);
21603
21934
  const load = useCallback30(async () => {
21604
21935
  const answered = await client.fieldHistory(
21605
21936
  recordId ? { table_id: tableId, field_key: fieldKey, record_id: recordId } : { table_id: tableId, field_key: fieldKey }
@@ -21611,7 +21942,7 @@ function FieldHistoryPanel({
21611
21942
  setError(null);
21612
21943
  setRows(answered.data);
21613
21944
  }, [client, tableId, fieldKey, recordId]);
21614
- useEffect50(() => {
21945
+ useEffect53(() => {
21615
21946
  void load();
21616
21947
  }, [load]);
21617
21948
  const label = (fields.data ?? []).find((f) => f.key === fieldKey)?.label || humanize(fieldKey);
@@ -21823,20 +22154,20 @@ function submissionStamp(args) {
21823
22154
  }
21824
22155
 
21825
22156
  // src/PortalBuilder.tsx
21826
- import { useCallback as useCallback34, useEffect as useEffect57, useMemo as useMemo37, useState as useState70 } from "react";
21827
- import { useRecordsClient as useRecordsClient50, useTables as useTables4 } from "@ai-matrx/records/react";
22157
+ import { useCallback as useCallback34, useEffect as useEffect60, useMemo as useMemo38, useState as useState71 } from "react";
22158
+ import { useRecordsClient as useRecordsClient52, useTables as useTables4 } from "@ai-matrx/records/react";
21828
22159
  import { BasicInput as BasicInput21, Button as Button60, Checkbox as Checkbox9, Label as Label16, Separator as Separator9, Skeleton as Skeleton20, cn as cn48 } from "@ai-matrx/design-system";
21829
22160
 
21830
22161
  // src/TablesHome.tsx
21831
- import { useCallback as useCallback33, useEffect as useEffect56, useState as useState69 } from "react";
21832
- import { useRecordsClient as useRecordsClient49, useTables as useTables3 } from "@ai-matrx/records/react";
22162
+ import { useCallback as useCallback33, useEffect as useEffect59, useState as useState70 } from "react";
22163
+ import { useRecordsClient as useRecordsClient51, useTables as useTables3 } from "@ai-matrx/records/react";
21833
22164
  import { withTableFacts } from "@ai-matrx/records/core";
21834
22165
  import { withTablePlacement } from "@ai-matrx/records";
21835
22166
  import { BasicInput as BasicInput20, Button as Button59, Skeleton as Skeleton19, cn as cn47 } from "@ai-matrx/design-system";
21836
22167
 
21837
22168
  // src/ExampleTables.tsx
21838
- import { useEffect as useEffect51, useState as useState64 } from "react";
21839
- import { useRecordsClient as useRecordsClient44 } from "@ai-matrx/records/react";
22169
+ import { useEffect as useEffect54, useState as useState65 } from "react";
22170
+ import { useRecordsClient as useRecordsClient46 } from "@ai-matrx/records/react";
21840
22171
  import { loadUseCase, summarize as summarize2, useCaseIds } from "@ai-matrx/records/use-cases";
21841
22172
  import { Button as Button55, Skeleton as Skeleton16, cn as cn44 } from "@ai-matrx/design-system";
21842
22173
  import { jsx as jsx74, jsxs as jsxs66 } from "react/jsx-runtime";
@@ -21845,12 +22176,12 @@ function ExampleTables({
21845
22176
  onClose,
21846
22177
  className
21847
22178
  }) {
21848
- const client = useRecordsClient44();
21849
- const [summaries, setSummaries] = useState64(null);
21850
- const [busy, setBusy] = useState64(null);
21851
- const [error, setError] = useState64(null);
21852
- const [built, setBuilt] = useState64(null);
21853
- useEffect51(() => {
22179
+ const client = useRecordsClient46();
22180
+ const [summaries, setSummaries] = useState65(null);
22181
+ const [busy, setBusy] = useState65(null);
22182
+ const [error, setError] = useState65(null);
22183
+ const [built, setBuilt] = useState65(null);
22184
+ useEffect54(() => {
21854
22185
  let alive = true;
21855
22186
  void Promise.all(useCaseIds().map(async (id) => summarize2(await loadUseCase(id)))).then((rows) => {
21856
22187
  if (alive) setSummaries(rows);
@@ -21925,23 +22256,23 @@ function ExampleTables({
21925
22256
  }
21926
22257
 
21927
22258
  // src/BookingSlots.tsx
21928
- import { useCallback as useCallback32, useEffect as useEffect54, useMemo as useMemo36, useState as useState67 } from "react";
21929
- import { useRecordsClient as useRecordsClient47, useMyLevels as useMyLevels2 } from "@ai-matrx/records/react";
22259
+ import { useCallback as useCallback32, useEffect as useEffect57, useMemo as useMemo37, useState as useState68 } from "react";
22260
+ import { useRecordsClient as useRecordsClient49, useMyLevels as useMyLevels2 } from "@ai-matrx/records/react";
21930
22261
  import { bookingPath as bookingPath2 } from "@ai-matrx/records";
21931
22262
  import { Badge as Badge19, Button as Button57, Skeleton as Skeleton18, cn as cn46 } from "@ai-matrx/design-system";
21932
22263
 
21933
22264
  // src/BookingBuilder.tsx
21934
- import { useCallback as useCallback31, useEffect as useEffect53, useMemo as useMemo35, useState as useState66 } from "react";
21935
- import { useFields as useFields18, useRecordsClient as useRecordsClient46, useTable as useTable15 } from "@ai-matrx/records/react";
22265
+ import { useCallback as useCallback31, useEffect as useEffect56, useMemo as useMemo36, useState as useState67 } from "react";
22266
+ import { useFields as useFields18, useRecordsClient as useRecordsClient48, useTable as useTable15 } from "@ai-matrx/records/react";
21936
22267
 
21937
22268
  // src/publish-gate.ts
21938
- import { useEffect as useEffect52, useState as useState65 } from "react";
21939
- import { useRecordsClient as useRecordsClient45 } from "@ai-matrx/records/react";
22269
+ import { useEffect as useEffect55, useState as useState66 } from "react";
22270
+ import { useRecordsClient as useRecordsClient47 } from "@ai-matrx/records/react";
21940
22271
  var PUBLISH_NEEDS_THE_STORE_ON = "This organization has its record store switched off, so publishing would hand you a link that opens nothing. An owner or an administrator turns it on under Database settings, on the unified data screen \u2014 everything you have already built here is kept and starts working the moment they do.";
21941
22272
  function usePublishGate() {
21942
- const client = useRecordsClient45();
21943
- const [storeOpen, setStoreOpen] = useState65(null);
21944
- useEffect52(() => {
22273
+ const client = useRecordsClient47();
22274
+ const [storeOpen, setStoreOpen] = useState66(null);
22275
+ useEffect55(() => {
21945
22276
  let alive = true;
21946
22277
  void (async () => {
21947
22278
  const answered = await client.storeIsOpen();
@@ -22054,36 +22385,36 @@ function draftWindows(availability) {
22054
22385
  });
22055
22386
  }
22056
22387
  function BookingBuilder({ tableId, bookingId, onSaved, onClose, className }) {
22057
- const client = useRecordsClient46();
22388
+ const client = useRecordsClient48();
22058
22389
  const publishGate = usePublishGate();
22059
22390
  const host = useRecordsUi();
22060
22391
  const table = useTable15(tableId);
22061
22392
  const rights = useTableRights(table.data);
22062
22393
  const fields = useFields18(tableId);
22063
- const [existing, setExisting] = useState66(null);
22064
- const [loaded, setLoaded] = useState66(false);
22065
- const [error, setError] = useState66(null);
22066
- const [saving, setSaving] = useState66(false);
22067
- const [publishing, setPublishing] = useState66(false);
22068
- const [copied, setCopied] = useState66(false);
22069
- const [title, setTitle] = useState66("");
22070
- const [minutes, setMinutes] = useState66(30);
22071
- const [buffer, setBuffer] = useState66(0);
22072
- const [lead, setLead] = useState66(120);
22073
- const [perDay, setPerDay] = useState66(8);
22074
- const [days, setDays] = useState66(30);
22075
- const [timezone, setTimezone] = useState66(() => ownTimeZone());
22076
- const [windows, setWindows] = useState66(() => draftWindows(null));
22077
- const [asked2, setAsked] = useState66([]);
22078
- const [confirmation, setConfirmation] = useState66("");
22079
- const [offer, setOffer] = useState66(null);
22080
- const [formId, setFormId] = useState66(bookingId ?? null);
22394
+ const [existing, setExisting] = useState67(null);
22395
+ const [loaded, setLoaded] = useState67(false);
22396
+ const [error, setError] = useState67(null);
22397
+ const [saving, setSaving] = useState67(false);
22398
+ const [publishing, setPublishing] = useState67(false);
22399
+ const [copied, setCopied] = useState67(false);
22400
+ const [title, setTitle] = useState67("");
22401
+ const [minutes, setMinutes] = useState67(30);
22402
+ const [buffer, setBuffer] = useState67(0);
22403
+ const [lead, setLead] = useState67(120);
22404
+ const [perDay, setPerDay] = useState67(8);
22405
+ const [days, setDays] = useState67(30);
22406
+ const [timezone, setTimezone] = useState67(() => ownTimeZone());
22407
+ const [windows, setWindows] = useState67(() => draftWindows(null));
22408
+ const [asked2, setAsked] = useState67([]);
22409
+ const [confirmation, setConfirmation] = useState67("");
22410
+ const [offer, setOffer] = useState67(null);
22411
+ const [formId, setFormId] = useState67(bookingId ?? null);
22081
22412
  const publicOrigin = host.publicOrigin ?? (typeof window === "undefined" ? "" : window.location.origin);
22082
- const askable = useMemo35(
22413
+ const askable = useMemo36(
22083
22414
  () => askableFields(fields.data ?? [], STORE_ANSWERS_THESE),
22084
22415
  [fields.data]
22085
22416
  );
22086
- const leftOut = useMemo35(
22417
+ const leftOut = useMemo36(
22087
22418
  () => whyNotAskable(fields.data ?? [], STORE_ANSWERS_THESE),
22088
22419
  [fields.data]
22089
22420
  );
@@ -22096,22 +22427,34 @@ function BookingBuilder({ tableId, bookingId, onSaved, onClose, className }) {
22096
22427
  }
22097
22428
  const mine = bookingId ? answered.data.find((p) => p.form_id === bookingId) ?? null : answered.data[0] ?? null;
22098
22429
  setExisting(mine);
22430
+ if (mine) {
22431
+ setFormId(mine.form_id);
22432
+ const pages = await client.forms({ table_id: tableId });
22433
+ const page = pages.ok ? pages.data.find((f) => f.form_id === mine.form_id) : void 0;
22434
+ const presentation = page?.presentation ?? {};
22435
+ const questions = Array.isArray(presentation["questions"]) ? presentation["questions"] : [];
22436
+ const keys = questions.map((q) => typeof q.field === "string" ? q.field : "").filter((k) => k !== "");
22437
+ if (keys.length > 0) setAsked(keys);
22438
+ const block = presentation["booking"];
22439
+ if (block && typeof block === "object" && Array.isArray(block.windows)) {
22440
+ setOffer(block);
22441
+ }
22442
+ }
22099
22443
  setLoaded(true);
22100
- if (mine) setFormId(mine.form_id);
22101
22444
  }, [client, tableId, bookingId]);
22102
- useEffect53(() => {
22445
+ useEffect56(() => {
22103
22446
  void load();
22104
22447
  }, [load]);
22105
- useEffect53(() => {
22448
+ useEffect56(() => {
22106
22449
  if (title !== "" || !table.data) return;
22107
- setTitle(existing?.title ?? `Book a ${minutes}-minute ${table.data.name} appointment`);
22450
+ setTitle(existing?.title ?? `Book a ${minutes}-minute ${singularNoun(table.data, "appointment")}`);
22108
22451
  }, [table.data, existing]);
22109
- useEffect53(() => {
22452
+ useEffect56(() => {
22110
22453
  if (!existing) return;
22111
22454
  setMinutes(existing.slot_minutes);
22112
22455
  if (existing.timezone && existing.timezone !== "UTC") setTimezone(existing.timezone);
22113
22456
  }, [existing]);
22114
- useEffect53(() => {
22457
+ useEffect56(() => {
22115
22458
  if (!offer) return;
22116
22459
  setWindows(draftWindows(offer));
22117
22460
  setMinutes(offer.slot_minutes);
@@ -22119,7 +22462,7 @@ function BookingBuilder({ tableId, bookingId, onSaved, onClose, className }) {
22119
22462
  setLead(offer.lead_minutes);
22120
22463
  setPerDay(offer.max_per_day);
22121
22464
  setDays(offer.days);
22122
- if (offer.timezone) setTimezone(offer.timezone);
22465
+ if (offer.timezone && offer.timezone !== "UTC") setTimezone(offer.timezone);
22123
22466
  }, [offer]);
22124
22467
  const availability = useCallback31(
22125
22468
  () => ({
@@ -22133,7 +22476,7 @@ function BookingBuilder({ tableId, bookingId, onSaved, onClose, className }) {
22133
22476
  }),
22134
22477
  [timezone, minutes, buffer, lead, perDay, days, windows]
22135
22478
  );
22136
- const [addingWho, setAddingWho] = useState66(false);
22479
+ const [addingWho, setAddingWho] = useState67(false);
22137
22480
  async function addWho() {
22138
22481
  setAddingWho(true);
22139
22482
  setError(null);
@@ -22152,8 +22495,8 @@ function BookingBuilder({ tableId, bookingId, onSaved, onClose, className }) {
22152
22495
  setAddingWho(false);
22153
22496
  setWhoAdded(true);
22154
22497
  }
22155
- const [whoAdded, setWhoAdded] = useState66(false);
22156
- useEffect53(() => {
22498
+ const [whoAdded, setWhoAdded] = useState67(false);
22499
+ useEffect56(() => {
22157
22500
  if (!whoAdded) return;
22158
22501
  const who = askable.filter((f) => isWhoField(f)).map((f) => f.key);
22159
22502
  if (who.length === 0) return;
@@ -22427,14 +22770,15 @@ function bookingSuggestion(tableName2) {
22427
22770
  var NO_ADMIN = "Opening a booking page lets people with no account take time in your calendar, so it needs the admin level on the table the appointments land in.";
22428
22771
  var STATE_WORDS = BOOKING_PAGE_STATE_LABEL;
22429
22772
  function BookingSlots({ tableId, activeBookingId, className }) {
22430
- const client = useRecordsClient47();
22773
+ const client = useRecordsClient49();
22431
22774
  const host = useRecordsUi();
22432
- const [pages, setPages] = useState67(null);
22433
- const [error, setError] = useState67(null);
22434
- const [busy, setBusy] = useState67(null);
22435
- const [copied, setCopied] = useState67(null);
22436
- const [shown3, setShown] = useState67(null);
22437
- const [building, setBuilding] = useState67(false);
22775
+ const [pages, setPages] = useState68(null);
22776
+ const [error, setError] = useState68(null);
22777
+ const [busy, setBusy] = useState68(null);
22778
+ const [copied, setCopied] = useState68(null);
22779
+ const [shown3, setShown] = useState68(null);
22780
+ const [building, setBuilding] = useState68(false);
22781
+ const [changing, setChanging] = useState68(null);
22438
22782
  const load = useCallback32(async () => {
22439
22783
  const answered = await client.bookings(tableId ? { table_id: tableId } : {});
22440
22784
  if (!answered.ok) {
@@ -22445,10 +22789,10 @@ function BookingSlots({ tableId, activeBookingId, className }) {
22445
22789
  setError(null);
22446
22790
  setPages(answered.data);
22447
22791
  }, [client, tableId]);
22448
- useEffect54(() => {
22792
+ useEffect57(() => {
22449
22793
  void load();
22450
22794
  }, [load]);
22451
- const subjectIds = useMemo36(
22795
+ const subjectIds = useMemo37(
22452
22796
  () => Array.from(
22453
22797
  /* @__PURE__ */ new Set([
22454
22798
  ...(pages ?? []).map((p) => p.table_id),
@@ -22500,6 +22844,17 @@ function BookingSlots({ tableId, activeBookingId, className }) {
22500
22844
  ] }),
22501
22845
  error ? /* @__PURE__ */ jsx77(RefusalNotice, { error }) : null,
22502
22846
  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,
22847
+ changing ? /* @__PURE__ */ jsx77(
22848
+ BookingBuilder,
22849
+ {
22850
+ tableId: changing.tableId,
22851
+ bookingId: changing.formId,
22852
+ onSaved: () => {
22853
+ void load();
22854
+ },
22855
+ onClose: () => setChanging(null)
22856
+ }
22857
+ ) : null,
22503
22858
  building && tableId ? /* @__PURE__ */ jsx77(
22504
22859
  BookingBuilder,
22505
22860
  {
@@ -22576,6 +22931,15 @@ function BookingSlots({ tableId, activeBookingId, className }) {
22576
22931
  /* @__PURE__ */ jsx77("p", { className: "mt-1 text-xs text-muted-foreground", children: nextInWords(page) }),
22577
22932
  /* @__PURE__ */ jsxs69("div", { className: "mt-2 flex flex-wrap items-center gap-1.5", children: [
22578
22933
  /* @__PURE__ */ jsx77(Button57, { size: "sm", variant: "outline", onClick: () => void copy(url, page.form_id), children: copied === page.form_id ? "Copied" : "Copy link" }),
22934
+ mayOpen ? /* @__PURE__ */ jsx77(
22935
+ Button57,
22936
+ {
22937
+ size: "sm",
22938
+ variant: "ghost",
22939
+ onClick: () => setChanging({ formId: page.form_id, tableId: page.table_id }),
22940
+ children: "Change it"
22941
+ }
22942
+ ) : null,
22579
22943
  mayOpen ? /* @__PURE__ */ jsx77(
22580
22944
  Button57,
22581
22945
  {
@@ -22637,22 +23001,22 @@ import {
22637
23001
  } from "@ai-matrx/records/core";
22638
23002
 
22639
23003
  // src/WhereItLives.tsx
22640
- import { useEffect as useEffect55, useState as useState68 } from "react";
23004
+ import { useEffect as useEffect58, useState as useState69 } from "react";
22641
23005
  import { moveConsequence } from "@ai-matrx/records";
22642
- import { useRecordsClient as useRecordsClient48 } from "@ai-matrx/records/react";
23006
+ import { useRecordsClient as useRecordsClient50 } from "@ai-matrx/records/react";
22643
23007
  import { Button as Button58, ErrorBox as ErrorBox2, Popover as Popover6, PopoverContent as PopoverContent6, PopoverTrigger as PopoverTrigger6 } from "@ai-matrx/design-system";
22644
23008
  import { jsx as jsx78, jsxs as jsxs70 } from "react/jsx-runtime";
22645
23009
  function WhereItLives({ tableId, knownOrganizationName, onMoved, variant = "header" }) {
22646
- const client = useRecordsClient48();
23010
+ const client = useRecordsClient50();
22647
23011
  const host = useRecordsUi();
22648
- const [answer, setAnswer] = useState68(null);
22649
- const [attempt, setAttempt] = useState68(0);
22650
- const [open, setOpen] = useState68(false);
22651
- const [armed, setArmed] = useState68(variant !== "row" || !knownOrganizationName);
22652
- const [choosing, setChoosing] = useState68(null);
22653
- const [moving, setMoving] = useState68(false);
22654
- const [said, setSaid] = useState68(null);
22655
- useEffect55(() => {
23012
+ const [answer, setAnswer] = useState69(null);
23013
+ const [attempt, setAttempt] = useState69(0);
23014
+ const [open, setOpen] = useState69(false);
23015
+ const [armed, setArmed] = useState69(variant !== "row" || !knownOrganizationName);
23016
+ const [choosing, setChoosing] = useState69(null);
23017
+ const [moving, setMoving] = useState69(false);
23018
+ const [said, setSaid] = useState69(null);
23019
+ useEffect58(() => {
22656
23020
  if (!armed) return;
22657
23021
  let alive = true;
22658
23022
  setAnswer(null);
@@ -22898,11 +23262,11 @@ function visibilityLaneFor(table) {
22898
23262
  return "organization";
22899
23263
  }
22900
23264
  function TablesHome({ onOpenTable, organizationName, makingOnly = false, askedBy, className }) {
22901
- const client = useRecordsClient49();
23265
+ const client = useRecordsClient51();
22902
23266
  const tables = useTables3();
22903
23267
  const me = client.config.actor.user_id ?? null;
22904
- const [facts, setFacts] = useState69({ phase: "reading" });
22905
- useEffect56(() => {
23268
+ const [facts, setFacts] = useState70({ phase: "reading" });
23269
+ useEffect59(() => {
22906
23270
  let alive = true;
22907
23271
  void client.tableFacts().then((answered) => {
22908
23272
  if (!alive) return;
@@ -22916,11 +23280,11 @@ function TablesHome({ onOpenTable, organizationName, makingOnly = false, askedBy
22916
23280
  withTableFacts(tables.data ?? [], facts.rows, me),
22917
23281
  facts.rows
22918
23282
  ) : tables.data ?? [];
22919
- const [showEverything, setShowEverything] = useState69(false);
23283
+ const [showEverything, setShowEverything] = useState70(false);
22920
23284
  const keptCount = listed.filter((t) => laneFor(t) === "app").length;
22921
- const [askedName, setAskedName] = useState69(null);
23285
+ const [askedName, setAskedName] = useState70(null);
22922
23286
  const firstTableId = listed[0]?.id ?? null;
22923
- useEffect56(() => {
23287
+ useEffect59(() => {
22924
23288
  if (organizationName || !firstTableId) return;
22925
23289
  let alive = true;
22926
23290
  void client.tableHome({ table_id: firstTableId }).then((answered) => {
@@ -22933,23 +23297,23 @@ function TablesHome({ onOpenTable, organizationName, makingOnly = false, askedBy
22933
23297
  const livesIn = organizationName || askedName;
22934
23298
  const isMine = (t) => Boolean(me) && laneFor(t) !== "system" && laneFor(t) !== "app" && t.created_by === me;
22935
23299
  const sectionsKnown = facts.phase !== "failed";
22936
- const [creating, setCreating] = useState69(false);
22937
- const [name, setName] = useState69("");
22938
- const [busy, setBusy] = useState69(false);
22939
- const [error, setError] = useState69(null);
22940
- const [importInto, setImportInto] = useState69(null);
22941
- const [examples, setExamples] = useState69(false);
23300
+ const [creating, setCreating] = useState70(false);
23301
+ const [name, setName] = useState70("");
23302
+ const [busy, setBusy] = useState70(false);
23303
+ const [error, setError] = useState70(null);
23304
+ const [importInto, setImportInto] = useState70(null);
23305
+ const [examples, setExamples] = useState70(false);
22942
23306
  const createAsked = askedBy?.create ?? 0;
22943
23307
  const examplesAsked = askedBy?.examples ?? 0;
22944
- useEffect56(() => {
23308
+ useEffect59(() => {
22945
23309
  if (createAsked > 0) setCreating(true);
22946
23310
  }, [createAsked]);
22947
- useEffect56(() => {
23311
+ useEffect59(() => {
22948
23312
  if (examplesAsked > 0) setExamples(true);
22949
23313
  }, [examplesAsked]);
22950
23314
  const hostButtons = askedBy !== void 0;
22951
- const [boards, setBoards] = useState69(null);
22952
- useEffect56(() => {
23315
+ const [boards, setBoards] = useState70(null);
23316
+ useEffect59(() => {
22953
23317
  if (makingOnly) return;
22954
23318
  let cancelled = false;
22955
23319
  void client.dashboards({}).then((result) => {
@@ -23128,21 +23492,21 @@ function TablesHome({ onOpenTable, organizationName, makingOnly = false, askedBy
23128
23492
  import { Fragment as Fragment33, jsx as jsx80, jsxs as jsxs72 } from "react/jsx-runtime";
23129
23493
  var RESTATING_REPLACES = "Saving replaces what this portal shows: a table you untick stops being visible to every client the moment you save. Who is invited is not touched.";
23130
23494
  function PortalBuilder({ tableId, portalId, onSaved, onClose, className }) {
23131
- const client = useRecordsClient50();
23495
+ const client = useRecordsClient52();
23132
23496
  const tables = useTables4();
23133
- const [title, setTitle] = useState70("");
23134
- const [clientTableId, setClientTableId] = useState70(null);
23135
- const [exposures, setExposures] = useState70({});
23136
- const [fieldsByTable, setFieldsByTable] = useState70({});
23137
- const [error, setError] = useState70(null);
23138
- const [saving, setSaving] = useState70(false);
23139
- const [savedId, setSavedId] = useState70(portalId ?? null);
23140
- const [existing, setExisting] = useState70(null);
23141
- const [loading, setLoading] = useState70(Boolean(portalId));
23142
- const [inviteEmail, setInviteEmail] = useState70("");
23143
- const [inviteRecordId, setInviteRecordId] = useState70("");
23144
- const [inviting, setInviting] = useState70(false);
23145
- const [invitationSaid, setInvitationSaid] = useState70(null);
23497
+ const [title, setTitle] = useState71("");
23498
+ const [clientTableId, setClientTableId] = useState71(null);
23499
+ const [exposures, setExposures] = useState71({});
23500
+ const [fieldsByTable, setFieldsByTable] = useState71({});
23501
+ const [error, setError] = useState71(null);
23502
+ const [saving, setSaving] = useState71(false);
23503
+ const [savedId, setSavedId] = useState71(portalId ?? null);
23504
+ const [existing, setExisting] = useState71(null);
23505
+ const [loading, setLoading] = useState71(Boolean(portalId));
23506
+ const [inviteEmail, setInviteEmail] = useState71("");
23507
+ const [inviteRecordId, setInviteRecordId] = useState71("");
23508
+ const [inviting, setInviting] = useState71(false);
23509
+ const [invitationSaid, setInvitationSaid] = useState71(null);
23146
23510
  const loadFields = useCallback34(
23147
23511
  async (id) => {
23148
23512
  if (fieldsByTable[id]) return;
@@ -23155,7 +23519,7 @@ function PortalBuilder({ tableId, portalId, onSaved, onClose, className }) {
23155
23519
  },
23156
23520
  [client, fieldsByTable]
23157
23521
  );
23158
- useEffect57(() => {
23522
+ useEffect60(() => {
23159
23523
  if (!portalId) return;
23160
23524
  void (async () => {
23161
23525
  const answered = await client.portalCard({ portal_id: portalId });
@@ -23169,7 +23533,7 @@ function PortalBuilder({ tableId, portalId, onSaved, onClose, className }) {
23169
23533
  setClientTableId(answered.data.client_table_id);
23170
23534
  })();
23171
23535
  }, [client, portalId]);
23172
- useEffect57(() => {
23536
+ useEffect60(() => {
23173
23537
  if (!tableId) return;
23174
23538
  setExposures(
23175
23539
  (prev) => prev[tableId] ? prev : {
@@ -23182,7 +23546,7 @@ function PortalBuilder({ tableId, portalId, onSaved, onClose, className }) {
23182
23546
  const cameFromPeople = Boolean(
23183
23547
  tableId && (fieldsByTable[tableId] ?? []).some((f) => editorKindFor(f) === "email")
23184
23548
  );
23185
- useEffect57(() => {
23549
+ useEffect60(() => {
23186
23550
  if (!tableId || portalId || clientTableId !== null || !cameFromPeople) return;
23187
23551
  setClientTableId(tableId);
23188
23552
  setExposures((prev) => {
@@ -23190,7 +23554,7 @@ function PortalBuilder({ tableId, portalId, onSaved, onClose, className }) {
23190
23554
  return rest;
23191
23555
  });
23192
23556
  }, [tableId, portalId, clientTableId, cameFromPeople]);
23193
- const ticked = useMemo37(() => Object.values(exposures).filter((e) => e.on), [exposures]);
23557
+ const ticked = useMemo38(() => Object.values(exposures).filter((e) => e.on), [exposures]);
23194
23558
  const tiesTo = useCallback34(
23195
23559
  (id) => (fieldsByTable[id] ?? []).filter(
23196
23560
  (f) => f.type === "relation" && f.relation_target === clientTableId
@@ -23430,8 +23794,8 @@ function PortalBuilder({ tableId, portalId, onSaved, onClose, className }) {
23430
23794
  }
23431
23795
 
23432
23796
  // src/PortalsPanel.tsx
23433
- import { useCallback as useCallback35, useEffect as useEffect59, useMemo as useMemo39, useState as useState72 } from "react";
23434
- import { useRecordsClient as useRecordsClient52 } from "@ai-matrx/records/react";
23797
+ import { useCallback as useCallback35, useEffect as useEffect62, useMemo as useMemo40, useState as useState73 } from "react";
23798
+ import { useRecordsClient as useRecordsClient54 } from "@ai-matrx/records/react";
23435
23799
  import {
23436
23800
  portalArchiveConsequence,
23437
23801
  portalConfirmLine as portalConfirmLine2,
@@ -23441,8 +23805,8 @@ import {
23441
23805
  import { Badge as Badge20, BasicInput as BasicInput23, Button as Button62, Separator as Separator10, Skeleton as Skeleton21, cn as cn50 } from "@ai-matrx/design-system";
23442
23806
 
23443
23807
  // src/PortalLookEditor.tsx
23444
- import { useEffect as useEffect58, useMemo as useMemo38, useState as useState71 } from "react";
23445
- import { useRecordsClient as useRecordsClient51 } from "@ai-matrx/records/react";
23808
+ import { useEffect as useEffect61, useMemo as useMemo39, useState as useState72 } from "react";
23809
+ import { useRecordsClient as useRecordsClient53 } from "@ai-matrx/records/react";
23446
23810
  import { BasicInput as BasicInput22, Button as Button61, cn as cn49 } from "@ai-matrx/design-system";
23447
23811
  import { STYLE_COLOR_LABELS as STYLE_COLOR_LABELS3, SWATCH_CLASS as SWATCH_CLASS2 } from "@ai-matrx/design-system/data-table";
23448
23812
  import { jsx as jsx81, jsxs as jsxs73 } from "react/jsx-runtime";
@@ -23470,20 +23834,20 @@ function candidateRows(card, available) {
23470
23834
  return rows;
23471
23835
  }
23472
23836
  function PortalLookEditor({ card, onSaved, className }) {
23473
- const client = useRecordsClient51();
23837
+ const client = useRecordsClient53();
23474
23838
  const stored = card.config?.style ?? {};
23475
- const [name, setName] = useState71(stored.display_name ?? "");
23476
- const [welcome, setWelcome] = useState71(stored.welcome ?? "");
23477
- const [logo, setLogo] = useState71(stored.logo_file_id ?? "");
23478
- const [accent, setAccent] = useState71(stored.accent ?? "");
23479
- const [links, setLinks] = useState71(stored.footer_links ?? []);
23480
- const [forms, setForms] = useState71(null);
23481
- const [busy, setBusy] = useState71(false);
23482
- const [error, setError] = useState71(null);
23483
- const [said, setSaid] = useState71(null);
23484
- const [formsError, setFormsError] = useState71(null);
23485
- const [formsUnread, setFormsUnread] = useState71(false);
23486
- useEffect58(() => {
23839
+ const [name, setName] = useState72(stored.display_name ?? "");
23840
+ const [welcome, setWelcome] = useState72(stored.welcome ?? "");
23841
+ const [logo, setLogo] = useState72(stored.logo_file_id ?? "");
23842
+ const [accent, setAccent] = useState72(stored.accent ?? "");
23843
+ const [links, setLinks] = useState72(stored.footer_links ?? []);
23844
+ const [forms, setForms] = useState72(null);
23845
+ const [busy, setBusy] = useState72(false);
23846
+ const [error, setError] = useState72(null);
23847
+ const [said, setSaid] = useState72(null);
23848
+ const [formsError, setFormsError] = useState72(null);
23849
+ const [formsUnread, setFormsUnread] = useState72(false);
23850
+ useEffect61(() => {
23487
23851
  let cancelled = false;
23488
23852
  void (async () => {
23489
23853
  try {
@@ -23503,7 +23867,7 @@ function PortalLookEditor({ card, onSaved, className }) {
23503
23867
  cancelled = true;
23504
23868
  };
23505
23869
  }, [card, client]);
23506
- const orgName = useMemo38(
23870
+ const orgName = useMemo39(
23507
23871
  () => card.style.from_organization.includes("display_name") ? card.style.display_name : null,
23508
23872
  [card.style]
23509
23873
  );
@@ -23765,18 +24129,18 @@ function stateWords(person) {
23765
24129
  }
23766
24130
  var PORTAL_SUGGESTION = "Let each of my customers sign in and see their own jobs and invoices, and nothing else.";
23767
24131
  function PortalsPanel({ tableId, activePortalId, className }) {
23768
- const client = useRecordsClient52();
24132
+ const client = useRecordsClient54();
23769
24133
  const host = useRecordsUi();
23770
- const [portals, setPortals] = useState72(null);
23771
- const [exposures, setExposures] = useState72([]);
23772
- const [listError, setListError] = useState72(null);
23773
- const [openId, setOpenId] = useState72(activePortalId ?? null);
23774
- useEffect59(() => {
24134
+ const [portals, setPortals] = useState73(null);
24135
+ const [exposures, setExposures] = useState73([]);
24136
+ const [listError, setListError] = useState73(null);
24137
+ const [openId, setOpenId] = useState73(activePortalId ?? null);
24138
+ useEffect62(() => {
23775
24139
  if (activePortalId) setOpenId(activePortalId);
23776
24140
  }, [activePortalId]);
23777
- const [building, setBuilding] = useState72(false);
23778
- const [adding, setAdding] = useState72(null);
23779
- const [archiveToken, setArchiveToken] = useState72(0);
24141
+ const [building, setBuilding] = useState73(false);
24142
+ const [adding, setAdding] = useState73(null);
24143
+ const [archiveToken, setArchiveToken] = useState73(0);
23780
24144
  const load = useCallback35(async () => {
23781
24145
  const [answered, mapped] = await Promise.all([client.portals(), client.portalTables()]);
23782
24146
  if (!answered.ok) {
@@ -23789,7 +24153,7 @@ function PortalsPanel({ tableId, activePortalId, className }) {
23789
24153
  setPortals(answered.data);
23790
24154
  setExposures(mapped.ok ? mapped.data : []);
23791
24155
  }, [client]);
23792
- useEffect59(() => {
24156
+ useEffect62(() => {
23793
24157
  void load();
23794
24158
  }, [load]);
23795
24159
  if (portals === null) return /* @__PURE__ */ jsx82(Skeleton21, { className: cn50("h-32 w-full", className) });
@@ -23945,12 +24309,12 @@ function ArchivePortalControl({
23945
24309
  portal,
23946
24310
  onArchived
23947
24311
  }) {
23948
- const client = useRecordsClient52();
23949
- const [asking, setAsking] = useState72(false);
23950
- const [typed, setTyped] = useState72("");
23951
- const [busy, setBusy] = useState72(false);
23952
- const [error, setError] = useState72(null);
23953
- const [said, setSaid] = useState72(null);
24312
+ const client = useRecordsClient54();
24313
+ const [asking, setAsking] = useState73(false);
24314
+ const [typed, setTyped] = useState73("");
24315
+ const [busy, setBusy] = useState73(false);
24316
+ const [error, setError] = useState73(null);
24317
+ const [said, setSaid] = useState73(null);
23954
24318
  const go = async () => {
23955
24319
  setBusy(true);
23956
24320
  setError(null);
@@ -24017,8 +24381,8 @@ function ArchivePortalControl({
24017
24381
  ] });
24018
24382
  }
24019
24383
  function CopyLink({ url, what }) {
24020
- const [copied, setCopied] = useState72(false);
24021
- const [shown3, setShown] = useState72(false);
24384
+ const [copied, setCopied] = useState73(false);
24385
+ const [shown3, setShown] = useState73(false);
24022
24386
  return /* @__PURE__ */ jsxs74(Fragment34, { children: [
24023
24387
  /* @__PURE__ */ jsx82(
24024
24388
  Button62,
@@ -24052,9 +24416,9 @@ function PortalDetail({
24052
24416
  origin,
24053
24417
  onChanged
24054
24418
  }) {
24055
- const client = useRecordsClient52();
24056
- const [card, setCard] = useState72(null);
24057
- const [error, setError] = useState72(null);
24419
+ const client = useRecordsClient54();
24420
+ const [card, setCard] = useState73(null);
24421
+ const [error, setError] = useState73(null);
24058
24422
  const load = useCallback35(async () => {
24059
24423
  const answered = await client.portalCard({ portal_id: portalId });
24060
24424
  if (!answered.ok) {
@@ -24065,7 +24429,7 @@ function PortalDetail({
24065
24429
  setError(null);
24066
24430
  setCard(answered.data);
24067
24431
  }, [client, portalId]);
24068
- useEffect59(() => {
24432
+ useEffect62(() => {
24069
24433
  void load();
24070
24434
  }, [load]);
24071
24435
  const revoke = useCallback35(
@@ -24182,11 +24546,11 @@ function People({
24182
24546
  origin
24183
24547
  }) {
24184
24548
  const here = origin ?? (typeof window === "undefined" ? "" : window.location.origin);
24185
- const [askingToRevoke, setAskingToRevoke] = useState72(null);
24186
- const [busy, setBusy] = useState72(false);
24187
- const [said, setSaid] = useState72(null);
24188
- const [error, setError] = useState72(null);
24189
- const [previewing, setPreviewing] = useState72(null);
24549
+ const [askingToRevoke, setAskingToRevoke] = useState73(null);
24550
+ const [busy, setBusy] = useState73(false);
24551
+ const [said, setSaid] = useState73(null);
24552
+ const [error, setError] = useState73(null);
24553
+ const [previewing, setPreviewing] = useState73(null);
24190
24554
  const revoke = useCallback35(
24191
24555
  async (person) => {
24192
24556
  setBusy(true);
@@ -24270,10 +24634,10 @@ function Preview({
24270
24634
  onPreview
24271
24635
  }) {
24272
24636
  const first = card.tables[0];
24273
- const [which, setWhich] = useState72(first?.table_id ?? null);
24274
- const [rows, setRows] = useState72(null);
24275
- const [error, setError] = useState72(null);
24276
- useEffect59(() => {
24637
+ const [which, setWhich] = useState73(first?.table_id ?? null);
24638
+ const [rows, setRows] = useState73(null);
24639
+ const [error, setError] = useState73(null);
24640
+ useEffect62(() => {
24277
24641
  if (!which) return;
24278
24642
  let cancelled = false;
24279
24643
  setRows(null);
@@ -24310,16 +24674,16 @@ function Preview({
24310
24674
  ] });
24311
24675
  }
24312
24676
  function Invite({ card, onInvited }) {
24313
- const client = useRecordsClient52();
24314
- const [rows, setRows] = useState72(null);
24315
- const [clientTable, setClientTable] = useState72(null);
24316
- const [search, setSearch] = useState72("");
24317
- const [picked, setPicked] = useState72(null);
24318
- const [email, setEmail] = useState72("");
24319
- const [busy, setBusy] = useState72(false);
24320
- const [said, setSaid] = useState72(null);
24321
- const [error, setError] = useState72(null);
24322
- useEffect59(() => {
24677
+ const client = useRecordsClient54();
24678
+ const [rows, setRows] = useState73(null);
24679
+ const [clientTable, setClientTable] = useState73(null);
24680
+ const [search, setSearch] = useState73("");
24681
+ const [picked, setPicked] = useState73(null);
24682
+ const [email, setEmail] = useState73("");
24683
+ const [busy, setBusy] = useState73(false);
24684
+ const [said, setSaid] = useState73(null);
24685
+ const [error, setError] = useState73(null);
24686
+ useEffect62(() => {
24323
24687
  let cancelled = false;
24324
24688
  void client.list({ table_id: card.client_table_id, limit: 200 }).then((answered) => {
24325
24689
  if (cancelled) return;
@@ -24337,7 +24701,7 @@ function Invite({ card, onInvited }) {
24337
24701
  cancelled = true;
24338
24702
  };
24339
24703
  }, [client, card.client_table_id]);
24340
- const options = useMemo39(() => {
24704
+ const options = useMemo40(() => {
24341
24705
  const all = (rows ?? []).map((row) => ({ id: row.id, name: rowNameIn(clientTable, row) }));
24342
24706
  const needle = search.trim().toLowerCase();
24343
24707
  return needle === "" ? all.slice(0, 25) : all.filter((o) => o.name.toLowerCase().includes(needle)).slice(0, 25);
@@ -24421,8 +24785,9 @@ function Invite({ card, onInvited }) {
24421
24785
  }
24422
24786
 
24423
24787
  // src/DigestScheduler.tsx
24424
- import { useCallback as useCallback36, useEffect as useEffect60, useMemo as useMemo40, useState as useState73 } from "react";
24425
- import { useRecordsClient as useRecordsClient53, useTable as useTable16 } from "@ai-matrx/records/react";
24788
+ import { useCallback as useCallback36, useEffect as useEffect63, useMemo as useMemo41, useState as useState74 } from "react";
24789
+ import { useRecordsClient as useRecordsClient55, useTable as useTable16 } from "@ai-matrx/records/react";
24790
+ import { hasQuietHours } from "@ai-matrx/records";
24426
24791
  import { BasicInput as BasicInput24, Button as Button63, Checkbox as Checkbox10, Label as Label17, Separator as Separator11, Skeleton as Skeleton22, cn as cn51 } from "@ai-matrx/design-system";
24427
24792
 
24428
24793
  // src/scheduleWords.ts
@@ -24465,6 +24830,12 @@ var CHANNEL_WORDS = {
24465
24830
  email: "by email \u2014 only if an address is on their account",
24466
24831
  sms: "by text \u2014 only if a number is on their account"
24467
24832
  };
24833
+ function scheduleParts(schedule) {
24834
+ const words2 = (schedule ?? "").trim().toLowerCase().split(/\s+/);
24835
+ const time = words2.find((w) => /^\d{1,2}:\d{2}$/.test(w)) ?? null;
24836
+ const day = WEEKDAYS.find((d) => words2.some((w) => w.slice(0, 3) === d.slice(0, 3))) ?? null;
24837
+ return { day, time: time ? time.padStart(5, "0") : null };
24838
+ }
24468
24839
  function DigestScheduler({
24469
24840
  tableId,
24470
24841
  savedViewId,
@@ -24472,31 +24843,46 @@ function DigestScheduler({
24472
24843
  filters,
24473
24844
  onScheduled,
24474
24845
  onClose,
24475
- className
24846
+ className,
24847
+ existing
24476
24848
  }) {
24477
- const client = useRecordsClient53();
24849
+ const client = useRecordsClient55();
24478
24850
  const host = useRecordsUi();
24479
- const [views, setViews] = useState73(null);
24480
- const [cadences, setCadences] = useState73([]);
24481
- const [members, setMembers] = useState73(null);
24482
- const [error, setError] = useState73(null);
24483
- const [viewId, setViewId] = useState73(savedViewId ?? "");
24484
- const [name, setName] = useState73(subjectName?.trim() ? `${subjectName.trim()} summary` : "");
24485
- const [cadence, setCadence] = useState73("weekly");
24486
- const [weekday, setWeekday] = useState73("monday");
24487
- const [time, setTime] = useState73("08:00");
24488
- const [timezone, setTimezone] = useState73(() => ownTimeZone());
24851
+ const [views, setViews] = useState74(null);
24852
+ const [cadences, setCadences] = useState74([]);
24853
+ const [members, setMembers] = useState74(null);
24854
+ const [error, setError] = useState74(null);
24855
+ const was = scheduleParts(existing?.schedule);
24856
+ const [viewId, setViewId] = useState74(
24857
+ existing?.saved_view_id ?? savedViewId ?? ""
24858
+ );
24859
+ const [name, setName] = useState74(
24860
+ existing?.name ?? (subjectName?.trim() ? `${subjectName.trim()} summary` : "")
24861
+ );
24862
+ const [cadence, setCadence] = useState74(
24863
+ ["hourly", "daily", "weekly"].includes(existing?.cadence ?? "") ? existing.cadence : "weekly"
24864
+ );
24865
+ const [weekday, setWeekday] = useState74(was.day ?? "monday");
24866
+ const [time, setTime] = useState74(was.time ?? "08:00");
24867
+ const [timezone, setTimezone] = useState74(() => {
24868
+ const kept = existing?.quiet_hours?.tz?.trim();
24869
+ return kept && kept.toUpperCase() !== "UTC" ? kept : ownTimeZone();
24870
+ });
24489
24871
  const table = useTable16(tableId);
24490
24872
  const tableName2 = table.data?.name?.trim() || null;
24491
- const [channel, setChannel] = useState73("in_app");
24492
- const [quiet, setQuiet] = useState73(false);
24493
- const [quietFrom, setQuietFrom] = useState73("22:00");
24494
- const [quietTo, setQuietTo] = useState73("07:00");
24495
- const [recipients, setRecipients] = useState73([]);
24496
- const [saving, setSaving] = useState73(false);
24497
- const [outcomes, setOutcomes] = useState73(null);
24498
- const [preview, setPreview] = useState73(null);
24499
- const [previewing, setPreviewing] = useState73(false);
24873
+ const [channel, setChannel] = useState74(
24874
+ existing?.channel === "email" || existing?.channel === "sms" ? existing.channel : "in_app"
24875
+ );
24876
+ const [quiet, setQuiet] = useState74(hasQuietHours(existing?.quiet_hours));
24877
+ const [quietFrom, setQuietFrom] = useState74(existing?.quiet_hours?.start ?? "22:00");
24878
+ const [quietTo, setQuietTo] = useState74(existing?.quiet_hours?.end ?? "07:00");
24879
+ const [recipients, setRecipients] = useState74(
24880
+ existing?.recipient_user_id ? [existing.recipient_user_id] : []
24881
+ );
24882
+ const [saving, setSaving] = useState74(false);
24883
+ const [outcomes, setOutcomes] = useState74(null);
24884
+ const [preview, setPreview] = useState74(null);
24885
+ const [previewing, setPreviewing] = useState74(false);
24500
24886
  const load = useCallback36(async () => {
24501
24887
  const [saved, offered] = await Promise.all([
24502
24888
  // The store's own door onto `platform.saved_view`, narrowed in SQL to
@@ -24516,15 +24902,15 @@ function DigestScheduler({
24516
24902
  setMembers([]);
24517
24903
  }
24518
24904
  }, [client, tableId, host]);
24519
- useEffect60(() => {
24905
+ useEffect63(() => {
24520
24906
  void load();
24521
24907
  }, [load]);
24522
- const schedule = useMemo40(() => {
24908
+ const schedule = useMemo41(() => {
24523
24909
  if (cadence === "weekly") return `${weekday} ${time}`;
24524
24910
  if (cadence === "daily") return time;
24525
24911
  return null;
24526
24912
  }, [cadence, weekday, time]);
24527
- const quietHours = useMemo40(
24913
+ const quietHours = useMemo41(
24528
24914
  () => quiet ? { start: quietFrom, end: quietTo, tz: timezone } : { tz: timezone },
24529
24915
  [quiet, quietFrom, quietTo, timezone]
24530
24916
  );
@@ -24563,7 +24949,8 @@ function DigestScheduler({
24563
24949
  schedule,
24564
24950
  channel,
24565
24951
  quiet_hours: quietHours,
24566
- ...userId === "" ? {} : { recipient_user_id: userId }
24952
+ ...userId === "" ? {} : { recipient_user_id: userId },
24953
+ ...existing ? { rule_id: existing.rule_id } : {}
24567
24954
  }
24568
24955
  });
24569
24956
  if (written.ok) done.push({ userId, who: label, ruleId: written.data });
@@ -24586,9 +24973,9 @@ function DigestScheduler({
24586
24973
  if (views === null && !error) return /* @__PURE__ */ jsx83(Skeleton22, { className: cn51("h-56 w-full", className) });
24587
24974
  return /* @__PURE__ */ jsxs75("section", { className: cn51("@container flex flex-col gap-3", className), children: [
24588
24975
  /* @__PURE__ */ jsxs75("header", { className: "flex items-center gap-2", children: [
24589
- /* @__PURE__ */ jsx83("h3", { className: "text-sm font-medium", children: "Send this on a schedule" }),
24976
+ /* @__PURE__ */ jsx83("h3", { className: "text-sm font-medium", children: existing ? "Change this summary" : "Send this on a schedule" }),
24590
24977
  /* @__PURE__ */ jsx83("div", { className: "flex-1" }),
24591
- /* @__PURE__ */ jsx83(Button63, { size: "sm", disabled: saving, onClick: () => void scheduleIt(), children: saving ? "Scheduling\u2026" : "Schedule it" }),
24978
+ /* @__PURE__ */ jsx83(Button63, { size: "sm", disabled: saving, onClick: () => void scheduleIt(), children: saving ? "Scheduling\u2026" : existing ? "Save the change" : "Schedule it" }),
24592
24979
  onClose ? /* @__PURE__ */ jsx83(Button63, { size: "sm", variant: "ghost", onClick: onClose, children: "Close" }) : null
24593
24980
  ] }),
24594
24981
  error ? /* @__PURE__ */ jsx83(RefusalNotice, { error }) : null,
@@ -24770,14 +25157,14 @@ function DigestScheduler({
24770
25157
  }
24771
25158
 
24772
25159
  // src/SubscriptionsPanel.tsx
24773
- import { useCallback as useCallback38, useEffect as useEffect62, useState as useState75 } from "react";
24774
- import { useRecordsClient as useRecordsClient55 } from "@ai-matrx/records/react";
24775
- import { hasQuietHours } from "@ai-matrx/records";
25160
+ import { useCallback as useCallback38, useEffect as useEffect65, useState as useState76 } from "react";
25161
+ import { useRecordsClient as useRecordsClient57 } from "@ai-matrx/records/react";
25162
+ import { hasQuietHours as hasQuietHours2 } from "@ai-matrx/records";
24776
25163
  import { Badge as Badge21, Button as Button65, Skeleton as Skeleton24, Switch as Switch2, cn as cn53 } from "@ai-matrx/design-system";
24777
25164
 
24778
25165
  // src/WebhooksPanel.tsx
24779
- import { useCallback as useCallback37, useEffect as useEffect61, useState as useState74 } from "react";
24780
- import { useRecordsClient as useRecordsClient54, useTable as useTable17 } from "@ai-matrx/records/react";
25166
+ import { useCallback as useCallback37, useEffect as useEffect64, useState as useState75 } from "react";
25167
+ import { useRecordsClient as useRecordsClient56, useTable as useTable17 } from "@ai-matrx/records/react";
24781
25168
  import { BasicInput as BasicInput25, Button as Button64, Checkbox as Checkbox11, ConfirmDialog as ConfirmDialog6, Label as Label18, Skeleton as Skeleton23, cn as cn52 } from "@ai-matrx/design-system";
24782
25169
  import { jsx as jsx84, jsxs as jsxs76 } from "react/jsx-runtime";
24783
25170
  var WEBHOOK_EVENT_LABEL = {
@@ -24797,29 +25184,32 @@ function health(hook) {
24797
25184
  return "Nothing has changed since it was set up, so nothing has been sent yet.";
24798
25185
  }
24799
25186
  function WebhooksPanel({ tableId, className }) {
24800
- const client = useRecordsClient54();
25187
+ const client = useRecordsClient56();
24801
25188
  const table = useTable17(tableId);
24802
25189
  const rights = useTableRights(table.data);
24803
- const [hooks, setHooks] = useState74(null);
24804
- const [error, setError] = useState74(null);
24805
- const [adding, setAdding] = useState74(false);
24806
- const [url, setUrl] = useState74("");
24807
- const [description, setDescription] = useState74("");
24808
- const [events, setEvents] = useState74(DEFAULT_EVENTS);
24809
- const [busy, setBusy] = useState74(false);
24810
- const [declared2, setDeclared] = useState74(null);
24811
- const [stopping, setStopping] = useState74(null);
25190
+ const [hooks, setHooks] = useState75(null);
25191
+ const [error, setError] = useState75(null);
25192
+ const [adding, setAdding] = useState75(false);
25193
+ const [url, setUrl] = useState75("");
25194
+ const [description, setDescription] = useState75("");
25195
+ const [events, setEvents] = useState75(DEFAULT_EVENTS);
25196
+ const [busy, setBusy] = useState75(false);
25197
+ const [declared2, setDeclared] = useState75(null);
25198
+ const [stopping, setStopping] = useState75(null);
25199
+ const [readRefused, setReadRefused] = useState75(null);
24812
25200
  const load = useCallback37(async () => {
24813
25201
  const answered = await client.tableWebhooks({ table_id: tableId });
24814
25202
  if (!answered.ok) {
25203
+ setReadRefused(answered.error);
24815
25204
  setError(answered.error);
24816
25205
  setHooks([]);
24817
25206
  return;
24818
25207
  }
25208
+ setReadRefused(null);
24819
25209
  setError(null);
24820
25210
  setHooks(answered.data ?? []);
24821
25211
  }, [client, tableId]);
24822
- useEffect61(() => {
25212
+ useEffect64(() => {
24823
25213
  void load();
24824
25214
  }, [load]);
24825
25215
  const declare2 = async () => {
@@ -24844,6 +25234,17 @@ function WebhooksPanel({ tableId, className }) {
24844
25234
  await load();
24845
25235
  };
24846
25236
  if (hooks === null) return /* @__PURE__ */ jsx84(Skeleton23, { className: cn52("h-16 w-full", className) });
25237
+ const notHers = readRefused?.sqlstate === "42501" && rights.known && !rights.structure;
25238
+ if (notHers) {
25239
+ return /* @__PURE__ */ jsxs76("section", { "data-records-webhooks": "", className: cn52("flex flex-col gap-2 border-t pt-3", className), children: [
25240
+ /* @__PURE__ */ jsx84("header", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsx84("h3", { className: "text-sm font-medium", children: "Webhooks" }) }),
25241
+ /* @__PURE__ */ jsxs76("p", { className: "text-xs text-muted-foreground", children: [
25242
+ "Which other systems are told about these records is for this table's admins.",
25243
+ " ",
25244
+ rights.why("structure")
25245
+ ] })
25246
+ ] });
25247
+ }
24847
25248
  const mayChange = rights.structure;
24848
25249
  const live = hooks.filter((h) => h.is_active);
24849
25250
  return /* @__PURE__ */ jsxs76("section", { "data-records-webhooks": "", className: cn52("flex flex-col gap-2 border-t pt-3", className), children: [
@@ -24978,12 +25379,13 @@ function nextSummaryAt(subscription, now) {
24978
25379
  var CHANNEL_WORDS2 = SUBSCRIPTION_CHANNEL_LABEL;
24979
25380
  var DIGEST_SUGGESTION = "Email me a summary of this every Monday at 8 in the morning.";
24980
25381
  function SubscriptionsPanel({ tableId, activeRuleId, className }) {
24981
- const client = useRecordsClient55();
24982
- const [rows, setRows] = useState75(null);
24983
- const [error, setError] = useState75(null);
24984
- const [busy, setBusy] = useState75(null);
24985
- const [preview, setPreview] = useState75(null);
24986
- const [scheduling, setScheduling] = useState75(false);
25382
+ const client = useRecordsClient57();
25383
+ const [rows, setRows] = useState76(null);
25384
+ const [error, setError] = useState76(null);
25385
+ const [busy, setBusy] = useState76(null);
25386
+ const [preview, setPreview] = useState76(null);
25387
+ const [scheduling, setScheduling] = useState76(false);
25388
+ const [changing, setChanging] = useState76(null);
24987
25389
  const host = useRecordsUi();
24988
25390
  const load = useCallback38(async () => {
24989
25391
  const answered = await client.subscriptions({ table_id: tableId });
@@ -24995,7 +25397,7 @@ function SubscriptionsPanel({ tableId, activeRuleId, className }) {
24995
25397
  setError(null);
24996
25398
  setRows(answered.data);
24997
25399
  }, [client, tableId]);
24998
- useEffect62(() => {
25400
+ useEffect65(() => {
24999
25401
  void load();
25000
25402
  }, [load]);
25001
25403
  const flip = useCallback38(
@@ -25055,6 +25457,18 @@ function SubscriptionsPanel({ tableId, activeRuleId, className }) {
25055
25457
  onClose: () => setScheduling(false)
25056
25458
  }
25057
25459
  ) : null,
25460
+ changing ? /* @__PURE__ */ jsx85(
25461
+ DigestScheduler,
25462
+ {
25463
+ tableId,
25464
+ existing: changing,
25465
+ onScheduled: () => {
25466
+ void load();
25467
+ },
25468
+ onClose: () => setChanging(null)
25469
+ },
25470
+ changing.rule_id
25471
+ ) : null,
25058
25472
  rows.length === 0 && !scheduling ? /* @__PURE__ */ jsx85(
25059
25473
  BuildOrAsk,
25060
25474
  {
@@ -25108,7 +25522,7 @@ function SubscriptionsPanel({ tableId, activeRuleId, className }) {
25108
25522
  "Last told you ",
25109
25523
  new Date(subscription.last_sent_at).toLocaleString()
25110
25524
  ] }) : /* @__PURE__ */ jsx85("span", { children: "It has not told you anything yet." }),
25111
- hasQuietHours(subscription.quiet_hours) ? /* @__PURE__ */ jsxs77("span", { children: [
25525
+ hasQuietHours2(subscription.quiet_hours) ? /* @__PURE__ */ jsxs77("span", { children: [
25112
25526
  "Not between ",
25113
25527
  subscription.quiet_hours.start,
25114
25528
  " and ",
@@ -25124,7 +25538,8 @@ function SubscriptionsPanel({ tableId, activeRuleId, className }) {
25124
25538
  onClick: () => void showOne(subscription),
25125
25539
  children: "Send me a preview now"
25126
25540
  }
25127
- )
25541
+ ),
25542
+ subscription.mine && subscription.cadence !== "instant" ? /* @__PURE__ */ jsx85(Button65, { size: "sm", variant: "ghost", onClick: () => setChanging(subscription), children: "Change it" }) : null
25128
25543
  ] }),
25129
25544
  preview && preview.rule_id === subscription.rule_id ? /* @__PURE__ */ jsxs77("div", { className: "mt-2 rounded-md border bg-muted/40 p-2.5 text-xs", children: [
25130
25545
  /* @__PURE__ */ jsx85("p", { className: "font-medium", children: preview.subject }),
@@ -25171,8 +25586,8 @@ function SubscriptionsPanel({ tableId, activeRuleId, className }) {
25171
25586
  }
25172
25587
 
25173
25588
  // src/FormBuilder.tsx
25174
- import { useCallback as useCallback41, useEffect as useEffect65, useMemo as useMemo42, useState as useState78 } from "react";
25175
- import { useFields as useFields20, useRecordsClient as useRecordsClient57, useTable as useTable19 } from "@ai-matrx/records/react";
25589
+ import { useCallback as useCallback41, useEffect as useEffect68, useMemo as useMemo43, useState as useState79 } from "react";
25590
+ import { useFields as useFields20, useRecordsClient as useRecordsClient59, useTable as useTable19 } from "@ai-matrx/records/react";
25176
25591
  import { publicFormPath } from "@ai-matrx/records";
25177
25592
  import {
25178
25593
  BasicInput as BasicInput26,
@@ -25185,7 +25600,7 @@ import {
25185
25600
  } from "@ai-matrx/design-system";
25186
25601
 
25187
25602
  // src/FormRunner.tsx
25188
- import { useCallback as useCallback39, useEffect as useEffect63, useMemo as useMemo41, useRef as useRef24, useState as useState76 } from "react";
25603
+ import { useCallback as useCallback39, useEffect as useEffect66, useMemo as useMemo42, useRef as useRef24, useState as useState77 } from "react";
25189
25604
  import { useFields as useFields19, useOptionalRecordsClient as useOptionalRecordsClient8 } from "@ai-matrx/records/react";
25190
25605
  import { Button as Button66, Progress, Skeleton as Skeleton25, cn as cn54 } from "@ai-matrx/design-system";
25191
25606
  import { Fragment as Fragment36, jsx as jsx86, jsxs as jsxs78 } from "react/jsx-runtime";
@@ -25278,16 +25693,16 @@ function FormStage({
25278
25693
  connected = false
25279
25694
  }) {
25280
25695
  const host = useRecordsUi();
25281
- const [answers, setAnswers] = useState76(() => ({ ...initialAnswers ?? {} }));
25282
- const [at, setAt] = useState76(0);
25283
- const [error, setError] = useState76(null);
25284
- const [refusal2, setRefusal] = useState76(null);
25285
- const [writing, setWriting] = useState76(false);
25286
- const [done, setDone] = useState76(null);
25287
- const [hidden, setHidden] = useState76({});
25696
+ const [answers, setAnswers] = useState77(() => ({ ...initialAnswers ?? {} }));
25697
+ const [at, setAt] = useState77(0);
25698
+ const [error, setError] = useState77(null);
25699
+ const [refusal2, setRefusal] = useState77(null);
25700
+ const [writing, setWriting] = useState77(false);
25701
+ const [done, setDone] = useState77(null);
25702
+ const [hidden, setHidden] = useState77({});
25288
25703
  const decoy = useRef24("");
25289
25704
  const stage = useRef24(null);
25290
- const questions = useMemo41(() => {
25705
+ const questions = useMemo42(() => {
25291
25706
  const byKey = new Map((fields ?? []).map((f) => [f.key, f]));
25292
25707
  return (form.questions ?? []).map((q) => {
25293
25708
  const field2 = byKey.get(q.field) ?? null;
@@ -25301,7 +25716,7 @@ function FormStage({
25301
25716
  };
25302
25717
  });
25303
25718
  }, [fields, form.questions]);
25304
- useEffect63(() => {
25719
+ useEffect66(() => {
25305
25720
  if (!whichAsked) return;
25306
25721
  if (!questions.some((q) => q.showIf)) return;
25307
25722
  let cancelled = false;
@@ -25345,7 +25760,7 @@ function FormStage({
25345
25760
  }, [whichAsked, questions, answers]);
25346
25761
  const live = questions.filter((q) => !hidden[q.key]);
25347
25762
  const told = useRef24(answers);
25348
- useEffect63(() => {
25763
+ useEffect66(() => {
25349
25764
  if (told.current === answers) return;
25350
25765
  told.current = answers;
25351
25766
  onAnswersChange?.(answers);
@@ -25356,7 +25771,7 @@ function FormStage({
25356
25771
  return v === void 0 || v === null || v === "";
25357
25772
  })?.key ?? null : null
25358
25773
  );
25359
- useEffect63(() => {
25774
+ useEffect66(() => {
25360
25775
  const key = resumeAt.current;
25361
25776
  if (!key) return;
25362
25777
  const i = live.findIndex((q) => q.key === key);
@@ -25422,7 +25837,7 @@ function FormStage({
25422
25837
  if (event.shiftKey) retreat();
25423
25838
  else advance();
25424
25839
  }
25425
- useEffect63(() => {
25840
+ useEffect66(() => {
25426
25841
  const input = stage.current?.querySelector(
25427
25842
  "input:not([tabindex='-1']), textarea, select, [role='combobox']"
25428
25843
  );
@@ -25533,7 +25948,7 @@ function ThankYou({ form, done, className }) {
25533
25948
  const host = useRecordsUi();
25534
25949
  const redirect = form.thankYou?.redirectUrl?.trim() || null;
25535
25950
  const going = redirect !== null && done !== "preview";
25536
- useEffect63(() => {
25951
+ useEffect66(() => {
25537
25952
  if (!going || !redirect) return;
25538
25953
  const timer = window.setTimeout(() => window.location.assign(redirect), REDIRECT_AFTER_MS);
25539
25954
  return () => window.clearTimeout(timer);
@@ -25546,7 +25961,12 @@ function ThankYou({ form, done, className }) {
25546
25961
  " ",
25547
25962
  /* @__PURE__ */ jsx86("a", { href: redirect, className: "underline underline-offset-2", children: "Go now" })
25548
25963
  ] }) : null,
25549
- /* @__PURE__ */ jsx86("p", { className: "mt-3 text-xs text-muted-foreground", children: done === "preview" ? redirect ? `This was a preview, so nothing was written. The live form goes on to ${redirect}.` : "This was a preview, so nothing was written." : done === "sent" ? `Saved to ${form.name}, with this form stamped on it.` : done })
25964
+ /* @__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" ? (
25965
+ // SAID TO THE PERSON WHO ANSWERED (lane HANDOVER, 2026-09-29): "Saved to Form 1, with
25966
+ // this form stamped on it" was the owner's bookkeeping read out to a front-desk member
25967
+ // and to strangers. Where it landed is the owner's to see on the table.
25968
+ "Your answers were received."
25969
+ ) : done })
25550
25970
  ] });
25551
25971
  }
25552
25972
  function Question({
@@ -25556,7 +25976,7 @@ function Question({
25556
25976
  upload
25557
25977
  }) {
25558
25978
  const host = useRecordsUi();
25559
- const [uploadError, setUploadError] = useState76(null);
25979
+ const [uploadError, setUploadError] = useState77(null);
25560
25980
  const field2 = question.field;
25561
25981
  if (!field2) return null;
25562
25982
  const id = `form-${field2.key}`;
@@ -25592,24 +26012,24 @@ function Question({
25592
26012
  }
25593
26013
 
25594
26014
  // src/NotifyRuleEditor.tsx
25595
- import { useCallback as useCallback40, useEffect as useEffect64, useState as useState77 } from "react";
25596
- import { useRecordsClient as useRecordsClient56, useTable as useTable18 } from "@ai-matrx/records/react";
25597
- import { hasQuietHours as hasQuietHours2 } from "@ai-matrx/records";
26015
+ import { useCallback as useCallback40, useEffect as useEffect67, useState as useState78 } from "react";
26016
+ import { useRecordsClient as useRecordsClient58, useTable as useTable18 } from "@ai-matrx/records/react";
26017
+ import { hasQuietHours as hasQuietHours3 } from "@ai-matrx/records";
25598
26018
  import { Button as Button67, Skeleton as Skeleton26, cn as cn55 } from "@ai-matrx/design-system";
25599
26019
  import { jsx as jsx87, jsxs as jsxs79 } from "react/jsx-runtime";
25600
26020
  var CADENCE_WORDS2 = SUBSCRIPTION_CADENCE_LABEL;
25601
26021
  var CHANNEL_WORDS3 = SUBSCRIPTION_CHANNEL_LABEL;
25602
26022
  function NotifyRuleEditor({ tableId, seed, chosenRuleId, onChoose, className }) {
25603
- const client = useRecordsClient56();
26023
+ const client = useRecordsClient58();
25604
26024
  const host = useRecordsUi();
25605
26025
  const table = useTable18(tableId);
25606
26026
  const rights = useTableRights(table.data);
25607
- const [subscriptions, setSubscriptions] = useState77(null);
25608
- const [cadences, setCadences] = useState77([]);
25609
- const [views, setViews] = useState77(null);
25610
- const [error, setError] = useState77(null);
25611
- const [busy, setBusy] = useState77(false);
25612
- const [stopping, setStopping] = useState77(null);
26027
+ const [subscriptions, setSubscriptions] = useState78(null);
26028
+ const [cadences, setCadences] = useState78([]);
26029
+ const [views, setViews] = useState78(null);
26030
+ const [error, setError] = useState78(null);
26031
+ const [busy, setBusy] = useState78(false);
26032
+ const [stopping, setStopping] = useState78(null);
25613
26033
  const load = useCallback40(async () => {
25614
26034
  const [held, offered] = await Promise.all([
25615
26035
  // THE PERSON'S OWN DOOR, not the notifier's. It answers what is addressed
@@ -25638,7 +26058,7 @@ function NotifyRuleEditor({ tableId, seed, chosenRuleId, onChoose, className })
25638
26058
  }
25639
26059
  setViews(listed.data.map((v) => ({ id: v.view_id, name: v.name })));
25640
26060
  }, [client, host, tableId]);
25641
- useEffect64(() => {
26061
+ useEffect67(() => {
25642
26062
  void load();
25643
26063
  }, [load]);
25644
26064
  const write = useCallback40(
@@ -25666,7 +26086,7 @@ function NotifyRuleEditor({ tableId, seed, chosenRuleId, onChoose, className })
25666
26086
  },
25667
26087
  [client, tableId]
25668
26088
  );
25669
- useEffect64(() => {
26089
+ useEffect67(() => {
25670
26090
  if (!subscriptions || !seed || seed.length === 0) return;
25671
26091
  const missing = seed.filter((s) => !subscriptions.some((held) => held.name === s.name));
25672
26092
  if (missing.length === 0) return;
@@ -25745,7 +26165,7 @@ function NotifyRuleEditor({ tableId, seed, chosenRuleId, onChoose, className })
25745
26165
  "next ",
25746
26166
  new Date(held.next_digest_at).toLocaleString()
25747
26167
  ] }) : null,
25748
- hasQuietHours2(held.quiet_hours) ? /* @__PURE__ */ jsxs79("span", { className: "text-muted-foreground", children: [
26168
+ hasQuietHours3(held.quiet_hours) ? /* @__PURE__ */ jsxs79("span", { className: "text-muted-foreground", children: [
25749
26169
  "quiet ",
25750
26170
  held.quiet_hours.start,
25751
26171
  "\u2013",
@@ -25849,23 +26269,23 @@ function NotifyRuleEditor({ tableId, seed, chosenRuleId, onChoose, className })
25849
26269
  // src/FormBuilder.tsx
25850
26270
  import { Fragment as Fragment37, jsx as jsx88, jsxs as jsxs80 } from "react/jsx-runtime";
25851
26271
  function FormBuilder({ tableId, seed, activeFormId, onActiveForm, startWithOne, className }) {
25852
- const client = useRecordsClient57();
26272
+ const client = useRecordsClient59();
25853
26273
  const publishGate = usePublishGate();
25854
26274
  const host = useRecordsUi();
25855
26275
  const claimSeed = useSeedGuard();
25856
26276
  const table = useTable19(tableId);
25857
26277
  const rights = useTableRights(table.data);
25858
26278
  const fields = useFields20(tableId);
25859
- const [forms, setForms] = useState78(null);
25860
- const [error, setError] = useState78(null);
25861
- const [refused, setRefused] = useState78(null);
25862
- const [activeId, setActiveId] = useState78(activeFormId ?? null);
25863
- const [draft, setDraft] = useState78(null);
25864
- const [saving, setSaving] = useState78(false);
25865
- const [saved, setSaved] = useState78(null);
25866
- const [publishing, setPublishing] = useState78(false);
25867
- const [copied, setCopied] = useState78(false);
25868
- const [shownUrl, setShownUrl] = useState78(null);
26279
+ const [forms, setForms] = useState79(null);
26280
+ const [error, setError] = useState79(null);
26281
+ const [refused, setRefused] = useState79(null);
26282
+ const [activeId, setActiveId] = useState79(activeFormId ?? null);
26283
+ const [draft, setDraft] = useState79(null);
26284
+ const [saving, setSaving] = useState79(false);
26285
+ const [saved, setSaved] = useState79(null);
26286
+ const [publishing, setPublishing] = useState79(false);
26287
+ const [copied, setCopied] = useState79(false);
26288
+ const [shownUrl, setShownUrl] = useState79(null);
25869
26289
  const publicOrigin = host.publicOrigin ?? (typeof window === "undefined" ? "" : window.location.origin);
25870
26290
  const load = useCallback41(async () => {
25871
26291
  const answered = await client.forms({ table_id: tableId });
@@ -25894,17 +26314,17 @@ function FormBuilder({ tableId, seed, activeFormId, onActiveForm, startWithOne,
25894
26314
  setError(null);
25895
26315
  setForms(mine);
25896
26316
  }, [client, tableId, seed, claimSeed]);
25897
- useEffect65(() => {
26317
+ useEffect68(() => {
25898
26318
  void load();
25899
26319
  }, [load]);
25900
- useEffect65(() => {
26320
+ useEffect68(() => {
25901
26321
  if (!forms || forms.length === 0) return;
25902
26322
  const chosen = forms.find((f) => f.id === (activeFormId ?? activeId)) ?? forms[0];
25903
26323
  if (chosen.id !== activeId) setActiveId(chosen.id);
25904
26324
  setDraft(chosen);
25905
26325
  onActiveForm?.(chosen);
25906
26326
  }, [forms, activeFormId]);
25907
- const byKey = useMemo42(() => new Map((fields.data ?? []).map((f) => [f.key, f])), [fields.data]);
26327
+ const byKey = useMemo43(() => new Map((fields.data ?? []).map((f) => [f.key, f])), [fields.data]);
25908
26328
  function patch(change) {
25909
26329
  setDraft((prev) => prev ? { ...prev, ...change } : prev);
25910
26330
  setSaved(null);
@@ -25981,13 +26401,14 @@ function FormBuilder({ tableId, seed, activeFormId, onActiveForm, startWithOne,
25981
26401
  setActiveId(written.data);
25982
26402
  await load();
25983
26403
  }
25984
- const [started, setStarted] = useState78(false);
25985
- useEffect65(() => {
26404
+ const [started, setStarted] = useState79(false);
26405
+ useEffect68(() => {
25986
26406
  if (!startWithOne || started || forms === null || forms.length > 0) return;
25987
26407
  if (askableFields(fields.data ?? []).length === 0) return;
26408
+ if (!table.data && !table.error) return;
25988
26409
  setStarted(true);
25989
26410
  void create(table.data?.name?.trim() ? `${table.data.name.trim()} form` : "Form 1");
25990
- }, [startWithOne, started, forms, fields.data, create, table.data?.name]);
26411
+ }, [startWithOne, started, forms, fields.data, create, table.data, table.error]);
25991
26412
  if (fields.error) return /* @__PURE__ */ jsx88(RefusalNotice, { error: fields.error, className });
25992
26413
  if (error) {
25993
26414
  return /* @__PURE__ */ jsx88(
@@ -26464,7 +26885,7 @@ function positionBucket(windowFrom, grain, weekStart, position) {
26464
26885
  else d.setUTCFullYear(d.getUTCFullYear() + position, 0, 1);
26465
26886
  return `${d.getUTCFullYear()}-${String(d.getUTCMonth() + 1).padStart(2, "0")}-${String(d.getUTCDate()).padStart(2, "0")}T${m[4]}${m[5]}`;
26466
26887
  }
26467
- function bucketWindow(groupKey, value) {
26888
+ function bucketWindow2(groupKey, value) {
26468
26889
  const grain = BUCKET_SUFFIX.exec(groupKey)?.[1];
26469
26890
  const m = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}:\d{2}:\d{2})(.*)$/.exec(value);
26470
26891
  if (!grain || !m) return null;
@@ -26481,17 +26902,17 @@ function bucketWindow(groupKey, value) {
26481
26902
 
26482
26903
  // src/chartFrame.tsx
26483
26904
  import {
26484
- useEffect as useEffect66,
26905
+ useEffect as useEffect69,
26485
26906
  useId as useId3,
26486
26907
  useRef as useRef25,
26487
- useState as useState79
26908
+ useState as useState80
26488
26909
  } from "react";
26489
26910
  import { cn as cn57 } from "@ai-matrx/design-system";
26490
26911
  import { jsx as jsx89, jsxs as jsxs81 } from "react/jsx-runtime";
26491
26912
  function useMeasuredWidth(fallback = 480) {
26492
26913
  const ref = useRef25(null);
26493
- const [width, setWidth] = useState79(fallback);
26494
- useEffect66(() => {
26914
+ const [width, setWidth] = useState80(fallback);
26915
+ useEffect69(() => {
26495
26916
  const node = ref.current;
26496
26917
  if (!node) return;
26497
26918
  const apply = () => {
@@ -26615,23 +27036,23 @@ function isSignatureField(field2) {
26615
27036
  }
26616
27037
 
26617
27038
  // src/DocTemplate.tsx
26618
- import { useCallback as useCallback42, useEffect as useEffect67, useState as useState80 } from "react";
26619
- import { useFields as useFields21, useRecordsClient as useRecordsClient58, useTable as useTable20 } from "@ai-matrx/records/react";
27039
+ import { useCallback as useCallback42, useEffect as useEffect70, useState as useState81 } from "react";
27040
+ import { useFields as useFields21, useRecordsClient as useRecordsClient60, useTable as useTable20 } from "@ai-matrx/records/react";
26620
27041
  import { BasicInput as BasicInput27, BasicTextarea as BasicTextarea12, Button as Button69, Label as Label20, Skeleton as Skeleton28, cn as cn58 } from "@ai-matrx/design-system";
26621
27042
  import { jsx as jsx90, jsxs as jsxs82 } from "react/jsx-runtime";
26622
27043
  function DocTemplate({ tableId, seed, activeTemplateId, onActiveTemplate, className }) {
26623
- const client = useRecordsClient58();
27044
+ const client = useRecordsClient60();
26624
27045
  const claimSeed = useSeedGuard();
26625
27046
  const table = useTable20(tableId);
26626
27047
  const rights = useTableRights(table.data);
26627
27048
  const fields = useFields21(tableId);
26628
- const [templates, setTemplates] = useState80(null);
26629
- const [error, setError] = useState80(null);
26630
- const [activeId, setActiveId] = useState80(activeTemplateId ?? null);
26631
- const [draftName, setDraftName] = useState80("");
26632
- const [draftBody, setDraftBody] = useState80("");
26633
- const [unresolved, setUnresolved] = useState80([]);
26634
- const [saving, setSaving] = useState80(false);
27049
+ const [templates, setTemplates] = useState81(null);
27050
+ const [error, setError] = useState81(null);
27051
+ const [activeId, setActiveId] = useState81(activeTemplateId ?? null);
27052
+ const [draftName, setDraftName] = useState81("");
27053
+ const [draftBody, setDraftBody] = useState81("");
27054
+ const [unresolved, setUnresolved] = useState81([]);
27055
+ const [saving, setSaving] = useState81(false);
26635
27056
  const load = useCallback42(async () => {
26636
27057
  const held = await client.docTemplates({ table_id: tableId });
26637
27058
  if (!held.ok) {
@@ -26663,10 +27084,10 @@ function DocTemplate({ tableId, seed, activeTemplateId, onActiveTemplate, classN
26663
27084
  setError(null);
26664
27085
  setTemplates(rows);
26665
27086
  }, [client, tableId, seed, fields.data]);
26666
- useEffect67(() => {
27087
+ useEffect70(() => {
26667
27088
  void load();
26668
27089
  }, [load]);
26669
- useEffect67(() => {
27090
+ useEffect70(() => {
26670
27091
  if (!templates || templates.length === 0) return;
26671
27092
  const chosen = templates.find((t) => t.id === (activeTemplateId ?? activeId)) ?? templates[0];
26672
27093
  if (chosen.id !== activeId) setActiveId(chosen.id);
@@ -26674,7 +27095,7 @@ function DocTemplate({ tableId, seed, activeTemplateId, onActiveTemplate, classN
26674
27095
  setDraftBody(chosen.body);
26675
27096
  onActiveTemplate?.(chosen);
26676
27097
  }, [templates, activeTemplateId]);
26677
- useEffect67(() => {
27098
+ useEffect70(() => {
26678
27099
  let cancelled = false;
26679
27100
  if (draftBody.trim() === "") {
26680
27101
  setUnresolved([]);
@@ -26799,17 +27220,17 @@ function DocTemplate({ tableId, seed, activeTemplateId, onActiveTemplate, classN
26799
27220
  }
26800
27221
 
26801
27222
  // src/DocRender.tsx
26802
- import { useCallback as useCallback43, useEffect as useEffect68, useRef as useRef26, useState as useState81 } from "react";
26803
- import { useRecordsClient as useRecordsClient59 } from "@ai-matrx/records/react";
27223
+ import { useCallback as useCallback43, useEffect as useEffect71, useRef as useRef26, useState as useState82 } from "react";
27224
+ import { useRecordsClient as useRecordsClient61 } from "@ai-matrx/records/react";
26804
27225
  import { Button as Button70, Skeleton as Skeleton29, cn as cn59 } from "@ai-matrx/design-system";
26805
27226
  import { jsx as jsx91, jsxs as jsxs83 } from "react/jsx-runtime";
26806
27227
  function DocRender({ templateId, recordId, filename, onRendered, className }) {
26807
- const client = useRecordsClient59();
26808
- const [preview, setPreview] = useState81(null);
26809
- const [renders, setRenders] = useState81(null);
26810
- const [showing, setShowing] = useState81(null);
26811
- const [error, setError] = useState81(null);
26812
- const [busy, setBusy] = useState81(null);
27228
+ const client = useRecordsClient61();
27229
+ const [preview, setPreview] = useState82(null);
27230
+ const [renders, setRenders] = useState82(null);
27231
+ const [showing, setShowing] = useState82(null);
27232
+ const [error, setError] = useState82(null);
27233
+ const [busy, setBusy] = useState82(null);
26813
27234
  const paper = useRef26(null);
26814
27235
  const load = useCallback43(async () => {
26815
27236
  const [body, held] = await Promise.all([
@@ -26828,7 +27249,7 @@ function DocRender({ templateId, recordId, filename, onRendered, className }) {
26828
27249
  setPreview(body.data);
26829
27250
  setRenders(held.data.filter((r) => r.template_id === templateId));
26830
27251
  }, [client, templateId, recordId]);
26831
- useEffect68(() => {
27252
+ useEffect71(() => {
26832
27253
  void load();
26833
27254
  }, [load]);
26834
27255
  async function freeze() {
@@ -26912,21 +27333,21 @@ function DocRender({ templateId, recordId, filename, onRendered, className }) {
26912
27333
  }
26913
27334
 
26914
27335
  // src/SignBlock.tsx
26915
- import { useCallback as useCallback44, useEffect as useEffect69, useState as useState82 } from "react";
26916
- import { useFields as useFields22, useRecordsClient as useRecordsClient60 } from "@ai-matrx/records/react";
27336
+ import { useCallback as useCallback44, useEffect as useEffect72, useState as useState83 } from "react";
27337
+ import { useFields as useFields22, useRecordsClient as useRecordsClient62 } from "@ai-matrx/records/react";
26917
27338
  import { BasicInput as BasicInput28, Button as Button71, Skeleton as Skeleton30, cn as cn60 } from "@ai-matrx/design-system";
26918
27339
  import { useTable as useTable21 } from "@ai-matrx/records/react";
26919
27340
  import { jsx as jsx92, jsxs as jsxs84 } from "react/jsx-runtime";
26920
27341
  function SignBlock({ tableId, recordId, render, className }) {
26921
- const client = useRecordsClient60();
27342
+ const client = useRecordsClient62();
26922
27343
  const table = useTable21(tableId);
26923
27344
  const rights = useTableRights(table.data);
26924
27345
  const fields = useFields22(tableId);
26925
- const [signatures, setSignatures] = useState82(null);
26926
- const [verdicts, setVerdicts] = useState82({});
26927
- const [error, setError] = useState82(null);
26928
- const [name, setName] = useState82("");
26929
- const [busy, setBusy] = useState82(false);
27346
+ const [signatures, setSignatures] = useState83(null);
27347
+ const [verdicts, setVerdicts] = useState83({});
27348
+ const [error, setError] = useState83(null);
27349
+ const [name, setName] = useState83("");
27350
+ const [busy, setBusy] = useState83(false);
26930
27351
  const load = useCallback44(async () => {
26931
27352
  const held = await client.docSignatures({ record_id: recordId });
26932
27353
  if (!held.ok) {
@@ -26942,7 +27363,7 @@ function SignBlock({ tableId, recordId, render, className }) {
26942
27363
  }
26943
27364
  setVerdicts(answers);
26944
27365
  }, [client, recordId]);
26945
- useEffect69(() => {
27366
+ useEffect72(() => {
26946
27367
  void load();
26947
27368
  }, [load]);
26948
27369
  async function sign(field2) {
@@ -27063,7 +27484,7 @@ function SignBlock({ tableId, recordId, render, className }) {
27063
27484
  }
27064
27485
 
27065
27486
  // src/ChartBlock.tsx
27066
- import { useMemo as useMemo43 } from "react";
27487
+ import { useMemo as useMemo44 } from "react";
27067
27488
  import {
27068
27489
  Bar,
27069
27490
  BarChart,
@@ -27158,7 +27579,7 @@ function ChartBlock({ block, subject, className }) {
27158
27579
  const grain = block.bucket?.by ?? null;
27159
27580
  const series = compared ? [primary, priorKey(primary)] : [primary];
27160
27581
  const target = kind === "stuck" ? null : block.target ?? null;
27161
- const points = useMemo43(() => {
27582
+ const points = useMemo44(() => {
27162
27583
  if (kind === "stuck") return [];
27163
27584
  const rows = block.rows ?? [];
27164
27585
  return rows.map((row, index) => {
@@ -27182,7 +27603,7 @@ function ChartBlock({ block, subject, className }) {
27182
27603
  };
27183
27604
  });
27184
27605
  }, [block.rows, kind, primary, compared, grain, windows]);
27185
- const config = useMemo43(() => {
27606
+ const config = useMemo44(() => {
27186
27607
  const out = {};
27187
27608
  out[primary] = {
27188
27609
  label: windows ? windowName(windows.window, windows.period) : primary.replace("_", " of "),
@@ -27209,7 +27630,7 @@ function ChartBlock({ block, subject, className }) {
27209
27630
  const filter = { ...block.filter ?? {} };
27210
27631
  if (windows) filter[windows.key] = { from: windows.window.from, to: windows.window.to };
27211
27632
  for (const [key, value] of Object.entries(point.groups)) {
27212
- const asWindow = typeof value === "string" ? bucketWindow(key, value) : null;
27633
+ const asWindow = typeof value === "string" ? bucketWindow2(key, value) : null;
27213
27634
  if (asWindow) filter[asWindow.key] = asWindow.window;
27214
27635
  else filter[key] = value;
27215
27636
  }
@@ -27515,8 +27936,8 @@ function onlyWholeNumbers(rows) {
27515
27936
  }
27516
27937
 
27517
27938
  // src/DashboardCanvas.tsx
27518
- import { useCallback as useCallback45, useEffect as useEffect70, useMemo as useMemo44, useState as useState83 } from "react";
27519
- import { useFields as useFields23, useRecordsClient as useRecordsClient61, useTable as useTable22 } from "@ai-matrx/records/react";
27939
+ import { useCallback as useCallback45, useEffect as useEffect73, useMemo as useMemo45, useState as useState84 } from "react";
27940
+ import { useFields as useFields23, useRecordsClient as useRecordsClient63, useTable as useTable22 } from "@ai-matrx/records/react";
27520
27941
  import {
27521
27942
  BasicInput as BasicInput29,
27522
27943
  Button as Button72,
@@ -27530,21 +27951,21 @@ import {
27530
27951
  } from "@ai-matrx/design-system";
27531
27952
  import { Fragment as Fragment39, jsx as jsx94, jsxs as jsxs86 } from "react/jsx-runtime";
27532
27953
  function DashboardCanvas({ tableId, activeDashboardId, filter, className }) {
27533
- const client = useRecordsClient61();
27954
+ const client = useRecordsClient63();
27534
27955
  const host = useRecordsUi();
27535
27956
  const table = useTable22(tableId);
27536
27957
  const rights = useTableRights(table.data);
27537
27958
  const fields = useFields23(tableId);
27538
- const [boards, setBoards] = useState83(null);
27539
- const [error, setError] = useState83(null);
27540
- const [activeId, setActiveId] = useState83(activeDashboardId ?? null);
27541
- const [askingToRemove, setAskingToRemove] = useState83(null);
27542
- const [run, setRun] = useState83(null);
27543
- const [running, setRunning] = useState83(false);
27544
- const [question, setQuestion] = useState83("");
27545
- const [asking, setAsking] = useState83(false);
27546
- const [scheduling, setScheduling] = useState83(false);
27547
- const [grain, setGrain] = useState83(null);
27959
+ const [boards, setBoards] = useState84(null);
27960
+ const [error, setError] = useState84(null);
27961
+ const [activeId, setActiveId] = useState84(activeDashboardId ?? null);
27962
+ const [askingToRemove, setAskingToRemove] = useState84(null);
27963
+ const [run, setRun] = useState84(null);
27964
+ const [running, setRunning] = useState84(false);
27965
+ const [question, setQuestion] = useState84("");
27966
+ const [asking, setAsking] = useState84(false);
27967
+ const [scheduling, setScheduling] = useState84(false);
27968
+ const [grain, setGrain] = useState84(null);
27548
27969
  const runArgs = (dashboard_id) => ({
27549
27970
  dashboard_id,
27550
27971
  ...filter ? { filter } : {},
@@ -27561,18 +27982,18 @@ function DashboardCanvas({ tableId, activeDashboardId, filter, className }) {
27561
27982
  setBoards(read);
27562
27983
  return read;
27563
27984
  }, [client, tableId]);
27564
- const [notKept, setNotKept] = useState83(null);
27565
- useEffect70(() => {
27985
+ const [notKept, setNotKept] = useState84(null);
27986
+ useEffect73(() => {
27566
27987
  void load();
27567
27988
  }, [load]);
27568
- useEffect70(() => {
27989
+ useEffect73(() => {
27569
27990
  if (!boards || boards.length === 0) return;
27570
27991
  const chosen = boards.find((d) => d.id === (activeDashboardId ?? activeId)) ?? boards[0];
27571
27992
  if (chosen.id !== activeId) setActiveId(chosen.id);
27572
27993
  }, [boards, activeDashboardId]);
27573
- const board = useMemo44(() => boards?.find((d) => d.id === activeId) ?? null, [boards, activeId]);
27994
+ const board = useMemo45(() => boards?.find((d) => d.id === activeId) ?? null, [boards, activeId]);
27574
27995
  const filterKey = JSON.stringify(filter ?? {});
27575
- useEffect70(() => {
27996
+ useEffect73(() => {
27576
27997
  if (!activeId) {
27577
27998
  setRun(null);
27578
27999
  return;
@@ -28027,10 +28448,10 @@ function TargetControl({
28027
28448
  onChange
28028
28449
  }) {
28029
28450
  const saved = !block.target ? "none" : "field" in block.target && block.target.field ? "field" : "value";
28030
- const [mode, setMode] = useState83(saved);
28451
+ const [mode, setMode] = useState84(saved);
28031
28452
  const savedValue = block.target && "value" in block.target && typeof block.target.value === "number" ? block.target.value : null;
28032
- const [draft, setDraft] = useState83(savedValue === null ? "" : String(savedValue));
28033
- useEffect70(() => {
28453
+ const [draft, setDraft] = useState84(savedValue === null ? "" : String(savedValue));
28454
+ useEffect73(() => {
28034
28455
  setMode(saved);
28035
28456
  setDraft(savedValue === null ? "" : String(savedValue));
28036
28457
  }, [saved, savedValue]);
@@ -28097,8 +28518,8 @@ function TargetControl({
28097
28518
  }
28098
28519
 
28099
28520
  // src/FormsPanel.tsx
28100
- import { useCallback as useCallback46, useEffect as useEffect71, useState as useState84 } from "react";
28101
- import { useRecordsClient as useRecordsClient62, useTable as useTable23 } from "@ai-matrx/records/react";
28521
+ import { useCallback as useCallback46, useEffect as useEffect74, useState as useState85 } from "react";
28522
+ import { useRecordsClient as useRecordsClient64, useTable as useTable23 } from "@ai-matrx/records/react";
28102
28523
  import { publicFormPath as publicFormPath2 } from "@ai-matrx/records";
28103
28524
  import { Badge as Badge22, Button as Button73, Skeleton as Skeleton32, cn as cn63 } from "@ai-matrx/design-system";
28104
28525
  import { Fragment as Fragment40, jsx as jsx95, jsxs as jsxs87 } from "react/jsx-runtime";
@@ -28110,19 +28531,19 @@ function formSuggestion(tableName2) {
28110
28531
  return `Make me a form that collects new ${subject} entries and tells me when somebody answers.`;
28111
28532
  }
28112
28533
  function FormsPanel({ tableId, activeFormId, className }) {
28113
- const client = useRecordsClient62();
28534
+ const client = useRecordsClient64();
28114
28535
  const publishGate = usePublishGate();
28115
28536
  const host = useRecordsUi();
28116
28537
  const table = useTable23(tableId);
28117
28538
  const rights = useTableRights(table.data);
28118
- const [forms, setForms] = useState84(null);
28119
- const [error, setError] = useState84(null);
28120
- const [busy, setBusy] = useState84(null);
28121
- const [copied, setCopied] = useState84(null);
28122
- const [building, setBuilding] = useState84(false);
28539
+ const [forms, setForms] = useState85(null);
28540
+ const [error, setError] = useState85(null);
28541
+ const [busy, setBusy] = useState85(null);
28542
+ const [copied, setCopied] = useState85(null);
28543
+ const [building, setBuilding] = useState85(false);
28123
28544
  const linked = activeFormId && forms !== null ? forms.find((f) => f.form_id === activeFormId) ?? null : null;
28124
28545
  const linkedMissing = Boolean(activeFormId) && forms !== null && linked === null;
28125
- useEffect71(() => {
28546
+ useEffect74(() => {
28126
28547
  if (linked && rights.structure) setBuilding(true);
28127
28548
  }, [linked, rights.structure]);
28128
28549
  const load = useCallback46(async () => {
@@ -28135,7 +28556,7 @@ function FormsPanel({ tableId, activeFormId, className }) {
28135
28556
  setError(null);
28136
28557
  setForms(answered.data);
28137
28558
  }, [client, tableId]);
28138
- useEffect71(() => {
28559
+ useEffect74(() => {
28139
28560
  void load();
28140
28561
  }, [load]);
28141
28562
  const toggle = useCallback46(
@@ -28152,7 +28573,7 @@ function FormsPanel({ tableId, activeFormId, className }) {
28152
28573
  },
28153
28574
  [client, load]
28154
28575
  );
28155
- const [shown3, setShown] = useState84(null);
28576
+ const [shown3, setShown] = useState85(null);
28156
28577
  const copy = useCallback46(async (url, formId) => {
28157
28578
  try {
28158
28579
  await navigator.clipboard.writeText(url);
@@ -28267,18 +28688,18 @@ function FormsPanel({ tableId, activeFormId, className }) {
28267
28688
  }
28268
28689
 
28269
28690
  // src/CaptureSheet.tsx
28270
- import { useCallback as useCallback48, useEffect as useEffect73, useRef as useRef28, useState as useState86 } from "react";
28271
- import { useFields as useFields24, useRecordsClient as useRecordsClient64, useTable as useTable24 } from "@ai-matrx/records/react";
28691
+ import { useCallback as useCallback48, useEffect as useEffect76, useRef as useRef28, useState as useState87 } from "react";
28692
+ import { useFields as useFields24, useRecordsClient as useRecordsClient66, useTable as useTable24 } from "@ai-matrx/records/react";
28272
28693
  import { Button as Button75, Input as Input4, Skeleton as Skeleton34, Textarea as Textarea3, cn as cn65 } from "@ai-matrx/design-system";
28273
28694
 
28274
28695
  // src/CaptureRun.tsx
28275
- import { useCallback as useCallback47, useEffect as useEffect72, useMemo as useMemo45, useRef as useRef27, useState as useState85 } from "react";
28696
+ import { useCallback as useCallback47, useEffect as useEffect75, useMemo as useMemo46, useRef as useRef27, useState as useState86 } from "react";
28276
28697
  import {
28277
28698
  coerceTypedAnswer as coerceTypedAnswer3,
28278
28699
  coercionLabel,
28279
28700
  openCaptureQueue
28280
28701
  } from "@ai-matrx/records";
28281
- import { useRecordsClient as useRecordsClient63 } from "@ai-matrx/records/react";
28702
+ import { useRecordsClient as useRecordsClient65 } from "@ai-matrx/records/react";
28282
28703
  import { Button as Button74, Input as Input3, Skeleton as Skeleton33, Textarea as Textarea2, cn as cn64 } from "@ai-matrx/design-system";
28283
28704
  import { jsx as jsx96, jsxs as jsxs88 } from "react/jsx-runtime";
28284
28705
  function controlFor(field2) {
@@ -28317,21 +28738,21 @@ function whereWeAre(timeoutMs = 4e3) {
28317
28738
  });
28318
28739
  }
28319
28740
  function CaptureRun({ sheetId, face: given, className }) {
28320
- const client = useRecordsClient63();
28741
+ const client = useRecordsClient65();
28321
28742
  const host = useRecordsUi();
28322
- const [face, setFace] = useState85(given);
28323
- const [loadFailed, setLoadFailed] = useState85(null);
28324
- const [at, setAt] = useState85(0);
28325
- const [answers, setAnswers] = useState85({});
28326
- const [files, setFiles] = useState85({});
28327
- const [missing, setMissing] = useState85(null);
28328
- const [done, setDone] = useState85(null);
28329
- const [counts, setCounts] = useState85({ waiting: 0, sending: 0, refused: 0, landed: 0 });
28330
- const [items, setItems] = useState85([]);
28331
- const [lastSynced, setLastSynced] = useState85(null);
28332
- const [sending, setSending] = useState85(false);
28743
+ const [face, setFace] = useState86(given);
28744
+ const [loadFailed, setLoadFailed] = useState86(null);
28745
+ const [at, setAt] = useState86(0);
28746
+ const [answers, setAnswers] = useState86({});
28747
+ const [files, setFiles] = useState86({});
28748
+ const [missing, setMissing] = useState86(null);
28749
+ const [done, setDone] = useState86(null);
28750
+ const [counts, setCounts] = useState86({ waiting: 0, sending: 0, refused: 0, landed: 0 });
28751
+ const [items, setItems] = useState86([]);
28752
+ const [lastSynced, setLastSynced] = useState86(null);
28753
+ const [sending, setSending] = useState86(false);
28333
28754
  const queueRef = useRef27(null);
28334
- useEffect72(() => {
28755
+ useEffect75(() => {
28335
28756
  const q2 = openCaptureQueue({
28336
28757
  onChange: (c, all) => {
28337
28758
  setCounts(c);
@@ -28369,7 +28790,7 @@ function CaptureRun({ sheetId, face: given, className }) {
28369
28790
  void q2.sync().then(() => void q2.lastSyncedAt().then(setLastSynced));
28370
28791
  return () => q2.dispose();
28371
28792
  }, [client, host]);
28372
- useEffect72(() => {
28793
+ useEffect75(() => {
28373
28794
  if (given !== void 0) return;
28374
28795
  let cancelled = false;
28375
28796
  void client.captureOpen({ sheet_id: sheetId }).then((res) => {
@@ -28381,7 +28802,7 @@ function CaptureRun({ sheetId, face: given, className }) {
28381
28802
  cancelled = true;
28382
28803
  };
28383
28804
  }, [client, given, sheetId]);
28384
- const questions = useMemo45(() => {
28805
+ const questions = useMemo46(() => {
28385
28806
  const asked2 = face?.presentation?.questions ?? [];
28386
28807
  if (asked2.length > 0) return asked2;
28387
28808
  return (face?.fields ?? []).map((f) => ({
@@ -28697,19 +29118,19 @@ function AdHocCaptureSheet({
28697
29118
  attachmentField,
28698
29119
  className
28699
29120
  }) {
28700
- const client = useRecordsClient64();
29121
+ const client = useRecordsClient66();
28701
29122
  const host = useRecordsUi();
28702
29123
  const table = useTable24(tableId);
28703
29124
  const fields = useFields24(tableId);
28704
- const [mode, setMode] = useState86("reading");
28705
- const [reading, setReading] = useState86("");
28706
- const [note, setNote] = useState86("");
28707
- const [fileId, setFileId] = useState86(null);
28708
- const [pending, setPending] = useState86(null);
28709
- const [saved, setSaved] = useState86([]);
28710
- const [error, setError] = useState86(null);
28711
- const [uploadError, setUploadError] = useState86(null);
28712
- const [flushing, setFlushing] = useState86(false);
29125
+ const [mode, setMode] = useState87("reading");
29126
+ const [reading, setReading] = useState87("");
29127
+ const [note, setNote] = useState87("");
29128
+ const [fileId, setFileId] = useState87(null);
29129
+ const [pending, setPending] = useState87(null);
29130
+ const [saved, setSaved] = useState87([]);
29131
+ const [error, setError] = useState87(null);
29132
+ const [uploadError, setUploadError] = useState87(null);
29133
+ const [flushing, setFlushing] = useState87(false);
28713
29134
  const queue = useRef28([]);
28714
29135
  const keep = useCallback48(
28715
29136
  async (next) => {
@@ -28719,7 +29140,7 @@ function AdHocCaptureSheet({
28719
29140
  },
28720
29141
  [host]
28721
29142
  );
28722
- useEffect73(() => {
29143
+ useEffect76(() => {
28723
29144
  let cancelled = false;
28724
29145
  void (async () => {
28725
29146
  const held = host.captureQueue ? await host.captureQueue.load() : [];
@@ -28898,17 +29319,17 @@ function AdHocCaptureSheet({
28898
29319
  }
28899
29320
 
28900
29321
  // src/PortalShell.tsx
28901
- import { useCallback as useCallback49, useEffect as useEffect74, useState as useState87 } from "react";
28902
- import { useRecordsClient as useRecordsClient65 } from "@ai-matrx/records/react";
29322
+ import { useCallback as useCallback49, useEffect as useEffect77, useState as useState88 } from "react";
29323
+ import { useRecordsClient as useRecordsClient67 } from "@ai-matrx/records/react";
28903
29324
  import { Button as Button76, Skeleton as Skeleton35, cn as cn66 } from "@ai-matrx/design-system";
28904
29325
  import { jsx as jsx98, jsxs as jsxs90 } from "react/jsx-runtime";
28905
29326
  function PortalShell({ tableId, form, resourceType = "record", className }) {
28906
- const client = useRecordsClient65();
28907
- const [card, setCard] = useState87(null);
28908
- const [reach, setReach] = useState87(null);
28909
- const [error, setError] = useState87(null);
28910
- const [open, setOpen] = useState87(null);
28911
- const [sending, setSending] = useState87(false);
29327
+ const client = useRecordsClient67();
29328
+ const [card, setCard] = useState88(null);
29329
+ const [reach, setReach] = useState88(null);
29330
+ const [error, setError] = useState88(null);
29331
+ const [open, setOpen] = useState88(null);
29332
+ const [sending, setSending] = useState88(false);
28912
29333
  const load = useCallback49(async () => {
28913
29334
  const who = await client.externalPrincipalCard();
28914
29335
  if (!who.ok) {
@@ -28924,7 +29345,7 @@ function PortalShell({ tableId, form, resourceType = "record", className }) {
28924
29345
  }
28925
29346
  setReach(reached.data.map((row) => row.resource_id));
28926
29347
  }, [client, resourceType]);
28927
- useEffect74(() => {
29348
+ useEffect77(() => {
28928
29349
  void load();
28929
29350
  }, [load]);
28930
29351
  if (error) {
@@ -28982,9 +29403,9 @@ function PortalShell({ tableId, form, resourceType = "record", className }) {
28982
29403
  ] });
28983
29404
  }
28984
29405
  function PortalRow({ tableId, recordId }) {
28985
- const client = useRecordsClient65();
28986
- const [title, setTitle] = useState87(null);
28987
- useEffect74(() => {
29406
+ const client = useRecordsClient67();
29407
+ const [title, setTitle] = useState88(null);
29408
+ useEffect77(() => {
28988
29409
  let cancelled = false;
28989
29410
  void client.recordRead({ record_id: recordId }).then((answered) => {
28990
29411
  if (cancelled) return;
@@ -29004,17 +29425,17 @@ function PortalRow({ tableId, recordId }) {
29004
29425
  }
29005
29426
 
29006
29427
  // src/PublicViewPage.tsx
29007
- import { useCallback as useCallback50, useEffect as useEffect75, useState as useState88 } from "react";
29008
- import { useRecordsClient as useRecordsClient66 } from "@ai-matrx/records/react";
29428
+ import { useCallback as useCallback50, useEffect as useEffect78, useState as useState89 } from "react";
29429
+ import { useRecordsClient as useRecordsClient68 } from "@ai-matrx/records/react";
29009
29430
  import { Skeleton as Skeleton36, cn as cn67 } from "@ai-matrx/design-system";
29010
29431
  import { jsx as jsx99, jsxs as jsxs91 } from "react/jsx-runtime";
29011
29432
  function PublicViewPage({ slug, className }) {
29012
- const client = useRecordsClient66();
29013
- const [binding, setBinding] = useState88(null);
29014
- const [rows, setRows] = useState88(null);
29015
- const [fields, setFields] = useState88(null);
29016
- const [error, setError] = useState88(null);
29017
- const [gap, setGap] = useState88(null);
29433
+ const client = useRecordsClient68();
29434
+ const [binding, setBinding] = useState89(null);
29435
+ const [rows, setRows] = useState89(null);
29436
+ const [fields, setFields] = useState89(null);
29437
+ const [error, setError] = useState89(null);
29438
+ const [gap, setGap] = useState89(null);
29018
29439
  const load = useCallback50(async () => {
29019
29440
  const notice = await client.worldPublishGapNotice();
29020
29441
  if (notice.ok) setGap(notice.data);
@@ -29048,7 +29469,7 @@ function PublicViewPage({ slug, className }) {
29048
29469
  }
29049
29470
  setRows([{ id: found.resource_id, document: read.data.document, level: "viewer", hidden: read.data.hidden }]);
29050
29471
  }, [client, slug]);
29051
- useEffect75(() => {
29472
+ useEffect78(() => {
29052
29473
  void load();
29053
29474
  }, [load]);
29054
29475
  if (error) return /* @__PURE__ */ jsx99(RefusalNotice, { error, className });
@@ -29085,8 +29506,8 @@ function PublicRow({ row, fields }) {
29085
29506
  }
29086
29507
 
29087
29508
  // src/EmbedFrame.tsx
29088
- import { useCallback as useCallback51, useEffect as useEffect76, useState as useState89 } from "react";
29089
- import { useRecordsClient as useRecordsClient67 } from "@ai-matrx/records/react";
29509
+ import { useCallback as useCallback51, useEffect as useEffect79, useState as useState90 } from "react";
29510
+ import { useRecordsClient as useRecordsClient69 } from "@ai-matrx/records/react";
29090
29511
  import { Button as Button77, Input as Input5, Skeleton as Skeleton37, Textarea as Textarea4, cn as cn68 } from "@ai-matrx/design-system";
29091
29512
  import { useTable as useTable25 } from "@ai-matrx/records/react";
29092
29513
  import { Fragment as Fragment42, jsx as jsx100, jsxs as jsxs92 } from "react/jsx-runtime";
@@ -29098,15 +29519,15 @@ function EmbedFrame({
29098
29519
  embedUrl,
29099
29520
  className
29100
29521
  }) {
29101
- const client = useRecordsClient67();
29522
+ const client = useRecordsClient69();
29102
29523
  const host = useRecordsUi();
29103
29524
  const table = useTable25(tableId);
29104
29525
  const rights = useTableRights(table.data);
29105
- const [origins, setOrigins] = useState89("");
29106
- const [secret, setSecret] = useState89(null);
29107
- const [tokenId, setTokenId] = useState89(null);
29108
- const [error, setError] = useState89(null);
29109
- const [busy, setBusy] = useState89(false);
29526
+ const [origins, setOrigins] = useState90("");
29527
+ const [secret, setSecret] = useState90(null);
29528
+ const [tokenId, setTokenId] = useState90(null);
29529
+ const [error, setError] = useState90(null);
29530
+ const [busy, setBusy] = useState90(false);
29110
29531
  const mode = formId ? "write" : "read";
29111
29532
  const parsed = origins.split(/[\s,]+/).map((o) => o.trim()).filter((o) => o.length > 0);
29112
29533
  const issue = useCallback51(async () => {
@@ -29192,13 +29613,13 @@ function EmbedFrame({
29192
29613
  ] });
29193
29614
  }
29194
29615
  function useEmbedHandshake(args) {
29195
- const client = useRecordsClient67();
29196
- const [binding, setBinding] = useState89(null);
29197
- const [error, setError] = useState89(null);
29198
- const [loading, setLoading] = useState89(true);
29616
+ const client = useRecordsClient69();
29617
+ const [binding, setBinding] = useState90(null);
29618
+ const [error, setError] = useState90(null);
29619
+ const [loading, setLoading] = useState90(true);
29199
29620
  const origin = args.origin ?? (typeof location === "undefined" ? "" : location.origin);
29200
29621
  const { secret, requiredMode } = args;
29201
- useEffect76(() => {
29622
+ useEffect79(() => {
29202
29623
  let cancelled = false;
29203
29624
  setLoading(true);
29204
29625
  setError(null);
@@ -29270,9 +29691,9 @@ function recordsDataSource(client, fallbackSchema = "custom") {
29270
29691
  }
29271
29692
 
29272
29693
  // src/TablePage.tsx
29273
- import { useCallback as useCallback52, useEffect as useEffect79, useRef as useRef30, useState as useState92 } from "react";
29694
+ import { useCallback as useCallback52, useEffect as useEffect82, useRef as useRef30, useState as useState93 } from "react";
29274
29695
  import { archivedByLine as archivedByLine2 } from "@ai-matrx/records";
29275
- import { useFields as useFields26, useRecordsClient as useRecordsClient68, useTable as useTable26 } from "@ai-matrx/records/react";
29696
+ import { useFields as useFields26, useRecordsClient as useRecordsClient70, useTable as useTable26 } from "@ai-matrx/records/react";
29276
29697
  import {
29277
29698
  BottomSheet,
29278
29699
  Button as Button79,
@@ -29293,7 +29714,7 @@ import {
29293
29714
  } from "@ai-matrx/design-system";
29294
29715
 
29295
29716
  // src/ViewFilter.tsx
29296
- import { useEffect as useEffect77, useMemo as useMemo46, useState as useState90 } from "react";
29717
+ import { useEffect as useEffect80, useMemo as useMemo47, useState as useState91 } from "react";
29297
29718
  import { Button as Button78, cn as cn69 } from "@ai-matrx/design-system";
29298
29719
  import { useFields as useFields25 } from "@ai-matrx/records/react";
29299
29720
  import { jsx as jsx102, jsxs as jsxs93 } from "react/jsx-runtime";
@@ -29307,14 +29728,14 @@ function conditionCount(expr) {
29307
29728
  }
29308
29729
  function ViewFilter({ tableId, view, onApply, className }) {
29309
29730
  const fields = useFields25(tableId);
29310
- const [open, setOpen] = useState90(false);
29731
+ const [open, setOpen] = useState91(false);
29311
29732
  const saved = view?.where ?? null;
29312
- const [draft, setDraft] = useState90(saved);
29733
+ const [draft, setDraft] = useState91(saved);
29313
29734
  const savedKey = JSON.stringify(saved);
29314
- useEffect77(() => {
29735
+ useEffect80(() => {
29315
29736
  setDraft(saved);
29316
29737
  }, [view?.id, savedKey]);
29317
- const conditionFields = useMemo46(
29738
+ const conditionFields = useMemo47(
29318
29739
  () => (fields.data ?? []).map((f) => ({ id: f.id, key: f.key, label: f.label || f.key, field: f })),
29319
29740
  [fields.data]
29320
29741
  );
@@ -29394,7 +29815,7 @@ function ViewFilter({ tableId, view, onApply, className }) {
29394
29815
  }
29395
29816
 
29396
29817
  // src/toolbarFit.ts
29397
- import { useEffect as useEffect78, useState as useState91 } from "react";
29818
+ import { useEffect as useEffect81, useState as useState92 } from "react";
29398
29819
  var FOLDED_GUESS = { look: 104, chooser: 96, tools: 120 };
29399
29820
  function toolbarFold(input) {
29400
29821
  const { available, needsNow, gap, folded } = input;
@@ -29445,8 +29866,8 @@ function rowNeeds(row) {
29445
29866
  return { needs: needs + gap * Math.max(0, pieces.length - 1), gap };
29446
29867
  }
29447
29868
  function useToolbarFit(row) {
29448
- const [fold, setFold] = useState91(0);
29449
- useEffect78(() => {
29869
+ const [fold, setFold] = useState92(0);
29870
+ useEffect81(() => {
29450
29871
  if (!row) return;
29451
29872
  const widths = {
29452
29873
  look: { full: null, folded: null },
@@ -29526,8 +29947,8 @@ function clippedEnds(scrollLeft, clientWidth, scrollWidth) {
29526
29947
  return start && end ? "both" : start ? "start" : end ? "end" : "none";
29527
29948
  }
29528
29949
  function useSlotScroll(slot) {
29529
- const [ends, setEnds] = useState91("none");
29530
- useEffect78(() => {
29950
+ const [ends, setEnds] = useState92("none");
29951
+ useEffect81(() => {
29531
29952
  if (!slot) return;
29532
29953
  let pending = 0;
29533
29954
  const read = () => {
@@ -29643,11 +30064,11 @@ function TableNotHere({
29643
30064
  leaveLabel,
29644
30065
  className
29645
30066
  }) {
29646
- const client = useRecordsClient68();
29647
- const [archived, setArchived] = useState92({ phase: "asking" });
29648
- const [restoring, setRestoring] = useState92(false);
29649
- const [refusal2, setRefusal] = useState92(null);
29650
- useEffect79(() => {
30067
+ const client = useRecordsClient70();
30068
+ const [archived, setArchived] = useState93({ phase: "asking" });
30069
+ const [restoring, setRestoring] = useState93(false);
30070
+ const [refusal2, setRefusal] = useState93(null);
30071
+ useEffect82(() => {
29651
30072
  let alive = true;
29652
30073
  void client.tableArchived({ table_id: tableId }).then((answered) => {
29653
30074
  if (!alive) return;
@@ -29834,15 +30255,15 @@ function TablePage({
29834
30255
  onShownViewChange,
29835
30256
  className
29836
30257
  }) {
29837
- const client = useRecordsClient68();
30258
+ const client = useRecordsClient70();
29838
30259
  const table = useTable26(tableId);
29839
30260
  const rights = useTableRights(table.data);
29840
30261
  const pageFields = useFields26(filter ? tableId : null);
29841
30262
  const askedInWords = filter ? filterInWords(filter, pageFields.data ?? []) : null;
29842
- const organizationId = useRecordsClient68().config.organizationId;
29843
- const [view, setView] = useState92(null);
29844
- const [looks, setLooks] = useState92(void 0);
29845
- useEffect79(() => {
30263
+ const organizationId = useRecordsClient70().config.organizationId;
30264
+ const [view, setView] = useState93(null);
30265
+ const [looks, setLooks] = useState93(void 0);
30266
+ useEffect82(() => {
29846
30267
  let live = true;
29847
30268
  setLooks(void 0);
29848
30269
  void readLooks(client, tableId).then((answered) => {
@@ -29855,7 +30276,7 @@ function TablePage({
29855
30276
  }, [client, tableId]);
29856
30277
  const look = view && looks ? looks[view.id] : void 0;
29857
30278
  const shown3 = view ? applyLook(view, look) : null;
29858
- const [viewsEpoch, setViewsEpoch] = useState92(0);
30279
+ const [viewsEpoch, setViewsEpoch] = useState93(0);
29859
30280
  const opening = openingRail(activeRecordId, activeRail);
29860
30281
  const hostLayouts = useRecordsUi().layouts ?? [];
29861
30282
  const hostLayoutFor = (asked2) => openingHostLayout(asked2, hostLayouts);
@@ -29863,30 +30284,30 @@ function TablePage({
29863
30284
  const savedFromLink = savedViewFromParam(activeView);
29864
30285
  const openedByPackage = openingView(hostFromLink || savedFromLink ? null : activeView, activeDashboardId);
29865
30286
  const opened = hostFromLink ? { ...openedByPackage, main: "records" } : openedByPackage;
29866
- const [hostLayout, setHostLayout] = useState92(hostFromLink);
29867
- const [views, setViews] = useState92(void 0);
29868
- const [pickedViewId, setPickedViewId] = useState92(savedFromLink);
30287
+ const [hostLayout, setHostLayout] = useState93(hostFromLink);
30288
+ const [views, setViews] = useState93(void 0);
30289
+ const [pickedViewId, setPickedViewId] = useState93(savedFromLink);
29869
30290
  const viewSeen = useRef30(null);
29870
- const [viewLinkMissed, setViewLinkMissed] = useState92(false);
29871
- const [layoutChosen, setLayoutChosen] = useState92(false);
30291
+ const [viewLinkMissed, setViewLinkMissed] = useState93(false);
30292
+ const [layoutChosen, setLayoutChosen] = useState93(false);
29872
30293
  const railAsked = typeof activeRail === "string" ? activeRail.trim() : "";
29873
30294
  const railUnknown = railAsked !== "" && railFromParam(railAsked) === null ? railAsked : null;
29874
30295
  const shareFromLink = railFromParam(activeRail) === "share";
29875
30296
  const canShare = useCanShare();
29876
30297
  const itemFor = (which) => railFromParam(activeRail) === which ? activeItemId ?? null : null;
29877
- const [asking, setAsking] = useState92(null);
29878
- const [layoutFromLink, setLayoutFromLink] = useState92(opened.layout);
29879
- const [surface, setSurface] = useState92({
30298
+ const [asking, setAsking] = useState93(null);
30299
+ const [layoutFromLink, setLayoutFromLink] = useState93(opened.layout);
30300
+ const [surface, setSurface] = useState93({
29880
30301
  main: opened.main,
29881
30302
  rail: opening.rail
29882
30303
  });
29883
30304
  const { main, rail } = surface;
29884
30305
  const setRail = (next) => setSurface((now) => ({ ...now, rail: next }));
29885
- const [openRecord, setOpenRecord] = useState92(opening.record);
30306
+ const [openRecord, setOpenRecord] = useState93(opening.record);
29886
30307
  const phone = useIsMobile2();
29887
- const [shareAsked, setShareAsked] = useState92(0);
29888
- const [toolbarSlot, setToolbarSlot] = useState92(null);
29889
- const [toolbarRow, setToolbarRow] = useState92(null);
30308
+ const [shareAsked, setShareAsked] = useState93(0);
30309
+ const [toolbarSlot, setToolbarSlot] = useState93(null);
30310
+ const [toolbarRow, setToolbarRow] = useState93(null);
29890
30311
  const toolbarFold2 = useToolbarFit(toolbarRow);
29891
30312
  const slotClipped = useSlotScroll(toolbarSlot);
29892
30313
  const face = tableOpening(view, hostLayouts.map((h) => h.id));
@@ -29894,7 +30315,7 @@ function TablePage({
29894
30315
  const chooserInline = !designated && !phone && toolbarFold2 < 2;
29895
30316
  const chooserCompact = !designated && !phone && toolbarFold2 >= 2;
29896
30317
  const controlsInSheet = phone && !designated;
29897
- useEffect79(() => {
30318
+ useEffect82(() => {
29898
30319
  if (face.kind !== "designated") return;
29899
30320
  if (hostFromLink || opened.layout || layoutChosen) return;
29900
30321
  setHostLayout(face.hostLayout);
@@ -29927,7 +30348,7 @@ function TablePage({
29927
30348
  const shownSignature = JSON.stringify(shownReport);
29928
30349
  const reportRef = useRef30(onShownViewChange);
29929
30350
  reportRef.current = onShownViewChange;
29930
- useEffect79(() => {
30351
+ useEffect82(() => {
29931
30352
  reportRef.current?.(JSON.parse(shownSignature));
29932
30353
  }, [shownSignature]);
29933
30354
  const pickLayout = (next) => {
@@ -29945,18 +30366,18 @@ function TablePage({
29945
30366
  onViewChanged?.(id);
29946
30367
  };
29947
30368
  const openedFromMenu = MENU.find((entry) => entry.press.main !== void 0 && entry.press.main === main) ?? MENU.find((entry) => entry.press.rail !== void 0 && entry.press.rail === rail) ?? null;
29948
- useEffect79(() => {
30369
+ useEffect82(() => {
29949
30370
  if (!activeRecordId) return;
29950
30371
  setOpenRecord(activeRecordId);
29951
30372
  setSurface((now) => ({ ...now, rail: "record" }));
29952
30373
  }, [activeRecordId]);
29953
- useEffect79(() => {
30374
+ useEffect82(() => {
29954
30375
  if (activeRecordId) return;
29955
30376
  const named = railFromParam(activeRail);
29956
30377
  if (named === null || named === "share") return;
29957
30378
  setSurface((now) => ({ ...now, rail: named }));
29958
30379
  }, [activeRail, activeRecordId]);
29959
- useEffect79(() => {
30380
+ useEffect82(() => {
29960
30381
  const host = hostLayoutFor(activeView);
29961
30382
  if (host) {
29962
30383
  setHostLayout(host);
@@ -29970,7 +30391,7 @@ function TablePage({
29970
30391
  setLayoutFromLink(isLayout ? named : null);
29971
30392
  setSurface((now) => ({ ...now, main: isLayout ? "records" : named }));
29972
30393
  }, [activeView]);
29973
- const [viewSaveRefused, setViewSaveRefused] = useState92(null);
30394
+ const [viewSaveRefused, setViewSaveRefused] = useState93(null);
29974
30395
  const patchView = useCallback52(
29975
30396
  async (asked2) => {
29976
30397
  const current = view;
@@ -29988,9 +30409,9 @@ function TablePage({
29988
30409
  [client, tableId, view, looks]
29989
30410
  );
29990
30411
  const lookShowing = Boolean(view && looks && lookDiffers(view, looks[view.id]));
29991
- const [lookRefused, setLookRefused] = useState92(null);
29992
- const [namingLook, setNamingLook] = useState92(false);
29993
- const [lookName, setLookName] = useState92("");
30412
+ const [lookRefused, setLookRefused] = useState93(null);
30413
+ const [namingLook, setNamingLook] = useState93(false);
30414
+ const [lookName, setLookName] = useState93("");
29994
30415
  const resetLook = async () => {
29995
30416
  const current = view;
29996
30417
  if (!current) return;
@@ -30048,7 +30469,7 @@ function TablePage({
30048
30469
  setPickedViewId(written.data);
30049
30470
  setViewsEpoch((n) => n + 1);
30050
30471
  };
30051
- const [designateRefused, setDesignateRefused] = useState92(null);
30472
+ const [designateRefused, setDesignateRefused] = useState93(null);
30052
30473
  const opensAs = view?.isDefault ? openingLayoutOf(view) : null;
30053
30474
  const canDesignate = Boolean(rights.write && view && layoutShowing && layoutShowing !== opensAs);
30054
30475
  const layoutShowingLabel = layoutShowing ? hostLayouts.find((h) => h.id === layoutShowing)?.label ?? (VIEW_LAYOUTS.includes(layoutShowing) ? LAYOUT_LABEL[layoutShowing] : layoutShowing) : "";
@@ -30908,6 +31329,7 @@ export {
30908
31329
  scalarText,
30909
31330
  seedIsSatisfied,
30910
31331
  shareUnavailableReason,
31332
+ singularNoun,
30911
31333
  snoozeChoices,
30912
31334
  specFromBlock,
30913
31335
  storeDecidesRights,