@cqa-lib/cqa-ui 1.1.188 → 1.1.189

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (23) hide show
  1. package/esm2020/lib/dynamic-select/dynamic-select-field.component.mjs +27 -3
  2. package/esm2020/lib/test-case-details/step-details-drawer/step-details-drawer-data.mjs +3 -0
  3. package/esm2020/lib/test-case-details/step-details-drawer/step-details-drawer-field.config.mjs +188 -0
  4. package/esm2020/lib/test-case-details/step-details-drawer/step-details-drawer-ref.mjs +28 -0
  5. package/esm2020/lib/test-case-details/step-details-drawer/step-details-drawer.component.mjs +291 -0
  6. package/esm2020/lib/test-case-details/step-details-drawer/step-details-drawer.service.mjs +67 -0
  7. package/esm2020/lib/ui-kit.module.mjs +8 -3
  8. package/esm2020/lib/utils/tw-overlay-container.mjs +6 -3
  9. package/esm2020/public-api.mjs +6 -1
  10. package/fesm2015/cqa-lib-cqa-ui.mjs +596 -7
  11. package/fesm2015/cqa-lib-cqa-ui.mjs.map +1 -1
  12. package/fesm2020/cqa-lib-cqa-ui.mjs +586 -7
  13. package/fesm2020/cqa-lib-cqa-ui.mjs.map +1 -1
  14. package/lib/dynamic-select/dynamic-select-field.component.d.ts +6 -0
  15. package/lib/test-case-details/step-details-drawer/step-details-drawer-data.d.ts +7 -0
  16. package/lib/test-case-details/step-details-drawer/step-details-drawer-field.config.d.ts +51 -0
  17. package/lib/test-case-details/step-details-drawer/step-details-drawer-ref.d.ts +13 -0
  18. package/lib/test-case-details/step-details-drawer/step-details-drawer.component.d.ts +60 -0
  19. package/lib/test-case-details/step-details-drawer/step-details-drawer.service.d.ts +22 -0
  20. package/lib/ui-kit.module.d.ts +21 -20
  21. package/package.json +1 -1
  22. package/public-api.d.ts +5 -0
  23. package/styles.css +1 -1
@@ -1721,6 +1721,7 @@ class DynamicSelectFieldComponent {
1721
1721
  throw new Error('cqa-dynamic-select: input "config.key" is required.');
1722
1722
  }
1723
1723
  this.applySelectedValueIfNeeded();
1724
+ this.syncDisabledState();
1724
1725
  this.lastOptionsLength = (((_a = this.config) === null || _a === void 0 ? void 0 : _a.options) || []).length;
1725
1726
  }
