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