@ai-matrx/records-ui 0.101.21 → 0.101.22

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,11 @@
1
1
  # Changelog — @ai-matrx/records-ui
2
2
 
3
+ ## 0.101.22
4
+
5
+ Automatic changed-only republish (docs/metadata drift since the last tag — see
6
+ `git diff npm/records-ui/v0.101.18..npm/records-ui/v0.101.22 -- apps/shared/records-ui`).
7
+ No source changes intended and no consumer action required.
8
+
3
9
  ## 0.101.21
4
10
 
5
11
  Automatic changed-only republish (docs/metadata drift since the last tag — see
package/dist/index.cjs CHANGED
@@ -14809,7 +14809,8 @@ function useDrillAnswers(args) {
14809
14809
  const groups = {};
14810
14810
  for (const ref of request.by) {
14811
14811
  const k = ref === time && t ? t.key : ref;
14812
- groups[ref] = row.groups[k] ?? null;
14812
+ const g = row.groups[k];
14813
+ groups[ref] = g === null || g === void 0 ? null : String(g);
14813
14814
  }
14814
14815
  return {
14815
14816
  groups,
@@ -23267,7 +23268,8 @@ function useEntitySource(token, options = {}) {
23267
23268
  rows: [],
23268
23269
  total: 0,
23269
23270
  loading: true,
23270
- error: null
23271
+ error: null,
23272
+ creatable: false
23271
23273
  });
23272
23274
  (0, import_react114.useEffect)(() => {
23273
23275
  let cancelled = false;
@@ -23286,7 +23288,8 @@ function useEntitySource(token, options = {}) {
23286
23288
  rows: page.data.rows ?? [],
23287
23289
  total: Number(page.data.total ?? 0),
23288
23290
  loading: false,
23289
- error: null
23291
+ error: null,
23292
+ creatable: api?.create_via === "insert" && !!entityNameColumn(api?.columns ?? [])?.writable
23290
23293
  });
23291
23294
  },
23292
23295
  (thrown) => {
@@ -23313,7 +23316,24 @@ function useEntitySource(token, options = {}) {
23313
23316
  },
23314
23317
  [client, token, state.rows]
23315
23318
  );
23316
- return { ...state, write, reload };
23319
+ const create = (0, import_react114.useCallback)(
23320
+ async (columns) => {
23321
+ const done = await client.entityRowWrite({ token, record_id: null, columns });
23322
+ if (!done.ok) return { refused: refusalSentence(done.error) || "That row was not added." };
23323
+ setTick((t) => t + 1);
23324
+ return { id: String(done.data.id) };
23325
+ },
23326
+ [client, token]
23327
+ );
23328
+ return { ...state, write, create, reload };
23329
+ }
23330
+ var NAME_KEYS = ["name", "display_name", "title", "subject"];
23331
+ function entityNameColumn(columns) {
23332
+ for (const key of NAME_KEYS) {
23333
+ const hit = columns.find((c) => c.api_name === key);
23334
+ if (hit) return hit;
23335
+ }
23336
+ return columns.find((c) => c.type === "text" && !c.lookup) ?? columns[0] ?? null;
23317
23337
  }
23318
23338
  function entityTableColumns(columns) {
23319
23339
  return columns.map((c) => ({
@@ -39436,8 +39456,9 @@ function linkIdsOf(value) {
39436
39456
  return t ? [t] : [];
39437
39457
  }
39438
39458
  function groupLabel(groups, named) {
39439
- const parts = Object.entries(groups).map(([key, v]) => {
39440
- if (v === null || v === "") return "\u2014";
39459
+ const parts = Object.entries(groups).map(([key, raw]) => {
39460
+ if (raw === null || raw === void 0 || raw === "") return "\u2014";
39461
+ const v = String(raw);
39441
39462
  const name = named?.(key, v);
39442
39463
  if (name !== void 0) return name ?? "\u2014";
39443
39464
  const grain = BUCKET_SUFFIX.exec(key)?.[1];
@@ -41911,7 +41932,8 @@ function rowsOf2(rows, groupKey, keys) {
41911
41932
  }
41912
41933
  const withheld = {};
41913
41934
  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) };
41935
+ const g = groupKey ? (r.groups ?? {})[groupKey] : null;
41936
+ return { group: g === null || g === void 0 ? null : String(g), values, withheld, n: Number(r.row_count ?? 0) };
41915
41937
  });
41916
41938
  }
41917
41939
  function sortAndCut(rows, spec, keys) {
@@ -46982,14 +47004,7 @@ var import_react266 = require("react");
46982
47004
  var import_design_system138 = require("@ai-matrx/design-system");
46983
47005
  var import_react267 = require("@ai-matrx/records/react");
46984
47006
  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
- }
47007
+ var entityTitleColumn = entityNameColumn;
46993
47008
  function entityChoiceColumns(columns) {
46994
47009
  return columns.filter((c) => c.type === "choice" && Array.isArray(c.choices) && c.choices.length > 0);
46995
47010
  }
@@ -47144,6 +47159,21 @@ function EntityTablePage({
47144
47159
  onLayoutChange?.(next);
47145
47160
  };
47146
47161
  const boardable = entityChoiceColumns(entity.columns).length > 0;
47162
+ const nameColumn = entityNameColumn(entity.columns);
47163
+ const [naming, setNaming] = (0, import_react266.useState)(null);
47164
+ const [adding, setAdding] = (0, import_react266.useState)(false);
47165
+ const [addRefused, setAddRefused] = (0, import_react266.useState)(null);
47166
+ const add = async () => {
47167
+ const name = (naming ?? "").trim();
47168
+ if (!name || !nameColumn || adding) return;
47169
+ setAdding(true);
47170
+ setAddRefused(null);
47171
+ const made = await entity.create({ [nameColumn.api_name]: name });
47172
+ setAdding(false);
47173
+ if ("refused" in made) return setAddRefused(made.refused);
47174
+ setNaming(null);
47175
+ onOpenRecord?.(made.id);
47176
+ };
47147
47177
  const [question, setQuestion] = (0, import_react266.useState)(() => questionFromGrouping(void 0));
47148
47178
  const { config: drill } = useDrill({
47149
47179
  source,
@@ -47154,7 +47184,7 @@ function EntityTablePage({
47154
47184
  enabled: layout === "grid"
47155
47185
  });
47156
47186
  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: [
47187
+ presentation === "page" || boardable || entity.creatable ? /* @__PURE__ */ (0, import_jsx_runtime153.jsxs)("div", { className: "flex min-w-0 items-center gap-2", children: [
47158
47188
  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
47189
  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
47190
  /* @__PURE__ */ (0, import_jsx_runtime153.jsxs)("span", { className: "ml-auto flex items-center gap-1", children: [
@@ -47162,9 +47192,41 @@ function EntityTablePage({
47162
47192
  /* @__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
47193
  /* @__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
47194
  ] }) : null,
47195
+ entity.creatable && naming === null ? /* @__PURE__ */ (0, import_jsx_runtime153.jsx)(import_design_system138.Button, { size: "sm", variant: "ghost", onClick: () => {
47196
+ setAddRefused(null);
47197
+ setNaming("");
47198
+ }, children: "New page" }) : null,
47199
+ entity.creatable && naming !== null ? /* @__PURE__ */ (0, import_jsx_runtime153.jsx)(
47200
+ import_design_system138.Input,
47201
+ {
47202
+ autoFocus: true,
47203
+ "data-records-entity-new": source.token,
47204
+ "aria-label": nameColumn?.name ?? "Name",
47205
+ placeholder: nameColumn?.name ?? "Name",
47206
+ value: naming,
47207
+ disabled: adding,
47208
+ className: "h-7 w-56 text-xs",
47209
+ onChange: (e) => setNaming(e.target.value),
47210
+ onKeyDown: (e) => {
47211
+ if (e.key === "Enter") {
47212
+ e.preventDefault();
47213
+ void add();
47214
+ }
47215
+ if (e.key === "Escape") {
47216
+ e.preventDefault();
47217
+ setNaming(null);
47218
+ setAddRefused(null);
47219
+ }
47220
+ },
47221
+ onBlur: () => {
47222
+ if (!adding && !(naming ?? "").trim()) setNaming(null);
47223
+ }
47224
+ }
47225
+ ) : null,
47165
47226
  actions
47166
47227
  ] })
47167
47228
  ] }) : null,
47229
+ 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
47230
  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
47231
  ] });
47170
47232
  }