@ai-matrx/records-ui 0.104.2 → 0.105.1
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 +36 -0
- package/dist/index.cjs +84 -55
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +70 -41
- package/dist/index.js.map +1 -1
- package/dist/object-actions.cjs +10 -3
- package/dist/object-actions.cjs.map +1 -1
- package/dist/object-actions.d.cts +1 -1
- package/dist/object-actions.d.ts +1 -1
- package/dist/object-actions.js +10 -3
- package/dist/object-actions.js.map +1 -1
- package/dist/{objectActions-XkhxU-DP.d.cts → objectActions-B7AUBkcl.d.cts} +3 -1
- package/dist/{objectActions-XkhxU-DP.d.ts → objectActions-B7AUBkcl.d.ts} +3 -1
- package/dist/pickers.cjs +9 -2
- package/dist/pickers.cjs.map +1 -1
- package/dist/pickers.js +9 -2
- package/dist/pickers.js.map +1 -1
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,41 @@
|
|
|
1
1
|
# Changelog — @ai-matrx/records-ui
|
|
2
2
|
|
|
3
|
+
## 0.105.1
|
|
4
|
+
|
|
5
|
+
Automatic changed-only republish (docs/metadata drift since the last tag — see
|
|
6
|
+
`git diff npm/records-ui/v0.104.2..npm/records-ui/v0.105.1 -- apps/shared/records-ui`).
|
|
7
|
+
No source changes intended and no consumer action required.
|
|
8
|
+
|
|
9
|
+
## 0.105.0
|
|
10
|
+
|
|
11
|
+
PAGE-BUNDLE: `recordsDataSource` marks itself `opensInOneCall`, so every table page (grid, board, record page, embedded table) opens its shape with one `custom.table_page_bundle` call through @ai-matrx/records 0.78. The `clinicStore` test kit can model the bundle (`bundle: true`); `a-table-opens-in-one-call.test.tsx` fails if a shape door is asked beside the bundle.
|
|
12
|
+
|
|
13
|
+
**Consumer action:** none.
|
|
14
|
+
|
|
15
|
+
## 0.104.5
|
|
16
|
+
|
|
17
|
+
Automatic changed-only republish (docs/metadata drift since the last tag — see
|
|
18
|
+
`git diff npm/records-ui/v0.104.2..npm/records-ui/v0.104.5 -- apps/shared/records-ui`).
|
|
19
|
+
No source changes intended and no consumer action required.
|
|
20
|
+
|
|
21
|
+
## 0.104.4
|
|
22
|
+
|
|
23
|
+
Table-duplicate progress, entity list totals and the export row-cap note format counts through `@ai-matrx/kit/format` `formatCount` (same digits; the export note keeps en-US). Package-twins collapse.
|
|
24
|
+
|
|
25
|
+
Consumer action: none.
|
|
26
|
+
|
|
27
|
+
## 0.104.3
|
|
28
|
+
|
|
29
|
+
Automatic changed-only republish (docs/metadata drift since the last tag — see
|
|
30
|
+
`git diff npm/records-ui/v0.104.2..npm/records-ui/v0.104.3 -- apps/shared/records-ui`).
|
|
31
|
+
No source changes intended and no consumer action required.
|
|
32
|
+
|
|
33
|
+
## 0.104.5
|
|
34
|
+
|
|
35
|
+
- `FormResultsPanel`: the four numbers are plain tiles (no "from 1 record" caption, the rate as a percentage); only choice, checkbox and number questions get an answer chart — free-text questions list their answers. Real-browser walk `demo/typeform-walk.mjs` (welcome, jump, ending, results; desktop and phone) joins `pnpm test:layout`.
|
|
36
|
+
|
|
37
|
+
**Consumer action:** none.
|
|
38
|
+
|
|
3
39
|
## 0.104.2
|
|
4
40
|
|
|
5
41
|
- (0.104.1 never reached npm: its gate found native selects in `FormFlowEditor` — now the package's `PickOne` — and the owner's-preview test still stubbing `form_preview_asks`; it now stubs `form_preview_route`.)
|
package/dist/index.cjs
CHANGED
|
@@ -619,6 +619,7 @@ var import_records = require("@ai-matrx/records");
|
|
|
619
619
|
var LEVEL_WORD = {
|
|
620
620
|
viewer: "Viewer",
|
|
621
621
|
commenter: "Commenter",
|
|
622
|
+
edit_content: "Content editor",
|
|
622
623
|
editor: "Editor",
|
|
623
624
|
admin: "Admin"
|
|
624
625
|
};
|
|
@@ -626,8 +627,12 @@ var NEEDS = {
|
|
|
626
627
|
read: "viewer",
|
|
627
628
|
// custom.io_comment_write
|
|
628
629
|
comment: "commenter",
|
|
629
|
-
// custom.record_update / custom.record_write
|
|
630
|
-
|
|
630
|
+
// custom.record_update / custom.record_write — `edit_content` changes rows and page content;
|
|
631
|
+
// columns, views and settings (structure) stay with admin below, and sharing with admin.
|
|
632
|
+
write: "edit_content",
|
|
633
|
+
// custom.view_designate / view_declare / migrate_merge / record_restore — all ask `editor`: more than
|
|
634
|
+
// changing content (`edit_content`), less than changing columns (`admin`).
|
|
635
|
+
organise: "editor",
|
|
631
636
|
// custom.record_delete
|
|
632
637
|
remove: "editor",
|
|
633
638
|
// custom.share_grant — passing your access on is an administrator's right
|
|
@@ -648,6 +653,7 @@ function sentenceFor(what, level) {
|
|
|
648
653
|
read: "open this",
|
|
649
654
|
comment: "leave a comment",
|
|
650
655
|
write: "change anything here",
|
|
656
|
+
organise: "organise this",
|
|
651
657
|
remove: "delete this",
|
|
652
658
|
share: "pass this on to somebody else",
|
|
653
659
|
structure: "change the columns of this table"
|
|
@@ -662,6 +668,7 @@ function whatYouMayDo(level, known = true) {
|
|
|
662
668
|
read: may("read"),
|
|
663
669
|
comment: may("comment"),
|
|
664
670
|
write: may("write"),
|
|
671
|
+
organise: may("organise"),
|
|
665
672
|
remove: may("remove"),
|
|
666
673
|
share: may("share"),
|
|
667
674
|
structure: may("structure"),
|
|
@@ -25057,6 +25064,7 @@ function createEntityRealtime(options = {}) {
|
|
|
25057
25064
|
}
|
|
25058
25065
|
|
|
25059
25066
|
// ../entity-data/src/port/port.ts
|
|
25067
|
+
var import_uuid3 = require("@ai-matrx/kit/uuid");
|
|
25060
25068
|
var import_records38 = require("@ai-matrx/records");
|
|
25061
25069
|
|
|
25062
25070
|
// ../entity-data/src/core/wire.ts
|
|
@@ -25157,8 +25165,6 @@ function toColumns(wire) {
|
|
|
25157
25165
|
}
|
|
25158
25166
|
|
|
25159
25167
|
// ../entity-data/src/port/port.ts
|
|
25160
|
-
var UUID_SHAPE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
25161
|
-
var isUuidShape3 = (value) => typeof value === "string" && UUID_SHAPE.test(value);
|
|
25162
25168
|
function toWireValue(value) {
|
|
25163
25169
|
if (isRef(value)) return value.id;
|
|
25164
25170
|
if (Array.isArray(value) && value.length > 0 && value.every(isRef)) {
|
|
@@ -25358,7 +25364,7 @@ function createEntityDataPort(options) {
|
|
|
25358
25364
|
async get(alias, id) {
|
|
25359
25365
|
const binding = bindingOf(alias);
|
|
25360
25366
|
if (!binding) return noSuchAlias(alias);
|
|
25361
|
-
if (!
|
|
25367
|
+
if (!(0, import_uuid3.isUuidShape)(id)) return refusal2("invalid_argument", `"${String(id)}" is not a row id.`);
|
|
25362
25368
|
return getCoalesced(alias, binding.token, id);
|
|
25363
25369
|
},
|
|
25364
25370
|
async create(alias, values) {
|
|
@@ -25378,20 +25384,20 @@ function createEntityDataPort(options) {
|
|
|
25378
25384
|
async update(alias, id, patch, baseVersion) {
|
|
25379
25385
|
const binding = bindingOf(alias);
|
|
25380
25386
|
if (!binding) return noSuchAlias(alias);
|
|
25381
|
-
if (!
|
|
25387
|
+
if (!(0, import_uuid3.isUuidShape)(id)) return refusal2("invalid_argument", `"${String(id)}" is not a row id.`);
|
|
25382
25388
|
const answer = await client.update({ token: binding.token, id, baseVersion, patch: toWireValues(patch), opId: (0, import_records38.mintOpId)() });
|
|
25383
25389
|
return readBack(alias, answer, "The change");
|
|
25384
25390
|
},
|
|
25385
25391
|
async archive(alias, id) {
|
|
25386
25392
|
const binding = bindingOf(alias);
|
|
25387
25393
|
if (!binding) return noSuchAlias(alias);
|
|
25388
|
-
if (!
|
|
25394
|
+
if (!(0, import_uuid3.isUuidShape)(id)) return refusal2("invalid_argument", `"${String(id)}" is not a row id.`);
|
|
25389
25395
|
return done(await client.archive({ token: binding.token, ids: [id], opId: (0, import_records38.mintOpId)() }));
|
|
25390
25396
|
},
|
|
25391
25397
|
async restore(alias, id) {
|
|
25392
25398
|
const binding = bindingOf(alias);
|
|
25393
25399
|
if (!binding) return noSuchAlias(alias);
|
|
25394
|
-
if (!
|
|
25400
|
+
if (!(0, import_uuid3.isUuidShape)(id)) return refusal2("invalid_argument", `"${String(id)}" is not a row id.`);
|
|
25395
25401
|
return done(await client.unarchive({ token: binding.token, ids: [id], opId: (0, import_records38.mintOpId)() }));
|
|
25396
25402
|
},
|
|
25397
25403
|
subscribe(event, listener) {
|
|
@@ -25757,6 +25763,7 @@ var import_react128 = require("@ai-matrx/records/react");
|
|
|
25757
25763
|
var import_core19 = require("@ai-matrx/records/core");
|
|
25758
25764
|
|
|
25759
25765
|
// src/viewExport.ts
|
|
25766
|
+
var import_format5 = require("@ai-matrx/kit/format");
|
|
25760
25767
|
var VIEW_EXPORT_PAGE = 500;
|
|
25761
25768
|
var VIEW_EXPORT_CEILING = 5e3;
|
|
25762
25769
|
function viewColumns(fields, presentation) {
|
|
@@ -25795,7 +25802,7 @@ async function readViewRows(client, tableId, fields, view, ceiling = VIEW_EXPORT
|
|
|
25795
25802
|
}
|
|
25796
25803
|
}
|
|
25797
25804
|
function cutWords(written) {
|
|
25798
|
-
return `First ${
|
|
25805
|
+
return `First ${(0, import_format5.formatCount)(written, { locale: "en-US" })} rows only`;
|
|
25799
25806
|
}
|
|
25800
25807
|
|
|
25801
25808
|
// src/ExportMenu.tsx
|
|
@@ -26245,7 +26252,7 @@ var import_clipboard3 = require("@ai-matrx/kit/clipboard");
|
|
|
26245
26252
|
var import_design_system66 = require("@ai-matrx/design-system");
|
|
26246
26253
|
var import_react133 = require("react");
|
|
26247
26254
|
var import_react134 = require("@ai-matrx/records/react");
|
|
26248
|
-
var
|
|
26255
|
+
var import_format6 = require("@ai-matrx/kit/format");
|
|
26249
26256
|
var import_records39 = require("@ai-matrx/records");
|
|
26250
26257
|
var import_design_system67 = require("@ai-matrx/design-system");
|
|
26251
26258
|
|
|
@@ -26582,7 +26589,7 @@ function BookingBuilder({ tableId, bookingId, onSaved, onClose, startNew, classN
|
|
|
26582
26589
|
className: "h-9 rounded border bg-background px-2 text-sm",
|
|
26583
26590
|
value: lead,
|
|
26584
26591
|
onChange: (e) => setLead(Number(e.target.value)),
|
|
26585
|
-
children: [0, 60, 120, 240, 1440].map((n) => /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("option", { value: n, children: n === 0 ? "Right away" : n === 1440 ? "A day from now" : `${(0,
|
|
26592
|
+
children: [0, 60, 120, 240, 1440].map((n) => /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("option", { value: n, children: n === 0 ? "Right away" : n === 1440 ? "A day from now" : `${(0, import_format6.formatDurationMinutes)(n, { style: "long" })} from now` }, n))
|
|
26586
26593
|
}
|
|
26587
26594
|
)
|
|
26588
26595
|
] }),
|
|
@@ -26935,7 +26942,7 @@ function tableActions(input) {
|
|
|
26935
26942
|
// custom.view_designate asks editor on the table — `canDesignate` in TablePage.
|
|
26936
26943
|
action(
|
|
26937
26944
|
{ id: "make-default", label: makeDefaultWords(host.layoutLabel), icon: "layout-grid", group: "manage", rank: 4 },
|
|
26938
|
-
"
|
|
26945
|
+
"organise",
|
|
26939
26946
|
input,
|
|
26940
26947
|
bind(host.makeDefault, table)
|
|
26941
26948
|
),
|
|
@@ -28114,7 +28121,7 @@ function SaveToTable({ source, shapeIndex = 0, onOpenTable, onSaved, onClose, cl
|
|
|
28114
28121
|
const levels = (0, import_react144.useMyLevels)(own3.map((t) => t.id));
|
|
28115
28122
|
const writable = own3.filter((t) => {
|
|
28116
28123
|
const level = levels.data?.[t.id];
|
|
28117
|
-
return level === "editor" || level === "admin";
|
|
28124
|
+
return level === "edit_content" || level === "editor" || level === "admin";
|
|
28118
28125
|
}).sort((a, b) => a.name.localeCompare(b.name));
|
|
28119
28126
|
const [tableId, setTableId] = (0, import_react143.useState)("");
|
|
28120
28127
|
const proposedName = shape?.name ?? source.title ?? "Saved table";
|
|
@@ -30458,7 +30465,7 @@ var import_react188 = require("@ai-matrx/records/react");
|
|
|
30458
30465
|
var import_records47 = require("@ai-matrx/records");
|
|
30459
30466
|
var import_design_system93 = require("@ai-matrx/design-system");
|
|
30460
30467
|
var import_data_table20 = require("@ai-matrx/design-system/data-table");
|
|
30461
|
-
var
|
|
30468
|
+
var import_format7 = require("@ai-matrx/kit/format");
|
|
30462
30469
|
|
|
30463
30470
|
// src/recordMoves.tsx
|
|
30464
30471
|
var import_react171 = require("react");
|
|
@@ -30695,10 +30702,10 @@ function recordActions(input) {
|
|
|
30695
30702
|
input,
|
|
30696
30703
|
copyText13 ? () => copyText13(url, record) : void 0
|
|
30697
30704
|
),
|
|
30698
|
-
action2({ id: "duplicate", label: "Duplicate", icon: "copy", group: "organize", verb: "duplicate" }, "
|
|
30705
|
+
action2({ id: "duplicate", label: "Duplicate", icon: "copy", group: "organize", verb: "duplicate" }, "organise", input, bind2(host.duplicate, record)),
|
|
30699
30706
|
action2(
|
|
30700
30707
|
{ id: "merge", label: "Merge with\u2026", icon: "git-merge", group: "organize" },
|
|
30701
|
-
"
|
|
30708
|
+
"organise",
|
|
30702
30709
|
input,
|
|
30703
30710
|
bind2(host.merge, record)
|
|
30704
30711
|
),
|
|
@@ -34333,9 +34340,9 @@ function ViewPager({ shown: shown4, total, onMore, step: step2 }) {
|
|
|
34333
34340
|
return /* @__PURE__ */ (0, import_jsx_runtime109.jsxs)("p", { className: "flex items-center gap-2 text-xs text-muted-foreground", "data-view-pager": "", children: [
|
|
34334
34341
|
/* @__PURE__ */ (0, import_jsx_runtime109.jsxs)("span", { children: [
|
|
34335
34342
|
"Showing ",
|
|
34336
|
-
(0,
|
|
34343
|
+
(0, import_format7.formatCount)(shown4),
|
|
34337
34344
|
" of ",
|
|
34338
|
-
(0,
|
|
34345
|
+
(0, import_format7.formatCount)(total),
|
|
34339
34346
|
" records."
|
|
34340
34347
|
] }),
|
|
34341
34348
|
/* @__PURE__ */ (0, import_jsx_runtime109.jsxs)(import_design_system93.Button, { size: "sm", variant: "outline", onClick: onMore, children: [
|
|
@@ -34805,8 +34812,8 @@ function ArchivedView({
|
|
|
34805
34812
|
onRestored?.(recordId);
|
|
34806
34813
|
};
|
|
34807
34814
|
const titleKey = table.data?.title_field ?? null;
|
|
34808
|
-
const mayRestore = rights.
|
|
34809
|
-
const whyNot = mayRestore ? "" : mayNotRestoreLine(rights.why("
|
|
34815
|
+
const mayRestore = rights.organise;
|
|
34816
|
+
const whyNot = mayRestore ? "" : mayNotRestoreLine(rights.why("organise"));
|
|
34810
34817
|
return /* @__PURE__ */ (0, import_jsx_runtime110.jsxs)("div", { className: (0, import_design_system94.cn)("flex min-h-0 flex-col gap-2", className), "data-testid": "archived-view", children: [
|
|
34811
34818
|
/* @__PURE__ */ (0, import_jsx_runtime110.jsxs)("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
34812
34819
|
/* @__PURE__ */ (0, import_jsx_runtime110.jsx)("span", { className: "text-sm font-medium", children: "Archived" }),
|
|
@@ -35548,7 +35555,7 @@ var import_react201 = require("react");
|
|
|
35548
35555
|
var import_react202 = require("@ai-matrx/records/react");
|
|
35549
35556
|
var import_design_system99 = require("@ai-matrx/design-system");
|
|
35550
35557
|
var import_data_table21 = require("@ai-matrx/design-system/data-table");
|
|
35551
|
-
var
|
|
35558
|
+
var import_format8 = require("@ai-matrx/kit/format");
|
|
35552
35559
|
|
|
35553
35560
|
// src/ChecklistRunner.tsx
|
|
35554
35561
|
var import_react199 = require("react");
|
|
@@ -36928,7 +36935,7 @@ function ActionInbox({
|
|
|
36928
36935
|
size: "sm",
|
|
36929
36936
|
variant: "ghost",
|
|
36930
36937
|
className: "h-6 px-2 text-[11px]",
|
|
36931
|
-
title: (0,
|
|
36938
|
+
title: (0, import_format8.formatAbsoluteDate)(c.until),
|
|
36932
36939
|
onClick: () => void snooze(item.item_id, item.title, c.until),
|
|
36933
36940
|
children: [
|
|
36934
36941
|
c.label,
|
|
@@ -36970,7 +36977,7 @@ function ActionInbox({
|
|
|
36970
36977
|
/* @__PURE__ */ (0, import_jsx_runtime115.jsx)("span", { className: "font-medium", children: held[item.item_id].approve ? "Approved" : "Declined" }),
|
|
36971
36978
|
/* @__PURE__ */ (0, import_jsx_runtime115.jsxs)("span", { className: "text-[11px] text-muted-foreground tabular-nums", children: [
|
|
36972
36979
|
"\xB7 made in ",
|
|
36973
|
-
(0,
|
|
36980
|
+
(0, import_format8.formatDurationMs)(Math.max(0, Math.ceil((held[item.item_id].until - Date.now()) / 1e3) * 1e3), { style: "compact" })
|
|
36974
36981
|
] }),
|
|
36975
36982
|
/* @__PURE__ */ (0, import_jsx_runtime115.jsx)(import_design_system99.Button, { size: "sm", variant: "ghost", className: "h-6 px-2 text-xs", onClick: () => undoHold(held[item.item_id].hold), children: "Undo" })
|
|
36976
36983
|
] })
|
|
@@ -37195,7 +37202,7 @@ function ActionInbox({
|
|
|
37195
37202
|
var import_react203 = require("react");
|
|
37196
37203
|
var import_react204 = require("@ai-matrx/records/react");
|
|
37197
37204
|
var import_design_system100 = require("@ai-matrx/design-system");
|
|
37198
|
-
var
|
|
37205
|
+
var import_format9 = require("@ai-matrx/kit/format");
|
|
37199
37206
|
var import_text_case14 = require("@ai-matrx/kit/text-case");
|
|
37200
37207
|
var import_jsx_runtime116 = require("react/jsx-runtime");
|
|
37201
37208
|
function HistoryPanel({ tableId, recordId, onAskAboutField, className }) {
|
|
@@ -37488,7 +37495,7 @@ function whenText(at) {
|
|
|
37488
37495
|
const then = new Date(at);
|
|
37489
37496
|
const age = Date.now() - then.getTime();
|
|
37490
37497
|
if (Number.isNaN(age)) return "\u2014";
|
|
37491
|
-
if (age < 864e5) return (0,
|
|
37498
|
+
if (age < 864e5) return (0, import_format9.formatRelativeTime)(then, { style: "intl" });
|
|
37492
37499
|
if (age < 7 * 864e5) {
|
|
37493
37500
|
return then.toLocaleString(void 0, { weekday: "short", hour: "numeric", minute: "2-digit" });
|
|
37494
37501
|
}
|
|
@@ -38134,7 +38141,7 @@ var import_recharts = require("recharts");
|
|
|
38134
38141
|
var import_records51 = require("@ai-matrx/records");
|
|
38135
38142
|
var import_core21 = require("@ai-matrx/records/core");
|
|
38136
38143
|
var import_design_system104 = require("@ai-matrx/design-system");
|
|
38137
|
-
var
|
|
38144
|
+
var import_format10 = require("@ai-matrx/kit/format");
|
|
38138
38145
|
|
|
38139
38146
|
// src/linkWords.ts
|
|
38140
38147
|
var import_react209 = require("react");
|
|
@@ -38742,7 +38749,7 @@ function BigNumber({
|
|
|
38742
38749
|
/* @__PURE__ */ (0, import_jsx_runtime120.jsx)("span", { className: "text-2xl font-semibold tabular-nums", children: pretty(total) }),
|
|
38743
38750
|
windows ? /* @__PURE__ */ (0, import_jsx_runtime120.jsx)(Trend, { pct: block.totals?.change_pct, aimingUp: !!target, className: "text-sm" }) : null
|
|
38744
38751
|
] }),
|
|
38745
|
-
/* @__PURE__ */ (0, import_jsx_runtime120.jsx)("span", { className: "text-xs text-muted-foreground", children: windows && typeof priorTotal === "number" ? `${windowName(windows.window, windows.period)} \xB7 ${pretty(priorTotal)} in ${windowName(windows.prior_window, windows.period)}` : `from ${(0,
|
|
38752
|
+
/* @__PURE__ */ (0, import_jsx_runtime120.jsx)("span", { className: "text-xs text-muted-foreground", children: windows && typeof priorTotal === "number" ? `${windowName(windows.window, windows.period)} \xB7 ${pretty(priorTotal)} in ${windowName(windows.prior_window, windows.period)}` : `from ${(0, import_format10.formatCount)(records)} ${records === 1 ? "record" : "records"}` })
|
|
38746
38753
|
] });
|
|
38747
38754
|
const ring = target && typeof target.progress === "number" && typeof target.value === "number" ? /* @__PURE__ */ (0, import_jsx_runtime120.jsxs)("span", { className: "ml-auto flex shrink-0 items-center gap-2", children: [
|
|
38748
38755
|
/* @__PURE__ */ (0, import_jsx_runtime120.jsxs)("span", { className: "text-right text-xs text-muted-foreground", children: [
|
|
@@ -38861,7 +38868,7 @@ var HEIGHT = CHART_PLOT_PX;
|
|
|
38861
38868
|
function compactTick(value) {
|
|
38862
38869
|
if (typeof value !== "number" || !Number.isFinite(value)) return String(value ?? "");
|
|
38863
38870
|
if (Math.abs(value) < 1e3 && !Number.isInteger(value)) return String(Math.round(value * 10) / 10);
|
|
38864
|
-
return (0,
|
|
38871
|
+
return (0, import_format10.formatCount)(value, { style: "compact" });
|
|
38865
38872
|
}
|
|
38866
38873
|
function Drawing({
|
|
38867
38874
|
kind,
|
|
@@ -39000,9 +39007,7 @@ function onlyWholeNumbers(rows) {
|
|
|
39000
39007
|
|
|
39001
39008
|
// src/FormResultsPanel.tsx
|
|
39002
39009
|
var import_jsx_runtime121 = require("react/jsx-runtime");
|
|
39003
|
-
|
|
39004
|
-
return { title, kind: "number", group_by: [], measures: [{ op: "count" }], rows: [{ groups: {}, measures: { count: value }, row_count: 1 }] };
|
|
39005
|
-
}
|
|
39010
|
+
var CHARTED_KINDS = /* @__PURE__ */ new Set(["select", "multi_select", "checkbox", "number", "currency", "percent", "member", "relation"]);
|
|
39006
39011
|
function dropOffBlock(results, label) {
|
|
39007
39012
|
return {
|
|
39008
39013
|
title: "Reached each question",
|
|
@@ -39044,6 +39049,13 @@ function FormResultsPanel({ form, className }) {
|
|
|
39044
39049
|
cancelled = true;
|
|
39045
39050
|
};
|
|
39046
39051
|
}, [client, form.id, round]);
|
|
39052
|
+
const charted = (0, import_react215.useMemo)(() => {
|
|
39053
|
+
const byKey = new Map((fields.data ?? []).map((f) => [f.key, f]));
|
|
39054
|
+
return (key) => {
|
|
39055
|
+
const field2 = byKey.get(key);
|
|
39056
|
+
return field2 ? CHARTED_KINDS.has(editorKindFor(field2)) : false;
|
|
39057
|
+
};
|
|
39058
|
+
}, [fields.data]);
|
|
39047
39059
|
const label = (0, import_react215.useMemo)(() => {
|
|
39048
39060
|
const byKey = new Map((fields.data ?? []).map((f) => [f.key, f]));
|
|
39049
39061
|
const asks = new Map((form.questions ?? []).map((q) => [q.field, q.ask]));
|
|
@@ -39057,12 +39069,15 @@ function FormResultsPanel({ form, className }) {
|
|
|
39057
39069
|
/* @__PURE__ */ (0, import_jsx_runtime121.jsx)("span", { className: "text-sm font-medium", children: "Results" }),
|
|
39058
39070
|
/* @__PURE__ */ (0, import_jsx_runtime121.jsx)(import_design_system105.Button, { size: "sm", variant: "ghost", className: "ml-auto", onClick: () => setRound((n) => n + 1), children: "Refresh" })
|
|
39059
39071
|
] }),
|
|
39060
|
-
/* @__PURE__ */ (0, import_jsx_runtime121.
|
|
39061
|
-
|
|
39062
|
-
|
|
39063
|
-
|
|
39064
|
-
|
|
39065
|
-
]
|
|
39072
|
+
/* @__PURE__ */ (0, import_jsx_runtime121.jsx)("dl", { className: "grid grid-cols-2 gap-2 @xl:grid-cols-4", "data-records-form-kpis": "", children: [
|
|
39073
|
+
["Views", results.views],
|
|
39074
|
+
["Starts", results.starts],
|
|
39075
|
+
["Completions", results.completions],
|
|
39076
|
+
["Completion rate", results.completion_rate === null ? null : `${results.completion_rate}%`]
|
|
39077
|
+
].map(([name, value]) => /* @__PURE__ */ (0, import_jsx_runtime121.jsxs)("div", { className: "flex flex-col gap-1 rounded-md border px-3 py-2", children: [
|
|
39078
|
+
/* @__PURE__ */ (0, import_jsx_runtime121.jsx)("dt", { className: "text-xs text-muted-foreground", children: name }),
|
|
39079
|
+
/* @__PURE__ */ (0, import_jsx_runtime121.jsx)("dd", { className: "text-2xl font-semibold tabular-nums", children: value ?? "\u2014" })
|
|
39080
|
+
] }, name)) }),
|
|
39066
39081
|
results.questions.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime121.jsx)(ChartBlock, { block: dropOffBlock(results, label), subject: form.subject }) : null,
|
|
39067
39082
|
/* @__PURE__ */ (0, import_jsx_runtime121.jsx)("ul", { className: "flex flex-col gap-1 text-xs", "data-records-form-dropoff": "", children: results.questions.map((q) => /* @__PURE__ */ (0, import_jsx_runtime121.jsxs)("li", { className: "flex items-center gap-2", children: [
|
|
39068
39083
|
/* @__PURE__ */ (0, import_jsx_runtime121.jsx)("span", { className: "min-w-0 flex-1 truncate", children: label(q.field_key) }),
|
|
@@ -39101,7 +39116,16 @@ function FormResultsPanel({ form, className }) {
|
|
|
39101
39116
|
/* @__PURE__ */ (0, import_jsx_runtime121.jsx)("span", { className: "flex-1 truncate", children: h.value }),
|
|
39102
39117
|
/* @__PURE__ */ (0, import_jsx_runtime121.jsx)("span", { className: "tabular-nums text-muted-foreground", children: h.count })
|
|
39103
39118
|
] }, `${h.key}:${h.value}`)) }) : null,
|
|
39104
|
-
results.questions.filter((q) => q.answers.length > 0).map(
|
|
39119
|
+
results.questions.filter((q) => q.answers.length > 0).map(
|
|
39120
|
+
(q) => charted(q.field_key) ? /* @__PURE__ */ (0, import_jsx_runtime121.jsx)(ChartBlock, { block: answersBlock(q, label(q.field_key)), subject: form.subject }, q.field_key) : /* @__PURE__ */ (0, import_jsx_runtime121.jsxs)("section", { className: "flex flex-col gap-1 rounded-md border px-3 py-2 text-xs", "data-records-form-text-answers": q.field_key, children: [
|
|
39121
|
+
/* @__PURE__ */ (0, import_jsx_runtime121.jsx)("span", { className: "font-medium", children: label(q.field_key) }),
|
|
39122
|
+
/* @__PURE__ */ (0, import_jsx_runtime121.jsxs)("span", { className: "text-muted-foreground", children: [
|
|
39123
|
+
q.answered,
|
|
39124
|
+
" answered"
|
|
39125
|
+
] }),
|
|
39126
|
+
/* @__PURE__ */ (0, import_jsx_runtime121.jsx)("ul", { className: "flex flex-col gap-0.5", children: q.answers.map((a) => /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("li", { className: "truncate", children: a.value }, a.value)) })
|
|
39127
|
+
] }, q.field_key)
|
|
39128
|
+
)
|
|
39105
39129
|
] });
|
|
39106
39130
|
}
|
|
39107
39131
|
|
|
@@ -41539,8 +41563,9 @@ function QuestionLogic({
|
|
|
41539
41563
|
const jumps = question.jumps ?? [];
|
|
41540
41564
|
const targets = jumpTargets(questions, index, endings, label);
|
|
41541
41565
|
const points = question.points ?? {};
|
|
41542
|
-
const
|
|
41543
|
-
const
|
|
41566
|
+
const choiceFields = field2 && isChoiceField(field2) ? [field2] : [];
|
|
41567
|
+
const options = useChoiceOptions(choiceFields, choiceFields.map((f) => f.key));
|
|
41568
|
+
const choices = field2 ? (options.get(field2.key) ?? []).map((o) => ({ key: o.key, label: o.label })) : [];
|
|
41544
41569
|
const [answer, setAnswer] = (0, import_react229.useState)("");
|
|
41545
41570
|
const setJump = (i, part) => onChange({ jumps: jumps.map((j, k) => k === i ? { ...j, ...part } : j) });
|
|
41546
41571
|
return /* @__PURE__ */ (0, import_jsx_runtime131.jsxs)("div", { className: "col-span-2 flex flex-col gap-1.5 text-xs", "data-records-form-logic": question.field, children: [
|
|
@@ -41564,25 +41589,25 @@ function QuestionLogic({
|
|
|
41564
41589
|
/* @__PURE__ */ (0, import_jsx_runtime131.jsxs)("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
41565
41590
|
targets.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime131.jsx)(import_design_system115.Button, { size: "sm", variant: "outline", onClick: () => onChange({ jumps: [...jumps, { when: null, to: targetOf(targets[0].value) }] }), children: "Add a jump" }) : null,
|
|
41566
41591
|
/* @__PURE__ */ (0, import_jsx_runtime131.jsx)("span", { className: "text-muted-foreground", children: "Points:" }),
|
|
41567
|
-
(choices.length > 0 ? choices : Object.keys(points)).map((choice) => /* @__PURE__ */ (0, import_jsx_runtime131.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
41568
|
-
/* @__PURE__ */ (0, import_jsx_runtime131.jsx)("span", { children: choice }),
|
|
41592
|
+
(choices.length > 0 ? choices : Object.keys(points).map((k) => ({ key: k, label: k }))).map((choice) => /* @__PURE__ */ (0, import_jsx_runtime131.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
41593
|
+
/* @__PURE__ */ (0, import_jsx_runtime131.jsx)("span", { children: choice.label }),
|
|
41569
41594
|
/* @__PURE__ */ (0, import_jsx_runtime131.jsx)(
|
|
41570
41595
|
import_design_system115.BasicInput,
|
|
41571
41596
|
{
|
|
41572
41597
|
className: "h-7 w-14 text-xs",
|
|
41573
41598
|
inputMode: "decimal",
|
|
41574
|
-
"aria-label": `Points for ${choice}`,
|
|
41575
|
-
value: points[choice] ?? "",
|
|
41599
|
+
"aria-label": `Points for ${choice.label}`,
|
|
41600
|
+
value: points[choice.key] ?? "",
|
|
41576
41601
|
onChange: (e) => {
|
|
41577
41602
|
const next = { ...points };
|
|
41578
41603
|
const n = Number(e.target.value);
|
|
41579
|
-
if (e.target.value.trim() === "" || Number.isNaN(n)) delete next[choice];
|
|
41580
|
-
else next[choice] = n;
|
|
41604
|
+
if (e.target.value.trim() === "" || Number.isNaN(n)) delete next[choice.key];
|
|
41605
|
+
else next[choice.key] = n;
|
|
41581
41606
|
onChange({ points: Object.keys(next).length > 0 ? next : null });
|
|
41582
41607
|
}
|
|
41583
41608
|
}
|
|
41584
41609
|
)
|
|
41585
|
-
] }, choice)),
|
|
41610
|
+
] }, choice.key)),
|
|
41586
41611
|
choices.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime131.jsxs)("span", { className: "flex items-center gap-1", children: [
|
|
41587
41612
|
/* @__PURE__ */ (0, import_jsx_runtime131.jsx)(import_design_system115.BasicInput, { className: "h-7 w-28 text-xs", "aria-label": "Answer worth points", placeholder: "An answer", value: answer, onChange: (e) => setAnswer(e.target.value) }),
|
|
41588
41613
|
/* @__PURE__ */ (0, import_jsx_runtime131.jsx)(
|
|
@@ -43854,6 +43879,8 @@ function recordsDataSource(client, fallbackSchema = "custom") {
|
|
|
43854
43879
|
function makeRecordsDataSource(client, fallbackSchema) {
|
|
43855
43880
|
const supabase = client;
|
|
43856
43881
|
return {
|
|
43882
|
+
// PAGE-BUNDLE: the real adapter opens a table page with one `custom.table_page_bundle` call.
|
|
43883
|
+
opensInOneCall: true,
|
|
43857
43884
|
async rpc(fn, args, options) {
|
|
43858
43885
|
const schema = options?.schema ?? fallbackSchema;
|
|
43859
43886
|
if (schema === "custom" && supabase.auth?.getSession && !await hasSession(supabase.auth.getSession)) {
|
|
@@ -46167,7 +46194,7 @@ var import_react256 = require("@ai-matrx/records/react");
|
|
|
46167
46194
|
var import_core24 = require("@ai-matrx/records/core");
|
|
46168
46195
|
var import_design_system129 = require("@ai-matrx/design-system");
|
|
46169
46196
|
var import_jsx_runtime145 = require("react/jsx-runtime");
|
|
46170
|
-
var EDIT_LEVELS = /* @__PURE__ */ new Set(["editor", "admin", "owner"]);
|
|
46197
|
+
var EDIT_LEVELS = /* @__PURE__ */ new Set(["edit_content", "editor", "admin", "owner"]);
|
|
46171
46198
|
function PageScreen({
|
|
46172
46199
|
pageId,
|
|
46173
46200
|
newOnTable,
|
|
@@ -48361,6 +48388,7 @@ function TableReferenceDialog({
|
|
|
48361
48388
|
}
|
|
48362
48389
|
|
|
48363
48390
|
// src/TableDuplicate.tsx
|
|
48391
|
+
var import_format11 = require("@ai-matrx/kit/format");
|
|
48364
48392
|
var import_react274 = require("react");
|
|
48365
48393
|
var import_react275 = require("@ai-matrx/records/react");
|
|
48366
48394
|
var import_design_system139 = require("@ai-matrx/design-system");
|
|
@@ -48369,7 +48397,7 @@ function copyNameFor(name) {
|
|
|
48369
48397
|
return `${name.trim() || "Table"} (copy)`;
|
|
48370
48398
|
}
|
|
48371
48399
|
function duplicateProgressWords(p) {
|
|
48372
|
-
if (p.records && p.records.total > 0) return `Copying records \xB7 ${p.records.done
|
|
48400
|
+
if (p.records && p.records.total > 0) return `Copying records \xB7 ${(0, import_format11.formatCount)(p.records.done)} of ${(0, import_format11.formatCount)(p.records.total)}`;
|
|
48373
48401
|
if (p.views.total > 0 && p.step === "views") return `Copying views \xB7 ${p.views.done} of ${p.views.total}`;
|
|
48374
48402
|
return "Copying columns\u2026";
|
|
48375
48403
|
}
|
|
@@ -48425,7 +48453,7 @@ function TableDuplicateDialog({ tableId, name, open, onOpenChange, onDuplicated
|
|
|
48425
48453
|
" columns, ",
|
|
48426
48454
|
phase.copy.copied.views,
|
|
48427
48455
|
" views",
|
|
48428
|
-
phase.copy.copied.withRecords ? `, ${phase.copy.copied.records
|
|
48456
|
+
phase.copy.copied.withRecords ? `, ${(0, import_format11.formatCount)(phase.copy.copied.records)} records` : "",
|
|
48429
48457
|
"."
|
|
48430
48458
|
] }),
|
|
48431
48459
|
phase.copy.notCopied.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime155.jsxs)("p", { className: "text-xs text-muted-foreground", children: [
|
|
@@ -48839,7 +48867,7 @@ function useSlotScroll(slot) {
|
|
|
48839
48867
|
}
|
|
48840
48868
|
|
|
48841
48869
|
// src/TablePage.tsx
|
|
48842
|
-
var
|
|
48870
|
+
var import_uuid4 = require("@ai-matrx/kit/uuid");
|
|
48843
48871
|
var import_jsx_runtime158 = require("react/jsx-runtime");
|
|
48844
48872
|
var RAIL_TITLE = {
|
|
48845
48873
|
settings: "Table settings",
|
|
@@ -49061,7 +49089,7 @@ function openingView(activeView, activeDashboardId) {
|
|
|
49061
49089
|
}
|
|
49062
49090
|
function savedViewFromParam(activeView) {
|
|
49063
49091
|
const word = typeof activeView === "string" ? activeView.trim() : "";
|
|
49064
|
-
return (0,
|
|
49092
|
+
return (0, import_uuid4.isUuidShape)(word) ? word.toLowerCase() : null;
|
|
49065
49093
|
}
|
|
49066
49094
|
function addressForView(view, layout) {
|
|
49067
49095
|
return view && !view.isDefault ? view.id : layout;
|
|
@@ -49382,7 +49410,7 @@ function TablePage({
|
|
|
49382
49410
|
const [designateRefused, setDesignateRefused] = (0, import_react279.useState)(null);
|
|
49383
49411
|
const opensAs = view?.isDefault ? view.layout : null;
|
|
49384
49412
|
const canDesignate = Boolean(
|
|
49385
|
-
rights.
|
|
49413
|
+
rights.organise && view && layoutShowing && layoutShowing !== opensAs && storeKeepsLayout(layoutShowing)
|
|
49386
49414
|
);
|
|
49387
49415
|
const layoutShowingLabel = layoutShowing ? LAYOUT_LABEL[layoutShowing] : "";
|
|
49388
49416
|
const designate = async () => {
|
|
@@ -49865,7 +49893,7 @@ function TablePage({
|
|
|
49865
49893
|
QuestionPanel,
|
|
49866
49894
|
{
|
|
49867
49895
|
tableId,
|
|
49868
|
-
activeQuestionId: questionsFromLink && activeItemId && (0,
|
|
49896
|
+
activeQuestionId: questionsFromLink && activeItemId && (0, import_uuid4.isUuidShape)(activeItemId) ? activeItemId : null,
|
|
49869
49897
|
draft: questionDraft
|
|
49870
49898
|
}
|
|
49871
49899
|
) : main === "archived" ? (
|
|
@@ -50090,6 +50118,7 @@ function usePublicReadOnly(client, organizationId, tableId, table, rights) {
|
|
|
50090
50118
|
}
|
|
50091
50119
|
|
|
50092
50120
|
// src/entityViews.tsx
|
|
50121
|
+
var import_format12 = require("@ai-matrx/kit/format");
|
|
50093
50122
|
var import_design_system143 = require("@ai-matrx/design-system");
|
|
50094
50123
|
var import_data_table24 = require("@ai-matrx/design-system/data-table");
|
|
50095
50124
|
var import_react281 = require("react");
|
|
@@ -50280,7 +50309,7 @@ function EntityTablePageBody({
|
|
|
50280
50309
|
return /* @__PURE__ */ (0, import_jsx_runtime159.jsxs)("div", { className: (0, import_design_system144.cn)("flex min-w-0 flex-col gap-2", className), "data-records-entity-page": source.token, children: [
|
|
50281
50310
|
presentation === "page" || boardable || entity.creatable ? /* @__PURE__ */ (0, import_jsx_runtime159.jsxs)("div", { className: "flex min-w-0 items-center gap-2", children: [
|
|
50282
50311
|
presentation === "page" ? /* @__PURE__ */ (0, import_jsx_runtime159.jsx)("h2", { className: "truncate text-base font-semibold", children: entity.label ?? (entity.loading ? "Loading\u2026" : "Table") }) : null,
|
|
50283
|
-
presentation === "page" ? /* @__PURE__ */ (0, import_jsx_runtime159.jsx)("span", { className: "text-xs tabular-nums text-muted-foreground", children: entity.loading || entity.total === null ? "" : entity.total
|
|
50312
|
+
presentation === "page" ? /* @__PURE__ */ (0, import_jsx_runtime159.jsx)("span", { className: "text-xs tabular-nums text-muted-foreground", children: entity.loading || entity.total === null ? "" : (0, import_format12.formatCount)(entity.total) }) : null,
|
|
50284
50313
|
/* @__PURE__ */ (0, import_jsx_runtime159.jsxs)("span", { className: "ml-auto flex items-center gap-1", children: [
|
|
50285
50314
|
boardable ? /* @__PURE__ */ (0, import_jsx_runtime159.jsxs)(import_jsx_runtime159.Fragment, { children: [
|
|
50286
50315
|
/* @__PURE__ */ (0, import_jsx_runtime159.jsx)(import_design_system144.Button, { size: "sm", variant: layout === "grid" ? "secondary" : "ghost", "aria-pressed": layout === "grid", onClick: () => choose("grid"), children: "Table" }),
|