@ai-matrx/records-ui 0.93.30 → 0.93.33
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 +18 -0
- package/dist/index.cjs +131 -98
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +49 -16
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -597,7 +597,7 @@ import {
|
|
|
597
597
|
|
|
598
598
|
// src/editors.tsx
|
|
599
599
|
import { useCallback as useCallback3, useEffect as useEffect7, useRef as useRef5, useState as useState9 } from "react";
|
|
600
|
-
import { allowsOtherValues, choiceValuesOf, coerceTypedAnswer, decideTypedChoice, isTheChosen, optionKey } from "@ai-matrx/records";
|
|
600
|
+
import { allowsOtherValues, choiceValuesOf, coerceTypedAnswer, decideTypedChoice, isTheChosen, optionKey as optionKey2 } from "@ai-matrx/records";
|
|
601
601
|
import { useOptionalRecordsClient as useOptionalRecordsClient5 } from "@ai-matrx/records/react";
|
|
602
602
|
import {
|
|
603
603
|
BasicInput as BasicInput5,
|
|
@@ -1325,6 +1325,7 @@ import { Badge, Button as Button5 } from "@ai-matrx/design-system";
|
|
|
1325
1325
|
// src/labels.tsx
|
|
1326
1326
|
import { createContext as createContext2, useCallback, useContext as useContext2, useEffect as useEffect3, useMemo as useMemo4, useRef, useState as useState4 } from "react";
|
|
1327
1327
|
import { useRecordsClient } from "@ai-matrx/records/react";
|
|
1328
|
+
import { optionKey } from "@ai-matrx/records";
|
|
1328
1329
|
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
1329
1330
|
var LabelContext = createContext2({
|
|
1330
1331
|
// With no provider the resolver is ABSENT, not silently empty: a caller gets
|
|
@@ -1345,6 +1346,9 @@ function idsOf(value) {
|
|
|
1345
1346
|
return [];
|
|
1346
1347
|
}
|
|
1347
1348
|
var UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
1349
|
+
function choiceKeyName(fieldId, key) {
|
|
1350
|
+
return `${fieldId}\0key\0${key}`;
|
|
1351
|
+
}
|
|
1348
1352
|
function isId(value) {
|
|
1349
1353
|
return typeof value === "string" && UUID.test(value);
|
|
1350
1354
|
}
|
|
@@ -1411,7 +1415,10 @@ function RecordLabelProvider({ children }) {
|
|
|
1411
1415
|
setNames((current) => {
|
|
1412
1416
|
const next = { ...current };
|
|
1413
1417
|
for (const option of result.data ?? []) {
|
|
1414
|
-
|
|
1418
|
+
const words2 = recordName(option.data, null, "Unnamed choice");
|
|
1419
|
+
next[option.id] = words2;
|
|
1420
|
+
const key = optionKey(option);
|
|
1421
|
+
if (key) next[choiceKeyName(field2.id, key)] = words2;
|
|
1415
1422
|
}
|
|
1416
1423
|
return next;
|
|
1417
1424
|
});
|
|
@@ -1475,14 +1482,26 @@ function RecordLabelProvider({ children }) {
|
|
|
1475
1482
|
},
|
|
1476
1483
|
[]
|
|
1477
1484
|
);
|
|
1485
|
+
const rereadFor = useRef(/* @__PURE__ */ new Set());
|
|
1478
1486
|
const lookup = useCallback(
|
|
1479
1487
|
(field2, id) => {
|
|
1488
|
+
if (field2.type === "list" && !isId(id)) {
|
|
1489
|
+
const named = names[choiceKeyName(field2.id, id)];
|
|
1490
|
+
if (named !== void 0) return named;
|
|
1491
|
+
const once = choiceKeyName(field2.id, id);
|
|
1492
|
+
if (settled[field2.id] && !rereadFor.current.has(once)) {
|
|
1493
|
+
rereadFor.current.add(once);
|
|
1494
|
+
asked2.current.delete(field2.id);
|
|
1495
|
+
want(field2);
|
|
1496
|
+
}
|
|
1497
|
+
return null;
|
|
1498
|
+
}
|
|
1480
1499
|
const known = names[id];
|
|
1481
1500
|
if (known !== void 0) return known;
|
|
1482
1501
|
if (settled[field2.id]) chase(field2, id);
|
|
1483
1502
|
return null;
|
|
1484
1503
|
},
|
|
1485
|
-
[names, settled, chase]
|
|
1504
|
+
[names, settled, chase, want]
|
|
1486
1505
|
);
|
|
1487
1506
|
const waiting = useCallback((field2) => waitingLines[field2.id] ?? null, [waitingLines]);
|
|
1488
1507
|
const value = useMemo4(() => ({ lookup, want, waiting }), [lookup, want, waiting]);
|
|
@@ -2564,7 +2583,7 @@ function TypedTextControl({ field: field2, value, onChange, disabled, id, onComm
|
|
|
2564
2583
|
" ",
|
|
2565
2584
|
needsChoices ? String(
|
|
2566
2585
|
(Array.isArray(withoutAddition(judged.value).value) ? withoutAddition(judged.value).value : [withoutAddition(judged.value).value]).map((k) => {
|
|
2567
|
-
const option = choices?.find((o) =>
|
|
2586
|
+
const option = choices?.find((o) => optionKey2(o) === k);
|
|
2568
2587
|
return option ? recordName(option.data, null, String(k)) : String(k);
|
|
2569
2588
|
}).join(", ")
|
|
2570
2589
|
) : (() => {
|
|
@@ -2836,18 +2855,18 @@ function OptionControl({ field: field2, value, onChange, disabled, id, autoOpen,
|
|
|
2836
2855
|
const titleOf = (option) => recordName(option.data, null, "Unnamed choice");
|
|
2837
2856
|
if (field2.multi) {
|
|
2838
2857
|
const chosen = options.filter((option) => choiceValuesOf(value).some((v) => isTheChosen(option, v)));
|
|
2839
|
-
const picked = new Set(chosen.map((option) =>
|
|
2858
|
+
const picked = new Set(chosen.map((option) => optionKey2(option)));
|
|
2840
2859
|
const toggles = /* @__PURE__ */ jsx12("div", { id: autoOpen ? void 0 : id, className: "flex flex-wrap gap-1", children: options.map((option) => /* @__PURE__ */ jsx12(
|
|
2841
2860
|
Button6,
|
|
2842
2861
|
{
|
|
2843
2862
|
type: "button",
|
|
2844
2863
|
size: "sm",
|
|
2845
|
-
variant: picked.has(
|
|
2864
|
+
variant: picked.has(optionKey2(option)) ? "default" : "outline",
|
|
2846
2865
|
disabled,
|
|
2847
2866
|
onClick: () => {
|
|
2848
2867
|
const next = new Set(picked);
|
|
2849
|
-
if (next.has(
|
|
2850
|
-
else next.add(
|
|
2868
|
+
if (next.has(optionKey2(option))) next.delete(optionKey2(option));
|
|
2869
|
+
else next.add(optionKey2(option));
|
|
2851
2870
|
onChange(next.size === 0 ? null : [...next]);
|
|
2852
2871
|
},
|
|
2853
2872
|
children: titleOf(option)
|
|
@@ -2873,7 +2892,7 @@ function OptionControl({ field: field2, value, onChange, disabled, id, autoOpen,
|
|
|
2873
2892
|
return /* @__PURE__ */ jsxs10(
|
|
2874
2893
|
Select2,
|
|
2875
2894
|
{
|
|
2876
|
-
value: current ?
|
|
2895
|
+
value: current ? optionKey2(current) : "",
|
|
2877
2896
|
disabled: disabled ?? false,
|
|
2878
2897
|
onValueChange: (next) => onChange(next === "" ? null : next),
|
|
2879
2898
|
...autoOpen ? {
|
|
@@ -2885,7 +2904,7 @@ function OptionControl({ field: field2, value, onChange, disabled, id, autoOpen,
|
|
|
2885
2904
|
} : {},
|
|
2886
2905
|
children: [
|
|
2887
2906
|
/* @__PURE__ */ jsx12(SelectTrigger2, { id, size: "sm", children: /* @__PURE__ */ jsx12(SelectValue2, { placeholder: "Choose" }) }),
|
|
2888
|
-
/* @__PURE__ */ jsx12(SelectContent2, { children: options.map((option) => /* @__PURE__ */ jsx12(SelectItem2, { value:
|
|
2907
|
+
/* @__PURE__ */ jsx12(SelectContent2, { children: options.map((option) => /* @__PURE__ */ jsx12(SelectItem2, { value: optionKey2(option), children: titleOf(option) }, option.id)) })
|
|
2889
2908
|
]
|
|
2890
2909
|
}
|
|
2891
2910
|
);
|
|
@@ -2933,7 +2952,7 @@ function OpenChoicePicker({
|
|
|
2933
2952
|
if (field2.multi) {
|
|
2934
2953
|
const existing = current.map((v) => {
|
|
2935
2954
|
const option = options.find((o) => isTheChosen(o, v));
|
|
2936
|
-
return option ?
|
|
2955
|
+
return option ? optionKey2(option) : String(v);
|
|
2937
2956
|
});
|
|
2938
2957
|
const has = existing.some((v) => v.toLowerCase() === word.toLowerCase());
|
|
2939
2958
|
const list = has ? existing.filter((v) => v.toLowerCase() !== word.toLowerCase()) : [...existing, word];
|
|
@@ -3006,7 +3025,7 @@ function OpenChoicePicker({
|
|
|
3006
3025
|
})),
|
|
3007
3026
|
onPick: (optionId) => {
|
|
3008
3027
|
const option = options.find((o) => o.id === optionId);
|
|
3009
|
-
if (option) choose(
|
|
3028
|
+
if (option) choose(optionKey2(option));
|
|
3010
3029
|
},
|
|
3011
3030
|
empty: q === "" ? /* @__PURE__ */ jsx12("p", { className: "p-2 text-xs text-muted-foreground", children: "No choices yet \u2014 type one to add it." }) : null,
|
|
3012
3031
|
add,
|
|
@@ -3933,6 +3952,10 @@ function scalarText(field2, value, labels, stillWaitingFor) {
|
|
|
3933
3952
|
if (isId(value) && (field2.type === "list" || field2.type === "relation")) {
|
|
3934
3953
|
return labels?.(field2, String(value)) ?? stillWaitingFor ?? "Loading\u2026";
|
|
3935
3954
|
}
|
|
3955
|
+
if (field2.type === "list" && typeof value === "string" && labels) {
|
|
3956
|
+
const words2 = labels(field2, value);
|
|
3957
|
+
if (words2) return words2;
|
|
3958
|
+
}
|
|
3936
3959
|
const shownAs = shownAsOf(field2);
|
|
3937
3960
|
if (shownAs) {
|
|
3938
3961
|
const said = formatFieldValue3(value, shownAs);
|
|
@@ -4533,6 +4556,13 @@ function GridCell({
|
|
|
4533
4556
|
onAskWhoChanged
|
|
4534
4557
|
}) {
|
|
4535
4558
|
const ui = useRecordsUi();
|
|
4559
|
+
const saidAt = useRef8(0);
|
|
4560
|
+
const sayWhyNot = () => {
|
|
4561
|
+
if (Date.now() - saidAt.current < 4e3) return;
|
|
4562
|
+
saidAt.current = Date.now();
|
|
4563
|
+
const why = fieldIsEditable(field2) ? `${fieldName(field2)} \u2014 ${whyNot ?? "you cannot change this record"}` : `${fieldName(field2)} is worked out by the system, so it cannot be typed in`;
|
|
4564
|
+
ui.notify?.error(why);
|
|
4565
|
+
};
|
|
4536
4566
|
const open = Boolean(
|
|
4537
4567
|
editing && editing.editing?.rowId === row.id && editing.editing.key === field2.key
|
|
4538
4568
|
);
|
|
@@ -4651,6 +4681,7 @@ function GridCell({
|
|
|
4651
4681
|
event.preventDefault();
|
|
4652
4682
|
event.stopPropagation();
|
|
4653
4683
|
if (editable) editing?.begin({ rowId: row.id, key: field2.key });
|
|
4684
|
+
else sayWhyNot();
|
|
4654
4685
|
},
|
|
4655
4686
|
onKeyDown: (event) => {
|
|
4656
4687
|
if (editable && (event.key === "Enter" || event.key === "F2")) {
|
|
@@ -4666,7 +4697,9 @@ function GridCell({
|
|
|
4666
4697
|
if (editable && isTypedCharacter(event) && typingOpens(field2) !== "none") {
|
|
4667
4698
|
event.preventDefault();
|
|
4668
4699
|
editing?.begin({ rowId: row.id, key: field2.key }, event.key);
|
|
4700
|
+
return;
|
|
4669
4701
|
}
|
|
4702
|
+
if (!editable && (event.key === "Enter" || event.key === "F2" || isTypedCharacter(event))) sayWhyNot();
|
|
4670
4703
|
},
|
|
4671
4704
|
tabIndex: editable || onAskWhoChanged ? 0 : void 0,
|
|
4672
4705
|
children: /* @__PURE__ */ jsx18(
|
|
@@ -7317,7 +7350,7 @@ function entityReferenceKindsOf(field2) {
|
|
|
7317
7350
|
|
|
7318
7351
|
// src/gridColors.tsx
|
|
7319
7352
|
import { useCallback as useCallback8, useEffect as useEffect18, useMemo as useMemo12, useState as useState21 } from "react";
|
|
7320
|
-
import { optionKey as
|
|
7353
|
+
import { optionKey as optionKey3, optionLabel as optionLabel2 } from "@ai-matrx/records";
|
|
7321
7354
|
import { useRecordsClient as useRecordsClient10 } from "@ai-matrx/records/react";
|
|
7322
7355
|
import {
|
|
7323
7356
|
Button as Button15,
|
|
@@ -7392,7 +7425,7 @@ function useChoiceOptions(fields, keys) {
|
|
|
7392
7425
|
function lookOf(option) {
|
|
7393
7426
|
const raw = option.data?.["color"];
|
|
7394
7427
|
const color = typeof raw === "string" && STYLE_COLORS4.includes(raw) ? raw : void 0;
|
|
7395
|
-
return { id: String(option.id), key:
|
|
7428
|
+
return { id: String(option.id), key: optionKey3(option), label: optionLabel2(option), ...color ? { color } : {} };
|
|
7396
7429
|
}
|
|
7397
7430
|
function paintByOption(style, fields, index, lookup) {
|
|
7398
7431
|
if (index.size === 0) return { style, documentOf: (doc) => doc, choiceColorFor: lookup };
|
|
@@ -8074,7 +8107,7 @@ function SummarySheetControls({
|
|
|
8074
8107
|
|
|
8075
8108
|
// src/pasteValues.ts
|
|
8076
8109
|
import { predictValueRefusals } from "@ai-matrx/records/core";
|
|
8077
|
-
import { coerceTypedAnswer as coerceTypedAnswer2, optionKey as
|
|
8110
|
+
import { coerceTypedAnswer as coerceTypedAnswer2, optionKey as optionKey4 } from "@ai-matrx/records";
|
|
8078
8111
|
function wordForStoredChoice(options, value) {
|
|
8079
8112
|
if (options === void 0 || typeof value !== "string" || value === "") return null;
|
|
8080
8113
|
for (const label of options.labels) {
|
|
@@ -8087,7 +8120,7 @@ function choiceOptionsOf(options) {
|
|
|
8087
8120
|
const labels = [];
|
|
8088
8121
|
for (const option of options) {
|
|
8089
8122
|
const id = option.id;
|
|
8090
|
-
const key =
|
|
8123
|
+
const key = optionKey4(option);
|
|
8091
8124
|
const label = recordName(option.data, null, "");
|
|
8092
8125
|
if (label) {
|
|
8093
8126
|
labels.push(label);
|