@ai-matrx/records-ui 0.85.10 → 0.85.11

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
@@ -3098,7 +3098,7 @@ function OpenCell({
3098
3098
  }
3099
3099
 
3100
3100
  // src/Grid.tsx
3101
- import { useCallback as useCallback8, useEffect as useEffect13, useMemo as useMemo13, useRef as useRef4, useState as useState15 } from "react";
3101
+ import { useCallback as useCallback8, useEffect as useEffect13, useMemo as useMemo13, useRef as useRef5, useState as useState15 } from "react";
3102
3102
  import {
3103
3103
  useFields as useFields3,
3104
3104
  useRecords as useRecords2,
@@ -4860,8 +4860,9 @@ function GridLayoutMenu({
4860
4860
  }
4861
4861
 
4862
4862
  // src/handOrder.tsx
4863
- import { useEffect as useEffect12, useMemo as useMemo12, useState as useState14 } from "react";
4863
+ import { useEffect as useEffect12, useMemo as useMemo12, useRef as useRef4, useState as useState14 } from "react";
4864
4864
  import { useRecordsClient as useRecordsClient9 } from "@ai-matrx/records/react";
4865
+ import { stableFilterKey } from "@ai-matrx/records";
4865
4866
  import { Button as Button12, ConfirmDialog as ConfirmDialog2, cn as cn13 } from "@ai-matrx/design-system";
4866
4867
 
4867
4868
  // src/viewKeys.ts
@@ -5177,12 +5178,6 @@ var HAND_ORDER_NOTE = "Sort: Manual \u2014 the cards are in the order set by han
5177
5178
  function reorderNote(startSortName, direction) {
5178
5179
  return startSortName && direction ? `Saving makes this order the view's sort. It replaces the sort by ${startSortName} ${sortArrow(direction)}. Nothing changes until you save.` : "Saving makes this order the view's sort. Nothing changes until you save.";
5179
5180
  }
5180
- function inHandOrder(rows, positions) {
5181
- const placed = rows.filter((r) => positions.has(r.id));
5182
- const rest = rows.filter((r) => !positions.has(r.id));
5183
- placed.sort((a, b) => positions.get(a.id) - positions.get(b.id));
5184
- return [...placed, ...rest];
5185
- }
5186
5181
  function moveRow(list, from, to) {
5187
5182
  if (from === to || from < 0 || from >= list.length) return [...list];
5188
5183
  const next = [...list];
@@ -5193,31 +5188,34 @@ function moveRow(list, from, to) {
5193
5188
  var DOOR_PAGE_MAX = 500;
5194
5189
  function useHandOrderRows(args) {
5195
5190
  const client = useRecordsClient9();
5196
- const { viewId, active, page, pageSize, filtered } = args;
5191
+ const { viewId, active, page, pageSize } = args;
5192
+ const filter = args.filter && Object.keys(args.filter).length > 0 ? args.filter : null;
5193
+ const filterKey = filter ? stableFilterKey(filter) : "";
5194
+ const filterNow = useRef4(filter);
5195
+ filterNow.current = filter;
5197
5196
  const [answer, setAnswer] = useState14(null);
5198
5197
  const [tick, setTick] = useState14(0);
5199
- const limit = filtered ? DOOR_PAGE_MAX : Math.max(1, Math.min(pageSize, DOOR_PAGE_MAX));
5200
- const offset = filtered ? 0 : page * pageSize;
5201
- const key = `${viewId ?? ""}:${limit}:${offset}`;
5198
+ const limit = Math.max(1, Math.min(pageSize, DOOR_PAGE_MAX));
5199
+ const offset = Math.max(0, page) * limit;
5200
+ const key = `${viewId ?? ""}:${limit}:${offset}:${filterKey}`;
5202
5201
  useEffect12(() => {
5203
5202
  if (!active || !viewId) return;
5204
5203
  let cancelled = false;
5205
- void client.readInViewOrder({ view_id: viewId, limit, offset }).then((result) => {
5204
+ void client.readInViewOrder({ view_id: viewId, filter: filterNow.current, limit, offset }).then((result) => {
5206
5205
  if (cancelled) return;
5207
- setAnswer(result.ok ? { key, rows: result.data ?? [], error: null } : { key, rows: [], error: result.error });
5206
+ setAnswer(
5207
+ result.ok ? { key, rows: (result.data ?? []).map(({ position: _p, ...row }) => row), error: null } : { key, rows: [], error: result.error }
5208
+ );
5208
5209
  });
5209
5210
  return () => {
5210
5211
  cancelled = true;
5211
5212
  };
5212
- }, [client, viewId, active, limit, offset, key, args.version, tick]);
5213
+ }, [client, viewId, active, limit, offset, key, filterKey, args.version, tick]);
5213
5214
  const rows = useMemo12(() => {
5214
5215
  if (!active || !viewId || !answer || answer.key !== key) return null;
5215
5216
  if (answer.error) return null;
5216
- if (!filtered) return answer.rows.map(({ position: _p, ...row }) => row);
5217
- const positions = /* @__PURE__ */ new Map();
5218
- answer.rows.forEach((row, i) => positions.set(row.id, row.position ?? DOOR_PAGE_MAX * 1024 + i));
5219
- return inHandOrder(args.filteredRows, positions);
5220
- }, [active, viewId, answer, key, filtered, args.filteredRows]);
5217
+ return answer.rows;
5218
+ }, [active, viewId, answer, key]);
5221
5219
  return {
5222
5220
  rows,
5223
5221
  loading: active && Boolean(viewId) && (!answer || answer.key !== key),
@@ -5356,8 +5354,7 @@ function Grid({
5356
5354
  active: manual,
5357
5355
  page,
5358
5356
  pageSize,
5359
- filtered: Boolean(filter),
5360
- filteredRows: storeRows,
5357
+ filter: filter ?? null,
5361
5358
  version: records.data
5362
5359
  });
5363
5360
  const rows = useMemo13(() => manual ? hand.rows ?? [] : storeRows, [manual, hand.rows, storeRows]);
@@ -5476,7 +5473,7 @@ function Grid({
5476
5473
  const [deleting, setDeleting] = useState15(null);
5477
5474
  const [deleteBusy, setDeleteBusy] = useState15(false);
5478
5475
  const [archived, setArchived] = useState15(null);
5479
- const choiceOptions = useRef4(/* @__PURE__ */ new Map());
5476
+ const choiceOptions = useRef5(/* @__PURE__ */ new Map());
5480
5477
  const loadChoiceOptions = useCallback8(
5481
5478
  async (fieldList) => {
5482
5479
  const wanted = fieldList.filter(
@@ -6489,7 +6486,7 @@ function ExportMenu({ tableId, rows, label, className }) {
6489
6486
  }
6490
6487
 
6491
6488
  // src/FilePicker.tsx
6492
- import { useCallback as useCallback9, useId, useRef as useRef5, useState as useState17 } from "react";
6489
+ import { useCallback as useCallback9, useId, useRef as useRef6, useState as useState17 } from "react";
6493
6490
  import { Button as Button15, cn as cn16 } from "@ai-matrx/design-system";
6494
6491
  import { jsx as jsx23, jsxs as jsxs18 } from "react/jsx-runtime";
6495
6492
  function FilePicker({
@@ -6504,7 +6501,7 @@ function FilePicker({
6504
6501
  className
6505
6502
  }) {
6506
6503
  const inputId = useId();
6507
- const input = useRef5(null);
6504
+ const input = useRef6(null);
6508
6505
  const [over, setOver] = useState17(false);
6509
6506
  const take = useCallback9(
6510
6507
  (file) => {
@@ -7501,7 +7498,7 @@ import {
7501
7498
  } from "@ai-matrx/design-system";
7502
7499
 
7503
7500
  // src/FormulaTextEditor.tsx
7504
- import { useEffect as useEffect15, useMemo as useMemo16, useRef as useRef6, useState as useState20 } from "react";
7501
+ import { useEffect as useEffect15, useMemo as useMemo16, useRef as useRef7, useState as useState20 } from "react";
7505
7502
  import { useRecordsClient as useRecordsClient13 } from "@ai-matrx/records/react";
7506
7503
  import { RULE_NODE_KINDS } from "@ai-matrx/records";
7507
7504
  import { BasicTextarea as BasicTextarea2, Button as Button18, Label as Label4, cn as cn19 } from "@ai-matrx/design-system";
@@ -7525,8 +7522,8 @@ function FormulaTextEditor({
7525
7522
  const client = useRecordsClient13();
7526
7523
  const [parsed, setParsed] = useState20(null);
7527
7524
  const [error, setError] = useState20(null);
7528
- const box = useRef6(null);
7529
- const report = useRef6(onChecked);
7525
+ const box = useRef7(null);
7526
+ const report = useRef7(onChecked);
7530
7527
  report.current = onChecked;
7531
7528
  useEffect15(() => {
7532
7529
  const asked = text.trim();
@@ -9973,7 +9970,7 @@ function entriesFor(scope) {
9973
9970
  import { Button as Button27, Separator as Separator8, Skeleton as Skeleton5, cn as cn27 } from "@ai-matrx/design-system";
9974
9971
 
9975
9972
  // src/RecordForm.tsx
9976
- import { useEffect as useEffect20, useMemo as useMemo23, useRef as useRef7, useState as useState29 } from "react";
9973
+ import { useEffect as useEffect20, useMemo as useMemo23, useRef as useRef8, useState as useState29 } from "react";
9977
9974
  import {
9978
9975
  useFields as useFields10,
9979
9976
  useRecord,
@@ -10221,7 +10218,7 @@ function RecordForm({
10221
10218
  const [answered, setAnswered] = useState29(null);
10222
10219
  const loaded = useRecordVersion(recordId ?? null);
10223
10220
  const loadedVersion = loaded.version;
10224
- const changedRef = useRef7({});
10221
+ const changedRef = useRef8({});
10225
10222
  changedRef.current = changed;
10226
10223
  useEffect20(() => {
10227
10224
  const document3 = existing.data?.document;
@@ -10576,7 +10573,7 @@ function computedInPlainWords(row, field) {
10576
10573
  // src/ViewSwitcher.tsx
10577
10574
  import { useEffect as useEffect23, useMemo as useMemo25, useState as useState33 } from "react";
10578
10575
  import { useFields as useFields13, useRecords as useRecords6, useRecordsClient as useRecordsClient22 } from "@ai-matrx/records/react";
10579
- import { stableFilterKey as stableFilterKey2 } from "@ai-matrx/records";
10576
+ import { stableFilterKey as stableFilterKey3 } from "@ai-matrx/records";
10580
10577
  import { Button as Button29, Skeleton as Skeleton7, cn as cn29 } from "@ai-matrx/design-system";
10581
10578
  import {
10582
10579
  resolveRowColor as resolveRowColor2,
@@ -10584,13 +10581,13 @@ import {
10584
10581
  } from "@ai-matrx/design-system/data-table";
10585
10582
 
10586
10583
  // src/Pipeline.tsx
10587
- import { useCallback as useCallback13, useEffect as useEffect22, useMemo as useMemo24, useRef as useRef8, useState as useState32 } from "react";
10584
+ import { useCallback as useCallback13, useEffect as useEffect22, useMemo as useMemo24, useRef as useRef9, useState as useState32 } from "react";
10588
10585
  import {
10589
10586
  mayDrag,
10590
10587
  useFields as useFields12,
10591
10588
  useRecordsClient as useRecordsClient21
10592
10589
  } from "@ai-matrx/records/react";
10593
- import { stableFilterKey } from "@ai-matrx/records";
10590
+ import { stableFilterKey as stableFilterKey2 } from "@ai-matrx/records";
10594
10591
  import {
10595
10592
  Button as Button28,
10596
10593
  DropdownMenu as DropdownMenu3,
@@ -10654,9 +10651,9 @@ function PipelineBoard({
10654
10651
  const [waiting, setWaiting] = useState32(/* @__PURE__ */ new Map());
10655
10652
  const [dragging, setDragging] = useState32(null);
10656
10653
  const [over, setOver] = useState32(null);
10657
- const alive = useRef8(true);
10654
+ const alive = useRef9(true);
10658
10655
  const [selected, setSelected] = useState32(/* @__PURE__ */ new Set());
10659
- const anchor = useRef8(null);
10656
+ const anchor = useRef9(null);
10660
10657
  const [versions, setVersions] = useState32(null);
10661
10658
  const [batch, setBatch] = useState32(/* @__PURE__ */ new Map());
10662
10659
  const [batchSaid, setBatchSaid] = useState32(null);
@@ -10668,7 +10665,7 @@ function PipelineBoard({
10668
10665
  alive.current = false;
10669
10666
  };
10670
10667
  }, []);
10671
- const filterKey = stableFilterKey(filter);
10668
+ const filterKey = stableFilterKey2(filter);
10672
10669
  const reload = useCallback13(async () => {
10673
10670
  setLoading(true);
10674
10671
  const [read, board, held] = await Promise.all([
@@ -11312,8 +11309,8 @@ function useViewRecords(view, pageSize = 200, filter, viewId) {
11312
11309
  cancelled = true;
11313
11310
  };
11314
11311
  }, [client, ruleId, pageSize]);
11315
- const asked = stableFilterKey2(filter ?? null);
11316
- const fromView = asked !== "{}" && (asked === stableFilterKey2(view.where ?? null) || asked === stableFilterKey2(view.filters ?? null));
11312
+ const asked = stableFilterKey3(filter ?? null);
11313
+ const fromView = asked !== "{}" && (asked === stableFilterKey3(view.where ?? null) || asked === stableFilterKey3(view.filters ?? null));
11317
11314
  const tableRows = useMemo25(() => table.data?.rows ?? [], [table.data]);
11318
11315
  const manual = view.order === "manual" && Boolean(viewId) && !ruleId;
11319
11316
  const hand = useHandOrderRows({
@@ -11321,8 +11318,7 @@ function useViewRecords(view, pageSize = 200, filter, viewId) {
11321
11318
  active: manual,
11322
11319
  page: 0,
11323
11320
  pageSize,
11324
- filtered: Boolean(filter),
11325
- filteredRows: tableRows,
11321
+ filter: filter ?? null,
11326
11322
  version: table.data
11327
11323
  });
11328
11324
  const rows = ruleId ? ruled.rows : manual ? hand.rows ?? [] : tableRows;
@@ -12197,9 +12193,9 @@ import { useRecordsClient as useRecordsClient25 } from "@ai-matrx/records/react"
12197
12193
  import { Button as Button32, Input as Input2, Skeleton as Skeleton10, cn as cn32 } from "@ai-matrx/design-system";
12198
12194
 
12199
12195
  // src/seedOnce.ts
12200
- import { useCallback as useCallback16, useRef as useRef9 } from "react";
12196
+ import { useCallback as useCallback16, useRef as useRef10 } from "react";
12201
12197
  function useSeedGuard() {
12202
- const claimed = useRef9(/* @__PURE__ */ new Set());
12198
+ const claimed = useRef10(/* @__PURE__ */ new Set());
12203
12199
  return useCallback16((name) => {
12204
12200
  if (claimed.current.has(name)) return false;
12205
12201
  claimed.current.add(name);
@@ -12444,7 +12440,7 @@ function ProposalRow({
12444
12440
  }
12445
12441
 
12446
12442
  // src/ActionInbox.tsx
12447
- import { useCallback as useCallback19, useEffect as useEffect28, useMemo as useMemo27, useRef as useRef10, useState as useState39 } from "react";
12443
+ import { useCallback as useCallback19, useEffect as useEffect28, useMemo as useMemo27, useRef as useRef11, useState as useState39 } from "react";
12448
12444
  import { useRecordsClient as useRecordsClient28 } from "@ai-matrx/records/react";
12449
12445
  import { Badge as Badge12, Button as Button35, Checkbox as Checkbox7, Skeleton as Skeleton12, cn as cn35 } from "@ai-matrx/design-system";
12450
12446
  import { toggleSelection as toggleSelection2 } from "@ai-matrx/design-system/data-table";
@@ -13236,9 +13232,9 @@ function ActionInbox({
13236
13232
  const [outcome, setOutcome] = useState39({});
13237
13233
  const [busy, setBusy] = useState39(null);
13238
13234
  const [cursor, setCursor] = useState39(0);
13239
- const listRef = useRef10(null);
13235
+ const listRef = useRef11(null);
13240
13236
  const [selected, setSelected] = useState39(/* @__PURE__ */ new Set());
13241
- const anchor = useRef10(null);
13237
+ const anchor = useRef11(null);
13242
13238
  const [deciding, setDeciding] = useState39(false);
13243
13239
  const [batchSaid, setBatchSaid] = useState39(null);
13244
13240
  const [view, setView] = useState39("inbox");
@@ -13836,7 +13832,7 @@ function ActionInbox({
13836
13832
  }
13837
13833
 
13838
13834
  // src/HistoryPanel.tsx
13839
- import { useCallback as useCallback20, useEffect as useEffect29, useRef as useRef11, useState as useState40 } from "react";
13835
+ import { useCallback as useCallback20, useEffect as useEffect29, useRef as useRef12, useState as useState40 } from "react";
13840
13836
  import {
13841
13837
  useFields as useFields15,
13842
13838
  useRecordChangeRevision,
@@ -13855,7 +13851,7 @@ function HistoryPanel({ tableId, recordId, onAskAboutField, className }) {
13855
13851
  const [open, setOpen] = useState40(null);
13856
13852
  const [pending, setPending] = useState40({ phase: "idle" });
13857
13853
  const [said, setSaid] = useState40(null);
13858
- const listRef = useRef11(null);
13854
+ const listRef = useRef12(null);
13859
13855
  const changed = useRecordChangeRevision(recordId);
13860
13856
  const load = useCallback20(async () => {
13861
13857
  const answered = await client.recordHistory({ record_id: recordId });
@@ -14147,7 +14143,7 @@ function say(value, field) {
14147
14143
  }
14148
14144
 
14149
14145
  // src/CommentThread.tsx
14150
- import { useCallback as useCallback21, useEffect as useEffect30, useMemo as useMemo28, useRef as useRef12, useState as useState41 } from "react";
14146
+ import { useCallback as useCallback21, useEffect as useEffect30, useMemo as useMemo28, useRef as useRef13, useState as useState41 } from "react";
14151
14147
  import {
14152
14148
  useFields as useFields16,
14153
14149
  useRecordsClient as useRecordsClient30,
@@ -14170,7 +14166,7 @@ function CommentThread({ tableId, recordId, fieldKey, className }) {
14170
14166
  const [people, setPeople] = useState41([]);
14171
14167
  const [mentionQuery, setMentionQuery] = useState41(null);
14172
14168
  const [picked, setPicked] = useState41([]);
14173
- const box = useRef12(null);
14169
+ const box = useRef13(null);
14174
14170
  const load = useCallback21(async () => {
14175
14171
  const answered = await client.commentThread({ record_id: recordId, include_resolved: showResolved });
14176
14172
  if (!answered.ok) {
@@ -15174,74 +15170,89 @@ function PortalLookEditor({ card, onSaved, className }) {
15174
15170
  ] }),
15175
15171
  /* @__PURE__ */ jsxs45("div", { className: "flex flex-col gap-1 text-xs", children: [
15176
15172
  /* @__PURE__ */ jsx50("span", { children: "Footer links" }),
15177
- links.map((link, i) => /* @__PURE__ */ jsxs45("div", { className: "flex gap-1.5", children: [
15178
- /* @__PURE__ */ jsx50(
15179
- BasicInput14,
15180
- {
15181
- value: link.label,
15182
- placeholder: "Call dispatch",
15183
- "aria-label": `Footer link ${i + 1} words`,
15184
- onChange: (e) => setLinks((ls) => ls.map((l, j) => j === i ? { ...l, label: e.target.value } : l))
15185
- }
15186
- ),
15187
- /* @__PURE__ */ jsx50(
15188
- BasicInput14,
15189
- {
15190
- value: link.url,
15191
- placeholder: "tel:+1 805 555 0142",
15192
- "aria-label": `Footer link ${i + 1} address`,
15193
- onChange: (e) => setLinks((ls) => ls.map((l, j) => j === i ? { ...l, url: e.target.value } : l))
15194
- }
15195
- ),
15196
- /* @__PURE__ */ jsx50(Button41, { type: "button", size: "sm", variant: "ghost", onClick: () => setLinks((ls) => ls.filter((_, j) => j !== i)), children: "Remove" })
15197
- ] }, i)),
15173
+ links.map((link, i) => (
15174
+ // Wraps at phone width: the two boxes share a row when there is room, and "Remove" is
15175
+ // never pushed past the edge (measured at 390: it was clipped).
15176
+ /* @__PURE__ */ jsxs45("div", { className: "flex flex-wrap items-center gap-1.5", children: [
15177
+ /* @__PURE__ */ jsx50(
15178
+ BasicInput14,
15179
+ {
15180
+ className: "min-w-0 flex-1 basis-32",
15181
+ value: link.label,
15182
+ placeholder: "Call dispatch",
15183
+ "aria-label": `Footer link ${i + 1} words`,
15184
+ onChange: (e) => setLinks((ls) => ls.map((l, j) => j === i ? { ...l, label: e.target.value } : l))
15185
+ }
15186
+ ),
15187
+ /* @__PURE__ */ jsx50(
15188
+ BasicInput14,
15189
+ {
15190
+ className: "min-w-0 flex-1 basis-40",
15191
+ value: link.url,
15192
+ placeholder: "tel:+1 805 555 0142",
15193
+ "aria-label": `Footer link ${i + 1} address`,
15194
+ onChange: (e) => setLinks((ls) => ls.map((l, j) => j === i ? { ...l, url: e.target.value } : l))
15195
+ }
15196
+ ),
15197
+ /* @__PURE__ */ jsx50(Button41, { type: "button", size: "sm", variant: "ghost", onClick: () => setLinks((ls) => ls.filter((_, j) => j !== i)), children: "Remove" })
15198
+ ] }, i)
15199
+ )),
15198
15200
  /* @__PURE__ */ jsx50("div", { children: /* @__PURE__ */ jsx50(Button41, { type: "button", size: "sm", variant: "outline", onClick: () => setLinks((ls) => [...ls, { label: "", url: "" }]), children: "Add a footer link" }) }),
15199
15201
  /* @__PURE__ */ jsx50("span", { className: "text-muted-foreground", children: "A link is a web address (https://), an email (mailto:) or a phone number (tel:)." })
15200
15202
  ] }),
15201
15203
  /* @__PURE__ */ jsx50("h4", { className: "mt-1 text-xs font-medium", children: "Forms clients can send" }),
15202
15204
  formsError ? /* @__PURE__ */ jsx50(RefusalNotice, { error: formsError }) : null,
15203
15205
  formsUnread ? /* @__PURE__ */ jsx50("span", { className: "text-xs text-muted-foreground", children: "The other forms on these tables could not be listed just now; the ones already on the portal are below." }) : null,
15204
- forms === null ? /* @__PURE__ */ jsx50("span", { className: "text-xs text-muted-foreground", children: "Reading the forms on this portal's tables\u2026" }) : forms.length === 0 ? /* @__PURE__ */ jsx50("span", { className: "text-xs text-muted-foreground", children: "None of the tables this portal shows has a form yet. Make one on a table's Forms tab and it appears here." }) : /* @__PURE__ */ jsx50("ul", { className: "flex flex-col gap-1", children: forms.map((f, i) => /* @__PURE__ */ jsxs45("li", { className: "flex flex-wrap items-center gap-1.5 rounded border border-border px-2 py-1 text-xs", children: [
15205
- /* @__PURE__ */ jsx50(
15206
- "input",
15207
- {
15208
- type: "checkbox",
15209
- checked: f.on,
15210
- "aria-label": `Offer ${f.title} on the portal`,
15211
- onChange: (e) => setForms((rows) => rows?.map((r) => r.form_id === f.form_id ? { ...r, on: e.target.checked } : r) ?? rows)
15212
- }
15213
- ),
15214
- /* @__PURE__ */ jsxs45("span", { className: "min-w-0 flex-1 truncate", children: [
15215
- /* @__PURE__ */ jsx50("span", { className: "font-medium", children: f.title }),
15216
- /* @__PURE__ */ jsxs45("span", { className: "text-muted-foreground", children: [
15217
- " \xB7 answers go to ",
15218
- f.table
15206
+ forms === null ? /* @__PURE__ */ jsx50("span", { className: "text-xs text-muted-foreground", children: "Reading the forms on this portal's tables\u2026" }) : forms.length === 0 ? /* @__PURE__ */ jsx50("span", { className: "text-xs text-muted-foreground", children: "None of the tables this portal shows has a form yet. Make one on a table's Forms tab and it appears here." }) : /* @__PURE__ */ jsx50("ul", { className: "flex flex-col gap-1", children: forms.map((f, i) => (
15207
+ // Two rows: the form's whole name first (at 390 a one-row layout truncated every title
15208
+ // to "Re…"/"Up…"), then its button words and its order.
15209
+ /* @__PURE__ */ jsxs45("li", { className: "flex flex-col gap-1 rounded border border-border px-2 py-1.5 text-xs", children: [
15210
+ /* @__PURE__ */ jsxs45("label", { className: "flex items-start gap-1.5", children: [
15211
+ /* @__PURE__ */ jsx50(
15212
+ "input",
15213
+ {
15214
+ className: "mt-0.5",
15215
+ type: "checkbox",
15216
+ checked: f.on,
15217
+ "aria-label": `Offer ${f.title} on the portal`,
15218
+ onChange: (e) => setForms((rows) => rows?.map((r) => r.form_id === f.form_id ? { ...r, on: e.target.checked } : r) ?? rows)
15219
+ }
15220
+ ),
15221
+ /* @__PURE__ */ jsxs45("span", { className: "min-w-0 flex-1", children: [
15222
+ /* @__PURE__ */ jsx50("span", { className: "font-medium", children: f.title }),
15223
+ /* @__PURE__ */ jsxs45("span", { className: "text-muted-foreground", children: [
15224
+ " \xB7 answers go to ",
15225
+ f.table
15226
+ ] })
15227
+ ] })
15228
+ ] }),
15229
+ /* @__PURE__ */ jsxs45("div", { className: "flex items-center gap-1.5 pl-5", children: [
15230
+ /* @__PURE__ */ jsx50(
15231
+ BasicInput14,
15232
+ {
15233
+ className: "h-7 min-w-0 flex-1",
15234
+ value: f.label,
15235
+ placeholder: "Button words (optional)",
15236
+ "aria-label": `What the portal calls ${f.title}`,
15237
+ onChange: (e) => setForms((rows) => rows?.map((r) => r.form_id === f.form_id ? { ...r, label: e.target.value } : r) ?? rows)
15238
+ }
15239
+ ),
15240
+ /* @__PURE__ */ jsx50(Button41, { type: "button", size: "sm", variant: "ghost", "aria-label": `Move ${f.title} up`, disabled: i === 0, onClick: () => move(i, -1), children: "Up" }),
15241
+ /* @__PURE__ */ jsx50(
15242
+ Button41,
15243
+ {
15244
+ type: "button",
15245
+ size: "sm",
15246
+ variant: "ghost",
15247
+ "aria-label": `Move ${f.title} down`,
15248
+ disabled: i === forms.length - 1,
15249
+ onClick: () => move(i, 1),
15250
+ children: "Down"
15251
+ }
15252
+ )
15219
15253
  ] })
15220
- ] }),
15221
- /* @__PURE__ */ jsx50(
15222
- BasicInput14,
15223
- {
15224
- className: "h-7 w-40",
15225
- value: f.label,
15226
- placeholder: "Button words (optional)",
15227
- "aria-label": `What the portal calls ${f.title}`,
15228
- onChange: (e) => setForms((rows) => rows?.map((r) => r.form_id === f.form_id ? { ...r, label: e.target.value } : r) ?? rows)
15229
- }
15230
- ),
15231
- /* @__PURE__ */ jsx50(Button41, { type: "button", size: "sm", variant: "ghost", "aria-label": `Move ${f.title} up`, disabled: i === 0, onClick: () => move(i, -1), children: "Up" }),
15232
- /* @__PURE__ */ jsx50(
15233
- Button41,
15234
- {
15235
- type: "button",
15236
- size: "sm",
15237
- variant: "ghost",
15238
- "aria-label": `Move ${f.title} down`,
15239
- disabled: i === forms.length - 1,
15240
- onClick: () => move(i, 1),
15241
- children: "Down"
15242
- }
15243
- )
15244
- ] }, f.form_id)) }),
15254
+ ] }, f.form_id)
15255
+ )) }),
15245
15256
  error ? /* @__PURE__ */ jsx50(RefusalNotice, { error }) : null,
15246
15257
  said ? /* @__PURE__ */ jsx50("p", { className: "text-xs text-muted-foreground", "aria-live": "polite", children: said }) : null,
15247
15258
  /* @__PURE__ */ jsx50("div", { children: /* @__PURE__ */ jsx50(Button41, { type: "button", size: "sm", onClick: () => void save(), disabled: busy, children: busy ? "Saving\u2026" : "Save the look and forms" }) })
@@ -16693,7 +16704,7 @@ import {
16693
16704
  } from "@ai-matrx/design-system";
16694
16705
 
16695
16706
  // src/FormRunner.tsx
16696
- import { useCallback as useCallback28, useEffect as useEffect39, useMemo as useMemo33, useRef as useRef13, useState as useState50 } from "react";
16707
+ import { useCallback as useCallback28, useEffect as useEffect39, useMemo as useMemo33, useRef as useRef14, useState as useState50 } from "react";
16697
16708
  import { useFields as useFields18, useOptionalRecordsClient as useOptionalRecordsClient5 } from "@ai-matrx/records/react";
16698
16709
  import { Button as Button46, Progress, Skeleton as Skeleton21, cn as cn46 } from "@ai-matrx/design-system";
16699
16710
  import { Fragment as Fragment23, jsx as jsx55, jsxs as jsxs50 } from "react/jsx-runtime";
@@ -16790,8 +16801,8 @@ function FormStage({
16790
16801
  const [writing, setWriting] = useState50(false);
16791
16802
  const [done, setDone] = useState50(null);
16792
16803
  const [hidden, setHidden] = useState50({});
16793
- const decoy = useRef13("");
16794
- const stage = useRef13(null);
16804
+ const decoy = useRef14("");
16805
+ const stage = useRef14(null);
16795
16806
  const questions = useMemo33(() => {
16796
16807
  const byKey = new Map((fields ?? []).map((f) => [f.key, f]));
16797
16808
  return (form.questions ?? []).map((q) => {
@@ -16849,13 +16860,13 @@ function FormStage({
16849
16860
  };
16850
16861
  }, [whichAsked, questions, answers]);
16851
16862
  const live = questions.filter((q) => !hidden[q.key]);
16852
- const told = useRef13(answers);
16863
+ const told = useRef14(answers);
16853
16864
  useEffect39(() => {
16854
16865
  if (told.current === answers) return;
16855
16866
  told.current = answers;
16856
16867
  onAnswersChange?.(answers);
16857
16868
  }, [answers, onAnswersChange]);
16858
- const resumeAt = useRef13(
16869
+ const resumeAt = useRef14(
16859
16870
  resumed && initialAnswers && Object.keys(initialAnswers).length > 0 ? questions.find((q) => {
16860
16871
  const v = initialAnswers[q.key];
16861
16872
  return v === void 0 || v === null || v === "";
@@ -17995,13 +18006,13 @@ function bucketWindow(groupKey, value) {
17995
18006
  import {
17996
18007
  useEffect as useEffect42,
17997
18008
  useId as useId2,
17998
- useRef as useRef14,
18009
+ useRef as useRef15,
17999
18010
  useState as useState53
18000
18011
  } from "react";
18001
18012
  import { cn as cn49 } from "@ai-matrx/design-system";
18002
18013
  import { jsx as jsx58, jsxs as jsxs53 } from "react/jsx-runtime";
18003
18014
  function useMeasuredWidth(fallback = 480) {
18004
- const ref = useRef14(null);
18015
+ const ref = useRef15(null);
18005
18016
  const [width, setWidth] = useState53(fallback);
18006
18017
  useEffect42(() => {
18007
18018
  const node = ref.current;
@@ -18311,7 +18322,7 @@ function DocTemplate({ tableId, seed, activeTemplateId, onActiveTemplate, classN
18311
18322
  }
18312
18323
 
18313
18324
  // src/DocRender.tsx
18314
- import { useCallback as useCallback32, useEffect as useEffect44, useRef as useRef15, useState as useState55 } from "react";
18325
+ import { useCallback as useCallback32, useEffect as useEffect44, useRef as useRef16, useState as useState55 } from "react";
18315
18326
  import { useRecordsClient as useRecordsClient42 } from "@ai-matrx/records/react";
18316
18327
  import { Button as Button50, Skeleton as Skeleton25, cn as cn51 } from "@ai-matrx/design-system";
18317
18328
  import { jsx as jsx60, jsxs as jsxs55 } from "react/jsx-runtime";
@@ -18322,7 +18333,7 @@ function DocRender({ templateId, recordId, filename, onRendered, className }) {
18322
18333
  const [showing, setShowing] = useState55(null);
18323
18334
  const [error, setError] = useState55(null);
18324
18335
  const [busy, setBusy] = useState55(null);
18325
- const paper = useRef15(null);
18336
+ const paper = useRef16(null);
18326
18337
  const load = useCallback32(async () => {
18327
18338
  const [body, held] = await Promise.all([
18328
18339
  client.docRenderBody({ template_id: templateId, record_id: recordId }),
@@ -20330,12 +20341,12 @@ function nextInWords(page) {
20330
20341
  }
20331
20342
 
20332
20343
  // src/CaptureSheet.tsx
20333
- import { useCallback as useCallback39, useEffect as useEffect51, useRef as useRef17, useState as useState62 } from "react";
20344
+ import { useCallback as useCallback39, useEffect as useEffect51, useRef as useRef18, useState as useState62 } from "react";
20334
20345
  import { useFields as useFields24, useRecordsClient as useRecordsClient49, useTable as useTable22 } from "@ai-matrx/records/react";
20335
20346
  import { Button as Button57, Input as Input4, Skeleton as Skeleton32, Textarea as Textarea3, cn as cn59 } from "@ai-matrx/design-system";
20336
20347
 
20337
20348
  // src/CaptureRun.tsx
20338
- import { useCallback as useCallback38, useEffect as useEffect50, useMemo as useMemo39, useRef as useRef16, useState as useState61 } from "react";
20349
+ import { useCallback as useCallback38, useEffect as useEffect50, useMemo as useMemo39, useRef as useRef17, useState as useState61 } from "react";
20339
20350
  import {
20340
20351
  coerceTypedAnswer as coerceTypedAnswer2,
20341
20352
  coercionLabel,
@@ -20393,7 +20404,7 @@ function CaptureRun({ sheetId, face: given, className }) {
20393
20404
  const [items, setItems] = useState61([]);
20394
20405
  const [lastSynced, setLastSynced] = useState61(null);
20395
20406
  const [sending, setSending] = useState61(false);
20396
- const queueRef = useRef16(null);
20407
+ const queueRef = useRef17(null);
20397
20408
  useEffect50(() => {
20398
20409
  const q2 = openCaptureQueue({
20399
20410
  onChange: (c, all) => {
@@ -20773,7 +20784,7 @@ function AdHocCaptureSheet({
20773
20784
  const [error, setError] = useState62(null);
20774
20785
  const [uploadError, setUploadError] = useState62(null);
20775
20786
  const [flushing, setFlushing] = useState62(false);
20776
- const queue = useRef17([]);
20787
+ const queue = useRef18([]);
20777
20788
  const keep = useCallback39(
20778
20789
  async (next) => {
20779
20790
  queue.current = next;