@ai-matrx/records-ui 0.76.0 → 0.78.0
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 +88 -0
- package/dist/index.cjs +585 -378
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +567 -340
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -4476,6 +4476,16 @@ var import_design_system13 = require("@ai-matrx/design-system");
|
|
|
4476
4476
|
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
4477
4477
|
var BATCH = 250;
|
|
4478
4478
|
var SAMPLES = 40;
|
|
4479
|
+
var MAPPING_COLUMNS = "minmax(9rem, 11rem) minmax(14rem, 17rem) minmax(13rem, 1fr) minmax(8rem, 10rem)";
|
|
4480
|
+
var ABSENT = "__absent__";
|
|
4481
|
+
function obviousTitleColumn(columns) {
|
|
4482
|
+
const says = /^(title|name|record|customer|client|company|job|item|subject|label|description)\b|(\bname|\btitle|\bnumber|\bid)$/i;
|
|
4483
|
+
const named = columns.find((c) => says.test(c.header.trim()));
|
|
4484
|
+
if (named) return named.header;
|
|
4485
|
+
const text = columns.find((c) => c.type === "text");
|
|
4486
|
+
if (text) return text.header;
|
|
4487
|
+
return columns[0]?.header ?? null;
|
|
4488
|
+
}
|
|
4479
4489
|
async function sha256(bytes) {
|
|
4480
4490
|
const subtle = globalThis.crypto?.subtle;
|
|
4481
4491
|
if (!subtle) return null;
|
|
@@ -4510,6 +4520,7 @@ function ImportWizard({ tableId, onDone, className }) {
|
|
|
4510
4520
|
const [alreadyRan, setAlreadyRan] = (0, import_react26.useState)(null);
|
|
4511
4521
|
const [columnsAdded, setColumnsAdded] = (0, import_react26.useState)(null);
|
|
4512
4522
|
const [show, setShow] = (0, import_react26.useState)("all");
|
|
4523
|
+
const [ledger, setLedger] = (0, import_react26.useState)(null);
|
|
4513
4524
|
const declared = fields.data ?? [];
|
|
4514
4525
|
const take = (0, import_react26.useCallback)(
|
|
4515
4526
|
async (file) => {
|
|
@@ -4520,6 +4531,7 @@ function ImportWizard({ tableId, onDone, className }) {
|
|
|
4520
4531
|
setProposals([]);
|
|
4521
4532
|
setAlreadyRan(null);
|
|
4522
4533
|
setProgress(0);
|
|
4534
|
+
setLedger(null);
|
|
4523
4535
|
try {
|
|
4524
4536
|
const xlsx = file.name.toLowerCase().endsWith(".xlsx");
|
|
4525
4537
|
const bytes = await file.arrayBuffer();
|
|
@@ -4546,6 +4558,11 @@ function ImportWizard({ tableId, onDone, className }) {
|
|
|
4546
4558
|
for (const column of answered.data.columns) {
|
|
4547
4559
|
if (column.matched) next[column.header] = column.field_key;
|
|
4548
4560
|
}
|
|
4561
|
+
const titleKey2 = table.data?.title_field ?? null;
|
|
4562
|
+
if (titleKey2 && !Object.values(next).includes(titleKey2)) {
|
|
4563
|
+
const guess = obviousTitleColumn(answered.data.columns);
|
|
4564
|
+
if (guess) next[guess] = titleKey2;
|
|
4565
|
+
}
|
|
4549
4566
|
setMapping(next);
|
|
4550
4567
|
setPhase("ready");
|
|
4551
4568
|
} catch (thrown) {
|
|
@@ -4553,7 +4570,7 @@ function ImportWizard({ tableId, onDone, className }) {
|
|
|
4553
4570
|
setPhase("waiting");
|
|
4554
4571
|
}
|
|
4555
4572
|
},
|
|
4556
|
-
[client, declared, tableId]
|
|
4573
|
+
[client, declared, tableId, table.data?.title_field]
|
|
4557
4574
|
);
|
|
4558
4575
|
const run = (0, import_react26.useCallback)(async () => {
|
|
4559
4576
|
if (!plan) return;
|
|
@@ -4561,6 +4578,7 @@ function ImportWizard({ tableId, onDone, className }) {
|
|
|
4561
4578
|
setOutcomes([]);
|
|
4562
4579
|
setColumnsAdded(null);
|
|
4563
4580
|
setProgress(0);
|
|
4581
|
+
setLedger(null);
|
|
4564
4582
|
if (unmapped === "create" && rights.admin) {
|
|
4565
4583
|
setPhase("declaring");
|
|
4566
4584
|
const made = await client.importDeclareColumns({ table_id: tableId, rows, mapping });
|
|
@@ -4596,6 +4614,7 @@ function ImportWizard({ tableId, onDone, className }) {
|
|
|
4596
4614
|
}
|
|
4597
4615
|
const importId = opened.data.import_id;
|
|
4598
4616
|
const collected = [];
|
|
4617
|
+
const told = { seen: 0, written: 0, duplicate: 0, refused: 0 };
|
|
4599
4618
|
let take2 = opened.data.rows_per_call ?? BATCH;
|
|
4600
4619
|
let at = 0;
|
|
4601
4620
|
while (at < rows.length) {
|
|
@@ -4604,11 +4623,17 @@ function ImportWizard({ tableId, onDone, className }) {
|
|
|
4604
4623
|
if (!answered.ok) {
|
|
4605
4624
|
setProblem(answered.error.message);
|
|
4606
4625
|
setOutcomes([...collected]);
|
|
4626
|
+
setLedger({ ...told, final: false });
|
|
4607
4627
|
setPhase("ready");
|
|
4608
4628
|
return;
|
|
4609
4629
|
}
|
|
4610
4630
|
collected.push(...answered.data.outcomes);
|
|
4611
4631
|
setOutcomes([...collected]);
|
|
4632
|
+
told.seen += answered.data.rows_seen;
|
|
4633
|
+
told.written += answered.data.rows_written;
|
|
4634
|
+
told.duplicate += answered.data.rows_duplicate;
|
|
4635
|
+
told.refused += answered.data.rows_refused;
|
|
4636
|
+
setLedger({ ...told, final: false });
|
|
4612
4637
|
at += batch.length;
|
|
4613
4638
|
setProgress(Math.min(at, rows.length));
|
|
4614
4639
|
if (answered.data.rows_per_call) take2 = answered.data.rows_per_call;
|
|
@@ -4621,6 +4646,13 @@ function ImportWizard({ tableId, onDone, className }) {
|
|
|
4621
4646
|
}
|
|
4622
4647
|
setSummary(finished.data.message);
|
|
4623
4648
|
setProposals(finished.data.proposals);
|
|
4649
|
+
setLedger({
|
|
4650
|
+
seen: finished.data.rows_seen,
|
|
4651
|
+
written: finished.data.rows_written,
|
|
4652
|
+
duplicate: finished.data.rows_duplicate,
|
|
4653
|
+
refused: finished.data.rows_refused,
|
|
4654
|
+
final: true
|
|
4655
|
+
});
|
|
4624
4656
|
setPhase("done");
|
|
4625
4657
|
onDone?.(finished.data.rows_written);
|
|
4626
4658
|
}, [client, dedupeKey, fileBytes, fileHash, fileName, format, mapping, onDuplicate, onDone, plan, rows, tableId, unmapped]);
|
|
@@ -4640,6 +4672,10 @@ function ImportWizard({ tableId, onDone, className }) {
|
|
|
4640
4672
|
[outcomes, show]
|
|
4641
4673
|
);
|
|
4642
4674
|
const mappedCount = Object.keys(mapping).length;
|
|
4675
|
+
const titleKey = table.data?.title_field ?? null;
|
|
4676
|
+
const titleMappedTo = titleKey ? Object.entries(mapping).find(([, key]) => key === titleKey)?.[0] ?? null : null;
|
|
4677
|
+
const titleMissing = Boolean(titleKey) && titleMappedTo === null;
|
|
4678
|
+
const titleFieldLabel = (titleKey ? plan?.fields.find((f) => f.key === titleKey)?.label : null) || (titleKey ? declared.find((f) => f.key === titleKey)?.label : null) || "the name column";
|
|
4643
4679
|
const busy = phase === "reading" || phase === "planning" || phase === "declaring" || phase === "writing";
|
|
4644
4680
|
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: (0, import_design_system13.cn)("flex min-w-0 flex-col gap-2 text-xs", className), children: [
|
|
4645
4681
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
@@ -4672,55 +4708,107 @@ function ImportWizard({ tableId, onDone, className }) {
|
|
|
4672
4708
|
phase === "reading" ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "text-muted-foreground", children: "Reading the file\u2026" }) : null,
|
|
4673
4709
|
phase === "planning" ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "text-muted-foreground", children: "Working out what each column is\u2026" }) : null,
|
|
4674
4710
|
plan && parsed ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
|
|
4675
|
-
/* @__PURE__ */ (0, import_jsx_runtime16.
|
|
4676
|
-
/* @__PURE__ */ (0, import_jsx_runtime16.
|
|
4677
|
-
|
|
4678
|
-
|
|
4679
|
-
|
|
4680
|
-
|
|
4681
|
-
|
|
4682
|
-
|
|
4683
|
-
|
|
4684
|
-
|
|
4685
|
-
|
|
4686
|
-
|
|
4687
|
-
|
|
4688
|
-
|
|
4711
|
+
titleKey ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex flex-wrap items-center gap-2 rounded border bg-muted/40 px-2 py-1.5", children: [
|
|
4712
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "font-medium", children: "What each record is called" }),
|
|
4713
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
4714
|
+
import_design_system13.Select,
|
|
4715
|
+
{
|
|
4716
|
+
value: titleMappedTo ?? "",
|
|
4717
|
+
disabled: busy,
|
|
4718
|
+
onValueChange: (chosen) => {
|
|
4719
|
+
setMapping((m) => {
|
|
4720
|
+
const next = { ...m };
|
|
4721
|
+
for (const [header, key] of Object.entries(next)) {
|
|
4722
|
+
if (key === titleKey) delete next[header];
|
|
4723
|
+
}
|
|
4724
|
+
if (chosen) next[chosen] = titleKey;
|
|
4725
|
+
return next;
|
|
4726
|
+
});
|
|
4727
|
+
},
|
|
4728
|
+
children: [
|
|
4729
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
4730
|
+
import_design_system13.SelectTrigger,
|
|
4731
|
+
{
|
|
4732
|
+
size: "sm",
|
|
4733
|
+
"aria-label": "Which column each record is named by",
|
|
4734
|
+
className: "min-w-[14rem]",
|
|
4735
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system13.SelectValue, { placeholder: "\u2014 choose the column \u2014" })
|
|
4736
|
+
}
|
|
4737
|
+
),
|
|
4738
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system13.SelectContent, { children: plan.columns.map((c) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system13.SelectItem, { value: c.header, children: c.header }, c.header)) })
|
|
4739
|
+
]
|
|
4740
|
+
}
|
|
4741
|
+
),
|
|
4742
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "text-muted-foreground", children: titleMappedTo ? `goes into ${titleFieldLabel}, so every record this file makes has a name you can read in the grid and on a chip.` : `Nothing goes into ${titleFieldLabel} yet, so every record this file makes would land with no name at all. Pick the column that says what each row IS.` })
|
|
4743
|
+
] }) : null,
|
|
4744
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "w-full overflow-x-auto rounded border", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "min-w-[52rem]", children: [
|
|
4745
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
4746
|
+
"div",
|
|
4747
|
+
{
|
|
4748
|
+
className: "grid items-center gap-x-3 border-b bg-muted px-2 py-1 font-medium",
|
|
4749
|
+
style: { gridTemplateColumns: MAPPING_COLUMNS },
|
|
4750
|
+
children: [
|
|
4751
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { children: "Column in the file" }),
|
|
4752
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { children: "Goes to" }),
|
|
4753
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { children: "Kind" }),
|
|
4754
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { children: "First values" })
|
|
4755
|
+
]
|
|
4756
|
+
}
|
|
4757
|
+
),
|
|
4758
|
+
plan.columns.map((column) => {
|
|
4689
4759
|
const to = mapping[column.header] ?? "";
|
|
4690
|
-
|
|
4691
|
-
|
|
4692
|
-
|
|
4693
|
-
|
|
4694
|
-
|
|
4695
|
-
|
|
4696
|
-
|
|
4697
|
-
|
|
4698
|
-
|
|
4699
|
-
|
|
4700
|
-
|
|
4701
|
-
|
|
4702
|
-
|
|
4703
|
-
|
|
4704
|
-
|
|
4705
|
-
|
|
4706
|
-
|
|
4707
|
-
|
|
4708
|
-
|
|
4709
|
-
|
|
4710
|
-
|
|
4711
|
-
|
|
4712
|
-
|
|
4713
|
-
|
|
4714
|
-
|
|
4715
|
-
|
|
4716
|
-
|
|
4717
|
-
|
|
4718
|
-
|
|
4719
|
-
|
|
4720
|
-
|
|
4721
|
-
|
|
4722
|
-
|
|
4723
|
-
|
|
4760
|
+
const absent = unmapped === "ignore" ? "\u2014 leave it out \u2014" : "\u2014 offer it as a new column \u2014";
|
|
4761
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
4762
|
+
"div",
|
|
4763
|
+
{
|
|
4764
|
+
className: "grid items-start gap-x-3 border-t px-2 py-1",
|
|
4765
|
+
style: { gridTemplateColumns: MAPPING_COLUMNS },
|
|
4766
|
+
children: [
|
|
4767
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "truncate pt-1.5 font-medium", title: column.header, children: column.header }),
|
|
4768
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
4769
|
+
import_design_system13.Select,
|
|
4770
|
+
{
|
|
4771
|
+
value: to || ABSENT,
|
|
4772
|
+
disabled: busy,
|
|
4773
|
+
onValueChange: (chosen) => {
|
|
4774
|
+
setMapping((m) => {
|
|
4775
|
+
const next = { ...m };
|
|
4776
|
+
if (chosen === ABSENT) delete next[column.header];
|
|
4777
|
+
else next[column.header] = chosen;
|
|
4778
|
+
return next;
|
|
4779
|
+
});
|
|
4780
|
+
},
|
|
4781
|
+
children: [
|
|
4782
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
4783
|
+
import_design_system13.SelectTrigger,
|
|
4784
|
+
{
|
|
4785
|
+
size: "sm",
|
|
4786
|
+
"aria-label": `Where ${column.header} goes`,
|
|
4787
|
+
"data-goes-to": column.header,
|
|
4788
|
+
className: "w-full min-w-[14rem]",
|
|
4789
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system13.SelectValue, {})
|
|
4790
|
+
}
|
|
4791
|
+
),
|
|
4792
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_design_system13.SelectContent, { children: [
|
|
4793
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system13.SelectItem, { value: ABSENT, children: absent }),
|
|
4794
|
+
plan.fields.map((f) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system13.SelectItem, { value: f.key, children: f.label || f.key }, f.field_id))
|
|
4795
|
+
] })
|
|
4796
|
+
]
|
|
4797
|
+
}
|
|
4798
|
+
),
|
|
4799
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "pt-1", children: [
|
|
4800
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system13.Badge, { variant: column.matched ? "secondary" : "outline", className: "text-[11px] font-normal", children: typeWord(column.type) }),
|
|
4801
|
+
column.unit ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "ml-1 opacity-60", children: column.unit }) : null,
|
|
4802
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "mt-0.5 text-muted-foreground", children: column.why }),
|
|
4803
|
+
column.ambiguous ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "text-destructive", children: "Check a date you know before you run this." }) : null,
|
|
4804
|
+
column.collides_with ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "text-destructive", children: "Two columns in this file would make the same column." }) : null
|
|
4805
|
+
] }),
|
|
4806
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "truncate pt-1.5 text-muted-foreground", children: (column.samples ?? []).slice(0, 3).map(String).join(" \xB7 ") })
|
|
4807
|
+
]
|
|
4808
|
+
},
|
|
4809
|
+
column.header
|
|
4810
|
+
);
|
|
4811
|
+
})
|
|
4724
4812
|
] }) }),
|
|
4725
4813
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system13.Separator, {}),
|
|
4726
4814
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex flex-wrap items-center gap-3", children: [
|
|
@@ -4778,13 +4866,18 @@ function ImportWizard({ tableId, onDone, className }) {
|
|
|
4778
4866
|
] })
|
|
4779
4867
|
] }),
|
|
4780
4868
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
4781
|
-
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
4782
|
-
|
|
4783
|
-
|
|
4784
|
-
|
|
4785
|
-
|
|
4786
|
-
|
|
4787
|
-
|
|
4869
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
4870
|
+
import_design_system13.Button,
|
|
4871
|
+
{
|
|
4872
|
+
size: "sm",
|
|
4873
|
+
disabled: busy || !rights.write || rows.length === 0 || titleMissing,
|
|
4874
|
+
onClick: () => void run(),
|
|
4875
|
+
children: phase === "declaring" ? "Adding the columns\u2026" : phase === "writing" ? `Writing\u2026 ${progress} of ${rows.length}` : `Import ${rows.length} row${rows.length === 1 ? "" : "s"}`
|
|
4876
|
+
}
|
|
4877
|
+
),
|
|
4878
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: (0, import_design_system13.cn)("text-muted-foreground", titleMissing && "text-destructive"), children: [
|
|
4879
|
+
titleMissing ? `Nothing goes into ${titleFieldLabel} yet, so these records would have no name. Choose the column above, then this will run.` : `${mappedCount} of ${plan.columns.length} columns go into this table`,
|
|
4880
|
+
fileHash || titleMissing ? "" : " \xB7 this browser cannot recognise the file again, so importing it twice would write it twice"
|
|
4788
4881
|
] })
|
|
4789
4882
|
] })
|
|
4790
4883
|
] }) : null,
|
|
@@ -4802,27 +4895,31 @@ function ImportWizard({ tableId, onDone, className }) {
|
|
|
4802
4895
|
] }) : null
|
|
4803
4896
|
] }) : null,
|
|
4804
4897
|
alreadyRan ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "text-muted-foreground", children: alreadyRan }) : null,
|
|
4805
|
-
outcomes.length > 0 || summary ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
|
|
4898
|
+
outcomes.length > 0 || summary || ledger ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
|
|
4806
4899
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system13.Separator, {}),
|
|
4807
4900
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
4808
|
-
/* @__PURE__ */ (0, import_jsx_runtime16.
|
|
4809
|
-
|
|
4810
|
-
|
|
4811
|
-
counts.duplicate,
|
|
4812
|
-
" already here \xB7 ",
|
|
4813
|
-
counts.refused,
|
|
4814
|
-
" refused"
|
|
4815
|
-
] }),
|
|
4816
|
-
counts.refused + counts.duplicate > 0 ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
|
|
4901
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { children: ledger ? `${ledger.written} landed \xB7 ${ledger.duplicate} already here \xB7 ${ledger.refused} refused, of ${ledger.seen} row${ledger.seen === 1 ? "" : "s"} offered` : `${counts.landed} landed \xB7 ${counts.duplicate} already here \xB7 ${counts.refused} refused` }),
|
|
4902
|
+
ledger && !ledger.final && phase !== "writing" ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "text-destructive", children: "The run stopped here, so the rest of the file was never offered \u2014 these are the rows that were dealt with before it stopped, not the whole file." }) : null,
|
|
4903
|
+
(ledger ? ledger.refused + ledger.duplicate : counts.refused + counts.duplicate) > 0 ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
|
|
4817
4904
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { type: "button", className: (0, import_design_system13.cn)("underline underline-offset-2", show === "all" && "font-medium"), onClick: () => setShow("all"), children: "everything that did not land" }),
|
|
4818
4905
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { type: "button", className: (0, import_design_system13.cn)("underline underline-offset-2", show === "refused" && "font-medium"), onClick: () => setShow("refused"), children: "refused" }),
|
|
4819
4906
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { type: "button", className: (0, import_design_system13.cn)("underline underline-offset-2", show === "duplicate" && "font-medium"), onClick: () => setShow("duplicate"), children: "already here" })
|
|
4820
4907
|
] }) : null
|
|
4821
4908
|
] }),
|
|
4822
4909
|
summary ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "text-muted-foreground", children: summary }) : null,
|
|
4910
|
+
ledger && show === "all" && ledger.refused + ledger.duplicate > interesting.length ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("p", { className: "text-muted-foreground", children: [
|
|
4911
|
+
interesting.length,
|
|
4912
|
+
" of the ",
|
|
4913
|
+
ledger.refused + ledger.duplicate,
|
|
4914
|
+
" row",
|
|
4915
|
+
ledger.refused + ledger.duplicate === 1 ? " that" : "s that",
|
|
4916
|
+
" did not land",
|
|
4917
|
+
interesting.length === 1 ? " is" : " are",
|
|
4918
|
+
" listed below by their line in your file \u2014 the store keeps the rest with this run and does not hand every one of them back at once."
|
|
4919
|
+
] }) : null,
|
|
4823
4920
|
interesting.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "max-h-64 overflow-auto rounded border", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("table", { className: "w-full", children: [
|
|
4824
4921
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("thead", { className: "sticky top-0 bg-muted", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("tr", { children: [
|
|
4825
|
-
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("th", { className: "px-2 py-1 text-left font-medium", children: "
|
|
4922
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("th", { className: "px-2 py-1 text-left font-medium", children: "Line in your file" }),
|
|
4826
4923
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("th", { className: "px-2 py-1 text-left font-medium", children: "What happened" }),
|
|
4827
4924
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("th", { className: "px-2 py-1 text-left font-medium", children: "The row in your file" })
|
|
4828
4925
|
] }) }),
|
|
@@ -6201,8 +6298,8 @@ function TableSettings({
|
|
|
6201
6298
|
const table = (0, import_react36.useTable)(tableId);
|
|
6202
6299
|
const fields = (0, import_react36.useFields)(tableId);
|
|
6203
6300
|
const rights = useTableRights(table.data);
|
|
6204
|
-
const mutation = (0, import_react36.useRecordMutation)();
|
|
6205
6301
|
const shape = (0, import_react36.useFieldMutation)();
|
|
6302
|
+
const archive = (0, import_react36.useTableArchive)(tableId);
|
|
6206
6303
|
const [editing, setEditing] = (0, import_react35.useState)(null);
|
|
6207
6304
|
const [askingToDelete, setAskingToDelete] = (0, import_react35.useState)(false);
|
|
6208
6305
|
const [askingToRemove, setAskingToRemove] = (0, import_react35.useState)(null);
|
|
@@ -6227,10 +6324,16 @@ function TableSettings({
|
|
|
6227
6324
|
table.reload();
|
|
6228
6325
|
}
|
|
6229
6326
|
};
|
|
6230
|
-
const
|
|
6231
|
-
const
|
|
6232
|
-
|
|
6233
|
-
|
|
6327
|
+
const startArchive = async () => {
|
|
6328
|
+
const finished = await archive.start();
|
|
6329
|
+
if (finished?.done && finished.table_archived) {
|
|
6330
|
+
setAskingToDelete(false);
|
|
6331
|
+
onDeleted?.();
|
|
6332
|
+
}
|
|
6333
|
+
};
|
|
6334
|
+
const askToArchive = async () => {
|
|
6335
|
+
setAskingToDelete(true);
|
|
6336
|
+
await archive.preview();
|
|
6234
6337
|
};
|
|
6235
6338
|
if (enriching) {
|
|
6236
6339
|
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className, children: [
|
|
@@ -6266,7 +6369,6 @@ function TableSettings({
|
|
|
6266
6369
|
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-muted-foreground", children: rows.length }),
|
|
6267
6370
|
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_design_system18.Button, { size: "sm", variant: "outline", className: "ml-auto", onClick: () => setEditing("new"), children: "Add a field" })
|
|
6268
6371
|
] }),
|
|
6269
|
-
mutation.error ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(RefusalNotice, { error: mutation.error }) : null,
|
|
6270
6372
|
shape.error ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(RefusalNotice, { error: shape.error }) : null,
|
|
6271
6373
|
askingToRemove ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex flex-wrap items-center gap-2 rounded border border-destructive/40 px-2 py-1.5", children: [
|
|
6272
6374
|
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { className: "text-destructive", children: [
|
|
@@ -6357,21 +6459,32 @@ function TableSettings({
|
|
|
6357
6459
|
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "font-medium", children: "This table" }),
|
|
6358
6460
|
askingToDelete ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
|
|
6359
6461
|
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("p", { className: "text-muted-foreground", children: [
|
|
6360
|
-
"
|
|
6462
|
+
"Archiving ",
|
|
6361
6463
|
table.data ? tableName(table.data) : "this table",
|
|
6362
6464
|
" takes it out of everyone's list, with its ",
|
|
6363
6465
|
rows.length,
|
|
6364
6466
|
" field",
|
|
6365
6467
|
rows.length === 1 ? "" : "s",
|
|
6366
|
-
" and
|
|
6367
|
-
|
|
6468
|
+
" and",
|
|
6469
|
+
" ",
|
|
6470
|
+
archive.progress ? `its ${archive.progress.remaining.toLocaleString()} record${archive.progress.remaining === 1 ? "" : "s"}` : "every record in it",
|
|
6471
|
+
".",
|
|
6472
|
+
table.data?.retention_days ? ` The store keeps them for ${table.data.retention_days} days, so it can still be brought back.` : " The store keeps them, so it can still be brought back."
|
|
6368
6473
|
] }),
|
|
6369
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("
|
|
6370
|
-
|
|
6474
|
+
archive.progress && (archive.running || archive.passes > 0) ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("p", { className: archive.error ? "text-destructive" : "text-muted-foreground", children: [
|
|
6475
|
+
archive.progress.total - archive.progress.remaining === archive.progress.total ? `All ${archive.progress.total.toLocaleString()} record${archive.progress.total === 1 ? "" : "s"} are put away.` : `${(archive.progress.total - archive.progress.remaining).toLocaleString()} of ${archive.progress.total.toLocaleString()} record${archive.progress.total === 1 ? "" : "s"} put away so far.`,
|
|
6476
|
+
archive.slowedDown ? " The store is busy, so it is taking smaller passes \u2014 it will still finish." : ""
|
|
6477
|
+
] }) : null,
|
|
6478
|
+
archive.interrupted && archive.progress ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "text-muted-foreground", children: archive.error ? `That pass did not finish, so the rest is still here. ${archive.progress.archived_total.toLocaleString()} record${archive.progress.archived_total === 1 ? " is" : "s are"} already archived and ${archive.progress.remaining.toLocaleString()} ${archive.progress.remaining === 1 ? "is" : "are"} left. Nothing was lost \u2014 carry on and it picks up where it stopped.` : `Stopped. ${archive.progress.archived_total.toLocaleString()} record${archive.progress.archived_total === 1 ? " is" : "s are"} archived and ${archive.progress.remaining.toLocaleString()} ${archive.progress.remaining === 1 ? "is" : "are"} left. Carry on whenever you like \u2014 it picks up where it stopped.` }) : null,
|
|
6479
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex gap-1", children: archive.running ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
|
|
6480
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_design_system18.Button, { size: "sm", variant: "destructive", disabled: true, children: "Archiving\u2026" }),
|
|
6481
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_design_system18.Button, { size: "sm", variant: "ghost", onClick: () => archive.stop(), children: "Stop" })
|
|
6482
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
|
|
6483
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_design_system18.Button, { size: "sm", variant: "destructive", onClick: () => void startArchive(), children: archive.interrupted ? "Carry on archiving" : "Archive this table" }),
|
|
6371
6484
|
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_design_system18.Button, { size: "sm", variant: "ghost", onClick: () => setAskingToDelete(false), children: "Keep it" })
|
|
6372
|
-
] })
|
|
6373
|
-
] }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_design_system18.Button, { size: "sm", variant: "outline", onClick: () =>
|
|
6374
|
-
|
|
6485
|
+
] }) })
|
|
6486
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_design_system18.Button, { size: "sm", variant: "outline", onClick: () => void askToArchive(), children: "Archive this table" }) }),
|
|
6487
|
+
archive.error ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(RefusalNotice, { error: archive.error }) : null
|
|
6375
6488
|
] })
|
|
6376
6489
|
] });
|
|
6377
6490
|
}
|
|
@@ -7671,6 +7784,7 @@ function ViewSwitcher({
|
|
|
7671
7784
|
)
|
|
7672
7785
|
] });
|
|
7673
7786
|
}
|
|
7787
|
+
var UNUSUAL_FIELD_NOTE = "an unusual column to use here";
|
|
7674
7788
|
function offerableFields(all, want) {
|
|
7675
7789
|
return all.filter((field) => {
|
|
7676
7790
|
const kind = editorKindFor(field);
|
|
@@ -7806,10 +7920,7 @@ function FieldPicker({
|
|
|
7806
7920
|
children: [
|
|
7807
7921
|
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("option", { value: "", children: "Choose a field" }),
|
|
7808
7922
|
offerable.map((field) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("option", { value: field.key, children: fieldName(field) }, field.key)),
|
|
7809
|
-
unusual ? /* @__PURE__ */ (0, import_jsx_runtime27.
|
|
7810
|
-
fieldName(unusual),
|
|
7811
|
-
" \u2014 an unusual column to use here"
|
|
7812
|
-
] }, unusual.key) : null
|
|
7923
|
+
unusual ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("option", { value: unusual.key, children: `${fieldName(unusual)} \u2014 ${UNUSUAL_FIELD_NOTE}` }, unusual.key) : null
|
|
7813
7924
|
]
|
|
7814
7925
|
}
|
|
7815
7926
|
),
|
|
@@ -11622,14 +11733,41 @@ function SubscriptionsPanel({ tableId, className }) {
|
|
|
11622
11733
|
}
|
|
11623
11734
|
|
|
11624
11735
|
// src/FormBuilder.tsx
|
|
11625
|
-
var
|
|
11626
|
-
var
|
|
11736
|
+
var import_react83 = require("react");
|
|
11737
|
+
var import_react84 = require("@ai-matrx/records/react");
|
|
11738
|
+
|
|
11739
|
+
// src/publish-gate.ts
|
|
11740
|
+
var import_react79 = require("react");
|
|
11741
|
+
var import_react80 = require("@ai-matrx/records/react");
|
|
11742
|
+
var PUBLISH_NEEDS_THE_STORE_ON = "This organization has its record store switched off, so publishing would hand you a link that opens nothing. An owner or an administrator turns it on under Database settings, on the unified data screen \u2014 everything you have already built here is kept and starts working the moment they do.";
|
|
11743
|
+
function usePublishGate() {
|
|
11744
|
+
const client = (0, import_react80.useRecordsClient)();
|
|
11745
|
+
const [storeOpen, setStoreOpen] = (0, import_react79.useState)(null);
|
|
11746
|
+
(0, import_react79.useEffect)(() => {
|
|
11747
|
+
let alive = true;
|
|
11748
|
+
void (async () => {
|
|
11749
|
+
const answered = await client.storeIsOpen();
|
|
11750
|
+
if (!alive) return;
|
|
11751
|
+
setStoreOpen(answered.ok ? answered.data : null);
|
|
11752
|
+
})();
|
|
11753
|
+
return () => {
|
|
11754
|
+
alive = false;
|
|
11755
|
+
};
|
|
11756
|
+
}, [client]);
|
|
11757
|
+
return {
|
|
11758
|
+
storeOpen,
|
|
11759
|
+
blocked: storeOpen === false,
|
|
11760
|
+
why: storeOpen === false ? PUBLISH_NEEDS_THE_STORE_ON : null
|
|
11761
|
+
};
|
|
11762
|
+
}
|
|
11763
|
+
|
|
11764
|
+
// src/FormBuilder.tsx
|
|
11627
11765
|
var import_records10 = require("@ai-matrx/records");
|
|
11628
11766
|
var import_design_system40 = require("@ai-matrx/design-system");
|
|
11629
11767
|
|
|
11630
11768
|
// src/FormRunner.tsx
|
|
11631
|
-
var
|
|
11632
|
-
var
|
|
11769
|
+
var import_react81 = require("react");
|
|
11770
|
+
var import_react82 = require("@ai-matrx/records/react");
|
|
11633
11771
|
var import_design_system39 = require("@ai-matrx/design-system");
|
|
11634
11772
|
var import_jsx_runtime42 = require("react/jsx-runtime");
|
|
11635
11773
|
function FormRunner(props) {
|
|
@@ -11639,10 +11777,10 @@ function FormRunner(props) {
|
|
|
11639
11777
|
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(ConnectedFormRunner, { ...props });
|
|
11640
11778
|
}
|
|
11641
11779
|
function ConnectedFormRunner(props) {
|
|
11642
|
-
const client = (0,
|
|
11643
|
-
const fields = (0,
|
|
11780
|
+
const client = (0, import_react82.useOptionalRecordsClient)();
|
|
11781
|
+
const fields = (0, import_react82.useFields)(props.form.subject);
|
|
11644
11782
|
const { form, className } = props;
|
|
11645
|
-
const submit = (0,
|
|
11783
|
+
const submit = (0, import_react81.useCallback)(
|
|
11646
11784
|
async (values) => {
|
|
11647
11785
|
if (!client) {
|
|
11648
11786
|
return {
|
|
@@ -11665,7 +11803,7 @@ function ConnectedFormRunner(props) {
|
|
|
11665
11803
|
},
|
|
11666
11804
|
[client, form]
|
|
11667
11805
|
);
|
|
11668
|
-
const evaluate = (0,
|
|
11806
|
+
const evaluate = (0, import_react81.useCallback)(
|
|
11669
11807
|
async (expr, values) => {
|
|
11670
11808
|
if (!client) return null;
|
|
11671
11809
|
const answered = await client.ruleEval({ expr, values });
|
|
@@ -11699,16 +11837,16 @@ function FormStage({
|
|
|
11699
11837
|
connected = false
|
|
11700
11838
|
}) {
|
|
11701
11839
|
const host = useRecordsUi();
|
|
11702
|
-
const [answers, setAnswers] = (0,
|
|
11703
|
-
const [at, setAt] = (0,
|
|
11704
|
-
const [error, setError] = (0,
|
|
11705
|
-
const [refusal, setRefusal] = (0,
|
|
11706
|
-
const [writing, setWriting] = (0,
|
|
11707
|
-
const [done, setDone] = (0,
|
|
11708
|
-
const [hidden, setHidden] = (0,
|
|
11709
|
-
const decoy = (0,
|
|
11710
|
-
const stage = (0,
|
|
11711
|
-
const questions = (0,
|
|
11840
|
+
const [answers, setAnswers] = (0, import_react81.useState)({});
|
|
11841
|
+
const [at, setAt] = (0, import_react81.useState)(0);
|
|
11842
|
+
const [error, setError] = (0, import_react81.useState)(null);
|
|
11843
|
+
const [refusal, setRefusal] = (0, import_react81.useState)(null);
|
|
11844
|
+
const [writing, setWriting] = (0, import_react81.useState)(false);
|
|
11845
|
+
const [done, setDone] = (0, import_react81.useState)(null);
|
|
11846
|
+
const [hidden, setHidden] = (0, import_react81.useState)({});
|
|
11847
|
+
const decoy = (0, import_react81.useRef)("");
|
|
11848
|
+
const stage = (0, import_react81.useRef)(null);
|
|
11849
|
+
const questions = (0, import_react81.useMemo)(() => {
|
|
11712
11850
|
const byKey = new Map((fields ?? []).map((f) => [f.key, f]));
|
|
11713
11851
|
return (form.questions ?? []).map((q) => {
|
|
11714
11852
|
const field = byKey.get(q.field) ?? null;
|
|
@@ -11722,7 +11860,7 @@ function FormStage({
|
|
|
11722
11860
|
};
|
|
11723
11861
|
});
|
|
11724
11862
|
}, [fields, form.questions]);
|
|
11725
|
-
(0,
|
|
11863
|
+
(0, import_react81.useEffect)(() => {
|
|
11726
11864
|
let cancelled = false;
|
|
11727
11865
|
const conditional = questions.filter((q) => q.showIf);
|
|
11728
11866
|
if (conditional.length === 0 || !evaluate) return;
|
|
@@ -11756,7 +11894,7 @@ function FormStage({
|
|
|
11756
11894
|
const v = answers[q.key];
|
|
11757
11895
|
return q.required && (v === void 0 || v === null || v === "");
|
|
11758
11896
|
});
|
|
11759
|
-
const submit = (0,
|
|
11897
|
+
const submit = (0, import_react81.useCallback)(async () => {
|
|
11760
11898
|
if (preview) {
|
|
11761
11899
|
setDone("preview");
|
|
11762
11900
|
return;
|
|
@@ -11793,7 +11931,7 @@ function FormStage({
|
|
|
11793
11931
|
if (event.shiftKey) retreat();
|
|
11794
11932
|
else advance();
|
|
11795
11933
|
}
|
|
11796
|
-
(0,
|
|
11934
|
+
(0, import_react81.useEffect)(() => {
|
|
11797
11935
|
const input = stage.current?.querySelector(
|
|
11798
11936
|
"input:not([tabindex='-1']), textarea, select, [role='combobox']"
|
|
11799
11937
|
);
|
|
@@ -11887,7 +12025,7 @@ function Question({
|
|
|
11887
12025
|
onChange,
|
|
11888
12026
|
upload
|
|
11889
12027
|
}) {
|
|
11890
|
-
const [uploadError, setUploadError] = (0,
|
|
12028
|
+
const [uploadError, setUploadError] = (0, import_react81.useState)(null);
|
|
11891
12029
|
const field = question.field;
|
|
11892
12030
|
if (!field) return null;
|
|
11893
12031
|
const id = `form-${field.key}`;
|
|
@@ -11944,23 +12082,24 @@ function whyNotAskable(fields, hidden = []) {
|
|
|
11944
12082
|
// src/FormBuilder.tsx
|
|
11945
12083
|
var import_jsx_runtime43 = require("react/jsx-runtime");
|
|
11946
12084
|
function FormBuilder({ tableId, seed, activeFormId, onActiveForm, className }) {
|
|
11947
|
-
const client = (0,
|
|
12085
|
+
const client = (0, import_react84.useRecordsClient)();
|
|
12086
|
+
const publishGate = usePublishGate();
|
|
11948
12087
|
const host = useRecordsUi();
|
|
11949
12088
|
const claimSeed = useSeedGuard();
|
|
11950
|
-
const table = (0,
|
|
12089
|
+
const table = (0, import_react84.useTable)(tableId);
|
|
11951
12090
|
const rights = useTableRights(table.data);
|
|
11952
|
-
const fields = (0,
|
|
11953
|
-
const [forms, setForms] = (0,
|
|
11954
|
-
const [error, setError] = (0,
|
|
11955
|
-
const [activeId, setActiveId] = (0,
|
|
11956
|
-
const [draft, setDraft] = (0,
|
|
11957
|
-
const [saving, setSaving] = (0,
|
|
11958
|
-
const [saved, setSaved] = (0,
|
|
11959
|
-
const [publishing, setPublishing] = (0,
|
|
11960
|
-
const [copied, setCopied] = (0,
|
|
11961
|
-
const [shownUrl, setShownUrl] = (0,
|
|
12091
|
+
const fields = (0, import_react84.useFields)(tableId);
|
|
12092
|
+
const [forms, setForms] = (0, import_react83.useState)(null);
|
|
12093
|
+
const [error, setError] = (0, import_react83.useState)(null);
|
|
12094
|
+
const [activeId, setActiveId] = (0, import_react83.useState)(activeFormId ?? null);
|
|
12095
|
+
const [draft, setDraft] = (0, import_react83.useState)(null);
|
|
12096
|
+
const [saving, setSaving] = (0, import_react83.useState)(false);
|
|
12097
|
+
const [saved, setSaved] = (0, import_react83.useState)(null);
|
|
12098
|
+
const [publishing, setPublishing] = (0, import_react83.useState)(false);
|
|
12099
|
+
const [copied, setCopied] = (0, import_react83.useState)(false);
|
|
12100
|
+
const [shownUrl, setShownUrl] = (0, import_react83.useState)(null);
|
|
11962
12101
|
const publicOrigin = host.publicOrigin ?? (typeof window === "undefined" ? "" : window.location.origin);
|
|
11963
|
-
const load = (0,
|
|
12102
|
+
const load = (0, import_react83.useCallback)(async () => {
|
|
11964
12103
|
const answered = await client.forms({ table_id: tableId });
|
|
11965
12104
|
if (!answered.ok) {
|
|
11966
12105
|
setError(answered.error);
|
|
@@ -11987,17 +12126,17 @@ function FormBuilder({ tableId, seed, activeFormId, onActiveForm, className }) {
|
|
|
11987
12126
|
setError(null);
|
|
11988
12127
|
setForms(mine);
|
|
11989
12128
|
}, [client, tableId, seed, claimSeed]);
|
|
11990
|
-
(0,
|
|
12129
|
+
(0, import_react83.useEffect)(() => {
|
|
11991
12130
|
void load();
|
|
11992
12131
|
}, [load]);
|
|
11993
|
-
(0,
|
|
12132
|
+
(0, import_react83.useEffect)(() => {
|
|
11994
12133
|
if (!forms || forms.length === 0) return;
|
|
11995
12134
|
const chosen = forms.find((f) => f.id === (activeFormId ?? activeId)) ?? forms[0];
|
|
11996
12135
|
if (chosen.id !== activeId) setActiveId(chosen.id);
|
|
11997
12136
|
setDraft(chosen);
|
|
11998
12137
|
onActiveForm?.(chosen);
|
|
11999
12138
|
}, [forms, activeFormId]);
|
|
12000
|
-
const byKey = (0,
|
|
12139
|
+
const byKey = (0, import_react83.useMemo)(() => new Map((fields.data ?? []).map((f) => [f.key, f])), [fields.data]);
|
|
12001
12140
|
function patch(change) {
|
|
12002
12141
|
setDraft((prev) => prev ? { ...prev, ...change } : prev);
|
|
12003
12142
|
setSaved(null);
|
|
@@ -12101,8 +12240,8 @@ function FormBuilder({ tableId, seed, activeFormId, onActiveForm, className }) {
|
|
|
12101
12240
|
{
|
|
12102
12241
|
url: `${publicOrigin}${(0, import_records10.publicFormPath)(draft.id)}`,
|
|
12103
12242
|
state: draft.state,
|
|
12104
|
-
mayPublish: rights.structure,
|
|
12105
|
-
why: rights.why("structure"),
|
|
12243
|
+
mayPublish: rights.structure && !publishGate.blocked,
|
|
12244
|
+
why: publishGate.why ?? rights.why("structure"),
|
|
12106
12245
|
busy: publishing,
|
|
12107
12246
|
copied,
|
|
12108
12247
|
shownUrl,
|
|
@@ -12400,13 +12539,13 @@ function groupLabel(groups) {
|
|
|
12400
12539
|
}
|
|
12401
12540
|
|
|
12402
12541
|
// src/chartFrame.tsx
|
|
12403
|
-
var
|
|
12542
|
+
var import_react85 = require("react");
|
|
12404
12543
|
var import_design_system41 = require("@ai-matrx/design-system");
|
|
12405
12544
|
var import_jsx_runtime44 = require("react/jsx-runtime");
|
|
12406
12545
|
function useMeasuredWidth(fallback = 480) {
|
|
12407
|
-
const ref = (0,
|
|
12408
|
-
const [width, setWidth] = (0,
|
|
12409
|
-
(0,
|
|
12546
|
+
const ref = (0, import_react85.useRef)(null);
|
|
12547
|
+
const [width, setWidth] = (0, import_react85.useState)(fallback);
|
|
12548
|
+
(0, import_react85.useEffect)(() => {
|
|
12410
12549
|
const node = ref.current;
|
|
12411
12550
|
if (!node) return;
|
|
12412
12551
|
const apply = () => {
|
|
@@ -12436,7 +12575,7 @@ function ChartFrame({
|
|
|
12436
12575
|
children
|
|
12437
12576
|
}) {
|
|
12438
12577
|
const [ref, width] = useMeasuredWidth();
|
|
12439
|
-
const chartId = `records-chart-${(0,
|
|
12578
|
+
const chartId = `records-chart-${(0, import_react85.useId)().replace(/:/g, "")}`;
|
|
12440
12579
|
return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
12441
12580
|
"div",
|
|
12442
12581
|
{
|
|
@@ -12530,24 +12669,24 @@ function isSignatureField(field) {
|
|
|
12530
12669
|
}
|
|
12531
12670
|
|
|
12532
12671
|
// src/DocTemplate.tsx
|
|
12533
|
-
var
|
|
12534
|
-
var
|
|
12672
|
+
var import_react86 = require("react");
|
|
12673
|
+
var import_react87 = require("@ai-matrx/records/react");
|
|
12535
12674
|
var import_design_system42 = require("@ai-matrx/design-system");
|
|
12536
12675
|
var import_jsx_runtime45 = require("react/jsx-runtime");
|
|
12537
12676
|
function DocTemplate({ tableId, seed, activeTemplateId, onActiveTemplate, className }) {
|
|
12538
|
-
const client = (0,
|
|
12677
|
+
const client = (0, import_react87.useRecordsClient)();
|
|
12539
12678
|
const claimSeed = useSeedGuard();
|
|
12540
|
-
const table = (0,
|
|
12679
|
+
const table = (0, import_react87.useTable)(tableId);
|
|
12541
12680
|
const rights = useTableRights(table.data);
|
|
12542
|
-
const fields = (0,
|
|
12543
|
-
const [templates, setTemplates] = (0,
|
|
12544
|
-
const [error, setError] = (0,
|
|
12545
|
-
const [activeId, setActiveId] = (0,
|
|
12546
|
-
const [draftName, setDraftName] = (0,
|
|
12547
|
-
const [draftBody, setDraftBody] = (0,
|
|
12548
|
-
const [unresolved, setUnresolved] = (0,
|
|
12549
|
-
const [saving, setSaving] = (0,
|
|
12550
|
-
const load = (0,
|
|
12681
|
+
const fields = (0, import_react87.useFields)(tableId);
|
|
12682
|
+
const [templates, setTemplates] = (0, import_react86.useState)(null);
|
|
12683
|
+
const [error, setError] = (0, import_react86.useState)(null);
|
|
12684
|
+
const [activeId, setActiveId] = (0, import_react86.useState)(activeTemplateId ?? null);
|
|
12685
|
+
const [draftName, setDraftName] = (0, import_react86.useState)("");
|
|
12686
|
+
const [draftBody, setDraftBody] = (0, import_react86.useState)("");
|
|
12687
|
+
const [unresolved, setUnresolved] = (0, import_react86.useState)([]);
|
|
12688
|
+
const [saving, setSaving] = (0, import_react86.useState)(false);
|
|
12689
|
+
const load = (0, import_react86.useCallback)(async () => {
|
|
12551
12690
|
const held = await client.docTemplates({ table_id: tableId });
|
|
12552
12691
|
if (!held.ok) {
|
|
12553
12692
|
setError(held.error);
|
|
@@ -12578,10 +12717,10 @@ function DocTemplate({ tableId, seed, activeTemplateId, onActiveTemplate, classN
|
|
|
12578
12717
|
setError(null);
|
|
12579
12718
|
setTemplates(rows);
|
|
12580
12719
|
}, [client, tableId, seed, fields.data]);
|
|
12581
|
-
(0,
|
|
12720
|
+
(0, import_react86.useEffect)(() => {
|
|
12582
12721
|
void load();
|
|
12583
12722
|
}, [load]);
|
|
12584
|
-
(0,
|
|
12723
|
+
(0, import_react86.useEffect)(() => {
|
|
12585
12724
|
if (!templates || templates.length === 0) return;
|
|
12586
12725
|
const chosen = templates.find((t) => t.id === (activeTemplateId ?? activeId)) ?? templates[0];
|
|
12587
12726
|
if (chosen.id !== activeId) setActiveId(chosen.id);
|
|
@@ -12589,7 +12728,7 @@ function DocTemplate({ tableId, seed, activeTemplateId, onActiveTemplate, classN
|
|
|
12589
12728
|
setDraftBody(chosen.body);
|
|
12590
12729
|
onActiveTemplate?.(chosen);
|
|
12591
12730
|
}, [templates, activeTemplateId]);
|
|
12592
|
-
(0,
|
|
12731
|
+
(0, import_react86.useEffect)(() => {
|
|
12593
12732
|
let cancelled = false;
|
|
12594
12733
|
if (draftBody.trim() === "") {
|
|
12595
12734
|
setUnresolved([]);
|
|
@@ -12709,19 +12848,19 @@ function DocTemplate({ tableId, seed, activeTemplateId, onActiveTemplate, classN
|
|
|
12709
12848
|
}
|
|
12710
12849
|
|
|
12711
12850
|
// src/DocRender.tsx
|
|
12712
|
-
var
|
|
12713
|
-
var
|
|
12851
|
+
var import_react88 = require("react");
|
|
12852
|
+
var import_react89 = require("@ai-matrx/records/react");
|
|
12714
12853
|
var import_design_system43 = require("@ai-matrx/design-system");
|
|
12715
12854
|
var import_jsx_runtime46 = require("react/jsx-runtime");
|
|
12716
12855
|
function DocRender({ templateId, recordId, filename, onRendered, className }) {
|
|
12717
|
-
const client = (0,
|
|
12718
|
-
const [preview, setPreview] = (0,
|
|
12719
|
-
const [renders, setRenders] = (0,
|
|
12720
|
-
const [showing, setShowing] = (0,
|
|
12721
|
-
const [error, setError] = (0,
|
|
12722
|
-
const [busy, setBusy] = (0,
|
|
12723
|
-
const paper = (0,
|
|
12724
|
-
const load = (0,
|
|
12856
|
+
const client = (0, import_react89.useRecordsClient)();
|
|
12857
|
+
const [preview, setPreview] = (0, import_react88.useState)(null);
|
|
12858
|
+
const [renders, setRenders] = (0, import_react88.useState)(null);
|
|
12859
|
+
const [showing, setShowing] = (0, import_react88.useState)(null);
|
|
12860
|
+
const [error, setError] = (0, import_react88.useState)(null);
|
|
12861
|
+
const [busy, setBusy] = (0, import_react88.useState)(null);
|
|
12862
|
+
const paper = (0, import_react88.useRef)(null);
|
|
12863
|
+
const load = (0, import_react88.useCallback)(async () => {
|
|
12725
12864
|
const [body, held] = await Promise.all([
|
|
12726
12865
|
client.docRenderBody({ template_id: templateId, record_id: recordId }),
|
|
12727
12866
|
client.docRenders({ record_id: recordId })
|
|
@@ -12738,7 +12877,7 @@ function DocRender({ templateId, recordId, filename, onRendered, className }) {
|
|
|
12738
12877
|
setPreview(body.data);
|
|
12739
12878
|
setRenders(held.data.filter((r) => r.template_id === templateId));
|
|
12740
12879
|
}, [client, templateId, recordId]);
|
|
12741
|
-
(0,
|
|
12880
|
+
(0, import_react88.useEffect)(() => {
|
|
12742
12881
|
void load();
|
|
12743
12882
|
}, [load]);
|
|
12744
12883
|
async function freeze() {
|
|
@@ -12822,22 +12961,22 @@ function DocRender({ templateId, recordId, filename, onRendered, className }) {
|
|
|
12822
12961
|
}
|
|
12823
12962
|
|
|
12824
12963
|
// src/SignBlock.tsx
|
|
12825
|
-
var
|
|
12826
|
-
var
|
|
12964
|
+
var import_react90 = require("react");
|
|
12965
|
+
var import_react91 = require("@ai-matrx/records/react");
|
|
12827
12966
|
var import_design_system44 = require("@ai-matrx/design-system");
|
|
12828
|
-
var
|
|
12967
|
+
var import_react92 = require("@ai-matrx/records/react");
|
|
12829
12968
|
var import_jsx_runtime47 = require("react/jsx-runtime");
|
|
12830
12969
|
function SignBlock({ tableId, recordId, render, className }) {
|
|
12831
|
-
const client = (0,
|
|
12832
|
-
const table = (0,
|
|
12970
|
+
const client = (0, import_react91.useRecordsClient)();
|
|
12971
|
+
const table = (0, import_react92.useTable)(tableId);
|
|
12833
12972
|
const rights = useTableRights(table.data);
|
|
12834
|
-
const fields = (0,
|
|
12835
|
-
const [signatures, setSignatures] = (0,
|
|
12836
|
-
const [verdicts, setVerdicts] = (0,
|
|
12837
|
-
const [error, setError] = (0,
|
|
12838
|
-
const [name, setName] = (0,
|
|
12839
|
-
const [busy, setBusy] = (0,
|
|
12840
|
-
const load = (0,
|
|
12973
|
+
const fields = (0, import_react91.useFields)(tableId);
|
|
12974
|
+
const [signatures, setSignatures] = (0, import_react90.useState)(null);
|
|
12975
|
+
const [verdicts, setVerdicts] = (0, import_react90.useState)({});
|
|
12976
|
+
const [error, setError] = (0, import_react90.useState)(null);
|
|
12977
|
+
const [name, setName] = (0, import_react90.useState)("");
|
|
12978
|
+
const [busy, setBusy] = (0, import_react90.useState)(false);
|
|
12979
|
+
const load = (0, import_react90.useCallback)(async () => {
|
|
12841
12980
|
const held = await client.docSignatures({ record_id: recordId });
|
|
12842
12981
|
if (!held.ok) {
|
|
12843
12982
|
setError(held.error);
|
|
@@ -12852,7 +12991,7 @@ function SignBlock({ tableId, recordId, render, className }) {
|
|
|
12852
12991
|
}
|
|
12853
12992
|
setVerdicts(answers);
|
|
12854
12993
|
}, [client, recordId]);
|
|
12855
|
-
(0,
|
|
12994
|
+
(0, import_react90.useEffect)(() => {
|
|
12856
12995
|
void load();
|
|
12857
12996
|
}, [load]);
|
|
12858
12997
|
async function sign(field) {
|
|
@@ -12959,23 +13098,23 @@ function SignBlock({ tableId, recordId, render, className }) {
|
|
|
12959
13098
|
}
|
|
12960
13099
|
|
|
12961
13100
|
// src/NotifyRuleEditor.tsx
|
|
12962
|
-
var
|
|
12963
|
-
var
|
|
13101
|
+
var import_react93 = require("react");
|
|
13102
|
+
var import_react94 = require("@ai-matrx/records/react");
|
|
12964
13103
|
var import_design_system45 = require("@ai-matrx/design-system");
|
|
12965
13104
|
var import_jsx_runtime48 = require("react/jsx-runtime");
|
|
12966
13105
|
var CADENCE_WORDS2 = SUBSCRIPTION_CADENCE_LABEL;
|
|
12967
13106
|
var CHANNEL_WORDS3 = SUBSCRIPTION_CHANNEL_LABEL;
|
|
12968
13107
|
function NotifyRuleEditor({ tableId, seed, className }) {
|
|
12969
|
-
const client = (0,
|
|
13108
|
+
const client = (0, import_react94.useRecordsClient)();
|
|
12970
13109
|
const host = useRecordsUi();
|
|
12971
|
-
const table = (0,
|
|
13110
|
+
const table = (0, import_react94.useTable)(tableId);
|
|
12972
13111
|
const rights = useTableRights(table.data);
|
|
12973
|
-
const [subscriptions, setSubscriptions] = (0,
|
|
12974
|
-
const [cadences, setCadences] = (0,
|
|
12975
|
-
const [views, setViews] = (0,
|
|
12976
|
-
const [error, setError] = (0,
|
|
12977
|
-
const [busy, setBusy] = (0,
|
|
12978
|
-
const load = (0,
|
|
13112
|
+
const [subscriptions, setSubscriptions] = (0, import_react93.useState)(null);
|
|
13113
|
+
const [cadences, setCadences] = (0, import_react93.useState)([]);
|
|
13114
|
+
const [views, setViews] = (0, import_react93.useState)(null);
|
|
13115
|
+
const [error, setError] = (0, import_react93.useState)(null);
|
|
13116
|
+
const [busy, setBusy] = (0, import_react93.useState)(false);
|
|
13117
|
+
const load = (0, import_react93.useCallback)(async () => {
|
|
12979
13118
|
const [held, offered] = await Promise.all([
|
|
12980
13119
|
// THE PERSON'S OWN DOOR, not the notifier's. It answers what is addressed
|
|
12981
13120
|
// to them plus — only where they hold admin on this Table — anyone's over
|
|
@@ -12995,10 +13134,10 @@ function NotifyRuleEditor({ tableId, seed, className }) {
|
|
|
12995
13134
|
if (host.savedViews) setViews(await host.savedViews());
|
|
12996
13135
|
else setViews(null);
|
|
12997
13136
|
}, [client, host, tableId]);
|
|
12998
|
-
(0,
|
|
13137
|
+
(0, import_react93.useEffect)(() => {
|
|
12999
13138
|
void load();
|
|
13000
13139
|
}, [load]);
|
|
13001
|
-
const write = (0,
|
|
13140
|
+
const write = (0, import_react93.useCallback)(
|
|
13002
13141
|
async (spec) => {
|
|
13003
13142
|
const declared = await client.subscriptionDeclare({
|
|
13004
13143
|
table_id: tableId,
|
|
@@ -13023,7 +13162,7 @@ function NotifyRuleEditor({ tableId, seed, className }) {
|
|
|
13023
13162
|
},
|
|
13024
13163
|
[client, tableId]
|
|
13025
13164
|
);
|
|
13026
|
-
(0,
|
|
13165
|
+
(0, import_react93.useEffect)(() => {
|
|
13027
13166
|
if (!subscriptions || !seed || seed.length === 0) return;
|
|
13028
13167
|
const missing = seed.filter((s) => !subscriptions.some((held) => held.name === s.name));
|
|
13029
13168
|
if (missing.length === 0) return;
|
|
@@ -13166,7 +13305,7 @@ function NotifyRuleEditor({ tableId, seed, className }) {
|
|
|
13166
13305
|
}
|
|
13167
13306
|
|
|
13168
13307
|
// src/ChartBlock.tsx
|
|
13169
|
-
var
|
|
13308
|
+
var import_react95 = require("react");
|
|
13170
13309
|
var import_recharts = require("recharts");
|
|
13171
13310
|
var import_records11 = require("@ai-matrx/records");
|
|
13172
13311
|
var import_core6 = require("@ai-matrx/records/core");
|
|
@@ -13191,7 +13330,7 @@ function ChartBlock({ block, subject, className }) {
|
|
|
13191
13330
|
const measures = block.measures && block.measures.length > 0 ? block.measures : [{ op: "count" }];
|
|
13192
13331
|
const primary = (0, import_records11.measureKey)(measures[0]);
|
|
13193
13332
|
const series = [primary];
|
|
13194
|
-
const points = (0,
|
|
13333
|
+
const points = (0, import_react95.useMemo)(() => {
|
|
13195
13334
|
if (kind === "stuck") return [];
|
|
13196
13335
|
const rows = block.rows ?? [];
|
|
13197
13336
|
return rows.map((row) => ({
|
|
@@ -13203,7 +13342,7 @@ function ChartBlock({ block, subject, className }) {
|
|
|
13203
13342
|
n: row.row_count
|
|
13204
13343
|
}));
|
|
13205
13344
|
}, [block.rows, kind, series.join("|")]);
|
|
13206
|
-
const config = (0,
|
|
13345
|
+
const config = (0, import_react95.useMemo)(() => {
|
|
13207
13346
|
const out = {};
|
|
13208
13347
|
series.forEach((key, index) => {
|
|
13209
13348
|
out[key] = {
|
|
@@ -13464,25 +13603,25 @@ function Drawing({
|
|
|
13464
13603
|
}
|
|
13465
13604
|
|
|
13466
13605
|
// src/DashboardCanvas.tsx
|
|
13467
|
-
var
|
|
13468
|
-
var
|
|
13606
|
+
var import_react96 = require("react");
|
|
13607
|
+
var import_react97 = require("@ai-matrx/records/react");
|
|
13469
13608
|
var import_design_system47 = require("@ai-matrx/design-system");
|
|
13470
13609
|
var import_jsx_runtime50 = require("react/jsx-runtime");
|
|
13471
13610
|
function DashboardCanvas({ tableId, activeDashboardId, filter, className }) {
|
|
13472
|
-
const client = (0,
|
|
13611
|
+
const client = (0, import_react97.useRecordsClient)();
|
|
13473
13612
|
const host = useRecordsUi();
|
|
13474
|
-
const table = (0,
|
|
13613
|
+
const table = (0, import_react97.useTable)(tableId);
|
|
13475
13614
|
const rights = useTableRights(table.data);
|
|
13476
|
-
const fields = (0,
|
|
13477
|
-
const [boards, setBoards] = (0,
|
|
13478
|
-
const [error, setError] = (0,
|
|
13479
|
-
const [activeId, setActiveId] = (0,
|
|
13480
|
-
const [run, setRun] = (0,
|
|
13481
|
-
const [running, setRunning] = (0,
|
|
13482
|
-
const [question, setQuestion] = (0,
|
|
13483
|
-
const [asking, setAsking] = (0,
|
|
13484
|
-
const [scheduling, setScheduling] = (0,
|
|
13485
|
-
const load = (0,
|
|
13615
|
+
const fields = (0, import_react97.useFields)(tableId);
|
|
13616
|
+
const [boards, setBoards] = (0, import_react96.useState)(null);
|
|
13617
|
+
const [error, setError] = (0, import_react96.useState)(null);
|
|
13618
|
+
const [activeId, setActiveId] = (0, import_react96.useState)(activeDashboardId ?? null);
|
|
13619
|
+
const [run, setRun] = (0, import_react96.useState)(null);
|
|
13620
|
+
const [running, setRunning] = (0, import_react96.useState)(false);
|
|
13621
|
+
const [question, setQuestion] = (0, import_react96.useState)("");
|
|
13622
|
+
const [asking, setAsking] = (0, import_react96.useState)(false);
|
|
13623
|
+
const [scheduling, setScheduling] = (0, import_react96.useState)(false);
|
|
13624
|
+
const load = (0, import_react96.useCallback)(async () => {
|
|
13486
13625
|
const answered = await client.dashboards({ table_id: tableId });
|
|
13487
13626
|
if (!answered.ok) {
|
|
13488
13627
|
setError(answered.error);
|
|
@@ -13491,17 +13630,17 @@ function DashboardCanvas({ tableId, activeDashboardId, filter, className }) {
|
|
|
13491
13630
|
setError(null);
|
|
13492
13631
|
setBoards(answered.data.map(dashboardFromSummary));
|
|
13493
13632
|
}, [client, tableId]);
|
|
13494
|
-
(0,
|
|
13633
|
+
(0, import_react96.useEffect)(() => {
|
|
13495
13634
|
void load();
|
|
13496
13635
|
}, [load]);
|
|
13497
|
-
(0,
|
|
13636
|
+
(0, import_react96.useEffect)(() => {
|
|
13498
13637
|
if (!boards || boards.length === 0) return;
|
|
13499
13638
|
const chosen = boards.find((d) => d.id === (activeDashboardId ?? activeId)) ?? boards[0];
|
|
13500
13639
|
if (chosen.id !== activeId) setActiveId(chosen.id);
|
|
13501
13640
|
}, [boards, activeDashboardId]);
|
|
13502
|
-
const board = (0,
|
|
13641
|
+
const board = (0, import_react96.useMemo)(() => boards?.find((d) => d.id === activeId) ?? null, [boards, activeId]);
|
|
13503
13642
|
const filterKey = JSON.stringify(filter ?? {});
|
|
13504
|
-
(0,
|
|
13643
|
+
(0, import_react96.useEffect)(() => {
|
|
13505
13644
|
if (!activeId) {
|
|
13506
13645
|
setRun(null);
|
|
13507
13646
|
return;
|
|
@@ -13519,7 +13658,7 @@ function DashboardCanvas({ tableId, activeDashboardId, filter, className }) {
|
|
|
13519
13658
|
cancelled = true;
|
|
13520
13659
|
};
|
|
13521
13660
|
}, [client, activeId, filterKey]);
|
|
13522
|
-
const declare2 = (0,
|
|
13661
|
+
const declare2 = (0, import_react96.useCallback)(
|
|
13523
13662
|
async (next, blocks) => {
|
|
13524
13663
|
const written = await client.dashboardDeclare(
|
|
13525
13664
|
dashboardDeclareArgs({ ...next, blocks }, tableId)
|
|
@@ -13540,8 +13679,8 @@ function DashboardCanvas({ tableId, activeDashboardId, filter, className }) {
|
|
|
13540
13679
|
[client, tableId, load, filter]
|
|
13541
13680
|
);
|
|
13542
13681
|
async function create() {
|
|
13543
|
-
const
|
|
13544
|
-
const byField =
|
|
13682
|
+
const all = fields.data ?? [];
|
|
13683
|
+
const byField = offerableFields(all, "choice")[0] ?? all.find((f) => f.type === "text" || f.type === "list");
|
|
13545
13684
|
const by = byField?.key;
|
|
13546
13685
|
await declare2(
|
|
13547
13686
|
{
|
|
@@ -13570,7 +13709,7 @@ function DashboardCanvas({ tableId, activeDashboardId, filter, className }) {
|
|
|
13570
13709
|
]
|
|
13571
13710
|
);
|
|
13572
13711
|
}
|
|
13573
|
-
const refresh = (0,
|
|
13712
|
+
const refresh = (0, import_react96.useCallback)(async () => {
|
|
13574
13713
|
if (!activeId) return;
|
|
13575
13714
|
setRunning(true);
|
|
13576
13715
|
const again = await client.dashboardRun({
|
|
@@ -13712,6 +13851,32 @@ function DashboardCanvas({ tableId, activeDashboardId, filter, className }) {
|
|
|
13712
13851
|
children: CHART_KINDS.map((kind) => /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("option", { value: kind, children: CHART_KIND_LABEL[kind] }, kind))
|
|
13713
13852
|
}
|
|
13714
13853
|
),
|
|
13854
|
+
(board.blocks[index].groupBy ?? []).length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
13855
|
+
GroupingPicker,
|
|
13856
|
+
{
|
|
13857
|
+
block: board.blocks[index],
|
|
13858
|
+
fields: fields.data ?? [],
|
|
13859
|
+
onPick: (key) => void declare2(
|
|
13860
|
+
board,
|
|
13861
|
+
board.blocks.map((b, i) => {
|
|
13862
|
+
if (i !== index) return b;
|
|
13863
|
+
const picked = (fields.data ?? []).find((f) => f.key === key);
|
|
13864
|
+
const wasNamedAfterItsColumn = (fields.data ?? []).some(
|
|
13865
|
+
(f) => b.title === `By ${fieldName(f)}`
|
|
13866
|
+
);
|
|
13867
|
+
return {
|
|
13868
|
+
...b,
|
|
13869
|
+
groupBy: [key],
|
|
13870
|
+
// A block titled after the column it grouped by
|
|
13871
|
+
// must not keep saying "By Job Number" once it
|
|
13872
|
+
// groups by Status. A title somebody wrote
|
|
13873
|
+
// themselves is left alone.
|
|
13874
|
+
...wasNamedAfterItsColumn && picked ? { title: `By ${fieldName(picked)}` } : {}
|
|
13875
|
+
};
|
|
13876
|
+
})
|
|
13877
|
+
)
|
|
13878
|
+
}
|
|
13879
|
+
) : null,
|
|
13715
13880
|
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
13716
13881
|
import_design_system47.Button,
|
|
13717
13882
|
{
|
|
@@ -13730,10 +13895,49 @@ function DashboardCanvas({ tableId, activeDashboardId, filter, className }) {
|
|
|
13730
13895
|
] })
|
|
13731
13896
|
] });
|
|
13732
13897
|
}
|
|
13898
|
+
function groupingChoices(all) {
|
|
13899
|
+
const once = [];
|
|
13900
|
+
for (const field of all) if (!once.some((f) => f.key === field.key)) once.push(field);
|
|
13901
|
+
const sensible = offerableFields(once, "choice");
|
|
13902
|
+
const isSensible = (field) => sensible.some((s) => s.key === field.key);
|
|
13903
|
+
return [
|
|
13904
|
+
...sensible.map((field) => ({ field, unusual: false })),
|
|
13905
|
+
...once.filter((field) => !isSensible(field)).map((field) => ({ field, unusual: true }))
|
|
13906
|
+
];
|
|
13907
|
+
}
|
|
13908
|
+
function GroupingPicker({
|
|
13909
|
+
block,
|
|
13910
|
+
fields,
|
|
13911
|
+
onPick
|
|
13912
|
+
}) {
|
|
13913
|
+
const choices = groupingChoices(fields);
|
|
13914
|
+
const current = block.groupBy?.[0] ?? "";
|
|
13915
|
+
if (choices.length === 0) {
|
|
13916
|
+
return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { className: "text-muted-foreground", children: "This table has no columns yet, so there is nothing to group this block by." });
|
|
13917
|
+
}
|
|
13918
|
+
const known = choices.some((c) => c.field.key === current);
|
|
13919
|
+
return /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(import_jsx_runtime50.Fragment, { children: [
|
|
13920
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)("label", { className: "text-muted-foreground", htmlFor: `block-group-${block.title}`, children: "Group by" }),
|
|
13921
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(import_design_system47.Select, { value: known ? current : "", onValueChange: onPick, children: [
|
|
13922
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
13923
|
+
import_design_system47.SelectTrigger,
|
|
13924
|
+
{
|
|
13925
|
+
size: "sm",
|
|
13926
|
+
id: `block-group-${block.title}`,
|
|
13927
|
+
"aria-label": `Which column ${block.title} is grouped by`,
|
|
13928
|
+
className: "h-7 min-w-[10rem] text-xs",
|
|
13929
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(import_design_system47.SelectValue, { placeholder: "Choose a column" })
|
|
13930
|
+
}
|
|
13931
|
+
),
|
|
13932
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)(import_design_system47.SelectContent, { children: choices.map(({ field, unusual }) => /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(import_design_system47.SelectItem, { value: field.key, children: unusual ? `${fieldName(field)} \u2014 ${UNUSUAL_FIELD_NOTE}` : fieldName(field) }, field.key)) })
|
|
13933
|
+
] }),
|
|
13934
|
+
known ? null : /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { className: "text-muted-foreground", children: "The column this block was grouped by is no longer on this table \u2014 choose another." })
|
|
13935
|
+
] });
|
|
13936
|
+
}
|
|
13733
13937
|
|
|
13734
13938
|
// src/FormsPanel.tsx
|
|
13735
|
-
var
|
|
13736
|
-
var
|
|
13939
|
+
var import_react98 = require("react");
|
|
13940
|
+
var import_react99 = require("@ai-matrx/records/react");
|
|
13737
13941
|
var import_records12 = require("@ai-matrx/records");
|
|
13738
13942
|
var import_design_system48 = require("@ai-matrx/design-system");
|
|
13739
13943
|
var import_jsx_runtime51 = require("react/jsx-runtime");
|
|
@@ -13744,16 +13948,17 @@ function formSuggestion(tableName2) {
|
|
|
13744
13948
|
return `Make me a form that collects new ${subject} entries and tells me when somebody answers.`;
|
|
13745
13949
|
}
|
|
13746
13950
|
function FormsPanel({ tableId, className }) {
|
|
13747
|
-
const client = (0,
|
|
13951
|
+
const client = (0, import_react99.useRecordsClient)();
|
|
13952
|
+
const publishGate = usePublishGate();
|
|
13748
13953
|
const host = useRecordsUi();
|
|
13749
|
-
const table = (0,
|
|
13954
|
+
const table = (0, import_react99.useTable)(tableId);
|
|
13750
13955
|
const rights = useTableRights(table.data);
|
|
13751
|
-
const [forms, setForms] = (0,
|
|
13752
|
-
const [error, setError] = (0,
|
|
13753
|
-
const [busy, setBusy] = (0,
|
|
13754
|
-
const [copied, setCopied] = (0,
|
|
13755
|
-
const [building, setBuilding] = (0,
|
|
13756
|
-
const load = (0,
|
|
13956
|
+
const [forms, setForms] = (0, import_react98.useState)(null);
|
|
13957
|
+
const [error, setError] = (0, import_react98.useState)(null);
|
|
13958
|
+
const [busy, setBusy] = (0, import_react98.useState)(null);
|
|
13959
|
+
const [copied, setCopied] = (0, import_react98.useState)(null);
|
|
13960
|
+
const [building, setBuilding] = (0, import_react98.useState)(false);
|
|
13961
|
+
const load = (0, import_react98.useCallback)(async () => {
|
|
13757
13962
|
const answered = await client.forms({ table_id: tableId });
|
|
13758
13963
|
if (!answered.ok) {
|
|
13759
13964
|
setError(answered.error);
|
|
@@ -13763,10 +13968,10 @@ function FormsPanel({ tableId, className }) {
|
|
|
13763
13968
|
setError(null);
|
|
13764
13969
|
setForms(answered.data);
|
|
13765
13970
|
}, [client, tableId]);
|
|
13766
|
-
(0,
|
|
13971
|
+
(0, import_react98.useEffect)(() => {
|
|
13767
13972
|
void load();
|
|
13768
13973
|
}, [load]);
|
|
13769
|
-
const toggle = (0,
|
|
13974
|
+
const toggle = (0, import_react98.useCallback)(
|
|
13770
13975
|
async (form) => {
|
|
13771
13976
|
setBusy(form.form_id);
|
|
13772
13977
|
const wanted = form.published_at === null || form.closed_at !== null;
|
|
@@ -13780,8 +13985,8 @@ function FormsPanel({ tableId, className }) {
|
|
|
13780
13985
|
},
|
|
13781
13986
|
[client, load]
|
|
13782
13987
|
);
|
|
13783
|
-
const [shown, setShown] = (0,
|
|
13784
|
-
const copy = (0,
|
|
13988
|
+
const [shown, setShown] = (0, import_react98.useState)(null);
|
|
13989
|
+
const copy = (0, import_react98.useCallback)(async (url, formId) => {
|
|
13785
13990
|
try {
|
|
13786
13991
|
await navigator.clipboard.writeText(url);
|
|
13787
13992
|
setCopied(formId);
|
|
@@ -13856,7 +14061,7 @@ function FormsPanel({ tableId, className }) {
|
|
|
13856
14061
|
] }),
|
|
13857
14062
|
/* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "mt-2 flex flex-wrap items-center gap-1.5", children: [
|
|
13858
14063
|
form.published_at ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_design_system48.Button, { size: "sm", variant: "outline", onClick: () => void copy(url, form.form_id), children: copied === form.form_id ? "Copied" : "Copy link" }) : null,
|
|
13859
|
-
rights.structure ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
14064
|
+
rights.structure && !publishGate.blocked ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
13860
14065
|
import_design_system48.Button,
|
|
13861
14066
|
{
|
|
13862
14067
|
size: "sm",
|
|
@@ -13867,6 +14072,7 @@ function FormsPanel({ tableId, className }) {
|
|
|
13867
14072
|
}
|
|
13868
14073
|
) : null
|
|
13869
14074
|
] }),
|
|
14075
|
+
rights.structure && publishGate.why ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("p", { className: "mt-1.5 text-xs text-muted-foreground", children: publishGate.why }) : null,
|
|
13870
14076
|
shown && shown === url ? /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("p", { className: "mt-1.5 break-all rounded border border-dashed px-2 py-1 text-xs", children: [
|
|
13871
14077
|
"This browser would not let the page copy for you, so here it is to copy by hand:",
|
|
13872
14078
|
" ",
|
|
@@ -13879,8 +14085,8 @@ function FormsPanel({ tableId, className }) {
|
|
|
13879
14085
|
}
|
|
13880
14086
|
|
|
13881
14087
|
// src/BookingBuilder.tsx
|
|
13882
|
-
var
|
|
13883
|
-
var
|
|
14088
|
+
var import_react100 = require("react");
|
|
14089
|
+
var import_react101 = require("@ai-matrx/records/react");
|
|
13884
14090
|
var import_records13 = require("@ai-matrx/records");
|
|
13885
14091
|
var import_design_system49 = require("@ai-matrx/design-system");
|
|
13886
14092
|
var import_jsx_runtime52 = require("react/jsx-runtime");
|
|
@@ -13908,38 +14114,39 @@ function draftWindows(availability) {
|
|
|
13908
14114
|
});
|
|
13909
14115
|
}
|
|
13910
14116
|
function BookingBuilder({ tableId, bookingId, onSaved, onClose, className }) {
|
|
13911
|
-
const client = (0,
|
|
14117
|
+
const client = (0, import_react101.useRecordsClient)();
|
|
14118
|
+
const publishGate = usePublishGate();
|
|
13912
14119
|
const host = useRecordsUi();
|
|
13913
|
-
const table = (0,
|
|
14120
|
+
const table = (0, import_react101.useTable)(tableId);
|
|
13914
14121
|
const rights = useTableRights(table.data);
|
|
13915
|
-
const fields = (0,
|
|
13916
|
-
const [existing, setExisting] = (0,
|
|
13917
|
-
const [loaded, setLoaded] = (0,
|
|
13918
|
-
const [error, setError] = (0,
|
|
13919
|
-
const [saving, setSaving] = (0,
|
|
13920
|
-
const [publishing, setPublishing] = (0,
|
|
13921
|
-
const [copied, setCopied] = (0,
|
|
13922
|
-
const [title, setTitle] = (0,
|
|
13923
|
-
const [minutes, setMinutes] = (0,
|
|
13924
|
-
const [buffer, setBuffer] = (0,
|
|
13925
|
-
const [lead, setLead] = (0,
|
|
13926
|
-
const [perDay, setPerDay] = (0,
|
|
13927
|
-
const [days, setDays] = (0,
|
|
13928
|
-
const [windows, setWindows] = (0,
|
|
13929
|
-
const [asked, setAsked] = (0,
|
|
13930
|
-
const [confirmation, setConfirmation] = (0,
|
|
13931
|
-
const [offer, setOffer] = (0,
|
|
13932
|
-
const [formId, setFormId] = (0,
|
|
14122
|
+
const fields = (0, import_react101.useFields)(tableId);
|
|
14123
|
+
const [existing, setExisting] = (0, import_react100.useState)(null);
|
|
14124
|
+
const [loaded, setLoaded] = (0, import_react100.useState)(false);
|
|
14125
|
+
const [error, setError] = (0, import_react100.useState)(null);
|
|
14126
|
+
const [saving, setSaving] = (0, import_react100.useState)(false);
|
|
14127
|
+
const [publishing, setPublishing] = (0, import_react100.useState)(false);
|
|
14128
|
+
const [copied, setCopied] = (0, import_react100.useState)(false);
|
|
14129
|
+
const [title, setTitle] = (0, import_react100.useState)("");
|
|
14130
|
+
const [minutes, setMinutes] = (0, import_react100.useState)(30);
|
|
14131
|
+
const [buffer, setBuffer] = (0, import_react100.useState)(0);
|
|
14132
|
+
const [lead, setLead] = (0, import_react100.useState)(120);
|
|
14133
|
+
const [perDay, setPerDay] = (0, import_react100.useState)(8);
|
|
14134
|
+
const [days, setDays] = (0, import_react100.useState)(30);
|
|
14135
|
+
const [windows, setWindows] = (0, import_react100.useState)(() => draftWindows(null));
|
|
14136
|
+
const [asked, setAsked] = (0, import_react100.useState)([]);
|
|
14137
|
+
const [confirmation, setConfirmation] = (0, import_react100.useState)("");
|
|
14138
|
+
const [offer, setOffer] = (0, import_react100.useState)(null);
|
|
14139
|
+
const [formId, setFormId] = (0, import_react100.useState)(bookingId ?? null);
|
|
13933
14140
|
const publicOrigin = host.publicOrigin ?? (typeof window === "undefined" ? "" : window.location.origin);
|
|
13934
|
-
const askable = (0,
|
|
14141
|
+
const askable = (0, import_react100.useMemo)(
|
|
13935
14142
|
() => askableFields(fields.data ?? [], STORE_ANSWERS_THESE),
|
|
13936
14143
|
[fields.data]
|
|
13937
14144
|
);
|
|
13938
|
-
const leftOut = (0,
|
|
14145
|
+
const leftOut = (0, import_react100.useMemo)(
|
|
13939
14146
|
() => whyNotAskable(fields.data ?? [], STORE_ANSWERS_THESE),
|
|
13940
14147
|
[fields.data]
|
|
13941
14148
|
);
|
|
13942
|
-
const load = (0,
|
|
14149
|
+
const load = (0, import_react100.useCallback)(async () => {
|
|
13943
14150
|
const answered = await client.bookings({ table_id: tableId });
|
|
13944
14151
|
if (!answered.ok) {
|
|
13945
14152
|
setError(answered.error);
|
|
@@ -13951,18 +14158,18 @@ function BookingBuilder({ tableId, bookingId, onSaved, onClose, className }) {
|
|
|
13951
14158
|
setLoaded(true);
|
|
13952
14159
|
if (mine) setFormId(mine.form_id);
|
|
13953
14160
|
}, [client, tableId, bookingId]);
|
|
13954
|
-
(0,
|
|
14161
|
+
(0, import_react100.useEffect)(() => {
|
|
13955
14162
|
void load();
|
|
13956
14163
|
}, [load]);
|
|
13957
|
-
(0,
|
|
14164
|
+
(0, import_react100.useEffect)(() => {
|
|
13958
14165
|
if (title !== "" || !table.data) return;
|
|
13959
14166
|
setTitle(existing?.title ?? `Book a ${minutes}-minute ${table.data.name} appointment`);
|
|
13960
14167
|
}, [table.data, existing]);
|
|
13961
|
-
(0,
|
|
14168
|
+
(0, import_react100.useEffect)(() => {
|
|
13962
14169
|
if (!existing) return;
|
|
13963
14170
|
setMinutes(existing.slot_minutes);
|
|
13964
14171
|
}, [existing]);
|
|
13965
|
-
(0,
|
|
14172
|
+
(0, import_react100.useEffect)(() => {
|
|
13966
14173
|
if (!offer) return;
|
|
13967
14174
|
setWindows(draftWindows(offer));
|
|
13968
14175
|
setMinutes(offer.slot_minutes);
|
|
@@ -13971,7 +14178,7 @@ function BookingBuilder({ tableId, bookingId, onSaved, onClose, className }) {
|
|
|
13971
14178
|
setPerDay(offer.max_per_day);
|
|
13972
14179
|
setDays(offer.days);
|
|
13973
14180
|
}, [offer]);
|
|
13974
|
-
const availability = (0,
|
|
14181
|
+
const availability = (0, import_react100.useCallback)(
|
|
13975
14182
|
() => ({
|
|
13976
14183
|
slot_minutes: minutes,
|
|
13977
14184
|
buffer_minutes: buffer,
|
|
@@ -14208,7 +14415,7 @@ function BookingBuilder({ tableId, bookingId, onSaved, onClose, className }) {
|
|
|
14208
14415
|
children: copied ? "Copied" : "Copy link"
|
|
14209
14416
|
}
|
|
14210
14417
|
),
|
|
14211
|
-
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
|
|
14418
|
+
publishGate.blocked ? null : /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
|
|
14212
14419
|
import_design_system49.Button,
|
|
14213
14420
|
{
|
|
14214
14421
|
size: "sm",
|
|
@@ -14217,15 +14424,15 @@ function BookingBuilder({ tableId, bookingId, onSaved, onClose, className }) {
|
|
|
14217
14424
|
children: publishing ? "\u2026" : existing?.published_at && !existing.closed_at ? "Unpublish" : "Publish"
|
|
14218
14425
|
}
|
|
14219
14426
|
),
|
|
14220
|
-
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)("p", { className: "w-full text-xs text-muted-foreground", children: existing?.published_at && !existing.closed_at ? "Open. Anyone with this link can book a time." : "Not open yet \u2014 the link does not take bookings until you publish it." })
|
|
14427
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)("p", { className: "w-full text-xs text-muted-foreground", children: publishGate.why ?? (existing?.published_at && !existing.closed_at ? "Open. Anyone with this link can book a time." : "Not open yet \u2014 the link does not take bookings until you publish it.") })
|
|
14221
14428
|
] }) : null
|
|
14222
14429
|
] })
|
|
14223
14430
|
);
|
|
14224
14431
|
}
|
|
14225
14432
|
|
|
14226
14433
|
// src/BookingSlots.tsx
|
|
14227
|
-
var
|
|
14228
|
-
var
|
|
14434
|
+
var import_react102 = require("react");
|
|
14435
|
+
var import_react103 = require("@ai-matrx/records/react");
|
|
14229
14436
|
var import_records14 = require("@ai-matrx/records");
|
|
14230
14437
|
var import_design_system50 = require("@ai-matrx/design-system");
|
|
14231
14438
|
var import_jsx_runtime53 = require("react/jsx-runtime");
|
|
@@ -14237,15 +14444,15 @@ function bookingSuggestion(tableName2) {
|
|
|
14237
14444
|
var NO_ADMIN2 = "Opening a booking page lets people with no account take time in your calendar, so it needs the admin level on the table the appointments land in.";
|
|
14238
14445
|
var STATE_WORDS = BOOKING_PAGE_STATE_LABEL;
|
|
14239
14446
|
function BookingSlots({ tableId, className }) {
|
|
14240
|
-
const client = (0,
|
|
14447
|
+
const client = (0, import_react103.useRecordsClient)();
|
|
14241
14448
|
const host = useRecordsUi();
|
|
14242
|
-
const [pages, setPages] = (0,
|
|
14243
|
-
const [error, setError] = (0,
|
|
14244
|
-
const [busy, setBusy] = (0,
|
|
14245
|
-
const [copied, setCopied] = (0,
|
|
14246
|
-
const [shown, setShown] = (0,
|
|
14247
|
-
const [building, setBuilding] = (0,
|
|
14248
|
-
const load = (0,
|
|
14449
|
+
const [pages, setPages] = (0, import_react102.useState)(null);
|
|
14450
|
+
const [error, setError] = (0, import_react102.useState)(null);
|
|
14451
|
+
const [busy, setBusy] = (0, import_react102.useState)(null);
|
|
14452
|
+
const [copied, setCopied] = (0, import_react102.useState)(null);
|
|
14453
|
+
const [shown, setShown] = (0, import_react102.useState)(null);
|
|
14454
|
+
const [building, setBuilding] = (0, import_react102.useState)(false);
|
|
14455
|
+
const load = (0, import_react102.useCallback)(async () => {
|
|
14249
14456
|
const answered = await client.bookings(tableId ? { table_id: tableId } : {});
|
|
14250
14457
|
if (!answered.ok) {
|
|
14251
14458
|
setError(answered.error);
|
|
@@ -14255,10 +14462,10 @@ function BookingSlots({ tableId, className }) {
|
|
|
14255
14462
|
setError(null);
|
|
14256
14463
|
setPages(answered.data);
|
|
14257
14464
|
}, [client, tableId]);
|
|
14258
|
-
(0,
|
|
14465
|
+
(0, import_react102.useEffect)(() => {
|
|
14259
14466
|
void load();
|
|
14260
14467
|
}, [load]);
|
|
14261
|
-
const subjectIds = (0,
|
|
14468
|
+
const subjectIds = (0, import_react102.useMemo)(
|
|
14262
14469
|
() => Array.from(
|
|
14263
14470
|
/* @__PURE__ */ new Set([
|
|
14264
14471
|
...(pages ?? []).map((p) => p.table_id),
|
|
@@ -14271,10 +14478,10 @@ function BookingSlots({ tableId, className }) {
|
|
|
14271
14478
|
),
|
|
14272
14479
|
[pages, tableId]
|
|
14273
14480
|
);
|
|
14274
|
-
const levels = (0,
|
|
14481
|
+
const levels = (0, import_react103.useMyLevels)(subjectIds);
|
|
14275
14482
|
const levelsKnown = !levels.loading && Boolean(levels.data);
|
|
14276
14483
|
const mayBuildHere = levelsKnown && Boolean(tableId) && levels.data?.[tableId] === "admin";
|
|
14277
|
-
const toggle = (0,
|
|
14484
|
+
const toggle = (0, import_react102.useCallback)(
|
|
14278
14485
|
async (page) => {
|
|
14279
14486
|
setBusy(page.form_id);
|
|
14280
14487
|
const wanted = page.published_at === null || page.closed_at !== null;
|
|
@@ -14288,7 +14495,7 @@ function BookingSlots({ tableId, className }) {
|
|
|
14288
14495
|
},
|
|
14289
14496
|
[client, load]
|
|
14290
14497
|
);
|
|
14291
|
-
const copy = (0,
|
|
14498
|
+
const copy = (0, import_react102.useCallback)(async (url, formId) => {
|
|
14292
14499
|
try {
|
|
14293
14500
|
await navigator.clipboard.writeText(url);
|
|
14294
14501
|
setCopied(formId);
|
|
@@ -14424,14 +14631,14 @@ function nextInWords(page) {
|
|
|
14424
14631
|
}
|
|
14425
14632
|
|
|
14426
14633
|
// src/CaptureSheet.tsx
|
|
14427
|
-
var
|
|
14428
|
-
var
|
|
14634
|
+
var import_react106 = require("react");
|
|
14635
|
+
var import_react107 = require("@ai-matrx/records/react");
|
|
14429
14636
|
var import_design_system52 = require("@ai-matrx/design-system");
|
|
14430
14637
|
|
|
14431
14638
|
// src/CaptureRun.tsx
|
|
14432
|
-
var
|
|
14639
|
+
var import_react104 = require("react");
|
|
14433
14640
|
var import_records15 = require("@ai-matrx/records");
|
|
14434
|
-
var
|
|
14641
|
+
var import_react105 = require("@ai-matrx/records/react");
|
|
14435
14642
|
var import_design_system51 = require("@ai-matrx/design-system");
|
|
14436
14643
|
var import_jsx_runtime54 = require("react/jsx-runtime");
|
|
14437
14644
|
function controlFor(field) {
|
|
@@ -14470,21 +14677,21 @@ function whereWeAre(timeoutMs = 4e3) {
|
|
|
14470
14677
|
});
|
|
14471
14678
|
}
|
|
14472
14679
|
function CaptureRun({ sheetId, face: given, className }) {
|
|
14473
|
-
const client = (0,
|
|
14680
|
+
const client = (0, import_react105.useRecordsClient)();
|
|
14474
14681
|
const host = useRecordsUi();
|
|
14475
|
-
const [face, setFace] = (0,
|
|
14476
|
-
const [loadFailed, setLoadFailed] = (0,
|
|
14477
|
-
const [at, setAt] = (0,
|
|
14478
|
-
const [answers, setAnswers] = (0,
|
|
14479
|
-
const [files, setFiles] = (0,
|
|
14480
|
-
const [missing, setMissing] = (0,
|
|
14481
|
-
const [done, setDone] = (0,
|
|
14482
|
-
const [counts, setCounts] = (0,
|
|
14483
|
-
const [items, setItems] = (0,
|
|
14484
|
-
const [lastSynced, setLastSynced] = (0,
|
|
14485
|
-
const [sending, setSending] = (0,
|
|
14486
|
-
const queueRef = (0,
|
|
14487
|
-
(0,
|
|
14682
|
+
const [face, setFace] = (0, import_react104.useState)(given);
|
|
14683
|
+
const [loadFailed, setLoadFailed] = (0, import_react104.useState)(null);
|
|
14684
|
+
const [at, setAt] = (0, import_react104.useState)(0);
|
|
14685
|
+
const [answers, setAnswers] = (0, import_react104.useState)({});
|
|
14686
|
+
const [files, setFiles] = (0, import_react104.useState)({});
|
|
14687
|
+
const [missing, setMissing] = (0, import_react104.useState)(null);
|
|
14688
|
+
const [done, setDone] = (0, import_react104.useState)(null);
|
|
14689
|
+
const [counts, setCounts] = (0, import_react104.useState)({ waiting: 0, sending: 0, refused: 0, landed: 0 });
|
|
14690
|
+
const [items, setItems] = (0, import_react104.useState)([]);
|
|
14691
|
+
const [lastSynced, setLastSynced] = (0, import_react104.useState)(null);
|
|
14692
|
+
const [sending, setSending] = (0, import_react104.useState)(false);
|
|
14693
|
+
const queueRef = (0, import_react104.useRef)(null);
|
|
14694
|
+
(0, import_react104.useEffect)(() => {
|
|
14488
14695
|
const q2 = (0, import_records15.openCaptureQueue)({
|
|
14489
14696
|
onChange: (c, all) => {
|
|
14490
14697
|
setCounts(c);
|
|
@@ -14522,7 +14729,7 @@ function CaptureRun({ sheetId, face: given, className }) {
|
|
|
14522
14729
|
void q2.sync().then(() => void q2.lastSyncedAt().then(setLastSynced));
|
|
14523
14730
|
return () => q2.dispose();
|
|
14524
14731
|
}, [client, host]);
|
|
14525
|
-
(0,
|
|
14732
|
+
(0, import_react104.useEffect)(() => {
|
|
14526
14733
|
if (given !== void 0) return;
|
|
14527
14734
|
let cancelled = false;
|
|
14528
14735
|
void client.captureOpen({ sheet_id: sheetId }).then((res) => {
|
|
@@ -14534,7 +14741,7 @@ function CaptureRun({ sheetId, face: given, className }) {
|
|
|
14534
14741
|
cancelled = true;
|
|
14535
14742
|
};
|
|
14536
14743
|
}, [client, given, sheetId]);
|
|
14537
|
-
const questions = (0,
|
|
14744
|
+
const questions = (0, import_react104.useMemo)(() => {
|
|
14538
14745
|
const asked = face?.presentation?.questions ?? [];
|
|
14539
14746
|
if (asked.length > 0) return asked;
|
|
14540
14747
|
return (face?.fields ?? []).map((f) => ({
|
|
@@ -14544,11 +14751,11 @@ function CaptureRun({ sheetId, face: given, className }) {
|
|
|
14544
14751
|
required: f.required
|
|
14545
14752
|
}));
|
|
14546
14753
|
}, [face]);
|
|
14547
|
-
const fieldOf = (0,
|
|
14754
|
+
const fieldOf = (0, import_react104.useCallback)(
|
|
14548
14755
|
(key) => (face?.fields ?? []).find((f) => f.key === key),
|
|
14549
14756
|
[face]
|
|
14550
14757
|
);
|
|
14551
|
-
const sync = (0,
|
|
14758
|
+
const sync = (0, import_react104.useCallback)(async () => {
|
|
14552
14759
|
const q2 = queueRef.current;
|
|
14553
14760
|
if (!q2) return;
|
|
14554
14761
|
setSending(true);
|
|
@@ -14561,7 +14768,7 @@ function CaptureRun({ sheetId, face: given, className }) {
|
|
|
14561
14768
|
setSending(false);
|
|
14562
14769
|
}
|
|
14563
14770
|
}, []);
|
|
14564
|
-
const answered = (0,
|
|
14771
|
+
const answered = (0, import_react104.useCallback)(
|
|
14565
14772
|
(key) => {
|
|
14566
14773
|
if (files[key]) return true;
|
|
14567
14774
|
const v = answers[key];
|
|
@@ -14832,21 +15039,21 @@ function AdHocCaptureSheet({
|
|
|
14832
15039
|
attachmentField,
|
|
14833
15040
|
className
|
|
14834
15041
|
}) {
|
|
14835
|
-
const client = (0,
|
|
15042
|
+
const client = (0, import_react107.useRecordsClient)();
|
|
14836
15043
|
const host = useRecordsUi();
|
|
14837
|
-
const table = (0,
|
|
14838
|
-
const fields = (0,
|
|
14839
|
-
const [mode, setMode] = (0,
|
|
14840
|
-
const [reading, setReading] = (0,
|
|
14841
|
-
const [note, setNote] = (0,
|
|
14842
|
-
const [fileId, setFileId] = (0,
|
|
14843
|
-
const [pending, setPending] = (0,
|
|
14844
|
-
const [saved, setSaved] = (0,
|
|
14845
|
-
const [error, setError] = (0,
|
|
14846
|
-
const [uploadError, setUploadError] = (0,
|
|
14847
|
-
const [flushing, setFlushing] = (0,
|
|
14848
|
-
const queue = (0,
|
|
14849
|
-
const keep = (0,
|
|
15044
|
+
const table = (0, import_react107.useTable)(tableId);
|
|
15045
|
+
const fields = (0, import_react107.useFields)(tableId);
|
|
15046
|
+
const [mode, setMode] = (0, import_react106.useState)("reading");
|
|
15047
|
+
const [reading, setReading] = (0, import_react106.useState)("");
|
|
15048
|
+
const [note, setNote] = (0, import_react106.useState)("");
|
|
15049
|
+
const [fileId, setFileId] = (0, import_react106.useState)(null);
|
|
15050
|
+
const [pending, setPending] = (0, import_react106.useState)(null);
|
|
15051
|
+
const [saved, setSaved] = (0, import_react106.useState)([]);
|
|
15052
|
+
const [error, setError] = (0, import_react106.useState)(null);
|
|
15053
|
+
const [uploadError, setUploadError] = (0, import_react106.useState)(null);
|
|
15054
|
+
const [flushing, setFlushing] = (0, import_react106.useState)(false);
|
|
15055
|
+
const queue = (0, import_react106.useRef)([]);
|
|
15056
|
+
const keep = (0, import_react106.useCallback)(
|
|
14850
15057
|
async (next) => {
|
|
14851
15058
|
queue.current = next;
|
|
14852
15059
|
setPending(next);
|
|
@@ -14854,7 +15061,7 @@ function AdHocCaptureSheet({
|
|
|
14854
15061
|
},
|
|
14855
15062
|
[host]
|
|
14856
15063
|
);
|
|
14857
|
-
(0,
|
|
15064
|
+
(0, import_react106.useEffect)(() => {
|
|
14858
15065
|
let cancelled = false;
|
|
14859
15066
|
void (async () => {
|
|
14860
15067
|
const held = host.captureQueue ? await host.captureQueue.load() : [];
|
|
@@ -14866,7 +15073,7 @@ function AdHocCaptureSheet({
|
|
|
14866
15073
|
cancelled = true;
|
|
14867
15074
|
};
|
|
14868
15075
|
}, [host]);
|
|
14869
|
-
const resolved = (0,
|
|
15076
|
+
const resolved = (0, import_react106.useCallback)(() => {
|
|
14870
15077
|
const all = fields.data ?? [];
|
|
14871
15078
|
return {
|
|
14872
15079
|
reading: readingField ?? all.find((f) => f.type === "range")?.key ?? null,
|
|
@@ -14874,7 +15081,7 @@ function AdHocCaptureSheet({
|
|
|
14874
15081
|
attachment: attachmentField ?? all.find((f) => f.format === "file" || f.format === "image")?.key ?? null
|
|
14875
15082
|
};
|
|
14876
15083
|
}, [attachmentField, fields.data, noteField, readingField, table.data]);
|
|
14877
|
-
const flush = (0,
|
|
15084
|
+
const flush = (0, import_react106.useCallback)(async () => {
|
|
14878
15085
|
if (flushing || queue.current.length === 0) return;
|
|
14879
15086
|
setFlushing(true);
|
|
14880
15087
|
const left = [];
|
|
@@ -15033,18 +15240,18 @@ function AdHocCaptureSheet({
|
|
|
15033
15240
|
}
|
|
15034
15241
|
|
|
15035
15242
|
// src/PortalShell.tsx
|
|
15036
|
-
var
|
|
15037
|
-
var
|
|
15243
|
+
var import_react108 = require("react");
|
|
15244
|
+
var import_react109 = require("@ai-matrx/records/react");
|
|
15038
15245
|
var import_design_system53 = require("@ai-matrx/design-system");
|
|
15039
15246
|
var import_jsx_runtime56 = require("react/jsx-runtime");
|
|
15040
15247
|
function PortalShell({ tableId, form, resourceType = "record", className }) {
|
|
15041
|
-
const client = (0,
|
|
15042
|
-
const [card, setCard] = (0,
|
|
15043
|
-
const [reach, setReach] = (0,
|
|
15044
|
-
const [error, setError] = (0,
|
|
15045
|
-
const [open, setOpen] = (0,
|
|
15046
|
-
const [sending, setSending] = (0,
|
|
15047
|
-
const load = (0,
|
|
15248
|
+
const client = (0, import_react109.useRecordsClient)();
|
|
15249
|
+
const [card, setCard] = (0, import_react108.useState)(null);
|
|
15250
|
+
const [reach, setReach] = (0, import_react108.useState)(null);
|
|
15251
|
+
const [error, setError] = (0, import_react108.useState)(null);
|
|
15252
|
+
const [open, setOpen] = (0, import_react108.useState)(null);
|
|
15253
|
+
const [sending, setSending] = (0, import_react108.useState)(false);
|
|
15254
|
+
const load = (0, import_react108.useCallback)(async () => {
|
|
15048
15255
|
const who = await client.externalPrincipalCard();
|
|
15049
15256
|
if (!who.ok) {
|
|
15050
15257
|
setError(who.error);
|
|
@@ -15059,7 +15266,7 @@ function PortalShell({ tableId, form, resourceType = "record", className }) {
|
|
|
15059
15266
|
}
|
|
15060
15267
|
setReach(reached.data.map((row) => row.resource_id));
|
|
15061
15268
|
}, [client, resourceType]);
|
|
15062
|
-
(0,
|
|
15269
|
+
(0, import_react108.useEffect)(() => {
|
|
15063
15270
|
void load();
|
|
15064
15271
|
}, [load]);
|
|
15065
15272
|
if (error) {
|
|
@@ -15117,9 +15324,9 @@ function PortalShell({ tableId, form, resourceType = "record", className }) {
|
|
|
15117
15324
|
] });
|
|
15118
15325
|
}
|
|
15119
15326
|
function PortalRow({ tableId, recordId }) {
|
|
15120
|
-
const client = (0,
|
|
15121
|
-
const [title, setTitle] = (0,
|
|
15122
|
-
(0,
|
|
15327
|
+
const client = (0, import_react109.useRecordsClient)();
|
|
15328
|
+
const [title, setTitle] = (0, import_react108.useState)(null);
|
|
15329
|
+
(0, import_react108.useEffect)(() => {
|
|
15123
15330
|
let cancelled = false;
|
|
15124
15331
|
void client.recordRead({ record_id: recordId }).then((answered) => {
|
|
15125
15332
|
if (cancelled) return;
|
|
@@ -15139,18 +15346,18 @@ function PortalRow({ tableId, recordId }) {
|
|
|
15139
15346
|
}
|
|
15140
15347
|
|
|
15141
15348
|
// src/PublicViewPage.tsx
|
|
15142
|
-
var
|
|
15143
|
-
var
|
|
15349
|
+
var import_react110 = require("react");
|
|
15350
|
+
var import_react111 = require("@ai-matrx/records/react");
|
|
15144
15351
|
var import_design_system54 = require("@ai-matrx/design-system");
|
|
15145
15352
|
var import_jsx_runtime57 = require("react/jsx-runtime");
|
|
15146
15353
|
function PublicViewPage({ slug, className }) {
|
|
15147
|
-
const client = (0,
|
|
15148
|
-
const [binding, setBinding] = (0,
|
|
15149
|
-
const [rows, setRows] = (0,
|
|
15150
|
-
const [fields, setFields] = (0,
|
|
15151
|
-
const [error, setError] = (0,
|
|
15152
|
-
const [gap, setGap] = (0,
|
|
15153
|
-
const load = (0,
|
|
15354
|
+
const client = (0, import_react111.useRecordsClient)();
|
|
15355
|
+
const [binding, setBinding] = (0, import_react110.useState)(null);
|
|
15356
|
+
const [rows, setRows] = (0, import_react110.useState)(null);
|
|
15357
|
+
const [fields, setFields] = (0, import_react110.useState)(null);
|
|
15358
|
+
const [error, setError] = (0, import_react110.useState)(null);
|
|
15359
|
+
const [gap, setGap] = (0, import_react110.useState)(null);
|
|
15360
|
+
const load = (0, import_react110.useCallback)(async () => {
|
|
15154
15361
|
const notice = await client.worldPublishGapNotice();
|
|
15155
15362
|
if (notice.ok) setGap(notice.data);
|
|
15156
15363
|
const resolved = await client.resolvePublishBinding({ slug });
|
|
@@ -15183,7 +15390,7 @@ function PublicViewPage({ slug, className }) {
|
|
|
15183
15390
|
}
|
|
15184
15391
|
setRows([{ id: found.resource_id, document: read.data.document, level: "viewer", hidden: read.data.hidden }]);
|
|
15185
15392
|
}, [client, slug]);
|
|
15186
|
-
(0,
|
|
15393
|
+
(0, import_react110.useEffect)(() => {
|
|
15187
15394
|
void load();
|
|
15188
15395
|
}, [load]);
|
|
15189
15396
|
if (error) return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(RefusalNotice, { error, className });
|
|
@@ -15220,10 +15427,10 @@ function PublicRow({ row, fields }) {
|
|
|
15220
15427
|
}
|
|
15221
15428
|
|
|
15222
15429
|
// src/EmbedFrame.tsx
|
|
15223
|
-
var
|
|
15224
|
-
var
|
|
15430
|
+
var import_react112 = require("react");
|
|
15431
|
+
var import_react113 = require("@ai-matrx/records/react");
|
|
15225
15432
|
var import_design_system55 = require("@ai-matrx/design-system");
|
|
15226
|
-
var
|
|
15433
|
+
var import_react114 = require("@ai-matrx/records/react");
|
|
15227
15434
|
var import_jsx_runtime58 = require("react/jsx-runtime");
|
|
15228
15435
|
function EmbedFrame({
|
|
15229
15436
|
tableId,
|
|
@@ -15233,18 +15440,18 @@ function EmbedFrame({
|
|
|
15233
15440
|
embedUrl,
|
|
15234
15441
|
className
|
|
15235
15442
|
}) {
|
|
15236
|
-
const client = (0,
|
|
15443
|
+
const client = (0, import_react113.useRecordsClient)();
|
|
15237
15444
|
const host = useRecordsUi();
|
|
15238
|
-
const table = (0,
|
|
15445
|
+
const table = (0, import_react114.useTable)(tableId);
|
|
15239
15446
|
const rights = useTableRights(table.data);
|
|
15240
|
-
const [origins, setOrigins] = (0,
|
|
15241
|
-
const [secret, setSecret] = (0,
|
|
15242
|
-
const [tokenId, setTokenId] = (0,
|
|
15243
|
-
const [error, setError] = (0,
|
|
15244
|
-
const [busy, setBusy] = (0,
|
|
15447
|
+
const [origins, setOrigins] = (0, import_react112.useState)("");
|
|
15448
|
+
const [secret, setSecret] = (0, import_react112.useState)(null);
|
|
15449
|
+
const [tokenId, setTokenId] = (0, import_react112.useState)(null);
|
|
15450
|
+
const [error, setError] = (0, import_react112.useState)(null);
|
|
15451
|
+
const [busy, setBusy] = (0, import_react112.useState)(false);
|
|
15245
15452
|
const mode = formId ? "write" : "read";
|
|
15246
15453
|
const parsed = origins.split(/[\s,]+/).map((o) => o.trim()).filter((o) => o.length > 0);
|
|
15247
|
-
const issue = (0,
|
|
15454
|
+
const issue = (0, import_react112.useCallback)(async () => {
|
|
15248
15455
|
setBusy(true);
|
|
15249
15456
|
setError(null);
|
|
15250
15457
|
const minted = await client.anonTokenIssue({
|
|
@@ -15263,7 +15470,7 @@ function EmbedFrame({
|
|
|
15263
15470
|
setTokenId(minted.data.token_id);
|
|
15264
15471
|
host.notify?.success("Embed token issued. Copy it now \u2014 it is never shown again.");
|
|
15265
15472
|
}, [client, formId, host, mode, parsed, recordId, savedViewId]);
|
|
15266
|
-
const revoke = (0,
|
|
15473
|
+
const revoke = (0, import_react112.useCallback)(async () => {
|
|
15267
15474
|
if (!tokenId) return;
|
|
15268
15475
|
setBusy(true);
|
|
15269
15476
|
const done = await client.anonTokenRevoke({ token_id: tokenId });
|
|
@@ -15327,13 +15534,13 @@ function EmbedFrame({
|
|
|
15327
15534
|
] });
|
|
15328
15535
|
}
|
|
15329
15536
|
function useEmbedHandshake(args) {
|
|
15330
|
-
const client = (0,
|
|
15331
|
-
const [binding, setBinding] = (0,
|
|
15332
|
-
const [error, setError] = (0,
|
|
15333
|
-
const [loading, setLoading] = (0,
|
|
15537
|
+
const client = (0, import_react113.useRecordsClient)();
|
|
15538
|
+
const [binding, setBinding] = (0, import_react112.useState)(null);
|
|
15539
|
+
const [error, setError] = (0, import_react112.useState)(null);
|
|
15540
|
+
const [loading, setLoading] = (0, import_react112.useState)(true);
|
|
15334
15541
|
const origin = args.origin ?? (typeof location === "undefined" ? "" : location.origin);
|
|
15335
15542
|
const { secret, requiredMode } = args;
|
|
15336
|
-
(0,
|
|
15543
|
+
(0, import_react112.useEffect)(() => {
|
|
15337
15544
|
let cancelled = false;
|
|
15338
15545
|
setLoading(true);
|
|
15339
15546
|
setError(null);
|
|
@@ -15355,7 +15562,7 @@ function useEmbedHandshake(args) {
|
|
|
15355
15562
|
}
|
|
15356
15563
|
|
|
15357
15564
|
// src/RecordsMount.tsx
|
|
15358
|
-
var
|
|
15565
|
+
var import_react115 = require("@ai-matrx/records/react");
|
|
15359
15566
|
var import_jsx_runtime59 = require("react/jsx-runtime");
|
|
15360
15567
|
var STORE_DECIDES_REASON = "This host offers exactly what the record store says this person may do: the level comes back with the table on the read door, so a control they cannot use is never drawn in the first place.";
|
|
15361
15568
|
function storeDecidesRights(_table) {
|
|
@@ -15369,7 +15576,7 @@ function RecordsMount({
|
|
|
15369
15576
|
}) {
|
|
15370
15577
|
const bound = { ...host ?? {} };
|
|
15371
15578
|
void letTheStoreDecideRights;
|
|
15372
|
-
return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
|
|
15579
|
+
return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(import_react115.RecordsProvider, { config, children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(RecordsUiProvider, { value: bound, children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(RecordLabelProvider, { children }) }) });
|
|
15373
15580
|
}
|
|
15374
15581
|
function personActor(userId) {
|
|
15375
15582
|
return userId ? { actor: "user", user_id: userId } : { actor: "user" };
|
|
@@ -15388,8 +15595,8 @@ function recordsDataSource(client, fallbackSchema = "custom") {
|
|
|
15388
15595
|
}
|
|
15389
15596
|
|
|
15390
15597
|
// src/TablesHome.tsx
|
|
15391
|
-
var
|
|
15392
|
-
var
|
|
15598
|
+
var import_react116 = require("react");
|
|
15599
|
+
var import_react117 = require("@ai-matrx/records/react");
|
|
15393
15600
|
var import_design_system56 = require("@ai-matrx/design-system");
|
|
15394
15601
|
|
|
15395
15602
|
// src/createTable.ts
|
|
@@ -15525,15 +15732,15 @@ function laneFor(table) {
|
|
|
15525
15732
|
return "organization";
|
|
15526
15733
|
}
|
|
15527
15734
|
function TablesHome({ onOpenTable, className }) {
|
|
15528
|
-
const client = (0,
|
|
15529
|
-
const tables = (0,
|
|
15530
|
-
const [creating, setCreating] = (0,
|
|
15531
|
-
const [name, setName] = (0,
|
|
15532
|
-
const [busy, setBusy] = (0,
|
|
15533
|
-
const [error, setError] = (0,
|
|
15534
|
-
const [importInto, setImportInto] = (0,
|
|
15535
|
-
const [boards, setBoards] = (0,
|
|
15536
|
-
(0,
|
|
15735
|
+
const client = (0, import_react117.useRecordsClient)();
|
|
15736
|
+
const tables = (0, import_react117.useTables)();
|
|
15737
|
+
const [creating, setCreating] = (0, import_react116.useState)(false);
|
|
15738
|
+
const [name, setName] = (0, import_react116.useState)("");
|
|
15739
|
+
const [busy, setBusy] = (0, import_react116.useState)(false);
|
|
15740
|
+
const [error, setError] = (0, import_react116.useState)(null);
|
|
15741
|
+
const [importInto, setImportInto] = (0, import_react116.useState)(null);
|
|
15742
|
+
const [boards, setBoards] = (0, import_react116.useState)(null);
|
|
15743
|
+
(0, import_react116.useEffect)(() => {
|
|
15537
15744
|
let cancelled = false;
|
|
15538
15745
|
void client.dashboards({}).then((result) => {
|
|
15539
15746
|
if (cancelled) return;
|
|
@@ -15543,7 +15750,7 @@ function TablesHome({ onOpenTable, className }) {
|
|
|
15543
15750
|
cancelled = true;
|
|
15544
15751
|
};
|
|
15545
15752
|
}, [client]);
|
|
15546
|
-
const create = (0,
|
|
15753
|
+
const create = (0, import_react116.useCallback)(
|
|
15547
15754
|
async (mode) => {
|
|
15548
15755
|
const trimmed = name.trim();
|
|
15549
15756
|
if (!trimmed) return;
|
|
@@ -15667,8 +15874,8 @@ function TablesHome({ onOpenTable, className }) {
|
|
|
15667
15874
|
}
|
|
15668
15875
|
|
|
15669
15876
|
// src/TablePage.tsx
|
|
15670
|
-
var
|
|
15671
|
-
var
|
|
15877
|
+
var import_react118 = require("react");
|
|
15878
|
+
var import_react119 = require("@ai-matrx/records/react");
|
|
15672
15879
|
var import_design_system57 = require("@ai-matrx/design-system");
|
|
15673
15880
|
var import_jsx_runtime61 = require("react/jsx-runtime");
|
|
15674
15881
|
function filterInWords(filter, fields) {
|
|
@@ -15750,24 +15957,24 @@ function TablePage({
|
|
|
15750
15957
|
filter,
|
|
15751
15958
|
className
|
|
15752
15959
|
}) {
|
|
15753
|
-
const client = (0,
|
|
15754
|
-
const table = (0,
|
|
15960
|
+
const client = (0, import_react119.useRecordsClient)();
|
|
15961
|
+
const table = (0, import_react119.useTable)(tableId);
|
|
15755
15962
|
const rights = useTableRights(table.data);
|
|
15756
|
-
const pageFields = (0,
|
|
15963
|
+
const pageFields = (0, import_react119.useFields)(filter ? tableId : null);
|
|
15757
15964
|
const askedInWords = filter ? filterInWords(filter, pageFields.data ?? []) : null;
|
|
15758
|
-
const organizationId = (0,
|
|
15759
|
-
const [view, setView] = (0,
|
|
15965
|
+
const organizationId = (0, import_react119.useRecordsClient)().config.organizationId;
|
|
15966
|
+
const [view, setView] = (0, import_react118.useState)(null);
|
|
15760
15967
|
const opening = openingRail(activeRecordId);
|
|
15761
15968
|
const opened = openingView(activeView, activeDashboardId);
|
|
15762
|
-
const [asking, setAsking] = (0,
|
|
15763
|
-
const [layoutFromLink, setLayoutFromLink] = (0,
|
|
15764
|
-
const [surface, setSurface] = (0,
|
|
15969
|
+
const [asking, setAsking] = (0, import_react118.useState)(null);
|
|
15970
|
+
const [layoutFromLink, setLayoutFromLink] = (0, import_react118.useState)(opened.layout);
|
|
15971
|
+
const [surface, setSurface] = (0, import_react118.useState)({
|
|
15765
15972
|
main: opened.main,
|
|
15766
15973
|
rail: opening.rail
|
|
15767
15974
|
});
|
|
15768
15975
|
const { main, rail } = surface;
|
|
15769
15976
|
const setRail = (next) => setSurface((now) => ({ ...now, rail: next }));
|
|
15770
|
-
const [openRecord, setOpenRecord] = (0,
|
|
15977
|
+
const [openRecord, setOpenRecord] = (0, import_react118.useState)(opening.record);
|
|
15771
15978
|
const viewVersion = useRecordVersion(view?.id ?? null);
|
|
15772
15979
|
const shownLayout = layoutFromLink ?? view?.layout ?? "grid";
|
|
15773
15980
|
const press = (pressed) => {
|
|
@@ -15778,19 +15985,19 @@ function TablePage({
|
|
|
15778
15985
|
}
|
|
15779
15986
|
};
|
|
15780
15987
|
const show = (next) => press({ rail: next });
|
|
15781
|
-
(0,
|
|
15988
|
+
(0, import_react118.useEffect)(() => {
|
|
15782
15989
|
if (!activeRecordId) return;
|
|
15783
15990
|
setOpenRecord(activeRecordId);
|
|
15784
15991
|
setSurface((now) => ({ ...now, rail: "record" }));
|
|
15785
15992
|
}, [activeRecordId]);
|
|
15786
|
-
(0,
|
|
15993
|
+
(0, import_react118.useEffect)(() => {
|
|
15787
15994
|
const named = pageViewFromParam(activeView);
|
|
15788
15995
|
if (named === null) return;
|
|
15789
15996
|
const isLayout = named !== "dashboards" && named !== "archived";
|
|
15790
15997
|
setLayoutFromLink(isLayout ? named : null);
|
|
15791
15998
|
setSurface((now) => ({ ...now, main: isLayout ? "records" : named }));
|
|
15792
15999
|
}, [activeView]);
|
|
15793
|
-
const patchView = (0,
|
|
16000
|
+
const patchView = (0, import_react118.useCallback)(
|
|
15794
16001
|
async (patch) => {
|
|
15795
16002
|
const current = view;
|
|
15796
16003
|
if (!current) return;
|