@scion/components 22.3.0 → 22.4.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/_index.scss +37 -18
- package/design/icons/_scion-icon-font.scss +2 -2
- package/fesm2022/scion-components-icon.mjs +3 -56
- package/fesm2022/scion-components-icon.mjs.map +1 -1
- package/fesm2022/scion-components-menu.mjs +10 -4
- package/fesm2022/scion-components-menu.mjs.map +1 -1
- package/fesm2022/scion-components-table.mjs +272 -200
- package/fesm2022/scion-components-table.mjs.map +1 -1
- package/package.json +2 -2
- package/types/scion-components-icon.d.ts +3 -56
- package/types/scion-components-table.d.ts +115 -97
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import {
|
|
2
|
+
import { computed, signal, InjectionToken, makeEnvironmentProviders, untracked, inject, Injector, linkedSignal, isSignal, runInInjectionContext, NgZone, resource, effect, assertNotInReactiveContext, assertInInjectionContext, DestroyRef, Injectable, input, Component, output, viewChild, Directive, afterNextRender, ElementRef, Pipe, debounced, viewChildren, ViewEncapsulation } from '@angular/core';
|
|
3
3
|
import { coerceSignal, createDestroyableInjector, toLazyObservable, SciComponentOutletDirective, SciAttributesDirective } from '@scion/components/common';
|
|
4
4
|
import { toObservable, rxResource, takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
5
|
-
import { map, shareReplay, fromEvent, switchMap, concat, of, timer, firstValueFrom, defaultIfEmpty, throwError, skip } from 'rxjs';
|
|
6
5
|
import { Objects, clamp, runSafe, Observables, Arrays } from '@scion/toolkit/util';
|
|
7
|
-
import {
|
|
6
|
+
import { fromEvent, switchMap, concat, of, timer, firstValueFrom, defaultIfEmpty, throwError, skip } from 'rxjs';
|
|
7
|
+
import { map, startWith, first } from 'rxjs/operators';
|
|
8
8
|
import { subscribeIn } from '@scion/toolkit/operators';
|
|
9
9
|
import { SciScrollbarComponent } from '@scion/components/viewport';
|
|
10
10
|
import { dimension } from '@scion/components/dimension';
|
|
@@ -28,54 +28,139 @@ import { FormsModule } from '@angular/forms';
|
|
|
28
28
|
* SPDX-License-Identifier: EPL-2.0
|
|
29
29
|
*/
|
|
30
30
|
class ɵSciTableColumnFactory {
|
|
31
|
-
|
|
31
|
+
_table;
|
|
32
32
|
columns = new Array();
|
|
33
|
-
constructor(
|
|
34
|
-
this.
|
|
33
|
+
constructor(_table) {
|
|
34
|
+
this._table = _table;
|
|
35
|
+
}
|
|
36
|
+
addStringColumn(descriptorLike, value) {
|
|
37
|
+
const descriptor = coerceColumnDescriptor(descriptorLike, value);
|
|
38
|
+
const column = this.mapToColumn(descriptor);
|
|
39
|
+
const sortable = descriptor.sortable ?? true;
|
|
40
|
+
const filterable = descriptor.filterable ?? true;
|
|
41
|
+
this.columns.push({
|
|
42
|
+
...column,
|
|
43
|
+
type: 'string',
|
|
44
|
+
value: descriptor.value,
|
|
45
|
+
sortable: computed(() => this._table.sortable() && !!sortable),
|
|
46
|
+
filterable: computed(() => this._table.filterable() && !!filterable),
|
|
47
|
+
compare: typeof sortable === 'object' ? sortable.comparator : (a, b) => a.value.localeCompare(b.value),
|
|
48
|
+
matches: typeof filterable === 'object' ? filterable.matcher : (text, context) => context.value.toLowerCase().includes(text.toLowerCase()),
|
|
49
|
+
});
|
|
50
|
+
return this;
|
|
35
51
|
}
|
|
36
|
-
|
|
37
|
-
|
|
52
|
+
addNumberColumn(descriptorLike, value) {
|
|
53
|
+
const descriptor = coerceColumnDescriptor(descriptorLike, value);
|
|
54
|
+
const column = this.mapToColumn(descriptor);
|
|
55
|
+
this.columns.push({
|
|
56
|
+
...column,
|
|
57
|
+
type: 'number',
|
|
58
|
+
value: descriptor.value,
|
|
59
|
+
sortable: computed(() => this._table.sortable() && (descriptor.sortable ?? true)),
|
|
60
|
+
filterable: computed(() => this._table.filterable() && (descriptor.filterable ?? true)),
|
|
61
|
+
compare: (a, b) => a.value - b.value,
|
|
62
|
+
matches: (text, context) => context.value === text,
|
|
63
|
+
});
|
|
64
|
+
return this;
|
|
38
65
|
}
|
|
39
|
-
|
|
40
|
-
|
|
66
|
+
addBooleanColumn(descriptorLike, value) {
|
|
67
|
+
const descriptor = coerceColumnDescriptor(descriptorLike, value);
|
|
68
|
+
const column = this.mapToColumn(descriptor);
|
|
69
|
+
this.columns.push({
|
|
70
|
+
...column,
|
|
71
|
+
type: 'boolean',
|
|
72
|
+
value: descriptor.value,
|
|
73
|
+
sortable: computed(() => this._table.sortable() && (descriptor.sortable ?? true)),
|
|
74
|
+
filterable: computed(() => this._table.filterable() && (descriptor.filterable ?? true)),
|
|
75
|
+
compare: (a, b) => a.value === b.value ? 0 : (a.value ? 1 : -1),
|
|
76
|
+
matches: (text, context) => context.value === text,
|
|
77
|
+
});
|
|
78
|
+
return this;
|
|
41
79
|
}
|
|
42
|
-
|
|
43
|
-
|
|
80
|
+
addComponentColumn(descriptor) {
|
|
81
|
+
// Require a filter matcher if filterable on an array datasource.
|
|
82
|
+
if (this._table.isArrayDatasource() && descriptor.filterable === true) {
|
|
83
|
+
throw Error('[ColumnDefinitionError] Component column requires a filter matcher in order to be filterable.');
|
|
84
|
+
}
|
|
85
|
+
// Require a sort comparator if sortable on an array datasource.
|
|
86
|
+
if (this._table.isArrayDatasource() && descriptor.sortable === true) {
|
|
87
|
+
throw Error('[ColumnDefinitionError] Component column requires a sort comparator in order to be sortable.');
|
|
88
|
+
}
|
|
89
|
+
const column = this.mapToColumn(descriptor);
|
|
90
|
+
this.columns.push({
|
|
91
|
+
...column,
|
|
92
|
+
type: 'component',
|
|
93
|
+
component: descriptor.component,
|
|
94
|
+
sortable: computed(() => this._table.sortable() && !!descriptor.sortable),
|
|
95
|
+
filterable: computed(() => this._table.filterable() && !!descriptor.filterable),
|
|
96
|
+
compare: typeof descriptor.sortable === 'object' ? descriptor.sortable.comparator : () => 0,
|
|
97
|
+
matches: typeof descriptor.filterable === 'object' ? descriptor.filterable.matcher : () => true,
|
|
98
|
+
padding: descriptor.padding ?? true,
|
|
99
|
+
});
|
|
100
|
+
return this;
|
|
44
101
|
}
|
|
45
|
-
|
|
46
|
-
//
|
|
47
|
-
if (
|
|
48
|
-
throw Error('[ColumnDefinitionError]
|
|
49
|
-
}
|
|
50
|
-
|
|
102
|
+
addTemplateColumn(descriptor) {
|
|
103
|
+
// Require a filter matcher if filterable on an array datasource.
|
|
104
|
+
if (this._table.isArrayDatasource() && descriptor.filterable === true) {
|
|
105
|
+
throw Error('[ColumnDefinitionError] Template column requires a filter matcher in order to be filterable.');
|
|
106
|
+
}
|
|
107
|
+
// Require a sort comparator if sortable on an array datasource.
|
|
108
|
+
if (this._table.isArrayDatasource() && descriptor.sortable === true) {
|
|
109
|
+
throw Error('[ColumnDefinitionError] Template column requires a sort comparator in order to be sortable.');
|
|
110
|
+
}
|
|
111
|
+
const column = this.mapToColumn(descriptor);
|
|
112
|
+
this.columns.push({
|
|
113
|
+
...column,
|
|
114
|
+
type: 'template',
|
|
115
|
+
template: descriptor.template,
|
|
116
|
+
sortable: computed(() => this._table.sortable() && !!descriptor.sortable),
|
|
117
|
+
filterable: computed(() => this._table.filterable() && !!descriptor.filterable),
|
|
118
|
+
compare: typeof descriptor.sortable === 'object' ? descriptor.sortable.comparator : () => 0,
|
|
119
|
+
matches: typeof descriptor.filterable === 'object' ? descriptor.filterable.matcher : () => true,
|
|
120
|
+
padding: descriptor.padding ?? true,
|
|
121
|
+
});
|
|
122
|
+
return this;
|
|
51
123
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
124
|
+
/**
|
|
125
|
+
* Maps given column descriptor to a {@link SciTableColumn}.
|
|
126
|
+
*/
|
|
127
|
+
mapToColumn(descriptor) {
|
|
128
|
+
// Require a unique column name.
|
|
129
|
+
const name = descriptor.name ?? `column:${this.columns.length}`;
|
|
130
|
+
if (this.columns.find(column => column.name === name)) {
|
|
131
|
+
throw Error(`[ColumnDefinitionError] Column names must be unique. "${name}" is defined more than once.`);
|
|
55
132
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
const config = (() => {
|
|
60
|
-
switch (typeof valueHeaderDescriptor) {
|
|
61
|
-
case 'string':
|
|
62
|
-
return { header: valueHeaderDescriptor, value: value };
|
|
63
|
-
case 'function':
|
|
64
|
-
return { value: valueHeaderDescriptor };
|
|
65
|
-
default:
|
|
66
|
-
return valueHeaderDescriptor;
|
|
67
|
-
}
|
|
68
|
-
})();
|
|
69
|
-
if (!isSignal(this._descriptor.ɵdatasource) && (typeof config.sortable === 'object' || typeof config.filterable === 'object')) {
|
|
70
|
-
throw Error('[ColumnDefinitionError] Data sources with a loader function cannot define a custom sort or filter function. Sorting and filtering have to be done within the loader function.');
|
|
133
|
+
// Disallow a filter matcher if using a custom datasource.
|
|
134
|
+
if (!this._table.isArrayDatasource() && typeof descriptor.filterable === 'object') {
|
|
135
|
+
throw Error('[ColumnDefinitionError] Configuring a filter matcher is not supported for tables using a datasource. Filtering must be done by the datasource.');
|
|
71
136
|
}
|
|
72
|
-
//
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
throw Error(`[ColumnDefinitionError] Column names have to be unique. "${name}" is defined more than once.`);
|
|
137
|
+
// Disallow a sort comparator if using a custom datasource.
|
|
138
|
+
if (!this._table.isArrayDatasource() && typeof descriptor.sortable === 'object') {
|
|
139
|
+
throw Error('[ColumnDefinitionError] Configuring a sort comparator is not supported for tables using a datasource. Sorting must be done by the datasource.');
|
|
76
140
|
}
|
|
77
|
-
|
|
78
|
-
|
|
141
|
+
return {
|
|
142
|
+
name: name,
|
|
143
|
+
header: coerceSignal(descriptor.header ?? ''),
|
|
144
|
+
resizable: computed(() => this._table.resizable() && (descriptor.resizable ?? true)),
|
|
145
|
+
width: computed(() => {
|
|
146
|
+
const userSettings = this._table.userSettings().columns?.find(column => column.name === name);
|
|
147
|
+
return userSettings?.width ? `${userSettings.width}px` : descriptor.width ?? '1fr';
|
|
148
|
+
}),
|
|
149
|
+
minWidth: descriptor.minWidth ?? 100,
|
|
150
|
+
resizing: signal(false),
|
|
151
|
+
padding: true,
|
|
152
|
+
location: { x: 0, width: 0 }, // set in `SciTableColumnComponent`
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
function coerceColumnDescriptor(argument1, argument2) {
|
|
157
|
+
switch (typeof argument1) {
|
|
158
|
+
case 'string':
|
|
159
|
+
return { header: argument1, value: argument2 };
|
|
160
|
+
case 'function':
|
|
161
|
+
return { value: argument1 };
|
|
162
|
+
default:
|
|
163
|
+
return argument1;
|
|
79
164
|
}
|
|
80
165
|
}
|
|
81
166
|
|
|
@@ -132,124 +217,153 @@ function provideTableStorage(storage) {
|
|
|
132
217
|
* SPDX-License-Identifier: EPL-2.0
|
|
133
218
|
*/
|
|
134
219
|
function arrayDatasource(data, columns) {
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
}));
|
|
146
|
-
return {
|
|
147
|
-
items,
|
|
148
|
-
columns: resolvedColumns,
|
|
149
|
-
};
|
|
150
|
-
}));
|
|
151
|
-
return (request) => {
|
|
152
|
-
const sortHash = request.sortCriteria.map(sc => `${sc.columnName}_${sc.direction}`).join('-');
|
|
153
|
-
const filterHash = request.columnFilters.map(fc => `${fc.columnName}_${fc.text}`).join('-');
|
|
154
|
-
const hash = `${sortHash}-${filterHash}-${request.tableFilter ?? ''}`;
|
|
155
|
-
if (!cache().has(hash)) {
|
|
156
|
-
const sortedAndFiltered$ = items$.pipe(map(({ items, columns }) => {
|
|
157
|
-
const sortCols = mapCriteria(request.sortCriteria, columns);
|
|
158
|
-
const filterCols = mapCriteria(request.columnFilters, columns);
|
|
159
|
-
return items
|
|
160
|
-
.filter(item => columnFilter(item, filterCols) && globalFilter(item, request.tableFilter))
|
|
161
|
-
.sort((a, b) => sort(a, b, sortCols));
|
|
162
|
-
}), shareReplay({ bufferSize: 1, refCount: true }));
|
|
163
|
-
// Only store one item in the cache.
|
|
164
|
-
// The cache is used for scrolling and multipage selection.
|
|
165
|
-
// It caches the data based on the current filter and sort.
|
|
166
|
-
cache.set(new Map().set(hash, sortedAndFiltered$));
|
|
167
|
-
}
|
|
168
|
-
return cache().get(hash).pipe(map(items => ({
|
|
169
|
-
totalCount: items.length,
|
|
170
|
-
items: items.slice(request.start, request.end).map(i => i.item),
|
|
220
|
+
const dataset = new Dataset(data, columns);
|
|
221
|
+
return markAsArrayDatasource((request) => {
|
|
222
|
+
dataset.columnFilters.set(request.columnFilters);
|
|
223
|
+
dataset.tableFilter.set(request.tableFilter);
|
|
224
|
+
dataset.sortCriteria.set(request.sortCriteria);
|
|
225
|
+
const totalCount = dataset.count;
|
|
226
|
+
const items = dataset.slice(request.start, request.end);
|
|
227
|
+
return toObservable(computed(() => ({
|
|
228
|
+
totalCount: totalCount(),
|
|
229
|
+
items: items(),
|
|
171
230
|
})));
|
|
172
|
-
};
|
|
231
|
+
});
|
|
173
232
|
}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
233
|
+
/**
|
|
234
|
+
* Provides a filtered and sorted view on given data.
|
|
235
|
+
*/
|
|
236
|
+
class Dataset {
|
|
237
|
+
_dataview;
|
|
238
|
+
columnFilters = signal([], { ...(ngDevMode ? { debugName: "columnFilters" } : /* istanbul ignore next */ {}), equal: Objects.isEqual });
|
|
239
|
+
sortCriteria = signal([], { ...(ngDevMode ? { debugName: "sortCriteria" } : /* istanbul ignore next */ {}), equal: Objects.isEqual });
|
|
240
|
+
tableFilter = signal(undefined, /* @ts-ignore */
|
|
241
|
+
...(ngDevMode ? [{ debugName: "tableFilter" }] : /* istanbul ignore next */ []));
|
|
242
|
+
/**
|
|
243
|
+
* Returns the total count of items matching the current filters and search criteria.
|
|
244
|
+
*/
|
|
245
|
+
count = computed(() => this._dataview().length, /* @ts-ignore */
|
|
246
|
+
...(ngDevMode ? [{ debugName: "count" }] : /* istanbul ignore next */ []));
|
|
247
|
+
constructor(data, columns) {
|
|
248
|
+
const dataset = computed(() => data().map(item => ({
|
|
249
|
+
item,
|
|
250
|
+
cells: columns().reduce((cells, column) => cells.set(column.name, {
|
|
251
|
+
column: column,
|
|
252
|
+
value: 'value' in column ? coerceSignal(untracked(() => column.value(item)), { coerceUndefined: true })() : undefined,
|
|
253
|
+
}), new Map()),
|
|
254
|
+
})), /* @ts-ignore */
|
|
255
|
+
...(ngDevMode ? [{ debugName: "dataset" }] : /* istanbul ignore next */ []));
|
|
256
|
+
// Memoize filtered/sorted view; recomputes only when dataset or criteria change, not when scrolling through the view, as sorting is an expensive operation.
|
|
257
|
+
this._dataview = computed(() => {
|
|
258
|
+
const rows = dataset();
|
|
259
|
+
const columnFilters = this.columnFilters();
|
|
260
|
+
const tableFilter = this.tableFilter();
|
|
261
|
+
const sortCriteria = this.sortCriteria();
|
|
262
|
+
// PERF: Do not track signals inside `Array.sort` to avoid Angular signal tracking overhead as the comparator runs repeatedly, degrading performance otherwise.
|
|
263
|
+
return untracked(() => rows
|
|
264
|
+
.filter(row => matchesRow(row, columnFilters) && matchesGlobalFilter(row, tableFilter ?? undefined))
|
|
265
|
+
.sort((a, b) => compareRows(a, b, sortCriteria)));
|
|
266
|
+
}, /* @ts-ignore */
|
|
267
|
+
...(ngDevMode ? [{ debugName: "_dataview" }] : /* istanbul ignore next */ []));
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Returns a slice of the filtered and sorted data within the given range (start inclusive, end exclusive).
|
|
271
|
+
*/
|
|
272
|
+
slice(start, end) {
|
|
273
|
+
return computed(() => this._dataview().slice(start, end).map(row => row.item));
|
|
274
|
+
}
|
|
182
275
|
}
|
|
183
|
-
|
|
276
|
+
/**
|
|
277
|
+
* Tests whether a row matches the given global filter.
|
|
278
|
+
*/
|
|
279
|
+
function matchesGlobalFilter(row, filter) {
|
|
184
280
|
if (!filter?.trim()) {
|
|
185
281
|
return true;
|
|
186
282
|
}
|
|
187
|
-
for (const
|
|
188
|
-
const
|
|
189
|
-
|
|
190
|
-
|
|
283
|
+
for (const cell of row.cells.values()) {
|
|
284
|
+
const text = coerceFilterText(filter, { to: cell.column.type });
|
|
285
|
+
if (text === undefined) {
|
|
286
|
+
continue;
|
|
287
|
+
}
|
|
288
|
+
if (matchesRow(row, [{ text, columnName: cell.column.name }])) {
|
|
191
289
|
return true;
|
|
192
290
|
}
|
|
193
291
|
}
|
|
194
292
|
return false;
|
|
195
293
|
}
|
|
196
|
-
|
|
197
|
-
|
|
294
|
+
/**
|
|
295
|
+
* Tests whether a row matches the given column filters.
|
|
296
|
+
*/
|
|
297
|
+
function matchesRow(row, columnFilters) {
|
|
298
|
+
if (!columnFilters.length) {
|
|
198
299
|
return true;
|
|
199
300
|
}
|
|
200
|
-
for (const
|
|
201
|
-
const
|
|
202
|
-
|
|
203
|
-
switch (criterion.column.type) {
|
|
204
|
-
case 'string':
|
|
205
|
-
return criterion.column.filter(criterion.text, { item: row.item, value: value });
|
|
206
|
-
case 'number':
|
|
207
|
-
return criterion.column.filter(criterion.text, { item: row.item, value: value });
|
|
208
|
-
case 'boolean':
|
|
209
|
-
return criterion.column.filter(criterion.text, { item: row.item, value: value });
|
|
210
|
-
case 'component':
|
|
211
|
-
case 'template':
|
|
212
|
-
return criterion.column.filter(criterion.text, { item: row.item, value: undefined });
|
|
213
|
-
default:
|
|
214
|
-
return true;
|
|
215
|
-
}
|
|
216
|
-
})();
|
|
217
|
-
// all filters must match (for now)
|
|
218
|
-
if (!filter) {
|
|
301
|
+
for (const columnFilter of columnFilters) {
|
|
302
|
+
const cell = row.cells.get(columnFilter.columnName);
|
|
303
|
+
if (!cell.column.matches(columnFilter.text, { item: row.item, value: cell.value })) { // component and template columns have no value
|
|
219
304
|
return false;
|
|
220
305
|
}
|
|
221
306
|
}
|
|
222
307
|
return true;
|
|
223
308
|
}
|
|
224
|
-
|
|
225
|
-
|
|
309
|
+
/**
|
|
310
|
+
* Compares two rows based on the given sort criteria.
|
|
311
|
+
*/
|
|
312
|
+
function compareRows(row1, row2, sortCriteria) {
|
|
313
|
+
if (!sortCriteria.length) {
|
|
226
314
|
return 0;
|
|
227
315
|
}
|
|
228
316
|
for (const criterion of sortCriteria) {
|
|
229
|
-
const
|
|
230
|
-
const
|
|
231
|
-
const
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
case 'number':
|
|
236
|
-
return criterion.column.sort({ item: a.item, value: aValue }, { item: b.item, value: bValue });
|
|
237
|
-
case 'boolean':
|
|
238
|
-
return criterion.column.sort({ item: a.item, value: aValue }, { item: b.item, value: bValue });
|
|
239
|
-
case 'component':
|
|
240
|
-
case 'template':
|
|
241
|
-
return criterion.column.sort({ item: a.item, value: undefined }, { item: b.item, value: undefined });
|
|
242
|
-
default:
|
|
243
|
-
return 0;
|
|
244
|
-
}
|
|
245
|
-
})();
|
|
246
|
-
if (sort !== 0) {
|
|
247
|
-
const dir = criterion.direction === 'asc' ? 1 : -1;
|
|
248
|
-
return sort * dir;
|
|
317
|
+
const cell1 = row1.cells.get(criterion.columnName);
|
|
318
|
+
const cell2 = row2.cells.get(criterion.columnName);
|
|
319
|
+
const comparison = cell1.column.compare({ item: row1.item, value: cell1.value }, { item: row2.item, value: cell2.value });
|
|
320
|
+
if (comparison !== 0) {
|
|
321
|
+
const signum = criterion.direction === 'asc' ? 1 : -1;
|
|
322
|
+
return signum * comparison;
|
|
249
323
|
}
|
|
250
324
|
}
|
|
251
325
|
return 0;
|
|
252
326
|
}
|
|
327
|
+
/**
|
|
328
|
+
* Checks whether given {@link SciTableDataLoaderFn} represents an {@link arrayDatasource}.
|
|
329
|
+
*/
|
|
330
|
+
function isArrayDatasource(loader) {
|
|
331
|
+
return ARRAY_DATASOURCE_MARKER in loader;
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Marks given {@link SciTableDataLoaderFn} as an array data source.
|
|
335
|
+
*/
|
|
336
|
+
function markAsArrayDatasource(loader) {
|
|
337
|
+
Object.defineProperty(loader, ARRAY_DATASOURCE_MARKER, { value: true, writable: false, enumerable: false, configurable: false });
|
|
338
|
+
return loader;
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Identifies a {@link SciTableDataLoaderFn} as an {@link arrayDatasource}.
|
|
342
|
+
*/
|
|
343
|
+
const ARRAY_DATASOURCE_MARKER = Symbol('ARRAY_DATASOURCE_HINT');
|
|
344
|
+
/**
|
|
345
|
+
* Coerces the given filter text into the specified column data type.
|
|
346
|
+
*/
|
|
347
|
+
function coerceFilterText(text, options) {
|
|
348
|
+
switch (options.to) {
|
|
349
|
+
case 'number': {
|
|
350
|
+
const number = Number.parseFloat(text);
|
|
351
|
+
return !Number.isNaN(number) ? number : undefined;
|
|
352
|
+
}
|
|
353
|
+
case 'boolean': {
|
|
354
|
+
if (text === 'true' || text === '1') {
|
|
355
|
+
return true;
|
|
356
|
+
}
|
|
357
|
+
if (text === 'false' || text === '0') {
|
|
358
|
+
return false;
|
|
359
|
+
}
|
|
360
|
+
return undefined;
|
|
361
|
+
}
|
|
362
|
+
default: {
|
|
363
|
+
return text;
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
253
367
|
|
|
254
368
|
/*
|
|
255
369
|
* Copyright (c) 2018-2026 Swiss Federal Railways
|
|
@@ -409,10 +523,12 @@ class ɵSciTable {
|
|
|
409
523
|
scrolling;
|
|
410
524
|
resizing = computed(() => this.columns().some(column => column.resizing()), /* @ts-ignore */
|
|
411
525
|
...(ngDevMode ? [{ debugName: "resizing" }] : /* istanbul ignore next */ []));
|
|
412
|
-
sortCriteria =
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
...(ngDevMode ?
|
|
526
|
+
sortCriteria = linkedSignal({ ...(ngDevMode ? { debugName: "sortCriteria" } : /* istanbul ignore next */ {}), source: () => this.columns(), // Discard stale criteria on column change.
|
|
527
|
+
computation: (columns, previous) => previous?.value.filter(criteria => columns.some(column => column.name === criteria.columnName)) ?? [],
|
|
528
|
+
equal: Objects.isEqual });
|
|
529
|
+
filterCriteria = linkedSignal({ ...(ngDevMode ? { debugName: "filterCriteria" } : /* istanbul ignore next */ {}), source: () => this.columns(), // Discard stale criteria on column change.
|
|
530
|
+
computation: (columns, previous) => previous?.value.filter(criteria => columns.some(column => column.name === criteria.columnName)) ?? [],
|
|
531
|
+
equal: Objects.isEqual });
|
|
416
532
|
_cache = new SciTableCache();
|
|
417
533
|
_tableFilter = signal(null, /* @ts-ignore */
|
|
418
534
|
...(ngDevMode ? [{ debugName: "_tableFilter" }] : /* istanbul ignore next */ []));
|
|
@@ -494,9 +610,9 @@ class ɵSciTable {
|
|
|
494
610
|
injector?.destroy();
|
|
495
611
|
injector = createDestroyableInjector({ parent: this._injector });
|
|
496
612
|
return runInInjectionContext(injector, () => {
|
|
497
|
-
const tableColumnFactory = new ɵSciTableColumnFactory(
|
|
613
|
+
const tableColumnFactory = new ɵSciTableColumnFactory(this);
|
|
498
614
|
descriptor.columns(tableColumnFactory);
|
|
499
|
-
return
|
|
615
|
+
return tableColumnFactory.columns;
|
|
500
616
|
});
|
|
501
617
|
});
|
|
502
618
|
}
|
|
@@ -573,7 +689,7 @@ class ɵSciTable {
|
|
|
573
689
|
defaultValue: 0,
|
|
574
690
|
params: () => this.tableViewRef()?.viewport,
|
|
575
691
|
stream: ({ params: viewport }) => fromEvent(viewport, 'scroll', { passive: true })
|
|
576
|
-
.pipe(map
|
|
692
|
+
.pipe(map(() => viewport.scrollTop), startWith(viewport.scrollTop), subscribeIn(fn => zone.runOutsideAngular(fn))),
|
|
577
693
|
}).value;
|
|
578
694
|
}
|
|
579
695
|
/**
|
|
@@ -585,7 +701,7 @@ class ɵSciTable {
|
|
|
585
701
|
defaultValue: false,
|
|
586
702
|
params: () => this.tableViewRef()?.viewport,
|
|
587
703
|
stream: ({ params: viewport }) => fromEvent(viewport, 'scroll', { passive: true })
|
|
588
|
-
.pipe(switchMap(() => concat(of(true), timer(150).pipe(map
|
|
704
|
+
.pipe(switchMap(() => concat(of(true), timer(150).pipe(map(() => false)))), startWith(false), subscribeIn(fn => zone.runOutsideAngular(fn))),
|
|
589
705
|
}).value;
|
|
590
706
|
}
|
|
591
707
|
/**
|
|
@@ -715,6 +831,14 @@ class ɵSciTable {
|
|
|
715
831
|
updateSelectedItems(updateFn) {
|
|
716
832
|
this._selectedItems.update(updateFn);
|
|
717
833
|
}
|
|
834
|
+
/**
|
|
835
|
+
* Indicates whether the built-in array datasource is used.
|
|
836
|
+
*
|
|
837
|
+
* Supports out-of-the-box filtering and sorting for built-in table columns.
|
|
838
|
+
*/
|
|
839
|
+
isArrayDatasource() {
|
|
840
|
+
return isArrayDatasource(this._dataLoaderFn);
|
|
841
|
+
}
|
|
718
842
|
reset() {
|
|
719
843
|
this._cache.clear();
|
|
720
844
|
this.totalCount.set(undefined);
|
|
@@ -761,32 +885,6 @@ class ɵSciTable {
|
|
|
761
885
|
this._cache.clear();
|
|
762
886
|
});
|
|
763
887
|
}
|
|
764
|
-
// TODO [dwi] Consider moving into factory
|
|
765
|
-
initColumn(type, config) {
|
|
766
|
-
// Columns with a custom component or template must provide a sort function to be sortable, because the default sort function does not work.
|
|
767
|
-
const sortable = type === 'component' || type === 'template' ? !!config.sortable : config.sortable !== false;
|
|
768
|
-
// Columns with a custom component or template must provide a filter function to be filterable, because the default filter function does not work.
|
|
769
|
-
const filterable = type === 'component' || type === 'template' ? !!config.filterable : config.filterable !== false;
|
|
770
|
-
return {
|
|
771
|
-
...config,
|
|
772
|
-
type,
|
|
773
|
-
name: config.name,
|
|
774
|
-
filter: typeof config.filterable === 'object' ? config.filterable.matcher : defaultFilter,
|
|
775
|
-
sort: typeof config.sortable === 'object' ? config.sortable.comparator : defaultSort,
|
|
776
|
-
sortable: computed(() => this.sortable() && sortable),
|
|
777
|
-
filterable: computed(() => this.filterable() && filterable),
|
|
778
|
-
resizable: computed(() => this.resizable() && (config.resizable ?? true)),
|
|
779
|
-
padding: 'padding' in config ? (config.padding ?? true) : true,
|
|
780
|
-
header: coerceSignal(config.header ?? ''),
|
|
781
|
-
width: computed(() => {
|
|
782
|
-
const userSettings = this.userSettings().columns?.find(column => column.name === config.name);
|
|
783
|
-
return userSettings?.width ? `${userSettings.width}px` : config.width ?? '1fr';
|
|
784
|
-
}),
|
|
785
|
-
minWidth: config.minWidth ?? 100,
|
|
786
|
-
resizing: signal(false),
|
|
787
|
-
location: { x: 0, width: 0 }, // injected in `SciColumnComponent`
|
|
788
|
-
};
|
|
789
|
-
}
|
|
790
888
|
mapItemsToRow(items, columns, pageStart) {
|
|
791
889
|
return items.map((item, i) => {
|
|
792
890
|
const id = this.trackBy(item);
|
|
@@ -855,32 +953,6 @@ class ɵSciTable {
|
|
|
855
953
|
});
|
|
856
954
|
}
|
|
857
955
|
}
|
|
858
|
-
function defaultFilter(text, { value }) {
|
|
859
|
-
if (typeof value !== typeof text) {
|
|
860
|
-
return false;
|
|
861
|
-
}
|
|
862
|
-
switch (typeof value) {
|
|
863
|
-
case 'string':
|
|
864
|
-
return value.toLowerCase().includes(text.toLowerCase());
|
|
865
|
-
default:
|
|
866
|
-
return text === value;
|
|
867
|
-
}
|
|
868
|
-
}
|
|
869
|
-
function defaultSort(a, b) {
|
|
870
|
-
if (typeof a.value !== typeof b.value) {
|
|
871
|
-
return 0;
|
|
872
|
-
}
|
|
873
|
-
switch (typeof a.value) {
|
|
874
|
-
case 'string':
|
|
875
|
-
return a.value.localeCompare(b.value);
|
|
876
|
-
case 'number':
|
|
877
|
-
return a.value - b.value;
|
|
878
|
-
case 'boolean':
|
|
879
|
-
return a.value === b.value ? 0 : (a.value ? 1 : -1);
|
|
880
|
-
default:
|
|
881
|
-
return 0;
|
|
882
|
-
}
|
|
883
|
-
}
|
|
884
956
|
/**
|
|
885
957
|
* Gets pages by range and page size, or `null` if empty. End is exclusive.
|
|
886
958
|
*/
|
|
@@ -1489,7 +1561,7 @@ class SciTableRowComponent {
|
|
|
1489
1561
|
onRowMouseLeave(event) {
|
|
1490
1562
|
const next = event.relatedTarget;
|
|
1491
1563
|
// Do not unset hovered row when hovering a column resize splitter.
|
|
1492
|
-
if (next instanceof Element && next.closest('sci-
|
|
1564
|
+
if (next instanceof Element && next.closest('sci-splitter')) {
|
|
1493
1565
|
return;
|
|
1494
1566
|
}
|
|
1495
1567
|
this.table().hoveredIndex.set(-1);
|
|
@@ -1507,7 +1579,7 @@ class SciTableRowComponent {
|
|
|
1507
1579
|
});
|
|
1508
1580
|
}
|
|
1509
1581
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: SciTableRowComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1510
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: SciTableRowComponent, isStandalone: true, selector: "sci-table-row", inputs: { row: { classPropertyName: "row", publicName: "row", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { primaryAction: "primaryAction" }, host: { listeners: { "click": "onRowClick($event)", "dblclick": "onRowDblClick($event)", "mouseenter": "onRowMouseEnter()", "mouseleave": "onRowMouseLeave($event)" }, properties: { "attr.data-active": "row().active() ? '' : null", "attr.data-selected": "row().selected() ? '' : null", "attr.data-hovered": "row().hovered() ? '' : null", "class": "row().bindings?.cssClass?.()" } }, viewQueries: [{ propertyName: "rowActionToolbar", first: true, predicate: SciToolbarComponent, descendants: true, isSignal: true }], ngImport: i0, template: "@let row = this.row();\n@for (cell of row.cells; track cell.column.name) {\n <sci-table-cell [cell]=\"cell\" [row]=\"row\"/>\n} @empty {\n @for (column of table().columns(); track column.name) {\n <div class=\"skeleton e2e-skeleton\" [attr.data-column]=\"column.name\"></div>\n }\n}\n\n@let hasRowActions = !!table().rowActions;\n@let isRowHovered = table().hoveredRow() === row;\n@let isRowActionMenuOpen = rowActionToolbar()?.menuOpen();\n\n@if (hasRowActions && (isRowHovered || isRowActionMenuOpen)) {\n <!--eslint-disable-next-line @angular-eslint/template/click-events-have-key-events,@angular-eslint/template/interactive-supports-focus -->\n <sci-toolbar [name]=\"rowActionsToolbarName\" (click)=\"onActionToolbarClick($event)\" class=\"row-actions\"/>\n}\n", styles: ["@charset \"UTF-8\";:host{display:inline-grid;grid-template-columns:subgrid;grid-auto-rows:var(--sci-table-row-height);align-items:stretch;-webkit-user-select:none;user-select:none;border-bottom:var(--\\275sci-table-border-size) solid var(--sci-table-gridline-color)}:host[data-hovered]{background-color:var(--sci-table-row-background-color-hover)}:host[data-selected]{background-color:var(--sci-table-row-background-color-selected);--\\275sci-table-row-selected: true}:host[data-hovered]:not([data-selected]){border-radius:var(--sci-table-row-border-radius)}:host:is(:first-child,:not([data-selected])+sci-table-row)[data-selected]{border-top-left-radius:var(--sci-table-row-border-radius);border-top-right-radius:var(--sci-table-row-border-radius)}:host[data-selected]:not(:has(+sci-table-row[data-selected])){border-bottom-left-radius:var(--sci-table-row-border-radius);border-bottom-right-radius:var(--sci-table-row-border-radius)}@container (style(--\\275sci-table-scrolling: true)) or (style(--\\275sci-table-resizing: true)){:host{pointer-events:none}}:host:has(>div.skeleton){pointer-events:none;align-items:center}:host:has(>div.skeleton)>div.skeleton{display:inline-block;position:relative;overflow:hidden;border-radius:var(--sci-corner-small);background-color:var(--sci-color-skeleton-subtle)}:host:has(>div.skeleton)>div.skeleton:after{position:absolute;inset:0;transform:translate(-100%);background-image:linear-gradient(to right,transparent 0,color-mix(in srgb,light-dark(var(--sci-static-color-white),var(--sci-static-color-black)) 30%,transparent) 50%,transparent);animation:shimmer 2s infinite;content:\"\"}@keyframes shimmer{to{transform:translate(100%)}}:host:has(>div.skeleton)>div.skeleton{height:1em;margin-inline:var(--\\275sci-table-cell-padding-inline)}:host>sci-toolbar.row-actions{position:sticky;right:0;transform:translate(calc(-1 * var(--\\275sci-table-cell-padding-inline)));justify-self:end;align-self:center;border-radius:var(--sci-corner);padding:1px;background-color:var(--\\275sci-table-row-action-background-color);z-index:2;--sci-toolbar-item-background-color-hover: color-mix(in srgb, var(--\\275sci-table-row-action-background-color) 85%, light-dark(var(--sci-static-color-black), var(--sci-static-color-white)));--sci-toolbar-item-background-color-active: color-mix(in srgb, var(--\\275sci-table-row-action-background-color) 75%, light-dark(var(--sci-static-color-black), var(--sci-static-color-white)))}@container not style(--\\275sci-table-row-selected: true){:host>sci-toolbar.row-actions{--\\275sci-table-row-action-background-color: var(--sci-table-row-action-background-color)}}@container style(--\\275sci-table-row-selected: true){:host>sci-toolbar.row-actions{--\\275sci-table-row-action-background-color: var(--sci-table-row-action-background-color-selected)}}:host>sci-toolbar.row-actions:empty{display:none}\n"], dependencies: [{ kind: "component", type: SciTableCellComponent, selector: "sci-table-cell", inputs: ["cell", "row"] }, { kind: "component", type: SciToolbarComponent, selector: "sci-toolbar", inputs: ["name", "orientation", "context", "acceleratorTarget", "popoverViewContainerRef"] }] });
|
|
1582
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: SciTableRowComponent, isStandalone: true, selector: "sci-table-row", inputs: { row: { classPropertyName: "row", publicName: "row", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { primaryAction: "primaryAction" }, host: { listeners: { "click": "onRowClick($event)", "dblclick": "onRowDblClick($event)", "mouseenter": "onRowMouseEnter()", "mouseleave": "onRowMouseLeave($event)" }, properties: { "attr.data-active": "row().active() ? '' : null", "attr.data-selected": "row().selected() ? '' : null", "attr.data-hovered": "row().hovered() ? '' : null", "class": "row().bindings?.cssClass?.()" } }, viewQueries: [{ propertyName: "rowActionToolbar", first: true, predicate: SciToolbarComponent, descendants: true, isSignal: true }], ngImport: i0, template: "@let row = this.row();\n@for (cell of row.cells; track cell.column.name) {\n <sci-table-cell [cell]=\"cell\" [row]=\"row\"/>\n} @empty {\n @for (column of table().columns(); track column.name) {\n <div class=\"skeleton e2e-skeleton\" [attr.data-column]=\"column.name\"></div>\n }\n}\n\n@let hasRowActions = !!table().rowActions;\n@let isRowHovered = table().hoveredRow() === row;\n@let isRowActionMenuOpen = rowActionToolbar()?.menuOpen();\n\n@if (hasRowActions && (isRowHovered || isRowActionMenuOpen)) {\n <!--eslint-disable-next-line @angular-eslint/template/click-events-have-key-events,@angular-eslint/template/interactive-supports-focus -->\n <sci-toolbar [name]=\"rowActionsToolbarName\" (click)=\"onActionToolbarClick($event)\" class=\"row-actions\"/>\n}\n", styles: ["@charset \"UTF-8\";:host{display:inline-grid;grid-template-columns:subgrid;grid-auto-rows:var(--sci-table-row-height);align-items:stretch;-webkit-user-select:none;user-select:none;border-bottom:var(--\\275sci-table-border-size) solid var(--sci-table-gridline-color)}:host[data-hovered]{background-color:var(--sci-table-row-background-color-hover)}:host[data-selected]{background-color:var(--sci-table-row-background-color-selected);--\\275sci-table-row-selected: true}:host[data-hovered]:not([data-selected]){border-radius:var(--sci-table-row-border-radius)}:host:is(:first-child,:not([data-selected])+sci-table-row)[data-selected]{border-top-left-radius:var(--sci-table-row-border-radius);border-top-right-radius:var(--sci-table-row-border-radius)}:host[data-selected]:not(:has(+sci-table-row[data-selected])){border-bottom-left-radius:var(--sci-table-row-border-radius);border-bottom-right-radius:var(--sci-table-row-border-radius)}@container (style(--\\275sci-table-scrolling: true)) or (style(--\\275sci-table-resizing: true)){:host{pointer-events:none}}:host:has(>div.skeleton){pointer-events:none;align-items:center}:host:has(>div.skeleton)>div.skeleton{display:inline-block;position:relative;overflow:hidden;border-radius:var(--sci-corner-small);background-color:var(--sci-color-skeleton-subtle);opacity:0;animation-name:visiblity;animation-duration:0s;animation-delay:50ms;animation-fill-mode:forwards}:host:has(>div.skeleton)>div.skeleton:after{position:absolute;inset:0;transform:translate(-100%);background-image:linear-gradient(to right,transparent 0,color-mix(in srgb,light-dark(var(--sci-static-color-white),var(--sci-static-color-black)) 30%,transparent) 50%,transparent);animation:shimmer 2s infinite;content:\"\"}@keyframes shimmer{to{transform:translate(100%)}}@keyframes visiblity{to{opacity:1}}:host:has(>div.skeleton)>div.skeleton{height:1em;margin-inline:var(--\\275sci-table-cell-padding-inline)}:host>sci-toolbar.row-actions{position:sticky;right:0;transform:translate(calc(-1 * var(--\\275sci-table-cell-padding-inline)));justify-self:end;align-self:center;border-radius:var(--sci-corner);padding:1px;background-color:var(--\\275sci-table-row-action-background-color);z-index:2;--sci-toolbar-item-background-color-hover: color-mix(in srgb, var(--\\275sci-table-row-action-background-color) 85%, light-dark(var(--sci-static-color-black), var(--sci-static-color-white)));--sci-toolbar-item-background-color-active: color-mix(in srgb, var(--\\275sci-table-row-action-background-color) 75%, light-dark(var(--sci-static-color-black), var(--sci-static-color-white)))}@container not style(--\\275sci-table-row-selected: true){:host>sci-toolbar.row-actions{--\\275sci-table-row-action-background-color: var(--sci-table-row-action-background-color)}}@container style(--\\275sci-table-row-selected: true){:host>sci-toolbar.row-actions{--\\275sci-table-row-action-background-color: var(--sci-table-row-action-background-color-selected)}}:host>sci-toolbar.row-actions:empty{display:none}\n"], dependencies: [{ kind: "component", type: SciTableCellComponent, selector: "sci-table-cell", inputs: ["cell", "row"] }, { kind: "component", type: SciToolbarComponent, selector: "sci-toolbar", inputs: ["name", "orientation", "context", "acceleratorTarget", "popoverViewContainerRef"] }] });
|
|
1511
1583
|
}
|
|
1512
1584
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: SciTableRowComponent, decorators: [{
|
|
1513
1585
|
type: Component,
|
|
@@ -1523,7 +1595,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
|
|
|
1523
1595
|
'(dblclick)': 'onRowDblClick($event)',
|
|
1524
1596
|
'(mouseenter)': 'onRowMouseEnter()',
|
|
1525
1597
|
'(mouseleave)': 'onRowMouseLeave($event)',
|
|
1526
|
-
}, template: "@let row = this.row();\n@for (cell of row.cells; track cell.column.name) {\n <sci-table-cell [cell]=\"cell\" [row]=\"row\"/>\n} @empty {\n @for (column of table().columns(); track column.name) {\n <div class=\"skeleton e2e-skeleton\" [attr.data-column]=\"column.name\"></div>\n }\n}\n\n@let hasRowActions = !!table().rowActions;\n@let isRowHovered = table().hoveredRow() === row;\n@let isRowActionMenuOpen = rowActionToolbar()?.menuOpen();\n\n@if (hasRowActions && (isRowHovered || isRowActionMenuOpen)) {\n <!--eslint-disable-next-line @angular-eslint/template/click-events-have-key-events,@angular-eslint/template/interactive-supports-focus -->\n <sci-toolbar [name]=\"rowActionsToolbarName\" (click)=\"onActionToolbarClick($event)\" class=\"row-actions\"/>\n}\n", styles: ["@charset \"UTF-8\";:host{display:inline-grid;grid-template-columns:subgrid;grid-auto-rows:var(--sci-table-row-height);align-items:stretch;-webkit-user-select:none;user-select:none;border-bottom:var(--\\275sci-table-border-size) solid var(--sci-table-gridline-color)}:host[data-hovered]{background-color:var(--sci-table-row-background-color-hover)}:host[data-selected]{background-color:var(--sci-table-row-background-color-selected);--\\275sci-table-row-selected: true}:host[data-hovered]:not([data-selected]){border-radius:var(--sci-table-row-border-radius)}:host:is(:first-child,:not([data-selected])+sci-table-row)[data-selected]{border-top-left-radius:var(--sci-table-row-border-radius);border-top-right-radius:var(--sci-table-row-border-radius)}:host[data-selected]:not(:has(+sci-table-row[data-selected])){border-bottom-left-radius:var(--sci-table-row-border-radius);border-bottom-right-radius:var(--sci-table-row-border-radius)}@container (style(--\\275sci-table-scrolling: true)) or (style(--\\275sci-table-resizing: true)){:host{pointer-events:none}}:host:has(>div.skeleton){pointer-events:none;align-items:center}:host:has(>div.skeleton)>div.skeleton{display:inline-block;position:relative;overflow:hidden;border-radius:var(--sci-corner-small);background-color:var(--sci-color-skeleton-subtle)}:host:has(>div.skeleton)>div.skeleton:after{position:absolute;inset:0;transform:translate(-100%);background-image:linear-gradient(to right,transparent 0,color-mix(in srgb,light-dark(var(--sci-static-color-white),var(--sci-static-color-black)) 30%,transparent) 50%,transparent);animation:shimmer 2s infinite;content:\"\"}@keyframes shimmer{to{transform:translate(100%)}}:host:has(>div.skeleton)>div.skeleton{height:1em;margin-inline:var(--\\275sci-table-cell-padding-inline)}:host>sci-toolbar.row-actions{position:sticky;right:0;transform:translate(calc(-1 * var(--\\275sci-table-cell-padding-inline)));justify-self:end;align-self:center;border-radius:var(--sci-corner);padding:1px;background-color:var(--\\275sci-table-row-action-background-color);z-index:2;--sci-toolbar-item-background-color-hover: color-mix(in srgb, var(--\\275sci-table-row-action-background-color) 85%, light-dark(var(--sci-static-color-black), var(--sci-static-color-white)));--sci-toolbar-item-background-color-active: color-mix(in srgb, var(--\\275sci-table-row-action-background-color) 75%, light-dark(var(--sci-static-color-black), var(--sci-static-color-white)))}@container not style(--\\275sci-table-row-selected: true){:host>sci-toolbar.row-actions{--\\275sci-table-row-action-background-color: var(--sci-table-row-action-background-color)}}@container style(--\\275sci-table-row-selected: true){:host>sci-toolbar.row-actions{--\\275sci-table-row-action-background-color: var(--sci-table-row-action-background-color-selected)}}:host>sci-toolbar.row-actions:empty{display:none}\n"] }]
|
|
1598
|
+
}, template: "@let row = this.row();\n@for (cell of row.cells; track cell.column.name) {\n <sci-table-cell [cell]=\"cell\" [row]=\"row\"/>\n} @empty {\n @for (column of table().columns(); track column.name) {\n <div class=\"skeleton e2e-skeleton\" [attr.data-column]=\"column.name\"></div>\n }\n}\n\n@let hasRowActions = !!table().rowActions;\n@let isRowHovered = table().hoveredRow() === row;\n@let isRowActionMenuOpen = rowActionToolbar()?.menuOpen();\n\n@if (hasRowActions && (isRowHovered || isRowActionMenuOpen)) {\n <!--eslint-disable-next-line @angular-eslint/template/click-events-have-key-events,@angular-eslint/template/interactive-supports-focus -->\n <sci-toolbar [name]=\"rowActionsToolbarName\" (click)=\"onActionToolbarClick($event)\" class=\"row-actions\"/>\n}\n", styles: ["@charset \"UTF-8\";:host{display:inline-grid;grid-template-columns:subgrid;grid-auto-rows:var(--sci-table-row-height);align-items:stretch;-webkit-user-select:none;user-select:none;border-bottom:var(--\\275sci-table-border-size) solid var(--sci-table-gridline-color)}:host[data-hovered]{background-color:var(--sci-table-row-background-color-hover)}:host[data-selected]{background-color:var(--sci-table-row-background-color-selected);--\\275sci-table-row-selected: true}:host[data-hovered]:not([data-selected]){border-radius:var(--sci-table-row-border-radius)}:host:is(:first-child,:not([data-selected])+sci-table-row)[data-selected]{border-top-left-radius:var(--sci-table-row-border-radius);border-top-right-radius:var(--sci-table-row-border-radius)}:host[data-selected]:not(:has(+sci-table-row[data-selected])){border-bottom-left-radius:var(--sci-table-row-border-radius);border-bottom-right-radius:var(--sci-table-row-border-radius)}@container (style(--\\275sci-table-scrolling: true)) or (style(--\\275sci-table-resizing: true)){:host{pointer-events:none}}:host:has(>div.skeleton){pointer-events:none;align-items:center}:host:has(>div.skeleton)>div.skeleton{display:inline-block;position:relative;overflow:hidden;border-radius:var(--sci-corner-small);background-color:var(--sci-color-skeleton-subtle);opacity:0;animation-name:visiblity;animation-duration:0s;animation-delay:50ms;animation-fill-mode:forwards}:host:has(>div.skeleton)>div.skeleton:after{position:absolute;inset:0;transform:translate(-100%);background-image:linear-gradient(to right,transparent 0,color-mix(in srgb,light-dark(var(--sci-static-color-white),var(--sci-static-color-black)) 30%,transparent) 50%,transparent);animation:shimmer 2s infinite;content:\"\"}@keyframes shimmer{to{transform:translate(100%)}}@keyframes visiblity{to{opacity:1}}:host:has(>div.skeleton)>div.skeleton{height:1em;margin-inline:var(--\\275sci-table-cell-padding-inline)}:host>sci-toolbar.row-actions{position:sticky;right:0;transform:translate(calc(-1 * var(--\\275sci-table-cell-padding-inline)));justify-self:end;align-self:center;border-radius:var(--sci-corner);padding:1px;background-color:var(--\\275sci-table-row-action-background-color);z-index:2;--sci-toolbar-item-background-color-hover: color-mix(in srgb, var(--\\275sci-table-row-action-background-color) 85%, light-dark(var(--sci-static-color-black), var(--sci-static-color-white)));--sci-toolbar-item-background-color-active: color-mix(in srgb, var(--\\275sci-table-row-action-background-color) 75%, light-dark(var(--sci-static-color-black), var(--sci-static-color-white)))}@container not style(--\\275sci-table-row-selected: true){:host>sci-toolbar.row-actions{--\\275sci-table-row-action-background-color: var(--sci-table-row-action-background-color)}}@container style(--\\275sci-table-row-selected: true){:host>sci-toolbar.row-actions{--\\275sci-table-row-action-background-color: var(--sci-table-row-action-background-color-selected)}}:host>sci-toolbar.row-actions:empty{display:none}\n"] }]
|
|
1527
1599
|
}], ctorParameters: () => [], propDecorators: { row: [{ type: i0.Input, args: [{ isSignal: true, alias: "row", required: true }] }], primaryAction: [{ type: i0.Output, args: ["primaryAction"] }], rowActionToolbar: [{ type: i0.ViewChild, args: [i0.forwardRef(() => SciToolbarComponent), { isSignal: true }] }] } });
|
|
1528
1600
|
|
|
1529
1601
|
/*
|
|
@@ -2214,7 +2286,7 @@ class SciTableComponent {
|
|
|
2214
2286
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: SciTableComponent, isStandalone: true, selector: "sci-table", inputs: { name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: true, transformFunction: null }, table: { classPropertyName: "table", publicName: "table", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { primaryAction: "primaryAction" }, host: { properties: { "attr.name": "name()", "style.--\u0275sci-table-scrolling": "table().scrolling() ? `true` : null", "style.--\u0275sci-table-resizing": "table().resizing() ? `true` : null" } }, providers: [
|
|
2215
2287
|
provideSciTable(),
|
|
2216
2288
|
SciTableSelectionService,
|
|
2217
|
-
], viewQueries: [{ propertyName: "_viewport", first: true, predicate: SciTableViewportComponent, descendants: true, read: ElementRef, isSignal: true }, { propertyName: "_viewportClient", first: true, predicate: SciTableGridComponent, descendants: true, read: ElementRef, isSignal: true }, { propertyName: "_tableHeader", first: true, predicate: SciTableHeaderComponent, descendants: true, read: ElementRef, isSignal: true }, { propertyName: "_tableBody", first: true, predicate: SciTableBodyComponent, descendants: true, read: ElementRef, isSignal: true }, { propertyName: "_itemSizeSyntheticElement", first: true, predicate: ["item_size_synthetic_element"], descendants: true, isSignal: true }, { propertyName: "_cellPaddingSyntheticElement", first: true, predicate: ["cell_padding_synthetic_element"], descendants: true, isSignal: true }, { propertyName: "rows", predicate: SciTableRowComponent, descendants: true, isSignal: true }], ngImport: i0, template: "@let table = this.table();\n\n<sci-table-viewport #viewport>\n <sci-table-grid>\n <!-- Table header -->\n @if (table.showHeader() || table.filterable()) {\n <sci-table-header/>\n }\n\n <!-- Table body -->\n <sci-table-body sciTableKeyboardNavigator>\n @if (!table.error()) {\n <!-- Track index to reuse the table row elements -->\n @for (row of table.rows(); track $index) {\n <sci-table-row [row]=\"row\" (primaryAction)=\"onRowPrimaryAction($event)\" [sciAttributes]=\"row.bindings?.attributes()\"/>\n } @empty {\n <span class=\"message e2e-no-data\">{{('%scion.components.no_items.message' | sciText)()}}</span>\n }\n } @else {\n <span class=\"message e2e-datasource\">\n {{('%scion.components.datasource_error.message' | sciText)()}}\n\n <button (click)=\"onRetry()\" class=\"action e2e-datasource-retry\">\n <!-- TODO [dwi] Replace with SCION icon -->\n <sci-icon>refresh</sci-icon>\n <span>{{('%scion.components.retry.label' | sciText)()}}</span>\n </button>\n </span>\n }\n\n <!-- Render active row outline separately to preserve row border-radius within block selection. -->\n @if (table.activeRow()) {\n <div class=\"active-row-outline e2e-active-row-outline\"></div>\n }\n </sci-table-body>\n\n <!-- Render column splitters. -->\n <sci-table-columns [rows]=\"rows()\"/>\n </sci-table-grid>\n</sci-table-viewport>\n\n<!-- Scrollbars -->\n<sci-scrollbar direction=\"hscroll\" [viewport]=\"viewport.host\"/>\n<sci-scrollbar direction=\"vscroll\" [viewport]=\"viewport.host\"/>\n\n@if (table.loading()) {\n <sci-throbber type=\"spinner\"/>\n}\n\n<!-- Synthetic element to compute the absolute pixel value of the `--sci-table-row-height`, relative to the table's font size if em-based. -->\n<div class=\"synthetic item-size\" #item_size_synthetic_element></div>\n\n<!-- Synthetic element to compute the absolute pixel value of the `--sci-table-cell-padding-inline`, relative to the table's font size if em-based. -->\n<div class=\"synthetic cell-padding\" #cell_padding_synthetic_element></div>\n", styles: ["@charset \"UTF-8\";:host{display:block;overflow:hidden;--\\275sci-table-border-size: 1px;--\\275sci-table-border-color: var(--sci-color-border)}:host:is(:not(:hover):not(:active),:host(:not(:hover):not(:active))) sci-scrollbar:not(.scrolling){opacity:0}:host>sci-table-viewport{display:block;position:relative;height:100%;overflow:auto;scrollbar-width:none;isolation:isolate;box-sizing:border-box;anchor-name:--sci-table-viewport}:host>sci-table-viewport:has(sci-table-header){--\\275sci-table-header-visible: true}:host>sci-table-viewport:has(sci-table-header>sci-column-header){--\\275sci-column-header-visible: true}:host>sci-table-viewport:has(~sci-scrollbar.scrolling){--\\275sci-table-scrolling: true}:host>sci-table-viewport>sci-table-grid{display:grid;grid-template-columns:var(--\\275sci-table-columns, repeat(auto-fit,
|
|
2289
|
+
], viewQueries: [{ propertyName: "_viewport", first: true, predicate: SciTableViewportComponent, descendants: true, read: ElementRef, isSignal: true }, { propertyName: "_viewportClient", first: true, predicate: SciTableGridComponent, descendants: true, read: ElementRef, isSignal: true }, { propertyName: "_tableHeader", first: true, predicate: SciTableHeaderComponent, descendants: true, read: ElementRef, isSignal: true }, { propertyName: "_tableBody", first: true, predicate: SciTableBodyComponent, descendants: true, read: ElementRef, isSignal: true }, { propertyName: "_itemSizeSyntheticElement", first: true, predicate: ["item_size_synthetic_element"], descendants: true, isSignal: true }, { propertyName: "_cellPaddingSyntheticElement", first: true, predicate: ["cell_padding_synthetic_element"], descendants: true, isSignal: true }, { propertyName: "rows", predicate: SciTableRowComponent, descendants: true, isSignal: true }], ngImport: i0, template: "@let table = this.table();\n\n<sci-table-viewport #viewport>\n <sci-table-grid>\n <!-- Table header -->\n @if (table.showHeader() || table.filterable()) {\n <sci-table-header/>\n }\n\n <!-- Table body -->\n <sci-table-body sciTableKeyboardNavigator>\n @if (!table.error()) {\n <!-- Track index to reuse the table row elements -->\n @for (row of table.rows(); track $index) {\n <sci-table-row [row]=\"row\" (primaryAction)=\"onRowPrimaryAction($event)\" [sciAttributes]=\"row.bindings?.attributes()\"/>\n } @empty {\n <span class=\"message e2e-no-data\">{{('%scion.components.no_items.message' | sciText)()}}</span>\n }\n } @else {\n <span class=\"message e2e-datasource\">\n {{('%scion.components.datasource_error.message' | sciText)()}}\n\n <button (click)=\"onRetry()\" class=\"action e2e-datasource-retry\">\n <!-- TODO [dwi] Replace with SCION icon -->\n <sci-icon>refresh</sci-icon>\n <span>{{('%scion.components.retry.label' | sciText)()}}</span>\n </button>\n </span>\n }\n\n <!-- Render active row outline separately to preserve row border-radius within block selection. -->\n @if (table.activeRow()) {\n <div class=\"active-row-outline e2e-active-row-outline\"></div>\n }\n </sci-table-body>\n\n <!-- Render column splitters. -->\n <sci-table-columns [rows]=\"rows()\"/>\n </sci-table-grid>\n</sci-table-viewport>\n\n<!-- Scrollbars -->\n<sci-scrollbar direction=\"hscroll\" [viewport]=\"viewport.host\"/>\n<sci-scrollbar direction=\"vscroll\" [viewport]=\"viewport.host\"/>\n\n@if (table.loading()) {\n <sci-throbber type=\"spinner\"/>\n}\n\n<!-- Synthetic element to compute the absolute pixel value of the `--sci-table-row-height`, relative to the table's font size if em-based. -->\n<div class=\"synthetic item-size\" #item_size_synthetic_element></div>\n\n<!-- Synthetic element to compute the absolute pixel value of the `--sci-table-cell-padding-inline`, relative to the table's font size if em-based. -->\n<div class=\"synthetic cell-padding\" #cell_padding_synthetic_element></div>\n", styles: ["@charset \"UTF-8\";:host{display:block;overflow:hidden;--\\275sci-table-border-size: 1px;--\\275sci-table-border-color: var(--sci-color-border)}:host:is(:not(:hover):not(:active),:host(:not(:hover):not(:active))) sci-scrollbar:not(.scrolling){opacity:0}:host>sci-table-viewport{display:block;position:relative;height:100%;overflow:auto;scrollbar-width:none;isolation:isolate;box-sizing:border-box;anchor-name:--sci-table-viewport}:host>sci-table-viewport:has(sci-table-header){--\\275sci-table-header-visible: true}:host>sci-table-viewport:has(sci-table-header>sci-column-header){--\\275sci-column-header-visible: true}:host>sci-table-viewport:has(~sci-scrollbar.scrolling){--\\275sci-table-scrolling: true}:host>sci-table-viewport>sci-table-grid{display:grid;grid-template-columns:var(--\\275sci-table-columns, repeat(auto-fit, 100px)) 0;grid-auto-rows:min-content;grid-template-rows:min-content 1fr;width:min-content;min-width:100%;min-height:100%}@container not style(--\\275sci-table-header-visible: true){:host>sci-table-viewport>sci-table-grid{grid-template-rows:1fr}}:host>sci-table-viewport>sci-table-grid>sci-table-header{z-index:1;grid-row:1;grid-column:1/-1;position:sticky;top:0}:host>sci-table-viewport>sci-table-grid>sci-table-body{anchor-name:--sci-table-body;grid-row:2}@container not style(--\\275sci-table-header-visible: true){:host>sci-table-viewport>sci-table-grid>sci-table-body{grid-row:1}}:host>sci-table-viewport>sci-table-grid>sci-table-body{display:grid;grid-template-columns:subgrid;grid-column:1/-1;grid-auto-rows:var(--sci-table-row-height);outline:none;padding-top:var(--\\275sci-table-virtual-scroll-offset-top);padding-bottom:var(--\\275sci-table-virtual-scroll-offset-bottom)}:host>sci-table-viewport>sci-table-grid>sci-table-body>sci-table-row{grid-column:1/-1}:host>sci-table-viewport>sci-table-grid>sci-table-body>sci-table-row[data-active]{anchor-name:--sci-table-active-row}:host>sci-table-viewport>sci-table-grid>sci-table-body>div.active-row-outline{position:absolute;top:anchor(--sci-table-active-row top);right:anchor(--sci-table-active-row right);bottom:anchor(--sci-table-active-row bottom);left:anchor(--sci-table-active-row left);border:var(--sci-table-row-outline-width) var(--sci-table-row-outline-style) var(--sci-table-row-outline-color);border-radius:var(--sci-table-row-border-radius);pointer-events:none}:host>sci-table-viewport>sci-table-grid>sci-table-body:not(:has(sci-table-row[data-active]))>div.active-row-outline{display:none}:host>sci-table-viewport>sci-table-grid>sci-table-body>span.message{grid-column:1/-1;grid-row:auto/span 2;justify-self:center;align-self:center;display:flex;flex-direction:column;align-items:center;gap:1em;-webkit-user-select:none;user-select:none;white-space:nowrap;color:var(--sci-color-text-subtle)}:host>sci-table-viewport>sci-table-grid>sci-table-body>span.message:has(button.action){grid-row:auto/span 4}:host>sci-table-viewport>sci-table-grid>sci-table-body>span.message>button.action{all:unset;display:inline-grid;place-content:center;place-items:center;padding:.25em;border-radius:var(--sci-button-border-radius);-webkit-user-select:none;user-select:none;overflow:hidden;cursor:var(--sci-button-cursor);--sci-icon-size: var(--sci-button-icon-size)}:host>sci-table-viewport>sci-table-grid>sci-table-body>span.message>button.action:hover:where(:not(:disabled)){background-color:var(--sci-button-background-color-hover)}:host>sci-table-viewport>sci-table-grid>sci-table-body>span.message>button.action:active:where(:not(:disabled)){background-color:var(--sci-button-background-color-active)}:host>sci-table-viewport>sci-table-grid>sci-table-body>span.message>button.action:focus:not(:focus-visible){outline:none}:host>sci-table-viewport>sci-table-grid>sci-table-body>span.message>button.action:focus-visible{outline:var(--sci-button-outline-width) solid var(--sci-color-accent)}:host>sci-table-viewport>sci-table-grid>sci-table-body>span.message>button.action:disabled{color:var(--sci-button-text-color-disabled)}:host>sci-table-viewport>sci-table-grid>sci-table-body>span.message>button.action{border:1px solid var(--sci-color-border);padding:.25em 1em}@container style(--\\275sci-table-viewport-client-width > --\\275sci-table-viewport-width){:host>sci-table-viewport>sci-table-grid>sci-table-body>span.message{position:sticky;left:50%;right:50%;width:0}}:host>sci-table-viewport>sci-table-grid>sci-table-body:has(>span.message){z-index:2}:host>sci-table-viewport>sci-table-grid>sci-table-columns{grid-area:1/1/-1/-1;z-index:1;position:sticky;top:0;max-height:var(--\\275sci-table-viewport-height)}:host>sci-scrollbar{position:absolute}:host>sci-scrollbar[direction=vscroll]{top:calc(anchor(--sci-table-body top) + 2px);right:calc(anchor(--sci-table-viewport right) + 2px);bottom:calc(anchor(--sci-table-viewport bottom) + 2px)}:host>sci-scrollbar[direction=hscroll]{left:calc(anchor(--sci-table-viewport left) + 2px);bottom:calc(anchor(--sci-table-viewport bottom) + 1px);right:calc(anchor(--sci-table-viewport right) + 2px)}@container style(--\\275sci-table-resizing: true){:host>sci-scrollbar{pointer-events:none}}:host>sci-throbber{--sci-throbber-size: 16px;position:absolute;top:calc(anchor(--sci-table-viewport top) + .5em);right:calc(anchor(--sci-table-viewport right) + .5em)}:host>div.synthetic{position:absolute;pointer-events:none;visibility:hidden}:host>div.synthetic.item-size{height:var(--sci-table-row-height)}:host>div.synthetic.cell-padding{width:var(--sci-table-cell-padding-inline)}\n"], dependencies: [{ kind: "component", type: SciTableViewportComponent, selector: "sci-table-viewport" }, { kind: "component", type: SciTableHeaderComponent, selector: "sci-table-header" }, { kind: "component", type: SciTableGridComponent, selector: "sci-table-grid" }, { kind: "component", type: SciTableBodyComponent, selector: "sci-table-body" }, { kind: "component", type: SciTableRowComponent, selector: "sci-table-row", inputs: ["row"], outputs: ["primaryAction"] }, { kind: "component", type: SciTableColumnsComponent, selector: "sci-table-columns", inputs: ["rows"] }, { kind: "directive", type: SciTableKeyboardNavigatorDirective, selector: "[sciTableKeyboardNavigator]" }, { kind: "directive", type: SciAttributesDirective, selector: "[sciAttributes]", inputs: ["sciAttributes"] }, { kind: "component", type: SciScrollbarComponent, selector: "sci-scrollbar", inputs: ["direction", "viewport"] }, { kind: "component", type: SciThrobberComponent, selector: "sci-throbber", inputs: ["type"] }, { kind: "component", type: SciIconComponent, selector: "sci-icon" }, { kind: "pipe", type: SciTextPipe, name: "sciText" }], encapsulation: i0.ViewEncapsulation.ShadowDom });
|
|
2218
2290
|
}
|
|
2219
2291
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: SciTableComponent, decorators: [{
|
|
2220
2292
|
type: Component,
|
|
@@ -2238,7 +2310,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
|
|
|
2238
2310
|
], providers: [
|
|
2239
2311
|
provideSciTable(),
|
|
2240
2312
|
SciTableSelectionService,
|
|
2241
|
-
], template: "@let table = this.table();\n\n<sci-table-viewport #viewport>\n <sci-table-grid>\n <!-- Table header -->\n @if (table.showHeader() || table.filterable()) {\n <sci-table-header/>\n }\n\n <!-- Table body -->\n <sci-table-body sciTableKeyboardNavigator>\n @if (!table.error()) {\n <!-- Track index to reuse the table row elements -->\n @for (row of table.rows(); track $index) {\n <sci-table-row [row]=\"row\" (primaryAction)=\"onRowPrimaryAction($event)\" [sciAttributes]=\"row.bindings?.attributes()\"/>\n } @empty {\n <span class=\"message e2e-no-data\">{{('%scion.components.no_items.message' | sciText)()}}</span>\n }\n } @else {\n <span class=\"message e2e-datasource\">\n {{('%scion.components.datasource_error.message' | sciText)()}}\n\n <button (click)=\"onRetry()\" class=\"action e2e-datasource-retry\">\n <!-- TODO [dwi] Replace with SCION icon -->\n <sci-icon>refresh</sci-icon>\n <span>{{('%scion.components.retry.label' | sciText)()}}</span>\n </button>\n </span>\n }\n\n <!-- Render active row outline separately to preserve row border-radius within block selection. -->\n @if (table.activeRow()) {\n <div class=\"active-row-outline e2e-active-row-outline\"></div>\n }\n </sci-table-body>\n\n <!-- Render column splitters. -->\n <sci-table-columns [rows]=\"rows()\"/>\n </sci-table-grid>\n</sci-table-viewport>\n\n<!-- Scrollbars -->\n<sci-scrollbar direction=\"hscroll\" [viewport]=\"viewport.host\"/>\n<sci-scrollbar direction=\"vscroll\" [viewport]=\"viewport.host\"/>\n\n@if (table.loading()) {\n <sci-throbber type=\"spinner\"/>\n}\n\n<!-- Synthetic element to compute the absolute pixel value of the `--sci-table-row-height`, relative to the table's font size if em-based. -->\n<div class=\"synthetic item-size\" #item_size_synthetic_element></div>\n\n<!-- Synthetic element to compute the absolute pixel value of the `--sci-table-cell-padding-inline`, relative to the table's font size if em-based. -->\n<div class=\"synthetic cell-padding\" #cell_padding_synthetic_element></div>\n", styles: ["@charset \"UTF-8\";:host{display:block;overflow:hidden;--\\275sci-table-border-size: 1px;--\\275sci-table-border-color: var(--sci-color-border)}:host:is(:not(:hover):not(:active),:host(:not(:hover):not(:active))) sci-scrollbar:not(.scrolling){opacity:0}:host>sci-table-viewport{display:block;position:relative;height:100%;overflow:auto;scrollbar-width:none;isolation:isolate;box-sizing:border-box;anchor-name:--sci-table-viewport}:host>sci-table-viewport:has(sci-table-header){--\\275sci-table-header-visible: true}:host>sci-table-viewport:has(sci-table-header>sci-column-header){--\\275sci-column-header-visible: true}:host>sci-table-viewport:has(~sci-scrollbar.scrolling){--\\275sci-table-scrolling: true}:host>sci-table-viewport>sci-table-grid{display:grid;grid-template-columns:var(--\\275sci-table-columns, repeat(auto-fit,
|
|
2313
|
+
], template: "@let table = this.table();\n\n<sci-table-viewport #viewport>\n <sci-table-grid>\n <!-- Table header -->\n @if (table.showHeader() || table.filterable()) {\n <sci-table-header/>\n }\n\n <!-- Table body -->\n <sci-table-body sciTableKeyboardNavigator>\n @if (!table.error()) {\n <!-- Track index to reuse the table row elements -->\n @for (row of table.rows(); track $index) {\n <sci-table-row [row]=\"row\" (primaryAction)=\"onRowPrimaryAction($event)\" [sciAttributes]=\"row.bindings?.attributes()\"/>\n } @empty {\n <span class=\"message e2e-no-data\">{{('%scion.components.no_items.message' | sciText)()}}</span>\n }\n } @else {\n <span class=\"message e2e-datasource\">\n {{('%scion.components.datasource_error.message' | sciText)()}}\n\n <button (click)=\"onRetry()\" class=\"action e2e-datasource-retry\">\n <!-- TODO [dwi] Replace with SCION icon -->\n <sci-icon>refresh</sci-icon>\n <span>{{('%scion.components.retry.label' | sciText)()}}</span>\n </button>\n </span>\n }\n\n <!-- Render active row outline separately to preserve row border-radius within block selection. -->\n @if (table.activeRow()) {\n <div class=\"active-row-outline e2e-active-row-outline\"></div>\n }\n </sci-table-body>\n\n <!-- Render column splitters. -->\n <sci-table-columns [rows]=\"rows()\"/>\n </sci-table-grid>\n</sci-table-viewport>\n\n<!-- Scrollbars -->\n<sci-scrollbar direction=\"hscroll\" [viewport]=\"viewport.host\"/>\n<sci-scrollbar direction=\"vscroll\" [viewport]=\"viewport.host\"/>\n\n@if (table.loading()) {\n <sci-throbber type=\"spinner\"/>\n}\n\n<!-- Synthetic element to compute the absolute pixel value of the `--sci-table-row-height`, relative to the table's font size if em-based. -->\n<div class=\"synthetic item-size\" #item_size_synthetic_element></div>\n\n<!-- Synthetic element to compute the absolute pixel value of the `--sci-table-cell-padding-inline`, relative to the table's font size if em-based. -->\n<div class=\"synthetic cell-padding\" #cell_padding_synthetic_element></div>\n", styles: ["@charset \"UTF-8\";:host{display:block;overflow:hidden;--\\275sci-table-border-size: 1px;--\\275sci-table-border-color: var(--sci-color-border)}:host:is(:not(:hover):not(:active),:host(:not(:hover):not(:active))) sci-scrollbar:not(.scrolling){opacity:0}:host>sci-table-viewport{display:block;position:relative;height:100%;overflow:auto;scrollbar-width:none;isolation:isolate;box-sizing:border-box;anchor-name:--sci-table-viewport}:host>sci-table-viewport:has(sci-table-header){--\\275sci-table-header-visible: true}:host>sci-table-viewport:has(sci-table-header>sci-column-header){--\\275sci-column-header-visible: true}:host>sci-table-viewport:has(~sci-scrollbar.scrolling){--\\275sci-table-scrolling: true}:host>sci-table-viewport>sci-table-grid{display:grid;grid-template-columns:var(--\\275sci-table-columns, repeat(auto-fit, 100px)) 0;grid-auto-rows:min-content;grid-template-rows:min-content 1fr;width:min-content;min-width:100%;min-height:100%}@container not style(--\\275sci-table-header-visible: true){:host>sci-table-viewport>sci-table-grid{grid-template-rows:1fr}}:host>sci-table-viewport>sci-table-grid>sci-table-header{z-index:1;grid-row:1;grid-column:1/-1;position:sticky;top:0}:host>sci-table-viewport>sci-table-grid>sci-table-body{anchor-name:--sci-table-body;grid-row:2}@container not style(--\\275sci-table-header-visible: true){:host>sci-table-viewport>sci-table-grid>sci-table-body{grid-row:1}}:host>sci-table-viewport>sci-table-grid>sci-table-body{display:grid;grid-template-columns:subgrid;grid-column:1/-1;grid-auto-rows:var(--sci-table-row-height);outline:none;padding-top:var(--\\275sci-table-virtual-scroll-offset-top);padding-bottom:var(--\\275sci-table-virtual-scroll-offset-bottom)}:host>sci-table-viewport>sci-table-grid>sci-table-body>sci-table-row{grid-column:1/-1}:host>sci-table-viewport>sci-table-grid>sci-table-body>sci-table-row[data-active]{anchor-name:--sci-table-active-row}:host>sci-table-viewport>sci-table-grid>sci-table-body>div.active-row-outline{position:absolute;top:anchor(--sci-table-active-row top);right:anchor(--sci-table-active-row right);bottom:anchor(--sci-table-active-row bottom);left:anchor(--sci-table-active-row left);border:var(--sci-table-row-outline-width) var(--sci-table-row-outline-style) var(--sci-table-row-outline-color);border-radius:var(--sci-table-row-border-radius);pointer-events:none}:host>sci-table-viewport>sci-table-grid>sci-table-body:not(:has(sci-table-row[data-active]))>div.active-row-outline{display:none}:host>sci-table-viewport>sci-table-grid>sci-table-body>span.message{grid-column:1/-1;grid-row:auto/span 2;justify-self:center;align-self:center;display:flex;flex-direction:column;align-items:center;gap:1em;-webkit-user-select:none;user-select:none;white-space:nowrap;color:var(--sci-color-text-subtle)}:host>sci-table-viewport>sci-table-grid>sci-table-body>span.message:has(button.action){grid-row:auto/span 4}:host>sci-table-viewport>sci-table-grid>sci-table-body>span.message>button.action{all:unset;display:inline-grid;place-content:center;place-items:center;padding:.25em;border-radius:var(--sci-button-border-radius);-webkit-user-select:none;user-select:none;overflow:hidden;cursor:var(--sci-button-cursor);--sci-icon-size: var(--sci-button-icon-size)}:host>sci-table-viewport>sci-table-grid>sci-table-body>span.message>button.action:hover:where(:not(:disabled)){background-color:var(--sci-button-background-color-hover)}:host>sci-table-viewport>sci-table-grid>sci-table-body>span.message>button.action:active:where(:not(:disabled)){background-color:var(--sci-button-background-color-active)}:host>sci-table-viewport>sci-table-grid>sci-table-body>span.message>button.action:focus:not(:focus-visible){outline:none}:host>sci-table-viewport>sci-table-grid>sci-table-body>span.message>button.action:focus-visible{outline:var(--sci-button-outline-width) solid var(--sci-color-accent)}:host>sci-table-viewport>sci-table-grid>sci-table-body>span.message>button.action:disabled{color:var(--sci-button-text-color-disabled)}:host>sci-table-viewport>sci-table-grid>sci-table-body>span.message>button.action{border:1px solid var(--sci-color-border);padding:.25em 1em}@container style(--\\275sci-table-viewport-client-width > --\\275sci-table-viewport-width){:host>sci-table-viewport>sci-table-grid>sci-table-body>span.message{position:sticky;left:50%;right:50%;width:0}}:host>sci-table-viewport>sci-table-grid>sci-table-body:has(>span.message){z-index:2}:host>sci-table-viewport>sci-table-grid>sci-table-columns{grid-area:1/1/-1/-1;z-index:1;position:sticky;top:0;max-height:var(--\\275sci-table-viewport-height)}:host>sci-scrollbar{position:absolute}:host>sci-scrollbar[direction=vscroll]{top:calc(anchor(--sci-table-body top) + 2px);right:calc(anchor(--sci-table-viewport right) + 2px);bottom:calc(anchor(--sci-table-viewport bottom) + 2px)}:host>sci-scrollbar[direction=hscroll]{left:calc(anchor(--sci-table-viewport left) + 2px);bottom:calc(anchor(--sci-table-viewport bottom) + 1px);right:calc(anchor(--sci-table-viewport right) + 2px)}@container style(--\\275sci-table-resizing: true){:host>sci-scrollbar{pointer-events:none}}:host>sci-throbber{--sci-throbber-size: 16px;position:absolute;top:calc(anchor(--sci-table-viewport top) + .5em);right:calc(anchor(--sci-table-viewport right) + .5em)}:host>div.synthetic{position:absolute;pointer-events:none;visibility:hidden}:host>div.synthetic.item-size{height:var(--sci-table-row-height)}:host>div.synthetic.cell-padding{width:var(--sci-table-cell-padding-inline)}\n"] }]
|
|
2242
2314
|
}], ctorParameters: () => [], propDecorators: { name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: true }] }], table: [{ type: i0.Input, args: [{ isSignal: true, alias: "table", required: true }] }], primaryAction: [{ type: i0.Output, args: ["primaryAction"] }], _viewport: [{ type: i0.ViewChild, args: [i0.forwardRef(() => SciTableViewportComponent), { ...{ read: ElementRef }, isSignal: true }] }], _viewportClient: [{ type: i0.ViewChild, args: [i0.forwardRef(() => SciTableGridComponent), { ...{ read: ElementRef }, isSignal: true }] }], _tableHeader: [{ type: i0.ViewChild, args: [i0.forwardRef(() => SciTableHeaderComponent), { ...{ read: ElementRef }, isSignal: true }] }], _tableBody: [{ type: i0.ViewChild, args: [i0.forwardRef(() => SciTableBodyComponent), { ...{ read: ElementRef }, isSignal: true }] }], _itemSizeSyntheticElement: [{ type: i0.ViewChild, args: ['item_size_synthetic_element', { isSignal: true }] }], _cellPaddingSyntheticElement: [{ type: i0.ViewChild, args: ['cell_padding_synthetic_element', { isSignal: true }] }], rows: [{ type: i0.ViewChildren, args: [i0.forwardRef(() => SciTableRowComponent), { isSignal: true }] }] } });
|
|
2243
2315
|
function provideSciTable() {
|
|
2244
2316
|
return {
|