@ai-matrx/records-ui 0.110.7 → 0.110.9
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 +15 -0
- package/dist/index.cjs +138 -106
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.js +49 -17
- package/dist/index.js.map +1 -1
- package/dist/pickers.cjs +13 -8
- package/dist/pickers.cjs.map +1 -1
- package/dist/pickers.js +8 -3
- package/dist/pickers.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -2287,6 +2287,12 @@ interface GridProps {
|
|
|
2287
2287
|
* row and hands the term through `searchOverride` (Spaces N-19). Default `true`.
|
|
2288
2288
|
*/
|
|
2289
2289
|
searchBox?: boolean | undefined;
|
|
2290
|
+
/**
|
|
2291
|
+
* `true`: a row action the person's level refuses (Archive record for a content editor, who may
|
|
2292
|
+
* change rows but not delete them) is left out of the row menu instead of drawn disabled with its
|
|
2293
|
+
* reason. Default `false` (disabled, saying why). Spaces sets it: Notion offers only what works.
|
|
2294
|
+
*/
|
|
2295
|
+
hideRefusedRowActions?: boolean | undefined;
|
|
2290
2296
|
/** The new-row line's words ("New page"). Default "Add row". */
|
|
2291
2297
|
newRowLabel?: string | undefined;
|
|
2292
2298
|
/**
|
|
@@ -4044,6 +4050,8 @@ interface ViewSwitcherProps {
|
|
|
4044
4050
|
* row and hands the term through `searchOverride` (Spaces N-19). Default `true`.
|
|
4045
4051
|
*/
|
|
4046
4052
|
searchBox?: boolean | undefined;
|
|
4053
|
+
/** `GridProps.hideRefusedRowActions`. */
|
|
4054
|
+
hideRefusedRowActions?: boolean | undefined;
|
|
4047
4055
|
/** The grid's new-row line words (`GridProps.newRowLabel`). */
|
|
4048
4056
|
newRowLabel?: string | undefined;
|
|
4049
4057
|
className?: string | undefined;
|
|
@@ -4075,7 +4083,7 @@ declare function useViewRecords(view: SavedViewSpec, pageSize?: number, filter?:
|
|
|
4075
4083
|
*/
|
|
4076
4084
|
membership: string;
|
|
4077
4085
|
};
|
|
4078
|
-
declare function ViewSwitcher({ view, onLayoutChange, onViewChange, onOpenRecord, openRecordId, onCloseRecord, onMoved, onNewRecordForm, onAskWhoChanged, pageSize: pageSizeAsked, titleField, filter, onClearFilter, chooser, viewId, onOrderPlaced, footer, embedded, sortOverride, searchOverride, onSearchChange, searchBox, newRowLabel, className, }: ViewSwitcherProps): react.JSX.Element;
|
|
4086
|
+
declare function ViewSwitcher({ view, onLayoutChange, onViewChange, onOpenRecord, openRecordId, onCloseRecord, onMoved, onNewRecordForm, onAskWhoChanged, pageSize: pageSizeAsked, titleField, filter, onClearFilter, chooser, viewId, onOrderPlaced, footer, embedded, sortOverride, searchOverride, onSearchChange, searchBox, hideRefusedRowActions, newRowLabel, className, }: ViewSwitcherProps): react.JSX.Element;
|
|
4079
4087
|
|
|
4080
4088
|
/** The host app's saved zone (IANA). `null` / junk clears it: the device zone applies. */
|
|
4081
4089
|
declare function setPersonTimeZone(next: string | null | undefined): void;
|
package/dist/index.d.ts
CHANGED
|
@@ -2287,6 +2287,12 @@ interface GridProps {
|
|
|
2287
2287
|
* row and hands the term through `searchOverride` (Spaces N-19). Default `true`.
|
|
2288
2288
|
*/
|
|
2289
2289
|
searchBox?: boolean | undefined;
|
|
2290
|
+
/**
|
|
2291
|
+
* `true`: a row action the person's level refuses (Archive record for a content editor, who may
|
|
2292
|
+
* change rows but not delete them) is left out of the row menu instead of drawn disabled with its
|
|
2293
|
+
* reason. Default `false` (disabled, saying why). Spaces sets it: Notion offers only what works.
|
|
2294
|
+
*/
|
|
2295
|
+
hideRefusedRowActions?: boolean | undefined;
|
|
2290
2296
|
/** The new-row line's words ("New page"). Default "Add row". */
|
|
2291
2297
|
newRowLabel?: string | undefined;
|
|
2292
2298
|
/**
|
|
@@ -4044,6 +4050,8 @@ interface ViewSwitcherProps {
|
|
|
4044
4050
|
* row and hands the term through `searchOverride` (Spaces N-19). Default `true`.
|
|
4045
4051
|
*/
|
|
4046
4052
|
searchBox?: boolean | undefined;
|
|
4053
|
+
/** `GridProps.hideRefusedRowActions`. */
|
|
4054
|
+
hideRefusedRowActions?: boolean | undefined;
|
|
4047
4055
|
/** The grid's new-row line words (`GridProps.newRowLabel`). */
|
|
4048
4056
|
newRowLabel?: string | undefined;
|
|
4049
4057
|
className?: string | undefined;
|
|
@@ -4075,7 +4083,7 @@ declare function useViewRecords(view: SavedViewSpec, pageSize?: number, filter?:
|
|
|
4075
4083
|
*/
|
|
4076
4084
|
membership: string;
|
|
4077
4085
|
};
|
|
4078
|
-
declare function ViewSwitcher({ view, onLayoutChange, onViewChange, onOpenRecord, openRecordId, onCloseRecord, onMoved, onNewRecordForm, onAskWhoChanged, pageSize: pageSizeAsked, titleField, filter, onClearFilter, chooser, viewId, onOrderPlaced, footer, embedded, sortOverride, searchOverride, onSearchChange, searchBox, newRowLabel, className, }: ViewSwitcherProps): react.JSX.Element;
|
|
4086
|
+
declare function ViewSwitcher({ view, onLayoutChange, onViewChange, onOpenRecord, openRecordId, onCloseRecord, onMoved, onNewRecordForm, onAskWhoChanged, pageSize: pageSizeAsked, titleField, filter, onClearFilter, chooser, viewId, onOrderPlaced, footer, embedded, sortOverride, searchOverride, onSearchChange, searchBox, hideRefusedRowActions, newRowLabel, className, }: ViewSwitcherProps): react.JSX.Element;
|
|
4079
4087
|
|
|
4080
4088
|
/** The host app's saved zone (IANA). `null` / junk clears it: the device zone applies. */
|
|
4081
4089
|
declare function setPersonTimeZone(next: string | null | undefined): void;
|
package/dist/index.js
CHANGED
|
@@ -1092,6 +1092,11 @@ function inColumnWords(error, fields) {
|
|
|
1092
1092
|
}
|
|
1093
1093
|
|
|
1094
1094
|
// src/askOnce.ts
|
|
1095
|
+
import { onTableStructureChanged } from "@ai-matrx/records/core";
|
|
1096
|
+
var structureEpoch = 0;
|
|
1097
|
+
onTableStructureChanged(() => {
|
|
1098
|
+
structureEpoch += 1;
|
|
1099
|
+
});
|
|
1095
1100
|
var asked = /* @__PURE__ */ new WeakMap();
|
|
1096
1101
|
var byPerson = /* @__PURE__ */ new WeakMap();
|
|
1097
1102
|
function heldFor(client) {
|
|
@@ -1122,7 +1127,7 @@ function askOnce(client, key, ask, freshMs) {
|
|
|
1122
1127
|
const held = heldFor(client);
|
|
1123
1128
|
const now = Date.now();
|
|
1124
1129
|
const kept = held.get(key);
|
|
1125
|
-
if (kept && now - kept.at <= freshMs) return kept.answer;
|
|
1130
|
+
if (kept && kept.epoch === structureEpoch && now - kept.at <= freshMs) return kept.answer;
|
|
1126
1131
|
const answer = ask().then(
|
|
1127
1132
|
(result) => {
|
|
1128
1133
|
if (!result.ok) held.delete(key);
|
|
@@ -1133,17 +1138,18 @@ function askOnce(client, key, ask, freshMs) {
|
|
|
1133
1138
|
throw thrown;
|
|
1134
1139
|
}
|
|
1135
1140
|
);
|
|
1136
|
-
held.set(key, { at: now, answer });
|
|
1141
|
+
held.set(key, { at: now, epoch: structureEpoch, answer });
|
|
1137
1142
|
return answer;
|
|
1138
1143
|
}
|
|
1139
1144
|
function forgetAsked(client, prefix) {
|
|
1140
1145
|
const held = heldFor(client);
|
|
1141
1146
|
for (const key of [...held.keys()]) if (key.startsWith(prefix)) held.delete(key);
|
|
1142
1147
|
}
|
|
1143
|
-
var FIELD_OPTIONS_FRESH_MS =
|
|
1148
|
+
var FIELD_OPTIONS_FRESH_MS = 1e4;
|
|
1144
1149
|
function fieldOptionsOnce(client, fieldId) {
|
|
1145
1150
|
return askOnce(client, `field_options:${fieldId}`, () => client.fieldOptions({ field_id: fieldId }), FIELD_OPTIONS_FRESH_MS);
|
|
1146
1151
|
}
|
|
1152
|
+
var ENRICH_CELLS_FRESH_MS = 5e3;
|
|
1147
1153
|
|
|
1148
1154
|
// src/labels.tsx
|
|
1149
1155
|
import { createContext as createContext3, useCallback, useContext as useContext3, useEffect as useEffect2, useMemo as useMemo2, useRef as useRef2, useState as useState2 } from "react";
|
|
@@ -2238,15 +2244,18 @@ function rowSection(rowId, ctx, rowText) {
|
|
|
2238
2244
|
items.push({ id: "row-history", label: "Row history", icon: "history", onSelect: () => a.openRecord?.(rowId) });
|
|
2239
2245
|
}
|
|
2240
2246
|
items.push(...ctx.extras?.row?.(rowId) ?? []);
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2247
|
+
const mayRemove = mayWrite && (ctx.mayRemoveRow ? ctx.mayRemoveRow(rowId) : true);
|
|
2248
|
+
if (mayRemove || !ctx.hideRefusedRowActions) {
|
|
2249
|
+
items.push({
|
|
2250
|
+
id: "row-archive",
|
|
2251
|
+
label: "Archive record",
|
|
2252
|
+
icon: "trash",
|
|
2253
|
+
destructive: true,
|
|
2254
|
+
separatorBefore: true,
|
|
2255
|
+
disabledReason: mayRemove ? void 0 : !mayWrite ? ctx.whyNotWrite(rowId) : ctx.whyNotRemove?.(rowId) ?? ctx.whyNotWrite(rowId),
|
|
2256
|
+
onSelect: () => a.archiveRow(rowId)
|
|
2257
|
+
});
|
|
2258
|
+
}
|
|
2250
2259
|
return { id: "row", title: ctx.extras?.rowTitle?.(rowId) || "Row", items };
|
|
2251
2260
|
}
|
|
2252
2261
|
function columnSection(columnId2, columnLabel2, ctx) {
|
|
@@ -16011,6 +16020,9 @@ function useMergedGridControls(args) {
|
|
|
16011
16020
|
canWrite,
|
|
16012
16021
|
mayWriteRow,
|
|
16013
16022
|
whyNotRow,
|
|
16023
|
+
mayRemoveRow,
|
|
16024
|
+
whyNotRemoveRow,
|
|
16025
|
+
hideRefusedRowActions,
|
|
16014
16026
|
rights,
|
|
16015
16027
|
editable,
|
|
16016
16028
|
presentation,
|
|
@@ -16268,6 +16280,9 @@ function useMergedGridControls(args) {
|
|
|
16268
16280
|
titleField: table?.title_field ?? null,
|
|
16269
16281
|
mayWriteRow: (rowId) => canWrite && mayWriteRow(rowId),
|
|
16270
16282
|
whyNotWrite: (rowId) => !editable ? "Editing is off here." : rowId ? whyNotRow(rowId) : rights.why("write"),
|
|
16283
|
+
mayRemoveRow: (rowId) => canWrite && mayRemoveRow(rowId),
|
|
16284
|
+
whyNotRemove: (rowId) => rowId ? whyNotRemoveRow(rowId) : rights.why("remove"),
|
|
16285
|
+
hideRefusedRowActions,
|
|
16271
16286
|
mayAddRecord: editable && rights.write,
|
|
16272
16287
|
whyNotAdd: editable ? rights.why("write") : "Editing is off here.",
|
|
16273
16288
|
mayStructure,
|
|
@@ -18562,12 +18577,14 @@ function useEnrichCells(tableId, recordIds) {
|
|
|
18562
18577
|
const [cells, setCells] = useState51(/* @__PURE__ */ new Map());
|
|
18563
18578
|
const [error, setError] = useState51(null);
|
|
18564
18579
|
const key = (recordIds ?? []).join(",");
|
|
18565
|
-
const
|
|
18580
|
+
const load = useCallback20(async (fresh) => {
|
|
18566
18581
|
if (!tableId || !recordIds || recordIds.length === 0) {
|
|
18567
18582
|
setCells(/* @__PURE__ */ new Map());
|
|
18568
18583
|
return;
|
|
18569
18584
|
}
|
|
18570
|
-
const
|
|
18585
|
+
const asking = `enrich_cells:${tableId}:${key}`;
|
|
18586
|
+
if (fresh) forgetAsked(client, asking);
|
|
18587
|
+
const answered = await askOnce(client, asking, () => client.enrichCells({ table_id: tableId, record_ids: recordIds }), ENRICH_CELLS_FRESH_MS);
|
|
18571
18588
|
if (!answered.ok) {
|
|
18572
18589
|
setError(answered.error);
|
|
18573
18590
|
return;
|
|
@@ -18577,9 +18594,10 @@ function useEnrichCells(tableId, recordIds) {
|
|
|
18577
18594
|
for (const cell2 of answered.data) next.set(`${cell2.record_id}:${cell2.field_key}`, cell2);
|
|
18578
18595
|
setCells(next);
|
|
18579
18596
|
}, [client, tableId, key]);
|
|
18597
|
+
const refresh = useCallback20(() => load(true), [load]);
|
|
18580
18598
|
useEffect42(() => {
|
|
18581
|
-
void
|
|
18582
|
-
}, [
|
|
18599
|
+
void load(false);
|
|
18600
|
+
}, [load]);
|
|
18583
18601
|
return { cells, refresh, error };
|
|
18584
18602
|
}
|
|
18585
18603
|
var NEVER2 = "Fill it in once and leave it alone";
|
|
@@ -23593,7 +23611,8 @@ function GridBody({
|
|
|
23593
23611
|
sortOverride,
|
|
23594
23612
|
searchOverride,
|
|
23595
23613
|
onSearchChange,
|
|
23596
|
-
searchBox = true
|
|
23614
|
+
searchBox = true,
|
|
23615
|
+
hideRefusedRowActions = false
|
|
23597
23616
|
}) {
|
|
23598
23617
|
const toolbarSlot = useTableToolbarSlot();
|
|
23599
23618
|
const tableCard = useMatrxTableCard();
|
|
@@ -23832,6 +23851,14 @@ function GridBody({
|
|
|
23832
23851
|
(rowId) => askPerRow ? rowRights(rowId)?.write ?? false : rights.write,
|
|
23833
23852
|
[askPerRow, rowRights, rights.write]
|
|
23834
23853
|
);
|
|
23854
|
+
const mayRemoveRow = useCallback28(
|
|
23855
|
+
(rowId) => askPerRow ? rowRights(rowId)?.remove ?? false : rights.remove,
|
|
23856
|
+
[askPerRow, rowRights, rights.remove]
|
|
23857
|
+
);
|
|
23858
|
+
const whyNotRemoveRow = useCallback28(
|
|
23859
|
+
(rowId) => askPerRow ? rowRights(rowId)?.why("remove") ?? rights.why("remove") : rights.why("remove"),
|
|
23860
|
+
[askPerRow, rowRights, rights]
|
|
23861
|
+
);
|
|
23835
23862
|
const whyNotRow = useCallback28(
|
|
23836
23863
|
(rowId) => askPerRow ? rowRights(rowId)?.why("write") ?? rights.why("write") : rights.why("write"),
|
|
23837
23864
|
[askPerRow, rowRights, rights]
|
|
@@ -24502,6 +24529,9 @@ function GridBody({
|
|
|
24502
24529
|
canWrite,
|
|
24503
24530
|
mayWriteRow,
|
|
24504
24531
|
whyNotRow,
|
|
24532
|
+
mayRemoveRow,
|
|
24533
|
+
whyNotRemoveRow,
|
|
24534
|
+
hideRefusedRowActions,
|
|
24505
24535
|
rights,
|
|
24506
24536
|
editable: Boolean(editable),
|
|
24507
24537
|
readOnly,
|
|
@@ -34123,6 +34153,7 @@ function ViewSwitcher({
|
|
|
34123
34153
|
searchOverride,
|
|
34124
34154
|
onSearchChange,
|
|
34125
34155
|
searchBox,
|
|
34156
|
+
hideRefusedRowActions,
|
|
34126
34157
|
newRowLabel,
|
|
34127
34158
|
className
|
|
34128
34159
|
}) {
|
|
@@ -34168,6 +34199,7 @@ function ViewSwitcher({
|
|
|
34168
34199
|
...searchOverride !== void 0 ? { searchOverride } : {},
|
|
34169
34200
|
...onSearchChange ? { onSearchChange } : {},
|
|
34170
34201
|
...searchBox === false ? { searchBox } : {},
|
|
34202
|
+
...hideRefusedRowActions ? { hideRefusedRowActions } : {},
|
|
34171
34203
|
...newRowLabel ? { newRowLabel } : {},
|
|
34172
34204
|
...filter ? { filter } : {},
|
|
34173
34205
|
...onClearFilter ? { onClearFilter } : {},
|