@openziti/ziti-console-lib 1.7.2 → 1.8.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/assets/styles/global.scss +2 -2
- package/fesm2022/openziti-ziti-console-lib-table-core.mjs +3067 -0
- package/fesm2022/openziti-ziti-console-lib-table-core.mjs.map +1 -0
- package/fesm2022/openziti-ziti-console-lib.mjs +733 -3312
- package/fesm2022/openziti-ziti-console-lib.mjs.map +1 -1
- package/index.d.ts +22 -870
- package/index.d.ts.map +1 -1
- package/package.json +48 -2
- package/table-core/index.d.ts +981 -0
- package/table-core/index.d.ts.map +1 -0
|
@@ -0,0 +1,981 @@
|
|
|
1
|
+
import * as rxjs from 'rxjs';
|
|
2
|
+
import { BehaviorSubject } from 'rxjs';
|
|
3
|
+
import { Router, ActivatedRoute } from '@angular/router';
|
|
4
|
+
import { Location } from '@angular/common';
|
|
5
|
+
import * as i0 from '@angular/core';
|
|
6
|
+
import { Type, OnInit, OnDestroy, EventEmitter, ElementRef, NgZone, AfterViewInit, AfterViewChecked, OnChanges } from '@angular/core';
|
|
7
|
+
import { CdkDragDrop } from '@angular/cdk/drag-drop';
|
|
8
|
+
import { SafeHtml, DomSanitizer } from '@angular/platform-browser';
|
|
9
|
+
import { MatDateRangePicker } from '@angular/material/datepicker';
|
|
10
|
+
|
|
11
|
+
type FilterObj = {
|
|
12
|
+
filterName: string;
|
|
13
|
+
columnId: string;
|
|
14
|
+
value: any;
|
|
15
|
+
label: string;
|
|
16
|
+
type?: string;
|
|
17
|
+
hidden?: boolean;
|
|
18
|
+
verb?: string;
|
|
19
|
+
};
|
|
20
|
+
declare class DataTableFilterService {
|
|
21
|
+
private location;
|
|
22
|
+
private router;
|
|
23
|
+
private activatedRoute;
|
|
24
|
+
filters: FilterObj[];
|
|
25
|
+
currentPage: number;
|
|
26
|
+
/** Rows requested per page. Defaults to the legacy page size; the list-table's
|
|
27
|
+
* rows-per-page control changes it via {@link changePageSize}. */
|
|
28
|
+
pageSize: number;
|
|
29
|
+
filtersChanged: BehaviorSubject<FilterObj[]>;
|
|
30
|
+
filtering: BehaviorSubject<boolean>;
|
|
31
|
+
pageChanged: BehaviorSubject<any>;
|
|
32
|
+
pageSizeChanged: BehaviorSubject<number>;
|
|
33
|
+
currentQueryParams: any[];
|
|
34
|
+
private static readonly URL_FILTER_PREFIX;
|
|
35
|
+
constructor(location: Location, router: Router, activatedRoute: ActivatedRoute);
|
|
36
|
+
updateFilter(filterObj: FilterObj): void;
|
|
37
|
+
removeFilter(filterObj: FilterObj): void;
|
|
38
|
+
getFilterString(key: string): string;
|
|
39
|
+
changePage(page: any): void;
|
|
40
|
+
changePageSize(size: number): void;
|
|
41
|
+
clearFilters(): void;
|
|
42
|
+
/**
|
|
43
|
+
* Remove every active filter (the toolbar/empty-state "clear filters" action).
|
|
44
|
+
* clearFilters() above re-reads the URL and so is really a load-time sync; this one
|
|
45
|
+
* passes the active filters to updateUrlParameters so they are dropped from the URL
|
|
46
|
+
* and storage instead of being restored, then emits the now-empty list.
|
|
47
|
+
*/
|
|
48
|
+
clearAllFilters(): void;
|
|
49
|
+
storeFilters(): void;
|
|
50
|
+
getStoredFilters(): any;
|
|
51
|
+
updateUrlParameters(filtersToRemove?: any[]): void;
|
|
52
|
+
getUrlFiltersMap(): any;
|
|
53
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<DataTableFilterService, never>;
|
|
54
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<DataTableFilterService>;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
type ListSortDir = 'asc' | 'desc' | undefined;
|
|
58
|
+
/**
|
|
59
|
+
* Context handed to component-cell input mappers.
|
|
60
|
+
*/
|
|
61
|
+
interface ListCellContext<T = any> {
|
|
62
|
+
row: T;
|
|
63
|
+
value: any;
|
|
64
|
+
colId: string;
|
|
65
|
+
rowIndex: number;
|
|
66
|
+
/** Emit a row action (flows to the table's `actionRequested` → the page handler). */
|
|
67
|
+
emitAction: (action: string, item?: any) => void;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Shim shape passed to legacy `cellHtml` / `valueFormatter` functions so the existing
|
|
71
|
+
* ag-grid-era renderer bodies (which read `row.data`, `row.column.colId`, `row.value`)
|
|
72
|
+
* keep working unchanged.
|
|
73
|
+
*/
|
|
74
|
+
interface ListLegacyCellShim {
|
|
75
|
+
data: any;
|
|
76
|
+
value?: any;
|
|
77
|
+
column: {
|
|
78
|
+
colId: string;
|
|
79
|
+
};
|
|
80
|
+
rowIndex?: number;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Declarative column definition for {@link ListTableComponent}. Replaces the ag-grid
|
|
84
|
+
* `ColDef` shape used by the legacy `lib-data-table`. Rendering precedence for a cell is:
|
|
85
|
+
* `cell` (a component) > `cellHtml` (sanitized markup) > `valueFormatter` (plain text) >
|
|
86
|
+
* the raw value at `field`.
|
|
87
|
+
*/
|
|
88
|
+
interface ListColumn<T = any> {
|
|
89
|
+
/** Stable column id (was ag-grid `colId`). Used for persistence + tracking. */
|
|
90
|
+
key: string;
|
|
91
|
+
/** Dot-path used to read the raw value from a row. Defaults to `key`. */
|
|
92
|
+
field?: string;
|
|
93
|
+
/** Header label (was ag-grid `headerName`). */
|
|
94
|
+
label: string;
|
|
95
|
+
/** Component class rendered in each cell, hosted via NgComponentOutlet. */
|
|
96
|
+
cell?: Type<any>;
|
|
97
|
+
/** Maps a row to the `@Input()`s of the `cell` component. */
|
|
98
|
+
cellInputs?: (ctx: ListCellContext<T>) => Record<string, unknown>;
|
|
99
|
+
/** Returns sanitized HTML for the cell (legacy string renderers). */
|
|
100
|
+
cellHtml?: (shim: ListLegacyCellShim) => string;
|
|
101
|
+
/** Returns plain text for the cell. */
|
|
102
|
+
valueFormatter?: (shim: ListLegacyCellShim) => string;
|
|
103
|
+
/** Initial width in px. Omit to let the column flex to fill available space. */
|
|
104
|
+
width?: number;
|
|
105
|
+
minWidth?: number;
|
|
106
|
+
/** Defaults to true. */
|
|
107
|
+
resizable?: boolean;
|
|
108
|
+
/** Extra class(es) applied to every cell in the column. */
|
|
109
|
+
cellClass?: string;
|
|
110
|
+
sortable?: boolean;
|
|
111
|
+
/** Convenience flag mirrored from legacy `headerComponentParams.enableSorting`. */
|
|
112
|
+
enableSorting?: boolean;
|
|
113
|
+
sortDir?: ListSortDir;
|
|
114
|
+
/** Called on header sort click with the resolved direction (was `sortColumn`). */
|
|
115
|
+
onSort?: (colId: string, dir: ListSortDir) => void;
|
|
116
|
+
/** Called on cell click (was ag-grid `onCellClicked`). */
|
|
117
|
+
onCellClick?: (ctx: ListCellContext<T>) => void;
|
|
118
|
+
filterType?: 'TEXTINPUT' | 'SELECT' | 'COMBO' | 'DATETIME' | 'ATTRIBUTE' | 'MULTISELECT' | 'CUSTOM' | string;
|
|
119
|
+
/** API field the filter queries. Defaults to `field` then `key`. Use when the
|
|
120
|
+
* display field differs from the filterable field (e.g. key `os` → `envInfo.os`,
|
|
121
|
+
* key `type` (display `type.name`) → `typeId`). */
|
|
122
|
+
filterField?: string;
|
|
123
|
+
/** Placeholder shown in the filter-row control when nothing is selected. */
|
|
124
|
+
filterPlaceholder?: string;
|
|
125
|
+
filterOptions?: any[];
|
|
126
|
+
getFilterOptions?: () => any[];
|
|
127
|
+
/** Extra params for the filter controls (attribute getters, combo options, etc.). */
|
|
128
|
+
headerParams?: Record<string, any>;
|
|
129
|
+
/** Component class rendered as a hover tooltip. */
|
|
130
|
+
tooltip?: Type<any>;
|
|
131
|
+
tooltipInputs?: (ctx: ListCellContext<T>) => Record<string, unknown>;
|
|
132
|
+
/** Defaults to true. When false the column cannot be hidden. */
|
|
133
|
+
hideable?: boolean;
|
|
134
|
+
/** Leave the column out of the Columns menu (it still renders in the table). */
|
|
135
|
+
excludeFromChooser?: boolean;
|
|
136
|
+
/** In tree mode, the column that holds the expand/collapse control and per-level
|
|
137
|
+
* indentation. When no column sets this, the first visible column is used. */
|
|
138
|
+
treeColumn?: boolean;
|
|
139
|
+
/** Defaults to true. When false the column cannot be drag-reordered. */
|
|
140
|
+
reorderable?: boolean;
|
|
141
|
+
/** Initial visibility (was ag-grid `hide`). */
|
|
142
|
+
hidden?: boolean;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Optional base interface for component cells hosted by {@link ListTableComponent}.
|
|
146
|
+
* The table sets whatever `@Input()`s a column's `cellInputs` returns; implementing this
|
|
147
|
+
* is not required but documents the common ones.
|
|
148
|
+
*/
|
|
149
|
+
interface ListCell<T = any> {
|
|
150
|
+
row?: T;
|
|
151
|
+
value?: any;
|
|
152
|
+
}
|
|
153
|
+
/** Nested-row layout: 'card' floats each level as a bordered card, 'flat' renders inline. */
|
|
154
|
+
type TreeVariant = 'card' | 'flat';
|
|
155
|
+
/** Per-control toolbar config. A control shows and is interactive by default; set
|
|
156
|
+
* `show: false` to remove it, or `disabled: true` to keep it visible but greyed out. */
|
|
157
|
+
interface ToolbarControlOptions {
|
|
158
|
+
show?: boolean;
|
|
159
|
+
disabled?: boolean;
|
|
160
|
+
}
|
|
161
|
+
/** Show/hide and enable/disable each control around the table: the bar above it
|
|
162
|
+
* (search, filters, refresh, auto-refresh, columns) and the footer below it
|
|
163
|
+
* (rows-per-page, pagination). */
|
|
164
|
+
interface ListTableToolbarOptions {
|
|
165
|
+
search?: ToolbarControlOptions;
|
|
166
|
+
filters?: ToolbarControlOptions;
|
|
167
|
+
refresh?: ToolbarControlOptions;
|
|
168
|
+
autoRefresh?: ToolbarControlOptions;
|
|
169
|
+
columns?: ToolbarControlOptions;
|
|
170
|
+
pageSize?: ToolbarControlOptions;
|
|
171
|
+
pagination?: ToolbarControlOptions;
|
|
172
|
+
}
|
|
173
|
+
/** Structural options for {@link ListTableComponent}. */
|
|
174
|
+
interface ListTableOptions {
|
|
175
|
+
noSelect?: boolean;
|
|
176
|
+
noMenu?: boolean;
|
|
177
|
+
pager?: 'pages' | 'cursor';
|
|
178
|
+
tree?: boolean;
|
|
179
|
+
/** Tree mode: render checkboxes on nested rows and include them in the selection. */
|
|
180
|
+
selectChildren?: boolean;
|
|
181
|
+
fitColumns?: boolean;
|
|
182
|
+
toolbar?: ListTableToolbarOptions;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Per-instance state + localStorage persistence for {@link ListTableComponent}.
|
|
187
|
+
* Uses its own `lt_<tableId>_*` keys (separate from the legacy ag-grid table) so a
|
|
188
|
+
* first visit starts from the column defs' default widths, not a carried-over ag layout.
|
|
189
|
+
*/
|
|
190
|
+
declare class ListTableService {
|
|
191
|
+
tableId: string;
|
|
192
|
+
/** Coordinates the toolbar dropdowns so only one (filter pill or column chooser)
|
|
193
|
+
* is open at a time. Openers emit themselves; others close when they see an
|
|
194
|
+
* owner that isn't them. */
|
|
195
|
+
private readonly menuOpenedSubject;
|
|
196
|
+
readonly menuOpened$: rxjs.Observable<unknown>;
|
|
197
|
+
notifyMenuOpened(owner: unknown): void;
|
|
198
|
+
private stateKey;
|
|
199
|
+
private widthsKey;
|
|
200
|
+
private pageSizeKey;
|
|
201
|
+
private treeVariantKey;
|
|
202
|
+
/** Returns the saved tree layout ('card' | 'flat'), or `fallback` if none. */
|
|
203
|
+
restoreTreeVariant(fallback: TreeVariant): TreeVariant;
|
|
204
|
+
saveTreeVariant(variant: TreeVariant): void;
|
|
205
|
+
private static pageSizeKeyFor;
|
|
206
|
+
restorePageSize(fallback: number): number;
|
|
207
|
+
savePageSize(size: number): void;
|
|
208
|
+
/** Reads a table's remembered rows-per-page without an instance (for host pre-seeding). */
|
|
209
|
+
static readPersistedPageSize(tableId: string, fallback: number): number;
|
|
210
|
+
/**
|
|
211
|
+
* Returns a shallow-cloned copy of `columns` with any persisted width, visibility,
|
|
212
|
+
* and order applied. Columns not present in the saved state keep their declared
|
|
213
|
+
* position (appended after the saved ones).
|
|
214
|
+
*/
|
|
215
|
+
/** Parses a stored JSON value, or null when missing/unavailable/malformed. */
|
|
216
|
+
private readJson;
|
|
217
|
+
/** Applies a widths map then a persisted order/visibility list onto a fresh copy of
|
|
218
|
+
* `columns`. Shared by the top-level and per-depth restore paths. */
|
|
219
|
+
private mergePersistedColumns;
|
|
220
|
+
/** Order + visibility + width entries for one set of columns. */
|
|
221
|
+
private columnStateEntries;
|
|
222
|
+
applyPersistedState(columns: ListColumn[]): ListColumn[];
|
|
223
|
+
/** Persists the current order + visibility (and widths embedded in each entry). */
|
|
224
|
+
saveState(columns: ListColumn[]): void;
|
|
225
|
+
private childStateKey;
|
|
226
|
+
private childWidthsKey;
|
|
227
|
+
/** Applies persisted order/visibility/width for one nested depth to its columns. */
|
|
228
|
+
applyPersistedChildState(level: number, columns: ListColumn[]): ListColumn[];
|
|
229
|
+
saveChildState(level: number, columns: ListColumn[]): void;
|
|
230
|
+
saveChildWidth(level: number, colId: string, width: number, columns: ListColumn[]): void;
|
|
231
|
+
/** Persists a single column's width, then rewrites the ordered state. */
|
|
232
|
+
saveWidth(colId: string, width: number, columns: ListColumn[]): void;
|
|
233
|
+
/** Clears all persisted layout for this table ("Restore Default Table"). */
|
|
234
|
+
reset(): void;
|
|
235
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ListTableService, never>;
|
|
236
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<ListTableService>;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Emits `clickOutside` when a click lands outside the host element. A local,
|
|
241
|
+
* dependency-free standalone replacement for `ng-click-outside`, so the table and
|
|
242
|
+
* its cells can be consumed from the package without pulling an undeclared dependency.
|
|
243
|
+
*
|
|
244
|
+
* The document listener runs outside Angular to avoid a change-detection pass on every
|
|
245
|
+
* click anywhere on the page; the emit re-enters the zone so bound handlers run normally.
|
|
246
|
+
*/
|
|
247
|
+
declare class ClickOutsideDirective implements OnInit, OnDestroy {
|
|
248
|
+
private el;
|
|
249
|
+
private ngZone;
|
|
250
|
+
private platformId;
|
|
251
|
+
clickOutside: EventEmitter<Event>;
|
|
252
|
+
constructor(el: ElementRef, ngZone: NgZone, platformId: Object);
|
|
253
|
+
ngOnInit(): void;
|
|
254
|
+
ngOnDestroy(): void;
|
|
255
|
+
private onDocumentClick;
|
|
256
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ClickOutsideDirective, never>;
|
|
257
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<ClickOutsideDirective, "[clickOutside]", never, {}, { "clickOutside": "clickOutside"; }, never, never, true, never>;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* A single row in a {@link ListMenuComponent}.
|
|
262
|
+
*
|
|
263
|
+
* `action` is the identifier the host dispatches on; `data` carries the original
|
|
264
|
+
* domain object (menu item / header action / filter option) so the host can act
|
|
265
|
+
* on it without the menu needing to know its shape.
|
|
266
|
+
*/
|
|
267
|
+
interface ListMenuItem {
|
|
268
|
+
/** Visible text. */
|
|
269
|
+
label: string;
|
|
270
|
+
/** Identifier emitted back to the host on click. */
|
|
271
|
+
action: string;
|
|
272
|
+
/** Optional icon class(es) rendered before the label. */
|
|
273
|
+
icon?: string;
|
|
274
|
+
/** Optional sanitized SVG rendered before the label (takes precedence over `icon`). */
|
|
275
|
+
iconSvg?: SafeHtml;
|
|
276
|
+
/** When true the row is present but visually removed (keeps list order stable). */
|
|
277
|
+
hidden?: boolean;
|
|
278
|
+
/** When true the row is shown but not clickable. */
|
|
279
|
+
disabled?: boolean;
|
|
280
|
+
/** Optional element id (preserves existing automation hooks). */
|
|
281
|
+
id?: string;
|
|
282
|
+
/** Original domain object this row was built from. */
|
|
283
|
+
data?: any;
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Generic, theme-driven action menu popover. Presentational only: the host owns
|
|
287
|
+
* open state and position and handles `(itemClick)` / `(closed)`.
|
|
288
|
+
*/
|
|
289
|
+
declare class ListMenuComponent {
|
|
290
|
+
/** Whether the menu is rendered. */
|
|
291
|
+
open: boolean;
|
|
292
|
+
/** Rows to render. */
|
|
293
|
+
items: ListMenuItem[];
|
|
294
|
+
/** Fixed-position left offset (px). */
|
|
295
|
+
left: number;
|
|
296
|
+
/** Fixed-position top offset (px). */
|
|
297
|
+
top: number;
|
|
298
|
+
/** Optional id for the menu container (automation hook). */
|
|
299
|
+
menuId?: string;
|
|
300
|
+
/** Emitted when a clickable row is selected. */
|
|
301
|
+
itemClick: EventEmitter<{
|
|
302
|
+
item: ListMenuItem;
|
|
303
|
+
event: MouseEvent;
|
|
304
|
+
}>;
|
|
305
|
+
/** Emitted when the user clicks outside the open menu. */
|
|
306
|
+
closed: EventEmitter<Event>;
|
|
307
|
+
onItem(item: ListMenuItem, event: MouseEvent): void;
|
|
308
|
+
onClickOutside(event: Event): void;
|
|
309
|
+
trackItem: (_: number, item: ListMenuItem) => string;
|
|
310
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ListMenuComponent, never>;
|
|
311
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<ListMenuComponent, "lib-list-menu", never, { "open": { "alias": "open"; "required": false; }; "items": { "alias": "items"; "required": false; }; "left": { "alias": "left"; "required": false; }; "top": { "alias": "top"; "required": false; }; "menuId": { "alias": "menuId"; "required": false; }; }, { "itemClick": "itemClick"; "closed": "closed"; }, never, never, true, never>;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Custom, token-skinnable list table. Columns are declared with {@link ListColumn};
|
|
316
|
+
* sort, filter, and pagination flow through {@link DataTableFilterService}.
|
|
317
|
+
*/
|
|
318
|
+
declare class ListTableComponent implements OnInit, AfterViewInit, AfterViewChecked, OnDestroy {
|
|
319
|
+
svc: ListTableService;
|
|
320
|
+
private tableFilterService;
|
|
321
|
+
private el;
|
|
322
|
+
private ngZone;
|
|
323
|
+
private sanitizer;
|
|
324
|
+
set tableId(id: string);
|
|
325
|
+
get tableId(): string;
|
|
326
|
+
private _tableId;
|
|
327
|
+
set columns(value: ListColumn[]);
|
|
328
|
+
set rowData(value: any[]);
|
|
329
|
+
get rowData(): any[];
|
|
330
|
+
private _rowData;
|
|
331
|
+
set isLoading(value: boolean);
|
|
332
|
+
get isLoading(): boolean;
|
|
333
|
+
private _isLoading;
|
|
334
|
+
/** Placeholder rows drawn during the first load, before any data has arrived. */
|
|
335
|
+
skeletonRowCount: number;
|
|
336
|
+
/** True once the table has shown real rows at least once, so a later load shows the
|
|
337
|
+
* refresh bar over the existing rows instead of the full-page skeleton again. */
|
|
338
|
+
hasLoadedOnce: boolean;
|
|
339
|
+
/** The logical "first load with nothing on screen yet" state. The skeleton renders
|
|
340
|
+
* off showSkeleton (below), which debounces this so a very fast first load goes
|
|
341
|
+
* straight to rows without a skeleton flash. */
|
|
342
|
+
get isInitialLoad(): boolean;
|
|
343
|
+
/** Whether the skeleton placeholder is visible. Debounced from isInitialLoad with the
|
|
344
|
+
* same show-delay as the refresh bar: a first load shorter than REFRESH_SHOW_DELAY
|
|
345
|
+
* never shows it. Unlike the bar there is no minimum-visible hold, so real rows
|
|
346
|
+
* replace the skeleton the moment they arrive. */
|
|
347
|
+
showSkeleton: boolean;
|
|
348
|
+
private skeletonShowTimer;
|
|
349
|
+
private updateSkeleton;
|
|
350
|
+
/** Whether the thin top refresh bar is visible. Debounced from isLoading via
|
|
351
|
+
* updateRefreshBar rather than read straight off it. */
|
|
352
|
+
showRefreshBar: boolean;
|
|
353
|
+
private readonly REFRESH_SHOW_DELAY;
|
|
354
|
+
private readonly REFRESH_MIN_VISIBLE;
|
|
355
|
+
private refreshShowTimer;
|
|
356
|
+
private refreshHideTimer;
|
|
357
|
+
private refreshShownAt;
|
|
358
|
+
private updateRefreshBar;
|
|
359
|
+
/** Row indexes for the skeleton loop (at least one). */
|
|
360
|
+
get skeletonRows(): number[];
|
|
361
|
+
private readonly SK_WIDTHS;
|
|
362
|
+
/** Skeleton bar width (as a %) for a given column/row, varied but stable. */
|
|
363
|
+
skeletonBarWidth(colIndex: number, rowIndex: number): number;
|
|
364
|
+
set options(value: ListTableOptions);
|
|
365
|
+
get options(): ListTableOptions;
|
|
366
|
+
private _options;
|
|
367
|
+
/** Resolved show/disabled state for each toolbar control, read by the template.
|
|
368
|
+
* Every control shows and is enabled unless the host's `options.toolbar` says otherwise. */
|
|
369
|
+
toolbarControls: {
|
|
370
|
+
search: {
|
|
371
|
+
show: boolean;
|
|
372
|
+
disabled: boolean;
|
|
373
|
+
};
|
|
374
|
+
filters: {
|
|
375
|
+
show: boolean;
|
|
376
|
+
disabled: boolean;
|
|
377
|
+
};
|
|
378
|
+
refresh: {
|
|
379
|
+
show: boolean;
|
|
380
|
+
disabled: boolean;
|
|
381
|
+
};
|
|
382
|
+
autoRefresh: {
|
|
383
|
+
show: boolean;
|
|
384
|
+
disabled: boolean;
|
|
385
|
+
};
|
|
386
|
+
columns: {
|
|
387
|
+
show: boolean;
|
|
388
|
+
disabled: boolean;
|
|
389
|
+
};
|
|
390
|
+
pageSize: {
|
|
391
|
+
show: boolean;
|
|
392
|
+
disabled: boolean;
|
|
393
|
+
};
|
|
394
|
+
pagination: {
|
|
395
|
+
show: boolean;
|
|
396
|
+
disabled: boolean;
|
|
397
|
+
};
|
|
398
|
+
};
|
|
399
|
+
private normalizeToolbar;
|
|
400
|
+
/** Tree mode: fetch a row's children the first time it is expanded. Return the
|
|
401
|
+
* child rows (any shape the columns render). A row with `leaf: true`, or one that
|
|
402
|
+
* resolves to an empty array, shows no expand control.
|
|
403
|
+
* Note: tree runtime state (`children`, `leaf`, `__tree*`) is written onto the row
|
|
404
|
+
* objects, so a host that reuses a row in a save call should strip it first. */
|
|
405
|
+
loadChildren?: (row: any) => Promise<any[]> | any[];
|
|
406
|
+
/** Tree mode: columns per depth level (index = level; level 0 uses `columns`).
|
|
407
|
+
* Nested rows render in their own grid with a per-level sub-header, so children
|
|
408
|
+
* need not match the parent. Unset renders children with the parent's columns.
|
|
409
|
+
* The bound value is the default; users can show/hide/reorder/resize child columns
|
|
410
|
+
* per depth from the Columns menu, persisted per table. */
|
|
411
|
+
set childColumnsByLevel(v: ListColumn[][] | undefined);
|
|
412
|
+
get childColumnsByLevel(): ListColumn[][] | undefined;
|
|
413
|
+
private _declaredChildColumnsByLevel?;
|
|
414
|
+
private _childColumnsByLevel?;
|
|
415
|
+
private _childLevelCache;
|
|
416
|
+
private _childColsVersion;
|
|
417
|
+
private _childLevelCacheVersion;
|
|
418
|
+
private _treeKeyCache;
|
|
419
|
+
private _leadOffsetCache;
|
|
420
|
+
private _treeMemoVersion;
|
|
421
|
+
private invalidateColumnCache;
|
|
422
|
+
private syncTreeMemo;
|
|
423
|
+
/** Rebuilds the effective per-level child columns from the declared defaults with
|
|
424
|
+
* any persisted order/visibility/width applied. */
|
|
425
|
+
private buildChildColumns;
|
|
426
|
+
nodeToggled: EventEmitter<{
|
|
427
|
+
row: any;
|
|
428
|
+
expanded: boolean;
|
|
429
|
+
}>;
|
|
430
|
+
hasNext: boolean;
|
|
431
|
+
hasPrev: boolean;
|
|
432
|
+
startCount: any;
|
|
433
|
+
endCount: any;
|
|
434
|
+
totalCount: any;
|
|
435
|
+
filterApplied: boolean;
|
|
436
|
+
menuItems: any[];
|
|
437
|
+
headerActions: any[];
|
|
438
|
+
/** @deprecated kept for the old lib-no-items bindings; the new empty state uses line glyphs, not images. */
|
|
439
|
+
noItemsImage: string;
|
|
440
|
+
showNoItemsAdd: boolean;
|
|
441
|
+
noItemsReadonly: boolean;
|
|
442
|
+
/** Primary create label shown on the first-use empty state (else the per-entity default). */
|
|
443
|
+
createLabel: string;
|
|
444
|
+
/** What these rows belong to, used in the empty headline ("This network has no services").
|
|
445
|
+
* Defaults to 'network' since the Ziti pages are network-scoped; set '' for a list that is not. */
|
|
446
|
+
emptyScope: string;
|
|
447
|
+
accessDenied: boolean;
|
|
448
|
+
entityTypeName: string;
|
|
449
|
+
filterName: string;
|
|
450
|
+
filterColumn: string;
|
|
451
|
+
actionRequested: EventEmitter<{
|
|
452
|
+
action: string;
|
|
453
|
+
item?: any;
|
|
454
|
+
}>;
|
|
455
|
+
tableReady: EventEmitter<any>;
|
|
456
|
+
/** Full set of selected rows (all depths) whenever the selection changes. */
|
|
457
|
+
selectionChanged: EventEmitter<any[]>;
|
|
458
|
+
/** The row the pointer is over, or null when it leaves. Emitted once per row (at the
|
|
459
|
+
* row level, not per cell) so consumers can react to the whole hovered row, for
|
|
460
|
+
* example to highlight that row's path in a connected diagram. */
|
|
461
|
+
rowHover: EventEmitter<any>;
|
|
462
|
+
contextMenu?: ElementRef;
|
|
463
|
+
filterZone?: ElementRef<HTMLElement>;
|
|
464
|
+
filtersRow?: ElementRef<HTMLElement>;
|
|
465
|
+
/** Full column list (includes hidden), after persisted state. */
|
|
466
|
+
allColumns: ListColumn[];
|
|
467
|
+
/** Currently rendered columns (visible + ordered). */
|
|
468
|
+
visibleColumns: ListColumn[];
|
|
469
|
+
/** Hidden columns, shaped for the shared hidden-columns bar (`headerName`). */
|
|
470
|
+
hiddenColumns: any[];
|
|
471
|
+
entityTypeLabel: string;
|
|
472
|
+
openMenu: boolean;
|
|
473
|
+
openHeaderMenu: boolean;
|
|
474
|
+
menuLeft: number;
|
|
475
|
+
menuTop: number;
|
|
476
|
+
selectedItem: any;
|
|
477
|
+
allToggled: boolean;
|
|
478
|
+
/** Rows actually rendered: in tree mode this is the roots plus the expanded
|
|
479
|
+
* descendants in order; otherwise it is `rowData` unchanged. */
|
|
480
|
+
flatRows: any[];
|
|
481
|
+
/** Tree look: 'card' floats each nested level as a bordered card; 'flat' renders
|
|
482
|
+
* nested rows inline with the table, sub-headers as plain strips, no card chrome.
|
|
483
|
+
* The bound value is the default; the user can switch it from the Columns menu and
|
|
484
|
+
* the choice is remembered per table. */
|
|
485
|
+
set treeVariant(v: TreeVariant);
|
|
486
|
+
get treeVariant(): TreeVariant;
|
|
487
|
+
private _treeVariant;
|
|
488
|
+
private _declaredTreeVariant;
|
|
489
|
+
/** Show the flat/nested row-layout switch in the Columns menu. Hidden for now;
|
|
490
|
+
* the variant still comes from the `treeVariant` input. */
|
|
491
|
+
showTreeVariantToggle: boolean;
|
|
492
|
+
/** Flat variant only: draw a running guide rail down the left of each nested level. */
|
|
493
|
+
treeRail: boolean;
|
|
494
|
+
get isFlatTree(): boolean;
|
|
495
|
+
/** Show the flat/nested switch only when the table actually renders nested rows. */
|
|
496
|
+
get canSwitchTreeVariant(): boolean;
|
|
497
|
+
setTreeVariant(variant: TreeVariant): void;
|
|
498
|
+
readonly treeIndentRem = 1.25;
|
|
499
|
+
readonly treeDeepAlignRem = 0.625;
|
|
500
|
+
readonly treeFlatBaseRem = 3.75;
|
|
501
|
+
readonly treeFlatStepRem = 2.125;
|
|
502
|
+
readonly treeCardBaseRem = 4;
|
|
503
|
+
readonly treeSelectColRem = 2.25;
|
|
504
|
+
showColumnChooser: boolean;
|
|
505
|
+
searchString: string;
|
|
506
|
+
activeFilters: FilterObj[];
|
|
507
|
+
filtering: boolean;
|
|
508
|
+
private inputChangedDebounced;
|
|
509
|
+
visibleFilterColumns: ListColumn[];
|
|
510
|
+
overflowFilterColumns: ListColumn[];
|
|
511
|
+
showFilterOverflow: boolean;
|
|
512
|
+
private filterWidths;
|
|
513
|
+
private filtersDirty;
|
|
514
|
+
private filterRO?;
|
|
515
|
+
private observedToolbar?;
|
|
516
|
+
private overflowRaf;
|
|
517
|
+
private readonly FILTER_GAP;
|
|
518
|
+
private readonly MORE_BTN_W;
|
|
519
|
+
private resizing?;
|
|
520
|
+
private readonly onPointerMove;
|
|
521
|
+
private readonly onPointerUp;
|
|
522
|
+
private _rawColumns;
|
|
523
|
+
private _initialColumns;
|
|
524
|
+
private _initialized;
|
|
525
|
+
private subscription;
|
|
526
|
+
private _expandedKeys;
|
|
527
|
+
private _childrenCache;
|
|
528
|
+
private _destroyed;
|
|
529
|
+
constructor(svc: ListTableService, tableFilterService: DataTableFilterService, el: ElementRef, ngZone: NgZone, sanitizer: DomSanitizer);
|
|
530
|
+
ngOnInit(): void;
|
|
531
|
+
ngAfterViewInit(): void;
|
|
532
|
+
ngAfterViewChecked(): void;
|
|
533
|
+
ngOnDestroy(): void;
|
|
534
|
+
get showTable(): boolean;
|
|
535
|
+
/** Columns surfaced as inline filter controls in the toolbar. Text filters are
|
|
536
|
+
* excluded because the free-text search box already covers the primary text field. */
|
|
537
|
+
get filterableColumns(): ListColumn[];
|
|
538
|
+
/** A filter column is "active" when it has an applied filter. */
|
|
539
|
+
isFilterActive(col: ListColumn): boolean;
|
|
540
|
+
/** Applied filters that are currently hidden in the overflow dropdown. */
|
|
541
|
+
get hiddenActiveCount(): number;
|
|
542
|
+
toggleFilterOverflow(event: MouseEvent): void;
|
|
543
|
+
closeFilterOverflow(event?: Event): void;
|
|
544
|
+
private ensureFilterResizeObserver;
|
|
545
|
+
private scheduleFilterOverflow;
|
|
546
|
+
private recomputeFilterOverflow;
|
|
547
|
+
/** Split filter controls into inline vs. overflow, pinning active filters and
|
|
548
|
+
* dropping inactive (then, only if forced, active) from the right until they fit. */
|
|
549
|
+
private applyFilterSplit;
|
|
550
|
+
private buildColumns;
|
|
551
|
+
private updateVisible;
|
|
552
|
+
trackRow: (index: number, row: any) => any;
|
|
553
|
+
trackCol: (index: number, col: ListColumn) => string;
|
|
554
|
+
colWidth(col: ListColumn): string | null;
|
|
555
|
+
private rawValue;
|
|
556
|
+
private cellContext;
|
|
557
|
+
private legacyShim;
|
|
558
|
+
renderMode(col: ListColumn): 'component' | 'html' | 'text';
|
|
559
|
+
cellInputs(col: ListColumn, row: any, i: number): Record<string, unknown>;
|
|
560
|
+
cellHtml(col: ListColumn, row: any, i: number): string;
|
|
561
|
+
cellText(col: ListColumn, row: any, i: number): any;
|
|
562
|
+
cellClass(col: ListColumn): string;
|
|
563
|
+
onCellClick(col: ListColumn, row: any, i: number): void;
|
|
564
|
+
tooltipInputs(col: ListColumn, row: any, i: number): Record<string, unknown>;
|
|
565
|
+
hoverTooltip: {
|
|
566
|
+
component: Type<any>;
|
|
567
|
+
inputs: Record<string, unknown>;
|
|
568
|
+
left: number;
|
|
569
|
+
top: number;
|
|
570
|
+
} | null;
|
|
571
|
+
onCellHover(col: ListColumn, row: any, i: number, event: MouseEvent): void;
|
|
572
|
+
onCellLeave(): void;
|
|
573
|
+
/** The row currently under the pointer, so we only emit when it actually changes. */
|
|
574
|
+
private hoveredRow;
|
|
575
|
+
onRowHover(row: any): void;
|
|
576
|
+
onRowLeave(row: any): void;
|
|
577
|
+
/** True when nested rows get checkboxes and join the selection (opt-in). */
|
|
578
|
+
get childSelectEnabled(): boolean;
|
|
579
|
+
/** Rows the checkboxes and select-all act on: top-level only, unless selectChildren
|
|
580
|
+
* is set. Keeps select-all from marking nested rows a host that reads rowData never sees. */
|
|
581
|
+
private get selectableRows();
|
|
582
|
+
toggleItem: (item: any) => void;
|
|
583
|
+
/** Some rows selected but the header select-all isn't fully on (indeterminate). */
|
|
584
|
+
get someSelected(): boolean;
|
|
585
|
+
toggleAll(): void;
|
|
586
|
+
private syncSelectAll;
|
|
587
|
+
/** Emit every selected row across all depths. Walks the full data, not just the rendered
|
|
588
|
+
* rows, so a collapsed parent's selected children are still reported. */
|
|
589
|
+
private emitSelection;
|
|
590
|
+
get isTreeMode(): boolean;
|
|
591
|
+
/** True when per-level child columns are configured (children render in their own
|
|
592
|
+
* grid with a sub-header rather than the parent's columns). */
|
|
593
|
+
get hasChildColumns(): boolean;
|
|
594
|
+
/** Columns used at a given depth: level 0 is the main (visible) columns; deeper
|
|
595
|
+
* levels use `childColumnsByLevel`, falling back to the deepest set defined. */
|
|
596
|
+
columnsForLevel(level: number): ListColumn[];
|
|
597
|
+
/** Child columns the chooser lists at a depth: all declared ones (including hidden),
|
|
598
|
+
* minus structural columns like the select checkbox or row-actions gutter. */
|
|
599
|
+
allColumnsForLevel(level: number): ListColumn[];
|
|
600
|
+
/** Depths that offer configurable columns (skips the level-0 placeholder and any
|
|
601
|
+
* level that only holds structural columns), one chooser group per level. */
|
|
602
|
+
get childLevels(): number[];
|
|
603
|
+
/** Chooser hint for a nested level: its first few column labels, then "+N". */
|
|
604
|
+
childLevelLabel(level: number): string;
|
|
605
|
+
/** Key of the column that carries the expand control + indentation for a column set:
|
|
606
|
+
* the flagged one, else the first real data column (skipping a leading structural
|
|
607
|
+
* column such as a select checkbox the host put at the start). */
|
|
608
|
+
private treeColumnKeyFor;
|
|
609
|
+
treeColumnKeyForLevel(level: number): string | undefined;
|
|
610
|
+
/** Width of the columns before the tree column, used to pull the flat first-column
|
|
611
|
+
* indent back by whatever structural columns (like a select checkbox) sit ahead of
|
|
612
|
+
* it, so its content still lands under the parent row's name. */
|
|
613
|
+
treeLeadOffset(level: number): string;
|
|
614
|
+
isTreeColumn(col: ListColumn, level: number): boolean;
|
|
615
|
+
isTreeCell(col: ListColumn): boolean;
|
|
616
|
+
/** Columns a full-width nested row spans: the data columns plus the select and
|
|
617
|
+
* menu gutters, matching the header's cell count. */
|
|
618
|
+
get treeSpanCount(): number;
|
|
619
|
+
/** Per-level indent (rem); the card variant nudges levels past the first so the edge meets the parent chevron. */
|
|
620
|
+
treeIndentFor(level: number): number;
|
|
621
|
+
/** Flat variant: left pad (rem) of a nested row's first column (sub-header + data),
|
|
622
|
+
* one chevron-width per level so it lines up under the parent row's name. */
|
|
623
|
+
treeFlatFirstIndentRem(level: number): number;
|
|
624
|
+
/** Flat variant: drop the chevron slot for a leaf-only level so values sit under their header. */
|
|
625
|
+
showTreeLead(row: any): boolean;
|
|
626
|
+
/** Left inset (rem) of a nested card at a given depth, matching the td padding. */
|
|
627
|
+
private treeCardLeftRem;
|
|
628
|
+
private _railCache;
|
|
629
|
+
/** Vertical guide lines redrawing each ancestor card's left edge at this row's
|
|
630
|
+
* position, so a card's left border stays continuous where a nested card is
|
|
631
|
+
* inserted between its rows. Returns a stack of 1px background gradients, or null
|
|
632
|
+
* when there is no ancestor to redraw (roots and the first nested level). */
|
|
633
|
+
treeAncestorRails(level: number): string | null;
|
|
634
|
+
private computeAncestorRails;
|
|
635
|
+
gridTemplate(level: number): string;
|
|
636
|
+
private hasChildren;
|
|
637
|
+
/** A row can be expanded unless it is a leaf, has no loaded children, and has no
|
|
638
|
+
* loader left to try. */
|
|
639
|
+
canExpand(row: any): boolean;
|
|
640
|
+
toggleNode(row: any): void;
|
|
641
|
+
private onChildrenLoaded;
|
|
642
|
+
/** Flatten the tree into the ordered render list, tagging each row with its depth.
|
|
643
|
+
* Outside tree mode the render list is `rowData` as-is. */
|
|
644
|
+
private rebuildFlatRows;
|
|
645
|
+
onHeaderSort(event: {
|
|
646
|
+
colId: string;
|
|
647
|
+
dir: ListSortDir;
|
|
648
|
+
}): void;
|
|
649
|
+
showColumn(event: {
|
|
650
|
+
column: any;
|
|
651
|
+
visible: boolean;
|
|
652
|
+
}): void;
|
|
653
|
+
onReorder(event: CdkDragDrop<ListColumn[]>): void;
|
|
654
|
+
resetTableColumns(): void;
|
|
655
|
+
/** Count of columns the user has hidden beyond the defaults (drives the badge).
|
|
656
|
+
* Columns hidden by default don't count, so a fresh/default load shows no badge. */
|
|
657
|
+
get hiddenColumnCount(): number;
|
|
658
|
+
/** True when visibility, order, and width all match the originally declared
|
|
659
|
+
* columns. Width is included so resizing a column alone still enables the
|
|
660
|
+
* reset button; a column with no declared width uses null on both sides so
|
|
661
|
+
* it only counts as changed once the user drags it to a concrete width. */
|
|
662
|
+
get columnsAtDefault(): boolean;
|
|
663
|
+
/** True when every nested level's columns match their declared order/visibility/width. */
|
|
664
|
+
private get childColumnsAtDefault();
|
|
665
|
+
/** True when the column is hidden in the originally declared defaults. */
|
|
666
|
+
isDefaultHidden(col: ListColumn): boolean;
|
|
667
|
+
toggleColumnChooser(event: MouseEvent): void;
|
|
668
|
+
closeColumnChooser(): void;
|
|
669
|
+
private _chooserDragged;
|
|
670
|
+
onChooserDragStarted(): void;
|
|
671
|
+
onChooserDragEnded(): void;
|
|
672
|
+
/** Toggle a column's visibility. `level` undefined targets the top-level columns;
|
|
673
|
+
* a number targets that nested depth's columns. */
|
|
674
|
+
toggleColumnVisible(col: ListColumn, level?: number): void;
|
|
675
|
+
/** True when this is the only visible column at its level, so its toggle is disabled
|
|
676
|
+
* to keep at least one column on screen. */
|
|
677
|
+
isLastVisibleColumn(col: ListColumn, level?: number): boolean;
|
|
678
|
+
/** Columns shown in the top-level Columns menu. */
|
|
679
|
+
get chooserColumns(): ListColumn[];
|
|
680
|
+
/** Reorder columns from a chooser drag. `level` undefined targets the top-level
|
|
681
|
+
* columns; a number targets that nested depth's columns. */
|
|
682
|
+
chooserReorder(event: CdkDragDrop<ListColumn[]>, level?: number): void;
|
|
683
|
+
/** Refresh and persist after a column visibility/order change, routing to the
|
|
684
|
+
* top-level or nested-level persistence as appropriate. */
|
|
685
|
+
private afterColumnChange;
|
|
686
|
+
private nestedChooserOpen;
|
|
687
|
+
isNestedGroupOpen(id: string): boolean;
|
|
688
|
+
toggleNestedGroup(id: string): void;
|
|
689
|
+
startResize(col: ListColumn, event: PointerEvent): void;
|
|
690
|
+
/** Resize a nested row's column. Measures the sub-header cell's current rendered
|
|
691
|
+
* width so a flexible (1fr) column converts to a concrete width before dragging;
|
|
692
|
+
* the grid reflows live because its template reads each column's width. */
|
|
693
|
+
startChildResize(col: ListColumn, level: number, event: PointerEvent): void;
|
|
694
|
+
private handleResizeMove;
|
|
695
|
+
/** fitColumns: pick the sink column and the range the drag may travel, so the column and the sink
|
|
696
|
+
* trade width while every other column stays fixed. No-op (plain resize) when fitColumns is off. */
|
|
697
|
+
private setupFitCompensation;
|
|
698
|
+
/** The column that absorbs a resize: a flexible column first (it is meant to take up slack), else
|
|
699
|
+
* the nearest resizable column that is not the tree column, so indentation never shifts. */
|
|
700
|
+
private pickSink;
|
|
701
|
+
private measuredHeaderWidth;
|
|
702
|
+
private measuredCellWidth;
|
|
703
|
+
private handleResizeEnd;
|
|
704
|
+
private detachResizeListeners;
|
|
705
|
+
openActionMenu: (event: MouseEvent, item: any) => void;
|
|
706
|
+
closeActionMenu: () => void;
|
|
707
|
+
openHeaderActionMenu(event: MouseEvent): void;
|
|
708
|
+
hideMenuItem(menuItem: any, selectedItem: any): boolean;
|
|
709
|
+
closeHeaderActionMenu: () => void;
|
|
710
|
+
/** Restore-default (rotate) icon for the built-in header action. */
|
|
711
|
+
private readonly RESET_TABLE_ICON;
|
|
712
|
+
/** Header action menu rows: the reset action followed by host-provided header actions.
|
|
713
|
+
* A host action's `icon` (SVG markup) is rendered before its label, like the row menu. */
|
|
714
|
+
get headerMenuItems(): ListMenuItem[];
|
|
715
|
+
onHeaderMenuClick(evt: {
|
|
716
|
+
item: ListMenuItem;
|
|
717
|
+
event: MouseEvent;
|
|
718
|
+
}): void;
|
|
719
|
+
/** Row action menu rows, built from `menuItems` against the currently selected row.
|
|
720
|
+
* A menu item's `icon` (SVG markup) is rendered before its label in the menu. */
|
|
721
|
+
get rowMenuItems(): ListMenuItem[];
|
|
722
|
+
onRowMenuClick(evt: {
|
|
723
|
+
item: ListMenuItem;
|
|
724
|
+
event: MouseEvent;
|
|
725
|
+
}): void;
|
|
726
|
+
openCreate(): void;
|
|
727
|
+
/** Clear the search box and every active filter, which drives the host to refetch
|
|
728
|
+
* unfiltered (used by the "no results" empty state's Clear filters action). */
|
|
729
|
+
clearTableFilters(): void;
|
|
730
|
+
onSearchInput(): void;
|
|
731
|
+
private applySearch;
|
|
732
|
+
nextPage(): void;
|
|
733
|
+
prevPage(): void;
|
|
734
|
+
get cursorPager(): boolean;
|
|
735
|
+
get nextDisabled(): boolean;
|
|
736
|
+
get prevDisabled(): boolean;
|
|
737
|
+
pageSizeOptions: number[];
|
|
738
|
+
/** Default rows-per-page when nothing is remembered (the persisted choice wins). */
|
|
739
|
+
initialPageSize: number;
|
|
740
|
+
/** Auto-refresh interval in seconds a page starts the table at (0 = off). This is the
|
|
741
|
+
* hook for a page to default the control on; left at 0, the table behaves as before
|
|
742
|
+
* (off until the user picks an interval). The user's in-session choice is not persisted. */
|
|
743
|
+
autoRefreshSeconds: number;
|
|
744
|
+
get pageSize(): number;
|
|
745
|
+
get currentPageNum(): number;
|
|
746
|
+
get totalPages(): number;
|
|
747
|
+
/** Page numbers to render, with `0` marking a gap ("..."). Shows the first and
|
|
748
|
+
* last page plus a window around the current page so long lists stay compact. */
|
|
749
|
+
get pageWindow(): number[];
|
|
750
|
+
goToPage(page: number): void;
|
|
751
|
+
onPageSizeChange(size: number): void;
|
|
752
|
+
/** Re-fetch the current page (re-emits the page so the host reloads its data). */
|
|
753
|
+
refresh(): void;
|
|
754
|
+
private iconCache;
|
|
755
|
+
private safeIcon;
|
|
756
|
+
private updateEntityTypeLabel;
|
|
757
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ListTableComponent, never>;
|
|
758
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<ListTableComponent, "lib-list-table", never, { "tableId": { "alias": "tableId"; "required": false; }; "columns": { "alias": "columns"; "required": false; }; "rowData": { "alias": "rowData"; "required": false; }; "isLoading": { "alias": "isLoading"; "required": false; }; "skeletonRowCount": { "alias": "skeletonRowCount"; "required": false; }; "options": { "alias": "options"; "required": false; }; "loadChildren": { "alias": "loadChildren"; "required": false; }; "childColumnsByLevel": { "alias": "childColumnsByLevel"; "required": false; }; "hasNext": { "alias": "hasNext"; "required": false; }; "hasPrev": { "alias": "hasPrev"; "required": false; }; "startCount": { "alias": "startCount"; "required": false; }; "endCount": { "alias": "endCount"; "required": false; }; "totalCount": { "alias": "totalCount"; "required": false; }; "filterApplied": { "alias": "filterApplied"; "required": false; }; "menuItems": { "alias": "menuItems"; "required": false; }; "headerActions": { "alias": "headerActions"; "required": false; }; "noItemsImage": { "alias": "noItemsImage"; "required": false; }; "showNoItemsAdd": { "alias": "showNoItemsAdd"; "required": false; }; "noItemsReadonly": { "alias": "noItemsReadonly"; "required": false; }; "createLabel": { "alias": "createLabel"; "required": false; }; "emptyScope": { "alias": "emptyScope"; "required": false; }; "accessDenied": { "alias": "accessDenied"; "required": false; }; "entityTypeName": { "alias": "entityTypeName"; "required": false; }; "filterName": { "alias": "filterName"; "required": false; }; "filterColumn": { "alias": "filterColumn"; "required": false; }; "treeVariant": { "alias": "treeVariant"; "required": false; }; "showTreeVariantToggle": { "alias": "showTreeVariantToggle"; "required": false; }; "treeRail": { "alias": "treeRail"; "required": false; }; "initialPageSize": { "alias": "initialPageSize"; "required": false; }; "autoRefreshSeconds": { "alias": "autoRefreshSeconds"; "required": false; }; }, { "nodeToggled": "nodeToggled"; "actionRequested": "actionRequested"; "tableReady": "tableReady"; "selectionChanged": "selectionChanged"; "rowHover": "rowHover"; }, never, ["[toolbar-filters]", "[empty-state]"], true, never>;
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
/**
|
|
762
|
+
* Row selection toggle for {@link ListTableComponent}. Router / exclusive /
|
|
763
|
+
* reserved / system rows cannot be toggled.
|
|
764
|
+
*/
|
|
765
|
+
declare class SelectCellComponent {
|
|
766
|
+
item: any;
|
|
767
|
+
disableToggle: boolean;
|
|
768
|
+
set row(v: any);
|
|
769
|
+
/** Host callback invoked with the row when a selectable row is toggled. */
|
|
770
|
+
toggleItem: ((item: any) => void) | undefined;
|
|
771
|
+
toggle(item: any): void;
|
|
772
|
+
get tooltip(): string;
|
|
773
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<SelectCellComponent, never>;
|
|
774
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<SelectCellComponent, "lib-select-cell", never, { "row": { "alias": "row"; "required": false; }; "toggleItem": { "alias": "toggleItem"; "required": false; }; }, {}, never, never, true, never>;
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
/** Header cell for {@link ListTableComponent}: label and 3-state sort (asc/desc). */
|
|
778
|
+
declare class ListHeaderCellComponent {
|
|
779
|
+
column: ListColumn;
|
|
780
|
+
sortDir: ListSortDir;
|
|
781
|
+
sortChanged: EventEmitter<{
|
|
782
|
+
colId: string;
|
|
783
|
+
dir: ListSortDir;
|
|
784
|
+
}>;
|
|
785
|
+
get enableSorting(): boolean;
|
|
786
|
+
sort(): void;
|
|
787
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ListHeaderCellComponent, never>;
|
|
788
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<ListHeaderCellComponent, "lib-list-header-cell", never, { "column": { "alias": "column"; "required": false; }; "sortDir": { "alias": "sortDir"; "required": false; }; }, { "sortChanged": "sortChanged"; }, never, never, true, never>;
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
type FilterMode = 'text' | 'single' | 'multi' | 'daterange';
|
|
792
|
+
interface FilterOption {
|
|
793
|
+
label: string;
|
|
794
|
+
value: any;
|
|
795
|
+
/** Optional class(es) to render the option as a colored chip/badge (e.g. Type). */
|
|
796
|
+
chipClass?: string;
|
|
797
|
+
}
|
|
798
|
+
/**
|
|
799
|
+
* A single control in the table's filter row. Renders the right widget for the
|
|
800
|
+
* column's `filterType` (text input / single-select / multi-select / date-range)
|
|
801
|
+
* and pushes changes through {@link DataTableFilterService}, whose value contract the
|
|
802
|
+
* controller query-builder already understands (icontains / = / anyOf() / datetime range).
|
|
803
|
+
*/
|
|
804
|
+
declare class ListFilterCellComponent implements OnInit, OnDestroy {
|
|
805
|
+
private filterService;
|
|
806
|
+
private listSvc;
|
|
807
|
+
column: ListColumn;
|
|
808
|
+
mode: FilterMode;
|
|
809
|
+
options: FilterOption[];
|
|
810
|
+
textValue: string;
|
|
811
|
+
selectedValue: any;
|
|
812
|
+
selectedValues: string[];
|
|
813
|
+
/** In-dropdown search text for the multi-select attribute combo. */
|
|
814
|
+
attrSearch: string;
|
|
815
|
+
/** Match any selected attribute (or) vs every one (and); attribute filters only. */
|
|
816
|
+
attrSemantic: 'AnyOf' | 'AllOf';
|
|
817
|
+
open: boolean;
|
|
818
|
+
menuLeft: number;
|
|
819
|
+
menuTop: number;
|
|
820
|
+
menuWidth: number;
|
|
821
|
+
trigger?: ElementRef<HTMLElement>;
|
|
822
|
+
rangePicker?: MatDateRangePicker<Date>;
|
|
823
|
+
dateRangeStart: Date | null;
|
|
824
|
+
dateRangeEnd: Date | null;
|
|
825
|
+
private sub;
|
|
826
|
+
private textDebounced;
|
|
827
|
+
constructor(filterService: DataTableFilterService, listSvc: ListTableService);
|
|
828
|
+
ngOnInit(): void;
|
|
829
|
+
ngOnDestroy(): void;
|
|
830
|
+
get field(): string;
|
|
831
|
+
get placeholder(): string;
|
|
832
|
+
/** True only for the Ziti role-attribute flavor of multi-select (adds #/@ prefixing). */
|
|
833
|
+
get isAttributeMode(): boolean;
|
|
834
|
+
private resolveMode;
|
|
835
|
+
private resolveOptions;
|
|
836
|
+
private labelForValue;
|
|
837
|
+
/** Short display of the current selection, shown after the field label when set. */
|
|
838
|
+
get valueLabel(): string;
|
|
839
|
+
get hasValue(): boolean;
|
|
840
|
+
isOptionSelected(opt: FilterOption): boolean;
|
|
841
|
+
/** Attribute options filtered by the in-dropdown search box (multi mode). */
|
|
842
|
+
get filteredOptions(): FilterOption[];
|
|
843
|
+
/** A named attribute (rendered with @ + secondary color) vs a role attribute (# + primary). */
|
|
844
|
+
isNamedOption(opt: FilterOption): boolean;
|
|
845
|
+
/** Option label. The attribute flavor prefixes # (role) / keeps @ (named); others render plain. */
|
|
846
|
+
optionLabel(opt: FilterOption): string;
|
|
847
|
+
toggleMenu(event: MouseEvent): void;
|
|
848
|
+
closeMenu(): void;
|
|
849
|
+
onTextInput(): void;
|
|
850
|
+
private emitText;
|
|
851
|
+
selectOption(opt: FilterOption): void;
|
|
852
|
+
toggleOption(opt: FilterOption): void;
|
|
853
|
+
private emitMulti;
|
|
854
|
+
setSemantic(semantic: 'AnyOf' | 'AllOf'): void;
|
|
855
|
+
selectDatePreset(opt: FilterOption): void;
|
|
856
|
+
openCustomRange(event: MouseEvent): void;
|
|
857
|
+
onRangeStartChanged(date: Date | null): void;
|
|
858
|
+
onRangeEndChanged(date: Date | null): void;
|
|
859
|
+
private emitCustomRange;
|
|
860
|
+
clear(event: MouseEvent): void;
|
|
861
|
+
private removeThis;
|
|
862
|
+
private syncFromFilters;
|
|
863
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ListFilterCellComponent, never>;
|
|
864
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<ListFilterCellComponent, "lib-list-filter-cell", never, { "column": { "alias": "column"; "required": false; }; }, {}, never, never, true, never>;
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
interface RefreshInterval {
|
|
868
|
+
label: string;
|
|
869
|
+
seconds: number;
|
|
870
|
+
}
|
|
871
|
+
/** Auto-refresh control: a pill + interval menu. Owns the timer and emits `refresh` each tick. */
|
|
872
|
+
declare class ListTableAutoRefreshComponent implements OnDestroy {
|
|
873
|
+
/** Current interval in seconds; 0 means off. */
|
|
874
|
+
set seconds(value: number);
|
|
875
|
+
get seconds(): number;
|
|
876
|
+
private _seconds;
|
|
877
|
+
/** Skip a tick while a refresh is already in flight. */
|
|
878
|
+
loading: boolean;
|
|
879
|
+
intervals: RefreshInterval[];
|
|
880
|
+
refresh: EventEmitter<void>;
|
|
881
|
+
secondsChange: EventEmitter<number>;
|
|
882
|
+
open: boolean;
|
|
883
|
+
/** Menu geometry, all measured when the menu opens: left offset so labels line up
|
|
884
|
+
* under the button's value, width so the right edge lands on the button's right
|
|
885
|
+
* edge, and right padding so the check centers under the chevron. */
|
|
886
|
+
menuLeft: number;
|
|
887
|
+
menuWidth: number;
|
|
888
|
+
menuPadRight: number;
|
|
889
|
+
private timer?;
|
|
890
|
+
arEl?: ElementRef<HTMLElement>;
|
|
891
|
+
valueEl?: ElementRef<HTMLElement>;
|
|
892
|
+
chevronEl?: ElementRef<HTMLElement>;
|
|
893
|
+
get enabled(): boolean;
|
|
894
|
+
get valueLabel(): string;
|
|
895
|
+
toggleMenu(event: MouseEvent): void;
|
|
896
|
+
/** Position + size the menu so its labels sit directly under the button's value,
|
|
897
|
+
* its right edge lands on the button's right edge (one shared border), and the
|
|
898
|
+
* right-aligned check centers under the chevron. */
|
|
899
|
+
private alignMenuToValue;
|
|
900
|
+
closeMenu(): void;
|
|
901
|
+
isSelected(seconds: number): boolean;
|
|
902
|
+
select(seconds: number): void;
|
|
903
|
+
private restartTimer;
|
|
904
|
+
ngOnDestroy(): void;
|
|
905
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ListTableAutoRefreshComponent, never>;
|
|
906
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<ListTableAutoRefreshComponent, "lib-list-table-auto-refresh", never, { "seconds": { "alias": "seconds"; "required": false; }; "loading": { "alias": "loading"; "required": false; }; "intervals": { "alias": "intervals"; "required": false; }; }, { "refresh": "refresh"; "secondsChange": "secondsChange"; }, never, never, true, never>;
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
/** Which situation the table is in when it has nothing to show. */
|
|
910
|
+
type EmptyVariant = 'empty' | 'no-results' | 'access-denied' | 'error';
|
|
911
|
+
/** Line glyph drawn in the empty-state figure. */
|
|
912
|
+
type EmptyGlyph = 'generic' | 'service' | 'identity' | 'router' | 'policy' | 'search' | 'lock' | 'alert';
|
|
913
|
+
/**
|
|
914
|
+
* Modern, themeable placeholder shown inside {@link ListTableComponent} when a list has
|
|
915
|
+
* no rows. Four variants (first-use empty, no search results, access denied, load error),
|
|
916
|
+
* per-entity default copy keyed by tableId, and a `[empty-state]` projection slot for a
|
|
917
|
+
* fully custom placeholder. All copy/glyph/actions can be overridden per table.
|
|
918
|
+
*/
|
|
919
|
+
declare class ListEmptyComponent {
|
|
920
|
+
variant: EmptyVariant;
|
|
921
|
+
/** tableId used to look up the default copy (e.g. 'services', 'identities'). */
|
|
922
|
+
entityKey: string;
|
|
923
|
+
/** Human label used to derive a noun when the key has no tailored copy. */
|
|
924
|
+
entityLabel: string;
|
|
925
|
+
/** What this list belongs to, e.g. 'network'. Set: "This network has no services";
|
|
926
|
+
* blank: "There are no services", for lists not tied to a network. */
|
|
927
|
+
scope: string;
|
|
928
|
+
/** Overrides for the generated content; unset falls back to the per-entity defaults. */
|
|
929
|
+
title?: string;
|
|
930
|
+
message?: string;
|
|
931
|
+
icon?: EmptyGlyph;
|
|
932
|
+
/** Label for the primary create action (first-use empty only). */
|
|
933
|
+
createLabel: string;
|
|
934
|
+
/** Whether the create action is offered (false hides it, e.g. read-only tables). */
|
|
935
|
+
hasAdd: boolean;
|
|
936
|
+
readonly: boolean;
|
|
937
|
+
/** Draw the soft card. On for the full-page state; off inside the table, so a card isn't nested in the grid. */
|
|
938
|
+
framed: boolean;
|
|
939
|
+
create: EventEmitter<void>;
|
|
940
|
+
clearFilters: EventEmitter<void>;
|
|
941
|
+
retry: EventEmitter<void>;
|
|
942
|
+
private static readonly COPY;
|
|
943
|
+
private get copy();
|
|
944
|
+
get glyph(): EmptyGlyph;
|
|
945
|
+
/** Tone drives the glyph colour away from the create-accent for non-create variants. */
|
|
946
|
+
get tone(): '' | 'warn' | 'danger';
|
|
947
|
+
private get noun();
|
|
948
|
+
get resolvedTitle(): string;
|
|
949
|
+
get resolvedMessage(): string;
|
|
950
|
+
/** The primary create action shows only on the first-use empty state when allowed. */
|
|
951
|
+
get showCreate(): boolean;
|
|
952
|
+
get primaryLabel(): string;
|
|
953
|
+
onCreate(): void;
|
|
954
|
+
onClear(): void;
|
|
955
|
+
onRetry(): void;
|
|
956
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ListEmptyComponent, never>;
|
|
957
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<ListEmptyComponent, "lib-list-empty", never, { "variant": { "alias": "variant"; "required": false; }; "entityKey": { "alias": "entityKey"; "required": false; }; "entityLabel": { "alias": "entityLabel"; "required": false; }; "scope": { "alias": "scope"; "required": false; }; "title": { "alias": "title"; "required": false; }; "message": { "alias": "message"; "required": false; }; "icon": { "alias": "icon"; "required": false; }; "createLabel": { "alias": "createLabel"; "required": false; }; "hasAdd": { "alias": "hasAdd"; "required": false; }; "readonly": { "alias": "readonly"; "required": false; }; "framed": { "alias": "framed"; "required": false; }; }, { "create": "create"; "clearFilters": "clearFilters"; "retry": "retry"; }, never, ["[empty-state]"], true, never>;
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
declare class NoItemsComponent implements OnChanges {
|
|
961
|
+
image: string;
|
|
962
|
+
typeName: string;
|
|
963
|
+
isEmpty: boolean;
|
|
964
|
+
hasAdd: boolean;
|
|
965
|
+
hiddenResults: boolean;
|
|
966
|
+
isLoading: boolean;
|
|
967
|
+
readonly: boolean;
|
|
968
|
+
accessDenied: boolean;
|
|
969
|
+
background: any;
|
|
970
|
+
clickEmit: EventEmitter<any>;
|
|
971
|
+
refresh: EventEmitter<any>;
|
|
972
|
+
constructor();
|
|
973
|
+
ngOnChanges(): void;
|
|
974
|
+
iconClick(): void;
|
|
975
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<NoItemsComponent, never>;
|
|
976
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<NoItemsComponent, "lib-no-items", never, { "image": { "alias": "image"; "required": false; }; "typeName": { "alias": "typeName"; "required": false; }; "isEmpty": { "alias": "isEmpty"; "required": false; }; "hasAdd": { "alias": "hasAdd"; "required": false; }; "hiddenResults": { "alias": "hiddenResults"; "required": false; }; "isLoading": { "alias": "isLoading"; "required": false; }; "readonly": { "alias": "readonly"; "required": false; }; "accessDenied": { "alias": "accessDenied"; "required": false; }; }, { "clickEmit": "clickEmit"; "refresh": "refresh"; }, never, never, true, never>;
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
export { ClickOutsideDirective, DataTableFilterService, ListEmptyComponent, ListFilterCellComponent, ListHeaderCellComponent, ListMenuComponent, ListTableAutoRefreshComponent, ListTableComponent, ListTableService, NoItemsComponent, SelectCellComponent };
|
|
980
|
+
export type { EmptyGlyph, EmptyVariant, FilterObj, ListCell, ListCellContext, ListColumn, ListLegacyCellShim, ListMenuItem, ListSortDir, ListTableOptions, ListTableToolbarOptions, RefreshInterval, ToolbarControlOptions, TreeVariant };
|
|
981
|
+
//# sourceMappingURL=index.d.ts.map
|