@cqa-lib/cqa-ui 1.1.557-beta.20 → 1.1.557-beta.24

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.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { EventEmitter, Component, Input, Output, HostListener, HostBinding, ViewChildren, ViewChild, ChangeDetectionStrategy, Directive, TemplateRef, ContentChildren, ContentChild, ElementRef, forwardRef, Optional, Inject, InjectionToken, Injector, Injectable, ChangeDetectorRef, SimpleChange, ViewContainerRef, Pipe, NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
2
+ import { EventEmitter, Component, Input, Output, HostListener, HostBinding, ViewChildren, ViewChild, ChangeDetectionStrategy, Directive, TemplateRef, ContentChildren, ContentChild, ElementRef, forwardRef, Optional, Inject, InjectionToken, Injector, Injectable, Pipe, ChangeDetectorRef, SimpleChange, ViewContainerRef, NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
3
3
  import * as i1 from '@angular/common';
4
4
  import { CommonModule } from '@angular/common';
5
5
  import * as i2$1 from '@angular/forms';
@@ -1007,7 +1007,12 @@ class DialogComponent {
1007
1007
  this.cdr.markForCheck();
1008
1008
  }
1009
1009
  normalizeRole(role) {
1010
- return (role ?? 'secondary').trim().split(/\s+/)[0];
1010
+ const raw = (role ?? 'secondary').trim().split(/\s+/)[0].toLowerCase();
1011
+ // Accept common destructive-action synonyms and map them to 'warn'.
1012
+ if (raw === 'error' || raw === 'danger' || raw === 'destructive') {
1013
+ return 'warn';
1014
+ }
1015
+ return raw;
1011
1016
  }
1012
1017
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DialogComponent, deps: [{ token: i0.ViewContainerRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
1013
1018
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: DialogComponent, selector: "cqa-dialog", host: { classAttribute: "cqa-ui-root" }, viewQueries: [{ propertyName: "portalOutlet", first: true, predicate: CdkPortalOutlet, descendants: true, static: true }], ngImport: i0, template: "<div class=\"cqa-ui-root\">\n <div class=\"cqa-flex cqa-w-full cqa-justify-center cqa-px-4 sm:cqa-px-6\">\n <div [ngClass]=\"panelClassList\" [ngStyle]=\"panelStyles\">\n <div class=\"cqa-flex cqa-flex-col cqa-gap-5\">\n <div class=\"cqa-flex cqa-flex-col cqa-gap-3\">\n <h2 class=\"cqa-text-lg cqa-font-semibold cqa-text-dialog\">\n {{ config.title }}\n </h2>\n\n <p *ngIf=\"config.description\" class=\"cqa-text-sm cqa-leading-6 cqa-text-dialog-secondary\">\n {{ config.description }}\n </p>\n\n <div *ngIf=\"config.warning\"\n class=\"cqa-rounded-xl cqa-border cqa-border-red-200 cqa-bg-red-50 cqa-px-4 cqa-py-3 cqa-text-sm cqa-leading-5 cqa-text-red-700\">\n {{ config.warning }}\n </div>\n </div>\n\n <div class=\"cqa-text-sm cqa-text-dialog\" [class.hidden]=\"!contentAttached\">\n <ng-template cdkPortalOutlet></ng-template>\n </div>\n\n <div class=\"cqa-mt-4 cqa-flex cqa-flex-wrap cqa-gap-3\" [ngClass]=\"buttonAlignmentClass\">\n <cqa-button *ngFor=\"let button of config.buttons\" type=\"button\" [variant]=\"buttonVariant(button)\"\n [disabled]=\"isButtonDisabled(button)\"\n [loading]=\"isButtonLoading(button)\"\n [ngClass]=\"buttonHostClasses(button)\" (clicked)=\"onButtonClick(button)\">\n {{ button.label }}\n </cqa-button>\n </div>\n </div>\n </div>\n </div>\n</div>", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2$2.CdkPortalOutlet, selector: "[cdkPortalOutlet]", inputs: ["cdkPortalOutlet"], outputs: ["attached"], exportAs: ["cdkPortalOutlet"] }, { kind: "component", type: ButtonComponent, selector: "cqa-button", inputs: ["variant", "btnSize", "disabled", "loading", "icon", "iconPosition", "fullWidth", "iconColor", "type", "text", "customClass", "inlineStyles", "tooltip", "tooltipPosition"], outputs: ["clicked"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
@@ -11519,11 +11524,11 @@ class ModularTableTemplateComponent {
11519
11524
  return ids;
11520
11525
  };
11521
11526
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ModularTableTemplateComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: DialogService }], target: i0.ɵɵFactoryTarget.Component });
11522
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: ModularTableTemplateComponent, selector: "cqa-modular-table-template", inputs: { 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", rootFolders: "rootFolders", selectedFolderId: "selectedFolderId", expandedFolderIds: "expandedFolderIds", unorganizedCount: "unorganizedCount", folderIdAccessor: "folderIdAccessor", modularConfig: "modularConfig", modularLabels: "modularLabels", bulkActions: "bulkActions", sidebarCollapsed: "sidebarCollapsed", subfolderSectionExpanded: "subfolderSectionExpanded", organizedSectionExpanded: "organizedSectionExpanded", serverSideSearch: "serverSideSearch", rootTotal: "rootTotal", folderSearchLoading: "folderSearchLoading", folderSearchValue: "folderSearchValue", rootFoldersLoading: "rootFoldersLoading", savingFolderIds: "savingFolderIds", selectedFolderNode: "selectedFolderNode", selectedFolderTrail: "selectedFolderTrail", useInternalDialogs: "useInternalDialogs", showReorderButton: "showReorderButton", reorderSaving: "reorderSaving", reorderLabels: "reorderLabels", columnVisibility: "columnVisibility" }, outputs: { onSearchChange: "onSearchChange", onExportClick: "onExportClick", onApplyFilterClick: "onApplyFilterClick", onResetFilterClick: "onResetFilterClick", onClearAll: "onClearAll", removeChip: "removeChip", viewModeChange: "viewModeChange", pageChange: "pageChange", sortChange: "sortChange", folderSelected: "folderSelected", folderExpansionToggled: "folderExpansionToggled", folderChildrenRequested: "folderChildrenRequested", folderLoadMoreRequested: "folderLoadMoreRequested", rootLoadMoreRequested: "rootLoadMoreRequested", folderSearchChange: "folderSearchChange", folderCreated: "folderCreated", folderCreateRequested: "folderCreateRequested", folderRenamed: "folderRenamed", folderDeleted: "folderDeleted", testsMoved: "testsMoved", bulkActionClick: "bulkActionClick", bulkSelectAllChange: "bulkSelectAllChange", bulkDismiss: "bulkDismiss", bulkActionInvoked: "bulkActionInvoked", sidebarCollapsedChange: "sidebarCollapsedChange", subfolderSectionExpandedChange: "subfolderSectionExpandedChange", organizedSectionExpandedChange: "organizedSectionExpandedChange", 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" }, host: { classAttribute: "cqa-ui-root" }, viewQueries: [{ propertyName: "dynamicFilterComponent", first: true, predicate: DynamicFilterComponent, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<!-- Reusable folder-icon chip. Render via <ng-container *ngTemplateOutlet=\"folderIconChip; context: { color: f.color }\"></ng-container>. -->\n<ng-template #folderIconChip let-color=\"color\">\n <span class=\"cqa-inline-flex cqa-items-center cqa-justify-center cqa-w-10 cqa-h-10 cqa-rounded-lg cqa-bg-[#F0F0F1] cqa-text-[#6D6D74] cqa-flex-shrink-0 group-hover:cqa-bg-indigo-50 group-hover:cqa-text-[#3F43EE]\">\n <svg width=\"14\" height=\"13\" viewBox=\"0 0 14 13\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M12.9583 10.4585C12.9583 10.79 12.8266 11.108 12.5921 11.3424C12.3577 11.5768 12.0398 11.7085 11.7083 11.7085H1.70825C1.37673 11.7085 1.05879 11.5768 0.824368 11.3424C0.589948 11.108 0.458252 10.79 0.458252 10.4585V1.7085C0.458252 1.37698 0.589948 1.05903 0.824368 0.824613C1.05879 0.590192 1.37673 0.458496 1.70825 0.458496H4.83325L6.08325 2.3335H11.7083C12.0398 2.3335 12.3577 2.46519 12.5921 2.69961C12.8266 2.93403 12.9583 3.25198 12.9583 3.5835V10.4585Z\" [attr.stroke]=\"color || 'currentColor'\" stroke-width=\"0.916667\"/>\n </svg>\n </span>\n</ng-template>\n\n<!-- Reusable indeterminate loading spinner. Render via\n <ng-container *ngTemplateOutlet=\"loadingSpinner; context: { size: 20 }\"></ng-container>. -->\n<ng-template #loadingSpinner let-size=\"size\">\n <svg [attr.width]=\"size || 20\" [attr.height]=\"size || 20\" viewBox=\"0 0 50 50\" aria-label=\"loading\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"25\" cy=\"25\" r=\"20\" stroke=\"#E5E7EB\" stroke-width=\"6\" fill=\"none\"></circle>\n <path d=\"M45 25a20 20 0 0 0-20-20\" stroke=\"#4F46E5\" stroke-width=\"6\" fill=\"none\" stroke-linecap=\"round\">\n <animateTransform attributeName=\"transform\" type=\"rotate\" from=\"0 25 25\" to=\"360 25 25\" dur=\"0.8s\" repeatCount=\"indefinite\"></animateTransform>\n </path>\n </svg>\n</ng-template>\n\n<!-- Reusable \"+\" chip used by the \"New folder\" tile. -->\n<ng-template #addIconChip>\n <span class=\"cqa-inline-flex cqa-items-center cqa-justify-center cqa-w-10 cqa-h-10 cqa-rounded-lg cqa-bg-[#F0F0F1] cqa-text-[#6D6D74] cqa-flex-shrink-0 group-hover:cqa-bg-indigo-50 group-hover:cqa-text-[#3F43EE]\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M8 3V13M3 8H13\" stroke=\"currentColor\" stroke-width=\"1.275\" stroke-linecap=\"round\"/>\n </svg>\n </span>\n</ng-template>\n\n<div class=\"cqa-ui-root\">\n <div class=\"cqa-w-full cqa-flex cqa-flex-col cqa-relative\">\n <div [class]=\"!showSearchBar ? 'cqa-justify-end' : 'cqa-justify-between'\" class=\"cqa-w-full cqa-flex cqa-items-center cqa-gap-3 cqa-flex-wrap cqa-mb-3\">\n <cqa-search-bar\n *ngIf=\"showSearchBar\"\n [placeholder]=\"searchPlaceholder\"\n [value]=\"searchValue\"\n [showClear]=\"showClear\"\n (valueChange)=\"valueChange($event)\"\n (search)=\"search($event)\"\n (cleared)=\"cleared()\"\n ></cqa-search-bar>\n <div class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-flex-wrap\">\n <cqa-button\n *ngIf=\"showExportButton\"\n variant=\"grey-solid\"\n icon=\"open_in_new\"\n [text]=\"isExporting ? 'Exporting...' : 'Export'\"\n [disabled]=\"isExporting\"\n (clicked)=\"exportCodeClick()\"\n >\n <span>{{ isExporting ? 'Exporting...' : 'Export' }}</span>\n </cqa-button>\n \n <!-- Export Code Modal -->\n <cqa-export-code-modal\n *ngIf=\"showExportButton\"\n [isOpen]=\"isExportModalOpen\"\n [cases]=\"selectedCasesForExport\"\n [disabled]=\"false\"\n (closeModal)=\"closeExportModal()\"\n (export)=\"onExportModalExport($event)\">\n </cqa-export-code-modal>\n <ng-container *ngFor=\"let dropdownTemplate of otherDropDownButtons; trackBy: trackByDropdownTemplateRef\">\n <ng-container *ngTemplateOutlet=\"dropdownTemplate\"></ng-container>\n </ng-container>\n\n <ng-container *ngFor=\"let selectDropdownTemplate of otherSelectDropDownButtons; trackBy: trackBySelectDropdownTemplateRef\">\n <ng-container *ngTemplateOutlet=\"selectDropdownTemplate\"></ng-container>\n </ng-container>\n \n <cqa-button\n *ngIf=\"showFilterButton\"\n variant=\"grey-solid\"\n icon=\"add\"\n [disabled]=\"isReordering\"\n (clicked)=\"toggleFilter()\"\n >\n <span class=\"cqa-flex cqa-items-center cqa-gap-1\">\n Filter \n <div [class]=\"arrowClasses\">\n <svg\n class=\"cqa-w-2 cqa-h-1 cqa-absolute cqa-left-[4px] cqa-top-[6px]\"\n viewBox=\"0 0 8 4\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M0 0L4 4L8 0\"\n stroke=\"#0B0B0C\"\n stroke-width=\"1.33\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </div>\n </span>\n </cqa-button>\n <cqa-column-visibility\n *ngIf=\"showSettingsButton\"\n [columns]=\"visibilityColumns\"\n [columnVisibility]=\"columnVisibility\"\n [selectedAutoRefreshInterval]=\"selectedAutoRefreshInterval\"\n (columnVisibilityChange)=\"onColumnVisibilityChange($event)\"\n (autoRefreshChange)=\"onAutoRefreshChange($event)\"\n ></cqa-column-visibility>\n <cqa-button\n *ngIf=\"showAutoRefreshButton\"\n variant=\"grey-solid\"\n icon=\"refresh\"\n (clicked)=\"handleRefreshClick()\"\n [tooltip]=\"'Refresh'\"\n tooltipPosition=\"below\"\n [disabled]=\"isReordering\"\n ></cqa-button>\n <ng-container *ngFor=\"let buttonTemplate of otherButtons; trackBy: trackByTemplateRef\">\n <ng-container *ngTemplateOutlet=\"buttonTemplate\"></ng-container>\n </ng-container>\n <cqa-segment-control\n *ngIf=\"showViewModeToggle\"\n size=\"lg\"\n [segments]=\"viewModeSegments\"\n [value]=\"viewMode\"\n (valueChange)=\"onViewModeChange($event)\"\n ></cqa-segment-control>\n <cqa-button\n *ngIf=\"showReorderButton && !isReordering\"\n variant=\"outlined\"\n icon=\"drag_indicator\"\n [text]=\"reorderLabels.reorderButton\"\n [disabled]=\"!pagedRows || pagedRows.length === 0 || isTableLoading || isTableDataLoading\"\n (clicked)=\"startReorder()\"\n ></cqa-button>\n <ng-container *ngIf=\"showReorderButton && isReordering\">\n <cqa-button\n variant=\"outlined\"\n [text]=\"reorderLabels.cancelButton\"\n [disabled]=\"reorderSaving\"\n (clicked)=\"cancelReorder()\"\n ></cqa-button>\n <cqa-button\n variant=\"filled\"\n [icon]=\"reorderSaving ? 'hourglass_empty' : ''\"\n [text]=\"reorderSaving ? reorderLabels.savingButton : reorderLabels.doneButton\"\n [disabled]=\"reorderSaving\"\n (clicked)=\"saveReorder()\"\n ></cqa-button>\n </ng-container>\n </div>\n </div>\n\n <!-- Reorder mode banner -->\n <div *ngIf=\"isReordering\" class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-mb-3 cqa-px-3 cqa-py-2 cqa-rounded-md cqa-bg-[#FFFBEB] cqa-border cqa-border-[#FDE68A]\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <circle cx=\"3\" cy=\"3\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"8\" cy=\"3\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"13\" cy=\"3\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"3\" cy=\"8\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"8\" cy=\"8\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"13\" cy=\"8\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"3\" cy=\"13\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"8\" cy=\"13\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"13\" cy=\"13\" r=\"1.5\" fill=\"#92400E\"></circle>\n </svg>\n <span class=\"cqa-text-sm cqa-font-semibold cqa-text-[#92400E]\">{{ reorderLabels.bannerTitle }}</span>\n <span class=\"cqa-text-sm cqa-text-[#92400E]\">{{ reorderLabels.bannerDescription }}</span>\n </div>\n\n <cqa-selected-filters\n [filterApplied]=\"filterApplied\"\n [chips]=\"chips\"\n (removeChip)=\"onRemoveChip($event)\"\n (clearAll)=\"onClearAllChips()\"\n (onClearAll)=\"onClearAll.emit()\"\n >\n </cqa-selected-filters>\n\n <cqa-dynamic-filter\n *ngIf=\"showFilterPanel\"\n [config]=\"filterConfig\"\n [model]=\"filterModel\"\n [showFilterPanel]=\"showFilterPanel\"\n (filtersChanged)=\"onFiltersChanged($event)\"\n (filtersApplied)=\"onFiltersApplied($event)\"\n (onApplyFilterClick)=\"onApplyFilterClick.emit($event)\"\n (onResetFilterClick)=\"handleResetFilterClick()\"\n >\n </cqa-dynamic-filter>\n\n <div class=\"cqa-flex cqa-items-stretch cqa-gap-2 cqa-min-h-0 \" style=\"border-bottom: 1px solid rgb(226, 226, 227);\">\n <!-- Sidebar (only shown in modular view) -->\n <cqa-folder-sidebar\n *ngIf=\"isModularView && modularConfig.showSidebar\"\n [folders]=\"folders\"\n [selectedFolderId]=\"selectedFolderId\"\n [expandedFolderIds]=\"expandedFolderIds\"\n [unorganizedCount]=\"unorganizedCount\"\n [allowCreate]=\"modularConfig.allowCreateFolder\"\n [allowRename]=\"modularConfig.allowRenameFolder\"\n [allowDelete]=\"modularConfig.allowDeleteFolder\"\n [allowDrop]=\"modularConfig.allowTestDragDrop\"\n [allowDuplicate]=\"modularConfig.allowDuplicateFolder\"\n [showCounts]=\"modularConfig.showCounts\"\n [collapsed]=\"sidebarCollapsed\"\n [labels]=\"modularLabels\"\n [serverSideSearch]=\"serverSideSearch\"\n [rootTotal]=\"rootTotal\"\n [folderSearchLoading]=\"folderSearchLoading\"\n [rootFoldersLoading]=\"rootFoldersLoading\"\n [savingFolderIds]=\"savingFolderIds\"\n [searchValue]=\"folderSearchValue\"\n (folderSelected)=\"onFolderSelected($event)\"\n (folderExpansionToggled)=\"onFolderExpansionToggled($event)\"\n (folderChildrenRequested)=\"folderChildrenRequested.emit($event)\"\n (folderLoadMoreRequested)=\"folderLoadMoreRequested.emit($event)\"\n (rootLoadMoreRequested)=\"rootLoadMoreRequested.emit()\"\n (searchChange)=\"folderSearchChange.emit($event)\"\n (folderCreated)=\"onFolderCreated($event)\"\n (folderCreateRequested)=\"onFolderCreateRequested($event)\"\n (folderRenamed)=\"onFolderRenamed($event)\"\n (folderDeleted)=\"onFolderDeleted($event)\"\n (folderMoveRequested)=\"onFolderMoveRequested($event)\"\n (folderDuplicateRequested)=\"onFolderDuplicateRequested($event)\"\n (testsDropped)=\"onTestsDropped($event)\"\n (folderDropped)=\"onFolderDropped($event)\"\n (collapsedChange)=\"onSidebarCollapsedChange($event)\"\n ></cqa-folder-sidebar>\n\n <!-- Right pane -->\n <div\n class=\"cqa-flex-1 cqa-flex cqa-flex-col cqa-min-w-0\"\n [style.border-top]=\"isModularView ? '1px solid #E2E2E3' : null\"\n [style.border-left]=\"isModularView ? '1px solid #E2E2E3' : null\"\n [style.border-right]=\"isModularView ? '1px solid #E2E2E3' : null\"\n >\n <!-- Breadcrumb (modular view, folder drilled-in) -->\n <nav\n *ngIf=\"isModularView && modularConfig.showBreadcrumb && !isRootView\"\n aria-label=\"Folder path\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-text-sm cqa-px-3 cqa-py-2 cqa-rounded-none cqa-min-w-0\"\n style=\"color: #6D6D74; border-bottom: 1px solid #E2E2E3;\"\n >\n <div class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-flex-1 cqa-min-w-0 cqa-overflow-x-auto cqa-scrollbar-thin cqa-whitespace-nowrap\">\n <button type=\"button\" class=\"hover:cqa-text-[#3F43EE] cqa-inline-flex cqa-items-center cqa-gap-1 cqa-flex-shrink-0\" (click)=\"onFolderSelected(null)\">\n <svg width=\"14\" height=\"13\" viewBox=\"0 0 14 13\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M12.9583 10.4585C12.9583 10.79 12.8266 11.108 12.5921 11.3424C12.3577 11.5768 12.0398 11.7085 11.7083 11.7085H1.70825C1.37673 11.7085 1.05879 11.5768 0.824368 11.3424C0.589948 11.108 0.458252 10.79 0.458252 10.4585V1.7085C0.458252 1.37698 0.589948 1.05903 0.824368 0.824613C1.05879 0.590192 1.37673 0.458496 1.70825 0.458496H4.83325L6.08325 2.3335H11.7083C12.0398 2.3335 12.3577 2.46519 12.5921 2.69961C12.8266 2.93403 12.9583 3.25198 12.9583 3.5835V10.4585Z\" stroke=\"currentColor\" stroke-width=\"0.916667\"/>\n </svg>\n <span>{{ modularLabels.allFolders }}</span>\n </button>\n <ng-container *ngFor=\"let crumb of breadcrumbTrail; let last = last\">\n <mat-icon class=\"cqa-align-middle cqa-flex-shrink-0\" style=\"font-size:16px;width:16px;height:16px;color:#6D6D74;\">chevron_right</mat-icon>\n <button\n type=\"button\"\n class=\"cqa-flex-shrink-0\"\n [ngClass]=\"last\n ? 'cqa-text-[#161617] cqa-font-semibold'\n : 'cqa-text-[#6D6D74] hover:cqa-text-[#3F43EE]'\"\n [disabled]=\"last\"\n (click)=\"!last && onFolderSelected(crumb.id)\"\n >{{ crumb.name }}</button>\n </ng-container>\n </div>\n <cqa-button\n *ngIf=\"modularConfig.showSubfolderSection && subfolderTiles.length\"\n class=\"cqa-flex-shrink-0\"\n variant=\"text\"\n btnSize=\"sm\"\n customClass=\"!cqa-text-[13px] !cqa-leading-[18px]\"\n [icon]=\"subfolderSectionExpanded ? 'expand_less' : 'expand_more'\"\n [text]=\"(subfolderSectionExpanded ? 'Hide' : 'Show') + ' subfolders'\"\n [attr.aria-expanded]=\"subfolderSectionExpanded\"\n (clicked)=\"toggleSubfolderSection()\"\n ></cqa-button>\n <cqa-button\n *ngIf=\"modularConfig.allowCreateFolder\"\n class=\"cqa-flex-shrink-0\"\n variant=\"text\"\n btnSize=\"sm\"\n customClass=\"!cqa-text-[13px] !cqa-leading-[18px]\"\n icon=\"add\"\n [text]=\"modularLabels.newFolder\"\n (clicked)=\"onFolderCreateRequested({ parentId: selectedFolderId })\"\n ></cqa-button>\n </nav>\n\n <!-- Folder grid: modular + root view -->\n <section\n *ngIf=\"isModularView && isRootView && modularConfig.showFolderGrid && rootFolderTiles.length\"\n class=\"cqa-px-5 cqa-pt-2\"\n style=\"border-bottom: 1px solid #F0F0F1;\"\n >\n <button\n type=\"button\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-mb-2 cqa-w-full cqa-text-left\"\n [attr.aria-expanded]=\"organizedSectionExpanded\"\n (click)=\"toggleOrganizedSection()\"\n >\n <svg width=\"14\" height=\"13\" viewBox=\"0 0 14 13\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M12.9583 10.4585C12.9583 10.79 12.8266 11.108 12.5921 11.3424C12.3577 11.5768 12.0398 11.7085 11.7083 11.7085H1.70825C1.37673 11.7085 1.05879 11.5768 0.824368 11.3424C0.589948 11.108 0.458252 10.79 0.458252 10.4585V1.7085C0.458252 1.37698 0.589948 1.05903 0.824368 0.824613C1.05879 0.590192 1.37673 0.458496 1.70825 0.458496H4.83325L6.08325 2.3335H11.7083C12.0398 2.3335 12.3577 2.46519 12.5921 2.69961C12.8266 2.93403 12.9583 3.25198 12.9583 3.5835V10.4585Z\" stroke=\"#6D6D74\" stroke-width=\"0.916667\"/>\n </svg>\n <h3 class=\"cqa-text-sm cqa-font-semibold cqa-text-[#6D6D74]\">{{ modularLabels.organized }}</h3>\n <span class=\"cqa-text-xs cqa-text-[#6D6D74]\">\n {{ rootFolderTiles.length === 1 ? modularLabels.foldersCountSingular : modularLabels.foldersCountPlural.replace('{n}', '' + rootFolderTiles.length) }}\n </span>\n <mat-icon class=\"cqa-text-[#6D6D74] cqa-ml-auto\" style=\"font-size:18px;width:18px;height:18px\">\n {{ organizedSectionExpanded ? 'expand_less' : 'expand_more' }}\n </mat-icon>\n </button>\n <div\n class=\"cqa-grid\"\n style=\"transition: grid-template-rows 300ms cubic-bezier(0.4, 0, 0.2, 1);\"\n [style.grid-template-rows]=\"organizedSectionExpanded ? '1fr' : '0fr'\"\n >\n <div class=\"cqa-min-h-0\" style=\"overflow: hidden;\">\n <div class=\"cqa-flex cqa-flex-nowrap cqa-gap-3 cqa-overflow-x-auto cqa-scrollbar-thin cqa-pb-1\"\n (scroll)=\"onRootGridScroll($event)\">\n <button\n *ngFor=\"let f of rootFolderTiles\"\n type=\"button\"\n [cqaFolderDrop]=\"f.id\"\n [dropEnabled]=\"modularConfig.allowTestDragDrop\"\n (testsDropped)=\"onTestsDropped($event)\"\n (click)=\"onFolderSelected(f.id)\"\n class=\"cqa-group cqa-flex-shrink-0 cqa-w-[240px] cqa-flex cqa-items-center cqa-justify-between cqa-gap-3 cqa-text-left cqa-p-3 cqa-rounded-[10px] cqa-border-solid cqa-border-[0.5px] cqa-border-[#E2E2E3] cqa-bg-white hover:cqa-border-[#3F43EE] hover:cqa-shadow-sm cqa-transition-colors\"\n >\n <div class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-min-w-0\">\n <ng-container *ngTemplateOutlet=\"folderIconChip; context: { color: f.color }\"></ng-container>\n <div class=\"cqa-flex cqa-flex-col cqa-min-w-0\">\n <span class=\"cqa-text-[15px] cqa-text-[#161617] cqa-truncate cqa-leading-tight group-hover:cqa-text-[#3F43EE]\">{{ f.name }}</span>\n <span *ngIf=\"modularConfig.showCounts\" class=\"cqa-text-sm cqa-text-neutral-500 cqa-truncate\">\n {{ (f.count ?? 0) === 1 ? modularLabels.testsCountSingular : modularLabels.testsCountPlural.replace('{n}', '' + (f.count ?? 0)) }}<ng-container *ngIf=\"f.children?.length\"> \u00B7 {{ f.children!.length === 1 ? modularLabels.oneSubfolder : modularLabels.subfoldersCount.replace('{n}', '' + f.children!.length) }}</ng-container>\n </span>\n </div>\n </div>\n <mat-icon class=\"cqa-text-neutral-400 cqa-flex-shrink-0\" style=\"font-size:20px;width:20px;height:20px\">chevron_right</mat-icon>\n </button>\n\n <!-- \"+ New folder\" tile -->\n <button\n *ngIf=\"modularConfig.allowCreateFolder\"\n type=\"button\"\n (click)=\"onFolderCreateRequested({ parentId: null })\"\n class=\"cqa-group cqa-flex-shrink-0 cqa-w-[240px] cqa-flex cqa-items-center cqa-gap-3 cqa-text-left cqa-p-3 cqa-rounded-[10px] cqa-border-dashed cqa-border-[0.5px] cqa-border-[#E2E2E3] cqa-bg-[#FAFAFA] hover:cqa-border-[#3F43EE] hover:cqa-bg-white cqa-transition-colors\"\n >\n <ng-container *ngTemplateOutlet=\"addIconChip\"></ng-container>\n <div class=\"cqa-flex cqa-flex-col cqa-min-w-0\">\n <span class=\"cqa-text-[15px] cqa-text-[#161617] cqa-truncate cqa-leading-tight group-hover:cqa-text-[#3F43EE]\">{{ modularLabels.newFolder }}</span>\n <span class=\"cqa-text-sm cqa-text-neutral-400\">{{ modularLabels.testsCountPlural.replace('{n}', '0') }}</span>\n </div>\n </button>\n\n <!-- Pagination spinner anchored at the right edge of the Organized\n row. Only renders during an in-flight root fetch (initial OR\n scroll-driven \"load more\"), and is filtered to suppress when\n the section is empty so we don't show a spinner inside an\n otherwise-blank row. -->\n <div\n *ngIf=\"rootFoldersLoading && rootFolderTiles.length > 0\"\n class=\"cqa-flex-shrink-0 cqa-flex cqa-items-center cqa-justify-center cqa-w-[80px]\"\n aria-live=\"polite\"\n [attr.aria-label]=\"'Loading more folders'\"\n >\n <ng-container *ngTemplateOutlet=\"loadingSpinner; context: { size: 20 }\"></ng-container>\n </div>\n </div>\n </div>\n </div>\n </section>\n\n <!-- Subfolder section: modular + folder view. Shown whenever drilled in\n (even if no subfolders, so the \"+ New folder\" tile remains\n reachable, and so we can render a loading state during the\n drill-in fetch before children arrive). -->\n <section\n *ngIf=\"isModularView && !isRootView && modularConfig.showSubfolderSection && (subfolderTiles.length || currentFolderNode?.childrenLoading)\"\n class=\"cqa-grid\"\n style=\"transition: grid-template-rows 300ms cubic-bezier(0.4, 0, 0.2, 1);\"\n [style.grid-template-rows]=\"subfolderSectionExpanded ? '1fr' : '0fr'\"\n >\n <div class=\"cqa-min-h-0\" style=\"overflow: hidden;\">\n <div class=\"cqa-px-3 cqa-py-2 cqa-flex cqa-flex-nowrap cqa-gap-3 cqa-overflow-x-auto cqa-scrollbar-thin\"\n (scroll)=\"onSubfolderGridScroll($event)\">\n <button\n *ngFor=\"let f of subfolderTiles\"\n type=\"button\"\n [cqaFolderDrop]=\"f.id\"\n [dropEnabled]=\"modularConfig.allowTestDragDrop\"\n (testsDropped)=\"onTestsDropped($event)\"\n (click)=\"onFolderSelected(f.id)\"\n class=\"cqa-group cqa-flex-shrink-0 cqa-w-[240px] cqa-flex cqa-items-center cqa-justify-between cqa-gap-3 cqa-text-left cqa-p-3 cqa-rounded-[10px] cqa-border-solid cqa-border-[0.5px] cqa-border-[#E2E2E3] cqa-bg-white hover:cqa-border-[#3F43EE] hover:cqa-shadow-sm cqa-transition-colors\"\n >\n <div class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-min-w-0\">\n <ng-container *ngTemplateOutlet=\"folderIconChip; context: { color: f.color }\"></ng-container>\n <div class=\"cqa-flex cqa-flex-col cqa-min-w-0\">\n <span class=\"cqa-text-[15px] cqa-text-[#161617] cqa-truncate cqa-leading-tight group-hover:cqa-text-[#3F43EE]\">{{ f.name }}</span>\n <span *ngIf=\"modularConfig.showCounts\" class=\"cqa-text-sm cqa-text-neutral-500 cqa-truncate\">\n {{ (f.count ?? 0) === 1 ? modularLabels.testsCountSingular : modularLabels.testsCountPlural.replace('{n}', '' + (f.count ?? 0)) }}\n </span>\n </div>\n </div>\n <mat-icon class=\"cqa-text-neutral-400 cqa-flex-shrink-0\" style=\"font-size:20px;width:20px;height:20px\">chevron_right</mat-icon>\n </button>\n\n <!-- \"+ New folder\" tile -->\n <button\n *ngIf=\"modularConfig.allowCreateFolder\"\n type=\"button\"\n (click)=\"onFolderCreateRequested({ parentId: selectedFolderId })\"\n class=\"cqa-group cqa-flex-shrink-0 cqa-w-[240px] cqa-flex cqa-items-center cqa-gap-3 cqa-text-left cqa-p-3 cqa-rounded-[10px] cqa-border-dashed cqa-border-[0.5px] cqa-border-[#E2E2E3] cqa-bg-[#FAFAFA] hover:cqa-border-[#3F43EE] hover:cqa-bg-white cqa-transition-colors\"\n >\n <ng-container *ngTemplateOutlet=\"addIconChip\"></ng-container>\n <div class=\"cqa-flex cqa-flex-col cqa-min-w-0\">\n <span class=\"cqa-text-[15px] cqa-text-[#161617] cqa-truncate cqa-leading-tight group-hover:cqa-text-[#3F43EE]\">{{ modularLabels.newFolder }}</span>\n <span class=\"cqa-text-sm cqa-text-neutral-400\">{{ modularLabels.testsCountPlural.replace('{n}', '0') }}</span>\n </div>\n </button>\n\n <!-- Subfolder fetch indicator. Two cases:\n - Drill-in fetch: no subfolderTiles yet, render a centered\n row spinner so the section isn't empty during the fetch.\n - Pagination fetch: tiles exist, anchor a small spinner at\n the right edge so the user knows the next page is loading. -->\n <div\n *ngIf=\"currentFolderNode?.childrenLoading\"\n class=\"cqa-flex-shrink-0 cqa-flex cqa-items-center cqa-justify-center cqa-w-[80px]\"\n aria-live=\"polite\"\n [attr.aria-label]=\"'Loading subfolders'\"\n >\n <ng-container *ngTemplateOutlet=\"loadingSpinner; context: { size: 20 }\"></ng-container>\n </div>\n </div>\n </div>\n </section>\n\n <div\n *ngIf=\"isModularView && !isRootView && modularConfig.showUnorganizedSection\"\n class=\"cqa-flex cqa-items-center cqa-justify-between cqa-px-4 cqa-py-3 cqa-border cqa-border-indigo-100\"\n style=\"background-color: #D8D9FC;\"\n >\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <svg width=\"14\" height=\"13\" viewBox=\"0 0 14 13\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M12.9585 10.4585C12.9585 10.79 12.8268 11.108 12.5924 11.3424C12.358 11.5768 12.04 11.7085 11.7085 11.7085H1.7085C1.37698 11.7085 1.05903 11.5768 0.824613 11.3424C0.590192 11.108 0.458496 10.79 0.458496 10.4585V1.7085C0.458496 1.37698 0.590192 1.05903 0.824613 0.824613C1.05903 0.590192 1.37698 0.458496 1.7085 0.458496H4.8335L6.0835 2.3335H11.7085C12.04 2.3335 12.358 2.46519 12.5924 2.69961C12.8268 2.93403 12.9585 3.25198 12.9585 3.5835V10.4585Z\" stroke=\"#3F43EE\" stroke-width=\"0.916667\"/>\n </svg>\n <span class=\"cqa-text-sm cqa-font-semibold\" style=\"color: #3F43EE;\">\n {{ currentFolderNode?.name }} ({{ currentFolderDirectCount }})\n </span>\n </div>\n <cqa-button\n variant=\"outlined\"\n btnSize=\"sm\"\n customClass=\"!cqa-text-[13px]\"\n inlineStyles=\"border-color: #3F43EE; color: #3F43EE;\"\n [text]=\"modularLabels.clearFilter\"\n (clicked)=\"onFolderSelected(null)\"\n ></cqa-button>\n </div>\n\n <!-- Unorganized section header at root view -->\n <div\n *ngIf=\"isModularView && isRootView && modularConfig.showUnorganizedSection\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-mb-2 cqa-mt-2\" style=\"margin-left: 20px;\"\n >\n <mat-icon class=\"cqa-text-[#6D6D74]\" style=\"font-size:16px;width:16px;height:16px\">inbox</mat-icon>\n <h3 class=\"cqa-text-sm cqa-font-semibold cqa-text-[#6D6D74]\">{{ modularLabels.unorganized }}</h3>\n <span class=\"cqa-text-xs cqa-text-[#6D6D74]\">\n {{ unorganizedCount === 1 ? modularLabels.testsCountSingular : modularLabels.testsCountPlural.replace('{n}', '' + unorganizedCount) }}\n </span>\n </div>\n\n <div class=\"cqa-overflow-hidden cqa-border-t cqa-border-l cqa-border-r cqa-border-grey-200 cqa-relative cqa-overflow-x-auto\"\n [class.cqa-modular-table-flush]=\"isModularView\"\n [attr.style]=\"(!isModularView ? 'border-radius: 7px;' : '') + ((pagedRows && pagedRows.length > 0) ? '' : ' border-bottom: none !important;')\">\n <ng-container *ngIf=\"(isTableLoading || isTableDataLoading) || (!effectiveIsEmptyState && pagedRows && pagedRows.length > 0); else storyEmptyTpl\">\n <app-dynamic-table\n [style.border-bottom]=\"pagedRows && pagedRows.length > 0 ? '1px solid rgb(226, 226, 227)' : null\"\n [columns]=\"computedColumns\"\n [data]=\"pagedRows\"\n [rowSelectable]=\"rowSelectable\"\n [enableLocalSort]=\"enableLocalSort && !isReordering\"\n [isTableLoading]=\"isTableLoading\"\n [isTableDataLoading]=\"isTableDataLoading\"\n [cellJsonPathGetter]=\"cellJsonPathGetter\"\n [onJsonPathCopiedHandler]=\"onJsonPathCopiedHandler\"\n [enableRowReorder]=\"isReordering\"\n (rowReorder)=\"onRowReorder($event)\"\n (sortChange)=\"sortChange.emit($event)\">\n <ng-template #emptyTableTpl>\n <div class=\"cqa-flex cqa-flex-col cqa-items-center cqa-justify-center cqa-py-8\">\n <img src=\"/assets/illustrations/empty-state.svg\" alt=\"No data\" class=\"cqa-w-32 cqa-h-32 cqa-mb-4\" />\n <h3 class=\"cqa-text-lg cqa-font-semibold cqa-mb-2\">No test cases</h3>\n <p class=\"cqa-text-sm cqa-text-neutral-500 cqa-mb-4\">Try adjusting filters or create a new test case.</p>\n <cqa-button variant=\"filled\" (clicked)=\"toggleFilter()\">Show Filters</cqa-button>\n </div>\n </ng-template>\n </app-dynamic-table>\n </ng-container>\n\n <ng-template #storyEmptyTpl>\n <div class=\"cqa-p-6 cqa-flex cqa-flex-col cqa-items-center cqa-justify-center\">\n <cqa-empty-state\n *ngIf=\"effectiveIsEmptyState\"\n [title]=\"effectiveEmptyStateConfig.title\"\n [description]=\"effectiveEmptyStateConfig.description\"\n [imageUrl]=\"effectiveEmptyStateConfig.imageUrl\"\n [actions]=\"effectiveEmptyStateConfig.actions\"\n (actionClick)=\"onEmptyAction($event)\"\n >\n </cqa-empty-state>\n </div>\n </ng-template>\n </div>\n\n <cqa-pagination\n [totalElements]=\"serverSidePagination ? totalElements : filteredRows.length\"\n [pageIndex]=\"pageIndex\"\n [pageSize]=\"pageSize\"\n [pageSizeOptions]=\"pageSizeOptions\"\n [pageSizeMenuDirection]=\"pageSizeMenuDirection\"\n [pageItemCount]=\"pagedRows.length\"\n (paginate)=\"onPaginate($event)\"\n (pageSizeChange)=\"onPageSizeChange($event)\"\n >\n </cqa-pagination>\n </div>\n </div>\n\n <!-- Reused bulk action toolbar -->\n <div *ngIf=\"anyRowSelected && modularConfig.allowBulkSelection && !isReordering\" class=\"cqa-absolute cqa-bottom-[18.75px] cqa-left-[50%] cqa-translate-x-[-50%] cqa-w-full lg:cqa-max-w-[68%] cqa-sm:max-w-[75%] cqa-max-w-[90%] cqa-z-[1]\">\n <cqa-table-action-toolbar\n [selectedItems]=\"selectedItems && selectedItems.length > 0 ? selectedItems : currentSelectedItems\"\n [actions]=\"effectiveBulkActions\"\n [showSelectAll]=\"showSelectAllInToolbar\"\n [allSelected]=\"allSelectedInToolbar\"\n [showDismiss]=\"showDismissInToolbar\"\n (actionClick)=\"onBulkAction($event)\"\n (selectAllChange)=\"onBulkSelectAll($event)\"\n (dismiss)=\"onBulkDismiss()\"\n ></cqa-table-action-toolbar>\n </div>\n\n </div>\n</div>\n\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: ButtonComponent, selector: "cqa-button", inputs: ["variant", "btnSize", "disabled", "loading", "icon", "iconPosition", "fullWidth", "iconColor", "type", "text", "customClass", "inlineStyles", "tooltip", "tooltipPosition"], outputs: ["clicked"] }, { kind: "component", type: SearchBarComponent, selector: "cqa-search-bar", inputs: ["placeholder", "value", "disabled", "showClear", "ariaLabel", "autoFocus", "size", "fullWidth"], outputs: ["valueChange", "search", "cleared"] }, { kind: "component", type: SegmentControlComponent, selector: "cqa-segment-control", inputs: ["segments", "value", "disabled", "containerBgColor", "fullWidth", "size"], outputs: ["valueChange"] }, { kind: "component", type: DynamicTableComponent, selector: "app-dynamic-table", inputs: ["data", "columns", "emptyState", "gridTemplateColumns", "screenWidth", "enableSelectAll", "rowSelectable", "enableLocalSort", "isTableLoading", "isTableDataLoading", "cellJsonPathGetter", "onJsonPathCopiedHandler", "enableRowReorder", "reorderHandleTooltip"], outputs: ["sortChange", "rowReorder"] }, { kind: "component", type: PaginationComponent, selector: "cqa-pagination", inputs: ["totalElements", "totalPages", "pageIndex", "pageSize", "pageItemCount", "pageSizeOptions", "pageSizeMenuDirection"], outputs: ["pageIndexChange", "pageSizeChange", "paginate"] }, { kind: "component", type: DynamicFilterComponent, selector: "cqa-dynamic-filter", inputs: ["config", "model", "showFilterPanel", "buttonLayout"], outputs: ["filtersApplied", "filtersChanged", "resetAction", "onApplyFilterClick", "onResetFilterClick"] }, { kind: "component", type: ColumnVisibilityComponent, selector: "cqa-column-visibility", inputs: ["isStepGroup", "columns", "columnVisibility", "selectedAutoRefreshInterval"], outputs: ["columnVisibilityChange", "autoRefreshChange"] }, { kind: "component", type: TableActionToolbarComponent, selector: "cqa-table-action-toolbar", inputs: ["selectedItems", "actions", "showSelectAll", "allSelected", "showDismiss"], outputs: ["actionClick", "selectAllChange", "dismiss"] }, { kind: "component", type: SelectedFiltersComponent, selector: "cqa-selected-filters", inputs: ["filterApplied", "chips", "defaultChips", "defaultChipClass"], outputs: ["removeChip", "clearAll", "onClearAll"] }, { kind: "component", type: EmptyStateComponent, selector: "cqa-empty-state", inputs: ["preset", "imageUrl", "title", "description", "actions"], outputs: ["actionClick"] }, { kind: "component", type: FolderSidebarComponent, selector: "cqa-folder-sidebar", inputs: ["folders", "selectedFolderId", "expandedFolderIds", "unorganizedCount", "allowCreate", "allowRename", "allowDelete", "allowMove", "allowDuplicate", "allowDrop", "showCounts", "collapsed", "foldersAccordionExpanded", "labels", "serverSideSearch", "rootTotal", "folderSearchLoading", "rootFoldersLoading", "savingFolderIds", "searchValue"], outputs: ["folderSelected", "folderExpansionToggled", "folderChildrenRequested", "folderLoadMoreRequested", "searchChange", "rootLoadMoreRequested", "folderCreated", "folderCreateRequested", "folderRenamed", "folderDeleted", "folderMoveRequested", "folderDuplicateRequested", "testsDropped", "folderDropped", "collapsedChange", "foldersAccordionExpandedChange"] }, { kind: "directive", type: FolderDropDirective, selector: "[cqaFolderDrop]", inputs: ["cqaFolderDrop", "dropEnabled"], outputs: ["testsDropped", "folderDropped"] }, { kind: "component", type: ExportCodeModalComponent, selector: "cqa-export-code-modal", inputs: ["isOpen", "cases", "disabled"], outputs: ["closeModal", "export"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
11527
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: ModularTableTemplateComponent, selector: "cqa-modular-table-template", inputs: { 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", rootFolders: "rootFolders", selectedFolderId: "selectedFolderId", expandedFolderIds: "expandedFolderIds", unorganizedCount: "unorganizedCount", folderIdAccessor: "folderIdAccessor", modularConfig: "modularConfig", modularLabels: "modularLabels", bulkActions: "bulkActions", sidebarCollapsed: "sidebarCollapsed", subfolderSectionExpanded: "subfolderSectionExpanded", organizedSectionExpanded: "organizedSectionExpanded", serverSideSearch: "serverSideSearch", rootTotal: "rootTotal", folderSearchLoading: "folderSearchLoading", folderSearchValue: "folderSearchValue", rootFoldersLoading: "rootFoldersLoading", savingFolderIds: "savingFolderIds", selectedFolderNode: "selectedFolderNode", selectedFolderTrail: "selectedFolderTrail", useInternalDialogs: "useInternalDialogs", showReorderButton: "showReorderButton", reorderSaving: "reorderSaving", reorderLabels: "reorderLabels", columnVisibility: "columnVisibility" }, outputs: { onSearchChange: "onSearchChange", onExportClick: "onExportClick", onApplyFilterClick: "onApplyFilterClick", onResetFilterClick: "onResetFilterClick", onClearAll: "onClearAll", removeChip: "removeChip", viewModeChange: "viewModeChange", pageChange: "pageChange", sortChange: "sortChange", folderSelected: "folderSelected", folderExpansionToggled: "folderExpansionToggled", folderChildrenRequested: "folderChildrenRequested", folderLoadMoreRequested: "folderLoadMoreRequested", rootLoadMoreRequested: "rootLoadMoreRequested", folderSearchChange: "folderSearchChange", folderCreated: "folderCreated", folderCreateRequested: "folderCreateRequested", folderRenamed: "folderRenamed", folderDeleted: "folderDeleted", testsMoved: "testsMoved", bulkActionClick: "bulkActionClick", bulkSelectAllChange: "bulkSelectAllChange", bulkDismiss: "bulkDismiss", bulkActionInvoked: "bulkActionInvoked", sidebarCollapsedChange: "sidebarCollapsedChange", subfolderSectionExpandedChange: "subfolderSectionExpandedChange", organizedSectionExpandedChange: "organizedSectionExpandedChange", 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" }, host: { classAttribute: "cqa-ui-root" }, viewQueries: [{ propertyName: "dynamicFilterComponent", first: true, predicate: DynamicFilterComponent, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<!-- Reusable folder-icon chip. Render via <ng-container *ngTemplateOutlet=\"folderIconChip; context: { color: f.color }\"></ng-container>. -->\n<ng-template #folderIconChip let-color=\"color\">\n <span class=\"cqa-inline-flex cqa-items-center cqa-justify-center cqa-w-10 cqa-h-10 cqa-rounded-lg cqa-bg-[#F0F0F1] cqa-text-[#6D6D74] cqa-flex-shrink-0 group-hover:cqa-bg-indigo-50 group-hover:cqa-text-[#3F43EE]\">\n <svg width=\"14\" height=\"13\" viewBox=\"0 0 14 13\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M12.9583 10.4585C12.9583 10.79 12.8266 11.108 12.5921 11.3424C12.3577 11.5768 12.0398 11.7085 11.7083 11.7085H1.70825C1.37673 11.7085 1.05879 11.5768 0.824368 11.3424C0.589948 11.108 0.458252 10.79 0.458252 10.4585V1.7085C0.458252 1.37698 0.589948 1.05903 0.824368 0.824613C1.05879 0.590192 1.37673 0.458496 1.70825 0.458496H4.83325L6.08325 2.3335H11.7083C12.0398 2.3335 12.3577 2.46519 12.5921 2.69961C12.8266 2.93403 12.9583 3.25198 12.9583 3.5835V10.4585Z\" [attr.stroke]=\"color || 'currentColor'\" stroke-width=\"0.916667\"/>\n </svg>\n </span>\n</ng-template>\n\n<!-- Reusable indeterminate loading spinner. Render via\n <ng-container *ngTemplateOutlet=\"loadingSpinner; context: { size: 20 }\"></ng-container>. -->\n<ng-template #loadingSpinner let-size=\"size\">\n <svg [attr.width]=\"size || 20\" [attr.height]=\"size || 20\" viewBox=\"0 0 50 50\" aria-label=\"loading\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"25\" cy=\"25\" r=\"20\" stroke=\"#E5E7EB\" stroke-width=\"6\" fill=\"none\"></circle>\n <path d=\"M45 25a20 20 0 0 0-20-20\" stroke=\"#4F46E5\" stroke-width=\"6\" fill=\"none\" stroke-linecap=\"round\">\n <animateTransform attributeName=\"transform\" type=\"rotate\" from=\"0 25 25\" to=\"360 25 25\" dur=\"0.8s\" repeatCount=\"indefinite\"></animateTransform>\n </path>\n </svg>\n</ng-template>\n\n<!-- Reusable \"+\" chip used by the \"New folder\" tile. -->\n<ng-template #addIconChip>\n <span class=\"cqa-inline-flex cqa-items-center cqa-justify-center cqa-w-10 cqa-h-10 cqa-rounded-lg cqa-bg-[#F0F0F1] cqa-text-[#6D6D74] cqa-flex-shrink-0 group-hover:cqa-bg-indigo-50 group-hover:cqa-text-[#3F43EE]\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M8 3V13M3 8H13\" stroke=\"currentColor\" stroke-width=\"1.275\" stroke-linecap=\"round\"/>\n </svg>\n </span>\n</ng-template>\n\n<div class=\"cqa-ui-root\">\n <div class=\"cqa-w-full cqa-max-w-full cqa-flex cqa-flex-col cqa-relative cqa-min-w-0\">\n <div [class]=\"!showSearchBar ? 'cqa-justify-end' : 'cqa-justify-between'\" class=\"cqa-w-full cqa-flex cqa-items-center cqa-gap-3 cqa-flex-wrap cqa-mb-3\">\n <cqa-search-bar\n *ngIf=\"showSearchBar\"\n [placeholder]=\"searchPlaceholder\"\n [value]=\"searchValue\"\n [showClear]=\"showClear\"\n (valueChange)=\"valueChange($event)\"\n (search)=\"search($event)\"\n (cleared)=\"cleared()\"\n ></cqa-search-bar>\n <div class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-flex-wrap\">\n <cqa-button\n *ngIf=\"showExportButton\"\n variant=\"grey-solid\"\n icon=\"open_in_new\"\n [text]=\"isExporting ? 'Exporting...' : 'Export'\"\n [disabled]=\"isExporting\"\n (clicked)=\"exportCodeClick()\"\n >\n <span>{{ isExporting ? 'Exporting...' : 'Export' }}</span>\n </cqa-button>\n \n <!-- Export Code Modal -->\n <cqa-export-code-modal\n *ngIf=\"showExportButton\"\n [isOpen]=\"isExportModalOpen\"\n [cases]=\"selectedCasesForExport\"\n [disabled]=\"false\"\n (closeModal)=\"closeExportModal()\"\n (export)=\"onExportModalExport($event)\">\n </cqa-export-code-modal>\n <ng-container *ngFor=\"let dropdownTemplate of otherDropDownButtons; trackBy: trackByDropdownTemplateRef\">\n <ng-container *ngTemplateOutlet=\"dropdownTemplate\"></ng-container>\n </ng-container>\n\n <ng-container *ngFor=\"let selectDropdownTemplate of otherSelectDropDownButtons; trackBy: trackBySelectDropdownTemplateRef\">\n <ng-container *ngTemplateOutlet=\"selectDropdownTemplate\"></ng-container>\n </ng-container>\n \n <cqa-button\n *ngIf=\"showFilterButton\"\n variant=\"grey-solid\"\n icon=\"add\"\n [disabled]=\"isReordering\"\n (clicked)=\"toggleFilter()\"\n >\n <span class=\"cqa-flex cqa-items-center cqa-gap-1\">\n Filter \n <div [class]=\"arrowClasses\">\n <svg\n class=\"cqa-w-2 cqa-h-1 cqa-absolute cqa-left-[4px] cqa-top-[6px]\"\n viewBox=\"0 0 8 4\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M0 0L4 4L8 0\"\n stroke=\"#0B0B0C\"\n stroke-width=\"1.33\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </div>\n </span>\n </cqa-button>\n <cqa-column-visibility\n *ngIf=\"showSettingsButton\"\n [columns]=\"visibilityColumns\"\n [columnVisibility]=\"columnVisibility\"\n [selectedAutoRefreshInterval]=\"selectedAutoRefreshInterval\"\n (columnVisibilityChange)=\"onColumnVisibilityChange($event)\"\n (autoRefreshChange)=\"onAutoRefreshChange($event)\"\n ></cqa-column-visibility>\n <cqa-button\n *ngIf=\"showAutoRefreshButton\"\n variant=\"grey-solid\"\n icon=\"refresh\"\n (clicked)=\"handleRefreshClick()\"\n [tooltip]=\"'Refresh'\"\n tooltipPosition=\"below\"\n [disabled]=\"isReordering\"\n ></cqa-button>\n <ng-container *ngFor=\"let buttonTemplate of otherButtons; trackBy: trackByTemplateRef\">\n <ng-container *ngTemplateOutlet=\"buttonTemplate\"></ng-container>\n </ng-container>\n <cqa-segment-control\n *ngIf=\"showViewModeToggle\"\n size=\"lg\"\n [segments]=\"viewModeSegments\"\n [value]=\"viewMode\"\n (valueChange)=\"onViewModeChange($event)\"\n ></cqa-segment-control>\n <cqa-button\n *ngIf=\"showReorderButton && !isReordering\"\n variant=\"outlined\"\n icon=\"drag_indicator\"\n [text]=\"reorderLabels.reorderButton\"\n [disabled]=\"!pagedRows || pagedRows.length === 0 || isTableLoading || isTableDataLoading\"\n (clicked)=\"startReorder()\"\n ></cqa-button>\n <ng-container *ngIf=\"showReorderButton && isReordering\">\n <cqa-button\n variant=\"outlined\"\n [text]=\"reorderLabels.cancelButton\"\n [disabled]=\"reorderSaving\"\n (clicked)=\"cancelReorder()\"\n ></cqa-button>\n <cqa-button\n variant=\"filled\"\n [icon]=\"reorderSaving ? 'hourglass_empty' : ''\"\n [text]=\"reorderSaving ? reorderLabels.savingButton : reorderLabels.doneButton\"\n [disabled]=\"reorderSaving\"\n (clicked)=\"saveReorder()\"\n ></cqa-button>\n </ng-container>\n </div>\n </div>\n\n <!-- Reorder mode banner -->\n <div *ngIf=\"isReordering\" class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-mb-3 cqa-px-3 cqa-py-2 cqa-rounded-md cqa-bg-[#FFFBEB] cqa-border cqa-border-[#FDE68A]\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <circle cx=\"3\" cy=\"3\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"8\" cy=\"3\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"13\" cy=\"3\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"3\" cy=\"8\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"8\" cy=\"8\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"13\" cy=\"8\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"3\" cy=\"13\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"8\" cy=\"13\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"13\" cy=\"13\" r=\"1.5\" fill=\"#92400E\"></circle>\n </svg>\n <span class=\"cqa-text-sm cqa-font-semibold cqa-text-[#92400E]\">{{ reorderLabels.bannerTitle }}</span>\n <span class=\"cqa-text-sm cqa-text-[#92400E]\">{{ reorderLabels.bannerDescription }}</span>\n </div>\n\n <cqa-selected-filters\n [filterApplied]=\"filterApplied\"\n [chips]=\"chips\"\n (removeChip)=\"onRemoveChip($event)\"\n (clearAll)=\"onClearAllChips()\"\n (onClearAll)=\"onClearAll.emit()\"\n >\n </cqa-selected-filters>\n\n <cqa-dynamic-filter\n *ngIf=\"showFilterPanel\"\n [config]=\"filterConfig\"\n [model]=\"filterModel\"\n [showFilterPanel]=\"showFilterPanel\"\n (filtersChanged)=\"onFiltersChanged($event)\"\n (filtersApplied)=\"onFiltersApplied($event)\"\n (onApplyFilterClick)=\"onApplyFilterClick.emit($event)\"\n (onResetFilterClick)=\"handleResetFilterClick()\"\n >\n </cqa-dynamic-filter>\n\n <div class=\"cqa-flex cqa-items-stretch cqa-gap-2 cqa-min-h-0 cqa-min-w-0 cqa-w-full cqa-max-w-full cqa-overflow-hidden\" style=\"border-bottom: 1px solid rgb(226, 226, 227);\">\n <!-- Sidebar (only shown in modular view) -->\n <cqa-folder-sidebar\n *ngIf=\"isModularView && modularConfig.showSidebar\"\n [folders]=\"folders\"\n [selectedFolderId]=\"selectedFolderId\"\n [expandedFolderIds]=\"expandedFolderIds\"\n [unorganizedCount]=\"unorganizedCount\"\n [allowCreate]=\"modularConfig.allowCreateFolder\"\n [allowRename]=\"modularConfig.allowRenameFolder\"\n [allowDelete]=\"modularConfig.allowDeleteFolder\"\n [allowDrop]=\"modularConfig.allowTestDragDrop\"\n [allowDuplicate]=\"modularConfig.allowDuplicateFolder\"\n [showCounts]=\"modularConfig.showCounts\"\n [collapsed]=\"sidebarCollapsed\"\n [labels]=\"modularLabels\"\n [serverSideSearch]=\"serverSideSearch\"\n [rootTotal]=\"rootTotal\"\n [folderSearchLoading]=\"folderSearchLoading\"\n [rootFoldersLoading]=\"rootFoldersLoading\"\n [savingFolderIds]=\"savingFolderIds\"\n [searchValue]=\"folderSearchValue\"\n (folderSelected)=\"onFolderSelected($event)\"\n (folderExpansionToggled)=\"onFolderExpansionToggled($event)\"\n (folderChildrenRequested)=\"folderChildrenRequested.emit($event)\"\n (folderLoadMoreRequested)=\"folderLoadMoreRequested.emit($event)\"\n (rootLoadMoreRequested)=\"rootLoadMoreRequested.emit()\"\n (searchChange)=\"folderSearchChange.emit($event)\"\n (folderCreated)=\"onFolderCreated($event)\"\n (folderCreateRequested)=\"onFolderCreateRequested($event)\"\n (folderRenamed)=\"onFolderRenamed($event)\"\n (folderDeleted)=\"onFolderDeleted($event)\"\n (folderMoveRequested)=\"onFolderMoveRequested($event)\"\n (folderDuplicateRequested)=\"onFolderDuplicateRequested($event)\"\n (testsDropped)=\"onTestsDropped($event)\"\n (folderDropped)=\"onFolderDropped($event)\"\n (collapsedChange)=\"onSidebarCollapsedChange($event)\"\n ></cqa-folder-sidebar>\n\n <!-- Right pane -->\n <div\n class=\"cqa-flex-1 cqa-flex cqa-flex-col cqa-min-w-0\"\n [style.border-top]=\"isModularView ? '1px solid #E2E2E3' : null\"\n [style.border-left]=\"isModularView ? '1px solid #E2E2E3' : null\"\n [style.border-right]=\"isModularView ? '1px solid #E2E2E3' : null\"\n >\n <!-- Breadcrumb (modular view, folder drilled-in) -->\n <nav\n *ngIf=\"isModularView && modularConfig.showBreadcrumb && !isRootView\"\n aria-label=\"Folder path\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-text-sm cqa-px-3 cqa-py-2 cqa-rounded-none cqa-min-w-0\"\n style=\"color: #6D6D74; border-bottom: 1px solid #E2E2E3;\"\n >\n <div class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-flex-1 cqa-min-w-0 cqa-overflow-x-auto cqa-scrollbar-thin cqa-whitespace-nowrap\">\n <button type=\"button\" class=\"hover:cqa-text-[#3F43EE] cqa-inline-flex cqa-items-center cqa-gap-1 cqa-flex-shrink-0\" (click)=\"onFolderSelected(null)\">\n <svg width=\"14\" height=\"13\" viewBox=\"0 0 14 13\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M12.9583 10.4585C12.9583 10.79 12.8266 11.108 12.5921 11.3424C12.3577 11.5768 12.0398 11.7085 11.7083 11.7085H1.70825C1.37673 11.7085 1.05879 11.5768 0.824368 11.3424C0.589948 11.108 0.458252 10.79 0.458252 10.4585V1.7085C0.458252 1.37698 0.589948 1.05903 0.824368 0.824613C1.05879 0.590192 1.37673 0.458496 1.70825 0.458496H4.83325L6.08325 2.3335H11.7083C12.0398 2.3335 12.3577 2.46519 12.5921 2.69961C12.8266 2.93403 12.9583 3.25198 12.9583 3.5835V10.4585Z\" stroke=\"currentColor\" stroke-width=\"0.916667\"/>\n </svg>\n <span>{{ modularLabels.allFolders }}</span>\n </button>\n <ng-container *ngFor=\"let crumb of breadcrumbTrail; let last = last\">\n <mat-icon class=\"cqa-align-middle cqa-flex-shrink-0\" style=\"font-size:16px;width:16px;height:16px;color:#6D6D74;\">chevron_right</mat-icon>\n <button\n type=\"button\"\n class=\"cqa-flex-shrink-0\"\n [ngClass]=\"last\n ? 'cqa-text-[#161617] cqa-font-semibold'\n : 'cqa-text-[#6D6D74] hover:cqa-text-[#3F43EE]'\"\n [disabled]=\"last\"\n (click)=\"!last && onFolderSelected(crumb.id)\"\n >{{ crumb.name }}</button>\n </ng-container>\n </div>\n <cqa-button\n *ngIf=\"modularConfig.showSubfolderSection && subfolderTiles.length\"\n class=\"cqa-flex-shrink-0\"\n variant=\"text\"\n btnSize=\"sm\"\n customClass=\"!cqa-text-[13px] !cqa-leading-[18px]\"\n [icon]=\"subfolderSectionExpanded ? 'expand_less' : 'expand_more'\"\n [text]=\"(subfolderSectionExpanded ? 'Hide' : 'Show') + ' subfolders'\"\n [attr.aria-expanded]=\"subfolderSectionExpanded\"\n (clicked)=\"toggleSubfolderSection()\"\n ></cqa-button>\n <cqa-button\n *ngIf=\"modularConfig.allowCreateFolder\"\n class=\"cqa-flex-shrink-0\"\n variant=\"text\"\n btnSize=\"sm\"\n customClass=\"!cqa-text-[13px] !cqa-leading-[18px]\"\n icon=\"add\"\n [text]=\"modularLabels.newFolder\"\n (clicked)=\"onFolderCreateRequested({ parentId: selectedFolderId })\"\n ></cqa-button>\n </nav>\n\n <!-- Folder grid: modular + root view -->\n <section\n *ngIf=\"isModularView && isRootView && modularConfig.showFolderGrid && rootFolderTiles.length\"\n class=\"cqa-px-5 cqa-pt-2\"\n style=\"border-bottom: 1px solid #F0F0F1;\"\n >\n <button\n type=\"button\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-mb-2 cqa-w-full cqa-text-left\"\n [attr.aria-expanded]=\"organizedSectionExpanded\"\n (click)=\"toggleOrganizedSection()\"\n >\n <svg width=\"14\" height=\"13\" viewBox=\"0 0 14 13\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M12.9583 10.4585C12.9583 10.79 12.8266 11.108 12.5921 11.3424C12.3577 11.5768 12.0398 11.7085 11.7083 11.7085H1.70825C1.37673 11.7085 1.05879 11.5768 0.824368 11.3424C0.589948 11.108 0.458252 10.79 0.458252 10.4585V1.7085C0.458252 1.37698 0.589948 1.05903 0.824368 0.824613C1.05879 0.590192 1.37673 0.458496 1.70825 0.458496H4.83325L6.08325 2.3335H11.7083C12.0398 2.3335 12.3577 2.46519 12.5921 2.69961C12.8266 2.93403 12.9583 3.25198 12.9583 3.5835V10.4585Z\" stroke=\"#6D6D74\" stroke-width=\"0.916667\"/>\n </svg>\n <h3 class=\"cqa-text-sm cqa-font-semibold cqa-text-[#6D6D74]\">{{ modularLabels.organized }}</h3>\n <span class=\"cqa-text-xs cqa-text-[#6D6D74]\">\n {{ rootFolderTiles.length === 1 ? modularLabels.foldersCountSingular : modularLabels.foldersCountPlural.replace('{n}', '' + rootFolderTiles.length) }}\n </span>\n <mat-icon class=\"cqa-text-[#6D6D74] cqa-ml-auto\" style=\"font-size:18px;width:18px;height:18px\">\n {{ organizedSectionExpanded ? 'expand_less' : 'expand_more' }}\n </mat-icon>\n </button>\n <div\n class=\"cqa-grid\"\n style=\"transition: grid-template-rows 300ms cubic-bezier(0.4, 0, 0.2, 1);\"\n [style.grid-template-rows]=\"organizedSectionExpanded ? '1fr' : '0fr'\"\n >\n <div class=\"cqa-min-h-0\" style=\"overflow: hidden;\">\n <div class=\"cqa-flex cqa-flex-nowrap cqa-gap-3 cqa-overflow-x-auto cqa-scrollbar-thin cqa-pb-1\"\n (scroll)=\"onRootGridScroll($event)\">\n <button\n *ngFor=\"let f of rootFolderTiles\"\n type=\"button\"\n [cqaFolderDrop]=\"f.id\"\n [dropEnabled]=\"modularConfig.allowTestDragDrop\"\n (testsDropped)=\"onTestsDropped($event)\"\n (click)=\"onFolderSelected(f.id)\"\n class=\"cqa-group cqa-flex-shrink-0 cqa-w-[240px] cqa-flex cqa-items-center cqa-justify-between cqa-gap-3 cqa-text-left cqa-p-3 cqa-rounded-[10px] cqa-border-solid cqa-border-[0.5px] cqa-border-[#E2E2E3] cqa-bg-white hover:cqa-border-[#3F43EE] hover:cqa-shadow-sm cqa-transition-colors\"\n >\n <div class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-min-w-0\">\n <ng-container *ngTemplateOutlet=\"folderIconChip; context: { color: f.color }\"></ng-container>\n <div class=\"cqa-flex cqa-flex-col cqa-min-w-0\">\n <span class=\"cqa-text-[15px] cqa-text-[#161617] cqa-truncate cqa-leading-tight group-hover:cqa-text-[#3F43EE]\">{{ f.name }}</span>\n <span *ngIf=\"modularConfig.showCounts\" class=\"cqa-text-sm cqa-text-neutral-500 cqa-truncate\">\n {{ (f.count ?? 0) === 1 ? modularLabels.testsCountSingular : modularLabels.testsCountPlural.replace('{n}', '' + (f.count ?? 0)) }}<ng-container *ngIf=\"f.children?.length\"> \u00B7 {{ f.children!.length === 1 ? modularLabels.oneSubfolder : modularLabels.subfoldersCount.replace('{n}', '' + f.children!.length) }}</ng-container>\n </span>\n </div>\n </div>\n <mat-icon class=\"cqa-text-neutral-400 cqa-flex-shrink-0\" style=\"font-size:20px;width:20px;height:20px\">chevron_right</mat-icon>\n </button>\n\n <!-- \"+ New folder\" tile -->\n <button\n *ngIf=\"modularConfig.allowCreateFolder\"\n type=\"button\"\n (click)=\"onFolderCreateRequested({ parentId: null })\"\n class=\"cqa-group cqa-flex-shrink-0 cqa-w-[240px] cqa-flex cqa-items-center cqa-gap-3 cqa-text-left cqa-p-3 cqa-rounded-[10px] cqa-border-dashed cqa-border-[0.5px] cqa-border-[#E2E2E3] cqa-bg-[#FAFAFA] hover:cqa-border-[#3F43EE] hover:cqa-bg-white cqa-transition-colors\"\n >\n <ng-container *ngTemplateOutlet=\"addIconChip\"></ng-container>\n <div class=\"cqa-flex cqa-flex-col cqa-min-w-0\">\n <span class=\"cqa-text-[15px] cqa-text-[#161617] cqa-truncate cqa-leading-tight group-hover:cqa-text-[#3F43EE]\">{{ modularLabels.newFolder }}</span>\n <span class=\"cqa-text-sm cqa-text-neutral-400\">{{ modularLabels.testsCountPlural.replace('{n}', '0') }}</span>\n </div>\n </button>\n\n <!-- Pagination spinner anchored at the right edge of the Organized\n row. Only renders during an in-flight root fetch (initial OR\n scroll-driven \"load more\"), and is filtered to suppress when\n the section is empty so we don't show a spinner inside an\n otherwise-blank row. -->\n <div\n *ngIf=\"rootFoldersLoading && rootFolderTiles.length > 0\"\n class=\"cqa-flex-shrink-0 cqa-flex cqa-items-center cqa-justify-center cqa-w-[80px]\"\n aria-live=\"polite\"\n [attr.aria-label]=\"'Loading more folders'\"\n >\n <ng-container *ngTemplateOutlet=\"loadingSpinner; context: { size: 20 }\"></ng-container>\n </div>\n </div>\n </div>\n </div>\n </section>\n\n <!-- Subfolder section: modular + folder view. Shown whenever drilled in\n (even if no subfolders, so the \"+ New folder\" tile remains\n reachable, and so we can render a loading state during the\n drill-in fetch before children arrive). -->\n <section\n *ngIf=\"isModularView && !isRootView && modularConfig.showSubfolderSection && (subfolderTiles.length || currentFolderNode?.childrenLoading)\"\n class=\"cqa-grid\"\n style=\"transition: grid-template-rows 300ms cubic-bezier(0.4, 0, 0.2, 1);\"\n [style.grid-template-rows]=\"subfolderSectionExpanded ? '1fr' : '0fr'\"\n >\n <div class=\"cqa-min-h-0\" style=\"overflow: hidden;\">\n <div class=\"cqa-px-3 cqa-py-2 cqa-flex cqa-flex-nowrap cqa-gap-3 cqa-overflow-x-auto cqa-scrollbar-thin\"\n (scroll)=\"onSubfolderGridScroll($event)\">\n <button\n *ngFor=\"let f of subfolderTiles\"\n type=\"button\"\n [cqaFolderDrop]=\"f.id\"\n [dropEnabled]=\"modularConfig.allowTestDragDrop\"\n (testsDropped)=\"onTestsDropped($event)\"\n (click)=\"onFolderSelected(f.id)\"\n class=\"cqa-group cqa-flex-shrink-0 cqa-w-[240px] cqa-flex cqa-items-center cqa-justify-between cqa-gap-3 cqa-text-left cqa-p-3 cqa-rounded-[10px] cqa-border-solid cqa-border-[0.5px] cqa-border-[#E2E2E3] cqa-bg-white hover:cqa-border-[#3F43EE] hover:cqa-shadow-sm cqa-transition-colors\"\n >\n <div class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-min-w-0\">\n <ng-container *ngTemplateOutlet=\"folderIconChip; context: { color: f.color }\"></ng-container>\n <div class=\"cqa-flex cqa-flex-col cqa-min-w-0\">\n <span class=\"cqa-text-[15px] cqa-text-[#161617] cqa-truncate cqa-leading-tight group-hover:cqa-text-[#3F43EE]\">{{ f.name }}</span>\n <span *ngIf=\"modularConfig.showCounts\" class=\"cqa-text-sm cqa-text-neutral-500 cqa-truncate\">\n {{ (f.count ?? 0) === 1 ? modularLabels.testsCountSingular : modularLabels.testsCountPlural.replace('{n}', '' + (f.count ?? 0)) }}\n </span>\n </div>\n </div>\n <mat-icon class=\"cqa-text-neutral-400 cqa-flex-shrink-0\" style=\"font-size:20px;width:20px;height:20px\">chevron_right</mat-icon>\n </button>\n\n <!-- \"+ New folder\" tile -->\n <button\n *ngIf=\"modularConfig.allowCreateFolder\"\n type=\"button\"\n (click)=\"onFolderCreateRequested({ parentId: selectedFolderId })\"\n class=\"cqa-group cqa-flex-shrink-0 cqa-w-[240px] cqa-flex cqa-items-center cqa-gap-3 cqa-text-left cqa-p-3 cqa-rounded-[10px] cqa-border-dashed cqa-border-[0.5px] cqa-border-[#E2E2E3] cqa-bg-[#FAFAFA] hover:cqa-border-[#3F43EE] hover:cqa-bg-white cqa-transition-colors\"\n >\n <ng-container *ngTemplateOutlet=\"addIconChip\"></ng-container>\n <div class=\"cqa-flex cqa-flex-col cqa-min-w-0\">\n <span class=\"cqa-text-[15px] cqa-text-[#161617] cqa-truncate cqa-leading-tight group-hover:cqa-text-[#3F43EE]\">{{ modularLabels.newFolder }}</span>\n <span class=\"cqa-text-sm cqa-text-neutral-400\">{{ modularLabels.testsCountPlural.replace('{n}', '0') }}</span>\n </div>\n </button>\n\n <!-- Subfolder fetch indicator. Two cases:\n - Drill-in fetch: no subfolderTiles yet, render a centered\n row spinner so the section isn't empty during the fetch.\n - Pagination fetch: tiles exist, anchor a small spinner at\n the right edge so the user knows the next page is loading. -->\n <div\n *ngIf=\"currentFolderNode?.childrenLoading\"\n class=\"cqa-flex-shrink-0 cqa-flex cqa-items-center cqa-justify-center cqa-w-[80px]\"\n aria-live=\"polite\"\n [attr.aria-label]=\"'Loading subfolders'\"\n >\n <ng-container *ngTemplateOutlet=\"loadingSpinner; context: { size: 20 }\"></ng-container>\n </div>\n </div>\n </div>\n </section>\n\n <div\n *ngIf=\"isModularView && !isRootView && modularConfig.showUnorganizedSection\"\n class=\"cqa-flex cqa-items-center cqa-justify-between cqa-px-4 cqa-py-3 cqa-border cqa-border-indigo-100\"\n style=\"background-color: #D8D9FC;\"\n >\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <svg width=\"14\" height=\"13\" viewBox=\"0 0 14 13\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M12.9585 10.4585C12.9585 10.79 12.8268 11.108 12.5924 11.3424C12.358 11.5768 12.04 11.7085 11.7085 11.7085H1.7085C1.37698 11.7085 1.05903 11.5768 0.824613 11.3424C0.590192 11.108 0.458496 10.79 0.458496 10.4585V1.7085C0.458496 1.37698 0.590192 1.05903 0.824613 0.824613C1.05903 0.590192 1.37698 0.458496 1.7085 0.458496H4.8335L6.0835 2.3335H11.7085C12.04 2.3335 12.358 2.46519 12.5924 2.69961C12.8268 2.93403 12.9585 3.25198 12.9585 3.5835V10.4585Z\" stroke=\"#3F43EE\" stroke-width=\"0.916667\"/>\n </svg>\n <span class=\"cqa-text-sm cqa-font-semibold\" style=\"color: #3F43EE;\">\n {{ currentFolderNode?.name }} ({{ currentFolderDirectCount }})\n </span>\n </div>\n <cqa-button\n variant=\"outlined\"\n btnSize=\"sm\"\n customClass=\"!cqa-text-[13px]\"\n inlineStyles=\"border-color: #3F43EE; color: #3F43EE;\"\n [text]=\"modularLabels.clearFilter\"\n (clicked)=\"onFolderSelected(null)\"\n ></cqa-button>\n </div>\n\n <!-- Unorganized section header at root view -->\n <div\n *ngIf=\"isModularView && isRootView && modularConfig.showUnorganizedSection\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-mb-2 cqa-mt-2\" style=\"margin-left: 20px;\"\n >\n <mat-icon class=\"cqa-text-[#6D6D74]\" style=\"font-size:16px;width:16px;height:16px\">inbox</mat-icon>\n <h3 class=\"cqa-text-sm cqa-font-semibold cqa-text-[#6D6D74]\">{{ modularLabels.unorganized }}</h3>\n <span class=\"cqa-text-xs cqa-text-[#6D6D74]\">\n {{ unorganizedCount === 1 ? modularLabels.testsCountSingular : modularLabels.testsCountPlural.replace('{n}', '' + unorganizedCount) }}\n </span>\n </div>\n\n <div class=\"cqa-overflow-hidden cqa-border-t cqa-border-l cqa-border-r cqa-border-grey-200 cqa-relative cqa-overflow-x-auto\"\n [class.cqa-modular-table-flush]=\"isModularView\"\n [attr.style]=\"(!isModularView ? 'border-radius: 7px;' : '') + ((pagedRows && pagedRows.length > 0) ? '' : ' border-bottom: none !important;')\">\n <ng-container *ngIf=\"(isTableLoading || isTableDataLoading) || (!effectiveIsEmptyState && pagedRows && pagedRows.length > 0); else storyEmptyTpl\">\n <app-dynamic-table\n [style.border-bottom]=\"pagedRows && pagedRows.length > 0 ? '1px solid rgb(226, 226, 227)' : null\"\n [columns]=\"computedColumns\"\n [data]=\"pagedRows\"\n [rowSelectable]=\"rowSelectable\"\n [enableLocalSort]=\"enableLocalSort && !isReordering\"\n [isTableLoading]=\"isTableLoading\"\n [isTableDataLoading]=\"isTableDataLoading\"\n [cellJsonPathGetter]=\"cellJsonPathGetter\"\n [onJsonPathCopiedHandler]=\"onJsonPathCopiedHandler\"\n [enableRowReorder]=\"isReordering\"\n (rowReorder)=\"onRowReorder($event)\"\n (sortChange)=\"sortChange.emit($event)\">\n <ng-template #emptyTableTpl>\n <div class=\"cqa-flex cqa-flex-col cqa-items-center cqa-justify-center cqa-py-8\">\n <img src=\"/assets/illustrations/empty-state.svg\" alt=\"No data\" class=\"cqa-w-32 cqa-h-32 cqa-mb-4\" />\n <h3 class=\"cqa-text-lg cqa-font-semibold cqa-mb-2\">No test cases</h3>\n <p class=\"cqa-text-sm cqa-text-neutral-500 cqa-mb-4\">Try adjusting filters or create a new test case.</p>\n <cqa-button variant=\"filled\" (clicked)=\"toggleFilter()\">Show Filters</cqa-button>\n </div>\n </ng-template>\n </app-dynamic-table>\n </ng-container>\n\n <ng-template #storyEmptyTpl>\n <div class=\"cqa-p-6 cqa-flex cqa-flex-col cqa-items-center cqa-justify-center\">\n <cqa-empty-state\n *ngIf=\"effectiveIsEmptyState\"\n [title]=\"effectiveEmptyStateConfig.title\"\n [description]=\"effectiveEmptyStateConfig.description\"\n [imageUrl]=\"effectiveEmptyStateConfig.imageUrl\"\n [actions]=\"effectiveEmptyStateConfig.actions\"\n (actionClick)=\"onEmptyAction($event)\"\n >\n </cqa-empty-state>\n </div>\n </ng-template>\n </div>\n\n <cqa-pagination\n [totalElements]=\"serverSidePagination ? totalElements : filteredRows.length\"\n [pageIndex]=\"pageIndex\"\n [pageSize]=\"pageSize\"\n [pageSizeOptions]=\"pageSizeOptions\"\n [pageSizeMenuDirection]=\"pageSizeMenuDirection\"\n [pageItemCount]=\"pagedRows.length\"\n (paginate)=\"onPaginate($event)\"\n (pageSizeChange)=\"onPageSizeChange($event)\"\n >\n </cqa-pagination>\n </div>\n </div>\n\n <!-- Reused bulk action toolbar -->\n <div *ngIf=\"anyRowSelected && modularConfig.allowBulkSelection && !isReordering\" class=\"cqa-absolute cqa-bottom-[18.75px] cqa-left-[50%] cqa-translate-x-[-50%] cqa-w-full lg:cqa-max-w-[68%] cqa-sm:max-w-[75%] cqa-max-w-[90%] cqa-z-[1]\">\n <cqa-table-action-toolbar\n [selectedItems]=\"selectedItems && selectedItems.length > 0 ? selectedItems : currentSelectedItems\"\n [actions]=\"effectiveBulkActions\"\n [showSelectAll]=\"showSelectAllInToolbar\"\n [allSelected]=\"allSelectedInToolbar\"\n [showDismiss]=\"showDismissInToolbar\"\n (actionClick)=\"onBulkAction($event)\"\n (selectAllChange)=\"onBulkSelectAll($event)\"\n (dismiss)=\"onBulkDismiss()\"\n ></cqa-table-action-toolbar>\n </div>\n\n </div>\n</div>\n\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: ButtonComponent, selector: "cqa-button", inputs: ["variant", "btnSize", "disabled", "loading", "icon", "iconPosition", "fullWidth", "iconColor", "type", "text", "customClass", "inlineStyles", "tooltip", "tooltipPosition"], outputs: ["clicked"] }, { kind: "component", type: SearchBarComponent, selector: "cqa-search-bar", inputs: ["placeholder", "value", "disabled", "showClear", "ariaLabel", "autoFocus", "size", "fullWidth"], outputs: ["valueChange", "search", "cleared"] }, { kind: "component", type: SegmentControlComponent, selector: "cqa-segment-control", inputs: ["segments", "value", "disabled", "containerBgColor", "fullWidth", "size"], outputs: ["valueChange"] }, { kind: "component", type: DynamicTableComponent, selector: "app-dynamic-table", inputs: ["data", "columns", "emptyState", "gridTemplateColumns", "screenWidth", "enableSelectAll", "rowSelectable", "enableLocalSort", "isTableLoading", "isTableDataLoading", "cellJsonPathGetter", "onJsonPathCopiedHandler", "enableRowReorder", "reorderHandleTooltip"], outputs: ["sortChange", "rowReorder"] }, { kind: "component", type: PaginationComponent, selector: "cqa-pagination", inputs: ["totalElements", "totalPages", "pageIndex", "pageSize", "pageItemCount", "pageSizeOptions", "pageSizeMenuDirection"], outputs: ["pageIndexChange", "pageSizeChange", "paginate"] }, { kind: "component", type: DynamicFilterComponent, selector: "cqa-dynamic-filter", inputs: ["config", "model", "showFilterPanel", "buttonLayout"], outputs: ["filtersApplied", "filtersChanged", "resetAction", "onApplyFilterClick", "onResetFilterClick"] }, { kind: "component", type: ColumnVisibilityComponent, selector: "cqa-column-visibility", inputs: ["isStepGroup", "columns", "columnVisibility", "selectedAutoRefreshInterval"], outputs: ["columnVisibilityChange", "autoRefreshChange"] }, { kind: "component", type: TableActionToolbarComponent, selector: "cqa-table-action-toolbar", inputs: ["selectedItems", "actions", "showSelectAll", "allSelected", "showDismiss"], outputs: ["actionClick", "selectAllChange", "dismiss"] }, { kind: "component", type: SelectedFiltersComponent, selector: "cqa-selected-filters", inputs: ["filterApplied", "chips", "defaultChips", "defaultChipClass"], outputs: ["removeChip", "clearAll", "onClearAll"] }, { kind: "component", type: EmptyStateComponent, selector: "cqa-empty-state", inputs: ["preset", "imageUrl", "title", "description", "actions"], outputs: ["actionClick"] }, { kind: "component", type: FolderSidebarComponent, selector: "cqa-folder-sidebar", inputs: ["folders", "selectedFolderId", "expandedFolderIds", "unorganizedCount", "allowCreate", "allowRename", "allowDelete", "allowMove", "allowDuplicate", "allowDrop", "showCounts", "collapsed", "foldersAccordionExpanded", "labels", "serverSideSearch", "rootTotal", "folderSearchLoading", "rootFoldersLoading", "savingFolderIds", "searchValue"], outputs: ["folderSelected", "folderExpansionToggled", "folderChildrenRequested", "folderLoadMoreRequested", "searchChange", "rootLoadMoreRequested", "folderCreated", "folderCreateRequested", "folderRenamed", "folderDeleted", "folderMoveRequested", "folderDuplicateRequested", "testsDropped", "folderDropped", "collapsedChange", "foldersAccordionExpandedChange"] }, { kind: "directive", type: FolderDropDirective, selector: "[cqaFolderDrop]", inputs: ["cqaFolderDrop", "dropEnabled"], outputs: ["testsDropped", "folderDropped"] }, { kind: "component", type: ExportCodeModalComponent, selector: "cqa-export-code-modal", inputs: ["isOpen", "cases", "disabled"], outputs: ["closeModal", "export"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
11523
11528
  }
11524
11529
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ModularTableTemplateComponent, decorators: [{
11525
11530
  type: Component,
11526
- args: [{ selector: 'cqa-modular-table-template', host: { class: 'cqa-ui-root' }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Reusable folder-icon chip. Render via <ng-container *ngTemplateOutlet=\"folderIconChip; context: { color: f.color }\"></ng-container>. -->\n<ng-template #folderIconChip let-color=\"color\">\n <span class=\"cqa-inline-flex cqa-items-center cqa-justify-center cqa-w-10 cqa-h-10 cqa-rounded-lg cqa-bg-[#F0F0F1] cqa-text-[#6D6D74] cqa-flex-shrink-0 group-hover:cqa-bg-indigo-50 group-hover:cqa-text-[#3F43EE]\">\n <svg width=\"14\" height=\"13\" viewBox=\"0 0 14 13\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M12.9583 10.4585C12.9583 10.79 12.8266 11.108 12.5921 11.3424C12.3577 11.5768 12.0398 11.7085 11.7083 11.7085H1.70825C1.37673 11.7085 1.05879 11.5768 0.824368 11.3424C0.589948 11.108 0.458252 10.79 0.458252 10.4585V1.7085C0.458252 1.37698 0.589948 1.05903 0.824368 0.824613C1.05879 0.590192 1.37673 0.458496 1.70825 0.458496H4.83325L6.08325 2.3335H11.7083C12.0398 2.3335 12.3577 2.46519 12.5921 2.69961C12.8266 2.93403 12.9583 3.25198 12.9583 3.5835V10.4585Z\" [attr.stroke]=\"color || 'currentColor'\" stroke-width=\"0.916667\"/>\n </svg>\n </span>\n</ng-template>\n\n<!-- Reusable indeterminate loading spinner. Render via\n <ng-container *ngTemplateOutlet=\"loadingSpinner; context: { size: 20 }\"></ng-container>. -->\n<ng-template #loadingSpinner let-size=\"size\">\n <svg [attr.width]=\"size || 20\" [attr.height]=\"size || 20\" viewBox=\"0 0 50 50\" aria-label=\"loading\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"25\" cy=\"25\" r=\"20\" stroke=\"#E5E7EB\" stroke-width=\"6\" fill=\"none\"></circle>\n <path d=\"M45 25a20 20 0 0 0-20-20\" stroke=\"#4F46E5\" stroke-width=\"6\" fill=\"none\" stroke-linecap=\"round\">\n <animateTransform attributeName=\"transform\" type=\"rotate\" from=\"0 25 25\" to=\"360 25 25\" dur=\"0.8s\" repeatCount=\"indefinite\"></animateTransform>\n </path>\n </svg>\n</ng-template>\n\n<!-- Reusable \"+\" chip used by the \"New folder\" tile. -->\n<ng-template #addIconChip>\n <span class=\"cqa-inline-flex cqa-items-center cqa-justify-center cqa-w-10 cqa-h-10 cqa-rounded-lg cqa-bg-[#F0F0F1] cqa-text-[#6D6D74] cqa-flex-shrink-0 group-hover:cqa-bg-indigo-50 group-hover:cqa-text-[#3F43EE]\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M8 3V13M3 8H13\" stroke=\"currentColor\" stroke-width=\"1.275\" stroke-linecap=\"round\"/>\n </svg>\n </span>\n</ng-template>\n\n<div class=\"cqa-ui-root\">\n <div class=\"cqa-w-full cqa-flex cqa-flex-col cqa-relative\">\n <div [class]=\"!showSearchBar ? 'cqa-justify-end' : 'cqa-justify-between'\" class=\"cqa-w-full cqa-flex cqa-items-center cqa-gap-3 cqa-flex-wrap cqa-mb-3\">\n <cqa-search-bar\n *ngIf=\"showSearchBar\"\n [placeholder]=\"searchPlaceholder\"\n [value]=\"searchValue\"\n [showClear]=\"showClear\"\n (valueChange)=\"valueChange($event)\"\n (search)=\"search($event)\"\n (cleared)=\"cleared()\"\n ></cqa-search-bar>\n <div class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-flex-wrap\">\n <cqa-button\n *ngIf=\"showExportButton\"\n variant=\"grey-solid\"\n icon=\"open_in_new\"\n [text]=\"isExporting ? 'Exporting...' : 'Export'\"\n [disabled]=\"isExporting\"\n (clicked)=\"exportCodeClick()\"\n >\n <span>{{ isExporting ? 'Exporting...' : 'Export' }}</span>\n </cqa-button>\n \n <!-- Export Code Modal -->\n <cqa-export-code-modal\n *ngIf=\"showExportButton\"\n [isOpen]=\"isExportModalOpen\"\n [cases]=\"selectedCasesForExport\"\n [disabled]=\"false\"\n (closeModal)=\"closeExportModal()\"\n (export)=\"onExportModalExport($event)\">\n </cqa-export-code-modal>\n <ng-container *ngFor=\"let dropdownTemplate of otherDropDownButtons; trackBy: trackByDropdownTemplateRef\">\n <ng-container *ngTemplateOutlet=\"dropdownTemplate\"></ng-container>\n </ng-container>\n\n <ng-container *ngFor=\"let selectDropdownTemplate of otherSelectDropDownButtons; trackBy: trackBySelectDropdownTemplateRef\">\n <ng-container *ngTemplateOutlet=\"selectDropdownTemplate\"></ng-container>\n </ng-container>\n \n <cqa-button\n *ngIf=\"showFilterButton\"\n variant=\"grey-solid\"\n icon=\"add\"\n [disabled]=\"isReordering\"\n (clicked)=\"toggleFilter()\"\n >\n <span class=\"cqa-flex cqa-items-center cqa-gap-1\">\n Filter \n <div [class]=\"arrowClasses\">\n <svg\n class=\"cqa-w-2 cqa-h-1 cqa-absolute cqa-left-[4px] cqa-top-[6px]\"\n viewBox=\"0 0 8 4\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M0 0L4 4L8 0\"\n stroke=\"#0B0B0C\"\n stroke-width=\"1.33\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </div>\n </span>\n </cqa-button>\n <cqa-column-visibility\n *ngIf=\"showSettingsButton\"\n [columns]=\"visibilityColumns\"\n [columnVisibility]=\"columnVisibility\"\n [selectedAutoRefreshInterval]=\"selectedAutoRefreshInterval\"\n (columnVisibilityChange)=\"onColumnVisibilityChange($event)\"\n (autoRefreshChange)=\"onAutoRefreshChange($event)\"\n ></cqa-column-visibility>\n <cqa-button\n *ngIf=\"showAutoRefreshButton\"\n variant=\"grey-solid\"\n icon=\"refresh\"\n (clicked)=\"handleRefreshClick()\"\n [tooltip]=\"'Refresh'\"\n tooltipPosition=\"below\"\n [disabled]=\"isReordering\"\n ></cqa-button>\n <ng-container *ngFor=\"let buttonTemplate of otherButtons; trackBy: trackByTemplateRef\">\n <ng-container *ngTemplateOutlet=\"buttonTemplate\"></ng-container>\n </ng-container>\n <cqa-segment-control\n *ngIf=\"showViewModeToggle\"\n size=\"lg\"\n [segments]=\"viewModeSegments\"\n [value]=\"viewMode\"\n (valueChange)=\"onViewModeChange($event)\"\n ></cqa-segment-control>\n <cqa-button\n *ngIf=\"showReorderButton && !isReordering\"\n variant=\"outlined\"\n icon=\"drag_indicator\"\n [text]=\"reorderLabels.reorderButton\"\n [disabled]=\"!pagedRows || pagedRows.length === 0 || isTableLoading || isTableDataLoading\"\n (clicked)=\"startReorder()\"\n ></cqa-button>\n <ng-container *ngIf=\"showReorderButton && isReordering\">\n <cqa-button\n variant=\"outlined\"\n [text]=\"reorderLabels.cancelButton\"\n [disabled]=\"reorderSaving\"\n (clicked)=\"cancelReorder()\"\n ></cqa-button>\n <cqa-button\n variant=\"filled\"\n [icon]=\"reorderSaving ? 'hourglass_empty' : ''\"\n [text]=\"reorderSaving ? reorderLabels.savingButton : reorderLabels.doneButton\"\n [disabled]=\"reorderSaving\"\n (clicked)=\"saveReorder()\"\n ></cqa-button>\n </ng-container>\n </div>\n </div>\n\n <!-- Reorder mode banner -->\n <div *ngIf=\"isReordering\" class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-mb-3 cqa-px-3 cqa-py-2 cqa-rounded-md cqa-bg-[#FFFBEB] cqa-border cqa-border-[#FDE68A]\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <circle cx=\"3\" cy=\"3\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"8\" cy=\"3\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"13\" cy=\"3\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"3\" cy=\"8\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"8\" cy=\"8\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"13\" cy=\"8\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"3\" cy=\"13\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"8\" cy=\"13\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"13\" cy=\"13\" r=\"1.5\" fill=\"#92400E\"></circle>\n </svg>\n <span class=\"cqa-text-sm cqa-font-semibold cqa-text-[#92400E]\">{{ reorderLabels.bannerTitle }}</span>\n <span class=\"cqa-text-sm cqa-text-[#92400E]\">{{ reorderLabels.bannerDescription }}</span>\n </div>\n\n <cqa-selected-filters\n [filterApplied]=\"filterApplied\"\n [chips]=\"chips\"\n (removeChip)=\"onRemoveChip($event)\"\n (clearAll)=\"onClearAllChips()\"\n (onClearAll)=\"onClearAll.emit()\"\n >\n </cqa-selected-filters>\n\n <cqa-dynamic-filter\n *ngIf=\"showFilterPanel\"\n [config]=\"filterConfig\"\n [model]=\"filterModel\"\n [showFilterPanel]=\"showFilterPanel\"\n (filtersChanged)=\"onFiltersChanged($event)\"\n (filtersApplied)=\"onFiltersApplied($event)\"\n (onApplyFilterClick)=\"onApplyFilterClick.emit($event)\"\n (onResetFilterClick)=\"handleResetFilterClick()\"\n >\n </cqa-dynamic-filter>\n\n <div class=\"cqa-flex cqa-items-stretch cqa-gap-2 cqa-min-h-0 \" style=\"border-bottom: 1px solid rgb(226, 226, 227);\">\n <!-- Sidebar (only shown in modular view) -->\n <cqa-folder-sidebar\n *ngIf=\"isModularView && modularConfig.showSidebar\"\n [folders]=\"folders\"\n [selectedFolderId]=\"selectedFolderId\"\n [expandedFolderIds]=\"expandedFolderIds\"\n [unorganizedCount]=\"unorganizedCount\"\n [allowCreate]=\"modularConfig.allowCreateFolder\"\n [allowRename]=\"modularConfig.allowRenameFolder\"\n [allowDelete]=\"modularConfig.allowDeleteFolder\"\n [allowDrop]=\"modularConfig.allowTestDragDrop\"\n [allowDuplicate]=\"modularConfig.allowDuplicateFolder\"\n [showCounts]=\"modularConfig.showCounts\"\n [collapsed]=\"sidebarCollapsed\"\n [labels]=\"modularLabels\"\n [serverSideSearch]=\"serverSideSearch\"\n [rootTotal]=\"rootTotal\"\n [folderSearchLoading]=\"folderSearchLoading\"\n [rootFoldersLoading]=\"rootFoldersLoading\"\n [savingFolderIds]=\"savingFolderIds\"\n [searchValue]=\"folderSearchValue\"\n (folderSelected)=\"onFolderSelected($event)\"\n (folderExpansionToggled)=\"onFolderExpansionToggled($event)\"\n (folderChildrenRequested)=\"folderChildrenRequested.emit($event)\"\n (folderLoadMoreRequested)=\"folderLoadMoreRequested.emit($event)\"\n (rootLoadMoreRequested)=\"rootLoadMoreRequested.emit()\"\n (searchChange)=\"folderSearchChange.emit($event)\"\n (folderCreated)=\"onFolderCreated($event)\"\n (folderCreateRequested)=\"onFolderCreateRequested($event)\"\n (folderRenamed)=\"onFolderRenamed($event)\"\n (folderDeleted)=\"onFolderDeleted($event)\"\n (folderMoveRequested)=\"onFolderMoveRequested($event)\"\n (folderDuplicateRequested)=\"onFolderDuplicateRequested($event)\"\n (testsDropped)=\"onTestsDropped($event)\"\n (folderDropped)=\"onFolderDropped($event)\"\n (collapsedChange)=\"onSidebarCollapsedChange($event)\"\n ></cqa-folder-sidebar>\n\n <!-- Right pane -->\n <div\n class=\"cqa-flex-1 cqa-flex cqa-flex-col cqa-min-w-0\"\n [style.border-top]=\"isModularView ? '1px solid #E2E2E3' : null\"\n [style.border-left]=\"isModularView ? '1px solid #E2E2E3' : null\"\n [style.border-right]=\"isModularView ? '1px solid #E2E2E3' : null\"\n >\n <!-- Breadcrumb (modular view, folder drilled-in) -->\n <nav\n *ngIf=\"isModularView && modularConfig.showBreadcrumb && !isRootView\"\n aria-label=\"Folder path\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-text-sm cqa-px-3 cqa-py-2 cqa-rounded-none cqa-min-w-0\"\n style=\"color: #6D6D74; border-bottom: 1px solid #E2E2E3;\"\n >\n <div class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-flex-1 cqa-min-w-0 cqa-overflow-x-auto cqa-scrollbar-thin cqa-whitespace-nowrap\">\n <button type=\"button\" class=\"hover:cqa-text-[#3F43EE] cqa-inline-flex cqa-items-center cqa-gap-1 cqa-flex-shrink-0\" (click)=\"onFolderSelected(null)\">\n <svg width=\"14\" height=\"13\" viewBox=\"0 0 14 13\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M12.9583 10.4585C12.9583 10.79 12.8266 11.108 12.5921 11.3424C12.3577 11.5768 12.0398 11.7085 11.7083 11.7085H1.70825C1.37673 11.7085 1.05879 11.5768 0.824368 11.3424C0.589948 11.108 0.458252 10.79 0.458252 10.4585V1.7085C0.458252 1.37698 0.589948 1.05903 0.824368 0.824613C1.05879 0.590192 1.37673 0.458496 1.70825 0.458496H4.83325L6.08325 2.3335H11.7083C12.0398 2.3335 12.3577 2.46519 12.5921 2.69961C12.8266 2.93403 12.9583 3.25198 12.9583 3.5835V10.4585Z\" stroke=\"currentColor\" stroke-width=\"0.916667\"/>\n </svg>\n <span>{{ modularLabels.allFolders }}</span>\n </button>\n <ng-container *ngFor=\"let crumb of breadcrumbTrail; let last = last\">\n <mat-icon class=\"cqa-align-middle cqa-flex-shrink-0\" style=\"font-size:16px;width:16px;height:16px;color:#6D6D74;\">chevron_right</mat-icon>\n <button\n type=\"button\"\n class=\"cqa-flex-shrink-0\"\n [ngClass]=\"last\n ? 'cqa-text-[#161617] cqa-font-semibold'\n : 'cqa-text-[#6D6D74] hover:cqa-text-[#3F43EE]'\"\n [disabled]=\"last\"\n (click)=\"!last && onFolderSelected(crumb.id)\"\n >{{ crumb.name }}</button>\n </ng-container>\n </div>\n <cqa-button\n *ngIf=\"modularConfig.showSubfolderSection && subfolderTiles.length\"\n class=\"cqa-flex-shrink-0\"\n variant=\"text\"\n btnSize=\"sm\"\n customClass=\"!cqa-text-[13px] !cqa-leading-[18px]\"\n [icon]=\"subfolderSectionExpanded ? 'expand_less' : 'expand_more'\"\n [text]=\"(subfolderSectionExpanded ? 'Hide' : 'Show') + ' subfolders'\"\n [attr.aria-expanded]=\"subfolderSectionExpanded\"\n (clicked)=\"toggleSubfolderSection()\"\n ></cqa-button>\n <cqa-button\n *ngIf=\"modularConfig.allowCreateFolder\"\n class=\"cqa-flex-shrink-0\"\n variant=\"text\"\n btnSize=\"sm\"\n customClass=\"!cqa-text-[13px] !cqa-leading-[18px]\"\n icon=\"add\"\n [text]=\"modularLabels.newFolder\"\n (clicked)=\"onFolderCreateRequested({ parentId: selectedFolderId })\"\n ></cqa-button>\n </nav>\n\n <!-- Folder grid: modular + root view -->\n <section\n *ngIf=\"isModularView && isRootView && modularConfig.showFolderGrid && rootFolderTiles.length\"\n class=\"cqa-px-5 cqa-pt-2\"\n style=\"border-bottom: 1px solid #F0F0F1;\"\n >\n <button\n type=\"button\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-mb-2 cqa-w-full cqa-text-left\"\n [attr.aria-expanded]=\"organizedSectionExpanded\"\n (click)=\"toggleOrganizedSection()\"\n >\n <svg width=\"14\" height=\"13\" viewBox=\"0 0 14 13\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M12.9583 10.4585C12.9583 10.79 12.8266 11.108 12.5921 11.3424C12.3577 11.5768 12.0398 11.7085 11.7083 11.7085H1.70825C1.37673 11.7085 1.05879 11.5768 0.824368 11.3424C0.589948 11.108 0.458252 10.79 0.458252 10.4585V1.7085C0.458252 1.37698 0.589948 1.05903 0.824368 0.824613C1.05879 0.590192 1.37673 0.458496 1.70825 0.458496H4.83325L6.08325 2.3335H11.7083C12.0398 2.3335 12.3577 2.46519 12.5921 2.69961C12.8266 2.93403 12.9583 3.25198 12.9583 3.5835V10.4585Z\" stroke=\"#6D6D74\" stroke-width=\"0.916667\"/>\n </svg>\n <h3 class=\"cqa-text-sm cqa-font-semibold cqa-text-[#6D6D74]\">{{ modularLabels.organized }}</h3>\n <span class=\"cqa-text-xs cqa-text-[#6D6D74]\">\n {{ rootFolderTiles.length === 1 ? modularLabels.foldersCountSingular : modularLabels.foldersCountPlural.replace('{n}', '' + rootFolderTiles.length) }}\n </span>\n <mat-icon class=\"cqa-text-[#6D6D74] cqa-ml-auto\" style=\"font-size:18px;width:18px;height:18px\">\n {{ organizedSectionExpanded ? 'expand_less' : 'expand_more' }}\n </mat-icon>\n </button>\n <div\n class=\"cqa-grid\"\n style=\"transition: grid-template-rows 300ms cubic-bezier(0.4, 0, 0.2, 1);\"\n [style.grid-template-rows]=\"organizedSectionExpanded ? '1fr' : '0fr'\"\n >\n <div class=\"cqa-min-h-0\" style=\"overflow: hidden;\">\n <div class=\"cqa-flex cqa-flex-nowrap cqa-gap-3 cqa-overflow-x-auto cqa-scrollbar-thin cqa-pb-1\"\n (scroll)=\"onRootGridScroll($event)\">\n <button\n *ngFor=\"let f of rootFolderTiles\"\n type=\"button\"\n [cqaFolderDrop]=\"f.id\"\n [dropEnabled]=\"modularConfig.allowTestDragDrop\"\n (testsDropped)=\"onTestsDropped($event)\"\n (click)=\"onFolderSelected(f.id)\"\n class=\"cqa-group cqa-flex-shrink-0 cqa-w-[240px] cqa-flex cqa-items-center cqa-justify-between cqa-gap-3 cqa-text-left cqa-p-3 cqa-rounded-[10px] cqa-border-solid cqa-border-[0.5px] cqa-border-[#E2E2E3] cqa-bg-white hover:cqa-border-[#3F43EE] hover:cqa-shadow-sm cqa-transition-colors\"\n >\n <div class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-min-w-0\">\n <ng-container *ngTemplateOutlet=\"folderIconChip; context: { color: f.color }\"></ng-container>\n <div class=\"cqa-flex cqa-flex-col cqa-min-w-0\">\n <span class=\"cqa-text-[15px] cqa-text-[#161617] cqa-truncate cqa-leading-tight group-hover:cqa-text-[#3F43EE]\">{{ f.name }}</span>\n <span *ngIf=\"modularConfig.showCounts\" class=\"cqa-text-sm cqa-text-neutral-500 cqa-truncate\">\n {{ (f.count ?? 0) === 1 ? modularLabels.testsCountSingular : modularLabels.testsCountPlural.replace('{n}', '' + (f.count ?? 0)) }}<ng-container *ngIf=\"f.children?.length\"> \u00B7 {{ f.children!.length === 1 ? modularLabels.oneSubfolder : modularLabels.subfoldersCount.replace('{n}', '' + f.children!.length) }}</ng-container>\n </span>\n </div>\n </div>\n <mat-icon class=\"cqa-text-neutral-400 cqa-flex-shrink-0\" style=\"font-size:20px;width:20px;height:20px\">chevron_right</mat-icon>\n </button>\n\n <!-- \"+ New folder\" tile -->\n <button\n *ngIf=\"modularConfig.allowCreateFolder\"\n type=\"button\"\n (click)=\"onFolderCreateRequested({ parentId: null })\"\n class=\"cqa-group cqa-flex-shrink-0 cqa-w-[240px] cqa-flex cqa-items-center cqa-gap-3 cqa-text-left cqa-p-3 cqa-rounded-[10px] cqa-border-dashed cqa-border-[0.5px] cqa-border-[#E2E2E3] cqa-bg-[#FAFAFA] hover:cqa-border-[#3F43EE] hover:cqa-bg-white cqa-transition-colors\"\n >\n <ng-container *ngTemplateOutlet=\"addIconChip\"></ng-container>\n <div class=\"cqa-flex cqa-flex-col cqa-min-w-0\">\n <span class=\"cqa-text-[15px] cqa-text-[#161617] cqa-truncate cqa-leading-tight group-hover:cqa-text-[#3F43EE]\">{{ modularLabels.newFolder }}</span>\n <span class=\"cqa-text-sm cqa-text-neutral-400\">{{ modularLabels.testsCountPlural.replace('{n}', '0') }}</span>\n </div>\n </button>\n\n <!-- Pagination spinner anchored at the right edge of the Organized\n row. Only renders during an in-flight root fetch (initial OR\n scroll-driven \"load more\"), and is filtered to suppress when\n the section is empty so we don't show a spinner inside an\n otherwise-blank row. -->\n <div\n *ngIf=\"rootFoldersLoading && rootFolderTiles.length > 0\"\n class=\"cqa-flex-shrink-0 cqa-flex cqa-items-center cqa-justify-center cqa-w-[80px]\"\n aria-live=\"polite\"\n [attr.aria-label]=\"'Loading more folders'\"\n >\n <ng-container *ngTemplateOutlet=\"loadingSpinner; context: { size: 20 }\"></ng-container>\n </div>\n </div>\n </div>\n </div>\n </section>\n\n <!-- Subfolder section: modular + folder view. Shown whenever drilled in\n (even if no subfolders, so the \"+ New folder\" tile remains\n reachable, and so we can render a loading state during the\n drill-in fetch before children arrive). -->\n <section\n *ngIf=\"isModularView && !isRootView && modularConfig.showSubfolderSection && (subfolderTiles.length || currentFolderNode?.childrenLoading)\"\n class=\"cqa-grid\"\n style=\"transition: grid-template-rows 300ms cubic-bezier(0.4, 0, 0.2, 1);\"\n [style.grid-template-rows]=\"subfolderSectionExpanded ? '1fr' : '0fr'\"\n >\n <div class=\"cqa-min-h-0\" style=\"overflow: hidden;\">\n <div class=\"cqa-px-3 cqa-py-2 cqa-flex cqa-flex-nowrap cqa-gap-3 cqa-overflow-x-auto cqa-scrollbar-thin\"\n (scroll)=\"onSubfolderGridScroll($event)\">\n <button\n *ngFor=\"let f of subfolderTiles\"\n type=\"button\"\n [cqaFolderDrop]=\"f.id\"\n [dropEnabled]=\"modularConfig.allowTestDragDrop\"\n (testsDropped)=\"onTestsDropped($event)\"\n (click)=\"onFolderSelected(f.id)\"\n class=\"cqa-group cqa-flex-shrink-0 cqa-w-[240px] cqa-flex cqa-items-center cqa-justify-between cqa-gap-3 cqa-text-left cqa-p-3 cqa-rounded-[10px] cqa-border-solid cqa-border-[0.5px] cqa-border-[#E2E2E3] cqa-bg-white hover:cqa-border-[#3F43EE] hover:cqa-shadow-sm cqa-transition-colors\"\n >\n <div class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-min-w-0\">\n <ng-container *ngTemplateOutlet=\"folderIconChip; context: { color: f.color }\"></ng-container>\n <div class=\"cqa-flex cqa-flex-col cqa-min-w-0\">\n <span class=\"cqa-text-[15px] cqa-text-[#161617] cqa-truncate cqa-leading-tight group-hover:cqa-text-[#3F43EE]\">{{ f.name }}</span>\n <span *ngIf=\"modularConfig.showCounts\" class=\"cqa-text-sm cqa-text-neutral-500 cqa-truncate\">\n {{ (f.count ?? 0) === 1 ? modularLabels.testsCountSingular : modularLabels.testsCountPlural.replace('{n}', '' + (f.count ?? 0)) }}\n </span>\n </div>\n </div>\n <mat-icon class=\"cqa-text-neutral-400 cqa-flex-shrink-0\" style=\"font-size:20px;width:20px;height:20px\">chevron_right</mat-icon>\n </button>\n\n <!-- \"+ New folder\" tile -->\n <button\n *ngIf=\"modularConfig.allowCreateFolder\"\n type=\"button\"\n (click)=\"onFolderCreateRequested({ parentId: selectedFolderId })\"\n class=\"cqa-group cqa-flex-shrink-0 cqa-w-[240px] cqa-flex cqa-items-center cqa-gap-3 cqa-text-left cqa-p-3 cqa-rounded-[10px] cqa-border-dashed cqa-border-[0.5px] cqa-border-[#E2E2E3] cqa-bg-[#FAFAFA] hover:cqa-border-[#3F43EE] hover:cqa-bg-white cqa-transition-colors\"\n >\n <ng-container *ngTemplateOutlet=\"addIconChip\"></ng-container>\n <div class=\"cqa-flex cqa-flex-col cqa-min-w-0\">\n <span class=\"cqa-text-[15px] cqa-text-[#161617] cqa-truncate cqa-leading-tight group-hover:cqa-text-[#3F43EE]\">{{ modularLabels.newFolder }}</span>\n <span class=\"cqa-text-sm cqa-text-neutral-400\">{{ modularLabels.testsCountPlural.replace('{n}', '0') }}</span>\n </div>\n </button>\n\n <!-- Subfolder fetch indicator. Two cases:\n - Drill-in fetch: no subfolderTiles yet, render a centered\n row spinner so the section isn't empty during the fetch.\n - Pagination fetch: tiles exist, anchor a small spinner at\n the right edge so the user knows the next page is loading. -->\n <div\n *ngIf=\"currentFolderNode?.childrenLoading\"\n class=\"cqa-flex-shrink-0 cqa-flex cqa-items-center cqa-justify-center cqa-w-[80px]\"\n aria-live=\"polite\"\n [attr.aria-label]=\"'Loading subfolders'\"\n >\n <ng-container *ngTemplateOutlet=\"loadingSpinner; context: { size: 20 }\"></ng-container>\n </div>\n </div>\n </div>\n </section>\n\n <div\n *ngIf=\"isModularView && !isRootView && modularConfig.showUnorganizedSection\"\n class=\"cqa-flex cqa-items-center cqa-justify-between cqa-px-4 cqa-py-3 cqa-border cqa-border-indigo-100\"\n style=\"background-color: #D8D9FC;\"\n >\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <svg width=\"14\" height=\"13\" viewBox=\"0 0 14 13\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M12.9585 10.4585C12.9585 10.79 12.8268 11.108 12.5924 11.3424C12.358 11.5768 12.04 11.7085 11.7085 11.7085H1.7085C1.37698 11.7085 1.05903 11.5768 0.824613 11.3424C0.590192 11.108 0.458496 10.79 0.458496 10.4585V1.7085C0.458496 1.37698 0.590192 1.05903 0.824613 0.824613C1.05903 0.590192 1.37698 0.458496 1.7085 0.458496H4.8335L6.0835 2.3335H11.7085C12.04 2.3335 12.358 2.46519 12.5924 2.69961C12.8268 2.93403 12.9585 3.25198 12.9585 3.5835V10.4585Z\" stroke=\"#3F43EE\" stroke-width=\"0.916667\"/>\n </svg>\n <span class=\"cqa-text-sm cqa-font-semibold\" style=\"color: #3F43EE;\">\n {{ currentFolderNode?.name }} ({{ currentFolderDirectCount }})\n </span>\n </div>\n <cqa-button\n variant=\"outlined\"\n btnSize=\"sm\"\n customClass=\"!cqa-text-[13px]\"\n inlineStyles=\"border-color: #3F43EE; color: #3F43EE;\"\n [text]=\"modularLabels.clearFilter\"\n (clicked)=\"onFolderSelected(null)\"\n ></cqa-button>\n </div>\n\n <!-- Unorganized section header at root view -->\n <div\n *ngIf=\"isModularView && isRootView && modularConfig.showUnorganizedSection\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-mb-2 cqa-mt-2\" style=\"margin-left: 20px;\"\n >\n <mat-icon class=\"cqa-text-[#6D6D74]\" style=\"font-size:16px;width:16px;height:16px\">inbox</mat-icon>\n <h3 class=\"cqa-text-sm cqa-font-semibold cqa-text-[#6D6D74]\">{{ modularLabels.unorganized }}</h3>\n <span class=\"cqa-text-xs cqa-text-[#6D6D74]\">\n {{ unorganizedCount === 1 ? modularLabels.testsCountSingular : modularLabels.testsCountPlural.replace('{n}', '' + unorganizedCount) }}\n </span>\n </div>\n\n <div class=\"cqa-overflow-hidden cqa-border-t cqa-border-l cqa-border-r cqa-border-grey-200 cqa-relative cqa-overflow-x-auto\"\n [class.cqa-modular-table-flush]=\"isModularView\"\n [attr.style]=\"(!isModularView ? 'border-radius: 7px;' : '') + ((pagedRows && pagedRows.length > 0) ? '' : ' border-bottom: none !important;')\">\n <ng-container *ngIf=\"(isTableLoading || isTableDataLoading) || (!effectiveIsEmptyState && pagedRows && pagedRows.length > 0); else storyEmptyTpl\">\n <app-dynamic-table\n [style.border-bottom]=\"pagedRows && pagedRows.length > 0 ? '1px solid rgb(226, 226, 227)' : null\"\n [columns]=\"computedColumns\"\n [data]=\"pagedRows\"\n [rowSelectable]=\"rowSelectable\"\n [enableLocalSort]=\"enableLocalSort && !isReordering\"\n [isTableLoading]=\"isTableLoading\"\n [isTableDataLoading]=\"isTableDataLoading\"\n [cellJsonPathGetter]=\"cellJsonPathGetter\"\n [onJsonPathCopiedHandler]=\"onJsonPathCopiedHandler\"\n [enableRowReorder]=\"isReordering\"\n (rowReorder)=\"onRowReorder($event)\"\n (sortChange)=\"sortChange.emit($event)\">\n <ng-template #emptyTableTpl>\n <div class=\"cqa-flex cqa-flex-col cqa-items-center cqa-justify-center cqa-py-8\">\n <img src=\"/assets/illustrations/empty-state.svg\" alt=\"No data\" class=\"cqa-w-32 cqa-h-32 cqa-mb-4\" />\n <h3 class=\"cqa-text-lg cqa-font-semibold cqa-mb-2\">No test cases</h3>\n <p class=\"cqa-text-sm cqa-text-neutral-500 cqa-mb-4\">Try adjusting filters or create a new test case.</p>\n <cqa-button variant=\"filled\" (clicked)=\"toggleFilter()\">Show Filters</cqa-button>\n </div>\n </ng-template>\n </app-dynamic-table>\n </ng-container>\n\n <ng-template #storyEmptyTpl>\n <div class=\"cqa-p-6 cqa-flex cqa-flex-col cqa-items-center cqa-justify-center\">\n <cqa-empty-state\n *ngIf=\"effectiveIsEmptyState\"\n [title]=\"effectiveEmptyStateConfig.title\"\n [description]=\"effectiveEmptyStateConfig.description\"\n [imageUrl]=\"effectiveEmptyStateConfig.imageUrl\"\n [actions]=\"effectiveEmptyStateConfig.actions\"\n (actionClick)=\"onEmptyAction($event)\"\n >\n </cqa-empty-state>\n </div>\n </ng-template>\n </div>\n\n <cqa-pagination\n [totalElements]=\"serverSidePagination ? totalElements : filteredRows.length\"\n [pageIndex]=\"pageIndex\"\n [pageSize]=\"pageSize\"\n [pageSizeOptions]=\"pageSizeOptions\"\n [pageSizeMenuDirection]=\"pageSizeMenuDirection\"\n [pageItemCount]=\"pagedRows.length\"\n (paginate)=\"onPaginate($event)\"\n (pageSizeChange)=\"onPageSizeChange($event)\"\n >\n </cqa-pagination>\n </div>\n </div>\n\n <!-- Reused bulk action toolbar -->\n <div *ngIf=\"anyRowSelected && modularConfig.allowBulkSelection && !isReordering\" class=\"cqa-absolute cqa-bottom-[18.75px] cqa-left-[50%] cqa-translate-x-[-50%] cqa-w-full lg:cqa-max-w-[68%] cqa-sm:max-w-[75%] cqa-max-w-[90%] cqa-z-[1]\">\n <cqa-table-action-toolbar\n [selectedItems]=\"selectedItems && selectedItems.length > 0 ? selectedItems : currentSelectedItems\"\n [actions]=\"effectiveBulkActions\"\n [showSelectAll]=\"showSelectAllInToolbar\"\n [allSelected]=\"allSelectedInToolbar\"\n [showDismiss]=\"showDismissInToolbar\"\n (actionClick)=\"onBulkAction($event)\"\n (selectAllChange)=\"onBulkSelectAll($event)\"\n (dismiss)=\"onBulkDismiss()\"\n ></cqa-table-action-toolbar>\n </div>\n\n </div>\n</div>\n\n" }]
11531
+ args: [{ selector: 'cqa-modular-table-template', host: { class: 'cqa-ui-root' }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Reusable folder-icon chip. Render via <ng-container *ngTemplateOutlet=\"folderIconChip; context: { color: f.color }\"></ng-container>. -->\n<ng-template #folderIconChip let-color=\"color\">\n <span class=\"cqa-inline-flex cqa-items-center cqa-justify-center cqa-w-10 cqa-h-10 cqa-rounded-lg cqa-bg-[#F0F0F1] cqa-text-[#6D6D74] cqa-flex-shrink-0 group-hover:cqa-bg-indigo-50 group-hover:cqa-text-[#3F43EE]\">\n <svg width=\"14\" height=\"13\" viewBox=\"0 0 14 13\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M12.9583 10.4585C12.9583 10.79 12.8266 11.108 12.5921 11.3424C12.3577 11.5768 12.0398 11.7085 11.7083 11.7085H1.70825C1.37673 11.7085 1.05879 11.5768 0.824368 11.3424C0.589948 11.108 0.458252 10.79 0.458252 10.4585V1.7085C0.458252 1.37698 0.589948 1.05903 0.824368 0.824613C1.05879 0.590192 1.37673 0.458496 1.70825 0.458496H4.83325L6.08325 2.3335H11.7083C12.0398 2.3335 12.3577 2.46519 12.5921 2.69961C12.8266 2.93403 12.9583 3.25198 12.9583 3.5835V10.4585Z\" [attr.stroke]=\"color || 'currentColor'\" stroke-width=\"0.916667\"/>\n </svg>\n </span>\n</ng-template>\n\n<!-- Reusable indeterminate loading spinner. Render via\n <ng-container *ngTemplateOutlet=\"loadingSpinner; context: { size: 20 }\"></ng-container>. -->\n<ng-template #loadingSpinner let-size=\"size\">\n <svg [attr.width]=\"size || 20\" [attr.height]=\"size || 20\" viewBox=\"0 0 50 50\" aria-label=\"loading\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"25\" cy=\"25\" r=\"20\" stroke=\"#E5E7EB\" stroke-width=\"6\" fill=\"none\"></circle>\n <path d=\"M45 25a20 20 0 0 0-20-20\" stroke=\"#4F46E5\" stroke-width=\"6\" fill=\"none\" stroke-linecap=\"round\">\n <animateTransform attributeName=\"transform\" type=\"rotate\" from=\"0 25 25\" to=\"360 25 25\" dur=\"0.8s\" repeatCount=\"indefinite\"></animateTransform>\n </path>\n </svg>\n</ng-template>\n\n<!-- Reusable \"+\" chip used by the \"New folder\" tile. -->\n<ng-template #addIconChip>\n <span class=\"cqa-inline-flex cqa-items-center cqa-justify-center cqa-w-10 cqa-h-10 cqa-rounded-lg cqa-bg-[#F0F0F1] cqa-text-[#6D6D74] cqa-flex-shrink-0 group-hover:cqa-bg-indigo-50 group-hover:cqa-text-[#3F43EE]\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M8 3V13M3 8H13\" stroke=\"currentColor\" stroke-width=\"1.275\" stroke-linecap=\"round\"/>\n </svg>\n </span>\n</ng-template>\n\n<div class=\"cqa-ui-root\">\n <div class=\"cqa-w-full cqa-max-w-full cqa-flex cqa-flex-col cqa-relative cqa-min-w-0\">\n <div [class]=\"!showSearchBar ? 'cqa-justify-end' : 'cqa-justify-between'\" class=\"cqa-w-full cqa-flex cqa-items-center cqa-gap-3 cqa-flex-wrap cqa-mb-3\">\n <cqa-search-bar\n *ngIf=\"showSearchBar\"\n [placeholder]=\"searchPlaceholder\"\n [value]=\"searchValue\"\n [showClear]=\"showClear\"\n (valueChange)=\"valueChange($event)\"\n (search)=\"search($event)\"\n (cleared)=\"cleared()\"\n ></cqa-search-bar>\n <div class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-flex-wrap\">\n <cqa-button\n *ngIf=\"showExportButton\"\n variant=\"grey-solid\"\n icon=\"open_in_new\"\n [text]=\"isExporting ? 'Exporting...' : 'Export'\"\n [disabled]=\"isExporting\"\n (clicked)=\"exportCodeClick()\"\n >\n <span>{{ isExporting ? 'Exporting...' : 'Export' }}</span>\n </cqa-button>\n \n <!-- Export Code Modal -->\n <cqa-export-code-modal\n *ngIf=\"showExportButton\"\n [isOpen]=\"isExportModalOpen\"\n [cases]=\"selectedCasesForExport\"\n [disabled]=\"false\"\n (closeModal)=\"closeExportModal()\"\n (export)=\"onExportModalExport($event)\">\n </cqa-export-code-modal>\n <ng-container *ngFor=\"let dropdownTemplate of otherDropDownButtons; trackBy: trackByDropdownTemplateRef\">\n <ng-container *ngTemplateOutlet=\"dropdownTemplate\"></ng-container>\n </ng-container>\n\n <ng-container *ngFor=\"let selectDropdownTemplate of otherSelectDropDownButtons; trackBy: trackBySelectDropdownTemplateRef\">\n <ng-container *ngTemplateOutlet=\"selectDropdownTemplate\"></ng-container>\n </ng-container>\n \n <cqa-button\n *ngIf=\"showFilterButton\"\n variant=\"grey-solid\"\n icon=\"add\"\n [disabled]=\"isReordering\"\n (clicked)=\"toggleFilter()\"\n >\n <span class=\"cqa-flex cqa-items-center cqa-gap-1\">\n Filter \n <div [class]=\"arrowClasses\">\n <svg\n class=\"cqa-w-2 cqa-h-1 cqa-absolute cqa-left-[4px] cqa-top-[6px]\"\n viewBox=\"0 0 8 4\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M0 0L4 4L8 0\"\n stroke=\"#0B0B0C\"\n stroke-width=\"1.33\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </div>\n </span>\n </cqa-button>\n <cqa-column-visibility\n *ngIf=\"showSettingsButton\"\n [columns]=\"visibilityColumns\"\n [columnVisibility]=\"columnVisibility\"\n [selectedAutoRefreshInterval]=\"selectedAutoRefreshInterval\"\n (columnVisibilityChange)=\"onColumnVisibilityChange($event)\"\n (autoRefreshChange)=\"onAutoRefreshChange($event)\"\n ></cqa-column-visibility>\n <cqa-button\n *ngIf=\"showAutoRefreshButton\"\n variant=\"grey-solid\"\n icon=\"refresh\"\n (clicked)=\"handleRefreshClick()\"\n [tooltip]=\"'Refresh'\"\n tooltipPosition=\"below\"\n [disabled]=\"isReordering\"\n ></cqa-button>\n <ng-container *ngFor=\"let buttonTemplate of otherButtons; trackBy: trackByTemplateRef\">\n <ng-container *ngTemplateOutlet=\"buttonTemplate\"></ng-container>\n </ng-container>\n <cqa-segment-control\n *ngIf=\"showViewModeToggle\"\n size=\"lg\"\n [segments]=\"viewModeSegments\"\n [value]=\"viewMode\"\n (valueChange)=\"onViewModeChange($event)\"\n ></cqa-segment-control>\n <cqa-button\n *ngIf=\"showReorderButton && !isReordering\"\n variant=\"outlined\"\n icon=\"drag_indicator\"\n [text]=\"reorderLabels.reorderButton\"\n [disabled]=\"!pagedRows || pagedRows.length === 0 || isTableLoading || isTableDataLoading\"\n (clicked)=\"startReorder()\"\n ></cqa-button>\n <ng-container *ngIf=\"showReorderButton && isReordering\">\n <cqa-button\n variant=\"outlined\"\n [text]=\"reorderLabels.cancelButton\"\n [disabled]=\"reorderSaving\"\n (clicked)=\"cancelReorder()\"\n ></cqa-button>\n <cqa-button\n variant=\"filled\"\n [icon]=\"reorderSaving ? 'hourglass_empty' : ''\"\n [text]=\"reorderSaving ? reorderLabels.savingButton : reorderLabels.doneButton\"\n [disabled]=\"reorderSaving\"\n (clicked)=\"saveReorder()\"\n ></cqa-button>\n </ng-container>\n </div>\n </div>\n\n <!-- Reorder mode banner -->\n <div *ngIf=\"isReordering\" class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-mb-3 cqa-px-3 cqa-py-2 cqa-rounded-md cqa-bg-[#FFFBEB] cqa-border cqa-border-[#FDE68A]\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <circle cx=\"3\" cy=\"3\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"8\" cy=\"3\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"13\" cy=\"3\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"3\" cy=\"8\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"8\" cy=\"8\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"13\" cy=\"8\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"3\" cy=\"13\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"8\" cy=\"13\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"13\" cy=\"13\" r=\"1.5\" fill=\"#92400E\"></circle>\n </svg>\n <span class=\"cqa-text-sm cqa-font-semibold cqa-text-[#92400E]\">{{ reorderLabels.bannerTitle }}</span>\n <span class=\"cqa-text-sm cqa-text-[#92400E]\">{{ reorderLabels.bannerDescription }}</span>\n </div>\n\n <cqa-selected-filters\n [filterApplied]=\"filterApplied\"\n [chips]=\"chips\"\n (removeChip)=\"onRemoveChip($event)\"\n (clearAll)=\"onClearAllChips()\"\n (onClearAll)=\"onClearAll.emit()\"\n >\n </cqa-selected-filters>\n\n <cqa-dynamic-filter\n *ngIf=\"showFilterPanel\"\n [config]=\"filterConfig\"\n [model]=\"filterModel\"\n [showFilterPanel]=\"showFilterPanel\"\n (filtersChanged)=\"onFiltersChanged($event)\"\n (filtersApplied)=\"onFiltersApplied($event)\"\n (onApplyFilterClick)=\"onApplyFilterClick.emit($event)\"\n (onResetFilterClick)=\"handleResetFilterClick()\"\n >\n </cqa-dynamic-filter>\n\n <div class=\"cqa-flex cqa-items-stretch cqa-gap-2 cqa-min-h-0 cqa-min-w-0 cqa-w-full cqa-max-w-full cqa-overflow-hidden\" style=\"border-bottom: 1px solid rgb(226, 226, 227);\">\n <!-- Sidebar (only shown in modular view) -->\n <cqa-folder-sidebar\n *ngIf=\"isModularView && modularConfig.showSidebar\"\n [folders]=\"folders\"\n [selectedFolderId]=\"selectedFolderId\"\n [expandedFolderIds]=\"expandedFolderIds\"\n [unorganizedCount]=\"unorganizedCount\"\n [allowCreate]=\"modularConfig.allowCreateFolder\"\n [allowRename]=\"modularConfig.allowRenameFolder\"\n [allowDelete]=\"modularConfig.allowDeleteFolder\"\n [allowDrop]=\"modularConfig.allowTestDragDrop\"\n [allowDuplicate]=\"modularConfig.allowDuplicateFolder\"\n [showCounts]=\"modularConfig.showCounts\"\n [collapsed]=\"sidebarCollapsed\"\n [labels]=\"modularLabels\"\n [serverSideSearch]=\"serverSideSearch\"\n [rootTotal]=\"rootTotal\"\n [folderSearchLoading]=\"folderSearchLoading\"\n [rootFoldersLoading]=\"rootFoldersLoading\"\n [savingFolderIds]=\"savingFolderIds\"\n [searchValue]=\"folderSearchValue\"\n (folderSelected)=\"onFolderSelected($event)\"\n (folderExpansionToggled)=\"onFolderExpansionToggled($event)\"\n (folderChildrenRequested)=\"folderChildrenRequested.emit($event)\"\n (folderLoadMoreRequested)=\"folderLoadMoreRequested.emit($event)\"\n (rootLoadMoreRequested)=\"rootLoadMoreRequested.emit()\"\n (searchChange)=\"folderSearchChange.emit($event)\"\n (folderCreated)=\"onFolderCreated($event)\"\n (folderCreateRequested)=\"onFolderCreateRequested($event)\"\n (folderRenamed)=\"onFolderRenamed($event)\"\n (folderDeleted)=\"onFolderDeleted($event)\"\n (folderMoveRequested)=\"onFolderMoveRequested($event)\"\n (folderDuplicateRequested)=\"onFolderDuplicateRequested($event)\"\n (testsDropped)=\"onTestsDropped($event)\"\n (folderDropped)=\"onFolderDropped($event)\"\n (collapsedChange)=\"onSidebarCollapsedChange($event)\"\n ></cqa-folder-sidebar>\n\n <!-- Right pane -->\n <div\n class=\"cqa-flex-1 cqa-flex cqa-flex-col cqa-min-w-0\"\n [style.border-top]=\"isModularView ? '1px solid #E2E2E3' : null\"\n [style.border-left]=\"isModularView ? '1px solid #E2E2E3' : null\"\n [style.border-right]=\"isModularView ? '1px solid #E2E2E3' : null\"\n >\n <!-- Breadcrumb (modular view, folder drilled-in) -->\n <nav\n *ngIf=\"isModularView && modularConfig.showBreadcrumb && !isRootView\"\n aria-label=\"Folder path\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-text-sm cqa-px-3 cqa-py-2 cqa-rounded-none cqa-min-w-0\"\n style=\"color: #6D6D74; border-bottom: 1px solid #E2E2E3;\"\n >\n <div class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-flex-1 cqa-min-w-0 cqa-overflow-x-auto cqa-scrollbar-thin cqa-whitespace-nowrap\">\n <button type=\"button\" class=\"hover:cqa-text-[#3F43EE] cqa-inline-flex cqa-items-center cqa-gap-1 cqa-flex-shrink-0\" (click)=\"onFolderSelected(null)\">\n <svg width=\"14\" height=\"13\" viewBox=\"0 0 14 13\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M12.9583 10.4585C12.9583 10.79 12.8266 11.108 12.5921 11.3424C12.3577 11.5768 12.0398 11.7085 11.7083 11.7085H1.70825C1.37673 11.7085 1.05879 11.5768 0.824368 11.3424C0.589948 11.108 0.458252 10.79 0.458252 10.4585V1.7085C0.458252 1.37698 0.589948 1.05903 0.824368 0.824613C1.05879 0.590192 1.37673 0.458496 1.70825 0.458496H4.83325L6.08325 2.3335H11.7083C12.0398 2.3335 12.3577 2.46519 12.5921 2.69961C12.8266 2.93403 12.9583 3.25198 12.9583 3.5835V10.4585Z\" stroke=\"currentColor\" stroke-width=\"0.916667\"/>\n </svg>\n <span>{{ modularLabels.allFolders }}</span>\n </button>\n <ng-container *ngFor=\"let crumb of breadcrumbTrail; let last = last\">\n <mat-icon class=\"cqa-align-middle cqa-flex-shrink-0\" style=\"font-size:16px;width:16px;height:16px;color:#6D6D74;\">chevron_right</mat-icon>\n <button\n type=\"button\"\n class=\"cqa-flex-shrink-0\"\n [ngClass]=\"last\n ? 'cqa-text-[#161617] cqa-font-semibold'\n : 'cqa-text-[#6D6D74] hover:cqa-text-[#3F43EE]'\"\n [disabled]=\"last\"\n (click)=\"!last && onFolderSelected(crumb.id)\"\n >{{ crumb.name }}</button>\n </ng-container>\n </div>\n <cqa-button\n *ngIf=\"modularConfig.showSubfolderSection && subfolderTiles.length\"\n class=\"cqa-flex-shrink-0\"\n variant=\"text\"\n btnSize=\"sm\"\n customClass=\"!cqa-text-[13px] !cqa-leading-[18px]\"\n [icon]=\"subfolderSectionExpanded ? 'expand_less' : 'expand_more'\"\n [text]=\"(subfolderSectionExpanded ? 'Hide' : 'Show') + ' subfolders'\"\n [attr.aria-expanded]=\"subfolderSectionExpanded\"\n (clicked)=\"toggleSubfolderSection()\"\n ></cqa-button>\n <cqa-button\n *ngIf=\"modularConfig.allowCreateFolder\"\n class=\"cqa-flex-shrink-0\"\n variant=\"text\"\n btnSize=\"sm\"\n customClass=\"!cqa-text-[13px] !cqa-leading-[18px]\"\n icon=\"add\"\n [text]=\"modularLabels.newFolder\"\n (clicked)=\"onFolderCreateRequested({ parentId: selectedFolderId })\"\n ></cqa-button>\n </nav>\n\n <!-- Folder grid: modular + root view -->\n <section\n *ngIf=\"isModularView && isRootView && modularConfig.showFolderGrid && rootFolderTiles.length\"\n class=\"cqa-px-5 cqa-pt-2\"\n style=\"border-bottom: 1px solid #F0F0F1;\"\n >\n <button\n type=\"button\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-mb-2 cqa-w-full cqa-text-left\"\n [attr.aria-expanded]=\"organizedSectionExpanded\"\n (click)=\"toggleOrganizedSection()\"\n >\n <svg width=\"14\" height=\"13\" viewBox=\"0 0 14 13\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M12.9583 10.4585C12.9583 10.79 12.8266 11.108 12.5921 11.3424C12.3577 11.5768 12.0398 11.7085 11.7083 11.7085H1.70825C1.37673 11.7085 1.05879 11.5768 0.824368 11.3424C0.589948 11.108 0.458252 10.79 0.458252 10.4585V1.7085C0.458252 1.37698 0.589948 1.05903 0.824368 0.824613C1.05879 0.590192 1.37673 0.458496 1.70825 0.458496H4.83325L6.08325 2.3335H11.7083C12.0398 2.3335 12.3577 2.46519 12.5921 2.69961C12.8266 2.93403 12.9583 3.25198 12.9583 3.5835V10.4585Z\" stroke=\"#6D6D74\" stroke-width=\"0.916667\"/>\n </svg>\n <h3 class=\"cqa-text-sm cqa-font-semibold cqa-text-[#6D6D74]\">{{ modularLabels.organized }}</h3>\n <span class=\"cqa-text-xs cqa-text-[#6D6D74]\">\n {{ rootFolderTiles.length === 1 ? modularLabels.foldersCountSingular : modularLabels.foldersCountPlural.replace('{n}', '' + rootFolderTiles.length) }}\n </span>\n <mat-icon class=\"cqa-text-[#6D6D74] cqa-ml-auto\" style=\"font-size:18px;width:18px;height:18px\">\n {{ organizedSectionExpanded ? 'expand_less' : 'expand_more' }}\n </mat-icon>\n </button>\n <div\n class=\"cqa-grid\"\n style=\"transition: grid-template-rows 300ms cubic-bezier(0.4, 0, 0.2, 1);\"\n [style.grid-template-rows]=\"organizedSectionExpanded ? '1fr' : '0fr'\"\n >\n <div class=\"cqa-min-h-0\" style=\"overflow: hidden;\">\n <div class=\"cqa-flex cqa-flex-nowrap cqa-gap-3 cqa-overflow-x-auto cqa-scrollbar-thin cqa-pb-1\"\n (scroll)=\"onRootGridScroll($event)\">\n <button\n *ngFor=\"let f of rootFolderTiles\"\n type=\"button\"\n [cqaFolderDrop]=\"f.id\"\n [dropEnabled]=\"modularConfig.allowTestDragDrop\"\n (testsDropped)=\"onTestsDropped($event)\"\n (click)=\"onFolderSelected(f.id)\"\n class=\"cqa-group cqa-flex-shrink-0 cqa-w-[240px] cqa-flex cqa-items-center cqa-justify-between cqa-gap-3 cqa-text-left cqa-p-3 cqa-rounded-[10px] cqa-border-solid cqa-border-[0.5px] cqa-border-[#E2E2E3] cqa-bg-white hover:cqa-border-[#3F43EE] hover:cqa-shadow-sm cqa-transition-colors\"\n >\n <div class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-min-w-0\">\n <ng-container *ngTemplateOutlet=\"folderIconChip; context: { color: f.color }\"></ng-container>\n <div class=\"cqa-flex cqa-flex-col cqa-min-w-0\">\n <span class=\"cqa-text-[15px] cqa-text-[#161617] cqa-truncate cqa-leading-tight group-hover:cqa-text-[#3F43EE]\">{{ f.name }}</span>\n <span *ngIf=\"modularConfig.showCounts\" class=\"cqa-text-sm cqa-text-neutral-500 cqa-truncate\">\n {{ (f.count ?? 0) === 1 ? modularLabels.testsCountSingular : modularLabels.testsCountPlural.replace('{n}', '' + (f.count ?? 0)) }}<ng-container *ngIf=\"f.children?.length\"> \u00B7 {{ f.children!.length === 1 ? modularLabels.oneSubfolder : modularLabels.subfoldersCount.replace('{n}', '' + f.children!.length) }}</ng-container>\n </span>\n </div>\n </div>\n <mat-icon class=\"cqa-text-neutral-400 cqa-flex-shrink-0\" style=\"font-size:20px;width:20px;height:20px\">chevron_right</mat-icon>\n </button>\n\n <!-- \"+ New folder\" tile -->\n <button\n *ngIf=\"modularConfig.allowCreateFolder\"\n type=\"button\"\n (click)=\"onFolderCreateRequested({ parentId: null })\"\n class=\"cqa-group cqa-flex-shrink-0 cqa-w-[240px] cqa-flex cqa-items-center cqa-gap-3 cqa-text-left cqa-p-3 cqa-rounded-[10px] cqa-border-dashed cqa-border-[0.5px] cqa-border-[#E2E2E3] cqa-bg-[#FAFAFA] hover:cqa-border-[#3F43EE] hover:cqa-bg-white cqa-transition-colors\"\n >\n <ng-container *ngTemplateOutlet=\"addIconChip\"></ng-container>\n <div class=\"cqa-flex cqa-flex-col cqa-min-w-0\">\n <span class=\"cqa-text-[15px] cqa-text-[#161617] cqa-truncate cqa-leading-tight group-hover:cqa-text-[#3F43EE]\">{{ modularLabels.newFolder }}</span>\n <span class=\"cqa-text-sm cqa-text-neutral-400\">{{ modularLabels.testsCountPlural.replace('{n}', '0') }}</span>\n </div>\n </button>\n\n <!-- Pagination spinner anchored at the right edge of the Organized\n row. Only renders during an in-flight root fetch (initial OR\n scroll-driven \"load more\"), and is filtered to suppress when\n the section is empty so we don't show a spinner inside an\n otherwise-blank row. -->\n <div\n *ngIf=\"rootFoldersLoading && rootFolderTiles.length > 0\"\n class=\"cqa-flex-shrink-0 cqa-flex cqa-items-center cqa-justify-center cqa-w-[80px]\"\n aria-live=\"polite\"\n [attr.aria-label]=\"'Loading more folders'\"\n >\n <ng-container *ngTemplateOutlet=\"loadingSpinner; context: { size: 20 }\"></ng-container>\n </div>\n </div>\n </div>\n </div>\n </section>\n\n <!-- Subfolder section: modular + folder view. Shown whenever drilled in\n (even if no subfolders, so the \"+ New folder\" tile remains\n reachable, and so we can render a loading state during the\n drill-in fetch before children arrive). -->\n <section\n *ngIf=\"isModularView && !isRootView && modularConfig.showSubfolderSection && (subfolderTiles.length || currentFolderNode?.childrenLoading)\"\n class=\"cqa-grid\"\n style=\"transition: grid-template-rows 300ms cubic-bezier(0.4, 0, 0.2, 1);\"\n [style.grid-template-rows]=\"subfolderSectionExpanded ? '1fr' : '0fr'\"\n >\n <div class=\"cqa-min-h-0\" style=\"overflow: hidden;\">\n <div class=\"cqa-px-3 cqa-py-2 cqa-flex cqa-flex-nowrap cqa-gap-3 cqa-overflow-x-auto cqa-scrollbar-thin\"\n (scroll)=\"onSubfolderGridScroll($event)\">\n <button\n *ngFor=\"let f of subfolderTiles\"\n type=\"button\"\n [cqaFolderDrop]=\"f.id\"\n [dropEnabled]=\"modularConfig.allowTestDragDrop\"\n (testsDropped)=\"onTestsDropped($event)\"\n (click)=\"onFolderSelected(f.id)\"\n class=\"cqa-group cqa-flex-shrink-0 cqa-w-[240px] cqa-flex cqa-items-center cqa-justify-between cqa-gap-3 cqa-text-left cqa-p-3 cqa-rounded-[10px] cqa-border-solid cqa-border-[0.5px] cqa-border-[#E2E2E3] cqa-bg-white hover:cqa-border-[#3F43EE] hover:cqa-shadow-sm cqa-transition-colors\"\n >\n <div class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-min-w-0\">\n <ng-container *ngTemplateOutlet=\"folderIconChip; context: { color: f.color }\"></ng-container>\n <div class=\"cqa-flex cqa-flex-col cqa-min-w-0\">\n <span class=\"cqa-text-[15px] cqa-text-[#161617] cqa-truncate cqa-leading-tight group-hover:cqa-text-[#3F43EE]\">{{ f.name }}</span>\n <span *ngIf=\"modularConfig.showCounts\" class=\"cqa-text-sm cqa-text-neutral-500 cqa-truncate\">\n {{ (f.count ?? 0) === 1 ? modularLabels.testsCountSingular : modularLabels.testsCountPlural.replace('{n}', '' + (f.count ?? 0)) }}\n </span>\n </div>\n </div>\n <mat-icon class=\"cqa-text-neutral-400 cqa-flex-shrink-0\" style=\"font-size:20px;width:20px;height:20px\">chevron_right</mat-icon>\n </button>\n\n <!-- \"+ New folder\" tile -->\n <button\n *ngIf=\"modularConfig.allowCreateFolder\"\n type=\"button\"\n (click)=\"onFolderCreateRequested({ parentId: selectedFolderId })\"\n class=\"cqa-group cqa-flex-shrink-0 cqa-w-[240px] cqa-flex cqa-items-center cqa-gap-3 cqa-text-left cqa-p-3 cqa-rounded-[10px] cqa-border-dashed cqa-border-[0.5px] cqa-border-[#E2E2E3] cqa-bg-[#FAFAFA] hover:cqa-border-[#3F43EE] hover:cqa-bg-white cqa-transition-colors\"\n >\n <ng-container *ngTemplateOutlet=\"addIconChip\"></ng-container>\n <div class=\"cqa-flex cqa-flex-col cqa-min-w-0\">\n <span class=\"cqa-text-[15px] cqa-text-[#161617] cqa-truncate cqa-leading-tight group-hover:cqa-text-[#3F43EE]\">{{ modularLabels.newFolder }}</span>\n <span class=\"cqa-text-sm cqa-text-neutral-400\">{{ modularLabels.testsCountPlural.replace('{n}', '0') }}</span>\n </div>\n </button>\n\n <!-- Subfolder fetch indicator. Two cases:\n - Drill-in fetch: no subfolderTiles yet, render a centered\n row spinner so the section isn't empty during the fetch.\n - Pagination fetch: tiles exist, anchor a small spinner at\n the right edge so the user knows the next page is loading. -->\n <div\n *ngIf=\"currentFolderNode?.childrenLoading\"\n class=\"cqa-flex-shrink-0 cqa-flex cqa-items-center cqa-justify-center cqa-w-[80px]\"\n aria-live=\"polite\"\n [attr.aria-label]=\"'Loading subfolders'\"\n >\n <ng-container *ngTemplateOutlet=\"loadingSpinner; context: { size: 20 }\"></ng-container>\n </div>\n </div>\n </div>\n </section>\n\n <div\n *ngIf=\"isModularView && !isRootView && modularConfig.showUnorganizedSection\"\n class=\"cqa-flex cqa-items-center cqa-justify-between cqa-px-4 cqa-py-3 cqa-border cqa-border-indigo-100\"\n style=\"background-color: #D8D9FC;\"\n >\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <svg width=\"14\" height=\"13\" viewBox=\"0 0 14 13\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M12.9585 10.4585C12.9585 10.79 12.8268 11.108 12.5924 11.3424C12.358 11.5768 12.04 11.7085 11.7085 11.7085H1.7085C1.37698 11.7085 1.05903 11.5768 0.824613 11.3424C0.590192 11.108 0.458496 10.79 0.458496 10.4585V1.7085C0.458496 1.37698 0.590192 1.05903 0.824613 0.824613C1.05903 0.590192 1.37698 0.458496 1.7085 0.458496H4.8335L6.0835 2.3335H11.7085C12.04 2.3335 12.358 2.46519 12.5924 2.69961C12.8268 2.93403 12.9585 3.25198 12.9585 3.5835V10.4585Z\" stroke=\"#3F43EE\" stroke-width=\"0.916667\"/>\n </svg>\n <span class=\"cqa-text-sm cqa-font-semibold\" style=\"color: #3F43EE;\">\n {{ currentFolderNode?.name }} ({{ currentFolderDirectCount }})\n </span>\n </div>\n <cqa-button\n variant=\"outlined\"\n btnSize=\"sm\"\n customClass=\"!cqa-text-[13px]\"\n inlineStyles=\"border-color: #3F43EE; color: #3F43EE;\"\n [text]=\"modularLabels.clearFilter\"\n (clicked)=\"onFolderSelected(null)\"\n ></cqa-button>\n </div>\n\n <!-- Unorganized section header at root view -->\n <div\n *ngIf=\"isModularView && isRootView && modularConfig.showUnorganizedSection\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-mb-2 cqa-mt-2\" style=\"margin-left: 20px;\"\n >\n <mat-icon class=\"cqa-text-[#6D6D74]\" style=\"font-size:16px;width:16px;height:16px\">inbox</mat-icon>\n <h3 class=\"cqa-text-sm cqa-font-semibold cqa-text-[#6D6D74]\">{{ modularLabels.unorganized }}</h3>\n <span class=\"cqa-text-xs cqa-text-[#6D6D74]\">\n {{ unorganizedCount === 1 ? modularLabels.testsCountSingular : modularLabels.testsCountPlural.replace('{n}', '' + unorganizedCount) }}\n </span>\n </div>\n\n <div class=\"cqa-overflow-hidden cqa-border-t cqa-border-l cqa-border-r cqa-border-grey-200 cqa-relative cqa-overflow-x-auto\"\n [class.cqa-modular-table-flush]=\"isModularView\"\n [attr.style]=\"(!isModularView ? 'border-radius: 7px;' : '') + ((pagedRows && pagedRows.length > 0) ? '' : ' border-bottom: none !important;')\">\n <ng-container *ngIf=\"(isTableLoading || isTableDataLoading) || (!effectiveIsEmptyState && pagedRows && pagedRows.length > 0); else storyEmptyTpl\">\n <app-dynamic-table\n [style.border-bottom]=\"pagedRows && pagedRows.length > 0 ? '1px solid rgb(226, 226, 227)' : null\"\n [columns]=\"computedColumns\"\n [data]=\"pagedRows\"\n [rowSelectable]=\"rowSelectable\"\n [enableLocalSort]=\"enableLocalSort && !isReordering\"\n [isTableLoading]=\"isTableLoading\"\n [isTableDataLoading]=\"isTableDataLoading\"\n [cellJsonPathGetter]=\"cellJsonPathGetter\"\n [onJsonPathCopiedHandler]=\"onJsonPathCopiedHandler\"\n [enableRowReorder]=\"isReordering\"\n (rowReorder)=\"onRowReorder($event)\"\n (sortChange)=\"sortChange.emit($event)\">\n <ng-template #emptyTableTpl>\n <div class=\"cqa-flex cqa-flex-col cqa-items-center cqa-justify-center cqa-py-8\">\n <img src=\"/assets/illustrations/empty-state.svg\" alt=\"No data\" class=\"cqa-w-32 cqa-h-32 cqa-mb-4\" />\n <h3 class=\"cqa-text-lg cqa-font-semibold cqa-mb-2\">No test cases</h3>\n <p class=\"cqa-text-sm cqa-text-neutral-500 cqa-mb-4\">Try adjusting filters or create a new test case.</p>\n <cqa-button variant=\"filled\" (clicked)=\"toggleFilter()\">Show Filters</cqa-button>\n </div>\n </ng-template>\n </app-dynamic-table>\n </ng-container>\n\n <ng-template #storyEmptyTpl>\n <div class=\"cqa-p-6 cqa-flex cqa-flex-col cqa-items-center cqa-justify-center\">\n <cqa-empty-state\n *ngIf=\"effectiveIsEmptyState\"\n [title]=\"effectiveEmptyStateConfig.title\"\n [description]=\"effectiveEmptyStateConfig.description\"\n [imageUrl]=\"effectiveEmptyStateConfig.imageUrl\"\n [actions]=\"effectiveEmptyStateConfig.actions\"\n (actionClick)=\"onEmptyAction($event)\"\n >\n </cqa-empty-state>\n </div>\n </ng-template>\n </div>\n\n <cqa-pagination\n [totalElements]=\"serverSidePagination ? totalElements : filteredRows.length\"\n [pageIndex]=\"pageIndex\"\n [pageSize]=\"pageSize\"\n [pageSizeOptions]=\"pageSizeOptions\"\n [pageSizeMenuDirection]=\"pageSizeMenuDirection\"\n [pageItemCount]=\"pagedRows.length\"\n (paginate)=\"onPaginate($event)\"\n (pageSizeChange)=\"onPageSizeChange($event)\"\n >\n </cqa-pagination>\n </div>\n </div>\n\n <!-- Reused bulk action toolbar -->\n <div *ngIf=\"anyRowSelected && modularConfig.allowBulkSelection && !isReordering\" class=\"cqa-absolute cqa-bottom-[18.75px] cqa-left-[50%] cqa-translate-x-[-50%] cqa-w-full lg:cqa-max-w-[68%] cqa-sm:max-w-[75%] cqa-max-w-[90%] cqa-z-[1]\">\n <cqa-table-action-toolbar\n [selectedItems]=\"selectedItems && selectedItems.length > 0 ? selectedItems : currentSelectedItems\"\n [actions]=\"effectiveBulkActions\"\n [showSelectAll]=\"showSelectAllInToolbar\"\n [allSelected]=\"allSelectedInToolbar\"\n [showDismiss]=\"showDismissInToolbar\"\n (actionClick)=\"onBulkAction($event)\"\n (selectAllChange)=\"onBulkSelectAll($event)\"\n (dismiss)=\"onBulkDismiss()\"\n ></cqa-table-action-toolbar>\n </div>\n\n </div>\n</div>\n\n" }]
11527
11532
  }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: DialogService }], propDecorators: { searchPlaceholder: [{
11528
11533
  type: Input
11529
11534
  }], searchValue: [{
@@ -12519,6 +12524,7 @@ class TailwindOverlayContainer extends OverlayContainer {
12519
12524
  // Check if this pane itself has library component classes (e.g., backdrop)
12520
12525
  const paneHasLibraryClass = pane.classList.contains('cqa-dialog-panel') ||
12521
12526
  pane.classList.contains('cqa-dialog-backdrop') ||
12527
+ pane.classList.contains('cqa-profile-menu-panel') ||
12522
12528
  pane.classList.contains('ctc-select-panel') ||
12523
12529
  pane.classList.contains('ctc-date-range-panel') ||
12524
12530
  pane.classList.contains('visual-difference-dialog') ||
@@ -12561,6 +12567,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
12561
12567
  type: Injectable
12562
12568
  }] });
12563
12569
 
12570
+ function isProfileMenuDivider(entry) {
12571
+ return entry.type === 'divider';
12572
+ }
12573
+
12564
12574
  function isNavSection(item) {
12565
12575
  return item.type === 'section';
12566
12576
  }
@@ -12713,11 +12723,11 @@ class NavItemComponent {
12713
12723
  }, NavItemComponent.FLYOUT_CLOSE_DELAY_MS);
12714
12724
  }
12715
12725
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NavItemComponent, deps: [{ token: i1$3.Overlay }], target: i0.ɵɵFactoryTarget.Component });
12716
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: NavItemComponent, selector: "cqa-nav-item", inputs: { item: "item", isActive: "isActive", isExpanded: "isExpanded", isOpen: "isOpen", activeNavId: "activeNavId" }, outputs: { itemClick: "itemClick" }, viewQueries: [{ propertyName: "navHostRef", first: true, predicate: ["navHost"], descendants: true }], ngImport: i0, template: "<div id=\"cqa-ui-root\" style=\"display:block\">\n <div\n #navHost\n class=\"cqa-nav-host\"\n [class.cqa-nav-host--collapsed]=\"!isExpanded\"\n (mouseenter)=\"onHostMouseEnter()\"\n (mouseleave)=\"onHostMouseLeave()\"\n (focusin)=\"onHostFocusIn($event)\"\n (focusout)=\"onHostFocusOut($event)\">\n\n <button\n cdkOverlayOrigin\n #flyoutOrigin=\"cdkOverlayOrigin\"\n class=\"cqa-nav-item\"\n [class.cqa-nav-item--active]=\"isActive\"\n [class.cqa-nav-item--has-children]=\"hasChildren\"\n [class.cqa-nav-item--collapsed]=\"!isExpanded\"\n [class.cqa-nav-item--disabled]=\"item?.disabled\"\n [class.cqa-nav-item--has-live]=\"item?.status === 'live'\"\n [matTooltip]=\"collapsedRailTooltip\"\n [matTooltipDisabled]=\"!collapsedRailTooltip\"\n [matTooltipClass]=\"collapsedRailTooltipClass\"\n matTooltipPosition=\"right\"\n (click)=\"onClick()\"\n type=\"button\"\n [attr.aria-label]=\"!isExpanded ? (item?.label || '') : null\"\n [attr.aria-expanded]=\"!isExpanded && hasChildren ? showCollapsedFlyout : null\"\n [attr.aria-haspopup]=\"!isExpanded && hasChildren ? 'menu' : null\">\n\n <!-- Icon -->\n <span class=\"cqa-nav-icon\">\n <i [class]=\"item?.iconClass\"></i>\n </span>\n\n <!-- Label (hidden when sidebar collapsed) -->\n <span class=\"cqa-nav-label\" [class.cqa-nav-label--visible]=\"isExpanded\">\n {{ item?.label }}\n </span>\n\n <!-- Trailing slot: only shown when expanded -->\n <ng-container *ngIf=\"isExpanded\">\n <span *ngIf=\"item?.badge && !hasChildren\" class=\"cqa-nav-badge\">{{ item.badge }}</span>\n\n <span\n *ngIf=\"item?.status === 'live' && !hasChildren\"\n class=\"cqa-nav-status-dot cqa-nav-status-dot--live\">\n </span>\n\n <span\n *ngIf=\"item?.status === 'danger' && !hasChildren\"\n class=\"cqa-nav-status-dot cqa-nav-status-dot--danger\">\n </span>\n\n <span *ngIf=\"hasChildren\" class=\"cqa-nav-chev\" [class.cqa-nav-chev--open]=\"isOpen\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" width=\"14\" height=\"14\">\n <polyline points=\"9,6 15,12 9,18\"/>\n </svg>\n </span>\n </ng-container>\n\n <span\n *ngIf=\"!isExpanded && item?.status === 'live'\"\n class=\"cqa-nav-live-corner\">\n </span>\n </button>\n\n <!-- Collapsed parent submenu: CDK overlay (outside aside / scrolling nav) -->\n <ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"flyoutOrigin\"\n [cdkConnectedOverlayOpen]=\"collapsedFlyoutOpen\"\n [cdkConnectedOverlayPositions]=\"collapsedFlyoutPositions\"\n [cdkConnectedOverlayHasBackdrop]=\"false\"\n [cdkConnectedOverlayPush]=\"true\"\n [cdkConnectedOverlayScrollStrategy]=\"flyoutScrollStrategy\"\n [cdkConnectedOverlayPanelClass]=\"'cqa-nav-flyout-overlay-pane'\"\n (overlayOutsideClick)=\"closeCollapsedFlyout()\"\n (detach)=\"closeCollapsedFlyout()\">\n <div\n class=\"cqa-nav-flyout-overlay cqa-nav-flyout-panel\"\n role=\"menu\"\n [attr.aria-label]=\"item.label\"\n (mouseenter)=\"onFlyoutOverlayPointerEnter()\"\n (mouseleave)=\"onFlyoutOverlayPointerLeave()\"\n (focusout)=\"onFlyoutOverlayFocusOut($event)\">\n <div class=\"cqa-nav-flyout-panel-title\">{{ item.label }}</div>\n <button\n *ngFor=\"let child of item?.children\"\n type=\"button\"\n role=\"menuitem\"\n class=\"cqa-nav-flyout-row\"\n [class.cqa-nav-flyout-row--active]=\"isChildRowActive(child.id)\"\n [disabled]=\"child.disabled\"\n (click)=\"onChildRowClick($event, child)\">\n <span class=\"cqa-nav-flyout-row-icon\">\n <i *ngIf=\"child.iconClass\" [class]=\"child.iconClass\"></i>\n </span>\n <span class=\"cqa-nav-flyout-row-label\">{{ child.label }}</span>\n <span *ngIf=\"child.isNew\" class=\"cqa-nav-flyout-row-new\">New</span>\n </button>\n </div>\n </ng-template>\n </div>\n</div>\n", styles: ["@charset \"UTF-8\";.cqa-nav-host{display:block;width:100%}.cqa-nav-host--collapsed{display:flex;flex-direction:column;align-items:center;position:relative;z-index:1}.cqa-nav-host--collapsed:hover,.cqa-nav-host--collapsed:focus-within{z-index:30}.cqa-nav-item{display:flex;align-items:center;gap:12px;padding:9px 10px;margin:1px 8px;border-radius:9px;color:#ffffffd9;font-size:14px;font-weight:600;line-height:normal;width:calc(100% - 16px);text-align:left;background:transparent;border:none;cursor:pointer;position:relative;transition:background .12s,color .12s;overflow:hidden;font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif}.cqa-nav-item:not(.cqa-nav-item--collapsed){color:#d8d9fc}.cqa-nav-item:hover:not(.cqa-nav-item--active):not(.cqa-nav-item--disabled){background:#ffffff1f;color:#fff}.cqa-nav-item--active:not(.cqa-nav-item--collapsed){background:#b1b2f81f;font-weight:600;margin:1px 10px;width:calc(100% - 20px);box-shadow:inset 3px 0 #b1b2f8;color:#fff}.cqa-nav-item--active:not(.cqa-nav-item--collapsed).cqa-nav-item--has-children{color:#d8d9fc}.cqa-nav-item--active:not(.cqa-nav-item--collapsed):hover{background:#b1b2f829}.cqa-nav-item--active:not(.cqa-nav-item--collapsed).cqa-nav-item--has-children:hover{color:#d8d9fc}.cqa-nav-item--active:not(.cqa-nav-item--collapsed):not(.cqa-nav-item--has-children):hover{color:#fff}.cqa-nav-item--active.cqa-nav-item--collapsed{background:#b1b2f86b;color:#fff;font-weight:600;box-shadow:inset 0 0 0 1px #d8d9fc4d}.cqa-nav-item.cqa-nav-item--collapsed:hover:not(.cqa-nav-item--active):not(.cqa-nav-item--disabled){background:#4c50ef;box-shadow:none}.cqa-nav-item--disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.cqa-nav-item.cqa-nav-item--collapsed{justify-content:center;align-items:center;gap:0;padding:9px 0;margin:1px 0;width:40px;max-width:100%;box-sizing:border-box;color:#ffffffe0;overflow:visible;z-index:1}.cqa-nav-item.cqa-nav-item--collapsed .cqa-nav-label{flex:0 0 0;width:0;min-width:0;height:0;margin:0;padding:0;overflow:hidden;opacity:0;border:0;pointer-events:none}.cqa-nav-item.cqa-nav-item--collapsed:hover{z-index:auto}.cqa-nav-icon{width:20px;height:20px;flex-shrink:0;display:flex;align-items:center;justify-content:center;font-size:18px;color:inherit}.cqa-nav-item--collapsed .cqa-nav-icon i{display:flex;align-items:center;justify-content:center;width:100%;height:100%;line-height:1}.cqa-nav-label{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;opacity:0;transition:opacity .16s 80ms;color:inherit}.cqa-nav-label--visible{opacity:1}.cqa-nav-badge{font-size:11px;font-weight:600;background:#ffffff2e;color:#fff;padding:1px 7px;border-radius:999px;flex-shrink:0}.cqa-nav-status-dot{width:7px;height:7px;border-radius:50%;flex-shrink:0}.cqa-nav-status-dot--live{background:#0dbd7d;box-shadow:0 0 6px #0dbd7d;animation:cqa-nav-pulse 2s ease-in-out infinite}.cqa-nav-status-dot--danger{background:#ee3f3f}.cqa-nav-chev{width:14px;height:14px;opacity:.6;flex-shrink:0;transition:transform .2s;display:flex;align-items:center;justify-content:center}.cqa-nav-chev--open{transform:rotate(90deg)}.cqa-nav-live-corner{position:absolute;top:5px;right:5px;width:9px;height:9px;background:#0dbd7d;border-radius:50%;border:2px solid #3f43ee;box-shadow:0 0 6px #0dbd7d}@keyframes cqa-nav-pulse{0%,to{opacity:1}50%{opacity:.4}}.cqa-nav-flyout-panel{min-width:188px;max-width:280px;padding:10px 8px 8px;background:#4c50ef;border-radius:10px;box-shadow:0 12px 32px #00000047;border:1px solid rgba(255,255,255,.12);pointer-events:auto;text-align:left;font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif}.cqa-nav-flyout-panel-title{font-size:10px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:#ffffff8c;padding:2px 8px 8px;line-height:1.2}.cqa-nav-flyout-row{display:flex;align-items:center;gap:10px;width:100%;padding:8px 10px;margin:0 0 2px;border:none;border-radius:8px;background:transparent;color:#fff;font-size:13px;font-weight:500;text-align:left;cursor:pointer;transition:background .12s,color .12s;font-family:inherit}.cqa-nav-flyout-row:last-child{margin-bottom:0}.cqa-nav-flyout-row:hover:not(:disabled){background:#ffffff1a;color:#fff}.cqa-nav-flyout-row:disabled{opacity:.45;cursor:not-allowed}.cqa-nav-flyout-row--active{background:#8a8cf4;color:#fbfcff;font-weight:600}.cqa-nav-flyout-row--active:hover:not(:disabled){background:#8a8cf4;color:#fbfcff}.cqa-nav-flyout-row-icon{width:16px;height:16px;flex-shrink:0;display:flex;align-items:center;justify-content:center;font-size:14px;opacity:.95}.cqa-nav-flyout-row-label{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.cqa-nav-flyout-row-new{flex-shrink:0;font-size:10px;font-weight:700;padding:2px 7px;border-radius:999px;background:#feecbd;color:#7e6012;border:1px solid #fddf92}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: i1$3.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: i1$3.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }] });
12726
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: NavItemComponent, selector: "cqa-nav-item", inputs: { item: "item", isActive: "isActive", isExpanded: "isExpanded", isOpen: "isOpen", activeNavId: "activeNavId" }, outputs: { itemClick: "itemClick" }, viewQueries: [{ propertyName: "navHostRef", first: true, predicate: ["navHost"], descendants: true }], ngImport: i0, template: "<div class=\"cqa-nav-surface\">\n <div\n #navHost\n class=\"cqa-nav-host\"\n [class.cqa-nav-host--collapsed]=\"!isExpanded\"\n (mouseenter)=\"onHostMouseEnter()\"\n (mouseleave)=\"onHostMouseLeave()\"\n (focusin)=\"onHostFocusIn($event)\"\n (focusout)=\"onHostFocusOut($event)\">\n\n <button\n cdkOverlayOrigin\n #flyoutOrigin=\"cdkOverlayOrigin\"\n class=\"cqa-nav-item\"\n [class.cqa-nav-item--active]=\"isActive\"\n [class.cqa-nav-item--has-children]=\"hasChildren\"\n [class.cqa-nav-item--collapsed]=\"!isExpanded\"\n [class.cqa-nav-item--disabled]=\"item?.disabled\"\n [class.cqa-nav-item--has-live]=\"item?.status === 'live'\"\n [matTooltip]=\"collapsedRailTooltip\"\n [matTooltipDisabled]=\"!collapsedRailTooltip\"\n [matTooltipClass]=\"collapsedRailTooltipClass\"\n matTooltipPosition=\"right\"\n (click)=\"onClick()\"\n type=\"button\"\n [attr.aria-label]=\"!isExpanded ? (item?.label || '') : null\"\n [attr.aria-expanded]=\"!isExpanded && hasChildren ? showCollapsedFlyout : null\"\n [attr.aria-haspopup]=\"!isExpanded && hasChildren ? 'menu' : null\">\n\n <!-- Icon -->\n <span class=\"cqa-nav-icon\">\n <i [class]=\"item?.iconClass\"></i>\n </span>\n\n <!-- Label (hidden when sidebar collapsed) -->\n <span class=\"cqa-nav-label\" [class.cqa-nav-label--visible]=\"isExpanded\">\n {{ item?.label }}\n </span>\n\n <!-- Trailing slot: only shown when expanded -->\n <ng-container *ngIf=\"isExpanded\">\n <span *ngIf=\"item?.badge && !hasChildren\" class=\"cqa-nav-badge\">{{ item.badge }}</span>\n\n <span\n *ngIf=\"item?.status === 'live' && !hasChildren\"\n class=\"cqa-nav-status-dot cqa-nav-status-dot--live\">\n </span>\n\n <span\n *ngIf=\"item?.status === 'danger' && !hasChildren\"\n class=\"cqa-nav-status-dot cqa-nav-status-dot--danger\">\n </span>\n\n <span *ngIf=\"hasChildren\" class=\"cqa-nav-chev\" [class.cqa-nav-chev--open]=\"isOpen\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" width=\"14\" height=\"14\">\n <polyline points=\"9,6 15,12 9,18\"/>\n </svg>\n </span>\n </ng-container>\n\n <span\n *ngIf=\"!isExpanded && item?.status === 'live'\"\n class=\"cqa-nav-live-corner\">\n </span>\n </button>\n\n <!-- Collapsed parent submenu: CDK overlay (outside aside / scrolling nav) -->\n <ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"flyoutOrigin\"\n [cdkConnectedOverlayOpen]=\"collapsedFlyoutOpen\"\n [cdkConnectedOverlayPositions]=\"collapsedFlyoutPositions\"\n [cdkConnectedOverlayHasBackdrop]=\"false\"\n [cdkConnectedOverlayPush]=\"true\"\n [cdkConnectedOverlayScrollStrategy]=\"flyoutScrollStrategy\"\n [cdkConnectedOverlayPanelClass]=\"'cqa-nav-flyout-overlay-pane'\"\n (overlayOutsideClick)=\"closeCollapsedFlyout()\"\n (detach)=\"closeCollapsedFlyout()\">\n <div\n class=\"cqa-nav-flyout-overlay cqa-nav-flyout-panel\"\n role=\"menu\"\n [attr.aria-label]=\"item.label\"\n (mouseenter)=\"onFlyoutOverlayPointerEnter()\"\n (mouseleave)=\"onFlyoutOverlayPointerLeave()\"\n (focusout)=\"onFlyoutOverlayFocusOut($event)\">\n <div class=\"cqa-nav-flyout-panel-title\">{{ item.label }}</div>\n <button\n *ngFor=\"let child of item?.children\"\n type=\"button\"\n role=\"menuitem\"\n class=\"cqa-nav-flyout-row\"\n [class.cqa-nav-flyout-row--active]=\"isChildRowActive(child.id)\"\n [disabled]=\"child.disabled\"\n (click)=\"onChildRowClick($event, child)\">\n <span class=\"cqa-nav-flyout-row-icon\">\n <i *ngIf=\"child.iconClass\" [class]=\"child.iconClass\"></i>\n </span>\n <span class=\"cqa-nav-flyout-row-label\">{{ child.label }}</span>\n <span *ngIf=\"child.isNew\" class=\"cqa-nav-flyout-row-new\">New</span>\n </button>\n </div>\n </ng-template>\n </div>\n</div>\n", styles: ["@charset \"UTF-8\";.cqa-nav-surface,.cqa-nav-host{display:block;width:100%}.cqa-nav-host--collapsed{display:flex;flex-direction:column;align-items:center;position:relative;z-index:1}.cqa-nav-host--collapsed:hover,.cqa-nav-host--collapsed:focus-within{z-index:30}.cqa-nav-item{display:flex;align-items:center;gap:12px;padding:9px 10px;margin:1px 8px;border-radius:9px;color:#ffffffd9;font-size:14px;font-weight:600;line-height:1;letter-spacing:0;width:calc(100% - 16px);text-align:left;background:transparent;border:none;cursor:pointer;position:relative;transition:background .12s,color .12s;overflow:hidden;font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif}.cqa-nav-item:not(.cqa-nav-item--collapsed){color:#d8d9fc}.cqa-nav-item:hover:not(.cqa-nav-item--active):not(.cqa-nav-item--disabled){background:#ffffff1f;color:#fff}.cqa-nav-item--active:not(.cqa-nav-item--collapsed){background:#8a8cf4;font-weight:600;box-shadow:inset 0 0 0 1px #d8d9fc4d;color:#fff}.cqa-nav-item--active:not(.cqa-nav-item--collapsed).cqa-nav-item--has-children{color:#d8d9fc}.cqa-nav-item--active:not(.cqa-nav-item--collapsed):hover{background:#8a8cf4}.cqa-nav-item--active:not(.cqa-nav-item--collapsed).cqa-nav-item--has-children:hover{color:#d8d9fc}.cqa-nav-item--active:not(.cqa-nav-item--collapsed):not(.cqa-nav-item--has-children):hover{color:#fff}.cqa-nav-item--active.cqa-nav-item--collapsed{background:#b1b2f86b;color:#fff;font-weight:600;box-shadow:inset 0 0 0 1px #d8d9fc4d}.cqa-nav-item.cqa-nav-item--collapsed:hover:not(.cqa-nav-item--active):not(.cqa-nav-item--disabled){background:#4c50ef;box-shadow:none}.cqa-nav-item--disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.cqa-nav-item.cqa-nav-item--collapsed{justify-content:center;align-items:center;gap:0;padding:9px 0;margin:1px 0;width:40px;max-width:100%;box-sizing:border-box;color:#ffffffe0;overflow:visible;z-index:1}.cqa-nav-item.cqa-nav-item--collapsed .cqa-nav-label{flex:0 0 0;width:0;min-width:0;height:0;margin:0;padding:0;overflow:hidden;opacity:0;border:0;pointer-events:none}.cqa-nav-item.cqa-nav-item--collapsed:hover{z-index:auto}.cqa-nav-icon{width:20px;height:20px;flex-shrink:0;display:flex;align-items:center;justify-content:center;font-size:18px;color:inherit}.cqa-nav-item--collapsed .cqa-nav-icon i{display:flex;align-items:center;justify-content:center;width:100%;height:100%;line-height:1}.cqa-nav-label{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;opacity:0;transition:opacity .16s 80ms;color:inherit}.cqa-nav-label--visible{opacity:1}.cqa-nav-badge{font-size:11px;font-weight:600;background:#ffffff2e;color:#fff;padding:1px 7px;border-radius:999px;flex-shrink:0}.cqa-nav-status-dot{width:7px;height:7px;border-radius:50%;flex-shrink:0}.cqa-nav-status-dot--live{background:#0dbd7d;box-shadow:0 0 6px #0dbd7d;animation:cqa-nav-pulse 2s ease-in-out infinite}.cqa-nav-status-dot--danger{background:#ee3f3f}.cqa-nav-chev{width:14px;height:14px;opacity:.6;flex-shrink:0;transition:transform .2s;display:flex;align-items:center;justify-content:center}.cqa-nav-chev--open{transform:rotate(90deg)}.cqa-nav-live-corner{position:absolute;top:5px;right:5px;width:9px;height:9px;background:#0dbd7d;border-radius:50%;border:2px solid #3f43ee;box-shadow:0 0 6px #0dbd7d}@keyframes cqa-nav-pulse{0%,to{opacity:1}50%{opacity:.4}}.cqa-nav-flyout-panel{min-width:188px;max-width:280px;padding:10px 8px 8px;background:#4c50ef;border-radius:10px;box-shadow:0 12px 32px #00000047;border:1px solid rgba(255,255,255,.12);pointer-events:auto;text-align:left;font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif}.cqa-nav-flyout-panel-title{font-size:10px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:#ffffff8c;padding:2px 8px 8px;line-height:1.2}.cqa-nav-flyout-row{display:flex;align-items:center;gap:10px;width:100%;padding:8px 10px;margin:0 0 2px;border:none;border-radius:8px;background:transparent;color:#fff;font-size:13px;font-weight:500;text-align:left;cursor:pointer;transition:background .12s,color .12s;font-family:inherit}.cqa-nav-flyout-row:last-child{margin-bottom:0}.cqa-nav-flyout-row:hover:not(:disabled){background:#ffffff1a;color:#fff}.cqa-nav-flyout-row:disabled{opacity:.45;cursor:not-allowed}.cqa-nav-flyout-row--active{background:#8a8cf4;color:#fbfcff;font-weight:600}.cqa-nav-flyout-row--active:hover:not(:disabled){background:#8a8cf4;color:#fbfcff}.cqa-nav-flyout-row-icon{width:16px;height:16px;flex-shrink:0;display:flex;align-items:center;justify-content:center;font-size:14px;opacity:.95}.cqa-nav-flyout-row-label{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.cqa-nav-flyout-row-new{flex-shrink:0;font-size:10px;font-weight:700;padding:2px 7px;border-radius:999px;background:#feecbd;color:#7e6012;border:1px solid #fddf92}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: i1$3.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: i1$3.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }] });
12717
12727
  }
12718
12728
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NavItemComponent, decorators: [{
12719
12729
  type: Component,
12720
- args: [{ selector: 'cqa-nav-item', template: "<div id=\"cqa-ui-root\" style=\"display:block\">\n <div\n #navHost\n class=\"cqa-nav-host\"\n [class.cqa-nav-host--collapsed]=\"!isExpanded\"\n (mouseenter)=\"onHostMouseEnter()\"\n (mouseleave)=\"onHostMouseLeave()\"\n (focusin)=\"onHostFocusIn($event)\"\n (focusout)=\"onHostFocusOut($event)\">\n\n <button\n cdkOverlayOrigin\n #flyoutOrigin=\"cdkOverlayOrigin\"\n class=\"cqa-nav-item\"\n [class.cqa-nav-item--active]=\"isActive\"\n [class.cqa-nav-item--has-children]=\"hasChildren\"\n [class.cqa-nav-item--collapsed]=\"!isExpanded\"\n [class.cqa-nav-item--disabled]=\"item?.disabled\"\n [class.cqa-nav-item--has-live]=\"item?.status === 'live'\"\n [matTooltip]=\"collapsedRailTooltip\"\n [matTooltipDisabled]=\"!collapsedRailTooltip\"\n [matTooltipClass]=\"collapsedRailTooltipClass\"\n matTooltipPosition=\"right\"\n (click)=\"onClick()\"\n type=\"button\"\n [attr.aria-label]=\"!isExpanded ? (item?.label || '') : null\"\n [attr.aria-expanded]=\"!isExpanded && hasChildren ? showCollapsedFlyout : null\"\n [attr.aria-haspopup]=\"!isExpanded && hasChildren ? 'menu' : null\">\n\n <!-- Icon -->\n <span class=\"cqa-nav-icon\">\n <i [class]=\"item?.iconClass\"></i>\n </span>\n\n <!-- Label (hidden when sidebar collapsed) -->\n <span class=\"cqa-nav-label\" [class.cqa-nav-label--visible]=\"isExpanded\">\n {{ item?.label }}\n </span>\n\n <!-- Trailing slot: only shown when expanded -->\n <ng-container *ngIf=\"isExpanded\">\n <span *ngIf=\"item?.badge && !hasChildren\" class=\"cqa-nav-badge\">{{ item.badge }}</span>\n\n <span\n *ngIf=\"item?.status === 'live' && !hasChildren\"\n class=\"cqa-nav-status-dot cqa-nav-status-dot--live\">\n </span>\n\n <span\n *ngIf=\"item?.status === 'danger' && !hasChildren\"\n class=\"cqa-nav-status-dot cqa-nav-status-dot--danger\">\n </span>\n\n <span *ngIf=\"hasChildren\" class=\"cqa-nav-chev\" [class.cqa-nav-chev--open]=\"isOpen\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" width=\"14\" height=\"14\">\n <polyline points=\"9,6 15,12 9,18\"/>\n </svg>\n </span>\n </ng-container>\n\n <span\n *ngIf=\"!isExpanded && item?.status === 'live'\"\n class=\"cqa-nav-live-corner\">\n </span>\n </button>\n\n <!-- Collapsed parent submenu: CDK overlay (outside aside / scrolling nav) -->\n <ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"flyoutOrigin\"\n [cdkConnectedOverlayOpen]=\"collapsedFlyoutOpen\"\n [cdkConnectedOverlayPositions]=\"collapsedFlyoutPositions\"\n [cdkConnectedOverlayHasBackdrop]=\"false\"\n [cdkConnectedOverlayPush]=\"true\"\n [cdkConnectedOverlayScrollStrategy]=\"flyoutScrollStrategy\"\n [cdkConnectedOverlayPanelClass]=\"'cqa-nav-flyout-overlay-pane'\"\n (overlayOutsideClick)=\"closeCollapsedFlyout()\"\n (detach)=\"closeCollapsedFlyout()\">\n <div\n class=\"cqa-nav-flyout-overlay cqa-nav-flyout-panel\"\n role=\"menu\"\n [attr.aria-label]=\"item.label\"\n (mouseenter)=\"onFlyoutOverlayPointerEnter()\"\n (mouseleave)=\"onFlyoutOverlayPointerLeave()\"\n (focusout)=\"onFlyoutOverlayFocusOut($event)\">\n <div class=\"cqa-nav-flyout-panel-title\">{{ item.label }}</div>\n <button\n *ngFor=\"let child of item?.children\"\n type=\"button\"\n role=\"menuitem\"\n class=\"cqa-nav-flyout-row\"\n [class.cqa-nav-flyout-row--active]=\"isChildRowActive(child.id)\"\n [disabled]=\"child.disabled\"\n (click)=\"onChildRowClick($event, child)\">\n <span class=\"cqa-nav-flyout-row-icon\">\n <i *ngIf=\"child.iconClass\" [class]=\"child.iconClass\"></i>\n </span>\n <span class=\"cqa-nav-flyout-row-label\">{{ child.label }}</span>\n <span *ngIf=\"child.isNew\" class=\"cqa-nav-flyout-row-new\">New</span>\n </button>\n </div>\n </ng-template>\n </div>\n</div>\n", styles: ["@charset \"UTF-8\";.cqa-nav-host{display:block;width:100%}.cqa-nav-host--collapsed{display:flex;flex-direction:column;align-items:center;position:relative;z-index:1}.cqa-nav-host--collapsed:hover,.cqa-nav-host--collapsed:focus-within{z-index:30}.cqa-nav-item{display:flex;align-items:center;gap:12px;padding:9px 10px;margin:1px 8px;border-radius:9px;color:#ffffffd9;font-size:14px;font-weight:600;line-height:normal;width:calc(100% - 16px);text-align:left;background:transparent;border:none;cursor:pointer;position:relative;transition:background .12s,color .12s;overflow:hidden;font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif}.cqa-nav-item:not(.cqa-nav-item--collapsed){color:#d8d9fc}.cqa-nav-item:hover:not(.cqa-nav-item--active):not(.cqa-nav-item--disabled){background:#ffffff1f;color:#fff}.cqa-nav-item--active:not(.cqa-nav-item--collapsed){background:#b1b2f81f;font-weight:600;margin:1px 10px;width:calc(100% - 20px);box-shadow:inset 3px 0 #b1b2f8;color:#fff}.cqa-nav-item--active:not(.cqa-nav-item--collapsed).cqa-nav-item--has-children{color:#d8d9fc}.cqa-nav-item--active:not(.cqa-nav-item--collapsed):hover{background:#b1b2f829}.cqa-nav-item--active:not(.cqa-nav-item--collapsed).cqa-nav-item--has-children:hover{color:#d8d9fc}.cqa-nav-item--active:not(.cqa-nav-item--collapsed):not(.cqa-nav-item--has-children):hover{color:#fff}.cqa-nav-item--active.cqa-nav-item--collapsed{background:#b1b2f86b;color:#fff;font-weight:600;box-shadow:inset 0 0 0 1px #d8d9fc4d}.cqa-nav-item.cqa-nav-item--collapsed:hover:not(.cqa-nav-item--active):not(.cqa-nav-item--disabled){background:#4c50ef;box-shadow:none}.cqa-nav-item--disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.cqa-nav-item.cqa-nav-item--collapsed{justify-content:center;align-items:center;gap:0;padding:9px 0;margin:1px 0;width:40px;max-width:100%;box-sizing:border-box;color:#ffffffe0;overflow:visible;z-index:1}.cqa-nav-item.cqa-nav-item--collapsed .cqa-nav-label{flex:0 0 0;width:0;min-width:0;height:0;margin:0;padding:0;overflow:hidden;opacity:0;border:0;pointer-events:none}.cqa-nav-item.cqa-nav-item--collapsed:hover{z-index:auto}.cqa-nav-icon{width:20px;height:20px;flex-shrink:0;display:flex;align-items:center;justify-content:center;font-size:18px;color:inherit}.cqa-nav-item--collapsed .cqa-nav-icon i{display:flex;align-items:center;justify-content:center;width:100%;height:100%;line-height:1}.cqa-nav-label{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;opacity:0;transition:opacity .16s 80ms;color:inherit}.cqa-nav-label--visible{opacity:1}.cqa-nav-badge{font-size:11px;font-weight:600;background:#ffffff2e;color:#fff;padding:1px 7px;border-radius:999px;flex-shrink:0}.cqa-nav-status-dot{width:7px;height:7px;border-radius:50%;flex-shrink:0}.cqa-nav-status-dot--live{background:#0dbd7d;box-shadow:0 0 6px #0dbd7d;animation:cqa-nav-pulse 2s ease-in-out infinite}.cqa-nav-status-dot--danger{background:#ee3f3f}.cqa-nav-chev{width:14px;height:14px;opacity:.6;flex-shrink:0;transition:transform .2s;display:flex;align-items:center;justify-content:center}.cqa-nav-chev--open{transform:rotate(90deg)}.cqa-nav-live-corner{position:absolute;top:5px;right:5px;width:9px;height:9px;background:#0dbd7d;border-radius:50%;border:2px solid #3f43ee;box-shadow:0 0 6px #0dbd7d}@keyframes cqa-nav-pulse{0%,to{opacity:1}50%{opacity:.4}}.cqa-nav-flyout-panel{min-width:188px;max-width:280px;padding:10px 8px 8px;background:#4c50ef;border-radius:10px;box-shadow:0 12px 32px #00000047;border:1px solid rgba(255,255,255,.12);pointer-events:auto;text-align:left;font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif}.cqa-nav-flyout-panel-title{font-size:10px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:#ffffff8c;padding:2px 8px 8px;line-height:1.2}.cqa-nav-flyout-row{display:flex;align-items:center;gap:10px;width:100%;padding:8px 10px;margin:0 0 2px;border:none;border-radius:8px;background:transparent;color:#fff;font-size:13px;font-weight:500;text-align:left;cursor:pointer;transition:background .12s,color .12s;font-family:inherit}.cqa-nav-flyout-row:last-child{margin-bottom:0}.cqa-nav-flyout-row:hover:not(:disabled){background:#ffffff1a;color:#fff}.cqa-nav-flyout-row:disabled{opacity:.45;cursor:not-allowed}.cqa-nav-flyout-row--active{background:#8a8cf4;color:#fbfcff;font-weight:600}.cqa-nav-flyout-row--active:hover:not(:disabled){background:#8a8cf4;color:#fbfcff}.cqa-nav-flyout-row-icon{width:16px;height:16px;flex-shrink:0;display:flex;align-items:center;justify-content:center;font-size:14px;opacity:.95}.cqa-nav-flyout-row-label{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.cqa-nav-flyout-row-new{flex-shrink:0;font-size:10px;font-weight:700;padding:2px 7px;border-radius:999px;background:#feecbd;color:#7e6012;border:1px solid #fddf92}\n"] }]
12730
+ args: [{ selector: 'cqa-nav-item', template: "<div class=\"cqa-nav-surface\">\n <div\n #navHost\n class=\"cqa-nav-host\"\n [class.cqa-nav-host--collapsed]=\"!isExpanded\"\n (mouseenter)=\"onHostMouseEnter()\"\n (mouseleave)=\"onHostMouseLeave()\"\n (focusin)=\"onHostFocusIn($event)\"\n (focusout)=\"onHostFocusOut($event)\">\n\n <button\n cdkOverlayOrigin\n #flyoutOrigin=\"cdkOverlayOrigin\"\n class=\"cqa-nav-item\"\n [class.cqa-nav-item--active]=\"isActive\"\n [class.cqa-nav-item--has-children]=\"hasChildren\"\n [class.cqa-nav-item--collapsed]=\"!isExpanded\"\n [class.cqa-nav-item--disabled]=\"item?.disabled\"\n [class.cqa-nav-item--has-live]=\"item?.status === 'live'\"\n [matTooltip]=\"collapsedRailTooltip\"\n [matTooltipDisabled]=\"!collapsedRailTooltip\"\n [matTooltipClass]=\"collapsedRailTooltipClass\"\n matTooltipPosition=\"right\"\n (click)=\"onClick()\"\n type=\"button\"\n [attr.aria-label]=\"!isExpanded ? (item?.label || '') : null\"\n [attr.aria-expanded]=\"!isExpanded && hasChildren ? showCollapsedFlyout : null\"\n [attr.aria-haspopup]=\"!isExpanded && hasChildren ? 'menu' : null\">\n\n <!-- Icon -->\n <span class=\"cqa-nav-icon\">\n <i [class]=\"item?.iconClass\"></i>\n </span>\n\n <!-- Label (hidden when sidebar collapsed) -->\n <span class=\"cqa-nav-label\" [class.cqa-nav-label--visible]=\"isExpanded\">\n {{ item?.label }}\n </span>\n\n <!-- Trailing slot: only shown when expanded -->\n <ng-container *ngIf=\"isExpanded\">\n <span *ngIf=\"item?.badge && !hasChildren\" class=\"cqa-nav-badge\">{{ item.badge }}</span>\n\n <span\n *ngIf=\"item?.status === 'live' && !hasChildren\"\n class=\"cqa-nav-status-dot cqa-nav-status-dot--live\">\n </span>\n\n <span\n *ngIf=\"item?.status === 'danger' && !hasChildren\"\n class=\"cqa-nav-status-dot cqa-nav-status-dot--danger\">\n </span>\n\n <span *ngIf=\"hasChildren\" class=\"cqa-nav-chev\" [class.cqa-nav-chev--open]=\"isOpen\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" width=\"14\" height=\"14\">\n <polyline points=\"9,6 15,12 9,18\"/>\n </svg>\n </span>\n </ng-container>\n\n <span\n *ngIf=\"!isExpanded && item?.status === 'live'\"\n class=\"cqa-nav-live-corner\">\n </span>\n </button>\n\n <!-- Collapsed parent submenu: CDK overlay (outside aside / scrolling nav) -->\n <ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"flyoutOrigin\"\n [cdkConnectedOverlayOpen]=\"collapsedFlyoutOpen\"\n [cdkConnectedOverlayPositions]=\"collapsedFlyoutPositions\"\n [cdkConnectedOverlayHasBackdrop]=\"false\"\n [cdkConnectedOverlayPush]=\"true\"\n [cdkConnectedOverlayScrollStrategy]=\"flyoutScrollStrategy\"\n [cdkConnectedOverlayPanelClass]=\"'cqa-nav-flyout-overlay-pane'\"\n (overlayOutsideClick)=\"closeCollapsedFlyout()\"\n (detach)=\"closeCollapsedFlyout()\">\n <div\n class=\"cqa-nav-flyout-overlay cqa-nav-flyout-panel\"\n role=\"menu\"\n [attr.aria-label]=\"item.label\"\n (mouseenter)=\"onFlyoutOverlayPointerEnter()\"\n (mouseleave)=\"onFlyoutOverlayPointerLeave()\"\n (focusout)=\"onFlyoutOverlayFocusOut($event)\">\n <div class=\"cqa-nav-flyout-panel-title\">{{ item.label }}</div>\n <button\n *ngFor=\"let child of item?.children\"\n type=\"button\"\n role=\"menuitem\"\n class=\"cqa-nav-flyout-row\"\n [class.cqa-nav-flyout-row--active]=\"isChildRowActive(child.id)\"\n [disabled]=\"child.disabled\"\n (click)=\"onChildRowClick($event, child)\">\n <span class=\"cqa-nav-flyout-row-icon\">\n <i *ngIf=\"child.iconClass\" [class]=\"child.iconClass\"></i>\n </span>\n <span class=\"cqa-nav-flyout-row-label\">{{ child.label }}</span>\n <span *ngIf=\"child.isNew\" class=\"cqa-nav-flyout-row-new\">New</span>\n </button>\n </div>\n </ng-template>\n </div>\n</div>\n", styles: ["@charset \"UTF-8\";.cqa-nav-surface,.cqa-nav-host{display:block;width:100%}.cqa-nav-host--collapsed{display:flex;flex-direction:column;align-items:center;position:relative;z-index:1}.cqa-nav-host--collapsed:hover,.cqa-nav-host--collapsed:focus-within{z-index:30}.cqa-nav-item{display:flex;align-items:center;gap:12px;padding:9px 10px;margin:1px 8px;border-radius:9px;color:#ffffffd9;font-size:14px;font-weight:600;line-height:1;letter-spacing:0;width:calc(100% - 16px);text-align:left;background:transparent;border:none;cursor:pointer;position:relative;transition:background .12s,color .12s;overflow:hidden;font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif}.cqa-nav-item:not(.cqa-nav-item--collapsed){color:#d8d9fc}.cqa-nav-item:hover:not(.cqa-nav-item--active):not(.cqa-nav-item--disabled){background:#ffffff1f;color:#fff}.cqa-nav-item--active:not(.cqa-nav-item--collapsed){background:#8a8cf4;font-weight:600;box-shadow:inset 0 0 0 1px #d8d9fc4d;color:#fff}.cqa-nav-item--active:not(.cqa-nav-item--collapsed).cqa-nav-item--has-children{color:#d8d9fc}.cqa-nav-item--active:not(.cqa-nav-item--collapsed):hover{background:#8a8cf4}.cqa-nav-item--active:not(.cqa-nav-item--collapsed).cqa-nav-item--has-children:hover{color:#d8d9fc}.cqa-nav-item--active:not(.cqa-nav-item--collapsed):not(.cqa-nav-item--has-children):hover{color:#fff}.cqa-nav-item--active.cqa-nav-item--collapsed{background:#b1b2f86b;color:#fff;font-weight:600;box-shadow:inset 0 0 0 1px #d8d9fc4d}.cqa-nav-item.cqa-nav-item--collapsed:hover:not(.cqa-nav-item--active):not(.cqa-nav-item--disabled){background:#4c50ef;box-shadow:none}.cqa-nav-item--disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.cqa-nav-item.cqa-nav-item--collapsed{justify-content:center;align-items:center;gap:0;padding:9px 0;margin:1px 0;width:40px;max-width:100%;box-sizing:border-box;color:#ffffffe0;overflow:visible;z-index:1}.cqa-nav-item.cqa-nav-item--collapsed .cqa-nav-label{flex:0 0 0;width:0;min-width:0;height:0;margin:0;padding:0;overflow:hidden;opacity:0;border:0;pointer-events:none}.cqa-nav-item.cqa-nav-item--collapsed:hover{z-index:auto}.cqa-nav-icon{width:20px;height:20px;flex-shrink:0;display:flex;align-items:center;justify-content:center;font-size:18px;color:inherit}.cqa-nav-item--collapsed .cqa-nav-icon i{display:flex;align-items:center;justify-content:center;width:100%;height:100%;line-height:1}.cqa-nav-label{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;opacity:0;transition:opacity .16s 80ms;color:inherit}.cqa-nav-label--visible{opacity:1}.cqa-nav-badge{font-size:11px;font-weight:600;background:#ffffff2e;color:#fff;padding:1px 7px;border-radius:999px;flex-shrink:0}.cqa-nav-status-dot{width:7px;height:7px;border-radius:50%;flex-shrink:0}.cqa-nav-status-dot--live{background:#0dbd7d;box-shadow:0 0 6px #0dbd7d;animation:cqa-nav-pulse 2s ease-in-out infinite}.cqa-nav-status-dot--danger{background:#ee3f3f}.cqa-nav-chev{width:14px;height:14px;opacity:.6;flex-shrink:0;transition:transform .2s;display:flex;align-items:center;justify-content:center}.cqa-nav-chev--open{transform:rotate(90deg)}.cqa-nav-live-corner{position:absolute;top:5px;right:5px;width:9px;height:9px;background:#0dbd7d;border-radius:50%;border:2px solid #3f43ee;box-shadow:0 0 6px #0dbd7d}@keyframes cqa-nav-pulse{0%,to{opacity:1}50%{opacity:.4}}.cqa-nav-flyout-panel{min-width:188px;max-width:280px;padding:10px 8px 8px;background:#4c50ef;border-radius:10px;box-shadow:0 12px 32px #00000047;border:1px solid rgba(255,255,255,.12);pointer-events:auto;text-align:left;font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif}.cqa-nav-flyout-panel-title{font-size:10px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:#ffffff8c;padding:2px 8px 8px;line-height:1.2}.cqa-nav-flyout-row{display:flex;align-items:center;gap:10px;width:100%;padding:8px 10px;margin:0 0 2px;border:none;border-radius:8px;background:transparent;color:#fff;font-size:13px;font-weight:500;text-align:left;cursor:pointer;transition:background .12s,color .12s;font-family:inherit}.cqa-nav-flyout-row:last-child{margin-bottom:0}.cqa-nav-flyout-row:hover:not(:disabled){background:#ffffff1a;color:#fff}.cqa-nav-flyout-row:disabled{opacity:.45;cursor:not-allowed}.cqa-nav-flyout-row--active{background:#8a8cf4;color:#fbfcff;font-weight:600}.cqa-nav-flyout-row--active:hover:not(:disabled){background:#8a8cf4;color:#fbfcff}.cqa-nav-flyout-row-icon{width:16px;height:16px;flex-shrink:0;display:flex;align-items:center;justify-content:center;font-size:14px;opacity:.95}.cqa-nav-flyout-row-label{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.cqa-nav-flyout-row-new{flex-shrink:0;font-size:10px;font-weight:700;padding:2px 7px;border-radius:999px;background:#feecbd;color:#7e6012;border:1px solid #fddf92}\n"] }]
12721
12731
  }], ctorParameters: () => [{ type: i1$3.Overlay }], propDecorators: { item: [{
12722
12732
  type: Input
12723
12733
  }], isActive: [{
@@ -12745,11 +12755,11 @@ class NavSubItemComponent {
12745
12755
  }
12746
12756
  }
12747
12757
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NavSubItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
12748
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: NavSubItemComponent, selector: "cqa-nav-sub-item", inputs: { item: "item", isActive: "isActive" }, outputs: { itemClick: "itemClick" }, ngImport: i0, template: "<div id=\"cqa-ui-root\" style=\"display:block\">\n <button\n class=\"cqa-nav-sub-item\"\n [class.cqa-nav-sub-item--active]=\"isActive\"\n [class.cqa-nav-sub-item--disabled]=\"item?.disabled\"\n (click)=\"onClick()\"\n type=\"button\">\n\n <span class=\"cqa-nav-sub-icon\">\n <i [class]=\"item?.iconClass\"></i>\n </span>\n\n <span class=\"cqa-nav-sub-label\">{{ item?.label }}</span>\n\n <span *ngIf=\"item?.isNew\" class=\"cqa-nav-sub-badge cqa-nav-sub-badge--new\">New</span>\n </button>\n</div>\n", styles: ["@charset \"UTF-8\";.cqa-nav-sub-item{display:flex;align-items:center;gap:10px;padding:7px 10px;margin:0;border-radius:7px;color:#d8d9fc;font-size:12px;font-weight:400;line-height:normal;width:100%;text-align:left;background:transparent;border:none;cursor:pointer;transition:background .12s,color .12s;font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif}.cqa-nav-sub-item:hover:not(.cqa-nav-sub-item--active){background:#ffffff1a;color:#fff}.cqa-nav-sub-item--active{background:#8a8cf4;color:#fbfcff;font-weight:600}.cqa-nav-sub-item--active .cqa-nav-sub-icon{opacity:1;color:#fbfcff}.cqa-nav-sub-item--active .cqa-nav-sub-label{color:#fbfcff;font-weight:600}.cqa-nav-sub-item--active:hover{background:#8a8cf4;color:#fbfcff}.cqa-nav-sub-item--disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.cqa-nav-sub-icon{width:15px;height:15px;flex-shrink:0;display:flex;align-items:center;justify-content:center;opacity:.92;font-size:13px;color:inherit}.cqa-nav-sub-label{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:inherit}.cqa-nav-sub-badge{font-size:11px;font-weight:600;padding:1px 7px;border-radius:999px;flex-shrink:0}.cqa-nav-sub-badge--new{background:#feecbd;color:#7e6012;border:1px solid #fddf92}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
12758
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: NavSubItemComponent, selector: "cqa-nav-sub-item", inputs: { item: "item", isActive: "isActive" }, outputs: { itemClick: "itemClick" }, ngImport: i0, template: "<div class=\"cqa-nav-surface\">\n <button\n class=\"cqa-nav-sub-item\"\n [class.cqa-nav-sub-item--active]=\"isActive\"\n [class.cqa-nav-sub-item--disabled]=\"item?.disabled\"\n (click)=\"onClick()\"\n type=\"button\">\n\n <span class=\"cqa-nav-sub-icon\">\n <i [class]=\"item?.iconClass\"></i>\n </span>\n\n <span class=\"cqa-nav-sub-label\">{{ item?.label }}</span>\n\n <span *ngIf=\"item?.isNew\" class=\"cqa-nav-sub-badge cqa-nav-sub-badge--new\">New</span>\n </button>\n</div>\n", styles: ["@charset \"UTF-8\";.cqa-nav-surface{display:block;width:100%}.cqa-nav-sub-item{display:flex;align-items:center;gap:10px;padding:7px 10px;margin:0;border-radius:7px;color:#d8d9fc;font-size:12px;font-weight:400;line-height:normal;width:100%;text-align:left;background:transparent;border:none;cursor:pointer;transition:background .12s,color .12s;font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif}.cqa-nav-sub-item:hover:not(.cqa-nav-sub-item--active){background:#ffffff1a;color:#fff}.cqa-nav-sub-item--active{background:#8a8cf4;color:#fbfcff;font-weight:600}.cqa-nav-sub-item--active .cqa-nav-sub-icon{opacity:1;color:#fbfcff}.cqa-nav-sub-item--active .cqa-nav-sub-label{color:#fbfcff;font-weight:600}.cqa-nav-sub-item--active:hover{background:#8a8cf4;color:#fbfcff}.cqa-nav-sub-item--disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.cqa-nav-sub-icon{width:15px;height:15px;flex-shrink:0;display:flex;align-items:center;justify-content:center;opacity:.92;font-size:13px;color:inherit}.cqa-nav-sub-label{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:inherit}.cqa-nav-sub-badge{font-size:11px;font-weight:600;padding:1px 7px;border-radius:999px;flex-shrink:0}.cqa-nav-sub-badge--new{background:#feecbd;color:#7e6012;border:1px solid #fddf92}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
12749
12759
  }
12750
12760
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NavSubItemComponent, decorators: [{
12751
12761
  type: Component,
12752
- args: [{ selector: 'cqa-nav-sub-item', template: "<div id=\"cqa-ui-root\" style=\"display:block\">\n <button\n class=\"cqa-nav-sub-item\"\n [class.cqa-nav-sub-item--active]=\"isActive\"\n [class.cqa-nav-sub-item--disabled]=\"item?.disabled\"\n (click)=\"onClick()\"\n type=\"button\">\n\n <span class=\"cqa-nav-sub-icon\">\n <i [class]=\"item?.iconClass\"></i>\n </span>\n\n <span class=\"cqa-nav-sub-label\">{{ item?.label }}</span>\n\n <span *ngIf=\"item?.isNew\" class=\"cqa-nav-sub-badge cqa-nav-sub-badge--new\">New</span>\n </button>\n</div>\n", styles: ["@charset \"UTF-8\";.cqa-nav-sub-item{display:flex;align-items:center;gap:10px;padding:7px 10px;margin:0;border-radius:7px;color:#d8d9fc;font-size:12px;font-weight:400;line-height:normal;width:100%;text-align:left;background:transparent;border:none;cursor:pointer;transition:background .12s,color .12s;font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif}.cqa-nav-sub-item:hover:not(.cqa-nav-sub-item--active){background:#ffffff1a;color:#fff}.cqa-nav-sub-item--active{background:#8a8cf4;color:#fbfcff;font-weight:600}.cqa-nav-sub-item--active .cqa-nav-sub-icon{opacity:1;color:#fbfcff}.cqa-nav-sub-item--active .cqa-nav-sub-label{color:#fbfcff;font-weight:600}.cqa-nav-sub-item--active:hover{background:#8a8cf4;color:#fbfcff}.cqa-nav-sub-item--disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.cqa-nav-sub-icon{width:15px;height:15px;flex-shrink:0;display:flex;align-items:center;justify-content:center;opacity:.92;font-size:13px;color:inherit}.cqa-nav-sub-label{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:inherit}.cqa-nav-sub-badge{font-size:11px;font-weight:600;padding:1px 7px;border-radius:999px;flex-shrink:0}.cqa-nav-sub-badge--new{background:#feecbd;color:#7e6012;border:1px solid #fddf92}\n"] }]
12762
+ args: [{ selector: 'cqa-nav-sub-item', template: "<div class=\"cqa-nav-surface\">\n <button\n class=\"cqa-nav-sub-item\"\n [class.cqa-nav-sub-item--active]=\"isActive\"\n [class.cqa-nav-sub-item--disabled]=\"item?.disabled\"\n (click)=\"onClick()\"\n type=\"button\">\n\n <span class=\"cqa-nav-sub-icon\">\n <i [class]=\"item?.iconClass\"></i>\n </span>\n\n <span class=\"cqa-nav-sub-label\">{{ item?.label }}</span>\n\n <span *ngIf=\"item?.isNew\" class=\"cqa-nav-sub-badge cqa-nav-sub-badge--new\">New</span>\n </button>\n</div>\n", styles: ["@charset \"UTF-8\";.cqa-nav-surface{display:block;width:100%}.cqa-nav-sub-item{display:flex;align-items:center;gap:10px;padding:7px 10px;margin:0;border-radius:7px;color:#d8d9fc;font-size:12px;font-weight:400;line-height:normal;width:100%;text-align:left;background:transparent;border:none;cursor:pointer;transition:background .12s,color .12s;font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif}.cqa-nav-sub-item:hover:not(.cqa-nav-sub-item--active){background:#ffffff1a;color:#fff}.cqa-nav-sub-item--active{background:#8a8cf4;color:#fbfcff;font-weight:600}.cqa-nav-sub-item--active .cqa-nav-sub-icon{opacity:1;color:#fbfcff}.cqa-nav-sub-item--active .cqa-nav-sub-label{color:#fbfcff;font-weight:600}.cqa-nav-sub-item--active:hover{background:#8a8cf4;color:#fbfcff}.cqa-nav-sub-item--disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.cqa-nav-sub-icon{width:15px;height:15px;flex-shrink:0;display:flex;align-items:center;justify-content:center;opacity:.92;font-size:13px;color:inherit}.cqa-nav-sub-label{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:inherit}.cqa-nav-sub-badge{font-size:11px;font-weight:600;padding:1px 7px;border-radius:999px;flex-shrink:0}.cqa-nav-sub-badge--new{background:#feecbd;color:#7e6012;border:1px solid #fddf92}\n"] }]
12753
12763
  }], propDecorators: { item: [{
12754
12764
  type: Input
12755
12765
  }], isActive: [{
@@ -12789,11 +12799,11 @@ class NavMenuComponent {
12789
12799
  this.itemClick.emit(id);
12790
12800
  }
12791
12801
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NavMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
12792
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: NavMenuComponent, selector: "cqa-nav-menu", inputs: { items: "items", activeId: "activeId", isExpanded: "isExpanded", openParents: "openParents" }, outputs: { itemClick: "itemClick" }, ngImport: i0, template: "<div id=\"cqa-ui-root\" style=\"display:flex;flex-direction:column;flex:1 1 auto;min-height:0;overflow:hidden;width:100%;\">\n <nav class=\"cqa-nav-menu\" [class.cqa-nav-menu--collapsed]=\"!isExpanded\">\n <ng-container *ngFor=\"let item of items\">\n\n <!-- Section header (expanded only \u2014 collapsed rail shows icons only) -->\n <ng-container *ngIf=\"isSection(item) && isExpanded\">\n <div class=\"cqa-nav-section\">\n <span class=\"cqa-nav-section-label\">{{ item.label }}</span>\n </div>\n </ng-container>\n\n <!-- Nav item -->\n <ng-container *ngIf=\"!isSection(item)\">\n <cqa-nav-item\n [item]=\"asNavItem(item)\"\n [isActive]=\"isItemActive(asNavItem(item))\"\n [isExpanded]=\"isExpanded\"\n [isOpen]=\"isParentOpen(asNavItem(item))\"\n [activeNavId]=\"activeId\"\n (itemClick)=\"onItemClick($event)\">\n </cqa-nav-item>\n\n <!-- Sub-menu (only rendered when sidebar is expanded) -->\n <div\n *ngIf=\"isExpanded && asNavItem(item).children?.length\"\n class=\"cqa-nav-children\"\n [class.cqa-nav-children--open]=\"isParentOpen(asNavItem(item))\">\n <cqa-nav-sub-item\n *ngFor=\"let child of asNavItem(item).children\"\n [item]=\"child\"\n [isActive]=\"isChildActive(child.id)\"\n (itemClick)=\"onItemClick($event)\">\n </cqa-nav-sub-item>\n </div>\n </ng-container>\n\n </ng-container>\n </nav>\n</div>\n", styles: [":host{display:flex;flex-direction:column;flex:1 1 auto;min-height:0;overflow:hidden;width:100%}.cqa-nav-menu{flex:1 1 auto;overflow-y:auto;overflow-x:hidden;padding:4px 0 8px;min-height:0}.cqa-nav-menu::-webkit-scrollbar{width:4px}.cqa-nav-menu::-webkit-scrollbar-thumb{background:#ffffff26;border-radius:2px}.cqa-nav-menu--collapsed{overflow-x:visible}.cqa-nav-section{font-size:10px;font-weight:700;letter-spacing:.1em;color:#ffffff8c;padding:14px 18px 6px;text-transform:uppercase;height:28px;overflow:hidden;transition:opacity .16s 80ms,padding .16s,font-size .16s;opacity:1}.cqa-nav-children{margin:1px 21px;padding:1px 0 1px 15px;border-left:1px solid rgba(255,255,255,.18);overflow:hidden;transition:max-height .25s ease-out,opacity .18s,margin .2s;max-height:0;opacity:0;display:flex;flex-direction:column;gap:1px}.cqa-nav-children--open{max-height:320px;opacity:1}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: NavItemComponent, selector: "cqa-nav-item", inputs: ["item", "isActive", "isExpanded", "isOpen", "activeNavId"], outputs: ["itemClick"] }, { kind: "component", type: NavSubItemComponent, selector: "cqa-nav-sub-item", inputs: ["item", "isActive"], outputs: ["itemClick"] }] });
12802
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: NavMenuComponent, selector: "cqa-nav-menu", inputs: { items: "items", activeId: "activeId", isExpanded: "isExpanded", openParents: "openParents" }, outputs: { itemClick: "itemClick" }, ngImport: i0, template: "<div class=\"cqa-nav-menu-outer\">\n <nav class=\"cqa-nav-menu\" [class.cqa-nav-menu--collapsed]=\"!isExpanded\">\n <ng-container *ngFor=\"let item of items\">\n\n <!-- Section header (expanded only \u2014 collapsed rail shows icons only) -->\n <ng-container *ngIf=\"isSection(item) && isExpanded\">\n <div class=\"cqa-nav-section\">\n <span class=\"cqa-nav-section-label\">{{ item.label }}</span>\n </div>\n </ng-container>\n\n <!-- Nav item -->\n <ng-container *ngIf=\"!isSection(item)\">\n <cqa-nav-item\n [item]=\"asNavItem(item)\"\n [isActive]=\"isItemActive(asNavItem(item))\"\n [isExpanded]=\"isExpanded\"\n [isOpen]=\"isParentOpen(asNavItem(item))\"\n [activeNavId]=\"activeId\"\n (itemClick)=\"onItemClick($event)\">\n </cqa-nav-item>\n\n <!-- Sub-menu (only rendered when sidebar is expanded) -->\n <div\n *ngIf=\"isExpanded && asNavItem(item).children?.length\"\n class=\"cqa-nav-children\"\n [class.cqa-nav-children--open]=\"isParentOpen(asNavItem(item))\">\n <cqa-nav-sub-item\n *ngFor=\"let child of asNavItem(item).children\"\n [item]=\"child\"\n [isActive]=\"isChildActive(child.id)\"\n (itemClick)=\"onItemClick($event)\">\n </cqa-nav-sub-item>\n </div>\n </ng-container>\n\n </ng-container>\n </nav>\n</div>\n", styles: [":host{display:flex;flex-direction:column;flex:1 1 0;min-height:0;overflow:hidden;width:100%}.cqa-nav-menu-outer{display:flex;flex-direction:column;flex:1 1 auto;min-height:0;overflow:hidden;width:100%}.cqa-nav-menu{flex:1 1 auto;overflow-y:auto;overflow-x:hidden;padding:4px 0 8px;min-height:0;overscroll-behavior:contain}.cqa-nav-menu::-webkit-scrollbar{width:4px}.cqa-nav-menu::-webkit-scrollbar-thumb{background:#ffffff26;border-radius:2px}.cqa-nav-menu--collapsed{overflow-x:visible}.cqa-nav-section{font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif;font-size:10px;font-weight:700;letter-spacing:.1em;color:#ffffff8c;padding:14px 18px 6px;text-transform:uppercase;overflow:hidden;transition:opacity .16s 80ms,padding .16s,font-size .16s;opacity:1}.cqa-nav-children{margin:1px 21px;padding:1px 0 1px 15px;border-left:1px solid rgba(255,255,255,.18);overflow:hidden;transition:max-height .25s ease-out,opacity .18s,margin .2s;max-height:0;opacity:0;display:flex;flex-direction:column;gap:1px}.cqa-nav-children--open{max-height:320px;opacity:1}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: NavItemComponent, selector: "cqa-nav-item", inputs: ["item", "isActive", "isExpanded", "isOpen", "activeNavId"], outputs: ["itemClick"] }, { kind: "component", type: NavSubItemComponent, selector: "cqa-nav-sub-item", inputs: ["item", "isActive"], outputs: ["itemClick"] }] });
12793
12803
  }
12794
12804
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NavMenuComponent, decorators: [{
12795
12805
  type: Component,
12796
- args: [{ selector: 'cqa-nav-menu', template: "<div id=\"cqa-ui-root\" style=\"display:flex;flex-direction:column;flex:1 1 auto;min-height:0;overflow:hidden;width:100%;\">\n <nav class=\"cqa-nav-menu\" [class.cqa-nav-menu--collapsed]=\"!isExpanded\">\n <ng-container *ngFor=\"let item of items\">\n\n <!-- Section header (expanded only \u2014 collapsed rail shows icons only) -->\n <ng-container *ngIf=\"isSection(item) && isExpanded\">\n <div class=\"cqa-nav-section\">\n <span class=\"cqa-nav-section-label\">{{ item.label }}</span>\n </div>\n </ng-container>\n\n <!-- Nav item -->\n <ng-container *ngIf=\"!isSection(item)\">\n <cqa-nav-item\n [item]=\"asNavItem(item)\"\n [isActive]=\"isItemActive(asNavItem(item))\"\n [isExpanded]=\"isExpanded\"\n [isOpen]=\"isParentOpen(asNavItem(item))\"\n [activeNavId]=\"activeId\"\n (itemClick)=\"onItemClick($event)\">\n </cqa-nav-item>\n\n <!-- Sub-menu (only rendered when sidebar is expanded) -->\n <div\n *ngIf=\"isExpanded && asNavItem(item).children?.length\"\n class=\"cqa-nav-children\"\n [class.cqa-nav-children--open]=\"isParentOpen(asNavItem(item))\">\n <cqa-nav-sub-item\n *ngFor=\"let child of asNavItem(item).children\"\n [item]=\"child\"\n [isActive]=\"isChildActive(child.id)\"\n (itemClick)=\"onItemClick($event)\">\n </cqa-nav-sub-item>\n </div>\n </ng-container>\n\n </ng-container>\n </nav>\n</div>\n", styles: [":host{display:flex;flex-direction:column;flex:1 1 auto;min-height:0;overflow:hidden;width:100%}.cqa-nav-menu{flex:1 1 auto;overflow-y:auto;overflow-x:hidden;padding:4px 0 8px;min-height:0}.cqa-nav-menu::-webkit-scrollbar{width:4px}.cqa-nav-menu::-webkit-scrollbar-thumb{background:#ffffff26;border-radius:2px}.cqa-nav-menu--collapsed{overflow-x:visible}.cqa-nav-section{font-size:10px;font-weight:700;letter-spacing:.1em;color:#ffffff8c;padding:14px 18px 6px;text-transform:uppercase;height:28px;overflow:hidden;transition:opacity .16s 80ms,padding .16s,font-size .16s;opacity:1}.cqa-nav-children{margin:1px 21px;padding:1px 0 1px 15px;border-left:1px solid rgba(255,255,255,.18);overflow:hidden;transition:max-height .25s ease-out,opacity .18s,margin .2s;max-height:0;opacity:0;display:flex;flex-direction:column;gap:1px}.cqa-nav-children--open{max-height:320px;opacity:1}\n"] }]
12806
+ args: [{ selector: 'cqa-nav-menu', template: "<div class=\"cqa-nav-menu-outer\">\n <nav class=\"cqa-nav-menu\" [class.cqa-nav-menu--collapsed]=\"!isExpanded\">\n <ng-container *ngFor=\"let item of items\">\n\n <!-- Section header (expanded only \u2014 collapsed rail shows icons only) -->\n <ng-container *ngIf=\"isSection(item) && isExpanded\">\n <div class=\"cqa-nav-section\">\n <span class=\"cqa-nav-section-label\">{{ item.label }}</span>\n </div>\n </ng-container>\n\n <!-- Nav item -->\n <ng-container *ngIf=\"!isSection(item)\">\n <cqa-nav-item\n [item]=\"asNavItem(item)\"\n [isActive]=\"isItemActive(asNavItem(item))\"\n [isExpanded]=\"isExpanded\"\n [isOpen]=\"isParentOpen(asNavItem(item))\"\n [activeNavId]=\"activeId\"\n (itemClick)=\"onItemClick($event)\">\n </cqa-nav-item>\n\n <!-- Sub-menu (only rendered when sidebar is expanded) -->\n <div\n *ngIf=\"isExpanded && asNavItem(item).children?.length\"\n class=\"cqa-nav-children\"\n [class.cqa-nav-children--open]=\"isParentOpen(asNavItem(item))\">\n <cqa-nav-sub-item\n *ngFor=\"let child of asNavItem(item).children\"\n [item]=\"child\"\n [isActive]=\"isChildActive(child.id)\"\n (itemClick)=\"onItemClick($event)\">\n </cqa-nav-sub-item>\n </div>\n </ng-container>\n\n </ng-container>\n </nav>\n</div>\n", styles: [":host{display:flex;flex-direction:column;flex:1 1 0;min-height:0;overflow:hidden;width:100%}.cqa-nav-menu-outer{display:flex;flex-direction:column;flex:1 1 auto;min-height:0;overflow:hidden;width:100%}.cqa-nav-menu{flex:1 1 auto;overflow-y:auto;overflow-x:hidden;padding:4px 0 8px;min-height:0;overscroll-behavior:contain}.cqa-nav-menu::-webkit-scrollbar{width:4px}.cqa-nav-menu::-webkit-scrollbar-thumb{background:#ffffff26;border-radius:2px}.cqa-nav-menu--collapsed{overflow-x:visible}.cqa-nav-section{font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif;font-size:10px;font-weight:700;letter-spacing:.1em;color:#ffffff8c;padding:14px 18px 6px;text-transform:uppercase;overflow:hidden;transition:opacity .16s 80ms,padding .16s,font-size .16s;opacity:1}.cqa-nav-children{margin:1px 21px;padding:1px 0 1px 15px;border-left:1px solid rgba(255,255,255,.18);overflow:hidden;transition:max-height .25s ease-out,opacity .18s,margin .2s;max-height:0;opacity:0;display:flex;flex-direction:column;gap:1px}.cqa-nav-children--open{max-height:320px;opacity:1}\n"] }]
12797
12807
  }], propDecorators: { items: [{
12798
12808
  type: Input
12799
12809
  }], activeId: [{
@@ -12806,6 +12816,144 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
12806
12816
  type: Output
12807
12817
  }] } });
12808
12818
 
12819
+ class SafeHtmlPipe {
12820
+ sanitizer;
12821
+ constructor(sanitizer) {
12822
+ this.sanitizer = sanitizer;
12823
+ }
12824
+ transform(value) {
12825
+ const str = value != null ? String(value) : '';
12826
+ return this.sanitizer.bypassSecurityTrustHtml(str);
12827
+ }
12828
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SafeHtmlPipe, deps: [{ token: i1$1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Pipe });
12829
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.14", ngImport: i0, type: SafeHtmlPipe, name: "cqaSafeHtml" });
12830
+ }
12831
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SafeHtmlPipe, decorators: [{
12832
+ type: Pipe,
12833
+ args: [{ name: 'cqaSafeHtml' }]
12834
+ }], ctorParameters: () => [{ type: i1$1.DomSanitizer }] });
12835
+
12836
+ class ProfileMenuComponent {
12837
+ overlay;
12838
+ viewContainerRef;
12839
+ user;
12840
+ entries = [];
12841
+ anchor = null;
12842
+ /** Optional id on the popover element — useful for aria-labelledby wiring. */
12843
+ popoverId;
12844
+ itemClick = new EventEmitter();
12845
+ dismissed = new EventEmitter();
12846
+ popoverTpl;
12847
+ overlayRef = null;
12848
+ keySub = null;
12849
+ backdropSub = null;
12850
+ viewInitialized = false;
12851
+ constructor(overlay, viewContainerRef) {
12852
+ this.overlay = overlay;
12853
+ this.viewContainerRef = viewContainerRef;
12854
+ }
12855
+ ngAfterViewInit() {
12856
+ this.viewInitialized = true;
12857
+ if (this.anchor) {
12858
+ this.openOverlay();
12859
+ }
12860
+ }
12861
+ ngOnChanges(changes) {
12862
+ if (!this.viewInitialized || !changes['anchor'])
12863
+ return;
12864
+ if (this.anchor) {
12865
+ this.openOverlay();
12866
+ }
12867
+ else {
12868
+ this.closeOverlay();
12869
+ }
12870
+ }
12871
+ ngOnDestroy() {
12872
+ this.closeOverlay();
12873
+ }
12874
+ isDivider = isProfileMenuDivider;
12875
+ /** Narrowing helper for the template — Angular's template type checker can't
12876
+ * follow our custom type guard through `*ngIf-else`, so we surface a typed cast
12877
+ * via this method instead. */
12878
+ asItem(entry) {
12879
+ return isProfileMenuDivider(entry) ? null : entry;
12880
+ }
12881
+ trackByEntry = (index, _entry) => index;
12882
+ onItemClick(item) {
12883
+ if (item.disabled) {
12884
+ return;
12885
+ }
12886
+ this.itemClick.emit(item.id);
12887
+ }
12888
+ openOverlay() {
12889
+ if (!this.anchor) {
12890
+ return;
12891
+ }
12892
+ this.closeOverlay();
12893
+ // Popover floats out to the right of the profile card, bottom-aligned with the card.
12894
+ // `withPush(false)` is critical — otherwise CDK slides the overlay back over the sidebar
12895
+ // when its viewport calculation thinks the popover doesn't fit (e.g. in narrow iframes).
12896
+ const positions = [
12897
+ { originX: 'end', originY: 'bottom', overlayX: 'start', overlayY: 'bottom', offsetX: 0, offsetY: 0 },
12898
+ { originX: 'end', originY: 'top', overlayX: 'start', overlayY: 'bottom', offsetX: 0, offsetY: -4 },
12899
+ ];
12900
+ const positionStrategy = this.overlay
12901
+ .position()
12902
+ .flexibleConnectedTo(this.anchor)
12903
+ .withPositions(positions)
12904
+ .withFlexibleDimensions(false)
12905
+ .withViewportMargin(8)
12906
+ .withPush(false);
12907
+ this.overlayRef = this.overlay.create({
12908
+ positionStrategy,
12909
+ scrollStrategy: this.overlay.scrollStrategies.reposition(),
12910
+ hasBackdrop: true,
12911
+ backdropClass: 'cdk-overlay-transparent-backdrop',
12912
+ panelClass: 'cqa-profile-menu-panel',
12913
+ });
12914
+ const portal = new TemplatePortal(this.popoverTpl, this.viewContainerRef);
12915
+ this.overlayRef.attach(portal);
12916
+ this.backdropSub = this.overlayRef.backdropClick().subscribe(() => this.dismissed.emit());
12917
+ this.keySub = this.overlayRef.keydownEvents().subscribe((event) => {
12918
+ if (event.key === 'Escape') {
12919
+ event.preventDefault();
12920
+ this.dismissed.emit();
12921
+ }
12922
+ });
12923
+ }
12924
+ closeOverlay() {
12925
+ this.backdropSub?.unsubscribe();
12926
+ this.backdropSub = null;
12927
+ this.keySub?.unsubscribe();
12928
+ this.keySub = null;
12929
+ if (this.overlayRef) {
12930
+ this.overlayRef.dispose();
12931
+ this.overlayRef = null;
12932
+ }
12933
+ }
12934
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ProfileMenuComponent, deps: [{ token: i1$3.Overlay }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Component });
12935
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: ProfileMenuComponent, selector: "cqa-profile-menu", inputs: { user: "user", entries: "entries", anchor: "anchor", popoverId: "popoverId" }, outputs: { itemClick: "itemClick", dismissed: "dismissed" }, viewQueries: [{ propertyName: "popoverTpl", first: true, predicate: ["popoverTpl"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<ng-template #popoverTpl>\n <div class=\"cqa-pm\" [attr.id]=\"popoverId\" role=\"menu\" aria-orientation=\"vertical\">\n <!-- ===== Header ===== -->\n <div class=\"cqa-pm-header\">\n <div class=\"cqa-pm-avatar\" [style.background]=\"user?.avatarColor || null\">\n {{ user?.initials }}\n </div>\n <div class=\"cqa-pm-identity\">\n <span class=\"cqa-pm-name\" [title]=\"user?.name\">{{ user?.name }}</span>\n <span *ngIf=\"user?.email\" class=\"cqa-pm-email\" [title]=\"user?.email\">{{ user?.email }}</span>\n <span\n *ngIf=\"user?.badge?.label\"\n class=\"cqa-pm-badge\"\n [class.cqa-pm-badge--admin]=\"(user?.badge?.variant || 'admin') === 'admin'\"\n [class.cqa-pm-badge--default]=\"user?.badge?.variant === 'default'\">\n {{ user?.badge?.label }}\n </span>\n </div>\n </div>\n\n <div class=\"cqa-pm-divider\"></div>\n\n <!-- ===== Entries ===== -->\n <ul class=\"cqa-pm-list\">\n <ng-container *ngFor=\"let entry of entries; trackBy: trackByEntry\">\n <li *ngIf=\"isDivider(entry); else itemTpl\" class=\"cqa-pm-list-divider\" role=\"separator\"></li>\n <ng-template #itemTpl>\n <li *ngIf=\"asItem(entry) as item\">\n <button\n type=\"button\"\n class=\"cqa-pm-item\"\n [class.cqa-pm-item--danger]=\"item.variant === 'danger'\"\n [class.cqa-pm-item--disabled]=\"item.disabled\"\n [disabled]=\"item.disabled\"\n role=\"menuitem\"\n (click)=\"onItemClick(item)\">\n <span\n *ngIf=\"item.iconSvg || item.iconClass\"\n class=\"cqa-pm-item-icon\"\n aria-hidden=\"true\">\n <span\n *ngIf=\"item.iconSvg; else fontIcon\"\n [innerHTML]=\"item.iconSvg | cqaSafeHtml\">\n </span>\n <ng-template #fontIcon>\n <i *ngIf=\"item.iconClass\" [ngClass]=\"item.iconClass\"></i>\n </ng-template>\n </span>\n <span class=\"cqa-pm-item-label\">{{ item.label }}</span>\n <span *ngIf=\"item.shortcut\" class=\"cqa-pm-item-shortcut\">{{ item.shortcut }}</span>\n </button>\n </li>\n </ng-template>\n </ng-container>\n </ul>\n </div>\n</ng-template>\n", styles: ["::ng-deep .cqa-profile-menu-panel{z-index:1200}.cqa-pm{width:270px;background:#fbfcff;border-radius:12px;box-shadow:0 0 0 1px #0f12a80a,0 12px 32px #0f12a82e;padding:6px;font-family:inherit;color:#161617;-webkit-user-select:none;user-select:none;animation:cqaPmFadeIn .12s cubic-bezier(.16,1,.3,1)}@keyframes cqaPmFadeIn{0%{opacity:0;transform:translateY(2px) scale(.985)}to{opacity:1;transform:translateY(0) scale(1)}}.cqa-pm-header{display:flex;align-items:flex-start;gap:10px;padding:10px 10px 12px}.cqa-pm-avatar{width:38px;height:38px;border-radius:50%;background:linear-gradient(135deg,#f472b6,#db2777);color:#fff;font-size:14px;font-weight:700;display:flex;align-items:center;justify-content:center;flex-shrink:0;letter-spacing:.2px}.cqa-pm-identity{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}.cqa-pm-name{font-size:14px;font-weight:600;line-height:1;color:#161617;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.cqa-pm-email{font-size:11.5px;font-weight:400;line-height:1;color:#6d6d74;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.cqa-pm-badge{display:inline-flex;align-items:center;align-self:flex-start;padding:2px 7px;border-radius:999px;font-size:10px;font-weight:700;line-height:1;white-space:nowrap}.cqa-pm-badge--admin{background:#6366f11a;color:#1216cc}.cqa-pm-badge--default{background:#eef0f3;color:#374151}.cqa-pm-divider{height:1px;background:#f0f0f1;margin:0}.cqa-pm-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column}.cqa-pm-list-divider{height:1px;background:#f0f0f1;margin:6px}.cqa-pm-item{width:100%;display:flex;align-items:center;gap:10px;padding:12px 10px 8px;background:transparent;border:none;border-radius:8px;cursor:pointer;font-family:inherit;font-size:13px;font-weight:400;line-height:1;color:#4c4c51;text-align:left;transition:background .12s,color .12s}.cqa-pm-item:hover:not(:disabled){background:#f4f5f7}.cqa-pm-item:focus-visible{outline:2px solid #4f46e5;outline-offset:1px}.cqa-pm-item--danger,.cqa-pm-item--danger .cqa-pm-item-icon{color:#e23a3a}.cqa-pm-item--danger:hover:not(:disabled){background:#fbeaea}.cqa-pm-item--disabled,.cqa-pm-item:disabled{cursor:not-allowed;opacity:.5}.cqa-pm-item-icon{width:16px;height:16px;font-size:16px;color:#161617a6;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0}.cqa-pm-item-label{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.cqa-pm-item-shortcut{background:#eef0f3;color:#6b7280;font-size:11px;font-weight:600;line-height:16px;padding:1px 6px;border-radius:4px;flex-shrink:0}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: SafeHtmlPipe, name: "cqaSafeHtml" }] });
12936
+ }
12937
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ProfileMenuComponent, decorators: [{
12938
+ type: Component,
12939
+ args: [{ selector: 'cqa-profile-menu', template: "<ng-template #popoverTpl>\n <div class=\"cqa-pm\" [attr.id]=\"popoverId\" role=\"menu\" aria-orientation=\"vertical\">\n <!-- ===== Header ===== -->\n <div class=\"cqa-pm-header\">\n <div class=\"cqa-pm-avatar\" [style.background]=\"user?.avatarColor || null\">\n {{ user?.initials }}\n </div>\n <div class=\"cqa-pm-identity\">\n <span class=\"cqa-pm-name\" [title]=\"user?.name\">{{ user?.name }}</span>\n <span *ngIf=\"user?.email\" class=\"cqa-pm-email\" [title]=\"user?.email\">{{ user?.email }}</span>\n <span\n *ngIf=\"user?.badge?.label\"\n class=\"cqa-pm-badge\"\n [class.cqa-pm-badge--admin]=\"(user?.badge?.variant || 'admin') === 'admin'\"\n [class.cqa-pm-badge--default]=\"user?.badge?.variant === 'default'\">\n {{ user?.badge?.label }}\n </span>\n </div>\n </div>\n\n <div class=\"cqa-pm-divider\"></div>\n\n <!-- ===== Entries ===== -->\n <ul class=\"cqa-pm-list\">\n <ng-container *ngFor=\"let entry of entries; trackBy: trackByEntry\">\n <li *ngIf=\"isDivider(entry); else itemTpl\" class=\"cqa-pm-list-divider\" role=\"separator\"></li>\n <ng-template #itemTpl>\n <li *ngIf=\"asItem(entry) as item\">\n <button\n type=\"button\"\n class=\"cqa-pm-item\"\n [class.cqa-pm-item--danger]=\"item.variant === 'danger'\"\n [class.cqa-pm-item--disabled]=\"item.disabled\"\n [disabled]=\"item.disabled\"\n role=\"menuitem\"\n (click)=\"onItemClick(item)\">\n <span\n *ngIf=\"item.iconSvg || item.iconClass\"\n class=\"cqa-pm-item-icon\"\n aria-hidden=\"true\">\n <span\n *ngIf=\"item.iconSvg; else fontIcon\"\n [innerHTML]=\"item.iconSvg | cqaSafeHtml\">\n </span>\n <ng-template #fontIcon>\n <i *ngIf=\"item.iconClass\" [ngClass]=\"item.iconClass\"></i>\n </ng-template>\n </span>\n <span class=\"cqa-pm-item-label\">{{ item.label }}</span>\n <span *ngIf=\"item.shortcut\" class=\"cqa-pm-item-shortcut\">{{ item.shortcut }}</span>\n </button>\n </li>\n </ng-template>\n </ng-container>\n </ul>\n </div>\n</ng-template>\n", styles: ["::ng-deep .cqa-profile-menu-panel{z-index:1200}.cqa-pm{width:270px;background:#fbfcff;border-radius:12px;box-shadow:0 0 0 1px #0f12a80a,0 12px 32px #0f12a82e;padding:6px;font-family:inherit;color:#161617;-webkit-user-select:none;user-select:none;animation:cqaPmFadeIn .12s cubic-bezier(.16,1,.3,1)}@keyframes cqaPmFadeIn{0%{opacity:0;transform:translateY(2px) scale(.985)}to{opacity:1;transform:translateY(0) scale(1)}}.cqa-pm-header{display:flex;align-items:flex-start;gap:10px;padding:10px 10px 12px}.cqa-pm-avatar{width:38px;height:38px;border-radius:50%;background:linear-gradient(135deg,#f472b6,#db2777);color:#fff;font-size:14px;font-weight:700;display:flex;align-items:center;justify-content:center;flex-shrink:0;letter-spacing:.2px}.cqa-pm-identity{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}.cqa-pm-name{font-size:14px;font-weight:600;line-height:1;color:#161617;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.cqa-pm-email{font-size:11.5px;font-weight:400;line-height:1;color:#6d6d74;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.cqa-pm-badge{display:inline-flex;align-items:center;align-self:flex-start;padding:2px 7px;border-radius:999px;font-size:10px;font-weight:700;line-height:1;white-space:nowrap}.cqa-pm-badge--admin{background:#6366f11a;color:#1216cc}.cqa-pm-badge--default{background:#eef0f3;color:#374151}.cqa-pm-divider{height:1px;background:#f0f0f1;margin:0}.cqa-pm-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column}.cqa-pm-list-divider{height:1px;background:#f0f0f1;margin:6px}.cqa-pm-item{width:100%;display:flex;align-items:center;gap:10px;padding:12px 10px 8px;background:transparent;border:none;border-radius:8px;cursor:pointer;font-family:inherit;font-size:13px;font-weight:400;line-height:1;color:#4c4c51;text-align:left;transition:background .12s,color .12s}.cqa-pm-item:hover:not(:disabled){background:#f4f5f7}.cqa-pm-item:focus-visible{outline:2px solid #4f46e5;outline-offset:1px}.cqa-pm-item--danger,.cqa-pm-item--danger .cqa-pm-item-icon{color:#e23a3a}.cqa-pm-item--danger:hover:not(:disabled){background:#fbeaea}.cqa-pm-item--disabled,.cqa-pm-item:disabled{cursor:not-allowed;opacity:.5}.cqa-pm-item-icon{width:16px;height:16px;font-size:16px;color:#161617a6;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0}.cqa-pm-item-label{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.cqa-pm-item-shortcut{background:#eef0f3;color:#6b7280;font-size:11px;font-weight:600;line-height:16px;padding:1px 6px;border-radius:4px;flex-shrink:0}\n"] }]
12940
+ }], ctorParameters: () => [{ type: i1$3.Overlay }, { type: i0.ViewContainerRef }], propDecorators: { user: [{
12941
+ type: Input
12942
+ }], entries: [{
12943
+ type: Input
12944
+ }], anchor: [{
12945
+ type: Input
12946
+ }], popoverId: [{
12947
+ type: Input
12948
+ }], itemClick: [{
12949
+ type: Output
12950
+ }], dismissed: [{
12951
+ type: Output
12952
+ }], popoverTpl: [{
12953
+ type: ViewChild,
12954
+ args: ['popoverTpl', { static: true }]
12955
+ }] } });
12956
+
12809
12957
  class SidebarComponent {
12810
12958
  sanitizer;
12811
12959
  config = {};
@@ -12813,6 +12961,17 @@ class SidebarComponent {
12813
12961
  activeNavId = '';
12814
12962
  /** Parent item IDs to open by default (in addition to the one containing the active item). */
12815
12963
  initialOpenParentIds = [];
12964
+ /**
12965
+ * User details rendered in the profile-menu popover header. Required for the popover
12966
+ * to open; when undefined the profile card retains its legacy single-action behavior
12967
+ * (clicking it directly fires `logoutClick`).
12968
+ */
12969
+ profileUser;
12970
+ /**
12971
+ * Menu entries shown inside the profile-menu popover. Provide at least one entry to
12972
+ * enable the popover; an empty array preserves the legacy `logoutClick` behavior.
12973
+ */
12974
+ profileMenuEntries = [];
12816
12975
  navItemClick = new EventEmitter();
12817
12976
  ctaClick = new EventEmitter();
12818
12977
  searchClick = new EventEmitter();
@@ -12823,10 +12982,13 @@ class SidebarComponent {
12823
12982
  speakerClick = new EventEmitter();
12824
12983
  liveChatClick = new EventEmitter();
12825
12984
  expandedChange = new EventEmitter();
12985
+ /** Emits `ProfileMenuItem.id` when the user activates an entry in the profile popover. */
12986
+ profileMenuItemClick = new EventEmitter();
12987
+ profileAnchorRef;
12826
12988
  isExpanded = false;
12827
- /** When true, expanded state is kept until the user collapses (mouse leave does not close). */
12828
12989
  isPinned = false;
12829
12990
  openParents = [];
12991
+ isProfileMenuOpen = false;
12830
12992
  leaveCollapseTimer = null;
12831
12993
  static LEAVE_COLLAPSE_MS = 220;
12832
12994
  constructor(sanitizer) {
@@ -12858,6 +13020,21 @@ class SidebarComponent {
12858
13020
  this.ensureActiveParentOpen();
12859
13021
  }
12860
13022
  }
13023
+ onProfileClick() {
13024
+ if (this.profileUser && this.profileMenuEntries?.length) {
13025
+ this.isProfileMenuOpen = !this.isProfileMenuOpen;
13026
+ return;
13027
+ }
13028
+ // Legacy single-action behaviour preserved for consumers that haven't migrated.
13029
+ this.logoutClick.emit();
13030
+ }
13031
+ onProfileMenuItemClick(id) {
13032
+ this.isProfileMenuOpen = false;
13033
+ this.profileMenuItemClick.emit(id);
13034
+ }
13035
+ onProfileMenuDismissed() {
13036
+ this.isProfileMenuOpen = false;
13037
+ }
12861
13038
  /** Burger: wide sidebar without pinning — collapses on mouse leave. */
12862
13039
  openSidebar() {
12863
13040
  this.clearLeaveCollapseTimer();
@@ -12914,7 +13091,12 @@ class SidebarComponent {
12914
13091
  }
12915
13092
  }
12916
13093
  onNavItemClick(id) {
12917
- const item = this.findNavItem(id);
13094
+ // Submenu leaf: always emit navigation (child id was wrongly treated as a parent for toggle).
13095
+ if (this.isChildNavId(id)) {
13096
+ this.navItemClick.emit(id);
13097
+ return;
13098
+ }
13099
+ const item = this.findTopLevelNavItem(id);
12918
13100
  if (!item) {
12919
13101
  this.navItemClick.emit(id);
12920
13102
  return;
@@ -12944,15 +13126,20 @@ class SidebarComponent {
12944
13126
  this.openParents = [...this.openParents, id];
12945
13127
  }
12946
13128
  }
12947
- findNavItem(id) {
13129
+ /** True if `id` matches a submenu row under some top-level nav item. */
13130
+ isChildNavId(id) {
13131
+ for (const item of this.navItems) {
13132
+ if (isNavSection(item))
13133
+ continue;
13134
+ if (item.children?.some((c) => c.id === id))
13135
+ return true;
13136
+ }
13137
+ return false;
13138
+ }
13139
+ findTopLevelNavItem(id) {
12948
13140
  for (const item of this.navItems) {
12949
13141
  if (!isNavSection(item) && item.id === id)
12950
13142
  return item;
12951
- if (!isNavSection(item) && item.children) {
12952
- const child = item.children.find(c => c.id === id);
12953
- if (child)
12954
- return item;
12955
- }
12956
13143
  }
12957
13144
  return null;
12958
13145
  }
@@ -12967,11 +13154,11 @@ class SidebarComponent {
12967
13154
  }
12968
13155
  }
12969
13156
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SidebarComponent, deps: [{ token: i1$1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Component });
12970
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: SidebarComponent, selector: "cqa-sidebar", inputs: { config: "config", navItems: "navItems", activeNavId: "activeNavId", initialOpenParentIds: "initialOpenParentIds" }, outputs: { navItemClick: "navItemClick", ctaClick: "ctaClick", searchClick: "searchClick", workspaceSwitchClick: "workspaceSwitchClick", logoutClick: "logoutClick", notificationsClick: "notificationsClick", helpDocsClick: "helpDocsClick", speakerClick: "speakerClick", liveChatClick: "liveChatClick", expandedChange: "expandedChange" }, usesOnChanges: true, ngImport: i0, template: "<div id=\"cqa-ui-root\" style=\"display:block;height:100%\">\n <aside\n class=\"cqa-sb\"\n [class.cqa-sb--expanded]=\"isExpanded\"\n (mouseenter)=\"onAsideMouseEnter()\"\n (mouseleave)=\"onAsideMouseLeave($event)\">\n\n <!-- ===== 1. Workspace header ===== -->\n <div class=\"cqa-sb-header\" [class.cqa-sb-header--expanded]=\"isExpanded\">\n <!-- Collapsed: hamburger chip -->\n <button\n *ngIf=\"!isExpanded\"\n class=\"cqa-sb-burger\"\n (click)=\"openSidebar()\"\n type=\"button\"\n aria-label=\"Open sidebar\">\n <svg viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"1.33\" stroke-linecap=\"round\"\n width=\"16\" height=\"16\">\n <line x1=\"2\" y1=\"4\" x2=\"14\" y2=\"4\"/>\n <line x1=\"2\" y1=\"8\" x2=\"14\" y2=\"8\"/>\n <line x1=\"2\" y1=\"12\" x2=\"14\" y2=\"12\"/>\n </svg>\n </button>\n\n <!-- Expanded: workspace selector + pin (unpinned) or close (pinned) -->\n <ng-container *ngIf=\"isExpanded\">\n <button class=\"cqa-sb-ws\" type=\"button\" (click)=\"workspaceSwitchClick.emit()\">\n <span class=\"cqa-sb-ws-main\">\n <span class=\"cqa-sb-ws-avatar\">\n <img *ngIf=\"workspaceLogoSafe; else wsInitialTpl\"\n class=\"cqa-sb-ws-logo\"\n [src]=\"workspaceLogoSafe\"\n [alt]=\"config?.workspaceName || 'Workspace logo'\" />\n <ng-template #wsInitialTpl>\n <span class=\"cqa-sb-ws-initial\">{{ workspaceInitial }}</span>\n </ng-template>\n <span *ngIf=\"config?.workspaceStatus === 'live'\" class=\"cqa-sb-ws-status\"></span>\n </span>\n <span class=\"cqa-sb-ws-info\">\n <span class=\"cqa-sb-ws-name-row\">\n <span class=\"cqa-sb-ws-name\">{{ config?.workspaceName || 'Workspace' }}</span>\n </span>\n </span>\n </span>\n <span class=\"cqa-sb-ws-switch\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 14 14\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"1.17\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\n width=\"14\" height=\"14\">\n <polyline points=\"3,9 7,12 11,9\"/>\n <polyline points=\"3,5 7,2 11,5\"/>\n </svg>\n </span>\n </button>\n\n <button\n *ngIf=\"isPinned || config?.showSidebarPin !== false\"\n class=\"cqa-sb-pin-or-close\"\n type=\"button\"\n (click)=\"isPinned ? closeSidebar() : pinSidebar()\"\n [matTooltip]=\"isPinned ? 'Close sidebar' : 'Pin sidebar'\"\n [matTooltipPosition]=\"isPinned ? 'right' : 'left'\"\n [attr.aria-label]=\"isPinned ? 'Close sidebar' : 'Pin sidebar'\">\n <svg\n *ngIf=\"isPinned\"\n viewBox=\"0 0 18 18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.35\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" width=\"18\" height=\"18\">\n <rect x=\"1.5\" y=\"1.5\" width=\"15\" height=\"15\" rx=\"2.5\"/>\n <line x1=\"6.5\" y1=\"1.5\" x2=\"6.5\" y2=\"16.5\"/>\n <polyline points=\"10.5,12 8.5,9 10.5,6\"/>\n </svg>\n <svg\n *ngIf=\"!isPinned\"\n viewBox=\"0 0 18 18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.35\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" width=\"18\" height=\"18\">\n <path d=\"M9 3v4M7 3h4v4l2 3H5l2-3V3z\"/>\n <line x1=\"9\" y1=\"10\" x2=\"9\" y2=\"15\"/>\n </svg>\n </button>\n </ng-container>\n </div>\n\n <!-- ===== 2. Search ===== -->\n <div *ngIf=\"config?.showSearch !== false\" class=\"cqa-sb-search-wrap\">\n <button class=\"cqa-sb-search\" type=\"button\"\n [matTooltip]=\"!isExpanded ? 'Search' : ''\" matTooltipPosition=\"right\"\n (click)=\"searchClick.emit()\">\n <svg class=\"cqa-sb-search-icon\" viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"1.33\" stroke-linecap=\"round\" stroke-linejoin=\"round\" width=\"16\" height=\"16\">\n <circle cx=\"7\" cy=\"7\" r=\"4.5\"/>\n <line x1=\"10.5\" y1=\"10.5\" x2=\"13.5\" y2=\"13.5\"/>\n </svg>\n <span class=\"cqa-sb-search-text\" [class.cqa-sb-search-text--visible]=\"isExpanded\">\n {{ config?.searchPlaceholder || 'Search Anything...' }}\n </span>\n <span\n *ngIf=\"config?.showSearchShortcut !== false && isExpanded\"\n class=\"cqa-sb-search-kbd\">\u2318K</span>\n </button>\n </div>\n\n <!-- ===== 3. CTA ===== -->\n <div *ngIf=\"config?.showCta !== false\" class=\"cqa-sb-cta-wrap\">\n <button class=\"cqa-sb-cta\" type=\"button\"\n [matTooltip]=\"!isExpanded ? (config?.ctaLabel || 'New') : ''\" matTooltipPosition=\"right\"\n (click)=\"ctaClick.emit()\">\n <svg viewBox=\"0 0 18 18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.6\"\n stroke-linecap=\"round\" width=\"18\" height=\"18\">\n <line x1=\"9\" y1=\"3\" x2=\"9\" y2=\"15\"/>\n <line x1=\"3\" y1=\"9\" x2=\"15\" y2=\"9\"/>\n </svg>\n <span class=\"cqa-sb-cta-text\" [class.cqa-sb-cta-text--visible]=\"isExpanded\">\n {{ config?.ctaLabel || 'New Test Cases' }}\n </span>\n </button>\n </div>\n\n <!-- ===== 4. Nav menu ===== -->\n <cqa-nav-menu\n [items]=\"navItems\"\n [activeId]=\"activeNavId\"\n [isExpanded]=\"isExpanded\"\n [openParents]=\"openParents\"\n (itemClick)=\"onNavItemClick($event)\">\n </cqa-nav-menu>\n\n <!-- ===== 5. Utility bar ===== -->\n <div class=\"cqa-sb-utility\" [class.cqa-sb-utility--expanded]=\"isExpanded\">\n <!-- Expanded: 2 wide tiles (Help & docs + Live chat) -->\n <ng-container *ngIf=\"isExpanded\">\n <button\n *ngIf=\"config?.showHelpDocs !== false\"\n class=\"cqa-sb-util-tile\"\n type=\"button\"\n (click)=\"helpDocsClick.emit()\">\n <svg viewBox=\"0 0 18 18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.35\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" width=\"18\" height=\"18\">\n <circle cx=\"9\" cy=\"9\" r=\"7.25\"/>\n <path d=\"M6.85 7a2.15 2.15 0 0 1 4.18.75c0 1.4-2.15 1.8-2.15 3.05\"/>\n <line x1=\"9\" y1=\"13.4\" x2=\"9.01\" y2=\"13.4\"/>\n </svg>\n <span class=\"cqa-sb-util-tile-label\">{{ config?.helpDocsLabel || 'Help & docs' }}</span>\n </button>\n\n <button\n *ngIf=\"config?.showLiveChat !== false\"\n class=\"cqa-sb-util-tile\"\n type=\"button\"\n (click)=\"liveChatClick.emit()\">\n <svg viewBox=\"0 0 18 18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.35\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" width=\"18\" height=\"18\">\n <path d=\"M16 2H2a1 1 0 0 0-1 1v9a1 1 0 0 0 1 1h3v3l4.5-3H16a1 1 0 0 0 1-1V3a1 1 0 0 0-1-1z\"/>\n </svg>\n <span class=\"cqa-sb-util-tile-label\">Live chat</span>\n </button>\n </ng-container>\n\n <!-- Collapsed: help + live chat only (notifications / speaker are not shown on the rail) -->\n <ng-container *ngIf=\"!isExpanded\">\n <button\n *ngIf=\"config?.showHelpDocs !== false\"\n class=\"cqa-sb-util-compact\"\n type=\"button\"\n [matTooltip]=\"config?.helpDocsLabel || 'Help & docs'\" matTooltipPosition=\"right\"\n (click)=\"helpDocsClick.emit()\">\n <svg viewBox=\"0 0 18 18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.35\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" width=\"18\" height=\"18\">\n <circle cx=\"9\" cy=\"9\" r=\"7.25\"/>\n <path d=\"M6.85 7a2.15 2.15 0 0 1 4.18.75c0 1.4-2.15 1.8-2.15 3.05\"/>\n <line x1=\"9\" y1=\"13.4\" x2=\"9.01\" y2=\"13.4\"/>\n </svg>\n </button>\n\n <button\n *ngIf=\"config?.showLiveChat !== false\"\n class=\"cqa-sb-util-compact\"\n type=\"button\"\n matTooltip=\"Live chat\" matTooltipPosition=\"right\"\n (click)=\"liveChatClick.emit()\">\n <svg viewBox=\"0 0 18 18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.35\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" width=\"18\" height=\"18\">\n <path d=\"M16 2H2a1 1 0 0 0-1 1v9a1 1 0 0 0 1 1h3v3l4.5-3H16a1 1 0 0 0 1-1V3a1 1 0 0 0-1-1z\"/>\n </svg>\n </button>\n </ng-container>\n </div>\n\n <!-- ===== 6. Profile card ===== -->\n <button class=\"cqa-sb-profile\" type=\"button\"\n [matTooltip]=\"!isExpanded ? (config?.userName || '') : ''\" matTooltipPosition=\"right\"\n (click)=\"logoutClick.emit()\">\n <div class=\"cqa-sb-profile-avatar\">{{ config?.userInitials || '?' }}</div>\n <div class=\"cqa-sb-profile-info\" [class.cqa-sb-profile-info--visible]=\"isExpanded\">\n <span class=\"cqa-sb-profile-name\">{{ config?.userName }}</span>\n <span *ngIf=\"config?.userRole\" class=\"cqa-sb-profile-role\">{{ config.userRole }}</span>\n </div>\n <span *ngIf=\"isExpanded\" class=\"cqa-sb-profile-logout\" aria-label=\"Logout\">\n <svg viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.2\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" width=\"16\" height=\"16\">\n <path d=\"M6 14H3a1 1 0 0 1-1-1V3a1 1 0 0 1 1-1h3\"/>\n <polyline points=\"11,11 14,8 11,5\"/>\n <line x1=\"14\" y1=\"8\" x2=\"6\" y2=\"8\"/>\n </svg>\n </span>\n </button>\n\n </aside>\n</div>\n", styles: [":host{display:flex;height:100%;flex-shrink:0}.cqa-sb{background:#3f43ee;color:#fff;height:100%;display:flex;flex-direction:column;flex-shrink:0;width:60px;transition:width .24s cubic-bezier(.32,.72,0,1);position:relative;z-index:50;overflow-x:visible;overflow-y:hidden}.cqa-sb--expanded{width:264px;overflow-x:hidden}.cqa-sb-header{padding:10px;position:relative;border-bottom:1px solid rgba(255,255,255,.08);min-height:51px;display:flex;align-items:center;justify-content:center;flex-shrink:0}.cqa-sb-header--expanded{justify-content:flex-start;padding:12px 40px 11px 12px;min-height:71px;gap:0}.cqa-sb-burger{width:28px;height:28px;border-radius:7px;background:#d8d9fc2e;display:flex;align-items:center;justify-content:center;border:none;cursor:pointer;color:#d8d9fc;flex-shrink:0;transition:background .15s,color .15s}.cqa-sb-burger:hover{background:#d8d9fc47;color:#fff}.cqa-sb-pin-or-close{position:absolute;right:10px;top:50%;transform:translateY(calc(-50% + 1px));width:28px;height:28px;border-radius:7px;display:flex;align-items:center;justify-content:center;background:transparent;border:none;cursor:pointer;color:#d8d9fc;flex-shrink:0;transition:background .15s,color .15s}.cqa-sb-pin-or-close:hover{background:#ffffff1a;color:#fff}.cqa-sb-ws{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:6px 14px 6px 6px;border-radius:10px;transition:background .12s;flex:1;min-width:0;text-align:left;background:transparent;border:none;cursor:pointer;color:#fff;overflow:hidden}.cqa-sb-ws:hover{background:#ffffff14}.cqa-sb-ws-main{display:flex;align-items:center;gap:10px;min-width:0}.cqa-sb-ws-avatar{width:36px;height:36px;border-radius:9px;background:linear-gradient(135deg,#cce1f4,#d7e7f9);display:flex;align-items:center;justify-content:center;flex-shrink:0;position:relative;box-shadow:0 1px 2px #0000001f,inset 0 0 0 1px #fff6;overflow:hidden}.cqa-sb-ws-avatar:after{content:\"\";position:absolute;inset:0;border-radius:inherit;background:linear-gradient(to bottom,#ffffff80,#fff0 50%);pointer-events:none}.cqa-sb-ws-logo{position:relative;z-index:1;width:22px;height:26px;object-fit:contain;display:block}.cqa-sb-ws-initial{position:relative;z-index:1;color:#1216cc;font-weight:800;font-size:15px}.cqa-sb-ws-status{position:absolute;bottom:-3px;right:-3px;width:12px;height:12px;background:#0dbd7d;border-radius:50%;border:2.5px solid #3f43ee;box-shadow:0 0 6px #0dbd7d}.cqa-sb-ws-info{flex:1;min-width:0;overflow:hidden}.cqa-sb-ws-name-row{display:flex;align-items:center;gap:6px}.cqa-sb-ws-name{font-weight:600;font-size:14px;line-height:16.8px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:#fff}.cqa-sb-ws-badge{background:#0dbd7d2e;color:#5ed3a8;font-size:9.5px;font-weight:700;padding:1px 6px 1px 4px;border-radius:4px;display:inline-flex;align-items:center;gap:3px;flex-shrink:0;text-transform:uppercase;letter-spacing:.04em}.cqa-sb-ws-badge:before{content:\"\";width:4px;height:4px;background:#0dbd7d;border-radius:50%;box-shadow:0 0 6px #0dbd7d}.cqa-sb-ws-switch{color:#ffffff8c;flex-shrink:0;padding:4px 0 7px;display:flex;align-items:center}.cqa-sb-search-wrap{padding:8px 12px;flex-shrink:0}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-search-wrap{padding:8px 10px 6px;display:flex;justify-content:center}.cqa-sb-search{background:#ffffff0d;border:1px solid rgba(255,255,255,.1);border-radius:8px;min-height:38px;padding:0 13px;font-size:12px;letter-spacing:-.02em;color:#ffffff80;display:flex;align-items:center;gap:8px;width:100%;cursor:pointer;transition:all .15s;overflow:hidden;font-family:inherit}.cqa-sb-search:hover{background:#ffffff14;color:#ffffffbf;border-color:#ffffff29}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-search{padding:0;width:40px;max-width:40px;height:40px;min-height:40px;margin:0 auto;justify-content:center;align-items:center;gap:0;background:transparent;border-color:#d8d9fc;border-radius:9px}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-search .cqa-sb-search-text,.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-search .cqa-sb-search-kbd{flex:0 0 0;width:0;min-width:0;height:0;margin:0;padding:0;overflow:hidden;opacity:0;border:0;pointer-events:none}.cqa-sb-search-icon{flex-shrink:0;width:14px;height:14px}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-search-icon{width:16px;height:16px}.cqa-sb-search-text{flex:1;text-align:left;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;opacity:0;transition:opacity .16s 80ms}.cqa-sb-search-text--visible{opacity:1}.cqa-sb-search-kbd{font-size:10.5px;background:#ffffff26;padding:2px 6px;border-radius:4px;color:#ffffffd9;font-family:ui-monospace,monospace;flex-shrink:0;opacity:0;transition:opacity .16s 80ms}.cqa-sb-search-kbd--visible{opacity:1}.cqa-sb-cta-wrap{padding:0 12px 12px;flex-shrink:0}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-cta-wrap{padding:0 10px 12px;display:flex;justify-content:center}.cqa-sb-cta{background:#5256f0;color:#fbfcff;border:none;border-radius:8px;padding:10px 24px 10px 16px;font-size:14px;font-weight:600;line-height:14px;letter-spacing:0;width:100%;display:flex;align-items:center;justify-content:center;gap:8px;cursor:pointer;transition:background .15s,transform .15s;overflow:hidden;font-family:inherit}.cqa-sb-cta:hover{background:#5b5ff2;transform:translateY(-1px)}.cqa-sb-cta:active{transform:translateY(0)}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-cta{padding:0;width:40px;height:40px;min-height:40px;margin:0 auto;position:relative;background:transparent;color:#fff}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-cta:before{content:\"\";position:absolute;inset:0;border-radius:9px;background:#b1b2f838;pointer-events:none}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-cta svg{position:relative;z-index:1;width:16px;height:16px}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-cta{box-shadow:inset 0 0 0 1px #d8d9fc38}.cqa-sb-cta-text{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;opacity:0;transition:opacity .16s 80ms;position:relative;z-index:1}.cqa-sb-cta-text--visible{opacity:1}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-cta-text{display:none}.cqa-sb-utility{border-top:none;box-shadow:inset 0 1px #ffffff1a;flex-shrink:0}.cqa-sb-utility--expanded{display:flex;align-items:center;justify-content:space-between;height:68px;gap:0;padding:9px 10px 8px}.cqa-sb-utility:not(.cqa-sb-utility--expanded){display:flex;flex-direction:column;align-items:center;justify-content:flex-start;gap:1px;padding:6px 10px}.cqa-sb-util-tile{width:110px;max-width:110px;border-radius:9px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;padding:8px 6px 6px;color:#ffffffd9;background:#ffffff0f;border:none;cursor:pointer;transition:background .12s,color .12s;font-family:inherit}.cqa-sb-util-tile:hover{background:#b1b2f838;color:#fff}.cqa-sb-util-tile-label{font-size:10.5px;font-weight:600;line-height:10.5px;letter-spacing:.105px;text-align:center;white-space:nowrap}.cqa-sb-util-compact{position:relative;width:36px;height:34px;border-radius:8px;display:flex;align-items:center;justify-content:center;color:#ffffffe0;background:transparent;border:none;cursor:pointer;transition:background .12s,color .12s;padding:0;flex-shrink:0}.cqa-sb-util-compact:hover{background:#ffffff14;color:#fff}.cqa-sb-util-compact-dot{position:absolute;top:6px;right:6px;width:8px;height:8px;background:#ee3f3f;border-radius:4px;border:2px solid #3f43ee;pointer-events:none}.cqa-sb-profile{border-top:1px solid rgba(255,255,255,.1);padding:13px 14px 12px;display:flex;align-items:center;gap:12px;background:#00000029;transition:background .15s;overflow:hidden;position:relative;width:100%;flex-shrink:0;border-left:none;border-right:none;border-bottom:none;cursor:pointer;color:#fff;font-family:inherit}.cqa-sb-profile:hover{background:#00000042}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-profile{justify-content:center;padding:12px 0;gap:0;background:#0000001f;border-top-color:#ffffff1f}.cqa-sb-profile-avatar{width:34px;height:34px;border-radius:17px;background:linear-gradient(135deg,#f472b6,#db2777);display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:700;flex-shrink:0;box-shadow:0 0 0 2px #ffffff26}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-profile-avatar{width:32px;height:32px;border-radius:16px;font-size:11.5px}.cqa-sb-profile-info{flex:1;min-width:0;overflow:hidden;opacity:0;transition:opacity .16s 80ms;display:flex;flex-direction:column;align-items:flex-start;justify-content:center;gap:4px}.cqa-sb-profile-info--visible{opacity:1}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-profile-info{display:none}.cqa-sb-profile-name{font-weight:600;font-size:12.5px;line-height:13.75px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:#fff}.cqa-sb-profile-role{display:inline-block;font-size:9px;font-weight:700;background:#d8d9fc38;padding:3px 8px;border-radius:999px;line-height:12.6px;color:#fff;border:1px solid rgba(216,217,252,.2);white-space:nowrap;align-self:flex-start}.cqa-sb-profile-logout{color:#ffffff8c;padding:6px 6px 9px;border-radius:6px;flex-shrink:0;transition:background .12s,color .12s;display:flex;align-items:center}.cqa-sb-profile-logout:hover{background:#ffffff1f;color:#fff}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: NavMenuComponent, selector: "cqa-nav-menu", inputs: ["items", "activeId", "isExpanded", "openParents"], outputs: ["itemClick"] }] });
13157
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: SidebarComponent, selector: "cqa-sidebar", inputs: { config: "config", navItems: "navItems", activeNavId: "activeNavId", initialOpenParentIds: "initialOpenParentIds", profileUser: "profileUser", profileMenuEntries: "profileMenuEntries" }, outputs: { navItemClick: "navItemClick", ctaClick: "ctaClick", searchClick: "searchClick", workspaceSwitchClick: "workspaceSwitchClick", logoutClick: "logoutClick", notificationsClick: "notificationsClick", helpDocsClick: "helpDocsClick", speakerClick: "speakerClick", liveChatClick: "liveChatClick", expandedChange: "expandedChange", profileMenuItemClick: "profileMenuItemClick" }, viewQueries: [{ propertyName: "profileAnchorRef", first: true, predicate: ["profileAnchor"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div id=\"cqa-ui-root\" class=\"cqa-sb-root\">\n <aside\n class=\"cqa-sb\"\n [class.cqa-sb--expanded]=\"isExpanded\"\n (mouseenter)=\"onAsideMouseEnter()\"\n (mouseleave)=\"onAsideMouseLeave($event)\">\n\n <!-- ===== 1. Workspace header ===== -->\n <div class=\"cqa-sb-header\" [class.cqa-sb-header--expanded]=\"isExpanded\">\n <!-- Collapsed: hamburger chip -->\n <button\n *ngIf=\"!isExpanded\"\n class=\"cqa-sb-burger\"\n (click)=\"openSidebar()\"\n type=\"button\"\n aria-label=\"Open sidebar\">\n <svg viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"1.33\" stroke-linecap=\"round\"\n width=\"16\" height=\"16\">\n <line x1=\"2\" y1=\"4\" x2=\"14\" y2=\"4\"/>\n <line x1=\"2\" y1=\"8\" x2=\"14\" y2=\"8\"/>\n <line x1=\"2\" y1=\"12\" x2=\"14\" y2=\"12\"/>\n </svg>\n </button>\n\n <!-- Expanded: workspace selector + pin (unpinned) or close (pinned) -->\n <ng-container *ngIf=\"isExpanded\">\n <button class=\"cqa-sb-ws\" type=\"button\" (click)=\"workspaceSwitchClick.emit()\">\n <span class=\"cqa-sb-ws-main\">\n <span class=\"cqa-sb-ws-avatar\">\n <img *ngIf=\"workspaceLogoSafe; else defaultLogoTpl\"\n class=\"cqa-sb-ws-logo\"\n [src]=\"workspaceLogoSafe\"\n [alt]=\"config?.workspaceName || 'Workspace logo'\" />\n <ng-template #defaultLogoTpl>\n <svg class=\"cqa-sb-ws-default\" width=\"36\" height=\"36\" viewBox=\"0 0 40 40\"\n fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <rect x=\"2\" y=\"1\" width=\"36\" height=\"36\" rx=\"9\" fill=\"url(#cqa-sb-ws-grad)\"/>\n <g filter=\"url(#cqa-sb-ws-shadow)\">\n <rect x=\"2\" y=\"1\" width=\"36\" height=\"36\" rx=\"9\" fill=\"white\" fill-opacity=\"0.01\" shape-rendering=\"crispEdges\"/>\n </g>\n <rect width=\"8.07969\" height=\"2.59969\" rx=\"1.29985\" transform=\"matrix(0.0555427 -0.998456 0.998194 0.0600698 10.3188 28.9912)\" fill=\"#97AFC5\"/>\n <rect width=\"8.0708\" height=\"2.60278\" rx=\"1.30139\" transform=\"matrix(-0.173269 -0.984874 0.982367 -0.186964 27.3413 29.4043)\" fill=\"#97AFC5\"/>\n <path d=\"M11.1884 23.5958C11.4549 23.7473 11.7865 23.6502 11.9291 23.3789L13.3623 20.6523C13.5049 20.381 13.4045 20.0382 13.1381 19.8867C12.2055 19.3564 11.0448 19.6964 10.5457 20.646L10.4037 20.9162C9.90451 21.8658 10.2559 23.0655 11.1884 23.5958Z\" fill=\"#C2DBF2\"/>\n <path d=\"M11.6714 22.4677C11.6714 20.1863 13.5208 18.3369 15.8022 18.3369H23.9505C26.2319 18.3369 28.0813 20.1863 28.0813 22.4677V23.7953C28.0813 28.3268 24.4078 32.0003 19.8764 32.0003C15.3449 32.0003 11.6714 28.3268 11.6714 23.7953V22.4677Z\" fill=\"#D7E7F9\"/>\n <path d=\"M28.8116 23.7315C28.5451 23.883 28.2135 23.7859 28.0709 23.5146L26.6377 20.7881C26.4951 20.5167 26.5955 20.174 26.8619 20.0225C27.7945 19.4922 28.9552 19.8321 29.4543 20.7817L29.5963 21.0519C30.0955 22.0015 29.7441 23.2012 28.8116 23.7315Z\" fill=\"#C2DBF2\"/>\n <path d=\"M26.3774 19.1758C26.3774 19.8026 23.4762 20.3107 19.8974 20.3107C16.3186 20.3107 13.4175 19.8026 13.4175 19.1758C13.4175 18.5491 16.3186 18.041 19.8974 18.041C23.4762 18.041 26.3774 18.5491 26.3774 19.1758Z\" fill=\"#C2DBF2\"/>\n <path d=\"M21.7507 26.7785L21.6221 26.6448C22.1471 25.7868 22.0506 24.6335 21.3329 23.8869C20.5026 23.0234 19.1473 23.0234 18.317 23.8869C17.4868 24.7505 17.4868 26.1601 18.317 27.0236C19.0348 27.7702 20.1437 27.8705 20.9686 27.3245L21.0972 27.4582L21.2686 27.6365C21.4507 27.8259 21.7453 27.8259 21.9221 27.6365C22.1042 27.4471 22.1042 27.1406 21.9221 26.9568L21.7507 26.7785ZM18.9706 26.3439C18.4992 25.8536 18.4992 25.0569 18.9706 24.5722C19.4419 24.0819 20.208 24.0819 20.674 24.5722C21.0275 24.9399 21.1132 25.4804 20.9365 25.9372C20.8775 26.0876 20.7918 26.2269 20.674 26.3439C20.5561 26.4665 20.4222 26.5556 20.2829 26.6169C19.8491 26.8008 19.3241 26.7116 18.9706 26.3439Z\" fill=\"#6366F1\"/>\n <rect width=\"17.4575\" height=\"10.8035\" rx=\"5.40176\" transform=\"matrix(0.999918 0.0128129 -0.0118443 0.99993 11.1401 6.9248)\" fill=\"#D7E7F9\"/>\n <path d=\"M11.9068 9.74961C12.2603 9.75414 12.5435 10.0444 12.5393 10.3979L12.4926 14.3376C12.4884 14.6911 12.1985 14.974 11.845 14.9694C10.6078 14.9536 9.61668 13.9377 9.63133 12.7005L9.64009 11.9611C9.65475 10.7239 10.6696 9.73376 11.9068 9.74961Z\" fill=\"#C2DBF2\"/>\n <path d=\"M27.7011 15.1723C27.3476 15.1677 27.0644 14.8775 27.0686 14.524L27.1153 10.5843C27.1195 10.2308 27.4094 9.94792 27.7629 9.95245C29.0001 9.9683 29.9912 10.9841 29.9766 12.2214L29.9678 12.9607C29.9532 14.198 28.9383 15.1881 27.7011 15.1723Z\" fill=\"#C2DBF2\"/>\n <rect width=\"13.0931\" height=\"6.80894\" rx=\"3.40447\" transform=\"matrix(0.999918 0.0128129 -0.0118443 0.99993 13.2988 8.9502)\" fill=\"#2F445B\"/>\n <ellipse cx=\"0.872874\" cy=\"0.907858\" rx=\"0.872874\" ry=\"0.907858\" transform=\"matrix(0.999918 0.0128129 -0.0118443 0.99993 22.2153 11.5605)\" fill=\"#6366F1\"/>\n <ellipse cx=\"0.872874\" cy=\"0.907858\" rx=\"0.872874\" ry=\"0.907858\" transform=\"matrix(0.999918 0.0128129 -0.0118443 0.99993 15.6255 11.4766)\" fill=\"#6366F1\"/>\n <path d=\"M16.9047 6.66572C16.9091 6.29805 17.2106 6.00382 17.5783 6.00853L22.1819 6.06752C22.5496 6.07223 22.8441 6.3741 22.8398 6.74177C22.8245 8.02859 21.769 9.05841 20.4822 9.04192L19.2071 9.02558C17.9203 9.00909 16.8895 7.95254 16.9047 6.66572Z\" fill=\"#C2DBF2\"/>\n <rect x=\"2\" y=\"1\" width=\"36\" height=\"36\" rx=\"9\" fill=\"url(#cqa-sb-ws-gloss)\"/>\n <defs>\n <filter id=\"cqa-sb-ws-shadow\" x=\"0\" y=\"0\" width=\"40\" height=\"40\" filterUnits=\"userSpaceOnUse\" color-interpolation-filters=\"sRGB\">\n <feFlood flood-opacity=\"0\" result=\"BackgroundImageFix\"/>\n <feColorMatrix in=\"SourceAlpha\" type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0\" result=\"hardAlpha\"/>\n <feOffset dy=\"1\"/>\n <feGaussianBlur stdDeviation=\"1\"/>\n <feComposite in2=\"hardAlpha\" operator=\"out\"/>\n <feColorMatrix type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.12 0\"/>\n <feBlend mode=\"normal\" in2=\"BackgroundImageFix\" result=\"effect1_dropShadow\"/>\n <feColorMatrix in=\"SourceAlpha\" type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0\" result=\"hardAlpha\"/>\n <feMorphology radius=\"1\" operator=\"erode\" in=\"SourceAlpha\" result=\"effect2_innerShadow\"/>\n <feOffset/>\n <feComposite in2=\"hardAlpha\" operator=\"arithmetic\" k2=\"-1\" k3=\"1\"/>\n <feColorMatrix type=\"matrix\" values=\"0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.4 0\"/>\n <feBlend mode=\"normal\" in2=\"effect1_dropShadow\" result=\"effect2_innerShadow\"/>\n </filter>\n <linearGradient id=\"cqa-sb-ws-grad\" x1=\"2\" y1=\"1\" x2=\"38\" y2=\"37\" gradientUnits=\"userSpaceOnUse\">\n <stop stop-color=\"#CCE1F4\"/>\n <stop offset=\"1\" stop-color=\"#D7E7F9\"/>\n </linearGradient>\n <linearGradient id=\"cqa-sb-ws-gloss\" x1=\"20\" y1=\"1\" x2=\"20\" y2=\"37\" gradientUnits=\"userSpaceOnUse\">\n <stop stop-color=\"white\" stop-opacity=\"0.5\"/>\n <stop offset=\"0.5\" stop-color=\"white\" stop-opacity=\"0\"/>\n </linearGradient>\n </defs>\n </svg>\n </ng-template>\n <span *ngIf=\"config?.workspaceStatus === 'live'\" class=\"cqa-sb-ws-status\"></span>\n </span>\n <span class=\"cqa-sb-ws-info\">\n <span class=\"cqa-sb-ws-name-row\">\n <span class=\"cqa-sb-ws-name\">{{ config?.workspaceName || 'Workspace' }}</span>\n </span>\n </span>\n </span>\n <span class=\"cqa-sb-ws-switch\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 14 14\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"1.17\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\n width=\"14\" height=\"14\">\n <polyline points=\"3,9 7,12 11,9\"/>\n <polyline points=\"3,5 7,2 11,5\"/>\n </svg>\n </span>\n </button>\n\n <button\n *ngIf=\"isPinned || config?.showSidebarPin !== false\"\n class=\"cqa-sb-pin-or-close\"\n type=\"button\"\n (click)=\"isPinned ? closeSidebar() : pinSidebar()\"\n [matTooltip]=\"isPinned ? 'Close sidebar' : 'Pin sidebar'\"\n [matTooltipPosition]=\"isPinned ? 'right' : 'left'\"\n [attr.aria-label]=\"isPinned ? 'Close sidebar' : 'Pin sidebar'\">\n <svg\n *ngIf=\"isPinned\"\n viewBox=\"0 0 18 18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.35\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" width=\"18\" height=\"18\">\n <rect x=\"1.5\" y=\"1.5\" width=\"15\" height=\"15\" rx=\"2.5\"/>\n <line x1=\"6.5\" y1=\"1.5\" x2=\"6.5\" y2=\"16.5\"/>\n <polyline points=\"10.5,12 8.5,9 10.5,6\"/>\n </svg>\n <svg\n *ngIf=\"!isPinned\"\n viewBox=\"0 0 18 18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.35\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" width=\"18\" height=\"18\">\n <path d=\"M9 3v4M7 3h4v4l2 3H5l2-3V3z\"/>\n <line x1=\"9\" y1=\"10\" x2=\"9\" y2=\"15\"/>\n </svg>\n </button>\n </ng-container>\n </div>\n\n <!-- ===== 2. Search ===== -->\n <div *ngIf=\"config?.showSearch !== false\" class=\"cqa-sb-search-wrap\">\n <button class=\"cqa-sb-search\" type=\"button\"\n [matTooltip]=\"!isExpanded ? 'Search' : ''\" matTooltipPosition=\"right\"\n (click)=\"searchClick.emit()\">\n <svg class=\"cqa-sb-search-icon\" viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"1.33\" stroke-linecap=\"round\" stroke-linejoin=\"round\" width=\"16\" height=\"16\">\n <circle cx=\"7\" cy=\"7\" r=\"4.5\"/>\n <line x1=\"10.5\" y1=\"10.5\" x2=\"13.5\" y2=\"13.5\"/>\n </svg>\n <span class=\"cqa-sb-search-text\" [class.cqa-sb-search-text--visible]=\"isExpanded\">\n {{ config?.searchPlaceholder || 'Search Anything...' }}\n </span>\n <span\n *ngIf=\"config?.showSearchShortcut !== false && isExpanded\"\n class=\"cqa-sb-search-kbd\">\u2318K</span>\n </button>\n </div>\n\n <!-- ===== 3. CTA ===== -->\n <div *ngIf=\"config?.showCta !== false\" class=\"cqa-sb-cta-wrap\">\n <button class=\"cqa-sb-cta\" type=\"button\"\n [matTooltip]=\"!isExpanded ? (config?.ctaLabel || 'New') : ''\" matTooltipPosition=\"right\"\n (click)=\"ctaClick.emit()\">\n <svg viewBox=\"0 0 18 18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.6\"\n stroke-linecap=\"round\" width=\"18\" height=\"18\">\n <line x1=\"9\" y1=\"3.75\" x2=\"9\" y2=\"14.25\"/>\n <line x1=\"3.75\" y1=\"9\" x2=\"14.25\" y2=\"9\"/>\n </svg>\n <span class=\"cqa-sb-cta-text\" [class.cqa-sb-cta-text--visible]=\"isExpanded\">\n {{ config?.ctaLabel || 'New Test Cases' }}\n </span>\n </button>\n </div>\n\n <!-- ===== 4. Nav menu ===== -->\n <cqa-nav-menu\n [items]=\"navItems\"\n [activeId]=\"activeNavId\"\n [isExpanded]=\"isExpanded\"\n [openParents]=\"openParents\"\n (itemClick)=\"onNavItemClick($event)\">\n </cqa-nav-menu>\n\n <!-- ===== 5. Utility bar ===== -->\n <div class=\"cqa-sb-utility\" [class.cqa-sb-utility--expanded]=\"isExpanded\">\n <!-- Expanded: 2 wide tiles (Help & docs + Live chat) -->\n <ng-container *ngIf=\"isExpanded\">\n <button\n *ngIf=\"config?.showHelpDocs !== false\"\n class=\"cqa-sb-util-tile\"\n type=\"button\"\n (click)=\"helpDocsClick.emit()\">\n <svg viewBox=\"0 0 18 18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.35\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" width=\"18\" height=\"18\">\n <circle cx=\"9\" cy=\"9\" r=\"7.25\"/>\n <path d=\"M6.85 7a2.15 2.15 0 0 1 4.18.75c0 1.4-2.15 1.8-2.15 3.05\"/>\n <line x1=\"9\" y1=\"13.4\" x2=\"9.01\" y2=\"13.4\"/>\n </svg>\n <span class=\"cqa-sb-util-tile-label\">{{ config?.helpDocsLabel || 'Help & docs' }}</span>\n </button>\n\n <button\n *ngIf=\"config?.showLiveChat !== false\"\n class=\"cqa-sb-util-tile\"\n type=\"button\"\n (click)=\"liveChatClick.emit()\">\n <svg viewBox=\"0 0 18 18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.35\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" width=\"18\" height=\"18\">\n <path d=\"M16 2H2a1 1 0 0 0-1 1v9a1 1 0 0 0 1 1h3v3l4.5-3H16a1 1 0 0 0 1-1V3a1 1 0 0 0-1-1z\"/>\n </svg>\n <span class=\"cqa-sb-util-tile-label\">Live chat</span>\n </button>\n </ng-container>\n\n <!-- Collapsed: help + live chat only (notifications / speaker are not shown on the rail) -->\n <ng-container *ngIf=\"!isExpanded\">\n <button\n *ngIf=\"config?.showHelpDocs !== false\"\n class=\"cqa-sb-util-compact\"\n type=\"button\"\n [matTooltip]=\"config?.helpDocsLabel || 'Help & docs'\" matTooltipPosition=\"right\"\n (click)=\"helpDocsClick.emit()\">\n <svg viewBox=\"0 0 18 18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.35\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" width=\"18\" height=\"18\">\n <circle cx=\"9\" cy=\"9\" r=\"7.25\"/>\n <path d=\"M6.85 7a2.15 2.15 0 0 1 4.18.75c0 1.4-2.15 1.8-2.15 3.05\"/>\n <line x1=\"9\" y1=\"13.4\" x2=\"9.01\" y2=\"13.4\"/>\n </svg>\n </button>\n\n <button\n *ngIf=\"config?.showLiveChat !== false\"\n class=\"cqa-sb-util-compact\"\n type=\"button\"\n matTooltip=\"Live chat\" matTooltipPosition=\"right\"\n (click)=\"liveChatClick.emit()\">\n <svg viewBox=\"0 0 18 18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.35\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" width=\"18\" height=\"18\">\n <path d=\"M16 2H2a1 1 0 0 0-1 1v9a1 1 0 0 0 1 1h3v3l4.5-3H16a1 1 0 0 0 1-1V3a1 1 0 0 0-1-1z\"/>\n </svg>\n </button>\n </ng-container>\n </div>\n\n <!-- ===== 6. Profile card ===== -->\n <div class=\"cqa-sb-profile\" #profileAnchor>\n <button class=\"cqa-sb-profile-main\" type=\"button\"\n [matTooltip]=\"!isExpanded ? (config?.userName || profileUser?.name || '') : ''\" matTooltipPosition=\"right\"\n [attr.aria-haspopup]=\"(profileUser && profileMenuEntries?.length) ? 'menu' : null\"\n [attr.aria-expanded]=\"(profileUser && profileMenuEntries?.length) ? isProfileMenuOpen : null\"\n (click)=\"onProfileClick()\">\n <div class=\"cqa-sb-profile-avatar\">{{ config?.userInitials || '?' }}</div>\n <div class=\"cqa-sb-profile-info\" [class.cqa-sb-profile-info--visible]=\"isExpanded\">\n <span class=\"cqa-sb-profile-name\">{{ config?.userName }}</span>\n <span *ngIf=\"config?.userRole\" class=\"cqa-sb-profile-role\">{{ config.userRole }}</span>\n </div>\n </button>\n <button *ngIf=\"isExpanded\" class=\"cqa-sb-profile-logout\" type=\"button\"\n aria-label=\"Logout\" (click)=\"logoutClick.emit()\">\n <svg viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.2\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" width=\"16\" height=\"16\">\n <path d=\"M6 14H3a1 1 0 0 1-1-1V3a1 1 0 0 1 1-1h3\"/>\n <polyline points=\"11,11 14,8 11,5\"/>\n <line x1=\"14\" y1=\"8\" x2=\"6\" y2=\"8\"/>\n </svg>\n </button>\n </div>\n\n <cqa-profile-menu\n *ngIf=\"isProfileMenuOpen && profileUser && profileMenuEntries?.length\"\n [user]=\"profileUser\"\n [entries]=\"profileMenuEntries\"\n [anchor]=\"profileAnchorRef?.nativeElement || null\"\n (itemClick)=\"onProfileMenuItemClick($event)\"\n (dismissed)=\"onProfileMenuDismissed()\">\n </cqa-profile-menu>\n\n </aside>\n</div>\n", styles: ["*{box-sizing:border-box}:host{display:flex;flex-direction:column;flex:1;align-self:stretch;min-height:0;max-height:100%;height:100%;flex-shrink:0}.cqa-sb-root{display:flex;flex-direction:column;flex:1 1 auto;min-height:0;max-height:100%;width:100%}.cqa-sb{background:#3f43ee;color:#fff;flex:1 1 auto;min-height:0;max-height:100%;height:100%;display:flex;flex-direction:column;flex-shrink:0;width:60px;transition:width .24s cubic-bezier(.32,.72,0,1);position:relative;z-index:50;overflow-x:visible;overflow-y:hidden}.cqa-sb--expanded{width:264px;overflow-x:hidden}.cqa-sb>cqa-nav-menu{flex:1 1 0;min-height:0;min-width:0;display:flex;flex-direction:column}.cqa-sb-header{padding:10px;position:relative;border-bottom:1px solid rgba(255,255,255,.08);min-height:51px;display:flex;align-items:center;justify-content:center;flex-shrink:0}.cqa-sb-header--expanded{justify-content:flex-start;padding:12px 40px 10px 12px;height:71px;max-height:71px;gap:0}.cqa-sb-burger{width:28px;height:28px;border-radius:7px;background:#d8d9fc2e;display:flex;align-items:center;justify-content:center;border:none;cursor:pointer;color:#d8d9fc;flex-shrink:0;transition:background .15s,color .15s}.cqa-sb-burger:hover{background:#d8d9fc47;color:#fff}.cqa-sb-pin-or-close{position:absolute;right:10px;top:50%;transform:translateY(calc(-50% + 1px));width:28px;height:28px;border-radius:7px;display:flex;align-items:center;justify-content:center;background:transparent;border:none;cursor:pointer;color:#d8d9fc;flex-shrink:0;transition:background .15s,color .15s}.cqa-sb-pin-or-close:hover{background:#ffffff1a;color:#fff}.cqa-sb-ws{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:6px 14px 6px 6px;border-radius:10px;line-height:1;height:48px;transition:background .12s;flex:1;min-width:0;text-align:left;background:transparent;border:none;cursor:pointer;color:#fff;overflow:hidden}.cqa-sb-ws:hover{background:#ffffff14}.cqa-sb-ws-main{display:flex;align-items:center;gap:10px;min-width:0}.cqa-sb-ws-avatar{width:36px;height:36px;border-radius:9px;display:flex;align-items:center;justify-content:center;flex-shrink:0;position:relative;overflow:hidden}.cqa-sb-ws-logo{position:relative;z-index:1;width:100%;height:100%;object-fit:contain;display:block}.cqa-sb-ws-default{position:relative;z-index:1;display:block;pointer-events:none}.cqa-sb-ws-status{position:absolute;bottom:-3px;right:-3px;width:12px;height:12px;background:#0dbd7d;border-radius:50%;border:2.5px solid #3f43ee;box-shadow:0 0 6px #0dbd7d}.cqa-sb-ws-info{flex:1;min-width:0;overflow:hidden}.cqa-sb-ws-name-row{display:flex;align-items:center;gap:6px}.cqa-sb-ws-name{font-weight:600;font-size:14px;line-height:16.8px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:#fff}.cqa-sb-ws-badge{background:#0dbd7d2e;color:#5ed3a8;font-size:9.5px;font-weight:700;padding:1px 6px 1px 4px;border-radius:4px;display:inline-flex;align-items:center;gap:3px;flex-shrink:0;text-transform:uppercase;letter-spacing:.04em}.cqa-sb-ws-badge:before{content:\"\";width:4px;height:4px;background:#0dbd7d;border-radius:50%;box-shadow:0 0 6px #0dbd7d}.cqa-sb-ws-switch{color:#ffffff8c;flex-shrink:0;padding:4px 0 7px;border-radius:6px;display:flex;align-items:center}.cqa-sb-search-wrap{padding:8px 12px;flex-shrink:0}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-search-wrap{padding:8px 10px 6px;display:flex;justify-content:center}.cqa-sb-search{background:#ffffff0d;border:1px solid rgba(255,255,255,.1);border-radius:8px;height:38px;padding:0 12px;font-size:12px;line-height:1;letter-spacing:-.31px;color:#ffffff80;display:flex;align-items:center;gap:8px;width:100%;cursor:pointer;transition:all .15s;overflow:hidden;font-family:inherit}.cqa-sb-search:hover{background:#ffffff14;color:#ffffffbf;border-color:#ffffff29}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-search{padding:0;width:40px;max-width:40px;height:40px;min-height:40px;margin:0 auto;justify-content:center;align-items:center;gap:0;background:transparent;border-color:#d8d9fc;border-radius:9px}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-search .cqa-sb-search-text,.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-search .cqa-sb-search-kbd{flex:0 0 0;width:0;min-width:0;height:0;margin:0;padding:0;overflow:hidden;opacity:0;border:0;pointer-events:none}.cqa-sb-search-icon{flex-shrink:0;width:14px;height:14px}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-search-icon{width:16px;height:16px}.cqa-sb-search-text{flex:1;text-align:left;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif;font-weight:400;font-size:12px;line-height:1;letter-spacing:-.31px;color:#ffffff80;opacity:0;transition:opacity .16s 80ms}.cqa-sb-search-text--visible{opacity:1}.cqa-sb-search-kbd{display:inline-flex;align-items:center;justify-content:center;height:16px;font-size:10.5px;line-height:1;letter-spacing:normal;text-align:center;background:#ffffff26;padding:2px 6px;border-radius:4px;color:#ffffffd9;font-family:Menlo,ui-monospace,monospace;flex-shrink:0}.cqa-sb-cta-wrap{padding:8px 12px;flex-shrink:0}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-cta-wrap{padding:0 10px 12px;display:flex;justify-content:center}.cqa-sb-cta{background:#5256f0;color:#fbfcff;border:none;border-radius:8px;height:38px;padding:10px 24px 10px 16px;font-size:14px;font-weight:600;line-height:14px;letter-spacing:0;width:100%;display:flex;align-items:center;justify-content:center;gap:8px;cursor:pointer;transition:background .15s,transform .15s;overflow:hidden;font-family:inherit}.cqa-sb-cta:hover{background:#5b5ff2;transform:translateY(-1px)}.cqa-sb-cta:active{transform:translateY(0)}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-cta{padding:0;width:40px;height:40px;min-height:40px;margin:0 auto;position:relative;background:transparent;color:#fff}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-cta:before{content:\"\";position:absolute;inset:0;border-radius:9px;background:#b1b2f838;pointer-events:none}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-cta svg{position:relative;z-index:1;width:16px;height:16px}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-cta{box-shadow:inset 0 0 0 1px #d8d9fc38}.cqa-sb-cta-text{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif;font-weight:600;font-size:14px;line-height:1;letter-spacing:0;color:#fbfcff;opacity:0;transition:opacity .16s 80ms;position:relative;z-index:1}.cqa-sb-cta-text--visible{opacity:1}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-cta-text{display:none}.cqa-sb-utility{border-top:none;box-shadow:inset 0 1px #ffffff1a;flex-shrink:0}.cqa-sb-utility--expanded{display:flex;align-items:center;justify-content:space-between;height:68px;gap:0;padding:8px 10px}.cqa-sb-utility:not(.cqa-sb-utility--expanded){display:flex;flex-direction:column;align-items:center;justify-content:flex-start;gap:1px;padding:6px 10px}.cqa-sb-util-tile{width:110px;max-width:110px;border-radius:9px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;padding:8px 6px 6px;color:#ffffffd9;background:#ffffff0f;border:none;cursor:pointer;transition:background .12s,color .12s;font-family:inherit}.cqa-sb-util-tile:hover{background:#b1b2f838;color:#fff}.cqa-sb-util-tile-label{font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif;font-size:10.5px;font-weight:600;line-height:10.5px;letter-spacing:.1px;color:#ffffffd9;text-align:center;white-space:nowrap}.cqa-sb-util-compact{position:relative;width:36px;height:34px;border-radius:8px;display:flex;align-items:center;justify-content:center;color:#ffffffe0;background:transparent;border:none;cursor:pointer;transition:background .12s,color .12s;padding:0;flex-shrink:0}.cqa-sb-util-compact:hover{background:#ffffff14;color:#fff}.cqa-sb-util-compact-dot{position:absolute;top:6px;right:6px;width:8px;height:8px;background:#ee3f3f;border-radius:4px;border:2px solid #3f43ee;pointer-events:none}.cqa-sb-profile{border-top:1px solid rgba(255,255,255,.1);padding:12px 14px;height:62px;display:flex;align-items:center;gap:12px;background:#00000029;overflow:hidden;position:relative;width:100%;flex-shrink:0;color:#fff}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-profile{justify-content:center;padding:12px 0;height:auto;gap:0;background:#0000001f;border-top-color:#ffffff1f}.cqa-sb-profile-main{flex:1;min-width:0;display:flex;align-items:center;gap:12px;padding:0;background:transparent;border:none;border-radius:8px;cursor:pointer;color:inherit;font-family:inherit;text-align:left;transition:background .15s}.cqa-sb-profile-main:hover{background:#0000001a}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-profile-main{justify-content:center;flex:0 0 auto}.cqa-sb-profile-avatar{width:34px;height:34px;border-radius:17px;background:linear-gradient(135deg,#f472b6,#db2777);display:flex;align-items:center;justify-content:center;font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif;font-size:12px;font-weight:700;line-height:1;letter-spacing:0;color:#fff;flex-shrink:0;box-shadow:0 0 0 2px #ffffff26}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-profile-avatar{width:32px;height:32px;border-radius:16px;font-size:11.5px}.cqa-sb-profile-info{flex:1;min-width:0;overflow:hidden;opacity:0;transition:opacity .16s 80ms;display:flex;flex-direction:column;align-items:flex-start;justify-content:center;gap:4px}.cqa-sb-profile-info--visible{opacity:1}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-profile-info{display:none}.cqa-sb-profile-name{font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif;font-weight:600;font-size:12.5px;line-height:13.75px;letter-spacing:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:#fff}.cqa-sb-profile-role{display:inline-block;font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif;font-size:9px;font-weight:700;line-height:12.6px;letter-spacing:0;background:#d8d9fc38;padding:2px 7px;border-radius:999px;color:#fff;border:1px solid rgba(216,217,252,.2);white-space:nowrap;align-self:flex-start}.cqa-sb-profile-logout{color:#ffffff8c;padding:6px 6px 9px;border-radius:6px;background:transparent;border:none;cursor:pointer;flex-shrink:0;transition:background .12s,color .12s;display:flex;align-items:center;justify-content:center}.cqa-sb-profile-logout:hover{background:#ffffff1f;color:#fff}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: NavMenuComponent, selector: "cqa-nav-menu", inputs: ["items", "activeId", "isExpanded", "openParents"], outputs: ["itemClick"] }, { kind: "component", type: ProfileMenuComponent, selector: "cqa-profile-menu", inputs: ["user", "entries", "anchor", "popoverId"], outputs: ["itemClick", "dismissed"] }] });
12971
13158
  }
12972
13159
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SidebarComponent, decorators: [{
12973
13160
  type: Component,
12974
- args: [{ selector: 'cqa-sidebar', template: "<div id=\"cqa-ui-root\" style=\"display:block;height:100%\">\n <aside\n class=\"cqa-sb\"\n [class.cqa-sb--expanded]=\"isExpanded\"\n (mouseenter)=\"onAsideMouseEnter()\"\n (mouseleave)=\"onAsideMouseLeave($event)\">\n\n <!-- ===== 1. Workspace header ===== -->\n <div class=\"cqa-sb-header\" [class.cqa-sb-header--expanded]=\"isExpanded\">\n <!-- Collapsed: hamburger chip -->\n <button\n *ngIf=\"!isExpanded\"\n class=\"cqa-sb-burger\"\n (click)=\"openSidebar()\"\n type=\"button\"\n aria-label=\"Open sidebar\">\n <svg viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"1.33\" stroke-linecap=\"round\"\n width=\"16\" height=\"16\">\n <line x1=\"2\" y1=\"4\" x2=\"14\" y2=\"4\"/>\n <line x1=\"2\" y1=\"8\" x2=\"14\" y2=\"8\"/>\n <line x1=\"2\" y1=\"12\" x2=\"14\" y2=\"12\"/>\n </svg>\n </button>\n\n <!-- Expanded: workspace selector + pin (unpinned) or close (pinned) -->\n <ng-container *ngIf=\"isExpanded\">\n <button class=\"cqa-sb-ws\" type=\"button\" (click)=\"workspaceSwitchClick.emit()\">\n <span class=\"cqa-sb-ws-main\">\n <span class=\"cqa-sb-ws-avatar\">\n <img *ngIf=\"workspaceLogoSafe; else wsInitialTpl\"\n class=\"cqa-sb-ws-logo\"\n [src]=\"workspaceLogoSafe\"\n [alt]=\"config?.workspaceName || 'Workspace logo'\" />\n <ng-template #wsInitialTpl>\n <span class=\"cqa-sb-ws-initial\">{{ workspaceInitial }}</span>\n </ng-template>\n <span *ngIf=\"config?.workspaceStatus === 'live'\" class=\"cqa-sb-ws-status\"></span>\n </span>\n <span class=\"cqa-sb-ws-info\">\n <span class=\"cqa-sb-ws-name-row\">\n <span class=\"cqa-sb-ws-name\">{{ config?.workspaceName || 'Workspace' }}</span>\n </span>\n </span>\n </span>\n <span class=\"cqa-sb-ws-switch\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 14 14\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"1.17\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\n width=\"14\" height=\"14\">\n <polyline points=\"3,9 7,12 11,9\"/>\n <polyline points=\"3,5 7,2 11,5\"/>\n </svg>\n </span>\n </button>\n\n <button\n *ngIf=\"isPinned || config?.showSidebarPin !== false\"\n class=\"cqa-sb-pin-or-close\"\n type=\"button\"\n (click)=\"isPinned ? closeSidebar() : pinSidebar()\"\n [matTooltip]=\"isPinned ? 'Close sidebar' : 'Pin sidebar'\"\n [matTooltipPosition]=\"isPinned ? 'right' : 'left'\"\n [attr.aria-label]=\"isPinned ? 'Close sidebar' : 'Pin sidebar'\">\n <svg\n *ngIf=\"isPinned\"\n viewBox=\"0 0 18 18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.35\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" width=\"18\" height=\"18\">\n <rect x=\"1.5\" y=\"1.5\" width=\"15\" height=\"15\" rx=\"2.5\"/>\n <line x1=\"6.5\" y1=\"1.5\" x2=\"6.5\" y2=\"16.5\"/>\n <polyline points=\"10.5,12 8.5,9 10.5,6\"/>\n </svg>\n <svg\n *ngIf=\"!isPinned\"\n viewBox=\"0 0 18 18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.35\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" width=\"18\" height=\"18\">\n <path d=\"M9 3v4M7 3h4v4l2 3H5l2-3V3z\"/>\n <line x1=\"9\" y1=\"10\" x2=\"9\" y2=\"15\"/>\n </svg>\n </button>\n </ng-container>\n </div>\n\n <!-- ===== 2. Search ===== -->\n <div *ngIf=\"config?.showSearch !== false\" class=\"cqa-sb-search-wrap\">\n <button class=\"cqa-sb-search\" type=\"button\"\n [matTooltip]=\"!isExpanded ? 'Search' : ''\" matTooltipPosition=\"right\"\n (click)=\"searchClick.emit()\">\n <svg class=\"cqa-sb-search-icon\" viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"1.33\" stroke-linecap=\"round\" stroke-linejoin=\"round\" width=\"16\" height=\"16\">\n <circle cx=\"7\" cy=\"7\" r=\"4.5\"/>\n <line x1=\"10.5\" y1=\"10.5\" x2=\"13.5\" y2=\"13.5\"/>\n </svg>\n <span class=\"cqa-sb-search-text\" [class.cqa-sb-search-text--visible]=\"isExpanded\">\n {{ config?.searchPlaceholder || 'Search Anything...' }}\n </span>\n <span\n *ngIf=\"config?.showSearchShortcut !== false && isExpanded\"\n class=\"cqa-sb-search-kbd\">\u2318K</span>\n </button>\n </div>\n\n <!-- ===== 3. CTA ===== -->\n <div *ngIf=\"config?.showCta !== false\" class=\"cqa-sb-cta-wrap\">\n <button class=\"cqa-sb-cta\" type=\"button\"\n [matTooltip]=\"!isExpanded ? (config?.ctaLabel || 'New') : ''\" matTooltipPosition=\"right\"\n (click)=\"ctaClick.emit()\">\n <svg viewBox=\"0 0 18 18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.6\"\n stroke-linecap=\"round\" width=\"18\" height=\"18\">\n <line x1=\"9\" y1=\"3\" x2=\"9\" y2=\"15\"/>\n <line x1=\"3\" y1=\"9\" x2=\"15\" y2=\"9\"/>\n </svg>\n <span class=\"cqa-sb-cta-text\" [class.cqa-sb-cta-text--visible]=\"isExpanded\">\n {{ config?.ctaLabel || 'New Test Cases' }}\n </span>\n </button>\n </div>\n\n <!-- ===== 4. Nav menu ===== -->\n <cqa-nav-menu\n [items]=\"navItems\"\n [activeId]=\"activeNavId\"\n [isExpanded]=\"isExpanded\"\n [openParents]=\"openParents\"\n (itemClick)=\"onNavItemClick($event)\">\n </cqa-nav-menu>\n\n <!-- ===== 5. Utility bar ===== -->\n <div class=\"cqa-sb-utility\" [class.cqa-sb-utility--expanded]=\"isExpanded\">\n <!-- Expanded: 2 wide tiles (Help & docs + Live chat) -->\n <ng-container *ngIf=\"isExpanded\">\n <button\n *ngIf=\"config?.showHelpDocs !== false\"\n class=\"cqa-sb-util-tile\"\n type=\"button\"\n (click)=\"helpDocsClick.emit()\">\n <svg viewBox=\"0 0 18 18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.35\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" width=\"18\" height=\"18\">\n <circle cx=\"9\" cy=\"9\" r=\"7.25\"/>\n <path d=\"M6.85 7a2.15 2.15 0 0 1 4.18.75c0 1.4-2.15 1.8-2.15 3.05\"/>\n <line x1=\"9\" y1=\"13.4\" x2=\"9.01\" y2=\"13.4\"/>\n </svg>\n <span class=\"cqa-sb-util-tile-label\">{{ config?.helpDocsLabel || 'Help & docs' }}</span>\n </button>\n\n <button\n *ngIf=\"config?.showLiveChat !== false\"\n class=\"cqa-sb-util-tile\"\n type=\"button\"\n (click)=\"liveChatClick.emit()\">\n <svg viewBox=\"0 0 18 18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.35\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" width=\"18\" height=\"18\">\n <path d=\"M16 2H2a1 1 0 0 0-1 1v9a1 1 0 0 0 1 1h3v3l4.5-3H16a1 1 0 0 0 1-1V3a1 1 0 0 0-1-1z\"/>\n </svg>\n <span class=\"cqa-sb-util-tile-label\">Live chat</span>\n </button>\n </ng-container>\n\n <!-- Collapsed: help + live chat only (notifications / speaker are not shown on the rail) -->\n <ng-container *ngIf=\"!isExpanded\">\n <button\n *ngIf=\"config?.showHelpDocs !== false\"\n class=\"cqa-sb-util-compact\"\n type=\"button\"\n [matTooltip]=\"config?.helpDocsLabel || 'Help & docs'\" matTooltipPosition=\"right\"\n (click)=\"helpDocsClick.emit()\">\n <svg viewBox=\"0 0 18 18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.35\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" width=\"18\" height=\"18\">\n <circle cx=\"9\" cy=\"9\" r=\"7.25\"/>\n <path d=\"M6.85 7a2.15 2.15 0 0 1 4.18.75c0 1.4-2.15 1.8-2.15 3.05\"/>\n <line x1=\"9\" y1=\"13.4\" x2=\"9.01\" y2=\"13.4\"/>\n </svg>\n </button>\n\n <button\n *ngIf=\"config?.showLiveChat !== false\"\n class=\"cqa-sb-util-compact\"\n type=\"button\"\n matTooltip=\"Live chat\" matTooltipPosition=\"right\"\n (click)=\"liveChatClick.emit()\">\n <svg viewBox=\"0 0 18 18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.35\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" width=\"18\" height=\"18\">\n <path d=\"M16 2H2a1 1 0 0 0-1 1v9a1 1 0 0 0 1 1h3v3l4.5-3H16a1 1 0 0 0 1-1V3a1 1 0 0 0-1-1z\"/>\n </svg>\n </button>\n </ng-container>\n </div>\n\n <!-- ===== 6. Profile card ===== -->\n <button class=\"cqa-sb-profile\" type=\"button\"\n [matTooltip]=\"!isExpanded ? (config?.userName || '') : ''\" matTooltipPosition=\"right\"\n (click)=\"logoutClick.emit()\">\n <div class=\"cqa-sb-profile-avatar\">{{ config?.userInitials || '?' }}</div>\n <div class=\"cqa-sb-profile-info\" [class.cqa-sb-profile-info--visible]=\"isExpanded\">\n <span class=\"cqa-sb-profile-name\">{{ config?.userName }}</span>\n <span *ngIf=\"config?.userRole\" class=\"cqa-sb-profile-role\">{{ config.userRole }}</span>\n </div>\n <span *ngIf=\"isExpanded\" class=\"cqa-sb-profile-logout\" aria-label=\"Logout\">\n <svg viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.2\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" width=\"16\" height=\"16\">\n <path d=\"M6 14H3a1 1 0 0 1-1-1V3a1 1 0 0 1 1-1h3\"/>\n <polyline points=\"11,11 14,8 11,5\"/>\n <line x1=\"14\" y1=\"8\" x2=\"6\" y2=\"8\"/>\n </svg>\n </span>\n </button>\n\n </aside>\n</div>\n", styles: [":host{display:flex;height:100%;flex-shrink:0}.cqa-sb{background:#3f43ee;color:#fff;height:100%;display:flex;flex-direction:column;flex-shrink:0;width:60px;transition:width .24s cubic-bezier(.32,.72,0,1);position:relative;z-index:50;overflow-x:visible;overflow-y:hidden}.cqa-sb--expanded{width:264px;overflow-x:hidden}.cqa-sb-header{padding:10px;position:relative;border-bottom:1px solid rgba(255,255,255,.08);min-height:51px;display:flex;align-items:center;justify-content:center;flex-shrink:0}.cqa-sb-header--expanded{justify-content:flex-start;padding:12px 40px 11px 12px;min-height:71px;gap:0}.cqa-sb-burger{width:28px;height:28px;border-radius:7px;background:#d8d9fc2e;display:flex;align-items:center;justify-content:center;border:none;cursor:pointer;color:#d8d9fc;flex-shrink:0;transition:background .15s,color .15s}.cqa-sb-burger:hover{background:#d8d9fc47;color:#fff}.cqa-sb-pin-or-close{position:absolute;right:10px;top:50%;transform:translateY(calc(-50% + 1px));width:28px;height:28px;border-radius:7px;display:flex;align-items:center;justify-content:center;background:transparent;border:none;cursor:pointer;color:#d8d9fc;flex-shrink:0;transition:background .15s,color .15s}.cqa-sb-pin-or-close:hover{background:#ffffff1a;color:#fff}.cqa-sb-ws{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:6px 14px 6px 6px;border-radius:10px;transition:background .12s;flex:1;min-width:0;text-align:left;background:transparent;border:none;cursor:pointer;color:#fff;overflow:hidden}.cqa-sb-ws:hover{background:#ffffff14}.cqa-sb-ws-main{display:flex;align-items:center;gap:10px;min-width:0}.cqa-sb-ws-avatar{width:36px;height:36px;border-radius:9px;background:linear-gradient(135deg,#cce1f4,#d7e7f9);display:flex;align-items:center;justify-content:center;flex-shrink:0;position:relative;box-shadow:0 1px 2px #0000001f,inset 0 0 0 1px #fff6;overflow:hidden}.cqa-sb-ws-avatar:after{content:\"\";position:absolute;inset:0;border-radius:inherit;background:linear-gradient(to bottom,#ffffff80,#fff0 50%);pointer-events:none}.cqa-sb-ws-logo{position:relative;z-index:1;width:22px;height:26px;object-fit:contain;display:block}.cqa-sb-ws-initial{position:relative;z-index:1;color:#1216cc;font-weight:800;font-size:15px}.cqa-sb-ws-status{position:absolute;bottom:-3px;right:-3px;width:12px;height:12px;background:#0dbd7d;border-radius:50%;border:2.5px solid #3f43ee;box-shadow:0 0 6px #0dbd7d}.cqa-sb-ws-info{flex:1;min-width:0;overflow:hidden}.cqa-sb-ws-name-row{display:flex;align-items:center;gap:6px}.cqa-sb-ws-name{font-weight:600;font-size:14px;line-height:16.8px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:#fff}.cqa-sb-ws-badge{background:#0dbd7d2e;color:#5ed3a8;font-size:9.5px;font-weight:700;padding:1px 6px 1px 4px;border-radius:4px;display:inline-flex;align-items:center;gap:3px;flex-shrink:0;text-transform:uppercase;letter-spacing:.04em}.cqa-sb-ws-badge:before{content:\"\";width:4px;height:4px;background:#0dbd7d;border-radius:50%;box-shadow:0 0 6px #0dbd7d}.cqa-sb-ws-switch{color:#ffffff8c;flex-shrink:0;padding:4px 0 7px;display:flex;align-items:center}.cqa-sb-search-wrap{padding:8px 12px;flex-shrink:0}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-search-wrap{padding:8px 10px 6px;display:flex;justify-content:center}.cqa-sb-search{background:#ffffff0d;border:1px solid rgba(255,255,255,.1);border-radius:8px;min-height:38px;padding:0 13px;font-size:12px;letter-spacing:-.02em;color:#ffffff80;display:flex;align-items:center;gap:8px;width:100%;cursor:pointer;transition:all .15s;overflow:hidden;font-family:inherit}.cqa-sb-search:hover{background:#ffffff14;color:#ffffffbf;border-color:#ffffff29}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-search{padding:0;width:40px;max-width:40px;height:40px;min-height:40px;margin:0 auto;justify-content:center;align-items:center;gap:0;background:transparent;border-color:#d8d9fc;border-radius:9px}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-search .cqa-sb-search-text,.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-search .cqa-sb-search-kbd{flex:0 0 0;width:0;min-width:0;height:0;margin:0;padding:0;overflow:hidden;opacity:0;border:0;pointer-events:none}.cqa-sb-search-icon{flex-shrink:0;width:14px;height:14px}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-search-icon{width:16px;height:16px}.cqa-sb-search-text{flex:1;text-align:left;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;opacity:0;transition:opacity .16s 80ms}.cqa-sb-search-text--visible{opacity:1}.cqa-sb-search-kbd{font-size:10.5px;background:#ffffff26;padding:2px 6px;border-radius:4px;color:#ffffffd9;font-family:ui-monospace,monospace;flex-shrink:0;opacity:0;transition:opacity .16s 80ms}.cqa-sb-search-kbd--visible{opacity:1}.cqa-sb-cta-wrap{padding:0 12px 12px;flex-shrink:0}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-cta-wrap{padding:0 10px 12px;display:flex;justify-content:center}.cqa-sb-cta{background:#5256f0;color:#fbfcff;border:none;border-radius:8px;padding:10px 24px 10px 16px;font-size:14px;font-weight:600;line-height:14px;letter-spacing:0;width:100%;display:flex;align-items:center;justify-content:center;gap:8px;cursor:pointer;transition:background .15s,transform .15s;overflow:hidden;font-family:inherit}.cqa-sb-cta:hover{background:#5b5ff2;transform:translateY(-1px)}.cqa-sb-cta:active{transform:translateY(0)}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-cta{padding:0;width:40px;height:40px;min-height:40px;margin:0 auto;position:relative;background:transparent;color:#fff}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-cta:before{content:\"\";position:absolute;inset:0;border-radius:9px;background:#b1b2f838;pointer-events:none}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-cta svg{position:relative;z-index:1;width:16px;height:16px}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-cta{box-shadow:inset 0 0 0 1px #d8d9fc38}.cqa-sb-cta-text{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;opacity:0;transition:opacity .16s 80ms;position:relative;z-index:1}.cqa-sb-cta-text--visible{opacity:1}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-cta-text{display:none}.cqa-sb-utility{border-top:none;box-shadow:inset 0 1px #ffffff1a;flex-shrink:0}.cqa-sb-utility--expanded{display:flex;align-items:center;justify-content:space-between;height:68px;gap:0;padding:9px 10px 8px}.cqa-sb-utility:not(.cqa-sb-utility--expanded){display:flex;flex-direction:column;align-items:center;justify-content:flex-start;gap:1px;padding:6px 10px}.cqa-sb-util-tile{width:110px;max-width:110px;border-radius:9px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;padding:8px 6px 6px;color:#ffffffd9;background:#ffffff0f;border:none;cursor:pointer;transition:background .12s,color .12s;font-family:inherit}.cqa-sb-util-tile:hover{background:#b1b2f838;color:#fff}.cqa-sb-util-tile-label{font-size:10.5px;font-weight:600;line-height:10.5px;letter-spacing:.105px;text-align:center;white-space:nowrap}.cqa-sb-util-compact{position:relative;width:36px;height:34px;border-radius:8px;display:flex;align-items:center;justify-content:center;color:#ffffffe0;background:transparent;border:none;cursor:pointer;transition:background .12s,color .12s;padding:0;flex-shrink:0}.cqa-sb-util-compact:hover{background:#ffffff14;color:#fff}.cqa-sb-util-compact-dot{position:absolute;top:6px;right:6px;width:8px;height:8px;background:#ee3f3f;border-radius:4px;border:2px solid #3f43ee;pointer-events:none}.cqa-sb-profile{border-top:1px solid rgba(255,255,255,.1);padding:13px 14px 12px;display:flex;align-items:center;gap:12px;background:#00000029;transition:background .15s;overflow:hidden;position:relative;width:100%;flex-shrink:0;border-left:none;border-right:none;border-bottom:none;cursor:pointer;color:#fff;font-family:inherit}.cqa-sb-profile:hover{background:#00000042}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-profile{justify-content:center;padding:12px 0;gap:0;background:#0000001f;border-top-color:#ffffff1f}.cqa-sb-profile-avatar{width:34px;height:34px;border-radius:17px;background:linear-gradient(135deg,#f472b6,#db2777);display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:700;flex-shrink:0;box-shadow:0 0 0 2px #ffffff26}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-profile-avatar{width:32px;height:32px;border-radius:16px;font-size:11.5px}.cqa-sb-profile-info{flex:1;min-width:0;overflow:hidden;opacity:0;transition:opacity .16s 80ms;display:flex;flex-direction:column;align-items:flex-start;justify-content:center;gap:4px}.cqa-sb-profile-info--visible{opacity:1}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-profile-info{display:none}.cqa-sb-profile-name{font-weight:600;font-size:12.5px;line-height:13.75px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:#fff}.cqa-sb-profile-role{display:inline-block;font-size:9px;font-weight:700;background:#d8d9fc38;padding:3px 8px;border-radius:999px;line-height:12.6px;color:#fff;border:1px solid rgba(216,217,252,.2);white-space:nowrap;align-self:flex-start}.cqa-sb-profile-logout{color:#ffffff8c;padding:6px 6px 9px;border-radius:6px;flex-shrink:0;transition:background .12s,color .12s;display:flex;align-items:center}.cqa-sb-profile-logout:hover{background:#ffffff1f;color:#fff}\n"] }]
13161
+ args: [{ selector: 'cqa-sidebar', template: "<div id=\"cqa-ui-root\" class=\"cqa-sb-root\">\n <aside\n class=\"cqa-sb\"\n [class.cqa-sb--expanded]=\"isExpanded\"\n (mouseenter)=\"onAsideMouseEnter()\"\n (mouseleave)=\"onAsideMouseLeave($event)\">\n\n <!-- ===== 1. Workspace header ===== -->\n <div class=\"cqa-sb-header\" [class.cqa-sb-header--expanded]=\"isExpanded\">\n <!-- Collapsed: hamburger chip -->\n <button\n *ngIf=\"!isExpanded\"\n class=\"cqa-sb-burger\"\n (click)=\"openSidebar()\"\n type=\"button\"\n aria-label=\"Open sidebar\">\n <svg viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"1.33\" stroke-linecap=\"round\"\n width=\"16\" height=\"16\">\n <line x1=\"2\" y1=\"4\" x2=\"14\" y2=\"4\"/>\n <line x1=\"2\" y1=\"8\" x2=\"14\" y2=\"8\"/>\n <line x1=\"2\" y1=\"12\" x2=\"14\" y2=\"12\"/>\n </svg>\n </button>\n\n <!-- Expanded: workspace selector + pin (unpinned) or close (pinned) -->\n <ng-container *ngIf=\"isExpanded\">\n <button class=\"cqa-sb-ws\" type=\"button\" (click)=\"workspaceSwitchClick.emit()\">\n <span class=\"cqa-sb-ws-main\">\n <span class=\"cqa-sb-ws-avatar\">\n <img *ngIf=\"workspaceLogoSafe; else defaultLogoTpl\"\n class=\"cqa-sb-ws-logo\"\n [src]=\"workspaceLogoSafe\"\n [alt]=\"config?.workspaceName || 'Workspace logo'\" />\n <ng-template #defaultLogoTpl>\n <svg class=\"cqa-sb-ws-default\" width=\"36\" height=\"36\" viewBox=\"0 0 40 40\"\n fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <rect x=\"2\" y=\"1\" width=\"36\" height=\"36\" rx=\"9\" fill=\"url(#cqa-sb-ws-grad)\"/>\n <g filter=\"url(#cqa-sb-ws-shadow)\">\n <rect x=\"2\" y=\"1\" width=\"36\" height=\"36\" rx=\"9\" fill=\"white\" fill-opacity=\"0.01\" shape-rendering=\"crispEdges\"/>\n </g>\n <rect width=\"8.07969\" height=\"2.59969\" rx=\"1.29985\" transform=\"matrix(0.0555427 -0.998456 0.998194 0.0600698 10.3188 28.9912)\" fill=\"#97AFC5\"/>\n <rect width=\"8.0708\" height=\"2.60278\" rx=\"1.30139\" transform=\"matrix(-0.173269 -0.984874 0.982367 -0.186964 27.3413 29.4043)\" fill=\"#97AFC5\"/>\n <path d=\"M11.1884 23.5958C11.4549 23.7473 11.7865 23.6502 11.9291 23.3789L13.3623 20.6523C13.5049 20.381 13.4045 20.0382 13.1381 19.8867C12.2055 19.3564 11.0448 19.6964 10.5457 20.646L10.4037 20.9162C9.90451 21.8658 10.2559 23.0655 11.1884 23.5958Z\" fill=\"#C2DBF2\"/>\n <path d=\"M11.6714 22.4677C11.6714 20.1863 13.5208 18.3369 15.8022 18.3369H23.9505C26.2319 18.3369 28.0813 20.1863 28.0813 22.4677V23.7953C28.0813 28.3268 24.4078 32.0003 19.8764 32.0003C15.3449 32.0003 11.6714 28.3268 11.6714 23.7953V22.4677Z\" fill=\"#D7E7F9\"/>\n <path d=\"M28.8116 23.7315C28.5451 23.883 28.2135 23.7859 28.0709 23.5146L26.6377 20.7881C26.4951 20.5167 26.5955 20.174 26.8619 20.0225C27.7945 19.4922 28.9552 19.8321 29.4543 20.7817L29.5963 21.0519C30.0955 22.0015 29.7441 23.2012 28.8116 23.7315Z\" fill=\"#C2DBF2\"/>\n <path d=\"M26.3774 19.1758C26.3774 19.8026 23.4762 20.3107 19.8974 20.3107C16.3186 20.3107 13.4175 19.8026 13.4175 19.1758C13.4175 18.5491 16.3186 18.041 19.8974 18.041C23.4762 18.041 26.3774 18.5491 26.3774 19.1758Z\" fill=\"#C2DBF2\"/>\n <path d=\"M21.7507 26.7785L21.6221 26.6448C22.1471 25.7868 22.0506 24.6335 21.3329 23.8869C20.5026 23.0234 19.1473 23.0234 18.317 23.8869C17.4868 24.7505 17.4868 26.1601 18.317 27.0236C19.0348 27.7702 20.1437 27.8705 20.9686 27.3245L21.0972 27.4582L21.2686 27.6365C21.4507 27.8259 21.7453 27.8259 21.9221 27.6365C22.1042 27.4471 22.1042 27.1406 21.9221 26.9568L21.7507 26.7785ZM18.9706 26.3439C18.4992 25.8536 18.4992 25.0569 18.9706 24.5722C19.4419 24.0819 20.208 24.0819 20.674 24.5722C21.0275 24.9399 21.1132 25.4804 20.9365 25.9372C20.8775 26.0876 20.7918 26.2269 20.674 26.3439C20.5561 26.4665 20.4222 26.5556 20.2829 26.6169C19.8491 26.8008 19.3241 26.7116 18.9706 26.3439Z\" fill=\"#6366F1\"/>\n <rect width=\"17.4575\" height=\"10.8035\" rx=\"5.40176\" transform=\"matrix(0.999918 0.0128129 -0.0118443 0.99993 11.1401 6.9248)\" fill=\"#D7E7F9\"/>\n <path d=\"M11.9068 9.74961C12.2603 9.75414 12.5435 10.0444 12.5393 10.3979L12.4926 14.3376C12.4884 14.6911 12.1985 14.974 11.845 14.9694C10.6078 14.9536 9.61668 13.9377 9.63133 12.7005L9.64009 11.9611C9.65475 10.7239 10.6696 9.73376 11.9068 9.74961Z\" fill=\"#C2DBF2\"/>\n <path d=\"M27.7011 15.1723C27.3476 15.1677 27.0644 14.8775 27.0686 14.524L27.1153 10.5843C27.1195 10.2308 27.4094 9.94792 27.7629 9.95245C29.0001 9.9683 29.9912 10.9841 29.9766 12.2214L29.9678 12.9607C29.9532 14.198 28.9383 15.1881 27.7011 15.1723Z\" fill=\"#C2DBF2\"/>\n <rect width=\"13.0931\" height=\"6.80894\" rx=\"3.40447\" transform=\"matrix(0.999918 0.0128129 -0.0118443 0.99993 13.2988 8.9502)\" fill=\"#2F445B\"/>\n <ellipse cx=\"0.872874\" cy=\"0.907858\" rx=\"0.872874\" ry=\"0.907858\" transform=\"matrix(0.999918 0.0128129 -0.0118443 0.99993 22.2153 11.5605)\" fill=\"#6366F1\"/>\n <ellipse cx=\"0.872874\" cy=\"0.907858\" rx=\"0.872874\" ry=\"0.907858\" transform=\"matrix(0.999918 0.0128129 -0.0118443 0.99993 15.6255 11.4766)\" fill=\"#6366F1\"/>\n <path d=\"M16.9047 6.66572C16.9091 6.29805 17.2106 6.00382 17.5783 6.00853L22.1819 6.06752C22.5496 6.07223 22.8441 6.3741 22.8398 6.74177C22.8245 8.02859 21.769 9.05841 20.4822 9.04192L19.2071 9.02558C17.9203 9.00909 16.8895 7.95254 16.9047 6.66572Z\" fill=\"#C2DBF2\"/>\n <rect x=\"2\" y=\"1\" width=\"36\" height=\"36\" rx=\"9\" fill=\"url(#cqa-sb-ws-gloss)\"/>\n <defs>\n <filter id=\"cqa-sb-ws-shadow\" x=\"0\" y=\"0\" width=\"40\" height=\"40\" filterUnits=\"userSpaceOnUse\" color-interpolation-filters=\"sRGB\">\n <feFlood flood-opacity=\"0\" result=\"BackgroundImageFix\"/>\n <feColorMatrix in=\"SourceAlpha\" type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0\" result=\"hardAlpha\"/>\n <feOffset dy=\"1\"/>\n <feGaussianBlur stdDeviation=\"1\"/>\n <feComposite in2=\"hardAlpha\" operator=\"out\"/>\n <feColorMatrix type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.12 0\"/>\n <feBlend mode=\"normal\" in2=\"BackgroundImageFix\" result=\"effect1_dropShadow\"/>\n <feColorMatrix in=\"SourceAlpha\" type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0\" result=\"hardAlpha\"/>\n <feMorphology radius=\"1\" operator=\"erode\" in=\"SourceAlpha\" result=\"effect2_innerShadow\"/>\n <feOffset/>\n <feComposite in2=\"hardAlpha\" operator=\"arithmetic\" k2=\"-1\" k3=\"1\"/>\n <feColorMatrix type=\"matrix\" values=\"0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.4 0\"/>\n <feBlend mode=\"normal\" in2=\"effect1_dropShadow\" result=\"effect2_innerShadow\"/>\n </filter>\n <linearGradient id=\"cqa-sb-ws-grad\" x1=\"2\" y1=\"1\" x2=\"38\" y2=\"37\" gradientUnits=\"userSpaceOnUse\">\n <stop stop-color=\"#CCE1F4\"/>\n <stop offset=\"1\" stop-color=\"#D7E7F9\"/>\n </linearGradient>\n <linearGradient id=\"cqa-sb-ws-gloss\" x1=\"20\" y1=\"1\" x2=\"20\" y2=\"37\" gradientUnits=\"userSpaceOnUse\">\n <stop stop-color=\"white\" stop-opacity=\"0.5\"/>\n <stop offset=\"0.5\" stop-color=\"white\" stop-opacity=\"0\"/>\n </linearGradient>\n </defs>\n </svg>\n </ng-template>\n <span *ngIf=\"config?.workspaceStatus === 'live'\" class=\"cqa-sb-ws-status\"></span>\n </span>\n <span class=\"cqa-sb-ws-info\">\n <span class=\"cqa-sb-ws-name-row\">\n <span class=\"cqa-sb-ws-name\">{{ config?.workspaceName || 'Workspace' }}</span>\n </span>\n </span>\n </span>\n <span class=\"cqa-sb-ws-switch\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 14 14\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"1.17\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\n width=\"14\" height=\"14\">\n <polyline points=\"3,9 7,12 11,9\"/>\n <polyline points=\"3,5 7,2 11,5\"/>\n </svg>\n </span>\n </button>\n\n <button\n *ngIf=\"isPinned || config?.showSidebarPin !== false\"\n class=\"cqa-sb-pin-or-close\"\n type=\"button\"\n (click)=\"isPinned ? closeSidebar() : pinSidebar()\"\n [matTooltip]=\"isPinned ? 'Close sidebar' : 'Pin sidebar'\"\n [matTooltipPosition]=\"isPinned ? 'right' : 'left'\"\n [attr.aria-label]=\"isPinned ? 'Close sidebar' : 'Pin sidebar'\">\n <svg\n *ngIf=\"isPinned\"\n viewBox=\"0 0 18 18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.35\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" width=\"18\" height=\"18\">\n <rect x=\"1.5\" y=\"1.5\" width=\"15\" height=\"15\" rx=\"2.5\"/>\n <line x1=\"6.5\" y1=\"1.5\" x2=\"6.5\" y2=\"16.5\"/>\n <polyline points=\"10.5,12 8.5,9 10.5,6\"/>\n </svg>\n <svg\n *ngIf=\"!isPinned\"\n viewBox=\"0 0 18 18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.35\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" width=\"18\" height=\"18\">\n <path d=\"M9 3v4M7 3h4v4l2 3H5l2-3V3z\"/>\n <line x1=\"9\" y1=\"10\" x2=\"9\" y2=\"15\"/>\n </svg>\n </button>\n </ng-container>\n </div>\n\n <!-- ===== 2. Search ===== -->\n <div *ngIf=\"config?.showSearch !== false\" class=\"cqa-sb-search-wrap\">\n <button class=\"cqa-sb-search\" type=\"button\"\n [matTooltip]=\"!isExpanded ? 'Search' : ''\" matTooltipPosition=\"right\"\n (click)=\"searchClick.emit()\">\n <svg class=\"cqa-sb-search-icon\" viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"1.33\" stroke-linecap=\"round\" stroke-linejoin=\"round\" width=\"16\" height=\"16\">\n <circle cx=\"7\" cy=\"7\" r=\"4.5\"/>\n <line x1=\"10.5\" y1=\"10.5\" x2=\"13.5\" y2=\"13.5\"/>\n </svg>\n <span class=\"cqa-sb-search-text\" [class.cqa-sb-search-text--visible]=\"isExpanded\">\n {{ config?.searchPlaceholder || 'Search Anything...' }}\n </span>\n <span\n *ngIf=\"config?.showSearchShortcut !== false && isExpanded\"\n class=\"cqa-sb-search-kbd\">\u2318K</span>\n </button>\n </div>\n\n <!-- ===== 3. CTA ===== -->\n <div *ngIf=\"config?.showCta !== false\" class=\"cqa-sb-cta-wrap\">\n <button class=\"cqa-sb-cta\" type=\"button\"\n [matTooltip]=\"!isExpanded ? (config?.ctaLabel || 'New') : ''\" matTooltipPosition=\"right\"\n (click)=\"ctaClick.emit()\">\n <svg viewBox=\"0 0 18 18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.6\"\n stroke-linecap=\"round\" width=\"18\" height=\"18\">\n <line x1=\"9\" y1=\"3.75\" x2=\"9\" y2=\"14.25\"/>\n <line x1=\"3.75\" y1=\"9\" x2=\"14.25\" y2=\"9\"/>\n </svg>\n <span class=\"cqa-sb-cta-text\" [class.cqa-sb-cta-text--visible]=\"isExpanded\">\n {{ config?.ctaLabel || 'New Test Cases' }}\n </span>\n </button>\n </div>\n\n <!-- ===== 4. Nav menu ===== -->\n <cqa-nav-menu\n [items]=\"navItems\"\n [activeId]=\"activeNavId\"\n [isExpanded]=\"isExpanded\"\n [openParents]=\"openParents\"\n (itemClick)=\"onNavItemClick($event)\">\n </cqa-nav-menu>\n\n <!-- ===== 5. Utility bar ===== -->\n <div class=\"cqa-sb-utility\" [class.cqa-sb-utility--expanded]=\"isExpanded\">\n <!-- Expanded: 2 wide tiles (Help & docs + Live chat) -->\n <ng-container *ngIf=\"isExpanded\">\n <button\n *ngIf=\"config?.showHelpDocs !== false\"\n class=\"cqa-sb-util-tile\"\n type=\"button\"\n (click)=\"helpDocsClick.emit()\">\n <svg viewBox=\"0 0 18 18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.35\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" width=\"18\" height=\"18\">\n <circle cx=\"9\" cy=\"9\" r=\"7.25\"/>\n <path d=\"M6.85 7a2.15 2.15 0 0 1 4.18.75c0 1.4-2.15 1.8-2.15 3.05\"/>\n <line x1=\"9\" y1=\"13.4\" x2=\"9.01\" y2=\"13.4\"/>\n </svg>\n <span class=\"cqa-sb-util-tile-label\">{{ config?.helpDocsLabel || 'Help & docs' }}</span>\n </button>\n\n <button\n *ngIf=\"config?.showLiveChat !== false\"\n class=\"cqa-sb-util-tile\"\n type=\"button\"\n (click)=\"liveChatClick.emit()\">\n <svg viewBox=\"0 0 18 18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.35\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" width=\"18\" height=\"18\">\n <path d=\"M16 2H2a1 1 0 0 0-1 1v9a1 1 0 0 0 1 1h3v3l4.5-3H16a1 1 0 0 0 1-1V3a1 1 0 0 0-1-1z\"/>\n </svg>\n <span class=\"cqa-sb-util-tile-label\">Live chat</span>\n </button>\n </ng-container>\n\n <!-- Collapsed: help + live chat only (notifications / speaker are not shown on the rail) -->\n <ng-container *ngIf=\"!isExpanded\">\n <button\n *ngIf=\"config?.showHelpDocs !== false\"\n class=\"cqa-sb-util-compact\"\n type=\"button\"\n [matTooltip]=\"config?.helpDocsLabel || 'Help & docs'\" matTooltipPosition=\"right\"\n (click)=\"helpDocsClick.emit()\">\n <svg viewBox=\"0 0 18 18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.35\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" width=\"18\" height=\"18\">\n <circle cx=\"9\" cy=\"9\" r=\"7.25\"/>\n <path d=\"M6.85 7a2.15 2.15 0 0 1 4.18.75c0 1.4-2.15 1.8-2.15 3.05\"/>\n <line x1=\"9\" y1=\"13.4\" x2=\"9.01\" y2=\"13.4\"/>\n </svg>\n </button>\n\n <button\n *ngIf=\"config?.showLiveChat !== false\"\n class=\"cqa-sb-util-compact\"\n type=\"button\"\n matTooltip=\"Live chat\" matTooltipPosition=\"right\"\n (click)=\"liveChatClick.emit()\">\n <svg viewBox=\"0 0 18 18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.35\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" width=\"18\" height=\"18\">\n <path d=\"M16 2H2a1 1 0 0 0-1 1v9a1 1 0 0 0 1 1h3v3l4.5-3H16a1 1 0 0 0 1-1V3a1 1 0 0 0-1-1z\"/>\n </svg>\n </button>\n </ng-container>\n </div>\n\n <!-- ===== 6. Profile card ===== -->\n <div class=\"cqa-sb-profile\" #profileAnchor>\n <button class=\"cqa-sb-profile-main\" type=\"button\"\n [matTooltip]=\"!isExpanded ? (config?.userName || profileUser?.name || '') : ''\" matTooltipPosition=\"right\"\n [attr.aria-haspopup]=\"(profileUser && profileMenuEntries?.length) ? 'menu' : null\"\n [attr.aria-expanded]=\"(profileUser && profileMenuEntries?.length) ? isProfileMenuOpen : null\"\n (click)=\"onProfileClick()\">\n <div class=\"cqa-sb-profile-avatar\">{{ config?.userInitials || '?' }}</div>\n <div class=\"cqa-sb-profile-info\" [class.cqa-sb-profile-info--visible]=\"isExpanded\">\n <span class=\"cqa-sb-profile-name\">{{ config?.userName }}</span>\n <span *ngIf=\"config?.userRole\" class=\"cqa-sb-profile-role\">{{ config.userRole }}</span>\n </div>\n </button>\n <button *ngIf=\"isExpanded\" class=\"cqa-sb-profile-logout\" type=\"button\"\n aria-label=\"Logout\" (click)=\"logoutClick.emit()\">\n <svg viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.2\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" width=\"16\" height=\"16\">\n <path d=\"M6 14H3a1 1 0 0 1-1-1V3a1 1 0 0 1 1-1h3\"/>\n <polyline points=\"11,11 14,8 11,5\"/>\n <line x1=\"14\" y1=\"8\" x2=\"6\" y2=\"8\"/>\n </svg>\n </button>\n </div>\n\n <cqa-profile-menu\n *ngIf=\"isProfileMenuOpen && profileUser && profileMenuEntries?.length\"\n [user]=\"profileUser\"\n [entries]=\"profileMenuEntries\"\n [anchor]=\"profileAnchorRef?.nativeElement || null\"\n (itemClick)=\"onProfileMenuItemClick($event)\"\n (dismissed)=\"onProfileMenuDismissed()\">\n </cqa-profile-menu>\n\n </aside>\n</div>\n", styles: ["*{box-sizing:border-box}:host{display:flex;flex-direction:column;flex:1;align-self:stretch;min-height:0;max-height:100%;height:100%;flex-shrink:0}.cqa-sb-root{display:flex;flex-direction:column;flex:1 1 auto;min-height:0;max-height:100%;width:100%}.cqa-sb{background:#3f43ee;color:#fff;flex:1 1 auto;min-height:0;max-height:100%;height:100%;display:flex;flex-direction:column;flex-shrink:0;width:60px;transition:width .24s cubic-bezier(.32,.72,0,1);position:relative;z-index:50;overflow-x:visible;overflow-y:hidden}.cqa-sb--expanded{width:264px;overflow-x:hidden}.cqa-sb>cqa-nav-menu{flex:1 1 0;min-height:0;min-width:0;display:flex;flex-direction:column}.cqa-sb-header{padding:10px;position:relative;border-bottom:1px solid rgba(255,255,255,.08);min-height:51px;display:flex;align-items:center;justify-content:center;flex-shrink:0}.cqa-sb-header--expanded{justify-content:flex-start;padding:12px 40px 10px 12px;height:71px;max-height:71px;gap:0}.cqa-sb-burger{width:28px;height:28px;border-radius:7px;background:#d8d9fc2e;display:flex;align-items:center;justify-content:center;border:none;cursor:pointer;color:#d8d9fc;flex-shrink:0;transition:background .15s,color .15s}.cqa-sb-burger:hover{background:#d8d9fc47;color:#fff}.cqa-sb-pin-or-close{position:absolute;right:10px;top:50%;transform:translateY(calc(-50% + 1px));width:28px;height:28px;border-radius:7px;display:flex;align-items:center;justify-content:center;background:transparent;border:none;cursor:pointer;color:#d8d9fc;flex-shrink:0;transition:background .15s,color .15s}.cqa-sb-pin-or-close:hover{background:#ffffff1a;color:#fff}.cqa-sb-ws{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:6px 14px 6px 6px;border-radius:10px;line-height:1;height:48px;transition:background .12s;flex:1;min-width:0;text-align:left;background:transparent;border:none;cursor:pointer;color:#fff;overflow:hidden}.cqa-sb-ws:hover{background:#ffffff14}.cqa-sb-ws-main{display:flex;align-items:center;gap:10px;min-width:0}.cqa-sb-ws-avatar{width:36px;height:36px;border-radius:9px;display:flex;align-items:center;justify-content:center;flex-shrink:0;position:relative;overflow:hidden}.cqa-sb-ws-logo{position:relative;z-index:1;width:100%;height:100%;object-fit:contain;display:block}.cqa-sb-ws-default{position:relative;z-index:1;display:block;pointer-events:none}.cqa-sb-ws-status{position:absolute;bottom:-3px;right:-3px;width:12px;height:12px;background:#0dbd7d;border-radius:50%;border:2.5px solid #3f43ee;box-shadow:0 0 6px #0dbd7d}.cqa-sb-ws-info{flex:1;min-width:0;overflow:hidden}.cqa-sb-ws-name-row{display:flex;align-items:center;gap:6px}.cqa-sb-ws-name{font-weight:600;font-size:14px;line-height:16.8px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:#fff}.cqa-sb-ws-badge{background:#0dbd7d2e;color:#5ed3a8;font-size:9.5px;font-weight:700;padding:1px 6px 1px 4px;border-radius:4px;display:inline-flex;align-items:center;gap:3px;flex-shrink:0;text-transform:uppercase;letter-spacing:.04em}.cqa-sb-ws-badge:before{content:\"\";width:4px;height:4px;background:#0dbd7d;border-radius:50%;box-shadow:0 0 6px #0dbd7d}.cqa-sb-ws-switch{color:#ffffff8c;flex-shrink:0;padding:4px 0 7px;border-radius:6px;display:flex;align-items:center}.cqa-sb-search-wrap{padding:8px 12px;flex-shrink:0}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-search-wrap{padding:8px 10px 6px;display:flex;justify-content:center}.cqa-sb-search{background:#ffffff0d;border:1px solid rgba(255,255,255,.1);border-radius:8px;height:38px;padding:0 12px;font-size:12px;line-height:1;letter-spacing:-.31px;color:#ffffff80;display:flex;align-items:center;gap:8px;width:100%;cursor:pointer;transition:all .15s;overflow:hidden;font-family:inherit}.cqa-sb-search:hover{background:#ffffff14;color:#ffffffbf;border-color:#ffffff29}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-search{padding:0;width:40px;max-width:40px;height:40px;min-height:40px;margin:0 auto;justify-content:center;align-items:center;gap:0;background:transparent;border-color:#d8d9fc;border-radius:9px}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-search .cqa-sb-search-text,.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-search .cqa-sb-search-kbd{flex:0 0 0;width:0;min-width:0;height:0;margin:0;padding:0;overflow:hidden;opacity:0;border:0;pointer-events:none}.cqa-sb-search-icon{flex-shrink:0;width:14px;height:14px}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-search-icon{width:16px;height:16px}.cqa-sb-search-text{flex:1;text-align:left;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif;font-weight:400;font-size:12px;line-height:1;letter-spacing:-.31px;color:#ffffff80;opacity:0;transition:opacity .16s 80ms}.cqa-sb-search-text--visible{opacity:1}.cqa-sb-search-kbd{display:inline-flex;align-items:center;justify-content:center;height:16px;font-size:10.5px;line-height:1;letter-spacing:normal;text-align:center;background:#ffffff26;padding:2px 6px;border-radius:4px;color:#ffffffd9;font-family:Menlo,ui-monospace,monospace;flex-shrink:0}.cqa-sb-cta-wrap{padding:8px 12px;flex-shrink:0}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-cta-wrap{padding:0 10px 12px;display:flex;justify-content:center}.cqa-sb-cta{background:#5256f0;color:#fbfcff;border:none;border-radius:8px;height:38px;padding:10px 24px 10px 16px;font-size:14px;font-weight:600;line-height:14px;letter-spacing:0;width:100%;display:flex;align-items:center;justify-content:center;gap:8px;cursor:pointer;transition:background .15s,transform .15s;overflow:hidden;font-family:inherit}.cqa-sb-cta:hover{background:#5b5ff2;transform:translateY(-1px)}.cqa-sb-cta:active{transform:translateY(0)}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-cta{padding:0;width:40px;height:40px;min-height:40px;margin:0 auto;position:relative;background:transparent;color:#fff}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-cta:before{content:\"\";position:absolute;inset:0;border-radius:9px;background:#b1b2f838;pointer-events:none}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-cta svg{position:relative;z-index:1;width:16px;height:16px}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-cta{box-shadow:inset 0 0 0 1px #d8d9fc38}.cqa-sb-cta-text{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif;font-weight:600;font-size:14px;line-height:1;letter-spacing:0;color:#fbfcff;opacity:0;transition:opacity .16s 80ms;position:relative;z-index:1}.cqa-sb-cta-text--visible{opacity:1}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-cta-text{display:none}.cqa-sb-utility{border-top:none;box-shadow:inset 0 1px #ffffff1a;flex-shrink:0}.cqa-sb-utility--expanded{display:flex;align-items:center;justify-content:space-between;height:68px;gap:0;padding:8px 10px}.cqa-sb-utility:not(.cqa-sb-utility--expanded){display:flex;flex-direction:column;align-items:center;justify-content:flex-start;gap:1px;padding:6px 10px}.cqa-sb-util-tile{width:110px;max-width:110px;border-radius:9px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;padding:8px 6px 6px;color:#ffffffd9;background:#ffffff0f;border:none;cursor:pointer;transition:background .12s,color .12s;font-family:inherit}.cqa-sb-util-tile:hover{background:#b1b2f838;color:#fff}.cqa-sb-util-tile-label{font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif;font-size:10.5px;font-weight:600;line-height:10.5px;letter-spacing:.1px;color:#ffffffd9;text-align:center;white-space:nowrap}.cqa-sb-util-compact{position:relative;width:36px;height:34px;border-radius:8px;display:flex;align-items:center;justify-content:center;color:#ffffffe0;background:transparent;border:none;cursor:pointer;transition:background .12s,color .12s;padding:0;flex-shrink:0}.cqa-sb-util-compact:hover{background:#ffffff14;color:#fff}.cqa-sb-util-compact-dot{position:absolute;top:6px;right:6px;width:8px;height:8px;background:#ee3f3f;border-radius:4px;border:2px solid #3f43ee;pointer-events:none}.cqa-sb-profile{border-top:1px solid rgba(255,255,255,.1);padding:12px 14px;height:62px;display:flex;align-items:center;gap:12px;background:#00000029;overflow:hidden;position:relative;width:100%;flex-shrink:0;color:#fff}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-profile{justify-content:center;padding:12px 0;height:auto;gap:0;background:#0000001f;border-top-color:#ffffff1f}.cqa-sb-profile-main{flex:1;min-width:0;display:flex;align-items:center;gap:12px;padding:0;background:transparent;border:none;border-radius:8px;cursor:pointer;color:inherit;font-family:inherit;text-align:left;transition:background .15s}.cqa-sb-profile-main:hover{background:#0000001a}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-profile-main{justify-content:center;flex:0 0 auto}.cqa-sb-profile-avatar{width:34px;height:34px;border-radius:17px;background:linear-gradient(135deg,#f472b6,#db2777);display:flex;align-items:center;justify-content:center;font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif;font-size:12px;font-weight:700;line-height:1;letter-spacing:0;color:#fff;flex-shrink:0;box-shadow:0 0 0 2px #ffffff26}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-profile-avatar{width:32px;height:32px;border-radius:16px;font-size:11.5px}.cqa-sb-profile-info{flex:1;min-width:0;overflow:hidden;opacity:0;transition:opacity .16s 80ms;display:flex;flex-direction:column;align-items:flex-start;justify-content:center;gap:4px}.cqa-sb-profile-info--visible{opacity:1}.cqa-sb:not(.cqa-sb--expanded) .cqa-sb-profile-info{display:none}.cqa-sb-profile-name{font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif;font-weight:600;font-size:12.5px;line-height:13.75px;letter-spacing:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:#fff}.cqa-sb-profile-role{display:inline-block;font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif;font-size:9px;font-weight:700;line-height:12.6px;letter-spacing:0;background:#d8d9fc38;padding:2px 7px;border-radius:999px;color:#fff;border:1px solid rgba(216,217,252,.2);white-space:nowrap;align-self:flex-start}.cqa-sb-profile-logout{color:#ffffff8c;padding:6px 6px 9px;border-radius:6px;background:transparent;border:none;cursor:pointer;flex-shrink:0;transition:background .12s,color .12s;display:flex;align-items:center;justify-content:center}.cqa-sb-profile-logout:hover{background:#ffffff1f;color:#fff}\n"] }]
12975
13162
  }], ctorParameters: () => [{ type: i1$1.DomSanitizer }], propDecorators: { config: [{
12976
13163
  type: Input
12977
13164
  }], navItems: [{
@@ -12980,6 +13167,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
12980
13167
  type: Input
12981
13168
  }], initialOpenParentIds: [{
12982
13169
  type: Input
13170
+ }], profileUser: [{
13171
+ type: Input
13172
+ }], profileMenuEntries: [{
13173
+ type: Input
12983
13174
  }], navItemClick: [{
12984
13175
  type: Output
12985
13176
  }], ctaClick: [{
@@ -13000,6 +13191,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
13000
13191
  type: Output
13001
13192
  }], expandedChange: [{
13002
13193
  type: Output
13194
+ }], profileMenuItemClick: [{
13195
+ type: Output
13196
+ }], profileAnchorRef: [{
13197
+ type: ViewChild,
13198
+ args: ['profileAnchor', { static: false }]
13003
13199
  }] } });
13004
13200
 
13005
13201
  const STEP_COMPONENT_MAP = new InjectionToken('STEP_COMPONENT_MAP');
@@ -33938,23 +34134,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
33938
34134
  args: ['viewDetailsTrigger', { static: false }]
33939
34135
  }] } });
33940
34136
 
33941
- class SafeHtmlPipe {
33942
- sanitizer;
33943
- constructor(sanitizer) {
33944
- this.sanitizer = sanitizer;
33945
- }
33946
- transform(value) {
33947
- const str = value != null ? String(value) : '';
33948
- return this.sanitizer.bypassSecurityTrustHtml(str);
33949
- }
33950
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SafeHtmlPipe, deps: [{ token: i1$1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Pipe });
33951
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.14", ngImport: i0, type: SafeHtmlPipe, name: "cqaSafeHtml" });
33952
- }
33953
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SafeHtmlPipe, decorators: [{
33954
- type: Pipe,
33955
- args: [{ name: 'cqaSafeHtml' }]
33956
- }], ctorParameters: () => [{ type: i1$1.DomSanitizer }] });
33957
-
33958
34137
  const CONDITION_BRANCH_EMPTY_STYLES = `
33959
34138
  /* Empty drop zone: ensure min height for drag-drop to work (IF/ELSE IF/ELSE branches) */
33960
34139
  .nested-step-drop-list:has(.step-drag-placeholder-nested:only-child) {
@@ -56425,6 +56604,7 @@ class UiKitModule {
56425
56604
  NavMenuComponent,
56426
56605
  NavItemComponent,
56427
56606
  NavSubItemComponent,
56607
+ ProfileMenuComponent,
56428
56608
  FolderSidebarComponent,
56429
56609
  MoveToFolderDialogComponent,
56430
56610
  MoveTestSuiteDialogComponent,
@@ -56626,6 +56806,7 @@ class UiKitModule {
56626
56806
  NavMenuComponent,
56627
56807
  NavItemComponent,
56628
56808
  NavSubItemComponent,
56809
+ ProfileMenuComponent,
56629
56810
  FolderSidebarComponent,
56630
56811
  NewFolderDialogComponent,
56631
56812
  DeleteFolderDialogComponent,
@@ -56873,6 +57054,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
56873
57054
  NavMenuComponent,
56874
57055
  NavItemComponent,
56875
57056
  NavSubItemComponent,
57057
+ ProfileMenuComponent,
56876
57058
  FolderSidebarComponent,
56877
57059
  MoveToFolderDialogComponent,
56878
57060
  MoveTestSuiteDialogComponent,
@@ -57080,6 +57262,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
57080
57262
  NavMenuComponent,
57081
57263
  NavItemComponent,
57082
57264
  NavSubItemComponent,
57265
+ ProfileMenuComponent,
57083
57266
  FolderSidebarComponent,
57084
57267
  NewFolderDialogComponent,
57085
57268
  DeleteFolderDialogComponent,
@@ -57934,5 +58117,5 @@ function buildTestCaseDetailsFromApi(data, options) {
57934
58117
  * Generated bundle index. Do not edit.
57935
58118
  */
57936
58119
 
57937
- export { ADVANCED_SUBFIELDS_BY_TYPE, ADVANCED_TOGGLE_KEYS, AIActionStepComponent, AIAgentStepComponent, ALL_FILTER_VALUE, API_EDIT_STEP_LABELS, ActionMenuButtonComponent, AddPrerequisiteCasesSectionComponent, AdvancedVariablesFormComponent, AiDebugAlertComponent, AiLogsWithReasoningComponent, AiPromptCardComponent, AiReasoningComponent, ApiEditStepComponent, ApiMockingCardComponent, ApiStepComponent, AssignEnvironmentsDialogComponent, AuditLogDrawerComponent, AuditLogDrawerService, AuditLogEntryCardComponent, AutocompleteComponent, BadgeComponent, BasicStepComponent, BreakpointsModalComponent, ButtonComponent, CUSTOM_EDIT_STEP_DATA, CUSTOM_EDIT_STEP_EDIT_IN_DEPTH, CUSTOM_EDIT_STEP_REF, CUSTOM_ELEMENT_POPUP_REF, CaptureVideoDialogComponent, ChangeHistoryComponent, ChartCardComponent, CodeEditorComponent, ColumnVisibilityComponent, CompareRunsComponent, ConditionBranchEditorComponent, ConditionDebugStepComponent, ConditionStepComponent, ConfigurationCardComponent, ConsoleAlertComponent, CoverageModuleCardComponent, CreateStepGroupComponent, CustomEditStepComponent, CustomEditStepRef, CustomEditStepService, CustomInputComponent, CustomTextareaComponent, CustomToggleComponent, DEFAULT_FOLDER_COLOR, DEFAULT_METADATA_COLOR, DEFAULT_MODULAR_CONFIG, DEFAULT_MODULAR_LABELS, DEFAULT_PRIORITY_COLOR_CONFIG, DEFAULT_REORDER_LABELS, DEFAULT_STATUS_COLOR_CONFIG, DEFAULT_TEST_SUITE_LABELS, DIALOG_DATA, DIALOG_REF, DashboardHeaderComponent, DaterangepickerComponent, DaterangepickerDirective, DbQueryExecutionItemComponent, DbVerificationStepComponent, DeleteFolderDialogComponent, DeleteStepsComponent, DetailDrawerComponent, DetailDrawerTabComponent, DetailDrawerTabContentDirective, DetailSidePanelComponent, DialogComponent, DialogRef, DialogService, DocumentVerificationStepComponent, DropdownButtonComponent, DynamicCellContainerDirective, DynamicCellTemplateDirective, DynamicFilterComponent, DynamicHeaderTemplateDirective, DynamicSelectFieldComponent, DynamicTableComponent, ELEMENT_POPUP_DATA, ELEMENT_POPUP_EDIT_IN_DEPTH, EMPTY_STATE_IMAGES, EMPTY_STATE_PRESETS, ENVIRONMENT_ACCENT_COLORS, ElementFormComponent, ElementListComponent, ElementPopupComponent, ElementPopupRef, ElementPopupService, EmptyStateComponent, ErrorModalComponent, ExecutionResultModalComponent, ExportCodeModalComponent, FOLDER_COLUMN_FIELD_ID, FOLDER_DRAG_MIME, FOLDER_NAME_MAX_LENGTH, FailedStepCardComponent, FailedStepComponent, FailedTestCasesCardComponent, FileDownloadStepComponent, FileUploadComponent, FolderDragDirective, FolderDropDirective, FolderSidebarComponent, FullTableLoaderComponent, HeatErrorMapCellComponent, InsightCardComponent, ItemListComponent, IterationsLoopComponent, JumpToStepModalComponent, LiveConversationComponent, LiveExecutionStepComponent, LoopStepComponent, MONACO_LANGUAGE_MAP, MainStepCollapseComponent, ManageColumnsDialogComponent, MetricsCardComponent, MixedVariableInputComponent, ModularTableTemplateComponent, MoveTestSuiteDialogComponent, MoveToFolderDialogComponent, NamePromptModalComponent, NavItemComponent, NavMenuComponent, NavSubItemComponent, NetworkRequestComponent, NewDbConfigDialogComponent, NewEnvironmentDialogComponent, NewEnvironmentVariableDialogComponent, NewFolderDialogComponent, NewGlobalVariableDialogComponent, NewTestDataProfileDialogComponent, NewVersionHistoryDetailComponent, OtherButtonComponent, PRIORITY_COLORS, PaginationComponent, PermissionToggleComponent, ProgressIndicatorComponent, ProgressTextCardComponent, QuestionnaireListComponent, RESULT_COLORS, ROW_DRAG_MIME, RadioCardGroupComponent, RecordingBannerComponent, ReviewRecordedStepsModalComponent, RowDragDirective, RunExecutionAlertComponent, RunHistoryCardComponent, STATUS_COLORS, STEP_DETAILS_DRAWER_DATA, STEP_DETAILS_DRAWER_REF, STEP_DETAILS_FIELDS_BY_TYPE, STEP_DETAILS_FIELD_META, STEP_DETAILS_MODAL_DATA, STEP_DETAILS_MODAL_REF, SearchBarComponent, SegmentControlComponent, SelectedFiltersComponent, SelfHealAnalysisComponent, SessionChangesModalComponent, SessionRestorationDialogComponent, SidebarComponent, SimulatorComponent, StepBuilderActionComponent, StepBuilderAiAgentComponent, StepBuilderConditionComponent, StepBuilderCustomCodeComponent, StepBuilderDatabaseComponent, StepBuilderDocumentComponent, StepBuilderDocumentGenerationTemplateStepComponent, StepBuilderGroupComponent, StepBuilderLoopComponent, StepBuilderRecordStepComponent, StepDetailsDrawerComponent, StepDetailsDrawerRef, StepDetailsDrawerService, StepDetailsModalComponent, StepDetailsModalRef, StepDetailsModalService, StepGroupComponent, StepProgressCardComponent, StepRendererComponent, StepStatusCardComponent, StepTypes, StepperComponent, SubStepsConfirmationDialogComponent, TEST_CASE_DETAILS_FIELD_MAP, TEST_CASE_DETAILS_SELECT_KEYS, TEST_DATA_MODAL_DATA, TEST_DATA_MODAL_EDIT_IN_DEPTH, TEST_DATA_MODAL_REF, TabComponent, TableActionToolbarComponent, TableDataLoaderComponent, TableTemplateComponent, TabsComponent, TailwindOverlayContainer, TemplateVariablesFormComponent, TestCaseAiAgentStepComponent, TestCaseAiVerifyStepComponent, TestCaseApiStepComponent, TestCaseConditionStepComponent, TestCaseCustomCodeStepComponent, TestCaseDatabaseStepComponent, TestCaseDetailsComponent, TestCaseDetailsEditComponent, TestCaseDetailsRendererComponent, TestCaseLinkCellComponent, TestCaseLoopStepComponent, TestCaseNormalStepComponent, TestCaseRestoreSessionStepComponent, TestCaseScreenshotStepComponent, TestCaseScrollStepComponent, TestCaseStepGroupComponent, TestCaseUploadStepComponent, TestCaseVerifyUrlStepComponent, TestDataModalComponent, TestDataModalRef, TestDataModalService, TestDistributionCardComponent, UiKitModule, UpdatedFailedStepComponent, VersionHistoryCompareComponent, VersionHistoryDetailComponent, VersionHistoryListComponent, VersionHistoryRestoreConfirmComponent, ViewCompareButtonComponent, ViewMoreFailedStepButtonComponent, ViewportSelectorComponent, VisualComparisonComponent, VisualDifferenceModalComponent, WorkspaceSelectorComponent, buildTestCaseDetailsFromApi, getDynamicFieldsFromLegacyConfig, getEmptyStatePreset, getMetadataColor, getMetadataValueStyle, getStepDetailsStepType, humanizeVariableKey, isAiAgentStepConfig, isAiVerifyStepConfig, isApiStepConfig, isConditionStepConfig, isCustomCodeStepConfig, isDatabaseStepConfig, isLoopStepConfig, isNavSection, isNormalStepConfig, isRestoreSessionStepConfig, isScreenshotStepConfig, isScrollStepConfig, isStepGroupConfig, isUploadStepConfig, isVerifyUrlStepConfig, mapApiVariablesToDynamicFields };
58120
+ export { ADVANCED_SUBFIELDS_BY_TYPE, ADVANCED_TOGGLE_KEYS, AIActionStepComponent, AIAgentStepComponent, ALL_FILTER_VALUE, API_EDIT_STEP_LABELS, ActionMenuButtonComponent, AddPrerequisiteCasesSectionComponent, AdvancedVariablesFormComponent, AiDebugAlertComponent, AiLogsWithReasoningComponent, AiPromptCardComponent, AiReasoningComponent, ApiEditStepComponent, ApiMockingCardComponent, ApiStepComponent, AssignEnvironmentsDialogComponent, AuditLogDrawerComponent, AuditLogDrawerService, AuditLogEntryCardComponent, AutocompleteComponent, BadgeComponent, BasicStepComponent, BreakpointsModalComponent, ButtonComponent, CUSTOM_EDIT_STEP_DATA, CUSTOM_EDIT_STEP_EDIT_IN_DEPTH, CUSTOM_EDIT_STEP_REF, CUSTOM_ELEMENT_POPUP_REF, CaptureVideoDialogComponent, ChangeHistoryComponent, ChartCardComponent, CodeEditorComponent, ColumnVisibilityComponent, CompareRunsComponent, ConditionBranchEditorComponent, ConditionDebugStepComponent, ConditionStepComponent, ConfigurationCardComponent, ConsoleAlertComponent, CoverageModuleCardComponent, CreateStepGroupComponent, CustomEditStepComponent, CustomEditStepRef, CustomEditStepService, CustomInputComponent, CustomTextareaComponent, CustomToggleComponent, DEFAULT_FOLDER_COLOR, DEFAULT_METADATA_COLOR, DEFAULT_MODULAR_CONFIG, DEFAULT_MODULAR_LABELS, DEFAULT_PRIORITY_COLOR_CONFIG, DEFAULT_REORDER_LABELS, DEFAULT_STATUS_COLOR_CONFIG, DEFAULT_TEST_SUITE_LABELS, DIALOG_DATA, DIALOG_REF, DashboardHeaderComponent, DaterangepickerComponent, DaterangepickerDirective, DbQueryExecutionItemComponent, DbVerificationStepComponent, DeleteFolderDialogComponent, DeleteStepsComponent, DetailDrawerComponent, DetailDrawerTabComponent, DetailDrawerTabContentDirective, DetailSidePanelComponent, DialogComponent, DialogRef, DialogService, DocumentVerificationStepComponent, DropdownButtonComponent, DynamicCellContainerDirective, DynamicCellTemplateDirective, DynamicFilterComponent, DynamicHeaderTemplateDirective, DynamicSelectFieldComponent, DynamicTableComponent, ELEMENT_POPUP_DATA, ELEMENT_POPUP_EDIT_IN_DEPTH, EMPTY_STATE_IMAGES, EMPTY_STATE_PRESETS, ENVIRONMENT_ACCENT_COLORS, ElementFormComponent, ElementListComponent, ElementPopupComponent, ElementPopupRef, ElementPopupService, EmptyStateComponent, ErrorModalComponent, ExecutionResultModalComponent, ExportCodeModalComponent, FOLDER_COLUMN_FIELD_ID, FOLDER_DRAG_MIME, FOLDER_NAME_MAX_LENGTH, FailedStepCardComponent, FailedStepComponent, FailedTestCasesCardComponent, FileDownloadStepComponent, FileUploadComponent, FolderDragDirective, FolderDropDirective, FolderSidebarComponent, FullTableLoaderComponent, HeatErrorMapCellComponent, InsightCardComponent, ItemListComponent, IterationsLoopComponent, JumpToStepModalComponent, LiveConversationComponent, LiveExecutionStepComponent, LoopStepComponent, MONACO_LANGUAGE_MAP, MainStepCollapseComponent, ManageColumnsDialogComponent, MetricsCardComponent, MixedVariableInputComponent, ModularTableTemplateComponent, MoveTestSuiteDialogComponent, MoveToFolderDialogComponent, NamePromptModalComponent, NavItemComponent, NavMenuComponent, NavSubItemComponent, NetworkRequestComponent, NewDbConfigDialogComponent, NewEnvironmentDialogComponent, NewEnvironmentVariableDialogComponent, NewFolderDialogComponent, NewGlobalVariableDialogComponent, NewTestDataProfileDialogComponent, NewVersionHistoryDetailComponent, OtherButtonComponent, PRIORITY_COLORS, PaginationComponent, PermissionToggleComponent, ProfileMenuComponent, ProgressIndicatorComponent, ProgressTextCardComponent, QuestionnaireListComponent, RESULT_COLORS, ROW_DRAG_MIME, RadioCardGroupComponent, RecordingBannerComponent, ReviewRecordedStepsModalComponent, RowDragDirective, RunExecutionAlertComponent, RunHistoryCardComponent, STATUS_COLORS, STEP_DETAILS_DRAWER_DATA, STEP_DETAILS_DRAWER_REF, STEP_DETAILS_FIELDS_BY_TYPE, STEP_DETAILS_FIELD_META, STEP_DETAILS_MODAL_DATA, STEP_DETAILS_MODAL_REF, SearchBarComponent, SegmentControlComponent, SelectedFiltersComponent, SelfHealAnalysisComponent, SessionChangesModalComponent, SessionRestorationDialogComponent, SidebarComponent, SimulatorComponent, StepBuilderActionComponent, StepBuilderAiAgentComponent, StepBuilderConditionComponent, StepBuilderCustomCodeComponent, StepBuilderDatabaseComponent, StepBuilderDocumentComponent, StepBuilderDocumentGenerationTemplateStepComponent, StepBuilderGroupComponent, StepBuilderLoopComponent, StepBuilderRecordStepComponent, StepDetailsDrawerComponent, StepDetailsDrawerRef, StepDetailsDrawerService, StepDetailsModalComponent, StepDetailsModalRef, StepDetailsModalService, StepGroupComponent, StepProgressCardComponent, StepRendererComponent, StepStatusCardComponent, StepTypes, StepperComponent, SubStepsConfirmationDialogComponent, TEST_CASE_DETAILS_FIELD_MAP, TEST_CASE_DETAILS_SELECT_KEYS, TEST_DATA_MODAL_DATA, TEST_DATA_MODAL_EDIT_IN_DEPTH, TEST_DATA_MODAL_REF, TabComponent, TableActionToolbarComponent, TableDataLoaderComponent, TableTemplateComponent, TabsComponent, TailwindOverlayContainer, TemplateVariablesFormComponent, TestCaseAiAgentStepComponent, TestCaseAiVerifyStepComponent, TestCaseApiStepComponent, TestCaseConditionStepComponent, TestCaseCustomCodeStepComponent, TestCaseDatabaseStepComponent, TestCaseDetailsComponent, TestCaseDetailsEditComponent, TestCaseDetailsRendererComponent, TestCaseLinkCellComponent, TestCaseLoopStepComponent, TestCaseNormalStepComponent, TestCaseRestoreSessionStepComponent, TestCaseScreenshotStepComponent, TestCaseScrollStepComponent, TestCaseStepGroupComponent, TestCaseUploadStepComponent, TestCaseVerifyUrlStepComponent, TestDataModalComponent, TestDataModalRef, TestDataModalService, TestDistributionCardComponent, UiKitModule, UpdatedFailedStepComponent, VersionHistoryCompareComponent, VersionHistoryDetailComponent, VersionHistoryListComponent, VersionHistoryRestoreConfirmComponent, ViewCompareButtonComponent, ViewMoreFailedStepButtonComponent, ViewportSelectorComponent, VisualComparisonComponent, VisualDifferenceModalComponent, WorkspaceSelectorComponent, buildTestCaseDetailsFromApi, getDynamicFieldsFromLegacyConfig, getEmptyStatePreset, getMetadataColor, getMetadataValueStyle, getStepDetailsStepType, humanizeVariableKey, isAiAgentStepConfig, isAiVerifyStepConfig, isApiStepConfig, isConditionStepConfig, isCustomCodeStepConfig, isDatabaseStepConfig, isLoopStepConfig, isNavSection, isNormalStepConfig, isProfileMenuDivider, isRestoreSessionStepConfig, isScreenshotStepConfig, isScrollStepConfig, isStepGroupConfig, isUploadStepConfig, isVerifyUrlStepConfig, mapApiVariablesToDynamicFields };
57938
58121
  //# sourceMappingURL=cqa-lib-cqa-ui.mjs.map