1726
1727
  get displayPlaceholder() {
@@ -1733,6 +1734,9 @@ class DynamicSelectFieldComponent {
1733
1734
  }
1734
1735
  ngOnChanges(changes) {
1735
1736
  var _a, _b, _c, _d, _e, _f, _g, _h, _j;
1737
+ if ('config' in changes || 'form' in changes) {
1738
+ this.syncDisabledState();
1739
+ }
1736
1740
  if ('config' in changes) {
1737
1741
  // When config changes (including toggling multiple), ensure control value shape matches
1738
1742
  this.syncControlValueForMultipleMode();
@@ -1829,6 +1833,27 @@ class DynamicSelectFieldComponent {
1829
1833
  }
1830
1834
  return !!value;
1831
1835
  }
1836
+ /**
1837
+ * Sync the form control's disabled state from config.
1838
+ * Use the FormControl API instead of [disabled] in the template to avoid Angular's
1839
+ * "changed after checked" / reactive forms disabled-attribute warning.
1840
+ */
1841
+ syncDisabledState() {
1842
+ var _a, _b;
1843
+ const key = (_a = this.config) === null || _a === void 0 ? void 0 : _a.key;
1844
+ if (!key || !this.form)
1845
+ return;
1846
+ const control = this.form.get(key);
1847
+ if (!control)
1848
+ return;
1849
+ const shouldDisable = this.toBoolean((_b = this.config) === null || _b === void 0 ? void 0 : _b.disabled);
1850
+ if (shouldDisable) {
1851
+ control.disable({ emitEvent: false });
1852
+ }
1853
+ else {
1854
+ control.enable({ emitEvent: false });
1855
+ }
1856
+ }
1832
1857
  syncControlValueForMultipleMode() {
1833
1858
  var _a;
1834
1859
  const key = (_a = this.config) === null || _a === void 0 ? void 0 : _a.key;
@@ -2258,10 +2283,10 @@ class DynamicSelectFieldComponent {
2258
2283
  }
2259
2284
  }
2260
2285
  DynamicSelectFieldComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DynamicSelectFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2261
- DynamicSelectFieldComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: DynamicSelectFieldComponent, selector: "cqa-dynamic-select", inputs: { form: "form", config: "config" }, outputs: { selectionChange: "selectionChange", selectClick: "selectClick", searchChange: "searchChange", loadMore: "loadMore" }, host: { listeners: { "document:click": "handleDocumentClick($event)" } }, viewQueries: [{ propertyName: "selectRef", first: true, predicate: ["selectRef"], descendants: true }, { propertyName: "hostEl", first: true, predicate: ["host"], descendants: true, read: ElementRef }], usesOnChanges: true, ngImport: i0, template: "<div class=\"cqa-ui-root\">\n <ng-container [formGroup]=\"form\">\n <label *ngIf=\"config.label\"\n class=\"form-label cqa-text-[#374151] cqa-text-[14px] cqa-font-medium cqa-block cqa-leading-[1.4] cqa-mb-2\">{{\n config.label }}</label>\n <mat-form-field #host class=\"mat-select-custom cqa-w-full\" appearance=\"fill\">\n <mat-select #selectRef=\"matSelect\" [placeholder]=\"displayPlaceholder\" [disabled]=\"isDisabled\" [multiple]=\"isMultiple\"\n disableOptionCentering [panelClass]=\"panelClass\" [formControlName]=\"config.key\"\n (openedChange)=\"onSelectOpenedChange($event, selectRef)\" (selectionChange)=\"onSelectionChange($event, selectRef)\">\n\n <mat-option *ngIf=\"config.searchable\" class=\"ts-select-search\" disabled>\n <input class=\"ts-select-search-input cqa-text-black-100\" type=\"text\" [value]=\"searchTextByKey[config.key] || ''\"\n (click)=\"$event.stopPropagation()\" (mousedown)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\" (input)=\"onSearch(config.key, $any($event.target).value)\"\n placeholder=\"Search...\" />\n </mat-option>\n \n <mat-option [ngClass]=\"{'checkmark': config.optionStyle === 'checkmark','checkbox': config.optionStyle !== 'checkmark','mat-selected': allSelected}\" [class]=\"config.optionStyle == 'checkmark' ? 'checkmark' : 'checkbox'\" *ngIf=\"isMultiple && config.showSelectAll\" [value]=\"SELECT_ALL_VALUE\">\n <ng-container *ngIf=\"useCheckboxStyle; else selectAllDefaultTpl\">\n <span class=\"cqa-flex cqa-items-center\">\n <span class=\"cqa-w-4 cqa-h-4 cqa-flex-shrink-0 cqa-rounded-[4px] cqa-border cqa-border-[#D1D5DB] cqa-mr-2 cqa-flex cqa-items-center cqa-justify-center cqa-border-solid\"\n [ngStyle]=\"allSelected ? {'background-color':'#4F46E5','border-color':'#4F46E5'} : {}\">\n <svg *ngIf=\"allSelected\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M10 3L4.5 8.5L2 6\" stroke=\"white\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </span>\n <span class=\"cqa-min-w-0\">{{ config.selectAllLabel || 'All' }}</span>\n </span>\n </ng-container>\n <ng-template #selectAllDefaultTpl>\n {{ config.selectAllLabel || 'All' }}\n </ng-template>\n </mat-option>\n\n <mat-option [class]=\"config.optionStyle == 'checkmark' ? 'checkmark' : 'checkbox'\" *ngFor=\"let opt of filteredOptions(config)\" [value]=\"opt.id ?? opt.value\">\n <ng-container *ngIf=\"config.isCompareRuns\"> \n <ng-container *ngIf=\"useCheckboxStyle; else compareRunsDefaultOptionTpl\">\n <span class=\"cqa-flex cqa-items-center cqa-justify-between cqa-w-full cqa-compare-runs-item\">\n <span class=\"cqa-flex cqa-items-center\">\n <span class=\"cqa-w-4 cqa-h-4 cqa-flex-shrink-0 cqa-rounded-[4px] cqa-border cqa-border-[#D1D5DB] cqa-mr-2 cqa-flex cqa-items-center cqa-justify-center cqa-border-solid\"\n [ngStyle]=\"isOptionSelected(opt) ? {'background-color':'#4F46E5','border-color':'#4F46E5'} : {}\">\n <svg *ngIf=\"isOptionSelected(opt)\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M10 3L4.5 8.5L2 6\" stroke=\"white\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </span>\n <span\n class=\"cqa-min-w-0 cqa-compare-runs\"\n *ngIf=\"hasHighlighting\"\n [style.color]=\"opt.statusColor || null\"\n [innerHTML]=\"highlightText(opt.name ?? opt.label ?? opt.value)\"></span>\n <ng-container *ngIf=\"!hasHighlighting\">\n <span\n class=\"cqa-min-w-0 cqa-compare-runs\"\n *ngIf=\"opt.runNumberLabel && opt.runDateLabel; else checkboxDefaultLabel\">\n <span [style.color]=\"opt.statusColor || null\">{{ opt.runNumberLabel }}</span>\n <span class=\"cqa-text-[#6B7280]\"> {{ opt.runDateLabel }}&nbsp;</span>\n </span>\n <ng-template #checkboxDefaultLabel>\n <span\n class=\"cqa-min-w-0 cqa-compare-runs\"\n [style.color]=\"opt.statusColor || null\">\n {{ opt.name ?? opt.label ?? opt.value }}\n </span>\n </ng-template>\n </ng-container>\n </span>\n <span\n *ngIf=\"opt.durationFormatted\"\n class=\"cqa-flex cqa-items-center cqa-justify-start cqa-gap-1 cqa-text-[12px] cqa-text-[#6B7280] cqa-flex-shrink-0 cqa-whitespace-nowrap cqa-max-w-[80px]\" \n [ngClass]=\"{\n 'cqa-min-w-[82px]': opt?.hasHourRun,\n 'cqa-min-w-[66px]': !opt?.hasHourRun && opt?.hasMinuteRun,\n 'cqa-min-w-[40px]': !opt?.hasHourRun && !opt?.hasMinuteRun\n }\">\n <svg class=\"cqa-min-w-[12px] cqa-max-w-[12px]\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"6\" r=\"4.5\" stroke=\"#9CA3AF\" stroke-width=\"1\"/>\n <path d=\"M6 3.5V6L7.5 7\" stroke=\"#4B5563\" stroke-width=\"1\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n <span>{{ opt.durationFormatted }}</span>\n </span>\n </span>\n </ng-container>\n <ng-template #compareRunsDefaultOptionTpl>\n <span class=\"cqa-flex cqa-items-center cqa-justify-between cqa-w-full cqa-compare-runs-item\">\n <span\n class=\"cqa-min-w-0 cqa-compare-runs\"\n *ngIf=\"hasHighlighting\"\n [style.color]=\"opt.statusColor || null\"\n [innerHTML]=\"highlightText(opt.name ?? opt.label ?? opt.value)\"></span>\n <ng-container *ngIf=\"!hasHighlighting\">\n <span\n class=\"cqa-min-w-0 cqa-compare-runs\"\n *ngIf=\"opt.runNumberLabel && opt.runDateLabel; else defaultLabel\">\n <span [style.color]=\"opt.statusColor || null\">{{ opt.runNumberLabel }}</span>\n <span class=\"cqa-text-[#6B7280]\"> {{ opt.runDateLabel }}&nbsp;</span>\n </span>\n <ng-template #defaultLabel>\n <span\n class=\"cqa-min-w-0 cqa-compare-runs\"\n [style.color]=\"opt.statusColor || null\">\n {{ opt.name ?? opt.label ?? opt.value }}\n </span>\n </ng-template>\n </ng-container>\n <span\n *ngIf=\"opt.durationFormatted\"\n class=\"cqa-flex cqa-items-center cqa-justify-start cqa-gap-1 cqa-text-[12px] cqa-text-[#6B7280] cqa-flex-shrink-0 cqa-whitespace-nowrap cqa-max-w-[80px]\" \n [ngClass]=\"{\n 'cqa-min-w-[82px]': opt?.hasHourRun,\n 'cqa-min-w-[66px]': !opt?.hasHourRun && opt?.hasMinuteRun,\n 'cqa-min-w-[40px]': !opt?.hasHourRun && !opt?.hasMinuteRun\n }\">\n <svg class=\"cqa-min-w-[12px] cqa-max-w-[12px]\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"6\" r=\"4.5\" stroke=\"#9CA3AF\" stroke-width=\"1\"/>\n <path d=\"M6 3.5V6L7.5 7\" stroke=\"#4B5563\" stroke-width=\"1\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n <span>{{ opt.durationFormatted }}</span>\n </span>\n </span>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"!config.isCompareRuns\">\n <ng-container *ngIf=\"useCheckboxStyle; else defaultOptionTpl\">\n <span class=\"cqa-flex cqa-items-center\">\n <span class=\"cqa-w-4 cqa-h-4 cqa-flex-shrink-0 cqa-rounded-[4px] cqa-border cqa-border-[#D1D5DB] cqa-mr-2 cqa-flex cqa-items-center cqa-justify-center cqa-border-solid\"\n [ngStyle]=\"isOptionSelected(opt) ? {'background-color':'#4F46E5','border-color':'#4F46E5'} : {}\">\n <svg *ngIf=\"isOptionSelected(opt)\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M10 3L4.5 8.5L2 6\" stroke=\"white\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </span>\n <!-- When displayLabelAsInnerHtml is true, render label as raw HTML -->\n <span class=\"cqa-min-w-0\"\n *ngIf=\"config?.displayLabelAsInnerHtml\"\n [innerHTML]=\"opt.label ?? opt.name ?? opt.value\">\n </span>\n <!-- Otherwise use normal/highlighted text rendering -->\n <span class=\"cqa-min-w-0\"\n *ngIf=\"!config?.displayLabelAsInnerHtml && hasHighlighting\"\n [innerHTML]=\"highlightText(opt.name ?? opt.label ?? opt.value)\">\n </span>\n <span class=\"cqa-min-w-0\"\n *ngIf=\"!config?.displayLabelAsInnerHtml && !hasHighlighting\">\n {{ opt.name ?? opt.label ?? opt.value }}\n </span>\n </span>\n </ng-container>\n <ng-template #defaultOptionTpl>\n <!-- When displayLabelAsInnerHtml is true, render label as raw HTML -->\n <span *ngIf=\"config?.displayLabelAsInnerHtml\"\n [innerHTML]=\"opt.label ?? opt.name ?? opt.value\">\n </span>\n <!-- Otherwise use normal/highlighted text rendering -->\n <span *ngIf=\"!config?.displayLabelAsInnerHtml && hasHighlighting\"\n [innerHTML]=\"highlightText(opt.name ?? opt.label ?? opt.value)\">\n </span>\n <span *ngIf=\"!config?.displayLabelAsInnerHtml && !hasHighlighting\">\n {{ opt.name ?? opt.label ?? opt.value }}\n </span>\n </ng-template>\n </ng-container>\n </mat-option>\n \n <!-- No results state (only when not loading and no options) -->\n <mat-option disabled *ngIf=\"!(config?.options?.length || 0) && !(config?.isLoading || loadingMore)\">\n No results\n </mat-option>\n <!-- Infinite scroll sentinel (serverSearch or explicit hasMore) -->\n <mat-option disabled class=\"load-more-sentinel\" *ngIf=\"config?.hasMore\">\n <span *ngIf=\"loadingMore || config?.isLoading\">Loading...</span>\n <span *ngIf=\"!loadingMore && !config?.isLoading\">Scroll to load more\u2026</span>\n </mat-option>\n </mat-select>\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <!-- Inline spinner shown when loading more (infinite scroll) or when config.isLoading is true -->\n <svg *ngIf=\"loadingMore || config?.isLoading\" width=\"16\" height=\"16\" viewBox=\"0 0 50 50\" aria-label=\"loading\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"25\" cy=\"25\" r=\"20\" stroke=\"#E5E7EB\" stroke-width=\"6\" fill=\"none\"/>\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\"\n dur=\"0.8s\" repeatCount=\"indefinite\"/>\n </path>\n </svg>\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M4 6L8 10L12 6\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </div>\n </mat-form-field>\n </ng-container>\n</div>", components: [{ type: i1$3.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i2$2.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { type: i3$2.MatOption, selector: "mat-option", exportAs: ["matOption"] }], directives: [{ type: i2$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i2$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i2$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2286
+ DynamicSelectFieldComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: DynamicSelectFieldComponent, selector: "cqa-dynamic-select", inputs: { form: "form", config: "config" }, outputs: { selectionChange: "selectionChange", selectClick: "selectClick", searchChange: "searchChange", loadMore: "loadMore" }, host: { listeners: { "document:click": "handleDocumentClick($event)" } }, viewQueries: [{ propertyName: "selectRef", first: true, predicate: ["selectRef"], descendants: true }, { propertyName: "hostEl", first: true, predicate: ["host"], descendants: true, read: ElementRef }], usesOnChanges: true, ngImport: i0, template: "<div class=\"cqa-ui-root\">\n <ng-container [formGroup]=\"form\">\n <label *ngIf=\"config.label\"\n class=\"form-label cqa-text-[#374151] cqa-text-[14px] cqa-font-medium cqa-block cqa-leading-[1.4] cqa-mb-2\">{{\n config.label }}</label>\n <mat-form-field #host class=\"mat-select-custom cqa-w-full\" appearance=\"fill\">\n <mat-select #selectRef=\"matSelect\" [placeholder]=\"displayPlaceholder\" [multiple]=\"isMultiple\"\n disableOptionCentering [panelClass]=\"panelClass\" [formControlName]=\"config.key\"\n (openedChange)=\"onSelectOpenedChange($event, selectRef)\" (selectionChange)=\"onSelectionChange($event, selectRef)\">\n\n <mat-option *ngIf=\"config.searchable\" class=\"ts-select-search\" disabled>\n <input class=\"ts-select-search-input cqa-text-black-100\" type=\"text\" [value]=\"searchTextByKey[config.key] || ''\"\n (click)=\"$event.stopPropagation()\" (mousedown)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\" (input)=\"onSearch(config.key, $any($event.target).value)\"\n placeholder=\"Search...\" />\n </mat-option>\n \n <mat-option [ngClass]=\"{'checkmark': config.optionStyle === 'checkmark','checkbox': config.optionStyle !== 'checkmark','mat-selected': allSelected}\" [class]=\"config.optionStyle == 'checkmark' ? 'checkmark' : 'checkbox'\" *ngIf=\"isMultiple && config.showSelectAll\" [value]=\"SELECT_ALL_VALUE\">\n <ng-container *ngIf=\"useCheckboxStyle; else selectAllDefaultTpl\">\n <span class=\"cqa-flex cqa-items-center\">\n <span class=\"cqa-w-4 cqa-h-4 cqa-flex-shrink-0 cqa-rounded-[4px] cqa-border cqa-border-[#D1D5DB] cqa-mr-2 cqa-flex cqa-items-center cqa-justify-center cqa-border-solid\"\n [ngStyle]=\"allSelected ? {'background-color':'#4F46E5','border-color':'#4F46E5'} : {}\">\n <svg *ngIf=\"allSelected\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M10 3L4.5 8.5L2 6\" stroke=\"white\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </span>\n <span class=\"cqa-min-w-0\">{{ config.selectAllLabel || 'All' }}</span>\n </span>\n </ng-container>\n <ng-template #selectAllDefaultTpl>\n {{ config.selectAllLabel || 'All' }}\n </ng-template>\n </mat-option>\n\n <mat-option [class]=\"config.optionStyle == 'checkmark' ? 'checkmark' : 'checkbox'\" *ngFor=\"let opt of filteredOptions(config)\" [value]=\"opt.id ?? opt.value\">\n <ng-container *ngIf=\"config.isCompareRuns\"> \n <ng-container *ngIf=\"useCheckboxStyle; else compareRunsDefaultOptionTpl\">\n <span class=\"cqa-flex cqa-items-center cqa-justify-between cqa-w-full cqa-compare-runs-item\">\n <span class=\"cqa-flex cqa-items-center\">\n <span class=\"cqa-w-4 cqa-h-4 cqa-flex-shrink-0 cqa-rounded-[4px] cqa-border cqa-border-[#D1D5DB] cqa-mr-2 cqa-flex cqa-items-center cqa-justify-center cqa-border-solid\"\n [ngStyle]=\"isOptionSelected(opt) ? {'background-color':'#4F46E5','border-color':'#4F46E5'} : {}\">\n <svg *ngIf=\"isOptionSelected(opt)\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M10 3L4.5 8.5L2 6\" stroke=\"white\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </span>\n <span\n class=\"cqa-min-w-0 cqa-compare-runs\"\n *ngIf=\"hasHighlighting\"\n [style.color]=\"opt.statusColor || null\"\n [innerHTML]=\"highlightText(opt.name ?? opt.label ?? opt.value)\"></span>\n <ng-container *ngIf=\"!hasHighlighting\">\n <span\n class=\"cqa-min-w-0 cqa-compare-runs\"\n *ngIf=\"opt.runNumberLabel && opt.runDateLabel; else checkboxDefaultLabel\">\n <span [style.color]=\"opt.statusColor || null\">{{ opt.runNumberLabel }}</span>\n <span class=\"cqa-text-[#6B7280]\"> {{ opt.runDateLabel }}&nbsp;</span>\n </span>\n <ng-template #checkboxDefaultLabel>\n <span\n class=\"cqa-min-w-0 cqa-compare-runs\"\n [style.color]=\"opt.statusColor || null\">\n {{ opt.name ?? opt.label ?? opt.value }}\n </span>\n </ng-template>\n </ng-container>\n </span>\n <span\n *ngIf=\"opt.durationFormatted\"\n class=\"cqa-flex cqa-items-center cqa-justify-start cqa-gap-1 cqa-text-[12px] cqa-text-[#6B7280] cqa-flex-shrink-0 cqa-whitespace-nowrap cqa-max-w-[80px]\" \n [ngClass]=\"{\n 'cqa-min-w-[82px]': opt?.hasHourRun,\n 'cqa-min-w-[66px]': !opt?.hasHourRun && opt?.hasMinuteRun,\n 'cqa-min-w-[40px]': !opt?.hasHourRun && !opt?.hasMinuteRun\n }\">\n <svg class=\"cqa-min-w-[12px] cqa-max-w-[12px]\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"6\" r=\"4.5\" stroke=\"#9CA3AF\" stroke-width=\"1\"/>\n <path d=\"M6 3.5V6L7.5 7\" stroke=\"#4B5563\" stroke-width=\"1\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n <span>{{ opt.durationFormatted }}</span>\n </span>\n </span>\n </ng-container>\n <ng-template #compareRunsDefaultOptionTpl>\n <span class=\"cqa-flex cqa-items-center cqa-justify-between cqa-w-full cqa-compare-runs-item\">\n <span\n class=\"cqa-min-w-0 cqa-compare-runs\"\n *ngIf=\"hasHighlighting\"\n [style.color]=\"opt.statusColor || null\"\n [innerHTML]=\"highlightText(opt.name ?? opt.label ?? opt.value)\"></span>\n <ng-container *ngIf=\"!hasHighlighting\">\n <span\n class=\"cqa-min-w-0 cqa-compare-runs\"\n *ngIf=\"opt.runNumberLabel && opt.runDateLabel; else defaultLabel\">\n <span [style.color]=\"opt.statusColor || null\">{{ opt.runNumberLabel }}</span>\n <span class=\"cqa-text-[#6B7280]\"> {{ opt.runDateLabel }}&nbsp;</span>\n </span>\n <ng-template #defaultLabel>\n <span\n class=\"cqa-min-w-0 cqa-compare-runs\"\n [style.color]=\"opt.statusColor || null\">\n {{ opt.name ?? opt.label ?? opt.value }}\n </span>\n </ng-template>\n </ng-container>\n <span\n *ngIf=\"opt.durationFormatted\"\n class=\"cqa-flex cqa-items-center cqa-justify-start cqa-gap-1 cqa-text-[12px] cqa-text-[#6B7280] cqa-flex-shrink-0 cqa-whitespace-nowrap cqa-max-w-[80px]\" \n [ngClass]=\"{\n 'cqa-min-w-[82px]': opt?.hasHourRun,\n 'cqa-min-w-[66px]': !opt?.hasHourRun && opt?.hasMinuteRun,\n 'cqa-min-w-[40px]': !opt?.hasHourRun && !opt?.hasMinuteRun\n }\">\n <svg class=\"cqa-min-w-[12px] cqa-max-w-[12px]\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"6\" r=\"4.5\" stroke=\"#9CA3AF\" stroke-width=\"1\"/>\n <path d=\"M6 3.5V6L7.5 7\" stroke=\"#4B5563\" stroke-width=\"1\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n <span>{{ opt.durationFormatted }}</span>\n </span>\n </span>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"!config.isCompareRuns\">\n <ng-container *ngIf=\"useCheckboxStyle; else defaultOptionTpl\">\n <span class=\"cqa-flex cqa-items-center\">\n <span class=\"cqa-w-4 cqa-h-4 cqa-flex-shrink-0 cqa-rounded-[4px] cqa-border cqa-border-[#D1D5DB] cqa-mr-2 cqa-flex cqa-items-center cqa-justify-center cqa-border-solid\"\n [ngStyle]=\"isOptionSelected(opt) ? {'background-color':'#4F46E5','border-color':'#4F46E5'} : {}\">\n <svg *ngIf=\"isOptionSelected(opt)\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M10 3L4.5 8.5L2 6\" stroke=\"white\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </span>\n <!-- When displayLabelAsInnerHtml is true, render label as raw HTML -->\n <span class=\"cqa-min-w-0\"\n *ngIf=\"config?.displayLabelAsInnerHtml\"\n [innerHTML]=\"opt.label ?? opt.name ?? opt.value\">\n </span>\n <!-- Otherwise use normal/highlighted text rendering -->\n <span class=\"cqa-min-w-0\"\n *ngIf=\"!config?.displayLabelAsInnerHtml && hasHighlighting\"\n [innerHTML]=\"highlightText(opt.name ?? opt.label ?? opt.value)\">\n </span>\n <span class=\"cqa-min-w-0\"\n *ngIf=\"!config?.displayLabelAsInnerHtml && !hasHighlighting\">\n {{ opt.name ?? opt.label ?? opt.value }}\n </span>\n </span>\n </ng-container>\n <ng-template #defaultOptionTpl>\n <!-- When displayLabelAsInnerHtml is true, render label as raw HTML -->\n <span *ngIf=\"config?.displayLabelAsInnerHtml\"\n [innerHTML]=\"opt.label ?? opt.name ?? opt.value\">\n </span>\n <!-- Otherwise use normal/highlighted text rendering -->\n <span *ngIf=\"!config?.displayLabelAsInnerHtml && hasHighlighting\"\n [innerHTML]=\"highlightText(opt.name ?? opt.label ?? opt.value)\">\n </span>\n <span *ngIf=\"!config?.displayLabelAsInnerHtml && !hasHighlighting\">\n {{ opt.name ?? opt.label ?? opt.value }}\n </span>\n </ng-template>\n </ng-container>\n </mat-option>\n \n <!-- No results state (only when not loading and no options) -->\n <mat-option disabled *ngIf=\"!(config?.options?.length || 0) && !(config?.isLoading || loadingMore)\">\n No results\n </mat-option>\n <!-- Infinite scroll sentinel (serverSearch or explicit hasMore) -->\n <mat-option disabled class=\"load-more-sentinel\" *ngIf=\"config?.hasMore\">\n <span *ngIf=\"loadingMore || config?.isLoading\">Loading...</span>\n <span *ngIf=\"!loadingMore && !config?.isLoading\">Scroll to load more\u2026</span>\n </mat-option>\n </mat-select>\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <!-- Inline spinner shown when loading more (infinite scroll) or when config.isLoading is true -->\n <svg *ngIf=\"loadingMore || config?.isLoading\" width=\"16\" height=\"16\" viewBox=\"0 0 50 50\" aria-label=\"loading\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"25\" cy=\"25\" r=\"20\" stroke=\"#E5E7EB\" stroke-width=\"6\" fill=\"none\"/>\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\"\n dur=\"0.8s\" repeatCount=\"indefinite\"/>\n </path>\n </svg>\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M4 6L8 10L12 6\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </div>\n </mat-form-field>\n </ng-container>\n</div>", components: [{ type: i1$3.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i2$2.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { type: i3$2.MatOption, selector: "mat-option", exportAs: ["matOption"] }], directives: [{ type: i2$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i2$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i2$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2262
2287
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DynamicSelectFieldComponent, decorators: [{
2263
2288
  type: Component,
2264
- args: [{ selector: 'cqa-dynamic-select', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"cqa-ui-root\">\n <ng-container [formGroup]=\"form\">\n <label *ngIf=\"config.label\"\n class=\"form-label cqa-text-[#374151] cqa-text-[14px] cqa-font-medium cqa-block cqa-leading-[1.4] cqa-mb-2\">{{\n config.label }}</label>\n <mat-form-field #host class=\"mat-select-custom cqa-w-full\" appearance=\"fill\">\n <mat-select #selectRef=\"matSelect\" [placeholder]=\"displayPlaceholder\" [disabled]=\"isDisabled\" [multiple]=\"isMultiple\"\n disableOptionCentering [panelClass]=\"panelClass\" [formControlName]=\"config.key\"\n (openedChange)=\"onSelectOpenedChange($event, selectRef)\" (selectionChange)=\"onSelectionChange($event, selectRef)\">\n\n <mat-option *ngIf=\"config.searchable\" class=\"ts-select-search\" disabled>\n <input class=\"ts-select-search-input cqa-text-black-100\" type=\"text\" [value]=\"searchTextByKey[config.key] || ''\"\n (click)=\"$event.stopPropagation()\" (mousedown)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\" (input)=\"onSearch(config.key, $any($event.target).value)\"\n placeholder=\"Search...\" />\n </mat-option>\n \n <mat-option [ngClass]=\"{'checkmark': config.optionStyle === 'checkmark','checkbox': config.optionStyle !== 'checkmark','mat-selected': allSelected}\" [class]=\"config.optionStyle == 'checkmark' ? 'checkmark' : 'checkbox'\" *ngIf=\"isMultiple && config.showSelectAll\" [value]=\"SELECT_ALL_VALUE\">\n <ng-container *ngIf=\"useCheckboxStyle; else selectAllDefaultTpl\">\n <span class=\"cqa-flex cqa-items-center\">\n <span class=\"cqa-w-4 cqa-h-4 cqa-flex-shrink-0 cqa-rounded-[4px] cqa-border cqa-border-[#D1D5DB] cqa-mr-2 cqa-flex cqa-items-center cqa-justify-center cqa-border-solid\"\n [ngStyle]=\"allSelected ? {'background-color':'#4F46E5','border-color':'#4F46E5'} : {}\">\n <svg *ngIf=\"allSelected\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M10 3L4.5 8.5L2 6\" stroke=\"white\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </span>\n <span class=\"cqa-min-w-0\">{{ config.selectAllLabel || 'All' }}</span>\n </span>\n </ng-container>\n <ng-template #selectAllDefaultTpl>\n {{ config.selectAllLabel || 'All' }}\n </ng-template>\n </mat-option>\n\n <mat-option [class]=\"config.optionStyle == 'checkmark' ? 'checkmark' : 'checkbox'\" *ngFor=\"let opt of filteredOptions(config)\" [value]=\"opt.id ?? opt.value\">\n <ng-container *ngIf=\"config.isCompareRuns\"> \n <ng-container *ngIf=\"useCheckboxStyle; else compareRunsDefaultOptionTpl\">\n <span class=\"cqa-flex cqa-items-center cqa-justify-between cqa-w-full cqa-compare-runs-item\">\n <span class=\"cqa-flex cqa-items-center\">\n <span class=\"cqa-w-4 cqa-h-4 cqa-flex-shrink-0 cqa-rounded-[4px] cqa-border cqa-border-[#D1D5DB] cqa-mr-2 cqa-flex cqa-items-center cqa-justify-center cqa-border-solid\"\n [ngStyle]=\"isOptionSelected(opt) ? {'background-color':'#4F46E5','border-color':'#4F46E5'} : {}\">\n <svg *ngIf=\"isOptionSelected(opt)\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M10 3L4.5 8.5L2 6\" stroke=\"white\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </span>\n <span\n class=\"cqa-min-w-0 cqa-compare-runs\"\n *ngIf=\"hasHighlighting\"\n [style.color]=\"opt.statusColor || null\"\n [innerHTML]=\"highlightText(opt.name ?? opt.label ?? opt.value)\"></span>\n <ng-container *ngIf=\"!hasHighlighting\">\n <span\n class=\"cqa-min-w-0 cqa-compare-runs\"\n *ngIf=\"opt.runNumberLabel && opt.runDateLabel; else checkboxDefaultLabel\">\n <span [style.color]=\"opt.statusColor || null\">{{ opt.runNumberLabel }}</span>\n <span class=\"cqa-text-[#6B7280]\"> {{ opt.runDateLabel }}&nbsp;</span>\n </span>\n <ng-template #checkboxDefaultLabel>\n <span\n class=\"cqa-min-w-0 cqa-compare-runs\"\n [style.color]=\"opt.statusColor || null\">\n {{ opt.name ?? opt.label ?? opt.value }}\n </span>\n </ng-template>\n </ng-container>\n </span>\n <span\n *ngIf=\"opt.durationFormatted\"\n class=\"cqa-flex cqa-items-center cqa-justify-start cqa-gap-1 cqa-text-[12px] cqa-text-[#6B7280] cqa-flex-shrink-0 cqa-whitespace-nowrap cqa-max-w-[80px]\" \n [ngClass]=\"{\n 'cqa-min-w-[82px]': opt?.hasHourRun,\n 'cqa-min-w-[66px]': !opt?.hasHourRun && opt?.hasMinuteRun,\n 'cqa-min-w-[40px]': !opt?.hasHourRun && !opt?.hasMinuteRun\n }\">\n <svg class=\"cqa-min-w-[12px] cqa-max-w-[12px]\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"6\" r=\"4.5\" stroke=\"#9CA3AF\" stroke-width=\"1\"/>\n <path d=\"M6 3.5V6L7.5 7\" stroke=\"#4B5563\" stroke-width=\"1\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n <span>{{ opt.durationFormatted }}</span>\n </span>\n </span>\n </ng-container>\n <ng-template #compareRunsDefaultOptionTpl>\n <span class=\"cqa-flex cqa-items-center cqa-justify-between cqa-w-full cqa-compare-runs-item\">\n <span\n class=\"cqa-min-w-0 cqa-compare-runs\"\n *ngIf=\"hasHighlighting\"\n [style.color]=\"opt.statusColor || null\"\n [innerHTML]=\"highlightText(opt.name ?? opt.label ?? opt.value)\"></span>\n <ng-container *ngIf=\"!hasHighlighting\">\n <span\n class=\"cqa-min-w-0 cqa-compare-runs\"\n *ngIf=\"opt.runNumberLabel && opt.runDateLabel; else defaultLabel\">\n <span [style.color]=\"opt.statusColor || null\">{{ opt.runNumberLabel }}</span>\n <span class=\"cqa-text-[#6B7280]\"> {{ opt.runDateLabel }}&nbsp;</span>\n </span>\n <ng-template #defaultLabel>\n <span\n class=\"cqa-min-w-0 cqa-compare-runs\"\n [style.color]=\"opt.statusColor || null\">\n {{ opt.name ?? opt.label ?? opt.value }}\n </span>\n </ng-template>\n </ng-container>\n <span\n *ngIf=\"opt.durationFormatted\"\n class=\"cqa-flex cqa-items-center cqa-justify-start cqa-gap-1 cqa-text-[12px] cqa-text-[#6B7280] cqa-flex-shrink-0 cqa-whitespace-nowrap cqa-max-w-[80px]\" \n [ngClass]=\"{\n 'cqa-min-w-[82px]': opt?.hasHourRun,\n 'cqa-min-w-[66px]': !opt?.hasHourRun && opt?.hasMinuteRun,\n 'cqa-min-w-[40px]': !opt?.hasHourRun && !opt?.hasMinuteRun\n }\">\n <svg class=\"cqa-min-w-[12px] cqa-max-w-[12px]\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"6\" r=\"4.5\" stroke=\"#9CA3AF\" stroke-width=\"1\"/>\n <path d=\"M6 3.5V6L7.5 7\" stroke=\"#4B5563\" stroke-width=\"1\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n <span>{{ opt.durationFormatted }}</span>\n </span>\n </span>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"!config.isCompareRuns\">\n <ng-container *ngIf=\"useCheckboxStyle; else defaultOptionTpl\">\n <span class=\"cqa-flex cqa-items-center\">\n <span class=\"cqa-w-4 cqa-h-4 cqa-flex-shrink-0 cqa-rounded-[4px] cqa-border cqa-border-[#D1D5DB] cqa-mr-2 cqa-flex cqa-items-center cqa-justify-center cqa-border-solid\"\n [ngStyle]=\"isOptionSelected(opt) ? {'background-color':'#4F46E5','border-color':'#4F46E5'} : {}\">\n <svg *ngIf=\"isOptionSelected(opt)\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M10 3L4.5 8.5L2 6\" stroke=\"white\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </span>\n <!-- When displayLabelAsInnerHtml is true, render label as raw HTML -->\n <span class=\"cqa-min-w-0\"\n *ngIf=\"config?.displayLabelAsInnerHtml\"\n [innerHTML]=\"opt.label ?? opt.name ?? opt.value\">\n </span>\n <!-- Otherwise use normal/highlighted text rendering -->\n <span class=\"cqa-min-w-0\"\n *ngIf=\"!config?.displayLabelAsInnerHtml && hasHighlighting\"\n [innerHTML]=\"highlightText(opt.name ?? opt.label ?? opt.value)\">\n </span>\n <span class=\"cqa-min-w-0\"\n *ngIf=\"!config?.displayLabelAsInnerHtml && !hasHighlighting\">\n {{ opt.name ?? opt.label ?? opt.value }}\n </span>\n </span>\n </ng-container>\n <ng-template #defaultOptionTpl>\n <!-- When displayLabelAsInnerHtml is true, render label as raw HTML -->\n <span *ngIf=\"config?.displayLabelAsInnerHtml\"\n [innerHTML]=\"opt.label ?? opt.name ?? opt.value\">\n </span>\n <!-- Otherwise use normal/highlighted text rendering -->\n <span *ngIf=\"!config?.displayLabelAsInnerHtml && hasHighlighting\"\n [innerHTML]=\"highlightText(opt.name ?? opt.label ?? opt.value)\">\n </span>\n <span *ngIf=\"!config?.displayLabelAsInnerHtml && !hasHighlighting\">\n {{ opt.name ?? opt.label ?? opt.value }}\n </span>\n </ng-template>\n </ng-container>\n </mat-option>\n \n <!-- No results state (only when not loading and no options) -->\n <mat-option disabled *ngIf=\"!(config?.options?.length || 0) && !(config?.isLoading || loadingMore)\">\n No results\n </mat-option>\n <!-- Infinite scroll sentinel (serverSearch or explicit hasMore) -->\n <mat-option disabled class=\"load-more-sentinel\" *ngIf=\"config?.hasMore\">\n <span *ngIf=\"loadingMore || config?.isLoading\">Loading...</span>\n <span *ngIf=\"!loadingMore && !config?.isLoading\">Scroll to load more\u2026</span>\n </mat-option>\n </mat-select>\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <!-- Inline spinner shown when loading more (infinite scroll) or when config.isLoading is true -->\n <svg *ngIf=\"loadingMore || config?.isLoading\" width=\"16\" height=\"16\" viewBox=\"0 0 50 50\" aria-label=\"loading\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"25\" cy=\"25\" r=\"20\" stroke=\"#E5E7EB\" stroke-width=\"6\" fill=\"none\"/>\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\"\n dur=\"0.8s\" repeatCount=\"indefinite\"/>\n </path>\n </svg>\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M4 6L8 10L12 6\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </div>\n </mat-form-field>\n </ng-container>\n</div>" }]
2289
+ args: [{ selector: 'cqa-dynamic-select', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"cqa-ui-root\">\n <ng-container [formGroup]=\"form\">\n <label *ngIf=\"config.label\"\n class=\"form-label cqa-text-[#374151] cqa-text-[14px] cqa-font-medium cqa-block cqa-leading-[1.4] cqa-mb-2\">{{\n config.label }}</label>\n <mat-form-field #host class=\"mat-select-custom cqa-w-full\" appearance=\"fill\">\n <mat-select #selectRef=\"matSelect\" [placeholder]=\"displayPlaceholder\" [multiple]=\"isMultiple\"\n disableOptionCentering [panelClass]=\"panelClass\" [formControlName]=\"config.key\"\n (openedChange)=\"onSelectOpenedChange($event, selectRef)\" (selectionChange)=\"onSelectionChange($event, selectRef)\">\n\n <mat-option *ngIf=\"config.searchable\" class=\"ts-select-search\" disabled>\n <input class=\"ts-select-search-input cqa-text-black-100\" type=\"text\" [value]=\"searchTextByKey[config.key] || ''\"\n (click)=\"$event.stopPropagation()\" (mousedown)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\" (input)=\"onSearch(config.key, $any($event.target).value)\"\n placeholder=\"Search...\" />\n </mat-option>\n \n <mat-option [ngClass]=\"{'checkmark': config.optionStyle === 'checkmark','checkbox': config.optionStyle !== 'checkmark','mat-selected': allSelected}\" [class]=\"config.optionStyle == 'checkmark' ? 'checkmark' : 'checkbox'\" *ngIf=\"isMultiple && config.showSelectAll\" [value]=\"SELECT_ALL_VALUE\">\n <ng-container *ngIf=\"useCheckboxStyle; else selectAllDefaultTpl\">\n <span class=\"cqa-flex cqa-items-center\">\n <span class=\"cqa-w-4 cqa-h-4 cqa-flex-shrink-0 cqa-rounded-[4px] cqa-border cqa-border-[#D1D5DB] cqa-mr-2 cqa-flex cqa-items-center cqa-justify-center cqa-border-solid\"\n [ngStyle]=\"allSelected ? {'background-color':'#4F46E5','border-color':'#4F46E5'} : {}\">\n <svg *ngIf=\"allSelected\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M10 3L4.5 8.5L2 6\" stroke=\"white\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </span>\n <span class=\"cqa-min-w-0\">{{ config.selectAllLabel || 'All' }}</span>\n </span>\n </ng-container>\n <ng-template #selectAllDefaultTpl>\n {{ config.selectAllLabel || 'All' }}\n </ng-template>\n </mat-option>\n\n <mat-option [class]=\"config.optionStyle == 'checkmark' ? 'checkmark' : 'checkbox'\" *ngFor=\"let opt of filteredOptions(config)\" [value]=\"opt.id ?? opt.value\">\n <ng-container *ngIf=\"config.isCompareRuns\"> \n <ng-container *ngIf=\"useCheckboxStyle; else compareRunsDefaultOptionTpl\">\n <span class=\"cqa-flex cqa-items-center cqa-justify-between cqa-w-full cqa-compare-runs-item\">\n <span class=\"cqa-flex cqa-items-center\">\n <span class=\"cqa-w-4 cqa-h-4 cqa-flex-shrink-0 cqa-rounded-[4px] cqa-border cqa-border-[#D1D5DB] cqa-mr-2 cqa-flex cqa-items-center cqa-justify-center cqa-border-solid\"\n [ngStyle]=\"isOptionSelected(opt) ? {'background-color':'#4F46E5','border-color':'#4F46E5'} : {}\">\n <svg *ngIf=\"isOptionSelected(opt)\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M10 3L4.5 8.5L2 6\" stroke=\"white\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </span>\n <span\n class=\"cqa-min-w-0 cqa-compare-runs\"\n *ngIf=\"hasHighlighting\"\n [style.color]=\"opt.statusColor || null\"\n [innerHTML]=\"highlightText(opt.name ?? opt.label ?? opt.value)\"></span>\n <ng-container *ngIf=\"!hasHighlighting\">\n <span\n class=\"cqa-min-w-0 cqa-compare-runs\"\n *ngIf=\"opt.runNumberLabel && opt.runDateLabel; else checkboxDefaultLabel\">\n <span [style.color]=\"opt.statusColor || null\">{{ opt.runNumberLabel }}</span>\n <span class=\"cqa-text-[#6B7280]\"> {{ opt.runDateLabel }}&nbsp;</span>\n </span>\n <ng-template #checkboxDefaultLabel>\n <span\n class=\"cqa-min-w-0 cqa-compare-runs\"\n [style.color]=\"opt.statusColor || null\">\n {{ opt.name ?? opt.label ?? opt.value }}\n </span>\n </ng-template>\n </ng-container>\n </span>\n <span\n *ngIf=\"opt.durationFormatted\"\n class=\"cqa-flex cqa-items-center cqa-justify-start cqa-gap-1 cqa-text-[12px] cqa-text-[#6B7280] cqa-flex-shrink-0 cqa-whitespace-nowrap cqa-max-w-[80px]\" \n [ngClass]=\"{\n 'cqa-min-w-[82px]': opt?.hasHourRun,\n 'cqa-min-w-[66px]': !opt?.hasHourRun && opt?.hasMinuteRun,\n 'cqa-min-w-[40px]': !opt?.hasHourRun && !opt?.hasMinuteRun\n }\">\n <svg class=\"cqa-min-w-[12px] cqa-max-w-[12px]\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"6\" r=\"4.5\" stroke=\"#9CA3AF\" stroke-width=\"1\"/>\n <path d=\"M6 3.5V6L7.5 7\" stroke=\"#4B5563\" stroke-width=\"1\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n <span>{{ opt.durationFormatted }}</span>\n </span>\n </span>\n </ng-container>\n <ng-template #compareRunsDefaultOptionTpl>\n <span class=\"cqa-flex cqa-items-center cqa-justify-between cqa-w-full cqa-compare-runs-item\">\n <span\n class=\"cqa-min-w-0 cqa-compare-runs\"\n *ngIf=\"hasHighlighting\"\n [style.color]=\"opt.statusColor || null\"\n [innerHTML]=\"highlightText(opt.name ?? opt.label ?? opt.value)\"></span>\n <ng-container *ngIf=\"!hasHighlighting\">\n <span\n class=\"cqa-min-w-0 cqa-compare-runs\"\n *ngIf=\"opt.runNumberLabel && opt.runDateLabel; else defaultLabel\">\n <span [style.color]=\"opt.statusColor || null\">{{ opt.runNumberLabel }}</span>\n <span class=\"cqa-text-[#6B7280]\"> {{ opt.runDateLabel }}&nbsp;</span>\n </span>\n <ng-template #defaultLabel>\n <span\n class=\"cqa-min-w-0 cqa-compare-runs\"\n [style.color]=\"opt.statusColor || null\">\n {{ opt.name ?? opt.label ?? opt.value }}\n </span>\n </ng-template>\n </ng-container>\n <span\n *ngIf=\"opt.durationFormatted\"\n class=\"cqa-flex cqa-items-center cqa-justify-start cqa-gap-1 cqa-text-[12px] cqa-text-[#6B7280] cqa-flex-shrink-0 cqa-whitespace-nowrap cqa-max-w-[80px]\" \n [ngClass]=\"{\n 'cqa-min-w-[82px]': opt?.hasHourRun,\n 'cqa-min-w-[66px]': !opt?.hasHourRun && opt?.hasMinuteRun,\n 'cqa-min-w-[40px]': !opt?.hasHourRun && !opt?.hasMinuteRun\n }\">\n <svg class=\"cqa-min-w-[12px] cqa-max-w-[12px]\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"6\" r=\"4.5\" stroke=\"#9CA3AF\" stroke-width=\"1\"/>\n <path d=\"M6 3.5V6L7.5 7\" stroke=\"#4B5563\" stroke-width=\"1\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n <span>{{ opt.durationFormatted }}</span>\n </span>\n </span>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"!config.isCompareRuns\">\n <ng-container *ngIf=\"useCheckboxStyle; else defaultOptionTpl\">\n <span class=\"cqa-flex cqa-items-center\">\n <span class=\"cqa-w-4 cqa-h-4 cqa-flex-shrink-0 cqa-rounded-[4px] cqa-border cqa-border-[#D1D5DB] cqa-mr-2 cqa-flex cqa-items-center cqa-justify-center cqa-border-solid\"\n [ngStyle]=\"isOptionSelected(opt) ? {'background-color':'#4F46E5','border-color':'#4F46E5'} : {}\">\n <svg *ngIf=\"isOptionSelected(opt)\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M10 3L4.5 8.5L2 6\" stroke=\"white\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </span>\n <!-- When displayLabelAsInnerHtml is true, render label as raw HTML -->\n <span class=\"cqa-min-w-0\"\n *ngIf=\"config?.displayLabelAsInnerHtml\"\n [innerHTML]=\"opt.label ?? opt.name ?? opt.value\">\n </span>\n <!-- Otherwise use normal/highlighted text rendering -->\n <span class=\"cqa-min-w-0\"\n *ngIf=\"!config?.displayLabelAsInnerHtml && hasHighlighting\"\n [innerHTML]=\"highlightText(opt.name ?? opt.label ?? opt.value)\">\n </span>\n <span class=\"cqa-min-w-0\"\n *ngIf=\"!config?.displayLabelAsInnerHtml && !hasHighlighting\">\n {{ opt.name ?? opt.label ?? opt.value }}\n </span>\n </span>\n </ng-container>\n <ng-template #defaultOptionTpl>\n <!-- When displayLabelAsInnerHtml is true, render label as raw HTML -->\n <span *ngIf=\"config?.displayLabelAsInnerHtml\"\n [innerHTML]=\"opt.label ?? opt.name ?? opt.value\">\n </span>\n <!-- Otherwise use normal/highlighted text rendering -->\n <span *ngIf=\"!config?.displayLabelAsInnerHtml && hasHighlighting\"\n [innerHTML]=\"highlightText(opt.name ?? opt.label ?? opt.value)\">\n </span>\n <span *ngIf=\"!config?.displayLabelAsInnerHtml && !hasHighlighting\">\n {{ opt.name ?? opt.label ?? opt.value }}\n </span>\n </ng-template>\n </ng-container>\n </mat-option>\n \n <!-- No results state (only when not loading and no options) -->\n <mat-option disabled *ngIf=\"!(config?.options?.length || 0) && !(config?.isLoading || loadingMore)\">\n No results\n </mat-option>\n <!-- Infinite scroll sentinel (serverSearch or explicit hasMore) -->\n <mat-option disabled class=\"load-more-sentinel\" *ngIf=\"config?.hasMore\">\n <span *ngIf=\"loadingMore || config?.isLoading\">Loading...</span>\n <span *ngIf=\"!loadingMore && !config?.isLoading\">Scroll to load more\u2026</span>\n </mat-option>\n </mat-select>\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <!-- Inline spinner shown when loading more (infinite scroll) or when config.isLoading is true -->\n <svg *ngIf=\"loadingMore || config?.isLoading\" width=\"16\" height=\"16\" viewBox=\"0 0 50 50\" aria-label=\"loading\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"25\" cy=\"25\" r=\"20\" stroke=\"#E5E7EB\" stroke-width=\"6\" fill=\"none\"/>\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\"\n dur=\"0.8s\" repeatCount=\"indefinite\"/>\n </path>\n </svg>\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M4 6L8 10L12 6\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </div>\n </mat-form-field>\n </ng-container>\n</div>" }]
2265
2290
  }], propDecorators: { form: [{
2266
2291
  type: Input
2267
2292
  }], config: [{
@@ -5865,7 +5890,8 @@ class TailwindOverlayContainer extends OverlayContainer {
5865
5890
  pane.classList.contains('ctc-date-range-panel') ||
5866
5891
  pane.classList.contains('visual-difference-dialog') ||
5867
5892
  pane.classList.contains('cqa-custom-edit-step-panel') ||
5868
- pane.classList.contains('cqa-test-data-modal-panel');
5893
+ pane.classList.contains('cqa-test-data-modal-panel') ||
5894
+ pane.classList.contains('cqa-step-details-drawer-panel');
5869
5895
  // Also check for library components inside the pane
5870
5896
  // These classes may be on child elements rather than the pane itself
5871
5897
  const hasLibraryDialogInside = pane.querySelector('.cqa-dialog-panel') !== null;
@@ -5878,10 +5904,12 @@ class TailwindOverlayContainer extends OverlayContainer {
5878
5904
  pane.querySelector('cqa-custom-edit-step') !== null;
5879
5905
  const hasTestDataModalInside = pane.querySelector('.cqa-test-data-modal-panel') !== null ||
5880
5906
  pane.querySelector('cqa-test-data-modal') !== null;
5907
+ const hasStepDetailsDrawerInside = pane.querySelector('.cqa-step-details-drawer-panel') !== null ||
5908
+ pane.querySelector('cqa-step-details-drawer') !== null;
5881
5909
  const isLibraryOverlay = paneHasLibraryClass || hasLibraryDialogInside ||
5882
5910
  hasLibrarySelectInside || hasLibraryDatePickerInside ||
5883
5911
  hasVisualDifferenceDialogInside || hasCustomEditStepInside ||
5884
- hasTestDataModalInside;
5912
+ hasTestDataModalInside || hasStepDetailsDrawerInside;
5885
5913
  if (isLibraryOverlay) {
5886
5914
  // This is a library overlay - add the class
5887
5915
  pane.classList.add('cqa-ui-root');
@@ -22068,6 +22096,506 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
22068
22096
  type: Output
22069
22097
  }] } });
22070
22098
 
22099
+ /**
22100
+ * Configuration for Step Details Drawer (Edit In Depth).
22101
+ * Form is fully dynamic by Step Type – no hardcoded field lists.
22102
+ */
22103
+ /**
22104
+ * Resolves drawer step type from a test case step config.
22105
+ */
22106
+ function getStepDetailsStepType(step) {
22107
+ if (!step)
22108
+ return null;
22109
+ if (isApiStepConfig(step))
22110
+ return 'api';
22111
+ if (isAiAgentStepConfig(step))
22112
+ return 'aiAgent';
22113
+ if (isNormalStepConfig(step) && step.eventType === 'custom')
22114
+ return 'custom';
22115
+ return null;
22116
+ }
22117
+ /**
22118
+ * Fields shown per step type (configuration-based).
22119
+ * Custom: Description, Metadata, Retry Count (if configured), Advanced (if configured).
22120
+ * API: Method, URL, Headers, Body, Save Output as Variable, Advanced (if configured).
22121
+ * AI Agent: Agent Task, Type, Metadata, Environment, Description, Constraints (toggles + Max Retries), Advanced (toggles + Retry Count, Iframe locator, Other Locators).
22122
+ */
22123
+ const STEP_DETAILS_FIELDS_BY_TYPE = {
22124
+ custom: ['description', 'metadata', 'retryCount', 'advanced'],
22125
+ api: ['method', 'url', 'headers', 'body', 'saveOutputAsVariable', 'advanced'],
22126
+ aiAgent: [
22127
+ 'agentTask',
22128
+ 'type',
22129
+ 'metadata',
22130
+ 'environment',
22131
+ 'description',
22132
+ 'onlyUseAttachedContext',
22133
+ 'takeScreenshotsWhenVerifying',
22134
+ 'maxRetries',
22135
+ 'advanced',
22136
+ 'retryCount',
22137
+ 'iframeLocator',
22138
+ 'otherLocators',
22139
+ ],
22140
+ };
22141
+ const STEP_DETAILS_FIELD_META = {
22142
+ description: { key: 'description', label: 'Description', placeholder: 'Text Input', controlType: 'text', section: 'main' },
22143
+ metadata: { key: 'metadata', label: 'Metadata', placeholder: 'Text Input', controlType: 'text', section: 'main' },
22144
+ retryCount: {
22145
+ key: 'retryCount',
22146
+ label: 'Retry Count',
22147
+ placeholder: 'Dynamic search selector from library or manual',
22148
+ controlType: 'dropdown',
22149
+ section: 'advanced',
22150
+ options: [
22151
+ { value: '0', label: '0' },
22152
+ { value: '1', label: '1' },
22153
+ { value: '2', label: '2' },
22154
+ { value: '3', label: '3' },
22155
+ ],
22156
+ },
22157
+ advanced: { key: 'advanced', label: 'Advanced', controlType: 'toggleGroup' },
22158
+ method: {
22159
+ key: 'method',
22160
+ label: 'Method',
22161
+ placeholder: 'Method',
22162
+ controlType: 'dropdown',
22163
+ section: 'main',
22164
+ options: [
22165
+ { value: 'GET', label: 'GET' },
22166
+ { value: 'POST', label: 'POST' },
22167
+ { value: 'PUT', label: 'PUT' },
22168
+ { value: 'DELETE', label: 'DELETE' },
22169
+ { value: 'PATCH', label: 'PATCH' },
22170
+ ],
22171
+ },
22172
+ url: { key: 'url', label: 'URL', placeholder: 'URL', controlType: 'text', section: 'main' },
22173
+ headers: { key: 'headers', label: 'Headers', controlType: 'text', section: 'main' },
22174
+ body: { key: 'body', label: 'Body', placeholder: 'Request body', controlType: 'code', section: 'main' },
22175
+ saveOutputAsVariable: {
22176
+ key: 'saveOutputAsVariable',
22177
+ label: 'Save Output as Variable',
22178
+ placeholder: 'Variable name',
22179
+ controlType: 'text',
22180
+ section: 'main',
22181
+ },
22182
+ agentTask: {
22183
+ key: 'agentTask',
22184
+ label: 'Agent Task',
22185
+ placeholder: 'What should the agent achieve?',
22186
+ controlType: 'textarea',
22187
+ section: 'main',
22188
+ required: true,
22189
+ rows: 4,
22190
+ tip: 'Tip: Use numbered steps or bullet points for complex tasks.',
22191
+ },
22192
+ type: {
22193
+ key: 'type',
22194
+ label: 'Type',
22195
+ placeholder: 'Type',
22196
+ controlType: 'dropdown',
22197
+ section: 'main',
22198
+ options: [
22199
+ { value: 'default', label: 'Default' },
22200
+ { value: 'browser', label: 'Browser' },
22201
+ ],
22202
+ },
22203
+ environment: {
22204
+ key: 'environment',
22205
+ label: 'Environment',
22206
+ placeholder: 'Environment',
22207
+ controlType: 'dropdown',
22208
+ section: 'main',
22209
+ options: [
22210
+ { value: 'default', label: 'Default' },
22211
+ { value: 'staging', label: 'Staging' },
22212
+ { value: 'prod', label: 'Production' },
22213
+ ],
22214
+ },
22215
+ maxRetries: {
22216
+ key: 'maxRetries',
22217
+ label: 'Max Retries',
22218
+ placeholder: '3 retries (recommended)',
22219
+ controlType: 'dropdown',
22220
+ section: 'constraints',
22221
+ options: [
22222
+ { value: '0', label: '0' },
22223
+ { value: '1', label: '1' },
22224
+ { value: '2', label: '2' },
22225
+ { value: '3', label: '3 retries (recommended)' },
22226
+ ],
22227
+ },
22228
+ onlyUseAttachedContext: {
22229
+ key: 'onlyUseAttachedContext',
22230
+ label: 'Use existing elements only',
22231
+ subLabel: 'Only use elements from the attached context',
22232
+ controlType: 'toggle',
22233
+ section: 'constraints',
22234
+ },
22235
+ takeScreenshotsWhenVerifying: {
22236
+ key: 'takeScreenshotsWhenVerifying',
22237
+ label: 'Capture evidence',
22238
+ subLabel: 'Take screenshots when verifying conditions',
22239
+ controlType: 'toggle',
22240
+ section: 'constraints',
22241
+ },
22242
+ iframeLocator: {
22243
+ key: 'iframeLocator',
22244
+ label: 'Iframe locator',
22245
+ placeholder: 'Dynamic search selector from library or manual',
22246
+ controlType: 'dropdown',
22247
+ section: 'advanced',
22248
+ options: [
22249
+ { value: 'manual', label: 'Dynamic search selector from library or manual' },
22250
+ ],
22251
+ },
22252
+ otherLocators: {
22253
+ key: 'otherLocators',
22254
+ label: 'Other Locators',
22255
+ placeholder: 'Dynamic search selector from library or manual',
22256
+ controlType: 'dropdown',
22257
+ section: 'advanced',
22258
+ options: [
22259
+ { value: 'manual', label: 'Dynamic search selector from library or manual' },
22260
+ ],
22261
+ },
22262
+ continueOnError: {
22263
+ key: 'continueOnError',
22264
+ label: 'Continue on Error',
22265
+ subLabel: "Don't fail the test if this step fails.",
22266
+ controlType: 'toggle',
22267
+ section: 'advanced',
22268
+ },
22269
+ disabled: {
22270
+ key: 'disabled',
22271
+ label: 'Disabled',
22272
+ subLabel: 'Skip this step during execution.',
22273
+ controlType: 'toggle',
22274
+ section: 'advanced',
22275
+ },
22276
+ };
22277
+ /** Toggle fields always shown inside the Advanced section. */
22278
+ const ADVANCED_TOGGLE_KEYS = ['continueOnError', 'disabled'];
22279
+ /** Field keys shown inside Advanced (per step type), in addition to ADVANCED_TOGGLE_KEYS. */
22280
+ const ADVANCED_SUBFIELDS_BY_TYPE = {
22281
+ custom: [],
22282
+ api: [],
22283
+ aiAgent: ['retryCount', 'iframeLocator', 'otherLocators'],
22284
+ };
22285
+
22286
+ class StepDetailsDrawerRef {
22287
+ constructor(overlayRef) {
22288
+ this.overlayRef = overlayRef;
22289
+ this.closed$ = new Subject();
22290
+ this.isClosed = false;
22291
+ this.overlayRef.detachments().subscribe(() => this.finishClose(undefined));
22292
+ }
22293
+ close(result) {
22294
+ if (this.isClosed)
22295
+ return;
22296
+ this.finishClose(result);
22297
+ this.overlayRef.dispose();
22298
+ }
22299
+ afterClosed() {
22300
+ return this.closed$.asObservable();
22301
+ }
22302
+ finishClose(result) {
22303
+ if (this.isClosed)
22304
+ return;
22305
+ this.isClosed = true;
22306
+ this.closed$.next(result);
22307
+ this.closed$.complete();
22308
+ }
22309
+ }
22310
+ const STEP_DETAILS_DRAWER_REF = new InjectionToken('STEP_DETAILS_DRAWER_REF');
22311
+
22312
+ const STEP_DETAILS_DRAWER_DATA = new InjectionToken('STEP_DETAILS_DRAWER_DATA');
22313
+
22314
+ /**
22315
+ * Step Details Drawer (Edit In Depth).
22316
+ * Single reusable component; form is dynamic by Step Type via configuration.
22317
+ * No Priority section. Uses CQA components only.
22318
+ */
22319
+ class StepDetailsDrawerComponent {
22320
+ constructor(ref, fb, cdr, data) {
22321
+ var _a, _b;
22322
+ this.ref = ref;
22323
+ this.fb = fb;
22324
+ this.cdr = cdr;
22325
+ this.saveChanges = new EventEmitter();
22326
+ this.cancel = new EventEmitter();
22327
+ this.saveAsTemplate = new EventEmitter();
22328
+ /** Optional: when provided (e.g. from Storybook Controls), use instead of STEP_DETAILS_DRAWER_DATA. */
22329
+ this.stepData = null;
22330
+ this.stepNumberInput = null;
22331
+ this.stepType = null;
22332
+ this.visibleFields = [];
22333
+ this.fieldMeta = STEP_DETAILS_FIELD_META;
22334
+ this.advancedToggleKeys = ADVANCED_TOGGLE_KEYS;
22335
+ this.advancedExpanded = false;
22336
+ this.agentTaskExpanded = true;
22337
+ /** Cached select configs (stable references per key) to avoid infinite change detection in template. */
22338
+ this.selectConfigMap = this.buildSelectConfigMap();
22339
+ this.step = (_a = data === null || data === void 0 ? void 0 : data.step) !== null && _a !== void 0 ? _a : {};
22340
+ this.stepNumber = (_b = data === null || data === void 0 ? void 0 : data.stepNumber) !== null && _b !== void 0 ? _b : 1;
22341
+ this.form = this.fb.group({});
22342
+ this.syncStepTypeAndForm();
22343
+ }
22344
+ /** Subfields to show inside Advanced section for current step type. */
22345
+ get advancedSubfields() {
22346
+ return this.stepType ? ADVANCED_SUBFIELDS_BY_TYPE[this.stepType] : [];
22347
+ }
22348
+ ngOnInit() {
22349
+ var _a, _b;
22350
+ if (this.stepData != null) {
22351
+ this.step = this.stepData;
22352
+ this.stepNumber = (_b = (_a = this.stepNumberInput) !== null && _a !== void 0 ? _a : this.stepData.stepNumber) !== null && _b !== void 0 ? _b : 1;
22353
+ this.syncStepTypeAndForm();
22354
+ this.cdr.markForCheck();
22355
+ }
22356
+ }
22357
+ ngOnChanges(changes) {
22358
+ var _a, _b;
22359
+ if (changes['stepData'] || changes['stepNumberInput']) {
22360
+ if (this.stepData != null) {
22361
+ this.step = this.stepData;
22362
+ this.stepNumber = (_b = (_a = this.stepNumberInput) !== null && _a !== void 0 ? _a : this.stepData.stepNumber) !== null && _b !== void 0 ? _b : 1;
22363
+ }
22364
+ this.syncStepTypeAndForm();
22365
+ this.cdr.detectChanges();
22366
+ }
22367
+ }
22368
+ syncStepTypeAndForm() {
22369
+ this.stepType = getStepDetailsStepType(this.step);
22370
+ this.visibleFields = this.stepType ? STEP_DETAILS_FIELDS_BY_TYPE[this.stepType] : [];
22371
+ this.buildFormFromStep();
22372
+ }
22373
+ buildFormFromStep() {
22374
+ const group = {};
22375
+ for (const key of this.visibleFields) {
22376
+ if (key === 'advanced')
22377
+ continue;
22378
+ group[key] = [this.getStepValue(key)];
22379
+ }
22380
+ for (const key of ADVANCED_TOGGLE_KEYS) {
22381
+ if (!(key in group))
22382
+ group[key] = [this.getStepValue(key)];
22383
+ }
22384
+ this.form = this.fb.group(group);
22385
+ }
22386
+ getStepValue(key) {
22387
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
22388
+ const step = this.step;
22389
+ if (isNormalStepConfig(this.step) && this.step.eventType === 'custom') {
22390
+ if (key === 'description') {
22391
+ const params = this.step.parameters;
22392
+ return (_c = (_b = (_a = params === null || params === void 0 ? void 0 : params[0]) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : this.step.description) !== null && _c !== void 0 ? _c : '';
22393
+ }
22394
+ if (key === 'metadata') {
22395
+ const params = this.step.parameters;
22396
+ return (_e = (_d = params === null || params === void 0 ? void 0 : params[1]) === null || _d === void 0 ? void 0 : _d.value) !== null && _e !== void 0 ? _e : '';
22397
+ }
22398
+ }
22399
+ if (isApiStepConfig(this.step)) {
22400
+ const api = this.step;
22401
+ if (key === 'method')
22402
+ return (_f = api.method) !== null && _f !== void 0 ? _f : 'GET';
22403
+ if (key === 'url')
22404
+ return api.baseUrl ? `${api.baseUrl}${api.endpoint || ''}` : (_g = api.endpoint) !== null && _g !== void 0 ? _g : '';
22405
+ if (key === 'headers')
22406
+ return api.headers ? JSON.stringify(api.headers, null, 2) : '';
22407
+ if (key === 'body')
22408
+ return (_h = api.requestBody) !== null && _h !== void 0 ? _h : '';
22409
+ if (key === 'saveOutputAsVariable')
22410
+ return (_j = api.saveTo) !== null && _j !== void 0 ? _j : '';
22411
+ }
22412
+ if (isAiAgentStepConfig(this.step)) {
22413
+ const ai = this.step;
22414
+ if (key === 'agentTask')
22415
+ return (_k = ai.instructions) !== null && _k !== void 0 ? _k : '';
22416
+ if (key === 'description')
22417
+ return (_l = ai.description) !== null && _l !== void 0 ? _l : '';
22418
+ if (key === 'metadata')
22419
+ return (_m = step.metadata) !== null && _m !== void 0 ? _m : '';
22420
+ }
22421
+ if (key === 'onlyUseAttachedContext' ||
22422
+ key === 'takeScreenshotsWhenVerifying' ||
22423
+ key === 'continueOnError' ||
22424
+ key === 'disabled') {
22425
+ return step[key] === true;
22426
+ }
22427
+ return (_o = step[key]) !== null && _o !== void 0 ? _o : '';
22428
+ }
22429
+ setStepValue(key, value) {
22430
+ const step = this.step;
22431
+ if (isNormalStepConfig(this.step) && this.step.eventType === 'custom') {
22432
+ if (key === 'description') {
22433
+ const params = this.step.parameters;
22434
+ if (params === null || params === void 0 ? void 0 : params[0])
22435
+ params[0].value = String(value);
22436
+ else
22437
+ this.step.description = String(value);
22438
+ return;
22439
+ }
22440
+ if (key === 'metadata') {
22441
+ const params = this.step.parameters;
22442
+ if (params === null || params === void 0 ? void 0 : params[1])
22443
+ params[1].value = String(value);
22444
+ return;
22445
+ }
22446
+ }
22447
+ if (isApiStepConfig(this.step)) {
22448
+ const api = this.step;
22449
+ if (key === 'method') {
22450
+ api.method = value;
22451
+ return;
22452
+ }
22453
+ if (key === 'url') {
22454
+ api.endpoint = String(value);
22455
+ return;
22456
+ }
22457
+ if (key === 'headers') {
22458
+ try {
22459
+ api.headers = JSON.parse(String(value) || '{}');
22460
+ }
22461
+ catch (_a) {
22462
+ api.headers = {};
22463
+ }
22464
+ return;
22465
+ }
22466
+ if (key === 'body') {
22467
+ api.requestBody = String(value);
22468
+ return;
22469
+ }
22470
+ if (key === 'saveOutputAsVariable') {
22471
+ api.saveTo = String(value);
22472
+ return;
22473
+ }
22474
+ }
22475
+ if (isAiAgentStepConfig(this.step)) {
22476
+ const ai = this.step;
22477
+ if (key === 'agentTask') {
22478
+ ai.instructions = String(value);
22479
+ return;
22480
+ }
22481
+ if (key === 'description') {
22482
+ ai.description = String(value);
22483
+ return;
22484
+ }
22485
+ if (key === 'metadata') {
22486
+ step.metadata = value;
22487
+ return;
22488
+ }
22489
+ }
22490
+ step[key] = value;
22491
+ }
22492
+ onBack() {
22493
+ this.cancel.emit();
22494
+ this.ref.close(undefined);
22495
+ }
22496
+ onClose() {
22497
+ this.cancel.emit();
22498
+ this.ref.close(undefined);
22499
+ }
22500
+ onCancel() {
22501
+ this.cancel.emit();
22502
+ this.ref.close(undefined);
22503
+ }
22504
+ onSaveAsTemplate() {
22505
+ this.applyFormToStep();
22506
+ this.saveAsTemplate.emit(this.step);
22507
+ this.ref.close({ action: 'saveAsTemplate', step: this.step });
22508
+ }
22509
+ onSaveChanges() {
22510
+ this.applyFormToStep();
22511
+ this.saveChanges.emit(this.step);
22512
+ this.ref.close({ action: 'saveChanges', step: this.step });
22513
+ }
22514
+ applyFormToStep() {
22515
+ var _a, _b;
22516
+ for (const key of this.visibleFields) {
22517
+ if (key === 'advanced')
22518
+ continue;
22519
+ if (this.form.contains(key))
22520
+ this.setStepValue(key, (_a = this.form.get(key)) === null || _a === void 0 ? void 0 : _a.value);
22521
+ }
22522
+ for (const key of ADVANCED_TOGGLE_KEYS) {
22523
+ if (this.form.contains(key))
22524
+ this.setStepValue(key, (_b = this.form.get(key)) === null || _b === void 0 ? void 0 : _b.value);
22525
+ }
22526
+ }
22527
+ /** Build cached map of select configs from field meta (stable refs to prevent CD loops). */
22528
+ buildSelectConfigMap() {
22529
+ var _a, _b;
22530
+ const map = {};
22531
+ const keys = Object.keys(STEP_DETAILS_FIELD_META);
22532
+ for (const key of keys) {
22533
+ const meta = STEP_DETAILS_FIELD_META[key];
22534
+ if (!meta || meta.controlType !== 'dropdown' || !((_a = meta.options) === null || _a === void 0 ? void 0 : _a.length))
22535
+ continue;
22536
+ const options = meta.options.map((o) => ({ value: o.value, label: o.label }));
22537
+ map[key] = {
22538
+ key: meta.key,
22539
+ placeholder: (_b = meta.placeholder) !== null && _b !== void 0 ? _b : meta.label,
22540
+ options,
22541
+ };
22542
+ }
22543
+ return map;
22544
+ }
22545
+ /** Return cached select config for key (for template use; same reference every time). */
22546
+ getSelectConfig(key) {
22547
+ var _a;
22548
+ return (_a = this.selectConfigMap[key]) !== null && _a !== void 0 ? _a : null;
22549
+ }
22550
+ /** Whether this key is the first in its section (for showing section headings). */
22551
+ isFirstInSection(key, section) {
22552
+ const meta = STEP_DETAILS_FIELD_META[key];
22553
+ if (!meta || meta.section !== section)
22554
+ return false;
22555
+ const idx = this.visibleFields.indexOf(key);
22556
+ if (idx <= 0)
22557
+ return true;
22558
+ const prevMeta = STEP_DETAILS_FIELD_META[this.visibleFields[idx - 1]];
22559
+ return !prevMeta || prevMeta.section !== section;
22560
+ }
22561
+ /** Dynamic drawer title by step type (e.g. "AI Agent Step Details"). */
22562
+ get drawerTitle() {
22563
+ if (this.stepType === 'custom')
22564
+ return 'Custom Step Details';
22565
+ if (this.stepType === 'api')
22566
+ return 'API Step Details';
22567
+ if (this.stepType === 'aiAgent')
22568
+ return 'AI Agent Step Details';
22569
+ return 'Step Details';
22570
+ }
22571
+ }
22572
+ StepDetailsDrawerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: StepDetailsDrawerComponent, deps: [{ token: STEP_DETAILS_DRAWER_REF }, { token: i2$1.FormBuilder }, { token: i0.ChangeDetectorRef }, { token: STEP_DETAILS_DRAWER_DATA, optional: true }], target: i0.ɵɵFactoryTarget.Component });
22573
+ StepDetailsDrawerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: StepDetailsDrawerComponent, selector: "cqa-step-details-drawer", inputs: { stepData: "stepData", stepNumberInput: "stepNumberInput" }, outputs: { saveChanges: "saveChanges", cancel: "cancel", saveAsTemplate: "saveAsTemplate" }, host: { classAttribute: "cqa-ui-root" }, usesOnChanges: true, ngImport: i0, template: "<!-- Step Details Drawer \u2013 Edit In Depth. No Priority. Fully config-driven. -->\n<div class=\"cqa-flex cqa-flex-col cqa-h-full cqa-w-full cqa-max-w-[480px] cqa-box-border\">\n <!-- Header: back chevron, dynamic title, Step N pill, close -->\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-3 cqa-px-4 cqa-py-4 cqa-bg-white cqa-rounded-t-[12px] cqa-border cqa-border-[#E5E5E5]\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <button type=\"button\" (click)=\"onBack()\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-8 cqa-h-8 cqa-rounded cqa-text-[#6B7280] hover:cqa-bg-[#F3F4F6] cqa-p-0\"\n aria-label=\"Back\">\n <mat-icon class=\"!cqa-w-5 !cqa-h-5 !cqa-text-[20px]\">chevron_left</mat-icon>\n </button>\n <h2 class=\"cqa-text-[16px] cqa-leading-[24px] cqa-font-semibold cqa-text-[#111827] cqa-m-0 cqa-flex-1\">\n {{ drawerTitle }}\n </h2>\n <span class=\"cqa-px-2.5 cqa-py-1 cqa-rounded-lg cqa-bg-[#EDE9FE] cqa-text-[#7C3AED] cqa-text-[12px] cqa-font-medium\">\n Step {{ stepNumber }}\n </span>\n </div>\n <button type=\"button\" (click)=\"onClose()\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-min-h-[28px] cqa-min-w-[28px] cqa-rounded cqa-text-[#6B7280] hover:cqa-bg-[#F3F4F6] cqa-p-0\"\n title=\"Close\" aria-label=\"Close\">\n <mat-icon class=\"!cqa-w-5 !cqa-h-5 !cqa-text-[20px]\">close</mat-icon>\n </button>\n </div>\n <div class=\"cqa-border cqa-border-solid cqa-border-[#E5E5E5]\"> </div>\n\n <!-- Content: Attributes + dynamic fields from config -->\n <div class=\"cqa-flex-1 cqa-overflow-y-auto cqa-bg-white cqa-px-4 cqa-py-4\">\n <ng-container *ngIf=\"stepType\">\n <p class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#6B7280] cqa-mb-3 cqa-mt-0\">Attributes</p>\n\n <div class=\"cqa-flex cqa-flex-col cqa-gap-4\">\n <ng-container *ngFor=\"let key of visibleFields\">\n <!-- Section heading: Constraints (first constraints field only) -->\n <ng-container *ngIf=\"key !== 'advanced' && isFirstInSection(key, 'constraints')\">\n <p class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#6B7280] cqa-mb-2 cqa-mt-0\">Constraints</p>\n </ng-container>\n\n <!-- Advanced: expandable section with config-driven toggles + subfields -->\n <ng-container *ngIf=\"key === 'advanced'\">\n <button type=\"button\"\n class=\"cqa-flex cqa-items-center cqa-justify-between cqa-w-full cqa-text-left cqa-text-[12px] cqa-font-medium cqa-text-[#111827] cqa-py-2 cqa-border-b cqa-border-[#E5E7EB]\"\n (click)=\"advancedExpanded = !advancedExpanded\">\n <span>Advanced</span>\n <mat-icon class=\"cqa-text-[20px] cqa-transition-transform\" [class.cqa-rotate-180]=\"!advancedExpanded\">\n expand_less\n </mat-icon>\n </button>\n <div *ngIf=\"advancedExpanded\" class=\"cqa-flex cqa-flex-col cqa-gap-3 cqa-pt-2\">\n <!-- Advanced toggles from config -->\n <ng-container *ngFor=\"let toggleKey of advancedToggleKeys\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\" *ngIf=\"fieldMeta[toggleKey]\">\n <cqa-custom-toggle\n [checked]=\"form.get(toggleKey)?.value\"\n (checkedChange)=\"form.get(toggleKey)?.setValue($event)\">\n </cqa-custom-toggle>\n <div class=\"cqa-flex cqa-flex-col\">\n <span class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#737373]\">{{ fieldMeta[toggleKey].label }}</span>\n <span class=\"cqa-text-[12px] cqa-text-[#0A0A0A]\" *ngIf=\"fieldMeta[toggleKey].subLabel\">{{ fieldMeta[toggleKey].subLabel }}</span>\n </div>\n </div>\n </ng-container>\n <!-- Advanced subfields (e.g. Retry Count, Iframe locator, Other Locators for aiAgent) -->\n <ng-container *ngFor=\"let subKey of advancedSubfields\">\n <div class=\"cqa-flex cqa-flex-col cqa-gap-1.5 cqa-step-details-drawer-select\" *ngIf=\"fieldMeta[subKey]?.controlType === 'dropdown' && getSelectConfig(subKey) && form.contains(subKey)\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#374151]\">{{ fieldMeta[subKey].label }}</label>\n <cqa-dynamic-select [form]=\"form\" [config]=\"getSelectConfig(subKey)!\">\n </cqa-dynamic-select>\n </div>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- Skip: advanced key (already rendered) and fields that are rendered inside advanced for this step type -->\n <ng-container *ngIf=\"key !== 'advanced' && !(stepType === 'aiAgent' && advancedSubfields.includes(key))\">\n <!-- text -->\n <div *ngIf=\"fieldMeta[key]?.controlType === 'text'\" class=\"cqa-flex cqa-flex-col cqa-gap-1.5\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#374151]\">{{ fieldMeta[key].label }}</label>\n <cqa-custom-input\n [placeholder]=\"fieldMeta[key].placeholder || ''\"\n [value]=\"form.get(key)?.value\"\n [fullWidth]=\"true\"\n (valueChange)=\"form.get(key)?.setValue($event)\">\n </cqa-custom-input>\n </div>\n\n <!-- textarea (including agentTask with optional required + tip) -->\n <div *ngIf=\"fieldMeta[key]?.controlType === 'textarea'\" class=\"cqa-flex cqa-flex-col cqa-gap-1.5\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#374151]\">{{ fieldMeta[key].label }}</label>\n <span *ngIf=\"fieldMeta[key].required\" class=\"cqa-px-2 cqa-py-0.5 cqa-rounded-full cqa-bg-[#FEE2E2] cqa-text-[#DC2626] cqa-text-[10px] cqa-font-medium\">Required</span>\n </div>\n <p *ngIf=\"key === 'agentTask'\" class=\"cqa-text-[12px] cqa-text-[#6B7280] cqa-m-0\">What should the agent achieve?</p>\n <cqa-custom-textarea\n [placeholder]=\"fieldMeta[key].placeholder || ''\"\n [value]=\"form.get(key)?.value\"\n [fullWidth]=\"true\"\n [rows]=\"fieldMeta[key].rows || 4\"\n customClass=\"cqa-p-2 cqa-text-[14px] cqa-leading-[20px]\"\n (valueChange)=\"form.get(key)?.setValue($event)\">\n </cqa-custom-textarea>\n <p *ngIf=\"fieldMeta[key].tip\" class=\"cqa-text-[12px] cqa-text-[#6B7280] cqa-m-0\">{{ fieldMeta[key].tip }}</p>\n </div>\n\n <!-- code -->\n <div *ngIf=\"fieldMeta[key]?.controlType === 'code'\" class=\"cqa-flex cqa-flex-col cqa-gap-1.5\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#374151]\">{{ fieldMeta[key].label }}</label>\n <cqa-custom-textarea\n [placeholder]=\"fieldMeta[key].placeholder || ''\"\n [value]=\"form.get(key)?.value\"\n [fullWidth]=\"true\"\n [rows]=\"8\"\n resize=\"vertical\"\n customClass=\"cqa-p-2 cqa-text-[14px] cqa-leading-[20px]\"\n (valueChange)=\"form.get(key)?.setValue($event)\">\n </cqa-custom-textarea>\n </div>\n\n <!-- dropdown (main + constraints; advanced-only dropdowns rendered inside Advanced section) -->\n <div *ngIf=\"fieldMeta[key]?.controlType === 'dropdown' && form.contains(key) && getSelectConfig(key) && !advancedSubfields.includes(key)\"\n class=\"cqa-flex cqa-flex-col cqa-gap-1.5 cqa-step-details-drawer-select\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#374151]\">{{ fieldMeta[key].label }}</label>\n <cqa-dynamic-select [form]=\"form\" [config]=\"getSelectConfig(key)!\">\n </cqa-dynamic-select>\n </div>\n\n <!-- toggle (e.g. onlyUseAttachedContext, takeScreenshotsWhenVerifying) -->\n <div *ngIf=\"fieldMeta[key]?.controlType === 'toggle'\" class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-2\">\n <div>\n <p class=\"cqa-text-[12px] cqa-text-[#111827] cqa-m-0\">{{ fieldMeta[key].label }}</p>\n <span *ngIf=\"fieldMeta[key].subLabel\" class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#374151]\">{{ fieldMeta[key].subLabel }}</span>\n </div>\n <cqa-custom-toggle\n [checked]=\"form.get(key)?.value\"\n (checkedChange)=\"form.get(key)?.setValue($event)\">\n </cqa-custom-toggle>\n </div>\n </ng-container>\n </ng-container>\n </div>\n </ng-container>\n\n <p *ngIf=\"!stepType\" class=\"cqa-text-[14px] cqa-text-[#6B7280]\">This step type is not supported in the drawer.</p>\n </div>\n<div class=\"cqa-border cqa-border-solid cqa-border-[#E5E5E5]\"> </div>\n <!-- Footer -->\n <div class=\"cqa-flex cqa-items-center cqa-justify-start cqa-gap-2 cqa-px-4 cqa-py-4 cqa-border-t cqa-border-[#E5E7EB] cqa-bg-[#F5F5F54D]\">\n <cqa-button variant=\"text\" btnSize=\"lg\" [text]=\"'Cancel'\" (clicked)=\"onCancel()\"\n [customClass]=\"'cqa-text-[14px] cqa-py-[9px] cqa-text-[#374151]'\"></cqa-button>\n <div class=\"cqa-flex-1 cqa-min-w-0\"></div>\n <cqa-button variant=\"outlined\" btnSize=\"lg\" [text]=\"'Save as Template'\" (clicked)=\"onSaveAsTemplate()\"\n [customClass]=\"'cqa-text-[14px] cqa-py-[9px] cqa-border-[#414146]'\"></cqa-button>\n <cqa-button variant=\"filled\" btnSize=\"lg\" [text]=\"'Save Changes'\" (clicked)=\"onSaveChanges()\"\n [customClass]=\"'cqa-text-[14px] cqa-py-[9px] cqa-bg-[#3F43EE] cqa-border-[#3F43EE]'\"></cqa-button>\n </div>\n</div>\n", components: [{ type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: CustomToggleComponent, selector: "cqa-custom-toggle", inputs: ["checked", "disabled", "ariaLabel"], outputs: ["checkedChange", "change"] }, { type: DynamicSelectFieldComponent, selector: "cqa-dynamic-select", inputs: ["form", "config"], outputs: ["selectionChange", "selectClick", "searchChange", "loadMore"] }, { type: CustomInputComponent, selector: "cqa-custom-input", inputs: ["label", "type", "placeholder", "value", "disabled", "errors", "required", "ariaLabel", "size", "fullWidth", "maxLength", "showCharCount", "inputInlineStyle", "labelInlineStyle"], outputs: ["valueChange", "blurred", "focused", "enterPressed"] }, { type: CustomTextareaComponent, selector: "cqa-custom-textarea", inputs: ["label", "placeholder", "value", "disabled", "errors", "required", "ariaLabel", "size", "fullWidth", "maxLength", "showCharCount", "rows", "cols", "resize", "textareaInlineStyle", "labelInlineStyle", "customClass"], outputs: ["valueChange", "blurred", "focused"] }, { type: ButtonComponent, selector: "cqa-button", inputs: ["variant", "btnSize", "disabled", "icon", "iconPosition", "fullWidth", "iconColor", "type", "text", "customClass", "inlineStyles", "tooltip", "tooltipPosition"], outputs: ["clicked"] }], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
22574
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: StepDetailsDrawerComponent, decorators: [{
22575
+ type: Component,
22576
+ args: [{ selector: 'cqa-step-details-drawer', host: { class: 'cqa-ui-root' }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Step Details Drawer \u2013 Edit In Depth. No Priority. Fully config-driven. -->\n<div class=\"cqa-flex cqa-flex-col cqa-h-full cqa-w-full cqa-max-w-[480px] cqa-box-border\">\n <!-- Header: back chevron, dynamic title, Step N pill, close -->\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-3 cqa-px-4 cqa-py-4 cqa-bg-white cqa-rounded-t-[12px] cqa-border cqa-border-[#E5E5E5]\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <button type=\"button\" (click)=\"onBack()\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-8 cqa-h-8 cqa-rounded cqa-text-[#6B7280] hover:cqa-bg-[#F3F4F6] cqa-p-0\"\n aria-label=\"Back\">\n <mat-icon class=\"!cqa-w-5 !cqa-h-5 !cqa-text-[20px]\">chevron_left</mat-icon>\n </button>\n <h2 class=\"cqa-text-[16px] cqa-leading-[24px] cqa-font-semibold cqa-text-[#111827] cqa-m-0 cqa-flex-1\">\n {{ drawerTitle }}\n </h2>\n <span class=\"cqa-px-2.5 cqa-py-1 cqa-rounded-lg cqa-bg-[#EDE9FE] cqa-text-[#7C3AED] cqa-text-[12px] cqa-font-medium\">\n Step {{ stepNumber }}\n </span>\n </div>\n <button type=\"button\" (click)=\"onClose()\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-min-h-[28px] cqa-min-w-[28px] cqa-rounded cqa-text-[#6B7280] hover:cqa-bg-[#F3F4F6] cqa-p-0\"\n title=\"Close\" aria-label=\"Close\">\n <mat-icon class=\"!cqa-w-5 !cqa-h-5 !cqa-text-[20px]\">close</mat-icon>\n </button>\n </div>\n <div class=\"cqa-border cqa-border-solid cqa-border-[#E5E5E5]\"> </div>\n\n <!-- Content: Attributes + dynamic fields from config -->\n <div class=\"cqa-flex-1 cqa-overflow-y-auto cqa-bg-white cqa-px-4 cqa-py-4\">\n <ng-container *ngIf=\"stepType\">\n <p class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#6B7280] cqa-mb-3 cqa-mt-0\">Attributes</p>\n\n <div class=\"cqa-flex cqa-flex-col cqa-gap-4\">\n <ng-container *ngFor=\"let key of visibleFields\">\n <!-- Section heading: Constraints (first constraints field only) -->\n <ng-container *ngIf=\"key !== 'advanced' && isFirstInSection(key, 'constraints')\">\n <p class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#6B7280] cqa-mb-2 cqa-mt-0\">Constraints</p>\n </ng-container>\n\n <!-- Advanced: expandable section with config-driven toggles + subfields -->\n <ng-container *ngIf=\"key === 'advanced'\">\n <button type=\"button\"\n class=\"cqa-flex cqa-items-center cqa-justify-between cqa-w-full cqa-text-left cqa-text-[12px] cqa-font-medium cqa-text-[#111827] cqa-py-2 cqa-border-b cqa-border-[#E5E7EB]\"\n (click)=\"advancedExpanded = !advancedExpanded\">\n <span>Advanced</span>\n <mat-icon class=\"cqa-text-[20px] cqa-transition-transform\" [class.cqa-rotate-180]=\"!advancedExpanded\">\n expand_less\n </mat-icon>\n </button>\n <div *ngIf=\"advancedExpanded\" class=\"cqa-flex cqa-flex-col cqa-gap-3 cqa-pt-2\">\n <!-- Advanced toggles from config -->\n <ng-container *ngFor=\"let toggleKey of advancedToggleKeys\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\" *ngIf=\"fieldMeta[toggleKey]\">\n <cqa-custom-toggle\n [checked]=\"form.get(toggleKey)?.value\"\n (checkedChange)=\"form.get(toggleKey)?.setValue($event)\">\n </cqa-custom-toggle>\n <div class=\"cqa-flex cqa-flex-col\">\n <span class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#737373]\">{{ fieldMeta[toggleKey].label }}</span>\n <span class=\"cqa-text-[12px] cqa-text-[#0A0A0A]\" *ngIf=\"fieldMeta[toggleKey].subLabel\">{{ fieldMeta[toggleKey].subLabel }}</span>\n </div>\n </div>\n </ng-container>\n <!-- Advanced subfields (e.g. Retry Count, Iframe locator, Other Locators for aiAgent) -->\n <ng-container *ngFor=\"let subKey of advancedSubfields\">\n <div class=\"cqa-flex cqa-flex-col cqa-gap-1.5 cqa-step-details-drawer-select\" *ngIf=\"fieldMeta[subKey]?.controlType === 'dropdown' && getSelectConfig(subKey) && form.contains(subKey)\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#374151]\">{{ fieldMeta[subKey].label }}</label>\n <cqa-dynamic-select [form]=\"form\" [config]=\"getSelectConfig(subKey)!\">\n </cqa-dynamic-select>\n </div>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- Skip: advanced key (already rendered) and fields that are rendered inside advanced for this step type -->\n <ng-container *ngIf=\"key !== 'advanced' && !(stepType === 'aiAgent' && advancedSubfields.includes(key))\">\n <!-- text -->\n <div *ngIf=\"fieldMeta[key]?.controlType === 'text'\" class=\"cqa-flex cqa-flex-col cqa-gap-1.5\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#374151]\">{{ fieldMeta[key].label }}</label>\n <cqa-custom-input\n [placeholder]=\"fieldMeta[key].placeholder || ''\"\n [value]=\"form.get(key)?.value\"\n [fullWidth]=\"true\"\n (valueChange)=\"form.get(key)?.setValue($event)\">\n </cqa-custom-input>\n </div>\n\n <!-- textarea (including agentTask with optional required + tip) -->\n <div *ngIf=\"fieldMeta[key]?.controlType === 'textarea'\" class=\"cqa-flex cqa-flex-col cqa-gap-1.5\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#374151]\">{{ fieldMeta[key].label }}</label>\n <span *ngIf=\"fieldMeta[key].required\" class=\"cqa-px-2 cqa-py-0.5 cqa-rounded-full cqa-bg-[#FEE2E2] cqa-text-[#DC2626] cqa-text-[10px] cqa-font-medium\">Required</span>\n </div>\n <p *ngIf=\"key === 'agentTask'\" class=\"cqa-text-[12px] cqa-text-[#6B7280] cqa-m-0\">What should the agent achieve?</p>\n <cqa-custom-textarea\n [placeholder]=\"fieldMeta[key].placeholder || ''\"\n [value]=\"form.get(key)?.value\"\n [fullWidth]=\"true\"\n [rows]=\"fieldMeta[key].rows || 4\"\n customClass=\"cqa-p-2 cqa-text-[14px] cqa-leading-[20px]\"\n (valueChange)=\"form.get(key)?.setValue($event)\">\n </cqa-custom-textarea>\n <p *ngIf=\"fieldMeta[key].tip\" class=\"cqa-text-[12px] cqa-text-[#6B7280] cqa-m-0\">{{ fieldMeta[key].tip }}</p>\n </div>\n\n <!-- code -->\n <div *ngIf=\"fieldMeta[key]?.controlType === 'code'\" class=\"cqa-flex cqa-flex-col cqa-gap-1.5\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#374151]\">{{ fieldMeta[key].label }}</label>\n <cqa-custom-textarea\n [placeholder]=\"fieldMeta[key].placeholder || ''\"\n [value]=\"form.get(key)?.value\"\n [fullWidth]=\"true\"\n [rows]=\"8\"\n resize=\"vertical\"\n customClass=\"cqa-p-2 cqa-text-[14px] cqa-leading-[20px]\"\n (valueChange)=\"form.get(key)?.setValue($event)\">\n </cqa-custom-textarea>\n </div>\n\n <!-- dropdown (main + constraints; advanced-only dropdowns rendered inside Advanced section) -->\n <div *ngIf=\"fieldMeta[key]?.controlType === 'dropdown' && form.contains(key) && getSelectConfig(key) && !advancedSubfields.includes(key)\"\n class=\"cqa-flex cqa-flex-col cqa-gap-1.5 cqa-step-details-drawer-select\">\n <label class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#374151]\">{{ fieldMeta[key].label }}</label>\n <cqa-dynamic-select [form]=\"form\" [config]=\"getSelectConfig(key)!\">\n </cqa-dynamic-select>\n </div>\n\n <!-- toggle (e.g. onlyUseAttachedContext, takeScreenshotsWhenVerifying) -->\n <div *ngIf=\"fieldMeta[key]?.controlType === 'toggle'\" class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-2\">\n <div>\n <p class=\"cqa-text-[12px] cqa-text-[#111827] cqa-m-0\">{{ fieldMeta[key].label }}</p>\n <span *ngIf=\"fieldMeta[key].subLabel\" class=\"cqa-text-[12px] cqa-font-medium cqa-text-[#374151]\">{{ fieldMeta[key].subLabel }}</span>\n </div>\n <cqa-custom-toggle\n [checked]=\"form.get(key)?.value\"\n (checkedChange)=\"form.get(key)?.setValue($event)\">\n </cqa-custom-toggle>\n </div>\n </ng-container>\n </ng-container>\n </div>\n </ng-container>\n\n <p *ngIf=\"!stepType\" class=\"cqa-text-[14px] cqa-text-[#6B7280]\">This step type is not supported in the drawer.</p>\n </div>\n<div class=\"cqa-border cqa-border-solid cqa-border-[#E5E5E5]\"> </div>\n <!-- Footer -->\n <div class=\"cqa-flex cqa-items-center cqa-justify-start cqa-gap-2 cqa-px-4 cqa-py-4 cqa-border-t cqa-border-[#E5E7EB] cqa-bg-[#F5F5F54D]\">\n <cqa-button variant=\"text\" btnSize=\"lg\" [text]=\"'Cancel'\" (clicked)=\"onCancel()\"\n [customClass]=\"'cqa-text-[14px] cqa-py-[9px] cqa-text-[#374151]'\"></cqa-button>\n <div class=\"cqa-flex-1 cqa-min-w-0\"></div>\n <cqa-button variant=\"outlined\" btnSize=\"lg\" [text]=\"'Save as Template'\" (clicked)=\"onSaveAsTemplate()\"\n [customClass]=\"'cqa-text-[14px] cqa-py-[9px] cqa-border-[#414146]'\"></cqa-button>\n <cqa-button variant=\"filled\" btnSize=\"lg\" [text]=\"'Save Changes'\" (clicked)=\"onSaveChanges()\"\n [customClass]=\"'cqa-text-[14px] cqa-py-[9px] cqa-bg-[#3F43EE] cqa-border-[#3F43EE]'\"></cqa-button>\n </div>\n</div>\n" }]
22577
+ }], ctorParameters: function () {
22578
+ return [{ type: StepDetailsDrawerRef, decorators: [{
22579
+ type: Inject,
22580
+ args: [STEP_DETAILS_DRAWER_REF]
22581
+ }] }, { type: i2$1.FormBuilder }, { type: i0.ChangeDetectorRef }, { type: undefined, decorators: [{
22582
+ type: Optional
22583
+ }, {
22584
+ type: Inject,
22585
+ args: [STEP_DETAILS_DRAWER_DATA]
22586
+ }] }];
22587
+ }, propDecorators: { saveChanges: [{
22588
+ type: Output
22589
+ }], cancel: [{
22590
+ type: Output
22591
+ }], saveAsTemplate: [{
22592
+ type: Output
22593
+ }], stepData: [{
22594
+ type: Input
22595
+ }], stepNumberInput: [{
22596
+ type: Input
22597
+ }] } });
22598
+
22071
22599
  class UiKitModule {
22072
22600
  constructor(iconRegistry) {
22073
22601
  iconRegistry.registerFontClassAlias('material-symbols-outlined', 'material-symbols-outlined');
@@ -22180,7 +22708,8 @@ UiKitModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "1
22180
22708
  StepBuilderDocumentGenerationTemplateStepComponent,
22181
22709
  ElementListComponent,
22182
22710
  StepBuilderDocumentComponent,
22183
- StepBuilderApiComponent], imports: [CommonModule,
22711
+ StepBuilderApiComponent,
22712
+ StepDetailsDrawerComponent], imports: [CommonModule,
22184
22713
  FormsModule,
22185
22714
  ReactiveFormsModule,
22186
22715
  MatIconModule,
@@ -22304,7 +22833,8 @@ UiKitModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "1
22304
22833
  StepBuilderDocumentGenerationTemplateStepComponent,
22305
22834
  StepBuilderApiComponent,
22306
22835
  ElementListComponent,
22307
- StepBuilderDocumentComponent] });
22836
+ StepBuilderDocumentComponent,
22837
+ StepDetailsDrawerComponent] });
22308
22838
  UiKitModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: UiKitModule, providers: [
22309
22839
  { provide: OverlayContainer, useClass: TailwindOverlayContainer },
22310
22840
  {
@@ -22478,6 +23008,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
22478
23008
  ElementListComponent,
22479
23009
  StepBuilderDocumentComponent,
22480
23010
  StepBuilderApiComponent,
23011
+ StepDetailsDrawerComponent,
22481
23012
  ],
22482
23013
  imports: [
22483
23014
  CommonModule,
@@ -22608,6 +23139,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
22608
23139
  StepBuilderApiComponent,
22609
23140
  ElementListComponent,
22610
23141
  StepBuilderDocumentComponent,
23142
+ StepDetailsDrawerComponent,
22611
23143
  ],
22612
23144
  providers: [
22613
23145
  { provide: OverlayContainer, useClass: TailwindOverlayContainer },
@@ -22784,9 +23316,66 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
22784
23316
  }]
22785
23317
  }], ctorParameters: function () { return [{ type: i1$6.Overlay }, { type: i0.Injector }]; } });
