@ai-matrx/records-ui 0.95.4 → 0.95.10

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/pickers.cjs CHANGED
@@ -751,7 +751,12 @@ var REMEDY = {
751
751
  unreachable: "Nothing was changed. Check your connection and open this again.",
752
752
  needs_approval: "Nothing was changed yet. The people who can approve it have been asked.",
753
753
  stale_read: "Open this again in a moment and it will be up to date.",
754
- timed_out: "Nothing was changed. Try a smaller page, or try again in a moment.",
754
+ // 🚨 ONE REMEDY THAT IS TRUE OF EVERY DOOR (lane CHAIR-STORE-PERF, 2026-10-03). The store cancels the
755
+ // WHOLE statement at its clock, so a timed-out door wrote nothing — a create, a column add and a page
756
+ // read alike. "Try a smaller page" was written for the page read and was printed to a person adding
757
+ // one row to a three-row table (clone walk, 2026-10-03; the clock was a lock another lane's
758
+ // rehearsal held, not the row). A door whose page can shrink says so in its own hint, which wins here.
759
+ timed_out: "Nothing was changed. Try again in a moment.",
755
760
  internal: "Nothing you did caused this. Try again, and tell us if it keeps happening."
756
761
  };
757
762
  var ENGINEER_TEXT = [
@@ -995,7 +1000,7 @@ var import_jsx_runtime4 = (
995
1000
  require("react/jsx-runtime")
996
1001
  );
997
1002
  var NO_STORE_ON_THIS_SCREEN_REASON = "This question points at a record in somebody's own data, and a page answered without an account is never allowed to search that. Leave it blank \u2014 whoever receives your answer will fill it in.";
998
- function RelationPicker({ field, value, onChange, disabled, id, className, allowCreate = true }) {
1003
+ function RelationPicker({ field, value, onChange, disabled, id, className, allowCreate = true, onPicked }) {
999
1004
  const client = (0, import_react4.useOptionalRecordsClient)();
1000
1005
  const [rows, setRows] = (0, import_react3.useState)(null);
1001
1006
  const [words, setWords] = (0, import_react3.useState)({});
@@ -1083,8 +1088,10 @@ function RelationPicker({ field, value, onChange, disabled, id, className, allow
1083
1088
  const full = field.multi && field.relation_max !== null && picked.length >= field.relation_max;
1084
1089
  const toggle = (recordId) => {
1085
1090
  if (!field.multi) {
1086
- onChange(picked[0] === recordId ? null : recordId);
1091
+ const choosing = picked[0] !== recordId;
1092
+ onChange(choosing ? recordId : null);
1087
1093
  setOpen(false);
1094
+ if (choosing && onPicked) setTimeout(onPicked, 0);
1088
1095
  return;
1089
1096
  }
1090
1097
  const next = new Set(picked);
@@ -3308,7 +3315,7 @@ function FieldControl({ field, value, onChange, disabled, id, autoOpen, onClose,
3308
3315
  }
3309
3316
  return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(RelationPicker, { field, value, onChange, disabled, id: inputId });
3310
3317
  case "relation":
3311
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(RelationPicker, { field, value, onChange, disabled, id: inputId });
3318
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(RelationPicker, { field, value, onChange, disabled, id: inputId, onPicked: onCommit });
3312
3319
  default:
3313
3320
  if (typeof value === "boolean" || field.config?.["kind"] === "boolean") {
3314
3321
  return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
@@ -3970,20 +3977,40 @@ function TablePicker({ dataSource, value, onChange, disabled, tables }) {
3970
3977
  const options = tablePickerEntries(
3971
3978
  list.rows.map((t) => ({ ...t, id: t.table_id, name: t.table_name })),
3972
3979
  { keep: value }
3973
- ).entries.map(({ table: t }) => ({
3974
- value: t.table_id,
3975
- // The organization hint already tells two same-named tables apart across organizations.
3976
- label: t.table_name,
3977
- hint: t.organization_name,
3978
- keywords: t.organization_name
3979
- }));
3980
+ ).entries.map(({ table: t }) => t);
3981
+ const sameName = /* @__PURE__ */ new Map();
3982
+ for (const t of options) {
3983
+ const key = `${t.organization_id}|${t.table_name.trim().toLowerCase()}`;
3984
+ sameName.set(key, (sameName.get(key) ?? 0) + 1);
3985
+ }
3986
+ const pickerOptions = options.map((t) => {
3987
+ const twin = (sameName.get(`${t.organization_id}|${t.table_name.trim().toLowerCase()}`) ?? 0) > 1;
3988
+ const row = t;
3989
+ const second = [
3990
+ row.created_by_name ? `by ${row.created_by_name}` : null,
3991
+ row.updated_at ? `changed ${new Date(row.updated_at).toLocaleDateString()}` : null
3992
+ ].filter(Boolean).join(" \xB7 ");
3993
+ return {
3994
+ value: t.table_id,
3995
+ // The organization hint already tells two same-named tables apart across organizations.
3996
+ label: t.table_name,
3997
+ hint: t.organization_name,
3998
+ keywords: t.organization_name,
3999
+ ...twin && second ? {
4000
+ render: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { className: "flex min-w-0 flex-col", children: [
4001
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "truncate", children: t.table_name }),
4002
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "truncate text-[11px] text-muted-foreground", children: second })
4003
+ ] })
4004
+ } : {}
4005
+ };
4006
+ });
3980
4007
  const missing = Boolean(value) && !list.loading && !list.error && !list.rows.some((t) => t.table_id === value);
3981
4008
  return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex flex-col gap-1", children: [
3982
4009
  /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3983
4010
  import_design_system16.CreatablePicker,
3984
4011
  {
3985
4012
  value: value || null,
3986
- options,
4013
+ options: pickerOptions,
3987
4014
  onSelect: onChange,
3988
4015
  placeholder: missing ? "Table not available" : "Choose a table",
3989
4016
  searchPlaceholder: "Search tables",
@@ -4505,7 +4532,7 @@ function referencesOf(field, value, kind, labels) {
4505
4532
  }));
4506
4533
  }
4507
4534
  var ARCHIVED_REFERENCE_WORD = "Archived";
4508
- var ARCHIVED_REFERENCE_TIP = "In Trash; restore it to use it again";
4535
+ var ARCHIVED_REFERENCE_TIP = "In the Archived view; restore it to use it again";
4509
4536
  function ReferenceChip({ reference, waiting }) {
4510
4537
  const host = useRecordsUi();
4511
4538
  const words = reference.label ?? (reference.token === "record" ? waiting ?? "Loading\u2026" : WITHHELD_ENTITY_LABEL);