nexus-shared 3.1.0 → 4.0.0
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 +2268 -446
- package/LICENSE +21 -21
- package/README.md +1705 -1084
- package/dist/Client.Index.d.ts +17 -0
- package/dist/Client.Index.js +17 -0
- package/dist/Components/Documents/DocumentFrame.d.ts +50 -0
- package/dist/Components/Documents/DocumentFrame.js +83 -0
- package/dist/Components/Documents/Menu.d.ts +4 -0
- package/dist/Components/Documents/Menu.js +40 -24
- package/dist/Components/Documents/PrintDocument.d.ts +95 -0
- package/dist/Components/Documents/PrintDocument.js +62 -0
- package/dist/Components/Documents/Tabs.d.ts +59 -0
- package/dist/Components/Documents/Tabs.js +70 -0
- package/dist/Components/Forms/ApiForm.js +19 -2
- package/dist/Components/Forms/Crud.d.ts +2 -2
- package/dist/Components/Forms/Crud.js +871 -377
- package/dist/Components/Forms/CrudActions.d.ts +136 -0
- package/dist/Components/Forms/CrudActions.js +184 -0
- package/dist/Components/Forms/CrudHistory.d.ts +66 -0
- package/dist/Components/Forms/CrudHistory.js +140 -0
- package/dist/Components/Forms/CrudNarrowPicker.d.ts +31 -0
- package/dist/Components/Forms/CrudNarrowPicker.js +180 -0
- package/dist/Components/Forms/CrudParts.d.ts +30 -2
- package/dist/Components/Forms/CrudParts.js +56 -5
- package/dist/Components/Forms/CrudRowForms.d.ts +26 -0
- package/dist/Components/Forms/CrudRowForms.js +114 -0
- package/dist/Components/Forms/CrudScopes.d.ts +28 -0
- package/dist/Components/Forms/CrudScopes.js +76 -0
- package/dist/Components/Forms/CrudTree.d.ts +90 -0
- package/dist/Components/Forms/CrudTree.js +363 -0
- package/dist/Components/Forms/CrudWorkspace.d.ts +63 -0
- package/dist/Components/Forms/CrudWorkspace.js +169 -0
- package/dist/Components/Forms/ExcelImport.js +3 -3
- package/dist/Components/Forms/Form.d.ts +4 -4
- package/dist/Components/Forms/Form.js +125 -16
- package/dist/Components/Forms/FormLeaveGuard.d.ts +44 -0
- package/dist/Components/Forms/FormLeaveGuard.js +65 -0
- package/dist/Components/Forms/RecordFlows.d.ts +50 -0
- package/dist/Components/Forms/RecordFlows.js +282 -0
- package/dist/Components/Forms/SubmitForm.d.ts +37 -2
- package/dist/Components/Forms/SubmitForm.js +195 -10
- package/dist/Components/Inputs/CheckBox.js +1 -1
- package/dist/Components/Inputs/ChoiceField.d.ts +21 -1
- package/dist/Components/Inputs/ChoiceField.js +28 -2
- package/dist/Components/Inputs/CodeBox.d.ts +69 -0
- package/dist/Components/Inputs/CodeBox.js +316 -0
- package/dist/Components/Inputs/DatePicker.js +4 -1
- package/dist/Components/Inputs/DateRangePicker.js +4 -1
- package/dist/Components/Inputs/DateTimePicker.js +4 -1
- package/dist/Components/Inputs/Dropdown.d.ts +13 -0
- package/dist/Components/Inputs/Dropdown.js +8 -5
- package/dist/Components/Inputs/DropdownParts.d.ts +3 -1
- package/dist/Components/Inputs/DropdownParts.js +16 -4
- package/dist/Components/Inputs/Field.d.ts +7 -1
- package/dist/Components/Inputs/Field.js +2 -2
- package/dist/Components/Inputs/GroupForm.d.ts +6 -6
- package/dist/Components/Inputs/GroupForm.js +10 -11
- package/dist/Components/Inputs/InputRenderer.d.ts +9 -6
- package/dist/Components/Inputs/InputRenderer.js +39 -31
- package/dist/Components/Inputs/NumberBox.js +4 -2
- package/dist/Components/Inputs/PictureInput.d.ts +41 -0
- package/dist/Components/Inputs/PictureInput.js +70 -0
- package/dist/Components/Inputs/RadioGroup.d.ts +16 -3
- package/dist/Components/Inputs/RadioGroup.js +8 -3
- package/dist/Components/Inputs/RowsInput.d.ts +1 -1
- package/dist/Components/Inputs/RowsInput.js +18 -3
- package/dist/Components/Inputs/TabularForm.d.ts +5 -5
- package/dist/Components/Inputs/TabularForm.js +29 -29
- package/dist/Components/Inputs/TextArea.d.ts +6 -0
- package/dist/Components/Inputs/TextArea.js +14 -2
- package/dist/Components/Inputs/TextBox.js +4 -1
- package/dist/Components/Inputs/TextBoxTypes.d.ts +6 -0
- package/dist/Components/Inputs/TextBoxTypes.js +17 -0
- package/dist/Components/Inputs/TimePicker.js +4 -1
- package/dist/Components/Inputs/TreeView.d.ts +107 -6
- package/dist/Components/Inputs/TreeView.js +513 -30
- package/dist/Components/Layouts/MessageBox.d.ts +15 -2
- package/dist/Components/Layouts/MessageBox.js +56 -7
- package/dist/Components/Layouts/Popup.d.ts +13 -6
- package/dist/Components/Layouts/Popup.js +37 -9
- package/dist/Components/Layouts/PopupDock.d.ts +3 -1
- package/dist/Components/Layouts/PopupDock.js +2 -1
- package/dist/Components/Layouts/PopupHost.js +5 -4
- package/dist/Components/Layouts/ThemePicker.d.ts +3 -2
- package/dist/Components/Layouts/ThemePicker.js +16 -4
- package/dist/Components/Viewers/DataTable.js +205 -61
- package/dist/Components/Viewers/DataTableFilters.d.ts +1 -1
- package/dist/Components/Viewers/DataTableFilters.js +17 -2
- package/dist/Components/Viewers/DataTableParts.d.ts +46 -12
- package/dist/Components/Viewers/DataTableParts.js +62 -21
- package/dist/Components/Viewers/OwnerFiles.d.ts +175 -0
- package/dist/Components/Viewers/OwnerFiles.js +589 -0
- package/dist/Components/Viewers/QrCodeImage.d.ts +22 -0
- package/dist/Components/Viewers/QrCodeImage.js +15 -0
- package/dist/Components/Viewers/RecordCards.d.ts +16 -0
- package/dist/Components/Viewers/RecordCards.js +509 -0
- package/dist/Helpers/ApiModules.d.ts +3 -34
- package/dist/Helpers/ApiModules.js +3 -3
- package/dist/Helpers/ApiRoutes.d.ts +68 -26
- package/dist/Helpers/ApiRoutes.js +31 -27
- package/dist/Helpers/ArrayHelpers.d.ts +0 -0
- package/dist/Helpers/ArrayHelpers.js +2 -0
- package/dist/Helpers/BusyHooks.d.ts +6 -0
- package/dist/Helpers/BusyHooks.js +39 -0
- package/dist/Helpers/CodeHelpers.d.ts +97 -0
- package/dist/Helpers/CodeHelpers.js +332 -0
- package/dist/Helpers/CrudBackend.d.ts +114 -6
- package/dist/Helpers/CrudBackend.js +214 -11
- package/dist/Helpers/CrudColumns.d.ts +98 -0
- package/dist/Helpers/CrudColumns.js +160 -0
- package/dist/Helpers/CrudDetailsTabs.d.ts +58 -0
- package/dist/Helpers/CrudDetailsTabs.js +126 -0
- package/dist/Helpers/CrudHelpers.d.ts +130 -6
- package/dist/Helpers/CrudHelpers.js +304 -12
- package/dist/Helpers/CrudNarrowPick.d.ts +83 -0
- package/dist/Helpers/CrudNarrowPick.js +157 -0
- package/dist/Helpers/CrudRowForms.d.ts +15 -0
- package/dist/Helpers/CrudRowForms.js +43 -0
- package/dist/Helpers/CrudScopes.d.ts +32 -0
- package/dist/Helpers/CrudScopes.js +79 -0
- package/dist/Helpers/DropdownHelpers.d.ts +3 -1
- package/dist/Helpers/DropdownHelpers.js +6 -2
- package/dist/Helpers/ExcelHelpers.d.ts +1 -1
- package/dist/Helpers/ExcelHelpers.js +12 -11
- package/dist/Helpers/FileAdapter.d.ts +78 -0
- package/dist/Helpers/FileAdapter.js +102 -0
- package/dist/Helpers/FilePrimaries.d.ts +48 -0
- package/dist/Helpers/FilePrimaries.js +138 -0
- package/dist/Helpers/FormConfirm.d.ts +32 -0
- package/dist/Helpers/FormConfirm.js +40 -0
- package/dist/Helpers/FormStore.d.ts +90 -5
- package/dist/Helpers/FormStore.js +318 -22
- package/dist/Helpers/InputConditions.d.ts +50 -0
- package/dist/Helpers/InputConditions.js +168 -0
- package/dist/Helpers/InputMemory.d.ts +106 -0
- package/dist/Helpers/InputMemory.js +385 -0
- package/dist/Helpers/InputNarrowing.d.ts +18 -0
- package/dist/Helpers/InputNarrowing.js +67 -0
- package/dist/Helpers/InputParamsHelpers.d.ts +44 -1
- package/dist/Helpers/InputParamsHelpers.js +162 -71
- package/dist/Helpers/MessageBuilder.js +2 -0
- package/dist/Helpers/NexusDriveAdapter.d.ts +55 -0
- package/dist/Helpers/NexusDriveAdapter.js +207 -0
- package/dist/Helpers/NexusHelpers.d.ts +0 -0
- package/dist/Helpers/NexusHelpers.js +1 -0
- package/dist/Helpers/NumberHelpers.d.ts +95 -0
- package/dist/Helpers/NumberHelpers.js +126 -0
- package/dist/Helpers/Permissions.js +2 -1
- package/dist/Helpers/QrCode.d.ts +26 -0
- package/dist/Helpers/QrCode.js +463 -0
- package/dist/Helpers/RecordCards.d.ts +205 -0
- package/dist/Helpers/RecordCards.js +378 -0
- package/dist/Helpers/RequestCache.d.ts +47 -0
- package/dist/Helpers/RequestCache.js +132 -0
- package/dist/Helpers/RowsStore.d.ts +37 -2
- package/dist/Helpers/RowsStore.js +128 -10
- package/dist/Helpers/ServerPreview.d.ts +69 -0
- package/dist/Helpers/ServerPreview.js +99 -0
- package/dist/Helpers/TableColumns.js +4 -3
- package/dist/Helpers/TableExport.d.ts +7 -1
- package/dist/Helpers/TableExport.js +21 -15
- package/dist/Helpers/TableFilters.d.ts +1 -1
- package/dist/Helpers/TableFilters.js +24 -23
- package/dist/Helpers/TableHelpers.d.ts +24 -3
- package/dist/Helpers/TableHelpers.js +58 -12
- package/dist/Helpers/TableJoins.d.ts +83 -0
- package/dist/Helpers/TableJoins.js +284 -0
- package/dist/Helpers/TableStore.d.ts +26 -1
- package/dist/Helpers/TableStore.js +73 -7
- package/dist/Helpers/TreeStore.d.ts +306 -11
- package/dist/Helpers/TreeStore.js +1048 -90
- package/dist/Helpers/UserPreferences.d.ts +8 -0
- package/dist/Helpers/UserPreferences.js +17 -0
- package/dist/Interfaces/CrudInterfaces.d.ts +512 -14
- package/dist/Interfaces/FileInterfaces.d.ts +162 -0
- package/dist/Interfaces/FileInterfaces.js +4 -0
- package/dist/Interfaces/FormInterfaces.d.ts +393 -29
- package/dist/Interfaces/FormInterfaces.js +79 -1
- package/dist/Interfaces/InputInterfaces.d.ts +39 -3
- package/dist/Interfaces/MessageInterfaces.d.ts +1 -1
- package/dist/Interfaces/PreferenceInterfaces.d.ts +8 -0
- package/dist/Interfaces/PreferenceInterfaces.js +2 -5
- package/dist/Interfaces/RecordInterfaces.d.ts +367 -0
- package/dist/Interfaces/RecordInterfaces.js +1 -0
- package/dist/Interfaces/TableInterfaces.d.ts +160 -5
- package/dist/Services/ApiProxy.d.ts +36 -1
- package/dist/Services/ApiProxy.js +182 -52
- package/dist/Services/ApiProxyRules.d.ts +203 -0
- package/dist/Services/ApiProxyRules.js +426 -0
- package/dist/Services/ExcelApi.js +5 -0
- package/dist/Services/FileApi.d.ts +13 -0
- package/dist/Services/FileApi.js +29 -0
- package/dist/Services/ImageEditorLoader.d.ts +14 -0
- package/dist/Services/ImageEditorLoader.js +51 -0
- package/dist/Services/JoinSources.d.ts +80 -0
- package/dist/Services/JoinSources.js +150 -0
- package/dist/Services/ModuleImport.d.ts +7 -0
- package/dist/Services/ModuleImport.js +22 -0
- package/dist/Services/ServerApi.d.ts +13 -2
- package/dist/Services/ServerApi.js +8 -3
- package/dist/Shared.Index.d.ts +20 -0
- package/dist/Shared.Index.js +20 -0
- package/package.json +92 -85
- package/src/Styles/Nexus.Avatar.css +80 -79
- package/src/Styles/Nexus.Base.css +117 -117
- package/src/Styles/Nexus.Button.css +186 -180
- package/src/Styles/Nexus.Calendar.css +273 -273
- package/src/Styles/Nexus.Chat.css +1443 -1443
- package/src/Styles/Nexus.Choice.css +359 -343
- package/src/Styles/Nexus.Crud.css +542 -168
- package/src/Styles/Nexus.DateTime.css +81 -81
- package/src/Styles/Nexus.Dropdown.css +733 -725
- package/src/Styles/Nexus.Editor.css +295 -295
- package/src/Styles/Nexus.Excel.css +389 -389
- package/src/Styles/Nexus.Files.css +410 -0
- package/src/Styles/Nexus.Form.css +282 -279
- package/src/Styles/Nexus.Index.css +41 -37
- package/src/Styles/Nexus.Input.css +238 -4
- package/src/Styles/Nexus.Markdown.css +237 -237
- package/src/Styles/Nexus.Menu.css +246 -237
- package/src/Styles/Nexus.Popup.css +800 -724
- package/src/Styles/Nexus.Print.css +288 -0
- package/src/Styles/Nexus.QrCode.css +12 -0
- package/src/Styles/Nexus.Record.css +430 -0
- package/src/Styles/Nexus.Rows.css +637 -637
- package/src/Styles/Nexus.Slider.css +276 -276
- package/src/Styles/Nexus.Tab.Buttons.css +497 -432
- package/src/Styles/Nexus.Table.css +98 -35
- package/src/Styles/Nexus.Theme.Picker.css +59 -3
- package/src/Styles/Nexus.Themes.css +200 -194
- package/src/Styles/Nexus.Time.css +144 -144
- package/src/Styles/Nexus.Toast.css +263 -263
- package/src/Styles/Nexus.Tokens.css +94 -89
- package/src/Styles/Nexus.Tree.css +530 -431
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { isEmptyValue } from "./InputConditions.js";
|
|
2
|
+
import { columnValue, readPath } from "./TableHelpers.js";
|
|
3
|
+
/*
|
|
4
|
+
* The rules of a details popup's tabs (`CrudDetailsOptions.tabs`), apart from drawing them, so they are tested without
|
|
5
|
+
* a browser: which tabs a person is offered for a record, which one opens, and where this browser keeps the last one;
|
|
6
|
+
* and which fields its profile shows (`profile.fields`), which the Details tab then leaves out.
|
|
7
|
+
*/
|
|
8
|
+
/** The built-in tab: the record's fields, with the details' `aside` beside them. */
|
|
9
|
+
export const CRUD_DETAILS_TAB = "details";
|
|
10
|
+
/**
|
|
11
|
+
* The tabs offered for a record, in the page's order: the built-in `details` first unless the page lists it, each tab
|
|
12
|
+
* whose `endpoint` the person may not call left out (`can`, the rule every action follows), and each the page hides
|
|
13
|
+
* for this record. A tab id listed twice is offered once, where it is first listed.
|
|
14
|
+
*/
|
|
15
|
+
export function offeredCrudTabs(tabs, row, can) {
|
|
16
|
+
const listed = tabs ?? [];
|
|
17
|
+
const all = listed.some(tab => tab.id === CRUD_DETAILS_TAB) ? listed : [{ id: CRUD_DETAILS_TAB }, ...listed];
|
|
18
|
+
const seen = new Set();
|
|
19
|
+
const offered = [];
|
|
20
|
+
for (const tab of all) {
|
|
21
|
+
if (seen.has(tab.id))
|
|
22
|
+
continue;
|
|
23
|
+
seen.add(tab.id);
|
|
24
|
+
if (tab.endpoint && !can(tab.endpoint))
|
|
25
|
+
continue;
|
|
26
|
+
if (tab.hidden?.(row))
|
|
27
|
+
continue;
|
|
28
|
+
const builtIn = tab.id === CRUD_DETAILS_TAB && !tab.render;
|
|
29
|
+
offered.push({ ...tab, label: tab.label ?? (tab.id === CRUD_DETAILS_TAB ? "Details" : tab.id), builtIn });
|
|
30
|
+
}
|
|
31
|
+
return offered;
|
|
32
|
+
}
|
|
33
|
+
/** The tab a popup opens on: the one asked for, else the one kept, while offered; otherwise the first. */
|
|
34
|
+
export function openingCrudTab(offered, ...wanted) {
|
|
35
|
+
for (const id of wanted)
|
|
36
|
+
if (id && offered.some(tab => tab.id === id))
|
|
37
|
+
return id;
|
|
38
|
+
return offered[0]?.id;
|
|
39
|
+
}
|
|
40
|
+
/** Where this browser keeps the last tab: `nx-crud-tab:{key}:{viewer}`; nothing without a viewer. */
|
|
41
|
+
export function crudTabStorageKey(remember) {
|
|
42
|
+
const viewer = remember?.viewer?.trim();
|
|
43
|
+
return remember?.key && viewer ? `nx-crud-tab:${remember.key}:${viewer}` : null;
|
|
44
|
+
}
|
|
45
|
+
/** The kept tab's id, or null. */
|
|
46
|
+
export function readCrudTab(storage, key) {
|
|
47
|
+
if (!storage || !key)
|
|
48
|
+
return null;
|
|
49
|
+
try {
|
|
50
|
+
const kept = storage.getItem(key);
|
|
51
|
+
return kept ? kept : null;
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/** Keeps the tab's id; a browser that will not keep it (storage off, full) is left as it is. */
|
|
58
|
+
export function writeCrudTab(storage, key, tab) {
|
|
59
|
+
if (!storage || !key)
|
|
60
|
+
return;
|
|
61
|
+
try {
|
|
62
|
+
storage.setItem(key, tab);
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
// Not kept: the popup opens on the first tab next time.
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/** Whether a profile is given as its parts (a `title`), rather than drawn by the page. */
|
|
69
|
+
export function isCrudProfile(value) {
|
|
70
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) && "title" in value && !("$$typeof" in value);
|
|
71
|
+
}
|
|
72
|
+
/** The key a profile's field names: a column's own, or the key given. */
|
|
73
|
+
const profileFieldKey = (field) => (typeof field === "string" ? field : field.key);
|
|
74
|
+
/**
|
|
75
|
+
* Whether a field waits on the full record: it is still being read (or its read failed) and the row has no value under
|
|
76
|
+
* the field's key at all - the list left it out. A column that draws or works out its own value (`render`, `value`)
|
|
77
|
+
* never waits: only it knows what it reads. The Details tab and the profile draw such a field blank while it is read,
|
|
78
|
+
* and "Not loaded" when the read failed.
|
|
79
|
+
*/
|
|
80
|
+
export function isAwaitedCrudField(column, row, read) {
|
|
81
|
+
return read !== "done" && !column.render && !column.value && readPath(row, column.key) === undefined;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* The fields a record's profile shows (`CrudDetailsProfile.fields`), in the page's order: a column given whole, or the
|
|
85
|
+
* details' column of the key given (a key no column has is left out); a key named twice is shown once, where first
|
|
86
|
+
* named; and a field with no value for the record - its own `value`, a join's or the field's: null, undefined, blank
|
|
87
|
+
* text, an empty list, NaN - is left out. `false` and `0` are values. A field the row lacks while the full record is
|
|
88
|
+
* read, or after its read failed (`isAwaitedCrudField`), is kept: the profile holds its line, then says "Not loaded".
|
|
89
|
+
*/
|
|
90
|
+
export function crudProfileFields(fields, columns, row, read = "done") {
|
|
91
|
+
const seen = new Set();
|
|
92
|
+
const shown = [];
|
|
93
|
+
for (const field of fields ?? []) {
|
|
94
|
+
const key = profileFieldKey(field);
|
|
95
|
+
if (seen.has(key))
|
|
96
|
+
continue;
|
|
97
|
+
seen.add(key);
|
|
98
|
+
const column = typeof field === "string" ? columns.find(one => one.key === field) : field;
|
|
99
|
+
if (!column)
|
|
100
|
+
continue;
|
|
101
|
+
if (isAwaitedCrudField(column, row, read)) {
|
|
102
|
+
shown.push(column);
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
const value = columnValue(column, row);
|
|
106
|
+
if (isEmptyValue(value) || (typeof value === "number" && Number.isNaN(value)))
|
|
107
|
+
continue;
|
|
108
|
+
shown.push(column);
|
|
109
|
+
}
|
|
110
|
+
return shown;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* The details' columns less every key a profile's `fields` names, so the Details tab never shows a field the profile
|
|
114
|
+
* does. A key the profile leaves out for having no value stays out of the Details too: it has nothing to show there. A
|
|
115
|
+
* field still being read, or whose read failed, is in the profile (`crudProfileFields`), held or "Not loaded".
|
|
116
|
+
*/
|
|
117
|
+
export function crudDetailsWithoutProfile(columns, fields) {
|
|
118
|
+
if (!fields?.length)
|
|
119
|
+
return columns;
|
|
120
|
+
const taken = new Set(fields.map(profileFieldKey));
|
|
121
|
+
return columns.filter(column => !taken.has(column.key));
|
|
122
|
+
}
|
|
123
|
+
/** Whether a profile's picture is given by the owner's Drive params, rather than drawn by the page. */
|
|
124
|
+
export function isCrudPicture(value) {
|
|
125
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) && "category" in value && "ownerId" in value && !("$$typeof" in value);
|
|
126
|
+
}
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import type { ApiEndpoint } from "../Interfaces/ApiInterfaces.ts";
|
|
2
|
-
import type { CrudActionName, CrudEndpoints, CrudMassActionName, CrudMode, CrudRowActionName } from "../Interfaces/CrudInterfaces.ts";
|
|
2
|
+
import type { CrudActionName, CrudChange, CrudEndpoints, CrudMark, CrudMassActionName, CrudMode, CrudNarrow, CrudRowActionName, CrudTreePlacement } from "../Interfaces/CrudInterfaces.ts";
|
|
3
|
+
import type { FormValues } from "../Interfaces/FormInterfaces.ts";
|
|
4
|
+
import type { CrudBackend } from "./CrudBackend.ts";
|
|
5
|
+
import type { TreeItemChange } from "./TreeStore.ts";
|
|
3
6
|
import type { MessageActionName } from "../Interfaces/MessageInterfaces.ts";
|
|
4
|
-
import type { TablePage, TablePaging, TableRow } from "../Interfaces/TableInterfaces.ts";
|
|
7
|
+
import type { TableColumn, TablePage, TablePaging, TableRow } from "../Interfaces/TableInterfaces.ts";
|
|
5
8
|
/** Every list, in the order the CRUD shows them. */
|
|
6
9
|
export declare const CRUD_MODES: readonly CrudMode[];
|
|
7
|
-
/** The built-in actions on one record, per list, in their menu order. */
|
|
10
|
+
/** The built-in actions on one record, per list, in their menu order. A record's history is on every list. */
|
|
8
11
|
export declare const CRUD_ROW_ACTIONS: Readonly<Record<CrudMode, readonly CrudRowActionName[]>>;
|
|
9
12
|
/** The built-in actions on selected records, per list. */
|
|
10
13
|
export declare const CRUD_MASS_ACTIONS: Readonly<Record<CrudMode, readonly CrudMassActionName[]>>;
|
|
@@ -18,8 +21,13 @@ export declare function crudRowActions(mode: CrudMode, allowed: (action: CrudRow
|
|
|
18
21
|
export declare function crudMassActions(mode: CrudMode, allowed: (action: CrudMassActionName) => boolean, trashless?: boolean): CrudMassActionName[];
|
|
19
22
|
/** The endpoint of a list: its full list for tables that page in the browser, its pages for server tables. */
|
|
20
23
|
export declare function crudListEndpoint(api: CrudEndpoints, mode: CrudMode, paging: TablePaging): ApiEndpoint | undefined;
|
|
21
|
-
/**
|
|
24
|
+
/**
|
|
25
|
+
* The endpoint of a row action. `view` needs none of its own: it shows the row (and calls `details` when there is one).
|
|
26
|
+
* Pin and Favourite both set the record's marks through `bookmark`; a backend without it may still pin, through `pin`.
|
|
27
|
+
*/
|
|
22
28
|
export declare function crudRowEndpoint(api: CrudEndpoints, action: CrudRowActionName): ApiEndpoint | undefined;
|
|
29
|
+
/** The endpoint of an action on many records: Pin and Favourite through `mass.bookmark`, or Pin through `mass.pin`. */
|
|
30
|
+
export declare function crudMassEndpoint(api: CrudEndpoints, action: CrudMassActionName): ApiEndpoint | undefined;
|
|
23
31
|
/** The lists a CRUD can offer: asked for, with an endpoint, and allowed. */
|
|
24
32
|
export declare function availableModes(api: CrudEndpoints, paging: TablePaging, wanted: readonly CrudMode[], can: (endpoint: ApiEndpoint) => boolean): CrudMode[];
|
|
25
33
|
/**
|
|
@@ -31,10 +39,86 @@ export declare function actionAllowed(action: CrudActionName, api: CrudEndpoints
|
|
|
31
39
|
export declare function massActionAllowed(action: CrudMassActionName, api: CrudEndpoints, wanted: readonly CrudActionName[], can: (endpoint: ApiEndpoint) => boolean): boolean;
|
|
32
40
|
/**
|
|
33
41
|
* Whether a record leaves the list shown after an action. Trash, recover, delete, and moving back to the trash take it
|
|
34
|
-
* to another list, and unflagging leaves the flagged list.
|
|
35
|
-
*
|
|
42
|
+
* to another list, and unflagging leaves the flagged list. A pin or a favourite never does: a marked record stays in
|
|
43
|
+
* the list it is in. `markOn` is the record's new flag.
|
|
36
44
|
*/
|
|
37
45
|
export declare function leavesList(action: CrudRowActionName | CrudMassActionName, mode: CrudMode, markOn?: boolean): boolean;
|
|
46
|
+
/**
|
|
47
|
+
* A CRUD change as changes to a tree that shows the same records (`CrudTreePlacement`): a record in the active list is
|
|
48
|
+
* put under its parent - added, changed or moved - and one out of it (in the trash, deleted) leaves the tree. Where it
|
|
49
|
+
* was comes from `before`: under its parent while it was active, out of the tree when it was not or is new, and not
|
|
50
|
+
* known otherwise (the tree then looks for it). A record without a status counts as active. Pins and favourites are a
|
|
51
|
+
* user's own and change no tree.
|
|
52
|
+
*/
|
|
53
|
+
export declare function crudTreeChanges<TRow extends FormValues, TItem extends object>(change: CrudChange<TRow>, place: CrudTreePlacement<TRow, TItem>, backend: CrudBackend): TreeItemChange<TItem>[];
|
|
54
|
+
/**
|
|
55
|
+
* The records whose child count a change moved, among `rows` (a list's rows), through a tree placement: what the tree's
|
|
56
|
+
* parents follow (`crudTreeChanges`) written into the parents' own rows. A record added or back under a parent counts one
|
|
57
|
+
* more there; one moved counts one fewer where it was and one more where it went; one trashed or deleted one fewer. Each
|
|
58
|
+
* parent row comes back with what `recordOf` reads from its item with the count moved written over it (so `recordOf`
|
|
59
|
+
* must carry the item's count back into the record); a row whose count did not move, or a count that is not a number, is
|
|
60
|
+
* left out.
|
|
61
|
+
*/
|
|
62
|
+
export declare function crudParentCounts<TRow extends FormValues, TItem extends object>(treeChanges: readonly TreeItemChange<TItem>[], rows: readonly TRow[], place: CrudTreePlacement<TRow, TItem>): TRow[];
|
|
63
|
+
/**
|
|
64
|
+
* A saved record with the child count a tree placement keeps for it (`rules.hasChildrenKey`): a new record's own, as
|
|
65
|
+
* `itemOf` gives it (none yet), and an edited one's from the row the page holds (`held`) - its form's copy is as old as
|
|
66
|
+
* the form, and a child added since counts. Written over the record through `recordOf`, which carries an item's count
|
|
67
|
+
* back; a placement without a count leaves the record as it is.
|
|
68
|
+
*/
|
|
69
|
+
export declare function crudSavedCount<TRow extends FormValues, TItem extends object>(record: TRow, held: TRow | undefined, place: CrudTreePlacement<TRow, TItem>): TRow;
|
|
70
|
+
/** What a save knows of the record a joined key names (`crudJoinedNames`): its name, and its status when it says. */
|
|
71
|
+
export interface CrudJoinedRecord {
|
|
72
|
+
name: unknown;
|
|
73
|
+
status?: unknown;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* The names the database joins into a record (`crudColumns.dbJoin` columns with `from`), written again after a save that
|
|
77
|
+
* answered only what was sent - with no call. For each such column: a key the save kept as `before` had it keeps
|
|
78
|
+
* `before`'s name and status; an emptied key empties both; a new or changed key takes the name and the status of the
|
|
79
|
+
* record `find(from, key)` gives - the one picked in the form, or one the page holds. Where it gives none, a new record
|
|
80
|
+
* keeps the name its save answered, if any, and an edited one drops the old record's name and status rather than show
|
|
81
|
+
* them for the new key: either way the record is then read back once (`crudJoinsMissing`). Names and statuses are written
|
|
82
|
+
* as top-level fields of the record.
|
|
83
|
+
*/
|
|
84
|
+
export declare function crudJoinedNames<TRow extends TableRow>(record: TRow, before: TRow | undefined, columns: readonly TableColumn<TRow>[], find: (from: string, key: string) => CrudJoinedRecord | null | undefined): TRow;
|
|
85
|
+
/**
|
|
86
|
+
* Whether a saved record still lacks a name the database joins into it, which is the one case a CRUD reads it back
|
|
87
|
+
* (`details`, once): a `crudColumns.dbJoin` column whose name the record does not hold while its key is set - no record
|
|
88
|
+
* was known for a new key (`crudJoinedNames`) - or one that names no key field (`from`) on a new record, whose save
|
|
89
|
+
* answered no name. An edited record keeps the name it had on a column without `from`: whether its key changed cannot
|
|
90
|
+
* be told.
|
|
91
|
+
*/
|
|
92
|
+
export declare function crudJoinsMissing<TRow extends TableRow>(record: TRow, before: TRow | undefined, columns: readonly TableColumn<TRow>[]): boolean;
|
|
93
|
+
/**
|
|
94
|
+
* Where an Add or Edit form with fixed fields stands, as text for its popup's key and its draft's: the fixed fields'
|
|
95
|
+
* names and values, in name order (`"@countryId=7&parentId="`), or "" when nothing is fixed. So a form opened inside one
|
|
96
|
+
* parent never comes back inside another, a fixed form never stands in for a free one, and a draft written before the
|
|
97
|
+
* record moved is not brought back over its new place.
|
|
98
|
+
*/
|
|
99
|
+
export declare function crudFormPlace(fixed: Readonly<Record<string, unknown>> | null | undefined): string;
|
|
100
|
+
/** What a narrowed list shows and fixes, read once from its `narrow`. */
|
|
101
|
+
export interface CrudNarrowing {
|
|
102
|
+
/** The field of the list's records that names the picked record. */
|
|
103
|
+
key: string;
|
|
104
|
+
/** The picked record's value as text, which a record's field must equal; `null` while none is picked: the list is empty. */
|
|
105
|
+
value: string | null;
|
|
106
|
+
/** The same value as the picked record holds it (a number stays a number): what a new record and a server's filter get. */
|
|
107
|
+
raw: unknown;
|
|
108
|
+
/** The picked record's name: its `labelKey` field, else the value. */
|
|
109
|
+
label: string;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* A `Crud` `narrow` read once: the field, the picked record's value (its `valueKey` field, else its `key` field) and its
|
|
113
|
+
* name (its `labelKey` field, else the value). `null` without a narrowing; a value of `null` while nothing is picked, or
|
|
114
|
+
* the picked record holds no value.
|
|
115
|
+
*/
|
|
116
|
+
export declare function crudNarrowing(narrow: CrudNarrow | null | undefined): CrudNarrowing | null;
|
|
117
|
+
/**
|
|
118
|
+
* Whether a record belongs in a narrowed list: its field holds the picked record's value (compared as text, so 7 and "7"
|
|
119
|
+
* are one). Every record does without a narrowing, and none while nothing is picked.
|
|
120
|
+
*/
|
|
121
|
+
export declare function crudInNarrowing(row: TableRow, narrowing: CrudNarrowing | null): boolean;
|
|
38
122
|
/** The message builder's action for a built-in action: "Guest recovered.", "Unpin 3 guests?" */
|
|
39
123
|
export declare function crudMessageAction(action: CrudRowActionName | CrudMassActionName, markOn?: boolean): MessageActionName;
|
|
40
124
|
/** What every CRUD follows, whatever module it shows. `configureCrud` changes it once, for the whole app. */
|
|
@@ -44,6 +128,8 @@ export interface CrudSettings {
|
|
|
44
128
|
* pins and can unpin, and may pin again once they are under it.
|
|
45
129
|
*/
|
|
46
130
|
maxPins: number;
|
|
131
|
+
/** Most records a user may make favourites, kept the same way. Default: whatever `maxPins` is. */
|
|
132
|
+
maxFavorites?: number;
|
|
47
133
|
}
|
|
48
134
|
/**
|
|
49
135
|
* Changes what every CRUD follows, once, where the app registers its API modules: `configureCrud({ maxPins: 50 })`.
|
|
@@ -57,6 +143,44 @@ export declare function getCrudSettings(): CrudSettings;
|
|
|
57
143
|
* when nothing counts the pins (no `pins` endpoint), and then there is no limit to keep.
|
|
58
144
|
*/
|
|
59
145
|
export declare function pinRoom(pinned: number | undefined, max?: number): number;
|
|
146
|
+
/** Every mark, in the order their sections show above the list: Pinned, then Favourites. */
|
|
147
|
+
export declare const CRUD_MARKS: readonly CrudMark[];
|
|
148
|
+
/**
|
|
149
|
+
* Each mark's bit in a record's set of marks, as the Nexus backend's `[Flags] EBookmarkTypes` numbers them. A set may
|
|
150
|
+
* hold bits this package does not know - a backend's next mark is its next bit - and a change here keeps them.
|
|
151
|
+
*/
|
|
152
|
+
export declare const CRUD_MARK_BITS: Readonly<Record<CrudMark, number>>;
|
|
153
|
+
/** Whether a set of marks holds this mark. */
|
|
154
|
+
export declare function hasMark(marks: number, mark: CrudMark): boolean;
|
|
155
|
+
/** The set of marks with this one put on or taken off, and every other bit as it was. */
|
|
156
|
+
export declare function withMark(marks: number, mark: CrudMark, on: boolean): number;
|
|
157
|
+
/** Most records a user may give a mark: `maxPins`, and for favourites `maxFavorites`, else the same as the pins. */
|
|
158
|
+
export declare function markLimit(mark: CrudMark, settings?: CrudSettings): number;
|
|
159
|
+
/**
|
|
160
|
+
* Which ways a selection can go for one mark, from each selected record's marks: on, when one of them lacks it, and
|
|
161
|
+
* off, when one of them has it. A mixed selection can go both ways, and each is offered on its own (the owner,
|
|
162
|
+
* 2026-10-07): no action that would change nothing.
|
|
163
|
+
*/
|
|
164
|
+
export declare function markDirections(marks: readonly number[], mark: CrudMark): {
|
|
165
|
+
on: boolean;
|
|
166
|
+
off: boolean;
|
|
167
|
+
};
|
|
168
|
+
/** This user's marked records, as a CRUD keeps them: every record's marks by key, and the records of each mark's section. */
|
|
169
|
+
export interface CrudMarkedRecords<TRow extends TableRow = TableRow> {
|
|
170
|
+
marks: ReadonlyMap<string, number>;
|
|
171
|
+
rows: Readonly<Record<CrudMark, readonly TRow[]>>;
|
|
172
|
+
}
|
|
173
|
+
/** The marked records as one listing answered them, in its order: `marksOf` reads each record's marks. */
|
|
174
|
+
export declare function markedRecords<TRow extends TableRow>(rows: readonly TRow[], marksOf: (row: TRow) => number, keyOf: (row: TRow) => string): CrudMarkedRecords<TRow>;
|
|
175
|
+
/**
|
|
176
|
+
* The marked records after a change, with no request. `stored` is each changed record's new set of marks (`0` for
|
|
177
|
+
* none). A record in `joining` - by default every record in `stored` - that now has a mark goes on top of that mark's
|
|
178
|
+
* section; one that lost a mark leaves it; every copy of a record in `rows` is replaced. With `joining` empty only the
|
|
179
|
+
* copies change: a flag or a save never moves a record into a section.
|
|
180
|
+
*/
|
|
181
|
+
export declare function patchMarkedRecords<TRow extends TableRow>(current: CrudMarkedRecords<TRow>, rows: readonly TRow[], stored: ReadonlyMap<string, number>, keyOf: (row: TRow) => string, joining?: ReadonlySet<string>): CrudMarkedRecords<TRow>;
|
|
182
|
+
/** The marked records with these records out of every section - they left the active lists - keeping their marks. */
|
|
183
|
+
export declare function dropMarkedRows<TRow extends TableRow>(current: CrudMarkedRecords<TRow>, keys: readonly string[], keyOf: (row: TRow) => string): CrudMarkedRecords<TRow>;
|
|
60
184
|
/** Default time a CRUD keeps a list: 5 minutes. */
|
|
61
185
|
export declare const CRUD_CACHE_LIFETIME: number;
|
|
62
186
|
/** Lists kept while a page is open, by key, each for a lifetime. Plain values; nothing is written to storage. */
|