@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.
- package/esm2020/lib/detail-side-panel/detail-side-panel.component.mjs +9 -127
- package/esm2020/lib/step-builder/advanced-variables-form/advanced-variables-form.component.mjs +3 -3
- package/esm2020/lib/step-builder/template-variables-form/template-variables-form.component.mjs +310 -146
- package/fesm2015/cqa-lib-cqa-ui.mjs +718 -671
- package/fesm2015/cqa-lib-cqa-ui.mjs.map +1 -1
- package/fesm2020/cqa-lib-cqa-ui.mjs +715 -668
- package/fesm2020/cqa-lib-cqa-ui.mjs.map +1 -1
- package/lib/detail-side-panel/detail-side-panel.component.d.ts +4 -62
- package/lib/step-builder/template-variables-form/template-variables-form.component.d.ts +1 -0
- package/package.json +1 -1
- package/styles.css +1 -1
|
@@ -25345,10 +25345,10 @@ class AdvancedVariablesFormComponent {
|
|
|
25345
25345
|
}
|
|
25346
25346
|
}
|
|
25347
25347
|
AdvancedVariablesFormComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: AdvancedVariablesFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
25348
|
-
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 });
|
|
25348
|
+
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 });
|
|
25349
25349
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: AdvancedVariablesFormComponent, decorators: [{
|
|
25350
25350
|
type: Component,
|
|
25351
|
-
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: [] }]
|
|
25351
|
+
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: [] }]
|
|
25352
25352
|
}], propDecorators: { advancedVariables: [{
|
|
25353
25353
|
type: Input
|
|
25354
25354
|
}], advancedVariableForm: [{
|
|
@@ -27442,15 +27442,18 @@ class TemplateVariablesFormComponent {
|
|
|
27442
27442
|
if (this.isElementType(variable) && variable.screenNameId) {
|
|
27443
27443
|
const variableGroup = this.getVariableFormGroup(variable.name);
|
|
27444
27444
|
if (variableGroup) {
|
|
27445
|
-
// Initialize screen name form control with screenNameId (
|
|
27445
|
+
// Initialize screen name form control with screenNameId as string (to match option id format), or 'none' by default
|
|
27446
27446
|
if (!variableGroup.get('selectedScreenName')) {
|
|
27447
|
-
|
|
27447
|
+
const initialValue = variable.screenNameId ? String(variable.screenNameId) : 'none';
|
|
27448
|
+
variableGroup.addControl('selectedScreenName', new FormControl(initialValue));
|
|
27448
27449
|
}
|
|
27449
27450
|
else {
|
|
27450
27451
|
// Update form control value if it doesn't match
|
|
27451
27452
|
const currentValue = variableGroup.get('selectedScreenName')?.value;
|
|
27452
|
-
|
|
27453
|
-
|
|
27453
|
+
const expectedValue = variable.screenNameId ? String(variable.screenNameId) : 'none';
|
|
27454
|
+
const currentValueStr = currentValue != null ? String(currentValue) : null;
|
|
27455
|
+
if (currentValueStr !== expectedValue && currentValue !== variable.screenNameId) {
|
|
27456
|
+
variableGroup.get('selectedScreenName')?.setValue(expectedValue, { emitEvent: false });
|
|
27454
27457
|
}
|
|
27455
27458
|
}
|
|
27456
27459
|
// If we have screenNameId but not selectedScreenName, find it from screenNameOptions
|
|
@@ -27484,67 +27487,105 @@ class TemplateVariablesFormComponent {
|
|
|
27484
27487
|
if (this.isElementType(variable)) {
|
|
27485
27488
|
const variableGroup = this.getVariableFormGroup(variable.name);
|
|
27486
27489
|
if (variableGroup) {
|
|
27487
|
-
|
|
27488
|
-
//
|
|
27490
|
+
// Only try to find and set element if elementId exists in template data
|
|
27491
|
+
// If no elementId, don't select anything - use default values
|
|
27489
27492
|
if (variable.elementId) {
|
|
27493
|
+
let element = null;
|
|
27494
|
+
// Priority 1: Find by elementId (from setTemplateVariables)
|
|
27490
27495
|
element = this.elementOptions.find(el => el.id === variable.elementId);
|
|
27491
|
-
|
|
27492
|
-
|
|
27493
|
-
|
|
27494
|
-
|
|
27495
|
-
|
|
27496
|
-
|
|
27497
|
-
|
|
27498
|
-
|
|
27499
|
-
|
|
27500
|
-
|
|
27501
|
-
|
|
27502
|
-
|
|
27503
|
-
|
|
27504
|
-
|
|
27505
|
-
|
|
27506
|
-
|
|
27507
|
-
|
|
27508
|
-
|
|
27509
|
-
|
|
27496
|
+
// Priority 2: Find by elementName if elementId search didn't find it (fallback)
|
|
27497
|
+
if (!element && variable.elementName) {
|
|
27498
|
+
element = this.elementOptions.find(el => el.name === variable.elementName);
|
|
27499
|
+
}
|
|
27500
|
+
// Priority 3: Find by locatorValue (for backward compatibility)
|
|
27501
|
+
if (!element && variable.value) {
|
|
27502
|
+
const elementValue = variable.value;
|
|
27503
|
+
element = this.elementOptions.find(el => el.locatorValue === elementValue);
|
|
27504
|
+
}
|
|
27505
|
+
if (element) {
|
|
27506
|
+
// Set screen name info from the found element
|
|
27507
|
+
if (element.screenNameId && element.screenNameObj) {
|
|
27508
|
+
variable.selectedScreenName = element.screenNameObj.name;
|
|
27509
|
+
variable.screenNameId = element.screenNameId;
|
|
27510
|
+
// Set form controls
|
|
27511
|
+
// Store screenNameId as string to match option id format (for consistency with getScreenNameSelectConfig)
|
|
27512
|
+
const screenNameIdString = String(element.screenNameId);
|
|
27513
|
+
if (!variableGroup.get('selectedScreenName')) {
|
|
27514
|
+
variableGroup.addControl('selectedScreenName', new FormControl(screenNameIdString));
|
|
27515
|
+
}
|
|
27516
|
+
else {
|
|
27517
|
+
// Only update if form control doesn't already have a valid screen name selected
|
|
27518
|
+
// This prevents resetting user's selection when elementOptions changes
|
|
27519
|
+
const currentValue = variableGroup.get('selectedScreenName')?.value;
|
|
27520
|
+
const currentValueStr = currentValue != null ? String(currentValue) : null;
|
|
27521
|
+
if (currentValueStr !== screenNameIdString && currentValueStr !== 'none') {
|
|
27522
|
+
variableGroup.get('selectedScreenName')?.setValue(screenNameIdString, { emitEvent: false });
|
|
27523
|
+
}
|
|
27524
|
+
}
|
|
27525
|
+
}
|
|
27526
|
+
// Set/update element details from the found element
|
|
27527
|
+
variable.elementId = element.id;
|
|
27528
|
+
variable.elementLocator = element.locatorValue || '';
|
|
27529
|
+
// Only update elementName if it wasn't already set (preserve from setTemplateVariables)
|
|
27530
|
+
if (!variable.elementName) {
|
|
27531
|
+
variable.elementName = element.name || '';
|
|
27532
|
+
}
|
|
27533
|
+
// For selector, use elementLocator as value; for others, use elementName
|
|
27534
|
+
if (variable.name === 'selector') {
|
|
27535
|
+
variable.value = element.locatorValue || element.name || '';
|
|
27536
|
+
}
|
|
27537
|
+
else if (!variable.value || variable.value === '') {
|
|
27538
|
+
variable.value = element.name || element.locatorValue || '';
|
|
27539
|
+
}
|
|
27540
|
+
// Set element ID form control for the dropdown (key is 'id' in config)
|
|
27541
|
+
if (!variableGroup.get('id')) {
|
|
27542
|
+
variableGroup.addControl('id', new FormControl(element.id));
|
|
27510
27543
|
}
|
|
27511
27544
|
else {
|
|
27512
|
-
variableGroup.get('
|
|
27545
|
+
variableGroup.get('id')?.setValue(element.id, { emitEvent: false });
|
|
27546
|
+
}
|
|
27547
|
+
// Update value form control
|
|
27548
|
+
if (variableGroup.get('value')) {
|
|
27549
|
+
variableGroup.get('value')?.setValue(variable.value, { emitEvent: false });
|
|
27513
27550
|
}
|
|
27514
27551
|
}
|
|
27515
|
-
|
|
27516
|
-
|
|
27517
|
-
|
|
27518
|
-
|
|
27519
|
-
|
|
27520
|
-
|
|
27521
|
-
}
|
|
27522
|
-
// For selector, use elementLocator as value; for others, use elementName
|
|
27523
|
-
if (variable.name === 'selector') {
|
|
27524
|
-
variable.value = element.locatorValue || element.name || '';
|
|
27552
|
+
else {
|
|
27553
|
+
// Element not found in elementOptions yet - might need to fetch
|
|
27554
|
+
// Keep elementId and elementName if they exist (from setTemplateVariables)
|
|
27555
|
+
// If we have elementId but element isn't found, we might need to fetch elements
|
|
27556
|
+
// However, we don't know the screen name yet, so we'll wait for elementOptions to be loaded
|
|
27557
|
+
// The initialization will run again when elementOptions changes via ngOnChanges
|
|
27525
27558
|
}
|
|
27526
|
-
|
|
27527
|
-
|
|
27559
|
+
}
|
|
27560
|
+
else {
|
|
27561
|
+
// No elementId in template data - clear all element-related fields and set defaults
|
|
27562
|
+
// But don't override user's screen name selection if they've already selected one
|
|
27563
|
+
variable.elementId = undefined;
|
|
27564
|
+
variable.elementLocator = undefined;
|
|
27565
|
+
variable.elementName = undefined;
|
|
27566
|
+
// Only clear screenNameId if it wasn't set by user selection
|
|
27567
|
+
// Check if form control has a valid screen name (not 'none')
|
|
27568
|
+
const currentScreenNameValue = variableGroup.get('selectedScreenName')?.value;
|
|
27569
|
+
if (!currentScreenNameValue || currentScreenNameValue === 'none' || currentScreenNameValue === null) {
|
|
27570
|
+
variable.screenNameId = undefined;
|
|
27571
|
+
variable.selectedScreenName = undefined;
|
|
27572
|
+
// Set form controls to default values
|
|
27573
|
+
// Screen name should be 'none' (Select option)
|
|
27574
|
+
if (!variableGroup.get('selectedScreenName')) {
|
|
27575
|
+
variableGroup.addControl('selectedScreenName', new FormControl('none'));
|
|
27576
|
+
}
|
|
27577
|
+
else {
|
|
27578
|
+
variableGroup.get('selectedScreenName')?.setValue('none', { emitEvent: false });
|
|
27579
|
+
}
|
|
27528
27580
|
}
|
|
27529
|
-
//
|
|
27581
|
+
// Element ID should be null
|
|
27530
27582
|
if (!variableGroup.get('id')) {
|
|
27531
|
-
variableGroup.addControl('id', new FormControl(
|
|
27583
|
+
variableGroup.addControl('id', new FormControl(null));
|
|
27532
27584
|
}
|
|
27533
27585
|
else {
|
|
27534
|
-
variableGroup.get('id')?.setValue(
|
|
27535
|
-
}
|
|
27536
|
-
// Update value form control
|
|
27537
|
-
if (variableGroup.get('value')) {
|
|
27538
|
-
variableGroup.get('value')?.setValue(variable.value, { emitEvent: false });
|
|
27586
|
+
variableGroup.get('id')?.setValue(null, { emitEvent: false });
|
|
27539
27587
|
}
|
|
27540
27588
|
}
|
|
27541
|
-
else {
|
|
27542
|
-
// Element not found in elementOptions yet - might need to fetch
|
|
27543
|
-
// Keep elementId and elementName if they exist (from setTemplateVariables)
|
|
27544
|
-
// If we have elementId but element isn't found, we might need to fetch elements
|
|
27545
|
-
// However, we don't know the screen name yet, so we'll wait for elementOptions to be loaded
|
|
27546
|
-
// The initialization will run again when elementOptions changes via ngOnChanges
|
|
27547
|
-
}
|
|
27548
27589
|
}
|
|
27549
27590
|
}
|
|
27550
27591
|
});
|
|
@@ -27761,66 +27802,104 @@ class TemplateVariablesFormComponent {
|
|
|
27761
27802
|
}
|
|
27762
27803
|
// For element type, parse the value to extract screen name and element
|
|
27763
27804
|
if (this.isElementType(variable)) {
|
|
27764
|
-
|
|
27765
|
-
//
|
|
27805
|
+
// Only try to find and set element if elementId exists in template data
|
|
27806
|
+
// If no elementId, don't select anything - use default values
|
|
27766
27807
|
if (variable.elementId) {
|
|
27808
|
+
let element = null;
|
|
27809
|
+
// Priority 1: Find by elementId (from setTemplateVariables)
|
|
27767
27810
|
element = this.elementOptions.find(el => el.id === variable.elementId);
|
|
27768
|
-
|
|
27769
|
-
|
|
27770
|
-
|
|
27771
|
-
|
|
27772
|
-
|
|
27773
|
-
|
|
27774
|
-
|
|
27775
|
-
|
|
27776
|
-
|
|
27777
|
-
|
|
27778
|
-
|
|
27779
|
-
|
|
27780
|
-
|
|
27781
|
-
|
|
27782
|
-
|
|
27783
|
-
|
|
27784
|
-
|
|
27785
|
-
|
|
27786
|
-
|
|
27811
|
+
// Priority 2: Find by elementName if elementId search didn't find it (fallback)
|
|
27812
|
+
if (!element && variable.elementName) {
|
|
27813
|
+
element = this.elementOptions.find(el => el.name === variable.elementName);
|
|
27814
|
+
}
|
|
27815
|
+
// Priority 3: Find by locatorValue (for backward compatibility)
|
|
27816
|
+
if (!element && variable.value) {
|
|
27817
|
+
const elementValue = variable.value;
|
|
27818
|
+
element = this.elementOptions.find(el => el.locatorValue === elementValue);
|
|
27819
|
+
}
|
|
27820
|
+
if (element) {
|
|
27821
|
+
// Set screen name info from the found element
|
|
27822
|
+
if (element.screenNameId && element.screenNameObj) {
|
|
27823
|
+
variable.selectedScreenName = element.screenNameObj.name;
|
|
27824
|
+
variable.screenNameId = element.screenNameId;
|
|
27825
|
+
// Set form controls
|
|
27826
|
+
// Store screenNameId as string to match option id format (for consistency with getScreenNameSelectConfig)
|
|
27827
|
+
const screenNameIdString = String(element.screenNameId);
|
|
27828
|
+
if (!variableGroup.get('selectedScreenName')) {
|
|
27829
|
+
variableGroup.addControl('selectedScreenName', new FormControl(screenNameIdString));
|
|
27830
|
+
}
|
|
27831
|
+
else {
|
|
27832
|
+
// Only update if form control doesn't already have a valid screen name selected
|
|
27833
|
+
// This prevents resetting user's selection when elementOptions changes
|
|
27834
|
+
const currentValue = variableGroup.get('selectedScreenName')?.value;
|
|
27835
|
+
const currentValueStr = currentValue != null ? String(currentValue) : null;
|
|
27836
|
+
if (currentValueStr !== screenNameIdString && currentValueStr !== 'none') {
|
|
27837
|
+
variableGroup.get('selectedScreenName')?.setValue(screenNameIdString, { emitEvent: false });
|
|
27838
|
+
}
|
|
27839
|
+
}
|
|
27840
|
+
}
|
|
27841
|
+
// Set/update element details from the found element
|
|
27842
|
+
variable.elementId = element.id;
|
|
27843
|
+
variable.elementLocator = element.locatorValue || '';
|
|
27844
|
+
// Only update elementName if it wasn't already set (preserve from setTemplateVariables)
|
|
27845
|
+
if (!variable.elementName) {
|
|
27846
|
+
variable.elementName = element.name || '';
|
|
27847
|
+
}
|
|
27848
|
+
// For selector, use elementLocator as value; for others, use elementName
|
|
27849
|
+
if (variable.name === 'selector') {
|
|
27850
|
+
variable.value = element.locatorValue || element.name || '';
|
|
27851
|
+
}
|
|
27852
|
+
else if (!variable.value || variable.value === '') {
|
|
27853
|
+
variable.value = element.name || element.locatorValue || '';
|
|
27854
|
+
}
|
|
27855
|
+
// Set element ID form control for the dropdown (key is 'id' in config)
|
|
27856
|
+
if (!variableGroup.get('id')) {
|
|
27857
|
+
variableGroup.addControl('id', new FormControl(element.id));
|
|
27787
27858
|
}
|
|
27788
27859
|
else {
|
|
27789
|
-
variableGroup.get('
|
|
27860
|
+
variableGroup.get('id')?.setValue(element.id, { emitEvent: false });
|
|
27861
|
+
}
|
|
27862
|
+
// Update value form control
|
|
27863
|
+
if (variableGroup.get('value')) {
|
|
27864
|
+
variableGroup.get('value')?.setValue(variable.value, { emitEvent: false });
|
|
27790
27865
|
}
|
|
27791
27866
|
}
|
|
27792
|
-
|
|
27793
|
-
|
|
27794
|
-
|
|
27795
|
-
|
|
27796
|
-
|
|
27797
|
-
|
|
27798
|
-
}
|
|
27799
|
-
// For selector, use elementLocator as value; for others, use elementName
|
|
27800
|
-
if (variable.name === 'selector') {
|
|
27801
|
-
variable.value = element.locatorValue || element.name || '';
|
|
27867
|
+
else {
|
|
27868
|
+
// Element not found in elementOptions yet - might need to fetch
|
|
27869
|
+
// Keep elementId and elementName if they exist (from setTemplateVariables)
|
|
27870
|
+
// If we have elementId but element isn't found, we might need to fetch elements
|
|
27871
|
+
// However, we don't know the screen name yet, so we'll wait for elementOptions to be loaded
|
|
27872
|
+
// The initialization will run again when elementOptions changes via ngOnChanges
|
|
27802
27873
|
}
|
|
27803
|
-
|
|
27804
|
-
|
|
27874
|
+
}
|
|
27875
|
+
else {
|
|
27876
|
+
// No elementId in template data - clear all element-related fields and set defaults
|
|
27877
|
+
// But don't override user's screen name selection if they've already selected one
|
|
27878
|
+
variable.elementId = undefined;
|
|
27879
|
+
variable.elementLocator = undefined;
|
|
27880
|
+
variable.elementName = undefined;
|
|
27881
|
+
// Only clear screenNameId if it wasn't set by user selection
|
|
27882
|
+
// Check if form control has a valid screen name (not 'none')
|
|
27883
|
+
const currentScreenNameValue = variableGroup.get('selectedScreenName')?.value;
|
|
27884
|
+
if (!currentScreenNameValue || currentScreenNameValue === 'none' || currentScreenNameValue === null) {
|
|
27885
|
+
variable.screenNameId = undefined;
|
|
27886
|
+
variable.selectedScreenName = undefined;
|
|
27887
|
+
// Set form controls to default values
|
|
27888
|
+
// Screen name should be 'none' (Select option)
|
|
27889
|
+
if (!variableGroup.get('selectedScreenName')) {
|
|
27890
|
+
variableGroup.addControl('selectedScreenName', new FormControl('none'));
|
|
27891
|
+
}
|
|
27892
|
+
else {
|
|
27893
|
+
variableGroup.get('selectedScreenName')?.setValue('none', { emitEvent: false });
|
|
27894
|
+
}
|
|
27805
27895
|
}
|
|
27806
|
-
//
|
|
27896
|
+
// Element ID should be null
|
|
27807
27897
|
if (!variableGroup.get('id')) {
|
|
27808
|
-
variableGroup.addControl('id', new FormControl(
|
|
27898
|
+
variableGroup.addControl('id', new FormControl(null));
|
|
27809
27899
|
}
|
|
27810
27900
|
else {
|
|
27811
|
-
variableGroup.get('id')?.setValue(
|
|
27901
|
+
variableGroup.get('id')?.setValue(null, { emitEvent: false });
|
|
27812
27902
|
}
|
|
27813
|
-
// Update value form control
|
|
27814
|
-
if (variableGroup.get('value')) {
|
|
27815
|
-
variableGroup.get('value')?.setValue(variable.value, { emitEvent: false });
|
|
27816
|
-
}
|
|
27817
|
-
}
|
|
27818
|
-
else {
|
|
27819
|
-
// Element not found in elementOptions yet - might need to fetch
|
|
27820
|
-
// Keep elementId and elementName if they exist (from setTemplateVariables)
|
|
27821
|
-
// If we have elementId but element isn't found, we might need to fetch elements
|
|
27822
|
-
// However, we don't know the screen name yet, so we'll wait for elementOptions to be loaded
|
|
27823
|
-
// The initialization will run again when elementOptions changes via ngOnChanges
|
|
27824
27903
|
}
|
|
27825
27904
|
}
|
|
27826
27905
|
}
|
|
@@ -28888,8 +28967,14 @@ class TemplateVariablesFormComponent {
|
|
|
28888
28967
|
}
|
|
28889
28968
|
/**
|
|
28890
28969
|
* Check if screen name is selected for an element variable
|
|
28970
|
+
* Returns true if either selectedScreenName or screenNameId is set (and not "None")
|
|
28891
28971
|
*/
|
|
28892
28972
|
hasSelectedScreenName(variable) {
|
|
28973
|
+
// Check if screenNameId exists and is a valid number (not null/undefined)
|
|
28974
|
+
if (variable.screenNameId != null && typeof variable.screenNameId === 'number' && !isNaN(variable.screenNameId)) {
|
|
28975
|
+
return true;
|
|
28976
|
+
}
|
|
28977
|
+
// Fallback: check selectedScreenName
|
|
28893
28978
|
return !!variable.selectedScreenName;
|
|
28894
28979
|
}
|
|
28895
28980
|
/**
|
|
@@ -28901,29 +28986,46 @@ class TemplateVariablesFormComponent {
|
|
|
28901
28986
|
if (this.screenNameSelectConfigCache.has(cacheKey)) {
|
|
28902
28987
|
return this.screenNameSelectConfigCache.get(cacheKey);
|
|
28903
28988
|
}
|
|
28904
|
-
//
|
|
28905
|
-
const optionsArray =
|
|
28906
|
-
|
|
28907
|
-
|
|
28908
|
-
|
|
28909
|
-
|
|
28910
|
-
|
|
28911
|
-
|
|
28989
|
+
// Build options: include a "None" option (displayed as "Select") plus screenNameOptions from API
|
|
28990
|
+
const optionsArray = [
|
|
28991
|
+
{
|
|
28992
|
+
id: 'none',
|
|
28993
|
+
value: 'Select',
|
|
28994
|
+
name: 'None',
|
|
28995
|
+
label: 'None'
|
|
28996
|
+
},
|
|
28997
|
+
...this.screenNameOptions.map(screenName => ({
|
|
28998
|
+
id: screenName.id?.toString() || '',
|
|
28999
|
+
value: screenName.name,
|
|
29000
|
+
name: screenName.name,
|
|
29001
|
+
label: screenName.name
|
|
29002
|
+
}))
|
|
29003
|
+
];
|
|
28912
29004
|
// Ensure form control exists for screen name selection
|
|
28913
|
-
//
|
|
29005
|
+
// The form control value should match the option id (string for "none", string representation of number for real screen names)
|
|
28914
29006
|
const variableGroup = this.getVariableFormGroup(variable.name);
|
|
28915
29007
|
if (variableGroup) {
|
|
28916
29008
|
if (!variableGroup.get('selectedScreenName')) {
|
|
28917
|
-
// Initialize with screenNameId
|
|
28918
|
-
const initialValue = variable.screenNameId
|
|
29009
|
+
// Initialize with screenNameId as string (to match option id format), or 'none' by default
|
|
29010
|
+
const initialValue = variable.screenNameId ? String(variable.screenNameId) : 'none';
|
|
28919
29011
|
variableGroup.addControl('selectedScreenName', new FormControl(initialValue));
|
|
28920
29012
|
}
|
|
28921
29013
|
else {
|
|
28922
29014
|
// Update form control value if variable has screenNameId but form control doesn't match
|
|
28923
29015
|
if (variable.screenNameId) {
|
|
28924
29016
|
const currentValue = variableGroup.get('selectedScreenName')?.value;
|
|
28925
|
-
|
|
28926
|
-
|
|
29017
|
+
const expectedValue = String(variable.screenNameId);
|
|
29018
|
+
// Compare as strings to handle both number and string values
|
|
29019
|
+
const currentValueStr = currentValue != null ? String(currentValue) : null;
|
|
29020
|
+
if (currentValueStr !== expectedValue) {
|
|
29021
|
+
variableGroup.get('selectedScreenName')?.setValue(expectedValue, { emitEvent: false });
|
|
29022
|
+
}
|
|
29023
|
+
}
|
|
29024
|
+
else {
|
|
29025
|
+
// If no screenNameId, ensure form control is 'none' (for "None" selection by default)
|
|
29026
|
+
const currentValue = variableGroup.get('selectedScreenName')?.value;
|
|
29027
|
+
if (currentValue !== 'none' && currentValue !== null && currentValue !== '') {
|
|
29028
|
+
variableGroup.get('selectedScreenName')?.setValue('none', { emitEvent: false });
|
|
28927
29029
|
}
|
|
28928
29030
|
}
|
|
28929
29031
|
}
|
|
@@ -28937,42 +29039,92 @@ class TemplateVariablesFormComponent {
|
|
|
28937
29039
|
options: optionsArray,
|
|
28938
29040
|
hasMore: this.hasMoreScreenNames,
|
|
28939
29041
|
isLoading: this.isLoadingScreenNames,
|
|
28940
|
-
valueBy: 'screenNameId',
|
|
28941
29042
|
onChange: (value) => {
|
|
28942
|
-
//
|
|
28943
|
-
|
|
28944
|
-
|
|
28945
|
-
|
|
28946
|
-
|
|
28947
|
-
|
|
28948
|
-
variable.
|
|
28949
|
-
|
|
28950
|
-
|
|
28951
|
-
|
|
28952
|
-
|
|
28953
|
-
|
|
28954
|
-
|
|
28955
|
-
|
|
28956
|
-
|
|
28957
|
-
|
|
28958
|
-
|
|
28959
|
-
|
|
28960
|
-
|
|
28961
|
-
|
|
28962
|
-
|
|
28963
|
-
|
|
28964
|
-
variableGroup.get('
|
|
29043
|
+
// If "None" is selected (value is 'none' string or null), clear screen name and element info
|
|
29044
|
+
if (value == null || value === 'none' || value === '') {
|
|
29045
|
+
variable.screenNameId = undefined;
|
|
29046
|
+
variable.selectedScreenName = undefined;
|
|
29047
|
+
variable.elementId = undefined;
|
|
29048
|
+
variable.elementLocator = undefined;
|
|
29049
|
+
variable.elementName = undefined;
|
|
29050
|
+
variable.value = '';
|
|
29051
|
+
// Clear element config cache for this variable
|
|
29052
|
+
const keysToDelete = [];
|
|
29053
|
+
this.elementSelectConfigCache.forEach((_, key) => {
|
|
29054
|
+
if (key.startsWith(`${variable.name}_element`)) {
|
|
29055
|
+
keysToDelete.push(key);
|
|
29056
|
+
}
|
|
29057
|
+
});
|
|
29058
|
+
keysToDelete.forEach(key => this.elementSelectConfigCache.delete(key));
|
|
29059
|
+
// Update form controls - clear all element-related form controls
|
|
29060
|
+
// Set selectedScreenName to 'none' to show "None" is selected
|
|
29061
|
+
if (variableGroup) {
|
|
29062
|
+
if (variableGroup.get('value')) {
|
|
29063
|
+
variableGroup.get('value')?.setValue('', { emitEvent: false });
|
|
29064
|
+
}
|
|
29065
|
+
if (variableGroup.get('selectedScreenName')) {
|
|
29066
|
+
variableGroup.get('selectedScreenName')?.setValue('none', { emitEvent: false });
|
|
29067
|
+
}
|
|
29068
|
+
// Clear element ID form control to ensure elementId is cleared
|
|
29069
|
+
if (variableGroup.get('id')) {
|
|
29070
|
+
variableGroup.get('id')?.setValue(null, { emitEvent: false });
|
|
29071
|
+
}
|
|
28965
29072
|
}
|
|
28966
|
-
//
|
|
28967
|
-
|
|
29073
|
+
// Mark for check and stop (no element fetch when None)
|
|
29074
|
+
this.cdr.markForCheck();
|
|
29075
|
+
return;
|
|
28968
29076
|
}
|
|
28969
|
-
//
|
|
28970
|
-
|
|
29077
|
+
// value is the option id (string for "none", string representation of number for real screen names)
|
|
29078
|
+
// Convert to number for screenNameId if it's a valid number
|
|
29079
|
+
const screenNameIdNum = typeof value === 'string' && value !== 'none' ? parseInt(value, 10) : (typeof value === 'number' ? value : null);
|
|
29080
|
+
if (screenNameIdNum && !isNaN(screenNameIdNum)) {
|
|
29081
|
+
// Store selected screen name on the variable object
|
|
29082
|
+
variable.screenNameId = screenNameIdNum;
|
|
29083
|
+
// Find and store screen name name from screenNameOptions
|
|
29084
|
+
const screenNameOption = this.screenNameOptions.find(sn => sn.id === screenNameIdNum);
|
|
29085
|
+
if (screenNameOption) {
|
|
29086
|
+
variable.selectedScreenName = screenNameOption.name;
|
|
29087
|
+
}
|
|
29088
|
+
else {
|
|
29089
|
+
// Fallback: if not found, still set the ID but clear the name
|
|
29090
|
+
variable.selectedScreenName = undefined;
|
|
29091
|
+
}
|
|
29092
|
+
// Clear the element selection when screen name changes
|
|
29093
|
+
variable.elementId = undefined;
|
|
29094
|
+
variable.elementLocator = undefined;
|
|
29095
|
+
variable.elementName = undefined;
|
|
29096
|
+
variable.value = '';
|
|
29097
|
+
// Clear element config cache to force refresh
|
|
29098
|
+
// Clear all element configs for this variable since screen name changed
|
|
29099
|
+
const keysToDelete = [];
|
|
29100
|
+
this.elementSelectConfigCache.forEach((_, key) => {
|
|
29101
|
+
if (key.startsWith(`${variable.name}_element`)) {
|
|
29102
|
+
keysToDelete.push(key);
|
|
29103
|
+
}
|
|
29104
|
+
});
|
|
29105
|
+
keysToDelete.forEach(key => this.elementSelectConfigCache.delete(key));
|
|
29106
|
+
// Update form control
|
|
29107
|
+
if (variableGroup) {
|
|
29108
|
+
if (variableGroup.get('value')) {
|
|
29109
|
+
variableGroup.get('value')?.setValue('', { emitEvent: false });
|
|
29110
|
+
}
|
|
29111
|
+
// Ensure form control has the correct value (as string to match option id)
|
|
29112
|
+
if (variableGroup.get('selectedScreenName')) {
|
|
29113
|
+
variableGroup.get('selectedScreenName')?.setValue(String(screenNameIdNum), { emitEvent: false });
|
|
29114
|
+
}
|
|
29115
|
+
}
|
|
29116
|
+
// Emit event to fetch elements filtered by selected screen name
|
|
28971
29117
|
this.searchElementsByScreenName.emit({
|
|
28972
29118
|
screenNameId: variable.screenNameId,
|
|
28973
29119
|
searchTerm: ''
|
|
28974
29120
|
});
|
|
28975
29121
|
}
|
|
29122
|
+
else {
|
|
29123
|
+
// Invalid value - clear everything
|
|
29124
|
+
variable.screenNameId = undefined;
|
|
29125
|
+
variable.selectedScreenName = undefined;
|
|
29126
|
+
variable.value = '';
|
|
29127
|
+
}
|
|
28976
29128
|
// Mark for check to update UI first
|
|
28977
29129
|
this.cdr.markForCheck();
|
|
28978
29130
|
// The element config will be recomputed automatically when elementOptions input changes
|
|
@@ -28994,7 +29146,6 @@ class TemplateVariablesFormComponent {
|
|
|
28994
29146
|
*/
|
|
28995
29147
|
getElementSelectConfig(variable, index) {
|
|
28996
29148
|
// Get selected screen name ID
|
|
28997
|
-
console.log('variable', variable);
|
|
28998
29149
|
const selectedScreenNameId = variable.screenNameId;
|
|
28999
29150
|
// Include elementOptions length and loading state in cache key to invalidate when elements change
|
|
29000
29151
|
const cacheKey = `${variable.name}_element_${selectedScreenNameId || ''}_${this.elementOptions.length}_${this.isLoadingElements}`;
|
|
@@ -29085,6 +29236,16 @@ class TemplateVariablesFormComponent {
|
|
|
29085
29236
|
variable.elementId = selectedElement.id;
|
|
29086
29237
|
variable.elementLocator = selectedElement.locatorValue || '';
|
|
29087
29238
|
variable.elementName = selectedElement.name || '';
|
|
29239
|
+
// Update screen name from the selected element
|
|
29240
|
+
// This ensures the screen name dropdown shows the correct selection
|
|
29241
|
+
if (selectedElement.screenNameId) {
|
|
29242
|
+
variable.screenNameId = selectedElement.screenNameId;
|
|
29243
|
+
// Find and store screen name name from screenNameOptions
|
|
29244
|
+
const screenNameOption = this.screenNameOptions.find(sn => sn.id === selectedElement.screenNameId);
|
|
29245
|
+
if (screenNameOption) {
|
|
29246
|
+
variable.selectedScreenName = screenNameOption.name;
|
|
29247
|
+
}
|
|
29248
|
+
}
|
|
29088
29249
|
// Find and patch the selector variable with dataKey 'not_found'
|
|
29089
29250
|
const selectorVariable = this.templateVariables.find(v => v.name === 'selector' && v.dataKey === 'not_found');
|
|
29090
29251
|
if (selectorVariable && selectedElement.locatorValue) {
|
|
@@ -29104,8 +29265,6 @@ class TemplateVariablesFormComponent {
|
|
|
29104
29265
|
// Fallback: if element not found, just set the value
|
|
29105
29266
|
variable.value = value;
|
|
29106
29267
|
}
|
|
29107
|
-
// Screen name ID is already stored on variable.selectedScreenNameId
|
|
29108
|
-
// (it was set when screen name was selected)
|
|
29109
29268
|
// Update form control in FormArray
|
|
29110
29269
|
const variableGroup = this.getVariableFormGroup(variable.name);
|
|
29111
29270
|
if (variableGroup) {
|
|
@@ -29116,6 +29275,11 @@ class TemplateVariablesFormComponent {
|
|
|
29116
29275
|
if (selectedElement && variableGroup.get('id')) {
|
|
29117
29276
|
variableGroup.get('id')?.setValue(selectedElement.id, { emitEvent: false });
|
|
29118
29277
|
}
|
|
29278
|
+
// Update screen name form control if element has a screen name
|
|
29279
|
+
if (selectedElement && selectedElement.screenNameId && variableGroup.get('selectedScreenName')) {
|
|
29280
|
+
// Set the screen name ID as string to match option id format
|
|
29281
|
+
variableGroup.get('selectedScreenName')?.setValue(String(selectedElement.screenNameId), { emitEvent: false });
|
|
29282
|
+
}
|
|
29119
29283
|
}
|
|
29120
29284
|
// Mark for check and emit
|
|
29121
29285
|
this.cdr.markForCheck();
|
|
@@ -29141,10 +29305,10 @@ class TemplateVariablesFormComponent {
|
|
|
29141
29305
|
}
|
|
29142
29306
|
}
|
|
29143
29307
|
TemplateVariablesFormComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TemplateVariablesFormComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
29144
|
-
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 });
|
|
29308
|
+
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 });
|
|
29145
29309
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TemplateVariablesFormComponent, decorators: [{
|
|
29146
29310
|
type: Component,
|
|
29147
|
-
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"] }]
|
|
29311
|
+
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"] }]
|
|
29148
29312
|
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { templateVariables: [{
|
|
29149
29313
|
type: Input
|
|
29150
29314
|
}], variablesForm: [{
|
|
@@ -33504,96 +33668,368 @@ const DETAIL_SIDE_PANEL_SCROLL_STYLES = `
|
|
|
33504
33668
|
}
|
|
33505
33669
|
`;
|
|
33506
33670
|
|
|
33507
|
-
|
|
33508
|
-
|
|
33509
|
-
|
|
33510
|
-
|
|
33511
|
-
|
|
33512
|
-
|
|
33513
|
-
|
|
33514
|
-
|
|
33515
|
-
|
|
33516
|
-
|
|
33517
|
-
|
|
33518
|
-
|
|
33519
|
-
|
|
33520
|
-
|
|
33521
|
-
|
|
33522
|
-
|
|
33523
|
-
|
|
33524
|
-
|
|
33525
|
-
|
|
33526
|
-
|
|
33527
|
-
|
|
33528
|
-
|
|
33529
|
-
|
|
33530
|
-
|
|
33531
|
-
|
|
33532
|
-
|
|
33533
|
-
|
|
33534
|
-
|
|
33535
|
-
|
|
33536
|
-
|
|
33537
|
-
|
|
33538
|
-
|
|
33539
|
-
|
|
33540
|
-
|
|
33541
|
-
this.
|
|
33542
|
-
|
|
33543
|
-
|
|
33544
|
-
this.
|
|
33545
|
-
|
|
33546
|
-
|
|
33547
|
-
|
|
33548
|
-
|
|
33549
|
-
|
|
33550
|
-
|
|
33551
|
-
|
|
33552
|
-
|
|
33553
|
-
this.
|
|
33554
|
-
|
|
33555
|
-
|
|
33556
|
-
|
|
33557
|
-
|
|
33558
|
-
|
|
33559
|
-
|
|
33560
|
-
|
|
33561
|
-
|
|
33562
|
-
|
|
33563
|
-
|
|
33564
|
-
this.
|
|
33565
|
-
|
|
33566
|
-
|
|
33567
|
-
|
|
33568
|
-
|
|
33569
|
-
|
|
33570
|
-
|
|
33571
|
-
|
|
33572
|
-
|
|
33573
|
-
|
|
33574
|
-
|
|
33575
|
-
|
|
33576
|
-
|
|
33577
|
-
|
|
33578
|
-
|
|
33579
|
-
|
|
33580
|
-
|
|
33581
|
-
|
|
33582
|
-
|
|
33583
|
-
|
|
33584
|
-
|
|
33585
|
-
|
|
33586
|
-
|
|
33587
|
-
|
|
33588
|
-
|
|
33589
|
-
|
|
33590
|
-
|
|
33591
|
-
|
|
33592
|
-
|
|
33593
|
-
|
|
33594
|
-
|
|
33595
|
-
|
|
33596
|
-
|
|
33671
|
+
class DetailSidePanelComponent {
|
|
33672
|
+
constructor() {
|
|
33673
|
+
/** Tabs - each tab has a side panel icon button; tabs and buttons are 1:1. Host defines tabs and content. */
|
|
33674
|
+
this.tabs = [
|
|
33675
|
+
{ label: 'Test Case', value: 'test-case', icon: 'description' },
|
|
33676
|
+
{ label: 'Data Library', value: 'data-library', icon: 'folder' },
|
|
33677
|
+
{ label: 'Variables', value: 'variables', icon: 'code' },
|
|
33678
|
+
];
|
|
33679
|
+
/** Currently active tab value */
|
|
33680
|
+
this.activeTab = 'test-case';
|
|
33681
|
+
/** Whether to show the close button in the side menu */
|
|
33682
|
+
this.showCloseButton = false;
|
|
33683
|
+
/** Whether the panel is expanded (affects expand button icon and panel width) */
|
|
33684
|
+
this.expanded = true;
|
|
33685
|
+
/** Panel width when expanded (e.g. '480px', '25%') */
|
|
33686
|
+
this.expandedWidth = '380px';
|
|
33687
|
+
/** Panel width when collapsed (e.g. '56px' - fits icon bar + back button) */
|
|
33688
|
+
this.collapsedWidth = '56px';
|
|
33689
|
+
this.hostOverflow = 'hidden';
|
|
33690
|
+
/** Tooltip for expand button when panel is collapsed */
|
|
33691
|
+
this.expandTooltip = 'Expand';
|
|
33692
|
+
/** Tooltip for expand button when panel is expanded (collapse) */
|
|
33693
|
+
this.collapseTooltip = 'Collapse';
|
|
33694
|
+
/** Tooltip for close button */
|
|
33695
|
+
this.closeTooltip = 'Close';
|
|
33696
|
+
this.back = new EventEmitter();
|
|
33697
|
+
this.tabChange = new EventEmitter();
|
|
33698
|
+
this.expandToggle = new EventEmitter();
|
|
33699
|
+
this.close = new EventEmitter();
|
|
33700
|
+
}
|
|
33701
|
+
get hostWidth() {
|
|
33702
|
+
return this.expanded ? this.expandedWidth : this.collapsedWidth;
|
|
33703
|
+
}
|
|
33704
|
+
get hostMinWidth() {
|
|
33705
|
+
return this.expanded ? this.expandedWidth : this.collapsedWidth;
|
|
33706
|
+
}
|
|
33707
|
+
get hostMaxWidth() {
|
|
33708
|
+
return this.expanded ? this.expandedWidth : this.collapsedWidth;
|
|
33709
|
+
}
|
|
33710
|
+
trackByTabValue(_i, tab) {
|
|
33711
|
+
return tab.value;
|
|
33712
|
+
}
|
|
33713
|
+
onBack() {
|
|
33714
|
+
this.back.emit();
|
|
33715
|
+
}
|
|
33716
|
+
onTabClick(tab) {
|
|
33717
|
+
if (!this.expanded) {
|
|
33718
|
+
this.expandToggle.emit();
|
|
33719
|
+
}
|
|
33720
|
+
if (tab.value !== this.activeTab) {
|
|
33721
|
+
this.tabChange.emit(tab.value);
|
|
33722
|
+
}
|
|
33723
|
+
}
|
|
33724
|
+
onExpandToggle() {
|
|
33725
|
+
this.expandToggle.emit();
|
|
33726
|
+
}
|
|
33727
|
+
onClose() {
|
|
33728
|
+
this.close.emit();
|
|
33729
|
+
}
|
|
33730
|
+
}
|
|
33731
|
+
DetailSidePanelComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DetailSidePanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
33732
|
+
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 });
|
|
33733
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DetailSidePanelComponent, decorators: [{
|
|
33734
|
+
type: Component,
|
|
33735
|
+
args: [{ selector: 'cqa-detail-side-panel', styles: [DETAIL_SIDE_PANEL_SCROLL_STYLES], changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
33736
|
+
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)]',
|
|
33737
|
+
style: 'transition: width 0.3s ease-in-out',
|
|
33738
|
+
}, 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" }]
|
|
33739
|
+
}], propDecorators: { tabs: [{
|
|
33740
|
+
type: Input
|
|
33741
|
+
}], activeTab: [{
|
|
33742
|
+
type: Input
|
|
33743
|
+
}], showCloseButton: [{
|
|
33744
|
+
type: Input
|
|
33745
|
+
}], expanded: [{
|
|
33746
|
+
type: Input
|
|
33747
|
+
}], expandedWidth: [{
|
|
33748
|
+
type: Input
|
|
33749
|
+
}], collapsedWidth: [{
|
|
33750
|
+
type: Input
|
|
33751
|
+
}], hostWidth: [{
|
|
33752
|
+
type: HostBinding,
|
|
33753
|
+
args: ['style.width']
|
|
33754
|
+
}], hostMinWidth: [{
|
|
33755
|
+
type: HostBinding,
|
|
33756
|
+
args: ['style.min-width']
|
|
33757
|
+
}], hostMaxWidth: [{
|
|
33758
|
+
type: HostBinding,
|
|
33759
|
+
args: ['style.max-width']
|
|
33760
|
+
}], hostOverflow: [{
|
|
33761
|
+
type: HostBinding,
|
|
33762
|
+
args: ['style.overflow']
|
|
33763
|
+
}], expandTooltip: [{
|
|
33764
|
+
type: Input
|
|
33765
|
+
}], collapseTooltip: [{
|
|
33766
|
+
type: Input
|
|
33767
|
+
}], closeTooltip: [{
|
|
33768
|
+
type: Input
|
|
33769
|
+
}], back: [{
|
|
33770
|
+
type: Output
|
|
33771
|
+
}], tabChange: [{
|
|
33772
|
+
type: Output
|
|
33773
|
+
}], expandToggle: [{
|
|
33774
|
+
type: Output
|
|
33775
|
+
}], close: [{
|
|
33776
|
+
type: Output
|
|
33777
|
+
}] } });
|
|
33778
|
+
|
|
33779
|
+
class DetailDrawerTabContentDirective {
|
|
33780
|
+
constructor(templateRef) {
|
|
33781
|
+
this.templateRef = templateRef;
|
|
33782
|
+
}
|
|
33783
|
+
}
|
|
33784
|
+
DetailDrawerTabContentDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DetailDrawerTabContentDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
|
|
33785
|
+
DetailDrawerTabContentDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.4.0", type: DetailDrawerTabContentDirective, selector: "[cqaTabContent]", ngImport: i0 });
|
|
33786
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DetailDrawerTabContentDirective, decorators: [{
|
|
33787
|
+
type: Directive,
|
|
33788
|
+
args: [{
|
|
33789
|
+
selector: '[cqaTabContent]',
|
|
33790
|
+
}]
|
|
33791
|
+
}], ctorParameters: function () { return [{ type: i0.TemplateRef }]; } });
|
|
33792
|
+
|
|
33793
|
+
class DetailDrawerTabComponent {
|
|
33794
|
+
constructor() {
|
|
33795
|
+
/** Tab label (shown in tooltip on icon button) */
|
|
33796
|
+
this.label = '';
|
|
33797
|
+
/** Tab value (unique identifier) */
|
|
33798
|
+
this.value = '';
|
|
33799
|
+
/** Material icon name for the tab button */
|
|
33800
|
+
this.icon = 'folder';
|
|
33801
|
+
}
|
|
33802
|
+
get contentTemplate() {
|
|
33803
|
+
return this.contentDirective?.templateRef ?? null;
|
|
33804
|
+
}
|
|
33805
|
+
}
|
|
33806
|
+
DetailDrawerTabComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DetailDrawerTabComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
33807
|
+
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 });
|
|
33808
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DetailDrawerTabComponent, decorators: [{
|
|
33809
|
+
type: Component,
|
|
33810
|
+
args: [{
|
|
33811
|
+
selector: 'cqa-detail-drawer-tab',
|
|
33812
|
+
template: '',
|
|
33813
|
+
host: {
|
|
33814
|
+
style: 'display: contents',
|
|
33815
|
+
},
|
|
33816
|
+
}]
|
|
33817
|
+
}], propDecorators: { label: [{
|
|
33818
|
+
type: Input
|
|
33819
|
+
}], value: [{
|
|
33820
|
+
type: Input
|
|
33821
|
+
}], icon: [{
|
|
33822
|
+
type: Input
|
|
33823
|
+
}], contentDirective: [{
|
|
33824
|
+
type: ContentChild,
|
|
33825
|
+
args: [DetailDrawerTabContentDirective]
|
|
33826
|
+
}] } });
|
|
33827
|
+
|
|
33828
|
+
class DetailDrawerComponent {
|
|
33829
|
+
constructor() {
|
|
33830
|
+
/** Currently active tab value */
|
|
33831
|
+
this.activeTab = '';
|
|
33832
|
+
/** Whether to show the close button */
|
|
33833
|
+
this.showCloseButton = true;
|
|
33834
|
+
/** Whether the drawer is expanded */
|
|
33835
|
+
this.expanded = true;
|
|
33836
|
+
/** Panel width when expanded */
|
|
33837
|
+
this.expandedWidth = '280px';
|
|
33838
|
+
/** Maximum width when expanded (e.g. '600px', '30vw'). Default: 30% of viewport */
|
|
33839
|
+
this.maxExpandedWidth = '30vw';
|
|
33840
|
+
/** Panel width when collapsed */
|
|
33841
|
+
this.collapsedWidth = '56px';
|
|
33842
|
+
this.expandTooltip = 'Expand';
|
|
33843
|
+
this.collapseTooltip = 'Collapse';
|
|
33844
|
+
this.closeTooltip = 'Close';
|
|
33845
|
+
this.activeTabChange = new EventEmitter();
|
|
33846
|
+
this.expandToggle = new EventEmitter();
|
|
33847
|
+
this.close = new EventEmitter();
|
|
33848
|
+
}
|
|
33849
|
+
get hostWidth() {
|
|
33850
|
+
return this.expanded ? this.expandedWidth : this.collapsedWidth;
|
|
33851
|
+
}
|
|
33852
|
+
get hostMinWidth() {
|
|
33853
|
+
return this.expanded && this.minExpandedWidth ? this.minExpandedWidth : null;
|
|
33854
|
+
}
|
|
33855
|
+
get hostMaxWidth() {
|
|
33856
|
+
return this.expanded ? this.maxExpandedWidth : null;
|
|
33857
|
+
}
|
|
33858
|
+
ngAfterContentInit() {
|
|
33859
|
+
this.ensureActiveTab();
|
|
33860
|
+
}
|
|
33861
|
+
ngAfterContentChecked() {
|
|
33862
|
+
this.ensureActiveTab();
|
|
33863
|
+
}
|
|
33864
|
+
ensureActiveTab() {
|
|
33865
|
+
const tabs = this.tabComponents?.toArray() ?? [];
|
|
33866
|
+
if (tabs.length > 0 && !this.activeTab) {
|
|
33867
|
+
this.activeTab = tabs[0].value;
|
|
33868
|
+
this.activeTabChange.emit(this.activeTab);
|
|
33869
|
+
}
|
|
33870
|
+
}
|
|
33871
|
+
onTabClick(tab) {
|
|
33872
|
+
// If drawer is collapsed, open it (but never close on tab click)
|
|
33873
|
+
if (!this.expanded) {
|
|
33874
|
+
this.expandToggle.emit();
|
|
33875
|
+
}
|
|
33876
|
+
// Select the tab
|
|
33877
|
+
if (tab.value !== this.activeTab) {
|
|
33878
|
+
this.activeTab = tab.value;
|
|
33879
|
+
this.activeTabChange.emit(this.activeTab);
|
|
33880
|
+
}
|
|
33881
|
+
}
|
|
33882
|
+
onExpandToggle() {
|
|
33883
|
+
this.expandToggle.emit();
|
|
33884
|
+
}
|
|
33885
|
+
onClose() {
|
|
33886
|
+
this.close.emit();
|
|
33887
|
+
}
|
|
33888
|
+
trackByValue(_i, tab) {
|
|
33889
|
+
return tab.value;
|
|
33890
|
+
}
|
|
33891
|
+
isTabActive(tab) {
|
|
33892
|
+
return tab.value === this.activeTab;
|
|
33893
|
+
}
|
|
33894
|
+
}
|
|
33895
|
+
DetailDrawerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DetailDrawerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
33896
|
+
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 });
|
|
33897
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DetailDrawerComponent, decorators: [{
|
|
33898
|
+
type: Component,
|
|
33899
|
+
args: [{ selector: 'cqa-detail-drawer', changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
33900
|
+
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)]',
|
|
33901
|
+
style: 'transition: width 0.3s ease-in-out',
|
|
33902
|
+
}, 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: [] }]
|
|
33903
|
+
}], propDecorators: { tabComponents: [{
|
|
33904
|
+
type: ContentChildren,
|
|
33905
|
+
args: [DetailDrawerTabComponent]
|
|
33906
|
+
}], activeTab: [{
|
|
33907
|
+
type: Input
|
|
33908
|
+
}], showCloseButton: [{
|
|
33909
|
+
type: Input
|
|
33910
|
+
}], expanded: [{
|
|
33911
|
+
type: Input
|
|
33912
|
+
}], expandedWidth: [{
|
|
33913
|
+
type: Input
|
|
33914
|
+
}], minExpandedWidth: [{
|
|
33915
|
+
type: Input
|
|
33916
|
+
}], maxExpandedWidth: [{
|
|
33917
|
+
type: Input
|
|
33918
|
+
}], collapsedWidth: [{
|
|
33919
|
+
type: Input
|
|
33920
|
+
}], hostWidth: [{
|
|
33921
|
+
type: HostBinding,
|
|
33922
|
+
args: ['style.width']
|
|
33923
|
+
}], hostMinWidth: [{
|
|
33924
|
+
type: HostBinding,
|
|
33925
|
+
args: ['style.min-width']
|
|
33926
|
+
}], hostMaxWidth: [{
|
|
33927
|
+
type: HostBinding,
|
|
33928
|
+
args: ['style.max-width']
|
|
33929
|
+
}], expandTooltip: [{
|
|
33930
|
+
type: Input
|
|
33931
|
+
}], collapseTooltip: [{
|
|
33932
|
+
type: Input
|
|
33933
|
+
}], closeTooltip: [{
|
|
33934
|
+
type: Input
|
|
33935
|
+
}], activeTabChange: [{
|
|
33936
|
+
type: Output
|
|
33937
|
+
}], expandToggle: [{
|
|
33938
|
+
type: Output
|
|
33939
|
+
}], close: [{
|
|
33940
|
+
type: Output
|
|
33941
|
+
}] } });
|
|
33942
|
+
|
|
33943
|
+
/** Keys for each dynamic select in test-case-details-edit. Use these with selectConfigOverrides. */
|
|
33944
|
+
const TEST_CASE_DETAILS_SELECT_KEYS = {
|
|
33945
|
+
status: 'status',
|
|
33946
|
+
priority: 'priority',
|
|
33947
|
+
type: 'type',
|
|
33948
|
+
labels: 'labels',
|
|
33949
|
+
prerequisiteCases: 'prerequisiteCases',
|
|
33950
|
+
testDataProfile: 'testDataProfile',
|
|
33951
|
+
testDataSet: 'testDataSet',
|
|
33952
|
+
videoRecording: 'videoRecording',
|
|
33953
|
+
enableAiSmartness: 'enableAiSmartness',
|
|
33954
|
+
defaultAiAction: 'defaultAiAction',
|
|
33955
|
+
knowledgeBaseDefaultTestCase: 'knowledgeBaseDefaultTestCase',
|
|
33956
|
+
useAiMetadata: 'useAiMetadata',
|
|
33957
|
+
defaultBrowser: 'defaultBrowser',
|
|
33958
|
+
defaultViewport: 'defaultViewport',
|
|
33959
|
+
deviceType: 'deviceType',
|
|
33960
|
+
deviceOS: 'deviceOS',
|
|
33961
|
+
};
|
|
33962
|
+
const FREQUENTLY_USED_LABELS = [
|
|
33963
|
+
'Case',
|
|
33964
|
+
'Critical',
|
|
33965
|
+
'PO',
|
|
33966
|
+
'Upload',
|
|
33967
|
+
'Validation',
|
|
33968
|
+
'Review',
|
|
33969
|
+
'Edge-cases',
|
|
33970
|
+
'Security',
|
|
33971
|
+
'Integration',
|
|
33972
|
+
'Smoke',
|
|
33973
|
+
];
|
|
33974
|
+
class TestCaseDetailsEditComponent {
|
|
33975
|
+
constructor(cdr) {
|
|
33976
|
+
this.cdr = cdr;
|
|
33977
|
+
this.descriptionTitle = 'Description';
|
|
33978
|
+
this.descriptionContent = '';
|
|
33979
|
+
/** When true, description uses Trix rich text editor (Bold, Italic, etc.). Host app must load Trix. */
|
|
33980
|
+
this.enableMarkdown = false;
|
|
33981
|
+
this.metadataItems = [];
|
|
33982
|
+
this.labels = [];
|
|
33983
|
+
this.configTitle = 'Configuration';
|
|
33984
|
+
this.configSections = [];
|
|
33985
|
+
this.configSectionsRow2 = [];
|
|
33986
|
+
/** Optional list of prerequisite test case options for the multi-select. If not provided, uses default sample options. */
|
|
33987
|
+
this.prerequisiteCaseOptions = [];
|
|
33988
|
+
/** Platform: 'web' shows Default Browser + Viewport; 'mobile' shows Device Type + OS. Defaults to 'web'. */
|
|
33989
|
+
this.platform = 'web';
|
|
33990
|
+
/** When true, hides Priority, Type, and Test Data Set fields (step groups don't have these). Defaults to false. */
|
|
33991
|
+
this.isStepGroup = false;
|
|
33992
|
+
/**
|
|
33993
|
+
* Override config per select key. Use for:
|
|
33994
|
+
* - API-driven options: pass options array (update when API returns)
|
|
33995
|
+
* - Server-side search: serverSearch: true, onSearch in override or listen to selectSearch
|
|
33996
|
+
* - Infinite scroll: hasMore: true, onLoadMore in override or listen to selectLoadMore
|
|
33997
|
+
* - Initial fetch on open: initialFetchOnOpen: true
|
|
33998
|
+
*/
|
|
33999
|
+
this.selectConfigOverrides = {};
|
|
34000
|
+
this.save = new EventEmitter();
|
|
34001
|
+
this.cancel = new EventEmitter();
|
|
34002
|
+
/** Emitted when user searches in a select (serverSearch mode). Call API and update options via selectConfigOverrides. */
|
|
34003
|
+
this.selectSearch = new EventEmitter();
|
|
34004
|
+
/** Emitted when user scrolls to load more. Call API, append to options via selectConfigOverrides. */
|
|
34005
|
+
this.selectLoadMore = new EventEmitter();
|
|
34006
|
+
/** Emitted when a select panel is opened. Use to call API for initial load (e.g. when initialFetchOnOpen). */
|
|
34007
|
+
this.selectOpened = new EventEmitter();
|
|
34008
|
+
/** Emitted when selection changes in any select. */
|
|
34009
|
+
this.selectionChange = new EventEmitter();
|
|
34010
|
+
/** Emitted when user adds a new custom label via the "New" option. */
|
|
34011
|
+
this.labelAdded = new EventEmitter();
|
|
34012
|
+
/** Form state */
|
|
34013
|
+
this.editDescription = '';
|
|
34014
|
+
this.editStatus = '';
|
|
34015
|
+
this.editPriority = '';
|
|
34016
|
+
this.editLabels = [];
|
|
34017
|
+
this.testCaseTimeout = '';
|
|
34018
|
+
this.waitTimeoutLocators = '';
|
|
34019
|
+
this.autoWaitEnabled = false;
|
|
34020
|
+
this.retryFailedSteps = '';
|
|
34021
|
+
this.configExpanded = true;
|
|
34022
|
+
this.executionExpanded = true;
|
|
34023
|
+
this.aiConfigExpanded = true;
|
|
34024
|
+
this.waitsRetriesExpanded = true;
|
|
34025
|
+
this.deviceExpanded = true;
|
|
34026
|
+
this.keyFlagsExpanded = true;
|
|
34027
|
+
this.mobileTestingEnabled = false;
|
|
34028
|
+
this.extensionUseEnabled = false;
|
|
34029
|
+
this.dataDrivenEnabled = false;
|
|
34030
|
+
this.frequentlyUsedLabels = FREQUENTLY_USED_LABELS;
|
|
34031
|
+
/** FormGroup for cqa-dynamic-select bindings */
|
|
34032
|
+
this.editForm = new FormGroup({
|
|
33597
34033
|
status: new FormControl(''),
|
|
33598
34034
|
priority: new FormControl(''),
|
|
33599
34035
|
type: new FormControl(''),
|
|
@@ -34424,234 +34860,43 @@ class TestCaseDetailsComponent {
|
|
|
34424
34860
|
return this.editing !== undefined ? this.editing : this._editing;
|
|
34425
34861
|
}
|
|
34426
34862
|
ngOnInit() {
|
|
34427
|
-
if (this.startInEditMode) {
|
|
34428
|
-
this._editing = true;
|
|
34429
|
-
}
|
|
34430
|
-
}
|
|
34431
|
-
/** Filtered metadata items - excludes Priority and Type for step groups */
|
|
34432
|
-
get filteredMetadataItems() {
|
|
34433
|
-
if (!this.isStepGroup) {
|
|
34434
|
-
return this.metadataItems;
|
|
34435
|
-
}
|
|
34436
|
-
return this.metadataItems.filter((item) => !this.stepGroupExcludedMetadataLabels.includes(item.label?.toLowerCase() ?? ''));
|
|
34437
|
-
}
|
|
34438
|
-
onEditClick() {
|
|
34439
|
-
if (this.editing === undefined) {
|
|
34440
|
-
this._editing = true;
|
|
34441
|
-
this.cdr.detectChanges();
|
|
34442
|
-
}
|
|
34443
|
-
this.editDescription.emit();
|
|
34444
|
-
}
|
|
34445
|
-
onSaveChanges(data) {
|
|
34446
|
-
if (this.editing === undefined) {
|
|
34447
|
-
this._editing = false;
|
|
34448
|
-
}
|
|
34449
|
-
this.cdr.detectChanges();
|
|
34450
|
-
this.saveChanges.emit(data);
|
|
34451
|
-
}
|
|
34452
|
-
onCancelEdit() {
|
|
34453
|
-
this.cancel.emit();
|
|
34454
|
-
if (this.editing === undefined) {
|
|
34455
|
-
this._editing = false;
|
|
34456
|
-
}
|
|
34457
|
-
this.cdr.detectChanges();
|
|
34458
|
-
}
|
|
34459
|
-
trackByConfigTitle(_i, section) {
|
|
34460
|
-
return section.title;
|
|
34461
|
-
}
|
|
34462
|
-
trackByMetadataLabel(_i, item) {
|
|
34463
|
-
return item.label;
|
|
34464
|
-
}
|
|
34465
|
-
onMetadataLinkClick(item) {
|
|
34466
|
-
if (item.link) {
|
|
34467
|
-
this.metadataLinkClick.emit(item);
|
|
34468
|
-
}
|
|
34469
|
-
}
|
|
34470
|
-
getStatusDotClass(item) {
|
|
34471
|
-
if (!item.statusColor)
|
|
34472
|
-
return '';
|
|
34473
|
-
switch (item.statusColor) {
|
|
34474
|
-
case 'yellow':
|
|
34475
|
-
return 'cqa-bg-[#EAB308]';
|
|
34476
|
-
case 'red':
|
|
34477
|
-
return 'cqa-bg-[#DC2626]';
|
|
34478
|
-
case 'green':
|
|
34479
|
-
return 'cqa-bg-[#16A34A]';
|
|
34480
|
-
case 'gray':
|
|
34481
|
-
default:
|
|
34482
|
-
return 'cqa-bg-[#94A3B8]';
|
|
34483
|
-
}
|
|
34484
|
-
}
|
|
34485
|
-
/** Text color for metadata value (e.g. red for critical priority) */
|
|
34486
|
-
getValueTextClass(item) {
|
|
34487
|
-
if (item.statusColor === 'red') {
|
|
34488
|
-
return 'cqa-text-[#DC2626]';
|
|
34489
|
-
}
|
|
34490
|
-
return 'cqa-text-[#111827]';
|
|
34491
|
-
}
|
|
34492
|
-
}
|
|
34493
|
-
TestCaseDetailsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TestCaseDetailsComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
34494
|
-
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 });
|
|
34495
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TestCaseDetailsComponent, decorators: [{
|
|
34496
|
-
type: Component,
|
|
34497
|
-
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: [] }]
|
|
34498
|
-
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { editing: [{
|
|
34499
|
-
type: Input
|
|
34500
|
-
}], startInEditMode: [{
|
|
34501
|
-
type: Input
|
|
34502
|
-
}], descriptionTitle: [{
|
|
34503
|
-
type: Input
|
|
34504
|
-
}], descriptionContent: [{
|
|
34505
|
-
type: Input
|
|
34506
|
-
}], enableMarkdown: [{
|
|
34507
|
-
type: Input
|
|
34508
|
-
}], showEditButton: [{
|
|
34509
|
-
type: Input
|
|
34510
|
-
}], metadataItems: [{
|
|
34511
|
-
type: Input
|
|
34512
|
-
}], labels: [{
|
|
34513
|
-
type: Input
|
|
34514
|
-
}], configTitle: [{
|
|
34515
|
-
type: Input
|
|
34516
|
-
}], configSections: [{
|
|
34517
|
-
type: Input
|
|
34518
|
-
}], configSectionsRow2: [{
|
|
34519
|
-
type: Input
|
|
34520
|
-
}], platform: [{
|
|
34521
|
-
type: Input
|
|
34522
|
-
}], isStepGroup: [{
|
|
34523
|
-
type: Input
|
|
34524
|
-
}], selectConfigOverrides: [{
|
|
34525
|
-
type: Input
|
|
34526
|
-
}], editDescription: [{
|
|
34527
|
-
type: Output
|
|
34528
|
-
}], cancel: [{
|
|
34529
|
-
type: Output
|
|
34530
|
-
}], saveChanges: [{
|
|
34531
|
-
type: Output
|
|
34532
|
-
}], metadataLinkClick: [{
|
|
34533
|
-
type: Output
|
|
34534
|
-
}], selectSearch: [{
|
|
34535
|
-
type: Output
|
|
34536
|
-
}], selectLoadMore: [{
|
|
34537
|
-
type: Output
|
|
34538
|
-
}], selectOpened: [{
|
|
34539
|
-
type: Output
|
|
34540
|
-
}], selectionChange: [{
|
|
34541
|
-
type: Output
|
|
34542
|
-
}], labelAdded: [{
|
|
34543
|
-
type: Output
|
|
34544
|
-
}] } });
|
|
34545
|
-
|
|
34546
|
-
class DetailSidePanelComponent {
|
|
34547
|
-
constructor(cdr) {
|
|
34548
|
-
this.cdr = cdr;
|
|
34549
|
-
/** Tabs - each tab has a side panel icon button; tabs and buttons are 1:1 */
|
|
34550
|
-
this.tabs = [
|
|
34551
|
-
{ label: 'Test Case', value: 'test-case', icon: 'description' },
|
|
34552
|
-
{ label: 'Data Library', value: 'data-library', icon: 'folder' },
|
|
34553
|
-
{ label: 'Variables', value: 'variables', icon: 'code' },
|
|
34554
|
-
];
|
|
34555
|
-
/** Currently active tab value */
|
|
34556
|
-
this.activeTab = 'test-case';
|
|
34557
|
-
/** Description section title */
|
|
34558
|
-
this.descriptionTitle = 'Description';
|
|
34559
|
-
/** Description text content */
|
|
34560
|
-
this.descriptionContent = '';
|
|
34561
|
-
/** When true, description uses rich text editor and renders as HTML. Host app must load Trix. */
|
|
34562
|
-
this.enableMarkdown = false;
|
|
34563
|
-
/** Whether to show the Edit button in the Description header */
|
|
34564
|
-
this.showEditButton = true;
|
|
34565
|
-
/** Metadata items (Created on, Status, Priority, etc.) */
|
|
34566
|
-
this.metadataItems = [];
|
|
34567
|
-
/** Labels/tags (e.g. Automation, API, SDK, UI/UX) */
|
|
34568
|
-
this.labels = [];
|
|
34569
|
-
/** Configuration sections - full width (e.g. Execution, AI Configuration) */
|
|
34570
|
-
this.configSections = [];
|
|
34571
|
-
/** Optional config sections displayed in a 2-column row (e.g. Waits & Retries, Device) */
|
|
34572
|
-
this.configSectionsRow2 = [];
|
|
34573
|
-
/** Platform: 'web' or 'mobile'. Defaults to 'web'. Used for Device Settings. */
|
|
34574
|
-
this.platform = 'web';
|
|
34575
|
-
/** When true, hides Priority, Type, Test Data Set, and Prerequisite Case (step groups don't have these). Defaults to false. */
|
|
34576
|
-
this.isStepGroup = false;
|
|
34577
|
-
/** Configuration section title */
|
|
34578
|
-
this.configTitle = 'Configuration';
|
|
34579
|
-
/** Whether to show the close button in the side menu */
|
|
34580
|
-
this.showCloseButton = false;
|
|
34581
|
-
/** When true, test case details start in edit mode (useful for Storybook). */
|
|
34582
|
-
this.startInEditMode = false;
|
|
34583
|
-
/** Override config per select for API-driven options, server search, load more. */
|
|
34584
|
-
this.selectConfigOverrides = {};
|
|
34585
|
-
/** Whether the panel is expanded (affects expand button icon and panel width) */
|
|
34586
|
-
this.expanded = true;
|
|
34587
|
-
/** Panel width when expanded (e.g. '480px', '25%') */
|
|
34588
|
-
this.expandedWidth = '380px';
|
|
34589
|
-
/** Panel width when collapsed (e.g. '56px' - fits icon bar + back button) */
|
|
34590
|
-
this.collapsedWidth = '56px';
|
|
34591
|
-
this.hostOverflow = 'hidden';
|
|
34592
|
-
/** Tooltip for expand button when panel is collapsed */
|
|
34593
|
-
this.expandTooltip = 'Expand';
|
|
34594
|
-
/** Tooltip for expand button when panel is expanded (collapse) */
|
|
34595
|
-
this.collapseTooltip = 'Collapse';
|
|
34596
|
-
/** Tooltip for close button */
|
|
34597
|
-
this.closeTooltip = 'Close';
|
|
34598
|
-
this.back = new EventEmitter();
|
|
34599
|
-
this.tabChange = new EventEmitter();
|
|
34600
|
-
this.editDescription = new EventEmitter();
|
|
34601
|
-
this.cancel = new EventEmitter();
|
|
34602
|
-
this.saveChanges = new EventEmitter();
|
|
34603
|
-
this.metadataLinkClick = new EventEmitter();
|
|
34604
|
-
this.selectSearch = new EventEmitter();
|
|
34605
|
-
this.selectLoadMore = new EventEmitter();
|
|
34606
|
-
this.selectOpened = new EventEmitter();
|
|
34607
|
-
this.selectionChange = new EventEmitter();
|
|
34608
|
-
this.labelAdded = new EventEmitter();
|
|
34609
|
-
this.expandToggle = new EventEmitter();
|
|
34610
|
-
this.close = new EventEmitter();
|
|
34611
|
-
}
|
|
34612
|
-
get hostWidth() {
|
|
34613
|
-
return this.expanded ? this.expandedWidth : this.collapsedWidth;
|
|
34614
|
-
}
|
|
34615
|
-
get hostMinWidth() {
|
|
34616
|
-
return this.expanded ? this.expandedWidth : this.collapsedWidth;
|
|
34617
|
-
}
|
|
34618
|
-
get hostMaxWidth() {
|
|
34619
|
-
return this.expanded ? this.expandedWidth : this.collapsedWidth;
|
|
34620
|
-
}
|
|
34621
|
-
trackByTabValue(_i, tab) {
|
|
34622
|
-
return tab.value;
|
|
34623
|
-
}
|
|
34624
|
-
trackByMetadataLabel(_i, item) {
|
|
34625
|
-
return item.label;
|
|
34626
|
-
}
|
|
34627
|
-
trackByConfigTitle(_i, section) {
|
|
34628
|
-
return section.title;
|
|
34629
|
-
}
|
|
34630
|
-
onBack() {
|
|
34631
|
-
this.back.emit();
|
|
34632
|
-
}
|
|
34633
|
-
onTabClick(tab) {
|
|
34634
|
-
if (!this.expanded) {
|
|
34635
|
-
this.expandToggle.emit();
|
|
34863
|
+
if (this.startInEditMode) {
|
|
34864
|
+
this._editing = true;
|
|
34636
34865
|
}
|
|
34637
|
-
|
|
34638
|
-
|
|
34866
|
+
}
|
|
34867
|
+
/** Filtered metadata items - excludes Priority and Type for step groups */
|
|
34868
|
+
get filteredMetadataItems() {
|
|
34869
|
+
if (!this.isStepGroup) {
|
|
34870
|
+
return this.metadataItems;
|
|
34639
34871
|
}
|
|
34872
|
+
return this.metadataItems.filter((item) => !this.stepGroupExcludedMetadataLabels.includes(item.label?.toLowerCase() ?? ''));
|
|
34640
34873
|
}
|
|
34641
|
-
|
|
34874
|
+
onEditClick() {
|
|
34875
|
+
if (this.editing === undefined) {
|
|
34876
|
+
this._editing = true;
|
|
34877
|
+
this.cdr.detectChanges();
|
|
34878
|
+
}
|
|
34642
34879
|
this.editDescription.emit();
|
|
34643
34880
|
}
|
|
34644
34881
|
onSaveChanges(data) {
|
|
34882
|
+
if (this.editing === undefined) {
|
|
34883
|
+
this._editing = false;
|
|
34884
|
+
}
|
|
34885
|
+
this.cdr.detectChanges();
|
|
34645
34886
|
this.saveChanges.emit(data);
|
|
34646
34887
|
}
|
|
34647
|
-
|
|
34888
|
+
onCancelEdit() {
|
|
34648
34889
|
this.cancel.emit();
|
|
34890
|
+
if (this.editing === undefined) {
|
|
34891
|
+
this._editing = false;
|
|
34892
|
+
}
|
|
34893
|
+
this.cdr.detectChanges();
|
|
34649
34894
|
}
|
|
34650
|
-
|
|
34651
|
-
|
|
34895
|
+
trackByConfigTitle(_i, section) {
|
|
34896
|
+
return section.title;
|
|
34652
34897
|
}
|
|
34653
|
-
|
|
34654
|
-
|
|
34898
|
+
trackByMetadataLabel(_i, item) {
|
|
34899
|
+
return item.label;
|
|
34655
34900
|
}
|
|
34656
34901
|
onMetadataLinkClick(item) {
|
|
34657
34902
|
if (item.link) {
|
|
@@ -34673,18 +34918,22 @@ class DetailSidePanelComponent {
|
|
|
34673
34918
|
return 'cqa-bg-[#94A3B8]';
|
|
34674
34919
|
}
|
|
34675
34920
|
}
|
|
34921
|
+
/** Text color for metadata value (e.g. red for critical priority) */
|
|
34922
|
+
getValueTextClass(item) {
|
|
34923
|
+
if (item.statusColor === 'red') {
|
|
34924
|
+
return 'cqa-text-[#DC2626]';
|
|
34925
|
+
}
|
|
34926
|
+
return 'cqa-text-[#111827]';
|
|
34927
|
+
}
|
|
34676
34928
|
}
|
|
34677
|
-
|
|
34678
|
-
|
|
34679
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type:
|
|
34929
|
+
TestCaseDetailsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TestCaseDetailsComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
34930
|
+
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 });
|
|
34931
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TestCaseDetailsComponent, decorators: [{
|
|
34680
34932
|
type: Component,
|
|
34681
|
-
args: [{ selector: 'cqa-
|
|
34682
|
-
|
|
34683
|
-
style: 'transition: width 0.3s ease-in-out',
|
|
34684
|
-
}, 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" }]
|
|
34685
|
-
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { tabs: [{
|
|
34933
|
+
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: [] }]
|
|
34934
|
+
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { editing: [{
|
|
34686
34935
|
type: Input
|
|
34687
|
-
}],
|
|
34936
|
+
}], startInEditMode: [{
|
|
34688
34937
|
type: Input
|
|
34689
34938
|
}], descriptionTitle: [{
|
|
34690
34939
|
type: Input
|
|
@@ -34698,6 +34947,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
|
|
|
34698
34947
|
type: Input
|
|
34699
34948
|
}], labels: [{
|
|
34700
34949
|
type: Input
|
|
34950
|
+
}], configTitle: [{
|
|
34951
|
+
type: Input
|
|
34701
34952
|
}], configSections: [{
|
|
34702
34953
|
type: Input
|
|
34703
34954
|
}], configSectionsRow2: [{
|
|
@@ -34706,44 +34957,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
|
|
|
34706
34957
|
type: Input
|
|
34707
34958
|
}], isStepGroup: [{
|
|
34708
34959
|
type: Input
|
|
34709
|
-
}], configTitle: [{
|
|
34710
|
-
type: Input
|
|
34711
|
-
}], showCloseButton: [{
|
|
34712
|
-
type: Input
|
|
34713
|
-
}], startInEditMode: [{
|
|
34714
|
-
type: Input
|
|
34715
|
-
}], editing: [{
|
|
34716
|
-
type: Input
|
|
34717
34960
|
}], selectConfigOverrides: [{
|
|
34718
34961
|
type: Input
|
|
34719
|
-
}], expanded: [{
|
|
34720
|
-
type: Input
|
|
34721
|
-
}], expandedWidth: [{
|
|
34722
|
-
type: Input
|
|
34723
|
-
}], collapsedWidth: [{
|
|
34724
|
-
type: Input
|
|
34725
|
-
}], hostWidth: [{
|
|
34726
|
-
type: HostBinding,
|
|
34727
|
-
args: ['style.width']
|
|
34728
|
-
}], hostMinWidth: [{
|
|
34729
|
-
type: HostBinding,
|
|
34730
|
-
args: ['style.min-width']
|
|
34731
|
-
}], hostMaxWidth: [{
|
|
34732
|
-
type: HostBinding,
|
|
34733
|
-
args: ['style.max-width']
|
|
34734
|
-
}], hostOverflow: [{
|
|
34735
|
-
type: HostBinding,
|
|
34736
|
-
args: ['style.overflow']
|
|
34737
|
-
}], expandTooltip: [{
|
|
34738
|
-
type: Input
|
|
34739
|
-
}], collapseTooltip: [{
|
|
34740
|
-
type: Input
|
|
34741
|
-
}], closeTooltip: [{
|
|
34742
|
-
type: Input
|
|
34743
|
-
}], back: [{
|
|
34744
|
-
type: Output
|
|
34745
|
-
}], tabChange: [{
|
|
34746
|
-
type: Output
|
|
34747
34962
|
}], editDescription: [{
|
|
34748
34963
|
type: Output
|
|
34749
34964
|
}], cancel: [{
|
|
@@ -34762,174 +34977,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
|
|
|
34762
34977
|
type: Output
|
|
34763
34978
|
}], labelAdded: [{
|
|
34764
34979
|
type: Output
|
|
34765
|
-
}], expandToggle: [{
|
|
34766
|
-
type: Output
|
|
34767
|
-
}], close: [{
|
|
34768
|
-
type: Output
|
|
34769
|
-
}] } });
|
|
34770
|
-
|
|
34771
|
-
class DetailDrawerTabContentDirective {
|
|
34772
|
-
constructor(templateRef) {
|
|
34773
|
-
this.templateRef = templateRef;
|
|
34774
|
-
}
|
|
34775
|
-
}
|
|
34776
|
-
DetailDrawerTabContentDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DetailDrawerTabContentDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
|
|
34777
|
-
DetailDrawerTabContentDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.4.0", type: DetailDrawerTabContentDirective, selector: "[cqaTabContent]", ngImport: i0 });
|
|
34778
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DetailDrawerTabContentDirective, decorators: [{
|
|
34779
|
-
type: Directive,
|
|
34780
|
-
args: [{
|
|
34781
|
-
selector: '[cqaTabContent]',
|
|
34782
|
-
}]
|
|
34783
|
-
}], ctorParameters: function () { return [{ type: i0.TemplateRef }]; } });
|
|
34784
|
-
|
|
34785
|
-
class DetailDrawerTabComponent {
|
|
34786
|
-
constructor() {
|
|
34787
|
-
/** Tab label (shown in tooltip on icon button) */
|
|
34788
|
-
this.label = '';
|
|
34789
|
-
/** Tab value (unique identifier) */
|
|
34790
|
-
this.value = '';
|
|
34791
|
-
/** Material icon name for the tab button */
|
|
34792
|
-
this.icon = 'folder';
|
|
34793
|
-
}
|
|
34794
|
-
get contentTemplate() {
|
|
34795
|
-
return this.contentDirective?.templateRef ?? null;
|
|
34796
|
-
}
|
|
34797
|
-
}
|
|
34798
|
-
DetailDrawerTabComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DetailDrawerTabComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
34799
|
-
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 });
|
|
34800
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DetailDrawerTabComponent, decorators: [{
|
|
34801
|
-
type: Component,
|
|
34802
|
-
args: [{
|
|
34803
|
-
selector: 'cqa-detail-drawer-tab',
|
|
34804
|
-
template: '',
|
|
34805
|
-
host: {
|
|
34806
|
-
style: 'display: contents',
|
|
34807
|
-
},
|
|
34808
|
-
}]
|
|
34809
|
-
}], propDecorators: { label: [{
|
|
34810
|
-
type: Input
|
|
34811
|
-
}], value: [{
|
|
34812
|
-
type: Input
|
|
34813
|
-
}], icon: [{
|
|
34814
|
-
type: Input
|
|
34815
|
-
}], contentDirective: [{
|
|
34816
|
-
type: ContentChild,
|
|
34817
|
-
args: [DetailDrawerTabContentDirective]
|
|
34818
|
-
}] } });
|
|
34819
|
-
|
|
34820
|
-
class DetailDrawerComponent {
|
|
34821
|
-
constructor() {
|
|
34822
|
-
/** Currently active tab value */
|
|
34823
|
-
this.activeTab = '';
|
|
34824
|
-
/** Whether to show the close button */
|
|
34825
|
-
this.showCloseButton = true;
|
|
34826
|
-
/** Whether the drawer is expanded */
|
|
34827
|
-
this.expanded = true;
|
|
34828
|
-
/** Panel width when expanded */
|
|
34829
|
-
this.expandedWidth = '280px';
|
|
34830
|
-
/** Maximum width when expanded (e.g. '600px', '30vw'). Default: 30% of viewport */
|
|
34831
|
-
this.maxExpandedWidth = '30vw';
|
|
34832
|
-
/** Panel width when collapsed */
|
|
34833
|
-
this.collapsedWidth = '56px';
|
|
34834
|
-
this.expandTooltip = 'Expand';
|
|
34835
|
-
this.collapseTooltip = 'Collapse';
|
|
34836
|
-
this.closeTooltip = 'Close';
|
|
34837
|
-
this.activeTabChange = new EventEmitter();
|
|
34838
|
-
this.expandToggle = new EventEmitter();
|
|
34839
|
-
this.close = new EventEmitter();
|
|
34840
|
-
}
|
|
34841
|
-
get hostWidth() {
|
|
34842
|
-
return this.expanded ? this.expandedWidth : this.collapsedWidth;
|
|
34843
|
-
}
|
|
34844
|
-
get hostMinWidth() {
|
|
34845
|
-
return this.expanded && this.minExpandedWidth ? this.minExpandedWidth : null;
|
|
34846
|
-
}
|
|
34847
|
-
get hostMaxWidth() {
|
|
34848
|
-
return this.expanded ? this.maxExpandedWidth : null;
|
|
34849
|
-
}
|
|
34850
|
-
ngAfterContentInit() {
|
|
34851
|
-
this.ensureActiveTab();
|
|
34852
|
-
}
|
|
34853
|
-
ngAfterContentChecked() {
|
|
34854
|
-
this.ensureActiveTab();
|
|
34855
|
-
}
|
|
34856
|
-
ensureActiveTab() {
|
|
34857
|
-
const tabs = this.tabComponents?.toArray() ?? [];
|
|
34858
|
-
if (tabs.length > 0 && !this.activeTab) {
|
|
34859
|
-
this.activeTab = tabs[0].value;
|
|
34860
|
-
this.activeTabChange.emit(this.activeTab);
|
|
34861
|
-
}
|
|
34862
|
-
}
|
|
34863
|
-
onTabClick(tab) {
|
|
34864
|
-
// If drawer is collapsed, open it (but never close on tab click)
|
|
34865
|
-
if (!this.expanded) {
|
|
34866
|
-
this.expandToggle.emit();
|
|
34867
|
-
}
|
|
34868
|
-
// Select the tab
|
|
34869
|
-
if (tab.value !== this.activeTab) {
|
|
34870
|
-
this.activeTab = tab.value;
|
|
34871
|
-
this.activeTabChange.emit(this.activeTab);
|
|
34872
|
-
}
|
|
34873
|
-
}
|
|
34874
|
-
onExpandToggle() {
|
|
34875
|
-
this.expandToggle.emit();
|
|
34876
|
-
}
|
|
34877
|
-
onClose() {
|
|
34878
|
-
this.close.emit();
|
|
34879
|
-
}
|
|
34880
|
-
trackByValue(_i, tab) {
|
|
34881
|
-
return tab.value;
|
|
34882
|
-
}
|
|
34883
|
-
isTabActive(tab) {
|
|
34884
|
-
return tab.value === this.activeTab;
|
|
34885
|
-
}
|
|
34886
|
-
}
|
|
34887
|
-
DetailDrawerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DetailDrawerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
34888
|
-
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 });
|
|
34889
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DetailDrawerComponent, decorators: [{
|
|
34890
|
-
type: Component,
|
|
34891
|
-
args: [{ selector: 'cqa-detail-drawer', changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
34892
|
-
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)]',
|
|
34893
|
-
style: 'transition: width 0.3s ease-in-out',
|
|
34894
|
-
}, 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: [] }]
|
|
34895
|
-
}], propDecorators: { tabComponents: [{
|
|
34896
|
-
type: ContentChildren,
|
|
34897
|
-
args: [DetailDrawerTabComponent]
|
|
34898
|
-
}], activeTab: [{
|
|
34899
|
-
type: Input
|
|
34900
|
-
}], showCloseButton: [{
|
|
34901
|
-
type: Input
|
|
34902
|
-
}], expanded: [{
|
|
34903
|
-
type: Input
|
|
34904
|
-
}], expandedWidth: [{
|
|
34905
|
-
type: Input
|
|
34906
|
-
}], minExpandedWidth: [{
|
|
34907
|
-
type: Input
|
|
34908
|
-
}], maxExpandedWidth: [{
|
|
34909
|
-
type: Input
|
|
34910
|
-
}], collapsedWidth: [{
|
|
34911
|
-
type: Input
|
|
34912
|
-
}], hostWidth: [{
|
|
34913
|
-
type: HostBinding,
|
|
34914
|
-
args: ['style.width']
|
|
34915
|
-
}], hostMinWidth: [{
|
|
34916
|
-
type: HostBinding,
|
|
34917
|
-
args: ['style.min-width']
|
|
34918
|
-
}], hostMaxWidth: [{
|
|
34919
|
-
type: HostBinding,
|
|
34920
|
-
args: ['style.max-width']
|
|
34921
|
-
}], expandTooltip: [{
|
|
34922
|
-
type: Input
|
|
34923
|
-
}], collapseTooltip: [{
|
|
34924
|
-
type: Input
|
|
34925
|
-
}], closeTooltip: [{
|
|
34926
|
-
type: Input
|
|
34927
|
-
}], activeTabChange: [{
|
|
34928
|
-
type: Output
|
|
34929
|
-
}], expandToggle: [{
|
|
34930
|
-
type: Output
|
|
34931
|
-
}], close: [{
|
|
34932
|
-
type: Output
|
|
34933
34980
|
}] } });
|
|
34934
34981
|
|
|
34935
34982
|
class StepBuilderGroupComponent {
|