@ai-matrx/records-ui 0.93.8 → 0.93.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.cjs CHANGED
@@ -70,7 +70,7 @@ __export(src_exports, {
70
70
  ConditionGroup: () => ConditionGroup,
71
71
  ConditionRow: () => ConditionRow,
72
72
  CustomFieldsSection: () => CustomFieldsSection,
73
- DEFAULT_FIELDS: () => import_core15.DEFAULT_FIELDS,
73
+ DEFAULT_FIELDS: () => import_core16.DEFAULT_FIELDS,
74
74
  DEFAULT_FOOTER: () => DEFAULT_FOOTER,
75
75
  DEFAULT_VIEW_NAME: () => DEFAULT_VIEW_NAME,
76
76
  DUE_STATE_LABEL: () => DUE_STATE_LABEL,
@@ -224,7 +224,7 @@ __export(src_exports, {
224
224
  WithheldValue: () => WithheldValue,
225
225
  actorBadge: () => actorBadge,
226
226
  actorWords: () => actorWords,
227
- addFields: () => import_core15.addFields,
227
+ addFields: () => import_core16.addFields,
228
228
  applyLook: () => applyLook,
229
229
  archiveConfirmSentence: () => archiveConfirmSentence,
230
230
  archivedRowLine: () => archivedRowLine,
@@ -259,7 +259,7 @@ __export(src_exports, {
259
259
  dashboardFromSummary: () => dashboardFromSummary,
260
260
  dateFormatFor: () => dateFormatFor,
261
261
  dateText: () => dateText,
262
- declareTable: () => import_core15.declareTable,
262
+ declareTable: () => import_core16.declareTable,
263
263
  declareView: () => declareView,
264
264
  defaultViewOf: () => defaultViewOf,
265
265
  designatedLayoutOf: () => designatedLayoutOf,
@@ -267,7 +267,7 @@ __export(src_exports, {
267
267
  ensureSystemTable: () => ensureSystemTable,
268
268
  entityReferenceSpec: () => entityReferenceSpec,
269
269
  envelopeFor: () => envelopeFor,
270
- fieldDeclarationFor: () => import_core15.fieldDeclarationFor,
270
+ fieldDeclarationFor: () => import_core16.fieldDeclarationFor,
271
271
  fieldIsEditable: () => fieldIsEditable,
272
272
  fieldName: () => fieldName,
273
273
  fieldToken: () => fieldToken,
@@ -357,7 +357,7 @@ __export(src_exports, {
357
357
  tableName: () => tableName,
358
358
  tableOpening: () => tableOpening,
359
359
  tableRightsAt: () => tableRightsAt,
360
- tokenFor: () => import_core15.tokenFor,
360
+ tokenFor: () => import_core16.tokenFor,
361
361
  unknownRailLine: () => unknownRailLine,
362
362
  unknownViewLine: () => unknownViewLine,
363
363
  useCanShare: () => useCanShare,
@@ -3107,7 +3107,7 @@ function OptionControl({ field: field2, value, onChange, disabled, id, autoOpen,
3107
3107
  if (refusal2)
3108
3108
  return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { id, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(RefusalLine, { error: refusal2 }) });
3109
3109
  if (!options) return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { id, className: "text-xs text-muted-foreground", children: "Reading this field's choices\u2026" });
3110
- if (CHOICE_EDITOR_ADDS_WHAT_IS_TYPED && (0, import_records5.allowsOtherValues)(field2)) {
3110
+ if (CHOICE_EDITOR_ADDS_WHAT_IS_TYPED && ((0, import_records5.allowsOtherValues)(field2) || !autoOpen)) {
3111
3111
  return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
3112
3112
  OpenChoicePicker,
3113
3113
  {
@@ -3118,6 +3118,7 @@ function OptionControl({ field: field2, value, onChange, disabled, id, autoOpen,
3118
3118
  disabled,
3119
3119
  id,
3120
3120
  addsChoices,
3121
+ allowOther: (0, import_records5.allowsOtherValues)(field2),
3121
3122
  onChoicesChanged: () => setReread((n) => n + 1)
3122
3123
  }
3123
3124
  );
@@ -3190,6 +3191,7 @@ function OpenChoicePicker({
3190
3191
  disabled,
3191
3192
  id,
3192
3193
  addsChoices,
3194
+ allowOther = true,
3193
3195
  onChoicesChanged
3194
3196
  }) {
3195
3197
  const client = (0, import_react18.useOptionalRecordsClient)();
@@ -3207,7 +3209,7 @@ function OpenChoicePicker({
3207
3209
  });
3208
3210
  const q = search.trim();
3209
3211
  const visible = options.filter((o) => q === "" || titleOf(o).toLowerCase().includes(q.toLowerCase()));
3210
- const decided = (0, import_records5.decideTypedChoice)({ words: q, options, allowOther: true, nudge: nudge ?? "ask" });
3212
+ const decided = (0, import_records5.decideTypedChoice)({ words: q, options, allowOther, nudge: nudge ?? "ask" });
3211
3213
  const choose = (word, addingIt = false) => {
3212
3214
  const pending = held.add.filter((w) => w.toLowerCase() !== word.toLowerCase());
3213
3215
  let next;
@@ -3292,7 +3294,10 @@ function OpenChoicePicker({
3292
3294
  empty: q === "" ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "p-2 text-xs text-muted-foreground", children: "No choices yet \u2014 type one to add it." }) : null,
3293
3295
  add,
3294
3296
  foot,
3295
- footNote: addRefused ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(RefusalLine, { error: addRefused }) : null
3297
+ footNote: addRefused ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(RefusalLine, { error: addRefused }) : offList && decided.decision === "not_a_choice" ? (
3298
+ // never_add on a column that takes only its choices: said, never a silent nothing.
3299
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { "data-records-typed-refusal": "", className: "p-2 text-xs text-muted-foreground", children: notAChoiceSentence(field2, [q]) })
3300
+ ) : null
3296
3301
  }
3297
3302
  )
3298
3303
  )
@@ -4986,7 +4991,7 @@ var import_react64 = require("react");
4986
4991
  var import_react65 = require("@ai-matrx/records/react");
4987
4992
  var import_records17 = require("@ai-matrx/records");
4988
4993
  var import_data_table9 = require("@ai-matrx/design-system/data-table");
4989
- var import_core8 = require("@ai-matrx/records/core");
4994
+ var import_core9 = require("@ai-matrx/records/core");
4990
4995
 
4991
4996
  // src/archiveWords.ts
4992
4997
  function archiveConfirmSentence(what) {
@@ -5226,6 +5231,7 @@ var import_design_system25 = require("@ai-matrx/design-system");
5226
5231
  // src/FieldEditor.tsx
5227
5232
  var import_react36 = require("react");
5228
5233
  var import_react37 = require("@ai-matrx/records/react");
5234
+ var import_core4 = require("@ai-matrx/records/core");
5229
5235
  var import_design_system21 = require("@ai-matrx/design-system");
5230
5236
 
5231
5237
  // src/FormulaTextEditor.tsx
@@ -5614,10 +5620,17 @@ function ChoiceListEditor({
5614
5620
  field: field2,
5615
5621
  rows,
5616
5622
  onRows,
5617
- onStart
5623
+ onStart,
5624
+ allowOther = false,
5625
+ rehome = {},
5626
+ onRehome
5618
5627
  }) {
5619
5628
  const client = (0, import_react35.useRecordsClient)();
5620
5629
  const [refused, setRefused] = (0, import_react34.useState)(null);
5630
+ const [usage, setUsage] = (0, import_react34.useState)(null);
5631
+ const [asking, setAsking] = (0, import_react34.useState)(null);
5632
+ const [moveTo, setMoveTo] = (0, import_react34.useState)("");
5633
+ const [removed, setRemoved] = (0, import_react34.useState)({});
5621
5634
  (0, import_react34.useEffect)(() => {
5622
5635
  if (rows !== null) return;
5623
5636
  let live = true;
@@ -5635,6 +5648,19 @@ function ChoiceListEditor({
5635
5648
  live = false;
5636
5649
  };
5637
5650
  }, [client, field2.id, rows, onRows, onStart]);
5651
+ (0, import_react34.useEffect)(() => {
5652
+ if (!onRehome) return;
5653
+ let live = true;
5654
+ void client.fieldChoiceUsage({ field_id: field2.id }).then(
5655
+ (got) => {
5656
+ if (live && got.ok) setUsage(got.data);
5657
+ },
5658
+ () => void 0
5659
+ );
5660
+ return () => {
5661
+ live = false;
5662
+ };
5663
+ }, [client, field2.id, onRehome]);
5638
5664
  if (refused) {
5639
5665
  return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("p", { className: "text-[11px] text-muted-foreground", "data-records-choice-list": "", children: [
5640
5666
  "The choices could not be read, so they are left as they are: ",
@@ -5651,6 +5677,37 @@ function ChoiceListEditor({
5651
5677
  onRows(next);
5652
5678
  };
5653
5679
  const named = (r, i) => r.words.trim() === "" ? `choice ${i + 1}` : `\u201C${r.words.trim()}\u201D`;
5680
+ const heldBy = (r) => r.id && onRehome ? usage?.[r.id]?.records ?? 0 : 0;
5681
+ const remove = (i) => {
5682
+ const r = rows[i];
5683
+ if (heldBy(r) > 0) {
5684
+ setAsking(r);
5685
+ setMoveTo("");
5686
+ return;
5687
+ }
5688
+ onRows(rows.filter((_, j) => j !== i));
5689
+ };
5690
+ const answer = (spec) => {
5691
+ if (!asking?.id || !onRehome) return;
5692
+ const index = rows.findIndex((r) => r.id === asking.id);
5693
+ setRemoved({ ...removed, [asking.id]: { row: asking, index: index < 0 ? rows.length : index } });
5694
+ onRows(rows.filter((r) => r.id !== asking.id));
5695
+ onRehome({ ...rehome, [asking.id]: spec });
5696
+ setAsking(null);
5697
+ };
5698
+ const putBack = (id) => {
5699
+ const was = removed[id];
5700
+ if (!was || !onRehome) return;
5701
+ const next = [...rows];
5702
+ next.splice(Math.min(was.index, next.length), 0, was.row);
5703
+ onRows(next);
5704
+ const { [id]: _gone, ...rest } = rehome;
5705
+ onRehome(rest);
5706
+ const { [id]: _was, ...keep } = removed;
5707
+ setRemoved(keep);
5708
+ };
5709
+ const targets = rows.filter((r) => r.id && r.id !== asking?.id && r.words.trim() !== "");
5710
+ const wordsOf = (id) => rows.find((r) => r.id === id)?.words.trim() ?? usage?.[id]?.words ?? "";
5654
5711
  return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col gap-1", "data-records-choice-list": "", children: [
5655
5712
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_design_system19.Label, { className: "text-xs", children: "The choices" }),
5656
5713
  rows.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-xs text-muted-foreground", "data-records-choice-list-empty": "", children: "No choices yet. Add the first one here, or type it into a cell and answer Add." }) : null,
@@ -5666,10 +5723,43 @@ function ChoiceListEditor({
5666
5723
  ),
5667
5724
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_design_system19.Button, { type: "button", size: "sm", variant: "ghost", className: "h-7 px-1.5 text-xs", "aria-label": `Move ${named(r, i)} up`, disabled: i === 0, onClick: () => move(i, -1), children: "\u2191" }),
5668
5725
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_design_system19.Button, { type: "button", size: "sm", variant: "ghost", className: "h-7 px-1.5 text-xs", "aria-label": `Move ${named(r, i)} down`, disabled: i === rows.length - 1, onClick: () => move(i, 1), children: "\u2193" }),
5669
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_design_system19.Button, { type: "button", size: "sm", variant: "ghost", className: "h-7 px-1.5 text-xs", "aria-label": `Remove ${named(r, i)}`, onClick: () => onRows(rows.filter((_, j) => j !== i)), children: "\xD7" })
5726
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_design_system19.Button, { type: "button", size: "sm", variant: "ghost", className: "h-7 px-1.5 text-xs", "aria-label": `Remove ${named(r, i)}`, onClick: () => remove(i), children: "\xD7" })
5670
5727
  ] }, r.row)) }),
5728
+ asking ? (
5729
+ // THE QUESTION, Notion-style: where do the records that hold it go?
5730
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
5731
+ "div",
5732
+ {
5733
+ role: "group",
5734
+ "aria-label": (0, import_records10.recordsUseSentence)(heldBy(asking), asking.words.trim()),
5735
+ "data-records-choice-removal-ask": "",
5736
+ className: "flex flex-col gap-1 rounded border bg-muted/40 p-2",
5737
+ children: [
5738
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-xs", children: (0, import_records10.recordsUseSentence)(heldBy(asking), asking.words.trim()) }),
5739
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-wrap items-center gap-1", children: [
5740
+ targets.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
5741
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_design_system19.Button, { type: "button", size: "sm", className: "h-7 px-2 text-xs", disabled: moveTo === "", onClick: () => answer({ then: "move", to: moveTo }), children: "Move them to" }),
5742
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_design_system19.Select, { value: moveTo, onValueChange: setMoveTo, children: [
5743
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_design_system19.SelectTrigger, { size: "sm", className: "h-7 w-36 text-xs", "aria-label": "Another choice", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_design_system19.SelectValue, { placeholder: "Another choice" }) }),
5744
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_design_system19.SelectContent, { children: targets.map((r) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_design_system19.SelectItem, { value: r.id, children: r.words.trim() }, r.id)) })
5745
+ ] })
5746
+ ] }) : null,
5747
+ allowOther ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_design_system19.Button, { type: "button", size: "sm", variant: "outline", className: "h-7 px-2 text-xs", onClick: () => answer({ then: "keep" }), children: "Keep the words as other values" }) : null,
5748
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_design_system19.Button, { type: "button", size: "sm", variant: "outline", className: "h-7 px-2 text-xs", onClick: () => answer({ then: "clear" }), children: "Clear them" }),
5749
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_design_system19.Button, { type: "button", size: "sm", variant: "ghost", className: "h-7 px-2 text-xs", onClick: () => setAsking(null), children: "Cancel" })
5750
+ ] })
5751
+ ]
5752
+ }
5753
+ )
5754
+ ) : null,
5755
+ Object.entries(rehome).map(
5756
+ ([id, spec]) => removed[id] ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center justify-between gap-2 text-[11px] text-muted-foreground", "data-records-choice-rehome": "", children: [
5757
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { children: (0, import_records10.rehomeSentence)(usage?.[id]?.records ?? 0, removed[id].row.words.trim(), spec, spec.then === "move" ? wordsOf(spec.to) : void 0) }),
5758
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_design_system19.Button, { type: "button", size: "sm", variant: "ghost", className: "h-6 px-1.5 text-[11px]", onClick: () => putBack(id), children: "Put it back" })
5759
+ ] }, id) : null
5760
+ ),
5671
5761
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_design_system19.Button, { type: "button", size: "sm", variant: "outline", className: "h-7 self-start text-xs", onClick: () => onRows([...rows, { id: null, words: "", row: nextRow() }]), children: "Add a choice" }),
5672
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-[11px] text-muted-foreground", children: "Changing a choice\u2019s words changes them in every record that holds it. A removed choice is no longer offered; records that hold it keep it." })
5762
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-[11px] text-muted-foreground", children: "Changing a choice\u2019s words changes them in every record that holds it. Removing a choice that records hold asks where those records go." })
5673
5763
  ] });
