@ai-matrx/records-ui 0.115.75 → 0.115.77
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 +22 -1
- package/dist/index.cjs +1511 -1299
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -6
- package/dist/index.d.ts +10 -6
- package/dist/index.js +1471 -1259
- package/dist/index.js.map +1 -1
- package/dist/pickers.cjs +132 -14
- package/dist/pickers.cjs.map +1 -1
- package/dist/pickers.js +137 -19
- package/dist/pickers.js.map +1 -1
- package/package.json +3 -3
package/dist/pickers.js
CHANGED
|
@@ -2046,7 +2046,7 @@ function RelationPicker({ field, value, onChange, disabled, id, className, allow
|
|
|
2046
2046
|
|
|
2047
2047
|
// src/buttonCell.tsx
|
|
2048
2048
|
import { useState as useState24 } from "react";
|
|
2049
|
-
import { Button as Button16, Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, Popover as Popover4, PopoverContent as PopoverContent4, PopoverTrigger as PopoverTrigger4, cn as cn21 } from "@ai-matrx/design-system";
|
|
2049
|
+
import { Button as Button16, Dialog as Dialog2, DialogContent as DialogContent2, DialogDescription, DialogHeader as DialogHeader2, DialogTitle as DialogTitle2, Popover as Popover4, PopoverContent as PopoverContent4, PopoverTrigger as PopoverTrigger4, cn as cn21 } from "@ai-matrx/design-system";
|
|
2050
2050
|
import { CHOICE_CHIP_CLASS as CHOICE_CHIP_CLASS2, NEUTRAL_CHIP_CLASS as NEUTRAL_CHIP_CLASS2, isStyleColor as isStyleColor2 } from "@ai-matrx/design-system/data-table";
|
|
2051
2051
|
import { buttonNeeds as buttonNeeds2, buttonOf as buttonOf2 } from "@ai-matrx/records";
|
|
2052
2052
|
import { useOptionalRecordsClient as useOptionalRecordsClient8 } from "@ai-matrx/records/react";
|
|
@@ -2584,9 +2584,7 @@ var NOT_TYPED_BY_NAME = /* @__PURE__ */ new Set([
|
|
|
2584
2584
|
"fx.lte",
|
|
2585
2585
|
"fx.gt",
|
|
2586
2586
|
"fx.gte",
|
|
2587
|
-
"fx.autonumber"
|
|
2588
|
-
"fx.created_time",
|
|
2589
|
-
"fx.modified_time"
|
|
2587
|
+
"fx.autonumber"
|
|
2590
2588
|
]);
|
|
2591
2589
|
function formulaFunctionNames(kinds) {
|
|
2592
2590
|
return [...new Set(kinds.map((row) => row.node))].filter((node) => node.startsWith("fx.") && !NOT_TYPED_BY_NAME.has(node)).map((node) => node.slice(3).toUpperCase()).sort();
|
|
@@ -3439,13 +3437,38 @@ var CONTEXT_POLICY_LABEL = {
|
|
|
3439
3437
|
exclude: "No, keep it away from assistants"
|
|
3440
3438
|
};
|
|
3441
3439
|
var SUBSCRIPTION_CADENCES = exhaustiveValuesOf()(["instant", "hourly", "daily", "weekly"]);
|
|
3442
|
-
var ROLLUP_AGG_VALUES = [
|
|
3440
|
+
var ROLLUP_AGG_VALUES = [
|
|
3441
|
+
"count",
|
|
3442
|
+
"sum",
|
|
3443
|
+
"avg",
|
|
3444
|
+
"min",
|
|
3445
|
+
"max",
|
|
3446
|
+
// AIRTABLE PARITY (lane AT-FORMULA): the aggregates that read the linked values as they are.
|
|
3447
|
+
"countall",
|
|
3448
|
+
"counta",
|
|
3449
|
+
"and",
|
|
3450
|
+
"or",
|
|
3451
|
+
"xor",
|
|
3452
|
+
"arrayjoin",
|
|
3453
|
+
"concatenate",
|
|
3454
|
+
"arrayunique",
|
|
3455
|
+
"arraycompact"
|
|
3456
|
+
];
|
|
3443
3457
|
var ROLLUP_AGG_LABEL = {
|
|
3444
3458
|
count: "How many there are",
|
|
3445
3459
|
sum: "The total of",
|
|
3446
3460
|
avg: "The average of",
|
|
3447
3461
|
min: "The smallest",
|
|
3448
|
-
max: "The largest"
|
|
3462
|
+
max: "The largest",
|
|
3463
|
+
countall: "How many values, empty ones too",
|
|
3464
|
+
counta: "How many values are filled in",
|
|
3465
|
+
and: "Yes when every value is yes",
|
|
3466
|
+
or: "Yes when any value is yes",
|
|
3467
|
+
xor: "Yes when an odd number are yes",
|
|
3468
|
+
arrayjoin: "All the values, joined with commas",
|
|
3469
|
+
concatenate: "All the values, run together",
|
|
3470
|
+
arrayunique: "Each different value once",
|
|
3471
|
+
arraycompact: "The values that are filled in"
|
|
3449
3472
|
};
|
|
3450
3473
|
var FORMULA_OP_VALUES = ["concat", "add", "sub", "mul", "div"];
|
|
3451
3474
|
var FORMULA_OP_LABEL = {
|
|
@@ -3917,7 +3940,7 @@ function linkChipText(raw) {
|
|
|
3917
3940
|
// src/gridAttachments.tsx
|
|
3918
3941
|
import { useEffect as useEffect11, useRef as useRef10, useState as useState17 } from "react";
|
|
3919
3942
|
import { useOptionalRecordsClient as useOptionalRecordsClient5 } from "@ai-matrx/records/react";
|
|
3920
|
-
import { Badge as Badge3, Button as Button10 } from "@ai-matrx/design-system";
|
|
3943
|
+
import { Badge as Badge3, Button as Button10, Dialog, DialogContent, DialogHeader, DialogTitle } from "@ai-matrx/design-system";
|
|
3921
3944
|
|
|
3922
3945
|
// src/FilePicker.tsx
|
|
3923
3946
|
import { useCallback as useCallback4, useId, useRef as useRef9, useState as useState16 } from "react";
|
|
@@ -4037,20 +4060,19 @@ function rememberHostFileIds(ids) {
|
|
|
4037
4060
|
}
|
|
4038
4061
|
var FILE_CHIP_UNREAD = "File";
|
|
4039
4062
|
var FILE_CHIP_NO_PAGE = "This screen has no way to open files yet.";
|
|
4040
|
-
function
|
|
4063
|
+
function useFileRead(id) {
|
|
4041
4064
|
const client = useOptionalRecordsClient5();
|
|
4042
|
-
const host = useRecordsUi();
|
|
4043
4065
|
const [read, setRead] = useState17(null);
|
|
4044
4066
|
useEffect11(() => {
|
|
4045
4067
|
let cancelled = false;
|
|
4046
|
-
if (!client) {
|
|
4047
|
-
setRead({ name: null, fileId: null, why: null });
|
|
4048
|
-
return;
|
|
4049
|
-
}
|
|
4050
4068
|
if (handedHostFileIds.has(id)) {
|
|
4051
4069
|
setRead({ name: null, fileId: id, why: null });
|
|
4052
4070
|
return;
|
|
4053
4071
|
}
|
|
4072
|
+
if (!client) {
|
|
4073
|
+
setRead({ name: null, fileId: null, why: null });
|
|
4074
|
+
return;
|
|
4075
|
+
}
|
|
4054
4076
|
void client.recordRead({ record_id: id }).then((answered) => {
|
|
4055
4077
|
if (cancelled) return;
|
|
4056
4078
|
if (!answered.ok) {
|
|
@@ -4066,11 +4088,30 @@ function AttachmentChip({ id, onRemove }) {
|
|
|
4066
4088
|
cancelled = true;
|
|
4067
4089
|
};
|
|
4068
4090
|
}, [client, id]);
|
|
4091
|
+
return read;
|
|
4092
|
+
}
|
|
4093
|
+
function AttachmentChip({ id, onRemove, onPreview }) {
|
|
4094
|
+
const host = useRecordsUi();
|
|
4095
|
+
const read = useFileRead(id);
|
|
4069
4096
|
const words = read?.name ?? (read ? FILE_CHIP_UNREAD : "\u2026");
|
|
4070
4097
|
const href = read?.fileId ? host.hrefForFile?.({ fileId: read.fileId }) : void 0;
|
|
4071
|
-
const title = href ? `Open ${words}` : read?.why ?? FILE_CHIP_NO_PAGE;
|
|
4098
|
+
const title = onPreview ? `Preview ${words}` : href ? `Open ${words}` : read?.why ?? FILE_CHIP_NO_PAGE;
|
|
4072
4099
|
return /* @__PURE__ */ jsxs19(Badge3, { variant: "secondary", className: "max-w-[14rem] gap-1 text-[11px]", "data-records-file-chip": id, title, children: [
|
|
4073
|
-
|
|
4100
|
+
onPreview ? /* @__PURE__ */ jsx21(
|
|
4101
|
+
"button",
|
|
4102
|
+
{
|
|
4103
|
+
type: "button",
|
|
4104
|
+
className: "truncate underline-offset-2 hover:underline",
|
|
4105
|
+
"data-records-file-preview": id,
|
|
4106
|
+
onClick: (event) => {
|
|
4107
|
+
event.stopPropagation();
|
|
4108
|
+
onPreview();
|
|
4109
|
+
},
|
|
4110
|
+
onMouseDown: (event) => event.stopPropagation(),
|
|
4111
|
+
onDoubleClick: (event) => event.stopPropagation(),
|
|
4112
|
+
children: words
|
|
4113
|
+
}
|
|
4114
|
+
) : href ? /* @__PURE__ */ jsx21(
|
|
4074
4115
|
OutboundLink4,
|
|
4075
4116
|
{
|
|
4076
4117
|
href,
|
|
@@ -4097,9 +4138,70 @@ function AttachmentChip({ id, onRemove }) {
|
|
|
4097
4138
|
] });
|
|
4098
4139
|
}
|
|
4099
4140
|
function AttachmentChips({ value, onRemove }) {
|
|
4141
|
+
const host = useRecordsUi();
|
|
4100
4142
|
const ids = attachmentIdsOf(value);
|
|
4143
|
+
const [viewing, setViewing] = useState17(null);
|
|
4101
4144
|
if (ids.length === 0) return null;
|
|
4102
|
-
|
|
4145
|
+
const canPreview = Boolean(host.fileImage);
|
|
4146
|
+
return /* @__PURE__ */ jsxs19("span", { className: "flex flex-wrap gap-1", "data-records-file-chips": "", children: [
|
|
4147
|
+
ids.map((id, index) => /* @__PURE__ */ jsx21(
|
|
4148
|
+
AttachmentChip,
|
|
4149
|
+
{
|
|
4150
|
+
id,
|
|
4151
|
+
...onRemove ? { onRemove: () => onRemove(id) } : {},
|
|
4152
|
+
...canPreview ? { onPreview: () => setViewing(index) } : {}
|
|
4153
|
+
},
|
|
4154
|
+
id
|
|
4155
|
+
)),
|
|
4156
|
+
viewing !== null && canPreview ? /* @__PURE__ */ jsx21(AttachmentViewer, { ids, index: Math.min(viewing, ids.length - 1), onIndex: setViewing, onClose: () => setViewing(null) }) : null
|
|
4157
|
+
] });
|
|
4158
|
+
}
|
|
4159
|
+
function stepAttachment(index, total, way) {
|
|
4160
|
+
return Math.max(0, Math.min(total - 1, index + way));
|
|
4161
|
+
}
|
|
4162
|
+
function AttachmentViewer({
|
|
4163
|
+
ids,
|
|
4164
|
+
index,
|
|
4165
|
+
onIndex,
|
|
4166
|
+
onClose
|
|
4167
|
+
}) {
|
|
4168
|
+
const host = useRecordsUi();
|
|
4169
|
+
const id = ids[index];
|
|
4170
|
+
const read = useFileRead(id);
|
|
4171
|
+
const name = read?.name ?? (read ? FILE_CHIP_UNREAD : "\u2026");
|
|
4172
|
+
const href = read?.fileId ? host.hrefForFile?.({ fileId: read.fileId }) : void 0;
|
|
4173
|
+
const go = (way) => onIndex(stepAttachment(index, ids.length, way));
|
|
4174
|
+
return /* @__PURE__ */ jsx21(Dialog, { open: true, onOpenChange: (open) => !open && onClose(), children: /* @__PURE__ */ jsxs19(
|
|
4175
|
+
DialogContent,
|
|
4176
|
+
{
|
|
4177
|
+
className: "sm:max-w-3xl",
|
|
4178
|
+
"data-records-attachment-viewer": id,
|
|
4179
|
+
onKeyDown: (event) => {
|
|
4180
|
+
if (event.key === "ArrowLeft") {
|
|
4181
|
+
event.preventDefault();
|
|
4182
|
+
go(-1);
|
|
4183
|
+
} else if (event.key === "ArrowRight") {
|
|
4184
|
+
event.preventDefault();
|
|
4185
|
+
go(1);
|
|
4186
|
+
}
|
|
4187
|
+
},
|
|
4188
|
+
onClick: (event) => event.stopPropagation(),
|
|
4189
|
+
children: [
|
|
4190
|
+
/* @__PURE__ */ jsx21(DialogHeader, { children: /* @__PURE__ */ jsx21(DialogTitle, { className: "truncate text-sm", children: name }) }),
|
|
4191
|
+
/* @__PURE__ */ jsx21("div", { className: "relative h-[60vh] w-full overflow-hidden rounded-md bg-muted", "data-records-attachment-stage": "", children: read?.fileId ? host.fileImage?.({ fileId: read.fileId, alt: name }) : null }),
|
|
4192
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-2", children: [
|
|
4193
|
+
/* @__PURE__ */ jsx21(Button10, { size: "sm", variant: "outline", "aria-label": "Previous file", disabled: index === 0, onClick: () => go(-1), "data-records-attachment-previous": "", children: "\u2190" }),
|
|
4194
|
+
/* @__PURE__ */ jsx21(Button10, { size: "sm", variant: "outline", "aria-label": "Next file", disabled: index >= ids.length - 1, onClick: () => go(1), "data-records-attachment-next": "", children: "\u2192" }),
|
|
4195
|
+
/* @__PURE__ */ jsxs19("span", { className: "text-xs tabular-nums text-muted-foreground", "data-records-attachment-position": "", children: [
|
|
4196
|
+
index + 1,
|
|
4197
|
+
" of ",
|
|
4198
|
+
ids.length
|
|
4199
|
+
] }),
|
|
4200
|
+
href ? /* @__PURE__ */ jsx21(OutboundLink4, { href, className: "ml-auto text-xs underline-offset-2 hover:underline", children: "Open in new tab" }) : null
|
|
4201
|
+
] })
|
|
4202
|
+
]
|
|
4203
|
+
}
|
|
4204
|
+
) });
|
|
4103
4205
|
}
|
|
4104
4206
|
function hostTakesFiles(host) {
|
|
4105
4207
|
return Boolean(host.pickFiles || host.upload);
|
|
@@ -6302,6 +6404,8 @@ function FieldEditor(props) {
|
|
|
6302
6404
|
const [statusGroups, setStatusGroups] = useState23({});
|
|
6303
6405
|
const [statusKeys, setStatusKeys] = useState23({});
|
|
6304
6406
|
const [symbology, setSymbology] = useState23(String(start?.config?.["symbology"] ?? ""));
|
|
6407
|
+
const descriptionStart = String(start?.config?.["description"] ?? "");
|
|
6408
|
+
const [description, setDescription] = useState23(descriptionStart);
|
|
6305
6409
|
const buttonStart = useMemo10(() => buttonOf(start) ?? { label: "" }, [start]);
|
|
6306
6410
|
const [buttonSettings, setButtonSettings] = useState23(buttonStart);
|
|
6307
6411
|
const prefixStart = autonumberPrefixOf3(start);
|
|
@@ -6451,6 +6555,7 @@ function FieldEditor(props) {
|
|
|
6451
6555
|
const defaultChanged = takesADefault(field) && JSON.stringify(defaultNow) !== JSON.stringify(defaultToKeep(field.default));
|
|
6452
6556
|
const patch = {
|
|
6453
6557
|
...defaultChanged ? { default: defaultNow } : {},
|
|
6558
|
+
...description.trim() !== descriptionStart.trim() ? { description: description.trim() === "" ? null : description.trim() } : {},
|
|
6454
6559
|
// The column's look travels in the same settings patch (`display_format`), so a save is
|
|
6455
6560
|
// still one store call. `FieldPatch` does not declare the key yet (store gap, reported);
|
|
6456
6561
|
// the door has carried it since the Sheet's seam started writing it.
|
|
@@ -6657,6 +6762,19 @@ function FieldEditor(props) {
|
|
|
6657
6762
|
}
|
|
6658
6763
|
) : null
|
|
6659
6764
|
] }),
|
|
6765
|
+
field ? /* @__PURE__ */ jsxs30("label", { className: "flex flex-col gap-1 sm:col-span-2", children: [
|
|
6766
|
+
/* @__PURE__ */ jsx32(Label8, { className: "text-xs", children: "Help text" }),
|
|
6767
|
+
/* @__PURE__ */ jsx32(
|
|
6768
|
+
BasicInput9,
|
|
6769
|
+
{
|
|
6770
|
+
value: description,
|
|
6771
|
+
maxLength: 300,
|
|
6772
|
+
"aria-label": "Help text",
|
|
6773
|
+
placeholder: "Shown when the column name is hovered",
|
|
6774
|
+
onChange: (e) => setDescription(e.target.value)
|
|
6775
|
+
}
|
|
6776
|
+
)
|
|
6777
|
+
] }) : null,
|
|
6660
6778
|
/* @__PURE__ */ jsxs30("div", { className: "flex flex-col gap-1", children: [
|
|
6661
6779
|
/* @__PURE__ */ jsx32(Label8, { className: "text-xs", children: "What it holds" }),
|
|
6662
6780
|
/* @__PURE__ */ jsxs30(
|
|
@@ -7546,9 +7664,9 @@ function ButtonValue({ field, recordId, inCell }) {
|
|
|
7546
7664
|
] }) : null
|
|
7547
7665
|
] })
|
|
7548
7666
|
] }),
|
|
7549
|
-
settingUp && tableId ? /* @__PURE__ */ jsx33(
|
|
7550
|
-
/* @__PURE__ */ jsxs31(
|
|
7551
|
-
/* @__PURE__ */ jsx33(
|
|
7667
|
+
settingUp && tableId ? /* @__PURE__ */ jsx33(Dialog2, { open: true, onOpenChange: (open) => open ? null : setSettingUp(false), children: /* @__PURE__ */ jsxs31(DialogContent2, { className: "max-h-[85vh] overflow-y-auto sm:max-w-2xl", onClick: stop, onPointerDown: stop, children: [
|
|
7668
|
+
/* @__PURE__ */ jsxs31(DialogHeader2, { children: [
|
|
7669
|
+
/* @__PURE__ */ jsx33(DialogTitle2, { children: `Column settings \xB7 ${fieldName(field)}` }),
|
|
7552
7670
|
/* @__PURE__ */ jsx33(DialogDescription, { className: "sr-only", children: "What the button does" })
|
|
7553
7671
|
] }),
|
|
7554
7672
|
/* @__PURE__ */ jsx33(FieldEditor, { tableId, field, onSaved: () => setSettingUp(false), onCancel: () => setSettingUp(false) })
|