@fuentis/phoenix-ui 0.0.9-alpha.637 → 0.0.9-alpha.639
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/fesm2022/fuentis-phoenix-ui.mjs +101 -11
- package/fesm2022/fuentis-phoenix-ui.mjs.map +1 -1
- package/index.d.ts +19 -1
- package/package.json +1 -1
|
@@ -2009,6 +2009,8 @@ class TableCaptionComponent {
|
|
|
2009
2009
|
/** Local storage keys */
|
|
2010
2010
|
FILTER_KEY = '';
|
|
2011
2011
|
COLUMN_KEY = '';
|
|
2012
|
+
/** Live subscription to the current filter form; torn down on each rebuild. */
|
|
2013
|
+
filtersValueSub;
|
|
2012
2014
|
/**
|
|
2013
2015
|
* When table detects that selected filter values no longer exist in data,
|
|
2014
2016
|
* it passes the remaining valid values here so table-caption can prune its form.
|
|
@@ -2032,8 +2034,17 @@ class TableCaptionComponent {
|
|
|
2032
2034
|
}
|
|
2033
2035
|
if (!this.tableConfiguration)
|
|
2034
2036
|
return;
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
+
// Storage key: prefer an explicit `stateKey` (unique per table view; avoids
|
|
2038
|
+
// the collisions where `key` doubles as the row-id field, e.g. two tables
|
|
2039
|
+
// sharing `filters_controls`), fall back to `key`. `stateKeyPrefix` (e.g. the
|
|
2040
|
+
// current user id) scopes state per user so a shared machine does not leak
|
|
2041
|
+
// one user's filters/columns to another.
|
|
2042
|
+
const stateBase = this.tableConfiguration.stateKey ?? this.tableConfiguration.key ?? 'table';
|
|
2043
|
+
const statePrefix = this.tableConfiguration.stateKeyPrefix
|
|
2044
|
+
? `${this.tableConfiguration.stateKeyPrefix}.`
|
|
2045
|
+
: '';
|
|
2046
|
+
this.FILTER_KEY = `filters_${statePrefix}${stateBase}`;
|
|
2047
|
+
this.COLUMN_KEY = `columns_${statePrefix}${stateBase}`;
|
|
2037
2048
|
// Default visible columns: all non-hidden columns
|
|
2038
2049
|
this._selectedColumns = (this.columns ?? []).filter((c) => !c?.hidden);
|
|
2039
2050
|
// Restore columns once when config/columns arrive
|
|
@@ -2045,7 +2056,13 @@ class TableCaptionComponent {
|
|
|
2045
2056
|
}
|
|
2046
2057
|
// Normalize filters (backward compatible) before building form
|
|
2047
2058
|
const normalizedFilters = this.normalizeFilters(this.filters);
|
|
2048
|
-
|
|
2059
|
+
// Key the rebuild signature on the storage identity (FILTER_KEY), not just
|
|
2060
|
+
// the table key. Sibling tabs that share the same filter columns (e.g. IT
|
|
2061
|
+
// Systems vs Virtualization) but persist under different stateKeys must
|
|
2062
|
+
// rebuild — and thus re-restore — when switched between while the caption
|
|
2063
|
+
// instance is reused; otherwise the reused form keeps the previous tab's
|
|
2064
|
+
// values and the persisted filter looks lost until a full reload.
|
|
2065
|
+
const signature = this.buildSignature(this.FILTER_KEY, normalizedFilters);
|
|
2049
2066
|
if (signature !== this.lastSignature) {
|
|
2050
2067
|
this.lastSignature = signature;
|
|
2051
2068
|
this.buildFiltersForm(normalizedFilters);
|
|
@@ -2082,19 +2099,34 @@ class TableCaptionComponent {
|
|
|
2082
2099
|
this.filtersForm = fg;
|
|
2083
2100
|
// 1) Restore persisted values (but only valid keys)
|
|
2084
2101
|
this.restoreFilterState(filtersCfg);
|
|
2085
|
-
//
|
|
2086
|
-
|
|
2102
|
+
// An empty `filtersCfg` means the filter options are not built yet (they are
|
|
2103
|
+
// derived from the loaded table data), NOT that the user cleared their
|
|
2104
|
+
// filters. Persisting here would write an empty payload and, via
|
|
2105
|
+
// persistState(), DELETE the saved state before the real config arrives on
|
|
2106
|
+
// the next build — the init-order wipe. Only persist once a real filter
|
|
2107
|
+
// config exists; a genuine "user cleared" is an empty value with a non-empty
|
|
2108
|
+
// config and still persists (and removes) correctly.
|
|
2109
|
+
const hasFilterConfig = filtersCfg.length > 0;
|
|
2110
|
+
// 2) Subscribe with debounce and emit normalized payload.
|
|
2111
|
+
// buildFiltersForm() runs again whenever the filter signature changes (e.g.
|
|
2112
|
+
// range bounds move on a data reload), so tear down the previous form's
|
|
2113
|
+
// subscription first — otherwise they accumulate for the component's whole
|
|
2114
|
+
// lifetime and emit/persist in multiples.
|
|
2115
|
+
this.filtersValueSub?.unsubscribe();
|
|
2116
|
+
this.filtersValueSub = this.filtersForm.valueChanges
|
|
2087
2117
|
.pipe(takeUntilDestroyed(this.dr), debounceTime(120), map((raw) => this.normalizeOutgoingPayload(raw, filtersCfg)))
|
|
2088
2118
|
.subscribe((payload) => {
|
|
2089
2119
|
this.applyFiltersEvent.emit(payload);
|
|
2090
|
-
|
|
2120
|
+
if (hasFilterConfig)
|
|
2121
|
+
this.persistState(payload, this.FILTER_KEY);
|
|
2091
2122
|
});
|
|
2092
2123
|
// 3) Emit initial state (normalized) once
|
|
2093
2124
|
queueMicrotask(() => {
|
|
2094
2125
|
const raw = this.filtersForm.getRawValue();
|
|
2095
2126
|
const payload = this.normalizeOutgoingPayload(raw, filtersCfg);
|
|
2096
2127
|
this.applyFiltersEvent.emit(payload);
|
|
2097
|
-
|
|
2128
|
+
if (hasFilterConfig)
|
|
2129
|
+
this.persistState(payload, this.FILTER_KEY);
|
|
2098
2130
|
});
|
|
2099
2131
|
}
|
|
2100
2132
|
/**
|
|
@@ -3276,7 +3308,14 @@ class TableComponent {
|
|
|
3276
3308
|
}
|
|
3277
3309
|
}
|
|
3278
3310
|
}
|
|
3279
|
-
|
|
3311
|
+
// Re-apply any active filters to the refreshed dataset. Previously this
|
|
3312
|
+
// reset to the full (unfiltered) originalData, so every SSE / reload dropped
|
|
3313
|
+
// the user's active filters until the caption happened to re-emit — the
|
|
3314
|
+
// "filters lost on reload" bug that consumers worked around app-side.
|
|
3315
|
+
this.allData =
|
|
3316
|
+
Object.keys(this.currentFilters).length > 0
|
|
3317
|
+
? this.getFilteredData()
|
|
3318
|
+
: [...this.originalData];
|
|
3280
3319
|
this.lastSortKey = '';
|
|
3281
3320
|
// allow re-applying initial sort for new dataset
|
|
3282
3321
|
this.initialSortApplied = false;
|
|
@@ -3301,8 +3340,16 @@ class TableComponent {
|
|
|
3301
3340
|
if (changes['filters']) {
|
|
3302
3341
|
this.enrichRangeFilters();
|
|
3303
3342
|
}
|
|
3304
|
-
|
|
3305
|
-
|
|
3343
|
+
// Keep the sort key on the same scheme as filters/columns (see
|
|
3344
|
+
// table-caption): honour `stateKey` (fallback `key`) and `stateKeyPrefix`
|
|
3345
|
+
// so sort state neither collides across tables sharing `key` nor leaks
|
|
3346
|
+
// between users on a shared machine.
|
|
3347
|
+
const sortBase = this.tableConfiguration?.stateKey ?? this.tableConfiguration?.key;
|
|
3348
|
+
if (sortBase) {
|
|
3349
|
+
const sortPrefix = this.tableConfiguration?.stateKeyPrefix
|
|
3350
|
+
? `${this.tableConfiguration.stateKeyPrefix}.`
|
|
3351
|
+
: '';
|
|
3352
|
+
this.SORT_KEY = `sort_${sortPrefix}${sortBase}`;
|
|
3306
3353
|
}
|
|
3307
3354
|
// Build columnTypeMap for sorting normalization
|
|
3308
3355
|
if (this.columns?.length > 0) {
|
|
@@ -8480,6 +8527,49 @@ var SimpleButtonType;
|
|
|
8480
8527
|
SimpleButtonType["SPLIT"] = "split";
|
|
8481
8528
|
})(SimpleButtonType || (SimpleButtonType = {}));
|
|
8482
8529
|
|
|
8530
|
+
/**
|
|
8531
|
+
* localStorage key prefixes the data-table persists its per-view UI state under.
|
|
8532
|
+
* Kept in sync with the key scheme in table-caption (filters/columns) and
|
|
8533
|
+
* table.component (sort): `${prefix}${stateKeyPrefix}.${stateKey ?? key}`.
|
|
8534
|
+
*/
|
|
8535
|
+
const TABLE_STATE_PREFIXES = ['filters_', 'columns_', 'sort_'];
|
|
8536
|
+
/**
|
|
8537
|
+
* Remove the data-table's persisted UI state (filters, selected columns, sort)
|
|
8538
|
+
* from localStorage. Call this on logout so a user's saved table views do not
|
|
8539
|
+
* carry over into the next login on a shared machine.
|
|
8540
|
+
*
|
|
8541
|
+
* @param userPrefix When the app persists state user-scoped
|
|
8542
|
+
* (`tableConfiguration.stateKeyPrefix`, e.g. the user id), pass the SAME value
|
|
8543
|
+
* to clear only that user's state — other users' saved views on this browser
|
|
8544
|
+
* stay intact. Omit to clear all persisted table state on this browser.
|
|
8545
|
+
*/
|
|
8546
|
+
function clearPersistedTableState(userPrefix) {
|
|
8547
|
+
let store;
|
|
8548
|
+
try {
|
|
8549
|
+
store = localStorage;
|
|
8550
|
+
}
|
|
8551
|
+
catch {
|
|
8552
|
+
return; // storage disabled / unavailable — nothing to clear
|
|
8553
|
+
}
|
|
8554
|
+
// Scoped keys look like `filters_<userPrefix>.<base>`; the trailing dot makes
|
|
8555
|
+
// the match exact so prefix "1" never also clears user "12"'s state.
|
|
8556
|
+
const scoped = userPrefix ? `${userPrefix}.` : '';
|
|
8557
|
+
const doomed = [];
|
|
8558
|
+
for (let i = 0; i < store.length; i++) {
|
|
8559
|
+
const key = store.key(i);
|
|
8560
|
+
if (!key)
|
|
8561
|
+
continue;
|
|
8562
|
+
for (const p of TABLE_STATE_PREFIXES) {
|
|
8563
|
+
if (key.startsWith(p + scoped)) {
|
|
8564
|
+
doomed.push(key);
|
|
8565
|
+
break;
|
|
8566
|
+
}
|
|
8567
|
+
}
|
|
8568
|
+
}
|
|
8569
|
+
for (const key of doomed)
|
|
8570
|
+
store.removeItem(key);
|
|
8571
|
+
}
|
|
8572
|
+
|
|
8483
8573
|
class StripHtmlSafePipe {
|
|
8484
8574
|
transform(value) {
|
|
8485
8575
|
if (value === null || value === undefined)
|
|
@@ -11284,5 +11374,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
11284
11374
|
* Generated bundle index. Do not edit.
|
|
11285
11375
|
*/
|
|
11286
11376
|
|
|
11287
|
-
export { ActionTypes, ActionsComponent, CardComponent, ContexObjectComponent, ControlType, GroupsFormComponent, InnerHeaderComponent, META_FORM_ASYNC_EXECUTOR, MetaFormButtonsComponent, MetaFormButtonsV2Component, MetaFormComponent, MetaFormFieldV2Component, MetaFormGroupV2Component, MetaFormService, MetaFormV2Component, MetaSubmitValidatorService, ObjectItemDialogComponent, QuickPickComponent, QuickPickSidePanelComponent, SearchBarComponent, ShellComponent, SidebarComponent, SidebarItemComponent, SimpleButtonType, StatusBarComponent, StatusColType, StatusHeaderComponent, StatusTooltipType, TableComponent, TopbarComponent, UserComponent, tableActionType, tableButtonContext, tableButtonFormat, tableColumnType, tableFilterType, tableSelectionType };
|
|
11377
|
+
export { ActionTypes, ActionsComponent, CardComponent, ContexObjectComponent, ControlType, GroupsFormComponent, InnerHeaderComponent, META_FORM_ASYNC_EXECUTOR, MetaFormButtonsComponent, MetaFormButtonsV2Component, MetaFormComponent, MetaFormFieldV2Component, MetaFormGroupV2Component, MetaFormService, MetaFormV2Component, MetaSubmitValidatorService, ObjectItemDialogComponent, QuickPickComponent, QuickPickSidePanelComponent, SearchBarComponent, ShellComponent, SidebarComponent, SidebarItemComponent, SimpleButtonType, StatusBarComponent, StatusColType, StatusHeaderComponent, StatusTooltipType, TableComponent, TopbarComponent, UserComponent, clearPersistedTableState, tableActionType, tableButtonContext, tableButtonFormat, tableColumnType, tableFilterType, tableSelectionType };
|
|
11288
11378
|
//# sourceMappingURL=fuentis-phoenix-ui.mjs.map
|