22786
23318
 
23319
+ /**
23320
+ * Opens the Step Details Drawer (Edit In Depth) from the right.
23321
+ */
23322
+ class StepDetailsDrawerService {
23323
+ constructor(overlay, injector) {
23324
+ this.overlay = overlay;
23325
+ this.injector = injector;
23326
+ this.currentRef = null;
23327
+ }
23328
+ open(data) {
23329
+ if (this.currentRef)
23330
+ return this.currentRef;
23331
+ const drawerWidth = 480;
23332
+ const positionStrategy = this.overlay
23333
+ .position()
23334
+ .global()
23335
+ .right('0')
23336
+ .top('0')
23337
+ .bottom('0')
23338
+ .width(`${drawerWidth}px`);
23339
+ const overlayRef = this.overlay.create(new OverlayConfig({
23340
+ hasBackdrop: true,
23341
+ backdropClass: 'cdk-overlay-transparent-backdrop',
23342
+ scrollStrategy: this.overlay.scrollStrategies.block(),
23343
+ positionStrategy,
23344
+ panelClass: ['cqa-step-details-drawer-panel', 'cqa-ui-root'],
23345
+ width: `${drawerWidth}px`,
23346
+ maxWidth: '100vw',
23347
+ height: '100%',
23348
+ }));
23349
+ const drawerRef = new StepDetailsDrawerRef(overlayRef);
23350
+ const injector = Injector.create({
23351
+ parent: this.injector,
23352
+ providers: [
23353
+ { provide: STEP_DETAILS_DRAWER_REF, useValue: drawerRef },
23354
+ { provide: STEP_DETAILS_DRAWER_DATA, useValue: data },
23355
+ ],
23356
+ });
23357
+ const portal = new ComponentPortal(StepDetailsDrawerComponent, undefined, injector);
23358
+ overlayRef.attach(portal);
23359
+ this.currentRef = drawerRef;
23360
+ drawerRef.afterClosed().subscribe(() => { this.currentRef = null; });
23361
+ overlayRef.backdropClick().subscribe(() => drawerRef.close({ action: 'cancel' }));
23362
+ overlayRef
23363
+ .keydownEvents()
23364
+ .pipe(filter((e) => e.key === 'Escape' || e.key === 'Esc'))
23365
+ .subscribe(() => drawerRef.close({ action: 'cancel' }));
23366
+ return drawerRef;
23367
+ }
23368
+ }
23369
+ StepDetailsDrawerService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: StepDetailsDrawerService, deps: [{ token: i1$6.Overlay }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable });
23370
+ StepDetailsDrawerService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: StepDetailsDrawerService, providedIn: 'root' });
23371
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: StepDetailsDrawerService, decorators: [{
23372
+ type: Injectable,
23373
+ args: [{ providedIn: 'root' }]
23374
+ }], ctorParameters: function () { return [{ type: i1$6.Overlay }, { type: i0.Injector }]; } });
23375
+
22787
23376
  /**
22788
23377
  * Generated bundle index. Do not edit.
22789
23378
  */