5674
5764
  }
5675
5765
 
@@ -6206,6 +6296,9 @@ function FieldEditor({ tableId, field: field2, onSaved, onCancel, onRemoved, cla
6206
6296
  const [optionText, setOptionText] = (0, import_react36.useState)("");
6207
6297
  const [choiceList, setChoiceList] = (0, import_react36.useState)(null);
6208
6298
  const [choiceListStart, setChoiceListStart] = (0, import_react36.useState)(null);
6299
+ const [rehome, setRehome] = (0, import_react36.useState)({});
6300
+ const [rehomed, setRehomed] = (0, import_react36.useState)(null);
6301
+ const [rehomeRefused, setRehomeRefused] = (0, import_react36.useState)(null);
6209
6302
  const [unit, setUnit] = (0, import_react36.useState)(field2?.unit ?? "$");
6210
6303
  const [withTime, setWithTime] = (0, import_react36.useState)(String(field2?.config?.["kind"] ?? "date") === "datetime");
6211
6304
  const [via, setVia] = (0, import_react36.useState)(String(field2?.config?.["via"] ?? ""));
@@ -6299,6 +6392,20 @@ function FieldEditor({ tableId, field: field2, onSaved, onCancel, onRemoved, cla
6299
6392
  // K2: a re-aimed formula goes WITH its type word, the arm `field_update` reads it in.
6300
6393
  ...type === "formula" && formulaWritten && formulaChanged && formulaText.trim() !== "" ? { type: "formula", formula_text: formulaText.trim() } : {}
6301
6394
  };
6395
+ if (Object.keys(rehome).length > 0 && Array.isArray(patch.options)) {
6396
+ setRehomeRefused(null);
6397
+ const done = await client.fieldUpdateRehomingChoices({ field_id: field2.id, patch, rehome });
6398
+ if (!done.ok) {
6399
+ setRehomeRefused(done.error);
6400
+ return;
6401
+ }
6402
+ (0, import_react37.tableShapeChanged)(tableId);
6403
+ for (const c of done.data.undo.cells_back) (0, import_core4.announceRecordChanged)(c.record_id);
6404
+ const n = done.data.rehomed.reduce((sum, r) => sum + r.records, 0);
6405
+ setRehome({});
6406
+ setRehomed({ said: `Saved. ${n} ${n === 1 ? "record was" : "records were"} changed with the choices.`, undo: done.data.undo });
6407
+ return;
6408
+ }
6302
6409
  const written2 = await mutation.update({ field_id: field2.id, patch });
6303
6410
  if (written2 !== null) onSaved?.();
6304
6411
  return;
@@ -6469,7 +6576,18 @@ function FieldEditor({ tableId, field: field2, onSaved, onCancel, onRemoved, cla
6469
6576
  relations,
6470
6577
  others,
6471
6578
  existingOptionsTable: Boolean(field2?.options_table_id ?? field2?.config?.["options_table_id"]),
6472
- choiceList: editing && field2 ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ChoiceListEditor, { field: field2, rows: choiceList, onRows: setChoiceList, onStart: setChoiceListStart }) : null,
6579
+ choiceList: editing && field2 ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
6580
+ ChoiceListEditor,
6581
+ {
6582
+ field: field2,
6583
+ rows: choiceList,
6584
+ onRows: setChoiceList,
6585
+ onStart: setChoiceListStart,
6586
+ allowOther,
6587
+ rehome,
6588
+ onRehome: setRehome
6589
+ }
6590
+ ) : null,
6473
6591
  allowedTypes,
6474
6592
  setAllowedTypes
6475
6593
  }
@@ -6619,6 +6737,36 @@ function FieldEditor({ tableId, field: field2, onSaved, onCancel, onRemoved, cla
6619
6737
  error: refusal("internal", COLUMN_DID_NOT_LAND_SENTENCE, COLUMN_DID_NOT_LAND_REMEDY)
6620
6738
  }
6621
6739
  ) : null,
6740
+ rehomeRefused ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(RefusalNotice, { error: rehomeRefused }) : null,
6741
+ rehomed ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { "data-records-choice-rehomed": "", className: "flex flex-wrap items-center gap-2 text-[11px]", children: [
6742
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { children: rehomed.said }),
6743
+ rehomed.undo ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
6744
+ import_design_system21.Button,
6745
+ {
6746
+ type: "button",
6747
+ size: "sm",
6748
+ variant: "outline",
6749
+ className: "h-6 px-2 text-xs",
6750
+ onClick: () => {
6751
+ const undo = rehomed.undo;
6752
+ if (!undo || !field2) return;
6753
+ void client.fieldUpdateRehomingChoices({ field_id: field2.id, patch: { options: undo.options }, cells_back: undo.cells_back }).then((back) => {
6754
+ if (!back.ok) {
6755
+ setRehomeRefused(back.error);
6756
+ return;
6757
+ }
6758
+ (0, import_react37.tableShapeChanged)(tableId);
6759
+ for (const c of undo.cells_back) (0, import_core4.announceRecordChanged)(c.record_id);
6760
+ setChoiceList(null);
6761
+ setChoiceListStart(null);
6762
+ setRehomed({ said: "Undone. The choices and the records that held them are back as they were.", undo: null });
6763
+ });
6764
+ },
6765
+ children: "Undo"
6766
+ }
6767
+ ) : null,
6768
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_design_system21.Button, { type: "button", size: "sm", className: "h-6 px-2 text-xs", onClick: () => onSaved?.(), children: "Done" })
6769
+ ] }) : null,
6622
6770
  backfillError ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { "data-records-autonumber-backfill-refused": "", className: "flex flex-col gap-1", children: [
6623
6771
  /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "text-[11px]", children: "The column is made. The records already in the table were not numbered:" }),
