@akcelik/strct 5.8.0 → 5.9.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.
|
@@ -14493,7 +14493,7 @@ class StrctDatagrid {
|
|
|
14493
14493
|
const sortRows = (rs) => {
|
|
14494
14494
|
const c = [...rs];
|
|
14495
14495
|
if (key)
|
|
14496
|
-
c.sort((a, b) =>
|
|
14496
|
+
c.sort((a, b) => this.compareRows(a, b, key, sign));
|
|
14497
14497
|
return c;
|
|
14498
14498
|
};
|
|
14499
14499
|
const filtering = this.activeFilters().length > 0 || this.quickTerm() !== '';
|
|
@@ -14527,7 +14527,7 @@ class StrctDatagrid {
|
|
|
14527
14527
|
if (!key)
|
|
14528
14528
|
return data;
|
|
14529
14529
|
const sign = dir === 'asc' ? 1 : -1;
|
|
14530
|
-
return data.sort((a, b) =>
|
|
14530
|
+
return data.sort((a, b) => this.compareRows(a, b, key, sign));
|
|
14531
14531
|
}, /* @ts-ignore */
|
|
14532
14532
|
...(ngDevMode ? [{ debugName: "sorted" }] : /* istanbul ignore next */ []));
|
|
14533
14533
|
paged = computed(() => {
|
|
@@ -14942,6 +14942,12 @@ class StrctDatagrid {
|
|
|
14942
14942
|
this.lazyLoad.emit(state);
|
|
14943
14943
|
});
|
|
14944
14944
|
});
|
|
14945
|
+
// The columns' own `hidden` flags, read once they exist — a required input
|
|
14946
|
+
// is not available in the constructor.
|
|
14947
|
+
effect(() => {
|
|
14948
|
+
const cols = this.columns();
|
|
14949
|
+
untracked(() => this.applyDeclaredHidden(cols));
|
|
14950
|
+
});
|
|
14945
14951
|
// Restore persisted column preferences once, before the first render.
|
|
14946
14952
|
const persisted = this.readPersistedState();
|
|
14947
14953
|
if (persisted)
|
|
@@ -14961,7 +14967,10 @@ class StrctDatagrid {
|
|
|
14961
14967
|
const widths = Object.fromEntries(this.columnWidths());
|
|
14962
14968
|
const hidden = [...this.hiddenColumns()];
|
|
14963
14969
|
const order = this.columnOrder() ?? undefined;
|
|
14964
|
-
|
|
14970
|
+
// A list an operator sorted by Host CPU opened sorted by name again, and
|
|
14971
|
+
// a lazy one asked the server for the wrong order first.
|
|
14972
|
+
const { key: sortKey, dir: sortDir } = this.sort();
|
|
14973
|
+
const st = { widths, hidden, order, sortKey, sortDir };
|
|
14965
14974
|
const key = JSON.stringify(st);
|
|
14966
14975
|
untracked(() => {
|
|
14967
14976
|
if (key === this.lastStateKey)
|
|
@@ -14994,8 +15003,31 @@ class StrctDatagrid {
|
|
|
14994
15003
|
}
|
|
14995
15004
|
applyColumnState(st) {
|
|
14996
15005
|
this.columnWidths.set(new Map(Object.entries(st.widths ?? {}).map(([k, v]) => [k, Number(v)])));
|
|
15006
|
+
if (st.hidden)
|
|
15007
|
+
this.hiddenDecidedByState = true;
|
|
14997
15008
|
this.hiddenColumns.set(new Set(st.hidden ?? []));
|
|
14998
15009
|
this.columnOrder.set(st.order?.length ? [...st.order] : null);
|
|
15010
|
+
if (st.sortKey !== undefined)
|
|
15011
|
+
this.sort.set({ key: st.sortKey, dir: st.sortDir ?? 'asc' });
|
|
15012
|
+
}
|
|
15013
|
+
/** Whether a persisted or bound state has already decided what is hidden. */
|
|
15014
|
+
hiddenDecidedByState = false;
|
|
15015
|
+
/** Whether the columns' own `hidden` flags have been read (once). */
|
|
15016
|
+
declaredHiddenApplied = false;
|
|
15017
|
+
/**
|
|
15018
|
+
* Columns the consumer declared hidden — the default for a column no state
|
|
15019
|
+
* mentions. A list that shows five of twenty columns says so on the columns,
|
|
15020
|
+
* rather than seeding `columnState` and reaching into the library's storage
|
|
15021
|
+
* key to keep from overriding what the operator chose.
|
|
15022
|
+
*/
|
|
15023
|
+
applyDeclaredHidden(cols) {
|
|
15024
|
+
if (this.declaredHiddenApplied || this.hiddenDecidedByState)
|
|
15025
|
+
return;
|
|
15026
|
+
this.declaredHiddenApplied = true;
|
|
15027
|
+
const declared = cols.filter((c) => c.hidden).map((c) => c.key);
|
|
15028
|
+
if (!declared.length)
|
|
15029
|
+
return;
|
|
15030
|
+
this.hiddenColumns.update((set) => new Set([...set, ...declared]));
|
|
14999
15031
|
}
|
|
15000
15032
|
/**
|
|
15001
15033
|
* The grid as CSV: header labels + every non-hidden column, all rows in the
|
|
@@ -15003,17 +15035,32 @@ class StrctDatagrid {
|
|
|
15003
15035
|
*/
|
|
15004
15036
|
toCSV() {
|
|
15005
15037
|
const hidden = this.hiddenColumns();
|
|
15006
|
-
|
|
15038
|
+
// The user's order, as the xlsx export already used: the same grid wrote
|
|
15039
|
+
// its columns two different ways.
|
|
15040
|
+
const cols = this.orderedColumns().filter((c) => !hidden.has(c.key));
|
|
15007
15041
|
const esc = (v) => {
|
|
15008
|
-
|
|
15042
|
+
let s = v == null ? '' : String(v);
|
|
15043
|
+
// A cell that opens with one of these is a formula to a spreadsheet, so
|
|
15044
|
+
// a VM named "=HYPERLINK(…)" ran when the export was opened. A leading
|
|
15045
|
+
// apostrophe is the spreadsheet's own "this is text".
|
|
15046
|
+
if (/^[=+\-@\t\r]/.test(s))
|
|
15047
|
+
s = `'${s}`;
|
|
15009
15048
|
return /[",\n;]/.test(s) ? `"${s.replace(/"/g, '""')}"` : s;
|
|
15010
15049
|
};
|
|
15011
15050
|
const data = this.lazy() ? this.rows() : this.sorted();
|
|
15012
15051
|
return [
|
|
15013
15052
|
cols.map((c) => esc(c.label)).join(','),
|
|
15014
|
-
...data.map((r) => cols.map((c) => esc(r
|
|
15053
|
+
...data.map((r) => cols.map((c) => esc(this.exportValueOf(r, c))).join(',')),
|
|
15015
15054
|
].join('\n');
|
|
15016
15055
|
}
|
|
15056
|
+
/**
|
|
15057
|
+
* What an export writes for a cell: what the column says, else the stored
|
|
15058
|
+
* value. A templated cell shows "2 h 15 m" and stored 8100; without this the
|
|
15059
|
+
* export carries the seconds, an enum code or a bare `true`.
|
|
15060
|
+
*/
|
|
15061
|
+
exportValueOf(row, col) {
|
|
15062
|
+
return col.exportValue ? col.exportValue(row) : row[col.key];
|
|
15063
|
+
}
|
|
15017
15064
|
/**
|
|
15018
15065
|
* The grid as a real .xlsx workbook (dependency-free SpreadsheetML):
|
|
15019
15066
|
* header labels + every non-hidden column in the current order, all rows in
|
|
@@ -15023,7 +15070,7 @@ class StrctDatagrid {
|
|
|
15023
15070
|
const hidden = this.hiddenColumns();
|
|
15024
15071
|
const cols = this.orderedColumns().filter((c) => !hidden.has(c.key));
|
|
15025
15072
|
const data = this.lazy() ? this.rows() : this.sorted();
|
|
15026
|
-
return buildXlsx(cols.map((c) => c.label), data.map((r) => cols.map((c) => r
|
|
15073
|
+
return buildXlsx(cols.map((c) => c.label), data.map((r) => cols.map((c) => this.exportValueOf(r, c))));
|
|
15027
15074
|
}
|
|
15028
15075
|
/** Download the grid as an .xlsx file. */
|
|
15029
15076
|
downloadXLSX(filename = 'datagrid.xlsx') {
|
|
@@ -15273,9 +15320,39 @@ class StrctDatagrid {
|
|
|
15273
15320
|
.filter((r) => !!r);
|
|
15274
15321
|
this.selectionChange.emit([...fresh, ...offData]);
|
|
15275
15322
|
}
|
|
15323
|
+
/**
|
|
15324
|
+
* One row's sort key for a column: what the column says to sort by, else the
|
|
15325
|
+
* stored value. A cell that shows "1.5 TB" sorts as text without this, which
|
|
15326
|
+
* puts it before "900 GB"; a date written by toLocaleString sorts across
|
|
15327
|
+
* days and AM/PM by its characters.
|
|
15328
|
+
*/
|
|
15329
|
+
sortKeyOf(row, col, key) {
|
|
15330
|
+
return col?.sortValue ? col.sortValue(row) : row[key];
|
|
15331
|
+
}
|
|
15332
|
+
/** The column a key belongs to — the comparator and the sort key need it. */
|
|
15333
|
+
columnOf(key) {
|
|
15334
|
+
return this.columns().find((c) => c.key === key);
|
|
15335
|
+
}
|
|
15336
|
+
/** Compare two rows by a column, honouring its comparator and nulls-last. */
|
|
15337
|
+
compareRows(a, b, key, sign) {
|
|
15338
|
+
const col = this.columnOf(key);
|
|
15339
|
+
if (col?.comparator)
|
|
15340
|
+
return sign * col.comparator(a, b);
|
|
15341
|
+
const av = this.sortKeyOf(a, col, key);
|
|
15342
|
+
const bv = this.sortKeyOf(b, col, key);
|
|
15343
|
+
// An unread value is neither the smallest nor the largest: it is not an
|
|
15344
|
+
// answer at all, so it goes last whichever way the column is sorted.
|
|
15345
|
+
const aEmpty = av == null || av === '';
|
|
15346
|
+
const bEmpty = bv == null || bv === '';
|
|
15347
|
+
if (aEmpty || bEmpty)
|
|
15348
|
+
return aEmpty && bEmpty ? 0 : aEmpty ? 1 : -1;
|
|
15349
|
+
return sign * this.compare(av, bv);
|
|
15350
|
+
}
|
|
15276
15351
|
compare(a, b) {
|
|
15277
15352
|
if (typeof a === 'number' && typeof b === 'number')
|
|
15278
15353
|
return a - b;
|
|
15354
|
+
if (a instanceof Date && b instanceof Date)
|
|
15355
|
+
return a.getTime() - b.getTime();
|
|
15279
15356
|
return String(a ?? '').localeCompare(String(b ?? ''), undefined, { numeric: true });
|
|
15280
15357
|
}
|
|
15281
15358
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctDatagrid, deps: [], target: i0.ɵɵFactoryTarget.Component });
|