@ai-matrx/records-ui 0.85.15 → 0.85.16
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 +32 -0
- package/dist/index.cjs +232 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +39 -1
- package/dist/index.d.ts +39 -1
- package/dist/index.js +233 -19
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,37 @@
|
|
|
1
1
|
# Changelog — @ai-matrx/records-ui
|
|
2
2
|
|
|
3
|
+
## 0.85.16
|
|
4
|
+
|
|
5
|
+
Automatic changed-only republish (docs/metadata drift since the last tag — see
|
|
6
|
+
`git diff npm/records-ui/v0.85.15..npm/records-ui/v0.85.16 -- apps/shared/records-ui`).
|
|
7
|
+
No source changes intended and no consumer action required.
|
|
8
|
+
|
|
9
|
+
## Unreleased — lane VIEW-STATE-PERSONAL (2026-09-25)
|
|
10
|
+
|
|
11
|
+
Needs `@ai-matrx/records` with `viewLookRead` / `viewLookSet` (Unreleased) and the store doors
|
|
12
|
+
`custom.view_look_read` / `custom.view_look_set` (live on production, 2026-09-25 19:19Z).
|
|
13
|
+
|
|
14
|
+
### A look at a view is yours until you save it (VERIFIER-23 item 1)
|
|
15
|
+
|
|
16
|
+
* **Every view-configuration change a person makes while looking is HER look, not the view's.** On
|
|
17
|
+
production the owner's *Group by → Status* on a board became the tenant liaison's board the next
|
|
18
|
+
time she opened it: `TablePage` merged every pick onto the shared view (`view_declare`). Now a
|
|
19
|
+
pick of the board's grouping, the calendar's date field, a sort, a filter, a hidden column, a
|
|
20
|
+
width, a colour or the layout is kept for that person through `custom.view_look_set` and laid
|
|
21
|
+
over the view (`applyLook`); a reload keeps it; nobody else sees it. The view row is never
|
|
22
|
+
written by a pick. (Airtable and Notion's rule; Notion's "Save for everyone" / "Reset".)
|
|
23
|
+
* **One line says so, with its doors** (`[data-view-look]`): *"You changed how this view looks. Only
|
|
24
|
+
you see it."* · **Save to view** (someone who may edit the table; the one `view_declare`, and the
|
|
25
|
+
default view's layout stays the person's look — "Make … the default" is that door) · **Save as
|
|
26
|
+
new view** (editor; the look becomes a view of its own) · **Reset to view** (everyone; the look is
|
|
27
|
+
archived). A viewer never sees Save to view or Save as new view — absent, not dead.
|
|
28
|
+
* **Reorder is offered only to someone who may edit the table**: a hand-set order is the view's
|
|
29
|
+
sort for everybody (`view_record_order_set` now needs editor; the store refuses it otherwise).
|
|
30
|
+
* New module `viewLook.ts` (exported): `ViewLook`, `lookPart`, `lookDocument`, `lookFromDocument`,
|
|
31
|
+
`applyLook`, `lookDiffers`, `saveToViewPlan`, `readLooks`, `keepLook`, `LOOK_WORDS`.
|
|
32
|
+
* Suite `a-look-at-a-view-is-yours-until-you-save-it.test.tsx`: RED 4/6 on the prior `TablePage` /
|
|
33
|
+
`ViewSwitcher` (the pick sent `view_declare`; no look, no Save / Reset) → GREEN 6/6.
|
|
34
|
+
|
|
3
35
|
## 0.85.15 (2026-09-25 — published by PUBLISH-SWEEP-7)
|
|
4
36
|
|
|
5
37
|
The tagged 0.85.14 never reached npm: its deterministic gate failed on `NeverRecorded … custom.field_declare` (fixture recorded against records 0.58.11). The fixture is re-recorded (below); everything 0.85.14 carried ships here. Needs `@ai-matrx/records` >= 0.58.13 (`viewDesignate` / `custom.view_designate`).
|
package/dist/index.cjs
CHANGED
|
@@ -116,6 +116,7 @@ __export(src_exports, {
|
|
|
116
116
|
LAYOUT_NEEDS: () => LAYOUT_NEEDS,
|
|
117
117
|
LAYOUT_NO_FIELD: () => LAYOUT_NO_FIELD,
|
|
118
118
|
LEVEL_WORD: () => LEVEL_WORD,
|
|
119
|
+
LOOK_WORDS: () => LOOK_WORDS,
|
|
119
120
|
MACHINE_IDENTITY: () => MACHINE_IDENTITY,
|
|
120
121
|
MAX_ROW_HEIGHT: () => MAX_ROW_HEIGHT,
|
|
121
122
|
MIN_ROW_HEIGHT: () => MIN_ROW_HEIGHT,
|
|
@@ -215,6 +216,7 @@ __export(src_exports, {
|
|
|
215
216
|
actorBadge: () => actorBadge,
|
|
216
217
|
actorWords: () => actorWords,
|
|
217
218
|
addFields: () => import_core11.addFields,
|
|
219
|
+
applyLook: () => applyLook,
|
|
218
220
|
archivedRowLine: () => archivedRowLine,
|
|
219
221
|
asRefusal: () => asRefusal,
|
|
220
222
|
askableFields: () => askableFields,
|
|
@@ -274,11 +276,16 @@ __export(src_exports, {
|
|
|
274
276
|
isPlainFieldType: () => isPlainFieldType,
|
|
275
277
|
isRelationFieldType: () => isRelationFieldType,
|
|
276
278
|
isSignatureField: () => isSignatureField,
|
|
279
|
+
keepLook: () => keepLook,
|
|
277
280
|
keptByTheApp: () => keptByTheApp,
|
|
278
281
|
keyFor: () => keyFor,
|
|
279
282
|
kindsWithNoChoice: () => kindsWithNoChoice,
|
|
280
283
|
laneFor: () => laneFor,
|
|
281
284
|
lastChangeSentence: () => lastChangeSentence,
|
|
285
|
+
lookDiffers: () => lookDiffers,
|
|
286
|
+
lookDocument: () => lookDocument,
|
|
287
|
+
lookFromDocument: () => lookFromDocument,
|
|
288
|
+
lookPart: () => lookPart,
|
|
282
289
|
looksLikeId: () => looksLikeId,
|
|
283
290
|
machineIdentityIn: () => machineIdentityIn,
|
|
284
291
|
mayNotRestoreLine: () => mayNotRestoreLine,
|
|
@@ -299,6 +306,7 @@ __export(src_exports, {
|
|
|
299
306
|
previewWords: () => previewWords,
|
|
300
307
|
publiclyAnswerable: () => publiclyAnswerable,
|
|
301
308
|
railFromParam: () => railFromParam,
|
|
309
|
+
readLooks: () => readLooks,
|
|
302
310
|
recordName: () => recordName,
|
|
303
311
|
recordNameIn: () => recordNameIn,
|
|
304
312
|
recordsDataSource: () => recordsDataSource,
|
|
@@ -312,6 +320,7 @@ __export(src_exports, {
|
|
|
312
320
|
revokeConsequence: () => revokeConsequence,
|
|
313
321
|
rowName: () => rowName,
|
|
314
322
|
rowNameIn: () => rowNameIn,
|
|
323
|
+
saveToViewPlan: () => saveToViewPlan,
|
|
315
324
|
saveViewPatch: () => saveViewPatch,
|
|
316
325
|
scalarText: () => scalarText,
|
|
317
326
|
seedIsSatisfied: () => seedIsSatisfied,
|
|
@@ -10831,6 +10840,86 @@ function computedInPlainWords(row, field) {
|
|
|
10831
10840
|
return `${name} was worked out as ${shown3}${at}.`;
|
|
10832
10841
|
}
|
|
10833
10842
|
|
|
10843
|
+
// src/viewLook.ts
|
|
10844
|
+
var LOOK_KEYS = [
|
|
10845
|
+
"layout",
|
|
10846
|
+
"groupField",
|
|
10847
|
+
"swimlaneField",
|
|
10848
|
+
"collapsedColumns",
|
|
10849
|
+
"measure",
|
|
10850
|
+
"dateField",
|
|
10851
|
+
"imageField",
|
|
10852
|
+
"sorts",
|
|
10853
|
+
"where",
|
|
10854
|
+
"presentation"
|
|
10855
|
+
];
|
|
10856
|
+
function lookPart(patch) {
|
|
10857
|
+
const out = {};
|
|
10858
|
+
for (const key of LOOK_KEYS) {
|
|
10859
|
+
if (patch[key] !== void 0) out[key] = patch[key];
|
|
10860
|
+
}
|
|
10861
|
+
return out;
|
|
10862
|
+
}
|
|
10863
|
+
function lookDocument(look) {
|
|
10864
|
+
return viewSettingsPatch(look);
|
|
10865
|
+
}
|
|
10866
|
+
function lookFromDocument(doc) {
|
|
10867
|
+
const data = doc ?? {};
|
|
10868
|
+
const read = viewSettings(data);
|
|
10869
|
+
const out = {};
|
|
10870
|
+
const has = (key) => Object.prototype.hasOwnProperty.call(data, key);
|
|
10871
|
+
if (has("layout") && VIEW_LAYOUTS.includes(String(data["layout"]))) {
|
|
10872
|
+
out.layout = data["layout"];
|
|
10873
|
+
}
|
|
10874
|
+
if (has("group_field")) out.groupField = read.groupField;
|
|
10875
|
+
if (has("swimlane_field")) out.swimlaneField = read.swimlaneField;
|
|
10876
|
+
if (has("collapsed_columns")) out.collapsedColumns = read.collapsedColumns;
|
|
10877
|
+
if (has("measure")) out.measure = read.measure;
|
|
10878
|
+
if (has("date_field")) out.dateField = read.dateField;
|
|
10879
|
+
if (has("image_field")) out.imageField = read.imageField;
|
|
10880
|
+
if (has("sorts")) out.sorts = read.sorts;
|
|
10881
|
+
if (has("where")) out.where = read.where;
|
|
10882
|
+
if (has("presentation")) out.presentation = parseGridPresentation(data["presentation"]);
|
|
10883
|
+
return out;
|
|
10884
|
+
}
|
|
10885
|
+
function applyLook(view, look) {
|
|
10886
|
+
if (!look) return view;
|
|
10887
|
+
return { ...view, ...look };
|
|
10888
|
+
}
|
|
10889
|
+
function lookDiffers(view, look) {
|
|
10890
|
+
if (!look) return false;
|
|
10891
|
+
const shown3 = applyLook(view, look);
|
|
10892
|
+
return LOOK_KEYS.some(
|
|
10893
|
+
(key) => look[key] !== void 0 && JSON.stringify(shown3[key] ?? null) !== JSON.stringify(view[key] ?? null)
|
|
10894
|
+
);
|
|
10895
|
+
}
|
|
10896
|
+
function saveToViewPlan(view, look) {
|
|
10897
|
+
const patch = viewPatchFor(view, look);
|
|
10898
|
+
const left = {};
|
|
10899
|
+
if (look.layout !== void 0 && patch.layout === void 0 && look.layout !== view.layout) left.layout = look.layout;
|
|
10900
|
+
return { patch, left: Object.keys(left).length > 0 ? left : null };
|
|
10901
|
+
}
|
|
10902
|
+
async function readLooks(client, tableId) {
|
|
10903
|
+
const answered = await client.viewLookRead({ table_id: tableId });
|
|
10904
|
+
if (!answered.ok) return answered;
|
|
10905
|
+
const out = {};
|
|
10906
|
+
for (const [viewId, row] of Object.entries(answered.data ?? {})) {
|
|
10907
|
+
out[viewId] = lookFromDocument(row?.look ?? null);
|
|
10908
|
+
}
|
|
10909
|
+
return { ok: true, data: out };
|
|
10910
|
+
}
|
|
10911
|
+
async function keepLook(client, tableId, viewId, look) {
|
|
10912
|
+
const doc = look ? lookDocument(look) : null;
|
|
10913
|
+
return client.viewLookSet({ table_id: tableId, view_id: viewId, look: doc && Object.keys(doc).length > 0 ? doc : null });
|
|
10914
|
+
}
|
|
10915
|
+
var LOOK_WORDS = {
|
|
10916
|
+
yours: "You changed how this view looks. Only you see it.",
|
|
10917
|
+
saveToView: "Save to view",
|
|
10918
|
+
saveAsNew: "Save as new view",
|
|
10919
|
+
reset: "Reset to view",
|
|
10920
|
+
newName: "Name for the new view"
|
|
10921
|
+
};
|
|
10922
|
+
|
|
10834
10923
|
// src/ViewSwitcher.tsx
|
|
10835
10924
|
var import_react67 = require("react");
|
|
10836
10925
|
var import_react68 = require("@ai-matrx/records/react");
|
|
@@ -11726,10 +11815,14 @@ function ViewSwitcher({
|
|
|
11726
11815
|
viewId,
|
|
11727
11816
|
order: local.order !== void 0 ? local.order : view.order ?? null,
|
|
11728
11817
|
sorts: local.sorts ?? view.sorts ?? [],
|
|
11729
|
-
|
|
11730
|
-
|
|
11731
|
-
|
|
11732
|
-
|
|
11818
|
+
/* Placing the rows saves the VIEW's order, so Reorder is offered only when the
|
|
11819
|
+
host bound it (TablePage: to someone who may edit the table). */
|
|
11820
|
+
...onOrderPlaced ? {
|
|
11821
|
+
onPlaced: () => {
|
|
11822
|
+
setLocal((held) => ({ ...held, order: "manual", sorts: [] }));
|
|
11823
|
+
onOrderPlaced();
|
|
11824
|
+
}
|
|
11825
|
+
} : {},
|
|
11733
11826
|
...onViewChange ? {
|
|
11734
11827
|
onUseSort: (sort) => change({ sorts: [sort], order: "sorted" })
|
|
11735
11828
|
} : {}
|
|
@@ -22646,6 +22739,21 @@ function TablePage({
|
|
|
22646
22739
|
const askedInWords = filter ? filterInWords(filter, pageFields.data ?? []) : null;
|
|
22647
22740
|
const organizationId = (0, import_react147.useRecordsClient)().config.organizationId;
|
|
22648
22741
|
const [view, setView] = (0, import_react146.useState)(null);
|
|
22742
|
+
const [looks, setLooks] = (0, import_react146.useState)(void 0);
|
|
22743
|
+
(0, import_react146.useEffect)(() => {
|
|
22744
|
+
let live = true;
|
|
22745
|
+
setLooks(void 0);
|
|
22746
|
+
void readLooks(client, tableId).then((answered) => {
|
|
22747
|
+
if (!live) return;
|
|
22748
|
+
setLooks(answered.ok ? answered.data : {});
|
|
22749
|
+
});
|
|
22750
|
+
return () => {
|
|
22751
|
+
live = false;
|
|
22752
|
+
};
|
|
22753
|
+
}, [client, tableId]);
|
|
22754
|
+
const look = view && looks ? looks[view.id] : void 0;
|
|
22755
|
+
const shown3 = view ? applyLook(view, look) : null;
|
|
22756
|
+
const [viewsEpoch, setViewsEpoch] = (0, import_react146.useState)(0);
|
|
22649
22757
|
const opening = openingRail(activeRecordId, activeRail);
|
|
22650
22758
|
const hostLayouts = useRecordsUi().layouts ?? [];
|
|
22651
22759
|
const hostLayoutFor = (asked) => openingHostLayout(asked, hostLayouts);
|
|
@@ -22680,9 +22788,9 @@ function TablePage({
|
|
|
22680
22788
|
if (hostFromLink || opened.layout || layoutChosen) return;
|
|
22681
22789
|
setHostLayout(face.hostLayout);
|
|
22682
22790
|
}, [face.kind, face.kind === "designated" ? face.hostLayout : null, layoutChosen]);
|
|
22683
|
-
const faceUnknown = !hostFromLink && !opened.layout && (views === void 0 || Array.isArray(views) && views.length > 0 && view === null);
|
|
22684
|
-
const shownLayout = layoutFromLink ??
|
|
22685
|
-
const shownFilter = filter ?? (
|
|
22791
|
+
const faceUnknown = !hostFromLink && !opened.layout && (views === void 0 || Array.isArray(views) && views.length > 0 && (view === null || looks === void 0));
|
|
22792
|
+
const shownLayout = layoutFromLink ?? shown3?.layout ?? "grid";
|
|
22793
|
+
const shownFilter = filter ?? (shown3?.where ? shown3.where : null) ?? (shown3?.filters && Object.keys(shown3.filters).length > 0 ? shown3.filters : null);
|
|
22686
22794
|
const press = (pressed) => {
|
|
22687
22795
|
const next = chooseSurface(surface, pressed);
|
|
22688
22796
|
setSurface(next);
|
|
@@ -22737,16 +22845,79 @@ function TablePage({
|
|
|
22737
22845
|
async (asked) => {
|
|
22738
22846
|
const current = view;
|
|
22739
22847
|
if (!current) return;
|
|
22740
|
-
const
|
|
22741
|
-
|
|
22742
|
-
|
|
22848
|
+
const part = lookPart(asked);
|
|
22849
|
+
if (Object.keys(part).length === 0) return;
|
|
22850
|
+
const before = looks?.[current.id];
|
|
22851
|
+
const next = { ...before ?? {}, ...part };
|
|
22852
|
+
setLooks((all) => ({ ...all ?? {}, [current.id]: next }));
|
|
22743
22853
|
setViewSaveRefused(null);
|
|
22744
|
-
const
|
|
22745
|
-
if (
|
|
22746
|
-
setViewSaveRefused({ error:
|
|
22854
|
+
const kept = await keepLook(client, tableId, current.id, next);
|
|
22855
|
+
if (kept.ok) return;
|
|
22856
|
+
setViewSaveRefused({ error: kept.error, patch: asked, lookBefore: before });
|
|
22747
22857
|
},
|
|
22748
|
-
[client, tableId, view]
|
|
22858
|
+
[client, tableId, view, looks]
|
|
22749
22859
|
);
|
|
22860
|
+
const lookShowing = Boolean(view && looks && lookDiffers(view, looks[view.id]));
|
|
22861
|
+
const [lookRefused, setLookRefused] = (0, import_react146.useState)(null);
|
|
22862
|
+
const [namingLook, setNamingLook] = (0, import_react146.useState)(false);
|
|
22863
|
+
const [lookName, setLookName] = (0, import_react146.useState)("");
|
|
22864
|
+
const resetLook = async () => {
|
|
22865
|
+
const current = view;
|
|
22866
|
+
if (!current) return;
|
|
22867
|
+
setLookRefused(null);
|
|
22868
|
+
setViewSaveRefused(null);
|
|
22869
|
+
const before = looks?.[current.id];
|
|
22870
|
+
setLooks((all) => {
|
|
22871
|
+
const { [current.id]: _gone, ...rest } = all ?? {};
|
|
22872
|
+
return rest;
|
|
22873
|
+
});
|
|
22874
|
+
const kept = await keepLook(client, tableId, current.id, null);
|
|
22875
|
+
if (!kept.ok) {
|
|
22876
|
+
setLooks((all) => ({ ...all ?? {}, [current.id]: before ?? {} }));
|
|
22877
|
+
setLookRefused(kept.error);
|
|
22878
|
+
}
|
|
22879
|
+
};
|
|
22880
|
+
const saveLookToView = async () => {
|
|
22881
|
+
const current = view;
|
|
22882
|
+
const mine = current && looks ? looks[current.id] : void 0;
|
|
22883
|
+
if (!current || !mine) return;
|
|
22884
|
+
setLookRefused(null);
|
|
22885
|
+
const { patch, left } = saveToViewPlan(current, mine);
|
|
22886
|
+
if (Object.keys(viewPatchDocument(patch)).length > 0) {
|
|
22887
|
+
const written = await saveViewPatch(client, tableId, current.id, patch);
|
|
22888
|
+
if (!written.ok) {
|
|
22889
|
+
setLookRefused(written.error);
|
|
22890
|
+
return;
|
|
22891
|
+
}
|
|
22892
|
+
setView({ ...current, ...patch });
|
|
22893
|
+
}
|
|
22894
|
+
setLooks((all) => {
|
|
22895
|
+
const { [current.id]: _saved, ...rest } = all ?? {};
|
|
22896
|
+
return left ? { ...rest, [current.id]: left } : rest;
|
|
22897
|
+
});
|
|
22898
|
+
const kept = await keepLook(client, tableId, current.id, left);
|
|
22899
|
+
if (!kept.ok) setLookRefused(kept.error);
|
|
22900
|
+
};
|
|
22901
|
+
const saveLookAsNewView = async (name) => {
|
|
22902
|
+
const current = view;
|
|
22903
|
+
const seen = shown3;
|
|
22904
|
+
if (!current || !seen || name.trim() === "") return;
|
|
22905
|
+
setLookRefused(null);
|
|
22906
|
+
const written = await declareView(client, { ...seen, name: name.trim(), subject: tableId, isDefault: false });
|
|
22907
|
+
if (!written.ok) {
|
|
22908
|
+
setLookRefused(written.error);
|
|
22909
|
+
return;
|
|
22910
|
+
}
|
|
22911
|
+
setNamingLook(false);
|
|
22912
|
+
setLookName("");
|
|
22913
|
+
setLooks((all) => {
|
|
22914
|
+
const { [current.id]: _moved, ...rest } = all ?? {};
|
|
22915
|
+
return rest;
|
|
22916
|
+
});
|
|
22917
|
+
void keepLook(client, tableId, current.id, null);
|
|
22918
|
+
setPickedViewId(written.data);
|
|
22919
|
+
setViewsEpoch((n) => n + 1);
|
|
22920
|
+
};
|
|
22750
22921
|
const [designateRefused, setDesignateRefused] = (0, import_react146.useState)(null);
|
|
22751
22922
|
const opensAs = view?.isDefault ? openingLayoutOf(view) : null;
|
|
22752
22923
|
const canDesignate = Boolean(rights.write && view && layoutShowing && layoutShowing !== opensAs);
|
|
@@ -22789,7 +22960,8 @@ function TablePage({
|
|
|
22789
22960
|
quietWhenAlone: !showViews,
|
|
22790
22961
|
seed: seedViews ?? [defaultView(tableId)],
|
|
22791
22962
|
className: "min-w-0 flex-1"
|
|
22792
|
-
}
|
|
22963
|
+
},
|
|
22964
|
+
viewsEpoch
|
|
22793
22965
|
),
|
|
22794
22966
|
/* @__PURE__ */ (0, import_jsx_runtime79.jsxs)("div", { className: "ml-auto flex shrink-0 items-center gap-1", "data-table-cluster": "", children: [
|
|
22795
22967
|
chooserInline ? /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)("div", { className: "flex items-center gap-0.5", role: "group", "aria-label": "Layout", children: [
|
|
@@ -22816,7 +22988,7 @@ function TablePage({
|
|
|
22816
22988
|
`host:${option.id}`
|
|
22817
22989
|
))
|
|
22818
22990
|
] }) : null,
|
|
22819
|
-
main === "records" && !hostLayout ? /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(ViewFilter, { tableId, view, onApply: (where) => void patchView({ where }) }) : null,
|
|
22991
|
+
main === "records" && !hostLayout ? /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(ViewFilter, { tableId, view: shown3, onApply: (where) => void patchView({ where }) }) : null,
|
|
22820
22992
|
rights.write && view && main === "records" && !hostLayout && shownLayout !== "grid" ? /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(import_design_system71.Button, { size: "sm", onClick: () => show("new-record"), children: "New record" }) : null,
|
|
22821
22993
|
openedFromMenu ? /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(
|
|
22822
22994
|
import_design_system71.Button,
|
|
@@ -22916,7 +23088,13 @@ function TablePage({
|
|
|
22916
23088
|
size: "sm",
|
|
22917
23089
|
variant: "ghost",
|
|
22918
23090
|
onClick: () => {
|
|
22919
|
-
|
|
23091
|
+
const current = view;
|
|
23092
|
+
if (current) {
|
|
23093
|
+
setLooks((all) => {
|
|
23094
|
+
const { [current.id]: _dropped, ...rest } = all ?? {};
|
|
23095
|
+
return viewSaveRefused.lookBefore ? { ...rest, [current.id]: viewSaveRefused.lookBefore } : rest;
|
|
23096
|
+
});
|
|
23097
|
+
}
|
|
22920
23098
|
setViewSaveRefused(null);
|
|
22921
23099
|
},
|
|
22922
23100
|
children: "Discard"
|
|
@@ -22925,6 +23103,36 @@ function TablePage({
|
|
|
22925
23103
|
] })
|
|
22926
23104
|
}
|
|
22927
23105
|
) : null,
|
|
23106
|
+
lookShowing && main === "records" ? /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)("div", { className: "flex min-w-0 flex-wrap items-center gap-1.5 text-xs text-muted-foreground", "data-view-look": "", children: [
|
|
23107
|
+
/* @__PURE__ */ (0, import_jsx_runtime79.jsx)("span", { className: "truncate", children: LOOK_WORDS.yours }),
|
|
23108
|
+
rights.write && view && Object.keys(viewPatchDocument(saveToViewPlan(view, look ?? {}).patch)).length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(import_design_system71.Button, { size: "sm", variant: "outline", className: "h-7", onClick: () => void saveLookToView(), "data-view-look-save": "", children: LOOK_WORDS.saveToView }) : null,
|
|
23109
|
+
rights.write ? namingLook ? /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)(
|
|
23110
|
+
"form",
|
|
23111
|
+
{
|
|
23112
|
+
className: "flex items-center gap-1",
|
|
23113
|
+
onSubmit: (e) => {
|
|
23114
|
+
e.preventDefault();
|
|
23115
|
+
void saveLookAsNewView(lookName);
|
|
23116
|
+
},
|
|
23117
|
+
children: [
|
|
23118
|
+
/* @__PURE__ */ (0, import_jsx_runtime79.jsx)(
|
|
23119
|
+
import_design_system71.Input,
|
|
23120
|
+
{
|
|
23121
|
+
autoFocus: true,
|
|
23122
|
+
"aria-label": LOOK_WORDS.newName,
|
|
23123
|
+
value: lookName,
|
|
23124
|
+
onChange: (e) => setLookName(e.target.value),
|
|
23125
|
+
className: "h-7 w-44 text-xs",
|
|
23126
|
+
placeholder: "View name"
|
|
23127
|
+
}
|
|
23128
|
+
),
|
|
23129
|
+
/* @__PURE__ */ (0, import_jsx_runtime79.jsx)(import_design_system71.Button, { size: "sm", type: "submit", className: "h-7", disabled: lookName.trim() === "", children: "Save" })
|
|
23130
|
+
]
|
|
23131
|
+
}
|
|
23132
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(import_design_system71.Button, { size: "sm", variant: "ghost", className: "h-7", onClick: () => setNamingLook(true), "data-view-look-save-new": "", children: LOOK_WORDS.saveAsNew }) : null,
|
|
23133
|
+
/* @__PURE__ */ (0, import_jsx_runtime79.jsx)(import_design_system71.Button, { size: "sm", variant: "ghost", className: "h-7", onClick: () => void resetLook(), "data-view-look-reset": "", children: LOOK_WORDS.reset })
|
|
23134
|
+
] }) : null,
|
|
23135
|
+
lookRefused ? /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(RefusalNotice, { error: lookRefused }) : null,
|
|
22928
23136
|
main === "dashboards" ? /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(DashboardCanvas, { tableId, activeDashboardId: activeDashboardId ?? null }) : main === "archived" ? (
|
|
22929
23137
|
/* THE ROWS THAT LEFT. Restoring one puts it back in the grid, so the
|
|
22930
23138
|
page returns to the records rather than leaving the person looking
|
|
@@ -22960,7 +23168,7 @@ function TablePage({
|
|
|
22960
23168
|
chooser: false,
|
|
22961
23169
|
openExport: () => setRail("export"),
|
|
22962
23170
|
view: {
|
|
22963
|
-
...
|
|
23171
|
+
...shown3 ?? defaultView(tableId),
|
|
22964
23172
|
layout: shownLayout,
|
|
22965
23173
|
// The address's field wins for this visit; silence keeps the
|
|
22966
23174
|
// saved view's own choice, exactly as it always did.
|
|
@@ -22981,7 +23189,12 @@ function TablePage({
|
|
|
22981
23189
|
...view ? { onViewChange: (patch) => void patchView(patch) } : {},
|
|
22982
23190
|
...view ? {
|
|
22983
23191
|
viewId: view.id,
|
|
22984
|
-
|
|
23192
|
+
/* A hand-set order is the VIEW's sort for everybody (VIEW-STATE-PERSONAL): placing
|
|
23193
|
+
the rows is saving to the view, so it is offered to someone who may edit the
|
|
23194
|
+
table and is absent otherwise (the store refuses it too). */
|
|
23195
|
+
...rights.write ? {
|
|
23196
|
+
onOrderPlaced: () => setView((current) => current ? { ...current, order: "manual", sorts: [] } : current)
|
|
23197
|
+
} : {}
|
|
22985
23198
|
} : {},
|
|
22986
23199
|
...rights.write ? { onNewRecordForm: () => setRail("new-record") } : {},
|
|
22987
23200
|
onOpenRecord: (recordId) => {
|