@cqa-lib/cqa-ui 1.1.264 → 1.1.266

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.
@@ -25293,10 +25293,10 @@ class AdvancedVariablesFormComponent {
25293
25293
  }
25294
25294
  }
25295
25295
  AdvancedVariablesFormComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: AdvancedVariablesFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
25296
- AdvancedVariablesFormComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: AdvancedVariablesFormComponent, selector: "cqa-advanced-variables-form", inputs: { advancedVariables: "advancedVariables", advancedVariableForm: "advancedVariableForm" }, outputs: { variableBooleanChange: "variableBooleanChange", variableValueChange: "variableValueChange" }, host: { classAttribute: "cqa-ui-root" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"cqa-flex cqa-gap-x-6 cqa-gap-y-4 cqa-flex-wrap advanced-variables-form cqa-mb-4\">\n <ng-container *ngFor=\"let variable of advancedVariables; let i = index; trackBy: trackByVariable\">\n <!-- Boolean variables with mat-slide-toggle -->\n <ng-container *ngIf=\"isBooleanType(variable)\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\" style=\"width: 100%\">\n <mat-slide-toggle \n [checked]=\"getBooleanValue(variable, i)\"\n (change)=\"onVariableBooleanChange(variable.name, $event.checked)\" \n color=\"primary\">\n </mat-slide-toggle>\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 capitalize-first\">\n {{ variable.label }}\n </label>\n </div>\n </ng-container>\n\n <!-- str_list variables with dynamic list -->\n <ng-container *ngIf=\"isStrListType(variable)\">\n <div class=\"cqa-flex cqa-flex-col cqa-w-full\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label }}\n </label>\n <div class=\"cqa-flex cqa-flex-col cqa-gap-2\">\n <ng-container *ngIf=\"getStrListFormArray(variable, i) as formArray\">\n <div *ngFor=\"let control of formArray.controls; let itemIndex = index; trackBy: trackByControl\" class=\"cqa-flex cqa-gap-2 cqa-items-center\">\n <cqa-custom-input \n [placeholder]=\"'Enter locator'\" \n [value]=\"control.value\" \n [fullWidth]=\"true\"\n (valueChange)=\"onStrListItemChange(variable, i, itemIndex, $event)\">\n </cqa-custom-input>\n <div class=\"cqa-cursor-pointer cqa-text-red-600 cqa-flex cqa-items-center cqa-justify-center\" (click)=\"removeStrListItem(variable, i, itemIndex)\">\n <mat-icon style=\"font-size: 24px;\">delete</mat-icon>\n </div>\n <div *ngIf=\"itemIndex === formArray.length - 1\" class=\"cqa-cursor-pointer cqa-text-blue-600 cqa-flex cqa-items-center cqa-justify-center\" (click)=\"addStrListItem(variable, i)\">\n <mat-icon style=\"font-size: 24px;\">add</mat-icon>\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n </ng-container>\n </ng-container>\n</div>\n\n", components: [{ type: i4$2.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["disabled", "disableRipple", "color", "tabIndex", "name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "checked"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { 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: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], directives: [{ type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
25296
+ AdvancedVariablesFormComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: AdvancedVariablesFormComponent, selector: "cqa-advanced-variables-form", inputs: { advancedVariables: "advancedVariables", advancedVariableForm: "advancedVariableForm" }, outputs: { variableBooleanChange: "variableBooleanChange", variableValueChange: "variableValueChange" }, host: { classAttribute: "cqa-ui-root" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"cqa-flex cqa-gap-x-6 cqa-gap-y-4 cqa-flex-wrap advanced-variables-form cqa-mb-4\">\n <ng-container *ngFor=\"let variable of advancedVariables; let i = index; trackBy: trackByVariable\">\n <!-- Boolean variables with mat-slide-toggle -->\n <ng-container *ngIf=\"isBooleanType(variable)\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\" style=\"width: 100%\">\n <mat-slide-toggle \n [checked]=\"getBooleanValue(variable, i)\"\n (change)=\"onVariableBooleanChange(variable.name, $event.checked)\" \n color=\"primary\">\n </mat-slide-toggle>\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 capitalize-first\">\n {{ variable.label }}\n </label>\n </div>\n </ng-container>\n\n <!-- str_list variables with dynamic list -->\n <ng-container *ngIf=\"isStrListType(variable)\">\n <div class=\"cqa-flex cqa-flex-col cqa-w-full\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label }}\n </label>\n <div class=\"cqa-flex cqa-flex-col cqa-gap-2\">\n <ng-container *ngIf=\"getStrListFormArray(variable, i) as formArray\">\n <div *ngFor=\"let control of formArray.controls; let itemIndex = index; trackBy: trackByControl\" class=\"cqa-flex cqa-gap-2 cqa-items-center\">\n <cqa-custom-input \n [placeholder]=\"'Enter locator'\" \n [value]=\"control.value\" \n [fullWidth]=\"true\"\n (valueChange)=\"onStrListItemChange(variable, i, itemIndex, $event)\">\n </cqa-custom-input>\n <div *ngIf=\"formArray.length > 1\" class=\"cqa-cursor-pointer cqa-text-red-600 cqa-flex cqa-items-center cqa-justify-center\" (click)=\"removeStrListItem(variable, i, itemIndex)\">\n <mat-icon style=\"font-size: 24px;\">delete</mat-icon>\n </div>\n <div *ngIf=\"itemIndex === formArray.length - 1\" class=\"cqa-cursor-pointer cqa-text-blue-600 cqa-flex cqa-items-center cqa-justify-center\" (click)=\"addStrListItem(variable, i)\">\n <mat-icon style=\"font-size: 24px;\">add</mat-icon>\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n </ng-container>\n </ng-container>\n</div>\n\n", components: [{ type: i4$2.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["disabled", "disableRipple", "color", "tabIndex", "name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "checked"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { 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: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], directives: [{ type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
25297
25297
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: AdvancedVariablesFormComponent, decorators: [{
25298
25298
  type: Component,
25299
- args: [{ selector: 'cqa-advanced-variables-form', host: { class: 'cqa-ui-root' }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"cqa-flex cqa-gap-x-6 cqa-gap-y-4 cqa-flex-wrap advanced-variables-form cqa-mb-4\">\n <ng-container *ngFor=\"let variable of advancedVariables; let i = index; trackBy: trackByVariable\">\n <!-- Boolean variables with mat-slide-toggle -->\n <ng-container *ngIf=\"isBooleanType(variable)\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\" style=\"width: 100%\">\n <mat-slide-toggle \n [checked]=\"getBooleanValue(variable, i)\"\n (change)=\"onVariableBooleanChange(variable.name, $event.checked)\" \n color=\"primary\">\n </mat-slide-toggle>\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 capitalize-first\">\n {{ variable.label }}\n </label>\n </div>\n </ng-container>\n\n <!-- str_list variables with dynamic list -->\n <ng-container *ngIf=\"isStrListType(variable)\">\n <div class=\"cqa-flex cqa-flex-col cqa-w-full\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label }}\n </label>\n <div class=\"cqa-flex cqa-flex-col cqa-gap-2\">\n <ng-container *ngIf=\"getStrListFormArray(variable, i) as formArray\">\n <div *ngFor=\"let control of formArray.controls; let itemIndex = index; trackBy: trackByControl\" class=\"cqa-flex cqa-gap-2 cqa-items-center\">\n <cqa-custom-input \n [placeholder]=\"'Enter locator'\" \n [value]=\"control.value\" \n [fullWidth]=\"true\"\n (valueChange)=\"onStrListItemChange(variable, i, itemIndex, $event)\">\n </cqa-custom-input>\n <div class=\"cqa-cursor-pointer cqa-text-red-600 cqa-flex cqa-items-center cqa-justify-center\" (click)=\"removeStrListItem(variable, i, itemIndex)\">\n <mat-icon style=\"font-size: 24px;\">delete</mat-icon>\n </div>\n <div *ngIf=\"itemIndex === formArray.length - 1\" class=\"cqa-cursor-pointer cqa-text-blue-600 cqa-flex cqa-items-center cqa-justify-center\" (click)=\"addStrListItem(variable, i)\">\n <mat-icon style=\"font-size: 24px;\">add</mat-icon>\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n </ng-container>\n </ng-container>\n</div>\n\n", styles: [] }]
25299
+ args: [{ selector: 'cqa-advanced-variables-form', host: { class: 'cqa-ui-root' }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"cqa-flex cqa-gap-x-6 cqa-gap-y-4 cqa-flex-wrap advanced-variables-form cqa-mb-4\">\n <ng-container *ngFor=\"let variable of advancedVariables; let i = index; trackBy: trackByVariable\">\n <!-- Boolean variables with mat-slide-toggle -->\n <ng-container *ngIf=\"isBooleanType(variable)\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\" style=\"width: 100%\">\n <mat-slide-toggle \n [checked]=\"getBooleanValue(variable, i)\"\n (change)=\"onVariableBooleanChange(variable.name, $event.checked)\" \n color=\"primary\">\n </mat-slide-toggle>\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 capitalize-first\">\n {{ variable.label }}\n </label>\n </div>\n </ng-container>\n\n <!-- str_list variables with dynamic list -->\n <ng-container *ngIf=\"isStrListType(variable)\">\n <div class=\"cqa-flex cqa-flex-col cqa-w-full\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label }}\n </label>\n <div class=\"cqa-flex cqa-flex-col cqa-gap-2\">\n <ng-container *ngIf=\"getStrListFormArray(variable, i) as formArray\">\n <div *ngFor=\"let control of formArray.controls; let itemIndex = index; trackBy: trackByControl\" class=\"cqa-flex cqa-gap-2 cqa-items-center\">\n <cqa-custom-input \n [placeholder]=\"'Enter locator'\" \n [value]=\"control.value\" \n [fullWidth]=\"true\"\n (valueChange)=\"onStrListItemChange(variable, i, itemIndex, $event)\">\n </cqa-custom-input>\n <div *ngIf=\"formArray.length > 1\" class=\"cqa-cursor-pointer cqa-text-red-600 cqa-flex cqa-items-center cqa-justify-center\" (click)=\"removeStrListItem(variable, i, itemIndex)\">\n <mat-icon style=\"font-size: 24px;\">delete</mat-icon>\n </div>\n <div *ngIf=\"itemIndex === formArray.length - 1\" class=\"cqa-cursor-pointer cqa-text-blue-600 cqa-flex cqa-items-center cqa-justify-center\" (click)=\"addStrListItem(variable, i)\">\n <mat-icon style=\"font-size: 24px;\">add</mat-icon>\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n </ng-container>\n </ng-container>\n</div>\n\n", styles: [] }]
25300
25300
  }], propDecorators: { advancedVariables: [{
25301
25301
  type: Input
25302
25302
  }], advancedVariableForm: [{
@@ -27417,15 +27417,18 @@ class TemplateVariablesFormComponent {
27417
27417
  if (this.isElementType(variable) && variable.screenNameId) {
27418
27418
  const variableGroup = this.getVariableFormGroup(variable.name);
27419
27419
  if (variableGroup) {
27420
- // Initialize screen name form control with screenNameId (since valueBy is 'screenNameId')
27420
+ // Initialize screen name form control with screenNameId as string (to match option id format), or 'none' by default
27421
27421
  if (!variableGroup.get('selectedScreenName')) {
27422
- variableGroup.addControl('selectedScreenName', new FormControl(variable.screenNameId));
27422
+ const initialValue = variable.screenNameId ? String(variable.screenNameId) : 'none';
27423
+ variableGroup.addControl('selectedScreenName', new FormControl(initialValue));
27423
27424
  }
27424
27425
  else {
27425
27426
  // Update form control value if it doesn't match
27426
27427
  const currentValue = (_a = variableGroup.get('selectedScreenName')) === null || _a === void 0 ? void 0 : _a.value;
27427
- if (currentValue !== variable.screenNameId) {
27428
- (_b = variableGroup.get('selectedScreenName')) === null || _b === void 0 ? void 0 : _b.setValue(variable.screenNameId, { emitEvent: false });
27428
+ const expectedValue = variable.screenNameId ? String(variable.screenNameId) : 'none';
27429
+ const currentValueStr = currentValue != null ? String(currentValue) : null;
27430
+ if (currentValueStr !== expectedValue && currentValue !== variable.screenNameId) {
27431
+ (_b = variableGroup.get('selectedScreenName')) === null || _b === void 0 ? void 0 : _b.setValue(expectedValue, { emitEvent: false });
27429
27432
  }
27430
27433
  }
27431
27434
  // If we have screenNameId but not selectedScreenName, find it from screenNameOptions
@@ -27456,71 +27459,109 @@ class TemplateVariablesFormComponent {
27456
27459
  // This ensures that when elements are loaded after screen name selection, the config is recomputed
27457
27460
  this.elementSelectConfigCache.clear();
27458
27461
  this.templateVariables.forEach((variable) => {
27459
- var _a, _b, _c;
27462
+ var _a, _b, _c, _d, _e, _f, _g;
27460
27463
  if (this.isElementType(variable)) {
27461
27464
  const variableGroup = this.getVariableFormGroup(variable.name);
27462
27465
  if (variableGroup) {
27463
- let element = null;
27464
- // Priority 1: Find by elementId if available (from setTemplateVariables)
27466
+ // Only try to find and set element if elementId exists in template data
27467
+ // If no elementId, don't select anything - use default values
27465
27468
  if (variable.elementId) {
27469
+ let element = null;
27470
+ // Priority 1: Find by elementId (from setTemplateVariables)
27466
27471
  element = this.elementOptions.find(el => el.id === variable.elementId);
27467
- }
27468
- // Priority 2: Find by elementName if available (from setTemplateVariables)
27469
- if (!element && variable.elementName) {
27470
- element = this.elementOptions.find(el => el.name === variable.elementName);
27471
- }
27472
- // Priority 3: Find by locatorValue (for backward compatibility)
27473
- if (!element && variable.value) {
27474
- const elementValue = variable.value;
27475
- element = this.elementOptions.find(el => el.locatorValue === elementValue);
27476
- }
27477
- if (element) {
27478
- // Set screen name info from the found element
27479
- if (element.screenNameId && element.screenNameObj) {
27480
- variable.selectedScreenName = element.screenNameObj.name;
27481
- variable.screenNameId = element.screenNameId;
27482
- // Set form controls
27483
- // Since valueBy is 'screenNameId', we need to store the screenNameId (number) in the form control
27484
- if (!variableGroup.get('selectedScreenName')) {
27485
- variableGroup.addControl('selectedScreenName', new FormControl(element.screenNameId));
27472
+ // Priority 2: Find by elementName if elementId search didn't find it (fallback)
27473
+ if (!element && variable.elementName) {
27474
+ element = this.elementOptions.find(el => el.name === variable.elementName);
27475
+ }
27476
+ // Priority 3: Find by locatorValue (for backward compatibility)
27477
+ if (!element && variable.value) {
27478
+ const elementValue = variable.value;
27479
+ element = this.elementOptions.find(el => el.locatorValue === elementValue);
27480
+ }
27481
+ if (element) {
27482
+ // Set screen name info from the found element
27483
+ if (element.screenNameId && element.screenNameObj) {
27484
+ variable.selectedScreenName = element.screenNameObj.name;
27485
+ variable.screenNameId = element.screenNameId;
27486
+ // Set form controls
27487
+ // Store screenNameId as string to match option id format (for consistency with getScreenNameSelectConfig)
27488
+ const screenNameIdString = String(element.screenNameId);
27489
+ if (!variableGroup.get('selectedScreenName')) {
27490
+ variableGroup.addControl('selectedScreenName', new FormControl(screenNameIdString));
27491
+ }
27492
+ else {
27493
+ // Only update if form control doesn't already have a valid screen name selected
27494
+ // This prevents resetting user's selection when elementOptions changes
27495
+ const currentValue = (_a = variableGroup.get('selectedScreenName')) === null || _a === void 0 ? void 0 : _a.value;
27496
+ const currentValueStr = currentValue != null ? String(currentValue) : null;
27497
+ if (currentValueStr !== screenNameIdString && currentValueStr !== 'none') {
27498
+ (_b = variableGroup.get('selectedScreenName')) === null || _b === void 0 ? void 0 : _b.setValue(screenNameIdString, { emitEvent: false });
27499
+ }
27500
+ }
27501
+ }
27502
+ // Set/update element details from the found element
27503
+ variable.elementId = element.id;
27504
+ variable.elementLocator = element.locatorValue || '';
27505
+ // Only update elementName if it wasn't already set (preserve from setTemplateVariables)
27506
+ if (!variable.elementName) {
27507
+ variable.elementName = element.name || '';
27508
+ }
27509
+ // For selector, use elementLocator as value; for others, use elementName
27510
+ if (variable.name === 'selector') {
27511
+ variable.value = element.locatorValue || element.name || '';
27512
+ }
27513
+ else if (!variable.value || variable.value === '') {
27514
+ variable.value = element.name || element.locatorValue || '';
27515
+ }
27516
+ // Set element ID form control for the dropdown (key is 'id' in config)
27517
+ if (!variableGroup.get('id')) {
27518
+ variableGroup.addControl('id', new FormControl(element.id));
27486
27519
  }
27487
27520
  else {
27488
- (_a = variableGroup.get('selectedScreenName')) === null || _a === void 0 ? void 0 : _a.setValue(element.screenNameId, { emitEvent: false });
27521
+ (_c = variableGroup.get('id')) === null || _c === void 0 ? void 0 : _c.setValue(element.id, { emitEvent: false });
27522
+ }
27523
+ // Update value form control
27524
+ if (variableGroup.get('value')) {
27525
+ (_d = variableGroup.get('value')) === null || _d === void 0 ? void 0 : _d.setValue(variable.value, { emitEvent: false });
27489
27526
  }
27490
27527
  }
27491
- // Set/update element details from the found element
27492
- variable.elementId = element.id;
27493
- variable.elementLocator = element.locatorValue || '';
27494
- // Only update elementName if it wasn't already set (preserve from setTemplateVariables)
27495
- if (!variable.elementName) {
27496
- variable.elementName = element.name || '';
27497
- }
27498
- // For selector, use elementLocator as value; for others, use elementName
27499
- if (variable.name === 'selector') {
27500
- variable.value = element.locatorValue || element.name || '';
27528
+ else {
27529
+ // Element not found in elementOptions yet - might need to fetch
27530
+ // Keep elementId and elementName if they exist (from setTemplateVariables)
27531
+ // If we have elementId but element isn't found, we might need to fetch elements
27532
+ // However, we don't know the screen name yet, so we'll wait for elementOptions to be loaded
27533
+ // The initialization will run again when elementOptions changes via ngOnChanges
27501
27534
  }
27502
- else if (!variable.value || variable.value === '') {
27503
- variable.value = element.name || element.locatorValue || '';
27535
+ }
27536
+ else {
27537
+ // No elementId in template data - clear all element-related fields and set defaults
27538
+ // But don't override user's screen name selection if they've already selected one
27539
+ variable.elementId = undefined;
27540
+ variable.elementLocator = undefined;
27541
+ variable.elementName = undefined;
27542
+ // Only clear screenNameId if it wasn't set by user selection
27543
+ // Check if form control has a valid screen name (not 'none')
27544
+ const currentScreenNameValue = (_e = variableGroup.get('selectedScreenName')) === null || _e === void 0 ? void 0 : _e.value;
27545
+ if (!currentScreenNameValue || currentScreenNameValue === 'none' || currentScreenNameValue === null) {
27546
+ variable.screenNameId = undefined;
27547
+ variable.selectedScreenName = undefined;
27548
+ // Set form controls to default values
27549
+ // Screen name should be 'none' (Select option)
27550
+ if (!variableGroup.get('selectedScreenName')) {
27551
+ variableGroup.addControl('selectedScreenName', new FormControl('none'));
27552
+ }
27553
+ else {
27554
+ (_f = variableGroup.get('selectedScreenName')) === null || _f === void 0 ? void 0 : _f.setValue('none', { emitEvent: false });
27555
+ }
27504
27556
  }
27505
- // Set element ID form control for the dropdown (key is 'id' in config)
27557
+ // Element ID should be null
27506
27558
  if (!variableGroup.get('id')) {
27507
- variableGroup.addControl('id', new FormControl(element.id));
27559
+ variableGroup.addControl('id', new FormControl(null));
27508
27560
  }
27509
27561
  else {
27510
- (_b = variableGroup.get('id')) === null || _b === void 0 ? void 0 : _b.setValue(element.id, { emitEvent: false });
27511
- }
27512
- // Update value form control
27513
- if (variableGroup.get('value')) {
27514
- (_c = variableGroup.get('value')) === null || _c === void 0 ? void 0 : _c.setValue(variable.value, { emitEvent: false });
27562
+ (_g = variableGroup.get('id')) === null || _g === void 0 ? void 0 : _g.setValue(null, { emitEvent: false });
27515
27563
  }
27516
27564
  }
27517
- else {
27518
- // Element not found in elementOptions yet - might need to fetch
27519
- // Keep elementId and elementName if they exist (from setTemplateVariables)
27520
- // If we have elementId but element isn't found, we might need to fetch elements
27521
- // However, we don't know the screen name yet, so we'll wait for elementOptions to be loaded
27522
- // The initialization will run again when elementOptions changes via ngOnChanges
27523
- }
27524
27565
  }
27525
27566
  }
27526
27567
  });
@@ -27579,7 +27620,7 @@ class TemplateVariablesFormComponent {
27579
27620
  }
27580
27621
  initializeTestDataVariables() {
27581
27622
  this.templateVariables.forEach((variable, index) => {
27582
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
27623
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
27583
27624
  if (this.needsDataTypeDropdown(variable)) {
27584
27625
  const { dataType, rawValue } = this.parseTestDataValue(variable.value || '');
27585
27626
  // Set properties directly on the variable object
@@ -27738,66 +27779,104 @@ class TemplateVariablesFormComponent {
27738
27779
  }
27739
27780
  // For element type, parse the value to extract screen name and element
27740
27781
  if (this.isElementType(variable)) {
27741
- let element = null;
27742
- // Priority 1: Find by elementId if available (from setTemplateVariables)
27782
+ // Only try to find and set element if elementId exists in template data
27783
+ // If no elementId, don't select anything - use default values
27743
27784
  if (variable.elementId) {
27785
+ let element = null;
27786
+ // Priority 1: Find by elementId (from setTemplateVariables)
27744
27787
  element = this.elementOptions.find(el => el.id === variable.elementId);
27745
- }
27746
- // Priority 2: Find by elementName if available (from setTemplateVariables)
27747
- if (!element && variable.elementName) {
27748
- element = this.elementOptions.find(el => el.name === variable.elementName);
27749
- }
27750
- // Priority 3: Find by locatorValue (for backward compatibility)
27751
- if (!element && variable.value) {
27752
- const elementValue = variable.value;
27753
- element = this.elementOptions.find(el => el.locatorValue === elementValue);
27754
- }
27755
- if (element) {
27756
- // Set screen name info from the found element
27757
- if (element.screenNameId && element.screenNameObj) {
27758
- variable.selectedScreenName = element.screenNameObj.name;
27759
- variable.screenNameId = element.screenNameId;
27760
- // Set form controls
27761
- // Since valueBy is 'screenNameId', we need to store the screenNameId (number) in the form control
27762
- if (!variableGroup.get('selectedScreenName')) {
27763
- variableGroup.addControl('selectedScreenName', new FormControl(element.screenNameId));
27788
+ // Priority 2: Find by elementName if elementId search didn't find it (fallback)
27789
+ if (!element && variable.elementName) {
27790
+ element = this.elementOptions.find(el => el.name === variable.elementName);
27791
+ }
27792
+ // Priority 3: Find by locatorValue (for backward compatibility)
27793
+ if (!element && variable.value) {
27794
+ const elementValue = variable.value;
27795
+ element = this.elementOptions.find(el => el.locatorValue === elementValue);
27796
+ }
27797
+ if (element) {
27798
+ // Set screen name info from the found element
27799
+ if (element.screenNameId && element.screenNameObj) {
27800
+ variable.selectedScreenName = element.screenNameObj.name;
27801
+ variable.screenNameId = element.screenNameId;
27802
+ // Set form controls
27803
+ // Store screenNameId as string to match option id format (for consistency with getScreenNameSelectConfig)
27804
+ const screenNameIdString = String(element.screenNameId);
27805
+ if (!variableGroup.get('selectedScreenName')) {
27806
+ variableGroup.addControl('selectedScreenName', new FormControl(screenNameIdString));
27807
+ }
27808
+ else {
27809
+ // Only update if form control doesn't already have a valid screen name selected
27810
+ // This prevents resetting user's selection when elementOptions changes
27811
+ const currentValue = (_l = variableGroup.get('selectedScreenName')) === null || _l === void 0 ? void 0 : _l.value;
27812
+ const currentValueStr = currentValue != null ? String(currentValue) : null;
27813
+ if (currentValueStr !== screenNameIdString && currentValueStr !== 'none') {
27814
+ (_m = variableGroup.get('selectedScreenName')) === null || _m === void 0 ? void 0 : _m.setValue(screenNameIdString, { emitEvent: false });
27815
+ }
27816
+ }
27817
+ }
27818
+ // Set/update element details from the found element
27819
+ variable.elementId = element.id;
27820
+ variable.elementLocator = element.locatorValue || '';
27821
+ // Only update elementName if it wasn't already set (preserve from setTemplateVariables)
27822
+ if (!variable.elementName) {
27823
+ variable.elementName = element.name || '';
27824
+ }
27825
+ // For selector, use elementLocator as value; for others, use elementName
27826
+ if (variable.name === 'selector') {
27827
+ variable.value = element.locatorValue || element.name || '';
27828
+ }
27829
+ else if (!variable.value || variable.value === '') {
27830
+ variable.value = element.name || element.locatorValue || '';
27831
+ }
27832
+ // Set element ID form control for the dropdown (key is 'id' in config)
27833
+ if (!variableGroup.get('id')) {
27834
+ variableGroup.addControl('id', new FormControl(element.id));
27764
27835
  }
27765
27836
  else {
27766
- (_l = variableGroup.get('selectedScreenName')) === null || _l === void 0 ? void 0 : _l.setValue(element.screenNameId, { emitEvent: false });
27837
+ (_o = variableGroup.get('id')) === null || _o === void 0 ? void 0 : _o.setValue(element.id, { emitEvent: false });
27838
+ }
27839
+ // Update value form control
27840
+ if (variableGroup.get('value')) {
27841
+ (_p = variableGroup.get('value')) === null || _p === void 0 ? void 0 : _p.setValue(variable.value, { emitEvent: false });
27767
27842
  }
27768
27843
  }
27769
- // Set/update element details from the found element
27770
- variable.elementId = element.id;
27771
- variable.elementLocator = element.locatorValue || '';
27772
- // Only update elementName if it wasn't already set (preserve from setTemplateVariables)
27773
- if (!variable.elementName) {
27774
- variable.elementName = element.name || '';
27775
- }
27776
- // For selector, use elementLocator as value; for others, use elementName
27777
- if (variable.name === 'selector') {
27778
- variable.value = element.locatorValue || element.name || '';
27844
+ else {
27845
+ // Element not found in elementOptions yet - might need to fetch
27846
+ // Keep elementId and elementName if they exist (from setTemplateVariables)
27847
+ // If we have elementId but element isn't found, we might need to fetch elements
27848
+ // However, we don't know the screen name yet, so we'll wait for elementOptions to be loaded
27849
+ // The initialization will run again when elementOptions changes via ngOnChanges
27779
27850
  }
27780
- else if (!variable.value || variable.value === '') {
27781
- variable.value = element.name || element.locatorValue || '';
27851
+ }
27852
+ else {
27853
+ // No elementId in template data - clear all element-related fields and set defaults
27854
+ // But don't override user's screen name selection if they've already selected one
27855
+ variable.elementId = undefined;
27856
+ variable.elementLocator = undefined;
27857
+ variable.elementName = undefined;
27858
+ // Only clear screenNameId if it wasn't set by user selection
27859
+ // Check if form control has a valid screen name (not 'none')
27860
+ const currentScreenNameValue = (_q = variableGroup.get('selectedScreenName')) === null || _q === void 0 ? void 0 : _q.value;
27861
+ if (!currentScreenNameValue || currentScreenNameValue === 'none' || currentScreenNameValue === null) {
27862
+ variable.screenNameId = undefined;
27863
+ variable.selectedScreenName = undefined;
27864
+ // Set form controls to default values
27865
+ // Screen name should be 'none' (Select option)
27866
+ if (!variableGroup.get('selectedScreenName')) {
27867
+ variableGroup.addControl('selectedScreenName', new FormControl('none'));
27868
+ }
27869
+ else {
27870
+ (_r = variableGroup.get('selectedScreenName')) === null || _r === void 0 ? void 0 : _r.setValue('none', { emitEvent: false });
27871
+ }
27782
27872
  }
27783
- // Set element ID form control for the dropdown (key is 'id' in config)
27873
+ // Element ID should be null
27784
27874
  if (!variableGroup.get('id')) {
27785
- variableGroup.addControl('id', new FormControl(element.id));
27875
+ variableGroup.addControl('id', new FormControl(null));
27786
27876
  }
27787
27877
  else {
27788
- (_m = variableGroup.get('id')) === null || _m === void 0 ? void 0 : _m.setValue(element.id, { emitEvent: false });
27878
+ (_s = variableGroup.get('id')) === null || _s === void 0 ? void 0 : _s.setValue(null, { emitEvent: false });
27789
27879
  }
27790
- // Update value form control
27791
- if (variableGroup.get('value')) {
27792
- (_o = variableGroup.get('value')) === null || _o === void 0 ? void 0 : _o.setValue(variable.value, { emitEvent: false });
27793
- }
27794
- }
27795
- else {
27796
- // Element not found in elementOptions yet - might need to fetch
27797
- // Keep elementId and elementName if they exist (from setTemplateVariables)
27798
- // If we have elementId but element isn't found, we might need to fetch elements
27799
- // However, we don't know the screen name yet, so we'll wait for elementOptions to be loaded
27800
- // The initialization will run again when elementOptions changes via ngOnChanges
27801
27880
  }
27802
27881
  }
27803
27882
  }
@@ -28882,46 +28961,69 @@ class TemplateVariablesFormComponent {
28882
28961
  }
28883
28962
  /**
28884
28963
  * Check if screen name is selected for an element variable
28964
+ * Returns true if either selectedScreenName or screenNameId is set (and not "None")
28885
28965
  */
28886
28966
  hasSelectedScreenName(variable) {
28967
+ // Check if screenNameId exists and is a valid number (not null/undefined)
28968
+ if (variable.screenNameId != null && typeof variable.screenNameId === 'number' && !isNaN(variable.screenNameId)) {
28969
+ return true;
28970
+ }
28971
+ // Fallback: check selectedScreenName
28887
28972
  return !!variable.selectedScreenName;
28888
28973
  }
28889
28974
  /**
28890
28975
  * Get select config for screen name dropdown (first dropdown for element variables)
28891
28976
  */
28892
28977
  getScreenNameSelectConfig(variable, index) {
28893
- var _a, _b;
28978
+ var _a, _b, _c, _d;
28894
28979
  // Include loading state in cache key to invalidate when loading completes
28895
28980
  const cacheKey = `${variable.name}_screenName_${this.screenNameOptions.length}_${this.isLoadingScreenNames}`;
28896
28981
  if (this.screenNameSelectConfigCache.has(cacheKey)) {
28897
28982
  return this.screenNameSelectConfigCache.get(cacheKey);
28898
28983
  }
28899
- // Use screenNameOptions from API (not extracted from elementOptions)
28900
- const optionsArray = this.screenNameOptions.map(screenName => {
28901
- var _a;
28902
- return ({
28903
- id: ((_a = screenName.id) === null || _a === void 0 ? void 0 : _a.toString()) || '',
28904
- value: screenName.name,
28905
- name: screenName.name,
28906
- label: screenName.name,
28907
- screenNameId: screenName.id
28908
- });
28909
- });
28984
+ // Build options: include a "None" option (displayed as "Select") plus screenNameOptions from API
28985
+ const optionsArray = [
28986
+ {
28987
+ id: 'none',
28988
+ value: 'Select',
28989
+ name: 'None',
28990
+ label: 'None'
28991
+ },
28992
+ ...this.screenNameOptions.map(screenName => {
28993
+ var _a;
28994
+ return ({
28995
+ id: ((_a = screenName.id) === null || _a === void 0 ? void 0 : _a.toString()) || '',
28996
+ value: screenName.name,
28997
+ name: screenName.name,
28998
+ label: screenName.name
28999
+ });
29000
+ })
29001
+ ];
28910
29002
  // Ensure form control exists for screen name selection
28911
- // Since valueBy is 'screenNameId', we need to store the screenNameId (number) in the form control
29003
+ // The form control value should match the option id (string for "none", string representation of number for real screen names)
28912
29004
  const variableGroup = this.getVariableFormGroup(variable.name);
28913
29005
  if (variableGroup) {
28914
29006
  if (!variableGroup.get('selectedScreenName')) {
28915
- // Initialize with screenNameId if available, otherwise null
28916
- const initialValue = variable.screenNameId || null;
29007
+ // Initialize with screenNameId as string (to match option id format), or 'none' by default
29008
+ const initialValue = variable.screenNameId ? String(variable.screenNameId) : 'none';
28917
29009
  variableGroup.addControl('selectedScreenName', new FormControl(initialValue));
28918
29010
  }
28919
29011
  else {
28920
29012
  // Update form control value if variable has screenNameId but form control doesn't match
28921
29013
  if (variable.screenNameId) {
28922
29014
  const currentValue = (_a = variableGroup.get('selectedScreenName')) === null || _a === void 0 ? void 0 : _a.value;
28923
- if (currentValue !== variable.screenNameId) {
28924
- (_b = variableGroup.get('selectedScreenName')) === null || _b === void 0 ? void 0 : _b.setValue(variable.screenNameId, { emitEvent: false });
29015
+ const expectedValue = String(variable.screenNameId);
29016
+ // Compare as strings to handle both number and string values
29017
+ const currentValueStr = currentValue != null ? String(currentValue) : null;
29018
+ if (currentValueStr !== expectedValue) {
29019
+ (_b = variableGroup.get('selectedScreenName')) === null || _b === void 0 ? void 0 : _b.setValue(expectedValue, { emitEvent: false });
29020
+ }
29021
+ }
29022
+ else {
29023
+ // If no screenNameId, ensure form control is 'none' (for "None" selection by default)
29024
+ const currentValue = (_c = variableGroup.get('selectedScreenName')) === null || _c === void 0 ? void 0 : _c.value;
29025
+ if (currentValue !== 'none' && currentValue !== null && currentValue !== '') {
29026
+ (_d = variableGroup.get('selectedScreenName')) === null || _d === void 0 ? void 0 : _d.setValue('none', { emitEvent: false });
28925
29027
  }
28926
29028
  }
28927
29029
  }
@@ -28935,43 +29037,93 @@ class TemplateVariablesFormComponent {
28935
29037
  options: optionsArray,
28936
29038
  hasMore: this.hasMoreScreenNames,
28937
29039
  isLoading: this.isLoadingScreenNames,
28938
- valueBy: 'screenNameId',
28939
29040
  onChange: (value) => {
28940
- var _a;
28941
- // Store selected screen name on the variable object
28942
- // value is the screenNameId (number) since valueBy is 'screenNameId'
28943
- variable.screenNameId = value;
28944
- // Find and store screen name name from screenNameOptions
28945
- const screenNameOption = this.screenNameOptions.find(sn => sn.id === value);
28946
- if (screenNameOption && screenNameOption.id) {
28947
- variable.selectedScreenName = screenNameOption.name;
28948
- }
28949
- // Clear the element selection when screen name changes
28950
- variable.value = '';
28951
- // Clear element config cache to force refresh
28952
- // Clear all element configs for this variable since screen name changed
28953
- const keysToDelete = [];
28954
- this.elementSelectConfigCache.forEach((_, key) => {
28955
- if (key.startsWith(`${variable.name}_element`)) {
28956
- keysToDelete.push(key);
28957
- }
28958
- });
28959
- keysToDelete.forEach(key => this.elementSelectConfigCache.delete(key));
28960
- // Update form control
28961
- if (variableGroup) {
28962
- if (variableGroup.get('value')) {
28963
- (_a = variableGroup.get('value')) === null || _a === void 0 ? void 0 : _a.setValue('', { emitEvent: false });
29041
+ var _a, _b, _c, _d, _e;
29042
+ // If "None" is selected (value is 'none' string or null), clear screen name and element info
29043
+ if (value == null || value === 'none' || value === '') {
29044
+ variable.screenNameId = undefined;
29045
+ variable.selectedScreenName = undefined;
29046
+ variable.elementId = undefined;
29047
+ variable.elementLocator = undefined;
29048
+ variable.elementName = undefined;
29049
+ variable.value = '';
29050
+ // Clear element config cache for this variable
29051
+ const keysToDelete = [];
29052
+ this.elementSelectConfigCache.forEach((_, key) => {
29053
+ if (key.startsWith(`${variable.name}_element`)) {
29054
+ keysToDelete.push(key);
29055
+ }
29056
+ });
29057
+ keysToDelete.forEach(key => this.elementSelectConfigCache.delete(key));
29058
+ // Update form controls - clear all element-related form controls
29059
+ // Set selectedScreenName to 'none' to show "None" is selected
29060
+ if (variableGroup) {
29061
+ if (variableGroup.get('value')) {
29062
+ (_a = variableGroup.get('value')) === null || _a === void 0 ? void 0 : _a.setValue('', { emitEvent: false });
29063
+ }
29064
+ if (variableGroup.get('selectedScreenName')) {
29065
+ (_b = variableGroup.get('selectedScreenName')) === null || _b === void 0 ? void 0 : _b.setValue('none', { emitEvent: false });
29066
+ }
29067
+ // Clear element ID form control to ensure elementId is cleared
29068
+ if (variableGroup.get('id')) {
29069
+ (_c = variableGroup.get('id')) === null || _c === void 0 ? void 0 : _c.setValue(null, { emitEvent: false });
29070
+ }
28964
29071
  }
28965
- // The form control already has the correct value (screenNameId) from the dropdown
28966
- // No need to update it here as it's already set by mat-select
29072
+ // Mark for check and stop (no element fetch when None)
29073
+ this.cdr.markForCheck();
29074
+ return;
28967
29075
  }
28968
- // Emit event to fetch elements filtered by selected screen name
28969
- if (variable.screenNameId) {
29076
+ // value is the option id (string for "none", string representation of number for real screen names)
29077
+ // Convert to number for screenNameId if it's a valid number
29078
+ const screenNameIdNum = typeof value === 'string' && value !== 'none' ? parseInt(value, 10) : (typeof value === 'number' ? value : null);
29079
+ if (screenNameIdNum && !isNaN(screenNameIdNum)) {
29080
+ // Store selected screen name on the variable object
29081
+ variable.screenNameId = screenNameIdNum;
29082
+ // Find and store screen name name from screenNameOptions
29083
+ const screenNameOption = this.screenNameOptions.find(sn => sn.id === screenNameIdNum);
29084
+ if (screenNameOption) {
29085
+ variable.selectedScreenName = screenNameOption.name;
29086
+ }
29087
+ else {
29088
+ // Fallback: if not found, still set the ID but clear the name
29089
+ variable.selectedScreenName = undefined;
29090
+ }
29091
+ // Clear the element selection when screen name changes
29092
+ variable.elementId = undefined;
29093
+ variable.elementLocator = undefined;
29094
+ variable.elementName = undefined;
29095
+ variable.value = '';
29096
+ // Clear element config cache to force refresh
29097
+ // Clear all element configs for this variable since screen name changed
29098
+ const keysToDelete = [];
29099
+ this.elementSelectConfigCache.forEach((_, key) => {
29100
+ if (key.startsWith(`${variable.name}_element`)) {
29101
+ keysToDelete.push(key);
29102
+ }
29103
+ });
29104
+ keysToDelete.forEach(key => this.elementSelectConfigCache.delete(key));
29105
+ // Update form control
29106
+ if (variableGroup) {
29107
+ if (variableGroup.get('value')) {
29108
+ (_d = variableGroup.get('value')) === null || _d === void 0 ? void 0 : _d.setValue('', { emitEvent: false });
29109
+ }
29110
+ // Ensure form control has the correct value (as string to match option id)
29111
+ if (variableGroup.get('selectedScreenName')) {
29112
+ (_e = variableGroup.get('selectedScreenName')) === null || _e === void 0 ? void 0 : _e.setValue(String(screenNameIdNum), { emitEvent: false });
29113
+ }
29114
+ }
29115
+ // Emit event to fetch elements filtered by selected screen name
28970
29116
  this.searchElementsByScreenName.emit({
28971
29117
  screenNameId: variable.screenNameId,
28972
29118
  searchTerm: ''
28973
29119
  });
28974
29120
  }
29121
+ else {
29122
+ // Invalid value - clear everything
29123
+ variable.screenNameId = undefined;
29124
+ variable.selectedScreenName = undefined;
29125
+ variable.value = '';
29126
+ }
28975
29127
  // Mark for check to update UI first
28976
29128
  this.cdr.markForCheck();
28977
29129
  // The element config will be recomputed automatically when elementOptions input changes
@@ -28993,7 +29145,6 @@ class TemplateVariablesFormComponent {
28993
29145
  */
28994
29146
  getElementSelectConfig(variable, index) {
28995
29147
  // Get selected screen name ID
28996
- console.log('variable', variable);
28997
29148
  const selectedScreenNameId = variable.screenNameId;
28998
29149
  // Include elementOptions length and loading state in cache key to invalidate when elements change
28999
29150
  const cacheKey = `${variable.name}_element_${selectedScreenNameId || ''}_${this.elementOptions.length}_${this.isLoadingElements}`;
@@ -29076,7 +29227,7 @@ class TemplateVariablesFormComponent {
29076
29227
  hasMore: this.hasMoreElements,
29077
29228
  isLoading: this.isLoadingElements,
29078
29229
  onChange: (value) => {
29079
- var _a, _b, _c;
29230
+ var _a, _b, _c, _d;
29080
29231
  // Find the selected element from elementOptions
29081
29232
  // value is the element ID (since config key is 'id')
29082
29233
  const selectedElement = this.elementOptions.find(el => el.id === value);
@@ -29086,6 +29237,16 @@ class TemplateVariablesFormComponent {
29086
29237
  variable.elementId = selectedElement.id;
29087
29238
  variable.elementLocator = selectedElement.locatorValue || '';
29088
29239
  variable.elementName = selectedElement.name || '';
29240
+ // Update screen name from the selected element
29241
+ // This ensures the screen name dropdown shows the correct selection
29242
+ if (selectedElement.screenNameId) {
29243
+ variable.screenNameId = selectedElement.screenNameId;
29244
+ // Find and store screen name name from screenNameOptions
29245
+ const screenNameOption = this.screenNameOptions.find(sn => sn.id === selectedElement.screenNameId);
29246
+ if (screenNameOption) {
29247
+ variable.selectedScreenName = screenNameOption.name;
29248
+ }
29249
+ }
29089
29250
  // Find and patch the selector variable with dataKey 'not_found'
29090
29251
  const selectorVariable = this.templateVariables.find(v => v.name === 'selector' && v.dataKey === 'not_found');
29091
29252
  if (selectorVariable && selectedElement.locatorValue) {
@@ -29105,8 +29266,6 @@ class TemplateVariablesFormComponent {
29105
29266
  // Fallback: if element not found, just set the value
29106
29267
  variable.value = value;
29107
29268
  }
29108
- // Screen name ID is already stored on variable.selectedScreenNameId
29109
- // (it was set when screen name was selected)
29110
29269
  // Update form control in FormArray
29111
29270
  const variableGroup = this.getVariableFormGroup(variable.name);
29112
29271
  if (variableGroup) {
@@ -29117,6 +29276,11 @@ class TemplateVariablesFormComponent {
29117
29276
  if (selectedElement && variableGroup.get('id')) {
29118
29277
  (_c = variableGroup.get('id')) === null || _c === void 0 ? void 0 : _c.setValue(selectedElement.id, { emitEvent: false });
29119
29278
  }
29279
+ // Update screen name form control if element has a screen name
29280
+ if (selectedElement && selectedElement.screenNameId && variableGroup.get('selectedScreenName')) {
29281
+ // Set the screen name ID as string to match option id format
29282
+ (_d = variableGroup.get('selectedScreenName')) === null || _d === void 0 ? void 0 : _d.setValue(String(selectedElement.screenNameId), { emitEvent: false });
29283
+ }
29120
29284
  }
29121
29285
  // Mark for check and emit
29122
29286
  this.cdr.markForCheck();
@@ -29142,10 +29306,10 @@ class TemplateVariablesFormComponent {
29142
29306
  }
29143
29307
  }
29144
29308
  TemplateVariablesFormComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TemplateVariablesFormComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
29145
- TemplateVariablesFormComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: TemplateVariablesFormComponent, selector: "cqa-template-variables-form", inputs: { templateVariables: "templateVariables", variablesForm: "variablesForm", metadata: "metadata", description: "description", elementOptions: "elementOptions", hasMoreElements: "hasMoreElements", isLoadingElements: "isLoadingElements", screenNameOptions: "screenNameOptions", hasMoreScreenNames: "hasMoreScreenNames", isLoadingScreenNames: "isLoadingScreenNames", parameterOptions: "parameterOptions", hasMoreParameters: "hasMoreParameters", isLoadingParameters: "isLoadingParameters", environmentOptions: "environmentOptions", hasMoreEnvironments: "hasMoreEnvironments", isLoadingEnvironments: "isLoadingEnvironments", defaultTestDataProfileId: "defaultTestDataProfileId", defaultTestDataStartIndex: "defaultTestDataStartIndex", isEditInDepth: "isEditInDepth", createElementVisible: "createElementVisible" }, outputs: { variableValueChange: "variableValueChange", variableBooleanChange: "variableBooleanChange", metadataChange: "metadataChange", descriptionChange: "descriptionChange", loadMoreElements: "loadMoreElements", searchElements: "searchElements", searchElementsByScreenName: "searchElementsByScreenName", createElement: "createElement", searchScreenName: "searchScreenName", loadMoreScreenNames: "loadMoreScreenNames", createScreenNameRequest: "createScreenNameRequest", searchParameters: "searchParameters", loadMoreParameters: "loadMoreParameters", searchEnvironments: "searchEnvironments", loadMoreEnvironments: "loadMoreEnvironments", cancelElementForm: "cancelElementForm", elementFormVisibilityChange: "elementFormVisibilityChange" }, host: { classAttribute: "cqa-ui-root" }, usesOnChanges: true, ngImport: i0, template: "<style>\n .capitalize-first::first-letter {\n text-transform: uppercase;\n }\n</style>\n<div class=\"cqa-flex cqa-gap-x-6 cqa-gap-y-4 cqa-flex-wrap template-variables-form\" [ngClass]=\"{'cqa-flex-col': isEditInDepth}\" *ngIf=\"!createElementVisible\">\n \n <!-- Metadata - Only show if element is available in form -->\n <div *ngIf=\"selectorVariableAvailable\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Metadata\n </label>\n <cqa-custom-input [placeholder]=\"'Text Input'\" [value]=\"metadata\" [fullWidth]=\"true\"\n (valueChange)=\"metadataChange.emit($event)\">\n </cqa-custom-input>\n </div>\n\n <!-- Description -->\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Description\n </label>\n <cqa-custom-input [placeholder]=\"'Text Input'\" [value]=\"description\" [fullWidth]=\"true\"\n (valueChange)=\"descriptionChange.emit($event)\">\n </cqa-custom-input>\n </div>\n \n <ng-container *ngFor=\"let variable of templateVariables; let i = index; trackBy: trackByVariable\">\n <!-- Boolean variables with mat-slide-toggle -->\n <ng-container *ngIf=\"variable.type === 'boolean'\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 capitalize-first\">\n {{ variable.label }}\n </label>\n <mat-slide-toggle [checked]=\"variablesForm.at(i)?.get('value')?.value || variable.value || false\"\n (change)=\"onVariableBooleanChange(variable.name, $event.checked)\" color=\"primary\">\n </mat-slide-toggle>\n </div>\n </ng-container>\n\n <!-- Non-boolean, non-custom_code variables -->\n <ng-container *ngIf=\"variable.name !== 'custom_code' && variable.type !== 'boolean'\">\n <!-- Element variables with cascading dropdowns (screen name + element) -->\n <ng-container *ngIf=\"isElementType(variable)\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label }} Screen Name\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getScreenNameSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n <div *ngIf=\"hasSelectedScreenName(variable)\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label }}\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getElementSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n </ng-container>\n <ng-container *ngIf=\"!isElementType(variable)\">\n <!-- Other dropdown variables (type, scrollTo, label) -->\n <ng-container *ngIf=\"shouldShowDropdown(variable); else defaultInput\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label }}\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n </ng-container>\n </ng-container>\n <ng-template #defaultInput>\n <!-- Test-data, source-value, or target-value with data type dropdown -->\n <ng-container *ngIf=\"needsDataTypeDropdown(variable); else regularInput\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label }} Type\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getDataTypeSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n <ng-container *ngIf=\"isEnvironmentType(variable)\">\n <div *ngIf=\"isEnvironmentType(variable)\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Environment Name\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getEnvironmentSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n <div *ngIf=\"hasSelectedEnvironment(variable)\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Environment Value\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getEnvironmentParameterSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n </ng-container>\n <ng-container *ngIf=\"isParameterType(variable)\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Test Data Profile\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getTestDataProfileSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n <div *ngIf=\"hasSelectedTestDataProfile(variable)\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Data Set\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getDataSetSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n <div *ngIf=\"hasSelectedDataSet(variable)\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label }}\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getParameterSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div> \n </ng-container>\n <div *ngIf=\"isPlainTextType(variable) || isRuntimeType(variable)\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label }} \n </label>\n <!-- Show custom input for plain-text type -->\n <cqa-custom-input [placeholder]=\"'Text Input'\" [value]=\"getRawValue(variable)\" [fullWidth]=\"true\"\n (valueChange)=\"onTestDataValueChange(variable.name, $event)\">\n </cqa-custom-input>\n </div>\n </ng-container>\n <ng-template #regularInput>\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label }}\n </label>\n <cqa-custom-input [placeholder]=\"'Text Input'\" [value]=\"variable.value\" [fullWidth]=\"true\"\n (valueChange)=\"onVariableValueChange(variable.name, $event)\">\n </cqa-custom-input>\n </div>\n </ng-template>\n </ng-template>\n </ng-container>\n </ng-container>\n</div>\n\n<div *ngIf=\"createElementVisible\">\n <cqa-element-form\n [isCreateMode]=\"true\"\n [screenNameOptions]=\"screenNameOptions\"\n [hasMoreScreenNames]=\"hasMoreScreenNames\"\n [isLoadingScreenNames]=\"isLoadingScreenNames\"\n [isEditInDepthAvailable]=\"false\"\n (createElement)=\"onCreateElement($event)\"\n (cancel)=\"onCancelElementForm()\"\n (searchScreenName)=\"searchScreenName.emit($event)\"\n (loadMoreScreenNames)=\"loadMoreScreenNames.emit($event)\"\n (createScreenNameRequest)=\"createScreenNameRequest.emit($event)\">\n </cqa-element-form>\n</div>", styles: ["\n .capitalize-first::first-letter {\n text-transform: uppercase;\n }\n"], components: [{ 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: i4$2.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["disabled", "disableRipple", "color", "tabIndex", "name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "checked"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { type: DynamicSelectFieldComponent, selector: "cqa-dynamic-select", inputs: ["form", "config"], outputs: ["selectionChange", "selectClick", "searchChange", "loadMore", "addCustomValue"] }, { type: ElementFormComponent, selector: "cqa-element-form", inputs: ["elementId", "element", "screenNameOptions", "hasMoreScreenNames", "isLoadingScreenNames", "isElementLoading", "isEditMode", "isCreateMode", "isEditInDepthAvailable"], outputs: ["createElement", "updateElement", "createScreenNameRequest", "searchScreenName", "loadMoreScreenNames", "cancel", "editInDepth"] }], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
29309
+ TemplateVariablesFormComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: TemplateVariablesFormComponent, selector: "cqa-template-variables-form", inputs: { templateVariables: "templateVariables", variablesForm: "variablesForm", metadata: "metadata", description: "description", elementOptions: "elementOptions", hasMoreElements: "hasMoreElements", isLoadingElements: "isLoadingElements", screenNameOptions: "screenNameOptions", hasMoreScreenNames: "hasMoreScreenNames", isLoadingScreenNames: "isLoadingScreenNames", parameterOptions: "parameterOptions", hasMoreParameters: "hasMoreParameters", isLoadingParameters: "isLoadingParameters", environmentOptions: "environmentOptions", hasMoreEnvironments: "hasMoreEnvironments", isLoadingEnvironments: "isLoadingEnvironments", defaultTestDataProfileId: "defaultTestDataProfileId", defaultTestDataStartIndex: "defaultTestDataStartIndex", isEditInDepth: "isEditInDepth", createElementVisible: "createElementVisible" }, outputs: { variableValueChange: "variableValueChange", variableBooleanChange: "variableBooleanChange", metadataChange: "metadataChange", descriptionChange: "descriptionChange", loadMoreElements: "loadMoreElements", searchElements: "searchElements", searchElementsByScreenName: "searchElementsByScreenName", createElement: "createElement", searchScreenName: "searchScreenName", loadMoreScreenNames: "loadMoreScreenNames", createScreenNameRequest: "createScreenNameRequest", searchParameters: "searchParameters", loadMoreParameters: "loadMoreParameters", searchEnvironments: "searchEnvironments", loadMoreEnvironments: "loadMoreEnvironments", cancelElementForm: "cancelElementForm", elementFormVisibilityChange: "elementFormVisibilityChange" }, host: { classAttribute: "cqa-ui-root" }, usesOnChanges: true, ngImport: i0, template: "<style>\n .capitalize-first::first-letter {\n text-transform: uppercase;\n }\n</style>\n<div class=\"cqa-flex cqa-gap-x-6 cqa-gap-y-4 cqa-flex-wrap template-variables-form\" [ngClass]=\"{'cqa-flex-col': isEditInDepth}\" *ngIf=\"!createElementVisible\">\n \n <!-- Metadata - Only show if element is available in form -->\n <div *ngIf=\"selectorVariableAvailable\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Metadata\n </label>\n <cqa-custom-input [placeholder]=\"'Text Input'\" [value]=\"metadata\" [fullWidth]=\"true\"\n (valueChange)=\"metadataChange.emit($event)\">\n </cqa-custom-input>\n </div>\n\n <!-- Description -->\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Description\n </label>\n <cqa-custom-input [placeholder]=\"'Text Input'\" [value]=\"description\" [fullWidth]=\"true\"\n (valueChange)=\"descriptionChange.emit($event)\">\n </cqa-custom-input>\n </div>\n \n <ng-container *ngFor=\"let variable of templateVariables; let i = index; trackBy: trackByVariable\">\n <!-- Boolean variables with mat-slide-toggle -->\n <ng-container *ngIf=\"variable.type === 'boolean'\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 capitalize-first\">\n {{ variable.label }}\n </label>\n <mat-slide-toggle [checked]=\"variablesForm.at(i)?.get('value')?.value || variable.value || false\"\n (change)=\"onVariableBooleanChange(variable.name, $event.checked)\" color=\"primary\">\n </mat-slide-toggle>\n </div>\n </ng-container>\n\n <!-- Non-boolean, non-custom_code variables -->\n <ng-container *ngIf=\"variable.name !== 'custom_code' && variable.type !== 'boolean'\">\n <!-- Element variables with cascading dropdowns (screen name + element) -->\n <ng-container *ngIf=\"isElementType(variable)\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label }} Screen Name\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getScreenNameSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n <div *ngIf=\"hasSelectedScreenName(variable); else elementManualInput\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label }}\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getElementSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n <ng-template #elementManualInput>\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label }}\n </label>\n <cqa-custom-input [placeholder]=\"'Text Input'\" [value]=\"variable.value\" [fullWidth]=\"true\"\n (valueChange)=\"onVariableValueChange(variable.name, $event)\">\n </cqa-custom-input>\n </div>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"!isElementType(variable)\">\n <!-- Other dropdown variables (type, scrollTo, label) -->\n <ng-container *ngIf=\"shouldShowDropdown(variable); else defaultInput\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label }}\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n </ng-container>\n </ng-container>\n <ng-template #defaultInput>\n <!-- Test-data, source-value, or target-value with data type dropdown -->\n <ng-container *ngIf=\"needsDataTypeDropdown(variable); else regularInput\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label }} Type\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getDataTypeSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n <ng-container *ngIf=\"isEnvironmentType(variable)\">\n <div *ngIf=\"isEnvironmentType(variable)\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Environment Name\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getEnvironmentSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n <div *ngIf=\"hasSelectedEnvironment(variable)\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Environment Value\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getEnvironmentParameterSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n </ng-container>\n <ng-container *ngIf=\"isParameterType(variable)\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Test Data Profile\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getTestDataProfileSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n <div *ngIf=\"hasSelectedTestDataProfile(variable)\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Data Set\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getDataSetSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n <div *ngIf=\"hasSelectedDataSet(variable)\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label }}\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getParameterSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div> \n </ng-container>\n <div *ngIf=\"isPlainTextType(variable) || isRuntimeType(variable)\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label }} \n </label>\n <!-- Show custom input for plain-text type -->\n <cqa-custom-input [placeholder]=\"'Text Input'\" [value]=\"getRawValue(variable)\" [fullWidth]=\"true\"\n (valueChange)=\"onTestDataValueChange(variable.name, $event)\">\n </cqa-custom-input>\n </div>\n </ng-container>\n <ng-template #regularInput>\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label }}\n </label>\n <cqa-custom-input [placeholder]=\"'Text Input'\" [value]=\"variable.value\" [fullWidth]=\"true\"\n (valueChange)=\"onVariableValueChange(variable.name, $event)\">\n </cqa-custom-input>\n </div>\n </ng-template>\n </ng-template>\n </ng-container>\n </ng-container>\n</div>\n\n<div *ngIf=\"createElementVisible\">\n <cqa-element-form\n [isCreateMode]=\"true\"\n [screenNameOptions]=\"screenNameOptions\"\n [hasMoreScreenNames]=\"hasMoreScreenNames\"\n [isLoadingScreenNames]=\"isLoadingScreenNames\"\n [isEditInDepthAvailable]=\"false\"\n (createElement)=\"onCreateElement($event)\"\n (cancel)=\"onCancelElementForm()\"\n (searchScreenName)=\"searchScreenName.emit($event)\"\n (loadMoreScreenNames)=\"loadMoreScreenNames.emit($event)\"\n (createScreenNameRequest)=\"createScreenNameRequest.emit($event)\">\n </cqa-element-form>\n</div>", styles: ["\n .capitalize-first::first-letter {\n text-transform: uppercase;\n }\n"], components: [{ 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: i4$2.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["disabled", "disableRipple", "color", "tabIndex", "name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "checked"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { type: DynamicSelectFieldComponent, selector: "cqa-dynamic-select", inputs: ["form", "config"], outputs: ["selectionChange", "selectClick", "searchChange", "loadMore", "addCustomValue"] }, { type: ElementFormComponent, selector: "cqa-element-form", inputs: ["elementId", "element", "screenNameOptions", "hasMoreScreenNames", "isLoadingScreenNames", "isElementLoading", "isEditMode", "isCreateMode", "isEditInDepthAvailable"], outputs: ["createElement", "updateElement", "createScreenNameRequest", "searchScreenName", "loadMoreScreenNames", "cancel", "editInDepth"] }], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
29146
29310
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TemplateVariablesFormComponent, decorators: [{
29147
29311
  type: Component,
29148
- args: [{ selector: 'cqa-template-variables-form', host: { class: 'cqa-ui-root' }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<style>\n .capitalize-first::first-letter {\n text-transform: uppercase;\n }\n</style>\n<div class=\"cqa-flex cqa-gap-x-6 cqa-gap-y-4 cqa-flex-wrap template-variables-form\" [ngClass]=\"{'cqa-flex-col': isEditInDepth}\" *ngIf=\"!createElementVisible\">\n \n <!-- Metadata - Only show if element is available in form -->\n <div *ngIf=\"selectorVariableAvailable\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Metadata\n </label>\n <cqa-custom-input [placeholder]=\"'Text Input'\" [value]=\"metadata\" [fullWidth]=\"true\"\n (valueChange)=\"metadataChange.emit($event)\">\n </cqa-custom-input>\n </div>\n\n <!-- Description -->\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Description\n </label>\n <cqa-custom-input [placeholder]=\"'Text Input'\" [value]=\"description\" [fullWidth]=\"true\"\n (valueChange)=\"descriptionChange.emit($event)\">\n </cqa-custom-input>\n </div>\n \n <ng-container *ngFor=\"let variable of templateVariables; let i = index; trackBy: trackByVariable\">\n <!-- Boolean variables with mat-slide-toggle -->\n <ng-container *ngIf=\"variable.type === 'boolean'\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 capitalize-first\">\n {{ variable.label }}\n </label>\n <mat-slide-toggle [checked]=\"variablesForm.at(i)?.get('value')?.value || variable.value || false\"\n (change)=\"onVariableBooleanChange(variable.name, $event.checked)\" color=\"primary\">\n </mat-slide-toggle>\n </div>\n </ng-container>\n\n <!-- Non-boolean, non-custom_code variables -->\n <ng-container *ngIf=\"variable.name !== 'custom_code' && variable.type !== 'boolean'\">\n <!-- Element variables with cascading dropdowns (screen name + element) -->\n <ng-container *ngIf=\"isElementType(variable)\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label }} Screen Name\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getScreenNameSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n <div *ngIf=\"hasSelectedScreenName(variable)\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label }}\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getElementSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n </ng-container>\n <ng-container *ngIf=\"!isElementType(variable)\">\n <!-- Other dropdown variables (type, scrollTo, label) -->\n <ng-container *ngIf=\"shouldShowDropdown(variable); else defaultInput\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label }}\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n </ng-container>\n </ng-container>\n <ng-template #defaultInput>\n <!-- Test-data, source-value, or target-value with data type dropdown -->\n <ng-container *ngIf=\"needsDataTypeDropdown(variable); else regularInput\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label }} Type\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getDataTypeSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n <ng-container *ngIf=\"isEnvironmentType(variable)\">\n <div *ngIf=\"isEnvironmentType(variable)\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Environment Name\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getEnvironmentSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n <div *ngIf=\"hasSelectedEnvironment(variable)\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Environment Value\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getEnvironmentParameterSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n </ng-container>\n <ng-container *ngIf=\"isParameterType(variable)\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Test Data Profile\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getTestDataProfileSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n <div *ngIf=\"hasSelectedTestDataProfile(variable)\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Data Set\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getDataSetSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n <div *ngIf=\"hasSelectedDataSet(variable)\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label }}\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getParameterSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div> \n </ng-container>\n <div *ngIf=\"isPlainTextType(variable) || isRuntimeType(variable)\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label }} \n </label>\n <!-- Show custom input for plain-text type -->\n <cqa-custom-input [placeholder]=\"'Text Input'\" [value]=\"getRawValue(variable)\" [fullWidth]=\"true\"\n (valueChange)=\"onTestDataValueChange(variable.name, $event)\">\n </cqa-custom-input>\n </div>\n </ng-container>\n <ng-template #regularInput>\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label }}\n </label>\n <cqa-custom-input [placeholder]=\"'Text Input'\" [value]=\"variable.value\" [fullWidth]=\"true\"\n (valueChange)=\"onVariableValueChange(variable.name, $event)\">\n </cqa-custom-input>\n </div>\n </ng-template>\n </ng-template>\n </ng-container>\n </ng-container>\n</div>\n\n<div *ngIf=\"createElementVisible\">\n <cqa-element-form\n [isCreateMode]=\"true\"\n [screenNameOptions]=\"screenNameOptions\"\n [hasMoreScreenNames]=\"hasMoreScreenNames\"\n [isLoadingScreenNames]=\"isLoadingScreenNames\"\n [isEditInDepthAvailable]=\"false\"\n (createElement)=\"onCreateElement($event)\"\n (cancel)=\"onCancelElementForm()\"\n (searchScreenName)=\"searchScreenName.emit($event)\"\n (loadMoreScreenNames)=\"loadMoreScreenNames.emit($event)\"\n (createScreenNameRequest)=\"createScreenNameRequest.emit($event)\">\n </cqa-element-form>\n</div>", styles: ["\n .capitalize-first::first-letter {\n text-transform: uppercase;\n }\n"] }]
29312
+ args: [{ selector: 'cqa-template-variables-form', host: { class: 'cqa-ui-root' }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<style>\n .capitalize-first::first-letter {\n text-transform: uppercase;\n }\n</style>\n<div class=\"cqa-flex cqa-gap-x-6 cqa-gap-y-4 cqa-flex-wrap template-variables-form\" [ngClass]=\"{'cqa-flex-col': isEditInDepth}\" *ngIf=\"!createElementVisible\">\n \n <!-- Metadata - Only show if element is available in form -->\n <div *ngIf=\"selectorVariableAvailable\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Metadata\n </label>\n <cqa-custom-input [placeholder]=\"'Text Input'\" [value]=\"metadata\" [fullWidth]=\"true\"\n (valueChange)=\"metadataChange.emit($event)\">\n </cqa-custom-input>\n </div>\n\n <!-- Description -->\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Description\n </label>\n <cqa-custom-input [placeholder]=\"'Text Input'\" [value]=\"description\" [fullWidth]=\"true\"\n (valueChange)=\"descriptionChange.emit($event)\">\n </cqa-custom-input>\n </div>\n \n <ng-container *ngFor=\"let variable of templateVariables; let i = index; trackBy: trackByVariable\">\n <!-- Boolean variables with mat-slide-toggle -->\n <ng-container *ngIf=\"variable.type === 'boolean'\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 capitalize-first\">\n {{ variable.label }}\n </label>\n <mat-slide-toggle [checked]=\"variablesForm.at(i)?.get('value')?.value || variable.value || false\"\n (change)=\"onVariableBooleanChange(variable.name, $event.checked)\" color=\"primary\">\n </mat-slide-toggle>\n </div>\n </ng-container>\n\n <!-- Non-boolean, non-custom_code variables -->\n <ng-container *ngIf=\"variable.name !== 'custom_code' && variable.type !== 'boolean'\">\n <!-- Element variables with cascading dropdowns (screen name + element) -->\n <ng-container *ngIf=\"isElementType(variable)\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label }} Screen Name\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getScreenNameSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n <div *ngIf=\"hasSelectedScreenName(variable); else elementManualInput\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label }}\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getElementSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n <ng-template #elementManualInput>\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label }}\n </label>\n <cqa-custom-input [placeholder]=\"'Text Input'\" [value]=\"variable.value\" [fullWidth]=\"true\"\n (valueChange)=\"onVariableValueChange(variable.name, $event)\">\n </cqa-custom-input>\n </div>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"!isElementType(variable)\">\n <!-- Other dropdown variables (type, scrollTo, label) -->\n <ng-container *ngIf=\"shouldShowDropdown(variable); else defaultInput\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label }}\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n </ng-container>\n </ng-container>\n <ng-template #defaultInput>\n <!-- Test-data, source-value, or target-value with data type dropdown -->\n <ng-container *ngIf=\"needsDataTypeDropdown(variable); else regularInput\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label }} Type\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getDataTypeSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n <ng-container *ngIf=\"isEnvironmentType(variable)\">\n <div *ngIf=\"isEnvironmentType(variable)\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Environment Name\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getEnvironmentSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n <div *ngIf=\"hasSelectedEnvironment(variable)\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Environment Value\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getEnvironmentParameterSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n </ng-container>\n <ng-container *ngIf=\"isParameterType(variable)\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Test Data Profile\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getTestDataProfileSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n <div *ngIf=\"hasSelectedTestDataProfile(variable)\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Data Set\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getDataSetSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n <div *ngIf=\"hasSelectedDataSet(variable)\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label }}\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getParameterSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div> \n </ng-container>\n <div *ngIf=\"isPlainTextType(variable) || isRuntimeType(variable)\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label }} \n </label>\n <!-- Show custom input for plain-text type -->\n <cqa-custom-input [placeholder]=\"'Text Input'\" [value]=\"getRawValue(variable)\" [fullWidth]=\"true\"\n (valueChange)=\"onTestDataValueChange(variable.name, $event)\">\n </cqa-custom-input>\n </div>\n </ng-container>\n <ng-template #regularInput>\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label }}\n </label>\n <cqa-custom-input [placeholder]=\"'Text Input'\" [value]=\"variable.value\" [fullWidth]=\"true\"\n (valueChange)=\"onVariableValueChange(variable.name, $event)\">\n </cqa-custom-input>\n </div>\n </ng-template>\n </ng-template>\n </ng-container>\n </ng-container>\n</div>\n\n<div *ngIf=\"createElementVisible\">\n <cqa-element-form\n [isCreateMode]=\"true\"\n [screenNameOptions]=\"screenNameOptions\"\n [hasMoreScreenNames]=\"hasMoreScreenNames\"\n [isLoadingScreenNames]=\"isLoadingScreenNames\"\n [isEditInDepthAvailable]=\"false\"\n (createElement)=\"onCreateElement($event)\"\n (cancel)=\"onCancelElementForm()\"\n (searchScreenName)=\"searchScreenName.emit($event)\"\n (loadMoreScreenNames)=\"loadMoreScreenNames.emit($event)\"\n (createScreenNameRequest)=\"createScreenNameRequest.emit($event)\">\n </cqa-element-form>\n</div>", styles: ["\n .capitalize-first::first-letter {\n text-transform: uppercase;\n }\n"] }]
29149
29313
  }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { templateVariables: [{
29150
29314
  type: Input
29151
29315
  }], variablesForm: [{
@@ -33524,91 +33688,365 @@ const DETAIL_SIDE_PANEL_SCROLL_STYLES = `
33524
33688
  }
33525
33689
  `;
33526
33690
 
33527
- /** Keys for each dynamic select in test-case-details-edit. Use these with selectConfigOverrides. */
33528
- const TEST_CASE_DETAILS_SELECT_KEYS = {
33529
- status: 'status',
33530
- priority: 'priority',
33531
- type: 'type',
33532
- labels: 'labels',
33533
- prerequisiteCases: 'prerequisiteCases',
33534
- testDataProfile: 'testDataProfile',
33535
- testDataSet: 'testDataSet',
33536
- videoRecording: 'videoRecording',
33537
- enableAiSmartness: 'enableAiSmartness',
33538
- defaultAiAction: 'defaultAiAction',
33539
- knowledgeBaseDefaultTestCase: 'knowledgeBaseDefaultTestCase',
33540
- useAiMetadata: 'useAiMetadata',
33541
- defaultBrowser: 'defaultBrowser',
33542
- defaultViewport: 'defaultViewport',
33543
- deviceType: 'deviceType',
33544
- deviceOS: 'deviceOS',
33545
- };
33546
- const FREQUENTLY_USED_LABELS = [
33547
- 'Case',
33548
- 'Critical',
33549
- 'PO',
33550
- 'Upload',
33551
- 'Validation',
33552
- 'Review',
33553
- 'Edge-cases',
33554
- 'Security',
33555
- 'Integration',
33556
- 'Smoke',
33557
- ];
33558
- class TestCaseDetailsEditComponent {
33559
- constructor(cdr) {
33560
- this.cdr = cdr;
33561
- this.descriptionTitle = 'Description';
33562
- this.descriptionContent = '';
33563
- /** When true, description uses Trix rich text editor (Bold, Italic, etc.). Host app must load Trix. */
33564
- this.enableMarkdown = false;
33565
- this.metadataItems = [];
33566
- this.labels = [];
33567
- this.configTitle = 'Configuration';
33568
- this.configSections = [];
33569
- this.configSectionsRow2 = [];
33570
- /** Optional list of prerequisite test case options for the multi-select. If not provided, uses default sample options. */
33571
- this.prerequisiteCaseOptions = [];
33572
- /** Platform: 'web' shows Default Browser + Viewport; 'mobile' shows Device Type + OS. Defaults to 'web'. */
33573
- this.platform = 'web';
33574
- /** When true, hides Priority, Type, and Test Data Set fields (step groups don't have these). Defaults to false. */
33575
- this.isStepGroup = false;
33576
- /**
33577
- * Override config per select key. Use for:
33578
- * - API-driven options: pass options array (update when API returns)
33579
- * - Server-side search: serverSearch: true, onSearch in override or listen to selectSearch
33580
- * - Infinite scroll: hasMore: true, onLoadMore in override or listen to selectLoadMore
33581
- * - Initial fetch on open: initialFetchOnOpen: true
33582
- */
33583
- this.selectConfigOverrides = {};
33584
- this.save = new EventEmitter();
33585
- this.cancel = new EventEmitter();
33586
- /** Emitted when user searches in a select (serverSearch mode). Call API and update options via selectConfigOverrides. */
33587
- this.selectSearch = new EventEmitter();
33588
- /** Emitted when user scrolls to load more. Call API, append to options via selectConfigOverrides. */
33589
- this.selectLoadMore = new EventEmitter();
33590
- /** Emitted when a select panel is opened. Use to call API for initial load (e.g. when initialFetchOnOpen). */
33591
- this.selectOpened = new EventEmitter();
33592
- /** Emitted when selection changes in any select. */
33593
- this.selectionChange = new EventEmitter();
33594
- /** Emitted when user adds a new custom label via the "New" option. */
33595
- this.labelAdded = new EventEmitter();
33596
- /** Form state */
33597
- this.editDescription = '';
33598
- this.editStatus = '';
33599
- this.editPriority = '';
33600
- this.editLabels = [];
33601
- this.testCaseTimeout = '';
33602
- this.waitTimeoutLocators = '';
33603
- this.autoWaitEnabled = false;
33604
- this.retryFailedSteps = '';
33605
- this.configExpanded = true;
33606
- this.executionExpanded = true;
33607
- this.aiConfigExpanded = true;
33608
- this.waitsRetriesExpanded = true;
33609
- this.deviceExpanded = true;
33610
- this.keyFlagsExpanded = true;
33611
- this.mobileTestingEnabled = false;
33691
+ class DetailSidePanelComponent {
33692
+ constructor() {
33693
+ /** Tabs - each tab has a side panel icon button; tabs and buttons are 1:1. Host defines tabs and content. */
33694
+ this.tabs = [
33695
+ { label: 'Test Case', value: 'test-case', icon: 'description' },
33696
+ { label: 'Data Library', value: 'data-library', icon: 'folder' },
33697
+ { label: 'Variables', value: 'variables', icon: 'code' },
33698
+ ];
33699
+ /** Currently active tab value */
33700
+ this.activeTab = 'test-case';
33701
+ /** Whether to show the close button in the side menu */
33702
+ this.showCloseButton = false;
33703
+ /** Whether the panel is expanded (affects expand button icon and panel width) */
33704
+ this.expanded = true;
33705
+ /** Panel width when expanded (e.g. '480px', '25%') */
33706
+ this.expandedWidth = '380px';
33707
+ /** Panel width when collapsed (e.g. '56px' - fits icon bar + back button) */
33708
+ this.collapsedWidth = '56px';
33709
+ this.hostOverflow = 'hidden';
33710
+ /** Tooltip for expand button when panel is collapsed */
33711
+ this.expandTooltip = 'Expand';
33712
+ /** Tooltip for expand button when panel is expanded (collapse) */
33713
+ this.collapseTooltip = 'Collapse';
33714
+ /** Tooltip for close button */
33715
+ this.closeTooltip = 'Close';
33716
+ this.back = new EventEmitter();
33717
+ this.tabChange = new EventEmitter();
33718
+ this.expandToggle = new EventEmitter();
33719
+ this.close = new EventEmitter();
33720
+ }
33721
+ get hostWidth() {
33722
+ return this.expanded ? this.expandedWidth : this.collapsedWidth;
33723
+ }
33724
+ get hostMinWidth() {
33725
+ return this.expanded ? this.expandedWidth : this.collapsedWidth;
33726
+ }
33727
+ get hostMaxWidth() {
33728
+ return this.expanded ? this.expandedWidth : this.collapsedWidth;
33729
+ }
33730
+ trackByTabValue(_i, tab) {
33731
+ return tab.value;
33732
+ }
33733
+ onBack() {
33734
+ this.back.emit();
33735
+ }
33736
+ onTabClick(tab) {
33737
+ if (!this.expanded) {
33738
+ this.expandToggle.emit();
33739
+ }
33740
+ if (tab.value !== this.activeTab) {
33741
+ this.tabChange.emit(tab.value);
33742
+ }
33743
+ }
33744
+ onExpandToggle() {
33745
+ this.expandToggle.emit();
33746
+ }
33747
+ onClose() {
33748
+ this.close.emit();
33749
+ }
33750
+ }
33751
+ DetailSidePanelComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DetailSidePanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
33752
+ DetailSidePanelComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: DetailSidePanelComponent, selector: "cqa-detail-side-panel", inputs: { tabs: "tabs", activeTab: "activeTab", showCloseButton: "showCloseButton", expanded: "expanded", expandedWidth: "expandedWidth", collapsedWidth: "collapsedWidth", expandTooltip: "expandTooltip", collapseTooltip: "collapseTooltip", closeTooltip: "closeTooltip" }, outputs: { back: "back", tabChange: "tabChange", expandToggle: "expandToggle", close: "close" }, host: { properties: { "style.width": "this.hostWidth", "style.min-width": "this.hostMinWidth", "style.max-width": "this.hostMaxWidth", "style.overflow": "this.hostOverflow" }, styleAttribute: "transition: width 0.3s ease-in-out", classAttribute: "cqa-ui-root cqa-flex cqa-flex-col cqa-h-full cqa-flex-shrink-0 cqa-flex-grow-0 cqa-bg-white cqa-shadow-[-4px_0_6px_-1px_rgba(0,0,0,0.05)]" }, ngImport: i0, template: "<div class=\"cqa-flex cqa-flex-col cqa-h-full cqa-min-w-0 cqa-bg-white\">\n <!-- Main content: Side menu + Scrollable content -->\n <div\n class=\"cqa-grid cqa-flex-1 cqa-min-h-0 cqa-min-w-0 cqa-overflow-hidden\"\n [style.grid-template-columns]=\"expanded ? 'auto 1fr' : 'auto 0fr'\"\n style=\"transition: grid-template-columns 0.3s ease-in-out\">\n <!-- Left vertical icon menu -->\n <div\n class=\"cqa-flex cqa-flex-col cqa-items-center cqa-gap-2 cqa-py-4 cqa-px-2 cqa-border-r cqa-border-[#F5F5F5] cqa-flex-shrink-0 cqa-text-[#0A0A0A]\"\n style=\"box-shadow: 1px 4px 12px 1px rgba(0, 0, 0, 0.05);\">\n <!-- Expand / Collapse button (always visible) -->\n <button\n type=\"button\"\n [matTooltip]=\"expanded ? collapseTooltip : expandTooltip\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-9 cqa-h-9 cqa-rounded-lg cqa-text-[#64748B] hover:cqa-bg-[#E2E8F0] hover:cqa-text-[#334155] cqa-transition-colors focus:cqa-outline-none focus-visible:cqa-ring-2 focus-visible:cqa-ring-[#3F43EE] focus-visible:cqa-ring-offset-2\"\n (click)=\"onExpandToggle()\">\n <mat-icon class=\"cqa-text-[20px] cqa-w-5 cqa-h-5\">{{ expanded ? 'chevron_left' : 'chevron_right' }}</mat-icon>\n </button>\n <!-- Close button -->\n <button\n *ngIf=\"showCloseButton\"\n type=\"button\"\n [matTooltip]=\"closeTooltip\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-9 cqa-h-9 cqa-rounded-lg cqa-text-[#64748B] hover:cqa-bg-[#E2E8F0] hover:cqa-text-[#334155] cqa-transition-colors focus:cqa-outline-none focus-visible:cqa-ring-2 focus-visible:cqa-ring-[#3F43EE] focus-visible:cqa-ring-offset-2\"\n (click)=\"onClose()\">\n <mat-icon class=\"cqa-text-[20px] cqa-w-5 cqa-h-5\">close</mat-icon>\n </button>\n <!-- Tab buttons (1:1 with tabs) -->\n <button\n *ngFor=\"let tab of tabs; trackBy: trackByTabValue\"\n type=\"button\"\n [matTooltip]=\"tab.label\"\n [class.cqa-bg-[#3F43EE]]=\"activeTab === tab.value\"\n [class.cqa-text-white]=\"activeTab === tab.value\"\n [class.cqa-text-[#64748B]]=\"activeTab !== tab.value\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-9 cqa-h-9 cqa-rounded-lg hover:cqa-bg-[#E2E8F0] hover:cqa-text-[#334155] cqa-transition-colors focus:cqa-outline-none focus-visible:cqa-ring-2 focus-visible:cqa-ring-[#3F43EE] focus-visible:cqa-ring-offset-2\"\n (click)=\"onTabClick(tab)\">\n <mat-icon class=\"cqa-text-[20px] cqa-w-5 cqa-h-5\">{{ tab.icon || 'circle' }}</mat-icon>\n </button>\n </div>\n\n <!-- Scrollable content area (collapses with animation when expanded is false) -->\n <div class=\"cqa-flex cqa-flex-col cqa-min-h-0 cqa-min-w-0 cqa-overflow-hidden cqa-w-full cqa-h-full\">\n <div class=\"detail-side-panel-scroll cqa-flex-1 cqa-min-h-0 cqa-min-w-0 cqa-overflow-y-auto cqa-overflow-x-hidden cqa-p-4 cqa-space-y-4\" style=\"overflow-y: auto; overflow-x: hidden; min-height: 0; -webkit-overflow-scrolling: touch;\">\n <!-- Tabs: equally distributed (Figma: purple active, gray inactive) -->\n <div class=\"cqa-flex cqa-gap-[3.5px] cqa-p-[3.5px] cqa-bg-[#F1F5F9] cqa-rounded-lg cqa-w-full\" role=\"tablist\">\n <button\n *ngFor=\"let tab of tabs; trackBy: trackByTabValue\"\n type=\"button\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === tab.value\"\n [class.cqa-bg-[#3F43EE]]=\"activeTab === tab.value\"\n [class.cqa-text-white]=\"activeTab === tab.value\"\n [class.cqa-text-[#64748B]]=\"activeTab !== tab.value\"\n class=\"cqa-flex-1 cqa-flex cqa-justify-center cqa-items-center cqa-py-2 cqa-rounded-lg cqa-text-xs cqa-font-medium cqa-transition-colors hover:cqa-opacity-90 focus:cqa-outline-none focus-visible:cqa-ring-2 focus-visible:cqa-ring-[#3F43EE] focus-visible:cqa-ring-offset-2\"\n (click)=\"onTabClick(tab)\">\n {{ tab.label }}\n </button>\n </div>\n\n <!-- Tab content: fully provided by host via content projection. Host uses *ngIf per tab so only active content is projected. Add/remove tabs in the host without changing cqa-ui-lib. -->\n <ng-content></ng-content>\n </div>\n </div>\n </div>\n</div>\n", styles: [".detail-side-panel-scroll{overflow-y:auto!important;overflow-x:hidden!important;min-height:0!important;-webkit-overflow-scrolling:touch}\n"], components: [{ type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], directives: [{ type: i5.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
33753
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DetailSidePanelComponent, decorators: [{
33754
+ type: Component,
33755
+ args: [{ selector: 'cqa-detail-side-panel', styles: [DETAIL_SIDE_PANEL_SCROLL_STYLES], changeDetection: ChangeDetectionStrategy.OnPush, host: {
33756
+ class: 'cqa-ui-root cqa-flex cqa-flex-col cqa-h-full cqa-flex-shrink-0 cqa-flex-grow-0 cqa-bg-white cqa-shadow-[-4px_0_6px_-1px_rgba(0,0,0,0.05)]',
33757
+ style: 'transition: width 0.3s ease-in-out',
33758
+ }, template: "<div class=\"cqa-flex cqa-flex-col cqa-h-full cqa-min-w-0 cqa-bg-white\">\n <!-- Main content: Side menu + Scrollable content -->\n <div\n class=\"cqa-grid cqa-flex-1 cqa-min-h-0 cqa-min-w-0 cqa-overflow-hidden\"\n [style.grid-template-columns]=\"expanded ? 'auto 1fr' : 'auto 0fr'\"\n style=\"transition: grid-template-columns 0.3s ease-in-out\">\n <!-- Left vertical icon menu -->\n <div\n class=\"cqa-flex cqa-flex-col cqa-items-center cqa-gap-2 cqa-py-4 cqa-px-2 cqa-border-r cqa-border-[#F5F5F5] cqa-flex-shrink-0 cqa-text-[#0A0A0A]\"\n style=\"box-shadow: 1px 4px 12px 1px rgba(0, 0, 0, 0.05);\">\n <!-- Expand / Collapse button (always visible) -->\n <button\n type=\"button\"\n [matTooltip]=\"expanded ? collapseTooltip : expandTooltip\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-9 cqa-h-9 cqa-rounded-lg cqa-text-[#64748B] hover:cqa-bg-[#E2E8F0] hover:cqa-text-[#334155] cqa-transition-colors focus:cqa-outline-none focus-visible:cqa-ring-2 focus-visible:cqa-ring-[#3F43EE] focus-visible:cqa-ring-offset-2\"\n (click)=\"onExpandToggle()\">\n <mat-icon class=\"cqa-text-[20px] cqa-w-5 cqa-h-5\">{{ expanded ? 'chevron_left' : 'chevron_right' }}</mat-icon>\n </button>\n <!-- Close button -->\n <button\n *ngIf=\"showCloseButton\"\n type=\"button\"\n [matTooltip]=\"closeTooltip\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-9 cqa-h-9 cqa-rounded-lg cqa-text-[#64748B] hover:cqa-bg-[#E2E8F0] hover:cqa-text-[#334155] cqa-transition-colors focus:cqa-outline-none focus-visible:cqa-ring-2 focus-visible:cqa-ring-[#3F43EE] focus-visible:cqa-ring-offset-2\"\n (click)=\"onClose()\">\n <mat-icon class=\"cqa-text-[20px] cqa-w-5 cqa-h-5\">close</mat-icon>\n </button>\n <!-- Tab buttons (1:1 with tabs) -->\n <button\n *ngFor=\"let tab of tabs; trackBy: trackByTabValue\"\n type=\"button\"\n [matTooltip]=\"tab.label\"\n [class.cqa-bg-[#3F43EE]]=\"activeTab === tab.value\"\n [class.cqa-text-white]=\"activeTab === tab.value\"\n [class.cqa-text-[#64748B]]=\"activeTab !== tab.value\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-9 cqa-h-9 cqa-rounded-lg hover:cqa-bg-[#E2E8F0] hover:cqa-text-[#334155] cqa-transition-colors focus:cqa-outline-none focus-visible:cqa-ring-2 focus-visible:cqa-ring-[#3F43EE] focus-visible:cqa-ring-offset-2\"\n (click)=\"onTabClick(tab)\">\n <mat-icon class=\"cqa-text-[20px] cqa-w-5 cqa-h-5\">{{ tab.icon || 'circle' }}</mat-icon>\n </button>\n </div>\n\n <!-- Scrollable content area (collapses with animation when expanded is false) -->\n <div class=\"cqa-flex cqa-flex-col cqa-min-h-0 cqa-min-w-0 cqa-overflow-hidden cqa-w-full cqa-h-full\">\n <div class=\"detail-side-panel-scroll cqa-flex-1 cqa-min-h-0 cqa-min-w-0 cqa-overflow-y-auto cqa-overflow-x-hidden cqa-p-4 cqa-space-y-4\" style=\"overflow-y: auto; overflow-x: hidden; min-height: 0; -webkit-overflow-scrolling: touch;\">\n <!-- Tabs: equally distributed (Figma: purple active, gray inactive) -->\n <div class=\"cqa-flex cqa-gap-[3.5px] cqa-p-[3.5px] cqa-bg-[#F1F5F9] cqa-rounded-lg cqa-w-full\" role=\"tablist\">\n <button\n *ngFor=\"let tab of tabs; trackBy: trackByTabValue\"\n type=\"button\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === tab.value\"\n [class.cqa-bg-[#3F43EE]]=\"activeTab === tab.value\"\n [class.cqa-text-white]=\"activeTab === tab.value\"\n [class.cqa-text-[#64748B]]=\"activeTab !== tab.value\"\n class=\"cqa-flex-1 cqa-flex cqa-justify-center cqa-items-center cqa-py-2 cqa-rounded-lg cqa-text-xs cqa-font-medium cqa-transition-colors hover:cqa-opacity-90 focus:cqa-outline-none focus-visible:cqa-ring-2 focus-visible:cqa-ring-[#3F43EE] focus-visible:cqa-ring-offset-2\"\n (click)=\"onTabClick(tab)\">\n {{ tab.label }}\n </button>\n </div>\n\n <!-- Tab content: fully provided by host via content projection. Host uses *ngIf per tab so only active content is projected. Add/remove tabs in the host without changing cqa-ui-lib. -->\n <ng-content></ng-content>\n </div>\n </div>\n </div>\n</div>\n" }]
33759
+ }], propDecorators: { tabs: [{
33760
+ type: Input
33761
+ }], activeTab: [{
33762
+ type: Input
33763
+ }], showCloseButton: [{
33764
+ type: Input
33765
+ }], expanded: [{
33766
+ type: Input
33767
+ }], expandedWidth: [{
33768
+ type: Input
33769
+ }], collapsedWidth: [{
33770
+ type: Input
33771
+ }], hostWidth: [{
33772
+ type: HostBinding,
33773
+ args: ['style.width']
33774
+ }], hostMinWidth: [{
33775
+ type: HostBinding,
33776
+ args: ['style.min-width']
33777
+ }], hostMaxWidth: [{
33778
+ type: HostBinding,
33779
+ args: ['style.max-width']
33780
+ }], hostOverflow: [{
33781
+ type: HostBinding,
33782
+ args: ['style.overflow']
33783
+ }], expandTooltip: [{
33784
+ type: Input
33785
+ }], collapseTooltip: [{
33786
+ type: Input
33787
+ }], closeTooltip: [{
33788
+ type: Input
33789
+ }], back: [{
33790
+ type: Output
33791
+ }], tabChange: [{
33792
+ type: Output
33793
+ }], expandToggle: [{
33794
+ type: Output
33795
+ }], close: [{
33796
+ type: Output
33797
+ }] } });
33798
+
33799
+ class DetailDrawerTabContentDirective {
33800
+ constructor(templateRef) {
33801
+ this.templateRef = templateRef;
33802
+ }
33803
+ }
33804
+ DetailDrawerTabContentDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DetailDrawerTabContentDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
33805
+ DetailDrawerTabContentDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.4.0", type: DetailDrawerTabContentDirective, selector: "[cqaTabContent]", ngImport: i0 });
33806
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DetailDrawerTabContentDirective, decorators: [{
33807
+ type: Directive,
33808
+ args: [{
33809
+ selector: '[cqaTabContent]',
33810
+ }]
33811
+ }], ctorParameters: function () { return [{ type: i0.TemplateRef }]; } });
33812
+
33813
+ class DetailDrawerTabComponent {
33814
+ constructor() {
33815
+ /** Tab label (shown in tooltip on icon button) */
33816
+ this.label = '';
33817
+ /** Tab value (unique identifier) */
33818
+ this.value = '';
33819
+ /** Material icon name for the tab button */
33820
+ this.icon = 'folder';
33821
+ }
33822
+ get contentTemplate() {
33823
+ var _a, _b;
33824
+ return (_b = (_a = this.contentDirective) === null || _a === void 0 ? void 0 : _a.templateRef) !== null && _b !== void 0 ? _b : null;
33825
+ }
33826
+ }
33827
+ DetailDrawerTabComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DetailDrawerTabComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
33828
+ DetailDrawerTabComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: DetailDrawerTabComponent, selector: "cqa-detail-drawer-tab", inputs: { label: "label", value: "value", icon: "icon" }, host: { styleAttribute: "display: contents" }, queries: [{ propertyName: "contentDirective", first: true, predicate: DetailDrawerTabContentDirective, descendants: true }], ngImport: i0, template: '', isInline: true });
33829
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DetailDrawerTabComponent, decorators: [{
33830
+ type: Component,
33831
+ args: [{
33832
+ selector: 'cqa-detail-drawer-tab',
33833
+ template: '',
33834
+ host: {
33835
+ style: 'display: contents',
33836
+ },
33837
+ }]
33838
+ }], propDecorators: { label: [{
33839
+ type: Input
33840
+ }], value: [{
33841
+ type: Input
33842
+ }], icon: [{
33843
+ type: Input
33844
+ }], contentDirective: [{
33845
+ type: ContentChild,
33846
+ args: [DetailDrawerTabContentDirective]
33847
+ }] } });
33848
+
33849
+ class DetailDrawerComponent {
33850
+ constructor() {
33851
+ /** Currently active tab value */
33852
+ this.activeTab = '';
33853
+ /** Whether to show the close button */
33854
+ this.showCloseButton = true;
33855
+ /** Whether the drawer is expanded */
33856
+ this.expanded = true;
33857
+ /** Panel width when expanded */
33858
+ this.expandedWidth = '280px';
33859
+ /** Maximum width when expanded (e.g. '600px', '30vw'). Default: 30% of viewport */
33860
+ this.maxExpandedWidth = '30vw';
33861
+ /** Panel width when collapsed */
33862
+ this.collapsedWidth = '56px';
33863
+ this.expandTooltip = 'Expand';
33864
+ this.collapseTooltip = 'Collapse';
33865
+ this.closeTooltip = 'Close';
33866
+ this.activeTabChange = new EventEmitter();
33867
+ this.expandToggle = new EventEmitter();
33868
+ this.close = new EventEmitter();
33869
+ }
33870
+ get hostWidth() {
33871
+ return this.expanded ? this.expandedWidth : this.collapsedWidth;
33872
+ }
33873
+ get hostMinWidth() {
33874
+ return this.expanded && this.minExpandedWidth ? this.minExpandedWidth : null;
33875
+ }
33876
+ get hostMaxWidth() {
33877
+ return this.expanded ? this.maxExpandedWidth : null;
33878
+ }
33879
+ ngAfterContentInit() {
33880
+ this.ensureActiveTab();
33881
+ }
33882
+ ngAfterContentChecked() {
33883
+ this.ensureActiveTab();
33884
+ }
33885
+ ensureActiveTab() {
33886
+ var _a, _b;
33887
+ const tabs = (_b = (_a = this.tabComponents) === null || _a === void 0 ? void 0 : _a.toArray()) !== null && _b !== void 0 ? _b : [];
33888
+ if (tabs.length > 0 && !this.activeTab) {
33889
+ this.activeTab = tabs[0].value;
33890
+ this.activeTabChange.emit(this.activeTab);
33891
+ }
33892
+ }
33893
+ onTabClick(tab) {
33894
+ // If drawer is collapsed, open it (but never close on tab click)
33895
+ if (!this.expanded) {
33896
+ this.expandToggle.emit();
33897
+ }
33898
+ // Select the tab
33899
+ if (tab.value !== this.activeTab) {
33900
+ this.activeTab = tab.value;
33901
+ this.activeTabChange.emit(this.activeTab);
33902
+ }
33903
+ }
33904
+ onExpandToggle() {
33905
+ this.expandToggle.emit();
33906
+ }
33907
+ onClose() {
33908
+ this.close.emit();
33909
+ }
33910
+ trackByValue(_i, tab) {
33911
+ return tab.value;
33912
+ }
33913
+ isTabActive(tab) {
33914
+ return tab.value === this.activeTab;
33915
+ }
33916
+ }
33917
+ DetailDrawerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DetailDrawerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
33918
+ DetailDrawerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: DetailDrawerComponent, selector: "cqa-detail-drawer", inputs: { activeTab: "activeTab", showCloseButton: "showCloseButton", expanded: "expanded", expandedWidth: "expandedWidth", minExpandedWidth: "minExpandedWidth", maxExpandedWidth: "maxExpandedWidth", collapsedWidth: "collapsedWidth", expandTooltip: "expandTooltip", collapseTooltip: "collapseTooltip", closeTooltip: "closeTooltip" }, outputs: { activeTabChange: "activeTabChange", expandToggle: "expandToggle", close: "close" }, host: { properties: { "style.width": "this.hostWidth", "style.min-width": "this.hostMinWidth", "style.max-width": "this.hostMaxWidth" }, styleAttribute: "transition: width 0.3s ease-in-out", classAttribute: "cqa-ui-root cqa-flex cqa-flex-col cqa-h-full cqa-bg-white cqa-shadow-[-4px_0_6px_-1px_rgba(0,0,0,0.05)]" }, queries: [{ propertyName: "tabComponents", predicate: DetailDrawerTabComponent }], ngImport: i0, template: "<div class=\"cqa-flex cqa-flex-col cqa-h-full cqa-bg-white\">\n <div\n class=\"cqa-grid cqa-flex-1 cqa-min-h-0 cqa-overflow-hidden\"\n [style.grid-template-columns]=\"expanded ? 'auto 1fr' : 'auto 0fr'\"\n style=\"transition: grid-template-columns 0.3s ease-in-out\">\n <!-- Left vertical icon bar: one button per tab -->\n <div class=\"cqa-flex cqa-flex-col cqa-flex-1 cqa-min-h-0 cqa-items-center cqa-py-4 cqa-px-2 cqa-border-r cqa-border-[#E2E8F0] cqa-bg-[#FAFAFA] cqa-flex-shrink-0\">\n <!-- Expand / Collapse button (always visible) -->\n <button\n type=\"button\"\n [matTooltip]=\"expanded ? collapseTooltip : expandTooltip\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-9 cqa-h-9 cqa-rounded-lg cqa-text-[#64748B] hover:cqa-bg-[#E2E8F0] hover:cqa-text-[#334155] cqa-transition-colors focus:cqa-outline-none focus-visible:cqa-ring-2 focus-visible:cqa-ring-[#3F43EE] focus-visible:cqa-ring-offset-2 cqa-flex-shrink-0\"\n (click)=\"onExpandToggle()\">\n <mat-icon class=\"cqa-text-[20px] cqa-w-5 cqa-h-5\">{{ expanded ? 'unfold_less' : 'unfold_more' }}</mat-icon>\n </button>\n <!-- Close button -->\n <button\n *ngIf=\"showCloseButton\"\n type=\"button\"\n [matTooltip]=\"closeTooltip\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-9 cqa-h-9 cqa-rounded-lg cqa-text-[#64748B] hover:cqa-bg-[#E2E8F0] hover:cqa-text-[#334155] cqa-transition-colors focus:cqa-outline-none focus-visible:cqa-ring-2 focus-visible:cqa-ring-[#3F43EE] focus-visible:cqa-ring-offset-2 cqa-flex-shrink-0\"\n (click)=\"onClose()\">\n <mat-icon class=\"cqa-text-[20px] cqa-w-5 cqa-h-5\">close</mat-icon>\n </button>\n <!-- Tab buttons: equally distributed in remaining space -->\n <div class=\"cqa-flex cqa-flex-1 cqa-flex-col cqa-justify-evenly cqa-items-center cqa-w-full\">\n <button\n *ngFor=\"let tab of tabComponents; trackBy: trackByValue\"\n type=\"button\"\n role=\"tab\"\n [attr.aria-selected]=\"isTabActive(tab)\"\n [matTooltip]=\"tab.label\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-9 cqa-h-9 cqa-rounded-lg cqa-transition-colors focus:cqa-outline-none focus-visible:cqa-ring-2 focus-visible:cqa-ring-[#3F43EE] focus-visible:cqa-ring-offset-2 cqa-flex-shrink-0\"\n [ngClass]=\"{\n 'cqa-bg-[#3F43EE] cqa-text-white': isTabActive(tab),\n 'cqa-text-[#64748B] hover:cqa-bg-[#E2E8F0] hover:cqa-text-[#334155]': !isTabActive(tab)\n }\"\n (click)=\"onTabClick(tab)\">\n <mat-icon class=\"cqa-text-[20px] cqa-w-5 cqa-h-5\">{{ tab.icon }}</mat-icon>\n </button>\n </div>\n </div>\n\n <!-- Content area: show only the active tab's content -->\n <div class=\"cqa-min-w-0 cqa-overflow-hidden\">\n <div class=\"cqa-h-full cqa-overflow-y-auto cqa-p-4\">\n <ng-container *ngFor=\"let tab of tabComponents\">\n <ng-container *ngIf=\"tab.value === activeTab && tab.contentTemplate\" [ngTemplateOutlet]=\"tab.contentTemplate\"></ng-container>\n </ng-container>\n </div>\n </div>\n </div>\n</div>\n", components: [{ type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], directives: [{ type: i5.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
33919
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DetailDrawerComponent, decorators: [{
33920
+ type: Component,
33921
+ args: [{ selector: 'cqa-detail-drawer', changeDetection: ChangeDetectionStrategy.OnPush, host: {
33922
+ class: 'cqa-ui-root cqa-flex cqa-flex-col cqa-h-full cqa-bg-white cqa-shadow-[-4px_0_6px_-1px_rgba(0,0,0,0.05)]',
33923
+ style: 'transition: width 0.3s ease-in-out',
33924
+ }, template: "<div class=\"cqa-flex cqa-flex-col cqa-h-full cqa-bg-white\">\n <div\n class=\"cqa-grid cqa-flex-1 cqa-min-h-0 cqa-overflow-hidden\"\n [style.grid-template-columns]=\"expanded ? 'auto 1fr' : 'auto 0fr'\"\n style=\"transition: grid-template-columns 0.3s ease-in-out\">\n <!-- Left vertical icon bar: one button per tab -->\n <div class=\"cqa-flex cqa-flex-col cqa-flex-1 cqa-min-h-0 cqa-items-center cqa-py-4 cqa-px-2 cqa-border-r cqa-border-[#E2E8F0] cqa-bg-[#FAFAFA] cqa-flex-shrink-0\">\n <!-- Expand / Collapse button (always visible) -->\n <button\n type=\"button\"\n [matTooltip]=\"expanded ? collapseTooltip : expandTooltip\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-9 cqa-h-9 cqa-rounded-lg cqa-text-[#64748B] hover:cqa-bg-[#E2E8F0] hover:cqa-text-[#334155] cqa-transition-colors focus:cqa-outline-none focus-visible:cqa-ring-2 focus-visible:cqa-ring-[#3F43EE] focus-visible:cqa-ring-offset-2 cqa-flex-shrink-0\"\n (click)=\"onExpandToggle()\">\n <mat-icon class=\"cqa-text-[20px] cqa-w-5 cqa-h-5\">{{ expanded ? 'unfold_less' : 'unfold_more' }}</mat-icon>\n </button>\n <!-- Close button -->\n <button\n *ngIf=\"showCloseButton\"\n type=\"button\"\n [matTooltip]=\"closeTooltip\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-9 cqa-h-9 cqa-rounded-lg cqa-text-[#64748B] hover:cqa-bg-[#E2E8F0] hover:cqa-text-[#334155] cqa-transition-colors focus:cqa-outline-none focus-visible:cqa-ring-2 focus-visible:cqa-ring-[#3F43EE] focus-visible:cqa-ring-offset-2 cqa-flex-shrink-0\"\n (click)=\"onClose()\">\n <mat-icon class=\"cqa-text-[20px] cqa-w-5 cqa-h-5\">close</mat-icon>\n </button>\n <!-- Tab buttons: equally distributed in remaining space -->\n <div class=\"cqa-flex cqa-flex-1 cqa-flex-col cqa-justify-evenly cqa-items-center cqa-w-full\">\n <button\n *ngFor=\"let tab of tabComponents; trackBy: trackByValue\"\n type=\"button\"\n role=\"tab\"\n [attr.aria-selected]=\"isTabActive(tab)\"\n [matTooltip]=\"tab.label\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-9 cqa-h-9 cqa-rounded-lg cqa-transition-colors focus:cqa-outline-none focus-visible:cqa-ring-2 focus-visible:cqa-ring-[#3F43EE] focus-visible:cqa-ring-offset-2 cqa-flex-shrink-0\"\n [ngClass]=\"{\n 'cqa-bg-[#3F43EE] cqa-text-white': isTabActive(tab),\n 'cqa-text-[#64748B] hover:cqa-bg-[#E2E8F0] hover:cqa-text-[#334155]': !isTabActive(tab)\n }\"\n (click)=\"onTabClick(tab)\">\n <mat-icon class=\"cqa-text-[20px] cqa-w-5 cqa-h-5\">{{ tab.icon }}</mat-icon>\n </button>\n </div>\n </div>\n\n <!-- Content area: show only the active tab's content -->\n <div class=\"cqa-min-w-0 cqa-overflow-hidden\">\n <div class=\"cqa-h-full cqa-overflow-y-auto cqa-p-4\">\n <ng-container *ngFor=\"let tab of tabComponents\">\n <ng-container *ngIf=\"tab.value === activeTab && tab.contentTemplate\" [ngTemplateOutlet]=\"tab.contentTemplate\"></ng-container>\n </ng-container>\n </div>\n </div>\n </div>\n</div>\n", styles: [] }]
33925
+ }], propDecorators: { tabComponents: [{
33926
+ type: ContentChildren,
33927
+ args: [DetailDrawerTabComponent]
33928
+ }], activeTab: [{
33929
+ type: Input
33930
+ }], showCloseButton: [{
33931
+ type: Input
33932
+ }], expanded: [{
33933
+ type: Input
33934
+ }], expandedWidth: [{
33935
+ type: Input
33936
+ }], minExpandedWidth: [{
33937
+ type: Input
33938
+ }], maxExpandedWidth: [{
33939
+ type: Input
33940
+ }], collapsedWidth: [{
33941
+ type: Input
33942
+ }], hostWidth: [{
33943
+ type: HostBinding,
33944
+ args: ['style.width']
33945
+ }], hostMinWidth: [{
33946
+ type: HostBinding,
33947
+ args: ['style.min-width']
33948
+ }], hostMaxWidth: [{
33949
+ type: HostBinding,
33950
+ args: ['style.max-width']
33951
+ }], expandTooltip: [{
33952
+ type: Input
33953
+ }], collapseTooltip: [{
33954
+ type: Input
33955
+ }], closeTooltip: [{
33956
+ type: Input
33957
+ }], activeTabChange: [{
33958
+ type: Output
33959
+ }], expandToggle: [{
33960
+ type: Output
33961
+ }], close: [{
33962
+ type: Output
33963
+ }] } });
33964
+
33965
+ /** Keys for each dynamic select in test-case-details-edit. Use these with selectConfigOverrides. */
33966
+ const TEST_CASE_DETAILS_SELECT_KEYS = {
33967
+ status: 'status',
33968
+ priority: 'priority',
33969
+ type: 'type',
33970
+ labels: 'labels',
33971
+ prerequisiteCases: 'prerequisiteCases',
33972
+ testDataProfile: 'testDataProfile',
33973
+ testDataSet: 'testDataSet',
33974
+ videoRecording: 'videoRecording',
33975
+ enableAiSmartness: 'enableAiSmartness',
33976
+ defaultAiAction: 'defaultAiAction',
33977
+ knowledgeBaseDefaultTestCase: 'knowledgeBaseDefaultTestCase',
33978
+ useAiMetadata: 'useAiMetadata',
33979
+ defaultBrowser: 'defaultBrowser',
33980
+ defaultViewport: 'defaultViewport',
33981
+ deviceType: 'deviceType',
33982
+ deviceOS: 'deviceOS',
33983
+ };
33984
+ const FREQUENTLY_USED_LABELS = [
33985
+ 'Case',
33986
+ 'Critical',
33987
+ 'PO',
33988
+ 'Upload',
33989
+ 'Validation',
33990
+ 'Review',
33991
+ 'Edge-cases',
33992
+ 'Security',
33993
+ 'Integration',
33994
+ 'Smoke',
33995
+ ];
33996
+ class TestCaseDetailsEditComponent {
33997
+ constructor(cdr) {
33998
+ this.cdr = cdr;
33999
+ this.descriptionTitle = 'Description';
34000
+ this.descriptionContent = '';
34001
+ /** When true, description uses Trix rich text editor (Bold, Italic, etc.). Host app must load Trix. */
34002
+ this.enableMarkdown = false;
34003
+ this.metadataItems = [];
34004
+ this.labels = [];
34005
+ this.configTitle = 'Configuration';
34006
+ this.configSections = [];
34007
+ this.configSectionsRow2 = [];
34008
+ /** Optional list of prerequisite test case options for the multi-select. If not provided, uses default sample options. */
34009
+ this.prerequisiteCaseOptions = [];
34010
+ /** Platform: 'web' shows Default Browser + Viewport; 'mobile' shows Device Type + OS. Defaults to 'web'. */
34011
+ this.platform = 'web';
34012
+ /** When true, hides Priority, Type, and Test Data Set fields (step groups don't have these). Defaults to false. */
34013
+ this.isStepGroup = false;
34014
+ /**
34015
+ * Override config per select key. Use for:
34016
+ * - API-driven options: pass options array (update when API returns)
34017
+ * - Server-side search: serverSearch: true, onSearch in override or listen to selectSearch
34018
+ * - Infinite scroll: hasMore: true, onLoadMore in override or listen to selectLoadMore
34019
+ * - Initial fetch on open: initialFetchOnOpen: true
34020
+ */
34021
+ this.selectConfigOverrides = {};
34022
+ this.save = new EventEmitter();
34023
+ this.cancel = new EventEmitter();
34024
+ /** Emitted when user searches in a select (serverSearch mode). Call API and update options via selectConfigOverrides. */
34025
+ this.selectSearch = new EventEmitter();
34026
+ /** Emitted when user scrolls to load more. Call API, append to options via selectConfigOverrides. */
34027
+ this.selectLoadMore = new EventEmitter();
34028
+ /** Emitted when a select panel is opened. Use to call API for initial load (e.g. when initialFetchOnOpen). */
34029
+ this.selectOpened = new EventEmitter();
34030
+ /** Emitted when selection changes in any select. */
34031
+ this.selectionChange = new EventEmitter();
34032
+ /** Emitted when user adds a new custom label via the "New" option. */
34033
+ this.labelAdded = new EventEmitter();
34034
+ /** Form state */
34035
+ this.editDescription = '';
34036
+ this.editStatus = '';
34037
+ this.editPriority = '';
34038
+ this.editLabels = [];
34039
+ this.testCaseTimeout = '';
34040
+ this.waitTimeoutLocators = '';
34041
+ this.autoWaitEnabled = false;
34042
+ this.retryFailedSteps = '';
34043
+ this.configExpanded = true;
34044
+ this.executionExpanded = true;
34045
+ this.aiConfigExpanded = true;
34046
+ this.waitsRetriesExpanded = true;
34047
+ this.deviceExpanded = true;
34048
+ this.keyFlagsExpanded = true;
34049
+ this.mobileTestingEnabled = false;
33612
34050
  this.extensionUseEnabled = false;
33613
34051
  this.dataDrivenEnabled = false;
33614
34052
  this.frequentlyUsedLabels = FREQUENTLY_USED_LABELS;
@@ -34459,231 +34897,40 @@ class TestCaseDetailsComponent {
34459
34897
  if (this.startInEditMode) {
34460
34898
  this._editing = true;
34461
34899
  }
34462
- }
34463
- /** Filtered metadata items - excludes Priority and Type for step groups */
34464
- get filteredMetadataItems() {
34465
- if (!this.isStepGroup) {
34466
- return this.metadataItems;
34467
- }
34468
- return this.metadataItems.filter((item) => { var _a, _b; return !this.stepGroupExcludedMetadataLabels.includes((_b = (_a = item.label) === null || _a === void 0 ? void 0 : _a.toLowerCase()) !== null && _b !== void 0 ? _b : ''); });
34469
- }
34470
- onEditClick() {
34471
- if (this.editing === undefined) {
34472
- this._editing = true;
34473
- this.cdr.detectChanges();
34474
- }
34475
- this.editDescription.emit();
34476
- }
34477
- onSaveChanges(data) {
34478
- if (this.editing === undefined) {
34479
- this._editing = false;
34480
- }
34481
- this.cdr.detectChanges();
34482
- this.saveChanges.emit(data);
34483
- }
34484
- onCancelEdit() {
34485
- this.cancel.emit();
34486
- if (this.editing === undefined) {
34487
- this._editing = false;
34488
- }
34489
- this.cdr.detectChanges();
34490
- }
34491
- trackByConfigTitle(_i, section) {
34492
- return section.title;
34493
- }
34494
- trackByMetadataLabel(_i, item) {
34495
- return item.label;
34496
- }
34497
- onMetadataLinkClick(item) {
34498
- if (item.link) {
34499
- this.metadataLinkClick.emit(item);
34500
- }
34501
- }
34502
- getStatusDotClass(item) {
34503
- if (!item.statusColor)
34504
- return '';
34505
- switch (item.statusColor) {
34506
- case 'yellow':
34507
- return 'cqa-bg-[#EAB308]';
34508
- case 'red':
34509
- return 'cqa-bg-[#DC2626]';
34510
- case 'green':
34511
- return 'cqa-bg-[#16A34A]';
34512
- case 'gray':
34513
- default:
34514
- return 'cqa-bg-[#94A3B8]';
34515
- }
34516
- }
34517
- /** Text color for metadata value (e.g. red for critical priority) */
34518
- getValueTextClass(item) {
34519
- if (item.statusColor === 'red') {
34520
- return 'cqa-text-[#DC2626]';
34521
- }
34522
- return 'cqa-text-[#111827]';
34523
- }
34524
- }
34525
- TestCaseDetailsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TestCaseDetailsComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
34526
- TestCaseDetailsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: TestCaseDetailsComponent, selector: "cqa-test-case-details", inputs: { editing: "editing", startInEditMode: "startInEditMode", descriptionTitle: "descriptionTitle", descriptionContent: "descriptionContent", enableMarkdown: "enableMarkdown", showEditButton: "showEditButton", metadataItems: "metadataItems", labels: "labels", configTitle: "configTitle", configSections: "configSections", configSectionsRow2: "configSectionsRow2", platform: "platform", isStepGroup: "isStepGroup", selectConfigOverrides: "selectConfigOverrides" }, outputs: { editDescription: "editDescription", cancel: "cancel", saveChanges: "saveChanges", metadataLinkClick: "metadataLinkClick", selectSearch: "selectSearch", selectLoadMore: "selectLoadMore", selectOpened: "selectOpened", selectionChange: "selectionChange", labelAdded: "labelAdded" }, ngImport: i0, template: "<!-- Edit mode: show edit form (Figma design) -->\n<cqa-test-case-details-edit\n *ngIf=\"isEditing\"\n [descriptionTitle]=\"descriptionTitle\"\n [descriptionContent]=\"descriptionContent\"\n [enableMarkdown]=\"enableMarkdown\"\n [metadataItems]=\"metadataItems\"\n [labels]=\"labels\"\n [configTitle]=\"configTitle\"\n [configSections]=\"configSections\"\n [configSectionsRow2]=\"configSectionsRow2\"\n [platform]=\"platform\"\n [isStepGroup]=\"isStepGroup\"\n [selectConfigOverrides]=\"selectConfigOverrides\"\n (save)=\"onSaveChanges($event)\"\n (cancel)=\"onCancelEdit()\"\n (selectSearch)=\"selectSearch.emit($event)\"\n (selectLoadMore)=\"selectLoadMore.emit($event)\"\n (selectOpened)=\"selectOpened.emit($event)\"\n (selectionChange)=\"selectionChange.emit($event)\"\n (labelAdded)=\"labelAdded.emit($event)\">\n</cqa-test-case-details-edit>\n\n<!-- View mode: read-only details -->\n<div *ngIf=\"!isEditing\" class=\"cqa-self-stretch cqa-py-4 cqa-px-0 cqa-flex cqa-flex-col cqa-justify-start cqa-items-start cqa-gap-4 cqa-text-sm cqa-leading-[19.6px]\">\n <div class=\"cqa-self-stretch cqa-flex cqa-flex-col cqa-justify-start cqa-items-start cqa-gap-4 cqa-text-sm cqa-leading-[19.6px]\">\n <!-- Description Section -->\n <div class=\"cqa-self-stretch cqa-flex cqa-flex-col cqa-justify-start cqa-items-start cqa-gap-2.5\">\n <div class=\"cqa-self-stretch cqa-inline-flex cqa-justify-between cqa-items-center\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <div class=\"cqa-w-5 cqa-h-5 cqa-p-1 cqa-flex-shrink-0 cqa-bg-[#3F43EE1A] cqa-rounded-md cqa-inline-flex cqa-justify-center cqa-items-center\">\n <mat-icon class=\"cqa-text-[#1B1FEB] cqa-text-[12px] cqa-w-3 cqa-h-3 cqa-leading-none cqa-block\">description</mat-icon>\n </div>\n <span class=\"cqa-text-[#374151] cqa-text-sm cqa-font-semibold cqa-leading-[19.6px]\">{{ descriptionTitle }}</span>\n </div>\n <button\n *ngIf=\"showEditButton\"\n type=\"button\"\n class=\"cqa-flex cqa-justify-end cqa-items-center cqa-gap-2 cqa-text-[#A3A3A3] cqa-text-xs cqa-font-semibold hover:cqa-text-[#737373] cqa-transition-colors focus:cqa-outline-none focus-visible:cqa-ring-2 focus-visible:cqa-ring-[#3F43EE] focus-visible:cqa-ring-offset-2\"\n (click)=\"onEditClick()\">\n <mat-icon class=\"cqa-text-[14px] cqa-w-4 cqa-h-4\">edit</mat-icon>\n Edit\n </button>\n </div>\n <div *ngIf=\"descriptionContent\" class=\"cqa-self-stretch cqa-flex cqa-flex-col cqa-justify-start cqa-items-start\">\n <div *ngIf=\"enableMarkdown\" class=\"cqa-self-stretch cqa-text-[#111827] cqa-text-sm cqa-leading-[19.6px] cqa-font-normal cqa-prose cqa-prose-sm cqa-max-w-none\" [innerHTML]=\"descriptionContent\"></div>\n <div *ngIf=\"!enableMarkdown\" class=\"cqa-self-stretch cqa-text-[#111827] cqa-text-sm cqa-leading-[19.6px] cqa-font-normal\">{{ descriptionContent }}</div>\n </div>\n </div>\n\n <!-- Metadata Section -->\n <div *ngIf=\"filteredMetadataItems.length\" class=\"cqa-self-stretch cqa-flex cqa-flex-col cqa-justify-start cqa-items-start cqa-gap-2.5\">\n <div class=\"cqa-self-stretch cqa-grid cqa-grid-cols-2 cqa-gap-x-0 cqa-gap-y-4\">\n <ng-container *ngFor=\"let item of filteredMetadataItems; trackBy: trackByMetadataLabel\">\n <div class=\"cqa-flex cqa-flex-col cqa-justify-start cqa-items-start cqa-gap-0.5\">\n <div class=\"cqa-text-[#6B7280] cqa-text-xs cqa-leading-[15px] cqa-font-medium\">{{ item.label }}</div>\n <div\n class=\"cqa-flex cqa-justify-start cqa-items-center cqa-gap-[5px] cqa-min-w-0 cqa-w-full cqa-text-left cqa-text-[#0A0A0A] cqa-border cqa-border-[#F5F5F5]\">\n <mat-icon *ngIf=\"item.icon && (!item.iconLibrary || item.iconLibrary === 'mat')\" class=\"cqa-text-[#6B7280] cqa-text-sm cqa-w-4 cqa-h-4\">\n {{ item.icon }}\n </mat-icon>\n <span *ngIf=\"item.statusColor\" class=\"cqa-w-3.5 cqa-h-3.5 cqa-rounded-full cqa-flex-shrink-0\" [ngClass]=\"getStatusDotClass(item)\"></span>\n <a\n *ngIf=\"item.link\"\n href=\"javascript:void(0)\"\n class=\"cqa-text-[#2563EB] cqa-text-xs cqa-leading-[12px] cqa-font-normal hover:cqa-underline cqa-cursor-pointer cqa-block cqa-truncate cqa-min-w-0\"\n (click)=\"onMetadataLinkClick(item); $event.preventDefault()\">\n {{ item.value }}\n </a>\n <span *ngIf=\"!item.link\" class=\"cqa-text-xs cqa-leading-[12px] cqa-font-normal cqa-align-middle\" [ngClass]=\"getValueTextClass(item)\">\n {{ item.value }}\n </span>\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n\n <!-- Labels (Figma: Labels title, cqa-badge chips with tag icon) -->\n <div *ngIf=\"labels.length\" class=\"cqa-self-stretch cqa-flex cqa-flex-col cqa-justify-start cqa-items-start cqa-gap-2 cqa-text-sm cqa-leading-[19.6px]\">\n <span class=\"cqa-text-[#111827] cqa-text-sm cqa-font-medium cqa-leading-5\">Labels</span>\n <div class=\"cqa-flex cqa-flex-wrap cqa-gap-2\">\n <cqa-badge\n *ngFor=\"let label of labels\"\n [label]=\"label\"\n icon=\"label\"\n variant=\"outline\"\n size=\"small\"\n backgroundColor=\"#ffffff\"\n textColor=\"#475569\"\n borderColor=\"#E2E8F0\"\n iconColor=\"#94A3B8\">\n </cqa-badge>\n </div>\n </div>\n\n <!-- Configuration Section -->\n <div *ngIf=\"configSections.length || configSectionsRow2.length\" class=\"cqa-self-stretch cqa-flex cqa-flex-col cqa-justify-start cqa-items-start cqa-gap-2.5\">\n <div class=\"cqa-self-stretch cqa-inline-flex cqa-justify-start cqa-items-center\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <div class=\"cqa-w-5 cqa-h-5 cqa-p-1 cqa-flex-shrink-0 cqa-bg-[#3F43EE1A] cqa-rounded-md cqa-inline-flex cqa-justify-center cqa-items-center\">\n <mat-icon class=\"cqa-text-[#1B1FEB] cqa-text-[12px] cqa-w-3 cqa-h-3 cqa-leading-none cqa-block\">settings</mat-icon>\n </div>\n <span class=\"cqa-text-[#374151] cqa-text-sm cqa-font-semibold cqa-leading-[19.6px]\">{{ configTitle }}</span>\n </div>\n </div>\n <div class=\"cqa-self-stretch cqa-flex cqa-flex-col cqa-justify-start cqa-items-start cqa-gap-2.5\">\n <div class=\"cqa-self-stretch cqa-grid cqa-grid-cols-1 cqa-gap-2.5\">\n <ng-container *ngFor=\"let section of configSections; trackBy: trackByConfigTitle\">\n <cqa-configuration-card\n [icon]=\"section.icon || 'tune'\"\n [title]=\"section.title\"\n [data]=\"section.items\">\n </cqa-configuration-card>\n </ng-container>\n </div>\n <div *ngIf=\"configSectionsRow2.length\" class=\"cqa-self-stretch cqa-flex cqa-flex-col cqa-gap-4 cqa-text-sm cqa-leading-[19.6px]\">\n <cqa-configuration-card\n *ngFor=\"let section of configSectionsRow2; trackBy: trackByConfigTitle\"\n [icon]=\"section.icon || 'tune'\"\n [title]=\"section.title\"\n [data]=\"section.items\">\n </cqa-configuration-card>\n </div>\n </div>\n </div>\n </div>\n</div>\n", components: [{ type: TestCaseDetailsEditComponent, selector: "cqa-test-case-details-edit", inputs: ["descriptionTitle", "descriptionContent", "enableMarkdown", "metadataItems", "labels", "configTitle", "configSections", "configSectionsRow2", "prerequisiteCaseOptions", "platform", "isStepGroup", "selectConfigOverrides"], outputs: ["save", "cancel", "selectSearch", "selectLoadMore", "selectOpened", "selectionChange", "labelAdded"] }, { type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: BadgeComponent, selector: "cqa-badge", inputs: ["type", "label", "icon", "iconLibrary", "variant", "size", "backgroundColor", "textColor", "borderColor", "iconBackgroundColor", "iconColor", "iconSize", "inlineStyles", "key", "value", "keyTextColor", "valueTextColor", "isLoading"] }, { type: ConfigurationCardComponent, selector: "cqa-configuration-card", inputs: ["icon", "title", "data"] }], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
34527
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TestCaseDetailsComponent, decorators: [{
34528
- type: Component,
34529
- args: [{ selector: 'cqa-test-case-details', changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Edit mode: show edit form (Figma design) -->\n<cqa-test-case-details-edit\n *ngIf=\"isEditing\"\n [descriptionTitle]=\"descriptionTitle\"\n [descriptionContent]=\"descriptionContent\"\n [enableMarkdown]=\"enableMarkdown\"\n [metadataItems]=\"metadataItems\"\n [labels]=\"labels\"\n [configTitle]=\"configTitle\"\n [configSections]=\"configSections\"\n [configSectionsRow2]=\"configSectionsRow2\"\n [platform]=\"platform\"\n [isStepGroup]=\"isStepGroup\"\n [selectConfigOverrides]=\"selectConfigOverrides\"\n (save)=\"onSaveChanges($event)\"\n (cancel)=\"onCancelEdit()\"\n (selectSearch)=\"selectSearch.emit($event)\"\n (selectLoadMore)=\"selectLoadMore.emit($event)\"\n (selectOpened)=\"selectOpened.emit($event)\"\n (selectionChange)=\"selectionChange.emit($event)\"\n (labelAdded)=\"labelAdded.emit($event)\">\n</cqa-test-case-details-edit>\n\n<!-- View mode: read-only details -->\n<div *ngIf=\"!isEditing\" class=\"cqa-self-stretch cqa-py-4 cqa-px-0 cqa-flex cqa-flex-col cqa-justify-start cqa-items-start cqa-gap-4 cqa-text-sm cqa-leading-[19.6px]\">\n <div class=\"cqa-self-stretch cqa-flex cqa-flex-col cqa-justify-start cqa-items-start cqa-gap-4 cqa-text-sm cqa-leading-[19.6px]\">\n <!-- Description Section -->\n <div class=\"cqa-self-stretch cqa-flex cqa-flex-col cqa-justify-start cqa-items-start cqa-gap-2.5\">\n <div class=\"cqa-self-stretch cqa-inline-flex cqa-justify-between cqa-items-center\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <div class=\"cqa-w-5 cqa-h-5 cqa-p-1 cqa-flex-shrink-0 cqa-bg-[#3F43EE1A] cqa-rounded-md cqa-inline-flex cqa-justify-center cqa-items-center\">\n <mat-icon class=\"cqa-text-[#1B1FEB] cqa-text-[12px] cqa-w-3 cqa-h-3 cqa-leading-none cqa-block\">description</mat-icon>\n </div>\n <span class=\"cqa-text-[#374151] cqa-text-sm cqa-font-semibold cqa-leading-[19.6px]\">{{ descriptionTitle }}</span>\n </div>\n <button\n *ngIf=\"showEditButton\"\n type=\"button\"\n class=\"cqa-flex cqa-justify-end cqa-items-center cqa-gap-2 cqa-text-[#A3A3A3] cqa-text-xs cqa-font-semibold hover:cqa-text-[#737373] cqa-transition-colors focus:cqa-outline-none focus-visible:cqa-ring-2 focus-visible:cqa-ring-[#3F43EE] focus-visible:cqa-ring-offset-2\"\n (click)=\"onEditClick()\">\n <mat-icon class=\"cqa-text-[14px] cqa-w-4 cqa-h-4\">edit</mat-icon>\n Edit\n </button>\n </div>\n <div *ngIf=\"descriptionContent\" class=\"cqa-self-stretch cqa-flex cqa-flex-col cqa-justify-start cqa-items-start\">\n <div *ngIf=\"enableMarkdown\" class=\"cqa-self-stretch cqa-text-[#111827] cqa-text-sm cqa-leading-[19.6px] cqa-font-normal cqa-prose cqa-prose-sm cqa-max-w-none\" [innerHTML]=\"descriptionContent\"></div>\n <div *ngIf=\"!enableMarkdown\" class=\"cqa-self-stretch cqa-text-[#111827] cqa-text-sm cqa-leading-[19.6px] cqa-font-normal\">{{ descriptionContent }}</div>\n </div>\n </div>\n\n <!-- Metadata Section -->\n <div *ngIf=\"filteredMetadataItems.length\" class=\"cqa-self-stretch cqa-flex cqa-flex-col cqa-justify-start cqa-items-start cqa-gap-2.5\">\n <div class=\"cqa-self-stretch cqa-grid cqa-grid-cols-2 cqa-gap-x-0 cqa-gap-y-4\">\n <ng-container *ngFor=\"let item of filteredMetadataItems; trackBy: trackByMetadataLabel\">\n <div class=\"cqa-flex cqa-flex-col cqa-justify-start cqa-items-start cqa-gap-0.5\">\n <div class=\"cqa-text-[#6B7280] cqa-text-xs cqa-leading-[15px] cqa-font-medium\">{{ item.label }}</div>\n <div\n class=\"cqa-flex cqa-justify-start cqa-items-center cqa-gap-[5px] cqa-min-w-0 cqa-w-full cqa-text-left cqa-text-[#0A0A0A] cqa-border cqa-border-[#F5F5F5]\">\n <mat-icon *ngIf=\"item.icon && (!item.iconLibrary || item.iconLibrary === 'mat')\" class=\"cqa-text-[#6B7280] cqa-text-sm cqa-w-4 cqa-h-4\">\n {{ item.icon }}\n </mat-icon>\n <span *ngIf=\"item.statusColor\" class=\"cqa-w-3.5 cqa-h-3.5 cqa-rounded-full cqa-flex-shrink-0\" [ngClass]=\"getStatusDotClass(item)\"></span>\n <a\n *ngIf=\"item.link\"\n href=\"javascript:void(0)\"\n class=\"cqa-text-[#2563EB] cqa-text-xs cqa-leading-[12px] cqa-font-normal hover:cqa-underline cqa-cursor-pointer cqa-block cqa-truncate cqa-min-w-0\"\n (click)=\"onMetadataLinkClick(item); $event.preventDefault()\">\n {{ item.value }}\n </a>\n <span *ngIf=\"!item.link\" class=\"cqa-text-xs cqa-leading-[12px] cqa-font-normal cqa-align-middle\" [ngClass]=\"getValueTextClass(item)\">\n {{ item.value }}\n </span>\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n\n <!-- Labels (Figma: Labels title, cqa-badge chips with tag icon) -->\n <div *ngIf=\"labels.length\" class=\"cqa-self-stretch cqa-flex cqa-flex-col cqa-justify-start cqa-items-start cqa-gap-2 cqa-text-sm cqa-leading-[19.6px]\">\n <span class=\"cqa-text-[#111827] cqa-text-sm cqa-font-medium cqa-leading-5\">Labels</span>\n <div class=\"cqa-flex cqa-flex-wrap cqa-gap-2\">\n <cqa-badge\n *ngFor=\"let label of labels\"\n [label]=\"label\"\n icon=\"label\"\n variant=\"outline\"\n size=\"small\"\n backgroundColor=\"#ffffff\"\n textColor=\"#475569\"\n borderColor=\"#E2E8F0\"\n iconColor=\"#94A3B8\">\n </cqa-badge>\n </div>\n </div>\n\n <!-- Configuration Section -->\n <div *ngIf=\"configSections.length || configSectionsRow2.length\" class=\"cqa-self-stretch cqa-flex cqa-flex-col cqa-justify-start cqa-items-start cqa-gap-2.5\">\n <div class=\"cqa-self-stretch cqa-inline-flex cqa-justify-start cqa-items-center\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <div class=\"cqa-w-5 cqa-h-5 cqa-p-1 cqa-flex-shrink-0 cqa-bg-[#3F43EE1A] cqa-rounded-md cqa-inline-flex cqa-justify-center cqa-items-center\">\n <mat-icon class=\"cqa-text-[#1B1FEB] cqa-text-[12px] cqa-w-3 cqa-h-3 cqa-leading-none cqa-block\">settings</mat-icon>\n </div>\n <span class=\"cqa-text-[#374151] cqa-text-sm cqa-font-semibold cqa-leading-[19.6px]\">{{ configTitle }}</span>\n </div>\n </div>\n <div class=\"cqa-self-stretch cqa-flex cqa-flex-col cqa-justify-start cqa-items-start cqa-gap-2.5\">\n <div class=\"cqa-self-stretch cqa-grid cqa-grid-cols-1 cqa-gap-2.5\">\n <ng-container *ngFor=\"let section of configSections; trackBy: trackByConfigTitle\">\n <cqa-configuration-card\n [icon]=\"section.icon || 'tune'\"\n [title]=\"section.title\"\n [data]=\"section.items\">\n </cqa-configuration-card>\n </ng-container>\n </div>\n <div *ngIf=\"configSectionsRow2.length\" class=\"cqa-self-stretch cqa-flex cqa-flex-col cqa-gap-4 cqa-text-sm cqa-leading-[19.6px]\">\n <cqa-configuration-card\n *ngFor=\"let section of configSectionsRow2; trackBy: trackByConfigTitle\"\n [icon]=\"section.icon || 'tune'\"\n [title]=\"section.title\"\n [data]=\"section.items\">\n </cqa-configuration-card>\n </div>\n </div>\n </div>\n </div>\n</div>\n", styles: [] }]
34530
- }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { editing: [{
34531
- type: Input
34532
- }], startInEditMode: [{
34533
- type: Input
34534
- }], descriptionTitle: [{
34535
- type: Input
34536
- }], descriptionContent: [{
34537
- type: Input
34538
- }], enableMarkdown: [{
34539
- type: Input
34540
- }], showEditButton: [{
34541
- type: Input
34542
- }], metadataItems: [{
34543
- type: Input
34544
- }], labels: [{
34545
- type: Input
34546
- }], configTitle: [{
34547
- type: Input
34548
- }], configSections: [{
34549
- type: Input
34550
- }], configSectionsRow2: [{
34551
- type: Input
34552
- }], platform: [{
34553
- type: Input
34554
- }], isStepGroup: [{
34555
- type: Input
34556
- }], selectConfigOverrides: [{
34557
- type: Input
34558
- }], editDescription: [{
34559
- type: Output
34560
- }], cancel: [{
34561
- type: Output
34562
- }], saveChanges: [{
34563
- type: Output
34564
- }], metadataLinkClick: [{
34565
- type: Output
34566
- }], selectSearch: [{
34567
- type: Output
34568
- }], selectLoadMore: [{
34569
- type: Output
34570
- }], selectOpened: [{
34571
- type: Output
34572
- }], selectionChange: [{
34573
- type: Output
34574
- }], labelAdded: [{
34575
- type: Output
34576
- }] } });
34577
-
34578
- class DetailSidePanelComponent {
34579
- constructor(cdr) {
34580
- this.cdr = cdr;
34581
- /** Tabs - each tab has a side panel icon button; tabs and buttons are 1:1 */
34582
- this.tabs = [
34583
- { label: 'Test Case', value: 'test-case', icon: 'description' },
34584
- { label: 'Data Library', value: 'data-library', icon: 'folder' },
34585
- { label: 'Variables', value: 'variables', icon: 'code' },
34586
- ];
34587
- /** Currently active tab value */
34588
- this.activeTab = 'test-case';
34589
- /** Description section title */
34590
- this.descriptionTitle = 'Description';
34591
- /** Description text content */
34592
- this.descriptionContent = '';
34593
- /** When true, description uses rich text editor and renders as HTML. Host app must load Trix. */
34594
- this.enableMarkdown = false;
34595
- /** Whether to show the Edit button in the Description header */
34596
- this.showEditButton = true;
34597
- /** Metadata items (Created on, Status, Priority, etc.) */
34598
- this.metadataItems = [];
34599
- /** Labels/tags (e.g. Automation, API, SDK, UI/UX) */
34600
- this.labels = [];
34601
- /** Configuration sections - full width (e.g. Execution, AI Configuration) */
34602
- this.configSections = [];
34603
- /** Optional config sections displayed in a 2-column row (e.g. Waits & Retries, Device) */
34604
- this.configSectionsRow2 = [];
34605
- /** Platform: 'web' or 'mobile'. Defaults to 'web'. Used for Device Settings. */
34606
- this.platform = 'web';
34607
- /** When true, hides Priority, Type, Test Data Set, and Prerequisite Case (step groups don't have these). Defaults to false. */
34608
- this.isStepGroup = false;
34609
- /** Configuration section title */
34610
- this.configTitle = 'Configuration';
34611
- /** Whether to show the close button in the side menu */
34612
- this.showCloseButton = false;
34613
- /** When true, test case details start in edit mode (useful for Storybook). */
34614
- this.startInEditMode = false;
34615
- /** Override config per select for API-driven options, server search, load more. */
34616
- this.selectConfigOverrides = {};
34617
- /** Whether the panel is expanded (affects expand button icon and panel width) */
34618
- this.expanded = true;
34619
- /** Panel width when expanded (e.g. '480px', '25%') */
34620
- this.expandedWidth = '380px';
34621
- /** Panel width when collapsed (e.g. '56px' - fits icon bar + back button) */
34622
- this.collapsedWidth = '56px';
34623
- this.hostOverflow = 'hidden';
34624
- /** Tooltip for expand button when panel is collapsed */
34625
- this.expandTooltip = 'Expand';
34626
- /** Tooltip for expand button when panel is expanded (collapse) */
34627
- this.collapseTooltip = 'Collapse';
34628
- /** Tooltip for close button */
34629
- this.closeTooltip = 'Close';
34630
- this.back = new EventEmitter();
34631
- this.tabChange = new EventEmitter();
34632
- this.editDescription = new EventEmitter();
34633
- this.cancel = new EventEmitter();
34634
- this.saveChanges = new EventEmitter();
34635
- this.metadataLinkClick = new EventEmitter();
34636
- this.selectSearch = new EventEmitter();
34637
- this.selectLoadMore = new EventEmitter();
34638
- this.selectOpened = new EventEmitter();
34639
- this.selectionChange = new EventEmitter();
34640
- this.labelAdded = new EventEmitter();
34641
- this.expandToggle = new EventEmitter();
34642
- this.close = new EventEmitter();
34643
- }
34644
- get hostWidth() {
34645
- return this.expanded ? this.expandedWidth : this.collapsedWidth;
34646
- }
34647
- get hostMinWidth() {
34648
- return this.expanded ? this.expandedWidth : this.collapsedWidth;
34649
- }
34650
- get hostMaxWidth() {
34651
- return this.expanded ? this.expandedWidth : this.collapsedWidth;
34652
- }
34653
- trackByTabValue(_i, tab) {
34654
- return tab.value;
34655
- }
34656
- trackByMetadataLabel(_i, item) {
34657
- return item.label;
34658
- }
34659
- trackByConfigTitle(_i, section) {
34660
- return section.title;
34661
- }
34662
- onBack() {
34663
- this.back.emit();
34664
- }
34665
- onTabClick(tab) {
34666
- if (!this.expanded) {
34667
- this.expandToggle.emit();
34668
- }
34669
- if (tab.value !== this.activeTab) {
34670
- this.tabChange.emit(tab.value);
34900
+ }
34901
+ /** Filtered metadata items - excludes Priority and Type for step groups */
34902
+ get filteredMetadataItems() {
34903
+ if (!this.isStepGroup) {
34904
+ return this.metadataItems;
34671
34905
  }
34906
+ return this.metadataItems.filter((item) => { var _a, _b; return !this.stepGroupExcludedMetadataLabels.includes((_b = (_a = item.label) === null || _a === void 0 ? void 0 : _a.toLowerCase()) !== null && _b !== void 0 ? _b : ''); });
34672
34907
  }
34673
- onEditDescription() {
34908
+ onEditClick() {
34909
+ if (this.editing === undefined) {
34910
+ this._editing = true;
34911
+ this.cdr.detectChanges();
34912
+ }
34674
34913
  this.editDescription.emit();
34675
34914
  }
34676
34915
  onSaveChanges(data) {
34916
+ if (this.editing === undefined) {
34917
+ this._editing = false;
34918
+ }
34919
+ this.cdr.detectChanges();
34677
34920
  this.saveChanges.emit(data);
34678
34921
  }
34679
- onCancel() {
34922
+ onCancelEdit() {
34680
34923
  this.cancel.emit();
34924
+ if (this.editing === undefined) {
34925
+ this._editing = false;
34926
+ }
34927
+ this.cdr.detectChanges();
34681
34928
  }
34682
- onExpandToggle() {
34683
- this.expandToggle.emit();
34929
+ trackByConfigTitle(_i, section) {
34930
+ return section.title;
34684
34931
  }
34685
- onClose() {
34686
- this.close.emit();
34932
+ trackByMetadataLabel(_i, item) {
34933
+ return item.label;
34687
34934
  }
34688
34935
  onMetadataLinkClick(item) {
34689
34936
  if (item.link) {
@@ -34705,18 +34952,22 @@ class DetailSidePanelComponent {
34705
34952
  return 'cqa-bg-[#94A3B8]';
34706
34953
  }
34707
34954
  }
34955
+ /** Text color for metadata value (e.g. red for critical priority) */
34956
+ getValueTextClass(item) {
34957
+ if (item.statusColor === 'red') {
34958
+ return 'cqa-text-[#DC2626]';
34959
+ }
34960
+ return 'cqa-text-[#111827]';
34961
+ }
34708
34962
  }
34709
- DetailSidePanelComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DetailSidePanelComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
34710
- DetailSidePanelComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: DetailSidePanelComponent, selector: "cqa-detail-side-panel", inputs: { tabs: "tabs", activeTab: "activeTab", descriptionTitle: "descriptionTitle", descriptionContent: "descriptionContent", enableMarkdown: "enableMarkdown", showEditButton: "showEditButton", metadataItems: "metadataItems", labels: "labels", configSections: "configSections", configSectionsRow2: "configSectionsRow2", platform: "platform", isStepGroup: "isStepGroup", configTitle: "configTitle", showCloseButton: "showCloseButton", startInEditMode: "startInEditMode", editing: "editing", selectConfigOverrides: "selectConfigOverrides", expanded: "expanded", expandedWidth: "expandedWidth", collapsedWidth: "collapsedWidth", expandTooltip: "expandTooltip", collapseTooltip: "collapseTooltip", closeTooltip: "closeTooltip" }, outputs: { back: "back", tabChange: "tabChange", editDescription: "editDescription", cancel: "cancel", saveChanges: "saveChanges", metadataLinkClick: "metadataLinkClick", selectSearch: "selectSearch", selectLoadMore: "selectLoadMore", selectOpened: "selectOpened", selectionChange: "selectionChange", labelAdded: "labelAdded", expandToggle: "expandToggle", close: "close" }, host: { properties: { "style.width": "this.hostWidth", "style.min-width": "this.hostMinWidth", "style.max-width": "this.hostMaxWidth", "style.overflow": "this.hostOverflow" }, styleAttribute: "transition: width 0.3s ease-in-out", classAttribute: "cqa-ui-root cqa-flex cqa-flex-col cqa-h-full cqa-flex-shrink-0 cqa-flex-grow-0 cqa-bg-white cqa-shadow-[-4px_0_6px_-1px_rgba(0,0,0,0.05)]" }, ngImport: i0, template: "<div class=\"cqa-flex cqa-flex-col cqa-h-full cqa-min-w-0 cqa-bg-white\">\n <!-- Main content: Side menu + Scrollable content -->\n <div\n class=\"cqa-grid cqa-flex-1 cqa-min-h-0 cqa-min-w-0 cqa-overflow-hidden\"\n [style.grid-template-columns]=\"expanded ? 'auto 1fr' : 'auto 0fr'\"\n style=\"transition: grid-template-columns 0.3s ease-in-out\">\n <!-- Left vertical icon menu -->\n <div\n class=\"cqa-flex cqa-flex-col cqa-items-center cqa-gap-2 cqa-py-4 cqa-px-2 cqa-border-r cqa-border-[#F5F5F5] cqa-flex-shrink-0 cqa-text-[#0A0A0A]\"\n style=\"box-shadow: 1px 4px 12px 1px rgba(0, 0, 0, 0.05);\">\n <!-- Expand / Collapse button (always visible) -->\n <button\n type=\"button\"\n [matTooltip]=\"expanded ? collapseTooltip : expandTooltip\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-9 cqa-h-9 cqa-rounded-lg cqa-text-[#64748B] hover:cqa-bg-[#E2E8F0] hover:cqa-text-[#334155] cqa-transition-colors focus:cqa-outline-none focus-visible:cqa-ring-2 focus-visible:cqa-ring-[#3F43EE] focus-visible:cqa-ring-offset-2\"\n (click)=\"onExpandToggle()\">\n <mat-icon class=\"cqa-text-[20px] cqa-w-5 cqa-h-5\">{{ expanded ? 'chevron_left' : 'chevron_right' }}</mat-icon>\n </button>\n <!-- Close button -->\n <button\n *ngIf=\"showCloseButton\"\n type=\"button\"\n [matTooltip]=\"closeTooltip\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-9 cqa-h-9 cqa-rounded-lg cqa-text-[#64748B] hover:cqa-bg-[#E2E8F0] hover:cqa-text-[#334155] cqa-transition-colors focus:cqa-outline-none focus-visible:cqa-ring-2 focus-visible:cqa-ring-[#3F43EE] focus-visible:cqa-ring-offset-2\"\n (click)=\"onClose()\">\n <mat-icon class=\"cqa-text-[20px] cqa-w-5 cqa-h-5\">close</mat-icon>\n </button>\n <!-- Tab buttons (1:1 with tabs) -->\n <button\n *ngFor=\"let tab of tabs; trackBy: trackByTabValue\"\n type=\"button\"\n [matTooltip]=\"tab.label\"\n [class.cqa-bg-[#3F43EE]]=\"activeTab === tab.value\"\n [class.cqa-text-white]=\"activeTab === tab.value\"\n [class.cqa-text-[#64748B]]=\"activeTab !== tab.value\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-9 cqa-h-9 cqa-rounded-lg hover:cqa-bg-[#E2E8F0] hover:cqa-text-[#334155] cqa-transition-colors focus:cqa-outline-none focus-visible:cqa-ring-2 focus-visible:cqa-ring-[#3F43EE] focus-visible:cqa-ring-offset-2\"\n (click)=\"onTabClick(tab)\">\n <mat-icon class=\"cqa-text-[20px] cqa-w-5 cqa-h-5\">{{ tab.icon || 'circle' }}</mat-icon>\n </button>\n </div>\n\n <!-- Scrollable content area (collapses with animation when expanded is false) -->\n <div class=\"cqa-flex cqa-flex-col cqa-min-h-0 cqa-min-w-0 cqa-overflow-hidden cqa-w-full cqa-h-full\">\n <div class=\"detail-side-panel-scroll cqa-flex-1 cqa-min-h-0 cqa-min-w-0 cqa-overflow-y-auto cqa-overflow-x-hidden cqa-p-4 cqa-space-y-4\" style=\"overflow-y: auto; overflow-x: hidden; min-height: 0; -webkit-overflow-scrolling: touch;\">\n <!-- Tabs: equally distributed (Figma: purple active, gray inactive) -->\n <div class=\"cqa-flex cqa-gap-[3.5px] cqa-p-[3.5px] cqa-bg-[#F1F5F9] cqa-rounded-lg cqa-w-full\" role=\"tablist\">\n <button\n *ngFor=\"let tab of tabs; trackBy: trackByTabValue\"\n type=\"button\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === tab.value\"\n [class.cqa-bg-[#3F43EE]]=\"activeTab === tab.value\"\n [class.cqa-text-white]=\"activeTab === tab.value\"\n [class.cqa-text-[#64748B]]=\"activeTab !== tab.value\"\n class=\"cqa-flex-1 cqa-flex cqa-justify-center cqa-items-center cqa-py-2 cqa-rounded-lg cqa-text-xs cqa-font-medium cqa-transition-colors hover:cqa-opacity-90 focus:cqa-outline-none focus-visible:cqa-ring-2 focus-visible:cqa-ring-[#3F43EE] focus-visible:cqa-ring-offset-2\"\n (click)=\"onTabClick(tab)\">\n {{ tab.label }}\n </button>\n </div>\n\n <!-- Test Case tab: use cqa-test-case-details (Figma design) -->\n <cqa-test-case-details\n *ngIf=\"activeTab === 'test-case'\"\n [descriptionTitle]=\"descriptionTitle\"\n [descriptionContent]=\"descriptionContent\"\n [enableMarkdown]=\"enableMarkdown\"\n [showEditButton]=\"showEditButton\"\n [startInEditMode]=\"startInEditMode\"\n [editing]=\"editing\"\n [selectConfigOverrides]=\"selectConfigOverrides\"\n [metadataItems]=\"metadataItems\"\n [labels]=\"labels\"\n [configTitle]=\"configTitle\"\n [configSections]=\"configSections\"\n [configSectionsRow2]=\"configSectionsRow2\"\n [platform]=\"platform\"\n [isStepGroup]=\"isStepGroup\"\n (editDescription)=\"onEditDescription()\"\n (cancel)=\"onCancel()\"\n (saveChanges)=\"onSaveChanges($event)\"\n (metadataLinkClick)=\"onMetadataLinkClick($event)\"\n (selectSearch)=\"selectSearch.emit($event)\"\n (selectLoadMore)=\"selectLoadMore.emit($event)\"\n (selectOpened)=\"selectOpened.emit($event)\"\n (selectionChange)=\"selectionChange.emit($event)\"\n (labelAdded)=\"labelAdded.emit($event)\">\n </cqa-test-case-details>\n\n <!-- Placeholder for other tabs (Data Library, Variables) -->\n <div *ngIf=\"activeTab !== 'test-case'\" class=\"cqa-p-4 cqa-text-[#64748B] cqa-text-sm\">\n {{ activeTab === 'data-library' ? 'Data Library content' : 'Variables content' }} \u2013 coming soon\n </div>\n </div>\n </div>\n </div>\n</div>\n", styles: [".detail-side-panel-scroll{overflow-y:auto!important;overflow-x:hidden!important;min-height:0!important;-webkit-overflow-scrolling:touch}\n"], components: [{ type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: TestCaseDetailsComponent, selector: "cqa-test-case-details", inputs: ["editing", "startInEditMode", "descriptionTitle", "descriptionContent", "enableMarkdown", "showEditButton", "metadataItems", "labels", "configTitle", "configSections", "configSectionsRow2", "platform", "isStepGroup", "selectConfigOverrides"], outputs: ["editDescription", "cancel", "saveChanges", "metadataLinkClick", "selectSearch", "selectLoadMore", "selectOpened", "selectionChange", "labelAdded"] }], directives: [{ type: i5.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
34711
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DetailSidePanelComponent, decorators: [{
34963
+ TestCaseDetailsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TestCaseDetailsComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
34964
+ TestCaseDetailsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: TestCaseDetailsComponent, selector: "cqa-test-case-details", inputs: { editing: "editing", startInEditMode: "startInEditMode", descriptionTitle: "descriptionTitle", descriptionContent: "descriptionContent", enableMarkdown: "enableMarkdown", showEditButton: "showEditButton", metadataItems: "metadataItems", labels: "labels", configTitle: "configTitle", configSections: "configSections", configSectionsRow2: "configSectionsRow2", platform: "platform", isStepGroup: "isStepGroup", selectConfigOverrides: "selectConfigOverrides" }, outputs: { editDescription: "editDescription", cancel: "cancel", saveChanges: "saveChanges", metadataLinkClick: "metadataLinkClick", selectSearch: "selectSearch", selectLoadMore: "selectLoadMore", selectOpened: "selectOpened", selectionChange: "selectionChange", labelAdded: "labelAdded" }, ngImport: i0, template: "<!-- Edit mode: show edit form (Figma design) -->\n<cqa-test-case-details-edit\n *ngIf=\"isEditing\"\n [descriptionTitle]=\"descriptionTitle\"\n [descriptionContent]=\"descriptionContent\"\n [enableMarkdown]=\"enableMarkdown\"\n [metadataItems]=\"metadataItems\"\n [labels]=\"labels\"\n [configTitle]=\"configTitle\"\n [configSections]=\"configSections\"\n [configSectionsRow2]=\"configSectionsRow2\"\n [platform]=\"platform\"\n [isStepGroup]=\"isStepGroup\"\n [selectConfigOverrides]=\"selectConfigOverrides\"\n (save)=\"onSaveChanges($event)\"\n (cancel)=\"onCancelEdit()\"\n (selectSearch)=\"selectSearch.emit($event)\"\n (selectLoadMore)=\"selectLoadMore.emit($event)\"\n (selectOpened)=\"selectOpened.emit($event)\"\n (selectionChange)=\"selectionChange.emit($event)\"\n (labelAdded)=\"labelAdded.emit($event)\">\n</cqa-test-case-details-edit>\n\n<!-- View mode: read-only details -->\n<div *ngIf=\"!isEditing\" class=\"cqa-self-stretch cqa-py-4 cqa-px-0 cqa-flex cqa-flex-col cqa-justify-start cqa-items-start cqa-gap-4 cqa-text-sm cqa-leading-[19.6px]\">\n <div class=\"cqa-self-stretch cqa-flex cqa-flex-col cqa-justify-start cqa-items-start cqa-gap-4 cqa-text-sm cqa-leading-[19.6px]\">\n <!-- Description Section -->\n <div class=\"cqa-self-stretch cqa-flex cqa-flex-col cqa-justify-start cqa-items-start cqa-gap-2.5\">\n <div class=\"cqa-self-stretch cqa-inline-flex cqa-justify-between cqa-items-center\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <div class=\"cqa-w-5 cqa-h-5 cqa-p-1 cqa-flex-shrink-0 cqa-bg-[#3F43EE1A] cqa-rounded-md cqa-inline-flex cqa-justify-center cqa-items-center\">\n <mat-icon class=\"cqa-text-[#1B1FEB] cqa-text-[12px] cqa-w-3 cqa-h-3 cqa-leading-none cqa-block\">description</mat-icon>\n </div>\n <span class=\"cqa-text-[#374151] cqa-text-sm cqa-font-semibold cqa-leading-[19.6px]\">{{ descriptionTitle }}</span>\n </div>\n <button\n *ngIf=\"showEditButton\"\n type=\"button\"\n class=\"cqa-flex cqa-justify-end cqa-items-center cqa-gap-2 cqa-text-[#A3A3A3] cqa-text-xs cqa-font-semibold hover:cqa-text-[#737373] cqa-transition-colors focus:cqa-outline-none focus-visible:cqa-ring-2 focus-visible:cqa-ring-[#3F43EE] focus-visible:cqa-ring-offset-2\"\n (click)=\"onEditClick()\">\n <mat-icon class=\"cqa-text-[14px] cqa-w-4 cqa-h-4\">edit</mat-icon>\n Edit\n </button>\n </div>\n <div *ngIf=\"descriptionContent\" class=\"cqa-self-stretch cqa-flex cqa-flex-col cqa-justify-start cqa-items-start\">\n <div *ngIf=\"enableMarkdown\" class=\"cqa-self-stretch cqa-text-[#111827] cqa-text-sm cqa-leading-[19.6px] cqa-font-normal cqa-prose cqa-prose-sm cqa-max-w-none\" [innerHTML]=\"descriptionContent\"></div>\n <div *ngIf=\"!enableMarkdown\" class=\"cqa-self-stretch cqa-text-[#111827] cqa-text-sm cqa-leading-[19.6px] cqa-font-normal\">{{ descriptionContent }}</div>\n </div>\n </div>\n\n <!-- Metadata Section -->\n <div *ngIf=\"filteredMetadataItems.length\" class=\"cqa-self-stretch cqa-flex cqa-flex-col cqa-justify-start cqa-items-start cqa-gap-2.5\">\n <div class=\"cqa-self-stretch cqa-grid cqa-grid-cols-2 cqa-gap-x-0 cqa-gap-y-4\">\n <ng-container *ngFor=\"let item of filteredMetadataItems; trackBy: trackByMetadataLabel\">\n <div class=\"cqa-flex cqa-flex-col cqa-justify-start cqa-items-start cqa-gap-0.5\">\n <div class=\"cqa-text-[#6B7280] cqa-text-xs cqa-leading-[15px] cqa-font-medium\">{{ item.label }}</div>\n <div\n class=\"cqa-flex cqa-justify-start cqa-items-center cqa-gap-[5px] cqa-min-w-0 cqa-w-full cqa-text-left cqa-text-[#0A0A0A] cqa-border cqa-border-[#F5F5F5]\">\n <mat-icon *ngIf=\"item.icon && (!item.iconLibrary || item.iconLibrary === 'mat')\" class=\"cqa-text-[#6B7280] cqa-text-sm cqa-w-4 cqa-h-4\">\n {{ item.icon }}\n </mat-icon>\n <span *ngIf=\"item.statusColor\" class=\"cqa-w-3.5 cqa-h-3.5 cqa-rounded-full cqa-flex-shrink-0\" [ngClass]=\"getStatusDotClass(item)\"></span>\n <a\n *ngIf=\"item.link\"\n href=\"javascript:void(0)\"\n class=\"cqa-text-[#2563EB] cqa-text-xs cqa-leading-[12px] cqa-font-normal hover:cqa-underline cqa-cursor-pointer cqa-block cqa-truncate cqa-min-w-0\"\n (click)=\"onMetadataLinkClick(item); $event.preventDefault()\">\n {{ item.value }}\n </a>\n <span *ngIf=\"!item.link\" class=\"cqa-text-xs cqa-leading-[12px] cqa-font-normal cqa-align-middle\" [ngClass]=\"getValueTextClass(item)\">\n {{ item.value }}\n </span>\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n\n <!-- Labels (Figma: Labels title, cqa-badge chips with tag icon) -->\n <div *ngIf=\"labels.length\" class=\"cqa-self-stretch cqa-flex cqa-flex-col cqa-justify-start cqa-items-start cqa-gap-2 cqa-text-sm cqa-leading-[19.6px]\">\n <span class=\"cqa-text-[#111827] cqa-text-sm cqa-font-medium cqa-leading-5\">Labels</span>\n <div class=\"cqa-flex cqa-flex-wrap cqa-gap-2\">\n <cqa-badge\n *ngFor=\"let label of labels\"\n [label]=\"label\"\n icon=\"label\"\n variant=\"outline\"\n size=\"small\"\n backgroundColor=\"#ffffff\"\n textColor=\"#475569\"\n borderColor=\"#E2E8F0\"\n iconColor=\"#94A3B8\">\n </cqa-badge>\n </div>\n </div>\n\n <!-- Configuration Section -->\n <div *ngIf=\"configSections.length || configSectionsRow2.length\" class=\"cqa-self-stretch cqa-flex cqa-flex-col cqa-justify-start cqa-items-start cqa-gap-2.5\">\n <div class=\"cqa-self-stretch cqa-inline-flex cqa-justify-start cqa-items-center\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <div class=\"cqa-w-5 cqa-h-5 cqa-p-1 cqa-flex-shrink-0 cqa-bg-[#3F43EE1A] cqa-rounded-md cqa-inline-flex cqa-justify-center cqa-items-center\">\n <mat-icon class=\"cqa-text-[#1B1FEB] cqa-text-[12px] cqa-w-3 cqa-h-3 cqa-leading-none cqa-block\">settings</mat-icon>\n </div>\n <span class=\"cqa-text-[#374151] cqa-text-sm cqa-font-semibold cqa-leading-[19.6px]\">{{ configTitle }}</span>\n </div>\n </div>\n <div class=\"cqa-self-stretch cqa-flex cqa-flex-col cqa-justify-start cqa-items-start cqa-gap-2.5\">\n <div class=\"cqa-self-stretch cqa-grid cqa-grid-cols-1 cqa-gap-2.5\">\n <ng-container *ngFor=\"let section of configSections; trackBy: trackByConfigTitle\">\n <cqa-configuration-card\n [icon]=\"section.icon || 'tune'\"\n [title]=\"section.title\"\n [data]=\"section.items\">\n </cqa-configuration-card>\n </ng-container>\n </div>\n <div *ngIf=\"configSectionsRow2.length\" class=\"cqa-self-stretch cqa-flex cqa-flex-col cqa-gap-4 cqa-text-sm cqa-leading-[19.6px]\">\n <cqa-configuration-card\n *ngFor=\"let section of configSectionsRow2; trackBy: trackByConfigTitle\"\n [icon]=\"section.icon || 'tune'\"\n [title]=\"section.title\"\n [data]=\"section.items\">\n </cqa-configuration-card>\n </div>\n </div>\n </div>\n </div>\n</div>\n", components: [{ type: TestCaseDetailsEditComponent, selector: "cqa-test-case-details-edit", inputs: ["descriptionTitle", "descriptionContent", "enableMarkdown", "metadataItems", "labels", "configTitle", "configSections", "configSectionsRow2", "prerequisiteCaseOptions", "platform", "isStepGroup", "selectConfigOverrides"], outputs: ["save", "cancel", "selectSearch", "selectLoadMore", "selectOpened", "selectionChange", "labelAdded"] }, { type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: BadgeComponent, selector: "cqa-badge", inputs: ["type", "label", "icon", "iconLibrary", "variant", "size", "backgroundColor", "textColor", "borderColor", "iconBackgroundColor", "iconColor", "iconSize", "inlineStyles", "key", "value", "keyTextColor", "valueTextColor", "isLoading"] }, { type: ConfigurationCardComponent, selector: "cqa-configuration-card", inputs: ["icon", "title", "data"] }], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
34965
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TestCaseDetailsComponent, decorators: [{
34712
34966
  type: Component,
34713
- args: [{ selector: 'cqa-detail-side-panel', styles: [DETAIL_SIDE_PANEL_SCROLL_STYLES], changeDetection: ChangeDetectionStrategy.OnPush, host: {
34714
- class: 'cqa-ui-root cqa-flex cqa-flex-col cqa-h-full cqa-flex-shrink-0 cqa-flex-grow-0 cqa-bg-white cqa-shadow-[-4px_0_6px_-1px_rgba(0,0,0,0.05)]',
34715
- style: 'transition: width 0.3s ease-in-out',
34716
- }, template: "<div class=\"cqa-flex cqa-flex-col cqa-h-full cqa-min-w-0 cqa-bg-white\">\n <!-- Main content: Side menu + Scrollable content -->\n <div\n class=\"cqa-grid cqa-flex-1 cqa-min-h-0 cqa-min-w-0 cqa-overflow-hidden\"\n [style.grid-template-columns]=\"expanded ? 'auto 1fr' : 'auto 0fr'\"\n style=\"transition: grid-template-columns 0.3s ease-in-out\">\n <!-- Left vertical icon menu -->\n <div\n class=\"cqa-flex cqa-flex-col cqa-items-center cqa-gap-2 cqa-py-4 cqa-px-2 cqa-border-r cqa-border-[#F5F5F5] cqa-flex-shrink-0 cqa-text-[#0A0A0A]\"\n style=\"box-shadow: 1px 4px 12px 1px rgba(0, 0, 0, 0.05);\">\n <!-- Expand / Collapse button (always visible) -->\n <button\n type=\"button\"\n [matTooltip]=\"expanded ? collapseTooltip : expandTooltip\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-9 cqa-h-9 cqa-rounded-lg cqa-text-[#64748B] hover:cqa-bg-[#E2E8F0] hover:cqa-text-[#334155] cqa-transition-colors focus:cqa-outline-none focus-visible:cqa-ring-2 focus-visible:cqa-ring-[#3F43EE] focus-visible:cqa-ring-offset-2\"\n (click)=\"onExpandToggle()\">\n <mat-icon class=\"cqa-text-[20px] cqa-w-5 cqa-h-5\">{{ expanded ? 'chevron_left' : 'chevron_right' }}</mat-icon>\n </button>\n <!-- Close button -->\n <button\n *ngIf=\"showCloseButton\"\n type=\"button\"\n [matTooltip]=\"closeTooltip\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-9 cqa-h-9 cqa-rounded-lg cqa-text-[#64748B] hover:cqa-bg-[#E2E8F0] hover:cqa-text-[#334155] cqa-transition-colors focus:cqa-outline-none focus-visible:cqa-ring-2 focus-visible:cqa-ring-[#3F43EE] focus-visible:cqa-ring-offset-2\"\n (click)=\"onClose()\">\n <mat-icon class=\"cqa-text-[20px] cqa-w-5 cqa-h-5\">close</mat-icon>\n </button>\n <!-- Tab buttons (1:1 with tabs) -->\n <button\n *ngFor=\"let tab of tabs; trackBy: trackByTabValue\"\n type=\"button\"\n [matTooltip]=\"tab.label\"\n [class.cqa-bg-[#3F43EE]]=\"activeTab === tab.value\"\n [class.cqa-text-white]=\"activeTab === tab.value\"\n [class.cqa-text-[#64748B]]=\"activeTab !== tab.value\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-9 cqa-h-9 cqa-rounded-lg hover:cqa-bg-[#E2E8F0] hover:cqa-text-[#334155] cqa-transition-colors focus:cqa-outline-none focus-visible:cqa-ring-2 focus-visible:cqa-ring-[#3F43EE] focus-visible:cqa-ring-offset-2\"\n (click)=\"onTabClick(tab)\">\n <mat-icon class=\"cqa-text-[20px] cqa-w-5 cqa-h-5\">{{ tab.icon || 'circle' }}</mat-icon>\n </button>\n </div>\n\n <!-- Scrollable content area (collapses with animation when expanded is false) -->\n <div class=\"cqa-flex cqa-flex-col cqa-min-h-0 cqa-min-w-0 cqa-overflow-hidden cqa-w-full cqa-h-full\">\n <div class=\"detail-side-panel-scroll cqa-flex-1 cqa-min-h-0 cqa-min-w-0 cqa-overflow-y-auto cqa-overflow-x-hidden cqa-p-4 cqa-space-y-4\" style=\"overflow-y: auto; overflow-x: hidden; min-height: 0; -webkit-overflow-scrolling: touch;\">\n <!-- Tabs: equally distributed (Figma: purple active, gray inactive) -->\n <div class=\"cqa-flex cqa-gap-[3.5px] cqa-p-[3.5px] cqa-bg-[#F1F5F9] cqa-rounded-lg cqa-w-full\" role=\"tablist\">\n <button\n *ngFor=\"let tab of tabs; trackBy: trackByTabValue\"\n type=\"button\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === tab.value\"\n [class.cqa-bg-[#3F43EE]]=\"activeTab === tab.value\"\n [class.cqa-text-white]=\"activeTab === tab.value\"\n [class.cqa-text-[#64748B]]=\"activeTab !== tab.value\"\n class=\"cqa-flex-1 cqa-flex cqa-justify-center cqa-items-center cqa-py-2 cqa-rounded-lg cqa-text-xs cqa-font-medium cqa-transition-colors hover:cqa-opacity-90 focus:cqa-outline-none focus-visible:cqa-ring-2 focus-visible:cqa-ring-[#3F43EE] focus-visible:cqa-ring-offset-2\"\n (click)=\"onTabClick(tab)\">\n {{ tab.label }}\n </button>\n </div>\n\n <!-- Test Case tab: use cqa-test-case-details (Figma design) -->\n <cqa-test-case-details\n *ngIf=\"activeTab === 'test-case'\"\n [descriptionTitle]=\"descriptionTitle\"\n [descriptionContent]=\"descriptionContent\"\n [enableMarkdown]=\"enableMarkdown\"\n [showEditButton]=\"showEditButton\"\n [startInEditMode]=\"startInEditMode\"\n [editing]=\"editing\"\n [selectConfigOverrides]=\"selectConfigOverrides\"\n [metadataItems]=\"metadataItems\"\n [labels]=\"labels\"\n [configTitle]=\"configTitle\"\n [configSections]=\"configSections\"\n [configSectionsRow2]=\"configSectionsRow2\"\n [platform]=\"platform\"\n [isStepGroup]=\"isStepGroup\"\n (editDescription)=\"onEditDescription()\"\n (cancel)=\"onCancel()\"\n (saveChanges)=\"onSaveChanges($event)\"\n (metadataLinkClick)=\"onMetadataLinkClick($event)\"\n (selectSearch)=\"selectSearch.emit($event)\"\n (selectLoadMore)=\"selectLoadMore.emit($event)\"\n (selectOpened)=\"selectOpened.emit($event)\"\n (selectionChange)=\"selectionChange.emit($event)\"\n (labelAdded)=\"labelAdded.emit($event)\">\n </cqa-test-case-details>\n\n <!-- Placeholder for other tabs (Data Library, Variables) -->\n <div *ngIf=\"activeTab !== 'test-case'\" class=\"cqa-p-4 cqa-text-[#64748B] cqa-text-sm\">\n {{ activeTab === 'data-library' ? 'Data Library content' : 'Variables content' }} \u2013 coming soon\n </div>\n </div>\n </div>\n </div>\n</div>\n" }]
34717
- }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { tabs: [{
34967
+ args: [{ selector: 'cqa-test-case-details', changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Edit mode: show edit form (Figma design) -->\n<cqa-test-case-details-edit\n *ngIf=\"isEditing\"\n [descriptionTitle]=\"descriptionTitle\"\n [descriptionContent]=\"descriptionContent\"\n [enableMarkdown]=\"enableMarkdown\"\n [metadataItems]=\"metadataItems\"\n [labels]=\"labels\"\n [configTitle]=\"configTitle\"\n [configSections]=\"configSections\"\n [configSectionsRow2]=\"configSectionsRow2\"\n [platform]=\"platform\"\n [isStepGroup]=\"isStepGroup\"\n [selectConfigOverrides]=\"selectConfigOverrides\"\n (save)=\"onSaveChanges($event)\"\n (cancel)=\"onCancelEdit()\"\n (selectSearch)=\"selectSearch.emit($event)\"\n (selectLoadMore)=\"selectLoadMore.emit($event)\"\n (selectOpened)=\"selectOpened.emit($event)\"\n (selectionChange)=\"selectionChange.emit($event)\"\n (labelAdded)=\"labelAdded.emit($event)\">\n</cqa-test-case-details-edit>\n\n<!-- View mode: read-only details -->\n<div *ngIf=\"!isEditing\" class=\"cqa-self-stretch cqa-py-4 cqa-px-0 cqa-flex cqa-flex-col cqa-justify-start cqa-items-start cqa-gap-4 cqa-text-sm cqa-leading-[19.6px]\">\n <div class=\"cqa-self-stretch cqa-flex cqa-flex-col cqa-justify-start cqa-items-start cqa-gap-4 cqa-text-sm cqa-leading-[19.6px]\">\n <!-- Description Section -->\n <div class=\"cqa-self-stretch cqa-flex cqa-flex-col cqa-justify-start cqa-items-start cqa-gap-2.5\">\n <div class=\"cqa-self-stretch cqa-inline-flex cqa-justify-between cqa-items-center\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <div class=\"cqa-w-5 cqa-h-5 cqa-p-1 cqa-flex-shrink-0 cqa-bg-[#3F43EE1A] cqa-rounded-md cqa-inline-flex cqa-justify-center cqa-items-center\">\n <mat-icon class=\"cqa-text-[#1B1FEB] cqa-text-[12px] cqa-w-3 cqa-h-3 cqa-leading-none cqa-block\">description</mat-icon>\n </div>\n <span class=\"cqa-text-[#374151] cqa-text-sm cqa-font-semibold cqa-leading-[19.6px]\">{{ descriptionTitle }}</span>\n </div>\n <button\n *ngIf=\"showEditButton\"\n type=\"button\"\n class=\"cqa-flex cqa-justify-end cqa-items-center cqa-gap-2 cqa-text-[#A3A3A3] cqa-text-xs cqa-font-semibold hover:cqa-text-[#737373] cqa-transition-colors focus:cqa-outline-none focus-visible:cqa-ring-2 focus-visible:cqa-ring-[#3F43EE] focus-visible:cqa-ring-offset-2\"\n (click)=\"onEditClick()\">\n <mat-icon class=\"cqa-text-[14px] cqa-w-4 cqa-h-4\">edit</mat-icon>\n Edit\n </button>\n </div>\n <div *ngIf=\"descriptionContent\" class=\"cqa-self-stretch cqa-flex cqa-flex-col cqa-justify-start cqa-items-start\">\n <div *ngIf=\"enableMarkdown\" class=\"cqa-self-stretch cqa-text-[#111827] cqa-text-sm cqa-leading-[19.6px] cqa-font-normal cqa-prose cqa-prose-sm cqa-max-w-none\" [innerHTML]=\"descriptionContent\"></div>\n <div *ngIf=\"!enableMarkdown\" class=\"cqa-self-stretch cqa-text-[#111827] cqa-text-sm cqa-leading-[19.6px] cqa-font-normal\">{{ descriptionContent }}</div>\n </div>\n </div>\n\n <!-- Metadata Section -->\n <div *ngIf=\"filteredMetadataItems.length\" class=\"cqa-self-stretch cqa-flex cqa-flex-col cqa-justify-start cqa-items-start cqa-gap-2.5\">\n <div class=\"cqa-self-stretch cqa-grid cqa-grid-cols-2 cqa-gap-x-0 cqa-gap-y-4\">\n <ng-container *ngFor=\"let item of filteredMetadataItems; trackBy: trackByMetadataLabel\">\n <div class=\"cqa-flex cqa-flex-col cqa-justify-start cqa-items-start cqa-gap-0.5\">\n <div class=\"cqa-text-[#6B7280] cqa-text-xs cqa-leading-[15px] cqa-font-medium\">{{ item.label }}</div>\n <div\n class=\"cqa-flex cqa-justify-start cqa-items-center cqa-gap-[5px] cqa-min-w-0 cqa-w-full cqa-text-left cqa-text-[#0A0A0A] cqa-border cqa-border-[#F5F5F5]\">\n <mat-icon *ngIf=\"item.icon && (!item.iconLibrary || item.iconLibrary === 'mat')\" class=\"cqa-text-[#6B7280] cqa-text-sm cqa-w-4 cqa-h-4\">\n {{ item.icon }}\n </mat-icon>\n <span *ngIf=\"item.statusColor\" class=\"cqa-w-3.5 cqa-h-3.5 cqa-rounded-full cqa-flex-shrink-0\" [ngClass]=\"getStatusDotClass(item)\"></span>\n <a\n *ngIf=\"item.link\"\n href=\"javascript:void(0)\"\n class=\"cqa-text-[#2563EB] cqa-text-xs cqa-leading-[12px] cqa-font-normal hover:cqa-underline cqa-cursor-pointer cqa-block cqa-truncate cqa-min-w-0\"\n (click)=\"onMetadataLinkClick(item); $event.preventDefault()\">\n {{ item.value }}\n </a>\n <span *ngIf=\"!item.link\" class=\"cqa-text-xs cqa-leading-[12px] cqa-font-normal cqa-align-middle\" [ngClass]=\"getValueTextClass(item)\">\n {{ item.value }}\n </span>\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n\n <!-- Labels (Figma: Labels title, cqa-badge chips with tag icon) -->\n <div *ngIf=\"labels.length\" class=\"cqa-self-stretch cqa-flex cqa-flex-col cqa-justify-start cqa-items-start cqa-gap-2 cqa-text-sm cqa-leading-[19.6px]\">\n <span class=\"cqa-text-[#111827] cqa-text-sm cqa-font-medium cqa-leading-5\">Labels</span>\n <div class=\"cqa-flex cqa-flex-wrap cqa-gap-2\">\n <cqa-badge\n *ngFor=\"let label of labels\"\n [label]=\"label\"\n icon=\"label\"\n variant=\"outline\"\n size=\"small\"\n backgroundColor=\"#ffffff\"\n textColor=\"#475569\"\n borderColor=\"#E2E8F0\"\n iconColor=\"#94A3B8\">\n </cqa-badge>\n </div>\n </div>\n\n <!-- Configuration Section -->\n <div *ngIf=\"configSections.length || configSectionsRow2.length\" class=\"cqa-self-stretch cqa-flex cqa-flex-col cqa-justify-start cqa-items-start cqa-gap-2.5\">\n <div class=\"cqa-self-stretch cqa-inline-flex cqa-justify-start cqa-items-center\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <div class=\"cqa-w-5 cqa-h-5 cqa-p-1 cqa-flex-shrink-0 cqa-bg-[#3F43EE1A] cqa-rounded-md cqa-inline-flex cqa-justify-center cqa-items-center\">\n <mat-icon class=\"cqa-text-[#1B1FEB] cqa-text-[12px] cqa-w-3 cqa-h-3 cqa-leading-none cqa-block\">settings</mat-icon>\n </div>\n <span class=\"cqa-text-[#374151] cqa-text-sm cqa-font-semibold cqa-leading-[19.6px]\">{{ configTitle }}</span>\n </div>\n </div>\n <div class=\"cqa-self-stretch cqa-flex cqa-flex-col cqa-justify-start cqa-items-start cqa-gap-2.5\">\n <div class=\"cqa-self-stretch cqa-grid cqa-grid-cols-1 cqa-gap-2.5\">\n <ng-container *ngFor=\"let section of configSections; trackBy: trackByConfigTitle\">\n <cqa-configuration-card\n [icon]=\"section.icon || 'tune'\"\n [title]=\"section.title\"\n [data]=\"section.items\">\n </cqa-configuration-card>\n </ng-container>\n </div>\n <div *ngIf=\"configSectionsRow2.length\" class=\"cqa-self-stretch cqa-flex cqa-flex-col cqa-gap-4 cqa-text-sm cqa-leading-[19.6px]\">\n <cqa-configuration-card\n *ngFor=\"let section of configSectionsRow2; trackBy: trackByConfigTitle\"\n [icon]=\"section.icon || 'tune'\"\n [title]=\"section.title\"\n [data]=\"section.items\">\n </cqa-configuration-card>\n </div>\n </div>\n </div>\n </div>\n</div>\n", styles: [] }]
34968
+ }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { editing: [{
34718
34969
  type: Input
34719
- }], activeTab: [{
34970
+ }], startInEditMode: [{
34720
34971
  type: Input
34721
34972
  }], descriptionTitle: [{
34722
34973
  type: Input
@@ -34730,6 +34981,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
34730
34981
  type: Input
34731
34982
  }], labels: [{
34732
34983
  type: Input
34984
+ }], configTitle: [{
34985
+ type: Input
34733
34986
  }], configSections: [{
34734
34987
  type: Input
34735
34988
  }], configSectionsRow2: [{
@@ -34738,44 +34991,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
34738
34991
  type: Input
34739
34992
  }], isStepGroup: [{
34740
34993
  type: Input
34741
- }], configTitle: [{
34742
- type: Input
34743
- }], showCloseButton: [{
34744
- type: Input
34745
- }], startInEditMode: [{
34746
- type: Input
34747
- }], editing: [{
34748
- type: Input
34749
34994
  }], selectConfigOverrides: [{
34750
34995
  type: Input
34751
- }], expanded: [{
34752
- type: Input
34753
- }], expandedWidth: [{
34754
- type: Input
34755
- }], collapsedWidth: [{
34756
- type: Input
34757
- }], hostWidth: [{
34758
- type: HostBinding,
34759
- args: ['style.width']
34760
- }], hostMinWidth: [{
34761
- type: HostBinding,
34762
- args: ['style.min-width']
34763
- }], hostMaxWidth: [{
34764
- type: HostBinding,
34765
- args: ['style.max-width']
34766
- }], hostOverflow: [{
34767
- type: HostBinding,
34768
- args: ['style.overflow']
34769
- }], expandTooltip: [{
34770
- type: Input
34771
- }], collapseTooltip: [{
34772
- type: Input
34773
- }], closeTooltip: [{
34774
- type: Input
34775
- }], back: [{
34776
- type: Output
34777
- }], tabChange: [{
34778
- type: Output
34779
34996
  }], editDescription: [{
34780
34997
  type: Output
34781
34998
  }], cancel: [{
@@ -34794,176 +35011,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
34794
35011
  type: Output
34795
35012
  }], labelAdded: [{
34796
35013
  type: Output
34797
- }], expandToggle: [{
34798
- type: Output
34799
- }], close: [{
34800
- type: Output
34801
- }] } });
34802
-
34803
- class DetailDrawerTabContentDirective {
34804
- constructor(templateRef) {
34805
- this.templateRef = templateRef;
34806
- }
34807
- }
34808
- DetailDrawerTabContentDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DetailDrawerTabContentDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
34809
- DetailDrawerTabContentDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.4.0", type: DetailDrawerTabContentDirective, selector: "[cqaTabContent]", ngImport: i0 });
34810
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DetailDrawerTabContentDirective, decorators: [{
34811
- type: Directive,
34812
- args: [{
34813
- selector: '[cqaTabContent]',
34814
- }]
34815
- }], ctorParameters: function () { return [{ type: i0.TemplateRef }]; } });
34816
-
34817
- class DetailDrawerTabComponent {
34818
- constructor() {
34819
- /** Tab label (shown in tooltip on icon button) */
34820
- this.label = '';
34821
- /** Tab value (unique identifier) */
34822
- this.value = '';
34823
- /** Material icon name for the tab button */
34824
- this.icon = 'folder';
34825
- }
34826
- get contentTemplate() {
34827
- var _a, _b;
34828
- return (_b = (_a = this.contentDirective) === null || _a === void 0 ? void 0 : _a.templateRef) !== null && _b !== void 0 ? _b : null;
34829
- }
34830
- }
34831
- DetailDrawerTabComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DetailDrawerTabComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
34832
- DetailDrawerTabComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: DetailDrawerTabComponent, selector: "cqa-detail-drawer-tab", inputs: { label: "label", value: "value", icon: "icon" }, host: { styleAttribute: "display: contents" }, queries: [{ propertyName: "contentDirective", first: true, predicate: DetailDrawerTabContentDirective, descendants: true }], ngImport: i0, template: '', isInline: true });
34833
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DetailDrawerTabComponent, decorators: [{
34834
- type: Component,
34835
- args: [{
34836
- selector: 'cqa-detail-drawer-tab',
34837
- template: '',
34838
- host: {
34839
- style: 'display: contents',
34840
- },
34841
- }]
34842
- }], propDecorators: { label: [{
34843
- type: Input
34844
- }], value: [{
34845
- type: Input
34846
- }], icon: [{
34847
- type: Input
34848
- }], contentDirective: [{
34849
- type: ContentChild,
34850
- args: [DetailDrawerTabContentDirective]
34851
- }] } });
34852
-
34853
- class DetailDrawerComponent {
34854
- constructor() {
34855
- /** Currently active tab value */
34856
- this.activeTab = '';
34857
- /** Whether to show the close button */
34858
- this.showCloseButton = true;
34859
- /** Whether the drawer is expanded */
34860
- this.expanded = true;
34861
- /** Panel width when expanded */
34862
- this.expandedWidth = '280px';
34863
- /** Maximum width when expanded (e.g. '600px', '30vw'). Default: 30% of viewport */
34864
- this.maxExpandedWidth = '30vw';
34865
- /** Panel width when collapsed */
34866
- this.collapsedWidth = '56px';
34867
- this.expandTooltip = 'Expand';
34868
- this.collapseTooltip = 'Collapse';
34869
- this.closeTooltip = 'Close';
34870
- this.activeTabChange = new EventEmitter();
34871
- this.expandToggle = new EventEmitter();
34872
- this.close = new EventEmitter();
34873
- }
34874
- get hostWidth() {
34875
- return this.expanded ? this.expandedWidth : this.collapsedWidth;
34876
- }
34877
- get hostMinWidth() {
34878
- return this.expanded && this.minExpandedWidth ? this.minExpandedWidth : null;
34879
- }
34880
- get hostMaxWidth() {
34881
- return this.expanded ? this.maxExpandedWidth : null;
34882
- }
34883
- ngAfterContentInit() {
34884
- this.ensureActiveTab();
34885
- }
34886
- ngAfterContentChecked() {
34887
- this.ensureActiveTab();
34888
- }
34889
- ensureActiveTab() {
34890
- var _a, _b;
34891
- const tabs = (_b = (_a = this.tabComponents) === null || _a === void 0 ? void 0 : _a.toArray()) !== null && _b !== void 0 ? _b : [];
34892
- if (tabs.length > 0 && !this.activeTab) {
34893
- this.activeTab = tabs[0].value;
34894
- this.activeTabChange.emit(this.activeTab);
34895
- }
34896
- }
34897
- onTabClick(tab) {
34898
- // If drawer is collapsed, open it (but never close on tab click)
34899
- if (!this.expanded) {
34900
- this.expandToggle.emit();
34901
- }
34902
- // Select the tab
34903
- if (tab.value !== this.activeTab) {
34904
- this.activeTab = tab.value;
34905
- this.activeTabChange.emit(this.activeTab);
34906
- }
34907
- }
34908
- onExpandToggle() {
34909
- this.expandToggle.emit();
34910
- }
34911
- onClose() {
34912
- this.close.emit();
34913
- }
34914
- trackByValue(_i, tab) {
34915
- return tab.value;
34916
- }
34917
- isTabActive(tab) {
34918
- return tab.value === this.activeTab;
34919
- }
34920
- }
34921
- DetailDrawerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DetailDrawerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
34922
- DetailDrawerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: DetailDrawerComponent, selector: "cqa-detail-drawer", inputs: { activeTab: "activeTab", showCloseButton: "showCloseButton", expanded: "expanded", expandedWidth: "expandedWidth", minExpandedWidth: "minExpandedWidth", maxExpandedWidth: "maxExpandedWidth", collapsedWidth: "collapsedWidth", expandTooltip: "expandTooltip", collapseTooltip: "collapseTooltip", closeTooltip: "closeTooltip" }, outputs: { activeTabChange: "activeTabChange", expandToggle: "expandToggle", close: "close" }, host: { properties: { "style.width": "this.hostWidth", "style.min-width": "this.hostMinWidth", "style.max-width": "this.hostMaxWidth" }, styleAttribute: "transition: width 0.3s ease-in-out", classAttribute: "cqa-ui-root cqa-flex cqa-flex-col cqa-h-full cqa-bg-white cqa-shadow-[-4px_0_6px_-1px_rgba(0,0,0,0.05)]" }, queries: [{ propertyName: "tabComponents", predicate: DetailDrawerTabComponent }], ngImport: i0, template: "<div class=\"cqa-flex cqa-flex-col cqa-h-full cqa-bg-white\">\n <div\n class=\"cqa-grid cqa-flex-1 cqa-min-h-0 cqa-overflow-hidden\"\n [style.grid-template-columns]=\"expanded ? 'auto 1fr' : 'auto 0fr'\"\n style=\"transition: grid-template-columns 0.3s ease-in-out\">\n <!-- Left vertical icon bar: one button per tab -->\n <div class=\"cqa-flex cqa-flex-col cqa-flex-1 cqa-min-h-0 cqa-items-center cqa-py-4 cqa-px-2 cqa-border-r cqa-border-[#E2E8F0] cqa-bg-[#FAFAFA] cqa-flex-shrink-0\">\n <!-- Expand / Collapse button (always visible) -->\n <button\n type=\"button\"\n [matTooltip]=\"expanded ? collapseTooltip : expandTooltip\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-9 cqa-h-9 cqa-rounded-lg cqa-text-[#64748B] hover:cqa-bg-[#E2E8F0] hover:cqa-text-[#334155] cqa-transition-colors focus:cqa-outline-none focus-visible:cqa-ring-2 focus-visible:cqa-ring-[#3F43EE] focus-visible:cqa-ring-offset-2 cqa-flex-shrink-0\"\n (click)=\"onExpandToggle()\">\n <mat-icon class=\"cqa-text-[20px] cqa-w-5 cqa-h-5\">{{ expanded ? 'unfold_less' : 'unfold_more' }}</mat-icon>\n </button>\n <!-- Close button -->\n <button\n *ngIf=\"showCloseButton\"\n type=\"button\"\n [matTooltip]=\"closeTooltip\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-9 cqa-h-9 cqa-rounded-lg cqa-text-[#64748B] hover:cqa-bg-[#E2E8F0] hover:cqa-text-[#334155] cqa-transition-colors focus:cqa-outline-none focus-visible:cqa-ring-2 focus-visible:cqa-ring-[#3F43EE] focus-visible:cqa-ring-offset-2 cqa-flex-shrink-0\"\n (click)=\"onClose()\">\n <mat-icon class=\"cqa-text-[20px] cqa-w-5 cqa-h-5\">close</mat-icon>\n </button>\n <!-- Tab buttons: equally distributed in remaining space -->\n <div class=\"cqa-flex cqa-flex-1 cqa-flex-col cqa-justify-evenly cqa-items-center cqa-w-full\">\n <button\n *ngFor=\"let tab of tabComponents; trackBy: trackByValue\"\n type=\"button\"\n role=\"tab\"\n [attr.aria-selected]=\"isTabActive(tab)\"\n [matTooltip]=\"tab.label\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-9 cqa-h-9 cqa-rounded-lg cqa-transition-colors focus:cqa-outline-none focus-visible:cqa-ring-2 focus-visible:cqa-ring-[#3F43EE] focus-visible:cqa-ring-offset-2 cqa-flex-shrink-0\"\n [ngClass]=\"{\n 'cqa-bg-[#3F43EE] cqa-text-white': isTabActive(tab),\n 'cqa-text-[#64748B] hover:cqa-bg-[#E2E8F0] hover:cqa-text-[#334155]': !isTabActive(tab)\n }\"\n (click)=\"onTabClick(tab)\">\n <mat-icon class=\"cqa-text-[20px] cqa-w-5 cqa-h-5\">{{ tab.icon }}</mat-icon>\n </button>\n </div>\n </div>\n\n <!-- Content area: show only the active tab's content -->\n <div class=\"cqa-min-w-0 cqa-overflow-hidden\">\n <div class=\"cqa-h-full cqa-overflow-y-auto cqa-p-4\">\n <ng-container *ngFor=\"let tab of tabComponents\">\n <ng-container *ngIf=\"tab.value === activeTab && tab.contentTemplate\" [ngTemplateOutlet]=\"tab.contentTemplate\"></ng-container>\n </ng-container>\n </div>\n </div>\n </div>\n</div>\n", components: [{ type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], directives: [{ type: i5.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
34923
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DetailDrawerComponent, decorators: [{
34924
- type: Component,
34925
- args: [{ selector: 'cqa-detail-drawer', changeDetection: ChangeDetectionStrategy.OnPush, host: {
34926
- class: 'cqa-ui-root cqa-flex cqa-flex-col cqa-h-full cqa-bg-white cqa-shadow-[-4px_0_6px_-1px_rgba(0,0,0,0.05)]',
34927
- style: 'transition: width 0.3s ease-in-out',
34928
- }, template: "<div class=\"cqa-flex cqa-flex-col cqa-h-full cqa-bg-white\">\n <div\n class=\"cqa-grid cqa-flex-1 cqa-min-h-0 cqa-overflow-hidden\"\n [style.grid-template-columns]=\"expanded ? 'auto 1fr' : 'auto 0fr'\"\n style=\"transition: grid-template-columns 0.3s ease-in-out\">\n <!-- Left vertical icon bar: one button per tab -->\n <div class=\"cqa-flex cqa-flex-col cqa-flex-1 cqa-min-h-0 cqa-items-center cqa-py-4 cqa-px-2 cqa-border-r cqa-border-[#E2E8F0] cqa-bg-[#FAFAFA] cqa-flex-shrink-0\">\n <!-- Expand / Collapse button (always visible) -->\n <button\n type=\"button\"\n [matTooltip]=\"expanded ? collapseTooltip : expandTooltip\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-9 cqa-h-9 cqa-rounded-lg cqa-text-[#64748B] hover:cqa-bg-[#E2E8F0] hover:cqa-text-[#334155] cqa-transition-colors focus:cqa-outline-none focus-visible:cqa-ring-2 focus-visible:cqa-ring-[#3F43EE] focus-visible:cqa-ring-offset-2 cqa-flex-shrink-0\"\n (click)=\"onExpandToggle()\">\n <mat-icon class=\"cqa-text-[20px] cqa-w-5 cqa-h-5\">{{ expanded ? 'unfold_less' : 'unfold_more' }}</mat-icon>\n </button>\n <!-- Close button -->\n <button\n *ngIf=\"showCloseButton\"\n type=\"button\"\n [matTooltip]=\"closeTooltip\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-9 cqa-h-9 cqa-rounded-lg cqa-text-[#64748B] hover:cqa-bg-[#E2E8F0] hover:cqa-text-[#334155] cqa-transition-colors focus:cqa-outline-none focus-visible:cqa-ring-2 focus-visible:cqa-ring-[#3F43EE] focus-visible:cqa-ring-offset-2 cqa-flex-shrink-0\"\n (click)=\"onClose()\">\n <mat-icon class=\"cqa-text-[20px] cqa-w-5 cqa-h-5\">close</mat-icon>\n </button>\n <!-- Tab buttons: equally distributed in remaining space -->\n <div class=\"cqa-flex cqa-flex-1 cqa-flex-col cqa-justify-evenly cqa-items-center cqa-w-full\">\n <button\n *ngFor=\"let tab of tabComponents; trackBy: trackByValue\"\n type=\"button\"\n role=\"tab\"\n [attr.aria-selected]=\"isTabActive(tab)\"\n [matTooltip]=\"tab.label\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-9 cqa-h-9 cqa-rounded-lg cqa-transition-colors focus:cqa-outline-none focus-visible:cqa-ring-2 focus-visible:cqa-ring-[#3F43EE] focus-visible:cqa-ring-offset-2 cqa-flex-shrink-0\"\n [ngClass]=\"{\n 'cqa-bg-[#3F43EE] cqa-text-white': isTabActive(tab),\n 'cqa-text-[#64748B] hover:cqa-bg-[#E2E8F0] hover:cqa-text-[#334155]': !isTabActive(tab)\n }\"\n (click)=\"onTabClick(tab)\">\n <mat-icon class=\"cqa-text-[20px] cqa-w-5 cqa-h-5\">{{ tab.icon }}</mat-icon>\n </button>\n </div>\n </div>\n\n <!-- Content area: show only the active tab's content -->\n <div class=\"cqa-min-w-0 cqa-overflow-hidden\">\n <div class=\"cqa-h-full cqa-overflow-y-auto cqa-p-4\">\n <ng-container *ngFor=\"let tab of tabComponents\">\n <ng-container *ngIf=\"tab.value === activeTab && tab.contentTemplate\" [ngTemplateOutlet]=\"tab.contentTemplate\"></ng-container>\n </ng-container>\n </div>\n </div>\n </div>\n</div>\n", styles: [] }]
34929
- }], propDecorators: { tabComponents: [{
34930
- type: ContentChildren,
34931
- args: [DetailDrawerTabComponent]
34932
- }], activeTab: [{
34933
- type: Input
34934
- }], showCloseButton: [{
34935
- type: Input
34936
- }], expanded: [{
34937
- type: Input
34938
- }], expandedWidth: [{
34939
- type: Input
34940
- }], minExpandedWidth: [{
34941
- type: Input
34942
- }], maxExpandedWidth: [{
34943
- type: Input
34944
- }], collapsedWidth: [{
34945
- type: Input
34946
- }], hostWidth: [{
34947
- type: HostBinding,
34948
- args: ['style.width']
34949
- }], hostMinWidth: [{
34950
- type: HostBinding,
34951
- args: ['style.min-width']
34952
- }], hostMaxWidth: [{
34953
- type: HostBinding,
34954
- args: ['style.max-width']
34955
- }], expandTooltip: [{
34956
- type: Input
34957
- }], collapseTooltip: [{
34958
- type: Input
34959
- }], closeTooltip: [{
34960
- type: Input
34961
- }], activeTabChange: [{
34962
- type: Output
34963
- }], expandToggle: [{
34964
- type: Output
34965
- }], close: [{
34966
- type: Output
34967
35014
  }] } });
34968
35015
 
34969
35016
  class StepBuilderGroupComponent {