6624
6772
  /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(RefusalNotice, { error: backfillError })
@@ -7803,7 +7951,7 @@ function SummarySheetControls({
7803
7951
  }
7804
7952
 
7805
7953
  // src/pasteValues.ts
7806
- var import_core4 = require("@ai-matrx/records/core");
7954
+ var import_core5 = require("@ai-matrx/records/core");
7807
7955
  var import_records14 = require("@ai-matrx/records");
7808
7956
  function wordForStoredChoice(options, value) {
7809
7957
  if (options === void 0 || typeof value !== "string" || value === "") return null;
@@ -7881,7 +8029,7 @@ function planPastedBlock(args) {
7881
8029
  });
7882
8030
  accepted[key] = judged.value;
7883
8031
  }
7884
- const predicted = (0, import_core4.predictValueRefusals)(args.fields, accepted);
8032
+ const predicted = (0, import_core5.predictValueRefusals)(args.fields, accepted);
7885
8033
  for (const refusal2 of predicted) {
7886
8034
  const key = refusal2.field_key;
7887
8035
  if (key === void 0) continue;
@@ -9863,7 +10011,7 @@ function GridLayoutMenu({
9863
10011
  // src/gridUndo.tsx
9864
10012
  var import_react56 = require("react");
9865
10013
  var import_react57 = require("@ai-matrx/records/react");
9866
- var import_core5 = require("@ai-matrx/records/core");
10014
+ var import_core6 = require("@ai-matrx/records/core");
9867
10015
  var import_design_system32 = require("@ai-matrx/design-system");
9868
10016
  var import_data_table8 = require("@ai-matrx/design-system/data-table");
9869
10017
  var import_jsx_runtime38 = require("react/jsx-runtime");
@@ -9931,7 +10079,7 @@ function useGridUndo(args) {
9931
10079
  }
9932
10080
  forget(step2.cells.map((c) => ({ rowId: c.rowId, key: c.key })));
9933
10081
  for (const id of /* @__PURE__ */ new Set([...step2.cells.map((c) => c.rowId), ...step2.created ?? [], ...step2.archived ?? []])) {
9934
- (0, import_core5.announceRecordChanged)(id);
10082
+ (0, import_core6.announceRecordChanged)(id);
9935
10083
  }
9936
10084
  setHeld(() => {
9937
10085
  let stack = taken.stack;
@@ -10076,7 +10224,7 @@ function undoKey(event) {
10076
10224
 
10077
10225
  // src/gridAssist.tsx
10078
10226
  var import_react59 = require("react");
10079
- var import_core6 = require("@ai-matrx/records/core");
10227
+ var import_core7 = require("@ai-matrx/records/core");
10080
10228
  var import_content_transfer = require("@ai-matrx/design-system/content-transfer");
10081
10229
 
10082
10230
  // src/gridAgentContext.ts
@@ -10355,7 +10503,7 @@ function useGridAssist(args) {
10355
10503
  if (!row) return;
10356
10504
  const document2 = row.document ?? {};
10357
10505
  const value = editing.valueFor(row, fieldOf2(key));
10358
- const pointer = typeof document2[key] === "string" ? (0, import_core6.wholeValueOf)(document2, key) : null;
10506
+ const pointer = typeof document2[key] === "string" ? (0, import_core7.wholeValueOf)(document2, key) : null;
10359
10507
  setWhole({ rowId, key, rowTitle: titleOf(row), value, pointer });
10360
10508
  },
10361
10509
  [rowOf, fieldOf2, titleOf, editing]
@@ -10448,7 +10596,7 @@ function useGridAssist(args) {
10448
10596
  // src/gridBulk.tsx
10449
10597
  var import_react60 = require("react");
10450
10598
  var import_react61 = require("@ai-matrx/records/react");
10451
- var import_core7 = require("@ai-matrx/records/core");
10599
+ var import_core8 = require("@ai-matrx/records/core");
10452
10600
  var import_design_system34 = require("@ai-matrx/design-system");
10453
10601
  var import_jsx_runtime41 = require("react/jsx-runtime");
10454
10602
  function countOf(n, one, many) {
@@ -10505,7 +10653,7 @@ function useGridBulk(args) {
10505
10653
  setRefusal(done.error);
10506
10654
  return null;
10507
10655
  }
10508
- for (const change of changes) if ("record_id" in change && change.record_id) (0, import_core7.announceRecordChanged)(change.record_id);
10656
+ for (const change of changes) if ("record_id" in change && change.record_id) (0, import_core8.announceRecordChanged)(change.record_id);
10509
10657
  return done.data;
10510
10658
  },
10511
10659
  [client, tableId]
@@ -11647,7 +11795,7 @@ function Grid({
11647
11795
  }))
11648
11796
  );
11649
11797
  editing.forget(cells);
11650
- for (const u of updates) (0, import_core8.announceRecordChanged)(u.row.recordId);
11798
+ for (const u of updates) (0, import_core9.announceRecordChanged)(u.row.recordId);
11651
11799
  const lines = updates.length + creates.length;
11652
11800
  undo.push({ label: `Pasted ${lines} ${lines === 1 ? "row" : "rows"}`, cells, created });
11653
11801
  const expected = [
@@ -12819,7 +12967,7 @@ function withHeaderMenus(columns, menuFor, filterFor) {
12819
12967
  // src/ExportMenu.tsx
12820
12968
  var import_react66 = require("react");
12821
12969
  var import_react67 = require("@ai-matrx/records/react");
12822
- var import_core9 = require("@ai-matrx/records/core");
12970
+ var import_core10 = require("@ai-matrx/records/core");
12823
12971
  var import_react68 = require("@ai-matrx/alchemy/react");
12824
12972
  var import_design_system37 = require("@ai-matrx/design-system");
12825
12973
  var import_jsx_runtime44 = require("react/jsx-runtime");
@@ -12838,7 +12986,7 @@ function toRows(fields, records, labels) {
12838
12986
  absent_reason: envelope?.absent ?? null,
12839
12987
  // A VALUE KEPT AS A FILE carries its pointer, so the export writes the whole text
12840
12988
  // (`withWholeValues`), never the first words passed off as the value.
12841
- source: (0, import_core9.wholeValueOf)(document2, field2.key)
12989
+ source: (0, import_core10.wholeValueOf)(document2, field2.key)
12842
12990
  };
12843
12991
  }
12844
12992
  return row;
@@ -12892,7 +13040,7 @@ function ExportMenu({ tableId, rows, label, className }) {
12892
13040
  );
12893
13041
  const lookup = (field2, id) => labels(field2, id) ?? learned.get(`${field2.id}:${id}`) ?? null;
12894
13042
  const read = host.readFileText;
12895
- return (0, import_core9.withWholeValues)(toRows(all, records, lookup), read ? (fileId) => read({ fileId }) : null);
13043
+ return (0, import_core10.withWholeValues)(toRows(all, records, lookup), read ? (fileId) => read({ fileId }) : null);
12896
13044
  };
12897
13045
  return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: (0, import_design_system37.cn)("flex items-center gap-1", className), children: [
12898
13046
  /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
@@ -12900,7 +13048,7 @@ function ExportMenu({ tableId, rows, label, className }) {
12900
13048
  {
12901
13049
  size: "sm",
12902
13050
  variant: "outline",
12903
- onClick: () => void exported().then((rows2) => download(`${name}.csv`, "text/csv;charset=utf-8", (0, import_core9.exportCsv)(fields.data ?? [], rows2))).catch(
13051
+ onClick: () => void exported().then((rows2) => download(`${name}.csv`, "text/csv;charset=utf-8", (0, import_core10.exportCsv)(fields.data ?? [], rows2))).catch(
12904
13052
  (thrown) => setFailure(refusalFromThrown(thrown, "The CSV could not be written.", "Try again in a moment."))
12905
13053
  ),
12906
13054
  children: "CSV"
@@ -12921,7 +13069,7 @@ function ExportMenu({ tableId, rows, label, className }) {
12921
13069
  );
12922
13070
  setFailure(null);
12923
13071
  try {
12924
- exported().then((rows2) => (0, import_core9.exportXlsx)(fields.data ?? [], rows2, name)).then(
13072
+ exported().then((rows2) => (0, import_core10.exportXlsx)(fields.data ?? [], rows2, name)).then(
12925
13073
  (bytes) => download(
12926
13074
  `${name}.xlsx`,
12927
13075
  "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
@@ -12942,7 +13090,7 @@ function ExportMenu({ tableId, rows, label, className }) {
12942
13090
  sourceId: `records:${tableId}`,
12943
13091
  size: "xs",
12944
13092
  json: () => records.map((r) => r.document),
12945
- human: () => (0, import_core9.exportCsv)(fields.data ?? [], toRows(fields.data ?? [], records, labels))
13093
+ human: () => (0, import_core10.exportCsv)(fields.data ?? [], toRows(fields.data ?? [], records, labels))
12946
13094
  }
12947
13095
  ),
12948
13096
  failure ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(RefusalLine, { error: failure }) : null
@@ -12952,11 +13100,11 @@ function ExportMenu({ tableId, rows, label, className }) {
12952
13100
  // src/ImportWizard.tsx
12953
13101
  var import_react69 = require("react");
12954
13102
  var import_react70 = require("@ai-matrx/records/react");
12955
- var import_core11 = require("@ai-matrx/records/core");
13103
+ var import_core12 = require("@ai-matrx/records/core");
12956
13104
  var import_design_system38 = require("@ai-matrx/design-system");
12957
13105
 
12958
13106
  // src/importRuleCheck.ts
12959
- var import_core10 = require("@ai-matrx/records/core");
13107
+ var import_core11 = require("@ai-matrx/records/core");
12960
13108
  function checkImportRules(fields, rows, mapping) {
12961
13109
  const byKey = new Map(fields.map((f) => [f.key, f]));
12962
13110
  const verdicts = [];
@@ -12974,7 +13122,7 @@ function checkImportRules(fields, rows, mapping) {
12974
13122
  let why = null;
12975
13123
  if ("refusal" in meant) why = meant.refusal;
12976
13124
  else {
12977
- const predicted = (0, import_core10.predictValueRefusals)([field2], { [key]: meant.value }).filter(
13125
+ const predicted = (0, import_core11.predictValueRefusals)([field2], { [key]: meant.value }).filter(
12978
13126
  (p) => p.field_key === void 0 || p.field_key === key
12979
13127
  );
12980
13128
  if (predicted.length > 0) why = predicted[0].message;
@@ -13102,7 +13250,7 @@ function ImportWizard({ tableId, onDone, onWrote, className }) {
13102
13250
  try {
13103
13251
  const xlsx = file.name.toLowerCase().endsWith(".xlsx");
13104
13252
  const bytes = await file.arrayBuffer();
13105
- const result = xlsx ? await (0, import_core11.importXlsx)(bytes) : (0, import_core11.importCsv)(new TextDecoder().decode(bytes));
13253
+ const result = xlsx ? await (0, import_core12.importXlsx)(bytes) : (0, import_core12.importCsv)(new TextDecoder().decode(bytes));
13106
13254
  setFormat(xlsx ? "xlsx" : "csv");
13107
13255
  setFileName(file.name);
13108
13256
  setFileBytes(file.size);
@@ -13729,6 +13877,7 @@ function CustomFieldsSection({
13729
13877
  const [newLabel, setNewLabel] = (0, import_react71.useState)("");
13730
13878
  const [newType, setNewType] = (0, import_react71.useState)("text");
13731
13879
  const [draft, setDraft] = (0, import_react71.useState)({});
13880
+ const [removing, setRemoving] = (0, import_react71.useState)(null);
13732
13881
  const fields = (0, import_react71.useMemo)(() => read.data?.fields ?? [], [read.data]);
13733
13882
  const mayAdd = rights.data?.may_declare === true;
13734
13883
  const live = (0, import_react71.useRef)({ fields, rights: rights.data, loading: rights.loading, reload: read.reload });
@@ -13888,7 +14037,46 @@ function CustomFieldsSection({
13888
14037
  const field2 = asField(f);
13889
14038
  const id = `cf-${recordId}-${f.key}`;
13890
14039
  return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex min-w-0 flex-col gap-1", children: [
13891
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(FieldLabel, { field: field2, htmlFor: id }),
14040
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex items-center gap-2", children: [
14041
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(FieldLabel, { field: field2, htmlFor: id }),
14042
+ mayAdd && removing !== f.id ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
14043
+ import_design_system39.Button,
14044
+ {
14045
+ size: "sm",
14046
+ variant: "ghost",
14047
+ className: "ml-auto h-6 px-2 text-xs text-muted-foreground",
14048
+ onClick: () => setRemoving(f.id),
14049
+ children: "Remove field"
14050
+ }
14051
+ ) : null
14052
+ ] }),
14053
+ removing === f.id ? /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex flex-wrap items-center gap-2", children: [
14054
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("span", { className: "text-destructive", children: [
14055
+ archiveConfirmSentence(`the field \u201C${f.label}\u201D`),
14056
+ " It is removed for everyone in this organization; its values stay in every record and come back with it."
14057
+ ] }),
14058
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
14059
+ import_design_system39.Button,
14060
+ {
14061
+ size: "sm",
14062
+ variant: "destructive",
14063
+ disabled: mutation.saving,
14064
+ onClick: async () => {
14065
+ const gone = await mutation.retire({ field_id: f.id });
14066
+ setRemoving(null);
14067
+ if (gone) {
14068
+ setDraft((d) => {
14069
+ const { [f.key]: _dropped, ...rest } = d;
14070
+ return rest;
14071
+ });
14072
+ read.reload();
14073
+ }
14074
+ },
14075
+ children: "Remove it"
14076
+ }
14077
+ ),
14078
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_design_system39.Button, { size: "sm", variant: "ghost", onClick: () => setRemoving(null), children: "Keep it" })
14079
+ ] }) : null,
13892
14080
  /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
13893
14081
  FieldControl,
13894
14082
  {
@@ -15541,10 +15729,10 @@ var import_design_system48 = require("@ai-matrx/design-system");
15541
15729
  // src/RecordForm.tsx
15542
15730
  var import_react86 = require("react");
15543
15731
  var import_react87 = require("@ai-matrx/records/react");
15544
- var import_core13 = require("@ai-matrx/records/core");
15732
+ var import_core14 = require("@ai-matrx/records/core");
15545
15733
 
15546
15734
  // src/writeOnTheWinningVersion.ts
15547
- var import_core12 = require("@ai-matrx/records/core");
15735
+ var import_core13 = require("@ai-matrx/records/core");
15548
15736
  function sameStoredValue(left, right) {
15549
15737
  if (left === right) return true;
15550
15738
  const empty = (v) => v === null || v === void 0 || v === "";
@@ -15566,7 +15754,7 @@ async function updateOnTheWinningVersion(client, recordId, patch, expectedVersio
15566
15754
  });
15567
15755
  const first = await send(expectedVersion);
15568
15756
  if (first.ok) return first;
15569
- const conflict = (0, import_core12.asWriteConflict)(first.error, recordId);
15757
+ const conflict = (0, import_core13.asWriteConflict)(first.error, recordId);
15570
15758
  if (!conflict) return first;
15571
15759
  const untouched = base === "always" || Object.keys(patch).every((key) => sameStoredValue(conflict.contested_fields[key], base[key]));
15572
15760
  if (!untouched) return first;
@@ -15803,7 +15991,7 @@ function RecordForm({
15803
15991
  return out;
15804
15992
  }, [draft]);
15805
15993
  const predicted = (0, import_react86.useMemo)(
15806
- () => fields.data ? (0, import_core13.predictWriteRefusals)({ fields: fields.data, document: document2, ...recordType ? { recordType } : {} }) : [],
15994
+ () => fields.data ? (0, import_core14.predictWriteRefusals)({ fields: fields.data, document: document2, ...recordType ? { recordType } : {} }) : [],
15807
15995
  [fields.data, document2, recordType]
15808
15996
  );
15809
15997
  if (fields.error) return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(RefusalNotice, { error: fields.error, className });
@@ -15852,7 +16040,7 @@ function RecordForm({
15852
16040
  setEdit({
15853
16041
  saving: false,
15854
16042
  error: answered2.ok ? null : answered2.error,
15855
- conflict: answered2.ok ? null : (0, import_core13.asWriteConflict)(answered2.error, recordId)
16043
+ conflict: answered2.ok ? null : (0, import_core14.asWriteConflict)(answered2.error, recordId)
15856
16044
  });
15857
16045
  const moved = answered2.ok ? answered2.data : null;
15858
16046
  if (moved !== null) {
@@ -15958,7 +16146,7 @@ function FieldRow({
15958
16146
  }) {
15959
16147
  const id = `field-${field2.id}`;
15960
16148
  const storedWords = document2?.[field2.key];
15961
- const whole = typeof storedWords === "string" ? (0, import_core13.wholeValueOf)(document2, field2.key) : null;
16149
+ const whole = typeof storedWords === "string" ? (0, import_core14.wholeValueOf)(document2, field2.key) : null;
15962
16150
  return /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: (0, import_design_system46.cn)("flex min-w-0 flex-col gap-1", whole && "sm:col-span-2"), children: [
15963
16151
  /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(FieldLabel, { field: field2, htmlFor: id, children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(ProvenanceBadge, { document: document2, fieldKey: field2.key }) }),
15964
16152
  whole ? (
@@ -24460,7 +24648,7 @@ function SignBlock({ tableId, recordId, render, className }) {
24460
24648
  var import_react144 = require("react");
24461
24649
  var import_recharts = require("recharts");
24462
24650
  var import_records24 = require("@ai-matrx/records");
24463
- var import_core14 = require("@ai-matrx/records/core");
24651
+ var import_core15 = require("@ai-matrx/records/core");
24464
24652
  var import_design_system74 = require("@ai-matrx/design-system");
24465
24653
  var import_jsx_runtime82 = require("react/jsx-runtime");
24466
24654
  var priorKey = (key) => `prior__${key}`;
@@ -24517,7 +24705,7 @@ function pretty(n) {
24517
24705
  return Number.isInteger(n) ? n.toLocaleString() : n.toLocaleString(void 0, { maximumFractionDigits: 2 });
24518
24706
  }
24519
24707
  function asRefusal2(block) {
24520
- return (0, import_core14.mapPgError)(
24708
+ return (0, import_core15.mapPgError)(
24521
24709
  {
24522
24710
  message: block.refused ?? "",
24523
24711
  ...block.sqlstate ? { code: block.sqlstate } : {}
@@ -27191,7 +27379,7 @@ function recordsDataSource(client, fallbackSchema = "custom") {
27191
27379
  // src/TablesHome.tsx
27192
27380
  var import_react170 = require("react");
27193
27381
  var import_react171 = require("@ai-matrx/records/react");
27194
- var import_core16 = require("@ai-matrx/records/core");
27382
+ var import_core17 = require("@ai-matrx/records/core");
27195
27383
  var import_records30 = require("@ai-matrx/records");
27196
27384
  var import_design_system86 = require("@ai-matrx/design-system");
27197
27385
 
@@ -27286,7 +27474,7 @@ function ExampleTables({
27286
27474
  }
27287
27475
 
27288
27476
  // src/createTable.ts
27289
- var import_core15 = require("@ai-matrx/records/core");
27477
+ var import_core16 = require("@ai-matrx/records/core");
27290
27478
 
27291
27479
  // src/WhereItLives.tsx
27292
27480
  var import_react168 = require("react");
@@ -27565,7 +27753,7 @@ function TablesHome({ onOpenTable, organizationName, makingOnly = false, classNa
27565
27753
  };
27566
27754
  }, [client]);
27567
27755
  const listed = facts.phase === "read" ? (0, import_records30.withTablePlacement)(
27568
- (0, import_core16.withTableFacts)(tables.data ?? [], facts.rows, me),
27756
+ (0, import_core17.withTableFacts)(tables.data ?? [], facts.rows, me),
27569
27757
  facts.rows
27570
27758
  ) : tables.data ?? [];
27571
27759
  const [showEverything, setShowEverything] = (0, import_react170.useState)(false);
@@ -27609,7 +27797,7 @@ function TablesHome({ onOpenTable, organizationName, makingOnly = false, classNa
27609
27797
  if (!trimmed) return;
27610
27798
  setBusy(true);
27611
27799
  setError(null);
27612
- const result = await (0, import_core15.declareTable)(client, { name: trimmed, slug: (0, import_core15.tokenFor)(trimmed) });
27800
+ const result = await (0, import_core16.declareTable)(client, { name: trimmed, slug: (0, import_core16.tokenFor)(trimmed) });
27613
27801
  setBusy(false);
27614
27802
  if (!result.ok) {
27615
27803
  setError(result.error);