@ai-matrx/records-ui 0.101.21 → 0.101.23

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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog — @ai-matrx/records-ui
2
2
 
3
+ ## 0.101.23
4
+
5
+ Automatic changed-only republish (docs/metadata drift since the last tag — see
6
+ `git diff npm/records-ui/v0.101.22..npm/records-ui/v0.101.23 -- apps/shared/records-ui`).
7
+ No source changes intended and no consumer action required.
8
+
9
+ ## 0.101.22
10
+
11
+ Automatic changed-only republish (docs/metadata drift since the last tag — see
12
+ `git diff npm/records-ui/v0.101.18..npm/records-ui/v0.101.22 -- apps/shared/records-ui`).
13
+ No source changes intended and no consumer action required.
14
+
3
15
  ## 0.101.21
4
16
 
5
17
  Automatic changed-only republish (docs/metadata drift since the last tag — see
package/dist/index.cjs CHANGED
@@ -12907,6 +12907,9 @@ function storedValueAgrees(field2, stored, written, options) {
12907
12907
  }
12908
12908
  return JSON.stringify(stored) === JSON.stringify(written);
12909
12909
  }
12910
+ function refusalsBeyondTheHeader(refusals, headerRowId) {
12911
+ return headerRowId === void 0 ? [...refusals] : refusals.filter((r) => r.rowId !== headerRowId);
12912
+ }
12910
12913
  function columnsTheGridTurnedAway(turnedAway, columnKeys, columnName, already) {
12911
12914
  const said = /* @__PURE__ */ new Map();
12912
12915
  for (const refused of turnedAway) {
@@ -14809,7 +14812,8 @@ function useDrillAnswers(args) {
14809
14812
  const groups = {};
14810
14813
  for (const ref of request.by) {
14811
14814
  const k = ref === time && t ? t.key : ref;
14812
- groups[ref] = row.groups[k] ?? null;
14815
+ const g = row.groups[k];
14816
+ groups[ref] = g === null || g === void 0 ? null : String(g);
14813
14817
  }
14814
14818
  return {
14815
14819
  groups,
@@ -21761,7 +21765,12 @@ function GridBody({
21761
21765
  ...headed ? { header: { unmatched: headed.unmatched } } : {}
21762
21766
  });
21763
21767
  built.refusals.push(
21764
- ...columnsTheGridTurnedAway(sheetPlan.refusals, columnKeys, (id) => columnLabel(fieldList, id), built.refusals)
21768
+ ...columnsTheGridTurnedAway(
21769
+ refusalsBeyondTheHeader(sheetPlan.refusals, headed ? touched[0] : void 0),
21770
+ columnKeys,
21771
+ (id) => columnLabel(fieldList, id),
21772
+ built.refusals
21773
+ )
21765
21774
  );
21766
21775
  if (merged && built.cells > 0 && built.creates === 0 && built.refusals.length === 0 && built.pastRightEdge === 0 && (built.header?.unmatched.length ?? 0) === 0 && built.unmatchedOptions.length === 0) {
21767
21776
  const outcome = await pasteAtOnce.current(built);
@@ -23267,7 +23276,8 @@ function useEntitySource(token, options = {}) {
23267
23276
  rows: [],
23268
23277
  total: 0,
23269
23278
  loading: true,
23270
- error: null
23279
+ error: null,
23280
+ creatable: false
23271
23281
  });
23272
23282
  (0, import_react114.useEffect)(() => {
23273
23283
  let cancelled = false;
@@ -23286,7 +23296,8 @@ function useEntitySource(token, options = {}) {
23286
23296
  rows: page.data.rows ?? [],
23287
23297
  total: Number(page.data.total ?? 0),
23288
23298
  loading: false,
23289
- error: null
23299
+ error: null,
23300
+ creatable: api?.create_via === "insert" && !!entityNameColumn(api?.columns ?? [])?.writable
23290
23301
  });
23291
23302
  },
23292
23303
  (thrown) => {
@@ -23313,7 +23324,24 @@ function useEntitySource(token, options = {}) {
23313
23324
  },
23314
23325
  [client, token, state.rows]
23315
23326
  );
23316
- return { ...state, write, reload };
23327
+ const create = (0, import_react114.useCallback)(
23328
+ async (columns) => {
23329
+ const done = await client.entityRowWrite({ token, record_id: null, columns });
23330
+ if (!done.ok) return { refused: refusalSentence(done.error) || "That row was not added." };
23331
+ setTick((t) => t + 1);
23332
+ return { id: String(done.data.id) };
23333
+ },
23334
+ [client, token]
23335
+ );
23336
+ return { ...state, write, create, reload };
23337
+ }
23338
+ var NAME_KEYS = ["name", "display_name", "title", "subject"];
23339
+ function entityNameColumn(columns) {
23340
+ for (const key of NAME_KEYS) {
23341
+ const hit = columns.find((c) => c.api_name === key);
23342
+ if (hit) return hit;
23343
+ }
23344
+ return columns.find((c) => c.type === "text" && !c.lookup) ?? columns[0] ?? null;
23317
23345
  }
23318
23346
  function entityTableColumns(columns) {
23319
23347
  return columns.map((c) => ({
@@ -39436,8 +39464,9 @@ function linkIdsOf(value) {
39436
39464
  return t ? [t] : [];
39437
39465
  }
39438
39466
  function groupLabel(groups, named) {
39439
- const parts = Object.entries(groups).map(([key, v]) => {
39440
- if (v === null || v === "") return "\u2014";
39467
+ const parts = Object.entries(groups).map(([key, raw]) => {
39468
+ if (raw === null || raw === void 0 || raw === "") return "\u2014";
39469
+ const v = String(raw);
39441
39470
  const name = named?.(key, v);
39442
39471
  if (name !== void 0) return name ?? "\u2014";
39443
39472
  const grain = BUCKET_SUFFIX.exec(key)?.[1];
@@ -41911,7 +41940,8 @@ function rowsOf2(rows, groupKey, keys) {
41911
41940
  }
41912
41941
  const withheld = {};
41913
41942
  for (const [name, notice] of Object.entries(r.withheld ?? {})) if (keys.includes(name)) withheld[name] = notice;
41914
- return { group: groupKey ? (r.groups ?? {})[groupKey] ?? null : null, values, withheld, n: Number(r.row_count ?? 0) };
41943
+ const g = groupKey ? (r.groups ?? {})[groupKey] : null;
41944
+ return { group: g === null || g === void 0 ? null : String(g), values, withheld, n: Number(r.row_count ?? 0) };
41915
41945
  });
41916
41946
  }
41917
41947
  function sortAndCut(rows, spec, keys) {
@@ -46982,14 +47012,7 @@ var import_react266 = require("react");
46982
47012
  var import_design_system138 = require("@ai-matrx/design-system");
46983
47013
  var import_react267 = require("@ai-matrx/records/react");
46984
47014
  var import_jsx_runtime153 = require("react/jsx-runtime");
46985
- var TITLE_KEYS = ["name", "display_name", "title", "subject"];
46986
- function entityTitleColumn(columns) {
46987
- for (const key of TITLE_KEYS) {
46988
- const hit = columns.find((c) => c.api_name === key);
46989
- if (hit) return hit;
46990
- }
46991
- return columns.find((c) => c.type === "text" && !c.lookup) ?? columns[0] ?? null;
46992
- }
47015
+ var entityTitleColumn = entityNameColumn;
46993
47016
  function entityChoiceColumns(columns) {
46994
47017
  return columns.filter((c) => c.type === "choice" && Array.isArray(c.choices) && c.choices.length > 0);
46995
47018
  }
@@ -47144,6 +47167,21 @@ function EntityTablePage({
47144
47167
  onLayoutChange?.(next);
47145
47168
  };
47146
47169
  const boardable = entityChoiceColumns(entity.columns).length > 0;
47170
+ const nameColumn = entityNameColumn(entity.columns);
47171
+ const [naming, setNaming] = (0, import_react266.useState)(null);
47172
+ const [adding, setAdding] = (0, import_react266.useState)(false);
47173
+ const [addRefused, setAddRefused] = (0, import_react266.useState)(null);
47174
+ const add = async () => {
47175
+ const name = (naming ?? "").trim();
47176
+ if (!name || !nameColumn || adding) return;
47177
+ setAdding(true);
47178
+ setAddRefused(null);
47179
+ const made = await entity.create({ [nameColumn.api_name]: name });
47180
+ setAdding(false);
47181
+ if ("refused" in made) return setAddRefused(made.refused);
47182
+ setNaming(null);
47183
+ onOpenRecord?.(made.id);
47184
+ };
47147
47185
  const [question, setQuestion] = (0, import_react266.useState)(() => questionFromGrouping(void 0));
47148
47186
  const { config: drill } = useDrill({
47149
47187
  source,
@@ -47154,7 +47192,7 @@ function EntityTablePage({
47154
47192
  enabled: layout === "grid"
47155
47193
  });
47156
47194
  return /* @__PURE__ */ (0, import_jsx_runtime153.jsxs)("div", { className: (0, import_design_system138.cn)("flex min-w-0 flex-col gap-2", className), "data-records-entity-page": source.token, children: [
47157
- presentation === "page" || boardable ? /* @__PURE__ */ (0, import_jsx_runtime153.jsxs)("div", { className: "flex min-w-0 items-center gap-2", children: [
47195
+ presentation === "page" || boardable || entity.creatable ? /* @__PURE__ */ (0, import_jsx_runtime153.jsxs)("div", { className: "flex min-w-0 items-center gap-2", children: [
47158
47196
  presentation === "page" ? /* @__PURE__ */ (0, import_jsx_runtime153.jsx)("h2", { className: "truncate text-base font-semibold", children: entity.label ?? (entity.loading ? "Loading\u2026" : "Table") }) : null,
47159
47197
  presentation === "page" ? /* @__PURE__ */ (0, import_jsx_runtime153.jsx)("span", { className: "text-xs tabular-nums text-muted-foreground", children: entity.loading ? "" : entity.total.toLocaleString() }) : null,
47160
47198
  /* @__PURE__ */ (0, import_jsx_runtime153.jsxs)("span", { className: "ml-auto flex items-center gap-1", children: [
@@ -47162,9 +47200,41 @@ function EntityTablePage({
47162
47200
  /* @__PURE__ */ (0, import_jsx_runtime153.jsx)(import_design_system138.Button, { size: "sm", variant: layout === "grid" ? "secondary" : "ghost", "aria-pressed": layout === "grid", onClick: () => choose("grid"), children: "Table" }),
47163
47201
  /* @__PURE__ */ (0, import_jsx_runtime153.jsx)(import_design_system138.Button, { size: "sm", variant: layout === "board" ? "secondary" : "ghost", "aria-pressed": layout === "board", onClick: () => choose("board"), children: "Board" })
47164
47202
  ] }) : null,
47203
+ entity.creatable && naming === null ? /* @__PURE__ */ (0, import_jsx_runtime153.jsx)(import_design_system138.Button, { size: "sm", variant: "ghost", onClick: () => {
47204
+ setAddRefused(null);
47205
+ setNaming("");
47206
+ }, children: "New page" }) : null,
47207
+ entity.creatable && naming !== null ? /* @__PURE__ */ (0, import_jsx_runtime153.jsx)(
47208
+ import_design_system138.Input,
47209
+ {
47210
+ autoFocus: true,
47211
+ "data-records-entity-new": source.token,
47212
+ "aria-label": nameColumn?.name ?? "Name",
47213
+ placeholder: nameColumn?.name ?? "Name",
47214
+ value: naming,
47215
+ disabled: adding,
47216
+ className: "h-7 w-56 text-xs",
47217
+ onChange: (e) => setNaming(e.target.value),
47218
+ onKeyDown: (e) => {
47219
+ if (e.key === "Enter") {
47220
+ e.preventDefault();
47221
+ void add();
47222
+ }
47223
+ if (e.key === "Escape") {
47224
+ e.preventDefault();
47225
+ setNaming(null);
47226
+ setAddRefused(null);
47227
+ }
47228
+ },
47229
+ onBlur: () => {
47230
+ if (!adding && !(naming ?? "").trim()) setNaming(null);
47231
+ }
47232
+ }
47233
+ ) : null,
47165
47234
  actions
47166
47235
  ] })
47167
47236
  ] }) : null,
47237
+ addRefused ? /* @__PURE__ */ (0, import_jsx_runtime153.jsx)(import_design_system138.ErrorBox, { className: "rounded border border-destructive/40 px-1.5 py-1 text-xs text-destructive", message: addRefused, operation: "Add a row", origin: "records-ui/entityViews" }) : null,
47168
47238
  entity.error ? /* @__PURE__ */ (0, import_jsx_runtime153.jsx)("p", { className: "px-1 py-3 text-xs text-muted-foreground", children: `This table could not be read: ${entity.error}` }) : layout === "board" && boardable ? /* @__PURE__ */ (0, import_jsx_runtime153.jsx)(EntityBoard, { entity, groupBy, onOpenRecord }) : /* @__PURE__ */ (0, import_jsx_runtime153.jsx)(EntityGrid, { entity, pageSize, ...drill ? { drill } : {} })
47169
47239
  ] });
47170
47240
  }