nexus-shared 3.2.0 → 4.1.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 +2359 -0
- package/README.md +1911 -1123
- package/dist/Client.Index.d.ts +27 -0
- package/dist/Client.Index.js +27 -0
- package/dist/Components/Chats/ChatComposer.d.ts +7 -1
- package/dist/Components/Chats/ChatComposer.js +9 -6
- package/dist/Components/Chats/ChatParts.d.ts +15 -2
- package/dist/Components/Chats/ChatParts.js +15 -4
- package/dist/Components/Chats/ChatPopup.d.ts +46 -0
- package/dist/Components/Chats/ChatPopup.js +34 -0
- package/dist/Components/Chats/ChatThread.d.ts +9 -1
- package/dist/Components/Chats/ChatThread.js +54 -6
- package/dist/Components/Dashboards/DashboardBoard.d.ts +62 -0
- package/dist/Components/Dashboards/DashboardBoard.js +594 -0
- package/dist/Components/Dashboards/DashboardWidgets.d.ts +155 -0
- package/dist/Components/Dashboards/DashboardWidgets.js +159 -0
- package/dist/Components/Dashboards/WidgetFrame.d.ts +51 -0
- package/dist/Components/Dashboards/WidgetFrame.js +45 -0
- package/dist/Components/Documents/Button.d.ts +6 -1
- package/dist/Components/Documents/Button.js +2 -2
- 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/TabButtons.d.ts +6 -0
- package/dist/Components/Documents/TabButtons.js +5 -4
- package/dist/Components/Documents/Tabs.d.ts +59 -0
- package/dist/Components/Documents/Tabs.js +70 -0
- package/dist/Components/Domains/DomainCard.d.ts +98 -0
- package/dist/Components/Domains/DomainCard.js +182 -0
- package/dist/Components/Forms/ApiForm.js +24 -3
- package/dist/Components/Forms/Crud.d.ts +2 -2
- package/dist/Components/Forms/Crud.js +628 -247
- package/dist/Components/Forms/CrudActions.d.ts +137 -0
- package/dist/Components/Forms/CrudActions.js +214 -0
- package/dist/Components/Forms/CrudHistory.d.ts +6 -1
- package/dist/Components/Forms/CrudHistory.js +14 -6
- package/dist/Components/Forms/CrudNarrowPicker.d.ts +31 -0
- package/dist/Components/Forms/CrudNarrowPicker.js +180 -0
- package/dist/Components/Forms/CrudParts.d.ts +37 -2
- package/dist/Components/Forms/CrudParts.js +123 -7
- package/dist/Components/Forms/CrudRowForms.d.ts +26 -0
- package/dist/Components/Forms/CrudRowForms.js +174 -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 +73 -0
- package/dist/Components/Forms/CrudWorkspace.js +177 -0
- package/dist/Components/Forms/ExcelImport.js +3 -3
- package/dist/Components/Forms/Form.d.ts +6 -5
- package/dist/Components/Forms/Form.js +134 -21
- package/dist/Components/Forms/FormLeaveGuard.d.ts +44 -0
- package/dist/Components/Forms/FormLeaveGuard.js +65 -0
- package/dist/Components/Forms/FormQuestion.d.ts +6 -0
- package/dist/Components/Forms/FormQuestion.js +28 -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 +182 -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/ComputedInput.d.ts +51 -0
- package/dist/Components/Inputs/ComputedInput.js +179 -0
- package/dist/Components/Inputs/Dropdown.d.ts +13 -0
- package/dist/Components/Inputs/Dropdown.js +8 -6
- 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 +12 -12
- package/dist/Components/Inputs/InputRenderer.d.ts +13 -6
- package/dist/Components/Inputs/InputRenderer.js +37 -32
- package/dist/Components/Inputs/MarkdownEditor.d.ts +6 -0
- package/dist/Components/Inputs/MarkdownEditor.js +32 -6
- package/dist/Components/Inputs/PictureInput.d.ts +41 -0
- package/dist/Components/Inputs/PictureInput.js +75 -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 +15 -2
- package/dist/Components/Inputs/RowsInput.js +96 -8
- package/dist/Components/Inputs/TabularForm.d.ts +5 -5
- package/dist/Components/Inputs/TabularForm.js +45 -32
- package/dist/Components/Inputs/TextArea.d.ts +6 -0
- package/dist/Components/Inputs/TextArea.js +11 -2
- package/dist/Components/Inputs/TextBoxTypes.d.ts +6 -0
- package/dist/Components/Inputs/TextBoxTypes.js +17 -0
- package/dist/Components/Inputs/TreeView.d.ts +76 -2
- package/dist/Components/Inputs/TreeView.js +227 -16
- package/dist/Components/Layouts/MessageBox.d.ts +15 -2
- package/dist/Components/Layouts/MessageBox.js +56 -7
- package/dist/Components/Layouts/Popup.d.ts +34 -7
- package/dist/Components/Layouts/Popup.js +143 -13
- 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/Messages/MailClient.d.ts +50 -0
- package/dist/Components/Messages/MailClient.js +410 -0
- package/dist/Components/Messages/MailColumns.d.ts +21 -0
- package/dist/Components/Messages/MailColumns.js +92 -0
- package/dist/Components/Messages/MailCompose.d.ts +46 -0
- package/dist/Components/Messages/MailCompose.js +154 -0
- package/dist/Components/Messages/MailReader.d.ts +43 -0
- package/dist/Components/Messages/MailReader.js +207 -0
- package/dist/Components/Messages/MailThread.d.ts +71 -0
- package/dist/Components/Messages/MailThread.js +185 -0
- package/dist/Components/Messages/MessageBell.d.ts +41 -0
- package/dist/Components/Messages/MessageBell.js +76 -0
- package/dist/Components/Viewers/DataTable.js +153 -49
- package/dist/Components/Viewers/DataTableColumns.d.ts +2 -2
- package/dist/Components/Viewers/DataTableColumns.js +2 -1
- package/dist/Components/Viewers/DataTableFilters.d.ts +1 -1
- package/dist/Components/Viewers/DataTableFilters.js +17 -2
- package/dist/Components/Viewers/DataTableParts.d.ts +23 -5
- package/dist/Components/Viewers/DataTableParts.js +26 -14
- package/dist/Components/Viewers/OwnerFiles.d.ts +227 -0
- package/dist/Components/Viewers/OwnerFiles.js +700 -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.js +4 -0
- package/dist/Helpers/AuditEntries.d.ts +50 -0
- package/dist/Helpers/AuditEntries.js +96 -0
- package/dist/Helpers/BusyHooks.d.ts +6 -0
- package/dist/Helpers/BusyHooks.js +39 -0
- package/dist/Helpers/ChatBackend.d.ts +8 -1
- package/dist/Helpers/ChatBackend.js +18 -0
- package/dist/Helpers/ChatHelpers.d.ts +2 -0
- package/dist/Helpers/ChatHelpers.js +4 -1
- package/dist/Helpers/CrudBackend.d.ts +20 -2
- package/dist/Helpers/CrudBackend.js +46 -2
- package/dist/Helpers/CrudColumns.d.ts +91 -6
- package/dist/Helpers/CrudColumns.js +148 -7
- package/dist/Helpers/CrudDetailsTabs.d.ts +58 -0
- package/dist/Helpers/CrudDetailsTabs.js +126 -0
- package/dist/Helpers/CrudHelpers.d.ts +116 -2
- package/dist/Helpers/CrudHelpers.js +256 -0
- package/dist/Helpers/CrudNarrowPick.d.ts +83 -0
- package/dist/Helpers/CrudNarrowPick.js +157 -0
- package/dist/Helpers/CrudPickerPlan.d.ts +58 -0
- package/dist/Helpers/CrudPickerPlan.js +46 -0
- package/dist/Helpers/CrudRowForms.d.ts +32 -0
- package/dist/Helpers/CrudRowForms.js +76 -0
- package/dist/Helpers/CrudScopes.d.ts +32 -0
- package/dist/Helpers/CrudScopes.js +79 -0
- package/dist/Helpers/DashboardHelpers.d.ts +115 -0
- package/dist/Helpers/DashboardHelpers.js +305 -0
- package/dist/Helpers/DomainCards.d.ts +140 -0
- package/dist/Helpers/DomainCards.js +370 -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 +158 -0
- package/dist/Helpers/FileAdapter.js +173 -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 +100 -5
- package/dist/Helpers/FormStore.js +368 -25
- package/dist/Helpers/InputConditions.d.ts +56 -0
- package/dist/Helpers/InputConditions.js +192 -0
- package/dist/Helpers/InputMemory.d.ts +106 -0
- package/dist/Helpers/InputMemory.js +395 -0
- package/dist/Helpers/InputNarrowing.d.ts +50 -0
- package/dist/Helpers/InputNarrowing.js +148 -0
- package/dist/Helpers/InputParamsHelpers.d.ts +44 -1
- package/dist/Helpers/InputParamsHelpers.js +157 -74
- package/dist/Helpers/MailClientHelpers.d.ts +96 -0
- package/dist/Helpers/MailClientHelpers.js +211 -0
- package/dist/Helpers/MessageBackend.d.ts +152 -0
- package/dist/Helpers/MessageBackend.js +329 -0
- package/dist/Helpers/MessageHelpers.d.ts +160 -0
- package/dist/Helpers/MessageHelpers.js +573 -0
- package/dist/Helpers/MessageUnread.d.ts +95 -0
- package/dist/Helpers/MessageUnread.js +245 -0
- package/dist/Helpers/NexusDriveAdapter.d.ts +71 -0
- package/dist/Helpers/NexusDriveAdapter.js +236 -0
- package/dist/Helpers/NumberHelpers.d.ts +156 -0
- package/dist/Helpers/NumberHelpers.js +242 -0
- package/dist/Helpers/PagedPicker.d.ts +42 -0
- package/dist/Helpers/PagedPicker.js +85 -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 +14 -2
- package/dist/Helpers/RequestCache.js +22 -3
- package/dist/Helpers/RowsStore.d.ts +61 -2
- package/dist/Helpers/RowsStore.js +203 -16
- 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 +9 -3
- package/dist/Helpers/TableFilters.d.ts +1 -1
- package/dist/Helpers/TableFilters.js +24 -23
- package/dist/Helpers/TableHelpers.d.ts +38 -4
- package/dist/Helpers/TableHelpers.js +78 -10
- package/dist/Helpers/TableJoins.d.ts +13 -0
- package/dist/Helpers/TableJoins.js +34 -0
- package/dist/Helpers/TableStore.d.ts +28 -4
- package/dist/Helpers/TableStore.js +73 -11
- package/dist/Helpers/ToolbarFit.d.ts +23 -0
- package/dist/Helpers/ToolbarFit.js +30 -0
- package/dist/Helpers/TreeStore.d.ts +156 -6
- package/dist/Helpers/TreeStore.js +547 -18
- package/dist/Interfaces/ApiInterfaces.d.ts +10 -1
- package/dist/Interfaces/ApiInterfaces.js +10 -1
- package/dist/Interfaces/ChatInterfaces.d.ts +22 -0
- package/dist/Interfaces/CrudInterfaces.d.ts +539 -6
- package/dist/Interfaces/DashboardInterfaces.d.ts +123 -0
- package/dist/Interfaces/DashboardInterfaces.js +1 -0
- package/dist/Interfaces/DomainInterfaces.d.ts +145 -0
- package/dist/Interfaces/DomainInterfaces.js +1 -0
- package/dist/Interfaces/FileInterfaces.d.ts +183 -0
- package/dist/Interfaces/FileInterfaces.js +6 -0
- package/dist/Interfaces/FormInterfaces.d.ts +460 -32
- package/dist/Interfaces/FormInterfaces.js +79 -1
- package/dist/Interfaces/InputInterfaces.d.ts +22 -3
- package/dist/Interfaces/MailInterfaces.d.ts +192 -0
- package/dist/Interfaces/MailInterfaces.js +1 -0
- package/dist/Interfaces/RecordInterfaces.d.ts +367 -0
- package/dist/Interfaces/RecordInterfaces.js +1 -0
- package/dist/Interfaces/TableInterfaces.d.ts +102 -3
- 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 +79 -6
- package/dist/Services/JoinSources.js +132 -21
- package/dist/Services/MessageApi.d.ts +18 -0
- package/dist/Services/MessageApi.js +64 -0
- package/dist/Services/ModuleImport.d.ts +7 -0
- package/dist/Services/ModuleImport.js +22 -0
- package/dist/Shared.Index.d.ts +28 -0
- package/dist/Shared.Index.js +28 -0
- package/package.json +13 -2
- package/src/Styles/Nexus.Avatar.css +6 -5
- package/src/Styles/Nexus.Button.css +39 -4
- package/src/Styles/Nexus.Chat.css +114 -22
- package/src/Styles/Nexus.Choice.css +16 -0
- package/src/Styles/Nexus.Crud.css +486 -21
- package/src/Styles/Nexus.Dashboard.css +763 -0
- package/src/Styles/Nexus.Domain.css +384 -0
- package/src/Styles/Nexus.Dropdown.css +8 -0
- package/src/Styles/Nexus.Editor.css +20 -0
- package/src/Styles/Nexus.Files.css +437 -0
- package/src/Styles/Nexus.Form.css +5 -2
- package/src/Styles/Nexus.Index.css +7 -0
- package/src/Styles/Nexus.Input.css +73 -0
- package/src/Styles/Nexus.Mail.css +1062 -0
- package/src/Styles/Nexus.Menu.css +10 -1
- package/src/Styles/Nexus.Popup.css +135 -1
- 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.Tab.Buttons.css +87 -22
- package/src/Styles/Nexus.Table.css +1458 -1387
- package/src/Styles/Nexus.Theme.Picker.css +1 -0
- package/src/Styles/Nexus.Themes.css +12 -6
- package/src/Styles/Nexus.Tokens.css +8 -3
- package/src/Styles/Nexus.Tree.css +41 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { errorMessage, isAbortError } from "./ApiResponses.js";
|
|
2
2
|
import { activeFilters } from "./TableFilters.js";
|
|
3
|
-
import { DEFAULT_MAX_SELECTION, DEFAULT_PAGE_SIZE, MIN_COLUMN_WIDTH, clampPage, moveColumnKey, nextSort, queryRows, readTablePage, rowKeyText } from "./TableHelpers.js";
|
|
3
|
+
import { DEFAULT_MAX_SELECTION, DEFAULT_PAGE_SIZE, MIN_COLUMN_WIDTH, clampPage, columnPin, moveColumnKey, nextSort, queryRows, readTablePage, rowKeyText } from "./TableHelpers.js";
|
|
4
4
|
/** How long a changed or added row stays highlighted. */
|
|
5
5
|
export const TABLE_FLASH_MS = 1600;
|
|
6
6
|
const EMPTY_MAP = new Map();
|
|
@@ -19,6 +19,7 @@ function initialState(pageSize) {
|
|
|
19
19
|
matches: 0,
|
|
20
20
|
query: { search: "", sort: null, page: 1, pageSize },
|
|
21
21
|
selected: EMPTY_MAP,
|
|
22
|
+
picked: null,
|
|
22
23
|
busy: EMPTY_SET,
|
|
23
24
|
flashed: EMPTY_SET,
|
|
24
25
|
hidden: EMPTY_SET,
|
|
@@ -103,13 +104,18 @@ export class TableStore {
|
|
|
103
104
|
if (changes.selected && changes.selected !== previous.selected)
|
|
104
105
|
this.options.onSelectionChange?.(this.getSelected());
|
|
105
106
|
}
|
|
106
|
-
/**
|
|
107
|
-
|
|
107
|
+
/**
|
|
108
|
+
* Puts back what was saved on this device (page size, sort, columns): before the first load, telling nobody, or, with
|
|
109
|
+
* `notify`, over a table already shown (another key's settings), its rows shown again in them on the first page.
|
|
110
|
+
*/
|
|
111
|
+
restore(saved, options = {}) {
|
|
108
112
|
const query = { ...this.state.query };
|
|
109
113
|
if (saved.pageSize && saved.pageSize > 0)
|
|
110
114
|
query.pageSize = saved.pageSize;
|
|
111
115
|
if (saved.sort !== undefined)
|
|
112
116
|
query.sort = saved.sort;
|
|
117
|
+
if (options.notify)
|
|
118
|
+
query.page = 1;
|
|
113
119
|
this.state = {
|
|
114
120
|
...this.state,
|
|
115
121
|
query,
|
|
@@ -118,6 +124,8 @@ export class TableStore {
|
|
|
118
124
|
widths: saved.widths ?? this.state.widths,
|
|
119
125
|
pinned: saved.pinned ?? this.state.pinned,
|
|
120
126
|
};
|
|
127
|
+
if (options.notify)
|
|
128
|
+
this.view();
|
|
121
129
|
}
|
|
122
130
|
/* Rows given by the page */
|
|
123
131
|
/** Shows these rows: every row there is. The table searches, sorts, and pages them. */
|
|
@@ -127,7 +135,9 @@ export class TableStore {
|
|
|
127
135
|
this.given = rows;
|
|
128
136
|
this.all = [...rows];
|
|
129
137
|
this.dropMissingSelection();
|
|
130
|
-
|
|
138
|
+
const picked = this.state.picked;
|
|
139
|
+
this.view({ status: "ready", error: null, refreshing: false, picked: this.followPicked(this.all, true) });
|
|
140
|
+
this.pickedChanged(picked);
|
|
131
141
|
}
|
|
132
142
|
/* Loading */
|
|
133
143
|
/**
|
|
@@ -151,6 +161,9 @@ export class TableStore {
|
|
|
151
161
|
this.state = { ...this.state, query: { ...this.state.query, search: "", page: 1 } };
|
|
152
162
|
if (this.state.selected.size)
|
|
153
163
|
this.set({ selected: EMPTY_MAP });
|
|
164
|
+
// Another list: the row picked in the one before is not in it.
|
|
165
|
+
if (this.state.picked)
|
|
166
|
+
this.pick(null);
|
|
154
167
|
}
|
|
155
168
|
const keepRows = quiet ?? (this.state.status === "ready" && !reset);
|
|
156
169
|
const query = this.state.query;
|
|
@@ -197,6 +210,7 @@ export class TableStore {
|
|
|
197
210
|
void this.reload({ quiet: true });
|
|
198
211
|
return;
|
|
199
212
|
}
|
|
213
|
+
const picked = this.state.picked;
|
|
200
214
|
this.set({
|
|
201
215
|
status: "ready",
|
|
202
216
|
refreshing: false,
|
|
@@ -207,13 +221,17 @@ export class TableStore {
|
|
|
207
221
|
offset: (query.page - 1) * query.pageSize,
|
|
208
222
|
query,
|
|
209
223
|
selected: this.refreshSelected(page.rows),
|
|
224
|
+
picked: this.followPicked(page.rows, false),
|
|
210
225
|
});
|
|
226
|
+
this.pickedChanged(picked);
|
|
211
227
|
return;
|
|
212
228
|
}
|
|
213
229
|
this.all = page.rows;
|
|
214
230
|
this.given = null;
|
|
215
231
|
this.dropMissingSelection();
|
|
216
|
-
|
|
232
|
+
const picked = this.state.picked;
|
|
233
|
+
this.view({ status: "ready", refreshing: false, error: null, picked: this.followPicked(this.all, true) });
|
|
234
|
+
this.pickedChanged(picked);
|
|
217
235
|
}
|
|
218
236
|
fail(error, seq) {
|
|
219
237
|
if (seq !== this.seq)
|
|
@@ -301,6 +319,9 @@ export class TableStore {
|
|
|
301
319
|
*/
|
|
302
320
|
upsert(row, { at = "start", flash = true } = {}) {
|
|
303
321
|
const key = this.keyOf(row);
|
|
322
|
+
// The picked record's new copy is the one picked now.
|
|
323
|
+
const before = this.state.picked;
|
|
324
|
+
const picked = before && key && this.keyOf(before) === key ? row : before;
|
|
304
325
|
if (this.options.paging === "server") {
|
|
305
326
|
const index = this.state.rows.findIndex(candidate => this.keyOf(candidate) === key);
|
|
306
327
|
const rows = [...this.state.rows];
|
|
@@ -315,7 +336,7 @@ export class TableStore {
|
|
|
315
336
|
total++;
|
|
316
337
|
matches++;
|
|
317
338
|
}
|
|
318
|
-
this.set({ rows, total, matches, selected: this.replaceSelected(key, row), status: "ready" });
|
|
339
|
+
this.set({ rows, total, matches, selected: this.replaceSelected(key, row), picked, status: "ready" });
|
|
319
340
|
}
|
|
320
341
|
else {
|
|
321
342
|
const index = this.all.findIndex(candidate => this.keyOf(candidate) === key);
|
|
@@ -326,8 +347,9 @@ export class TableStore {
|
|
|
326
347
|
else
|
|
327
348
|
this.all.push(row);
|
|
328
349
|
this.all = [...this.all];
|
|
329
|
-
this.view({ selected: this.replaceSelected(key, row), status: "ready" });
|
|
350
|
+
this.view({ selected: this.replaceSelected(key, row), picked, status: "ready" });
|
|
330
351
|
}
|
|
352
|
+
this.pickedChanged(before);
|
|
331
353
|
if (flash && key)
|
|
332
354
|
this.flash([key]);
|
|
333
355
|
}
|
|
@@ -355,6 +377,9 @@ export class TableStore {
|
|
|
355
377
|
for (const key of gone)
|
|
356
378
|
selected.delete(key);
|
|
357
379
|
const busy = new Set([...this.state.busy].filter(key => !gone.has(key)));
|
|
380
|
+
// A picked record that left the list is no longer picked.
|
|
381
|
+
const before = this.state.picked;
|
|
382
|
+
const picked = before && gone.has(this.keyOf(before)) ? null : before;
|
|
358
383
|
if (this.options.paging === "server") {
|
|
359
384
|
const rows = this.state.rows.filter(row => !gone.has(this.keyOf(row)));
|
|
360
385
|
const removed = this.state.rows.length - rows.length;
|
|
@@ -363,15 +388,18 @@ export class TableStore {
|
|
|
363
388
|
total: Math.max(0, this.state.total - removed),
|
|
364
389
|
matches: Math.max(0, this.state.matches - removed),
|
|
365
390
|
selected: selected.size === this.state.selected.size ? this.state.selected : selected,
|
|
391
|
+
picked,
|
|
366
392
|
busy,
|
|
367
393
|
});
|
|
394
|
+
this.pickedChanged(before);
|
|
368
395
|
// A short wait lets several removals (a mass action's rows) share one load.
|
|
369
396
|
clearTimeout(this.reloadTimer);
|
|
370
397
|
this.reloadTimer = setTimeout(() => void this.reload({ quiet: true }), 60);
|
|
371
398
|
return;
|
|
372
399
|
}
|
|
373
400
|
this.all = this.all.filter(row => !gone.has(this.keyOf(row)));
|
|
374
|
-
this.view({ selected: selected.size === this.state.selected.size ? this.state.selected : selected, busy });
|
|
401
|
+
this.view({ selected: selected.size === this.state.selected.size ? this.state.selected : selected, picked, busy });
|
|
402
|
+
this.pickedChanged(before);
|
|
375
403
|
}
|
|
376
404
|
/* Selection */
|
|
377
405
|
/** Selects or unselects rows, up to `maxSelection`. Returns how many rows it could not select. */
|
|
@@ -440,6 +468,35 @@ export class TableStore {
|
|
|
440
468
|
this.state = { ...this.state, selected: selected.size ? selected : EMPTY_MAP };
|
|
441
469
|
this.options.onSelectionChange?.(this.getSelected());
|
|
442
470
|
}
|
|
471
|
+
/* The picked row */
|
|
472
|
+
/**
|
|
473
|
+
* Picks a row (`DataTable` `onPick`), or none: the one row whose own records the page shows beside the table. It
|
|
474
|
+
* follows the record from then on - its newest copy after an upsert, none once it is removed or gone after a load -
|
|
475
|
+
* and every change is told to `onPickChange`.
|
|
476
|
+
*/
|
|
477
|
+
pick(row) {
|
|
478
|
+
const next = row !== null && this.keyOf(row) !== "" ? row : null;
|
|
479
|
+
if (next === this.state.picked)
|
|
480
|
+
return;
|
|
481
|
+
this.set({ picked: next });
|
|
482
|
+
this.options.onPickChange?.(next);
|
|
483
|
+
}
|
|
484
|
+
/**
|
|
485
|
+
* The picked row as these rows hold it: its newest copy, or none when they are every row there is (`whole`, a client
|
|
486
|
+
* table) and it is not among them. A server page without it keeps it, since it may be on another page.
|
|
487
|
+
*/
|
|
488
|
+
followPicked(rows, whole) {
|
|
489
|
+
const picked = this.state.picked;
|
|
490
|
+
if (!picked)
|
|
491
|
+
return null;
|
|
492
|
+
const key = this.keyOf(picked);
|
|
493
|
+
return rows.find(row => this.keyOf(row) === key) ?? (whole ? null : picked);
|
|
494
|
+
}
|
|
495
|
+
/** Tells the page when a change left another copy of the picked row, or none. */
|
|
496
|
+
pickedChanged(before) {
|
|
497
|
+
if (this.state.picked !== before)
|
|
498
|
+
this.options.onPickChange?.(this.state.picked);
|
|
499
|
+
}
|
|
443
500
|
/* Rows with an action running, and rows to highlight */
|
|
444
501
|
setBusy(keys, on) {
|
|
445
502
|
const busy = new Set(this.state.busy);
|
|
@@ -505,12 +562,17 @@ export class TableStore {
|
|
|
505
562
|
return;
|
|
506
563
|
this.set({ widths: NO_WIDTHS });
|
|
507
564
|
}
|
|
508
|
-
/**
|
|
565
|
+
/**
|
|
566
|
+
* Keeps a column on the left or the right while the others scroll, or lets it scroll again (`null`). A choice equal
|
|
567
|
+
* to the column's own `pinned` is no change to remember; unpinning a column its params pin is remembered as `null`,
|
|
568
|
+
* which wins over them.
|
|
569
|
+
*/
|
|
509
570
|
setPinned(key, side) {
|
|
510
|
-
|
|
571
|
+
const own = this.options.columns.find(column => column.key === key)?.pinned ?? null;
|
|
572
|
+
if (columnPin({ key, pinned: own ?? undefined }, this.state.pinned) === side)
|
|
511
573
|
return;
|
|
512
574
|
const pinned = { ...this.state.pinned };
|
|
513
|
-
if (side ===
|
|
575
|
+
if (side === own)
|
|
514
576
|
delete pinned[key];
|
|
515
577
|
else
|
|
516
578
|
pinned[key] = side;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** The sizes a toolbar is laid out with, in pixels. */
|
|
2
|
+
export interface ToolbarSizes {
|
|
3
|
+
/** A button's width. */
|
|
4
|
+
tool: number;
|
|
5
|
+
/** A divider's width with its margins. */
|
|
6
|
+
divider: number;
|
|
7
|
+
/** The gap between two items. */
|
|
8
|
+
gap: number;
|
|
9
|
+
/** The "More" button's width. Default `tool`. */
|
|
10
|
+
more?: number;
|
|
11
|
+
}
|
|
12
|
+
/** What a toolbar of a width shows: its items in order, dividers among them, and the tools left for the menu. */
|
|
13
|
+
export interface ToolbarFit<T extends string> {
|
|
14
|
+
shown: (T | "|")[];
|
|
15
|
+
hidden: T[];
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* The items of a toolbar that fit `width`, in order, and the rest for its "More" menu. All of them when they fit; else
|
|
19
|
+
* as many as fit beside the "More" button, with no divider left at the end of the row and none in the menu.
|
|
20
|
+
*
|
|
21
|
+
* @example fitToolbar(["bold", "italic", "|", "link"], 70, { tool: 28, divider: 11, gap: 2 }) // { shown: ["bold"], hidden: ["italic", "link"] }
|
|
22
|
+
*/
|
|
23
|
+
export declare function fitToolbar<T extends string>(items: readonly (T | "|")[], width: number, sizes: ToolbarSizes): ToolbarFit<T>;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* A toolbar that keeps to one row: which of its buttons fit the room it has, and which go into its "More" menu. Pure,
|
|
3
|
+
* so it is checked without a browser; an editor measures its row and its sizes and draws what this answers.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* The items of a toolbar that fit `width`, in order, and the rest for its "More" menu. All of them when they fit; else
|
|
7
|
+
* as many as fit beside the "More" button, with no divider left at the end of the row and none in the menu.
|
|
8
|
+
*
|
|
9
|
+
* @example fitToolbar(["bold", "italic", "|", "link"], 70, { tool: 28, divider: 11, gap: 2 }) // { shown: ["bold"], hidden: ["italic", "link"] }
|
|
10
|
+
*/
|
|
11
|
+
export function fitToolbar(items, width, sizes) {
|
|
12
|
+
const size = (item) => (item === "|" ? sizes.divider : sizes.tool);
|
|
13
|
+
const all = items.reduce((total, item, index) => total + size(item) + (index > 0 ? sizes.gap : 0), 0);
|
|
14
|
+
if (all <= width)
|
|
15
|
+
return { shown: [...items], hidden: [] };
|
|
16
|
+
const room = width - (sizes.more ?? sizes.tool) - sizes.gap;
|
|
17
|
+
let used = 0;
|
|
18
|
+
let count = 0;
|
|
19
|
+
for (const item of items) {
|
|
20
|
+
const next = size(item) + (count > 0 ? sizes.gap : 0);
|
|
21
|
+
if (used + next > room)
|
|
22
|
+
break;
|
|
23
|
+
used += next;
|
|
24
|
+
count++;
|
|
25
|
+
}
|
|
26
|
+
const shown = items.slice(0, count);
|
|
27
|
+
while (shown.length > 0 && shown[shown.length - 1] === "|")
|
|
28
|
+
shown.pop();
|
|
29
|
+
return { shown, hidden: items.slice(count).filter((item) => item !== "|") };
|
|
30
|
+
}
|
|
@@ -38,7 +38,34 @@ export interface TreeStoreOptions<TItem extends TreeItem = TreeItem> {
|
|
|
38
38
|
* than 0). Without it, or when the field is empty, a node counts as having children until its first page answers.
|
|
39
39
|
*/
|
|
40
40
|
hasChildrenKey?: string;
|
|
41
|
+
/** The leaves shown at the start: see `TreeStore.setFilter`. Default: all. */
|
|
42
|
+
filter?: TreeFilterMatch<TItem> | null;
|
|
41
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* Which leaves a filtered tree shows (`TreeStore.setFilter`): asked of every item without children. A parent shows when it
|
|
46
|
+
* holds a leaf the filter shows; one whose children are still to load (a lazy tree) shows too, since they may.
|
|
47
|
+
*/
|
|
48
|
+
export type TreeFilterMatch<TItem extends TreeItem = TreeItem> = (item: TItem) => boolean;
|
|
49
|
+
/** One tab of a tree's filters (TreeView `filters`): what it is called, and the leaves it shows. */
|
|
50
|
+
export interface TreeFilter<TItem extends TreeItem = TreeItem> {
|
|
51
|
+
/** Unique among the filters: what `defaultFilter`, the kept choice and `onFilterChange` name. */
|
|
52
|
+
id: string;
|
|
53
|
+
/** The tab's text, e.g. "View only". */
|
|
54
|
+
label: string;
|
|
55
|
+
/** The tab's tooltip. */
|
|
56
|
+
title?: string;
|
|
57
|
+
/** The leaves it shows, asked of every item without children. Left out: all of them (an "All" tab). */
|
|
58
|
+
match?: TreeFilterMatch<TItem>;
|
|
59
|
+
}
|
|
60
|
+
/** Where a tree keeps the filter chosen in this browser: per `key` and `viewer`, nothing without a viewer. */
|
|
61
|
+
export declare function treeFilterStorageKey(remember: {
|
|
62
|
+
key: string;
|
|
63
|
+
viewer?: string | null;
|
|
64
|
+
} | undefined): string | null;
|
|
65
|
+
/** The filter on: the one chosen, else the default, else the first; `undefined` without filters. An id no filter has is passed over. */
|
|
66
|
+
export declare function shownTreeFilter<TFilter extends {
|
|
67
|
+
id: string;
|
|
68
|
+
}>(filters: readonly TFilter[] | undefined, chosen: string | null | undefined, defaultId?: string): TFilter | undefined;
|
|
42
69
|
/** A row that is not an item, under a parent of a lazy tree: its page is on its way, failed (Retry), or more can be loaded. */
|
|
43
70
|
export type TreeStatusKind = "loading" | "error" | "more";
|
|
44
71
|
/** Where a lazy parent's children stand: what was asked of the loader, and what it said. */
|
|
@@ -78,6 +105,40 @@ export interface TreeChildrenPage<TItem extends TreeItem = TreeItem> {
|
|
|
78
105
|
/** Whether another page follows. Default: `total` says so, or the page was full. */
|
|
79
106
|
hasMore?: boolean;
|
|
80
107
|
}
|
|
108
|
+
/**
|
|
109
|
+
* A change to one item of a tree's source made somewhere else - a form saved, a record moved to the trash - written into
|
|
110
|
+
* the pages kept for the tree (`writeTreeChanges`) and into every tree on screen that shows them, so nothing is read
|
|
111
|
+
* from the server again for it.
|
|
112
|
+
*/
|
|
113
|
+
export type TreeItemChange<TItem extends TreeItem = TreeItem> = {
|
|
114
|
+
/** Added, changed, or moved: the item as it is now, under the item whose value is `parent` (`null`: the top level). */
|
|
115
|
+
type: "put";
|
|
116
|
+
item: TItem;
|
|
117
|
+
parent: TreeValue | null;
|
|
118
|
+
/**
|
|
119
|
+
* Where it was: its parent's value (`null`: the top level), or `false` when it was not in the tree at all - just
|
|
120
|
+
* added, or back from the trash. Left out when not known: a tree that holds the item knows, and the kept pages are
|
|
121
|
+
* searched; an item found nowhere then changes no count.
|
|
122
|
+
*/
|
|
123
|
+
before?: TreeValue | null | false;
|
|
124
|
+
} | {
|
|
125
|
+
/** Out of the tree - moved to the trash, deleted: the item's value, and its parent's when known. */
|
|
126
|
+
type: "remove";
|
|
127
|
+
value: TreeValue;
|
|
128
|
+
parent?: TreeValue | null;
|
|
129
|
+
};
|
|
130
|
+
/** How a tree reads its items, for changes written from outside it: the same keys the tree is given. */
|
|
131
|
+
export interface TreeChangeRules<TItem extends TreeItem = TreeItem> {
|
|
132
|
+
/** The item field that holds its value: the tree's `valueKey`. Default `id`. */
|
|
133
|
+
valueKey?: string;
|
|
134
|
+
/** The tree's `hasChildrenKey`: a parent's count there goes up and down with its children, and its chevron with it. */
|
|
135
|
+
hasChildrenKey?: string;
|
|
136
|
+
/**
|
|
137
|
+
* The order of siblings, as the server sorts them, so an item added or changed goes where a fresh read would put it.
|
|
138
|
+
* Without it an added item goes after the children loaded, and a changed one stays where it was.
|
|
139
|
+
*/
|
|
140
|
+
compare?: (a: TItem, b: TItem) => number;
|
|
141
|
+
}
|
|
81
142
|
/** Children's pages kept for every lazy tree on the page that names a `cacheKey`, for 5 minutes: see `RequestCache`. */
|
|
82
143
|
export declare const treePages: RequestCache<TreeChildrenPage<object>>;
|
|
83
144
|
/** The start of every key a tree keeps its pages under, or one parent's pages (`null`: the top level). */
|
|
@@ -90,6 +151,24 @@ export declare function treePageKey(cacheKey: string, parent: TreeValue | null,
|
|
|
90
151
|
* its `refresh()` loads that again.
|
|
91
152
|
*/
|
|
92
153
|
export declare function expireTreePages(cacheKey: string, parent?: TreeValue | null | readonly (TreeValue | null)[]): number;
|
|
154
|
+
/**
|
|
155
|
+
* Writes changes made elsewhere into the pages kept for a tree's source, and into every tree on screen that keeps its
|
|
156
|
+
* pages under `cacheKey` - so a record saved in a form, moved, or sent to the trash shows in the tree at once, and
|
|
157
|
+
* leaving the page and coming back reads nothing again for it. Items go where the parent's children are known (see
|
|
158
|
+
* `TreeStore.placeItem`); a parent whose children were never loaded only counts one more or one fewer, and its first page
|
|
159
|
+
* comes from the server when it is opened, as it would have anyway.
|
|
160
|
+
*/
|
|
161
|
+
export declare function writeTreeChanges<TItem extends TreeItem>(cacheKey: string, changes: readonly TreeItemChange<TItem>[], rules?: TreeChangeRules<TItem>): void;
|
|
162
|
+
type TreeChangeListener = (changes: readonly TreeItemChange[], rules: TreeChangeRules) => void;
|
|
163
|
+
/** Hears the changes written for `cacheKey`: what a tree on screen does to write them into itself. Returns the way out. */
|
|
164
|
+
export declare function subscribeTreeChanges(cacheKey: string, listener: TreeChangeListener): () => void;
|
|
165
|
+
/**
|
|
166
|
+
* The kept pages under `cacheKey` with the changes written in (what `writeTreeChanges` does to `treePages`). A parent's
|
|
167
|
+
* pages are read as one list from its first child, the changes applied to it, and the list written back in pages of the
|
|
168
|
+
* same size, each with the parent's total - so a tree reading them again, page by page, asks the server for exactly the
|
|
169
|
+
* children it does not have. A page still on its way for a changed parent is dropped: its answer may predate the change.
|
|
170
|
+
*/
|
|
171
|
+
export declare function patchTreePages<TItem extends TreeItem>(cache: RequestCache<TreeChildrenPage>, cacheKey: string, changes: readonly TreeItemChange<TItem>[], rules?: TreeChangeRules<TItem>): void;
|
|
93
172
|
/** A has-children field read as the tree reads it: a boolean, or a count above 0; `undefined` when it says nothing. */
|
|
94
173
|
export declare function treeHasChildren(value: unknown): boolean | undefined;
|
|
95
174
|
/** The key of the status row under a parent (`null`: the top level), as `TreeNode.key` holds it. */
|
|
@@ -137,6 +216,21 @@ export interface TreeNode<TItem extends TreeItem = TreeItem> {
|
|
|
137
216
|
* cannot be checked or unchecked as a whole (see `TreeStore.toggle`), and never shows checked unless the value names it.
|
|
138
217
|
*/
|
|
139
218
|
partial: boolean;
|
|
219
|
+
/**
|
|
220
|
+
* A row of the filtered tree (`TreeStore.setFilter`): a leaf the filter shows, a parent holding one, a draft, or a lazy
|
|
221
|
+
* item whose children are still to load. Always true without a filter.
|
|
222
|
+
*/
|
|
223
|
+
shown: boolean;
|
|
224
|
+
/** Children that are `shown`: all of them without a filter. */
|
|
225
|
+
shownChildren: number;
|
|
226
|
+
/**
|
|
227
|
+
* `leaves`, `checkedLeaves`, `openLeaves` and `openChecked` over the leaves the filter shows - what a box, a count and a
|
|
228
|
+
* check of a parent work on while a filter is on. The same numbers without a filter. The value never reads them.
|
|
229
|
+
*/
|
|
230
|
+
shownLeaves: number;
|
|
231
|
+
shownChecked: number;
|
|
232
|
+
shownOpenLeaves: number;
|
|
233
|
+
shownOpenChecked: number;
|
|
140
234
|
/**
|
|
141
235
|
* Set only on a status row, a row that is not an item: under its `parent` (`null`: the top level) a page is on its
|
|
142
236
|
* way, failed, or more can be loaded. A status row is in `rows` only - never in `children`, the value, or the items -
|
|
@@ -200,7 +294,23 @@ export declare class TreeStore<TItem extends TreeItem = TreeItem> {
|
|
|
200
294
|
private openNodes;
|
|
201
295
|
private openCheckedNodes;
|
|
202
296
|
private indexCache;
|
|
297
|
+
/** The leaves shown (`setFilter`); `null`: all. */
|
|
298
|
+
private match;
|
|
299
|
+
/** Goes up whenever a node's counts are worked out again, so what is kept from them knows it is old. */
|
|
300
|
+
private counted;
|
|
301
|
+
private shownRoots;
|
|
203
302
|
constructor(items?: readonly TItem[], options?: TreeStoreOptions<TItem>, value?: readonly TreeValue[]);
|
|
303
|
+
/** Whether a filter is on (`setFilter`). */
|
|
304
|
+
get filtered(): boolean;
|
|
305
|
+
/**
|
|
306
|
+
* Shows only the leaves `match` takes, and the parents that hold one (`null`: every item). Nothing is checked or
|
|
307
|
+
* unchecked by it, and the value is the same whatever filter is on. While one is on, a parent's box, its count, and a
|
|
308
|
+
* check of it - or of "select all" - work on the leaves shown only: checking a parent checks its shown leaves, and a
|
|
309
|
+
* leaf the filter hides keeps its check exactly as it was. Expanded items stay expanded.
|
|
310
|
+
*/
|
|
311
|
+
setFilter(match: TreeFilterMatch<TItem> | null): void;
|
|
312
|
+
/** Children of a parent (`null`: the top level) that are rows of the filtered tree: all of them without a filter. */
|
|
313
|
+
shownChildCount(parent: TreeNode<TItem> | null): number;
|
|
204
314
|
/** Items in the tree, drafts included. */
|
|
205
315
|
get size(): number;
|
|
206
316
|
/** The node of a value. */
|
|
@@ -228,11 +338,19 @@ export declare class TreeStore<TItem extends TreeItem = TreeItem> {
|
|
|
228
338
|
* unloaded items are not in the value - unless the value names it (`valueMode: "checked"`, where it stands for all).
|
|
229
339
|
*/
|
|
230
340
|
state(node: TreeNode<TItem>): TreeCheckState;
|
|
231
|
-
/**
|
|
341
|
+
/** The state of a parent over all of its leaves, whatever the filter shows. */
|
|
342
|
+
private wholeState;
|
|
343
|
+
private stateOver;
|
|
344
|
+
/** Checked boxes and all boxes: leaves with `cascade`, every item without it. Drafts count. The filter does not narrow it. */
|
|
232
345
|
counts(): {
|
|
233
346
|
checked: number;
|
|
234
347
|
total: number;
|
|
235
348
|
};
|
|
349
|
+
/** `counts` over what the filter shows: the leaves shown with `cascade`, the rows of items without it. */
|
|
350
|
+
shownCounts(): {
|
|
351
|
+
checked: number;
|
|
352
|
+
total: number;
|
|
353
|
+
};
|
|
236
354
|
/**
|
|
237
355
|
* The checked values, in tree order, following `valueMode`. In a lazy tree, values whose items are not loaded yet
|
|
238
356
|
* (or not settled) follow the others, so a saved value survives until its items come.
|
|
@@ -254,16 +372,19 @@ export declare class TreeStore<TItem extends TreeItem = TreeItem> {
|
|
|
254
372
|
* silently leave the rest out. The items under it whose own items are all loaded can still be checked one by one.
|
|
255
373
|
*/
|
|
256
374
|
toggle(node: TreeNode<TItem>): boolean;
|
|
257
|
-
/**
|
|
375
|
+
/**
|
|
376
|
+
* Checks or unchecks a node; with `cascade`, every item under it that is not locked - and, while a filter is on, that
|
|
377
|
+
* the filter shows: the hidden ones keep their checks. Returns whether anything changed.
|
|
378
|
+
*/
|
|
258
379
|
setChecked(node: TreeNode<TItem>, checked: boolean): boolean;
|
|
259
|
-
/** The state of a "select all" box, over the items that are not locked; `null` when every
|
|
380
|
+
/** The state of a "select all" box, over the items that are not locked (and shown); `null` when every one is locked. */
|
|
260
381
|
allState(): TreeCheckState | null;
|
|
261
382
|
/** What a click on a "select all" box does: checks every item that is not locked, or unchecks them all when all are checked. */
|
|
262
383
|
toggleAll(): boolean;
|
|
263
384
|
/**
|
|
264
|
-
* Checks or unchecks every item that is not locked. Returns whether anything changed. In a
|
|
265
|
-
* a node whose items are not all loaded is passed over and the loaded parts under it are
|
|
266
|
-
* items are not loaded stay as they are.
|
|
385
|
+
* Checks or unchecks every item that is not locked, and that the filter shows. Returns whether anything changed. In a
|
|
386
|
+
* lazy tree with `cascade`, a node whose items are not all loaded is passed over and the loaded parts under it are
|
|
387
|
+
* changed; values whose items are not loaded stay as they are.
|
|
267
388
|
*/
|
|
268
389
|
checkAll(checked: boolean): boolean;
|
|
269
390
|
/** Whether every parent of the node is expanded, so the node is a row. */
|
|
@@ -342,6 +463,34 @@ export declare class TreeStore<TItem extends TreeItem = TreeItem> {
|
|
|
342
463
|
}): void;
|
|
343
464
|
/** Removes a node and everything under it. Returns the removed nodes in tree order. */
|
|
344
465
|
remove(node: TreeNode<TItem>): TreeNode<TItem>[];
|
|
466
|
+
/**
|
|
467
|
+
* Writes an item where a change made elsewhere left it (see `TreeItemChange`): in place under the same parent (moved
|
|
468
|
+
* among its siblings by `compare`), under its new parent when it moved - with what is loaded under it - and in for the
|
|
469
|
+
* first time when it is new or back. Only where the parent's children are known: given, loaded, or known to be none.
|
|
470
|
+
* Under a parent never opened it waits for that parent's first page, and one that sorts after the loaded children while
|
|
471
|
+
* more are to come waits for its page. A lazy parent's `loaded` and `total` follow, so its next page skips the right
|
|
472
|
+
* number, and so does the count in `hasChildrenKey` on the parent's own item, which its chevron goes by. Returns the
|
|
473
|
+
* item's node where it is now, or `undefined` when this tree does not show it.
|
|
474
|
+
*/
|
|
475
|
+
placeItem(item: TItem, parentValue: TreeValue | null, options?: {
|
|
476
|
+
before?: TreeValue | null | false;
|
|
477
|
+
compare?: (a: TItem, b: TItem) => number;
|
|
478
|
+
}): TreeNode<TItem> | undefined;
|
|
479
|
+
/**
|
|
480
|
+
* Takes out an item a change made elsewhere took out of the tree - moved to the trash, deleted - with everything under
|
|
481
|
+
* it. Its parent counts one fewer (its pages' `loaded` and `total`, the count on its item) and loses its chevron when
|
|
482
|
+
* none are left. An item not loaded here still lowers its parent's counts when `parentValue` names the parent.
|
|
483
|
+
* Returns the nodes taken out.
|
|
484
|
+
*/
|
|
485
|
+
removeItem(value: TreeValue, parentValue?: TreeValue | null): TreeNode<TItem>[];
|
|
486
|
+
/** Whether a parent's children are known here: given in the items, loaded (all or the first pages), or known to be none. */
|
|
487
|
+
private listsChildren;
|
|
488
|
+
/**
|
|
489
|
+
* One child more or fewer under a parent (`null`: the top level): its pages' total, and the count its own item
|
|
490
|
+
* carries in `hasChildrenKey` - a new copy of the item. A parent never opened reads its children from the new count,
|
|
491
|
+
* so one that has none left loses its chevron; one whose children were loaded knows already.
|
|
492
|
+
*/
|
|
493
|
+
private countChild;
|
|
345
494
|
private createNode;
|
|
346
495
|
/** A lazy node's pages before anything is asked: none to ask for when its item says it has no children. */
|
|
347
496
|
private newPages;
|
|
@@ -400,3 +549,4 @@ export declare class TreeStore<TItem extends TreeItem = TreeItem> {
|
|
|
400
549
|
}
|
|
401
550
|
/** Nodes in tree order: each node, then its children. No recursion, so even a chain 100,000 levels deep works. */
|
|
402
551
|
export declare function preOrder<TItem extends TreeItem>(nodes: readonly TreeNode<TItem>[]): TreeNode<TItem>[];
|
|
552
|
+
export {};
|