@ai-matrx/records-ui 0.107.5 → 0.109.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 +26 -0
- package/dist/first-page.cjs +435 -0
- package/dist/first-page.cjs.map +1 -0
- package/dist/first-page.d.cts +320 -0
- package/dist/first-page.d.ts +320 -0
- package/dist/first-page.js +429 -0
- package/dist/first-page.js.map +1 -0
- package/dist/index.cjs +842 -797
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.js +629 -586
- package/dist/index.js.map +1 -1
- package/dist/pickers.cjs +1 -0
- package/dist/pickers.cjs.map +1 -1
- package/dist/pickers.js +2 -3
- package/dist/pickers.js.map +1 -1
- package/package.json +30 -5
package/dist/index.cjs
CHANGED
|
@@ -1462,8 +1462,8 @@ function FormulaTextEditor({
|
|
|
1462
1462
|
}
|
|
1463
1463
|
|
|
1464
1464
|
// src/TableDetails.tsx
|
|
1465
|
-
var
|
|
1466
|
-
var
|
|
1465
|
+
var import_react16 = require("react");
|
|
1466
|
+
var import_react17 = require("@ai-matrx/records/react");
|
|
1467
1467
|
var import_design_system8 = require("@ai-matrx/design-system");
|
|
1468
1468
|
|
|
1469
1469
|
// src/reversePrefix.ts
|
|
@@ -1473,6 +1473,54 @@ var REVERSE_COLUMN_PREFIX = "linked:";
|
|
|
1473
1473
|
var import_records5 = require("@ai-matrx/records");
|
|
1474
1474
|
var import_data_table2 = require("@ai-matrx/design-system/data-table");
|
|
1475
1475
|
|
|
1476
|
+
// src/personTime.ts
|
|
1477
|
+
var import_react6 = require("react");
|
|
1478
|
+
var zone = null;
|
|
1479
|
+
var listeners = /* @__PURE__ */ new Set();
|
|
1480
|
+
function valid(z) {
|
|
1481
|
+
if (typeof z !== "string" || !z.trim()) return false;
|
|
1482
|
+
try {
|
|
1483
|
+
new Intl.DateTimeFormat("en-US", { timeZone: z });
|
|
1484
|
+
return true;
|
|
1485
|
+
} catch {
|
|
1486
|
+
return false;
|
|
1487
|
+
}
|
|
1488
|
+
}
|
|
1489
|
+
function setPersonTimeZone(next) {
|
|
1490
|
+
const clean = valid(next) ? next : null;
|
|
1491
|
+
if (clean === zone) return;
|
|
1492
|
+
zone = clean;
|
|
1493
|
+
listeners.forEach((l) => l());
|
|
1494
|
+
}
|
|
1495
|
+
function getPersonTimeZone() {
|
|
1496
|
+
return zone;
|
|
1497
|
+
}
|
|
1498
|
+
function usePersonTimeZone() {
|
|
1499
|
+
return (0, import_react6.useSyncExternalStore)(
|
|
1500
|
+
(cb) => {
|
|
1501
|
+
listeners.add(cb);
|
|
1502
|
+
return () => listeners.delete(cb);
|
|
1503
|
+
},
|
|
1504
|
+
() => zone,
|
|
1505
|
+
() => null
|
|
1506
|
+
);
|
|
1507
|
+
}
|
|
1508
|
+
function personWallNow(at = /* @__PURE__ */ new Date()) {
|
|
1509
|
+
if (!zone) return at;
|
|
1510
|
+
const parts = new Intl.DateTimeFormat("en-US", {
|
|
1511
|
+
timeZone: zone,
|
|
1512
|
+
year: "numeric",
|
|
1513
|
+
month: "2-digit",
|
|
1514
|
+
day: "2-digit",
|
|
1515
|
+
hour: "2-digit",
|
|
1516
|
+
minute: "2-digit",
|
|
1517
|
+
second: "2-digit",
|
|
1518
|
+
hourCycle: "h23"
|
|
1519
|
+
}).formatToParts(at);
|
|
1520
|
+
const n = (t) => Number(parts.find((p) => p.type === t)?.value ?? 0);
|
|
1521
|
+
return new Date(n("year"), n("month") - 1, n("day"), n("hour"), n("minute"), n("second"));
|
|
1522
|
+
}
|
|
1523
|
+
|
|
1476
1524
|
// src/choiceLooks.ts
|
|
1477
1525
|
var import_data_table = require("@ai-matrx/design-system/data-table");
|
|
1478
1526
|
function displayFormatOf(field2) {
|
|
@@ -1815,9 +1863,10 @@ function clauseFor(f, value, now = /* @__PURE__ */ new Date()) {
|
|
|
1815
1863
|
return { rule: value.negated ? not(range) : range };
|
|
1816
1864
|
}
|
|
1817
1865
|
case "date": {
|
|
1818
|
-
const
|
|
1866
|
+
const zone2 = getPersonTimeZone() ?? void 0;
|
|
1867
|
+
const moments = (0, import_data_table2.dateFilterBounds)(value.preset ? { ...value, anchor: now.toISOString() } : value, now, zone2);
|
|
1819
1868
|
const holdsDays = String((f.config ?? {})["kind"] ?? "") === "date";
|
|
1820
|
-
const bounds = holdsDays ? (0, import_data_table2.dateFilterDayBounds)(moments) : moments;
|
|
1869
|
+
const bounds = holdsDays ? (0, import_data_table2.dateFilterDayBounds)(moments, zone2) : moments;
|
|
1821
1870
|
if (bounds.since === void 0 && bounds.until === void 0) return null;
|
|
1822
1871
|
return {
|
|
1823
1872
|
flat: {
|
|
@@ -1833,11 +1882,10 @@ function clauseFor(f, value, now = /* @__PURE__ */ new Date()) {
|
|
|
1833
1882
|
}
|
|
1834
1883
|
}
|
|
1835
1884
|
function dayWindow(day, holdsDays) {
|
|
1885
|
+
if (!holdsDays) return (0, import_data_table2.dayInstantWindow)(day, getPersonTimeZone() ?? void 0);
|
|
1836
1886
|
const [y, m, d] = day.split("-").map(Number);
|
|
1837
|
-
const
|
|
1838
|
-
|
|
1839
|
-
const ymd = (t) => `${t.getFullYear()}-${String(t.getMonth() + 1).padStart(2, "0")}-${String(t.getDate()).padStart(2, "0")}`;
|
|
1840
|
-
return holdsDays ? { from: ymd(start), to: ymd(next) } : { from: start.toISOString(), to: next.toISOString() };
|
|
1887
|
+
const ymd = (t) => `${t.getUTCFullYear()}-${String(t.getUTCMonth() + 1).padStart(2, "0")}-${String(t.getUTCDate()).padStart(2, "0")}`;
|
|
1888
|
+
return { from: ymd(new Date(Date.UTC(y, (m ?? 1) - 1, d ?? 1))), to: ymd(new Date(Date.UTC(y, (m ?? 1) - 1, (d ?? 1) + 1))) };
|
|
1841
1889
|
}
|
|
1842
1890
|
function storeQuestion(fields, base, columnFilters, now = /* @__PURE__ */ new Date()) {
|
|
1843
1891
|
const refused = [];
|
|
@@ -1920,15 +1968,15 @@ function fieldOptionsOnce(client, fieldId) {
|
|
|
1920
1968
|
}
|
|
1921
1969
|
|
|
1922
1970
|
// src/labels.tsx
|
|
1923
|
-
var
|
|
1924
|
-
var
|
|
1971
|
+
var import_react9 = require("react");
|
|
1972
|
+
var import_react10 = require("@ai-matrx/records/react");
|
|
1925
1973
|
var import_records6 = require("@ai-matrx/records");
|
|
1926
1974
|
var import_uuid2 = require("@ai-matrx/kit/uuid");
|
|
1927
1975
|
|
|
1928
1976
|
// src/signature.tsx
|
|
1929
|
-
var
|
|
1977
|
+
var import_react7 = require("react");
|
|
1930
1978
|
var import_design_system3 = require("@ai-matrx/design-system");
|
|
1931
|
-
var
|
|
1979
|
+
var import_react8 = require("@ai-matrx/records/react");
|
|
1932
1980
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
1933
1981
|
var DRAWN = /^data:image\/(png|jpeg);base64,[A-Za-z0-9+/=]{64,}$/;
|
|
1934
1982
|
function drawnSignatureOf(value) {
|
|
@@ -2003,10 +2051,10 @@ function SignatureDrawing({
|
|
|
2003
2051
|
value,
|
|
2004
2052
|
inCell
|
|
2005
2053
|
}) {
|
|
2006
|
-
const client = (0,
|
|
2054
|
+
const client = (0, import_react8.useOptionalRecordsClient)();
|
|
2007
2055
|
const host = useRecordsUi();
|
|
2008
|
-
const [drawing, setDrawing] = (0,
|
|
2009
|
-
(0,
|
|
2056
|
+
const [drawing, setDrawing] = (0, import_react7.useState)(null);
|
|
2057
|
+
(0, import_react7.useEffect)(() => {
|
|
2010
2058
|
let cancelled = false;
|
|
2011
2059
|
setDrawing(null);
|
|
2012
2060
|
if (!client) return;
|
|
@@ -2053,12 +2101,12 @@ function SignaturePad({
|
|
|
2053
2101
|
}) {
|
|
2054
2102
|
const kept = drawnSignatureOf(value);
|
|
2055
2103
|
const named = !kept && typeof value === "string" && value !== "" ? value : null;
|
|
2056
|
-
const [showPad, setShowPad] = (0,
|
|
2057
|
-
const canvasRef = (0,
|
|
2058
|
-
const drawing = (0,
|
|
2059
|
-
const [dirty, setDirty] = (0,
|
|
2060
|
-
const [tooBig, setTooBig] = (0,
|
|
2061
|
-
(0,
|
|
2104
|
+
const [showPad, setShowPad] = (0, import_react7.useState)(() => !kept && !named);
|
|
2105
|
+
const canvasRef = (0, import_react7.useRef)(null);
|
|
2106
|
+
const drawing = (0, import_react7.useRef)(false);
|
|
2107
|
+
const [dirty, setDirty] = (0, import_react7.useState)(false);
|
|
2108
|
+
const [tooBig, setTooBig] = (0, import_react7.useState)(false);
|
|
2109
|
+
(0, import_react7.useEffect)(() => {
|
|
2062
2110
|
if (!showPad) return;
|
|
2063
2111
|
const canvas = canvasRef.current;
|
|
2064
2112
|
if (!canvas) return;
|
|
@@ -2197,7 +2245,7 @@ function encodeAt(canvas, type, maxWidth, quality) {
|
|
|
2197
2245
|
|
|
2198
2246
|
// src/labels.tsx
|
|
2199
2247
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
2200
|
-
var LabelContext = (0,
|
|
2248
|
+
var LabelContext = (0, import_react9.createContext)({
|
|
2201
2249
|
// With no provider the resolver is ABSENT, not silently empty: a caller gets
|
|
2202
2250
|
// null and says "Loading…" forever, which is visible. The mount always
|
|
2203
2251
|
// provides one, so this is only ever a bare unit test.
|
|
@@ -2238,16 +2286,16 @@ function shownValue(field2, value, labels) {
|
|
|
2238
2286
|
return Array.isArray(value) ? words2 : words2[0];
|
|
2239
2287
|
}
|
|
2240
2288
|
function RecordLabelProvider({ children }) {
|
|
2241
|
-
const client = (0,
|
|
2242
|
-
const [names, setNames] = (0,
|
|
2243
|
-
const [archivedRefs, setArchivedRefs] = (0,
|
|
2244
|
-
const [iconsOf, setIconsOf] = (0,
|
|
2245
|
-
const [settled, setSettled] = (0,
|
|
2246
|
-
const [waitingLines, setWaitingLines] = (0,
|
|
2247
|
-
const asked3 = (0,
|
|
2248
|
-
const chased = (0,
|
|
2249
|
-
const timers = (0,
|
|
2250
|
-
const startWaitClock = (0,
|
|
2289
|
+
const client = (0, import_react10.useRecordsClient)();
|
|
2290
|
+
const [names, setNames] = (0, import_react9.useState)({});
|
|
2291
|
+
const [archivedRefs, setArchivedRefs] = (0, import_react9.useState)({});
|
|
2292
|
+
const [iconsOf, setIconsOf] = (0, import_react9.useState)({});
|
|
2293
|
+
const [settled, setSettled] = (0, import_react9.useState)({});
|
|
2294
|
+
const [waitingLines, setWaitingLines] = (0, import_react9.useState)({});
|
|
2295
|
+
const asked3 = (0, import_react9.useRef)(/* @__PURE__ */ new Set());
|
|
2296
|
+
const chased = (0, import_react9.useRef)(/* @__PURE__ */ new Set());
|
|
2297
|
+
const timers = (0, import_react9.useRef)(/* @__PURE__ */ new Map());
|
|
2298
|
+
const startWaitClock = (0, import_react9.useCallback)((field2, target) => {
|
|
2251
2299
|
if (timers.current.has(field2.id)) return;
|
|
2252
2300
|
timers.current.set(
|
|
2253
2301
|
field2.id,
|
|
@@ -2259,7 +2307,7 @@ function RecordLabelProvider({ children }) {
|
|
|
2259
2307
|
}, SAY_WHAT_YOU_ARE_WAITING_FOR_AFTER_MS)
|
|
2260
2308
|
);
|
|
2261
2309
|
}, []);
|
|
2262
|
-
const stopWaitClock = (0,
|
|
2310
|
+
const stopWaitClock = (0, import_react9.useCallback)((fieldId) => {
|
|
2263
2311
|
const timer = timers.current.get(fieldId);
|
|
2264
2312
|
if (timer) {
|
|
2265
2313
|
clearTimeout(timer);
|
|
@@ -2272,14 +2320,14 @@ function RecordLabelProvider({ children }) {
|
|
|
2272
2320
|
return next;
|
|
2273
2321
|
});
|
|
2274
2322
|
}, []);
|
|
2275
|
-
(0,
|
|
2323
|
+
(0, import_react9.useEffect)(
|
|
2276
2324
|
() => () => {
|
|
2277
2325
|
for (const timer of timers.current.values()) clearTimeout(timer);
|
|
2278
2326
|
timers.current.clear();
|
|
2279
2327
|
},
|
|
2280
2328
|
[]
|
|
2281
2329
|
);
|
|
2282
|
-
const want = (0,
|
|
2330
|
+
const want = (0, import_react9.useCallback)(
|
|
2283
2331
|
(field2) => {
|
|
2284
2332
|
if (!pointsAtRecords(field2)) return;
|
|
2285
2333
|
if (asked3.current.has(field2.id)) return;
|
|
@@ -2314,9 +2362,9 @@ function RecordLabelProvider({ children }) {
|
|
|
2314
2362
|
},
|
|
2315
2363
|
[client, startWaitClock, stopWaitClock]
|
|
2316
2364
|
);
|
|
2317
|
-
const queued = (0,
|
|
2318
|
-
const flushing = (0,
|
|
2319
|
-
const flush = (0,
|
|
2365
|
+
const queued = (0, import_react9.useRef)(/* @__PURE__ */ new Map());
|
|
2366
|
+
const flushing = (0, import_react9.useRef)(null);
|
|
2367
|
+
const flush = (0, import_react9.useCallback)(() => {
|
|
2320
2368
|
flushing.current = null;
|
|
2321
2369
|
const batch = [...queued.current.values()];
|
|
2322
2370
|
queued.current.clear();
|
|
@@ -2346,7 +2394,7 @@ function RecordLabelProvider({ children }) {
|
|
|
2346
2394
|
for (const { field: field2 } of batch) stopWaitClock(field2.id);
|
|
2347
2395
|
})();
|
|
2348
2396
|
}, [client, stopWaitClock]);
|
|
2349
|
-
const chase = (0,
|
|
2397
|
+
const chase = (0, import_react9.useCallback)(
|
|
2350
2398
|
(field2, id) => {
|
|
2351
2399
|
const key = `${field2.id}:${id}`;
|
|
2352
2400
|
if (chased.current.has(key)) return;
|
|
@@ -2359,14 +2407,14 @@ function RecordLabelProvider({ children }) {
|
|
|
2359
2407
|
},
|
|
2360
2408
|
[flush, startWaitClock]
|
|
2361
2409
|
);
|
|
2362
|
-
(0,
|
|
2410
|
+
(0, import_react9.useEffect)(
|
|
2363
2411
|
() => () => {
|
|
2364
2412
|
if (flushing.current !== null) clearTimeout(flushing.current);
|
|
2365
2413
|
},
|
|
2366
2414
|
[]
|
|
2367
2415
|
);
|
|
2368
|
-
const rereadFor = (0,
|
|
2369
|
-
const lookupWords = (0,
|
|
2416
|
+
const rereadFor = (0, import_react9.useRef)(/* @__PURE__ */ new Set());
|
|
2417
|
+
const lookupWords = (0, import_react9.useCallback)(
|
|
2370
2418
|
(field2, id) => {
|
|
2371
2419
|
if (field2.type === "list" && !isId(id)) {
|
|
2372
2420
|
const named = names[choiceKeyName(field2.id, id)];
|
|
@@ -2386,7 +2434,7 @@ function RecordLabelProvider({ children }) {
|
|
|
2386
2434
|
},
|
|
2387
2435
|
[names, settled, chase, want]
|
|
2388
2436
|
);
|
|
2389
|
-
const lookup = (0,
|
|
2437
|
+
const lookup = (0, import_react9.useMemo)(
|
|
2390
2438
|
() => {
|
|
2391
2439
|
const answer = ((field2, id) => lookupWords(field2, id));
|
|
2392
2440
|
answer.archived = (field2, id) => archivedRefs[`${field2.id}:${id}`] === true;
|
|
@@ -2395,19 +2443,19 @@ function RecordLabelProvider({ children }) {
|
|
|
2395
2443
|
},
|
|
2396
2444
|
[lookupWords, archivedRefs, iconsOf]
|
|
2397
2445
|
);
|
|
2398
|
-
const waiting = (0,
|
|
2399
|
-
const value = (0,
|
|
2446
|
+
const waiting = (0, import_react9.useCallback)((field2) => waitingLines[field2.id] ?? null, [waitingLines]);
|
|
2447
|
+
const value = (0, import_react9.useMemo)(() => ({ lookup, want, waiting }), [lookup, want, waiting]);
|
|
2400
2448
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(LabelContext.Provider, { value, children });
|
|
2401
2449
|
}
|
|
2402
2450
|
function useRecordLabels(fields) {
|
|
2403
|
-
const { lookup, want } = (0,
|
|
2404
|
-
(0,
|
|
2451
|
+
const { lookup, want } = (0, import_react9.useContext)(LabelContext);
|
|
2452
|
+
(0, import_react9.useEffect)(() => {
|
|
2405
2453
|
for (const field2 of fields ?? []) want(field2);
|
|
2406
2454
|
}, [fields, want]);
|
|
2407
2455
|
return lookup;
|
|
2408
2456
|
}
|
|
2409
2457
|
function useLabelWait(field2) {
|
|
2410
|
-
const { waiting } = (0,
|
|
2458
|
+
const { waiting } = (0, import_react9.useContext)(LabelContext);
|
|
2411
2459
|
return field2 ? waiting(field2) : null;
|
|
2412
2460
|
}
|
|
2413
2461
|
|
|
@@ -2589,9 +2637,9 @@ function gridCopyConfig(args) {
|
|
|
2589
2637
|
}
|
|
2590
2638
|
|
|
2591
2639
|
// src/FieldRetype.tsx
|
|
2592
|
-
var
|
|
2640
|
+
var import_react11 = require("react");
|
|
2593
2641
|
var import_records7 = require("@ai-matrx/records");
|
|
2594
|
-
var
|
|
2642
|
+
var import_react12 = require("@ai-matrx/records/react");
|
|
2595
2643
|
var import_design_system4 = require("@ai-matrx/design-system");
|
|
2596
2644
|
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
2597
2645
|
var RETYPE_TARGETS = [
|
|
@@ -2628,17 +2676,17 @@ function currentTarget(field2) {
|
|
|
2628
2676
|
return "text";
|
|
2629
2677
|
}
|
|
2630
2678
|
function FieldRetype({ field: field2, tableId, onRetyped }) {
|
|
2631
|
-
const client = (0,
|
|
2679
|
+
const client = (0, import_react12.useRecordsClient)();
|
|
2632
2680
|
const notify = useRecordsUi().notify;
|
|
2633
|
-
const [to, setTo] = (0,
|
|
2634
|
-
const [preview, setPreview] = (0,
|
|
2635
|
-
const [asking, setAsking] = (0,
|
|
2636
|
-
const [refusal4, setRefusal] = (0,
|
|
2637
|
-
const [busy, setBusy] = (0,
|
|
2638
|
-
const [said2, setSaid] = (0,
|
|
2681
|
+
const [to, setTo] = (0, import_react11.useState)(null);
|
|
2682
|
+
const [preview, setPreview] = (0, import_react11.useState)(null);
|
|
2683
|
+
const [asking, setAsking] = (0, import_react11.useState)(false);
|
|
2684
|
+
const [refusal4, setRefusal] = (0, import_react11.useState)(null);
|
|
2685
|
+
const [busy, setBusy] = (0, import_react11.useState)(false);
|
|
2686
|
+
const [said2, setSaid] = (0, import_react11.useState)(null);
|
|
2639
2687
|
const name = fieldName(field2);
|
|
2640
2688
|
const targets = RETYPE_TARGETS.filter((t) => t.id !== currentTarget(field2));
|
|
2641
|
-
(0,
|
|
2689
|
+
(0, import_react11.useEffect)(() => {
|
|
2642
2690
|
if (!to) return;
|
|
2643
2691
|
let cancelled = false;
|
|
2644
2692
|
setPreview(null);
|
|
@@ -2694,7 +2742,7 @@ function FieldRetype({ field: field2, tableId, onRetyped }) {
|
|
|
2694
2742
|
undo: async () => {
|
|
2695
2743
|
const back = await client.migrateUndo({ migration_id: migration });
|
|
2696
2744
|
if (!back.ok) throw new Error(refusalSentence(back.error));
|
|
2697
|
-
(0,
|
|
2745
|
+
(0, import_react12.tableShapeChanged)(tableId);
|
|
2698
2746
|
onRetyped?.();
|
|
2699
2747
|
}
|
|
2700
2748
|
});
|
|
@@ -2705,7 +2753,7 @@ function FieldRetype({ field: field2, tableId, onRetyped }) {
|
|
|
2705
2753
|
);
|
|
2706
2754
|
setTo(null);
|
|
2707
2755
|
setPreview(null);
|
|
2708
|
-
(0,
|
|
2756
|
+
(0, import_react12.tableShapeChanged)(tableId);
|
|
2709
2757
|
onRetyped?.();
|
|
2710
2758
|
};
|
|
2711
2759
|
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex flex-col gap-1.5", "data-records-retype": "", children: [
|
|
@@ -3075,11 +3123,11 @@ function nextFieldSort(fields) {
|
|
|
3075
3123
|
}
|
|
3076
3124
|
|
|
3077
3125
|
// src/PickOne.tsx
|
|
3078
|
-
var
|
|
3126
|
+
var import_react14 = require("react");
|
|
3079
3127
|
var import_design_system7 = require("@ai-matrx/design-system");
|
|
3080
3128
|
|
|
3081
3129
|
// src/PickOrAdd.tsx
|
|
3082
|
-
var
|
|
3130
|
+
var import_react13 = require("react");
|
|
3083
3131
|
|
|
3084
3132
|
// src/personChip.tsx
|
|
3085
3133
|
var import_design_system5 = require("@ai-matrx/design-system");
|
|
@@ -3130,9 +3178,9 @@ var CROSS = "M18 6 6 18M6 6l12 12";
|
|
|
3130
3178
|
var PLUS = "M12 5v14M5 12h14";
|
|
3131
3179
|
function useListKeys(args) {
|
|
3132
3180
|
const { count, resetOn, onPick, onNothing, onClose, onFinish, onBackspaceEmpty, searchEmpty } = args;
|
|
3133
|
-
const [highlight, setHighlight] = (0,
|
|
3134
|
-
const [moved, setMoved] = (0,
|
|
3135
|
-
(0,
|
|
3181
|
+
const [highlight, setHighlight] = (0, import_react13.useState)(0);
|
|
3182
|
+
const [moved, setMoved] = (0, import_react13.useState)(false);
|
|
3183
|
+
(0, import_react13.useEffect)(() => {
|
|
3136
3184
|
setHighlight(0);
|
|
3137
3185
|
setMoved(false);
|
|
3138
3186
|
}, [resetOn]);
|
|
@@ -3177,8 +3225,8 @@ function PickRow({
|
|
|
3177
3225
|
onPick,
|
|
3178
3226
|
onPoint
|
|
3179
3227
|
}) {
|
|
3180
|
-
const ref = (0,
|
|
3181
|
-
(0,
|
|
3228
|
+
const ref = (0, import_react13.useRef)(null);
|
|
3229
|
+
(0, import_react13.useEffect)(() => {
|
|
3182
3230
|
if (highlighted) ref.current?.scrollIntoView?.({ block: "nearest" });
|
|
3183
3231
|
}, [highlighted]);
|
|
3184
3232
|
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
@@ -3390,8 +3438,8 @@ function PickOne({
|
|
|
3390
3438
|
disabled,
|
|
3391
3439
|
attrs
|
|
3392
3440
|
}) {
|
|
3393
|
-
const [open, setOpen] = (0,
|
|
3394
|
-
const [search, setSearch] = (0,
|
|
3441
|
+
const [open, setOpen] = (0, import_react14.useState)(false);
|
|
3442
|
+
const [search, setSearch] = (0, import_react14.useState)("");
|
|
3395
3443
|
const current = options.find((o) => o.value === value);
|
|
3396
3444
|
if (options.length > PICK_ONE_SEARCH_AFTER) {
|
|
3397
3445
|
const q = search.trim().toLowerCase();
|
|
@@ -3459,7 +3507,7 @@ function groupsOf(options) {
|
|
|
3459
3507
|
}
|
|
3460
3508
|
|
|
3461
3509
|
// src/recordVersions.ts
|
|
3462
|
-
var
|
|
3510
|
+
var import_react15 = require("react");
|
|
3463
3511
|
|
|
3464
3512
|
// src/refusals.ts
|
|
3465
3513
|
function refusal(code, sentence2, remedy, diagnostic) {
|
|
@@ -3516,22 +3564,22 @@ function signatureOf(row) {
|
|
|
3516
3564
|
}
|
|
3517
3565
|
}
|
|
3518
3566
|
function useRecordVersions(client, rows, mayRead) {
|
|
3519
|
-
const versions = (0,
|
|
3520
|
-
const drawn = (0,
|
|
3521
|
-
const unread = (0,
|
|
3522
|
-
const pending = (0,
|
|
3523
|
-
const generation = (0,
|
|
3524
|
-
const mayReadRef = (0,
|
|
3567
|
+
const versions = (0, import_react15.useRef)(/* @__PURE__ */ new Map());
|
|
3568
|
+
const drawn = (0, import_react15.useRef)(/* @__PURE__ */ new Map());
|
|
3569
|
+
const unread = (0, import_react15.useRef)(/* @__PURE__ */ new Set());
|
|
3570
|
+
const pending = (0, import_react15.useRef)(/* @__PURE__ */ new Map());
|
|
3571
|
+
const generation = (0, import_react15.useRef)(0);
|
|
3572
|
+
const mayReadRef = (0, import_react15.useRef)(mayRead);
|
|
3525
3573
|
mayReadRef.current = mayRead;
|
|
3526
|
-
const rowsRef = (0,
|
|
3574
|
+
const rowsRef = (0, import_react15.useRef)(rows);
|
|
3527
3575
|
rowsRef.current = rows;
|
|
3528
|
-
const key = (0,
|
|
3576
|
+
const key = (0, import_react15.useMemo)(() => rows.map((row) => `${row.id}${signatureOf(row)}`).join(""), [rows]);
|
|
3529
3577
|
const raise = (id, version) => {
|
|
3530
3578
|
const held = versions.current.get(id);
|
|
3531
3579
|
if (held === void 0 || version > held) versions.current.set(id, version);
|
|
3532
3580
|
unread.current.delete(id);
|
|
3533
3581
|
};
|
|
3534
|
-
const readHeaders = (0,
|
|
3582
|
+
const readHeaders = (0, import_react15.useCallback)(
|
|
3535
3583
|
(toRead) => {
|
|
3536
3584
|
if (toRead.length === 0) return;
|
|
3537
3585
|
generation.current += 1;
|
|
@@ -3562,7 +3610,7 @@ function useRecordVersions(client, rows, mayRead) {
|
|
|
3562
3610
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
3563
3611
|
[client]
|
|
3564
3612
|
);
|
|
3565
|
-
(0,
|
|
3613
|
+
(0, import_react15.useEffect)(() => {
|
|
3566
3614
|
const toRead = [];
|
|
3567
3615
|
for (const row of rowsRef.current) {
|
|
3568
3616
|
if (mayReadRef.current && !mayReadRef.current(row)) continue;
|
|
@@ -3575,8 +3623,8 @@ function useRecordVersions(client, rows, mayRead) {
|
|
|
3575
3623
|
}
|
|
3576
3624
|
readHeaders(toRead);
|
|
3577
3625
|
}, [readHeaders, key]);
|
|
3578
|
-
const refresh = (0,
|
|
3579
|
-
const seen = (0,
|
|
3626
|
+
const refresh = (0, import_react15.useCallback)((ids) => readHeaders([...ids]), [readHeaders]);
|
|
3627
|
+
const seen = (0, import_react15.useCallback)(async (id) => {
|
|
3580
3628
|
for (let guard = 0; guard < 5; guard += 1) {
|
|
3581
3629
|
const waiting = pending.current.get(id);
|
|
3582
3630
|
if (!waiting) break;
|
|
@@ -3585,7 +3633,7 @@ function useRecordVersions(client, rows, mayRead) {
|
|
|
3585
3633
|
if (unread.current.has(id)) return null;
|
|
3586
3634
|
return versions.current.get(id) ?? null;
|
|
3587
3635
|
}, []);
|
|
3588
|
-
const seenMany = (0,
|
|
3636
|
+
const seenMany = (0, import_react15.useCallback)(
|
|
3589
3637
|
async (ids) => {
|
|
3590
3638
|
const out = /* @__PURE__ */ new Map();
|
|
3591
3639
|
for (const id of ids) out.set(id, await seen(id));
|
|
@@ -3593,14 +3641,14 @@ function useRecordVersions(client, rows, mayRead) {
|
|
|
3593
3641
|
},
|
|
3594
3642
|
[seen]
|
|
3595
3643
|
);
|
|
3596
|
-
const wrote = (0,
|
|
3644
|
+
const wrote = (0, import_react15.useCallback)(
|
|
3597
3645
|
(id, version) => {
|
|
3598
3646
|
raise(id, version);
|
|
3599
3647
|
readHeaders([id]);
|
|
3600
3648
|
},
|
|
3601
3649
|
[readHeaders]
|
|
3602
3650
|
);
|
|
3603
|
-
return (0,
|
|
3651
|
+
return (0, import_react15.useMemo)(() => ({ seen, seenMany, wrote, refresh }), [seen, seenMany, wrote, refresh]);
|
|
3604
3652
|
}
|
|
3605
3653
|
async function readVersionNow(client, id) {
|
|
3606
3654
|
try {
|
|
@@ -3666,19 +3714,19 @@ async function readTableVersionNow(client, tableId) {
|
|
|
3666
3714
|
}
|
|
3667
3715
|
}
|
|
3668
3716
|
function useTableVersion(client, tableId, table) {
|
|
3669
|
-
const key = (0,
|
|
3717
|
+
const key = (0, import_react15.useMemo)(() => {
|
|
3670
3718
|
try {
|
|
3671
3719
|
return `${tableId ?? ""}${JSON.stringify(table ?? null)}`;
|
|
3672
3720
|
} catch {
|
|
3673
3721
|
return String(tableId ?? "");
|
|
3674
3722
|
}
|
|
3675
3723
|
}, [tableId, table]);
|
|
3676
|
-
const read = (0,
|
|
3677
|
-
const clientRef = (0,
|
|
3724
|
+
const read = (0, import_react15.useRef)(null);
|
|
3725
|
+
const clientRef = (0, import_react15.useRef)(client);
|
|
3678
3726
|
clientRef.current = client;
|
|
3679
|
-
const keyRef = (0,
|
|
3727
|
+
const keyRef = (0, import_react15.useRef)(key);
|
|
3680
3728
|
keyRef.current = key;
|
|
3681
|
-
return (0,
|
|
3729
|
+
return (0, import_react15.useCallback)(async () => {
|
|
3682
3730
|
if (!tableId) return null;
|
|
3683
3731
|
if (read.current && read.current.key === keyRef.current) return read.current.version;
|
|
3684
3732
|
const version = readTableVersionNow(clientRef.current, tableId);
|
|
@@ -3731,17 +3779,17 @@ function TableDetails({
|
|
|
3731
3779
|
fields,
|
|
3732
3780
|
onSaved
|
|
3733
3781
|
}) {
|
|
3734
|
-
const client = (0,
|
|
3782
|
+
const client = (0, import_react17.useRecordsClient)();
|
|
3735
3783
|
const kept = typeof table.metadata?.["description"] === "string" ? table.metadata["description"] : "";
|
|
3736
|
-
const [text2, setText] = (0,
|
|
3737
|
-
const [busy, setBusy] = (0,
|
|
3738
|
-
const [refused, setRefused] = (0,
|
|
3739
|
-
(0,
|
|
3740
|
-
const choices = (0,
|
|
3784
|
+
const [text2, setText] = (0, import_react16.useState)(kept);
|
|
3785
|
+
const [busy, setBusy] = (0, import_react16.useState)(false);
|
|
3786
|
+
const [refused, setRefused] = (0, import_react16.useState)(null);
|
|
3787
|
+
(0, import_react16.useEffect)(() => setText(kept), [kept]);
|
|
3788
|
+
const choices = (0, import_react16.useMemo)(() => rowLabelChoices(fields), [fields]);
|
|
3741
3789
|
const slots = useSettingsAgentSlots();
|
|
3742
|
-
const drafted = (0,
|
|
3790
|
+
const drafted = (0, import_react16.useRef)({ description: text2, kept });
|
|
3743
3791
|
drafted.current = { description: text2, kept };
|
|
3744
|
-
(0,
|
|
3792
|
+
(0, import_react16.useEffect)(() => {
|
|
3745
3793
|
if (!slots) return void 0;
|
|
3746
3794
|
const slot = { draft: () => drafted.current, stageDescription: (next) => setText(next) };
|
|
3747
3795
|
slots.details.current = slot;
|
|
@@ -3758,7 +3806,7 @@ function TableDetails({
|
|
|
3758
3806
|
setRefused(refusalSentence(written.error));
|
|
3759
3807
|
return;
|
|
3760
3808
|
}
|
|
3761
|
-
(0,
|
|
3809
|
+
(0, import_react17.tableShapeChanged)(tableId);
|
|
3762
3810
|
onSaved?.();
|
|
3763
3811
|
};
|
|
3764
3812
|
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex flex-col gap-2", "data-table-details": "", children: [
|
|
@@ -3822,22 +3870,22 @@ async function saveTableDescription(client, tableId, text2) {
|
|
|
3822
3870
|
{ metadata: table.metadata ?? {} }
|
|
3823
3871
|
);
|
|
3824
3872
|
if (!written.ok) return { ok: false, says: refusalSentence(written.error) };
|
|
3825
|
-
(0,
|
|
3873
|
+
(0, import_react17.tableShapeChanged)(tableId);
|
|
3826
3874
|
return { ok: true };
|
|
3827
3875
|
}
|
|
3828
3876
|
|
|
3829
3877
|
// src/ReferenceBuilder.tsx
|
|
3830
|
-
var
|
|
3831
|
-
var
|
|
3878
|
+
var import_react20 = require("react");
|
|
3879
|
+
var import_react21 = require("@ai-matrx/records/react");
|
|
3832
3880
|
var import_core3 = require("@ai-matrx/records/core");
|
|
3833
3881
|
|
|
3834
3882
|
// src/createTable.ts
|
|
3835
3883
|
var import_core2 = require("@ai-matrx/records/core");
|
|
3836
3884
|
|
|
3837
3885
|
// src/tablePicking.tsx
|
|
3838
|
-
var
|
|
3886
|
+
var import_react18 = require("react");
|
|
3839
3887
|
var import_records8 = require("@ai-matrx/records");
|
|
3840
|
-
var
|
|
3888
|
+
var import_react19 = require("@ai-matrx/records/react");
|
|
3841
3889
|
var import_design_system9 = require("@ai-matrx/design-system");
|
|
3842
3890
|
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
3843
3891
|
var APP_TABLE_PREFIX = "records_ui_";
|
|
@@ -3881,16 +3929,16 @@ function madeOn(stamp) {
|
|
|
3881
3929
|
return new Intl.DateTimeFormat(void 0, { month: "short", day: "numeric", year: "numeric" }).format(at);
|
|
3882
3930
|
}
|
|
3883
3931
|
function usePickerTables() {
|
|
3884
|
-
const client = (0,
|
|
3885
|
-
const tables = (0,
|
|
3886
|
-
const [facts, setFacts] = (0,
|
|
3887
|
-
const [nonce, setNonce] = (0,
|
|
3932
|
+
const client = (0, import_react19.useRecordsClient)();
|
|
3933
|
+
const tables = (0, import_react19.useTables)();
|
|
3934
|
+
const [facts, setFacts] = (0, import_react18.useState)("reading");
|
|
3935
|
+
const [nonce, setNonce] = (0, import_react18.useState)(0);
|
|
3888
3936
|
const reloadTables = tables.reload;
|
|
3889
|
-
const reload = (0,
|
|
3937
|
+
const reload = (0, import_react18.useCallback)(() => {
|
|
3890
3938
|
reloadTables();
|
|
3891
3939
|
setNonce((n) => n + 1);
|
|
3892
3940
|
}, [reloadTables]);
|
|
3893
|
-
(0,
|
|
3941
|
+
(0, import_react18.useEffect)(() => {
|
|
3894
3942
|
let alive = true;
|
|
3895
3943
|
void client.tableFacts().then((answered) => {
|
|
3896
3944
|
if (alive) setFacts(answered.ok ? answered.data ?? null : null);
|
|
@@ -3899,7 +3947,7 @@ function usePickerTables() {
|
|
|
3899
3947
|
alive = false;
|
|
3900
3948
|
};
|
|
3901
3949
|
}, [client, nonce]);
|
|
3902
|
-
const data = (0,
|
|
3950
|
+
const data = (0, import_react18.useMemo)(
|
|
3903
3951
|
() => (0, import_records8.withTablePlacement)(tables.data ?? [], facts === "reading" ? null : facts),
|
|
3904
3952
|
[tables.data, facts]
|
|
3905
3953
|
);
|
|
@@ -3955,11 +4003,11 @@ function previewWords(document2, display, titleField) {
|
|
|
3955
4003
|
return "an untitled record";
|
|
3956
4004
|
}
|
|
3957
4005
|
function useTargetColumns(target) {
|
|
3958
|
-
const declared2 = (0,
|
|
4006
|
+
const declared2 = (0, import_react21.useFields)(target);
|
|
3959
4007
|
const usable = (declared2.data ?? []).filter((f) => f.type !== "formula");
|
|
3960
4008
|
const needSample = usable.length === 0 && !declared2.loading && target !== null;
|
|
3961
|
-
const sample = (0,
|
|
3962
|
-
return (0,
|
|
4009
|
+
const sample = (0, import_react21.useRecords)(needSample ? target : null, { pageSize: 1 });
|
|
4010
|
+
return (0, import_react20.useMemo)(() => {
|
|
3963
4011
|
if (usable.length > 0) return { keys: usable.map((f) => f.key), loading: false };
|
|
3964
4012
|
const carried = sample.data?.rows[0]?.document ?? null;
|
|
3965
4013
|
if (!carried) return { keys: [], loading: declared2.loading || sample.loading };
|
|
@@ -3977,19 +4025,19 @@ function ReferenceBuilder({
|
|
|
3977
4025
|
className
|
|
3978
4026
|
}) {
|
|
3979
4027
|
const tables = usePickerTables();
|
|
3980
|
-
const client = (0,
|
|
3981
|
-
const [naming, setNaming] = (0,
|
|
3982
|
-
const [making, setMaking] = (0,
|
|
3983
|
-
const [refused, setRefused] = (0,
|
|
3984
|
-
const [born, setBorn] = (0,
|
|
4028
|
+
const client = (0, import_react21.useRecordsClient)();
|
|
4029
|
+
const [naming, setNaming] = (0, import_react20.useState)(null);
|
|
4030
|
+
const [making, setMaking] = (0, import_react20.useState)(false);
|
|
4031
|
+
const [refused, setRefused] = (0, import_react20.useState)(null);
|
|
4032
|
+
const [born, setBorn] = (0, import_react20.useState)(null);
|
|
3985
4033
|
const target = value.targetTableId || null;
|
|
3986
4034
|
const columns = useTargetColumns(target);
|
|
3987
|
-
const preview = (0,
|
|
4035
|
+
const preview = (0, import_react21.useRecords)(target, { pageSize: 3 });
|
|
3988
4036
|
const targetTable = (tables.data ?? []).find((t) => t.id === target) ?? null;
|
|
3989
4037
|
const titleField = targetTable?.title_field ?? null;
|
|
3990
|
-
const [overriding, setOverriding] = (0,
|
|
3991
|
-
const [showLists, setShowLists] = (0,
|
|
3992
|
-
const picking = (0,
|
|
4038
|
+
const [overriding, setOverriding] = (0, import_react20.useState)(value.display !== null);
|
|
4039
|
+
const [showLists, setShowLists] = (0, import_react20.useState)(false);
|
|
4040
|
+
const picking = (0, import_react20.useMemo)(
|
|
3993
4041
|
() => tablePickerEntries(
|
|
3994
4042
|
[
|
|
3995
4043
|
...(tables.data ?? []).map((t) => ({ ...t, name: tableName(t) })),
|
|
@@ -4250,9 +4298,9 @@ function ReferenceBuilder({
|
|
|
4250
4298
|
}
|
|
4251
4299
|
|
|
4252
4300
|
// src/PersonPicker.tsx
|
|
4253
|
-
var
|
|
4301
|
+
var import_react22 = require("react");
|
|
4254
4302
|
var import_records9 = require("@ai-matrx/records");
|
|
4255
|
-
var
|
|
4303
|
+
var import_react23 = require("@ai-matrx/records/react");
|
|
4256
4304
|
var import_design_system11 = require("@ai-matrx/design-system");
|
|
4257
4305
|
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
4258
4306
|
function personFromRow(row) {
|
|
@@ -4285,27 +4333,27 @@ async function personRecordForMember(client, personTableId, people, member) {
|
|
|
4285
4333
|
return written;
|
|
4286
4334
|
}
|
|
4287
4335
|
function PersonPicker({ field: field2, value, onChange, disabled, id, className, autoOpen, onClose, onCancel, initialSearch }) {
|
|
4288
|
-
const client = (0,
|
|
4336
|
+
const client = (0, import_react23.useOptionalRecordsClient)();
|
|
4289
4337
|
const host = useRecordsUi();
|
|
4290
|
-
const [members, setMembers] = (0,
|
|
4291
|
-
const [people, setPeople] = (0,
|
|
4292
|
-
const [error, setError] = (0,
|
|
4293
|
-
const [search, setSearch] = (0,
|
|
4294
|
-
const [open, setOpenState] = (0,
|
|
4295
|
-
const onCloseRef = (0,
|
|
4338
|
+
const [members, setMembers] = (0, import_react22.useState)(null);
|
|
4339
|
+
const [people, setPeople] = (0, import_react22.useState)([]);
|
|
4340
|
+
const [error, setError] = (0, import_react22.useState)(null);
|
|
4341
|
+
const [search, setSearch] = (0, import_react22.useState)(initialSearch ?? "");
|
|
4342
|
+
const [open, setOpenState] = (0, import_react22.useState)(autoOpen === true);
|
|
4343
|
+
const onCloseRef = (0, import_react22.useRef)(onClose);
|
|
4296
4344
|
onCloseRef.current = onClose;
|
|
4297
|
-
const setOpen = (0,
|
|
4345
|
+
const setOpen = (0, import_react22.useCallback)((next) => {
|
|
4298
4346
|
setOpenState(next);
|
|
4299
4347
|
if (!next) onCloseRef.current?.();
|
|
4300
4348
|
}, []);
|
|
4301
|
-
const [busy, setBusy] = (0,
|
|
4349
|
+
const [busy, setBusy] = (0, import_react22.useState)(false);
|
|
4302
4350
|
const membersPort = host.members;
|
|
4303
4351
|
const personTable = field2.relation_target;
|
|
4304
|
-
const picked = (0,
|
|
4352
|
+
const picked = (0, import_react22.useMemo)(
|
|
4305
4353
|
() => Array.isArray(value) ? value.map(String) : value === null || value === void 0 ? [] : [String(value)],
|
|
4306
4354
|
[value]
|
|
4307
4355
|
);
|
|
4308
|
-
const load = (0,
|
|
4356
|
+
const load = (0, import_react22.useCallback)(async () => {
|
|
4309
4357
|
if (!membersPort || !client) return;
|
|
4310
4358
|
const [roster, records] = await Promise.all([
|
|
4311
4359
|
membersPort(),
|
|
@@ -4318,11 +4366,11 @@ function PersonPicker({ field: field2, value, onChange, disabled, id, className,
|
|
|
4318
4366
|
}
|
|
4319
4367
|
setPeople(records ? records.data.rows.map(personFromRow).filter((p) => p.userId !== null) : []);
|
|
4320
4368
|
}, [membersPort, client, personTable]);
|
|
4321
|
-
(0,
|
|
4369
|
+
(0, import_react22.useEffect)(() => {
|
|
4322
4370
|
if (!open) return;
|
|
4323
4371
|
void load();
|
|
4324
4372
|
}, [open, load]);
|
|
4325
|
-
(0,
|
|
4373
|
+
(0, import_react22.useEffect)(() => {
|
|
4326
4374
|
if (picked.length === 0 || !personTable || people.length > 0 || !client) return;
|
|
4327
4375
|
let cancelled = false;
|
|
4328
4376
|
void client.list({ table_id: personTable, limit: 500 }).then((result) => {
|
|
@@ -4437,11 +4485,12 @@ function PersonPicker({ field: field2, value, onChange, disabled, id, className,
|
|
|
4437
4485
|
|
|
4438
4486
|
// src/gridEditing.tsx
|
|
4439
4487
|
var import_react48 = require("react");
|
|
4440
|
-
var
|
|
4488
|
+
var import_core7 = require("@ai-matrx/records/core");
|
|
4441
4489
|
var import_react49 = require("@ai-matrx/records/react");
|
|
4442
4490
|
var import_design_system26 = require("@ai-matrx/design-system");
|
|
4443
4491
|
|
|
4444
4492
|
// src/presentation.ts
|
|
4493
|
+
var import_table_style = require("@ai-matrx/design-system/data-table/table-style");
|
|
4445
4494
|
var import_data_table3 = require("@ai-matrx/design-system/data-table");
|
|
4446
4495
|
var import_field_formats2 = require("@ai-matrx/design-system/field-formats");
|
|
4447
4496
|
var import_records10 = require("@ai-matrx/records");
|
|
@@ -4574,8 +4623,8 @@ function parseGridPresentation(raw) {
|
|
|
4574
4623
|
}
|
|
4575
4624
|
if (!isRecord(value)) return {};
|
|
4576
4625
|
const out = {};
|
|
4577
|
-
const style = (0,
|
|
4578
|
-
if (!(0,
|
|
4626
|
+
const style = (0, import_table_style.parseTableStyle)(value["style"]);
|
|
4627
|
+
if (!(0, import_table_style.tableStyleIsEmpty)(style)) out.style = style;
|
|
4579
4628
|
if (isRecord(value["formats"])) {
|
|
4580
4629
|
const formats = {};
|
|
4581
4630
|
for (const [key, cfg] of Object.entries(value["formats"])) {
|
|
@@ -4705,7 +4754,7 @@ function parseGrouping(raw) {
|
|
|
4705
4754
|
return out;
|
|
4706
4755
|
}
|
|
4707
4756
|
function presentationIsEmpty(p) {
|
|
4708
|
-
return (p.style === void 0 || (0,
|
|
4757
|
+
return (p.style === void 0 || (0, import_table_style.tableStyleIsEmpty)(p.style)) && Object.keys(p.formats ?? {}).length === 0 && (p.frozen?.length ?? 0) === 0 && p.grouping === void 0 && Object.keys(p.widths ?? {}).length === 0 && p.rowHeight === void 0 && (p.hiddenFields?.length ?? 0) === 0 && p.cardHidden === void 0 && (p.columnOrder?.length ?? 0) === 0 && p.gallerySize === void 0 && p.wrap === void 0 && p.fit === void 0 && p.freezeFirst === void 0 && p.footer === void 0 && Object.keys(p.summaries ?? {}).length === 0;
|
|
4709
4758
|
}
|
|
4710
4759
|
function presentationDocument(p) {
|
|
4711
4760
|
return presentationIsEmpty(p) ? "" : JSON.stringify(p);
|
|
@@ -4850,7 +4899,7 @@ var import_react39 = require("@ai-matrx/records/react");
|
|
|
4850
4899
|
var import_design_system20 = require("@ai-matrx/design-system");
|
|
4851
4900
|
|
|
4852
4901
|
// src/newerKindValues.tsx
|
|
4853
|
-
var
|
|
4902
|
+
var import_react24 = require("react");
|
|
4854
4903
|
var import_source = require("@ai-matrx/content-ir/source");
|
|
4855
4904
|
var import_records11 = require("@ai-matrx/records");
|
|
4856
4905
|
var import_design_system12 = require("@ai-matrx/design-system");
|
|
@@ -5033,9 +5082,9 @@ function newerKindControl(props) {
|
|
|
5033
5082
|
}
|
|
5034
5083
|
}
|
|
5035
5084
|
function DurationControl({ value, onChange, disabled, id }) {
|
|
5036
|
-
const [text2, setText] = (0,
|
|
5037
|
-
const [wrong, setWrong] = (0,
|
|
5038
|
-
(0,
|
|
5085
|
+
const [text2, setText] = (0, import_react24.useState)(() => (0, import_records11.durationText)(value) ?? "");
|
|
5086
|
+
const [wrong, setWrong] = (0, import_react24.useState)(false);
|
|
5087
|
+
(0, import_react24.useEffect)(() => {
|
|
5039
5088
|
setText((0, import_records11.durationText)(value) ?? "");
|
|
5040
5089
|
}, [value]);
|
|
5041
5090
|
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "flex flex-col gap-1", children: [
|
|
@@ -5108,8 +5157,8 @@ function barcodeDetector() {
|
|
|
5108
5157
|
return typeof ctor === "function" ? ctor : null;
|
|
5109
5158
|
}
|
|
5110
5159
|
function BarcodeControl({ value, onChange, disabled, id }) {
|
|
5111
|
-
const file = (0,
|
|
5112
|
-
const [said2, setSaid] = (0,
|
|
5160
|
+
const file = (0, import_react24.useRef)(null);
|
|
5161
|
+
const [said2, setSaid] = (0, import_react24.useState)(null);
|
|
5113
5162
|
const Detect = barcodeDetector();
|
|
5114
5163
|
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "flex flex-col gap-1", children: [
|
|
5115
5164
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "flex items-center gap-1.5", children: [
|
|
@@ -5165,9 +5214,9 @@ function BarcodeControl({ value, onChange, disabled, id }) {
|
|
|
5165
5214
|
}
|
|
5166
5215
|
|
|
5167
5216
|
// src/RelationPicker.tsx
|
|
5168
|
-
var
|
|
5217
|
+
var import_react25 = require("react");
|
|
5169
5218
|
var import_records12 = require("@ai-matrx/records");
|
|
5170
|
-
var
|
|
5219
|
+
var import_react26 = require("@ai-matrx/records/react");
|
|
5171
5220
|
var import_design_system13 = require("@ai-matrx/design-system");
|
|
5172
5221
|
|
|
5173
5222
|
// src/tellApart.ts
|
|
@@ -5214,29 +5263,29 @@ var import_jsx_runtime15 = (
|
|
|
5214
5263
|
);
|
|
5215
5264
|
var NO_STORE_ON_THIS_SCREEN_REASON = "This question points at a record in somebody's own data, and a page answered without an account is never allowed to search that. Leave it blank \u2014 whoever receives your answer will fill it in.";
|
|
5216
5265
|
function RelationPicker({ field: field2, value, onChange, disabled, id, className, allowCreate = true, onPicked, autoOpen, onClose, onCancel }) {
|
|
5217
|
-
const client = (0,
|
|
5218
|
-
const [rows, setRows] = (0,
|
|
5219
|
-
const [words2, setWords] = (0,
|
|
5220
|
-
const [refusal4, setRefusal] = (0,
|
|
5221
|
-
const [search, setSearch] = (0,
|
|
5222
|
-
const [open, setOpenState] = (0,
|
|
5223
|
-
const onCloseRef = (0,
|
|
5266
|
+
const client = (0, import_react26.useOptionalRecordsClient)();
|
|
5267
|
+
const [rows, setRows] = (0, import_react25.useState)(null);
|
|
5268
|
+
const [words2, setWords] = (0, import_react25.useState)({});
|
|
5269
|
+
const [refusal4, setRefusal] = (0, import_react25.useState)(null);
|
|
5270
|
+
const [search, setSearch] = (0, import_react25.useState)("");
|
|
5271
|
+
const [open, setOpenState] = (0, import_react25.useState)(autoOpen === true);
|
|
5272
|
+
const onCloseRef = (0, import_react25.useRef)(onClose);
|
|
5224
5273
|
onCloseRef.current = onClose;
|
|
5225
|
-
const setOpen = (0,
|
|
5274
|
+
const setOpen = (0, import_react25.useCallback)((next) => {
|
|
5226
5275
|
setOpenState(next);
|
|
5227
5276
|
if (!next) onCloseRef.current?.();
|
|
5228
5277
|
}, []);
|
|
5229
|
-
const [target, setTarget] = (0,
|
|
5230
|
-
const [targetRefusal, setTargetRefusal] = (0,
|
|
5231
|
-
const [creating, setCreating] = (0,
|
|
5232
|
-
const [newTitle, setNewTitle] = (0,
|
|
5233
|
-
const [busy, setBusy] = (0,
|
|
5234
|
-
const [createRefusal, setCreateRefusal] = (0,
|
|
5235
|
-
const picked = (0,
|
|
5278
|
+
const [target, setTarget] = (0, import_react25.useState)(null);
|
|
5279
|
+
const [targetRefusal, setTargetRefusal] = (0, import_react25.useState)(null);
|
|
5280
|
+
const [creating, setCreating] = (0, import_react25.useState)(false);
|
|
5281
|
+
const [newTitle, setNewTitle] = (0, import_react25.useState)("");
|
|
5282
|
+
const [busy, setBusy] = (0, import_react25.useState)(false);
|
|
5283
|
+
const [createRefusal, setCreateRefusal] = (0, import_react25.useState)(null);
|
|
5284
|
+
const picked = (0, import_react25.useMemo)(
|
|
5236
5285
|
() => Array.isArray(value) ? value.map(String) : value === null || value === void 0 ? [] : [String(value)],
|
|
5237
5286
|
[value]
|
|
5238
5287
|
);
|
|
5239
|
-
(0,
|
|
5288
|
+
(0, import_react25.useEffect)(() => {
|
|
5240
5289
|
const target2 = field2.relation_target;
|
|
5241
5290
|
if (!target2 || !client) return;
|
|
5242
5291
|
let cancelled = false;
|
|
@@ -5249,7 +5298,7 @@ function RelationPicker({ field: field2, value, onChange, disabled, id, classNam
|
|
|
5249
5298
|
cancelled = true;
|
|
5250
5299
|
};
|
|
5251
5300
|
}, [client, field2.relation_target]);
|
|
5252
|
-
(0,
|
|
5301
|
+
(0, import_react25.useEffect)(() => {
|
|
5253
5302
|
if (!rows || !client) return;
|
|
5254
5303
|
const wanted = [.../* @__PURE__ */ new Set([...rows.map((row) => row.id), ...picked])].filter(
|
|
5255
5304
|
(id2) => words2[id2] === void 0
|
|
@@ -5269,7 +5318,7 @@ function RelationPicker({ field: field2, value, onChange, disabled, id, classNam
|
|
|
5269
5318
|
cancelled = true;
|
|
5270
5319
|
};
|
|
5271
5320
|
}, [client, field2.id, rows, picked, words2]);
|
|
5272
|
-
(0,
|
|
5321
|
+
(0, import_react25.useEffect)(() => {
|
|
5273
5322
|
if (!open || !allowCreate || target || targetRefusal || !client) return;
|
|
5274
5323
|
const id2 = field2.relation_target;
|
|
5275
5324
|
if (!id2) return;
|
|
@@ -5476,12 +5525,12 @@ function RelationPicker({ field: field2, value, onChange, disabled, id, classNam
|
|
|
5476
5525
|
}
|
|
5477
5526
|
|
|
5478
5527
|
// src/gridAttachments.tsx
|
|
5479
|
-
var
|
|
5480
|
-
var
|
|
5528
|
+
var import_react28 = require("react");
|
|
5529
|
+
var import_react29 = require("@ai-matrx/records/react");
|
|
5481
5530
|
var import_design_system15 = require("@ai-matrx/design-system");
|
|
5482
5531
|
|
|
5483
5532
|
// src/FilePicker.tsx
|
|
5484
|
-
var
|
|
5533
|
+
var import_react27 = require("react");
|
|
5485
5534
|
var import_design_system14 = require("@ai-matrx/design-system");
|
|
5486
5535
|
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
5487
5536
|
function FilePicker({
|
|
@@ -5495,17 +5544,17 @@ function FilePicker({
|
|
|
5495
5544
|
chosenName,
|
|
5496
5545
|
className
|
|
5497
5546
|
}) {
|
|
5498
|
-
const inputId = (0,
|
|
5499
|
-
const input = (0,
|
|
5500
|
-
const [over, setOver] = (0,
|
|
5501
|
-
const take = (0,
|
|
5547
|
+
const inputId = (0, import_react27.useId)();
|
|
5548
|
+
const input = (0, import_react27.useRef)(null);
|
|
5549
|
+
const [over, setOver] = (0, import_react27.useState)(false);
|
|
5550
|
+
const take = (0, import_react27.useCallback)(
|
|
5502
5551
|
(file) => {
|
|
5503
5552
|
if (!file || disabled) return;
|
|
5504
5553
|
onFile(file);
|
|
5505
5554
|
},
|
|
5506
5555
|
[disabled, onFile]
|
|
5507
5556
|
);
|
|
5508
|
-
const onDrop = (0,
|
|
5557
|
+
const onDrop = (0, import_react27.useCallback)(
|
|
5509
5558
|
(e) => {
|
|
5510
5559
|
e.preventDefault();
|
|
5511
5560
|
setOver(false);
|
|
@@ -5598,10 +5647,10 @@ function rememberHostFileIds(ids) {
|
|
|
5598
5647
|
var FILE_CHIP_UNREAD = "File";
|
|
5599
5648
|
var FILE_CHIP_NO_PAGE = "This screen has no way to open files yet.";
|
|
5600
5649
|
function AttachmentChip({ id, onRemove }) {
|
|
5601
|
-
const client = (0,
|
|
5650
|
+
const client = (0, import_react29.useOptionalRecordsClient)();
|
|
5602
5651
|
const host = useRecordsUi();
|
|
5603
|
-
const [read, setRead] = (0,
|
|
5604
|
-
(0,
|
|
5652
|
+
const [read, setRead] = (0, import_react28.useState)(null);
|
|
5653
|
+
(0, import_react28.useEffect)(() => {
|
|
5605
5654
|
let cancelled = false;
|
|
5606
5655
|
if (!client) {
|
|
5607
5656
|
setRead({ name: null, fileId: null, why: null });
|
|
@@ -5676,9 +5725,9 @@ function AttachmentControl({
|
|
|
5676
5725
|
onClose
|
|
5677
5726
|
}) {
|
|
5678
5727
|
const host = useRecordsUi();
|
|
5679
|
-
const [busy, setBusy] = (0,
|
|
5680
|
-
const [why, setWhy] = (0,
|
|
5681
|
-
const latest = (0,
|
|
5728
|
+
const [busy, setBusy] = (0, import_react28.useState)(false);
|
|
5729
|
+
const [why, setWhy] = (0, import_react28.useState)(null);
|
|
5730
|
+
const latest = (0, import_react28.useRef)(value);
|
|
5682
5731
|
latest.current = value;
|
|
5683
5732
|
const multiple = Boolean(field2.multi);
|
|
5684
5733
|
const pick = async () => {
|
|
@@ -5699,8 +5748,8 @@ function AttachmentControl({
|
|
|
5699
5748
|
setBusy(false);
|
|
5700
5749
|
onClose?.();
|
|
5701
5750
|
};
|
|
5702
|
-
const opened = (0,
|
|
5703
|
-
(0,
|
|
5751
|
+
const opened = (0, import_react28.useRef)(false);
|
|
5752
|
+
(0, import_react28.useEffect)(() => {
|
|
5704
5753
|
if (!autoOpen || opened.current || !host.pickFiles) return;
|
|
5705
5754
|
opened.current = true;
|
|
5706
5755
|
void pick();
|
|
@@ -5743,9 +5792,9 @@ function AttachmentControl({
|
|
|
5743
5792
|
}
|
|
5744
5793
|
|
|
5745
5794
|
// src/EntityReferenceControl.tsx
|
|
5746
|
-
var
|
|
5795
|
+
var import_react30 = require("react");
|
|
5747
5796
|
var import_records13 = require("@ai-matrx/records");
|
|
5748
|
-
var
|
|
5797
|
+
var import_react31 = require("@ai-matrx/records/react");
|
|
5749
5798
|
var import_design_system16 = require("@ai-matrx/design-system");
|
|
5750
5799
|
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
5751
5800
|
var WITHHELD_ENTITY_LABEL = "Something you have not been given access to";
|
|
@@ -5761,19 +5810,19 @@ function allowedKindsOf(field2) {
|
|
|
5761
5810
|
return kinds.map((k) => String(k).trim().toLowerCase()).filter(Boolean);
|
|
5762
5811
|
}
|
|
5763
5812
|
function EntityReferenceControl(props) {
|
|
5764
|
-
const client = (0,
|
|
5813
|
+
const client = (0, import_react31.useOptionalRecordsClient)();
|
|
5765
5814
|
return client ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(WithWords, { ...props }) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Chips, { ...props, words: null, picker: null });
|
|
5766
5815
|
}
|
|
5767
5816
|
function WithWords(props) {
|
|
5768
|
-
const refs = (0,
|
|
5769
|
-
const [known, setKnown] = (0,
|
|
5817
|
+
const refs = (0, import_react30.useMemo)(() => (0, import_records13.entityRefsOf)(props.value), [props.value]);
|
|
5818
|
+
const [known, setKnown] = (0, import_react30.useState)([]);
|
|
5770
5819
|
const withKnown = refs.map((r) => r.label === null ? known.find((k) => k.token === r.token && k.id === r.id) ?? r : r);
|
|
5771
|
-
const unlabelled = (0,
|
|
5820
|
+
const unlabelled = (0, import_react30.useMemo)(
|
|
5772
5821
|
() => withKnown.filter((r) => r.label === null).map((r) => ({ token: r.token, id: r.id })),
|
|
5773
5822
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
5774
5823
|
[JSON.stringify(withKnown)]
|
|
5775
5824
|
);
|
|
5776
|
-
const words2 = (0,
|
|
5825
|
+
const words2 = (0, import_react31.useEntityReferenceWords)(unlabelled);
|
|
5777
5826
|
const picker = props.disabled ? null : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5778
5827
|
EntityReferencePicker,
|
|
5779
5828
|
{
|
|
@@ -5795,13 +5844,13 @@ function EntityReferencePicker({
|
|
|
5795
5844
|
onPick
|
|
5796
5845
|
}) {
|
|
5797
5846
|
const allowed = allowedKindsOf(field2);
|
|
5798
|
-
const kinds = (0,
|
|
5847
|
+
const kinds = (0, import_react31.useEntityReferenceKinds)();
|
|
5799
5848
|
const labelOfKind = (token) => kinds.data?.find((k) => k.token === token)?.label ?? token.replace(/_/g, " ");
|
|
5800
|
-
const [open, setOpen] = (0,
|
|
5801
|
-
const [search, setSearch] = (0,
|
|
5802
|
-
const [only, setOnly] = (0,
|
|
5849
|
+
const [open, setOpen] = (0, import_react30.useState)(false);
|
|
5850
|
+
const [search, setSearch] = (0, import_react30.useState)("");
|
|
5851
|
+
const [only, setOnly] = (0, import_react30.useState)(null);
|
|
5803
5852
|
const tokens = only ? [only] : allowed;
|
|
5804
|
-
const found = (0,
|
|
5853
|
+
const found = (0, import_react31.useEntityReferenceSearch)(tokens, search, open);
|
|
5805
5854
|
const multi = Boolean(field2.multi);
|
|
5806
5855
|
const items = (found.data ?? []).map((r) => ({
|
|
5807
5856
|
id: `${r.token}:${r.id}`,
|
|
@@ -5872,7 +5921,7 @@ function Chips({
|
|
|
5872
5921
|
words: words2,
|
|
5873
5922
|
picker
|
|
5874
5923
|
}) {
|
|
5875
|
-
const refs = (0,
|
|
5924
|
+
const refs = (0, import_react30.useMemo)(() => (0, import_records13.entityRefsOf)(value), [value]);
|
|
5876
5925
|
const labelOf = (token, refId, own3) => {
|
|
5877
5926
|
if (own3) return own3;
|
|
5878
5927
|
const read = words2?.data?.find((w) => w.token === token && w.id === refId)?.label;
|
|
@@ -5908,7 +5957,7 @@ function Chips({
|
|
|
5908
5957
|
}
|
|
5909
5958
|
|
|
5910
5959
|
// src/FloatingRefusal.tsx
|
|
5911
|
-
var
|
|
5960
|
+
var import_react32 = require("react");
|
|
5912
5961
|
var import_react_dom = require("react-dom");
|
|
5913
5962
|
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
5914
5963
|
var GAP = 4;
|
|
@@ -5926,11 +5975,11 @@ function placeFor(anchor, note) {
|
|
|
5926
5975
|
return { position: "fixed", top: a.top + (a.height - height) / 2, left: Math.max(a.left, a.right - width - 8) };
|
|
5927
5976
|
}
|
|
5928
5977
|
function FloatingRefusal({ text: text2, why }) {
|
|
5929
|
-
const spot = (0,
|
|
5930
|
-
const note = (0,
|
|
5931
|
-
const [style, setStyle] = (0,
|
|
5932
|
-
const [floating, setFloating] = (0,
|
|
5933
|
-
(0,
|
|
5978
|
+
const spot = (0, import_react32.useRef)(null);
|
|
5979
|
+
const note = (0, import_react32.useRef)(null);
|
|
5980
|
+
const [style, setStyle] = (0, import_react32.useState)(null);
|
|
5981
|
+
const [floating, setFloating] = (0, import_react32.useState)(false);
|
|
5982
|
+
(0, import_react32.useLayoutEffect)(() => {
|
|
5934
5983
|
const here = spot.current;
|
|
5935
5984
|
if (!here) return;
|
|
5936
5985
|
const anchor = here.closest("[data-matrx-cell-editor]");
|
|
@@ -5972,12 +6021,12 @@ function FloatingRefusal({ text: text2, why }) {
|
|
|
5972
6021
|
}
|
|
5973
6022
|
|
|
5974
6023
|
// src/formatControls.tsx
|
|
5975
|
-
var
|
|
6024
|
+
var import_react34 = require("react");
|
|
5976
6025
|
var import_design_system18 = require("@ai-matrx/design-system");
|
|
5977
6026
|
var import_field_formats4 = require("@ai-matrx/design-system/field-formats");
|
|
5978
6027
|
|
|
5979
6028
|
// src/formattedValue.tsx
|
|
5980
|
-
var
|
|
6029
|
+
var import_react33 = require("react");
|
|
5981
6030
|
var import_data_table4 = require("@ai-matrx/design-system/data-table");
|
|
5982
6031
|
var import_field_formats3 = require("@ai-matrx/design-system/field-formats");
|
|
5983
6032
|
var import_design_system17 = require("@ai-matrx/design-system");
|
|
@@ -5999,7 +6048,7 @@ function RatingStars({
|
|
|
5999
6048
|
label,
|
|
6000
6049
|
selectFirst
|
|
6001
6050
|
}) {
|
|
6002
|
-
const armed = (0,
|
|
6051
|
+
const armed = (0, import_react33.useRef)(true);
|
|
6003
6052
|
const score = numberOf(value) ?? 0;
|
|
6004
6053
|
const shown4 = Math.round(score);
|
|
6005
6054
|
const said2 = `${shown4} out of ${max}`;
|
|
@@ -6148,9 +6197,9 @@ function keptValue(format, raw) {
|
|
|
6148
6197
|
return parsed;
|
|
6149
6198
|
}
|
|
6150
6199
|
function NumberInFormat({ format, value, onChange, disabled, id }) {
|
|
6151
|
-
const [text2, setText] = (0,
|
|
6152
|
-
const lastSent = (0,
|
|
6153
|
-
(0,
|
|
6200
|
+
const [text2, setText] = (0, import_react34.useState)(() => typedText(format, value));
|
|
6201
|
+
const lastSent = (0, import_react34.useRef)(void 0);
|
|
6202
|
+
(0, import_react34.useEffect)(() => {
|
|
6154
6203
|
if (value === lastSent.current) return;
|
|
6155
6204
|
setText(typedText(format, value));
|
|
6156
6205
|
}, [value, format]);
|
|
@@ -6227,56 +6276,6 @@ function formatControl(args) {
|
|
|
6227
6276
|
var import_react35 = require("react");
|
|
6228
6277
|
var import_design_system19 = require("@ai-matrx/design-system");
|
|
6229
6278
|
var import_records14 = require("@ai-matrx/records");
|
|
6230
|
-
|
|
6231
|
-
// src/personTime.ts
|
|
6232
|
-
var import_react34 = require("react");
|
|
6233
|
-
var zone = null;
|
|
6234
|
-
var listeners = /* @__PURE__ */ new Set();
|
|
6235
|
-
function valid(z) {
|
|
6236
|
-
if (typeof z !== "string" || !z.trim()) return false;
|
|
6237
|
-
try {
|
|
6238
|
-
new Intl.DateTimeFormat("en-US", { timeZone: z });
|
|
6239
|
-
return true;
|
|
6240
|
-
} catch {
|
|
6241
|
-
return false;
|
|
6242
|
-
}
|
|
6243
|
-
}
|
|
6244
|
-
function setPersonTimeZone(next) {
|
|
6245
|
-
const clean = valid(next) ? next : null;
|
|
6246
|
-
if (clean === zone) return;
|
|
6247
|
-
zone = clean;
|
|
6248
|
-
listeners.forEach((l) => l());
|
|
6249
|
-
}
|
|
6250
|
-
function getPersonTimeZone() {
|
|
6251
|
-
return zone;
|
|
6252
|
-
}
|
|
6253
|
-
function usePersonTimeZone() {
|
|
6254
|
-
return (0, import_react34.useSyncExternalStore)(
|
|
6255
|
-
(cb) => {
|
|
6256
|
-
listeners.add(cb);
|
|
6257
|
-
return () => listeners.delete(cb);
|
|
6258
|
-
},
|
|
6259
|
-
() => zone,
|
|
6260
|
-
() => null
|
|
6261
|
-
);
|
|
6262
|
-
}
|
|
6263
|
-
function personWallNow(at = /* @__PURE__ */ new Date()) {
|
|
6264
|
-
if (!zone) return at;
|
|
6265
|
-
const parts = new Intl.DateTimeFormat("en-US", {
|
|
6266
|
-
timeZone: zone,
|
|
6267
|
-
year: "numeric",
|
|
6268
|
-
month: "2-digit",
|
|
6269
|
-
day: "2-digit",
|
|
6270
|
-
hour: "2-digit",
|
|
6271
|
-
minute: "2-digit",
|
|
6272
|
-
second: "2-digit",
|
|
6273
|
-
hourCycle: "h23"
|
|
6274
|
-
}).formatToParts(at);
|
|
6275
|
-
const n = (t) => Number(parts.find((p) => p.type === t)?.value ?? 0);
|
|
6276
|
-
return new Date(n("year"), n("month") - 1, n("day"), n("hour"), n("minute"), n("second"));
|
|
6277
|
-
}
|
|
6278
|
-
|
|
6279
|
-
// src/typedDateHelper.tsx
|
|
6280
6279
|
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
6281
6280
|
var WEEK = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
|
|
6282
6281
|
var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
|
|
@@ -7589,6 +7588,473 @@ var import_design_system25 = require("@ai-matrx/design-system");
|
|
|
7589
7588
|
|
|
7590
7589
|
// src/embeddedLook.tsx
|
|
7591
7590
|
var import_react42 = require("react");
|
|
7591
|
+
|
|
7592
|
+
// src/firstPage.ts
|
|
7593
|
+
var import_core4 = require("@ai-matrx/records/core");
|
|
7594
|
+
|
|
7595
|
+
// src/viewKeys.ts
|
|
7596
|
+
var STORE_KEEPS_TIMELINE = true;
|
|
7597
|
+
var ALL = ["grid", "kanban", "calendar", "gallery", ...STORE_KEEPS_TIMELINE ? ["timeline"] : [], "list"];
|
|
7598
|
+
var HIDES = ["grid", "gallery", "kanban", "calendar", ...STORE_KEEPS_TIMELINE ? ["timeline"] : [], "list"];
|
|
7599
|
+
var GRIDS = ["grid"];
|
|
7600
|
+
var VIEW_KEYS = [
|
|
7601
|
+
{ path: "layout", shape: "kind", layouts: ALL, writer: "caller" },
|
|
7602
|
+
{ path: "filters", shape: "filter", layouts: ALL, writer: "caller" },
|
|
7603
|
+
{ path: "where", shape: "rule", layouts: ALL, writer: "caller" },
|
|
7604
|
+
{ path: "group_field", shape: "field", layouts: ["kanban", ...STORE_KEEPS_TIMELINE ? ["timeline"] : []], writer: "caller" },
|
|
7605
|
+
{ path: "swimlane_field", shape: "field:lane", layouts: ["kanban"], writer: "caller" },
|
|
7606
|
+
{ path: "collapsed_columns", shape: "values", layouts: ["kanban"], writer: "caller" },
|
|
7607
|
+
{ path: "measure", shape: "field:number", layouts: ["kanban"], writer: "caller" },
|
|
7608
|
+
{ path: "date_field", shape: "field:date", layouts: ["calendar"], writer: "caller" },
|
|
7609
|
+
...STORE_KEEPS_TIMELINE ? [
|
|
7610
|
+
{ path: "start_field", shape: "field:date", layouts: ["timeline"], writer: "caller" },
|
|
7611
|
+
{ path: "end_field", shape: "field:date", layouts: ["calendar", "timeline"], writer: "caller" }
|
|
7612
|
+
] : [],
|
|
7613
|
+
{ path: "image_field", shape: "field", layouts: ["gallery"], writer: "caller" },
|
|
7614
|
+
{ path: "sorts", shape: "sorts", layouts: ALL, writer: "caller" },
|
|
7615
|
+
{ path: "rule_id", shape: "uuid", layouts: ALL, writer: "caller" },
|
|
7616
|
+
{ path: "is_default", shape: "boolean", layouts: ALL, writer: "caller" },
|
|
7617
|
+
{ path: "presentation", shape: "presentation", layouts: ALL, writer: "caller" },
|
|
7618
|
+
{ path: "presentation.style", shape: "style", layouts: ALL, writer: "caller" },
|
|
7619
|
+
{ path: "presentation.formats", shape: "object", layouts: GRIDS, writer: "caller" },
|
|
7620
|
+
{ path: "presentation.frozen", shape: "fields", layouts: GRIDS, writer: "caller" },
|
|
7621
|
+
{ path: "presentation.grouping", shape: "grouping", layouts: ["grid", "gallery", "list"], writer: "caller" },
|
|
7622
|
+
{ path: "presentation.widths", shape: "widths", layouts: GRIDS, writer: "caller" },
|
|
7623
|
+
{ path: "presentation.rowHeight", shape: "row_height", layouts: GRIDS, writer: "caller" },
|
|
7624
|
+
{ path: "presentation.hiddenFields", shape: "fields", layouts: HIDES, writer: "caller" },
|
|
7625
|
+
{ path: "presentation.cardHidden", shape: "fields", layouts: ["kanban", "calendar", ...STORE_KEEPS_TIMELINE ? ["timeline"] : [], "list", "gallery"], writer: "caller" },
|
|
7626
|
+
{ path: "presentation.columnOrder", shape: "fields", layouts: GRIDS, writer: "caller" },
|
|
7627
|
+
{ path: "presentation.gallerySize", shape: "gallery_size", layouts: ["gallery"], writer: "caller" },
|
|
7628
|
+
{ path: "presentation.wrap", shape: "boolean", layouts: GRIDS, writer: "caller" },
|
|
7629
|
+
{ path: "presentation.wrapColumns", shape: "fields", layouts: GRIDS, writer: "caller" },
|
|
7630
|
+
{ path: "presentation.fit", shape: "fit", layouts: GRIDS, writer: "caller" },
|
|
7631
|
+
{ path: "presentation.freezeFirst", shape: "boolean", layouts: GRIDS, writer: "caller" },
|
|
7632
|
+
{ path: "presentation.footer", shape: "footer", layouts: GRIDS, writer: "caller" },
|
|
7633
|
+
{ path: "presentation.summaries", shape: "summaries", layouts: GRIDS, writer: "caller" },
|
|
7634
|
+
{ path: "grid", shape: "grid", layouts: GRIDS, writer: "caller" },
|
|
7635
|
+
{ path: "hidden_fields", shape: "input", layouts: HIDES, writer: "input" },
|
|
7636
|
+
{ path: "table_id", shape: "server", layouts: ALL, writer: "server" },
|
|
7637
|
+
{ path: "order", shape: "server", layouts: GRIDS, writer: "server" },
|
|
7638
|
+
{ path: "moved_from", shape: "server", layouts: ALL, writer: "server" }
|
|
7639
|
+
];
|
|
7640
|
+
var STORE_KEPT_LAYOUTS = ["grid", "kanban", "calendar", "gallery", ...STORE_KEEPS_TIMELINE ? ["timeline"] : [], "list"];
|
|
7641
|
+
function storeKeepsLayout(layout) {
|
|
7642
|
+
return STORE_KEPT_LAYOUTS.includes(layout);
|
|
7643
|
+
}
|
|
7644
|
+
function viewKeysFor(layout) {
|
|
7645
|
+
return VIEW_KEYS.filter((k) => k.layouts.includes(layout)).map((k) => k.path);
|
|
7646
|
+
}
|
|
7647
|
+
var KINDS = STORE_KEPT_LAYOUTS;
|
|
7648
|
+
function viewSettings(definition, rowFilters) {
|
|
7649
|
+
const data = definition ?? {};
|
|
7650
|
+
const text2 = (key) => {
|
|
7651
|
+
const v = data[key];
|
|
7652
|
+
return typeof v === "string" && v !== "" ? v : null;
|
|
7653
|
+
};
|
|
7654
|
+
const layout = String(data["layout"] ?? "grid");
|
|
7655
|
+
const flat = rowFilters ?? (isObject2(data["filters"]) ? data["filters"] : null);
|
|
7656
|
+
const moved = data["moved_from"];
|
|
7657
|
+
return {
|
|
7658
|
+
layout: KINDS.includes(layout) ? layout : "grid",
|
|
7659
|
+
filters: flat && Object.keys(flat).length > 0 ? flat : null,
|
|
7660
|
+
where: isRule(data["where"]) ? data["where"] : null,
|
|
7661
|
+
groupField: text2("group_field"),
|
|
7662
|
+
swimlaneField: text2("swimlane_field"),
|
|
7663
|
+
collapsedColumns: Array.isArray(data["collapsed_columns"]) ? data["collapsed_columns"].filter((v) => ["string", "number", "boolean"].includes(typeof v)).map(String) : [],
|
|
7664
|
+
measure: text2("measure"),
|
|
7665
|
+
dateField: text2("date_field"),
|
|
7666
|
+
startField: text2("start_field"),
|
|
7667
|
+
endField: text2("end_field"),
|
|
7668
|
+
imageField: text2("image_field"),
|
|
7669
|
+
sorts: parseSorts(data["sorts"]),
|
|
7670
|
+
ruleId: text2("rule_id"),
|
|
7671
|
+
isDefault: data["is_default"] === true || data["is_default"] === "true",
|
|
7672
|
+
presentation: parseGridPresentation(data["presentation"]),
|
|
7673
|
+
movedFrom: isObject2(moved) ? moved : null
|
|
7674
|
+
};
|
|
7675
|
+
}
|
|
7676
|
+
function viewSettingsFor(settings, layout) {
|
|
7677
|
+
const reads = new Set(viewKeysFor(layout));
|
|
7678
|
+
const out = { layout: settings.layout };
|
|
7679
|
+
const take = (key, path) => {
|
|
7680
|
+
if (reads.has(path)) out[key] = settings[key];
|
|
7681
|
+
};
|
|
7682
|
+
take("filters", "filters");
|
|
7683
|
+
take("where", "where");
|
|
7684
|
+
take("groupField", "group_field");
|
|
7685
|
+
take("swimlaneField", "swimlane_field");
|
|
7686
|
+
take("collapsedColumns", "collapsed_columns");
|
|
7687
|
+
take("measure", "measure");
|
|
7688
|
+
take("dateField", "date_field");
|
|
7689
|
+
take("startField", "start_field");
|
|
7690
|
+
take("endField", "end_field");
|
|
7691
|
+
take("imageField", "image_field");
|
|
7692
|
+
take("sorts", "sorts");
|
|
7693
|
+
take("ruleId", "rule_id");
|
|
7694
|
+
take("isDefault", "is_default");
|
|
7695
|
+
const p = settings.presentation;
|
|
7696
|
+
const look = {};
|
|
7697
|
+
for (const [key, value] of Object.entries(p)) {
|
|
7698
|
+
if (reads.has(`presentation.${key}`)) look[key] = value;
|
|
7699
|
+
}
|
|
7700
|
+
out.presentation = look;
|
|
7701
|
+
return out;
|
|
7702
|
+
}
|
|
7703
|
+
function viewSettingsPatch(patch) {
|
|
7704
|
+
const out = {};
|
|
7705
|
+
const field2 = (key, path) => {
|
|
7706
|
+
if (patch[key] !== void 0) out[path] = patch[key] || null;
|
|
7707
|
+
};
|
|
7708
|
+
if (patch.layout !== void 0 && storeKeepsLayout(patch.layout)) out["layout"] = patch.layout;
|
|
7709
|
+
field2("groupField", "group_field");
|
|
7710
|
+
field2("swimlaneField", "swimlane_field");
|
|
7711
|
+
field2("measure", "measure");
|
|
7712
|
+
field2("dateField", "date_field");
|
|
7713
|
+
if (STORE_KEEPS_TIMELINE) {
|
|
7714
|
+
field2("startField", "start_field");
|
|
7715
|
+
field2("endField", "end_field");
|
|
7716
|
+
}
|
|
7717
|
+
field2("imageField", "image_field");
|
|
7718
|
+
field2("ruleId", "rule_id");
|
|
7719
|
+
if (patch.collapsedColumns !== void 0) out["collapsed_columns"] = patch.collapsedColumns ?? [];
|
|
7720
|
+
if (patch.sorts !== void 0) out["sorts"] = patch.sorts ?? [];
|
|
7721
|
+
if (patch.where !== void 0) out["where"] = patch.where ?? null;
|
|
7722
|
+
if (patch.isDefault !== void 0) out["is_default"] = patch.isDefault === true;
|
|
7723
|
+
if (patch.presentation !== void 0) {
|
|
7724
|
+
out["presentation"] = !patch.presentation || presentationIsEmpty(patch.presentation) ? null : JSON.parse(presentationDocument(patch.presentation));
|
|
7725
|
+
}
|
|
7726
|
+
return out;
|
|
7727
|
+
}
|
|
7728
|
+
function isObject2(raw) {
|
|
7729
|
+
return Boolean(raw) && typeof raw === "object" && !Array.isArray(raw);
|
|
7730
|
+
}
|
|
7731
|
+
function isRule(raw) {
|
|
7732
|
+
if (!isObject2(raw)) return false;
|
|
7733
|
+
const node = raw;
|
|
7734
|
+
return typeof node.op === "string" && Array.isArray(node.args);
|
|
7735
|
+
}
|
|
7736
|
+
function parseSorts(raw) {
|
|
7737
|
+
let list = raw;
|
|
7738
|
+
if (typeof raw === "string") {
|
|
7739
|
+
try {
|
|
7740
|
+
list = raw.trim() === "" ? [] : JSON.parse(raw);
|
|
7741
|
+
} catch {
|
|
7742
|
+
return [];
|
|
7743
|
+
}
|
|
7744
|
+
}
|
|
7745
|
+
if (!Array.isArray(list)) return [];
|
|
7746
|
+
return list.filter((s) => isObject2(s) && typeof s.field === "string").map((s) => ({ field: s.field, direction: s.direction === "desc" ? "desc" : "asc" }));
|
|
7747
|
+
}
|
|
7748
|
+
|
|
7749
|
+
// src/views.ts
|
|
7750
|
+
var VIEW_LAYOUTS = ["grid", "kanban", "calendar", "gallery", "timeline", "list"];
|
|
7751
|
+
var LAYOUT_LABEL = {
|
|
7752
|
+
grid: "Grid",
|
|
7753
|
+
kanban: "Kanban",
|
|
7754
|
+
calendar: "Calendar",
|
|
7755
|
+
gallery: "Gallery",
|
|
7756
|
+
timeline: "Timeline",
|
|
7757
|
+
list: "List"
|
|
7758
|
+
};
|
|
7759
|
+
function wordsList(words2) {
|
|
7760
|
+
const clean = words2.map((w) => w.trim()).filter((w) => w !== "");
|
|
7761
|
+
if (clean.length <= 1) return clean.join("");
|
|
7762
|
+
return `${clean.slice(0, -1).join(", ")} and ${clean[clean.length - 1]}`;
|
|
7763
|
+
}
|
|
7764
|
+
var VIEW_NEEDS = {
|
|
7765
|
+
grid: null,
|
|
7766
|
+
// A list reads nothing a table can lack: rows, titled, grouped only when the person chooses.
|
|
7767
|
+
list: null,
|
|
7768
|
+
kanban: {
|
|
7769
|
+
kind: "choice",
|
|
7770
|
+
viewKey: "groupField",
|
|
7771
|
+
blocking: true,
|
|
7772
|
+
starter: { label: "Status", type: "select", options: ["To do", "In progress", "Done"] },
|
|
7773
|
+
pick: "Pick the choice column the board's columns come from.",
|
|
7774
|
+
missing: "This table has no choice column to make the board's columns from.",
|
|
7775
|
+
does: (label) => `Make it work adds a ${label} column with the choices below and groups the board by it.`,
|
|
7776
|
+
ask: (label, options) => `Add a choice column called ${label} to this table${options.length > 0 ? ` with the choices ${wordsList(options)}` : ""}, then group the Kanban board by it.`
|
|
7777
|
+
},
|
|
7778
|
+
calendar: {
|
|
7779
|
+
kind: "date",
|
|
7780
|
+
viewKey: "dateField",
|
|
7781
|
+
blocking: true,
|
|
7782
|
+
starter: { label: "Date", type: "datetime" },
|
|
7783
|
+
pick: "Pick the date column the calendar places records by.",
|
|
7784
|
+
missing: "This table has no date column to place records on.",
|
|
7785
|
+
does: (label) => `Make it work adds a ${label} column and lays the calendar out by it.`,
|
|
7786
|
+
ask: (label) => `Add a date column called ${label} to this table, then lay the Calendar out by it.`
|
|
7787
|
+
},
|
|
7788
|
+
gallery: {
|
|
7789
|
+
kind: "file",
|
|
7790
|
+
viewKey: "imageField",
|
|
7791
|
+
blocking: false,
|
|
7792
|
+
starter: { label: "Photo", type: "attachment" },
|
|
7793
|
+
pick: "Pick the file column each card shows as its picture.",
|
|
7794
|
+
missing: "The cards have no picture because this table has no file column.",
|
|
7795
|
+
does: (label) => `Make it work adds a ${label} column and shows it on each card.`,
|
|
7796
|
+
ask: (label) => `Add a file column called ${label} to this table, then show it as the picture on each Gallery card.`
|
|
7797
|
+
},
|
|
7798
|
+
timeline: {
|
|
7799
|
+
kind: "date",
|
|
7800
|
+
viewKey: "dateField",
|
|
7801
|
+
blocking: true,
|
|
7802
|
+
starter: { label: "Start", type: "datetime" },
|
|
7803
|
+
pick: "Pick the date column each bar starts on.",
|
|
7804
|
+
missing: "This table has no date column to place records on.",
|
|
7805
|
+
does: (label) => `Make it work adds a ${label} column and lays the timeline out by it.`,
|
|
7806
|
+
ask: (label) => `Add a date column called ${label} to this table, then lay the Timeline out by it.`
|
|
7807
|
+
}
|
|
7808
|
+
};
|
|
7809
|
+
function freeColumnName(wanted, taken) {
|
|
7810
|
+
const held = new Set(taken.map((t) => t.trim().toLowerCase()));
|
|
7811
|
+
const base = wanted.trim() === "" ? "Column" : wanted.trim();
|
|
7812
|
+
if (!held.has(base.toLowerCase())) return base;
|
|
7813
|
+
for (let n = 2; n < 100; n += 1) {
|
|
7814
|
+
const next = `${base} ${n}`;
|
|
7815
|
+
if (!held.has(next.toLowerCase())) return next;
|
|
7816
|
+
}
|
|
7817
|
+
return base;
|
|
7818
|
+
}
|
|
7819
|
+
function viewOrderOf(definition) {
|
|
7820
|
+
const raw = definition?.["order"];
|
|
7821
|
+
return raw === "manual" ? "manual" : raw === "sorted" ? "sorted" : null;
|
|
7822
|
+
}
|
|
7823
|
+
function defaultViewOf(views) {
|
|
7824
|
+
return views.find((v) => v.isDefault);
|
|
7825
|
+
}
|
|
7826
|
+
var LAYOUT_FIELD_KIND = {
|
|
7827
|
+
grid: null,
|
|
7828
|
+
kanban: "choice",
|
|
7829
|
+
calendar: "date",
|
|
7830
|
+
gallery: "file",
|
|
7831
|
+
timeline: "date",
|
|
7832
|
+
list: null
|
|
7833
|
+
};
|
|
7834
|
+
var PAGE_VIEWS = [...VIEW_LAYOUTS, "dashboards", "archived"];
|
|
7835
|
+
var PAGE_VIEW_LABEL = {
|
|
7836
|
+
...LAYOUT_LABEL,
|
|
7837
|
+
dashboards: "Dashboards",
|
|
7838
|
+
archived: "Archived"
|
|
7839
|
+
};
|
|
7840
|
+
var PAGE_VIEW_SPELLINGS = {
|
|
7841
|
+
grid: "grid",
|
|
7842
|
+
table: "grid",
|
|
7843
|
+
rows: "grid",
|
|
7844
|
+
list: "list",
|
|
7845
|
+
kanban: "kanban",
|
|
7846
|
+
board: "kanban",
|
|
7847
|
+
pipeline: "kanban",
|
|
7848
|
+
calendar: "calendar",
|
|
7849
|
+
month: "calendar",
|
|
7850
|
+
schedule: "calendar",
|
|
7851
|
+
gallery: "gallery",
|
|
7852
|
+
cards: "gallery",
|
|
7853
|
+
timeline: "timeline",
|
|
7854
|
+
gantt: "timeline",
|
|
7855
|
+
dashboards: "dashboards",
|
|
7856
|
+
dashboard: "dashboards",
|
|
7857
|
+
charts: "dashboards",
|
|
7858
|
+
archived: "archived",
|
|
7859
|
+
archive: "archived",
|
|
7860
|
+
// The grid's row action says "Delete" and the store soft-deletes, so the word
|
|
7861
|
+
// a person types is as likely to be the one the button used as the one this
|
|
7862
|
+
// view is called. Both land in the same place; neither dies.
|
|
7863
|
+
deleted: "archived",
|
|
7864
|
+
trash: "archived",
|
|
7865
|
+
removed: "archived"
|
|
7866
|
+
};
|
|
7867
|
+
function pageViewFromParam(raw) {
|
|
7868
|
+
if (typeof raw !== "string") return null;
|
|
7869
|
+
const token = raw.trim().toLowerCase();
|
|
7870
|
+
if (token === "") return null;
|
|
7871
|
+
return PAGE_VIEW_SPELLINGS[token] ?? null;
|
|
7872
|
+
}
|
|
7873
|
+
function unknownViewLine(raw) {
|
|
7874
|
+
return `The link asked for a view called \u201C${raw}\u201D, which this table has no view for, so you are looking at ${PAGE_VIEW_LABEL.grid}. The views this table has are ${PAGE_VIEWS.map((v) => PAGE_VIEW_LABEL[v]).join(", ")} \u2014 pick one above and the address follows it.`;
|
|
7875
|
+
}
|
|
7876
|
+
function viewDocument(spec) {
|
|
7877
|
+
const out = {
|
|
7878
|
+
// A layout the store does not keep yet is not sent: the view is saved as a grid (`STORE_KEPT_LAYOUTS`).
|
|
7879
|
+
layout: storeKeepsLayout(spec.layout) ? spec.layout : "grid",
|
|
7880
|
+
sorts: spec.sorts ?? [],
|
|
7881
|
+
is_default: spec.isDefault === true
|
|
7882
|
+
};
|
|
7883
|
+
if (spec.groupField) out["group_field"] = spec.groupField;
|
|
7884
|
+
if (spec.swimlaneField) out["swimlane_field"] = spec.swimlaneField;
|
|
7885
|
+
if (spec.collapsedColumns && spec.collapsedColumns.length > 0) out["collapsed_columns"] = spec.collapsedColumns;
|
|
7886
|
+
if (spec.measure) out["measure"] = spec.measure;
|
|
7887
|
+
if (spec.dateField) out["date_field"] = spec.dateField;
|
|
7888
|
+
if (STORE_KEEPS_TIMELINE && spec.startField) out["start_field"] = spec.startField;
|
|
7889
|
+
if (STORE_KEEPS_TIMELINE && spec.endField) out["end_field"] = spec.endField;
|
|
7890
|
+
if (spec.imageField) out["image_field"] = spec.imageField;
|
|
7891
|
+
if (spec.ruleId) out["rule_id"] = spec.ruleId;
|
|
7892
|
+
if (spec.where) out["where"] = spec.where;
|
|
7893
|
+
if (spec.presentation && !presentationIsEmpty(spec.presentation)) {
|
|
7894
|
+
out["presentation"] = JSON.parse(presentationDocument(spec.presentation));
|
|
7895
|
+
}
|
|
7896
|
+
return out;
|
|
7897
|
+
}
|
|
7898
|
+
function viewFromRow(row) {
|
|
7899
|
+
const data = row.definition ?? {};
|
|
7900
|
+
const k = viewSettings(data, row.filters && Object.keys(row.filters).length > 0 ? row.filters : null);
|
|
7901
|
+
const tableFromDefinition = typeof data["table_id"] === "string" && data["table_id"] !== "" ? data["table_id"] : null;
|
|
7902
|
+
return {
|
|
7903
|
+
id: row.view_id,
|
|
7904
|
+
name: row.name || "Untitled view",
|
|
7905
|
+
subject: row.table_id ?? tableFromDefinition ?? "",
|
|
7906
|
+
layout: k.layout,
|
|
7907
|
+
groupField: k.groupField,
|
|
7908
|
+
swimlaneField: k.swimlaneField,
|
|
7909
|
+
collapsedColumns: k.collapsedColumns,
|
|
7910
|
+
measure: k.measure,
|
|
7911
|
+
dateField: k.dateField,
|
|
7912
|
+
startField: k.startField,
|
|
7913
|
+
endField: k.endField,
|
|
7914
|
+
imageField: k.imageField,
|
|
7915
|
+
sorts: k.sorts,
|
|
7916
|
+
order: viewOrderOf(data),
|
|
7917
|
+
ruleId: k.ruleId,
|
|
7918
|
+
...k.filters ? { filters: k.filters } : {},
|
|
7919
|
+
where: k.where,
|
|
7920
|
+
// The older table's own default view, carried in by the mover, IS this table's default —
|
|
7921
|
+
// the mover wrote the row's column, which `custom.views` does not return. Read as anything
|
|
7922
|
+
// else, the page would seed a second "All records" beside it and open on that.
|
|
7923
|
+
isDefault: k.isDefault || k.movedFrom?.["kind"] === "default_view",
|
|
7924
|
+
presentation: k.presentation,
|
|
7925
|
+
movedFrom: k.movedFrom
|
|
7926
|
+
};
|
|
7927
|
+
}
|
|
7928
|
+
async function declareView(client, spec) {
|
|
7929
|
+
return client.viewDeclare({
|
|
7930
|
+
table_id: spec.subject,
|
|
7931
|
+
spec: {
|
|
7932
|
+
name: spec.name,
|
|
7933
|
+
...spec.filters ? { filters: spec.filters } : {},
|
|
7934
|
+
definition: viewDocument(spec)
|
|
7935
|
+
}
|
|
7936
|
+
});
|
|
7937
|
+
}
|
|
7938
|
+
async function saveViewPatch(client, tableId, viewId, patch) {
|
|
7939
|
+
const definition = viewPatchDocument(patch);
|
|
7940
|
+
const renamed = patch.name !== void 0 && patch.name.trim() !== "";
|
|
7941
|
+
const refiltered = patch.filters !== void 0;
|
|
7942
|
+
return client.viewDeclare({
|
|
7943
|
+
table_id: tableId,
|
|
7944
|
+
spec: {
|
|
7945
|
+
view_id: viewId,
|
|
7946
|
+
...renamed ? { name: patch.name.trim() } : {},
|
|
7947
|
+
...refiltered ? { filters: patch.filters ?? null } : {},
|
|
7948
|
+
definition
|
|
7949
|
+
}
|
|
7950
|
+
});
|
|
7951
|
+
}
|
|
7952
|
+
function viewPatchDocument(patch) {
|
|
7953
|
+
const { name: _name, subject: _subject, filters: _filters, ...keys } = patch;
|
|
7954
|
+
return viewSettingsPatch(keys);
|
|
7955
|
+
}
|
|
7956
|
+
function viewPatchFor(view, patch) {
|
|
7957
|
+
if (!view.isDefault) return patch;
|
|
7958
|
+
const { layout: _layout, isDefault: _isDefault, ...kept } = patch;
|
|
7959
|
+
return kept;
|
|
7960
|
+
}
|
|
7961
|
+
async function designateView(client, tableId, viewId, layout) {
|
|
7962
|
+
return client.viewDesignate({ table_id: tableId, view_id: viewId, layout });
|
|
7963
|
+
}
|
|
7964
|
+
|
|
7965
|
+
// src/viewLook.ts
|
|
7966
|
+
var LOOK_KEYS = [
|
|
7967
|
+
"layout",
|
|
7968
|
+
"groupField",
|
|
7969
|
+
"swimlaneField",
|
|
7970
|
+
"collapsedColumns",
|
|
7971
|
+
"measure",
|
|
7972
|
+
"dateField",
|
|
7973
|
+
"startField",
|
|
7974
|
+
"endField",
|
|
7975
|
+
"imageField",
|
|
7976
|
+
"sorts",
|
|
7977
|
+
"where",
|
|
7978
|
+
"presentation"
|
|
7979
|
+
];
|
|
7980
|
+
function lookPart(patch) {
|
|
7981
|
+
const out = {};
|
|
7982
|
+
for (const key of LOOK_KEYS) {
|
|
7983
|
+
if (patch[key] !== void 0) out[key] = patch[key];
|
|
7984
|
+
}
|
|
7985
|
+
return out;
|
|
7986
|
+
}
|
|
7987
|
+
function lookDocument(look) {
|
|
7988
|
+
return viewSettingsPatch(look);
|
|
7989
|
+
}
|
|
7990
|
+
function lookFromDocument(doc) {
|
|
7991
|
+
const data = doc ?? {};
|
|
7992
|
+
const read = viewSettings(data);
|
|
7993
|
+
const out = {};
|
|
7994
|
+
const has = (key) => Object.prototype.hasOwnProperty.call(data, key);
|
|
7995
|
+
if (has("layout") && VIEW_LAYOUTS.includes(String(data["layout"]))) {
|
|
7996
|
+
out.layout = data["layout"];
|
|
7997
|
+
}
|
|
7998
|
+
if (has("group_field")) out.groupField = read.groupField;
|
|
7999
|
+
if (has("swimlane_field")) out.swimlaneField = read.swimlaneField;
|
|
8000
|
+
if (has("collapsed_columns")) out.collapsedColumns = read.collapsedColumns;
|
|
8001
|
+
if (has("measure")) out.measure = read.measure;
|
|
8002
|
+
if (has("date_field")) out.dateField = read.dateField;
|
|
8003
|
+
if (has("start_field")) out.startField = read.startField;
|
|
8004
|
+
if (has("end_field")) out.endField = read.endField;
|
|
8005
|
+
if (has("image_field")) out.imageField = read.imageField;
|
|
8006
|
+
if (has("sorts")) out.sorts = read.sorts;
|
|
8007
|
+
if (has("where")) out.where = read.where;
|
|
8008
|
+
if (has("presentation")) out.presentation = parseGridPresentation(data["presentation"]);
|
|
8009
|
+
return out;
|
|
8010
|
+
}
|
|
8011
|
+
function applyLook(view, look) {
|
|
8012
|
+
if (!look) return view;
|
|
8013
|
+
return { ...view, ...look };
|
|
8014
|
+
}
|
|
8015
|
+
function lookDiffers(view, look) {
|
|
8016
|
+
if (!look) return false;
|
|
8017
|
+
const shown4 = applyLook(view, look);
|
|
8018
|
+
return LOOK_KEYS.some(
|
|
8019
|
+
(key) => look[key] !== void 0 && JSON.stringify(shown4[key] ?? null) !== JSON.stringify(view[key] ?? null)
|
|
8020
|
+
);
|
|
8021
|
+
}
|
|
8022
|
+
function saveToViewPlan(view, look) {
|
|
8023
|
+
const patch = viewPatchFor(view, look);
|
|
8024
|
+
const left = {};
|
|
8025
|
+
if (look.layout !== void 0 && patch.layout === void 0 && look.layout !== view.layout) left.layout = look.layout;
|
|
8026
|
+
return { patch, left: Object.keys(left).length > 0 ? left : null };
|
|
8027
|
+
}
|
|
8028
|
+
async function readLooks(client, tableId) {
|
|
8029
|
+
const answered = await client.viewLookRead({ table_id: tableId });
|
|
8030
|
+
if (!answered.ok) return answered;
|
|
8031
|
+
const out = {};
|
|
8032
|
+
for (const [viewId, row] of Object.entries(answered.data ?? {})) {
|
|
8033
|
+
out[viewId] = lookFromDocument(row?.look ?? null);
|
|
8034
|
+
}
|
|
8035
|
+
return { ok: true, data: out };
|
|
8036
|
+
}
|
|
8037
|
+
async function keepLook(client, tableId, viewId, look) {
|
|
8038
|
+
const doc = look ? lookDocument(look) : null;
|
|
8039
|
+
return client.viewLookSet({ table_id: tableId, view_id: viewId, look: doc && Object.keys(doc).length > 0 ? doc : null });
|
|
8040
|
+
}
|
|
8041
|
+
var LOOK_WORDS = {
|
|
8042
|
+
/** The reason, for a tooltip or a screen reader — never a line on the page (interface-text). */
|
|
8043
|
+
yours: "You changed how this view looks. Only you see it.",
|
|
8044
|
+
/** The visible label for the same fact. */
|
|
8045
|
+
yoursLabel: "Only you see this",
|
|
8046
|
+
saveToView: "Save to view",
|
|
8047
|
+
saveAsNew: "Save as new view",
|
|
8048
|
+
reset: "Reset to view",
|
|
8049
|
+
/** The one button your look's doors fold into when the toolbar row has no room for three. */
|
|
8050
|
+
folded: "Your look",
|
|
8051
|
+
newName: "Name for the new view"
|
|
8052
|
+
};
|
|
8053
|
+
|
|
8054
|
+
// src/firstPage.ts
|
|
8055
|
+
var EMBEDDED_PAGE_SIZE = 50;
|
|
8056
|
+
|
|
8057
|
+
// src/embeddedLook.tsx
|
|
7592
8058
|
var EMBEDDED_LOOK = { blankEmpty: true, choiceDot: true, plainRelation: true };
|
|
7593
8059
|
var EmbeddedLookContext = (0, import_react42.createContext)(null);
|
|
7594
8060
|
var EmbeddedLookProvider = EmbeddedLookContext.Provider;
|
|
@@ -7606,7 +8072,6 @@ var EMBEDDED_TABLE_CLASS = [
|
|
|
7606
8072
|
"[&_thead_th:last-child]:border-r-0"
|
|
7607
8073
|
].join(" ");
|
|
7608
8074
|
var EMBEDDED_PLAIN_FOOTER_CLASS = "[&_tfoot]:bg-transparent [&_tfoot]:border-t-0";
|
|
7609
|
-
var EMBEDDED_PAGE_SIZE = 50;
|
|
7610
8075
|
|
|
7611
8076
|
// src/enumLabels.ts
|
|
7612
8077
|
function exhaustiveValuesOf() {
|
|
@@ -7745,16 +8210,16 @@ var ABSENCE_WORD_LABEL = {
|
|
|
7745
8210
|
};
|
|
7746
8211
|
|
|
7747
8212
|
// src/values.tsx
|
|
7748
|
-
var
|
|
8213
|
+
var import_core6 = require("@ai-matrx/records/core");
|
|
7749
8214
|
|
|
7750
8215
|
// src/WholeValue.tsx
|
|
7751
8216
|
var import_react43 = require("react");
|
|
7752
|
-
var
|
|
8217
|
+
var import_core5 = require("@ai-matrx/records/core");
|
|
7753
8218
|
var import_design_system21 = require("@ai-matrx/design-system");
|
|
7754
8219
|
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
7755
8220
|
var WHOLE_VALUE_UNBOUND = "The whole text is kept as a file, and this screen has no way to open files yet.";
|
|
7756
8221
|
function wholeValueLine(pointer) {
|
|
7757
|
-
return `Open the whole text (${(0,
|
|
8222
|
+
return `Open the whole text (${(0, import_core5.wholeValueSize)(pointer)})`;
|
|
7758
8223
|
}
|
|
7759
8224
|
function WholeValueCell({ words: words2, pointer }) {
|
|
7760
8225
|
const host = useRecordsUi();
|
|
@@ -7765,12 +8230,12 @@ function WholeValueCell({ words: words2, pointer }) {
|
|
|
7765
8230
|
words2,
|
|
7766
8231
|
"\u2026"
|
|
7767
8232
|
] }),
|
|
7768
|
-
href ? host.Link ? host.Link({ href, children: line, className: "shrink-0 text-xs text-primary underline-offset-2 hover:underline" }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("a", { className: "shrink-0 text-xs text-primary underline-offset-2 hover:underline", href, target: "_blank", rel: "noreferrer", children: line }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "shrink-0 text-xs italic text-muted-foreground", title: WHOLE_VALUE_UNBOUND, children: `${(0,
|
|
8233
|
+
href ? host.Link ? host.Link({ href, children: line, className: "shrink-0 text-xs text-primary underline-offset-2 hover:underline" }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("a", { className: "shrink-0 text-xs text-primary underline-offset-2 hover:underline", href, target: "_blank", rel: "noreferrer", children: line }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "shrink-0 text-xs italic text-muted-foreground", title: WHOLE_VALUE_UNBOUND, children: `${(0, import_core5.wholeValueSize)(pointer)} in a file` })
|
|
7769
8234
|
] });
|
|
7770
8235
|
}
|
|
7771
8236
|
var WHOLE_VALUE_NOT_EDITABLE_HERE = "The whole text is kept as a file. Open it to read it; this screen cannot load it to edit.";
|
|
7772
8237
|
function wholeValueOpening(pointer) {
|
|
7773
|
-
return `Opening the whole text (${(0,
|
|
8238
|
+
return `Opening the whole text (${(0, import_core5.wholeValueSize)(pointer)})\u2026`;
|
|
7774
8239
|
}
|
|
7775
8240
|
function useWholeText(pointer) {
|
|
7776
8241
|
const host = useRecordsUi();
|
|
@@ -8466,7 +8931,7 @@ function renderValue(field2, value, document2, labels, stillWaitingFor, look) {
|
|
|
8466
8931
|
if (isSignatureField(field2)) return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(SignatureValue, { value, fieldKey: field2.key, document: document2 });
|
|
8467
8932
|
const newer = newerKindValue(field2, value);
|
|
8468
8933
|
if (newer !== void 0) return newer;
|
|
8469
|
-
const whole = typeof value === "string" ? (0,
|
|
8934
|
+
const whole = typeof value === "string" ? (0, import_core6.wholeValueOf)(document2, field2.key) : null;
|
|
8470
8935
|
if (whole) return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(WholeValueCell, { words: value, pointer: whole });
|
|
8471
8936
|
const kind = editorKindFor(field2);
|
|
8472
8937
|
if (kind === "relation" || kind === "entity_reference") {
|
|
@@ -8589,7 +9054,7 @@ function scalarText(field2, value, labels, stillWaitingFor) {
|
|
|
8589
9054
|
function ProvenanceBadge({ document: document2, fieldKey }) {
|
|
8590
9055
|
const envelope = envelopeFor(document2, fieldKey);
|
|
8591
9056
|
if (!envelope?.src) return null;
|
|
8592
|
-
if ((0,
|
|
9057
|
+
if ((0, import_core6.wholeValueOf)(document2, fieldKey)) return null;
|
|
8593
9058
|
const sources = document2?._sources;
|
|
8594
9059
|
const source = sources?.[envelope.src];
|
|
8595
9060
|
const label = source ? Object.values(source).map(String).join(" \xB7 ") : envelope.src;
|
|
@@ -8624,7 +9089,7 @@ function RecordValue({
|
|
|
8624
9089
|
const newer = newerKindValue(field2, value, { inCell });
|
|
8625
9090
|
if (newer !== void 0) return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_jsx_runtime31.Fragment, { children: newer });
|
|
8626
9091
|
}
|
|
8627
|
-
if (inCell && ui.grid === "merged" && ui.renderText && typeof value === "string" && value.trim() !== "" && editorKindFor(field2) === "long_text" && !shownAsOf(field2) && !(0,
|
|
9092
|
+
if (inCell && ui.grid === "merged" && ui.renderText && typeof value === "string" && value.trim() !== "" && editorKindFor(field2) === "long_text" && !shownAsOf(field2) && !(0, import_core6.wholeValueOf)(document2, field2.key) && !envelopeFor(document2, field2.key)?.absent && // A long-text cell holding a kind is drawn by the kind system below, not as markdown.
|
|
8628
9093
|
!kindValueOf(value)) {
|
|
8629
9094
|
return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "block h-[1.5em] min-w-0 overflow-hidden whitespace-normal", "data-records-cell-text": "", children: ui.renderText(value, "cell") });
|
|
8630
9095
|
}
|
|
@@ -8837,7 +9302,7 @@ function useGridEditing({ tableId, fields, rows, reload, reloadAfterWrite, canWr
|
|
|
8837
9302
|
}
|
|
8838
9303
|
const held = optimistic[cellKey(address.rowId, address.key)];
|
|
8839
9304
|
const document2 = rows.find((r) => r.id === address.rowId)?.document;
|
|
8840
|
-
const pointer = held === void 0 && typeof current === "string" ? (0,
|
|
9305
|
+
const pointer = held === void 0 && typeof current === "string" ? (0, import_core7.wholeValueOf)(document2, address.key) : null;
|
|
8841
9306
|
if (pointer) {
|
|
8842
9307
|
const read = host.readFileText;
|
|
8843
9308
|
if (!read) return;
|
|
@@ -8948,7 +9413,7 @@ function useGridEditing({ tableId, fields, rows, reload, reloadAfterWrite, canWr
|
|
|
8948
9413
|
delete next[id];
|
|
8949
9414
|
return next;
|
|
8950
9415
|
});
|
|
8951
|
-
const conflict = (0,
|
|
9416
|
+
const conflict = (0, import_core7.asWriteConflict)(written.error, rowId);
|
|
8952
9417
|
if (written.error.code === "stale_write") {
|
|
8953
9418
|
if (conflict) rememberVersion(versions.current, rowId, conflict.current_version);
|
|
8954
9419
|
else versions.current.delete(rowId);
|
|
@@ -9036,7 +9501,7 @@ function useGridEditing({ tableId, fields, rows, reload, reloadAfterWrite, canWr
|
|
|
9036
9501
|
}
|
|
9037
9502
|
const starting = shownValue2(next.rowId, next.key);
|
|
9038
9503
|
const nextDocument = rows.find((r) => r.id === next.rowId)?.document;
|
|
9039
|
-
if (typeof starting === "string" && optimistic[cellKey(next.rowId, next.key)] === void 0 && (0,
|
|
9504
|
+
if (typeof starting === "string" && optimistic[cellKey(next.rowId, next.key)] === void 0 && (0, import_core7.wholeValueOf)(nextDocument, next.key)) {
|
|
9040
9505
|
setEditing(null);
|
|
9041
9506
|
setDraft(null);
|
|
9042
9507
|
typed2.current = null;
|
|
@@ -10057,7 +10522,7 @@ var import_react122 = require("react");
|
|
|
10057
10522
|
var import_react123 = require("@ai-matrx/records/react");
|
|
10058
10523
|
var import_records36 = require("@ai-matrx/records");
|
|
10059
10524
|
var import_data_table13 = require("@ai-matrx/design-system/data-table");
|
|
10060
|
-
var
|
|
10525
|
+
var import_core17 = require("@ai-matrx/records/core");
|
|
10061
10526
|
|
|
10062
10527
|
// src/archiveWords.ts
|
|
10063
10528
|
var import_format2 = require("@ai-matrx/kit/format");
|
|
@@ -10203,7 +10668,7 @@ function columnNameTakenLine(taken, noun = "column") {
|
|
|
10203
10668
|
// src/FieldEditor.tsx
|
|
10204
10669
|
var import_react65 = require("react");
|
|
10205
10670
|
var import_react66 = require("@ai-matrx/records/react");
|
|
10206
|
-
var
|
|
10671
|
+
var import_core8 = require("@ai-matrx/records/core");
|
|
10207
10672
|
var import_design_system35 = require("@ai-matrx/design-system");
|
|
10208
10673
|
|
|
10209
10674
|
// src/EntityReferenceKindPicker.tsx
|
|
@@ -11891,7 +12356,7 @@ function FieldEditor(props) {
|
|
|
11891
12356
|
return;
|
|
11892
12357
|
}
|
|
11893
12358
|
(0, import_react66.tableShapeChanged)(tableId);
|
|
11894
|
-
for (const c of done.data.undo.cells_back) (0,
|
|
12359
|
+
for (const c of done.data.undo.cells_back) (0, import_core8.announceRecordChanged)(c.record_id);
|
|
11895
12360
|
const n = done.data.rehomed.reduce((sum, r) => sum + r.records, 0);
|
|
11896
12361
|
setRehome({});
|
|
11897
12362
|
setRehomed({ said: `Saved. ${n} ${n === 1 ? "record was" : "records were"} changed with the choices.`, undo: done.data.undo });
|
|
@@ -12313,7 +12778,7 @@ function FieldEditor(props) {
|
|
|
12313
12778
|
return;
|
|
12314
12779
|
}
|
|
12315
12780
|
(0, import_react66.tableShapeChanged)(tableId);
|
|
12316
|
-
for (const c of undo.cells_back) (0,
|
|
12781
|
+
for (const c of undo.cells_back) (0, import_core8.announceRecordChanged)(c.record_id);
|
|
12317
12782
|
setChoiceList(null);
|
|
12318
12783
|
setChoiceListStart(null);
|
|
12319
12784
|
setRehomed({ said: "Undone. The choices and the records that held them are back as they were.", undo: null });
|
|
@@ -15004,7 +15469,7 @@ function WholeTextDialog({
|
|
|
15004
15469
|
}
|
|
15005
15470
|
|
|
15006
15471
|
// src/pasteValues.ts
|
|
15007
|
-
var
|
|
15472
|
+
var import_core9 = require("@ai-matrx/records/core");
|
|
15008
15473
|
var import_records29 = require("@ai-matrx/records");
|
|
15009
15474
|
function wordForStoredChoice(options, value) {
|
|
15010
15475
|
if (options === void 0 || typeof value !== "string" || value === "") return null;
|
|
@@ -15083,7 +15548,7 @@ function planPastedBlock(args) {
|
|
|
15083
15548
|
});
|
|
15084
15549
|
accepted[key] = judged.value;
|
|
15085
15550
|
}
|
|
15086
|
-
const predicted = (0,
|
|
15551
|
+
const predicted = (0, import_core9.predictValueRefusals)(args.fields, accepted);
|
|
15087
15552
|
for (const refusal4 of predicted) {
|
|
15088
15553
|
const key = refusal4.field_key;
|
|
15089
15554
|
if (key === void 0) continue;
|
|
@@ -15604,9 +16069,17 @@ function useMergedGridControls(args) {
|
|
|
15604
16069
|
const row = rows.find((r) => r.id === rowId);
|
|
15605
16070
|
if (row) args.duplicate(row);
|
|
15606
16071
|
},
|
|
16072
|
+
// ARCHIVE FROM THE ROW MENU NEVER FAILS SILENTLY (Spaces round 33): the confirm opens once the menu
|
|
16073
|
+
// layer has closed — opened from inside the menu's own select callback, the closing menu's focus
|
|
16074
|
+
// return dismissed the dialog the moment it opened (inside a contenteditable host every time), so the
|
|
16075
|
+
// press did nothing. A row the page no longer holds says so.
|
|
15607
16076
|
archiveRow: (rowId) => {
|
|
15608
16077
|
const row = rows.find((r) => r.id === rowId);
|
|
15609
|
-
if (row)
|
|
16078
|
+
if (!row) {
|
|
16079
|
+
notify?.error("This record is no longer on the page. Open it to archive it.");
|
|
16080
|
+
return;
|
|
16081
|
+
}
|
|
16082
|
+
afterMenuLayerCloses(() => args.askDelete(row));
|
|
15610
16083
|
},
|
|
15611
16084
|
...args.onOpenRecord ? { openRecord: (rowId) => args.onOpenRecord?.(rowId) } : {},
|
|
15612
16085
|
...args.onAskWhoChanged ? { askWhoChanged: (columnId2, rowId) => args.onAskWhoChanged?.(columnId2, rowId) } : {},
|
|
@@ -15965,6 +16438,10 @@ function backLinkSentence(column, readers = [], tableName2 = null) {
|
|
|
15965
16438
|
if (readers.length === 0) return base;
|
|
15966
16439
|
return `${readersSentence(readers.length, tableName2)} ${base}`;
|
|
15967
16440
|
}
|
|
16441
|
+
function afterMenuLayerCloses(next) {
|
|
16442
|
+
if (typeof window === "undefined") return next();
|
|
16443
|
+
requestAnimationFrame(() => requestAnimationFrame(next));
|
|
16444
|
+
}
|
|
15968
16445
|
function selectOpenCellText() {
|
|
15969
16446
|
if (typeof window === "undefined") return;
|
|
15970
16447
|
requestAnimationFrame(
|
|
@@ -15988,7 +16465,7 @@ var import_design_system51 = require("@ai-matrx/design-system");
|
|
|
15988
16465
|
// src/RecordForm.tsx
|
|
15989
16466
|
var import_react92 = require("react");
|
|
15990
16467
|
var import_react93 = require("@ai-matrx/records/react");
|
|
15991
|
-
var
|
|
16468
|
+
var import_core11 = require("@ai-matrx/records/core");
|
|
15992
16469
|
var import_design_system50 = require("@ai-matrx/design-system");
|
|
15993
16470
|
var import_text_case6 = require("@ai-matrx/kit/text-case");
|
|
15994
16471
|
|
|
@@ -16001,7 +16478,7 @@ var import_design_system49 = require("@ai-matrx/design-system");
|
|
|
16001
16478
|
var import_react88 = require("react");
|
|
16002
16479
|
var import_react89 = require("@ai-matrx/records/react");
|
|
16003
16480
|
var import_design_system48 = require("@ai-matrx/design-system");
|
|
16004
|
-
var
|
|
16481
|
+
var import_core10 = require("@ai-matrx/records/core");
|
|
16005
16482
|
var import_jsx_runtime55 = require("react/jsx-runtime");
|
|
16006
16483
|
function isEmptyValue(value) {
|
|
16007
16484
|
return value === null || value === void 0 || value === "" || Array.isArray(value) && value.length === 0;
|
|
@@ -16073,7 +16550,7 @@ async function writeStandardRowValues(client, args) {
|
|
|
16073
16550
|
{ schema: config.schema ?? "custom" }
|
|
16074
16551
|
);
|
|
16075
16552
|
if (!old.error) return { ok: true };
|
|
16076
|
-
const error = (0,
|
|
16553
|
+
const error = (0, import_core10.mapPgError)(old.error, "entityValueWrite");
|
|
16077
16554
|
return { ok: false, error: doorIsAbsent(error) && first && first.error.code !== "door_absent" ? first.error : error };
|
|
16078
16555
|
}
|
|
16079
16556
|
function doorIsAbsent(error) {
|
|
@@ -16644,7 +17121,7 @@ function CustomRecordForm({
|
|
|
16644
17121
|
return out;
|
|
16645
17122
|
}, [draft]);
|
|
16646
17123
|
const predicted = (0, import_react92.useMemo)(
|
|
16647
|
-
() => fields.data ? (0,
|
|
17124
|
+
() => fields.data ? (0, import_core11.predictWriteRefusals)({ fields: fields.data, document: document2, ...recordType ? { recordType } : {} }) : [],
|
|
16648
17125
|
[fields.data, document2, recordType]
|
|
16649
17126
|
);
|
|
16650
17127
|
if (fields.error) return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(RefusalNotice, { error: fields.error, className });
|
|
@@ -16694,7 +17171,7 @@ function CustomRecordForm({
|
|
|
16694
17171
|
setEdit({
|
|
16695
17172
|
saving: false,
|
|
16696
17173
|
error: answered2.ok ? null : answered2.error,
|
|
16697
|
-
conflict: answered2.ok ? null : (0,
|
|
17174
|
+
conflict: answered2.ok ? null : (0, import_core11.asWriteConflict)(answered2.error, recordId)
|
|
16698
17175
|
});
|
|
16699
17176
|
const moved = answered2.ok ? answered2.data : null;
|
|
16700
17177
|
if (moved !== null) {
|
|
@@ -16803,7 +17280,7 @@ function FieldRow({
|
|
|
16803
17280
|
}) {
|
|
16804
17281
|
const id = `field-${field2.id}`;
|
|
16805
17282
|
const storedWords = document2?.[field2.key];
|
|
16806
|
-
const whole = typeof storedWords === "string" ? (0,
|
|
17283
|
+
const whole = typeof storedWords === "string" ? (0, import_core11.wholeValueOf)(document2, field2.key) : null;
|
|
16807
17284
|
return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: (0, import_design_system50.cn)("flex min-w-0 flex-col gap-1", whole && "sm:col-span-2"), children: [
|
|
16808
17285
|
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(FieldLabel, { field: field2, htmlFor: id, children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(ProvenanceBadge, { document: document2, fieldKey: field2.key }) }),
|
|
16809
17286
|
whole ? (
|
|
@@ -18852,12 +19329,12 @@ function withOpenRecord(columns, onOpen, nameOf2, place = "end", hrefOf) {
|
|
|
18852
19329
|
// src/ImportWizard.tsx
|
|
18853
19330
|
var import_react105 = require("react");
|
|
18854
19331
|
var import_react106 = require("@ai-matrx/records/react");
|
|
18855
|
-
var
|
|
19332
|
+
var import_core13 = require("@ai-matrx/records/core");
|
|
18856
19333
|
var import_design_system56 = require("@ai-matrx/design-system");
|
|
18857
19334
|
var import_records33 = require("@ai-matrx/records");
|
|
18858
19335
|
|
|
18859
19336
|
// src/importRuleCheck.ts
|
|
18860
|
-
var
|
|
19337
|
+
var import_core12 = require("@ai-matrx/records/core");
|
|
18861
19338
|
function checkImportRules(fields, rows, mapping, choiceOptions, relationNames) {
|
|
18862
19339
|
const byKey = new Map(fields.map((f) => [f.key, f]));
|
|
18863
19340
|
const verdicts = [];
|
|
@@ -18883,7 +19360,7 @@ function checkImportRules(fields, rows, mapping, choiceOptions, relationNames) {
|
|
|
18883
19360
|
if ("unmatchedNames" in meant) return;
|
|
18884
19361
|
if ("refusal" in meant) why = meant.refusal;
|
|
18885
19362
|
else {
|
|
18886
|
-
const predicted = (0,
|
|
19363
|
+
const predicted = (0, import_core12.predictValueRefusals)([field2], { [key]: meant.value }).filter(
|
|
18887
19364
|
(p) => p.field_key === void 0 || p.field_key === key
|
|
18888
19365
|
);
|
|
18889
19366
|
if (predicted.length > 0) why = predicted[0].message;
|
|
@@ -19387,7 +19864,7 @@ function ImportWizard({ tableId, source, onDone, onWrote, className }) {
|
|
|
19387
19864
|
try {
|
|
19388
19865
|
const xlsx = file.name.toLowerCase().endsWith(".xlsx");
|
|
19389
19866
|
const bytes = await file.arrayBuffer();
|
|
19390
|
-
const result = xlsx ? await (0,
|
|
19867
|
+
const result = xlsx ? await (0, import_core13.importXlsx)(bytes) : (0, import_core13.importCsv)(new TextDecoder().decode(bytes));
|
|
19391
19868
|
await planFrom(result, { name: file.name, bytes: file.size, hash: await sha256(bytes), format: xlsx ? "xlsx" : "csv" });
|
|
19392
19869
|
} catch (thrown) {
|
|
19393
19870
|
setProblem(
|
|
@@ -21405,7 +21882,7 @@ function useGroupLabel(fields, groupKey) {
|
|
|
21405
21882
|
// src/gridUndo.tsx
|
|
21406
21883
|
var import_react113 = require("react");
|
|
21407
21884
|
var import_react114 = require("@ai-matrx/records/react");
|
|
21408
|
-
var
|
|
21885
|
+
var import_core14 = require("@ai-matrx/records/core");
|
|
21409
21886
|
var import_design_system58 = require("@ai-matrx/design-system");
|
|
21410
21887
|
var import_data_table12 = require("@ai-matrx/design-system/data-table");
|
|
21411
21888
|
var import_jsx_runtime68 = require("react/jsx-runtime");
|
|
@@ -21499,7 +21976,7 @@ function useGridUndo(args) {
|
|
|
21499
21976
|
}
|
|
21500
21977
|
forget(step2.cells.map((c) => ({ rowId: c.rowId, key: c.key })));
|
|
21501
21978
|
for (const id of /* @__PURE__ */ new Set([...step2.cells.map((c) => c.rowId), ...step2.created ?? [], ...step2.archived ?? []])) {
|
|
21502
|
-
(0,
|
|
21979
|
+
(0, import_core14.announceRecordChanged)(id);
|
|
21503
21980
|
}
|
|
21504
21981
|
setHeld(() => {
|
|
21505
21982
|
let stack = taken.stack;
|
|
@@ -21784,7 +22261,7 @@ function holdKeys() {
|
|
|
21784
22261
|
// src/gridAssist.tsx
|
|
21785
22262
|
var import_clipboard2 = require("@ai-matrx/kit/clipboard");
|
|
21786
22263
|
var import_react116 = require("react");
|
|
21787
|
-
var
|
|
22264
|
+
var import_core15 = require("@ai-matrx/records/core");
|
|
21788
22265
|
var import_workspace = require("@ai-matrx/alchemy/react/workspace");
|
|
21789
22266
|
|
|
21790
22267
|
// src/gridAgentContext.ts
|
|
@@ -21914,7 +22391,7 @@ function useGridAssist(args) {
|
|
|
21914
22391
|
const copyRecordReference = (0, import_react116.useCallback)(
|
|
21915
22392
|
(rowId) => {
|
|
21916
22393
|
void (async () => {
|
|
21917
|
-
const text2 = JSON.stringify({ __kind: (0,
|
|
22394
|
+
const text2 = JSON.stringify({ __kind: (0, import_core15.tableKindSlug)(tableId), _record_id: rowId });
|
|
21918
22395
|
if (!await (0, import_clipboard2.copyText)(text2)) {
|
|
21919
22396
|
say2(false, "This browser did not let the page write to the clipboard.");
|
|
21920
22397
|
return;
|
|
@@ -21970,7 +22447,7 @@ function useGridAssist(args) {
|
|
|
21970
22447
|
if (!row) return;
|
|
21971
22448
|
const document2 = row.document ?? {};
|
|
21972
22449
|
const value = editing.valueFor(row, fieldOf2(key));
|
|
21973
|
-
const pointer = typeof document2[key] === "string" ? (0,
|
|
22450
|
+
const pointer = typeof document2[key] === "string" ? (0, import_core15.wholeValueOf)(document2, key) : null;
|
|
21974
22451
|
setWhole({ rowId, key, rowTitle: titleOf(row), value, pointer });
|
|
21975
22452
|
},
|
|
21976
22453
|
[rowOf, fieldOf2, titleOf, editing]
|
|
@@ -22066,7 +22543,7 @@ function useGridAssist(args) {
|
|
|
22066
22543
|
// src/gridBulk.tsx
|
|
22067
22544
|
var import_react117 = require("react");
|
|
22068
22545
|
var import_react118 = require("@ai-matrx/records/react");
|
|
22069
|
-
var
|
|
22546
|
+
var import_core16 = require("@ai-matrx/records/core");
|
|
22070
22547
|
var import_design_system59 = require("@ai-matrx/design-system");
|
|
22071
22548
|
var import_jsx_runtime70 = require("react/jsx-runtime");
|
|
22072
22549
|
function countOf(n, one, many) {
|
|
@@ -22132,7 +22609,7 @@ function useGridBulk(args) {
|
|
|
22132
22609
|
return null;
|
|
22133
22610
|
}
|
|
22134
22611
|
for (const result of done.data ?? []) if (result.op === "update") versions.wrote(result.id, result.version);
|
|
22135
|
-
for (const change of changes) if ("record_id" in change && change.record_id) (0,
|
|
22612
|
+
for (const change of changes) if ("record_id" in change && change.record_id) (0, import_core16.announceRecordChanged)(change.record_id);
|
|
22136
22613
|
return done.data;
|
|
22137
22614
|
},
|
|
22138
22615
|
[client, tableId, versions, reload]
|
|
@@ -22297,378 +22774,6 @@ var import_react119 = require("react");
|
|
|
22297
22774
|
var import_react120 = require("@ai-matrx/records/react");
|
|
22298
22775
|
var import_records35 = require("@ai-matrx/records");
|
|
22299
22776
|
var import_design_system60 = require("@ai-matrx/design-system");
|
|
22300
|
-
|
|
22301
|
-
// src/viewKeys.ts
|
|
22302
|
-
var STORE_KEEPS_TIMELINE = true;
|
|
22303
|
-
var ALL = ["grid", "kanban", "calendar", "gallery", ...STORE_KEEPS_TIMELINE ? ["timeline"] : [], "list"];
|
|
22304
|
-
var HIDES = ["grid", "gallery", "kanban", "calendar", ...STORE_KEEPS_TIMELINE ? ["timeline"] : [], "list"];
|
|
22305
|
-
var GRIDS = ["grid"];
|
|
22306
|
-
var VIEW_KEYS = [
|
|
22307
|
-
{ path: "layout", shape: "kind", layouts: ALL, writer: "caller" },
|
|
22308
|
-
{ path: "filters", shape: "filter", layouts: ALL, writer: "caller" },
|
|
22309
|
-
{ path: "where", shape: "rule", layouts: ALL, writer: "caller" },
|
|
22310
|
-
{ path: "group_field", shape: "field", layouts: ["kanban", ...STORE_KEEPS_TIMELINE ? ["timeline"] : []], writer: "caller" },
|
|
22311
|
-
{ path: "swimlane_field", shape: "field:lane", layouts: ["kanban"], writer: "caller" },
|
|
22312
|
-
{ path: "collapsed_columns", shape: "values", layouts: ["kanban"], writer: "caller" },
|
|
22313
|
-
{ path: "measure", shape: "field:number", layouts: ["kanban"], writer: "caller" },
|
|
22314
|
-
{ path: "date_field", shape: "field:date", layouts: ["calendar"], writer: "caller" },
|
|
22315
|
-
...STORE_KEEPS_TIMELINE ? [
|
|
22316
|
-
{ path: "start_field", shape: "field:date", layouts: ["timeline"], writer: "caller" },
|
|
22317
|
-
{ path: "end_field", shape: "field:date", layouts: ["calendar", "timeline"], writer: "caller" }
|
|
22318
|
-
] : [],
|
|
22319
|
-
{ path: "image_field", shape: "field", layouts: ["gallery"], writer: "caller" },
|
|
22320
|
-
{ path: "sorts", shape: "sorts", layouts: ALL, writer: "caller" },
|
|
22321
|
-
{ path: "rule_id", shape: "uuid", layouts: ALL, writer: "caller" },
|
|
22322
|
-
{ path: "is_default", shape: "boolean", layouts: ALL, writer: "caller" },
|
|
22323
|
-
{ path: "presentation", shape: "presentation", layouts: ALL, writer: "caller" },
|
|
22324
|
-
{ path: "presentation.style", shape: "style", layouts: ALL, writer: "caller" },
|
|
22325
|
-
{ path: "presentation.formats", shape: "object", layouts: GRIDS, writer: "caller" },
|
|
22326
|
-
{ path: "presentation.frozen", shape: "fields", layouts: GRIDS, writer: "caller" },
|
|
22327
|
-
{ path: "presentation.grouping", shape: "grouping", layouts: ["grid", "gallery", "list"], writer: "caller" },
|
|
22328
|
-
{ path: "presentation.widths", shape: "widths", layouts: GRIDS, writer: "caller" },
|
|
22329
|
-
{ path: "presentation.rowHeight", shape: "row_height", layouts: GRIDS, writer: "caller" },
|
|
22330
|
-
{ path: "presentation.hiddenFields", shape: "fields", layouts: HIDES, writer: "caller" },
|
|
22331
|
-
{ path: "presentation.cardHidden", shape: "fields", layouts: ["kanban", "calendar", ...STORE_KEEPS_TIMELINE ? ["timeline"] : [], "list", "gallery"], writer: "caller" },
|
|
22332
|
-
{ path: "presentation.columnOrder", shape: "fields", layouts: GRIDS, writer: "caller" },
|
|
22333
|
-
{ path: "presentation.gallerySize", shape: "gallery_size", layouts: ["gallery"], writer: "caller" },
|
|
22334
|
-
{ path: "presentation.wrap", shape: "boolean", layouts: GRIDS, writer: "caller" },
|
|
22335
|
-
{ path: "presentation.wrapColumns", shape: "fields", layouts: GRIDS, writer: "caller" },
|
|
22336
|
-
{ path: "presentation.fit", shape: "fit", layouts: GRIDS, writer: "caller" },
|
|
22337
|
-
{ path: "presentation.freezeFirst", shape: "boolean", layouts: GRIDS, writer: "caller" },
|
|
22338
|
-
{ path: "presentation.footer", shape: "footer", layouts: GRIDS, writer: "caller" },
|
|
22339
|
-
{ path: "presentation.summaries", shape: "summaries", layouts: GRIDS, writer: "caller" },
|
|
22340
|
-
{ path: "grid", shape: "grid", layouts: GRIDS, writer: "caller" },
|
|
22341
|
-
{ path: "hidden_fields", shape: "input", layouts: HIDES, writer: "input" },
|
|
22342
|
-
{ path: "table_id", shape: "server", layouts: ALL, writer: "server" },
|
|
22343
|
-
{ path: "order", shape: "server", layouts: GRIDS, writer: "server" },
|
|
22344
|
-
{ path: "moved_from", shape: "server", layouts: ALL, writer: "server" }
|
|
22345
|
-
];
|
|
22346
|
-
var STORE_KEPT_LAYOUTS = ["grid", "kanban", "calendar", "gallery", ...STORE_KEEPS_TIMELINE ? ["timeline"] : [], "list"];
|
|
22347
|
-
function storeKeepsLayout(layout) {
|
|
22348
|
-
return STORE_KEPT_LAYOUTS.includes(layout);
|
|
22349
|
-
}
|
|
22350
|
-
function viewKeysFor(layout) {
|
|
22351
|
-
return VIEW_KEYS.filter((k) => k.layouts.includes(layout)).map((k) => k.path);
|
|
22352
|
-
}
|
|
22353
|
-
var KINDS = STORE_KEPT_LAYOUTS;
|
|
22354
|
-
function viewSettings(definition, rowFilters) {
|
|
22355
|
-
const data = definition ?? {};
|
|
22356
|
-
const text2 = (key) => {
|
|
22357
|
-
const v = data[key];
|
|
22358
|
-
return typeof v === "string" && v !== "" ? v : null;
|
|
22359
|
-
};
|
|
22360
|
-
const layout = String(data["layout"] ?? "grid");
|
|
22361
|
-
const flat = rowFilters ?? (isObject2(data["filters"]) ? data["filters"] : null);
|
|
22362
|
-
const moved = data["moved_from"];
|
|
22363
|
-
return {
|
|
22364
|
-
layout: KINDS.includes(layout) ? layout : "grid",
|
|
22365
|
-
filters: flat && Object.keys(flat).length > 0 ? flat : null,
|
|
22366
|
-
where: isRule(data["where"]) ? data["where"] : null,
|
|
22367
|
-
groupField: text2("group_field"),
|
|
22368
|
-
swimlaneField: text2("swimlane_field"),
|
|
22369
|
-
collapsedColumns: Array.isArray(data["collapsed_columns"]) ? data["collapsed_columns"].filter((v) => ["string", "number", "boolean"].includes(typeof v)).map(String) : [],
|
|
22370
|
-
measure: text2("measure"),
|
|
22371
|
-
dateField: text2("date_field"),
|
|
22372
|
-
startField: text2("start_field"),
|
|
22373
|
-
endField: text2("end_field"),
|
|
22374
|
-
imageField: text2("image_field"),
|
|
22375
|
-
sorts: parseSorts(data["sorts"]),
|
|
22376
|
-
ruleId: text2("rule_id"),
|
|
22377
|
-
isDefault: data["is_default"] === true || data["is_default"] === "true",
|
|
22378
|
-
presentation: parseGridPresentation(data["presentation"]),
|
|
22379
|
-
movedFrom: isObject2(moved) ? moved : null
|
|
22380
|
-
};
|
|
22381
|
-
}
|
|
22382
|
-
function viewSettingsFor(settings, layout) {
|
|
22383
|
-
const reads = new Set(viewKeysFor(layout));
|
|
22384
|
-
const out = { layout: settings.layout };
|
|
22385
|
-
const take = (key, path) => {
|
|
22386
|
-
if (reads.has(path)) out[key] = settings[key];
|
|
22387
|
-
};
|
|
22388
|
-
take("filters", "filters");
|
|
22389
|
-
take("where", "where");
|
|
22390
|
-
take("groupField", "group_field");
|
|
22391
|
-
take("swimlaneField", "swimlane_field");
|
|
22392
|
-
take("collapsedColumns", "collapsed_columns");
|
|
22393
|
-
take("measure", "measure");
|
|
22394
|
-
take("dateField", "date_field");
|
|
22395
|
-
take("startField", "start_field");
|
|
22396
|
-
take("endField", "end_field");
|
|
22397
|
-
take("imageField", "image_field");
|
|
22398
|
-
take("sorts", "sorts");
|
|
22399
|
-
take("ruleId", "rule_id");
|
|
22400
|
-
take("isDefault", "is_default");
|
|
22401
|
-
const p = settings.presentation;
|
|
22402
|
-
const look = {};
|
|
22403
|
-
for (const [key, value] of Object.entries(p)) {
|
|
22404
|
-
if (reads.has(`presentation.${key}`)) look[key] = value;
|
|
22405
|
-
}
|
|
22406
|
-
out.presentation = look;
|
|
22407
|
-
return out;
|
|
22408
|
-
}
|
|
22409
|
-
function viewSettingsPatch(patch) {
|
|
22410
|
-
const out = {};
|
|
22411
|
-
const field2 = (key, path) => {
|
|
22412
|
-
if (patch[key] !== void 0) out[path] = patch[key] || null;
|
|
22413
|
-
};
|
|
22414
|
-
if (patch.layout !== void 0 && storeKeepsLayout(patch.layout)) out["layout"] = patch.layout;
|
|
22415
|
-
field2("groupField", "group_field");
|
|
22416
|
-
field2("swimlaneField", "swimlane_field");
|
|
22417
|
-
field2("measure", "measure");
|
|
22418
|
-
field2("dateField", "date_field");
|
|
22419
|
-
if (STORE_KEEPS_TIMELINE) {
|
|
22420
|
-
field2("startField", "start_field");
|
|
22421
|
-
field2("endField", "end_field");
|
|
22422
|
-
}
|
|
22423
|
-
field2("imageField", "image_field");
|
|
22424
|
-
field2("ruleId", "rule_id");
|
|
22425
|
-
if (patch.collapsedColumns !== void 0) out["collapsed_columns"] = patch.collapsedColumns ?? [];
|
|
22426
|
-
if (patch.sorts !== void 0) out["sorts"] = patch.sorts ?? [];
|
|
22427
|
-
if (patch.where !== void 0) out["where"] = patch.where ?? null;
|
|
22428
|
-
if (patch.isDefault !== void 0) out["is_default"] = patch.isDefault === true;
|
|
22429
|
-
if (patch.presentation !== void 0) {
|
|
22430
|
-
out["presentation"] = !patch.presentation || presentationIsEmpty(patch.presentation) ? null : JSON.parse(presentationDocument(patch.presentation));
|
|
22431
|
-
}
|
|
22432
|
-
return out;
|
|
22433
|
-
}
|
|
22434
|
-
function isObject2(raw) {
|
|
22435
|
-
return Boolean(raw) && typeof raw === "object" && !Array.isArray(raw);
|
|
22436
|
-
}
|
|
22437
|
-
function isRule(raw) {
|
|
22438
|
-
if (!isObject2(raw)) return false;
|
|
22439
|
-
const node = raw;
|
|
22440
|
-
return typeof node.op === "string" && Array.isArray(node.args);
|
|
22441
|
-
}
|
|
22442
|
-
function parseSorts(raw) {
|
|
22443
|
-
let list = raw;
|
|
22444
|
-
if (typeof raw === "string") {
|
|
22445
|
-
try {
|
|
22446
|
-
list = raw.trim() === "" ? [] : JSON.parse(raw);
|
|
22447
|
-
} catch {
|
|
22448
|
-
return [];
|
|
22449
|
-
}
|
|
22450
|
-
}
|
|
22451
|
-
if (!Array.isArray(list)) return [];
|
|
22452
|
-
return list.filter((s) => isObject2(s) && typeof s.field === "string").map((s) => ({ field: s.field, direction: s.direction === "desc" ? "desc" : "asc" }));
|
|
22453
|
-
}
|
|
22454
|
-
|
|
22455
|
-
// src/views.ts
|
|
22456
|
-
var VIEW_LAYOUTS = ["grid", "kanban", "calendar", "gallery", "timeline", "list"];
|
|
22457
|
-
var LAYOUT_LABEL = {
|
|
22458
|
-
grid: "Grid",
|
|
22459
|
-
kanban: "Kanban",
|
|
22460
|
-
calendar: "Calendar",
|
|
22461
|
-
gallery: "Gallery",
|
|
22462
|
-
timeline: "Timeline",
|
|
22463
|
-
list: "List"
|
|
22464
|
-
};
|
|
22465
|
-
function wordsList(words2) {
|
|
22466
|
-
const clean = words2.map((w) => w.trim()).filter((w) => w !== "");
|
|
22467
|
-
if (clean.length <= 1) return clean.join("");
|
|
22468
|
-
return `${clean.slice(0, -1).join(", ")} and ${clean[clean.length - 1]}`;
|
|
22469
|
-
}
|
|
22470
|
-
var VIEW_NEEDS = {
|
|
22471
|
-
grid: null,
|
|
22472
|
-
// A list reads nothing a table can lack: rows, titled, grouped only when the person chooses.
|
|
22473
|
-
list: null,
|
|
22474
|
-
kanban: {
|
|
22475
|
-
kind: "choice",
|
|
22476
|
-
viewKey: "groupField",
|
|
22477
|
-
blocking: true,
|
|
22478
|
-
starter: { label: "Status", type: "select", options: ["To do", "In progress", "Done"] },
|
|
22479
|
-
pick: "Pick the choice column the board's columns come from.",
|
|
22480
|
-
missing: "This table has no choice column to make the board's columns from.",
|
|
22481
|
-
does: (label) => `Make it work adds a ${label} column with the choices below and groups the board by it.`,
|
|
22482
|
-
ask: (label, options) => `Add a choice column called ${label} to this table${options.length > 0 ? ` with the choices ${wordsList(options)}` : ""}, then group the Kanban board by it.`
|
|
22483
|
-
},
|
|
22484
|
-
calendar: {
|
|
22485
|
-
kind: "date",
|
|
22486
|
-
viewKey: "dateField",
|
|
22487
|
-
blocking: true,
|
|
22488
|
-
starter: { label: "Date", type: "datetime" },
|
|
22489
|
-
pick: "Pick the date column the calendar places records by.",
|
|
22490
|
-
missing: "This table has no date column to place records on.",
|
|
22491
|
-
does: (label) => `Make it work adds a ${label} column and lays the calendar out by it.`,
|
|
22492
|
-
ask: (label) => `Add a date column called ${label} to this table, then lay the Calendar out by it.`
|
|
22493
|
-
},
|
|
22494
|
-
gallery: {
|
|
22495
|
-
kind: "file",
|
|
22496
|
-
viewKey: "imageField",
|
|
22497
|
-
blocking: false,
|
|
22498
|
-
starter: { label: "Photo", type: "attachment" },
|
|
22499
|
-
pick: "Pick the file column each card shows as its picture.",
|
|
22500
|
-
missing: "The cards have no picture because this table has no file column.",
|
|
22501
|
-
does: (label) => `Make it work adds a ${label} column and shows it on each card.`,
|
|
22502
|
-
ask: (label) => `Add a file column called ${label} to this table, then show it as the picture on each Gallery card.`
|
|
22503
|
-
},
|
|
22504
|
-
timeline: {
|
|
22505
|
-
kind: "date",
|
|
22506
|
-
viewKey: "dateField",
|
|
22507
|
-
blocking: true,
|
|
22508
|
-
starter: { label: "Start", type: "datetime" },
|
|
22509
|
-
pick: "Pick the date column each bar starts on.",
|
|
22510
|
-
missing: "This table has no date column to place records on.",
|
|
22511
|
-
does: (label) => `Make it work adds a ${label} column and lays the timeline out by it.`,
|
|
22512
|
-
ask: (label) => `Add a date column called ${label} to this table, then lay the Timeline out by it.`
|
|
22513
|
-
}
|
|
22514
|
-
};
|
|
22515
|
-
function freeColumnName(wanted, taken) {
|
|
22516
|
-
const held = new Set(taken.map((t) => t.trim().toLowerCase()));
|
|
22517
|
-
const base = wanted.trim() === "" ? "Column" : wanted.trim();
|
|
22518
|
-
if (!held.has(base.toLowerCase())) return base;
|
|
22519
|
-
for (let n = 2; n < 100; n += 1) {
|
|
22520
|
-
const next = `${base} ${n}`;
|
|
22521
|
-
if (!held.has(next.toLowerCase())) return next;
|
|
22522
|
-
}
|
|
22523
|
-
return base;
|
|
22524
|
-
}
|
|
22525
|
-
function viewOrderOf(definition) {
|
|
22526
|
-
const raw = definition?.["order"];
|
|
22527
|
-
return raw === "manual" ? "manual" : raw === "sorted" ? "sorted" : null;
|
|
22528
|
-
}
|
|
22529
|
-
function defaultViewOf(views) {
|
|
22530
|
-
return views.find((v) => v.isDefault);
|
|
22531
|
-
}
|
|
22532
|
-
var LAYOUT_FIELD_KIND = {
|
|
22533
|
-
grid: null,
|
|
22534
|
-
kanban: "choice",
|
|
22535
|
-
calendar: "date",
|
|
22536
|
-
gallery: "file",
|
|
22537
|
-
timeline: "date",
|
|
22538
|
-
list: null
|
|
22539
|
-
};
|
|
22540
|
-
var PAGE_VIEWS = [...VIEW_LAYOUTS, "dashboards", "archived"];
|
|
22541
|
-
var PAGE_VIEW_LABEL = {
|
|
22542
|
-
...LAYOUT_LABEL,
|
|
22543
|
-
dashboards: "Dashboards",
|
|
22544
|
-
archived: "Archived"
|
|
22545
|
-
};
|
|
22546
|
-
var PAGE_VIEW_SPELLINGS = {
|
|
22547
|
-
grid: "grid",
|
|
22548
|
-
table: "grid",
|
|
22549
|
-
rows: "grid",
|
|
22550
|
-
list: "list",
|
|
22551
|
-
kanban: "kanban",
|
|
22552
|
-
board: "kanban",
|
|
22553
|
-
pipeline: "kanban",
|
|
22554
|
-
calendar: "calendar",
|
|
22555
|
-
month: "calendar",
|
|
22556
|
-
schedule: "calendar",
|
|
22557
|
-
gallery: "gallery",
|
|
22558
|
-
cards: "gallery",
|
|
22559
|
-
timeline: "timeline",
|
|
22560
|
-
gantt: "timeline",
|
|
22561
|
-
dashboards: "dashboards",
|
|
22562
|
-
dashboard: "dashboards",
|
|
22563
|
-
charts: "dashboards",
|
|
22564
|
-
archived: "archived",
|
|
22565
|
-
archive: "archived",
|
|
22566
|
-
// The grid's row action says "Delete" and the store soft-deletes, so the word
|
|
22567
|
-
// a person types is as likely to be the one the button used as the one this
|
|
22568
|
-
// view is called. Both land in the same place; neither dies.
|
|
22569
|
-
deleted: "archived",
|
|
22570
|
-
trash: "archived",
|
|
22571
|
-
removed: "archived"
|
|
22572
|
-
};
|
|
22573
|
-
function pageViewFromParam(raw) {
|
|
22574
|
-
if (typeof raw !== "string") return null;
|
|
22575
|
-
const token = raw.trim().toLowerCase();
|
|
22576
|
-
if (token === "") return null;
|
|
22577
|
-
return PAGE_VIEW_SPELLINGS[token] ?? null;
|
|
22578
|
-
}
|
|
22579
|
-
function unknownViewLine(raw) {
|
|
22580
|
-
return `The link asked for a view called \u201C${raw}\u201D, which this table has no view for, so you are looking at ${PAGE_VIEW_LABEL.grid}. The views this table has are ${PAGE_VIEWS.map((v) => PAGE_VIEW_LABEL[v]).join(", ")} \u2014 pick one above and the address follows it.`;
|
|
22581
|
-
}
|
|
22582
|
-
function viewDocument(spec) {
|
|
22583
|
-
const out = {
|
|
22584
|
-
// A layout the store does not keep yet is not sent: the view is saved as a grid (`STORE_KEPT_LAYOUTS`).
|
|
22585
|
-
layout: storeKeepsLayout(spec.layout) ? spec.layout : "grid",
|
|
22586
|
-
sorts: spec.sorts ?? [],
|
|
22587
|
-
is_default: spec.isDefault === true
|
|
22588
|
-
};
|
|
22589
|
-
if (spec.groupField) out["group_field"] = spec.groupField;
|
|
22590
|
-
if (spec.swimlaneField) out["swimlane_field"] = spec.swimlaneField;
|
|
22591
|
-
if (spec.collapsedColumns && spec.collapsedColumns.length > 0) out["collapsed_columns"] = spec.collapsedColumns;
|
|
22592
|
-
if (spec.measure) out["measure"] = spec.measure;
|
|
22593
|
-
if (spec.dateField) out["date_field"] = spec.dateField;
|
|
22594
|
-
if (STORE_KEEPS_TIMELINE && spec.startField) out["start_field"] = spec.startField;
|
|
22595
|
-
if (STORE_KEEPS_TIMELINE && spec.endField) out["end_field"] = spec.endField;
|
|
22596
|
-
if (spec.imageField) out["image_field"] = spec.imageField;
|
|
22597
|
-
if (spec.ruleId) out["rule_id"] = spec.ruleId;
|
|
22598
|
-
if (spec.where) out["where"] = spec.where;
|
|
22599
|
-
if (spec.presentation && !presentationIsEmpty(spec.presentation)) {
|
|
22600
|
-
out["presentation"] = JSON.parse(presentationDocument(spec.presentation));
|
|
22601
|
-
}
|
|
22602
|
-
return out;
|
|
22603
|
-
}
|
|
22604
|
-
function viewFromRow(row) {
|
|
22605
|
-
const data = row.definition ?? {};
|
|
22606
|
-
const k = viewSettings(data, row.filters && Object.keys(row.filters).length > 0 ? row.filters : null);
|
|
22607
|
-
const tableFromDefinition = typeof data["table_id"] === "string" && data["table_id"] !== "" ? data["table_id"] : null;
|
|
22608
|
-
return {
|
|
22609
|
-
id: row.view_id,
|
|
22610
|
-
name: row.name || "Untitled view",
|
|
22611
|
-
subject: row.table_id ?? tableFromDefinition ?? "",
|
|
22612
|
-
layout: k.layout,
|
|
22613
|
-
groupField: k.groupField,
|
|
22614
|
-
swimlaneField: k.swimlaneField,
|
|
22615
|
-
collapsedColumns: k.collapsedColumns,
|
|
22616
|
-
measure: k.measure,
|
|
22617
|
-
dateField: k.dateField,
|
|
22618
|
-
startField: k.startField,
|
|
22619
|
-
endField: k.endField,
|
|
22620
|
-
imageField: k.imageField,
|
|
22621
|
-
sorts: k.sorts,
|
|
22622
|
-
order: viewOrderOf(data),
|
|
22623
|
-
ruleId: k.ruleId,
|
|
22624
|
-
...k.filters ? { filters: k.filters } : {},
|
|
22625
|
-
where: k.where,
|
|
22626
|
-
// The older table's own default view, carried in by the mover, IS this table's default —
|
|
22627
|
-
// the mover wrote the row's column, which `custom.views` does not return. Read as anything
|
|
22628
|
-
// else, the page would seed a second "All records" beside it and open on that.
|
|
22629
|
-
isDefault: k.isDefault || k.movedFrom?.["kind"] === "default_view",
|
|
22630
|
-
presentation: k.presentation,
|
|
22631
|
-
movedFrom: k.movedFrom
|
|
22632
|
-
};
|
|
22633
|
-
}
|
|
22634
|
-
async function declareView(client, spec) {
|
|
22635
|
-
return client.viewDeclare({
|
|
22636
|
-
table_id: spec.subject,
|
|
22637
|
-
spec: {
|
|
22638
|
-
name: spec.name,
|
|
22639
|
-
...spec.filters ? { filters: spec.filters } : {},
|
|
22640
|
-
definition: viewDocument(spec)
|
|
22641
|
-
}
|
|
22642
|
-
});
|
|
22643
|
-
}
|
|
22644
|
-
async function saveViewPatch(client, tableId, viewId, patch) {
|
|
22645
|
-
const definition = viewPatchDocument(patch);
|
|
22646
|
-
const renamed = patch.name !== void 0 && patch.name.trim() !== "";
|
|
22647
|
-
const refiltered = patch.filters !== void 0;
|
|
22648
|
-
return client.viewDeclare({
|
|
22649
|
-
table_id: tableId,
|
|
22650
|
-
spec: {
|
|
22651
|
-
view_id: viewId,
|
|
22652
|
-
...renamed ? { name: patch.name.trim() } : {},
|
|
22653
|
-
...refiltered ? { filters: patch.filters ?? null } : {},
|
|
22654
|
-
definition
|
|
22655
|
-
}
|
|
22656
|
-
});
|
|
22657
|
-
}
|
|
22658
|
-
function viewPatchDocument(patch) {
|
|
22659
|
-
const { name: _name, subject: _subject, filters: _filters, ...keys } = patch;
|
|
22660
|
-
return viewSettingsPatch(keys);
|
|
22661
|
-
}
|
|
22662
|
-
function viewPatchFor(view, patch) {
|
|
22663
|
-
if (!view.isDefault) return patch;
|
|
22664
|
-
const { layout: _layout, isDefault: _isDefault, ...kept } = patch;
|
|
22665
|
-
return kept;
|
|
22666
|
-
}
|
|
22667
|
-
async function designateView(client, tableId, viewId, layout) {
|
|
22668
|
-
return client.viewDesignate({ table_id: tableId, view_id: viewId, layout });
|
|
22669
|
-
}
|
|
22670
|
-
|
|
22671
|
-
// src/handOrder.tsx
|
|
22672
22777
|
var import_jsx_runtime71 = require("react/jsx-runtime");
|
|
22673
22778
|
function sortArrow(direction) {
|
|
22674
22779
|
return direction === "asc" ? "\u2191" : "\u2193";
|
|
@@ -23641,7 +23746,7 @@ function GridBody({
|
|
|
23641
23746
|
}))
|
|
23642
23747
|
);
|
|
23643
23748
|
editing.forget(cells);
|
|
23644
|
-
for (const u of updates) (0,
|
|
23749
|
+
for (const u of updates) (0, import_core17.announceRecordChanged)(u.row.recordId);
|
|
23645
23750
|
const lines = updates.length + creates.length;
|
|
23646
23751
|
undo.push({ label: `Pasted ${lines} ${lines === 1 ? "row" : "rows"}`, cells, created });
|
|
23647
23752
|
const expected = [
|
|
@@ -25114,10 +25219,10 @@ var import_react_query = require("@tanstack/react-query");
|
|
|
25114
25219
|
var import_react125 = require("@ai-matrx/records/data/react");
|
|
25115
25220
|
|
|
25116
25221
|
// ../entity-data/src/core/client.ts
|
|
25117
|
-
var
|
|
25222
|
+
var import_core19 = require("@ai-matrx/records/core");
|
|
25118
25223
|
|
|
25119
25224
|
// ../entity-data/src/core/errors.ts
|
|
25120
|
-
var
|
|
25225
|
+
var import_core18 = require("@ai-matrx/records/core");
|
|
25121
25226
|
var ENTITY_REFUSALS = {
|
|
25122
25227
|
/** conflict_version: somebody else's write won. */
|
|
25123
25228
|
MX001: "stale_write",
|
|
@@ -25141,7 +25246,7 @@ var ENTITY_REFUSALS = {
|
|
|
25141
25246
|
MX016: "invalid_argument"
|
|
25142
25247
|
};
|
|
25143
25248
|
function mapEntityError(error, where) {
|
|
25144
|
-
const mapped = (0,
|
|
25249
|
+
const mapped = (0, import_core18.mapPgError)(error, where);
|
|
25145
25250
|
const state = mapped.sqlstate;
|
|
25146
25251
|
if (state && /^MX\d{3}$/.test(state)) {
|
|
25147
25252
|
const code = ENTITY_REFUSALS[state];
|
|
@@ -25163,7 +25268,7 @@ function refusal2(code, message, hint) {
|
|
|
25163
25268
|
var OP_ID_HEADER = "x-matrx-op-id";
|
|
25164
25269
|
var ENTITY_DOOR_SCHEMA = "platform";
|
|
25165
25270
|
function createEntityClient(options) {
|
|
25166
|
-
const source = (0,
|
|
25271
|
+
const source = (0, import_core19.asRecordsDataSource)(options.dataSource ?? options.supabase);
|
|
25167
25272
|
let warnedHeaderless = false;
|
|
25168
25273
|
function withHeaders(pending, headers) {
|
|
25169
25274
|
if (!headers) return;
|
|
@@ -26086,7 +26191,7 @@ function ConnectedRecordsTableCard({
|
|
|
26086
26191
|
var import_download2 = require("@ai-matrx/kit/download");
|
|
26087
26192
|
var import_react130 = require("react");
|
|
26088
26193
|
var import_react131 = require("@ai-matrx/records/react");
|
|
26089
|
-
var
|
|
26194
|
+
var import_core20 = require("@ai-matrx/records/core");
|
|
26090
26195
|
|
|
26091
26196
|
// src/viewExport.ts
|
|
26092
26197
|
var import_format5 = require("@ai-matrx/kit/format");
|
|
@@ -26153,7 +26258,7 @@ function toRows(fields, records, labels) {
|
|
|
26153
26258
|
absent_reason: envelope?.absent ?? null,
|
|
26154
26259
|
// A VALUE KEPT AS A FILE carries its pointer, so the export writes the whole text
|
|
26155
26260
|
// (`withWholeValues`), never the first words passed off as the value.
|
|
26156
|
-
source: (0,
|
|
26261
|
+
source: (0, import_core20.wholeValueOf)(document2, field2.key)
|
|
26157
26262
|
};
|
|
26158
26263
|
}
|
|
26159
26264
|
return row;
|
|
@@ -26184,7 +26289,7 @@ async function rowsForFile(args) {
|
|
|
26184
26289
|
);
|
|
26185
26290
|
const lookup = ((field2, id) => labels(field2, id) ?? learned.get(`${field2.id}:${id}`) ?? null);
|
|
26186
26291
|
const read = host.readFileText;
|
|
26187
|
-
return (0,
|
|
26292
|
+
return (0, import_core20.withWholeValues)(toRows(all, records, lookup), read ? (fileId) => read({ fileId }) : null);
|
|
26188
26293
|
}
|
|
26189
26294
|
function ExportMenu({ tableId, rows, label, className, view }) {
|
|
26190
26295
|
const client = (0, import_react131.useRecordsClient)();
|
|
@@ -26223,7 +26328,7 @@ function ExportMenu({ tableId, rows, label, className, view }) {
|
|
|
26223
26328
|
{
|
|
26224
26329
|
size: "sm",
|
|
26225
26330
|
variant: "outline",
|
|
26226
|
-
onClick: () => void exported().then((rows2) => download(`${name}.csv`, "text/csv;charset=utf-8", (0,
|
|
26331
|
+
onClick: () => void exported().then((rows2) => download(`${name}.csv`, "text/csv;charset=utf-8", (0, import_core20.exportCsv)(columns, rows2))).catch(
|
|
26227
26332
|
(thrown) => setFailure(refusalFromThrown(thrown, "The CSV could not be written.", "Try again in a moment."))
|
|
26228
26333
|
),
|
|
26229
26334
|
children: "CSV"
|
|
@@ -26244,7 +26349,7 @@ function ExportMenu({ tableId, rows, label, className, view }) {
|
|
|
26244
26349
|
);
|
|
26245
26350
|
setFailure(null);
|
|
26246
26351
|
try {
|
|
26247
|
-
exported().then((rows2) => (0,
|
|
26352
|
+
exported().then((rows2) => (0, import_core20.exportXlsx)(columns, rows2, name)).then(
|
|
26248
26353
|
(bytes) => download(
|
|
26249
26354
|
`${name}.xlsx`,
|
|
26250
26355
|
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
@@ -26265,7 +26370,7 @@ function ExportMenu({ tableId, rows, label, className, view }) {
|
|
|
26265
26370
|
sourceId: `records:${tableId}`,
|
|
26266
26371
|
size: "xs",
|
|
26267
26372
|
json: () => records.map((r) => r.document),
|
|
26268
|
-
human: () => (0,
|
|
26373
|
+
human: () => (0, import_core20.exportCsv)(columns, toRows(columns, records, labels))
|
|
26269
26374
|
}
|
|
26270
26375
|
),
|
|
26271
26376
|
viewHeld && "rows" in viewHeld && viewHeld.cut ? /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("span", { className: "text-xs text-muted-foreground", children: cutWords(viewHeld.rows.length) }) : null,
|
|
@@ -26385,7 +26490,7 @@ var import_design_system74 = require("@ai-matrx/design-system");
|
|
|
26385
26490
|
// src/TablesHome.tsx
|
|
26386
26491
|
var import_react144 = require("react");
|
|
26387
26492
|
var import_react145 = require("@ai-matrx/records/react");
|
|
26388
|
-
var
|
|
26493
|
+
var import_core21 = require("@ai-matrx/records/core");
|
|
26389
26494
|
var import_records43 = require("@ai-matrx/records");
|
|
26390
26495
|
var import_design_system73 = require("@ai-matrx/design-system");
|
|
26391
26496
|
|
|
@@ -28121,7 +28226,7 @@ function TablesHome({ onOpenTable, organizationName, makingOnly = false, askedBy
|
|
|
28121
28226
|
};
|
|
28122
28227
|
}, [client]);
|
|
28123
28228
|
const listed = facts.phase === "read" ? (0, import_records43.withTablePlacement)(
|
|
28124
|
-
(0,
|
|
28229
|
+
(0, import_core21.withTableFacts)(tables.data ?? [], facts.rows, me),
|
|
28125
28230
|
facts.rows
|
|
28126
28231
|
) : tables.data ?? [];
|
|
28127
28232
|
const [showEverything, setShowEverything] = (0, import_react144.useState)(false);
|
|
@@ -30696,95 +30801,6 @@ function useSystemTable(spec) {
|
|
|
30696
30801
|
return state;
|
|
30697
30802
|
}
|
|
30698
30803
|
|
|
30699
|
-
// src/viewLook.ts
|
|
30700
|
-
var LOOK_KEYS = [
|
|
30701
|
-
"layout",
|
|
30702
|
-
"groupField",
|
|
30703
|
-
"swimlaneField",
|
|
30704
|
-
"collapsedColumns",
|
|
30705
|
-
"measure",
|
|
30706
|
-
"dateField",
|
|
30707
|
-
"startField",
|
|
30708
|
-
"endField",
|
|
30709
|
-
"imageField",
|
|
30710
|
-
"sorts",
|
|
30711
|
-
"where",
|
|
30712
|
-
"presentation"
|
|
30713
|
-
];
|
|
30714
|
-
function lookPart(patch) {
|
|
30715
|
-
const out = {};
|
|
30716
|
-
for (const key of LOOK_KEYS) {
|
|
30717
|
-
if (patch[key] !== void 0) out[key] = patch[key];
|
|
30718
|
-
}
|
|
30719
|
-
return out;
|
|
30720
|
-
}
|
|
30721
|
-
function lookDocument(look) {
|
|
30722
|
-
return viewSettingsPatch(look);
|
|
30723
|
-
}
|
|
30724
|
-
function lookFromDocument(doc) {
|
|
30725
|
-
const data = doc ?? {};
|
|
30726
|
-
const read = viewSettings(data);
|
|
30727
|
-
const out = {};
|
|
30728
|
-
const has = (key) => Object.prototype.hasOwnProperty.call(data, key);
|
|
30729
|
-
if (has("layout") && VIEW_LAYOUTS.includes(String(data["layout"]))) {
|
|
30730
|
-
out.layout = data["layout"];
|
|
30731
|
-
}
|
|
30732
|
-
if (has("group_field")) out.groupField = read.groupField;
|
|
30733
|
-
if (has("swimlane_field")) out.swimlaneField = read.swimlaneField;
|
|
30734
|
-
if (has("collapsed_columns")) out.collapsedColumns = read.collapsedColumns;
|
|
30735
|
-
if (has("measure")) out.measure = read.measure;
|
|
30736
|
-
if (has("date_field")) out.dateField = read.dateField;
|
|
30737
|
-
if (has("start_field")) out.startField = read.startField;
|
|
30738
|
-
if (has("end_field")) out.endField = read.endField;
|
|
30739
|
-
if (has("image_field")) out.imageField = read.imageField;
|
|
30740
|
-
if (has("sorts")) out.sorts = read.sorts;
|
|
30741
|
-
if (has("where")) out.where = read.where;
|
|
30742
|
-
if (has("presentation")) out.presentation = parseGridPresentation(data["presentation"]);
|
|
30743
|
-
return out;
|
|
30744
|
-
}
|
|
30745
|
-
function applyLook(view, look) {
|
|
30746
|
-
if (!look) return view;
|
|
30747
|
-
return { ...view, ...look };
|
|
30748
|
-
}
|
|
30749
|
-
function lookDiffers(view, look) {
|
|
30750
|
-
if (!look) return false;
|
|
30751
|
-
const shown4 = applyLook(view, look);
|
|
30752
|
-
return LOOK_KEYS.some(
|
|
30753
|
-
(key) => look[key] !== void 0 && JSON.stringify(shown4[key] ?? null) !== JSON.stringify(view[key] ?? null)
|
|
30754
|
-
);
|
|
30755
|
-
}
|
|
30756
|
-
function saveToViewPlan(view, look) {
|
|
30757
|
-
const patch = viewPatchFor(view, look);
|
|
30758
|
-
const left = {};
|
|
30759
|
-
if (look.layout !== void 0 && patch.layout === void 0 && look.layout !== view.layout) left.layout = look.layout;
|
|
30760
|
-
return { patch, left: Object.keys(left).length > 0 ? left : null };
|
|
30761
|
-
}
|
|
30762
|
-
async function readLooks(client, tableId) {
|
|
30763
|
-
const answered = await client.viewLookRead({ table_id: tableId });
|
|
30764
|
-
if (!answered.ok) return answered;
|
|
30765
|
-
const out = {};
|
|
30766
|
-
for (const [viewId, row] of Object.entries(answered.data ?? {})) {
|
|
30767
|
-
out[viewId] = lookFromDocument(row?.look ?? null);
|
|
30768
|
-
}
|
|
30769
|
-
return { ok: true, data: out };
|
|
30770
|
-
}
|
|
30771
|
-
async function keepLook(client, tableId, viewId, look) {
|
|
30772
|
-
const doc = look ? lookDocument(look) : null;
|
|
30773
|
-
return client.viewLookSet({ table_id: tableId, view_id: viewId, look: doc && Object.keys(doc).length > 0 ? doc : null });
|
|
30774
|
-
}
|
|
30775
|
-
var LOOK_WORDS = {
|
|
30776
|
-
/** The reason, for a tooltip or a screen reader — never a line on the page (interface-text). */
|
|
30777
|
-
yours: "You changed how this view looks. Only you see it.",
|
|
30778
|
-
/** The visible label for the same fact. */
|
|
30779
|
-
yoursLabel: "Only you see this",
|
|
30780
|
-
saveToView: "Save to view",
|
|
30781
|
-
saveAsNew: "Save as new view",
|
|
30782
|
-
reset: "Reset to view",
|
|
30783
|
-
/** The one button your look's doors fold into when the toolbar row has no room for three. */
|
|
30784
|
-
folded: "Your look",
|
|
30785
|
-
newName: "Name for the new view"
|
|
30786
|
-
};
|
|
30787
|
-
|
|
30788
30804
|
// src/ViewSwitcher.tsx
|
|
30789
30805
|
var import_react190 = require("react");
|
|
30790
30806
|
var import_react191 = require("@ai-matrx/records/react");
|
|
@@ -35498,16 +35514,20 @@ function seedIsSatisfied(seed, views) {
|
|
|
35498
35514
|
if (views.some((v) => v.name === seed.name)) return true;
|
|
35499
35515
|
return seed.isDefault === true && views.some((v) => v.isDefault);
|
|
35500
35516
|
}
|
|
35501
|
-
function ViewBar({ tableId, activeViewId, onActiveView, seed, settings, onViews, className }) {
|
|
35517
|
+
function ViewBar({ tableId, activeViewId, onActiveView, seed, settings, onViews, initialViews, className }) {
|
|
35502
35518
|
const client = (0, import_react198.useRecordsClient)();
|
|
35503
35519
|
const claimSeed = useSeedGuard();
|
|
35504
35520
|
const table = (0, import_react199.useTable)(tableId);
|
|
35505
35521
|
const rights = useTableRights(table.data);
|
|
35506
35522
|
const notify = useRecordsUi().notify;
|
|
35507
|
-
const [views, setViews] = (0, import_react197.useState)(null);
|
|
35523
|
+
const [views, setViews] = (0, import_react197.useState)(() => initialViews ?? null);
|
|
35508
35524
|
const [error, setError] = (0, import_react197.useState)(null);
|
|
35509
35525
|
const [unavailable, setUnavailable] = (0, import_react197.useState)(false);
|
|
35510
|
-
const [active, setActive] = (0, import_react197.useState)(
|
|
35526
|
+
const [active, setActive] = (0, import_react197.useState)(() => {
|
|
35527
|
+
if (!initialViews || initialViews.length === 0) return activeViewId ?? null;
|
|
35528
|
+
return (initialViews.find((v) => v.id === activeViewId) ?? defaultViewOf(initialViews) ?? initialViews[0]).id;
|
|
35529
|
+
});
|
|
35530
|
+
const readOnMount = (0, import_react197.useRef)(initialViews === void 0);
|
|
35511
35531
|
const [naming, setNaming] = (0, import_react197.useState)(false);
|
|
35512
35532
|
const [draftName, setDraftName] = (0, import_react197.useState)("");
|
|
35513
35533
|
const [open, setOpen] = (0, import_react197.useState)(false);
|
|
@@ -35554,6 +35574,10 @@ function ViewBar({ tableId, activeViewId, onActiveView, seed, settings, onViews,
|
|
|
35554
35574
|
onViews?.(mine);
|
|
35555
35575
|
}, [client, readViews, tableId, seedKey]);
|
|
35556
35576
|
(0, import_react197.useEffect)(() => {
|
|
35577
|
+
if (!readOnMount.current) {
|
|
35578
|
+
readOnMount.current = true;
|
|
35579
|
+
return;
|
|
35580
|
+
}
|
|
35557
35581
|
void load();
|
|
35558
35582
|
}, [load]);
|
|
35559
35583
|
(0, import_react197.useEffect)(() => {
|
|
@@ -38514,7 +38538,7 @@ var import_design_system105 = require("@ai-matrx/design-system");
|
|
|
38514
38538
|
var import_react217 = require("react");
|
|
38515
38539
|
var import_recharts = require("recharts");
|
|
38516
38540
|
var import_records51 = require("@ai-matrx/records");
|
|
38517
|
-
var
|
|
38541
|
+
var import_core22 = require("@ai-matrx/records/core");
|
|
38518
38542
|
var import_design_system104 = require("@ai-matrx/design-system");
|
|
38519
38543
|
var import_format10 = require("@ai-matrx/kit/format");
|
|
38520
38544
|
|
|
@@ -38976,7 +39000,7 @@ function pretty(n) {
|
|
|
38976
39000
|
return Number.isInteger(n) ? n.toLocaleString() : n.toLocaleString(void 0, { maximumFractionDigits: 2 });
|
|
38977
39001
|
}
|
|
38978
39002
|
function asRefusal2(block) {
|
|
38979
|
-
return (0,
|
|
39003
|
+
return (0, import_core22.mapPgError)(
|
|
38980
39004
|
{
|
|
38981
39005
|
message: block.refused ?? "",
|
|
38982
39006
|
...block.sqlstate ? { code: block.sqlstate } : {}
|
|
@@ -41884,7 +41908,7 @@ function SubscriptionsPanel({ tableId, activeRuleId, className }) {
|
|
|
41884
41908
|
var import_clipboard9 = require("@ai-matrx/kit/clipboard");
|
|
41885
41909
|
var import_design_system117 = require("@ai-matrx/design-system");
|
|
41886
41910
|
var import_react235 = require("react");
|
|
41887
|
-
var
|
|
41911
|
+
var import_core23 = require("@dnd-kit/core");
|
|
41888
41912
|
var import_sortable = require("@dnd-kit/sortable");
|
|
41889
41913
|
var import_utilities = require("@dnd-kit/utilities");
|
|
41890
41914
|
var import_react236 = require("@ai-matrx/records/react");
|
|
@@ -43511,9 +43535,9 @@ function QuestionList({
|
|
|
43511
43535
|
onQuestions,
|
|
43512
43536
|
onQuestion
|
|
43513
43537
|
}) {
|
|
43514
|
-
const sensors = (0,
|
|
43515
|
-
(0,
|
|
43516
|
-
(0,
|
|
43538
|
+
const sensors = (0, import_core23.useSensors)(
|
|
43539
|
+
(0, import_core23.useSensor)(import_core23.PointerSensor, { activationConstraint: { distance: 4 } }),
|
|
43540
|
+
(0, import_core23.useSensor)(import_core23.KeyboardSensor, { coordinateGetter: import_sortable.sortableKeyboardCoordinates })
|
|
43517
43541
|
);
|
|
43518
43542
|
const askable = askableFields([...fields]);
|
|
43519
43543
|
const unasked = askable.filter((f) => !draft.questions.some((q) => q.field === f.key));
|
|
@@ -43535,7 +43559,7 @@ function QuestionList({
|
|
|
43535
43559
|
/* @__PURE__ */ (0, import_jsx_runtime133.jsx)("span", { className: "font-medium text-foreground", children: "Questions" }),
|
|
43536
43560
|
/* @__PURE__ */ (0, import_jsx_runtime133.jsx)("span", { className: "tabular-nums", children: draft.questions.length })
|
|
43537
43561
|
] }),
|
|
43538
|
-
/* @__PURE__ */ (0, import_jsx_runtime133.jsx)(
|
|
43562
|
+
/* @__PURE__ */ (0, import_jsx_runtime133.jsx)(import_core23.DndContext, { sensors, collisionDetection: import_core23.closestCenter, onDragEnd: dragEnd, children: /* @__PURE__ */ (0, import_jsx_runtime133.jsx)(import_sortable.SortableContext, { items: draft.questions.map((q) => q.field), strategy: import_sortable.verticalListSortingStrategy, children: draft.questions.map((question, index) => /* @__PURE__ */ (0, import_jsx_runtime133.jsx)(
|
|
43539
43563
|
QuestionRow,
|
|
43540
43564
|
{
|
|
43541
43565
|
index,
|
|
@@ -44531,7 +44555,7 @@ var import_react253 = require("@ai-matrx/records/react");
|
|
|
44531
44555
|
var import_design_system126 = require("@ai-matrx/design-system");
|
|
44532
44556
|
|
|
44533
44557
|
// src/DashboardGrid.tsx
|
|
44534
|
-
var
|
|
44558
|
+
var import_core24 = require("@dnd-kit/core");
|
|
44535
44559
|
var import_sortable2 = require("@dnd-kit/sortable");
|
|
44536
44560
|
var import_utilities2 = require("@dnd-kit/utilities");
|
|
44537
44561
|
var import_design_system123 = require("@ai-matrx/design-system");
|
|
@@ -44587,7 +44611,7 @@ function withBlockIds(blocks) {
|
|
|
44587
44611
|
// src/DashboardGrid.tsx
|
|
44588
44612
|
var import_jsx_runtime138 = require("react/jsx-runtime");
|
|
44589
44613
|
var dashboardCollision = (args) => {
|
|
44590
|
-
const under = (0,
|
|
44614
|
+
const under = (0, import_core24.pointerWithin)(args);
|
|
44591
44615
|
if (under.length > 0) return under;
|
|
44592
44616
|
const at = args.collisionRect;
|
|
44593
44617
|
return args.droppableContainers.flatMap((container) => {
|
|
@@ -44597,9 +44621,9 @@ var dashboardCollision = (args) => {
|
|
|
44597
44621
|
}).sort((a, b) => a.data.value - b.data.value);
|
|
44598
44622
|
};
|
|
44599
44623
|
function DashboardGrid({ items, arranging, onMove, onSpan }) {
|
|
44600
|
-
const sensors = (0,
|
|
44601
|
-
(0,
|
|
44602
|
-
(0,
|
|
44624
|
+
const sensors = (0, import_core24.useSensors)(
|
|
44625
|
+
(0, import_core24.useSensor)(import_core24.PointerSensor, { activationConstraint: { distance: 4 } }),
|
|
44626
|
+
(0, import_core24.useSensor)(import_core24.KeyboardSensor, { coordinateGetter: import_sortable2.sortableKeyboardCoordinates })
|
|
44603
44627
|
);
|
|
44604
44628
|
const ids = items.map((item) => item.id);
|
|
44605
44629
|
function dragEnd(event) {
|
|
@@ -44609,7 +44633,7 @@ function DashboardGrid({ items, arranging, onMove, onSpan }) {
|
|
|
44609
44633
|
}
|
|
44610
44634
|
const grid = /* @__PURE__ */ (0, import_jsx_runtime138.jsx)("div", { className: "grid grid-cols-1 gap-2 sm:grid-cols-12", children: items.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime138.jsx)(GridCell2, { item, index, arranging, onSpan }, item.id)) });
|
|
44611
44635
|
if (!arranging) return grid;
|
|
44612
|
-
return /* @__PURE__ */ (0, import_jsx_runtime138.jsx)(
|
|
44636
|
+
return /* @__PURE__ */ (0, import_jsx_runtime138.jsx)(import_core24.DndContext, { sensors, collisionDetection: dashboardCollision, onDragEnd: dragEnd, children: /* @__PURE__ */ (0, import_jsx_runtime138.jsx)(import_sortable2.SortableContext, { items: ids, strategy: import_sortable2.rectSortingStrategy, children: grid }) });
|
|
44613
44637
|
}
|
|
44614
44638
|
function GridCell2({
|
|
44615
44639
|
item,
|
|
@@ -45822,7 +45846,7 @@ var import_react255 = require("@ai-matrx/records/react");
|
|
|
45822
45846
|
|
|
45823
45847
|
// src/question.ts
|
|
45824
45848
|
var import_records59 = require("@ai-matrx/records");
|
|
45825
|
-
var
|
|
45849
|
+
var import_core25 = require("@ai-matrx/records/core");
|
|
45826
45850
|
var QUESTION_OPS = ["count", "sum", "avg", "min", "max"];
|
|
45827
45851
|
var QUESTION_LIMIT_DEFAULT = 25;
|
|
45828
45852
|
var QUESTION_GROUP_CEILING = 200;
|
|
@@ -46074,7 +46098,7 @@ async function askAsOf(client, tableId, spec, fields, measures, keys) {
|
|
|
46074
46098
|
},
|
|
46075
46099
|
{ schema: config.schema ?? "custom" }
|
|
46076
46100
|
);
|
|
46077
|
-
if (response.error) return { ok: false, error: (0,
|
|
46101
|
+
if (response.error) return { ok: false, error: (0, import_core25.mapPgError)(response.error, "askQuestion.asOf") };
|
|
46078
46102
|
const rows2 = Array.isArray(response.data) ? response.data : [];
|
|
46079
46103
|
const bad = rows2.find((r) => Number(r.not_numbers ?? 0) > 0);
|
|
46080
46104
|
if (bad && m.op !== "count") {
|
|
@@ -46145,7 +46169,7 @@ function savedOf(row) {
|
|
|
46145
46169
|
}
|
|
46146
46170
|
async function questionsOf(client, tableId) {
|
|
46147
46171
|
const response = await client.config.dataSource.schema("platform").from("saved_view").select("id, name, definition, visibility, version, created_by").eq("surface_key", QUESTION_SURFACE).eq("subject_id", tableId).is("deleted_at", null).order("name", { ascending: true });
|
|
46148
|
-
if (response.error) return { ok: false, error: (0,
|
|
46172
|
+
if (response.error) return { ok: false, error: (0, import_core25.mapPgError)(response.error, "questionsOf") };
|
|
46149
46173
|
const me = client.config.actor?.user_id ?? null;
|
|
46150
46174
|
return {
|
|
46151
46175
|
ok: true,
|
|
@@ -46174,7 +46198,7 @@ async function questionSave(client, args) {
|
|
|
46174
46198
|
if (response.error.code === "23505") {
|
|
46175
46199
|
return { ok: false, error: { code: "already_exists", message: `You already have a question called \u201C${name}\u201D.` } };
|
|
46176
46200
|
}
|
|
46177
|
-
return { ok: false, error: (0,
|
|
46201
|
+
return { ok: false, error: (0, import_core25.mapPgError)(response.error, "questionSave") };
|
|
46178
46202
|
}
|
|
46179
46203
|
return { ok: true, data: response.data ? savedOf(response.data) : null };
|
|
46180
46204
|
}
|
|
@@ -46184,7 +46208,7 @@ async function questionArchive(client, id, version) {
|
|
|
46184
46208
|
{ p_surface_key: QUESTION_SURFACE, p_id: id, ...version !== void 0 ? { p_expected_version: version } : {} },
|
|
46185
46209
|
{ schema: "public" }
|
|
46186
46210
|
);
|
|
46187
|
-
if (response.error) return { ok: false, error: (0,
|
|
46211
|
+
if (response.error) return { ok: false, error: (0, import_core25.mapPgError)(response.error, "questionArchive") };
|
|
46188
46212
|
return { ok: true, data: response.data !== null };
|
|
46189
46213
|
}
|
|
46190
46214
|
|
|
@@ -47043,7 +47067,7 @@ function TableAsk({ tableId, onOpenInQuestions }) {
|
|
|
47043
47067
|
// src/PageScreen.tsx
|
|
47044
47068
|
var import_react258 = require("react");
|
|
47045
47069
|
var import_react259 = require("@ai-matrx/records/react");
|
|
47046
|
-
var
|
|
47070
|
+
var import_core26 = require("@ai-matrx/records/core");
|
|
47047
47071
|
var import_design_system129 = require("@ai-matrx/design-system");
|
|
47048
47072
|
var import_jsx_runtime145 = require("react/jsx-runtime");
|
|
47049
47073
|
var EDIT_LEVELS = /* @__PURE__ */ new Set(["edit_content", "editor", "admin", "owner"]);
|
|
@@ -47459,7 +47483,7 @@ function ListBlockView({
|
|
|
47459
47483
|
...sort.length > 0 ? { sort } : {}
|
|
47460
47484
|
});
|
|
47461
47485
|
const reload = page.reload;
|
|
47462
|
-
(0, import_react258.useEffect)(() => (0,
|
|
47486
|
+
(0, import_react258.useEffect)(() => (0, import_core26.onRecordChanged)(() => reload()), [reload]);
|
|
47463
47487
|
const rows = nobodyIsMe ? [] : page.data?.rows ?? [];
|
|
47464
47488
|
const columns = block.columns && block.columns.length > 0 ? block.columns.map((k) => all.find((f) => f.key === k)).filter((f) => !!f) : [...all].sort((a, b) => (a.sort ?? 100) - (b.sort ?? 100)).slice(0, DEFAULT_COLUMNS);
|
|
47465
47489
|
const firstId = rows[0]?.id ?? null;
|
|
@@ -48994,7 +49018,7 @@ var import_design_system142 = require("@ai-matrx/design-system");
|
|
|
48994
49018
|
var import_text_case19 = require("@ai-matrx/kit/text-case");
|
|
48995
49019
|
|
|
48996
49020
|
// src/viewShare.ts
|
|
48997
|
-
var
|
|
49021
|
+
var import_core27 = require("@ai-matrx/records/core");
|
|
48998
49022
|
var NO_VIEW_REASON = "No saved view yet";
|
|
48999
49023
|
function viewLink(tableId, viewId, origin) {
|
|
49000
49024
|
return `${tableLink(tableId, origin)}?view=${encodeURIComponent(viewId)}`;
|
|
@@ -49030,7 +49054,7 @@ async function downloadViewCsv(args) {
|
|
|
49030
49054
|
const columns = viewColumns(fields, view.presentation);
|
|
49031
49055
|
const rows = await rowsForFile({ client, host, fields: columns, records: read.rows, labels });
|
|
49032
49056
|
const name = fileNameOf(args.tableName) || "records";
|
|
49033
|
-
download(`${name}.csv`, "text/csv;charset=utf-8", (0,
|
|
49057
|
+
download(`${name}.csv`, "text/csv;charset=utf-8", (0, import_core27.exportCsv)(columns, rows));
|
|
49034
49058
|
host.notify?.success(read.cut ? cutWords(read.rows.length) : "CSV downloaded");
|
|
49035
49059
|
}
|
|
49036
49060
|
|
|
@@ -50010,9 +50034,29 @@ function TablePage({
|
|
|
50010
50034
|
const askedInWords = filter ? filterInWords(filter, pageFields.data ?? []) : null;
|
|
50011
50035
|
const organizationId = (0, import_react283.useRecordsClient)().config.organizationId;
|
|
50012
50036
|
const publicReadOnly = usePublicReadOnly(client, organizationId, tableId, table.data, rights);
|
|
50013
|
-
const
|
|
50014
|
-
|
|
50037
|
+
const seededOpening = (0, import_react283.useSeededAnswer)(
|
|
50038
|
+
`table-page-opening:${tableId}`,
|
|
50039
|
+
async (c) => {
|
|
50040
|
+
const [listed, looked] = await Promise.all([c.views({ table_id: tableId }), readLooks(c, tableId)]);
|
|
50041
|
+
if (!listed.ok) return listed;
|
|
50042
|
+
if (!looked.ok) return looked;
|
|
50043
|
+
const mine = listed.data.map(viewFromRow).filter((v) => v.subject === tableId);
|
|
50044
|
+
return { ok: true, data: { views: mine, looks: looked.data } };
|
|
50045
|
+
}
|
|
50046
|
+
);
|
|
50047
|
+
const seededViews = seededOpening && (seedViews ?? [defaultView(tableId)]).every((spec) => seedIsSatisfied(spec, seededOpening.views)) ? seededOpening.views : void 0;
|
|
50048
|
+
const [view, setView] = (0, import_react282.useState)(() => {
|
|
50049
|
+
if (!seededViews || seededViews.length === 0) return null;
|
|
50050
|
+
const asked3 = savedViewFromParam(activeView);
|
|
50051
|
+
return seededViews.find((v) => v.id === asked3) ?? defaultViewOf(seededViews) ?? seededViews[0];
|
|
50052
|
+
});
|
|
50053
|
+
const [looks, setLooks] = (0, import_react282.useState)(() => seededViews ? seededOpening?.looks : void 0);
|
|
50054
|
+
const looksSeededFor = (0, import_react282.useRef)(seededViews && seededOpening ? tableId : null);
|
|
50015
50055
|
(0, import_react282.useEffect)(() => {
|
|
50056
|
+
if (looksSeededFor.current === tableId) {
|
|
50057
|
+
looksSeededFor.current = null;
|
|
50058
|
+
return;
|
|
50059
|
+
}
|
|
50016
50060
|
let live = true;
|
|
50017
50061
|
setLooks(void 0);
|
|
50018
50062
|
void readLooks(client, tableId).then((answered) => {
|
|
@@ -50032,7 +50076,7 @@ function TablePage({
|
|
|
50032
50076
|
const questionsFromLink = questionsFromParam(activeView);
|
|
50033
50077
|
const openedByPackage = openingView(savedFromLink || questionsFromLink ? null : activeView, activeDashboardId);
|
|
50034
50078
|
const opened = questionsFromLink ? { ...openedByPackage, main: "questions" } : openedByPackage;
|
|
50035
|
-
const [views, setViews] = (0, import_react282.useState)(
|
|
50079
|
+
const [views, setViews] = (0, import_react282.useState)(() => seededViews);
|
|
50036
50080
|
const [pickedViewId, setPickedViewId] = (0, import_react282.useState)(savedFromLink);
|
|
50037
50081
|
const viewSeen = (0, import_react282.useRef)(null);
|
|
50038
50082
|
const [viewLinkMissed, setViewLinkMissed] = (0, import_react282.useState)(false);
|
|
@@ -50568,6 +50612,7 @@ function TablePage({
|
|
|
50568
50612
|
}
|
|
50569
50613
|
},
|
|
50570
50614
|
onViews: setViews,
|
|
50615
|
+
...seededViews && viewsEpoch === 0 ? { initialViews: seededViews } : {},
|
|
50571
50616
|
seed: seedViews ?? [defaultView(tableId)],
|
|
50572
50617
|
settings: view && main === "records" && shownLayout === "grid" ? /* @__PURE__ */ (0, import_jsx_runtime158.jsxs)("div", { className: "flex flex-col gap-0.5 px-1 py-1", role: "radiogroup", "aria-label": FOOTER_WORDS.label, children: [
|
|
50573
50618
|
/* @__PURE__ */ (0, import_jsx_runtime158.jsx)("span", { className: "px-1 pb-0.5 text-[11px] font-medium text-muted-foreground", children: FOOTER_WORDS.label }),
|