@cqa-lib/cqa-ui 1.1.525 → 1.1.527
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/esm2020/lib/assets/images/image-assets.constants.mjs +3 -1
- package/esm2020/lib/compare-runs/compare-runs.component.mjs +1 -1
- package/esm2020/lib/execution-screen/db-query-execution-item/db-query-execution-item.component.mjs +1 -1
- package/esm2020/lib/execution-screen/db-verification-step/db-verification-step.component.mjs +1 -1
- package/esm2020/lib/iterations-loop/iterations-loop.component.mjs +1 -1
- package/esm2020/lib/segment-control/segment-control.component.mjs +6 -3
- package/esm2020/lib/simulator/simulator.component.mjs +3 -3
- package/esm2020/lib/step-builder/step-builder-document-generation-template-step/step-builder-document-generation-template-step.component.mjs +1 -1
- package/esm2020/lib/table/dynamic-table/dynamic-table.component.mjs +148 -4
- package/esm2020/lib/templates/modular-table-template/dialogs/delete-folder-dialog.component.mjs +181 -0
- package/esm2020/lib/templates/modular-table-template/dialogs/move-to-folder-dialog.component.mjs +264 -0
- package/esm2020/lib/templates/modular-table-template/dialogs/new-folder-dialog.component.mjs +352 -0
- package/esm2020/lib/templates/modular-table-template/directives/folder-drag.directive.mjs +45 -0
- package/esm2020/lib/templates/modular-table-template/directives/folder-drop.directive.mjs +95 -0
- package/esm2020/lib/templates/modular-table-template/directives/row-drag.directive.mjs +44 -0
- package/esm2020/lib/templates/modular-table-template/folder-sidebar/folder-sidebar.component.mjs +479 -0
- package/esm2020/lib/templates/modular-table-template/modular-table-template.component.mjs +1475 -0
- package/esm2020/lib/templates/modular-table-template/modular-table-template.models.mjs +79 -0
- package/esm2020/lib/templates/table-template.component.mjs +88 -12
- package/esm2020/lib/test-case-details/api-edit-step/api-edit-step.component.mjs +1 -1
- package/esm2020/lib/ui-kit.module.mjs +41 -1
- package/esm2020/public-api.mjs +10 -1
- package/fesm2015/cqa-lib-cqa-ui.mjs +3409 -179
- package/fesm2015/cqa-lib-cqa-ui.mjs.map +1 -1
- package/fesm2020/cqa-lib-cqa-ui.mjs +3389 -177
- package/fesm2020/cqa-lib-cqa-ui.mjs.map +1 -1
- package/lib/assets/images/image-assets.constants.d.ts +1 -0
- package/lib/segment-control/segment-control.component.d.ts +2 -1
- package/lib/table/dynamic-table/dynamic-table.component.d.ts +43 -1
- package/lib/templates/modular-table-template/dialogs/delete-folder-dialog.component.d.ts +34 -0
- package/lib/templates/modular-table-template/dialogs/move-to-folder-dialog.component.d.ts +57 -0
- package/lib/templates/modular-table-template/dialogs/new-folder-dialog.component.d.ts +79 -0
- package/lib/templates/modular-table-template/directives/folder-drag.directive.d.ts +10 -0
- package/lib/templates/modular-table-template/directives/folder-drop.directive.d.ts +22 -0
- package/lib/templates/modular-table-template/directives/row-drag.directive.d.ts +10 -0
- package/lib/templates/modular-table-template/folder-sidebar/folder-sidebar.component.d.ts +149 -0
- package/lib/templates/modular-table-template/modular-table-template.component.d.ts +453 -0
- package/lib/templates/modular-table-template/modular-table-template.models.d.ts +150 -0
- package/lib/templates/table-template.component.d.ts +40 -2
- package/lib/ui-kit.module.d.ts +153 -145
- package/package.json +1 -1
- package/public-api.d.ts +9 -0
- package/src/lib/assets/images/EmptyFolderState.png +0 -0
- package/src/lib/assets/images/image-assets.constants.ts +3 -0
- package/styles.css +1 -1
|
@@ -0,0 +1,453 @@
|
|
|
1
|
+
import { EventEmitter, OnChanges, OnInit, SimpleChanges, OnDestroy, ChangeDetectorRef, TemplateRef } from '@angular/core';
|
|
2
|
+
import { DynamicFilterItem, DynamicFilterComponent } from '../../filters/dynamic-filter/dynamic-filter.component';
|
|
3
|
+
import { DynamicTableColumn } from '../../table/dynamic-table/dynamic-table.component';
|
|
4
|
+
import { ColumnVisibilityConfig } from '../../column-visibility/column-visibility.component';
|
|
5
|
+
import { TableAction } from '../../table-action-toolbar/table-action-toolbar.component';
|
|
6
|
+
import { EmptyStateConfig } from '../../empty-state/empty-state-config.interface';
|
|
7
|
+
import { DialogService } from '../../dialog/dialog.service';
|
|
8
|
+
import { FolderCreatedPayload, FolderDeleteRequestedPayload, FolderDeletedPayload, FolderIdAccessor, FolderNode, FolderRenamedPayload, FolderMoveRequestedPayload, FolderMovedPayload, FolderDuplicateRequestedPayload, ModularConfig, ModularLabels, ReorderLabels, ReorderSavePayload, TestsMovedPayload, BulkActionInvokedPayload } from './modular-table-template.models';
|
|
9
|
+
import * as i0 from "@angular/core";
|
|
10
|
+
export declare class ModularTableTemplateComponent implements OnInit, OnChanges, OnDestroy {
|
|
11
|
+
private cdr;
|
|
12
|
+
private dialogService;
|
|
13
|
+
searchPlaceholder: string;
|
|
14
|
+
searchValue: string;
|
|
15
|
+
showClear: boolean;
|
|
16
|
+
showSearchBar: boolean;
|
|
17
|
+
showExportButton: boolean;
|
|
18
|
+
isExporting: boolean;
|
|
19
|
+
onSearchChange: EventEmitter<string>;
|
|
20
|
+
onExportClick: EventEmitter<void | {
|
|
21
|
+
type: 'local' | 'email';
|
|
22
|
+
emails?: string[];
|
|
23
|
+
framework?: 'WEBDRIVER_IO' | 'SELENIUM_JAVA';
|
|
24
|
+
selectedItems: any[];
|
|
25
|
+
}>;
|
|
26
|
+
onApplyFilterClick: EventEmitter<any>;
|
|
27
|
+
onResetFilterClick: EventEmitter<void>;
|
|
28
|
+
onClearAll: EventEmitter<void>;
|
|
29
|
+
removeChip: EventEmitter<any>;
|
|
30
|
+
filterConfig: DynamicFilterItem[];
|
|
31
|
+
filterModel: Record<string, any>;
|
|
32
|
+
showFilterPanel: boolean;
|
|
33
|
+
showFilterButton: boolean;
|
|
34
|
+
otherButtons: TemplateRef<any>[];
|
|
35
|
+
otherDropDownButtons: TemplateRef<any>[];
|
|
36
|
+
otherSelectDropDownButtons: TemplateRef<any>[];
|
|
37
|
+
/** @deprecated Use otherButtons array instead */
|
|
38
|
+
otherButtonLabel: string;
|
|
39
|
+
/** @deprecated Use otherButtons array instead */
|
|
40
|
+
otherButtonVariant: 'filled' | 'outlined' | 'text' | 'elevated' | 'tonal' | 'grey-solid';
|
|
41
|
+
/** @deprecated Use otherButtons array instead */
|
|
42
|
+
showOtherButton: boolean;
|
|
43
|
+
showActionButton: boolean;
|
|
44
|
+
showSettingsButton: boolean;
|
|
45
|
+
showAutoRefreshButton: boolean;
|
|
46
|
+
showViewModeToggle: boolean;
|
|
47
|
+
viewMode: 'list' | 'modular';
|
|
48
|
+
viewModeLabels: {
|
|
49
|
+
list: string;
|
|
50
|
+
modular: string;
|
|
51
|
+
};
|
|
52
|
+
viewModeChange: EventEmitter<"list" | "modular">;
|
|
53
|
+
get viewModeSegments(): Array<{
|
|
54
|
+
label: string;
|
|
55
|
+
value: string;
|
|
56
|
+
icon?: string;
|
|
57
|
+
}>;
|
|
58
|
+
onViewModeChange(value: string): void;
|
|
59
|
+
data: any[];
|
|
60
|
+
isEmptyState: boolean;
|
|
61
|
+
emptyStateConfig: EmptyStateConfig;
|
|
62
|
+
actions: TableAction[];
|
|
63
|
+
chips: Array<{
|
|
64
|
+
key?: string;
|
|
65
|
+
label?: string;
|
|
66
|
+
text: string;
|
|
67
|
+
fullText?: string;
|
|
68
|
+
hasMore?: boolean;
|
|
69
|
+
}>;
|
|
70
|
+
filterApplied: boolean;
|
|
71
|
+
columns: DynamicTableColumn[];
|
|
72
|
+
rowSelectable?: (row: any) => boolean;
|
|
73
|
+
selectedAutoRefreshInterval: number;
|
|
74
|
+
pageIndex: number;
|
|
75
|
+
pageSize: number;
|
|
76
|
+
pageSizeOptions: number[];
|
|
77
|
+
pageSizeMenuDirection: 'auto' | 'up' | 'down';
|
|
78
|
+
serverSidePagination: boolean;
|
|
79
|
+
totalElements: number;
|
|
80
|
+
pageChange: EventEmitter<{
|
|
81
|
+
pageIndex: number;
|
|
82
|
+
pageSize: number;
|
|
83
|
+
}>;
|
|
84
|
+
/**
|
|
85
|
+
* When false, header sort does not reorder rows locally (use with serverSidePagination + sortChange).
|
|
86
|
+
* Default true for backward compatibility.
|
|
87
|
+
*/
|
|
88
|
+
enableLocalSort: boolean;
|
|
89
|
+
sortChange: EventEmitter<{
|
|
90
|
+
fieldId: string;
|
|
91
|
+
fieldValue?: string;
|
|
92
|
+
direction: 'asc' | 'desc' | null;
|
|
93
|
+
}>;
|
|
94
|
+
isTableLoading?: boolean;
|
|
95
|
+
isTableDataLoading?: boolean;
|
|
96
|
+
cellJsonPathGetter?: (rowIndex: number, colId: string, row: any) => string;
|
|
97
|
+
onJsonPathCopiedHandler?: (event: {
|
|
98
|
+
path: string;
|
|
99
|
+
source: string;
|
|
100
|
+
}) => void;
|
|
101
|
+
selectedItems: any[];
|
|
102
|
+
/**
|
|
103
|
+
* When true, the action toolbar renders the "Select all" affordance. Defaults to false
|
|
104
|
+
* for now — host opts in. Matches the current product requirement to hide Select All.
|
|
105
|
+
*/
|
|
106
|
+
showSelectAllInToolbar: boolean;
|
|
107
|
+
/**
|
|
108
|
+
* When true, the action toolbar renders the dismiss (×) affordance. Defaults to false
|
|
109
|
+
* for now — host opts in. Matches the current product requirement to hide Cancel.
|
|
110
|
+
*/
|
|
111
|
+
showDismissInToolbar: boolean;
|
|
112
|
+
/** Bound to the toolbar's "Select all" checkbox — drives the checked state. */
|
|
113
|
+
allSelectedInToolbar: boolean;
|
|
114
|
+
private _columnVisibility;
|
|
115
|
+
private _cachedVisibilityColumns;
|
|
116
|
+
filteredRows: any[];
|
|
117
|
+
pagedRows: any[];
|
|
118
|
+
folders: FolderNode[];
|
|
119
|
+
selectedFolderId: number | null;
|
|
120
|
+
expandedFolderIds: number[];
|
|
121
|
+
unorganisedCount: number;
|
|
122
|
+
folderIdAccessor: FolderIdAccessor;
|
|
123
|
+
modularConfig: ModularConfig;
|
|
124
|
+
modularLabels: ModularLabels;
|
|
125
|
+
bulkActions: TableAction[];
|
|
126
|
+
sidebarCollapsed: boolean;
|
|
127
|
+
/**
|
|
128
|
+
* When true (default), the library opens its own Move dialog for convenience
|
|
129
|
+
* during testing. Hosts taking over API + UX should set this to `false` and
|
|
130
|
+
* listen on `moveRequested` to render their own.
|
|
131
|
+
*/
|
|
132
|
+
useInternalDialogs: boolean;
|
|
133
|
+
folderSelected: EventEmitter<number>;
|
|
134
|
+
folderExpansionToggled: EventEmitter<{
|
|
135
|
+
id: number;
|
|
136
|
+
expanded: boolean;
|
|
137
|
+
}>;
|
|
138
|
+
folderCreated: EventEmitter<FolderCreatedPayload>;
|
|
139
|
+
/** Emitted when the user clicks "+ New folder"; host should open a creation modal. */
|
|
140
|
+
folderCreateRequested: EventEmitter<{
|
|
141
|
+
parentId: number | null;
|
|
142
|
+
}>;
|
|
143
|
+
folderRenamed: EventEmitter<FolderRenamedPayload>;
|
|
144
|
+
/**
|
|
145
|
+
* Fires after the user confirms folder deletion via the internal dialog (or
|
|
146
|
+
* immediately, when `useInternalDialogs` is false and the host drives the UX).
|
|
147
|
+
* Payload now includes the user's chosen `strategy` for what happens to the
|
|
148
|
+
* folder's test cases.
|
|
149
|
+
*/
|
|
150
|
+
folderDeleted: EventEmitter<FolderDeletedPayload>;
|
|
151
|
+
testsMoved: EventEmitter<TestsMovedPayload>;
|
|
152
|
+
/** Fires on raw toolbar action click — *before* any internal dialog opens. */
|
|
153
|
+
bulkActionClick: EventEmitter<{
|
|
154
|
+
id: string;
|
|
155
|
+
selected: any[];
|
|
156
|
+
}>;
|
|
157
|
+
/** Fires when the toolbar's "Select all" is toggled. */
|
|
158
|
+
bulkSelectAllChange: EventEmitter<boolean>;
|
|
159
|
+
/** Fires when the toolbar's dismiss (×) is clicked. */
|
|
160
|
+
bulkDismiss: EventEmitter<void>;
|
|
161
|
+
/**
|
|
162
|
+
* Fires *after* the library-internal move-to-folder dialog resolves with a
|
|
163
|
+
* user confirmation, OR immediately for non-dialog bulk actions supplied by
|
|
164
|
+
* the host. Hosts with their own UX should listen on `bulkActionClick` +
|
|
165
|
+
* `moveRequested` and treat this as the "confirmed" signal.
|
|
166
|
+
*/
|
|
167
|
+
bulkActionInvoked: EventEmitter<BulkActionInvokedPayload>;
|
|
168
|
+
sidebarCollapsedChange: EventEmitter<boolean>;
|
|
169
|
+
/** When true, renders a "Reorder" button in the toolbar. Host-driven. */
|
|
170
|
+
showReorderButton: boolean;
|
|
171
|
+
/**
|
|
172
|
+
* Host flips this true while its bulk-update API call is in-flight. The
|
|
173
|
+
* component keeps the reorder UI pinned ("Saving...") while true and exits
|
|
174
|
+
* reorder mode when it flips back to false (the "future API call" hook).
|
|
175
|
+
*/
|
|
176
|
+
reorderSaving: boolean;
|
|
177
|
+
/** Partial override for the default reorder labels ("Reorder", "Done", etc.). */
|
|
178
|
+
set reorderLabels(partial: Partial<ReorderLabels> | undefined);
|
|
179
|
+
get reorderLabels(): ReorderLabels;
|
|
180
|
+
private _reorderLabels;
|
|
181
|
+
/** Fires when the user clicks "Reorder" and the component enters reorder mode. */
|
|
182
|
+
reorderStart: EventEmitter<void>;
|
|
183
|
+
/** Fires when the user clicks "Cancel" — the original order is already restored. */
|
|
184
|
+
reorderCancel: EventEmitter<void>;
|
|
185
|
+
/**
|
|
186
|
+
* Fires when the user clicks "Done". Host should take `orderedItems`, call its
|
|
187
|
+
* bulk-update API, refresh `[data]`, and flip `reorderSaving` back to `false` —
|
|
188
|
+
* the component will then exit reorder mode.
|
|
189
|
+
*
|
|
190
|
+
* Note: for server-side pagination, `orderedItems` is the *current page slice*,
|
|
191
|
+
* not the full dataset — same as the in-memory view the user was dragging.
|
|
192
|
+
*/
|
|
193
|
+
reorderSave: EventEmitter<ReorderSavePayload>;
|
|
194
|
+
/** Internal — true while the user is in reorder mode. */
|
|
195
|
+
isReordering: boolean;
|
|
196
|
+
/** Snapshot of `pagedRows` taken on enter; used to revert on cancel. */
|
|
197
|
+
private reorderSnapshot;
|
|
198
|
+
/** Draft of the reordered rows (current working state). */
|
|
199
|
+
private reorderDraft;
|
|
200
|
+
/** Auto-refresh interval captured on enter, so we can restore on cancel/done. */
|
|
201
|
+
private reorderSavedAutoRefresh;
|
|
202
|
+
/** True after Done has been clicked, awaiting the host's `reorderSaving` → false flip. */
|
|
203
|
+
private reorderAwaitingSaveFlip;
|
|
204
|
+
/**
|
|
205
|
+
* Fires when the user clicks the "Move to folder" bulk action — *before* the
|
|
206
|
+
* internal dialog opens. Hosts that want to render their own modal should
|
|
207
|
+
* set `useInternalDialogs = false` and listen here.
|
|
208
|
+
*/
|
|
209
|
+
moveRequested: EventEmitter<{
|
|
210
|
+
testIds: Array<string | number>;
|
|
211
|
+
selected: any[];
|
|
212
|
+
currentFolderId: number | null;
|
|
213
|
+
folders: FolderNode[];
|
|
214
|
+
}>;
|
|
215
|
+
/** Fires whenever the component's `selectedItems` changes from within (Select All / Dismiss). */
|
|
216
|
+
selectedItemsChange: EventEmitter<any[]>;
|
|
217
|
+
/**
|
|
218
|
+
* Fires when the user clicks a folder's delete affordance — *before* the
|
|
219
|
+
* internal confirmation dialog opens. Hosts owning the UX listen here.
|
|
220
|
+
* Payload includes `testCount` + `hasParent` so hosts can render the right
|
|
221
|
+
* options in their own modal.
|
|
222
|
+
*/
|
|
223
|
+
folderDeleteRequested: EventEmitter<FolderDeleteRequestedPayload>;
|
|
224
|
+
/**
|
|
225
|
+
* Fires when the user picks "Move folder" from a folder row's context menu —
|
|
226
|
+
* *before* any dialog opens. Hosts owning the UX listen here with
|
|
227
|
+
* `useInternalDialogs = false` and open their own folder picker.
|
|
228
|
+
*/
|
|
229
|
+
folderMoveRequested: EventEmitter<FolderMoveRequestedPayload>;
|
|
230
|
+
/**
|
|
231
|
+
* Fires after the user confirms a folder move via the internal picker
|
|
232
|
+
* (or immediately when `useInternalDialogs = false` and the host drives it).
|
|
233
|
+
*/
|
|
234
|
+
folderMoved: EventEmitter<FolderMovedPayload>;
|
|
235
|
+
/**
|
|
236
|
+
* Fires when the user picks "Duplicate folder" from a folder row's context menu.
|
|
237
|
+
* The library doesn't own persistence, so the host is expected to clone the
|
|
238
|
+
* folder's subtree server-side and *reference* (not copy) the test cases.
|
|
239
|
+
*/
|
|
240
|
+
folderDuplicateRequested: EventEmitter<FolderDuplicateRequestedPayload>;
|
|
241
|
+
constructor(cdr: ChangeDetectorRef, dialogService: DialogService);
|
|
242
|
+
private pendingFilters;
|
|
243
|
+
private appliedFilters;
|
|
244
|
+
private autoRefreshTimer?;
|
|
245
|
+
onReload: EventEmitter<void>;
|
|
246
|
+
onAutoRefreshClick: EventEmitter<void>;
|
|
247
|
+
columnVisibilityChange: EventEmitter<ColumnVisibilityConfig>;
|
|
248
|
+
autoRefreshIntervalChange: EventEmitter<number>;
|
|
249
|
+
dynamicFilterComponent?: DynamicFilterComponent;
|
|
250
|
+
computedColumns: DynamicTableColumn[];
|
|
251
|
+
visibilityColumns: Array<{
|
|
252
|
+
id: string;
|
|
253
|
+
label: string;
|
|
254
|
+
}>;
|
|
255
|
+
private updateComputedColumns;
|
|
256
|
+
private updateVisibilityColumns;
|
|
257
|
+
set columnVisibility(cfg: ColumnVisibilityConfig | undefined);
|
|
258
|
+
get columnVisibility(): ColumnVisibilityConfig;
|
|
259
|
+
ngOnInit(): void;
|
|
260
|
+
ngOnChanges(changes: SimpleChanges): void;
|
|
261
|
+
private initializeComponent;
|
|
262
|
+
/**
|
|
263
|
+
* Build `filteredRows` from `data` by applying (a) the field filters (status/priority/etc.)
|
|
264
|
+
* and (b) the folder filter derived from `selectedFolderId` + `folderIdAccessor`.
|
|
265
|
+
*/
|
|
266
|
+
private rebuildFilteredRows;
|
|
267
|
+
private passFolder;
|
|
268
|
+
/** True when the component should render the modular (folder-aware) UI. */
|
|
269
|
+
get isModularView(): boolean;
|
|
270
|
+
/**
|
|
271
|
+
* Get selected IDs from selectedItems (objects)
|
|
272
|
+
*/
|
|
273
|
+
private getSelectedIds;
|
|
274
|
+
private restoreSelectionState;
|
|
275
|
+
private initializeColumnVisibility;
|
|
276
|
+
get anyRowSelected(): boolean;
|
|
277
|
+
get currentSelectedItems(): any[];
|
|
278
|
+
actionClick(data: any): void;
|
|
279
|
+
view(id: number | string): void;
|
|
280
|
+
edit(row: any): void;
|
|
281
|
+
delete(row: any): void;
|
|
282
|
+
toggleFilter(): void;
|
|
283
|
+
onColumnVisibilityChange(cfg: ColumnVisibilityConfig): void;
|
|
284
|
+
onAutoRefreshChange(intervalMs: number): void;
|
|
285
|
+
valueChange(value: string): void;
|
|
286
|
+
search(value: string): void;
|
|
287
|
+
cleared(): void;
|
|
288
|
+
onEmptyAction(action: any): void;
|
|
289
|
+
onFiltersChanged(current: any): void;
|
|
290
|
+
onFiltersApplied(applied: any): void;
|
|
291
|
+
handleResetFilterClick(): void;
|
|
292
|
+
handleRefreshClick(): void;
|
|
293
|
+
private triggerReload;
|
|
294
|
+
private setupAutoRefresh;
|
|
295
|
+
private clearAutoRefresh;
|
|
296
|
+
ngOnDestroy(): void;
|
|
297
|
+
onPaginate(e: {
|
|
298
|
+
pageIndex: number;
|
|
299
|
+
pageSize: number;
|
|
300
|
+
}): void;
|
|
301
|
+
onPageSizeChange(size: number): void;
|
|
302
|
+
onRemoveChip(chip: any): void;
|
|
303
|
+
onClearAllChips(): void;
|
|
304
|
+
private applyPagination;
|
|
305
|
+
private mapVisibilityColumns;
|
|
306
|
+
private normalizeDate;
|
|
307
|
+
private passFilters;
|
|
308
|
+
trackByTemplateRef(index: number): number;
|
|
309
|
+
trackByDropdownTemplateRef(index: number): number;
|
|
310
|
+
trackBySelectDropdownTemplateRef(index: number): number;
|
|
311
|
+
isExportModalOpen: boolean;
|
|
312
|
+
exportCodeClick(): void;
|
|
313
|
+
closeExportModal(): void;
|
|
314
|
+
onExportModalExport(result: {
|
|
315
|
+
type: 'local' | 'email';
|
|
316
|
+
emails?: string[];
|
|
317
|
+
framework: 'WEBDRIVER_IO' | 'SELENIUM_JAVA';
|
|
318
|
+
}): void;
|
|
319
|
+
get selectedCasesForExport(): Array<{
|
|
320
|
+
id?: number;
|
|
321
|
+
name?: string;
|
|
322
|
+
}>;
|
|
323
|
+
get arrowClasses(): string;
|
|
324
|
+
/**
|
|
325
|
+
* Flat list of root-level folders for the "Organised" grid on the root view.
|
|
326
|
+
*/
|
|
327
|
+
get rootFolderTiles(): FolderNode[];
|
|
328
|
+
/**
|
|
329
|
+
* Subfolders of the currently-selected folder (for the "Subfolders in ..." grid).
|
|
330
|
+
*/
|
|
331
|
+
get subfolderTiles(): FolderNode[];
|
|
332
|
+
/**
|
|
333
|
+
* Breadcrumb trail from "All folders" down to the currently-selected folder.
|
|
334
|
+
*/
|
|
335
|
+
get breadcrumbTrail(): FolderNode[];
|
|
336
|
+
private buildTrail;
|
|
337
|
+
private findFolder;
|
|
338
|
+
/**
|
|
339
|
+
* Whether the component is in "root" view (no folder selected). Controls which
|
|
340
|
+
* sections render on the right-hand pane.
|
|
341
|
+
*/
|
|
342
|
+
get isRootView(): boolean;
|
|
343
|
+
/** The currently-selected folder node (or null at root). */
|
|
344
|
+
get currentFolderNode(): FolderNode | null;
|
|
345
|
+
/** Count of test cases directly under the currently-selected folder (excluding descendants). */
|
|
346
|
+
get currentFolderDirectCount(): number;
|
|
347
|
+
/**
|
|
348
|
+
* Renders the empty-state slot when the host explicitly opts in, OR when the
|
|
349
|
+
* table would otherwise render blank (no loading + no rows). Using a derived
|
|
350
|
+
* flag keeps the host contract identical to `cqa-table-template` while letting
|
|
351
|
+
* the modular view show "No Test Case Found" out of the box — the earlier ask.
|
|
352
|
+
*/
|
|
353
|
+
get effectiveIsEmptyState(): boolean;
|
|
354
|
+
/**
|
|
355
|
+
* Picks the host-provided `emptyStateConfig` when the host flagged the state
|
|
356
|
+
* itself; otherwise falls back to a library-owned "No Test Case Found" config
|
|
357
|
+
* driven by `modularLabels`.
|
|
358
|
+
*/
|
|
359
|
+
get effectiveEmptyStateConfig(): EmptyStateConfig;
|
|
360
|
+
onFolderSelected(id: number | null): void;
|
|
361
|
+
onFolderExpansionToggled(event: {
|
|
362
|
+
id: number;
|
|
363
|
+
expanded: boolean;
|
|
364
|
+
}): void;
|
|
365
|
+
onFolderCreated(payload: FolderCreatedPayload): void;
|
|
366
|
+
onFolderCreateRequested(payload: {
|
|
367
|
+
parentId: number | null;
|
|
368
|
+
}): void;
|
|
369
|
+
onFolderRenamed(payload: FolderRenamedPayload): void;
|
|
370
|
+
/**
|
|
371
|
+
* Wired to the sidebar's `folderDeleted` output — which fires on delete-icon
|
|
372
|
+
* *click*, not on confirmation. We re-emit a `folderDeleteRequested` event
|
|
373
|
+
* first (so hosts can intercept) and, when `useInternalDialogs` is enabled,
|
|
374
|
+
* open the confirmation dialog. `folderDeleted` now only fires after confirm.
|
|
375
|
+
*/
|
|
376
|
+
onFolderDeleted(payload: {
|
|
377
|
+
id: number;
|
|
378
|
+
}): void;
|
|
379
|
+
/** Builds the { id, name, testCount, hasParent } payload used by delete events/dialogs. */
|
|
380
|
+
private buildDeleteContext;
|
|
381
|
+
private countTestsInFolder;
|
|
382
|
+
/** Returns true when the folder is nested (i.e. not a root-level folder). */
|
|
383
|
+
private folderHasParent;
|
|
384
|
+
onTestsDropped(event: {
|
|
385
|
+
testIds: Array<string | number>;
|
|
386
|
+
targetFolderId: number | null;
|
|
387
|
+
}): void;
|
|
388
|
+
/**
|
|
389
|
+
* Folder-to-folder drag-drop. The sidebar has already validated against self/descendant
|
|
390
|
+
* cycles, so the drop is its own confirmation — we emit `folderMoved` directly without
|
|
391
|
+
* opening the move dialog. Gated on `allowTestDragDrop` (same flag as test drag-drop).
|
|
392
|
+
*/
|
|
393
|
+
onFolderDropped(event: {
|
|
394
|
+
id: number;
|
|
395
|
+
newParentId: number | null;
|
|
396
|
+
}): void;
|
|
397
|
+
/**
|
|
398
|
+
* Sidebar emitted `folderMoveRequested` (user picked "Move folder" from the context menu).
|
|
399
|
+
* We re-emit a richer payload for hosts, and — when running with internal dialogs —
|
|
400
|
+
* open the existing move-to-folder picker configured for a folder-move (self and
|
|
401
|
+
* descendants are disabled to prevent cycles).
|
|
402
|
+
*/
|
|
403
|
+
onFolderMoveRequested(payload: {
|
|
404
|
+
id: number;
|
|
405
|
+
}): void;
|
|
406
|
+
/**
|
|
407
|
+
* Sidebar emitted `folderDuplicateRequested`. The library can't persist —
|
|
408
|
+
* emit the host-level event so the host clones the subtree server-side.
|
|
409
|
+
* Test cases should be *referenced* from the new folders, not duplicated.
|
|
410
|
+
*/
|
|
411
|
+
onFolderDuplicateRequested(payload: {
|
|
412
|
+
id: number;
|
|
413
|
+
}): void;
|
|
414
|
+
onSidebarCollapsedChange(collapsed: boolean): void;
|
|
415
|
+
toggleSidebar(): void;
|
|
416
|
+
/**
|
|
417
|
+
* Default bulk actions shown in the toolbar merged with any host-supplied
|
|
418
|
+
* `bulkActions`. Currently only "Move to folder" ships by default —
|
|
419
|
+
* Delete / Add Tag are opt-in per the current product requirement. Hosts
|
|
420
|
+
* that want them back pass them via `bulkActions`.
|
|
421
|
+
*/
|
|
422
|
+
get effectiveBulkActions(): TableAction[];
|
|
423
|
+
onBulkAction(event: {
|
|
424
|
+
id: string;
|
|
425
|
+
selected: any[];
|
|
426
|
+
}): void;
|
|
427
|
+
onBulkSelectAll(checked: boolean): void;
|
|
428
|
+
onBulkDismiss(): void;
|
|
429
|
+
private openMoveDialog;
|
|
430
|
+
/**
|
|
431
|
+
* Opens the folder-picker dialog configured for moving a folder (rather than tests).
|
|
432
|
+
* The source folder itself is marked as the "current" folder so it's rendered as
|
|
433
|
+
* disabled in the picker. On confirm, emits `folderMoved` with the chosen parent.
|
|
434
|
+
*/
|
|
435
|
+
private openMoveFolderDialog;
|
|
436
|
+
private openCreateFolderDialog;
|
|
437
|
+
private openDeleteFolderDialog;
|
|
438
|
+
startReorder(): void;
|
|
439
|
+
cancelReorder(): void;
|
|
440
|
+
saveReorder(): void;
|
|
441
|
+
onRowReorder(event: {
|
|
442
|
+
previousIndex: number;
|
|
443
|
+
currentIndex: number;
|
|
444
|
+
orderedData: any[];
|
|
445
|
+
}): void;
|
|
446
|
+
private exitReorderMode;
|
|
447
|
+
/**
|
|
448
|
+
* Row-drag payload builder used by the [cqaRowDrag] directive via (buildPayload).
|
|
449
|
+
*/
|
|
450
|
+
buildRowDragPayload: (row: any) => Array<string | number>;
|
|
451
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ModularTableTemplateComponent, never>;
|
|
452
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<ModularTableTemplateComponent, "cqa-modular-table-template", never, { "searchPlaceholder": "searchPlaceholder"; "searchValue": "searchValue"; "showClear": "showClear"; "showSearchBar": "showSearchBar"; "showExportButton": "showExportButton"; "isExporting": "isExporting"; "filterConfig": "filterConfig"; "filterModel": "filterModel"; "showFilterPanel": "showFilterPanel"; "showFilterButton": "showFilterButton"; "otherButtons": "otherButtons"; "otherDropDownButtons": "otherDropDownButtons"; "otherSelectDropDownButtons": "otherSelectDropDownButtons"; "otherButtonLabel": "otherButtonLabel"; "otherButtonVariant": "otherButtonVariant"; "showOtherButton": "showOtherButton"; "showActionButton": "showActionButton"; "showSettingsButton": "showSettingsButton"; "showAutoRefreshButton": "showAutoRefreshButton"; "showViewModeToggle": "showViewModeToggle"; "viewMode": "viewMode"; "viewModeLabels": "viewModeLabels"; "data": "data"; "isEmptyState": "isEmptyState"; "emptyStateConfig": "emptyStateConfig"; "actions": "actions"; "chips": "chips"; "filterApplied": "filterApplied"; "columns": "columns"; "rowSelectable": "rowSelectable"; "selectedAutoRefreshInterval": "selectedAutoRefreshInterval"; "pageIndex": "pageIndex"; "pageSize": "pageSize"; "pageSizeOptions": "pageSizeOptions"; "pageSizeMenuDirection": "pageSizeMenuDirection"; "serverSidePagination": "serverSidePagination"; "totalElements": "totalElements"; "enableLocalSort": "enableLocalSort"; "isTableLoading": "isTableLoading"; "isTableDataLoading": "isTableDataLoading"; "cellJsonPathGetter": "cellJsonPathGetter"; "onJsonPathCopiedHandler": "onJsonPathCopiedHandler"; "selectedItems": "selectedItems"; "showSelectAllInToolbar": "showSelectAllInToolbar"; "showDismissInToolbar": "showDismissInToolbar"; "allSelectedInToolbar": "allSelectedInToolbar"; "folders": "folders"; "selectedFolderId": "selectedFolderId"; "expandedFolderIds": "expandedFolderIds"; "unorganisedCount": "unorganisedCount"; "folderIdAccessor": "folderIdAccessor"; "modularConfig": "modularConfig"; "modularLabels": "modularLabels"; "bulkActions": "bulkActions"; "sidebarCollapsed": "sidebarCollapsed"; "useInternalDialogs": "useInternalDialogs"; "showReorderButton": "showReorderButton"; "reorderSaving": "reorderSaving"; "reorderLabels": "reorderLabels"; "columnVisibility": "columnVisibility"; }, { "onSearchChange": "onSearchChange"; "onExportClick": "onExportClick"; "onApplyFilterClick": "onApplyFilterClick"; "onResetFilterClick": "onResetFilterClick"; "onClearAll": "onClearAll"; "removeChip": "removeChip"; "viewModeChange": "viewModeChange"; "pageChange": "pageChange"; "sortChange": "sortChange"; "folderSelected": "folderSelected"; "folderExpansionToggled": "folderExpansionToggled"; "folderCreated": "folderCreated"; "folderCreateRequested": "folderCreateRequested"; "folderRenamed": "folderRenamed"; "folderDeleted": "folderDeleted"; "testsMoved": "testsMoved"; "bulkActionClick": "bulkActionClick"; "bulkSelectAllChange": "bulkSelectAllChange"; "bulkDismiss": "bulkDismiss"; "bulkActionInvoked": "bulkActionInvoked"; "sidebarCollapsedChange": "sidebarCollapsedChange"; "reorderStart": "reorderStart"; "reorderCancel": "reorderCancel"; "reorderSave": "reorderSave"; "moveRequested": "moveRequested"; "selectedItemsChange": "selectedItemsChange"; "folderDeleteRequested": "folderDeleteRequested"; "folderMoveRequested": "folderMoveRequested"; "folderMoved": "folderMoved"; "folderDuplicateRequested": "folderDuplicateRequested"; "onReload": "onReload"; "onAutoRefreshClick": "onAutoRefreshClick"; "columnVisibilityChange": "columnVisibilityChange"; "autoRefreshIntervalChange": "autoRefreshIntervalChange"; }, never, never>;
|
|
453
|
+
}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
export interface FolderNode {
|
|
2
|
+
id: number;
|
|
3
|
+
name: string;
|
|
4
|
+
/** Direct test-case count — cases with `folderId === this.id`. Rendered as the row badge. */
|
|
5
|
+
count?: number;
|
|
6
|
+
/** Total test-case count including all descendants. Rendered as a tooltip on the folder row. */
|
|
7
|
+
totalCount?: number;
|
|
8
|
+
color?: string;
|
|
9
|
+
children?: FolderNode[];
|
|
10
|
+
}
|
|
11
|
+
export declare type FolderIdAccessor = (row: any) => number | null | undefined;
|
|
12
|
+
export interface ModularConfig {
|
|
13
|
+
showSidebar: boolean;
|
|
14
|
+
showBreadcrumb: boolean;
|
|
15
|
+
showFolderGrid: boolean;
|
|
16
|
+
showUnorganisedSection: boolean;
|
|
17
|
+
showSubfolderSection: boolean;
|
|
18
|
+
showCounts: boolean;
|
|
19
|
+
allowCreateFolder: boolean;
|
|
20
|
+
allowRenameFolder: boolean;
|
|
21
|
+
allowDeleteFolder: boolean;
|
|
22
|
+
allowNestedFolders: boolean;
|
|
23
|
+
allowTestDragDrop: boolean;
|
|
24
|
+
allowBulkSelection: boolean;
|
|
25
|
+
}
|
|
26
|
+
export declare const DEFAULT_MODULAR_CONFIG: ModularConfig;
|
|
27
|
+
export interface ModularLabels {
|
|
28
|
+
folders: string;
|
|
29
|
+
organised: string;
|
|
30
|
+
unorganised: string;
|
|
31
|
+
newFolder: string;
|
|
32
|
+
searchFoldersPlaceholder: string;
|
|
33
|
+
allFolders: string;
|
|
34
|
+
subfoldersIn: string;
|
|
35
|
+
moveToFolder: string;
|
|
36
|
+
addTag: string;
|
|
37
|
+
delete: string;
|
|
38
|
+
selectAll: string;
|
|
39
|
+
testsCountSingular: string;
|
|
40
|
+
testsCountPlural: string;
|
|
41
|
+
foldersCountSingular: string;
|
|
42
|
+
foldersCountPlural: string;
|
|
43
|
+
subfolderCountSingular: string;
|
|
44
|
+
subfolderCountPlural: string;
|
|
45
|
+
oneSubfolder: string;
|
|
46
|
+
subfoldersCount: string;
|
|
47
|
+
clearFilter: string;
|
|
48
|
+
moveDialogTitle: string;
|
|
49
|
+
moveDialogCancel: string;
|
|
50
|
+
moveDialogConfirm: string;
|
|
51
|
+
moveDialogRoot: string;
|
|
52
|
+
moveDialogDescriptionSingular: string;
|
|
53
|
+
moveDialogDescriptionPlural: string;
|
|
54
|
+
newFolderDialogTitle: string;
|
|
55
|
+
newFolderDialogDescription: string;
|
|
56
|
+
newFolderDialogNameLabel: string;
|
|
57
|
+
newFolderDialogNamePlaceholder: string;
|
|
58
|
+
newFolderDialogParentLabel: string;
|
|
59
|
+
newFolderDialogParentNone: string;
|
|
60
|
+
newFolderDialogColorLabel: string;
|
|
61
|
+
newFolderDialogCancel: string;
|
|
62
|
+
newFolderDialogConfirm: string;
|
|
63
|
+
folderMenuCreateSubfolder: string;
|
|
64
|
+
folderMenuRename: string;
|
|
65
|
+
folderMenuMove: string;
|
|
66
|
+
folderMenuDuplicate: string;
|
|
67
|
+
folderMenuDelete: string;
|
|
68
|
+
deleteFolderDialogTitle: string;
|
|
69
|
+
deleteFolderDialogBodySingular: string;
|
|
70
|
+
deleteFolderDialogBodyPlural: string;
|
|
71
|
+
deleteFolderDialogMoveToParentTitle: string;
|
|
72
|
+
deleteFolderDialogMoveToParentDescription: string;
|
|
73
|
+
deleteFolderDialogMoveToUnorganisedTitle: string;
|
|
74
|
+
deleteFolderDialogMoveToUnorganisedDescription: string;
|
|
75
|
+
deleteFolderDialogCancel: string;
|
|
76
|
+
deleteFolderDialogConfirm: string;
|
|
77
|
+
emptyNoTestsInFolderTitle: string;
|
|
78
|
+
emptyNoTestsInFolderDescription: string;
|
|
79
|
+
}
|
|
80
|
+
export declare const DEFAULT_MODULAR_LABELS: ModularLabels;
|
|
81
|
+
/**
|
|
82
|
+
* Emitted after a successful inline folder rename. Carries the full renamed node
|
|
83
|
+
* (with the new name already applied) plus its parent id, so hosts can issue
|
|
84
|
+
* a complete update request (e.g. `PUT /test_case_folders/{id}`) without a
|
|
85
|
+
* secondary lookup against their cached tree.
|
|
86
|
+
*/
|
|
87
|
+
export interface FolderRenamedPayload {
|
|
88
|
+
folder: FolderNode;
|
|
89
|
+
parentId: number | null;
|
|
90
|
+
/** Previous name, useful for undo messages / audit logs. */
|
|
91
|
+
previousName: string;
|
|
92
|
+
}
|
|
93
|
+
export interface FolderCreatedPayload {
|
|
94
|
+
parentId: number | null;
|
|
95
|
+
name: string;
|
|
96
|
+
color?: string;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Delete strategies match the backend `strategy` query param values on
|
|
100
|
+
* `DELETE /test_case_folders/{id}?strategy=…`. Only the two move strategies
|
|
101
|
+
* are covered by the library's internal dialog; `DELETE_IF_EMPTY` is the
|
|
102
|
+
* host's responsibility (precheck `count === 0 && totalCount === 0`).
|
|
103
|
+
*/
|
|
104
|
+
export declare type FolderDeleteStrategy = 'MOVE_TO_PARENT' | 'MOVE_TO_UNORGANISED';
|
|
105
|
+
export interface FolderDeleteRequestedPayload {
|
|
106
|
+
id: number;
|
|
107
|
+
name: string;
|
|
108
|
+
testCount: number;
|
|
109
|
+
hasParent: boolean;
|
|
110
|
+
}
|
|
111
|
+
export interface FolderMoveRequestedPayload {
|
|
112
|
+
id: number;
|
|
113
|
+
name: string;
|
|
114
|
+
hasParent: boolean;
|
|
115
|
+
}
|
|
116
|
+
export interface FolderMovedPayload {
|
|
117
|
+
id: number;
|
|
118
|
+
newParentId: number | null;
|
|
119
|
+
}
|
|
120
|
+
export interface FolderDuplicateRequestedPayload {
|
|
121
|
+
id: number;
|
|
122
|
+
name: string;
|
|
123
|
+
}
|
|
124
|
+
export interface FolderDeletedPayload {
|
|
125
|
+
id: number;
|
|
126
|
+
strategy?: FolderDeleteStrategy;
|
|
127
|
+
}
|
|
128
|
+
export interface TestsMovedPayload {
|
|
129
|
+
testIds: Array<string | number>;
|
|
130
|
+
targetFolderId: number | null;
|
|
131
|
+
}
|
|
132
|
+
export interface BulkActionInvokedPayload {
|
|
133
|
+
id: string;
|
|
134
|
+
selected: any[];
|
|
135
|
+
}
|
|
136
|
+
export interface ReorderLabels {
|
|
137
|
+
reorderButton: string;
|
|
138
|
+
cancelButton: string;
|
|
139
|
+
doneButton: string;
|
|
140
|
+
savingButton: string;
|
|
141
|
+
bannerTitle: string;
|
|
142
|
+
bannerDescription: string;
|
|
143
|
+
}
|
|
144
|
+
export declare const DEFAULT_REORDER_LABELS: ReorderLabels;
|
|
145
|
+
export interface ReorderSavePayload {
|
|
146
|
+
orderedItems: any[];
|
|
147
|
+
}
|
|
148
|
+
export declare const ROW_DRAG_MIME = "application/x-cqa-test-ids";
|
|
149
|
+
/** Custom MIME for folder-row drags in the sidebar. Payload is a JSON-stringified folder id. */
|
|
150
|
+
export declare const FOLDER_DRAG_MIME = "application/x-cqa-folder-id";
|