@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.
- 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 +1 -1
- 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 +3408 -178
- package/fesm2015/cqa-lib-cqa-ui.mjs.map +1 -1
- package/fesm2020/cqa-lib-cqa-ui.mjs +3388 -176
- 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
|
@@ -17,5 +17,6 @@ export declare const EMPTY_STATE_IMAGES: {
|
|
|
17
17
|
readonly ANALYTICS_CHART: "assets/images/ReportsIcon.png";
|
|
18
18
|
readonly DEFAULT: "assets/images/SearchIcon.png";
|
|
19
19
|
readonly COMPARE_RUNS: "assets/images/CompareRunsIcon.png";
|
|
20
|
+
readonly EMPTY_FOLDER_STATE: "assets/images/EmptyFolderState.png";
|
|
20
21
|
};
|
|
21
22
|
export declare type EmptyStateImageKey = keyof typeof EMPTY_STATE_IMAGES;
|
|
@@ -18,6 +18,7 @@ export declare class SegmentControlComponent implements OnChanges, AfterViewInit
|
|
|
18
18
|
containerBgColor: string;
|
|
19
19
|
/** When true, the control stretches to fill its parent and buttons share equal width. */
|
|
20
20
|
fullWidth: boolean;
|
|
21
|
+
size: 'md' | 'lg';
|
|
21
22
|
get hostDisplay(): string;
|
|
22
23
|
get hostWidth(): string;
|
|
23
24
|
valueChange: EventEmitter<string>;
|
|
@@ -47,6 +48,6 @@ export declare class SegmentControlComponent implements OnChanges, AfterViewInit
|
|
|
47
48
|
private updateIndicator;
|
|
48
49
|
get isIndicatorVisible(): boolean;
|
|
49
50
|
static ɵfac: i0.ɵɵFactoryDeclaration<SegmentControlComponent, never>;
|
|
50
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<SegmentControlComponent, "cqa-segment-control", never, { "segments": "segments"; "value": "value"; "disabled": "disabled"; "containerBgColor": "containerBgColor"; "fullWidth": "fullWidth"; }, { "valueChange": "valueChange"; }, never, never>;
|
|
51
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<SegmentControlComponent, "cqa-segment-control", never, { "segments": "segments"; "value": "value"; "disabled": "disabled"; "containerBgColor": "containerBgColor"; "fullWidth": "fullWidth"; "size": "size"; }, { "valueChange": "valueChange"; }, never, never>;
|
|
51
52
|
}
|
|
52
53
|
export {};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { QueryList, TemplateRef, EventEmitter, ViewContainerRef, Type, OnDestroy, ChangeDetectorRef, OnChanges, SimpleChanges } from "@angular/core";
|
|
2
2
|
import { DomSanitizer, SafeHtml } from "@angular/platform-browser";
|
|
3
|
+
import { DndDropEvent } from "ngx-drag-drop";
|
|
3
4
|
import { DynamicCellTemplateDirective, DynamicHeaderTemplateDirective } from "./dynamic-cell.directive";
|
|
4
5
|
import { ComponentRenderConfig } from "./component-render-config.interface";
|
|
5
6
|
import * as i0 from "@angular/core";
|
|
@@ -60,6 +61,30 @@ export declare class DynamicTableComponent implements OnDestroy, OnChanges {
|
|
|
60
61
|
path: string;
|
|
61
62
|
source: string;
|
|
62
63
|
}) => void;
|
|
64
|
+
/**
|
|
65
|
+
* When true, renders a drag-handle column as the leftmost cell and enables
|
|
66
|
+
* row drag-and-drop reordering via ngx-drag-drop. Off by default so existing
|
|
67
|
+
* consumers are unaffected.
|
|
68
|
+
*/
|
|
69
|
+
enableRowReorder: boolean;
|
|
70
|
+
/** Tooltip for the drag handle icon. */
|
|
71
|
+
reorderHandleTooltip: string;
|
|
72
|
+
/**
|
|
73
|
+
* Emitted after a successful row drop. `orderedData` is a freshly allocated
|
|
74
|
+
* array reflecting the new order — parents should assign it back to `[data]`
|
|
75
|
+
* rather than relying on in-place mutation.
|
|
76
|
+
*/
|
|
77
|
+
rowReorder: EventEmitter<{
|
|
78
|
+
previousIndex: number;
|
|
79
|
+
currentIndex: number;
|
|
80
|
+
orderedData: any[];
|
|
81
|
+
}>;
|
|
82
|
+
/** Index of the row the cursor is currently hovering during a reorder drag. */
|
|
83
|
+
dropHoverIndex: number | null;
|
|
84
|
+
/** Whether the cursor is in the top or bottom half of the hovered row. */
|
|
85
|
+
dropPosition: 'above' | 'below' | null;
|
|
86
|
+
/** The row currently being dragged — used to suppress the indicator on the source row. */
|
|
87
|
+
private draggedRow;
|
|
63
88
|
cellTemplates: QueryList<DynamicCellTemplateDirective>;
|
|
64
89
|
headerTemplates: QueryList<DynamicHeaderTemplateDirective>;
|
|
65
90
|
emptyTableTpl?: TemplateRef<any>;
|
|
@@ -122,6 +147,23 @@ export declare class DynamicTableComponent implements OnDestroy, OnChanges {
|
|
|
122
147
|
getSanitizedHtml(value: string): SafeHtml;
|
|
123
148
|
getCellValue(row: any, path?: string): any;
|
|
124
149
|
trackByIndex(index: number): number;
|
|
150
|
+
onRowDragStart(row: any): void;
|
|
151
|
+
onRowDragEnd(): void;
|
|
152
|
+
/**
|
|
153
|
+
* Fires continuously while a drag is over a row. Computes whether the cursor
|
|
154
|
+
* is in the top or bottom half of the row and updates the indicator state.
|
|
155
|
+
* Suppresses the indicator on the dragged row itself.
|
|
156
|
+
*/
|
|
157
|
+
onRowDragOver(event: Event, rowIndex: number): void;
|
|
158
|
+
/** Clears the indicator when the cursor leaves the tbody entirely. */
|
|
159
|
+
onTbodyDragLeave(event: Event): void;
|
|
160
|
+
private clearDropIndicator;
|
|
161
|
+
/**
|
|
162
|
+
* Handles a row drop from ngx-drag-drop. Prefers the tracked dragover position
|
|
163
|
+
* (which the user can see live via the insertion line) over `event.index` when
|
|
164
|
+
* computing the final insert slot. Emits a fresh array — does not mutate `data`.
|
|
165
|
+
*/
|
|
166
|
+
onRowDndDrop(event: DndDropEvent): void;
|
|
125
167
|
copyCellJsonPath(path: string, event: Event, source?: string): void;
|
|
126
168
|
private updateGridTemplate;
|
|
127
169
|
isRowSelectable(row: any): boolean;
|
|
@@ -141,5 +183,5 @@ export declare class DynamicTableComponent implements OnDestroy, OnChanges {
|
|
|
141
183
|
toggleSort(col: DynamicTableColumn): void;
|
|
142
184
|
private compareValues;
|
|
143
185
|
static ɵfac: i0.ɵɵFactoryDeclaration<DynamicTableComponent, never>;
|
|
144
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<DynamicTableComponent, "app-dynamic-table", never, { "data": "data"; "columns": "columns"; "emptyState": "emptyState"; "gridTemplateColumns": "gridTemplateColumns"; "screenWidth": "screenWidth"; "enableSelectAll": "enableSelectAll"; "rowSelectable": "rowSelectable"; "enableLocalSort": "enableLocalSort"; "isTableLoading": "isTableLoading"; "isTableDataLoading": "isTableDataLoading"; "cellJsonPathGetter": "cellJsonPathGetter"; "onJsonPathCopiedHandler": "onJsonPathCopiedHandler"; }, { "sortChange": "sortChange"; }, ["emptyTableTpl", "cellTemplates", "headerTemplates"], never>;
|
|
186
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<DynamicTableComponent, "app-dynamic-table", never, { "data": "data"; "columns": "columns"; "emptyState": "emptyState"; "gridTemplateColumns": "gridTemplateColumns"; "screenWidth": "screenWidth"; "enableSelectAll": "enableSelectAll"; "rowSelectable": "rowSelectable"; "enableLocalSort": "enableLocalSort"; "isTableLoading": "isTableLoading"; "isTableDataLoading": "isTableDataLoading"; "cellJsonPathGetter": "cellJsonPathGetter"; "onJsonPathCopiedHandler": "onJsonPathCopiedHandler"; "enableRowReorder": "enableRowReorder"; "reorderHandleTooltip": "reorderHandleTooltip"; }, { "sortChange": "sortChange"; "rowReorder": "rowReorder"; }, ["emptyTableTpl", "cellTemplates", "headerTemplates"], never>;
|
|
145
187
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { ChangeDetectorRef, EventEmitter, OnChanges, OnInit, SimpleChanges } from '@angular/core';
|
|
2
|
+
import { FolderDeleteStrategy, ModularLabels } from '../modular-table-template.models';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
/**
|
|
5
|
+
* Body of the "Delete folder" dialog — a radio-card picker for what happens to
|
|
6
|
+
* the folder's contained test cases.
|
|
7
|
+
*
|
|
8
|
+
* Designed to be usable two ways:
|
|
9
|
+
*
|
|
10
|
+
* 1. **From within this library** via `DialogService.open(...)`. The outer
|
|
11
|
+
* `cqa-dialog` supplies the title/Cancel/Delete-folder buttons; the Delete
|
|
12
|
+
* button reads `strategy` via `getComponentInstance()`.
|
|
13
|
+
*
|
|
14
|
+
* 2. **From the host/UI layer directly** — hosts render this inside their own
|
|
15
|
+
* modal and observe `(strategyChange)`.
|
|
16
|
+
*/
|
|
17
|
+
export declare class DeleteFolderDialogComponent implements OnInit, OnChanges {
|
|
18
|
+
private cdr;
|
|
19
|
+
folderName: string;
|
|
20
|
+
testCount: number;
|
|
21
|
+
hasParent: boolean;
|
|
22
|
+
labels: ModularLabels;
|
|
23
|
+
strategy: FolderDeleteStrategy;
|
|
24
|
+
strategyChange: EventEmitter<FolderDeleteStrategy>;
|
|
25
|
+
constructor(cdr: ChangeDetectorRef);
|
|
26
|
+
ngOnInit(): void;
|
|
27
|
+
ngOnChanges(changes: SimpleChanges): void;
|
|
28
|
+
/** If the folder has no parent, the "move to parent" option isn't available — fall back. */
|
|
29
|
+
private normaliseStrategy;
|
|
30
|
+
get bodyText(): string;
|
|
31
|
+
setStrategy(value: FolderDeleteStrategy): void;
|
|
32
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<DeleteFolderDialogComponent, never>;
|
|
33
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<DeleteFolderDialogComponent, "cqa-delete-folder-dialog", never, { "folderName": "folderName"; "testCount": "testCount"; "hasParent": "hasParent"; "labels": "labels"; "strategy": "strategy"; }, { "strategyChange": "strategyChange"; }, never, never>;
|
|
34
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { ChangeDetectorRef, EventEmitter, OnChanges, OnInit, SimpleChanges } from '@angular/core';
|
|
2
|
+
import { FolderNode, ModularLabels } from '../modular-table-template.models';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
interface FlatFolderRow {
|
|
5
|
+
id: number | null;
|
|
6
|
+
name: string;
|
|
7
|
+
depth: number;
|
|
8
|
+
disabled: boolean;
|
|
9
|
+
hasChildren: boolean;
|
|
10
|
+
expanded: boolean;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Folder-picker body used inside the Move-to-Folder dialog.
|
|
14
|
+
*
|
|
15
|
+
* This component is designed to be usable two ways:
|
|
16
|
+
*
|
|
17
|
+
* 1. **From inside the library** via `DialogService.open({ content: { type: 'component', component: MoveToFolderDialogComponent, inputs: {...} } })`.
|
|
18
|
+
* The outer `cqa-dialog` provides the title, description, Cancel and "Move here"
|
|
19
|
+
* buttons; the Move button reads `pickedFolderId` via `dialogRef.getComponentInstance()`.
|
|
20
|
+
*
|
|
21
|
+
* 2. **From the host/UI layer directly** once API ownership moves up. The host
|
|
22
|
+
* renders `<cqa-move-to-folder-dialog>` inside its own modal shell and
|
|
23
|
+
* listens to `(folderPicked)` (fires on every pick) to drive its own "Move here"
|
|
24
|
+
* button. All visual state lives on `pickedFolderId` so hosts can also two-way
|
|
25
|
+
* bind if they prefer.
|
|
26
|
+
*/
|
|
27
|
+
export declare class MoveToFolderDialogComponent implements OnInit, OnChanges {
|
|
28
|
+
private cdr;
|
|
29
|
+
/** Folder tree to pick from. */
|
|
30
|
+
folders: FolderNode[];
|
|
31
|
+
/** Label overrides. */
|
|
32
|
+
labels: ModularLabels;
|
|
33
|
+
/** The folder the tests currently live in — rendered as disabled (can't move into itself). */
|
|
34
|
+
currentFolderId: number | null;
|
|
35
|
+
/** Controls which folder is visually selected. Two-way-bind friendly via `pickedFolderIdChange`. */
|
|
36
|
+
pickedFolderId: number | null;
|
|
37
|
+
/** Folder ids to expand by default. If not provided, ancestors of `currentFolderId` are expanded. */
|
|
38
|
+
initialExpandedIds?: number[];
|
|
39
|
+
/** Fires whenever the user picks a destination. */
|
|
40
|
+
folderPicked: EventEmitter<number>;
|
|
41
|
+
/** Companion output for banana-in-the-box `[(pickedFolderId)]` binding. */
|
|
42
|
+
pickedFolderIdChange: EventEmitter<number>;
|
|
43
|
+
private expandedIds;
|
|
44
|
+
constructor(cdr: ChangeDetectorRef);
|
|
45
|
+
ngOnInit(): void;
|
|
46
|
+
ngOnChanges(changes: SimpleChanges): void;
|
|
47
|
+
private seedExpandedIds;
|
|
48
|
+
private collectAncestors;
|
|
49
|
+
get flatRows(): FlatFolderRow[];
|
|
50
|
+
isPicked(id: number | null): boolean;
|
|
51
|
+
pick(id: number | null): void;
|
|
52
|
+
toggleExpanded(id: number, event: Event): void;
|
|
53
|
+
trackById: (_: number, row: FlatFolderRow) => number;
|
|
54
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<MoveToFolderDialogComponent, never>;
|
|
55
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<MoveToFolderDialogComponent, "cqa-move-to-folder-dialog", never, { "folders": "folders"; "labels": "labels"; "currentFolderId": "currentFolderId"; "pickedFolderId": "pickedFolderId"; "initialExpandedIds": "initialExpandedIds"; }, { "folderPicked": "folderPicked"; "pickedFolderIdChange": "pickedFolderIdChange"; }, never, never>;
|
|
56
|
+
}
|
|
57
|
+
export {};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { ChangeDetectorRef, EventEmitter, OnInit } from '@angular/core';
|
|
2
|
+
import { FormGroup } from '@angular/forms';
|
|
3
|
+
import { DynamicSelectFieldConfig } from '../../../dynamic-select/dynamic-select-field.component';
|
|
4
|
+
import { FolderNode, ModularLabels } from '../modular-table-template.models';
|
|
5
|
+
import * as i0 from "@angular/core";
|
|
6
|
+
export declare const DEFAULT_FOLDER_COLOR = "#99999E";
|
|
7
|
+
/**
|
|
8
|
+
* Body of the "New Folder" dialog.
|
|
9
|
+
*
|
|
10
|
+
* Uses reusable library components (`cqa-custom-input` for the name field,
|
|
11
|
+
* `cqa-dynamic-select` for the parent dropdown) so hosts can drop this dialog
|
|
12
|
+
* into their own modal shell without worrying about styling drift.
|
|
13
|
+
*
|
|
14
|
+
* Two integration paths:
|
|
15
|
+
*
|
|
16
|
+
* 1. **From within this library** via `DialogService.open(...)`. The outer
|
|
17
|
+
* `cqa-dialog` supplies title/description/Cancel/Create-folder buttons; the
|
|
18
|
+
* Create button reads `name` + `parentId` via `getComponentInstance()`.
|
|
19
|
+
*
|
|
20
|
+
* 2. **Host-driven** — host renders `<cqa-new-folder-dialog>` inside its own
|
|
21
|
+
* modal and listens to `(submitted)` / `(cancelled)` / `(nameChange)` /
|
|
22
|
+
* `(parentIdChange)`.
|
|
23
|
+
*/
|
|
24
|
+
export declare class NewFolderDialogComponent implements OnInit {
|
|
25
|
+
private cdr;
|
|
26
|
+
private _folders;
|
|
27
|
+
set folders(value: FolderNode[]);
|
|
28
|
+
get folders(): FolderNode[];
|
|
29
|
+
private _labels;
|
|
30
|
+
set labels(value: ModularLabels);
|
|
31
|
+
get labels(): ModularLabels;
|
|
32
|
+
name: string;
|
|
33
|
+
private _parentId;
|
|
34
|
+
set parentId(value: number | null);
|
|
35
|
+
get parentId(): number | null;
|
|
36
|
+
color: string;
|
|
37
|
+
readonly presetColors: string[];
|
|
38
|
+
readonly rainbowBorder: string;
|
|
39
|
+
nameChange: EventEmitter<string>;
|
|
40
|
+
parentIdChange: EventEmitter<number>;
|
|
41
|
+
colorChange: EventEmitter<string>;
|
|
42
|
+
submitted: EventEmitter<{
|
|
43
|
+
name: string;
|
|
44
|
+
parentId: number | null;
|
|
45
|
+
color: string;
|
|
46
|
+
}>;
|
|
47
|
+
cancelled: EventEmitter<void>;
|
|
48
|
+
/** Reactive form used by cqa-dynamic-select. Untyped to match the project's Angular 13.4 forms API. */
|
|
49
|
+
parentForm: FormGroup;
|
|
50
|
+
/**
|
|
51
|
+
* Config passed to `cqa-dynamic-select`. Stored as a field (not a getter) so
|
|
52
|
+
* the object reference is stable across change-detection passes — a getter
|
|
53
|
+
* returns a fresh object every CD tick and causes
|
|
54
|
+
* `ExpressionChangedAfterItHasBeenCheckedError` + repeated `ngOnChanges` on
|
|
55
|
+
* the child select. Other consumers in this lib (e.g. `loop-step`) follow
|
|
56
|
+
* the same pattern.
|
|
57
|
+
*/
|
|
58
|
+
parentSelectConfig: DynamicSelectFieldConfig;
|
|
59
|
+
private parentOptions;
|
|
60
|
+
constructor(cdr: ChangeDetectorRef);
|
|
61
|
+
ngOnInit(): void;
|
|
62
|
+
private rebuildSelectConfig;
|
|
63
|
+
private rebuildOptions;
|
|
64
|
+
private syncParentControl;
|
|
65
|
+
onNameChange(value: string): void;
|
|
66
|
+
onParentSelectionChange(event: {
|
|
67
|
+
key: string;
|
|
68
|
+
value: any;
|
|
69
|
+
}): void;
|
|
70
|
+
isColor(c: string): boolean;
|
|
71
|
+
get isCustomColor(): boolean;
|
|
72
|
+
onColorChange(value: string): void;
|
|
73
|
+
onColorInputEvent(event: Event): void;
|
|
74
|
+
/** Returns true when the current state is a valid submission (non-empty, trimmed name). */
|
|
75
|
+
get isValid(): boolean;
|
|
76
|
+
submit(): void;
|
|
77
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<NewFolderDialogComponent, never>;
|
|
78
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<NewFolderDialogComponent, "cqa-new-folder-dialog", never, { "folders": "folders"; "labels": "labels"; "name": "name"; "parentId": "parentId"; "color": "color"; }, { "nameChange": "nameChange"; "parentIdChange": "parentIdChange"; "colorChange": "colorChange"; "submitted": "submitted"; "cancelled": "cancelled"; }, never, never>;
|
|
79
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as i0 from "@angular/core";
|
|
2
|
+
export declare class FolderDragDirective {
|
|
3
|
+
/** Folder id being dragged. */
|
|
4
|
+
folderId: number | null;
|
|
5
|
+
dragEnabled: boolean;
|
|
6
|
+
get draggable(): string;
|
|
7
|
+
onDragStart(event: DragEvent): void;
|
|
8
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<FolderDragDirective, never>;
|
|
9
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<FolderDragDirective, "[cqaFolderDrag]", never, { "folderId": "cqaFolderDrag"; "dragEnabled": "dragEnabled"; }, {}, never>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { EventEmitter } from '@angular/core';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
export declare class FolderDropDirective {
|
|
4
|
+
/** Folder id this drop target represents. `null` means "unorganised / root". */
|
|
5
|
+
targetFolderId: number | null;
|
|
6
|
+
dropEnabled: boolean;
|
|
7
|
+
testsDropped: EventEmitter<{
|
|
8
|
+
testIds: Array<string | number>;
|
|
9
|
+
targetFolderId: number | null;
|
|
10
|
+
}>;
|
|
11
|
+
/** Fires when a folder row is dropped here. `folderId` is the dragged folder's id. */
|
|
12
|
+
folderDropped: EventEmitter<{
|
|
13
|
+
folderId: number;
|
|
14
|
+
targetFolderId: number | null;
|
|
15
|
+
}>;
|
|
16
|
+
isOver: boolean;
|
|
17
|
+
onDragOver(event: DragEvent): void;
|
|
18
|
+
onDragLeave(): void;
|
|
19
|
+
onDrop(event: DragEvent): void;
|
|
20
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<FolderDropDirective, never>;
|
|
21
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<FolderDropDirective, "[cqaFolderDrop]", never, { "targetFolderId": "cqaFolderDrop"; "dropEnabled": "dropEnabled"; }, { "testsDropped": "testsDropped"; "folderDropped": "folderDropped"; }, never>;
|
|
22
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as i0 from "@angular/core";
|
|
2
|
+
export declare class RowDragDirective {
|
|
3
|
+
/** Function that returns the test id payload for this row (array of ids). */
|
|
4
|
+
buildPayload: () => Array<string | number>;
|
|
5
|
+
dragEnabled: boolean;
|
|
6
|
+
get draggable(): string;
|
|
7
|
+
onDragStart(event: DragEvent): void;
|
|
8
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<RowDragDirective, never>;
|
|
9
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<RowDragDirective, "[cqaRowDrag]", never, { "buildPayload": "cqaRowDrag"; "dragEnabled": "dragEnabled"; }, {}, never>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { ChangeDetectorRef, EventEmitter, OnDestroy } from '@angular/core';
|
|
2
|
+
import { FolderNode, FolderRenamedPayload, ModularLabels } from '../modular-table-template.models';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
interface RenderNode {
|
|
5
|
+
node: FolderNode;
|
|
6
|
+
depth: number;
|
|
7
|
+
visible: boolean;
|
|
8
|
+
hasChildren: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare class FolderSidebarComponent implements OnDestroy {
|
|
11
|
+
private cdr;
|
|
12
|
+
folders: FolderNode[];
|
|
13
|
+
selectedFolderId: number | null;
|
|
14
|
+
expandedFolderIds: number[];
|
|
15
|
+
unorganisedCount: number;
|
|
16
|
+
allowCreate: boolean;
|
|
17
|
+
allowRename: boolean;
|
|
18
|
+
allowDelete: boolean;
|
|
19
|
+
allowMove: boolean;
|
|
20
|
+
allowDuplicate: boolean;
|
|
21
|
+
allowDrop: boolean;
|
|
22
|
+
showCounts: boolean;
|
|
23
|
+
collapsed: boolean;
|
|
24
|
+
labels: ModularLabels;
|
|
25
|
+
folderSelected: EventEmitter<number>;
|
|
26
|
+
folderExpansionToggled: EventEmitter<{
|
|
27
|
+
id: number;
|
|
28
|
+
expanded: boolean;
|
|
29
|
+
}>;
|
|
30
|
+
/** Emitted after the host completes folder creation (e.g., inline rename flow). Reserved for future use. */
|
|
31
|
+
folderCreated: EventEmitter<{
|
|
32
|
+
parentId: number | null;
|
|
33
|
+
name: string;
|
|
34
|
+
}>;
|
|
35
|
+
/** Emitted when the user clicks the "+" header button. Host should open a creation modal. */
|
|
36
|
+
folderCreateRequested: EventEmitter<{
|
|
37
|
+
parentId: number | null;
|
|
38
|
+
}>;
|
|
39
|
+
/** Carries the full renamed folder node + parent id so hosts can issue complete update requests. */
|
|
40
|
+
folderRenamed: EventEmitter<FolderRenamedPayload>;
|
|
41
|
+
folderDeleted: EventEmitter<{
|
|
42
|
+
id: number;
|
|
43
|
+
}>;
|
|
44
|
+
/** User picked "Move folder" from the context menu. Host opens the folder picker. */
|
|
45
|
+
folderMoveRequested: EventEmitter<{
|
|
46
|
+
id: number;
|
|
47
|
+
}>;
|
|
48
|
+
/** User picked "Duplicate folder" from the context menu. Host clones the subtree (tests referenced, not copied). */
|
|
49
|
+
folderDuplicateRequested: EventEmitter<{
|
|
50
|
+
id: number;
|
|
51
|
+
}>;
|
|
52
|
+
testsDropped: EventEmitter<{
|
|
53
|
+
testIds: Array<string | number>;
|
|
54
|
+
targetFolderId: number | null;
|
|
55
|
+
}>;
|
|
56
|
+
/** Fires when a folder row is dropped onto another folder (or the Unorganised row). */
|
|
57
|
+
folderDropped: EventEmitter<{
|
|
58
|
+
id: number;
|
|
59
|
+
newParentId: number | null;
|
|
60
|
+
}>;
|
|
61
|
+
collapsedChange: EventEmitter<boolean>;
|
|
62
|
+
searchValue: string;
|
|
63
|
+
renamingId: number | null;
|
|
64
|
+
renameDraft: string;
|
|
65
|
+
/** Id of the folder whose context menu is open, or null when closed. */
|
|
66
|
+
contextMenuFolderId: number | null;
|
|
67
|
+
/** Viewport-anchored position (client coordinates) for the floating menu. */
|
|
68
|
+
contextMenuPosition: {
|
|
69
|
+
x: number;
|
|
70
|
+
y: number;
|
|
71
|
+
};
|
|
72
|
+
/** Pending auto-expand timers while a folder drag is hovered over collapsed rows. */
|
|
73
|
+
private dragExpandTimers;
|
|
74
|
+
private readonly DRAG_EXPAND_DELAY_MS;
|
|
75
|
+
/** Id of the folder currently being dragged; used to skip cycle targets and source-hover expansion. */
|
|
76
|
+
private activeFolderDragId;
|
|
77
|
+
constructor(cdr: ChangeDetectorRef);
|
|
78
|
+
get expandedSet(): Set<number>;
|
|
79
|
+
/** Flattened, depth-aware list of rows to render in order. Ancestors of matches are kept. */
|
|
80
|
+
get rows(): RenderNode[];
|
|
81
|
+
isExpanded(id: number): boolean;
|
|
82
|
+
isSelected(id: number | null): boolean;
|
|
83
|
+
onToggle(n: FolderNode, event: Event): void;
|
|
84
|
+
onSelect(n: FolderNode | null): void;
|
|
85
|
+
onSelectUnorganised(): void;
|
|
86
|
+
beginRename(n: FolderNode, event: Event): void;
|
|
87
|
+
commitRename(n: FolderNode): void;
|
|
88
|
+
cancelRename(): void;
|
|
89
|
+
onRenameKey(event: KeyboardEvent, n: FolderNode): void;
|
|
90
|
+
deleteFolder(n: FolderNode, event: Event): void;
|
|
91
|
+
/**
|
|
92
|
+
* Opens the folder context menu anchored at the given client coordinates.
|
|
93
|
+
* Called from both (contextmenu) on the row and (click) on the ellipsis button.
|
|
94
|
+
* Menu visibility is clamped in the template via CSS transforms so it never leaves the viewport.
|
|
95
|
+
*/
|
|
96
|
+
openContextMenu(n: FolderNode, event: MouseEvent): void;
|
|
97
|
+
closeContextMenu(): void;
|
|
98
|
+
/** True when at least one menu entry is enabled — otherwise the trigger is suppressed entirely. */
|
|
99
|
+
get hasAnyContextAction(): boolean;
|
|
100
|
+
onContextCreateSubfolder(n: FolderNode): void;
|
|
101
|
+
onContextRename(n: FolderNode): void;
|
|
102
|
+
onContextMove(n: FolderNode): void;
|
|
103
|
+
onContextDuplicate(n: FolderNode): void;
|
|
104
|
+
onContextDelete(n: FolderNode): void;
|
|
105
|
+
onDocumentClick(): void;
|
|
106
|
+
onEscape(): void;
|
|
107
|
+
/** Template helper: resolve a folder node by id from the input tree. */
|
|
108
|
+
folderById(id: number | null): FolderNode | null;
|
|
109
|
+
/** Returns the parent id of `id`, or null when `id` is a root folder / not found. */
|
|
110
|
+
private parentIdOf;
|
|
111
|
+
requestCreate(parentId?: number | null): void;
|
|
112
|
+
togglePanel(): void;
|
|
113
|
+
rowDropped(targetId: number | null, event: {
|
|
114
|
+
testIds: Array<string | number>;
|
|
115
|
+
targetFolderId: number | null;
|
|
116
|
+
}): void;
|
|
117
|
+
/**
|
|
118
|
+
* Drop target received a folder drag. Validate against self/descendant cycles and
|
|
119
|
+
* emit `folderDropped` if the move is legal. Called from the directive's
|
|
120
|
+
* `(folderDropped)` output on every row and on the Unorganised row.
|
|
121
|
+
*/
|
|
122
|
+
onFolderRowDropped(targetId: number | null, event: {
|
|
123
|
+
folderId: number;
|
|
124
|
+
targetFolderId: number | null;
|
|
125
|
+
}): void;
|
|
126
|
+
/** Remember the dragged folder so we can block self-hover expansion and cycle drops. */
|
|
127
|
+
onFolderDragStart(n: FolderNode): void;
|
|
128
|
+
onFolderDragEnd(): void;
|
|
129
|
+
/** Schedule an auto-expand for a collapsed folder that has children during drag-hover. */
|
|
130
|
+
onFolderRowDragOver(row: RenderNode): void;
|
|
131
|
+
onFolderRowDragLeave(row: RenderNode): void;
|
|
132
|
+
onDocumentDragEnd(): void;
|
|
133
|
+
/** True when `candidateId` is `sourceId` itself or any descendant of it. */
|
|
134
|
+
private isDescendantOf;
|
|
135
|
+
private clearAllExpandTimers;
|
|
136
|
+
ngOnDestroy(): void;
|
|
137
|
+
trackByRow: (_: number, row: RenderNode) => number;
|
|
138
|
+
onRowKeydown(event: KeyboardEvent, row: RenderNode, index: number): void;
|
|
139
|
+
private focusRowElement;
|
|
140
|
+
/**
|
|
141
|
+
* Focuses the inline rename input for the given folder. Uses `setTimeout` (not
|
|
142
|
+
* microtask) because the input is gated by `*ngIf="renamingId === ..."` and
|
|
143
|
+
* must survive the next OnPush change-detection cycle before it's in the DOM.
|
|
144
|
+
*/
|
|
145
|
+
private focusRenameInput;
|
|
146
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<FolderSidebarComponent, never>;
|
|
147
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<FolderSidebarComponent, "cqa-folder-sidebar", never, { "folders": "folders"; "selectedFolderId": "selectedFolderId"; "expandedFolderIds": "expandedFolderIds"; "unorganisedCount": "unorganisedCount"; "allowCreate": "allowCreate"; "allowRename": "allowRename"; "allowDelete": "allowDelete"; "allowMove": "allowMove"; "allowDuplicate": "allowDuplicate"; "allowDrop": "allowDrop"; "showCounts": "showCounts"; "collapsed": "collapsed"; "labels": "labels"; }, { "folderSelected": "folderSelected"; "folderExpansionToggled": "folderExpansionToggled"; "folderCreated": "folderCreated"; "folderCreateRequested": "folderCreateRequested"; "folderRenamed": "folderRenamed"; "folderDeleted": "folderDeleted"; "folderMoveRequested": "folderMoveRequested"; "folderDuplicateRequested": "folderDuplicateRequested"; "testsDropped": "testsDropped"; "folderDropped": "folderDropped"; "collapsedChange": "collapsedChange"; }, never, never>;
|
|
148
|
+
}
|
|
149
|
+
export {};
|