@lavalogic/scoria 0.12.2 → 0.13.1
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/dist/Components/Base/ContextWrapper.svelte +16 -1
- package/dist/Components/Base/ContextWrapper.svelte.d.ts +13 -0
- package/dist/Components/TabGroupButtonProps.d.ts +1 -1
- package/dist/Components/Table/Body/QuickSearchCell.svelte +2 -3
- package/dist/Components/Table/Body/Rows/ColumnList.svelte +1 -1
- package/dist/Components/Table/Body/Rows/ColumnListRow.svelte +1 -1
- package/dist/Components/Table/Body/Rows/Columns/AccessorComponent.svelte +3 -3
- package/dist/Components/Table/Body/Rows/Columns/AccessorComponent.svelte.d.ts +12 -12
- package/dist/Components/Table/Body/Rows/Columns/AccessorComponentProps.d.ts +2 -2
- package/dist/Components/Table/Body/Rows/Columns/ActionsCell.svelte +27 -17
- package/dist/Components/Table/Body/Rows/Columns/ActionsCell.svelte.d.ts +11 -11
- package/dist/Components/Table/Body/Rows/Columns/BubbleCell.svelte +11 -9
- package/dist/Components/Table/Body/Rows/Columns/BubbleCell.svelte.d.ts +12 -12
- package/dist/Components/Table/Body/Rows/Columns/ExpandCell.svelte +8 -4
- package/dist/Components/Table/Body/Rows/Columns/ExpandCell.svelte.d.ts +13 -12
- package/dist/Components/Table/Body/Rows/Columns/ExpandCellProps.d.ts +5 -4
- package/dist/Components/Table/Body/Rows/Columns/FocusableImmutableCell.svelte +4 -4
- package/dist/Components/Table/Body/Rows/Columns/FocusableImmutableCell.svelte.d.ts +12 -12
- package/dist/Components/Table/Body/Rows/Columns/FocusableImmutableCellProps.d.ts +2 -2
- package/dist/Components/Table/Body/Rows/Columns/ProgressCell.svelte +11 -8
- package/dist/Components/Table/Body/Rows/Columns/RowSelectionColumn.d.ts +5 -0
- package/dist/Components/Table/Body/Rows/Columns/RowSelectionColumn.js +1 -0
- package/dist/Components/Table/Body/Rows/Columns/RowSelectionTableCell.d.ts +5 -0
- package/dist/Components/Table/Body/Rows/Columns/RowSelectionTableCell.js +1 -0
- package/dist/Components/Table/Body/Rows/Columns/TableCheckbox.svelte +4 -3
- package/dist/Components/Table/Body/Rows/Columns/TableCheckbox.svelte.d.ts +2 -1
- package/dist/Components/Table/Body/Rows/Columns/TableColumn.svelte +16 -9
- package/dist/Components/Table/Body/Rows/Columns/TableColumn.svelte.d.ts +17 -16
- package/dist/Components/Table/Body/Rows/Columns/TableDatePicker.svelte +5 -4
- package/dist/Components/Table/Body/Rows/Columns/TableNumberInput.svelte +10 -8
- package/dist/Components/Table/Body/Rows/Columns/TableNumberInput.svelte.d.ts +2 -1
- package/dist/Components/Table/Body/Rows/Columns/TableQuerySelect.svelte +10 -7
- package/dist/Components/Table/Body/Rows/Columns/TableRowSelectionCheckbox.svelte +11 -7
- package/dist/Components/Table/Body/Rows/Columns/TableRowSelectionCheckbox.svelte.d.ts +2 -1
- package/dist/Components/Table/Body/Rows/Columns/TableSelect.svelte +10 -7
- package/dist/Components/Table/Body/Rows/Columns/TableTextInput.svelte +11 -9
- package/dist/Components/Table/Body/Rows/Columns/TableTextInput.svelte.d.ts +12 -12
- package/dist/Components/Table/Body/Rows/Columns/TableTextInputProps.d.ts +2 -2
- package/dist/Components/Table/Body/Rows/Columns/ValidityCell.svelte +7 -7
- package/dist/Components/Table/Body/Rows/Columns/ValidityCell.svelte.d.ts +12 -12
- package/dist/Components/Table/Body/Rows/Columns/ValidityCellProps.d.ts +2 -2
- package/dist/Components/Table/Body/Rows/TableRow.svelte +7 -6
- package/dist/Components/Table/Body/TableBody.svelte +19 -15
- package/dist/Components/Table/ColumnDefinitions/ExampleItemColumnDefRepository.svelte.d.ts +1 -1
- package/dist/Components/Table/ColumnDefinitions/ExampleItemColumnDefRepository.svelte.js +17 -2
- package/dist/Components/Table/Headers/HighlightAllHeader.svelte +29 -16
- package/dist/Components/Table/Headers/SelectAllHeader.svelte +1 -1
- package/dist/Components/Table/Headers/TableHead.svelte +1 -1
- package/dist/Components/Table/Misc/ColumnPanel.svelte +1 -1
- package/dist/Components/Table/Misc/ColumnPanelModal.svelte +1 -1
- package/dist/Components/Table/Misc/FilterInput.svelte +1 -3
- package/dist/Components/Table/Misc/FilterPanel.svelte +2 -2
- package/dist/Components/Table/Misc/FilterPanelModal.svelte +1 -1
- package/dist/Components/Table/Misc/TableFooter.svelte +1 -1
- package/dist/Components/Table/Misc/TableHorizontalBar.svelte +1 -1
- package/dist/Components/Table/Misc/TableSidebar.svelte +2 -1
- package/dist/Components/Table/Misc/ToolboxPanel.svelte +2 -2
- package/dist/Components/Table/Misc/ToolboxPanelModal.svelte +1 -1
- package/dist/Components/Table/NestedTable.svelte +12 -8
- package/dist/Components/Table/NestedTable.svelte.d.ts +15 -15
- package/dist/Components/Table/Table.svelte +111 -118
- package/dist/Components/Table/Table.svelte.d.ts +16 -15
- package/dist/Components/Table/Types/Columns/Column.d.ts +2 -2
- package/dist/Components/Table/Types/Columns/Definitions/ColumnDef.svelte.d.ts +2 -2
- package/dist/Components/Table/Types/Columns/Definitions/Display/AbstractDisplayDef.svelte.d.ts +6 -6
- package/dist/Components/Table/Types/Columns/Definitions/Display/ValidityDef.svelte.d.ts +3 -3
- package/dist/Components/Table/Types/Columns/Definitions/Expand/ExpandDef.svelte.d.ts +6 -6
- package/dist/Components/Table/Types/Columns/DefsWrapper.d.ts +2 -2
- package/dist/Components/Table/Types/Columns/ExpandColumn.d.ts +3 -2
- package/dist/Components/Table/Types/Columns/ExpandTableCell.d.ts +3 -2
- package/dist/Components/Table/Types/Columns/ProgressBarTableCell.d.ts +2 -1
- package/dist/Components/Table/Types/Columns/TableCell.d.ts +2 -2
- package/dist/Components/Table/Types/Context/ITable.d.ts +1 -1
- package/dist/Components/Table/Types/Context/TableContext.svelte.d.ts +32 -29
- package/dist/Components/Table/Types/Context/TableContext.svelte.js +313 -278
- package/dist/Components/Table/Types/Context/TableInitOptions.d.ts +4 -2
- package/dist/Components/Table/Types/DataRepository/IDataRepository.d.ts +1 -1
- package/dist/Components/Table/Types/DataRepository/ILocalDataRepository.d.ts +1 -2
- package/dist/Components/Table/Types/DataRepository/LocalTableDataRepository.svelte.d.ts +2 -1
- package/dist/Components/Table/Types/DataRepository/LocalTableDataRepository.svelte.js +31 -8
- package/dist/Components/Table/Types/DataRepository/TableDataRepository.svelte.d.ts +2 -1
- package/dist/Components/Table/Types/DataRepository/TableDataRepository.svelte.js +4 -1
- package/dist/Components/Table/Types/Filtering/CustomFilterFn.d.ts +1 -1
- package/dist/Components/Table/Types/Filtering/FilterFn.d.ts +1 -1
- package/dist/Components/Table/Types/Focus/TableFocusDetails.svelte.d.ts +7 -6
- package/dist/Components/Table/Types/Focus/TableFocusDetails.svelte.js +8 -2
- package/dist/Components/VerticalTabGroupButton.svelte +1 -1
- package/dist/Components/VerticalTabGroupButton.svelte.d.ts +5 -5
- package/dist/Components/VerticalTabGroupProps.d.ts +2 -2
- package/dist/Contexts/ToastContext.svelte.d.ts +3 -1
- package/dist/Contexts/ToastContext.svelte.js +2 -2
- package/dist/Helpers/Helpers.svelte.d.ts +1 -2
- package/dist/Types/Examples/ExampleModal.svelte +2 -2
- package/dist/Types/Examples/ExampleModal.svelte.d.ts +23 -2
- package/dist/Types/Internal/TabOption.d.ts +1 -1
- package/dist/index.d.ts +1 -1
- package/package.json +18 -18
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { browser, dev } from '$app/environment';
|
|
2
|
-
import { asyncAll, asyncFilterIndices, asyncSleep, devCatch, getCanvasContext, getErrorMessage } from '../../../../Helpers/Helpers.svelte.js';
|
|
3
|
-
import { tick } from 'svelte';
|
|
2
|
+
import { asyncAll, asyncFilterIndices, asyncForEach, asyncMap, asyncSleep, devCatch, getCanvasContext, getErrorMessage } from '../../../../Helpers/Helpers.svelte.js';
|
|
3
|
+
import { tick, untrack } from 'svelte';
|
|
4
4
|
import { SvelteMap, SvelteSet } from 'svelte/reactivity';
|
|
5
5
|
import { ColumnType } from '../Columns/ColumnType.js';
|
|
6
6
|
import { AccessorDef } from '../Columns/Definitions/Accessors/AccessorDef.svelte.js';
|
|
@@ -39,15 +39,16 @@ export class TableContext {
|
|
|
39
39
|
selectionExtractor;
|
|
40
40
|
getUserId;
|
|
41
41
|
_onEditCell;
|
|
42
|
+
debug;
|
|
42
43
|
static identifier = Symbol();
|
|
43
44
|
static init(defaultColumnDefs, tableName, dataRepo, options) {
|
|
44
|
-
const context = new this(InternalSymbol, defaultColumnDefs, tableName, dataRepo, options.allowCopy ?? true, options.enableResize ?? true, options.allowColumnReordering ?? true, options.allowQuickFiltering ?? true, options.showQuickFilterByDefault ?? true, options.allowAdvancedFiltering ?? true, options.toolbar ?? ToolbarPosition.Right, options.displayFooter ?? true, options.selectionExtractor, options.getUserId, options.onEditCell);
|
|
45
|
+
const context = new this(InternalSymbol, defaultColumnDefs, tableName, dataRepo, options.allowCopy ?? true, options.enableResize ?? true, options.allowColumnReordering ?? true, options.allowQuickFiltering ?? true, options.showQuickFilterByDefault ?? true, options.allowAdvancedFiltering ?? true, options.toolbar ?? ToolbarPosition.Right, options.displayFooter ?? true, options.selectionExtractor, options.getUserId, options.onEditCell, options.debug ?? false);
|
|
45
46
|
return context;
|
|
46
47
|
}
|
|
47
48
|
// #region constructor
|
|
48
49
|
constructor(INTERNAL_ONLY, defaultColumnDefs, tableName, dataRepo, allowCopy, enableResize, allowColumnReordering, allowQuickFiltering, showQuickFilterByDefault, allowAdvancedFiltering, toolbarPosition, displayFooter, selectionExtractor, getUserId, _onEditCell = () => {
|
|
49
50
|
console.warn('Cannot edit immutable table');
|
|
50
|
-
}) {
|
|
51
|
+
}, debug) {
|
|
51
52
|
this.defaultColumnDefs = defaultColumnDefs;
|
|
52
53
|
this.tableName = tableName;
|
|
53
54
|
this.allowCopy = allowCopy;
|
|
@@ -61,11 +62,24 @@ export class TableContext {
|
|
|
61
62
|
this.selectionExtractor = selectionExtractor;
|
|
62
63
|
this.getUserId = getUserId;
|
|
63
64
|
this._onEditCell = _onEditCell;
|
|
65
|
+
this.debug = debug;
|
|
64
66
|
if (INTERNAL_ONLY != InternalSymbol) {
|
|
65
67
|
throw new Error('This class may only be instantiated through the static init() method');
|
|
66
68
|
}
|
|
67
69
|
this._dataRepo = $state(dataRepo);
|
|
68
70
|
// this.dataRepo.forceRefresh = this.forceVisibilityUpdate;
|
|
71
|
+
$effect(() => {
|
|
72
|
+
void this.currentPageData;
|
|
73
|
+
void this.selectedItems;
|
|
74
|
+
untrack(async () => {
|
|
75
|
+
await this.currentPageData;
|
|
76
|
+
if (this.paginationRepo?.paginationState.pageIndex != undefined) {
|
|
77
|
+
await this.updateSelectedItems();
|
|
78
|
+
this.resetHighlightedRows();
|
|
79
|
+
this.recalculateAllSelectedInCurrentPage();
|
|
80
|
+
}
|
|
81
|
+
}).catch(devCatch);
|
|
82
|
+
});
|
|
69
83
|
if (defaultColumnDefs.remoteFilters) {
|
|
70
84
|
this.remoteFilters = defaultColumnDefs.remoteFilters;
|
|
71
85
|
}
|
|
@@ -142,11 +156,13 @@ export class TableContext {
|
|
|
142
156
|
$effect(() => {
|
|
143
157
|
void this.paginationRepo?.paginationType;
|
|
144
158
|
void this.dataRepo.filtering;
|
|
145
|
-
void this.dataRepo.filterModes
|
|
159
|
+
void this.dataRepo.filterModes;
|
|
146
160
|
void this.dataRepo.data;
|
|
161
|
+
void this.paginationRepo?.paginationState;
|
|
162
|
+
// console.log('massive effect start');
|
|
147
163
|
(async () => {
|
|
148
164
|
const startTime = Date.now();
|
|
149
|
-
let
|
|
165
|
+
let currentTimer;
|
|
150
166
|
const abortController = new AbortController();
|
|
151
167
|
try {
|
|
152
168
|
if (this.paginationRepo?.paginationType == PaginationType.Local) {
|
|
@@ -156,77 +172,75 @@ export class TableContext {
|
|
|
156
172
|
const snapshot = $state.snapshot(filter.value);
|
|
157
173
|
checkedIds.add(filter.id);
|
|
158
174
|
const filterMode = this.dataRepo.filterModes.get(filter.id);
|
|
159
|
-
return (
|
|
160
|
-
|
|
161
|
-
|
|
175
|
+
return ((snapshot !== '' &&
|
|
176
|
+
snapshot != null &&
|
|
177
|
+
(!Array.isArray(snapshot) || !!snapshot[0])) ||
|
|
178
|
+
(!!filterMode && allowedEmptyFilterModes.has(filterMode)));
|
|
162
179
|
});
|
|
163
180
|
const data = this.dataRepo.data;
|
|
164
|
-
|
|
165
|
-
// this.dataRepo?.filterModes?.entries().forEach(([key, value]) => {
|
|
166
|
-
// if (!checkedIds.has(key)) {
|
|
167
|
-
// checkedIds.add(key);
|
|
168
|
-
// if (allowedEmptyFilterModes.has(value)) {
|
|
169
|
-
// filterState.push({
|
|
170
|
-
// id: key,
|
|
171
|
-
// value: ''
|
|
172
|
-
// });
|
|
173
|
-
// }
|
|
174
|
-
// } else {
|
|
175
|
-
// console.warn(`key ${key} was already checked, new value:`, value);
|
|
176
|
-
// }
|
|
177
|
-
// });
|
|
178
|
-
if (!filterState.length) {
|
|
179
|
-
this.filteredIndices = data.map((_, index) => index);
|
|
180
|
-
}
|
|
181
|
-
currentTimerPromise = this.filterTimer = this.filterTimer + 1;
|
|
181
|
+
currentTimer = ++this.filterTimer;
|
|
182
182
|
await asyncSleep(150);
|
|
183
|
-
|
|
184
|
-
if (currentTimerPromise != this.filterTimer) {
|
|
183
|
+
if (currentTimer != this.filterTimer) {
|
|
185
184
|
throw new Error('stale filter');
|
|
186
185
|
}
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
186
|
+
if (!filterState.length) {
|
|
187
|
+
if (dev) {
|
|
188
|
+
console.log('no filter state was found');
|
|
189
|
+
}
|
|
190
|
+
this.filteredIndices = data.map((_item, index) => {
|
|
191
|
+
return index;
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
this.dataRepo.isLoading = true;
|
|
196
|
+
if (this.debug) {
|
|
197
|
+
console.log('getting filter promise');
|
|
198
|
+
}
|
|
199
|
+
const settled = $state({ value: false });
|
|
200
|
+
const filterPromise = asyncFilterIndices(data, async (item, index) => {
|
|
201
|
+
const row = this.createRow(item, index, index);
|
|
202
|
+
return asyncAll(filterState, async (filter) => {
|
|
203
|
+
abortController.signal.throwIfAborted();
|
|
204
|
+
const def = this.columnDefsById.get(filter.id);
|
|
205
|
+
if (!def) {
|
|
206
|
+
console.warn(`Could not find column def for filter with id ${filter.id}`);
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
209
|
+
if (def.filterFn) {
|
|
210
|
+
return def.filterFn(row, filter.id, filter.value);
|
|
211
|
+
}
|
|
212
|
+
if (this.debug) {
|
|
213
|
+
console.warn(`column ${def.id} did not have a filter function`);
|
|
214
|
+
}
|
|
195
215
|
return false;
|
|
216
|
+
});
|
|
217
|
+
});
|
|
218
|
+
filterPromise
|
|
219
|
+
.then((indices) => {
|
|
220
|
+
if (this.debug) {
|
|
221
|
+
console.log(`iteration ${currentTimer}: got indices from filter promise:`, indices);
|
|
222
|
+
}
|
|
223
|
+
this.filteredIndices = indices;
|
|
224
|
+
})
|
|
225
|
+
.catch((e) => {
|
|
226
|
+
if (this.debug) {
|
|
227
|
+
console.log(`caught filter rejection:`, e);
|
|
228
|
+
console.log(`iteration ${currentTimer} cancelled after ${Date.now() - startTime}ms`);
|
|
229
|
+
}
|
|
230
|
+
})
|
|
231
|
+
.finally(() => {
|
|
232
|
+
if (this.debug) {
|
|
233
|
+
console.log(`timer ${currentTimer} is settled`);
|
|
196
234
|
}
|
|
197
|
-
|
|
198
|
-
|
|
235
|
+
settled.value = true;
|
|
236
|
+
if (currentTimer === this.filterTimer) {
|
|
237
|
+
this.dataRepo.isLoading = false;
|
|
199
238
|
}
|
|
200
|
-
if (
|
|
201
|
-
console.warn(`
|
|
239
|
+
else if (this.debug) {
|
|
240
|
+
console.warn(`skipping disabling load overlay because current timer is ${currentTimer} but newest is ${this.filterTimer}`);
|
|
202
241
|
}
|
|
203
|
-
return false;
|
|
204
242
|
});
|
|
205
|
-
|
|
206
|
-
filterPromise
|
|
207
|
-
.then((indices) => {
|
|
208
|
-
this.filteredIndices = indices;
|
|
209
|
-
})
|
|
210
|
-
.catch((e) => {
|
|
211
|
-
if (dev) {
|
|
212
|
-
console.log(`caught filter rejection:`, e);
|
|
213
|
-
console.log(`iteration ${currentTimer} cancelled after ${Date.now() - startTime}ms`);
|
|
214
|
-
}
|
|
215
|
-
})
|
|
216
|
-
.finally(() => {
|
|
217
|
-
settled = true;
|
|
218
|
-
});
|
|
219
|
-
for (;;) {
|
|
220
|
-
if (currentTimerPromise !== this.filterTimer) {
|
|
221
|
-
abortController.abort('stale data');
|
|
222
|
-
}
|
|
223
|
-
// HACK this warning is wrong. We're in an async context and settled is being changed in the finally callback above
|
|
224
|
-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
225
|
-
if (settled) {
|
|
226
|
-
console.log(`iteration ${currentTimerPromise} finished ${Date.now() - startTime}ms`);
|
|
227
|
-
return;
|
|
228
|
-
}
|
|
229
|
-
await tick();
|
|
243
|
+
await this.filteringLoop(currentTimer, abortController, settled, startTime);
|
|
230
244
|
}
|
|
231
245
|
}
|
|
232
246
|
}
|
|
@@ -234,9 +248,11 @@ export class TableContext {
|
|
|
234
248
|
if (dev) {
|
|
235
249
|
const message = getErrorMessage(e);
|
|
236
250
|
if (!message.toLocaleLowerCase().startsWith('stale')) {
|
|
237
|
-
console.error(e);
|
|
251
|
+
console.error(`Iteration ${currentTimer}`, e);
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
console.log(`iteration ${currentTimer} cancelled after ${Date.now() - startTime}ms`);
|
|
238
255
|
}
|
|
239
|
-
console.log(`iteration ${currentTimerPromise} cancelled after ${Date.now() - startTime}ms`);
|
|
240
256
|
}
|
|
241
257
|
}
|
|
242
258
|
})().catch(devCatch);
|
|
@@ -258,6 +274,14 @@ export class TableContext {
|
|
|
258
274
|
return this._showQuickFiltering;
|
|
259
275
|
}
|
|
260
276
|
set showQuickFiltering(v) {
|
|
277
|
+
if (this.debug) {
|
|
278
|
+
if (!this.allowQuickFiltering) {
|
|
279
|
+
console.log(`attempted to toggle quick filtering when allowQuickFiltering = false`);
|
|
280
|
+
}
|
|
281
|
+
else {
|
|
282
|
+
console.log(`setting quick filtering = ${v}`);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
261
285
|
this._showQuickFiltering = this.allowQuickFiltering && v;
|
|
262
286
|
}
|
|
263
287
|
_dataRepo;
|
|
@@ -305,12 +329,7 @@ export class TableContext {
|
|
|
305
329
|
return this._columnDefs;
|
|
306
330
|
}
|
|
307
331
|
set columnDefs(v) {
|
|
308
|
-
// if (this._columnDefs.length > 0 && v != this._columnDefs) {
|
|
309
|
-
// debugger;
|
|
310
|
-
// }
|
|
311
332
|
this._columnDefs = v;
|
|
312
|
-
// this causes an error...?
|
|
313
|
-
// this.table = createTable(this.tableOptions);
|
|
314
333
|
}
|
|
315
334
|
_columnPresets = $state([]);
|
|
316
335
|
get columnPresets() {
|
|
@@ -358,7 +377,7 @@ export class TableContext {
|
|
|
358
377
|
}
|
|
359
378
|
set focusStart(v) {
|
|
360
379
|
this._focusStart = v;
|
|
361
|
-
this._recalculateFocusedElements();
|
|
380
|
+
this._recalculateFocusedElements().catch(devCatch);
|
|
362
381
|
}
|
|
363
382
|
_focusStartIsBeingEdited = $state(false);
|
|
364
383
|
get focusStartIsBeingEdited() {
|
|
@@ -373,7 +392,7 @@ export class TableContext {
|
|
|
373
392
|
}
|
|
374
393
|
set focusEnd(v) {
|
|
375
394
|
this._focusEnd = v;
|
|
376
|
-
this._recalculateFocusedElements();
|
|
395
|
+
this._recalculateFocusedElements().catch(devCatch);
|
|
377
396
|
}
|
|
378
397
|
_singleClickEditing = $state(false);
|
|
379
398
|
get singleClickEditing() {
|
|
@@ -445,34 +464,38 @@ export class TableContext {
|
|
|
445
464
|
set openModalCoordinates(v) {
|
|
446
465
|
this._openModalCoordinates = v;
|
|
447
466
|
}
|
|
448
|
-
_allSelectedInCurrentPage = $derived.by(() => {
|
|
467
|
+
_allSelectedInCurrentPage = $derived.by(async () => {
|
|
449
468
|
if (this.selectedItems.size === 0) {
|
|
450
469
|
return Promise.resolve(false);
|
|
451
470
|
}
|
|
471
|
+
void this.paginationRepo?.pageStartIndex;
|
|
472
|
+
void this.columnDefs;
|
|
473
|
+
const sortedData = await this.sortedData;
|
|
452
474
|
const pageStartIndex = this.paginationRepo ? this.paginationRepo.pageStartIndex : 0;
|
|
453
475
|
const pageEndIndexExclusive = this.paginationRepo
|
|
454
|
-
? Math.min(this.paginationRepo.pageEndIndexExclusive,
|
|
455
|
-
:
|
|
476
|
+
? Math.min(this.paginationRepo.pageEndIndexExclusive, sortedData.length)
|
|
477
|
+
: sortedData.length;
|
|
456
478
|
const selectableMethod = this.columnDefs.find((it) => it instanceof RowSelectionDef)?.isSelectable;
|
|
457
|
-
return this.allSelectedBySelectableMethod(pageStartIndex, pageEndIndexExclusive, selectableMethod);
|
|
479
|
+
return await this.allSelectedBySelectableMethod(pageStartIndex, pageEndIndexExclusive, selectableMethod);
|
|
458
480
|
});
|
|
459
481
|
get allSelectedInCurrentPage() {
|
|
460
482
|
return this._allSelectedInCurrentPage;
|
|
461
483
|
}
|
|
462
484
|
async allSelectedBySelectableMethod(pageStartIndex, pageEndIndexExclusive, selectableMethod) {
|
|
485
|
+
const sortedData = await this.sortedData;
|
|
463
486
|
if (selectableMethod) {
|
|
464
487
|
for (let index = pageStartIndex; index < pageEndIndexExclusive; index++) {
|
|
465
|
-
const item =
|
|
488
|
+
const item = sortedData[index];
|
|
466
489
|
if ((await selectableMethod(item, index)) &&
|
|
467
|
-
!this.selectedItems.has(this.selectionExtractor(item))) {
|
|
490
|
+
!this.selectedItems.has(await this.selectionExtractor(item))) {
|
|
468
491
|
return Promise.resolve(false);
|
|
469
492
|
}
|
|
470
493
|
}
|
|
471
494
|
}
|
|
472
495
|
else {
|
|
473
496
|
for (let index = pageStartIndex; index < pageEndIndexExclusive; index++) {
|
|
474
|
-
const item =
|
|
475
|
-
if (!this.selectedItems.has(this.selectionExtractor(item))) {
|
|
497
|
+
const item = sortedData[index];
|
|
498
|
+
if (!this.selectedItems.has(await this.selectionExtractor(item))) {
|
|
476
499
|
return Promise.resolve(false);
|
|
477
500
|
}
|
|
478
501
|
}
|
|
@@ -480,48 +503,28 @@ export class TableContext {
|
|
|
480
503
|
return Promise.resolve(true);
|
|
481
504
|
}
|
|
482
505
|
async _areAllHighlighted(pageStartIndex, pageEndIndexExclusive) {
|
|
506
|
+
const sortedData = await this.sortedData;
|
|
483
507
|
for (let index = pageStartIndex; index < pageEndIndexExclusive; index++) {
|
|
484
|
-
const item =
|
|
485
|
-
if (!this.highlightedItems.has(this.selectionExtractor(item))) {
|
|
508
|
+
const item = sortedData[index];
|
|
509
|
+
if (!this.highlightedItems.has(await this.selectionExtractor(item))) {
|
|
486
510
|
return Promise.resolve(false);
|
|
487
511
|
}
|
|
488
512
|
}
|
|
489
513
|
return Promise.resolve(true);
|
|
490
514
|
}
|
|
491
|
-
_allHighlighted = $derived.by(() => {
|
|
515
|
+
_allHighlighted = $derived.by(async () => {
|
|
492
516
|
if (this.highlightedItems.size === 0) {
|
|
493
517
|
return Promise.resolve(false);
|
|
494
518
|
}
|
|
495
519
|
const pageStartIndex = this.paginationRepo ? this.paginationRepo.pageStartIndex : 0;
|
|
496
520
|
const pageEndIndexExclusive = this.paginationRepo
|
|
497
|
-
? Math.min(this.paginationRepo.pageEndIndexExclusive, this.sortedData.length)
|
|
498
|
-
: this.sortedData.length;
|
|
499
|
-
return this._areAllHighlighted(pageStartIndex, pageEndIndexExclusive);
|
|
521
|
+
? Math.min(this.paginationRepo.pageEndIndexExclusive, (await this.sortedData).length)
|
|
522
|
+
: (await this.sortedData).length;
|
|
523
|
+
return await this._areAllHighlighted(pageStartIndex, pageEndIndexExclusive);
|
|
500
524
|
});
|
|
501
525
|
get allHighlighted() {
|
|
502
526
|
return this._allHighlighted;
|
|
503
527
|
}
|
|
504
|
-
// private _allHighlighted: boolean = $derived.by(() => {
|
|
505
|
-
// if (!this.dataRepo || this.highlightedItems.size === 0) {
|
|
506
|
-
// return false;
|
|
507
|
-
// }
|
|
508
|
-
// const pageStartIndex = this.paginationRepo ? this.paginationRepo.pageStartIndex : 0;
|
|
509
|
-
// const pageEndIndexExclusive = this.paginationRepo
|
|
510
|
-
// ? Math.min(this.paginationRepo.pageEndIndexExclusive, this.sortedData.length)
|
|
511
|
-
// : this.sortedData.length;
|
|
512
|
-
// if (pageStartIndex == undefined || pageEndIndexExclusive == undefined) {
|
|
513
|
-
// return false;
|
|
514
|
-
// }
|
|
515
|
-
// for (let index = pageStartIndex; index < pageEndIndexExclusive; index++) {
|
|
516
|
-
// if (!this.highlightedItems.has(index)) {
|
|
517
|
-
// return false;
|
|
518
|
-
// }
|
|
519
|
-
// }
|
|
520
|
-
// return true;
|
|
521
|
-
// });
|
|
522
|
-
// public get allHighlighted(): boolean {
|
|
523
|
-
// return this._allHighlighted;
|
|
524
|
-
// }
|
|
525
528
|
_hasHighlightedItems = $derived(this.highlightedItems.size > 0);
|
|
526
529
|
get hasHighlightedItems() {
|
|
527
530
|
return this._hasHighlightedItems;
|
|
@@ -534,18 +537,6 @@ export class TableContext {
|
|
|
534
537
|
set selectedItems(v) {
|
|
535
538
|
this._selectedItems = v;
|
|
536
539
|
}
|
|
537
|
-
// HACK this is lazily loaded. it will not be used before initialisation.
|
|
538
|
-
// public getSelectedItemsAsObjects = (): T[] => {
|
|
539
|
-
// if (!this.selectionExtractor) {
|
|
540
|
-
// throw new Error("No selection extractor was supplied.")
|
|
541
|
-
// };
|
|
542
|
-
// return this.sortedData.filter((item) => {
|
|
543
|
-
// return this._selectedIdentifiers.has(this.selectionExtractor(item));
|
|
544
|
-
// }) ?? []
|
|
545
|
-
// }
|
|
546
|
-
// public get selectedItemsAsObjects(): T[] {
|
|
547
|
-
// return this._selectedItemsAsObjects;
|
|
548
|
-
// }
|
|
549
540
|
_invalidValues = $state(new SvelteMap());
|
|
550
541
|
get invalidValues() {
|
|
551
542
|
return this._invalidValues;
|
|
@@ -591,10 +582,6 @@ export class TableContext {
|
|
|
591
582
|
// }
|
|
592
583
|
return comparableSortingFn(id, desc);
|
|
593
584
|
};
|
|
594
|
-
originalRowIndices = $derived(
|
|
595
|
-
// TODO decide
|
|
596
|
-
// eslint-disable-next-line svelte/prefer-svelte-reactivity
|
|
597
|
-
new Map(this.dataRepo.data.map((item, index) => [item, index])));
|
|
598
585
|
// private _filterTimer: ReturnType<typeof setTimeout> | undefined;
|
|
599
586
|
_filterTimer = 1;
|
|
600
587
|
get filterTimer() {
|
|
@@ -608,31 +595,43 @@ export class TableContext {
|
|
|
608
595
|
return this._filteredIndices;
|
|
609
596
|
}
|
|
610
597
|
set filteredIndices(v) {
|
|
598
|
+
if (this.debug) {
|
|
599
|
+
console.log('updating filtered indices');
|
|
600
|
+
}
|
|
611
601
|
this._filteredIndices = v;
|
|
612
602
|
}
|
|
613
603
|
filteredData = $derived.by(() => {
|
|
604
|
+
void this.dataRepo.data;
|
|
605
|
+
void this.filteredIndices;
|
|
606
|
+
void this.showSelectedOnly;
|
|
607
|
+
const dataRepo = this.dataRepo;
|
|
614
608
|
if (this.paginationRepo?.paginationType == PaginationType.Local) {
|
|
615
609
|
const data = this.showSelectedOnly
|
|
616
610
|
? // FIXME this will show the selected items by order of insertion to the selectedItems map.
|
|
617
611
|
[...this.selectedItems.values()]
|
|
618
612
|
: this.filteredIndices.map((index) => {
|
|
619
|
-
return
|
|
613
|
+
return dataRepo.data[index];
|
|
620
614
|
});
|
|
621
615
|
return data;
|
|
622
616
|
}
|
|
623
|
-
|
|
617
|
+
if (this.debug) {
|
|
618
|
+
console.log(`updating filtered data. Selected only: ${this.showSelectedOnly}`);
|
|
619
|
+
}
|
|
620
|
+
return this.showSelectedOnly ? [...this.selectedItems.values()] : dataRepo.data;
|
|
624
621
|
});
|
|
625
|
-
|
|
622
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
623
|
+
sortedData = $derived.by(async () => {
|
|
624
|
+
if (this.debug) {
|
|
625
|
+
console.log('sorted data');
|
|
626
|
+
}
|
|
627
|
+
const fd = this.filteredData;
|
|
628
|
+
const sorting = this.dataRepo.sorting;
|
|
626
629
|
if (this.paginationRepo?.paginationType == PaginationType.Local) {
|
|
627
|
-
const
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
[...this.selectedItems.values()]
|
|
631
|
-
: this.filteredData.concat();
|
|
632
|
-
sortedData.sort((a, b) => {
|
|
633
|
-
const end = state.length;
|
|
630
|
+
const dataToSort = fd.concat();
|
|
631
|
+
dataToSort.sort((a, b) => {
|
|
632
|
+
const end = sorting.length;
|
|
634
633
|
for (let i = 0; i < end; i++) {
|
|
635
|
-
const { id, desc } =
|
|
634
|
+
const { id, desc } = sorting[i];
|
|
636
635
|
const sortingFn = this.getSortingFn(id, desc);
|
|
637
636
|
if (sortingFn) {
|
|
638
637
|
const result = sortingFn(a, b);
|
|
@@ -640,19 +639,27 @@ export class TableContext {
|
|
|
640
639
|
return result;
|
|
641
640
|
}
|
|
642
641
|
}
|
|
643
|
-
else {
|
|
642
|
+
else if (dev) {
|
|
644
643
|
console.warn('no sorting fn found for ' + id);
|
|
645
644
|
}
|
|
646
645
|
}
|
|
647
646
|
return 0;
|
|
648
647
|
});
|
|
649
|
-
return
|
|
648
|
+
return dataToSort;
|
|
650
649
|
}
|
|
651
|
-
return
|
|
650
|
+
return fd;
|
|
652
651
|
});
|
|
653
|
-
sortedRowModel = $derived.by(() => {
|
|
654
|
-
|
|
655
|
-
|
|
652
|
+
sortedRowModel = $derived.by(async () => {
|
|
653
|
+
void this.originalRowIndices;
|
|
654
|
+
void this.sortedData;
|
|
655
|
+
const sd = await this.sortedData;
|
|
656
|
+
const ori = await this.originalRowIndices;
|
|
657
|
+
const rows = await asyncMap(sd, async (item, index) => {
|
|
658
|
+
const originalIndex = ori.get(await this.selectionExtractor(item));
|
|
659
|
+
const unsortedIndex = originalIndex ?? index;
|
|
660
|
+
if (originalIndex == null) {
|
|
661
|
+
throw new Error(`Sorted Data not found in Original Row Indices: original index ${originalIndex}, index ${index}`);
|
|
662
|
+
}
|
|
656
663
|
return this.createRow(item, index, unsortedIndex);
|
|
657
664
|
});
|
|
658
665
|
return {
|
|
@@ -661,13 +668,33 @@ export class TableContext {
|
|
|
661
668
|
rowsById: new Map(rows.map((it, index) => [index.toString(), it])) //FIXME should this be by sorted id or by original id?
|
|
662
669
|
};
|
|
663
670
|
});
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
+
currentPageData = $derived.by(async () => {
|
|
672
|
+
void this.sortedData;
|
|
673
|
+
const dataRepo = this.dataRepo;
|
|
674
|
+
const sd = await this.sortedData;
|
|
675
|
+
if (dataRepo.paginationType != PaginationType.Local) {
|
|
676
|
+
return sd;
|
|
677
|
+
}
|
|
678
|
+
const x = sd.slice(dataRepo.pageStartIndex, dataRepo.pageEndIndexExclusive);
|
|
679
|
+
return x;
|
|
680
|
+
});
|
|
681
|
+
// FIXME this is most likely the cuplrit for add pod not working on receipt. It may be one tick behind the other values
|
|
682
|
+
originalRowIndices = $derived.by(async () => {
|
|
683
|
+
const dataRepo = this.dataRepo;
|
|
684
|
+
const awaited = await asyncMap(dataRepo.data, async (item, index) => [await this.selectionExtractor(item), index]);
|
|
685
|
+
// eslint-disable-next-line svelte/prefer-svelte-reactivity
|
|
686
|
+
return new Map(awaited);
|
|
687
|
+
});
|
|
688
|
+
paginationRowModel = $derived.by(async () => {
|
|
689
|
+
void this.originalRowIndices;
|
|
690
|
+
void this.currentPageData;
|
|
691
|
+
void this.columnDefsById;
|
|
692
|
+
void this.columnVisibility;
|
|
693
|
+
void this.paginationRepo?.sorting;
|
|
694
|
+
void this.columnPinning;
|
|
695
|
+
const currentPageData = await this.currentPageData;
|
|
696
|
+
const rows = await asyncMap(currentPageData, async (item, index) => {
|
|
697
|
+
const unsortedIndex = (await this.originalRowIndices).get(item) ?? index;
|
|
671
698
|
const row = {
|
|
672
699
|
getValue: async (key) => {
|
|
673
700
|
const gotValue = await this.columnDefsById.get(key)?.accessorFn?.(item, index);
|
|
@@ -739,44 +766,25 @@ export class TableContext {
|
|
|
739
766
|
rowsById: new Map(rows.map((it, index) => [index.toString(), it])) //FIXME should this be by sorted id or by original id?
|
|
740
767
|
};
|
|
741
768
|
});
|
|
742
|
-
get currentPageData() {
|
|
743
|
-
return this._currentPageData;
|
|
744
|
-
}
|
|
745
769
|
// #endregion
|
|
746
770
|
// #region public methods
|
|
747
|
-
selectionContains = (item) => {
|
|
771
|
+
selectionContains = async (item) => {
|
|
748
772
|
if (!this.isSelectable) {
|
|
749
773
|
return true;
|
|
750
774
|
}
|
|
751
|
-
return this.selectedItems.has(this.selectionExtractor(item));
|
|
775
|
+
return this.selectedItems.has(await this.selectionExtractor(item));
|
|
752
776
|
};
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
// throw new Error('No selection extractor was supplied');
|
|
756
|
-
// }
|
|
757
|
-
// if (!this.isSelectable) {
|
|
758
|
-
// return true;
|
|
759
|
-
// }
|
|
760
|
-
// const key = this.selectionExtractor(item);
|
|
761
|
-
// if (this.selectedItems.has(key)) {
|
|
762
|
-
// this.selectedItems.delete(key);
|
|
763
|
-
// this.selectedItems.set(key, item);
|
|
764
|
-
// } else {
|
|
765
|
-
// this.selectedItems.set(key, item);
|
|
766
|
-
// this.selectedItems.delete(key);
|
|
767
|
-
// }
|
|
768
|
-
// };
|
|
769
|
-
addInvalidValue = (item) => {
|
|
770
|
-
this.invalidValues.set(this.selectionExtractor(item), item);
|
|
777
|
+
addInvalidValue = async (item) => {
|
|
778
|
+
this.invalidValues.set(await this.selectionExtractor(item), item);
|
|
771
779
|
};
|
|
772
|
-
removeInvalidValue = (item) => {
|
|
773
|
-
this.invalidValues.delete(this.selectionExtractor(item));
|
|
780
|
+
removeInvalidValue = async (item) => {
|
|
781
|
+
this.invalidValues.delete(await this.selectionExtractor(item));
|
|
774
782
|
};
|
|
775
783
|
setOpenModalCoordinates = (coordinates) => {
|
|
776
784
|
this.openModalCoordinates = coordinates ? { ...coordinates } : null;
|
|
777
785
|
};
|
|
778
|
-
toggleHighlightedRow = (item) => {
|
|
779
|
-
const key = this.selectionExtractor(item);
|
|
786
|
+
toggleHighlightedRow = async (item) => {
|
|
787
|
+
const key = await this.selectionExtractor(item);
|
|
780
788
|
if (this.highlightedItems.has(key)) {
|
|
781
789
|
this.highlightedItems.delete(key);
|
|
782
790
|
}
|
|
@@ -784,58 +792,49 @@ export class TableContext {
|
|
|
784
792
|
this.highlightedItems.set(key, item);
|
|
785
793
|
}
|
|
786
794
|
};
|
|
787
|
-
// public readonly toggleHighlightedRow = (rowIndex: number) => {
|
|
788
|
-
// if (this.highlightedRowIndexIds.has(rowIndex)) {
|
|
789
|
-
// this.highlightedRowIndexIds.delete(rowIndex);
|
|
790
|
-
// } else {
|
|
791
|
-
// this.highlightedRowIndexIds.add(rowIndex);
|
|
792
|
-
// }
|
|
793
|
-
// };
|
|
794
795
|
resetHighlightedRows = () => {
|
|
795
796
|
this.highlightedItems.clear();
|
|
796
797
|
};
|
|
797
|
-
toggleSelected = (item, selected) => {
|
|
798
|
-
const key = this.selectionExtractor(item);
|
|
798
|
+
toggleSelected = async (item, selected) => {
|
|
799
|
+
const key = await this.selectionExtractor(item);
|
|
799
800
|
if (selected) {
|
|
800
801
|
this.selectedItems.set(key, item);
|
|
801
802
|
}
|
|
802
803
|
else {
|
|
803
804
|
this.selectedItems.delete(key);
|
|
804
805
|
}
|
|
805
|
-
this.recalculateAllSelectedInCurrentPage();
|
|
806
806
|
};
|
|
807
807
|
setSelectionMap = (set) => {
|
|
808
808
|
this.selectedItems = set;
|
|
809
809
|
};
|
|
810
810
|
updateSelectedItems = async () => {
|
|
811
811
|
const pageStartIndex = this.paginationRepo ? this.paginationRepo.pageStartIndex : 0;
|
|
812
|
+
const sortedData = await this.sortedData;
|
|
812
813
|
const pageEndIndexExclusive = this.paginationRepo
|
|
813
|
-
? Math.min(this.paginationRepo.pageEndIndexExclusive,
|
|
814
|
-
:
|
|
814
|
+
? Math.min(this.paginationRepo.pageEndIndexExclusive, sortedData.length)
|
|
815
|
+
: sortedData.length;
|
|
815
816
|
const selectableMethod = this.columnDefs.find((it) => it instanceof RowSelectionDef)?.isSelectable;
|
|
817
|
+
const updateSelectedItem = async (item) => {
|
|
818
|
+
const key = await this.selectionExtractor(item);
|
|
819
|
+
if (this.selectedItems.has(key)) {
|
|
820
|
+
//replace selected item with newer version of the same identity
|
|
821
|
+
this.selectedItems.set(key, item);
|
|
822
|
+
}
|
|
823
|
+
};
|
|
816
824
|
if (selectableMethod) {
|
|
817
825
|
for (let index = pageStartIndex; index < pageEndIndexExclusive; index++) {
|
|
818
|
-
const item =
|
|
826
|
+
const item = sortedData[index];
|
|
819
827
|
if (await selectableMethod(item, index)) {
|
|
820
|
-
|
|
821
|
-
if (this.selectedItems.has(key)) {
|
|
822
|
-
//replace selected item with newer version of the same identity
|
|
823
|
-
this.selectedItems.set(key, item);
|
|
824
|
-
}
|
|
828
|
+
await updateSelectedItem(item);
|
|
825
829
|
}
|
|
826
830
|
}
|
|
827
831
|
}
|
|
828
832
|
else {
|
|
829
833
|
for (let index = pageStartIndex; index < pageEndIndexExclusive; index++) {
|
|
830
|
-
const item =
|
|
831
|
-
|
|
832
|
-
if (this.selectedItems.has(key)) {
|
|
833
|
-
//replace selected item with newer version of the same identity
|
|
834
|
-
this.selectedItems.set(key, item);
|
|
835
|
-
}
|
|
834
|
+
const item = sortedData[index];
|
|
835
|
+
await updateSelectedItem(item);
|
|
836
836
|
}
|
|
837
837
|
}
|
|
838
|
-
this.recalculateAllSelectedInCurrentPage();
|
|
839
838
|
};
|
|
840
839
|
resetSelectedItems = () => {
|
|
841
840
|
for (const key of this.selectedItems.keys()) {
|
|
@@ -843,25 +842,37 @@ export class TableContext {
|
|
|
843
842
|
}
|
|
844
843
|
this.recalculateAllSelectedInCurrentPage();
|
|
845
844
|
};
|
|
845
|
+
lastIncrement = Number.MIN_SAFE_INTEGER;
|
|
846
846
|
recalculateAllSelectedInCurrentPage = () => {
|
|
847
|
-
|
|
847
|
+
const invalidValues = this._invalidValues;
|
|
848
|
+
const allSelectedInCurrentPage = [...this.selectedItems.keys()];
|
|
849
|
+
const currentIncrement = ++this.lastIncrement;
|
|
850
|
+
this.allSelectedInCurrentPage
|
|
848
851
|
.then(() => {
|
|
849
|
-
|
|
850
|
-
this.hasInvalidSelectedItems =
|
|
851
|
-
|
|
852
|
+
if (this.lastIncrement == currentIncrement) {
|
|
853
|
+
this.hasInvalidSelectedItems = allSelectedInCurrentPage.some((key) => {
|
|
854
|
+
return invalidValues.has(key);
|
|
855
|
+
});
|
|
856
|
+
}
|
|
857
|
+
else {
|
|
858
|
+
if (dev) {
|
|
859
|
+
console.log('skipping recalculation due to stale data');
|
|
860
|
+
}
|
|
861
|
+
}
|
|
852
862
|
})
|
|
853
863
|
.catch(devCatch);
|
|
854
864
|
};
|
|
855
865
|
selectAllInCurrentPage = async () => {
|
|
866
|
+
void this.paginationRepo?.pageStartIndex;
|
|
867
|
+
const sortedData = await this.sortedData;
|
|
856
868
|
if (await this.allSelectedInCurrentPage) {
|
|
857
|
-
// this.resetSelectedItems();
|
|
858
869
|
const pageStartIndex = this.paginationRepo ? this.paginationRepo.pageStartIndex : 0;
|
|
859
870
|
const pageEndIndexExclusive = this.paginationRepo
|
|
860
|
-
? Math.min(this.paginationRepo.pageEndIndexExclusive,
|
|
861
|
-
:
|
|
871
|
+
? Math.min(this.paginationRepo.pageEndIndexExclusive, sortedData.length)
|
|
872
|
+
: sortedData.length;
|
|
862
873
|
for (let index = pageStartIndex; index < pageEndIndexExclusive; index++) {
|
|
863
|
-
const item =
|
|
864
|
-
this.selectedItems.delete(this.selectionExtractor(item));
|
|
874
|
+
const item = sortedData[index];
|
|
875
|
+
this.selectedItems.delete(await this.selectionExtractor(item));
|
|
865
876
|
}
|
|
866
877
|
}
|
|
867
878
|
else {
|
|
@@ -869,50 +880,51 @@ export class TableContext {
|
|
|
869
880
|
// const selectedItems = new SvelteSet<number>();
|
|
870
881
|
const pageStartIndex = this.paginationRepo ? this.paginationRepo.pageStartIndex : 0;
|
|
871
882
|
const pageEndIndexExclusive = this.paginationRepo
|
|
872
|
-
? Math.min(this.paginationRepo.pageEndIndexExclusive,
|
|
873
|
-
:
|
|
883
|
+
? Math.min(this.paginationRepo.pageEndIndexExclusive, sortedData.length)
|
|
884
|
+
: sortedData.length;
|
|
874
885
|
const selectableMethod = this.columnDefs.find((it) => it instanceof RowSelectionDef)?.isSelectable;
|
|
875
886
|
if (selectableMethod) {
|
|
876
887
|
for (let index = pageStartIndex; index < pageEndIndexExclusive; index++) {
|
|
877
|
-
const item =
|
|
888
|
+
const item = sortedData[index];
|
|
878
889
|
if (await selectableMethod(item, index)) {
|
|
879
|
-
this.selectedItems.set(this.selectionExtractor(item), item);
|
|
890
|
+
this.selectedItems.set(await this.selectionExtractor(item), item);
|
|
880
891
|
}
|
|
881
892
|
}
|
|
882
893
|
}
|
|
883
894
|
else {
|
|
884
895
|
for (let index = pageStartIndex; index < pageEndIndexExclusive; index++) {
|
|
885
|
-
const item =
|
|
886
|
-
this.selectedItems.set(this.selectionExtractor(item), item);
|
|
896
|
+
const item = sortedData[index];
|
|
897
|
+
this.selectedItems.set(await this.selectionExtractor(item), item);
|
|
887
898
|
}
|
|
888
899
|
}
|
|
889
900
|
}
|
|
890
|
-
this.recalculateAllSelectedInCurrentPage();
|
|
891
901
|
};
|
|
892
902
|
onHighlightAll = () => {
|
|
893
903
|
this.allHighlighted
|
|
894
904
|
.then((areAllHighlighted) => {
|
|
895
905
|
if (areAllHighlighted) {
|
|
896
906
|
this.highlightedItems.clear();
|
|
907
|
+
return Promise.resolve();
|
|
897
908
|
}
|
|
898
909
|
else {
|
|
899
|
-
this.
|
|
900
|
-
|
|
910
|
+
return this.currentPageData.then((items) => {
|
|
911
|
+
return asyncForEach(items, async (item) => {
|
|
912
|
+
this.highlightedItems.set(await this.selectionExtractor(item), item);
|
|
913
|
+
});
|
|
901
914
|
});
|
|
902
915
|
}
|
|
903
916
|
})
|
|
904
917
|
.catch(devCatch);
|
|
905
918
|
};
|
|
906
919
|
onEditCell = async (item, coords, value) => {
|
|
907
|
-
const oldKey = this.selectionExtractor(item);
|
|
908
|
-
const wasSelected =
|
|
909
|
-
// debugger;
|
|
920
|
+
const oldKey = await this.selectionExtractor(item);
|
|
921
|
+
const wasSelected = this.selectedItems.has(oldKey);
|
|
910
922
|
if (wasSelected) {
|
|
911
923
|
this.selectedItems.delete(oldKey);
|
|
912
924
|
}
|
|
913
925
|
await this._onEditCell?.(item, coords, value);
|
|
914
926
|
if (wasSelected && this.isSelectable) {
|
|
915
|
-
const newKey = this.selectionExtractor(item);
|
|
927
|
+
const newKey = await this.selectionExtractor(item);
|
|
916
928
|
if (newKey) {
|
|
917
929
|
this.selectedItems.set(newKey, item);
|
|
918
930
|
}
|
|
@@ -941,13 +953,16 @@ export class TableContext {
|
|
|
941
953
|
this.tabBackward();
|
|
942
954
|
}
|
|
943
955
|
else {
|
|
944
|
-
this.tabForward();
|
|
956
|
+
this.tabForward().catch(devCatch);
|
|
945
957
|
}
|
|
946
958
|
}
|
|
947
959
|
if (e.target.tagName === 'INPUT' &&
|
|
948
960
|
e.target.attributes.getNamedItem('type')?.value !== 'checkbox') {
|
|
949
961
|
return;
|
|
950
962
|
}
|
|
963
|
+
this.handleKeystroke(e).catch(devCatch);
|
|
964
|
+
};
|
|
965
|
+
async handleKeystroke(e) {
|
|
951
966
|
switch (e.key) {
|
|
952
967
|
case 'Enter':
|
|
953
968
|
case 'F2':
|
|
@@ -955,7 +970,6 @@ export class TableContext {
|
|
|
955
970
|
break;
|
|
956
971
|
}
|
|
957
972
|
e.preventDefault();
|
|
958
|
-
e.stopPropagation();
|
|
959
973
|
e.target?.dispatchEvent(new CustomEvent('edit', { detail: { selectAll: e.key === 'Enter' } }));
|
|
960
974
|
// focusStartIsBeingEdited.set(true);
|
|
961
975
|
break;
|
|
@@ -966,20 +980,20 @@ export class TableContext {
|
|
|
966
980
|
if (!this.allowCopy) {
|
|
967
981
|
return;
|
|
968
982
|
}
|
|
969
|
-
this.focusToTop();
|
|
983
|
+
await this.focusToTop();
|
|
970
984
|
}
|
|
971
985
|
else {
|
|
972
|
-
this.moveToTop();
|
|
986
|
+
await this.moveToTop();
|
|
973
987
|
}
|
|
974
988
|
}
|
|
975
989
|
else if (e.getModifierState('Shift')) {
|
|
976
990
|
if (!this.allowCopy) {
|
|
977
991
|
return;
|
|
978
992
|
}
|
|
979
|
-
this.moveFocusUp();
|
|
993
|
+
await this.moveFocusUp();
|
|
980
994
|
}
|
|
981
995
|
else {
|
|
982
|
-
this.setFocusUp();
|
|
996
|
+
await this.setFocusUp();
|
|
983
997
|
}
|
|
984
998
|
return;
|
|
985
999
|
}
|
|
@@ -990,20 +1004,20 @@ export class TableContext {
|
|
|
990
1004
|
if (!this.allowCopy) {
|
|
991
1005
|
return;
|
|
992
1006
|
}
|
|
993
|
-
this.focusToBottom();
|
|
1007
|
+
await this.focusToBottom();
|
|
994
1008
|
}
|
|
995
1009
|
else {
|
|
996
|
-
this.moveToBottom();
|
|
1010
|
+
await this.moveToBottom();
|
|
997
1011
|
}
|
|
998
1012
|
}
|
|
999
1013
|
else if (e.getModifierState('Shift')) {
|
|
1000
1014
|
if (!this.allowCopy) {
|
|
1001
1015
|
return;
|
|
1002
1016
|
}
|
|
1003
|
-
this.moveFocusDown();
|
|
1017
|
+
await this.moveFocusDown();
|
|
1004
1018
|
}
|
|
1005
1019
|
else {
|
|
1006
|
-
this.setFocusDown();
|
|
1020
|
+
await this.setFocusDown();
|
|
1007
1021
|
}
|
|
1008
1022
|
return;
|
|
1009
1023
|
}
|
|
@@ -1058,9 +1072,9 @@ export class TableContext {
|
|
|
1058
1072
|
case 'a': {
|
|
1059
1073
|
if (e.ctrlKey) {
|
|
1060
1074
|
e.preventDefault();
|
|
1061
|
-
this.moveToTop();
|
|
1075
|
+
await this.moveToTop();
|
|
1062
1076
|
this.moveToStart();
|
|
1063
|
-
this.focusToBottom();
|
|
1077
|
+
await this.focusToBottom();
|
|
1064
1078
|
this.focusToEnd();
|
|
1065
1079
|
}
|
|
1066
1080
|
break;
|
|
@@ -1069,12 +1083,12 @@ export class TableContext {
|
|
|
1069
1083
|
case 'C':
|
|
1070
1084
|
if (e.getModifierState('Control')) {
|
|
1071
1085
|
e.preventDefault();
|
|
1072
|
-
this.copyDataToClipboard()
|
|
1086
|
+
await this.copyDataToClipboard();
|
|
1073
1087
|
}
|
|
1074
1088
|
break;
|
|
1075
1089
|
}
|
|
1076
1090
|
}
|
|
1077
|
-
}
|
|
1091
|
+
}
|
|
1078
1092
|
toggleQuickFiltering = () => {
|
|
1079
1093
|
if (this.allowQuickFiltering) {
|
|
1080
1094
|
const fs = this.focusStart;
|
|
@@ -1147,12 +1161,12 @@ export class TableContext {
|
|
|
1147
1161
|
if (!browser) {
|
|
1148
1162
|
return;
|
|
1149
1163
|
}
|
|
1150
|
-
const ctx = getCanvasContext();
|
|
1151
|
-
const currentPageContents = this.currentPageData;
|
|
1152
1164
|
const colId = columnDef.id;
|
|
1153
1165
|
if (!colId) {
|
|
1154
1166
|
return;
|
|
1155
1167
|
}
|
|
1168
|
+
const currentPageContents = await this.currentPageData;
|
|
1169
|
+
const ctx = getCanvasContext();
|
|
1156
1170
|
let maxWidth = 0;
|
|
1157
1171
|
if (columnDef.accessorFn) {
|
|
1158
1172
|
for (let i = currentPageContents.length - 1; i > -1; i--) {
|
|
@@ -1325,41 +1339,41 @@ export class TableContext {
|
|
|
1325
1339
|
this.focusStart = null;
|
|
1326
1340
|
this.focusEnd = null;
|
|
1327
1341
|
};
|
|
1328
|
-
focusToTop = () => {
|
|
1342
|
+
focusToTop = async () => {
|
|
1329
1343
|
if (!this.allowCopy) {
|
|
1330
1344
|
return;
|
|
1331
1345
|
}
|
|
1332
|
-
this._moveFocusEndRow(-Infinity);
|
|
1346
|
+
return this._moveFocusEndRow(-Infinity);
|
|
1333
1347
|
};
|
|
1334
1348
|
focusToBottom = () => {
|
|
1335
1349
|
if (!this.allowCopy) {
|
|
1336
1350
|
return;
|
|
1337
1351
|
}
|
|
1338
|
-
this._moveFocusEndRow(Infinity);
|
|
1352
|
+
return this._moveFocusEndRow(Infinity);
|
|
1339
1353
|
};
|
|
1340
|
-
moveToBottom = () => {
|
|
1341
|
-
this._moveFocusRow(Infinity);
|
|
1354
|
+
moveToBottom = async () => {
|
|
1355
|
+
return this._moveFocusRow(Infinity);
|
|
1342
1356
|
};
|
|
1343
|
-
moveToTop = () => {
|
|
1344
|
-
this._moveFocusRow(-Infinity);
|
|
1357
|
+
moveToTop = async () => {
|
|
1358
|
+
return this._moveFocusRow(-Infinity);
|
|
1345
1359
|
};
|
|
1346
|
-
moveFocusUp = () => {
|
|
1360
|
+
moveFocusUp = async () => {
|
|
1347
1361
|
if (!this.allowCopy) {
|
|
1348
1362
|
return;
|
|
1349
1363
|
}
|
|
1350
|
-
this._moveFocusEndRow(-1);
|
|
1364
|
+
return this._moveFocusEndRow(-1);
|
|
1351
1365
|
};
|
|
1352
|
-
setFocusUp = () => {
|
|
1353
|
-
this._moveFocusRow(-1);
|
|
1366
|
+
setFocusUp = async () => {
|
|
1367
|
+
return this._moveFocusRow(-1);
|
|
1354
1368
|
};
|
|
1355
|
-
tabForward = () => {
|
|
1369
|
+
tabForward = async () => {
|
|
1356
1370
|
if (!this.allowCopy) {
|
|
1357
1371
|
return;
|
|
1358
1372
|
}
|
|
1359
1373
|
const defs = this.columnDefs;
|
|
1360
1374
|
const visibility = this.columnVisibility;
|
|
1361
1375
|
const indexBounds = defs.length;
|
|
1362
|
-
const rowBounds = this.sortedData.length;
|
|
1376
|
+
const rowBounds = (await this.sortedData).length;
|
|
1363
1377
|
if (!this.focusStart || !rowBounds) {
|
|
1364
1378
|
return;
|
|
1365
1379
|
}
|
|
@@ -1480,14 +1494,14 @@ export class TableContext {
|
|
|
1480
1494
|
}
|
|
1481
1495
|
//otherwise return without doing anything
|
|
1482
1496
|
};
|
|
1483
|
-
moveFocusDown = () => {
|
|
1497
|
+
moveFocusDown = async () => {
|
|
1484
1498
|
if (!this.allowCopy) {
|
|
1485
1499
|
return;
|
|
1486
1500
|
}
|
|
1487
|
-
this._moveFocusEndRow(1);
|
|
1501
|
+
return this._moveFocusEndRow(1);
|
|
1488
1502
|
};
|
|
1489
|
-
setFocusDown = () => {
|
|
1490
|
-
this._moveFocusRow(1);
|
|
1503
|
+
setFocusDown = async () => {
|
|
1504
|
+
return this._moveFocusRow(1);
|
|
1491
1505
|
};
|
|
1492
1506
|
moveFocusLeft = () => {
|
|
1493
1507
|
if (!this.allowCopy) {
|
|
@@ -1611,6 +1625,9 @@ export class TableContext {
|
|
|
1611
1625
|
// }
|
|
1612
1626
|
// };
|
|
1613
1627
|
setSelectedPreset = (preset) => {
|
|
1628
|
+
if (this.debug) {
|
|
1629
|
+
console.log('setting selected preset:', preset);
|
|
1630
|
+
}
|
|
1614
1631
|
this.columnDefs = preset.columnDefs;
|
|
1615
1632
|
if (!this.paginationRepo?.updateSorting) {
|
|
1616
1633
|
console.warn('no sorting state found');
|
|
@@ -1751,7 +1768,7 @@ export class TableContext {
|
|
|
1751
1768
|
};
|
|
1752
1769
|
localStorage.setItem(`${this.userId}-${this.tableName}-settings`, JSON.stringify(settingsObject));
|
|
1753
1770
|
}
|
|
1754
|
-
_moveFocusEndRow(offset) {
|
|
1771
|
+
async _moveFocusEndRow(offset) {
|
|
1755
1772
|
if (!this.allowCopy) {
|
|
1756
1773
|
return;
|
|
1757
1774
|
}
|
|
@@ -1760,27 +1777,27 @@ export class TableContext {
|
|
|
1760
1777
|
return;
|
|
1761
1778
|
}
|
|
1762
1779
|
const focusEnd = this.focusEnd;
|
|
1763
|
-
const rows = this.paginationRowModel.rows;
|
|
1780
|
+
const rows = (await this.paginationRowModel).rows;
|
|
1764
1781
|
const endRowIndex = rows.findIndex((row) => row.visibleIndex === focusEnd.row);
|
|
1765
1782
|
this.focusEnd = {
|
|
1766
1783
|
...this.focusEnd,
|
|
1767
1784
|
row: rows[Math.max(Math.min(endRowIndex + offset, rows.length - 1), 0)].visibleIndex
|
|
1768
1785
|
};
|
|
1769
1786
|
}
|
|
1770
|
-
_moveFocusRow(offset) {
|
|
1787
|
+
async _moveFocusRow(offset) {
|
|
1771
1788
|
if (!this.focusStart) {
|
|
1772
1789
|
console.warn('no focusStart found');
|
|
1773
1790
|
return;
|
|
1774
1791
|
}
|
|
1775
1792
|
const focusStart = this.focusStart;
|
|
1776
|
-
const newEndRowIndex = (() => {
|
|
1777
|
-
const rows = this.paginationRowModel.rows;
|
|
1793
|
+
const newEndRowIndex = await (async () => {
|
|
1794
|
+
const rows = (await this.paginationRowModel).rows;
|
|
1778
1795
|
const endRowIndex = rows.findIndex((row) => row.visibleIndex === focusStart.row);
|
|
1779
1796
|
return rows[Math.max(Math.min(endRowIndex + offset, rows.length - 1), 0)].visibleIndex;
|
|
1780
1797
|
})();
|
|
1781
1798
|
this.moveFocus({ ...this.focusStart, row: newEndRowIndex });
|
|
1782
1799
|
}
|
|
1783
|
-
_recalculateFocusedElements() {
|
|
1800
|
+
async _recalculateFocusedElements() {
|
|
1784
1801
|
if (!this.focusStart || !this.focusEnd) {
|
|
1785
1802
|
this.focusedRowIndexIds = new SvelteSet();
|
|
1786
1803
|
this.focusedColumnIds = new SvelteSet();
|
|
@@ -1788,7 +1805,7 @@ export class TableContext {
|
|
|
1788
1805
|
}
|
|
1789
1806
|
const { row: startRowIndexId, column: startColumnIndex } = this.focusStart;
|
|
1790
1807
|
const { row: endRowIndexId, column: endColumnIndex } = this.focusEnd;
|
|
1791
|
-
const model = this.sortedRowModel;
|
|
1808
|
+
const model = await this.sortedRowModel;
|
|
1792
1809
|
const startRowIndex = model.rows.findIndex((row) => row.visibleIndex === startRowIndexId);
|
|
1793
1810
|
const endRowIndex = model.rows.findIndex((row) => row.visibleIndex === endRowIndexId);
|
|
1794
1811
|
if (startRowIndex == -1 || endRowIndex == -1) {
|
|
@@ -1822,11 +1839,12 @@ export class TableContext {
|
|
|
1822
1839
|
// eslint-disable-next-line svelte/prefer-svelte-reactivity
|
|
1823
1840
|
const indices = new Map();
|
|
1824
1841
|
const selectedRows = [...this.highlightedItems.values()];
|
|
1842
|
+
const sortedData = await this.sortedData;
|
|
1825
1843
|
for (const item of selectedRows) {
|
|
1826
|
-
const rowIndex =
|
|
1844
|
+
const rowIndex = sortedData.indexOf(item);
|
|
1827
1845
|
if (rowIndex == -1) {
|
|
1828
|
-
|
|
1829
|
-
|
|
1846
|
+
console.warn(`row index for highlighted row data not found`);
|
|
1847
|
+
continue;
|
|
1830
1848
|
}
|
|
1831
1849
|
indices.set(item, rowIndex);
|
|
1832
1850
|
}
|
|
@@ -1835,22 +1853,22 @@ export class TableContext {
|
|
|
1835
1853
|
const rowLength = selectedRows.length;
|
|
1836
1854
|
for (let rowIndex = 0; rowIndex < rowLength; rowIndex++) {
|
|
1837
1855
|
const item = selectedRows[rowIndex];
|
|
1838
|
-
const key = this.selectionExtractor(item);
|
|
1856
|
+
const key = await this.selectionExtractor(item);
|
|
1839
1857
|
selectedCells[rowIndex] = [];
|
|
1840
1858
|
const targetRow = selectedCells[rowIndex];
|
|
1841
1859
|
const colLength = affectedColumns.length;
|
|
1842
1860
|
for (let colIndex = 0; colIndex < colLength; colIndex++) {
|
|
1843
1861
|
const columnDef = affectedColumns[colIndex];
|
|
1844
1862
|
if (columnDef instanceof RowSelectionDef) {
|
|
1845
|
-
targetRow.push(
|
|
1863
|
+
targetRow.push(this.selectedItems.has(key) ? 'true' : 'false');
|
|
1846
1864
|
continue;
|
|
1847
1865
|
}
|
|
1848
1866
|
if (uncopyableColumns.has(columnDef.columnType)) {
|
|
1849
1867
|
continue;
|
|
1850
1868
|
}
|
|
1851
|
-
const x = (await columnDef.getDisplayValue?.(item,
|
|
1869
|
+
const x = (await columnDef.getDisplayValue?.(item, sortedData.lastIndexOf(item))) ||
|
|
1852
1870
|
('accessorFn' in columnDef &&
|
|
1853
|
-
(await columnDef.accessorFn?.(item,
|
|
1871
|
+
(await columnDef.accessorFn?.(item, sortedData.indexOf(item))));
|
|
1854
1872
|
if (x && typeof x === 'string') {
|
|
1855
1873
|
targetRow.push(x);
|
|
1856
1874
|
continue;
|
|
@@ -1878,10 +1896,10 @@ export class TableContext {
|
|
|
1878
1896
|
const { row: startRowIndexId, column: startColumnIndex } = this.focusStart;
|
|
1879
1897
|
const { row: endRowIndexId, column: endColumnIndex } = this.focusEnd;
|
|
1880
1898
|
// const model = this._currentPageData;
|
|
1881
|
-
const model = this.paginationRowModel;
|
|
1899
|
+
const model = await this.paginationRowModel;
|
|
1882
1900
|
const startRowIndex = model.rows.findIndex((row) => row.visibleIndex === startRowIndexId);
|
|
1883
1901
|
const endRowIndex = model.rows.findIndex((row) => row.visibleIndex === endRowIndexId);
|
|
1884
|
-
if (!this.
|
|
1902
|
+
if (!(await this.currentPageData).length || startRowIndex == -1 || endRowIndex == -1) {
|
|
1885
1903
|
throw new Error(`copy was missing one of the two indices. First: ${startRowIndex}, second: ${endRowIndex}`);
|
|
1886
1904
|
}
|
|
1887
1905
|
const minRowIndex = Math.min(startRowIndex, endRowIndex);
|
|
@@ -1906,24 +1924,25 @@ export class TableContext {
|
|
|
1906
1924
|
// TODO somewhere between here and the ending of the copy functionality, we end up with issues where instead of it using the accessor fn, it tries to pick up the select option, and ends up using the value ("1", etc)
|
|
1907
1925
|
const selectedCells = [];
|
|
1908
1926
|
const rowLength = selectedRows.length;
|
|
1927
|
+
const sortedData = await this.sortedData;
|
|
1909
1928
|
for (let rowIndex = 0; rowIndex < rowLength; rowIndex++) {
|
|
1910
1929
|
const item = selectedRows[rowIndex];
|
|
1911
|
-
const key = this.selectionExtractor(item);
|
|
1930
|
+
const key = await this.selectionExtractor(item);
|
|
1912
1931
|
selectedCells[rowIndex] = [];
|
|
1913
1932
|
const targetRow = selectedCells[rowIndex];
|
|
1914
1933
|
const colLength = affectedColumns.length;
|
|
1915
1934
|
for (let colIndex = 0; colIndex < colLength; colIndex++) {
|
|
1916
1935
|
const columnDef = affectedColumns[colIndex];
|
|
1917
1936
|
if (columnDef instanceof RowSelectionDef) {
|
|
1918
|
-
targetRow.push(
|
|
1937
|
+
targetRow.push(this.selectedItems.has(key) ? 'true' : 'false');
|
|
1919
1938
|
continue;
|
|
1920
1939
|
}
|
|
1921
1940
|
if (uncopyableColumns.has(columnDef.columnType)) {
|
|
1922
1941
|
continue;
|
|
1923
1942
|
}
|
|
1924
|
-
const x = (await columnDef.getDisplayValue?.(item,
|
|
1943
|
+
const x = (await columnDef.getDisplayValue?.(item, sortedData.lastIndexOf(item))) ||
|
|
1925
1944
|
('accessorFn' in columnDef &&
|
|
1926
|
-
(await columnDef.accessorFn?.(item,
|
|
1945
|
+
(await columnDef.accessorFn?.(item, sortedData.indexOf(item))));
|
|
1927
1946
|
if (x && typeof x === 'string') {
|
|
1928
1947
|
targetRow.push(x);
|
|
1929
1948
|
continue;
|
|
@@ -2207,6 +2226,22 @@ export class TableContext {
|
|
|
2207
2226
|
};
|
|
2208
2227
|
});
|
|
2209
2228
|
}
|
|
2229
|
+
async filteringLoop(currentTimer, abortController, settled, startTime) {
|
|
2230
|
+
for (;;) {
|
|
2231
|
+
if (currentTimer !== this.filterTimer) {
|
|
2232
|
+
if (this.debug) {
|
|
2233
|
+
console.log(`aborting due to stale data`);
|
|
2234
|
+
}
|
|
2235
|
+
abortController.abort('stale data');
|
|
2236
|
+
return;
|
|
2237
|
+
}
|
|
2238
|
+
if (settled.value) {
|
|
2239
|
+
console.log(`iteration ${currentTimer} finished ${Date.now() - startTime}ms`);
|
|
2240
|
+
return;
|
|
2241
|
+
}
|
|
2242
|
+
await tick();
|
|
2243
|
+
}
|
|
2244
|
+
}
|
|
2210
2245
|
}
|
|
2211
2246
|
// #region static functions
|
|
2212
2247
|
function areDefsEquivalent(newColumnDefs, oldColumnDefs) {
|