@ai-matrx/records-ui 0.82.0 → 0.83.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +37 -0
- package/dist/index.cjs +347 -61
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +73 -4
- package/dist/index.d.ts +73 -4
- package/dist/index.js +447 -160
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2114,7 +2114,7 @@ function useGridEditing({ tableId, fields, rows, reload, canWrite, mayWriteRow }
|
|
|
2114
2114
|
startedFrom.current = null;
|
|
2115
2115
|
}, []);
|
|
2116
2116
|
const writeCellNow = useCallback4(
|
|
2117
|
-
async (rowId, key, value) => {
|
|
2117
|
+
async (rowId, key, value, base, resent = false) => {
|
|
2118
2118
|
const id = cellKey(rowId, key);
|
|
2119
2119
|
setOptimistic((held) => ({ ...held, [id]: value }));
|
|
2120
2120
|
setSaving((held) => ({ ...held, [id]: true }));
|
|
@@ -2157,22 +2157,31 @@ function useGridEditing({ tableId, fields, rows, reload, canWrite, mayWriteRow }
|
|
|
2157
2157
|
delete next[id];
|
|
2158
2158
|
return next;
|
|
2159
2159
|
});
|
|
2160
|
-
|
|
2160
|
+
const conflict = asWriteConflict(written.error, rowId);
|
|
2161
|
+
if (written.error.code === "stale_write") {
|
|
2162
|
+
if (conflict) rememberVersion(versions.current, rowId, conflict.current_version);
|
|
2163
|
+
else versions.current.delete(rowId);
|
|
2164
|
+
if (conflict && !resent && sameValue(conflict.contested_fields[key], base)) {
|
|
2165
|
+
await writeCellNow(rowId, key, value, base, true);
|
|
2166
|
+
return;
|
|
2167
|
+
}
|
|
2168
|
+
}
|
|
2161
2169
|
setRefusals((held) => ({
|
|
2162
2170
|
...held,
|
|
2163
2171
|
[id]: {
|
|
2164
2172
|
error: written.error,
|
|
2165
|
-
conflict
|
|
2173
|
+
conflict,
|
|
2166
2174
|
attempted: value
|
|
2167
2175
|
}
|
|
2168
2176
|
}));
|
|
2169
2177
|
},
|
|
2178
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
2170
2179
|
[client, reload]
|
|
2171
2180
|
);
|
|
2172
2181
|
const writeCell = useCallback4(
|
|
2173
|
-
(rowId, key, value) => {
|
|
2182
|
+
(rowId, key, value, base) => {
|
|
2174
2183
|
const behind = queues.current.get(rowId) ?? Promise.resolve();
|
|
2175
|
-
const next = behind.then(() => writeCellNow(rowId, key, value));
|
|
2184
|
+
const next = behind.then(() => writeCellNow(rowId, key, value, base));
|
|
2176
2185
|
queues.current.set(
|
|
2177
2186
|
rowId,
|
|
2178
2187
|
next.then(
|
|
@@ -2190,7 +2199,7 @@ function useGridEditing({ tableId, fields, rows, reload, canWrite, mayWriteRow }
|
|
|
2190
2199
|
const open = editing;
|
|
2191
2200
|
if (!open) return;
|
|
2192
2201
|
const value = typed.current;
|
|
2193
|
-
if (!sameValue(startedFrom.current, value)) void writeCell(open.rowId, open.key, value);
|
|
2202
|
+
if (!sameValue(startedFrom.current, value)) void writeCell(open.rowId, open.key, value, startedFrom.current);
|
|
2194
2203
|
if (!move) {
|
|
2195
2204
|
setEditing(null);
|
|
2196
2205
|
setDraft(null);
|
|
@@ -2219,7 +2228,7 @@ function useGridEditing({ tableId, fields, rows, reload, canWrite, mayWriteRow }
|
|
|
2219
2228
|
(rowId, key) => {
|
|
2220
2229
|
const held = refusals[cellKey(rowId, key)];
|
|
2221
2230
|
if (!held) return;
|
|
2222
|
-
void writeCell(rowId, key, held.attempted);
|
|
2231
|
+
void writeCell(rowId, key, held.attempted, held.conflict?.contested_fields[key]);
|
|
2223
2232
|
},
|
|
2224
2233
|
[refusals, writeCell]
|
|
2225
2234
|
);
|
|
@@ -2241,6 +2250,33 @@ function useGridEditing({ tableId, fields, rows, reload, canWrite, mayWriteRow }
|
|
|
2241
2250
|
},
|
|
2242
2251
|
[reload]
|
|
2243
2252
|
);
|
|
2253
|
+
const keepEditing = useCallback4(
|
|
2254
|
+
(rowId, key) => {
|
|
2255
|
+
const held = refusals[cellKey(rowId, key)];
|
|
2256
|
+
if (!held || !writable(rowId)) return;
|
|
2257
|
+
startedFrom.current = shownValue(rowId, key);
|
|
2258
|
+
typed.current = held.attempted;
|
|
2259
|
+
setDraft(held.attempted);
|
|
2260
|
+
setEditing({ rowId, key });
|
|
2261
|
+
},
|
|
2262
|
+
[refusals, writable, shownValue]
|
|
2263
|
+
);
|
|
2264
|
+
const discard = useCallback4((rowId, key) => {
|
|
2265
|
+
const id = cellKey(rowId, key);
|
|
2266
|
+
setRefusals((held) => {
|
|
2267
|
+
if (!held[id]) return held;
|
|
2268
|
+
const next = { ...held };
|
|
2269
|
+
delete next[id];
|
|
2270
|
+
return next;
|
|
2271
|
+
});
|
|
2272
|
+
setOptimistic((held) => {
|
|
2273
|
+
if (!(id in held)) return held;
|
|
2274
|
+
const next = { ...held };
|
|
2275
|
+
delete next[id];
|
|
2276
|
+
return next;
|
|
2277
|
+
});
|
|
2278
|
+
setEditing((open) => open && open.rowId === rowId && open.key === key ? null : open);
|
|
2279
|
+
}, []);
|
|
2244
2280
|
const remove = useCallback4(
|
|
2245
2281
|
async (rowId) => {
|
|
2246
2282
|
setBusy(true);
|
|
@@ -2288,10 +2324,12 @@ function useGridEditing({ tableId, fields, rows, reload, canWrite, mayWriteRow }
|
|
|
2288
2324
|
commit,
|
|
2289
2325
|
setCell: (rowId, key, value) => {
|
|
2290
2326
|
if (!writable(rowId)) return;
|
|
2291
|
-
void writeCell(rowId, key, value);
|
|
2327
|
+
void writeCell(rowId, key, value, shownValue(rowId, key));
|
|
2292
2328
|
},
|
|
2293
2329
|
retry,
|
|
2294
2330
|
keepTheirs,
|
|
2331
|
+
keepEditing,
|
|
2332
|
+
discard,
|
|
2295
2333
|
remove,
|
|
2296
2334
|
addRecord,
|
|
2297
2335
|
rowError,
|
|
@@ -2360,13 +2398,28 @@ function GridCell({
|
|
|
2360
2398
|
draft: editing.draft,
|
|
2361
2399
|
onType: editing.type,
|
|
2362
2400
|
onCommit: (move) => editing.commit(move),
|
|
2363
|
-
onCancel: editing.cancel
|
|
2401
|
+
onCancel: editing.cancel,
|
|
2402
|
+
below: (
|
|
2403
|
+
// KEPT EDITING: the refusal stays beside the value it is about, so the
|
|
2404
|
+
// person reads what to change while changing it. Keep editing is the
|
|
2405
|
+
// state they are in, so only Discard is offered. It is INSIDE the open
|
|
2406
|
+
// cell, so pressing Discard is not "focus left the cell" — which would
|
|
2407
|
+
// commit the refused value one more time on its way out.
|
|
2408
|
+
refusal2 && !refusal2.conflict ? /* @__PURE__ */ jsx10(
|
|
2409
|
+
RefusalNotice,
|
|
2410
|
+
{
|
|
2411
|
+
error: refusal2.error,
|
|
2412
|
+
className: "py-1.5 text-left",
|
|
2413
|
+
onDiscard: () => editing.discard(row.id, field.key)
|
|
2414
|
+
}
|
|
2415
|
+
) : null
|
|
2416
|
+
)
|
|
2364
2417
|
}
|
|
2365
2418
|
);
|
|
2366
2419
|
}
|
|
2367
2420
|
if (editorKindFor(field) === "checkbox") {
|
|
2368
2421
|
const answered = value === true || value === false;
|
|
2369
|
-
return /* @__PURE__ */ jsxs6("span", { "data-matrx-cell-control": "", className: "flex w-full items-center gap-1.5", children: [
|
|
2422
|
+
return /* @__PURE__ */ jsxs6("span", { "data-matrx-cell-control": "", className: "flex w-full flex-wrap items-center gap-1.5", children: [
|
|
2370
2423
|
/* @__PURE__ */ jsx10(
|
|
2371
2424
|
Checkbox3,
|
|
2372
2425
|
{
|
|
@@ -2379,10 +2432,7 @@ function GridCell({
|
|
|
2379
2432
|
}
|
|
2380
2433
|
),
|
|
2381
2434
|
answered ? null : /* @__PURE__ */ jsx10("span", { className: "text-xs text-muted-foreground", title: "nobody has answered this yet", children: "\u2014" }),
|
|
2382
|
-
refusal2 ? /* @__PURE__ */
|
|
2383
|
-
/* @__PURE__ */ jsx10(RefusalLine, { error: refusal2.error }),
|
|
2384
|
-
/* @__PURE__ */ jsx10(Button5, { size: "sm", variant: "outline", onClick: () => editing?.retry(row.id, field.key), children: "Try again" })
|
|
2385
|
-
] }) : null
|
|
2435
|
+
refusal2 ? /* @__PURE__ */ jsx10(CellRefusalNotice, { refusal: refusal2, field, row, editing, typed: false }) : null
|
|
2386
2436
|
] });
|
|
2387
2437
|
}
|
|
2388
2438
|
const openThisCell = (event) => {
|
|
@@ -2455,22 +2505,48 @@ function GridCell({
|
|
|
2455
2505
|
),
|
|
2456
2506
|
onAskWhoChanged ? /* @__PURE__ */ jsx10(WhoBadge, { field, row, onAskWhoChanged }) : null,
|
|
2457
2507
|
state === "saving" ? /* @__PURE__ */ jsx10("span", { className: "px-1 text-[10px] text-muted-foreground", children: "Saving\u2026" }) : null,
|
|
2458
|
-
refusal2 ? /* @__PURE__ */
|
|
2459
|
-
/* @__PURE__ */ jsx10(RefusalLine, { error: refusal2.error }),
|
|
2460
|
-
refusal2.conflict ? /* @__PURE__ */ jsxs6("span", { className: "text-[11px]", children: [
|
|
2461
|
-
"Theirs: ",
|
|
2462
|
-
/* @__PURE__ */ jsx10("strong", { children: formatTheirs(refusal2.conflict, field.key) })
|
|
2463
|
-
] }) : null,
|
|
2464
|
-
/* @__PURE__ */ jsxs6("span", { className: "flex gap-1", children: [
|
|
2465
|
-
/* @__PURE__ */ jsx10(Button5, { size: "sm", variant: "outline", onClick: () => editing?.retry(row.id, field.key), children: "Try again" }),
|
|
2466
|
-
/* @__PURE__ */ jsx10(Button5, { size: "sm", variant: "ghost", onClick: () => editing?.keepTheirs(row.id, field.key), children: "Keep theirs" })
|
|
2467
|
-
] })
|
|
2468
|
-
] }) : null
|
|
2508
|
+
refusal2 ? /* @__PURE__ */ jsx10(CellRefusalNotice, { refusal: refusal2, field, row, editing, typed: true }) : null
|
|
2469
2509
|
]
|
|
2470
2510
|
}
|
|
2471
2511
|
)
|
|
2472
2512
|
);
|
|
2473
2513
|
}
|
|
2514
|
+
function CellRefusalNotice({
|
|
2515
|
+
refusal: refusal2,
|
|
2516
|
+
field,
|
|
2517
|
+
row,
|
|
2518
|
+
editing,
|
|
2519
|
+
typed
|
|
2520
|
+
}) {
|
|
2521
|
+
if (refusal2.conflict) {
|
|
2522
|
+
return /* @__PURE__ */ jsx10(
|
|
2523
|
+
RefusalNotice,
|
|
2524
|
+
{
|
|
2525
|
+
error: refusal2.error,
|
|
2526
|
+
className: "py-1.5 text-left",
|
|
2527
|
+
actions: /* @__PURE__ */ jsxs6("span", { className: "flex flex-col gap-1", "data-refusal-conflict": "", children: [
|
|
2528
|
+
/* @__PURE__ */ jsxs6("span", { className: "text-[11px]", children: [
|
|
2529
|
+
"Theirs: ",
|
|
2530
|
+
/* @__PURE__ */ jsx10("strong", { children: formatTheirs(refusal2.conflict, field.key) })
|
|
2531
|
+
] }),
|
|
2532
|
+
/* @__PURE__ */ jsxs6("span", { className: "flex flex-wrap gap-1", children: [
|
|
2533
|
+
/* @__PURE__ */ jsx10(Button5, { size: "sm", variant: "outline", onClick: () => editing?.retry(row.id, field.key), children: "Try again" }),
|
|
2534
|
+
/* @__PURE__ */ jsx10(Button5, { size: "sm", variant: "ghost", onClick: () => editing?.keepTheirs(row.id, field.key), children: "Keep theirs" })
|
|
2535
|
+
] })
|
|
2536
|
+
] })
|
|
2537
|
+
}
|
|
2538
|
+
);
|
|
2539
|
+
}
|
|
2540
|
+
return /* @__PURE__ */ jsx10(
|
|
2541
|
+
RefusalNotice,
|
|
2542
|
+
{
|
|
2543
|
+
error: refusal2.error,
|
|
2544
|
+
className: "py-1.5 text-left",
|
|
2545
|
+
...typed ? { onKeepEditing: () => editing?.keepEditing(row.id, field.key) } : {},
|
|
2546
|
+
onDiscard: () => editing?.discard(row.id, field.key)
|
|
2547
|
+
}
|
|
2548
|
+
);
|
|
2549
|
+
}
|
|
2474
2550
|
function WhoBadge({
|
|
2475
2551
|
field,
|
|
2476
2552
|
row,
|
|
@@ -2523,7 +2599,8 @@ function OpenCell({
|
|
|
2523
2599
|
draft,
|
|
2524
2600
|
onType,
|
|
2525
2601
|
onCommit,
|
|
2526
|
-
onCancel
|
|
2602
|
+
onCancel,
|
|
2603
|
+
below
|
|
2527
2604
|
}) {
|
|
2528
2605
|
const multiline = takesANewline(field);
|
|
2529
2606
|
const blurCommits = closesOnBlur(field);
|
|
@@ -2552,6 +2629,7 @@ function OpenCell({
|
|
|
2552
2629
|
className: "flex w-full min-w-[10rem] flex-col gap-1",
|
|
2553
2630
|
onDoubleClick: (event) => event.stopPropagation(),
|
|
2554
2631
|
onKeyDown: (event) => {
|
|
2632
|
+
if (event.target?.closest?.("[data-refusal-notice]")) return;
|
|
2555
2633
|
if (event.key === "Escape") {
|
|
2556
2634
|
event.preventDefault();
|
|
2557
2635
|
event.stopPropagation();
|
|
@@ -2577,7 +2655,8 @@ function OpenCell({
|
|
|
2577
2655
|
blurCommits ? /* @__PURE__ */ jsx10("span", { className: "text-[10px] text-muted-foreground", children: multiline ? "\u23CE saves \xB7 \u21E7\u23CE new line \xB7 Esc cancels \xB7 Tab next" : "\u23CE saves \xB7 Esc cancels \xB7 Tab next" }) : /* @__PURE__ */ jsxs6("span", { className: "flex items-center gap-1", children: [
|
|
2578
2656
|
/* @__PURE__ */ jsx10(Button5, { size: "sm", onClick: () => once(() => onCommit(null)), children: "Save" }),
|
|
2579
2657
|
/* @__PURE__ */ jsx10(Button5, { size: "sm", variant: "ghost", onClick: () => once(onCancel), children: "Cancel" })
|
|
2580
|
-
] })
|
|
2658
|
+
] }),
|
|
2659
|
+
below
|
|
2581
2660
|
]
|
|
2582
2661
|
}
|
|
2583
2662
|
);
|
|
@@ -6604,8 +6683,8 @@ function TableSettings({
|
|
|
6604
6683
|
/* @__PURE__ */ jsx21(Button16, { size: "sm", variant: "ghost", onClick: () => setAskingToRemove(null), children: "Keep it" })
|
|
6605
6684
|
] }) : null,
|
|
6606
6685
|
/* @__PURE__ */ jsxs17("ul", { className: "divide-y rounded border", children: [
|
|
6607
|
-
rows.map((field, index) => /* @__PURE__ */ jsxs17("li", { className: "flex items-center gap-2 px-2 py-1.5", children: [
|
|
6608
|
-
/* @__PURE__ */ jsx21("span", { className: "min-w-
|
|
6686
|
+
rows.map((field, index) => /* @__PURE__ */ jsxs17("li", { "data-settings-field": "", className: "flex flex-wrap items-center gap-x-2 gap-y-1 px-2 py-1.5", children: [
|
|
6687
|
+
/* @__PURE__ */ jsx21("span", { "data-settings-field-name": "", className: "min-w-[8rem] flex-1 break-words", children: fieldName(field) }),
|
|
6609
6688
|
/* @__PURE__ */ jsx21(Badge6, { variant: "outline", className: "text-[10px] font-normal", children: fieldTypeLabel(field) }),
|
|
6610
6689
|
field.required ? /* @__PURE__ */ jsx21("span", { className: "text-[10px] text-destructive", children: "required" }) : null,
|
|
6611
6690
|
/* @__PURE__ */ jsx21(
|
|
@@ -6662,9 +6741,9 @@ function TableSettings({
|
|
|
6662
6741
|
/* @__PURE__ */ jsx21("span", { className: "font-medium", children: "Proposed" }),
|
|
6663
6742
|
/* @__PURE__ */ jsx21("span", { className: "text-muted-foreground", children: proposals?.length ?? 0 })
|
|
6664
6743
|
] }),
|
|
6665
|
-
proposals === void 0 ? /* @__PURE__ */ jsx21("p", { className: "text-muted-foreground", children: "Nothing is listing proposals here yet: the store has no `custom.field_propose` door, so this panel would be inventing an empty queue. When the door lands, its rows appear in this list with the same accept and reject." }) : proposals.length === 0 ? /* @__PURE__ */ jsx21("p", { className: "text-muted-foreground", children: "No field is waiting for a decision." }) : /* @__PURE__ */ jsx21("ul", { className: "divide-y rounded border", children: proposals.map((proposal) => /* @__PURE__ */ jsxs17("li", { className: "flex items-center gap-2 px-2 py-1.5", children: [
|
|
6666
|
-
/* @__PURE__ */ jsx21("span", { className: "min-w-
|
|
6667
|
-
/* @__PURE__ */ jsx21("span", { className: "min-w-
|
|
6744
|
+
proposals === void 0 ? /* @__PURE__ */ jsx21("p", { className: "text-muted-foreground", children: "Nothing is listing proposals here yet: the store has no `custom.field_propose` door, so this panel would be inventing an empty queue. When the door lands, its rows appear in this list with the same accept and reject." }) : proposals.length === 0 ? /* @__PURE__ */ jsx21("p", { className: "text-muted-foreground", children: "No field is waiting for a decision." }) : /* @__PURE__ */ jsx21("ul", { className: "divide-y rounded border", children: proposals.map((proposal) => /* @__PURE__ */ jsxs17("li", { className: "flex flex-wrap items-center gap-x-2 gap-y-1 px-2 py-1.5", children: [
|
|
6745
|
+
/* @__PURE__ */ jsx21("span", { className: "min-w-[8rem] flex-1 break-words", children: proposal.field.label || proposal.field.key }),
|
|
6746
|
+
/* @__PURE__ */ jsx21("span", { className: "min-w-[8rem] flex-1 break-words text-muted-foreground", children: proposal.why }),
|
|
6668
6747
|
/* @__PURE__ */ jsx21(Badge6, { variant: "secondary", className: "text-[10px] font-normal", children: proposal.proposed_by }),
|
|
6669
6748
|
/* @__PURE__ */ jsx21(Button16, { size: "sm", variant: "outline", onClick: () => onAcceptProposal?.(proposal), children: "Accept" }),
|
|
6670
6749
|
/* @__PURE__ */ jsx21(Button16, { size: "sm", variant: "ghost", onClick: () => onRejectProposal?.(proposal), children: "Reject" })
|
|
@@ -6706,7 +6785,7 @@ function TableSettings({
|
|
|
6706
6785
|
|
|
6707
6786
|
// src/Peek.tsx
|
|
6708
6787
|
import { useState as useState23 } from "react";
|
|
6709
|
-
import { useFields as useFields10, useRecord as useRecord2, useRecordsClient as
|
|
6788
|
+
import { useFields as useFields10, useRecord as useRecord2, useRecordsClient as useRecordsClient12, useTable as useTable7 } from "@ai-matrx/records/react";
|
|
6710
6789
|
import { AlchemyMenu as AlchemyMenu2 } from "@ai-matrx/alchemy/react";
|
|
6711
6790
|
|
|
6712
6791
|
// src/RecordChat.tsx
|
|
@@ -6837,13 +6916,46 @@ function entriesFor(scope) {
|
|
|
6837
6916
|
import { Button as Button19, Separator as Separator8, Skeleton as Skeleton5, cn as cn19 } from "@ai-matrx/design-system";
|
|
6838
6917
|
|
|
6839
6918
|
// src/RecordForm.tsx
|
|
6840
|
-
import { useEffect as useEffect12, useMemo as useMemo16, useState as useState21 } from "react";
|
|
6919
|
+
import { useEffect as useEffect12, useMemo as useMemo16, useRef as useRef6, useState as useState21 } from "react";
|
|
6841
6920
|
import {
|
|
6842
6921
|
useFields as useFields9,
|
|
6843
6922
|
useRecord,
|
|
6844
|
-
useRecordMutation
|
|
6923
|
+
useRecordMutation,
|
|
6924
|
+
useRecordsClient as useRecordsClient11
|
|
6845
6925
|
} from "@ai-matrx/records/react";
|
|
6846
|
-
import { predictWriteRefusals } from "@ai-matrx/records/core";
|
|
6926
|
+
import { asWriteConflict as asWriteConflict3, predictWriteRefusals } from "@ai-matrx/records/core";
|
|
6927
|
+
|
|
6928
|
+
// src/writeOnTheWinningVersion.ts
|
|
6929
|
+
import { asWriteConflict as asWriteConflict2 } from "@ai-matrx/records/core";
|
|
6930
|
+
function sameStoredValue(left, right) {
|
|
6931
|
+
if (left === right) return true;
|
|
6932
|
+
const empty = (v) => v === null || v === void 0 || v === "";
|
|
6933
|
+
if (empty(left) || empty(right)) return empty(left) && empty(right);
|
|
6934
|
+
if (typeof left === "object" || typeof right === "object") {
|
|
6935
|
+
try {
|
|
6936
|
+
return JSON.stringify(left) === JSON.stringify(right);
|
|
6937
|
+
} catch {
|
|
6938
|
+
return false;
|
|
6939
|
+
}
|
|
6940
|
+
}
|
|
6941
|
+
return false;
|
|
6942
|
+
}
|
|
6943
|
+
async function updateOnTheWinningVersion(client, recordId, patch, expectedVersion, base) {
|
|
6944
|
+
const send = (expected) => client.recordUpdate({
|
|
6945
|
+
record_id: recordId,
|
|
6946
|
+
patch,
|
|
6947
|
+
...expected === null ? {} : { expectedVersion: expected }
|
|
6948
|
+
});
|
|
6949
|
+
const first = await send(expectedVersion);
|
|
6950
|
+
if (first.ok) return first;
|
|
6951
|
+
const conflict = asWriteConflict2(first.error, recordId);
|
|
6952
|
+
if (!conflict) return first;
|
|
6953
|
+
const untouched = base === "always" || Object.keys(patch).every((key) => sameStoredValue(conflict.contested_fields[key], base[key]));
|
|
6954
|
+
if (!untouched) return first;
|
|
6955
|
+
return send(conflict.current_version);
|
|
6956
|
+
}
|
|
6957
|
+
|
|
6958
|
+
// src/RecordForm.tsx
|
|
6847
6959
|
import { Button as Button17, Separator as Separator7, cn as cn18 } from "@ai-matrx/design-system";
|
|
6848
6960
|
|
|
6849
6961
|
// src/systemTable.ts
|
|
@@ -7031,13 +7143,38 @@ function RecordForm({
|
|
|
7031
7143
|
const fields = useFields9(tableId, recordType);
|
|
7032
7144
|
const existing = useRecord(recordId ?? null);
|
|
7033
7145
|
const mutation = useRecordMutation();
|
|
7146
|
+
const client = useRecordsClient11();
|
|
7147
|
+
const [edit, setEdit] = useState21({
|
|
7148
|
+
saving: false,
|
|
7149
|
+
error: null,
|
|
7150
|
+
conflict: null
|
|
7151
|
+
});
|
|
7152
|
+
const said = {
|
|
7153
|
+
saving: mutation.saving || edit.saving,
|
|
7154
|
+
error: recordId ? edit.error : mutation.error,
|
|
7155
|
+
conflict: recordId ? edit.conflict : mutation.conflict,
|
|
7156
|
+
clearConflict: () => {
|
|
7157
|
+
mutation.clearConflict();
|
|
7158
|
+
setEdit((e) => ({ ...e, conflict: null }));
|
|
7159
|
+
}
|
|
7160
|
+
};
|
|
7034
7161
|
const [draft, setDraft] = useState21({});
|
|
7035
7162
|
const [touched, setTouched] = useState21(false);
|
|
7163
|
+
const [changed, setChanged] = useState21({});
|
|
7164
|
+
const [answered, setAnswered] = useState21(null);
|
|
7036
7165
|
const loaded = useRecordVersion(recordId ?? null);
|
|
7037
7166
|
const loadedVersion = loaded.version;
|
|
7167
|
+
const changedRef = useRef6({});
|
|
7168
|
+
changedRef.current = changed;
|
|
7038
7169
|
useEffect12(() => {
|
|
7039
7170
|
const document3 = existing.data?.document;
|
|
7040
|
-
if (document3)
|
|
7171
|
+
if (!document3) return;
|
|
7172
|
+
const mine = changedRef.current;
|
|
7173
|
+
setDraft((held) => {
|
|
7174
|
+
const next = { ...document3 };
|
|
7175
|
+
for (const key of Object.keys(mine)) next[key] = held[key];
|
|
7176
|
+
return next;
|
|
7177
|
+
});
|
|
7041
7178
|
}, [existing.data?.record_id, loadedVersion]);
|
|
7042
7179
|
const document2 = useMemo16(() => {
|
|
7043
7180
|
const out = {};
|
|
@@ -7053,17 +7190,56 @@ function RecordForm({
|
|
|
7053
7190
|
);
|
|
7054
7191
|
if (fields.error) return /* @__PURE__ */ jsx23(RefusalNotice, { error: fields.error, className });
|
|
7055
7192
|
if (existing.error) return /* @__PURE__ */ jsx23(RefusalNotice, { error: existing.error, className });
|
|
7193
|
+
const storeSaid = said.error && said.error !== answered ? said.error : null;
|
|
7194
|
+
const fieldProblems = predicted.filter((p) => p.field_key);
|
|
7195
|
+
const problemsShown = (key) => touched || changed[key] ? fieldProblems.filter((p) => p.field_key === key) : [];
|
|
7196
|
+
const storeRefusalIsOnAField = storeSaid !== null && !said.conflict && storeSaid.code === "refused_by_rule" && (fields.data ?? []).some((f) => problemsShown(f.key).length > 0);
|
|
7197
|
+
const stored = existing.data?.document;
|
|
7198
|
+
const focusField = (field) => {
|
|
7199
|
+
if (!field) return;
|
|
7200
|
+
globalThis.document?.getElementById(`field-${field.id}`)?.focus();
|
|
7201
|
+
};
|
|
7202
|
+
const keepEditing = (field) => {
|
|
7203
|
+
if (storeSaid) setAnswered(storeSaid);
|
|
7204
|
+
const first = field ?? (fields.data ?? []).find((f) => problemsShown(f.key).length > 0) ?? (fields.data ?? [])[0];
|
|
7205
|
+
focusField(first);
|
|
7206
|
+
};
|
|
7207
|
+
const discard = (field) => {
|
|
7208
|
+
if (storeSaid) setAnswered(storeSaid);
|
|
7209
|
+
if (field) {
|
|
7210
|
+
setDraft((d) => ({ ...d, [field.key]: stored ? stored[field.key] : void 0 }));
|
|
7211
|
+
setChanged((c) => {
|
|
7212
|
+
const next = { ...c };
|
|
7213
|
+
delete next[field.key];
|
|
7214
|
+
return next;
|
|
7215
|
+
});
|
|
7216
|
+
return;
|
|
7217
|
+
}
|
|
7218
|
+
setDraft(stored ? { ...stored } : {});
|
|
7219
|
+
setChanged({});
|
|
7220
|
+
setTouched(false);
|
|
7221
|
+
};
|
|
7056
7222
|
const save = async () => {
|
|
7057
7223
|
setTouched(true);
|
|
7224
|
+
setAnswered(null);
|
|
7058
7225
|
if (recordId) {
|
|
7059
7226
|
const version = loadedVersion;
|
|
7060
|
-
|
|
7061
|
-
|
|
7062
|
-
|
|
7063
|
-
|
|
7227
|
+
if (Object.keys(changed).length === 0) {
|
|
7228
|
+
onSaved?.(recordId);
|
|
7229
|
+
return;
|
|
7230
|
+
}
|
|
7231
|
+
const patch = Object.fromEntries(Object.entries(document2).filter(([key]) => changed[key]));
|
|
7232
|
+
setEdit({ saving: true, error: null, conflict: null });
|
|
7233
|
+
const answered2 = await updateOnTheWinningVersion(client, recordId, patch, version, stored ?? {});
|
|
7234
|
+
setEdit({
|
|
7235
|
+
saving: false,
|
|
7236
|
+
error: answered2.ok ? null : answered2.error,
|
|
7237
|
+
conflict: answered2.ok ? null : asWriteConflict3(answered2.error, recordId)
|
|
7064
7238
|
});
|
|
7239
|
+
const moved = answered2.ok ? answered2.data : null;
|
|
7065
7240
|
if (moved !== null) {
|
|
7066
7241
|
loaded.note(moved);
|
|
7242
|
+
setChanged({});
|
|
7067
7243
|
host.notify?.success("Saved");
|
|
7068
7244
|
existing.reload();
|
|
7069
7245
|
onSaved?.(recordId);
|
|
@@ -7091,8 +7267,13 @@ function RecordForm({
|
|
|
7091
7267
|
field,
|
|
7092
7268
|
value: draft[field.key],
|
|
7093
7269
|
document: existing.data?.document,
|
|
7094
|
-
problems:
|
|
7095
|
-
onChange: (value) =>
|
|
7270
|
+
problems: problemsShown(field.key),
|
|
7271
|
+
onChange: (value) => {
|
|
7272
|
+
setDraft((d) => ({ ...d, [field.key]: value }));
|
|
7273
|
+
setChanged((c) => c[field.key] ? c : { ...c, [field.key]: true });
|
|
7274
|
+
},
|
|
7275
|
+
onKeepEditing: () => keepEditing(field),
|
|
7276
|
+
onDiscard: () => discard(field)
|
|
7096
7277
|
},
|
|
7097
7278
|
field.id
|
|
7098
7279
|
)) }),
|
|
@@ -7103,13 +7284,13 @@ function RecordForm({
|
|
|
7103
7284
|
},
|
|
7104
7285
|
p.message
|
|
7105
7286
|
)) : null,
|
|
7106
|
-
|
|
7287
|
+
storeSaid && !storeRefusalIsOnAField ? /* @__PURE__ */ jsx23(
|
|
7107
7288
|
RefusalNotice,
|
|
7108
7289
|
{
|
|
7109
|
-
error:
|
|
7110
|
-
...
|
|
7290
|
+
error: storeSaid,
|
|
7291
|
+
...said.conflict ? {
|
|
7111
7292
|
actions: /* @__PURE__ */ jsxs19("div", { className: "mt-1 space-y-1", children: [
|
|
7112
|
-
Object.entries(
|
|
7293
|
+
Object.entries(said.conflict.contested_fields).map(([key, theirs]) => {
|
|
7113
7294
|
const column = (fields.data ?? []).find((f) => f.key === key);
|
|
7114
7295
|
return /* @__PURE__ */ jsxs19("p", { className: "text-[11px]", children: [
|
|
7115
7296
|
column ? fieldName(column) : humanize(key),
|
|
@@ -7127,19 +7308,21 @@ function RecordForm({
|
|
|
7127
7308
|
size: "sm",
|
|
7128
7309
|
variant: "outline",
|
|
7129
7310
|
onClick: () => {
|
|
7311
|
+
if (said.conflict) loaded.note(said.conflict.current_version);
|
|
7130
7312
|
existing.reload();
|
|
7131
|
-
|
|
7313
|
+
said.clearConflict();
|
|
7314
|
+
setAnswered(storeSaid);
|
|
7132
7315
|
},
|
|
7133
7316
|
children: "Take theirs and start again"
|
|
7134
7317
|
}
|
|
7135
7318
|
)
|
|
7136
7319
|
] })
|
|
7137
|
-
} : {}
|
|
7320
|
+
} : { onKeepEditing: () => keepEditing(), onDiscard: () => discard() }
|
|
7138
7321
|
}
|
|
7139
7322
|
) : null,
|
|
7140
7323
|
/* @__PURE__ */ jsx23(Separator7, {}),
|
|
7141
7324
|
/* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-2", children: [
|
|
7142
|
-
/* @__PURE__ */ jsx23(Button17, { type: "submit", size: "sm", disabled:
|
|
7325
|
+
/* @__PURE__ */ jsx23(Button17, { type: "submit", size: "sm", disabled: said.saving, children: said.saving ? "Saving\u2026" : recordId ? "Save" : "Create" }),
|
|
7143
7326
|
onCancel ? /* @__PURE__ */ jsx23(Button17, { type: "button", size: "sm", variant: "ghost", onClick: onCancel, children: "Cancel" }) : null
|
|
7144
7327
|
] })
|
|
7145
7328
|
]
|
|
@@ -7151,17 +7334,20 @@ function FieldRow({
|
|
|
7151
7334
|
value,
|
|
7152
7335
|
document: document2,
|
|
7153
7336
|
problems,
|
|
7154
|
-
onChange
|
|
7337
|
+
onChange,
|
|
7338
|
+
onKeepEditing,
|
|
7339
|
+
onDiscard
|
|
7155
7340
|
}) {
|
|
7156
7341
|
const id = `field-${field.id}`;
|
|
7157
7342
|
return /* @__PURE__ */ jsxs19("div", { className: "flex min-w-0 flex-col gap-1", children: [
|
|
7158
7343
|
/* @__PURE__ */ jsx23(FieldLabel, { field, htmlFor: id, children: /* @__PURE__ */ jsx23(ProvenanceBadge, { document: document2, fieldKey: field.key }) }),
|
|
7159
7344
|
/* @__PURE__ */ jsx23(FieldControl, { field, value, onChange, id }),
|
|
7160
|
-
problems.map((problem) => /* @__PURE__ */ jsx23(
|
|
7345
|
+
problems.map((problem, index) => /* @__PURE__ */ jsx23(
|
|
7161
7346
|
RefusalNotice,
|
|
7162
7347
|
{
|
|
7163
7348
|
error: { code: "refused_by_rule", message: problem.message },
|
|
7164
|
-
className: "border-0 p-0"
|
|
7349
|
+
className: "border-0 p-0",
|
|
7350
|
+
...index === 0 ? { onKeepEditing, onDiscard } : {}
|
|
7165
7351
|
},
|
|
7166
7352
|
problem.message
|
|
7167
7353
|
))
|
|
@@ -7236,7 +7422,7 @@ function Peek({ tableId, recordId, onClose, className }) {
|
|
|
7236
7422
|
const record = useRecord2(recordId, true);
|
|
7237
7423
|
const may = useRecordRights(recordId);
|
|
7238
7424
|
const host = useRecordsUi();
|
|
7239
|
-
const organizationId =
|
|
7425
|
+
const organizationId = useRecordsClient12().config.organizationId;
|
|
7240
7426
|
const [editing, setEditing] = useState23(false);
|
|
7241
7427
|
const [talking, setTalking] = useState23(false);
|
|
7242
7428
|
if (record.error) return /* @__PURE__ */ jsx25(RefusalNotice, { error: record.error, className });
|
|
@@ -7454,6 +7640,9 @@ function viewFromRecord(row) {
|
|
|
7454
7640
|
presentation: parseGridPresentation(data["presentation"])
|
|
7455
7641
|
};
|
|
7456
7642
|
}
|
|
7643
|
+
async function saveViewPatch(client, viewId, document2, expectedVersion) {
|
|
7644
|
+
return updateOnTheWinningVersion(client, viewId, document2, expectedVersion, "always");
|
|
7645
|
+
}
|
|
7457
7646
|
function viewPatchDocument(patch) {
|
|
7458
7647
|
const out = {};
|
|
7459
7648
|
if (patch.name !== void 0) out["name"] = patch.name;
|
|
@@ -7482,15 +7671,15 @@ function parseSorts(raw) {
|
|
|
7482
7671
|
|
|
7483
7672
|
// src/ViewSwitcher.tsx
|
|
7484
7673
|
import { useEffect as useEffect15, useMemo as useMemo18, useState as useState25 } from "react";
|
|
7485
|
-
import { useFields as useFields12, useRecords as useRecords5, useRecordsClient as
|
|
7674
|
+
import { useFields as useFields12, useRecords as useRecords5, useRecordsClient as useRecordsClient14 } from "@ai-matrx/records/react";
|
|
7486
7675
|
import { Button as Button21, Skeleton as Skeleton7, cn as cn21 } from "@ai-matrx/design-system";
|
|
7487
7676
|
|
|
7488
7677
|
// src/Pipeline.tsx
|
|
7489
|
-
import { useCallback as useCallback10, useEffect as useEffect14, useMemo as useMemo17, useRef as
|
|
7678
|
+
import { useCallback as useCallback10, useEffect as useEffect14, useMemo as useMemo17, useRef as useRef7, useState as useState24 } from "react";
|
|
7490
7679
|
import {
|
|
7491
7680
|
mayDrag,
|
|
7492
7681
|
useFields as useFields11,
|
|
7493
|
-
useRecordsClient as
|
|
7682
|
+
useRecordsClient as useRecordsClient13
|
|
7494
7683
|
} from "@ai-matrx/records/react";
|
|
7495
7684
|
import { Button as Button20, Skeleton as Skeleton6, cn as cn20 } from "@ai-matrx/design-system";
|
|
7496
7685
|
import { jsx as jsx26, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
@@ -7524,7 +7713,7 @@ function PipelineBoard({
|
|
|
7524
7713
|
onMoved,
|
|
7525
7714
|
className
|
|
7526
7715
|
}) {
|
|
7527
|
-
const client =
|
|
7716
|
+
const client = useRecordsClient13();
|
|
7528
7717
|
const fields = useFields11(tableId);
|
|
7529
7718
|
const [definition, setDefinition] = useState24(null);
|
|
7530
7719
|
const [columns, setColumns] = useState24([]);
|
|
@@ -7534,7 +7723,7 @@ function PipelineBoard({
|
|
|
7534
7723
|
const [waiting, setWaiting] = useState24(/* @__PURE__ */ new Map());
|
|
7535
7724
|
const [dragging, setDragging] = useState24(null);
|
|
7536
7725
|
const [over, setOver] = useState24(null);
|
|
7537
|
-
const alive =
|
|
7726
|
+
const alive = useRef7(true);
|
|
7538
7727
|
useEffect14(() => {
|
|
7539
7728
|
alive.current = true;
|
|
7540
7729
|
return () => {
|
|
@@ -7918,7 +8107,7 @@ function unplacedName(record, field, labels) {
|
|
|
7918
8107
|
import { jsx as jsx27, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
7919
8108
|
var NO_FIELDS = [];
|
|
7920
8109
|
function useViewRecords(view, pageSize = 200, filter) {
|
|
7921
|
-
const client =
|
|
8110
|
+
const client = useRecordsClient14();
|
|
7922
8111
|
const table = useRecords5(view.ruleId ? null : view.subject, {
|
|
7923
8112
|
pageSize,
|
|
7924
8113
|
...filter ? { filter } : {}
|
|
@@ -8056,7 +8245,7 @@ function offerableFields(all, want) {
|
|
|
8056
8245
|
});
|
|
8057
8246
|
}
|
|
8058
8247
|
function useStageField(tableId) {
|
|
8059
|
-
const client =
|
|
8248
|
+
const client = useRecordsClient14();
|
|
8060
8249
|
const [stage, setStage] = useState25({
|
|
8061
8250
|
asked: false,
|
|
8062
8251
|
key: null
|
|
@@ -8339,7 +8528,7 @@ import {
|
|
|
8339
8528
|
archivedByLine,
|
|
8340
8529
|
emptyArchiveLine
|
|
8341
8530
|
} from "@ai-matrx/records";
|
|
8342
|
-
import { useFields as useFields13, useRecordsClient as
|
|
8531
|
+
import { useFields as useFields13, useRecordsClient as useRecordsClient15, useTable as useTable8 } from "@ai-matrx/records/react";
|
|
8343
8532
|
import { Button as Button22, Skeleton as Skeleton8, cn as cn22 } from "@ai-matrx/design-system";
|
|
8344
8533
|
import { jsx as jsx28, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
8345
8534
|
var ARCHIVE_MEANS = "Archiving never destroys anything. A record you remove from the grid waits here until somebody brings it back.";
|
|
@@ -8358,7 +8547,7 @@ function ArchivedView({
|
|
|
8358
8547
|
onRestored,
|
|
8359
8548
|
className
|
|
8360
8549
|
}) {
|
|
8361
|
-
const client =
|
|
8550
|
+
const client = useRecordsClient15();
|
|
8362
8551
|
const table = useTable8(tableId);
|
|
8363
8552
|
const rights = useTableRights(table.data);
|
|
8364
8553
|
const fields = useFields13(tableId);
|
|
@@ -8471,7 +8660,7 @@ import {
|
|
|
8471
8660
|
portalConfirmLine,
|
|
8472
8661
|
portalTitleTypedBack
|
|
8473
8662
|
} from "@ai-matrx/records";
|
|
8474
|
-
import { useRecordsClient as
|
|
8663
|
+
import { useRecordsClient as useRecordsClient16 } from "@ai-matrx/records/react";
|
|
8475
8664
|
import { BasicInput as BasicInput8, Button as Button23, Skeleton as Skeleton9, cn as cn23 } from "@ai-matrx/design-system";
|
|
8476
8665
|
import { jsx as jsx29, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
8477
8666
|
var ARCHIVED_NEVER_DESTROYED = "Archiving never destroys anything. What you put away waits here until somebody brings it back.";
|
|
@@ -8516,7 +8705,7 @@ function ArchivedPortals({
|
|
|
8516
8705
|
defaultOpen,
|
|
8517
8706
|
className
|
|
8518
8707
|
}) {
|
|
8519
|
-
const client =
|
|
8708
|
+
const client = useRecordsClient16();
|
|
8520
8709
|
const [rows, setRows] = useState27(null);
|
|
8521
8710
|
const [error, setError] = useState27(null);
|
|
8522
8711
|
const [confirming, setConfirming] = useState27(null);
|
|
@@ -8651,13 +8840,13 @@ function ArchivedPortals({
|
|
|
8651
8840
|
|
|
8652
8841
|
// src/ViewBar.tsx
|
|
8653
8842
|
import { useCallback as useCallback14, useEffect as useEffect18, useState as useState28 } from "react";
|
|
8654
|
-
import { useRecordsClient as
|
|
8843
|
+
import { useRecordsClient as useRecordsClient17 } from "@ai-matrx/records/react";
|
|
8655
8844
|
import { Button as Button24, Input as Input2, Skeleton as Skeleton10, cn as cn24 } from "@ai-matrx/design-system";
|
|
8656
8845
|
|
|
8657
8846
|
// src/seedOnce.ts
|
|
8658
|
-
import { useCallback as useCallback13, useRef as
|
|
8847
|
+
import { useCallback as useCallback13, useRef as useRef8 } from "react";
|
|
8659
8848
|
function useSeedGuard() {
|
|
8660
|
-
const claimed =
|
|
8849
|
+
const claimed = useRef8(/* @__PURE__ */ new Set());
|
|
8661
8850
|
return useCallback13((name) => {
|
|
8662
8851
|
if (claimed.current.has(name)) return false;
|
|
8663
8852
|
claimed.current.add(name);
|
|
@@ -8670,7 +8859,7 @@ import { useTable as useTable9 } from "@ai-matrx/records/react";
|
|
|
8670
8859
|
import { jsx as jsx30, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
8671
8860
|
var SAVED_VIEWS_UNAVAILABLE = "Saved views are not available in this organization right now, so the layout you pick here is not being kept. Everything else on this table works as usual.";
|
|
8672
8861
|
function ViewBar({ tableId, activeViewId, onActiveView, seed, className }) {
|
|
8673
|
-
const client =
|
|
8862
|
+
const client = useRecordsClient17();
|
|
8674
8863
|
const claimSeed = useSeedGuard();
|
|
8675
8864
|
const table = useTable9(tableId);
|
|
8676
8865
|
const rights = useTableRights(table.data);
|
|
@@ -8791,7 +8980,7 @@ function ViewBar({ tableId, activeViewId, onActiveView, seed, className }) {
|
|
|
8791
8980
|
|
|
8792
8981
|
// src/ProposalRow.tsx
|
|
8793
8982
|
import { useState as useState29 } from "react";
|
|
8794
|
-
import { useRecordsClient as
|
|
8983
|
+
import { useRecordsClient as useRecordsClient18 } from "@ai-matrx/records/react";
|
|
8795
8984
|
import { Badge as Badge7, Button as Button25, cn as cn25 } from "@ai-matrx/design-system";
|
|
8796
8985
|
import { jsx as jsx31, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
8797
8986
|
var ACT_WORD = PROPOSED_CHANGE_ACT_LABEL;
|
|
@@ -8804,7 +8993,7 @@ function ProposalRow({
|
|
|
8804
8993
|
onSettled,
|
|
8805
8994
|
className
|
|
8806
8995
|
}) {
|
|
8807
|
-
const client =
|
|
8996
|
+
const client = useRecordsClient18();
|
|
8808
8997
|
const [settled, setSettled] = useState29(outcome ?? null);
|
|
8809
8998
|
const [busy, setBusy] = useState29(false);
|
|
8810
8999
|
const [confirming, setConfirming] = useState29(false);
|
|
@@ -8892,13 +9081,13 @@ function ProposalRow({
|
|
|
8892
9081
|
}
|
|
8893
9082
|
|
|
8894
9083
|
// src/ActionInbox.tsx
|
|
8895
|
-
import { useCallback as useCallback16, useEffect as useEffect20, useMemo as useMemo20, useRef as
|
|
8896
|
-
import { useRecordsClient as
|
|
9084
|
+
import { useCallback as useCallback16, useEffect as useEffect20, useMemo as useMemo20, useRef as useRef9, useState as useState31 } from "react";
|
|
9085
|
+
import { useRecordsClient as useRecordsClient20 } from "@ai-matrx/records/react";
|
|
8897
9086
|
import { Badge as Badge9, Button as Button27, Skeleton as Skeleton12, cn as cn27 } from "@ai-matrx/design-system";
|
|
8898
9087
|
|
|
8899
9088
|
// src/ChecklistRunner.tsx
|
|
8900
9089
|
import { useCallback as useCallback15, useEffect as useEffect19, useMemo as useMemo19, useState as useState30 } from "react";
|
|
8901
|
-
import { useRecordsClient as
|
|
9090
|
+
import { useRecordsClient as useRecordsClient19, useTable as useTable10 } from "@ai-matrx/records/react";
|
|
8902
9091
|
import { Badge as Badge8, BasicInput as BasicInput9, BasicTextarea as BasicTextarea4, Button as Button26, Skeleton as Skeleton11, cn as cn26 } from "@ai-matrx/design-system";
|
|
8903
9092
|
import { Fragment as Fragment13, jsx as jsx32, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
8904
9093
|
var DUE_WORD = DUE_STATE_LABEL;
|
|
@@ -8912,7 +9101,7 @@ function ChecklistRunner({
|
|
|
8912
9101
|
offerToStart,
|
|
8913
9102
|
className
|
|
8914
9103
|
}) {
|
|
8915
|
-
const client =
|
|
9104
|
+
const client = useRecordsClient19();
|
|
8916
9105
|
const table = useTable10(tableId ?? null);
|
|
8917
9106
|
const rights = useTableRights(table.data);
|
|
8918
9107
|
const [runs, setRuns] = useState30(null);
|
|
@@ -9161,7 +9350,7 @@ function StepRow({
|
|
|
9161
9350
|
);
|
|
9162
9351
|
}
|
|
9163
9352
|
function useMyChecklistSteps(limit = 25) {
|
|
9164
|
-
const client =
|
|
9353
|
+
const client = useRecordsClient19();
|
|
9165
9354
|
const me = client.config.actor.user_id ?? null;
|
|
9166
9355
|
const [steps, setSteps] = useState30([]);
|
|
9167
9356
|
const [loading, setLoading] = useState30(true);
|
|
@@ -9200,7 +9389,7 @@ function useMyChecklistSteps(limit = 25) {
|
|
|
9200
9389
|
return { steps, loading, error, refresh };
|
|
9201
9390
|
}
|
|
9202
9391
|
function MyChecklistSteps({ className }) {
|
|
9203
|
-
const client =
|
|
9392
|
+
const client = useRecordsClient19();
|
|
9204
9393
|
const { steps, loading, error, refresh } = useMyChecklistSteps();
|
|
9205
9394
|
const [busy, setBusy] = useState30(null);
|
|
9206
9395
|
const [refusal2, setRefusal] = useState30(null);
|
|
@@ -9239,7 +9428,7 @@ function MyChecklistSteps({ className }) {
|
|
|
9239
9428
|
] });
|
|
9240
9429
|
}
|
|
9241
9430
|
function ChecklistsPanel({ tableId, onOpenRecord, className }) {
|
|
9242
|
-
const client =
|
|
9431
|
+
const client = useRecordsClient19();
|
|
9243
9432
|
const table = useTable10(tableId);
|
|
9244
9433
|
const rights = useTableRights(table.data);
|
|
9245
9434
|
const [templates, setTemplates] = useState30(null);
|
|
@@ -9400,7 +9589,7 @@ function ChecklistTemplateEditor({
|
|
|
9400
9589
|
onDone,
|
|
9401
9590
|
className
|
|
9402
9591
|
}) {
|
|
9403
|
-
const client =
|
|
9592
|
+
const client = useRecordsClient19();
|
|
9404
9593
|
const [name, setName] = useState30("");
|
|
9405
9594
|
const [rows, setRows] = useState30([{ ...EMPTY_ROW }]);
|
|
9406
9595
|
const [refusal2, setRefusal] = useState30(null);
|
|
@@ -9613,13 +9802,13 @@ var ACTION_KINDS = ["approval", "assignment", "proposal"];
|
|
|
9613
9802
|
var KIND_WORD = WORK_INBOX_KIND_LABEL;
|
|
9614
9803
|
var DUE_WORD2 = DUE_STATE_LABEL;
|
|
9615
9804
|
function ActionInbox({ tableId, includeSettled = false, onOpenRecord, className }) {
|
|
9616
|
-
const client =
|
|
9805
|
+
const client = useRecordsClient20();
|
|
9617
9806
|
const [items, setItems] = useState31(null);
|
|
9618
9807
|
const [error, setError] = useState31(null);
|
|
9619
9808
|
const [outcome, setOutcome] = useState31({});
|
|
9620
9809
|
const [busy, setBusy] = useState31(null);
|
|
9621
9810
|
const [cursor, setCursor] = useState31(0);
|
|
9622
|
-
const listRef =
|
|
9811
|
+
const listRef = useRef9(null);
|
|
9623
9812
|
const load = useCallback16(async () => {
|
|
9624
9813
|
const result = await client.workInbox({ limit: 200, includeDecided: includeSettled });
|
|
9625
9814
|
if (!result.ok) {
|
|
@@ -9767,16 +9956,16 @@ function ActionInbox({ tableId, includeSettled = false, onOpenRecord, className
|
|
|
9767
9956
|
}
|
|
9768
9957
|
|
|
9769
9958
|
// src/HistoryPanel.tsx
|
|
9770
|
-
import { useCallback as useCallback17, useEffect as useEffect21, useRef as
|
|
9959
|
+
import { useCallback as useCallback17, useEffect as useEffect21, useRef as useRef10, useState as useState32 } from "react";
|
|
9771
9960
|
import {
|
|
9772
9961
|
useFields as useFields14,
|
|
9773
|
-
useRecordsClient as
|
|
9962
|
+
useRecordsClient as useRecordsClient21,
|
|
9774
9963
|
useTable as useTable11
|
|
9775
9964
|
} from "@ai-matrx/records/react";
|
|
9776
9965
|
import { Badge as Badge10, Button as Button28, Skeleton as Skeleton13, cn as cn28 } from "@ai-matrx/design-system";
|
|
9777
9966
|
import { jsx as jsx34, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
9778
9967
|
function HistoryPanel({ tableId, recordId, onAskAboutField, className }) {
|
|
9779
|
-
const client =
|
|
9968
|
+
const client = useRecordsClient21();
|
|
9780
9969
|
const table = useTable11(tableId);
|
|
9781
9970
|
const fields = useFields14(tableId);
|
|
9782
9971
|
const rights = useTableRights(table.data);
|
|
@@ -9785,7 +9974,7 @@ function HistoryPanel({ tableId, recordId, onAskAboutField, className }) {
|
|
|
9785
9974
|
const [open, setOpen] = useState32(null);
|
|
9786
9975
|
const [pending, setPending] = useState32({ phase: "idle" });
|
|
9787
9976
|
const [said, setSaid] = useState32(null);
|
|
9788
|
-
const listRef =
|
|
9977
|
+
const listRef = useRef10(null);
|
|
9789
9978
|
const load = useCallback17(async () => {
|
|
9790
9979
|
const answered = await client.recordHistory({ record_id: recordId });
|
|
9791
9980
|
if (!answered.ok) {
|
|
@@ -10076,16 +10265,16 @@ function say(value, field) {
|
|
|
10076
10265
|
}
|
|
10077
10266
|
|
|
10078
10267
|
// src/CommentThread.tsx
|
|
10079
|
-
import { useCallback as useCallback18, useEffect as useEffect22, useMemo as useMemo21, useRef as
|
|
10268
|
+
import { useCallback as useCallback18, useEffect as useEffect22, useMemo as useMemo21, useRef as useRef11, useState as useState33 } from "react";
|
|
10080
10269
|
import {
|
|
10081
10270
|
useFields as useFields15,
|
|
10082
|
-
useRecordsClient as
|
|
10271
|
+
useRecordsClient as useRecordsClient22,
|
|
10083
10272
|
useTable as useTable12
|
|
10084
10273
|
} from "@ai-matrx/records/react";
|
|
10085
10274
|
import { Badge as Badge11, Button as Button29, Skeleton as Skeleton14, Textarea, cn as cn29 } from "@ai-matrx/design-system";
|
|
10086
10275
|
import { jsx as jsx35, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
10087
10276
|
function CommentThread({ tableId, recordId, fieldKey, className }) {
|
|
10088
|
-
const client =
|
|
10277
|
+
const client = useRecordsClient22();
|
|
10089
10278
|
const table = useTable12(tableId);
|
|
10090
10279
|
const fields = useFields15(tableId);
|
|
10091
10280
|
const host = useRecordsUi();
|
|
@@ -10099,7 +10288,7 @@ function CommentThread({ tableId, recordId, fieldKey, className }) {
|
|
|
10099
10288
|
const [people, setPeople] = useState33([]);
|
|
10100
10289
|
const [mentionQuery, setMentionQuery] = useState33(null);
|
|
10101
10290
|
const [picked, setPicked] = useState33([]);
|
|
10102
|
-
const box =
|
|
10291
|
+
const box = useRef11(null);
|
|
10103
10292
|
const load = useCallback18(async () => {
|
|
10104
10293
|
const answered = await client.commentThread({ record_id: recordId, include_resolved: showResolved });
|
|
10105
10294
|
if (!answered.ok) {
|
|
@@ -10322,7 +10511,7 @@ function Line({
|
|
|
10322
10511
|
import { useCallback as useCallback19, useEffect as useEffect23, useState as useState34 } from "react";
|
|
10323
10512
|
import {
|
|
10324
10513
|
useFields as useFields16,
|
|
10325
|
-
useRecordsClient as
|
|
10514
|
+
useRecordsClient as useRecordsClient23,
|
|
10326
10515
|
useTable as useTable13
|
|
10327
10516
|
} from "@ai-matrx/records/react";
|
|
10328
10517
|
import { Badge as Badge12, Button as Button30, Skeleton as Skeleton15, cn as cn30 } from "@ai-matrx/design-system";
|
|
@@ -10335,7 +10524,7 @@ function FieldHistoryPanel({
|
|
|
10335
10524
|
onOpenRecord,
|
|
10336
10525
|
className
|
|
10337
10526
|
}) {
|
|
10338
|
-
const client =
|
|
10527
|
+
const client = useRecordsClient23();
|
|
10339
10528
|
const table = useTable13(tableId);
|
|
10340
10529
|
const fields = useFields16(tableId);
|
|
10341
10530
|
const rights = useTableRights(table.data);
|
|
@@ -10548,12 +10737,12 @@ function submissionStamp(args) {
|
|
|
10548
10737
|
|
|
10549
10738
|
// src/PortalBuilder.tsx
|
|
10550
10739
|
import { useCallback as useCallback20, useEffect as useEffect24, useMemo as useMemo22, useState as useState35 } from "react";
|
|
10551
|
-
import { useRecordsClient as
|
|
10740
|
+
import { useRecordsClient as useRecordsClient24, useTables as useTables3 } from "@ai-matrx/records/react";
|
|
10552
10741
|
import { BasicInput as BasicInput10, Button as Button31, Checkbox as Checkbox5, Label as Label5, Separator as Separator9, Skeleton as Skeleton16, cn as cn31 } from "@ai-matrx/design-system";
|
|
10553
10742
|
import { Fragment as Fragment15, jsx as jsx37, jsxs as jsxs33 } from "react/jsx-runtime";
|
|
10554
10743
|
var RESTATING_REPLACES = "Saving replaces what this portal shows: a table you untick stops being visible to every client the moment you save. Who is invited is not touched.";
|
|
10555
10744
|
function PortalBuilder({ tableId, portalId, onSaved, onClose, className }) {
|
|
10556
|
-
const client =
|
|
10745
|
+
const client = useRecordsClient24();
|
|
10557
10746
|
const tables = useTables3();
|
|
10558
10747
|
const [title, setTitle] = useState35("");
|
|
10559
10748
|
const [clientTableId, setClientTableId] = useState35(null);
|
|
@@ -10843,7 +11032,7 @@ function PortalBuilder({ tableId, portalId, onSaved, onClose, className }) {
|
|
|
10843
11032
|
|
|
10844
11033
|
// src/PortalsPanel.tsx
|
|
10845
11034
|
import { useCallback as useCallback21, useEffect as useEffect25, useMemo as useMemo23, useState as useState36 } from "react";
|
|
10846
|
-
import { useRecordsClient as
|
|
11035
|
+
import { useRecordsClient as useRecordsClient25 } from "@ai-matrx/records/react";
|
|
10847
11036
|
import {
|
|
10848
11037
|
portalArchiveConsequence,
|
|
10849
11038
|
portalConfirmLine as portalConfirmLine2,
|
|
@@ -10914,7 +11103,7 @@ function stateWords(person) {
|
|
|
10914
11103
|
}
|
|
10915
11104
|
var PORTAL_SUGGESTION = "Let each of my customers sign in and see their own jobs and invoices, and nothing else.";
|
|
10916
11105
|
function PortalsPanel({ tableId, activePortalId, className }) {
|
|
10917
|
-
const client =
|
|
11106
|
+
const client = useRecordsClient25();
|
|
10918
11107
|
const host = useRecordsUi();
|
|
10919
11108
|
const [portals, setPortals] = useState36(null);
|
|
10920
11109
|
const [exposures, setExposures] = useState36([]);
|
|
@@ -11094,7 +11283,7 @@ function ArchivePortalControl({
|
|
|
11094
11283
|
portal,
|
|
11095
11284
|
onArchived
|
|
11096
11285
|
}) {
|
|
11097
|
-
const client =
|
|
11286
|
+
const client = useRecordsClient25();
|
|
11098
11287
|
const [asking, setAsking] = useState36(false);
|
|
11099
11288
|
const [typed, setTyped] = useState36("");
|
|
11100
11289
|
const [busy, setBusy] = useState36(false);
|
|
@@ -11201,7 +11390,7 @@ function PortalDetail({
|
|
|
11201
11390
|
origin,
|
|
11202
11391
|
onChanged
|
|
11203
11392
|
}) {
|
|
11204
|
-
const client =
|
|
11393
|
+
const client = useRecordsClient25();
|
|
11205
11394
|
const [card, setCard] = useState36(null);
|
|
11206
11395
|
const [error, setError] = useState36(null);
|
|
11207
11396
|
const load = useCallback21(async () => {
|
|
@@ -11444,7 +11633,7 @@ function Preview({
|
|
|
11444
11633
|
] });
|
|
11445
11634
|
}
|
|
11446
11635
|
function Invite({ card, onInvited }) {
|
|
11447
|
-
const client =
|
|
11636
|
+
const client = useRecordsClient25();
|
|
11448
11637
|
const [rows, setRows] = useState36(null);
|
|
11449
11638
|
const [clientTable, setClientTable] = useState36(null);
|
|
11450
11639
|
const [search, setSearch] = useState36("");
|
|
@@ -11556,7 +11745,7 @@ function Invite({ card, onInvited }) {
|
|
|
11556
11745
|
|
|
11557
11746
|
// src/DigestScheduler.tsx
|
|
11558
11747
|
import { useCallback as useCallback22, useEffect as useEffect26, useMemo as useMemo24, useState as useState37 } from "react";
|
|
11559
|
-
import { useRecordsClient as
|
|
11748
|
+
import { useRecordsClient as useRecordsClient26 } from "@ai-matrx/records/react";
|
|
11560
11749
|
import { BasicInput as BasicInput12, Button as Button34, Checkbox as Checkbox6, Label as Label6, Separator as Separator11, Skeleton as Skeleton18, cn as cn34 } from "@ai-matrx/design-system";
|
|
11561
11750
|
import { Fragment as Fragment17, jsx as jsx40, jsxs as jsxs36 } from "react/jsx-runtime";
|
|
11562
11751
|
var WEEKDAYS = ["monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"];
|
|
@@ -11580,7 +11769,7 @@ function DigestScheduler({
|
|
|
11580
11769
|
onClose,
|
|
11581
11770
|
className
|
|
11582
11771
|
}) {
|
|
11583
|
-
const client =
|
|
11772
|
+
const client = useRecordsClient26();
|
|
11584
11773
|
const host = useRecordsUi();
|
|
11585
11774
|
const [views, setViews] = useState37(null);
|
|
11586
11775
|
const [cadences, setCadences] = useState37([]);
|
|
@@ -11872,7 +12061,7 @@ function DigestScheduler({
|
|
|
11872
12061
|
|
|
11873
12062
|
// src/SubscriptionsPanel.tsx
|
|
11874
12063
|
import { useCallback as useCallback23, useEffect as useEffect27, useState as useState38 } from "react";
|
|
11875
|
-
import { useRecordsClient as
|
|
12064
|
+
import { useRecordsClient as useRecordsClient27 } from "@ai-matrx/records/react";
|
|
11876
12065
|
import { Badge as Badge14, Button as Button35, Skeleton as Skeleton19, Switch as Switch2, cn as cn35 } from "@ai-matrx/design-system";
|
|
11877
12066
|
import { jsx as jsx41, jsxs as jsxs37 } from "react/jsx-runtime";
|
|
11878
12067
|
var RULE_NOT_HERE_LINE = "The link named a digest that is not one of yours on this table \u2014 it belongs to somebody else, or it was switched off for good. Yours are listed here; its owner can change theirs.";
|
|
@@ -11881,10 +12070,25 @@ function whenItFires(subscription) {
|
|
|
11881
12070
|
const every = subscription.cadence === "hourly" ? "an hourly summary" : subscription.cadence === "weekly" ? "a weekly summary" : "a daily summary";
|
|
11882
12071
|
return subscription.schedule ? `${every}, ${subscription.schedule}` : every;
|
|
11883
12072
|
}
|
|
12073
|
+
var PERIOD_MS = {
|
|
12074
|
+
hourly: 60 * 60 * 1e3,
|
|
12075
|
+
daily: 24 * 60 * 60 * 1e3,
|
|
12076
|
+
weekly: 7 * 24 * 60 * 60 * 1e3
|
|
12077
|
+
};
|
|
12078
|
+
function nextSummaryAt(subscription, now) {
|
|
12079
|
+
if (!subscription.next_digest_at) return null;
|
|
12080
|
+
const due = new Date(subscription.next_digest_at);
|
|
12081
|
+
if (Number.isNaN(due.getTime())) return null;
|
|
12082
|
+
if (due.getTime() > now.getTime()) return due;
|
|
12083
|
+
const period = PERIOD_MS[subscription.cadence];
|
|
12084
|
+
if (!period) return due;
|
|
12085
|
+
const behind = now.getTime() - due.getTime();
|
|
12086
|
+
return new Date(due.getTime() + (Math.floor(behind / period) + 1) * period);
|
|
12087
|
+
}
|
|
11884
12088
|
var CHANNEL_WORDS2 = SUBSCRIPTION_CHANNEL_LABEL;
|
|
11885
12089
|
var DIGEST_SUGGESTION = "Email me a summary of this every Monday at 8 in the morning.";
|
|
11886
12090
|
function SubscriptionsPanel({ tableId, activeRuleId, className }) {
|
|
11887
|
-
const client =
|
|
12091
|
+
const client = useRecordsClient27();
|
|
11888
12092
|
const [rows, setRows] = useState38(null);
|
|
11889
12093
|
const [error, setError] = useState38(null);
|
|
11890
12094
|
const [busy, setBusy] = useState38(null);
|
|
@@ -12008,7 +12212,7 @@ function SubscriptionsPanel({ tableId, activeRuleId, className }) {
|
|
|
12008
12212
|
/* @__PURE__ */ jsxs37("div", { className: "mt-1.5 flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-muted-foreground", children: [
|
|
12009
12213
|
subscription.next_digest_at ? /* @__PURE__ */ jsxs37("span", { children: [
|
|
12010
12214
|
"Next summary ",
|
|
12011
|
-
new Date(
|
|
12215
|
+
nextSummaryAt(subscription, /* @__PURE__ */ new Date())?.toLocaleString()
|
|
12012
12216
|
] }) : subscription.cadence === "instant" ? null : subscription.muted ? /* @__PURE__ */ jsx41("span", { children: "No next summary while it is off." }) : null,
|
|
12013
12217
|
subscription.last_sent_at ? /* @__PURE__ */ jsxs37("span", { children: [
|
|
12014
12218
|
"Last told you ",
|
|
@@ -12077,14 +12281,14 @@ function SubscriptionsPanel({ tableId, activeRuleId, className }) {
|
|
|
12077
12281
|
|
|
12078
12282
|
// src/FormBuilder.tsx
|
|
12079
12283
|
import { useCallback as useCallback25, useEffect as useEffect30, useMemo as useMemo26, useState as useState41 } from "react";
|
|
12080
|
-
import { useFields as useFields18, useRecordsClient as
|
|
12284
|
+
import { useFields as useFields18, useRecordsClient as useRecordsClient29, useTable as useTable14 } from "@ai-matrx/records/react";
|
|
12081
12285
|
|
|
12082
12286
|
// src/publish-gate.ts
|
|
12083
12287
|
import { useEffect as useEffect28, useState as useState39 } from "react";
|
|
12084
|
-
import { useRecordsClient as
|
|
12288
|
+
import { useRecordsClient as useRecordsClient28 } from "@ai-matrx/records/react";
|
|
12085
12289
|
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.";
|
|
12086
12290
|
function usePublishGate() {
|
|
12087
|
-
const client =
|
|
12291
|
+
const client = useRecordsClient28();
|
|
12088
12292
|
const [storeOpen, setStoreOpen] = useState39(null);
|
|
12089
12293
|
useEffect28(() => {
|
|
12090
12294
|
let alive = true;
|
|
@@ -12117,7 +12321,7 @@ import {
|
|
|
12117
12321
|
} from "@ai-matrx/design-system";
|
|
12118
12322
|
|
|
12119
12323
|
// src/FormRunner.tsx
|
|
12120
|
-
import { useCallback as useCallback24, useEffect as useEffect29, useMemo as useMemo25, useRef as
|
|
12324
|
+
import { useCallback as useCallback24, useEffect as useEffect29, useMemo as useMemo25, useRef as useRef12, useState as useState40 } from "react";
|
|
12121
12325
|
import { useFields as useFields17, useOptionalRecordsClient as useOptionalRecordsClient4 } from "@ai-matrx/records/react";
|
|
12122
12326
|
import { Button as Button36, Progress, Skeleton as Skeleton20, cn as cn36 } from "@ai-matrx/design-system";
|
|
12123
12327
|
import { Fragment as Fragment18, jsx as jsx42, jsxs as jsxs38 } from "react/jsx-runtime";
|
|
@@ -12202,8 +12406,8 @@ function FormStage({
|
|
|
12202
12406
|
const [writing, setWriting] = useState40(false);
|
|
12203
12407
|
const [done, setDone] = useState40(null);
|
|
12204
12408
|
const [hidden, setHidden] = useState40({});
|
|
12205
|
-
const decoy =
|
|
12206
|
-
const stage =
|
|
12409
|
+
const decoy = useRef12("");
|
|
12410
|
+
const stage = useRef12(null);
|
|
12207
12411
|
const questions = useMemo25(() => {
|
|
12208
12412
|
const byKey = new Map((fields ?? []).map((f) => [f.key, f]));
|
|
12209
12413
|
return (form.questions ?? []).map((q) => {
|
|
@@ -12467,7 +12671,7 @@ function whyNotAskable(fields, hidden = []) {
|
|
|
12467
12671
|
// src/FormBuilder.tsx
|
|
12468
12672
|
import { Fragment as Fragment19, jsx as jsx43, jsxs as jsxs39 } from "react/jsx-runtime";
|
|
12469
12673
|
function FormBuilder({ tableId, seed, activeFormId, onActiveForm, className }) {
|
|
12470
|
-
const client =
|
|
12674
|
+
const client = useRecordsClient29();
|
|
12471
12675
|
const publishGate = usePublishGate();
|
|
12472
12676
|
const host = useRecordsUi();
|
|
12473
12677
|
const claimSeed = useSeedGuard();
|
|
@@ -12927,13 +13131,13 @@ function groupLabel(groups) {
|
|
|
12927
13131
|
import {
|
|
12928
13132
|
useEffect as useEffect31,
|
|
12929
13133
|
useId as useId2,
|
|
12930
|
-
useRef as
|
|
13134
|
+
useRef as useRef13,
|
|
12931
13135
|
useState as useState42
|
|
12932
13136
|
} from "react";
|
|
12933
13137
|
import { cn as cn38 } from "@ai-matrx/design-system";
|
|
12934
13138
|
import { jsx as jsx44, jsxs as jsxs40 } from "react/jsx-runtime";
|
|
12935
13139
|
function useMeasuredWidth(fallback = 480) {
|
|
12936
|
-
const ref =
|
|
13140
|
+
const ref = useRef13(null);
|
|
12937
13141
|
const [width, setWidth] = useState42(fallback);
|
|
12938
13142
|
useEffect31(() => {
|
|
12939
13143
|
const node = ref.current;
|
|
@@ -13060,11 +13264,11 @@ function isSignatureField(field) {
|
|
|
13060
13264
|
|
|
13061
13265
|
// src/DocTemplate.tsx
|
|
13062
13266
|
import { useCallback as useCallback26, useEffect as useEffect32, useState as useState43 } from "react";
|
|
13063
|
-
import { useFields as useFields19, useRecordsClient as
|
|
13267
|
+
import { useFields as useFields19, useRecordsClient as useRecordsClient30, useTable as useTable15 } from "@ai-matrx/records/react";
|
|
13064
13268
|
import { BasicInput as BasicInput14, BasicTextarea as BasicTextarea6, Button as Button38, Label as Label8, Skeleton as Skeleton22, cn as cn39 } from "@ai-matrx/design-system";
|
|
13065
13269
|
import { jsx as jsx45, jsxs as jsxs41 } from "react/jsx-runtime";
|
|
13066
13270
|
function DocTemplate({ tableId, seed, activeTemplateId, onActiveTemplate, className }) {
|
|
13067
|
-
const client =
|
|
13271
|
+
const client = useRecordsClient30();
|
|
13068
13272
|
const claimSeed = useSeedGuard();
|
|
13069
13273
|
const table = useTable15(tableId);
|
|
13070
13274
|
const rights = useTableRights(table.data);
|
|
@@ -13243,18 +13447,18 @@ function DocTemplate({ tableId, seed, activeTemplateId, onActiveTemplate, classN
|
|
|
13243
13447
|
}
|
|
13244
13448
|
|
|
13245
13449
|
// src/DocRender.tsx
|
|
13246
|
-
import { useCallback as useCallback27, useEffect as useEffect33, useRef as
|
|
13247
|
-
import { useRecordsClient as
|
|
13450
|
+
import { useCallback as useCallback27, useEffect as useEffect33, useRef as useRef14, useState as useState44 } from "react";
|
|
13451
|
+
import { useRecordsClient as useRecordsClient31 } from "@ai-matrx/records/react";
|
|
13248
13452
|
import { Button as Button39, Skeleton as Skeleton23, cn as cn40 } from "@ai-matrx/design-system";
|
|
13249
13453
|
import { jsx as jsx46, jsxs as jsxs42 } from "react/jsx-runtime";
|
|
13250
13454
|
function DocRender({ templateId, recordId, filename, onRendered, className }) {
|
|
13251
|
-
const client =
|
|
13455
|
+
const client = useRecordsClient31();
|
|
13252
13456
|
const [preview, setPreview] = useState44(null);
|
|
13253
13457
|
const [renders, setRenders] = useState44(null);
|
|
13254
13458
|
const [showing, setShowing] = useState44(null);
|
|
13255
13459
|
const [error, setError] = useState44(null);
|
|
13256
13460
|
const [busy, setBusy] = useState44(null);
|
|
13257
|
-
const paper =
|
|
13461
|
+
const paper = useRef14(null);
|
|
13258
13462
|
const load = useCallback27(async () => {
|
|
13259
13463
|
const [body, held] = await Promise.all([
|
|
13260
13464
|
client.docRenderBody({ template_id: templateId, record_id: recordId }),
|
|
@@ -13357,12 +13561,12 @@ function DocRender({ templateId, recordId, filename, onRendered, className }) {
|
|
|
13357
13561
|
|
|
13358
13562
|
// src/SignBlock.tsx
|
|
13359
13563
|
import { useCallback as useCallback28, useEffect as useEffect34, useState as useState45 } from "react";
|
|
13360
|
-
import { useFields as useFields20, useRecordsClient as
|
|
13564
|
+
import { useFields as useFields20, useRecordsClient as useRecordsClient32 } from "@ai-matrx/records/react";
|
|
13361
13565
|
import { BasicInput as BasicInput15, Button as Button40, Skeleton as Skeleton24, cn as cn41 } from "@ai-matrx/design-system";
|
|
13362
13566
|
import { useTable as useTable16 } from "@ai-matrx/records/react";
|
|
13363
13567
|
import { jsx as jsx47, jsxs as jsxs43 } from "react/jsx-runtime";
|
|
13364
13568
|
function SignBlock({ tableId, recordId, render, className }) {
|
|
13365
|
-
const client =
|
|
13569
|
+
const client = useRecordsClient32();
|
|
13366
13570
|
const table = useTable16(tableId);
|
|
13367
13571
|
const rights = useTableRights(table.data);
|
|
13368
13572
|
const fields = useFields20(tableId);
|
|
@@ -13508,13 +13712,13 @@ function SignBlock({ tableId, recordId, render, className }) {
|
|
|
13508
13712
|
|
|
13509
13713
|
// src/NotifyRuleEditor.tsx
|
|
13510
13714
|
import { useCallback as useCallback29, useEffect as useEffect35, useState as useState46 } from "react";
|
|
13511
|
-
import { useRecordsClient as
|
|
13715
|
+
import { useRecordsClient as useRecordsClient33, useTable as useTable17 } from "@ai-matrx/records/react";
|
|
13512
13716
|
import { Button as Button41, Skeleton as Skeleton25, cn as cn42 } from "@ai-matrx/design-system";
|
|
13513
13717
|
import { jsx as jsx48, jsxs as jsxs44 } from "react/jsx-runtime";
|
|
13514
13718
|
var CADENCE_WORDS2 = SUBSCRIPTION_CADENCE_LABEL;
|
|
13515
13719
|
var CHANNEL_WORDS3 = SUBSCRIPTION_CHANNEL_LABEL;
|
|
13516
13720
|
function NotifyRuleEditor({ tableId, seed, className }) {
|
|
13517
|
-
const client =
|
|
13721
|
+
const client = useRecordsClient33();
|
|
13518
13722
|
const host = useRecordsUi();
|
|
13519
13723
|
const table = useTable17(tableId);
|
|
13520
13724
|
const rights = useTableRights(table.data);
|
|
@@ -14028,7 +14232,7 @@ function Drawing({
|
|
|
14028
14232
|
|
|
14029
14233
|
// src/DashboardCanvas.tsx
|
|
14030
14234
|
import { useCallback as useCallback30, useEffect as useEffect36, useMemo as useMemo28, useState as useState47 } from "react";
|
|
14031
|
-
import { useFields as useFields21, useRecordsClient as
|
|
14235
|
+
import { useFields as useFields21, useRecordsClient as useRecordsClient34, useTable as useTable18 } from "@ai-matrx/records/react";
|
|
14032
14236
|
import {
|
|
14033
14237
|
BasicInput as BasicInput16,
|
|
14034
14238
|
Button as Button42,
|
|
@@ -14042,7 +14246,7 @@ import {
|
|
|
14042
14246
|
} from "@ai-matrx/design-system";
|
|
14043
14247
|
import { Fragment as Fragment21, jsx as jsx50, jsxs as jsxs46 } from "react/jsx-runtime";
|
|
14044
14248
|
function DashboardCanvas({ tableId, activeDashboardId, filter, className }) {
|
|
14045
|
-
const client =
|
|
14249
|
+
const client = useRecordsClient34();
|
|
14046
14250
|
const host = useRecordsUi();
|
|
14047
14251
|
const table = useTable18(tableId);
|
|
14048
14252
|
const rights = useTableRights(table.data);
|
|
@@ -14371,7 +14575,7 @@ function GroupingPicker({
|
|
|
14371
14575
|
|
|
14372
14576
|
// src/FormsPanel.tsx
|
|
14373
14577
|
import { useCallback as useCallback31, useEffect as useEffect37, useState as useState48 } from "react";
|
|
14374
|
-
import { useRecordsClient as
|
|
14578
|
+
import { useRecordsClient as useRecordsClient35, useTable as useTable19 } from "@ai-matrx/records/react";
|
|
14375
14579
|
import { publicFormPath as publicFormPath2 } from "@ai-matrx/records";
|
|
14376
14580
|
import { Badge as Badge15, Button as Button43, Skeleton as Skeleton27, cn as cn45 } from "@ai-matrx/design-system";
|
|
14377
14581
|
import { Fragment as Fragment22, jsx as jsx51, jsxs as jsxs47 } from "react/jsx-runtime";
|
|
@@ -14383,7 +14587,7 @@ function formSuggestion(tableName2) {
|
|
|
14383
14587
|
return `Make me a form that collects new ${subject} entries and tells me when somebody answers.`;
|
|
14384
14588
|
}
|
|
14385
14589
|
function FormsPanel({ tableId, activeFormId, className }) {
|
|
14386
|
-
const client =
|
|
14590
|
+
const client = useRecordsClient35();
|
|
14387
14591
|
const publishGate = usePublishGate();
|
|
14388
14592
|
const host = useRecordsUi();
|
|
14389
14593
|
const table = useTable19(tableId);
|
|
@@ -14540,7 +14744,7 @@ function FormsPanel({ tableId, activeFormId, className }) {
|
|
|
14540
14744
|
|
|
14541
14745
|
// src/BookingBuilder.tsx
|
|
14542
14746
|
import { useCallback as useCallback32, useEffect as useEffect38, useMemo as useMemo29, useState as useState49 } from "react";
|
|
14543
|
-
import { useFields as useFields22, useRecordsClient as
|
|
14747
|
+
import { useFields as useFields22, useRecordsClient as useRecordsClient36, useTable as useTable20 } from "@ai-matrx/records/react";
|
|
14544
14748
|
import {
|
|
14545
14749
|
bookingPath
|
|
14546
14750
|
} from "@ai-matrx/records";
|
|
@@ -14570,7 +14774,7 @@ function draftWindows(availability) {
|
|
|
14570
14774
|
});
|
|
14571
14775
|
}
|
|
14572
14776
|
function BookingBuilder({ tableId, bookingId, onSaved, onClose, className }) {
|
|
14573
|
-
const client =
|
|
14777
|
+
const client = useRecordsClient36();
|
|
14574
14778
|
const publishGate = usePublishGate();
|
|
14575
14779
|
const host = useRecordsUi();
|
|
14576
14780
|
const table = useTable20(tableId);
|
|
@@ -14888,7 +15092,7 @@ function BookingBuilder({ tableId, bookingId, onSaved, onClose, className }) {
|
|
|
14888
15092
|
|
|
14889
15093
|
// src/BookingSlots.tsx
|
|
14890
15094
|
import { useCallback as useCallback33, useEffect as useEffect39, useMemo as useMemo30, useState as useState50 } from "react";
|
|
14891
|
-
import { useRecordsClient as
|
|
15095
|
+
import { useRecordsClient as useRecordsClient37, useMyLevels as useMyLevels2 } from "@ai-matrx/records/react";
|
|
14892
15096
|
import { bookingPath as bookingPath2 } from "@ai-matrx/records";
|
|
14893
15097
|
import { Badge as Badge16, Button as Button45, Skeleton as Skeleton29, cn as cn47 } from "@ai-matrx/design-system";
|
|
14894
15098
|
import { Fragment as Fragment24, jsx as jsx53, jsxs as jsxs49 } from "react/jsx-runtime";
|
|
@@ -14900,7 +15104,7 @@ function bookingSuggestion(tableName2) {
|
|
|
14900
15104
|
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.";
|
|
14901
15105
|
var STATE_WORDS = BOOKING_PAGE_STATE_LABEL;
|
|
14902
15106
|
function BookingSlots({ tableId, className }) {
|
|
14903
|
-
const client =
|
|
15107
|
+
const client = useRecordsClient37();
|
|
14904
15108
|
const host = useRecordsUi();
|
|
14905
15109
|
const [pages, setPages] = useState50(null);
|
|
14906
15110
|
const [error, setError] = useState50(null);
|
|
@@ -15087,18 +15291,18 @@ function nextInWords(page) {
|
|
|
15087
15291
|
}
|
|
15088
15292
|
|
|
15089
15293
|
// src/CaptureSheet.tsx
|
|
15090
|
-
import { useCallback as useCallback35, useEffect as useEffect41, useRef as
|
|
15091
|
-
import { useFields as useFields23, useRecordsClient as
|
|
15294
|
+
import { useCallback as useCallback35, useEffect as useEffect41, useRef as useRef16, useState as useState52 } from "react";
|
|
15295
|
+
import { useFields as useFields23, useRecordsClient as useRecordsClient39, useTable as useTable21 } from "@ai-matrx/records/react";
|
|
15092
15296
|
import { Button as Button47, Input as Input4, Skeleton as Skeleton31, Textarea as Textarea3, cn as cn49 } from "@ai-matrx/design-system";
|
|
15093
15297
|
|
|
15094
15298
|
// src/CaptureRun.tsx
|
|
15095
|
-
import { useCallback as useCallback34, useEffect as useEffect40, useMemo as useMemo31, useRef as
|
|
15299
|
+
import { useCallback as useCallback34, useEffect as useEffect40, useMemo as useMemo31, useRef as useRef15, useState as useState51 } from "react";
|
|
15096
15300
|
import {
|
|
15097
15301
|
coerceTypedAnswer as coerceTypedAnswer2,
|
|
15098
15302
|
coercionLabel,
|
|
15099
15303
|
openCaptureQueue
|
|
15100
15304
|
} from "@ai-matrx/records";
|
|
15101
|
-
import { useRecordsClient as
|
|
15305
|
+
import { useRecordsClient as useRecordsClient38 } from "@ai-matrx/records/react";
|
|
15102
15306
|
import { Button as Button46, Input as Input3, Skeleton as Skeleton30, Textarea as Textarea2, cn as cn48 } from "@ai-matrx/design-system";
|
|
15103
15307
|
import { jsx as jsx54, jsxs as jsxs50 } from "react/jsx-runtime";
|
|
15104
15308
|
function controlFor(field) {
|
|
@@ -15137,7 +15341,7 @@ function whereWeAre(timeoutMs = 4e3) {
|
|
|
15137
15341
|
});
|
|
15138
15342
|
}
|
|
15139
15343
|
function CaptureRun({ sheetId, face: given, className }) {
|
|
15140
|
-
const client =
|
|
15344
|
+
const client = useRecordsClient38();
|
|
15141
15345
|
const host = useRecordsUi();
|
|
15142
15346
|
const [face, setFace] = useState51(given);
|
|
15143
15347
|
const [loadFailed, setLoadFailed] = useState51(null);
|
|
@@ -15150,7 +15354,7 @@ function CaptureRun({ sheetId, face: given, className }) {
|
|
|
15150
15354
|
const [items, setItems] = useState51([]);
|
|
15151
15355
|
const [lastSynced, setLastSynced] = useState51(null);
|
|
15152
15356
|
const [sending, setSending] = useState51(false);
|
|
15153
|
-
const queueRef =
|
|
15357
|
+
const queueRef = useRef15(null);
|
|
15154
15358
|
useEffect40(() => {
|
|
15155
15359
|
const q2 = openCaptureQueue({
|
|
15156
15360
|
onChange: (c, all) => {
|
|
@@ -15517,7 +15721,7 @@ function AdHocCaptureSheet({
|
|
|
15517
15721
|
attachmentField,
|
|
15518
15722
|
className
|
|
15519
15723
|
}) {
|
|
15520
|
-
const client =
|
|
15724
|
+
const client = useRecordsClient39();
|
|
15521
15725
|
const host = useRecordsUi();
|
|
15522
15726
|
const table = useTable21(tableId);
|
|
15523
15727
|
const fields = useFields23(tableId);
|
|
@@ -15530,7 +15734,7 @@ function AdHocCaptureSheet({
|
|
|
15530
15734
|
const [error, setError] = useState52(null);
|
|
15531
15735
|
const [uploadError, setUploadError] = useState52(null);
|
|
15532
15736
|
const [flushing, setFlushing] = useState52(false);
|
|
15533
|
-
const queue =
|
|
15737
|
+
const queue = useRef16([]);
|
|
15534
15738
|
const keep = useCallback35(
|
|
15535
15739
|
async (next) => {
|
|
15536
15740
|
queue.current = next;
|
|
@@ -15719,11 +15923,11 @@ function AdHocCaptureSheet({
|
|
|
15719
15923
|
|
|
15720
15924
|
// src/PortalShell.tsx
|
|
15721
15925
|
import { useCallback as useCallback36, useEffect as useEffect42, useState as useState53 } from "react";
|
|
15722
|
-
import { useRecordsClient as
|
|
15926
|
+
import { useRecordsClient as useRecordsClient40 } from "@ai-matrx/records/react";
|
|
15723
15927
|
import { Button as Button48, Skeleton as Skeleton32, cn as cn50 } from "@ai-matrx/design-system";
|
|
15724
15928
|
import { jsx as jsx56, jsxs as jsxs52 } from "react/jsx-runtime";
|
|
15725
15929
|
function PortalShell({ tableId, form, resourceType = "record", className }) {
|
|
15726
|
-
const client =
|
|
15930
|
+
const client = useRecordsClient40();
|
|
15727
15931
|
const [card, setCard] = useState53(null);
|
|
15728
15932
|
const [reach, setReach] = useState53(null);
|
|
15729
15933
|
const [error, setError] = useState53(null);
|
|
@@ -15802,7 +16006,7 @@ function PortalShell({ tableId, form, resourceType = "record", className }) {
|
|
|
15802
16006
|
] });
|
|
15803
16007
|
}
|
|
15804
16008
|
function PortalRow({ tableId, recordId }) {
|
|
15805
|
-
const client =
|
|
16009
|
+
const client = useRecordsClient40();
|
|
15806
16010
|
const [title, setTitle] = useState53(null);
|
|
15807
16011
|
useEffect42(() => {
|
|
15808
16012
|
let cancelled = false;
|
|
@@ -15825,11 +16029,11 @@ function PortalRow({ tableId, recordId }) {
|
|
|
15825
16029
|
|
|
15826
16030
|
// src/PublicViewPage.tsx
|
|
15827
16031
|
import { useCallback as useCallback37, useEffect as useEffect43, useState as useState54 } from "react";
|
|
15828
|
-
import { useRecordsClient as
|
|
16032
|
+
import { useRecordsClient as useRecordsClient41 } from "@ai-matrx/records/react";
|
|
15829
16033
|
import { Skeleton as Skeleton33, cn as cn51 } from "@ai-matrx/design-system";
|
|
15830
16034
|
import { jsx as jsx57, jsxs as jsxs53 } from "react/jsx-runtime";
|
|
15831
16035
|
function PublicViewPage({ slug, className }) {
|
|
15832
|
-
const client =
|
|
16036
|
+
const client = useRecordsClient41();
|
|
15833
16037
|
const [binding, setBinding] = useState54(null);
|
|
15834
16038
|
const [rows, setRows] = useState54(null);
|
|
15835
16039
|
const [fields, setFields] = useState54(null);
|
|
@@ -15906,7 +16110,7 @@ function PublicRow({ row, fields }) {
|
|
|
15906
16110
|
|
|
15907
16111
|
// src/EmbedFrame.tsx
|
|
15908
16112
|
import { useCallback as useCallback38, useEffect as useEffect44, useState as useState55 } from "react";
|
|
15909
|
-
import { useRecordsClient as
|
|
16113
|
+
import { useRecordsClient as useRecordsClient42 } from "@ai-matrx/records/react";
|
|
15910
16114
|
import { Button as Button49, Input as Input5, Skeleton as Skeleton34, Textarea as Textarea4, cn as cn52 } from "@ai-matrx/design-system";
|
|
15911
16115
|
import { useTable as useTable22 } from "@ai-matrx/records/react";
|
|
15912
16116
|
import { Fragment as Fragment26, jsx as jsx58, jsxs as jsxs54 } from "react/jsx-runtime";
|
|
@@ -15918,7 +16122,7 @@ function EmbedFrame({
|
|
|
15918
16122
|
embedUrl,
|
|
15919
16123
|
className
|
|
15920
16124
|
}) {
|
|
15921
|
-
const client =
|
|
16125
|
+
const client = useRecordsClient42();
|
|
15922
16126
|
const host = useRecordsUi();
|
|
15923
16127
|
const table = useTable22(tableId);
|
|
15924
16128
|
const rights = useTableRights(table.data);
|
|
@@ -16012,7 +16216,7 @@ function EmbedFrame({
|
|
|
16012
16216
|
] });
|
|
16013
16217
|
}
|
|
16014
16218
|
function useEmbedHandshake(args) {
|
|
16015
|
-
const client =
|
|
16219
|
+
const client = useRecordsClient42();
|
|
16016
16220
|
const [binding, setBinding] = useState55(null);
|
|
16017
16221
|
const [error, setError] = useState55(null);
|
|
16018
16222
|
const [loading, setLoading] = useState55(true);
|
|
@@ -16074,7 +16278,7 @@ function recordsDataSource(client, fallbackSchema = "custom") {
|
|
|
16074
16278
|
|
|
16075
16279
|
// src/TablesHome.tsx
|
|
16076
16280
|
import { useCallback as useCallback39, useEffect as useEffect45, useState as useState56 } from "react";
|
|
16077
|
-
import { useRecordsClient as
|
|
16281
|
+
import { useRecordsClient as useRecordsClient43, useTables as useTables4 } from "@ai-matrx/records/react";
|
|
16078
16282
|
import { BasicInput as BasicInput18, Button as Button50, Skeleton as Skeleton35, cn as cn53 } from "@ai-matrx/design-system";
|
|
16079
16283
|
|
|
16080
16284
|
// src/createTable.ts
|
|
@@ -16202,15 +16406,32 @@ var LANE_EMPTY = {
|
|
|
16202
16406
|
community: "Nothing shared beyond your organization. A table published by link or to the world lands here.",
|
|
16203
16407
|
app: "The app has not needed a table of its own in this organization yet. Saving a view, writing a comment or building a form makes one, and it appears here rather than among your own data."
|
|
16204
16408
|
};
|
|
16409
|
+
function keptByTheApp(table) {
|
|
16410
|
+
return table.kept_by_the_app === true;
|
|
16411
|
+
}
|
|
16205
16412
|
function laneFor(table) {
|
|
16206
16413
|
if (table.is_kernel) return "system";
|
|
16207
|
-
if ((table.slug ?? "").startsWith(APP_TABLE_PREFIX)) return "app";
|
|
16414
|
+
if ((table.slug ?? "").startsWith(APP_TABLE_PREFIX) || keptByTheApp(table)) return "app";
|
|
16208
16415
|
if (table.visibility === "public" || table.visibility === "link") return "community";
|
|
16209
16416
|
if (table.visibility === "personal") return "mine";
|
|
16210
16417
|
return "organization";
|
|
16211
16418
|
}
|
|
16419
|
+
var VISIBILITY_LANES = ["mine", "organization", "community", "world"];
|
|
16420
|
+
var VISIBILITY_LANE_TITLE = {
|
|
16421
|
+
mine: "Mine",
|
|
16422
|
+
organization: "My organization",
|
|
16423
|
+
community: "Community",
|
|
16424
|
+
world: "World"
|
|
16425
|
+
};
|
|
16426
|
+
function visibilityLaneFor(table) {
|
|
16427
|
+
if (table.is_kernel) return null;
|
|
16428
|
+
if ((table.slug ?? "").startsWith(APP_TABLE_PREFIX) || keptByTheApp(table)) return null;
|
|
16429
|
+
if (table.visibility === "personal") return "mine";
|
|
16430
|
+
if (table.visibility === "link" || table.visibility === "public") return "world";
|
|
16431
|
+
return "organization";
|
|
16432
|
+
}
|
|
16212
16433
|
function TablesHome({ onOpenTable, className }) {
|
|
16213
|
-
const client =
|
|
16434
|
+
const client = useRecordsClient43();
|
|
16214
16435
|
const tables = useTables4();
|
|
16215
16436
|
const [creating, setCreating] = useState56(false);
|
|
16216
16437
|
const [name, setName] = useState56("");
|
|
@@ -16353,9 +16574,46 @@ function TablesHome({ onOpenTable, className }) {
|
|
|
16353
16574
|
|
|
16354
16575
|
// src/TablePage.tsx
|
|
16355
16576
|
import { useCallback as useCallback40, useEffect as useEffect46, useState as useState57 } from "react";
|
|
16356
|
-
import { useFields as useFields24, useRecordsClient as
|
|
16357
|
-
import { Button as Button51, Separator as Separator12, Skeleton as Skeleton36, cn as cn54 } from "@ai-matrx/design-system";
|
|
16577
|
+
import { useFields as useFields24, useRecordsClient as useRecordsClient44, useTable as useTable23 } from "@ai-matrx/records/react";
|
|
16578
|
+
import { BottomSheet, Button as Button51, Separator as Separator12, Skeleton as Skeleton36, cn as cn54, useIsMobile } from "@ai-matrx/design-system";
|
|
16358
16579
|
import { Fragment as Fragment28, jsx as jsx61, jsxs as jsxs56 } from "react/jsx-runtime";
|
|
16580
|
+
var RAIL_TITLE = {
|
|
16581
|
+
settings: "Table settings",
|
|
16582
|
+
inbox: "Inbox",
|
|
16583
|
+
import: "Import",
|
|
16584
|
+
field: "Add a field",
|
|
16585
|
+
record: "Record",
|
|
16586
|
+
"new-record": "New record",
|
|
16587
|
+
forms: "Forms",
|
|
16588
|
+
bookings: "Bookings",
|
|
16589
|
+
checklists: "Checklists",
|
|
16590
|
+
notifications: "Notifications",
|
|
16591
|
+
portals: "Portals",
|
|
16592
|
+
"who-changed": "Who changed this"
|
|
16593
|
+
};
|
|
16594
|
+
function RailFrame({
|
|
16595
|
+
phone,
|
|
16596
|
+
title,
|
|
16597
|
+
onClose,
|
|
16598
|
+
children
|
|
16599
|
+
}) {
|
|
16600
|
+
if (phone) {
|
|
16601
|
+
return /* @__PURE__ */ jsx61(
|
|
16602
|
+
BottomSheet,
|
|
16603
|
+
{
|
|
16604
|
+
open: true,
|
|
16605
|
+
onOpenChange: (open) => {
|
|
16606
|
+
if (!open) onClose();
|
|
16607
|
+
},
|
|
16608
|
+
title,
|
|
16609
|
+
size: "full",
|
|
16610
|
+
surface: "solid",
|
|
16611
|
+
children: /* @__PURE__ */ jsx61("div", { "data-rail-sheet": "", className: "min-h-0 flex-1 overflow-y-auto px-3 pb-6", children })
|
|
16612
|
+
}
|
|
16613
|
+
);
|
|
16614
|
+
}
|
|
16615
|
+
return /* @__PURE__ */ jsx61("aside", { "data-rail-column": "", className: "w-[26rem] shrink-0 overflow-y-auto rounded-md border p-3", children });
|
|
16616
|
+
}
|
|
16359
16617
|
function filterInWords(filter, fields) {
|
|
16360
16618
|
const nameOf = (key) => {
|
|
16361
16619
|
const field = fields.find((f) => f.key === key);
|
|
@@ -16471,12 +16729,12 @@ function TablePage({
|
|
|
16471
16729
|
activeItemId,
|
|
16472
16730
|
className
|
|
16473
16731
|
}) {
|
|
16474
|
-
const client =
|
|
16732
|
+
const client = useRecordsClient44();
|
|
16475
16733
|
const table = useTable23(tableId);
|
|
16476
16734
|
const rights = useTableRights(table.data);
|
|
16477
16735
|
const pageFields = useFields24(filter ? tableId : null);
|
|
16478
16736
|
const askedInWords = filter ? filterInWords(filter, pageFields.data ?? []) : null;
|
|
16479
|
-
const organizationId =
|
|
16737
|
+
const organizationId = useRecordsClient44().config.organizationId;
|
|
16480
16738
|
const [view, setView] = useState57(null);
|
|
16481
16739
|
const opening = openingRail(activeRecordId, activeRail);
|
|
16482
16740
|
const opened = openingView(activeView, activeDashboardId);
|
|
@@ -16495,6 +16753,7 @@ function TablePage({
|
|
|
16495
16753
|
const setRail = (next) => setSurface((now) => ({ ...now, rail: next }));
|
|
16496
16754
|
const [openRecord, setOpenRecord] = useState57(opening.record);
|
|
16497
16755
|
const viewVersion = useRecordVersion(view?.id ?? null);
|
|
16756
|
+
const phone = useIsMobile();
|
|
16498
16757
|
const shownLayout = layoutFromLink ?? view?.layout ?? "grid";
|
|
16499
16758
|
const press = (pressed) => {
|
|
16500
16759
|
const next = chooseSurface(surface, pressed);
|
|
@@ -16522,6 +16781,7 @@ function TablePage({
|
|
|
16522
16781
|
setLayoutFromLink(isLayout ? named : null);
|
|
16523
16782
|
setSurface((now) => ({ ...now, main: isLayout ? "records" : named }));
|
|
16524
16783
|
}, [activeView]);
|
|
16784
|
+
const [viewSaveRefused, setViewSaveRefused] = useState57(null);
|
|
16525
16785
|
const patchView = useCallback40(
|
|
16526
16786
|
async (patch) => {
|
|
16527
16787
|
const current = view;
|
|
@@ -16529,12 +16789,13 @@ function TablePage({
|
|
|
16529
16789
|
setView({ ...current, ...patch });
|
|
16530
16790
|
const document2 = viewPatchDocument(patch);
|
|
16531
16791
|
if (Object.keys(document2).length === 0) return;
|
|
16532
|
-
|
|
16533
|
-
|
|
16534
|
-
|
|
16535
|
-
|
|
16536
|
-
|
|
16537
|
-
|
|
16792
|
+
setViewSaveRefused(null);
|
|
16793
|
+
const written = await saveViewPatch(client, current.id, document2, viewVersion.version);
|
|
16794
|
+
if (written.ok) {
|
|
16795
|
+
viewVersion.note(written.data);
|
|
16796
|
+
return;
|
|
16797
|
+
}
|
|
16798
|
+
setViewSaveRefused({ error: written.error, patch, before: current });
|
|
16538
16799
|
},
|
|
16539
16800
|
[client, view, viewVersion]
|
|
16540
16801
|
);
|
|
@@ -16685,6 +16946,27 @@ function TablePage({
|
|
|
16685
16946
|
),
|
|
16686
16947
|
/* @__PURE__ */ jsx61(ExportMenu, { tableId })
|
|
16687
16948
|
] }),
|
|
16949
|
+
viewSaveRefused ? /* @__PURE__ */ jsx61(
|
|
16950
|
+
RefusalNotice,
|
|
16951
|
+
{
|
|
16952
|
+
error: viewSaveRefused.error,
|
|
16953
|
+
actions: /* @__PURE__ */ jsxs56("span", { className: "flex flex-wrap gap-1 pt-0.5", "data-view-save-refused": "", children: [
|
|
16954
|
+
/* @__PURE__ */ jsx61(Button51, { size: "sm", variant: "outline", onClick: () => void patchView(viewSaveRefused.patch), children: "Try again" }),
|
|
16955
|
+
/* @__PURE__ */ jsx61(
|
|
16956
|
+
Button51,
|
|
16957
|
+
{
|
|
16958
|
+
size: "sm",
|
|
16959
|
+
variant: "ghost",
|
|
16960
|
+
onClick: () => {
|
|
16961
|
+
setView(viewSaveRefused.before);
|
|
16962
|
+
setViewSaveRefused(null);
|
|
16963
|
+
},
|
|
16964
|
+
children: "Discard"
|
|
16965
|
+
}
|
|
16966
|
+
)
|
|
16967
|
+
] })
|
|
16968
|
+
}
|
|
16969
|
+
) : null,
|
|
16688
16970
|
main === "dashboards" ? /* @__PURE__ */ jsx61(DashboardCanvas, { tableId, activeDashboardId: activeDashboardId ?? null }) : main === "archived" ? (
|
|
16689
16971
|
/* THE ROWS THAT LEFT. Restoring one puts it back in the grid, so the
|
|
16690
16972
|
page returns to the records rather than leaving the person looking
|
|
@@ -16745,7 +17027,7 @@ function TablePage({
|
|
|
16745
17027
|
view ? null : /* @__PURE__ */ jsx61("p", { className: "text-xs text-muted-foreground", children: VIEW_NOT_SAVED_YET })
|
|
16746
17028
|
] })
|
|
16747
17029
|
] }),
|
|
16748
|
-
rail === "none" ? null : /* @__PURE__ */ jsxs56(
|
|
17030
|
+
rail === "none" ? null : /* @__PURE__ */ jsxs56(RailFrame, { phone, title: RAIL_TITLE[rail], onClose: () => setRail("none"), children: [
|
|
16749
17031
|
rail === "settings" ? /* @__PURE__ */ jsx61(
|
|
16750
17032
|
TableSettings,
|
|
16751
17033
|
{
|
|
@@ -16984,6 +17266,8 @@ export {
|
|
|
16984
17266
|
VIEW_LAYOUTS,
|
|
16985
17267
|
VIEW_NOT_SAVED_YET,
|
|
16986
17268
|
VIEW_TABLE,
|
|
17269
|
+
VISIBILITY_LANES,
|
|
17270
|
+
VISIBILITY_LANE_TITLE,
|
|
16987
17271
|
ViewBar,
|
|
16988
17272
|
ViewSwitcher,
|
|
16989
17273
|
WITHHELD_RECORD_LABEL,
|
|
@@ -17039,6 +17323,7 @@ export {
|
|
|
17039
17323
|
isPlainFieldType,
|
|
17040
17324
|
isRelationFieldType,
|
|
17041
17325
|
isSignatureField,
|
|
17326
|
+
keptByTheApp,
|
|
17042
17327
|
keyFor,
|
|
17043
17328
|
kindsWithNoChoice,
|
|
17044
17329
|
laneFor,
|
|
@@ -17074,6 +17359,7 @@ export {
|
|
|
17074
17359
|
revokeConsequence,
|
|
17075
17360
|
rowName,
|
|
17076
17361
|
rowNameIn,
|
|
17362
|
+
saveViewPatch,
|
|
17077
17363
|
scalarText,
|
|
17078
17364
|
shareUnavailableReason,
|
|
17079
17365
|
specFromBlock,
|
|
@@ -17103,6 +17389,7 @@ export {
|
|
|
17103
17389
|
viewDocument,
|
|
17104
17390
|
viewFromRecord,
|
|
17105
17391
|
viewPatchDocument,
|
|
17392
|
+
visibilityLaneFor,
|
|
17106
17393
|
whatIsMissing,
|
|
17107
17394
|
whatYouMayDo,
|
|
17108
17395
|
whatYouMayDoWithTable,
|