@cqa-lib/cqa-ui 1.1.525 → 1.1.526

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.
Files changed (45) hide show
  1. package/esm2020/lib/assets/images/image-assets.constants.mjs +3 -1
  2. package/esm2020/lib/compare-runs/compare-runs.component.mjs +1 -1
  3. package/esm2020/lib/execution-screen/db-query-execution-item/db-query-execution-item.component.mjs +1 -1
  4. package/esm2020/lib/execution-screen/db-verification-step/db-verification-step.component.mjs +1 -1
  5. package/esm2020/lib/iterations-loop/iterations-loop.component.mjs +1 -1
  6. package/esm2020/lib/segment-control/segment-control.component.mjs +6 -3
  7. package/esm2020/lib/simulator/simulator.component.mjs +1 -1
  8. package/esm2020/lib/step-builder/step-builder-document-generation-template-step/step-builder-document-generation-template-step.component.mjs +1 -1
  9. package/esm2020/lib/table/dynamic-table/dynamic-table.component.mjs +148 -4
  10. package/esm2020/lib/templates/modular-table-template/dialogs/delete-folder-dialog.component.mjs +181 -0
  11. package/esm2020/lib/templates/modular-table-template/dialogs/move-to-folder-dialog.component.mjs +264 -0
  12. package/esm2020/lib/templates/modular-table-template/dialogs/new-folder-dialog.component.mjs +352 -0
  13. package/esm2020/lib/templates/modular-table-template/directives/folder-drag.directive.mjs +45 -0
  14. package/esm2020/lib/templates/modular-table-template/directives/folder-drop.directive.mjs +95 -0
  15. package/esm2020/lib/templates/modular-table-template/directives/row-drag.directive.mjs +44 -0
  16. package/esm2020/lib/templates/modular-table-template/folder-sidebar/folder-sidebar.component.mjs +479 -0
  17. package/esm2020/lib/templates/modular-table-template/modular-table-template.component.mjs +1475 -0
  18. package/esm2020/lib/templates/modular-table-template/modular-table-template.models.mjs +79 -0
  19. package/esm2020/lib/templates/table-template.component.mjs +88 -12
  20. package/esm2020/lib/test-case-details/api-edit-step/api-edit-step.component.mjs +1 -1
  21. package/esm2020/lib/ui-kit.module.mjs +41 -1
  22. package/esm2020/public-api.mjs +10 -1
  23. package/fesm2015/cqa-lib-cqa-ui.mjs +3408 -178
  24. package/fesm2015/cqa-lib-cqa-ui.mjs.map +1 -1
  25. package/fesm2020/cqa-lib-cqa-ui.mjs +3388 -176
  26. package/fesm2020/cqa-lib-cqa-ui.mjs.map +1 -1
  27. package/lib/assets/images/image-assets.constants.d.ts +1 -0
  28. package/lib/segment-control/segment-control.component.d.ts +2 -1
  29. package/lib/table/dynamic-table/dynamic-table.component.d.ts +43 -1
  30. package/lib/templates/modular-table-template/dialogs/delete-folder-dialog.component.d.ts +34 -0
  31. package/lib/templates/modular-table-template/dialogs/move-to-folder-dialog.component.d.ts +57 -0
  32. package/lib/templates/modular-table-template/dialogs/new-folder-dialog.component.d.ts +79 -0
  33. package/lib/templates/modular-table-template/directives/folder-drag.directive.d.ts +10 -0
  34. package/lib/templates/modular-table-template/directives/folder-drop.directive.d.ts +22 -0
  35. package/lib/templates/modular-table-template/directives/row-drag.directive.d.ts +10 -0
  36. package/lib/templates/modular-table-template/folder-sidebar/folder-sidebar.component.d.ts +149 -0
  37. package/lib/templates/modular-table-template/modular-table-template.component.d.ts +453 -0
  38. package/lib/templates/modular-table-template/modular-table-template.models.d.ts +150 -0
  39. package/lib/templates/table-template.component.d.ts +40 -2
  40. package/lib/ui-kit.module.d.ts +153 -145
  41. package/package.json +1 -1
  42. package/public-api.d.ts +9 -0
  43. package/src/lib/assets/images/EmptyFolderState.png +0 -0
  44. package/src/lib/assets/images/image-assets.constants.ts +3 -0
  45. 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";