22790
23379
 
22791
- export { AIActionStepComponent, AIAgentStepComponent, ActionMenuButtonComponent, AddPrerequisiteCasesSectionComponent, AiDebugAlertComponent, AiReasoningComponent, ApiStepComponent, BadgeComponent, BasicStepComponent, ButtonComponent, CUSTOM_EDIT_STEP_DATA, CUSTOM_EDIT_STEP_EDIT_IN_DEPTH, CUSTOM_EDIT_STEP_REF, CUSTOM_ELEMENT_POPUP_REF, ChartCardComponent, ColumnVisibilityComponent, CompareRunsComponent, ConditionStepComponent, ConfigurationCardComponent, ConsoleAlertComponent, CoverageModuleCardComponent, CreateStepGroupComponent, CustomEditStepComponent, CustomEditStepRef, CustomEditStepService, CustomInputComponent, CustomTextareaComponent, CustomToggleComponent, DEFAULT_METADATA_COLOR, DIALOG_DATA, DIALOG_REF, DashboardHeaderComponent, DaterangepickerComponent, DaterangepickerDirective, DbQueryExecutionItemComponent, DbVerificationStepComponent, DeleteStepsComponent, 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, ElementListComponent, ElementPopupComponent, ElementPopupRef, ElementPopupService, EmptyStateComponent, ErrorModalComponent, ExecutionResultModalComponent, FailedStepCardComponent, FailedStepComponent, FailedTestCasesCardComponent, FileDownloadStepComponent, FileUploadComponent, FullTableLoaderComponent, HeatErrorMapCellComponent, InsightCardComponent, ItemListComponent, IterationsLoopComponent, LiveConversationComponent, LiveExecutionStepComponent, LoopStepComponent, MainStepCollapseComponent, MetricsCardComponent, NetworkRequestComponent, OtherButtonComponent, PRIORITY_COLORS, PaginationComponent, ProgressIndicatorComponent, ProgressTextCardComponent, RESULT_COLORS, RunHistoryCardComponent, STATUS_COLORS, SearchBarComponent, SegmentControlComponent, SelectedFiltersComponent, SelfHealAnalysisComponent, SimulatorComponent, StepBuilderActionComponent, StepBuilderAiAgentComponent, StepBuilderApiComponent, StepBuilderConditionComponent, StepBuilderCustomCodeComponent, StepBuilderDatabaseComponent, StepBuilderDocumentComponent, StepBuilderDocumentGenerationTemplateStepComponent, StepBuilderLoopComponent, StepBuilderRecordStepComponent, StepGroupComponent, StepProgressCardComponent, StepRendererComponent, StepStatusCardComponent, StepTypes, TEST_DATA_MODAL_DATA, TEST_DATA_MODAL_EDIT_IN_DEPTH, TEST_DATA_MODAL_REF, TableActionToolbarComponent, TableDataLoaderComponent, TableTemplateComponent, TailwindOverlayContainer, TestCaseAiAgentStepComponent, TestCaseAiVerifyStepComponent, TestCaseApiStepComponent, TestCaseConditionStepComponent, TestCaseCustomCodeStepComponent, TestCaseDatabaseStepComponent, TestCaseDetailsRendererComponent, TestCaseLoopStepComponent, TestCaseNormalStepComponent, TestCaseRestoreSessionStepComponent, TestCaseScreenshotStepComponent, TestCaseScrollStepComponent, TestCaseStepGroupComponent, TestCaseUploadStepComponent, TestCaseVerifyUrlStepComponent, TestDataModalComponent, TestDataModalRef, TestDataModalService, TestDistributionCardComponent, UiKitModule, UpdatedFailedStepComponent, ViewMoreFailedStepButtonComponent, VisualComparisonComponent, VisualDifferenceModalComponent, getEmptyStatePreset, getMetadataColor, getMetadataValueStyle, isAiAgentStepConfig, isAiVerifyStepConfig, isApiStepConfig, isConditionStepConfig, isCustomCodeStepConfig, isDatabaseStepConfig, isLoopStepConfig, isNormalStepConfig, isRestoreSessionStepConfig, isScreenshotStepConfig, isScrollStepConfig, isStepGroupConfig, isUploadStepConfig, isVerifyUrlStepConfig };
23380
+ export { ADVANCED_SUBFIELDS_BY_TYPE, ADVANCED_TOGGLE_KEYS, AIActionStepComponent, AIAgentStepComponent, ActionMenuButtonComponent, AddPrerequisiteCasesSectionComponent, AiDebugAlertComponent, AiReasoningComponent, ApiStepComponent, BadgeComponent, BasicStepComponent, ButtonComponent, CUSTOM_EDIT_STEP_DATA, CUSTOM_EDIT_STEP_EDIT_IN_DEPTH, CUSTOM_EDIT_STEP_REF, CUSTOM_ELEMENT_POPUP_REF, ChartCardComponent, ColumnVisibilityComponent, CompareRunsComponent, ConditionStepComponent, ConfigurationCardComponent, ConsoleAlertComponent, CoverageModuleCardComponent, CreateStepGroupComponent, CustomEditStepComponent, CustomEditStepRef, CustomEditStepService, CustomInputComponent, CustomTextareaComponent, CustomToggleComponent, DEFAULT_METADATA_COLOR, DIALOG_DATA, DIALOG_REF, DashboardHeaderComponent, DaterangepickerComponent, DaterangepickerDirective, DbQueryExecutionItemComponent, DbVerificationStepComponent, DeleteStepsComponent, 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, ElementListComponent, ElementPopupComponent, ElementPopupRef, ElementPopupService, EmptyStateComponent, ErrorModalComponent, ExecutionResultModalComponent, FailedStepCardComponent, FailedStepComponent, FailedTestCasesCardComponent, FileDownloadStepComponent, FileUploadComponent, FullTableLoaderComponent, HeatErrorMapCellComponent, InsightCardComponent, ItemListComponent, IterationsLoopComponent, LiveConversationComponent, LiveExecutionStepComponent, LoopStepComponent, MainStepCollapseComponent, MetricsCardComponent, NetworkRequestComponent, OtherButtonComponent, PRIORITY_COLORS, PaginationComponent, ProgressIndicatorComponent, ProgressTextCardComponent, RESULT_COLORS, RunHistoryCardComponent, STATUS_COLORS, STEP_DETAILS_DRAWER_DATA, STEP_DETAILS_DRAWER_REF, STEP_DETAILS_FIELDS_BY_TYPE, STEP_DETAILS_FIELD_META, SearchBarComponent, SegmentControlComponent, SelectedFiltersComponent, SelfHealAnalysisComponent, SimulatorComponent, StepBuilderActionComponent, StepBuilderAiAgentComponent, StepBuilderApiComponent, StepBuilderConditionComponent, StepBuilderCustomCodeComponent, StepBuilderDatabaseComponent, StepBuilderDocumentComponent, StepBuilderDocumentGenerationTemplateStepComponent, StepBuilderLoopComponent, StepBuilderRecordStepComponent, StepDetailsDrawerComponent, StepDetailsDrawerRef, StepDetailsDrawerService, StepGroupComponent, StepProgressCardComponent, StepRendererComponent, StepStatusCardComponent, StepTypes, TEST_DATA_MODAL_DATA, TEST_DATA_MODAL_EDIT_IN_DEPTH, TEST_DATA_MODAL_REF, TableActionToolbarComponent, TableDataLoaderComponent, TableTemplateComponent, TailwindOverlayContainer, TestCaseAiAgentStepComponent, TestCaseAiVerifyStepComponent, TestCaseApiStepComponent, TestCaseConditionStepComponent, TestCaseCustomCodeStepComponent, TestCaseDatabaseStepComponent, TestCaseDetailsRendererComponent, TestCaseLoopStepComponent, TestCaseNormalStepComponent, TestCaseRestoreSessionStepComponent, TestCaseScreenshotStepComponent, TestCaseScrollStepComponent, TestCaseStepGroupComponent, TestCaseUploadStepComponent, TestCaseVerifyUrlStepComponent, TestDataModalComponent, TestDataModalRef, TestDataModalService, TestDistributionCardComponent, UiKitModule, UpdatedFailedStepComponent, ViewMoreFailedStepButtonComponent, VisualComparisonComponent, VisualDifferenceModalComponent, getEmptyStatePreset, getMetadataColor, getMetadataValueStyle, getStepDetailsStepType, isAiAgentStepConfig, isAiVerifyStepConfig, isApiStepConfig, isConditionStepConfig, isCustomCodeStepConfig, isDatabaseStepConfig, isLoopStepConfig, isNormalStepConfig, isRestoreSessionStepConfig, isScreenshotStepConfig, isScrollStepConfig, isStepGroupConfig, isUploadStepConfig, isVerifyUrlStepConfig };
22792
23381
  //# sourceMappingURL=cqa-lib-cqa-ui.mjs.map