@cqa-lib/cqa-ui 1.1.263 → 1.1.265
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/test-case-details/element-popup/element-form/element-form.component.mjs +15 -3
- package/fesm2015/cqa-lib-cqa-ui.mjs +571 -677
- package/fesm2015/cqa-lib-cqa-ui.mjs.map +1 -1
- package/fesm2020/cqa-lib-cqa-ui.mjs +571 -677
- 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/test-case-details/element-popup/element-form/element-form.component.d.ts +4 -0
- package/package.json +1 -1
- package/styles.css +1 -1
|
@@ -19330,12 +19330,23 @@ class ElementFormComponent {
|
|
|
19330
19330
|
this.addTag();
|
|
19331
19331
|
}
|
|
19332
19332
|
}
|
|
19333
|
+
/** Tags to render as chips (limited) */
|
|
19334
|
+
get visibleTags() {
|
|
19335
|
+
if (!this.formLabels || this.formLabels.length) {
|
|
19336
|
+
return this.formLabels || [];
|
|
19337
|
+
}
|
|
19338
|
+
return [];
|
|
19339
|
+
}
|
|
19340
|
+
/** Tooltip text showing all tags */
|
|
19341
|
+
get allTagsTooltip() {
|
|
19342
|
+
return (this.formLabels || []).join(', ');
|
|
19343
|
+
}
|
|
19333
19344
|
}
|
|
19334
19345
|
ElementFormComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: ElementFormComponent, deps: [{ token: i1$1.FormBuilder, optional: true }, { token: i0.ChangeDetectorRef, optional: true }], target: i0.ɵɵFactoryTarget.Component });
|
|
19335
|
-
ElementFormComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: ElementFormComponent, selector: "cqa-element-form", inputs: { elementId: "elementId", element: "element", screenNameOptions: "screenNameOptions", hasMoreScreenNames: "hasMoreScreenNames", isLoadingScreenNames: "isLoadingScreenNames", isElementLoading: "isElementLoading", isEditMode: "isEditMode", isCreateMode: "isCreateMode", isEditInDepthAvailable: "isEditInDepthAvailable" }, outputs: { createElement: "createElement", updateElement: "updateElement", createScreenNameRequest: "createScreenNameRequest", searchScreenName: "searchScreenName", loadMoreScreenNames: "loadMoreScreenNames", cancel: "cancel", editInDepth: "editInDepth" }, host: { classAttribute: "cqa-ui-root" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"cqa-flex cqa-flex-col cqa-gap-4 cqa-px-1 cqa-pt-3\">\n <div *ngIf=\"isElementLoading && isEditMode\" class=\"cqa-flex cqa-flex-col cqa-items-center cqa-justify-center cqa-gap-3 cqa-py-8\">\n <svg class=\"cqa-animate-spin cqa-h-6 cqa-w-6 cqa-text-[#3F43EE]\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle class=\"cqa-opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"4\"></circle>\n <path class=\"cqa-opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"></path>\n </svg>\n <span class=\"cqa-text-[#6B7280] cqa-text-sm\">Loading element data...</span>\n </div>\n <div *ngIf=\"!isElementLoading\" class=\"cqa-flex cqa-gap-1.5\">\n <cqa-custom-input \n class=\"cqa-w-1/2\" \n label=\"Name\" \n placeholder=\"default-element\"\n [value]=\"getFormControlValue('name')\"\n [errors]=\"getFormControl('name')?.touched && getFormControl('name')?.invalid ? ['Name is required'] : []\"\n [required]=\"true\"\n (valueChange)=\"onFormControlChange('name', $event)\">\n </cqa-custom-input>\n <div class=\"cqa-w-1/2\">\n <cqa-dynamic-select [form]=\"form\" [config]=\"screenNameSelectConfig\"\n (addCustomValue)=\"createScreenNameRequest.emit($event.value)\"\n class=\"cqa-w-full\">\n </cqa-dynamic-select>\n <div *ngIf=\"getFormControl('screenNameId')?.touched && getFormControl('screenNameId')?.invalid\" class=\"cqa-flex cqa-flex-col cqa-gap-1 cqa-mt-1.5\">\n <div class=\"cqa-flex cqa-items-start cqa-gap-1.5\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 14 14\"\n fill=\"none\"\n class=\"cqa-flex-shrink-0 cqa-mt-0.5\">\n <path d=\"M7 1.75C4.1 1.75 1.75 4.1 1.75 7C1.75 9.9 4.1 12.25 7 12.25C9.9 12.25 12.25 9.9 12.25 7C12.25 4.1 9.9 1.75 7 1.75ZM7 9.625C6.65625 9.625 6.375 9.34375 6.375 9V7C6.375 6.65625 6.65625 6.375 7 6.375C7.34375 6.375 7.625 6.65625 7.625 7V9C7.625 9.34375 7.34375 9.625 7 9.625ZM7.625 5.25H6.375V4H7.625V5.25Z\" fill=\"#EF4444\"/>\n </svg>\n <span class=\"cqa-text-xs cqa-text-[#EF4444] cqa-font-medium cqa-leading-[18px]\">\n Screen Name is required\n </span>\n </div>\n </div>\n </div>\n </div>\n <ng-container *ngIf=\"!isElementLoading\">\n <cqa-custom-input \n class=\"cqa-w-full\" \n label=\"Enter Value\" \n placeholder=\"#default_id or xpath\"\n [value]=\"getFormControlValue('value')\"\n [errors]=\"getFormControl('value')?.touched && getFormControl('value')?.invalid ? ['Value is required'] : []\"\n [required]=\"true\"\n (valueChange)=\"onFormControlChange('value', $event)\">\n </cqa-custom-input>\n <div class=\"cqa-w-full\">\n <label class=\"cqa-block cqa-text-[14px] cqa-font-medium cqa-text-[#374151] cqa-mb-1\">Labels (tags)</label>\n <div
|
|
19346
|
+
ElementFormComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: ElementFormComponent, selector: "cqa-element-form", inputs: { elementId: "elementId", element: "element", screenNameOptions: "screenNameOptions", hasMoreScreenNames: "hasMoreScreenNames", isLoadingScreenNames: "isLoadingScreenNames", isElementLoading: "isElementLoading", isEditMode: "isEditMode", isCreateMode: "isCreateMode", isEditInDepthAvailable: "isEditInDepthAvailable" }, outputs: { createElement: "createElement", updateElement: "updateElement", createScreenNameRequest: "createScreenNameRequest", searchScreenName: "searchScreenName", loadMoreScreenNames: "loadMoreScreenNames", cancel: "cancel", editInDepth: "editInDepth" }, host: { classAttribute: "cqa-ui-root" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"cqa-flex cqa-flex-col cqa-gap-4 cqa-px-1 cqa-pt-3\">\n <div *ngIf=\"isElementLoading && isEditMode\" class=\"cqa-flex cqa-flex-col cqa-items-center cqa-justify-center cqa-gap-3 cqa-py-8\">\n <svg class=\"cqa-animate-spin cqa-h-6 cqa-w-6 cqa-text-[#3F43EE]\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle class=\"cqa-opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"4\"></circle>\n <path class=\"cqa-opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"></path>\n </svg>\n <span class=\"cqa-text-[#6B7280] cqa-text-sm\">Loading element data...</span>\n </div>\n <div *ngIf=\"!isElementLoading\" class=\"cqa-flex cqa-gap-1.5\">\n <cqa-custom-input \n class=\"cqa-w-1/2\" \n label=\"Name\" \n placeholder=\"default-element\"\n [value]=\"getFormControlValue('name')\"\n [errors]=\"getFormControl('name')?.touched && getFormControl('name')?.invalid ? ['Name is required'] : []\"\n [required]=\"true\"\n (valueChange)=\"onFormControlChange('name', $event)\">\n </cqa-custom-input>\n <div class=\"cqa-w-1/2\">\n <cqa-dynamic-select [form]=\"form\" [config]=\"screenNameSelectConfig\"\n (addCustomValue)=\"createScreenNameRequest.emit($event.value)\"\n class=\"cqa-w-full\">\n </cqa-dynamic-select>\n <div *ngIf=\"getFormControl('screenNameId')?.touched && getFormControl('screenNameId')?.invalid\" class=\"cqa-flex cqa-flex-col cqa-gap-1 cqa-mt-1.5\">\n <div class=\"cqa-flex cqa-items-start cqa-gap-1.5\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 14 14\"\n fill=\"none\"\n class=\"cqa-flex-shrink-0 cqa-mt-0.5\">\n <path d=\"M7 1.75C4.1 1.75 1.75 4.1 1.75 7C1.75 9.9 4.1 12.25 7 12.25C9.9 12.25 12.25 9.9 12.25 7C12.25 4.1 9.9 1.75 7 1.75ZM7 9.625C6.65625 9.625 6.375 9.34375 6.375 9V7C6.375 6.65625 6.65625 6.375 7 6.375C7.34375 6.375 7.625 6.65625 7.625 7V9C7.625 9.34375 7.34375 9.625 7 9.625ZM7.625 5.25H6.375V4H7.625V5.25Z\" fill=\"#EF4444\"/>\n </svg>\n <span class=\"cqa-text-xs cqa-text-[#EF4444] cqa-font-medium cqa-leading-[18px]\">\n Screen Name is required\n </span>\n </div>\n </div>\n </div>\n </div>\n <ng-container *ngIf=\"!isElementLoading\">\n <cqa-custom-input \n class=\"cqa-w-full\" \n label=\"Enter Value\" \n placeholder=\"#default_id or xpath\"\n [value]=\"getFormControlValue('value')\"\n [errors]=\"getFormControl('value')?.touched && getFormControl('value')?.invalid ? ['Value is required'] : []\"\n [required]=\"true\"\n (valueChange)=\"onFormControlChange('value', $event)\">\n </cqa-custom-input>\n <div class=\"cqa-w-full\">\n <label class=\"cqa-block cqa-text-[14px] cqa-font-medium cqa-text-[#374151] cqa-mb-1\">Labels (tags)</label>\n <div\n class=\"cqa-flex cqa-flex-wrap cqa-gap-2 cqa-p-2 cqa-border cqa-border-solid cqa-border-gray-200 cqa-rounded-md cqa-min-h-[42px] cqa-max-h-[80px] cqa-overflow-y-auto cqa-scrollbar-thin cqa-scrollbar-track-transparent cqa-scrollbar-thumb-[#E5E7EB] cqa-scrollbar-thumb-rounded-full cqa-scrollbar-thumb-hover:cqa-bg-[#D1D5DB]\"\n *ngIf=\"formLabels?.length; else noTagsContainer\">\n <span *ngFor=\"let tag of visibleTags\"\n class=\"cqa-inline-flex cqa-items-center cqa-gap-1 cqa-px-2 cqa-py-1 cqa-bg-[#eff6ff] cqa-border cqa-border-[#c8e0ff] cqa-rounded-[8px] cqa-text-[12px] cqa-text-[#3F43EE]\"\n [matTooltip]=\"tag\"\n matTooltipPosition=\"above\"\n style=\"max-width: 140px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;\">\n <span class=\"cqa-max-w-full cqa-truncate\">{{ tag }}</span>\n <button type=\"button\" (click)=\"removeTag(tag)\" class=\"cqa-p-0.5 hover:cqa-bg-[#c8e0ff] cqa-rounded cqa-cursor-pointer cqa-h-[16px] cqa-w-[16px]\">\n <mat-icon class=\"!cqa-w-3 !cqa-h-3 !cqa-text-[14px]\">close</mat-icon>\n </button>\n </span>\n <input type=\"text\"\n class=\"cqa-flex-1 cqa-min-w-[120px] cqa-px-2 cqa-py-1 cqa-text-sm cqa-border-0 cqa-outline-none cqa-bg-transparent\"\n placeholder=\"Type and press Enter to add\"\n [(ngModel)]=\"tagInputValue\"\n (keydown)=\"onTagInputKeydown($event)\"\n (blur)=\"addTag()\"\n [ngModelOptions]=\"{standalone: true}\">\n </div>\n <ng-template #noTagsContainer>\n <div class=\"cqa-flex cqa-flex-wrap cqa-gap-2 cqa-p-2 cqa-border cqa-border-solid cqa-border-gray-200 cqa-rounded-md cqa-min-h-[42px]\">\n <input type=\"text\"\n class=\"cqa-flex-1 cqa-min-w-[120px] cqa-px-2 cqa-py-1 cqa-text-sm cqa-border-0 cqa-outline-none cqa-bg-transparent\"\n placeholder=\"Type and press Enter to add\"\n [(ngModel)]=\"tagInputValue\"\n (keydown)=\"onTagInputKeydown($event)\"\n (blur)=\"addTag()\"\n [ngModelOptions]=\"{standalone: true}\">\n </div>\n </ng-template>\n </div>\n\n <div class=\"cqa-flex cqa-flex-col cqa-gap-3\">\n <div class=\"cqa-flex cqa-items-stretch cqa-gap-2 cqa-w-full\">\n <div class=\"cqa-flex-1 cqa-min-w-0\">\n <cqa-button variant=\"outlined\" btnSize=\"lg\" [text]=\"(elementId ? 'Cancel' : 'Select from Element list')\" [fullWidth]=\"true\" (clicked)=\"onCancel()\"\n [customClass]=\"'cqa-text-[14px] cqa-py-[9px] cqa-border-[#414146]'\" [disabled]=\"saving\"></cqa-button>\n </div>\n <div class=\"cqa-flex-1 cqa-min-w-0\">\n <cqa-button variant=\"filled\" btnSize=\"lg\" [text]=\"saving ? 'Saving...' : (isEditMode ? 'Update' : 'Create')\" [fullWidth]=\"true\" (clicked)=\"onApply()\"\n [customClass]=\"'cqa-text-[14px] cqa-py-[9px] cqa-border-[#3F43EE]'\" [disabled]=\"saving\"></cqa-button>\n </div>\n </div>\n </div>\n <a href=\"#\" *ngIf=\"isEditInDepthAvailable\" (click)=\"onEditInDepth($event)\"\n class=\"cqa-text-[#3F43EE] cqa-text-[12px] cqa-leading-[18px] cqa-font-medium cqa-flex cqa-items-center cqa-gap-1.5 cqa-no-underline hover:cqa-no-underline cqa-self-center\">\n <mat-icon class=\"!cqa-w-4 !cqa-h-4 !cqa-text-[16px]\">open_in_new</mat-icon>\n Edit in depth (open detailed right panel)\n </a>\n </ng-container>\n</div>\n\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: DynamicSelectFieldComponent, selector: "cqa-dynamic-select", inputs: ["form", "config"], outputs: ["selectionChange", "selectClick", "searchChange", "loadMore", "addCustomValue"] }, { type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: ButtonComponent, selector: "cqa-button", inputs: ["variant", "btnSize", "disabled", "icon", "iconPosition", "fullWidth", "iconColor", "type", "text", "customClass", "inlineStyles", "tooltip", "tooltipPosition"], outputs: ["clicked"] }], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i5.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
19336
19347
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: ElementFormComponent, decorators: [{
|
|
19337
19348
|
type: Component,
|
|
19338
|
-
args: [{ selector: 'cqa-element-form', host: { class: 'cqa-ui-root' }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"cqa-flex cqa-flex-col cqa-gap-4 cqa-px-1 cqa-pt-3\">\n <div *ngIf=\"isElementLoading && isEditMode\" class=\"cqa-flex cqa-flex-col cqa-items-center cqa-justify-center cqa-gap-3 cqa-py-8\">\n <svg class=\"cqa-animate-spin cqa-h-6 cqa-w-6 cqa-text-[#3F43EE]\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle class=\"cqa-opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"4\"></circle>\n <path class=\"cqa-opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"></path>\n </svg>\n <span class=\"cqa-text-[#6B7280] cqa-text-sm\">Loading element data...</span>\n </div>\n <div *ngIf=\"!isElementLoading\" class=\"cqa-flex cqa-gap-1.5\">\n <cqa-custom-input \n class=\"cqa-w-1/2\" \n label=\"Name\" \n placeholder=\"default-element\"\n [value]=\"getFormControlValue('name')\"\n [errors]=\"getFormControl('name')?.touched && getFormControl('name')?.invalid ? ['Name is required'] : []\"\n [required]=\"true\"\n (valueChange)=\"onFormControlChange('name', $event)\">\n </cqa-custom-input>\n <div class=\"cqa-w-1/2\">\n <cqa-dynamic-select [form]=\"form\" [config]=\"screenNameSelectConfig\"\n (addCustomValue)=\"createScreenNameRequest.emit($event.value)\"\n class=\"cqa-w-full\">\n </cqa-dynamic-select>\n <div *ngIf=\"getFormControl('screenNameId')?.touched && getFormControl('screenNameId')?.invalid\" class=\"cqa-flex cqa-flex-col cqa-gap-1 cqa-mt-1.5\">\n <div class=\"cqa-flex cqa-items-start cqa-gap-1.5\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 14 14\"\n fill=\"none\"\n class=\"cqa-flex-shrink-0 cqa-mt-0.5\">\n <path d=\"M7 1.75C4.1 1.75 1.75 4.1 1.75 7C1.75 9.9 4.1 12.25 7 12.25C9.9 12.25 12.25 9.9 12.25 7C12.25 4.1 9.9 1.75 7 1.75ZM7 9.625C6.65625 9.625 6.375 9.34375 6.375 9V7C6.375 6.65625 6.65625 6.375 7 6.375C7.34375 6.375 7.625 6.65625 7.625 7V9C7.625 9.34375 7.34375 9.625 7 9.625ZM7.625 5.25H6.375V4H7.625V5.25Z\" fill=\"#EF4444\"/>\n </svg>\n <span class=\"cqa-text-xs cqa-text-[#EF4444] cqa-font-medium cqa-leading-[18px]\">\n Screen Name is required\n </span>\n </div>\n </div>\n </div>\n </div>\n <ng-container *ngIf=\"!isElementLoading\">\n <cqa-custom-input \n class=\"cqa-w-full\" \n label=\"Enter Value\" \n placeholder=\"#default_id or xpath\"\n [value]=\"getFormControlValue('value')\"\n [errors]=\"getFormControl('value')?.touched && getFormControl('value')?.invalid ? ['Value is required'] : []\"\n [required]=\"true\"\n (valueChange)=\"onFormControlChange('value', $event)\">\n </cqa-custom-input>\n <div class=\"cqa-w-full\">\n <label class=\"cqa-block cqa-text-[14px] cqa-font-medium cqa-text-[#374151] cqa-mb-1\">Labels (tags)</label>\n <div
|
|
19349
|
+
args: [{ selector: 'cqa-element-form', host: { class: 'cqa-ui-root' }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"cqa-flex cqa-flex-col cqa-gap-4 cqa-px-1 cqa-pt-3\">\n <div *ngIf=\"isElementLoading && isEditMode\" class=\"cqa-flex cqa-flex-col cqa-items-center cqa-justify-center cqa-gap-3 cqa-py-8\">\n <svg class=\"cqa-animate-spin cqa-h-6 cqa-w-6 cqa-text-[#3F43EE]\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle class=\"cqa-opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"4\"></circle>\n <path class=\"cqa-opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"></path>\n </svg>\n <span class=\"cqa-text-[#6B7280] cqa-text-sm\">Loading element data...</span>\n </div>\n <div *ngIf=\"!isElementLoading\" class=\"cqa-flex cqa-gap-1.5\">\n <cqa-custom-input \n class=\"cqa-w-1/2\" \n label=\"Name\" \n placeholder=\"default-element\"\n [value]=\"getFormControlValue('name')\"\n [errors]=\"getFormControl('name')?.touched && getFormControl('name')?.invalid ? ['Name is required'] : []\"\n [required]=\"true\"\n (valueChange)=\"onFormControlChange('name', $event)\">\n </cqa-custom-input>\n <div class=\"cqa-w-1/2\">\n <cqa-dynamic-select [form]=\"form\" [config]=\"screenNameSelectConfig\"\n (addCustomValue)=\"createScreenNameRequest.emit($event.value)\"\n class=\"cqa-w-full\">\n </cqa-dynamic-select>\n <div *ngIf=\"getFormControl('screenNameId')?.touched && getFormControl('screenNameId')?.invalid\" class=\"cqa-flex cqa-flex-col cqa-gap-1 cqa-mt-1.5\">\n <div class=\"cqa-flex cqa-items-start cqa-gap-1.5\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 14 14\"\n fill=\"none\"\n class=\"cqa-flex-shrink-0 cqa-mt-0.5\">\n <path d=\"M7 1.75C4.1 1.75 1.75 4.1 1.75 7C1.75 9.9 4.1 12.25 7 12.25C9.9 12.25 12.25 9.9 12.25 7C12.25 4.1 9.9 1.75 7 1.75ZM7 9.625C6.65625 9.625 6.375 9.34375 6.375 9V7C6.375 6.65625 6.65625 6.375 7 6.375C7.34375 6.375 7.625 6.65625 7.625 7V9C7.625 9.34375 7.34375 9.625 7 9.625ZM7.625 5.25H6.375V4H7.625V5.25Z\" fill=\"#EF4444\"/>\n </svg>\n <span class=\"cqa-text-xs cqa-text-[#EF4444] cqa-font-medium cqa-leading-[18px]\">\n Screen Name is required\n </span>\n </div>\n </div>\n </div>\n </div>\n <ng-container *ngIf=\"!isElementLoading\">\n <cqa-custom-input \n class=\"cqa-w-full\" \n label=\"Enter Value\" \n placeholder=\"#default_id or xpath\"\n [value]=\"getFormControlValue('value')\"\n [errors]=\"getFormControl('value')?.touched && getFormControl('value')?.invalid ? ['Value is required'] : []\"\n [required]=\"true\"\n (valueChange)=\"onFormControlChange('value', $event)\">\n </cqa-custom-input>\n <div class=\"cqa-w-full\">\n <label class=\"cqa-block cqa-text-[14px] cqa-font-medium cqa-text-[#374151] cqa-mb-1\">Labels (tags)</label>\n <div\n class=\"cqa-flex cqa-flex-wrap cqa-gap-2 cqa-p-2 cqa-border cqa-border-solid cqa-border-gray-200 cqa-rounded-md cqa-min-h-[42px] cqa-max-h-[80px] cqa-overflow-y-auto cqa-scrollbar-thin cqa-scrollbar-track-transparent cqa-scrollbar-thumb-[#E5E7EB] cqa-scrollbar-thumb-rounded-full cqa-scrollbar-thumb-hover:cqa-bg-[#D1D5DB]\"\n *ngIf=\"formLabels?.length; else noTagsContainer\">\n <span *ngFor=\"let tag of visibleTags\"\n class=\"cqa-inline-flex cqa-items-center cqa-gap-1 cqa-px-2 cqa-py-1 cqa-bg-[#eff6ff] cqa-border cqa-border-[#c8e0ff] cqa-rounded-[8px] cqa-text-[12px] cqa-text-[#3F43EE]\"\n [matTooltip]=\"tag\"\n matTooltipPosition=\"above\"\n style=\"max-width: 140px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;\">\n <span class=\"cqa-max-w-full cqa-truncate\">{{ tag }}</span>\n <button type=\"button\" (click)=\"removeTag(tag)\" class=\"cqa-p-0.5 hover:cqa-bg-[#c8e0ff] cqa-rounded cqa-cursor-pointer cqa-h-[16px] cqa-w-[16px]\">\n <mat-icon class=\"!cqa-w-3 !cqa-h-3 !cqa-text-[14px]\">close</mat-icon>\n </button>\n </span>\n <input type=\"text\"\n class=\"cqa-flex-1 cqa-min-w-[120px] cqa-px-2 cqa-py-1 cqa-text-sm cqa-border-0 cqa-outline-none cqa-bg-transparent\"\n placeholder=\"Type and press Enter to add\"\n [(ngModel)]=\"tagInputValue\"\n (keydown)=\"onTagInputKeydown($event)\"\n (blur)=\"addTag()\"\n [ngModelOptions]=\"{standalone: true}\">\n </div>\n <ng-template #noTagsContainer>\n <div class=\"cqa-flex cqa-flex-wrap cqa-gap-2 cqa-p-2 cqa-border cqa-border-solid cqa-border-gray-200 cqa-rounded-md cqa-min-h-[42px]\">\n <input type=\"text\"\n class=\"cqa-flex-1 cqa-min-w-[120px] cqa-px-2 cqa-py-1 cqa-text-sm cqa-border-0 cqa-outline-none cqa-bg-transparent\"\n placeholder=\"Type and press Enter to add\"\n [(ngModel)]=\"tagInputValue\"\n (keydown)=\"onTagInputKeydown($event)\"\n (blur)=\"addTag()\"\n [ngModelOptions]=\"{standalone: true}\">\n </div>\n </ng-template>\n </div>\n\n <div class=\"cqa-flex cqa-flex-col cqa-gap-3\">\n <div class=\"cqa-flex cqa-items-stretch cqa-gap-2 cqa-w-full\">\n <div class=\"cqa-flex-1 cqa-min-w-0\">\n <cqa-button variant=\"outlined\" btnSize=\"lg\" [text]=\"(elementId ? 'Cancel' : 'Select from Element list')\" [fullWidth]=\"true\" (clicked)=\"onCancel()\"\n [customClass]=\"'cqa-text-[14px] cqa-py-[9px] cqa-border-[#414146]'\" [disabled]=\"saving\"></cqa-button>\n </div>\n <div class=\"cqa-flex-1 cqa-min-w-0\">\n <cqa-button variant=\"filled\" btnSize=\"lg\" [text]=\"saving ? 'Saving...' : (isEditMode ? 'Update' : 'Create')\" [fullWidth]=\"true\" (clicked)=\"onApply()\"\n [customClass]=\"'cqa-text-[14px] cqa-py-[9px] cqa-border-[#3F43EE]'\" [disabled]=\"saving\"></cqa-button>\n </div>\n </div>\n </div>\n <a href=\"#\" *ngIf=\"isEditInDepthAvailable\" (click)=\"onEditInDepth($event)\"\n class=\"cqa-text-[#3F43EE] cqa-text-[12px] cqa-leading-[18px] cqa-font-medium cqa-flex cqa-items-center cqa-gap-1.5 cqa-no-underline hover:cqa-no-underline cqa-self-center\">\n <mat-icon class=\"!cqa-w-4 !cqa-h-4 !cqa-text-[16px]\">open_in_new</mat-icon>\n Edit in depth (open detailed right panel)\n </a>\n </ng-container>\n</div>\n\n\n" }]
|
|
19339
19350
|
}], ctorParameters: function () {
|
|
19340
19351
|
return [{ type: i1$1.FormBuilder, decorators: [{
|
|
19341
19352
|
type: Optional
|
|
@@ -33513,252 +33524,526 @@ const DETAIL_SIDE_PANEL_SCROLL_STYLES = `
|
|
|
33513
33524
|
}
|
|
33514
33525
|
`;
|
|
33515
33526
|
|
|
33516
|
-
|
|
33517
|
-
|
|
33518
|
-
|
|
33519
|
-
|
|
33520
|
-
|
|
33521
|
-
|
|
33522
|
-
|
|
33523
|
-
testDataProfile: 'testDataProfile',
|
|
33524
|
-
testDataSet: 'testDataSet',
|
|
33525
|
-
videoRecording: 'videoRecording',
|
|
33526
|
-
enableAiSmartness: 'enableAiSmartness',
|
|
33527
|
-
defaultAiAction: 'defaultAiAction',
|
|
33528
|
-
knowledgeBaseDefaultTestCase: 'knowledgeBaseDefaultTestCase',
|
|
33529
|
-
useAiMetadata: 'useAiMetadata',
|
|
33530
|
-
defaultBrowser: 'defaultBrowser',
|
|
33531
|
-
defaultViewport: 'defaultViewport',
|
|
33532
|
-
deviceType: 'deviceType',
|
|
33533
|
-
deviceOS: 'deviceOS',
|
|
33534
|
-
};
|
|
33535
|
-
const FREQUENTLY_USED_LABELS = [
|
|
33536
|
-
'Case',
|
|
33537
|
-
'Critical',
|
|
33538
|
-
'PO',
|
|
33539
|
-
'Upload',
|
|
33540
|
-
'Validation',
|
|
33541
|
-
'Review',
|
|
33542
|
-
'Edge-cases',
|
|
33543
|
-
'Security',
|
|
33544
|
-
'Integration',
|
|
33545
|
-
'Smoke',
|
|
33546
|
-
];
|
|
33547
|
-
class TestCaseDetailsEditComponent {
|
|
33548
|
-
constructor(cdr) {
|
|
33549
|
-
this.cdr = cdr;
|
|
33550
|
-
this.descriptionTitle = 'Description';
|
|
33551
|
-
this.descriptionContent = '';
|
|
33552
|
-
/** When true, description uses Trix rich text editor (Bold, Italic, etc.). Host app must load Trix. */
|
|
33553
|
-
this.enableMarkdown = false;
|
|
33554
|
-
this.metadataItems = [];
|
|
33555
|
-
this.labels = [];
|
|
33556
|
-
this.configTitle = 'Configuration';
|
|
33557
|
-
this.configSections = [];
|
|
33558
|
-
this.configSectionsRow2 = [];
|
|
33559
|
-
/** Optional list of prerequisite test case options for the multi-select. If not provided, uses default sample options. */
|
|
33560
|
-
this.prerequisiteCaseOptions = [];
|
|
33561
|
-
/** Platform: 'web' shows Default Browser + Viewport; 'mobile' shows Device Type + OS. Defaults to 'web'. */
|
|
33562
|
-
this.platform = 'web';
|
|
33563
|
-
/** When true, hides Priority, Type, and Test Data Set fields (step groups don't have these). Defaults to false. */
|
|
33564
|
-
this.isStepGroup = false;
|
|
33565
|
-
/**
|
|
33566
|
-
* Override config per select key. Use for:
|
|
33567
|
-
* - API-driven options: pass options array (update when API returns)
|
|
33568
|
-
* - Server-side search: serverSearch: true, onSearch in override or listen to selectSearch
|
|
33569
|
-
* - Infinite scroll: hasMore: true, onLoadMore in override or listen to selectLoadMore
|
|
33570
|
-
* - Initial fetch on open: initialFetchOnOpen: true
|
|
33571
|
-
*/
|
|
33572
|
-
this.selectConfigOverrides = {};
|
|
33573
|
-
this.save = new EventEmitter();
|
|
33574
|
-
this.cancel = new EventEmitter();
|
|
33575
|
-
/** Emitted when user searches in a select (serverSearch mode). Call API and update options via selectConfigOverrides. */
|
|
33576
|
-
this.selectSearch = new EventEmitter();
|
|
33577
|
-
/** Emitted when user scrolls to load more. Call API, append to options via selectConfigOverrides. */
|
|
33578
|
-
this.selectLoadMore = new EventEmitter();
|
|
33579
|
-
/** Emitted when a select panel is opened. Use to call API for initial load (e.g. when initialFetchOnOpen). */
|
|
33580
|
-
this.selectOpened = new EventEmitter();
|
|
33581
|
-
/** Emitted when selection changes in any select. */
|
|
33582
|
-
this.selectionChange = new EventEmitter();
|
|
33583
|
-
/** Emitted when user adds a new custom label via the "New" option. */
|
|
33584
|
-
this.labelAdded = new EventEmitter();
|
|
33585
|
-
/** Form state */
|
|
33586
|
-
this.editDescription = '';
|
|
33587
|
-
this.editStatus = '';
|
|
33588
|
-
this.editPriority = '';
|
|
33589
|
-
this.editLabels = [];
|
|
33590
|
-
this.testCaseTimeout = '';
|
|
33591
|
-
this.waitTimeoutLocators = '';
|
|
33592
|
-
this.autoWaitEnabled = false;
|
|
33593
|
-
this.retryFailedSteps = '';
|
|
33594
|
-
this.configExpanded = true;
|
|
33595
|
-
this.executionExpanded = true;
|
|
33596
|
-
this.aiConfigExpanded = true;
|
|
33597
|
-
this.waitsRetriesExpanded = true;
|
|
33598
|
-
this.deviceExpanded = true;
|
|
33599
|
-
this.keyFlagsExpanded = true;
|
|
33600
|
-
this.mobileTestingEnabled = false;
|
|
33601
|
-
this.extensionUseEnabled = false;
|
|
33602
|
-
this.dataDrivenEnabled = false;
|
|
33603
|
-
this.frequentlyUsedLabels = FREQUENTLY_USED_LABELS;
|
|
33604
|
-
/** FormGroup for cqa-dynamic-select bindings */
|
|
33605
|
-
this.editForm = new FormGroup({
|
|
33606
|
-
status: new FormControl(''),
|
|
33607
|
-
priority: new FormControl(''),
|
|
33608
|
-
type: new FormControl(''),
|
|
33609
|
-
labels: new FormControl([]),
|
|
33610
|
-
prerequisiteCases: new FormControl([]),
|
|
33611
|
-
testDataProfile: new FormControl(''),
|
|
33612
|
-
testDataSet: new FormControl(''),
|
|
33613
|
-
defaultBrowser: new FormControl(''),
|
|
33614
|
-
videoRecording: new FormControl(''),
|
|
33615
|
-
defaultViewport: new FormControl(''),
|
|
33616
|
-
deviceType: new FormControl(''),
|
|
33617
|
-
deviceOS: new FormControl(''),
|
|
33618
|
-
enableAiSmartness: new FormControl(''),
|
|
33619
|
-
defaultAiAction: new FormControl(''),
|
|
33620
|
-
knowledgeBaseDefaultTestCase: new FormControl(''),
|
|
33621
|
-
useAiMetadata: new FormControl(''),
|
|
33622
|
-
});
|
|
33623
|
-
/** Cached configs to avoid new object refs each change detection (prevents infinite loops) */
|
|
33624
|
-
this.statusSelectConfig = {
|
|
33625
|
-
key: 'status',
|
|
33626
|
-
label: '',
|
|
33627
|
-
placeholder: 'Status',
|
|
33628
|
-
searchable: false,
|
|
33629
|
-
options: [
|
|
33630
|
-
{ value: 'Draft', name: 'Draft' },
|
|
33631
|
-
{ value: 'In Review', name: 'In Review' },
|
|
33632
|
-
{ value: 'Approved', name: 'Approved' },
|
|
33633
|
-
{ value: 'Active', name: 'Active' },
|
|
33634
|
-
{ value: 'Inactive', name: 'Inactive' },
|
|
33635
|
-
{ value: 'Blocked', name: 'Blocked' },
|
|
33636
|
-
],
|
|
33637
|
-
};
|
|
33638
|
-
this.typeSelectConfig = {
|
|
33639
|
-
key: 'type',
|
|
33640
|
-
label: '',
|
|
33641
|
-
placeholder: 'Type',
|
|
33642
|
-
searchable: true,
|
|
33643
|
-
options: [],
|
|
33644
|
-
};
|
|
33645
|
-
this.testDataProfileSelectConfig = {
|
|
33646
|
-
key: 'testDataProfile',
|
|
33647
|
-
label: '',
|
|
33648
|
-
placeholder: 'Test Data Profile',
|
|
33649
|
-
searchable: true,
|
|
33650
|
-
options: [],
|
|
33651
|
-
};
|
|
33652
|
-
this.testDataSetSelectConfig = {
|
|
33653
|
-
key: 'testDataSet',
|
|
33654
|
-
label: '',
|
|
33655
|
-
placeholder: 'Test Data Set',
|
|
33656
|
-
searchable: true,
|
|
33657
|
-
options: [],
|
|
33658
|
-
};
|
|
33659
|
-
this.defaultPrerequisiteCaseOptions = [
|
|
33660
|
-
{ value: 'TC-001', name: 'TC-001: Login flow' },
|
|
33661
|
-
{ value: 'TC-002', name: 'TC-002: User registration' },
|
|
33662
|
-
{ value: 'TC-003', name: 'TC-003: Password reset' },
|
|
33663
|
-
{ value: 'TC-004', name: 'TC-004: Dashboard load' },
|
|
33664
|
-
{ value: 'TC-005', name: 'TC-005: API health check' },
|
|
33527
|
+
class DetailSidePanelComponent {
|
|
33528
|
+
constructor() {
|
|
33529
|
+
/** Tabs - each tab has a side panel icon button; tabs and buttons are 1:1. Host defines tabs and content. */
|
|
33530
|
+
this.tabs = [
|
|
33531
|
+
{ label: 'Test Case', value: 'test-case', icon: 'description' },
|
|
33532
|
+
{ label: 'Data Library', value: 'data-library', icon: 'folder' },
|
|
33533
|
+
{ label: 'Variables', value: 'variables', icon: 'code' },
|
|
33665
33534
|
];
|
|
33666
|
-
|
|
33667
|
-
|
|
33668
|
-
|
|
33669
|
-
|
|
33670
|
-
|
|
33671
|
-
|
|
33672
|
-
|
|
33673
|
-
|
|
33674
|
-
|
|
33675
|
-
|
|
33676
|
-
|
|
33677
|
-
|
|
33678
|
-
|
|
33679
|
-
|
|
33680
|
-
|
|
33681
|
-
|
|
33682
|
-
|
|
33683
|
-
|
|
33684
|
-
|
|
33685
|
-
|
|
33686
|
-
|
|
33687
|
-
|
|
33688
|
-
|
|
33689
|
-
this.
|
|
33690
|
-
|
|
33691
|
-
|
|
33692
|
-
|
|
33693
|
-
|
|
33694
|
-
|
|
33695
|
-
|
|
33696
|
-
|
|
33697
|
-
|
|
33698
|
-
|
|
33699
|
-
|
|
33700
|
-
|
|
33701
|
-
|
|
33702
|
-
|
|
33703
|
-
|
|
33704
|
-
|
|
33705
|
-
|
|
33706
|
-
|
|
33707
|
-
|
|
33708
|
-
|
|
33709
|
-
|
|
33710
|
-
|
|
33711
|
-
|
|
33712
|
-
|
|
33713
|
-
|
|
33714
|
-
|
|
33715
|
-
|
|
33716
|
-
|
|
33717
|
-
|
|
33718
|
-
|
|
33719
|
-
|
|
33720
|
-
|
|
33721
|
-
|
|
33722
|
-
|
|
33723
|
-
|
|
33724
|
-
|
|
33725
|
-
|
|
33726
|
-
|
|
33727
|
-
|
|
33728
|
-
|
|
33729
|
-
|
|
33730
|
-
|
|
33731
|
-
|
|
33732
|
-
|
|
33733
|
-
|
|
33734
|
-
|
|
33735
|
-
|
|
33736
|
-
|
|
33737
|
-
|
|
33738
|
-
|
|
33739
|
-
|
|
33740
|
-
|
|
33741
|
-
|
|
33742
|
-
|
|
33743
|
-
|
|
33744
|
-
|
|
33745
|
-
|
|
33746
|
-
|
|
33747
|
-
|
|
33748
|
-
|
|
33749
|
-
|
|
33750
|
-
|
|
33751
|
-
|
|
33752
|
-
|
|
33753
|
-
|
|
33754
|
-
|
|
33755
|
-
|
|
33756
|
-
|
|
33757
|
-
|
|
33758
|
-
|
|
33759
|
-
|
|
33760
|
-
|
|
33761
|
-
|
|
33535
|
+
/** Currently active tab value */
|
|
33536
|
+
this.activeTab = 'test-case';
|
|
33537
|
+
/** Whether to show the close button in the side menu */
|
|
33538
|
+
this.showCloseButton = false;
|
|
33539
|
+
/** Whether the panel is expanded (affects expand button icon and panel width) */
|
|
33540
|
+
this.expanded = true;
|
|
33541
|
+
/** Panel width when expanded (e.g. '480px', '25%') */
|
|
33542
|
+
this.expandedWidth = '380px';
|
|
33543
|
+
/** Panel width when collapsed (e.g. '56px' - fits icon bar + back button) */
|
|
33544
|
+
this.collapsedWidth = '56px';
|
|
33545
|
+
this.hostOverflow = 'hidden';
|
|
33546
|
+
/** Tooltip for expand button when panel is collapsed */
|
|
33547
|
+
this.expandTooltip = 'Expand';
|
|
33548
|
+
/** Tooltip for expand button when panel is expanded (collapse) */
|
|
33549
|
+
this.collapseTooltip = 'Collapse';
|
|
33550
|
+
/** Tooltip for close button */
|
|
33551
|
+
this.closeTooltip = 'Close';
|
|
33552
|
+
this.back = new EventEmitter();
|
|
33553
|
+
this.tabChange = new EventEmitter();
|
|
33554
|
+
this.expandToggle = new EventEmitter();
|
|
33555
|
+
this.close = new EventEmitter();
|
|
33556
|
+
}
|
|
33557
|
+
get hostWidth() {
|
|
33558
|
+
return this.expanded ? this.expandedWidth : this.collapsedWidth;
|
|
33559
|
+
}
|
|
33560
|
+
get hostMinWidth() {
|
|
33561
|
+
return this.expanded ? this.expandedWidth : this.collapsedWidth;
|
|
33562
|
+
}
|
|
33563
|
+
get hostMaxWidth() {
|
|
33564
|
+
return this.expanded ? this.expandedWidth : this.collapsedWidth;
|
|
33565
|
+
}
|
|
33566
|
+
trackByTabValue(_i, tab) {
|
|
33567
|
+
return tab.value;
|
|
33568
|
+
}
|
|
33569
|
+
onBack() {
|
|
33570
|
+
this.back.emit();
|
|
33571
|
+
}
|
|
33572
|
+
onTabClick(tab) {
|
|
33573
|
+
if (!this.expanded) {
|
|
33574
|
+
this.expandToggle.emit();
|
|
33575
|
+
}
|
|
33576
|
+
if (tab.value !== this.activeTab) {
|
|
33577
|
+
this.tabChange.emit(tab.value);
|
|
33578
|
+
}
|
|
33579
|
+
}
|
|
33580
|
+
onExpandToggle() {
|
|
33581
|
+
this.expandToggle.emit();
|
|
33582
|
+
}
|
|
33583
|
+
onClose() {
|
|
33584
|
+
this.close.emit();
|
|
33585
|
+
}
|
|
33586
|
+
}
|
|
33587
|
+
DetailSidePanelComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DetailSidePanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
33588
|
+
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 });
|
|
33589
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DetailSidePanelComponent, decorators: [{
|
|
33590
|
+
type: Component,
|
|
33591
|
+
args: [{ selector: 'cqa-detail-side-panel', styles: [DETAIL_SIDE_PANEL_SCROLL_STYLES], changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
33592
|
+
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)]',
|
|
33593
|
+
style: 'transition: width 0.3s ease-in-out',
|
|
33594
|
+
}, 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" }]
|
|
33595
|
+
}], propDecorators: { tabs: [{
|
|
33596
|
+
type: Input
|
|
33597
|
+
}], activeTab: [{
|
|
33598
|
+
type: Input
|
|
33599
|
+
}], showCloseButton: [{
|
|
33600
|
+
type: Input
|
|
33601
|
+
}], expanded: [{
|
|
33602
|
+
type: Input
|
|
33603
|
+
}], expandedWidth: [{
|
|
33604
|
+
type: Input
|
|
33605
|
+
}], collapsedWidth: [{
|
|
33606
|
+
type: Input
|
|
33607
|
+
}], hostWidth: [{
|
|
33608
|
+
type: HostBinding,
|
|
33609
|
+
args: ['style.width']
|
|
33610
|
+
}], hostMinWidth: [{
|
|
33611
|
+
type: HostBinding,
|
|
33612
|
+
args: ['style.min-width']
|
|
33613
|
+
}], hostMaxWidth: [{
|
|
33614
|
+
type: HostBinding,
|
|
33615
|
+
args: ['style.max-width']
|
|
33616
|
+
}], hostOverflow: [{
|
|
33617
|
+
type: HostBinding,
|
|
33618
|
+
args: ['style.overflow']
|
|
33619
|
+
}], expandTooltip: [{
|
|
33620
|
+
type: Input
|
|
33621
|
+
}], collapseTooltip: [{
|
|
33622
|
+
type: Input
|
|
33623
|
+
}], closeTooltip: [{
|
|
33624
|
+
type: Input
|
|
33625
|
+
}], back: [{
|
|
33626
|
+
type: Output
|
|
33627
|
+
}], tabChange: [{
|
|
33628
|
+
type: Output
|
|
33629
|
+
}], expandToggle: [{
|
|
33630
|
+
type: Output
|
|
33631
|
+
}], close: [{
|
|
33632
|
+
type: Output
|
|
33633
|
+
}] } });
|
|
33634
|
+
|
|
33635
|
+
class DetailDrawerTabContentDirective {
|
|
33636
|
+
constructor(templateRef) {
|
|
33637
|
+
this.templateRef = templateRef;
|
|
33638
|
+
}
|
|
33639
|
+
}
|
|
33640
|
+
DetailDrawerTabContentDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DetailDrawerTabContentDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
|
|
33641
|
+
DetailDrawerTabContentDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.4.0", type: DetailDrawerTabContentDirective, selector: "[cqaTabContent]", ngImport: i0 });
|
|
33642
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DetailDrawerTabContentDirective, decorators: [{
|
|
33643
|
+
type: Directive,
|
|
33644
|
+
args: [{
|
|
33645
|
+
selector: '[cqaTabContent]',
|
|
33646
|
+
}]
|
|
33647
|
+
}], ctorParameters: function () { return [{ type: i0.TemplateRef }]; } });
|
|
33648
|
+
|
|
33649
|
+
class DetailDrawerTabComponent {
|
|
33650
|
+
constructor() {
|
|
33651
|
+
/** Tab label (shown in tooltip on icon button) */
|
|
33652
|
+
this.label = '';
|
|
33653
|
+
/** Tab value (unique identifier) */
|
|
33654
|
+
this.value = '';
|
|
33655
|
+
/** Material icon name for the tab button */
|
|
33656
|
+
this.icon = 'folder';
|
|
33657
|
+
}
|
|
33658
|
+
get contentTemplate() {
|
|
33659
|
+
var _a, _b;
|
|
33660
|
+
return (_b = (_a = this.contentDirective) === null || _a === void 0 ? void 0 : _a.templateRef) !== null && _b !== void 0 ? _b : null;
|
|
33661
|
+
}
|
|
33662
|
+
}
|
|
33663
|
+
DetailDrawerTabComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DetailDrawerTabComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
33664
|
+
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 });
|
|
33665
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DetailDrawerTabComponent, decorators: [{
|
|
33666
|
+
type: Component,
|
|
33667
|
+
args: [{
|
|
33668
|
+
selector: 'cqa-detail-drawer-tab',
|
|
33669
|
+
template: '',
|
|
33670
|
+
host: {
|
|
33671
|
+
style: 'display: contents',
|
|
33672
|
+
},
|
|
33673
|
+
}]
|
|
33674
|
+
}], propDecorators: { label: [{
|
|
33675
|
+
type: Input
|
|
33676
|
+
}], value: [{
|
|
33677
|
+
type: Input
|
|
33678
|
+
}], icon: [{
|
|
33679
|
+
type: Input
|
|
33680
|
+
}], contentDirective: [{
|
|
33681
|
+
type: ContentChild,
|
|
33682
|
+
args: [DetailDrawerTabContentDirective]
|
|
33683
|
+
}] } });
|
|
33684
|
+
|
|
33685
|
+
class DetailDrawerComponent {
|
|
33686
|
+
constructor() {
|
|
33687
|
+
/** Currently active tab value */
|
|
33688
|
+
this.activeTab = '';
|
|
33689
|
+
/** Whether to show the close button */
|
|
33690
|
+
this.showCloseButton = true;
|
|
33691
|
+
/** Whether the drawer is expanded */
|
|
33692
|
+
this.expanded = true;
|
|
33693
|
+
/** Panel width when expanded */
|
|
33694
|
+
this.expandedWidth = '280px';
|
|
33695
|
+
/** Maximum width when expanded (e.g. '600px', '30vw'). Default: 30% of viewport */
|
|
33696
|
+
this.maxExpandedWidth = '30vw';
|
|
33697
|
+
/** Panel width when collapsed */
|
|
33698
|
+
this.collapsedWidth = '56px';
|
|
33699
|
+
this.expandTooltip = 'Expand';
|
|
33700
|
+
this.collapseTooltip = 'Collapse';
|
|
33701
|
+
this.closeTooltip = 'Close';
|
|
33702
|
+
this.activeTabChange = new EventEmitter();
|
|
33703
|
+
this.expandToggle = new EventEmitter();
|
|
33704
|
+
this.close = new EventEmitter();
|
|
33705
|
+
}
|
|
33706
|
+
get hostWidth() {
|
|
33707
|
+
return this.expanded ? this.expandedWidth : this.collapsedWidth;
|
|
33708
|
+
}
|
|
33709
|
+
get hostMinWidth() {
|
|
33710
|
+
return this.expanded && this.minExpandedWidth ? this.minExpandedWidth : null;
|
|
33711
|
+
}
|
|
33712
|
+
get hostMaxWidth() {
|
|
33713
|
+
return this.expanded ? this.maxExpandedWidth : null;
|
|
33714
|
+
}
|
|
33715
|
+
ngAfterContentInit() {
|
|
33716
|
+
this.ensureActiveTab();
|
|
33717
|
+
}
|
|
33718
|
+
ngAfterContentChecked() {
|
|
33719
|
+
this.ensureActiveTab();
|
|
33720
|
+
}
|
|
33721
|
+
ensureActiveTab() {
|
|
33722
|
+
var _a, _b;
|
|
33723
|
+
const tabs = (_b = (_a = this.tabComponents) === null || _a === void 0 ? void 0 : _a.toArray()) !== null && _b !== void 0 ? _b : [];
|
|
33724
|
+
if (tabs.length > 0 && !this.activeTab) {
|
|
33725
|
+
this.activeTab = tabs[0].value;
|
|
33726
|
+
this.activeTabChange.emit(this.activeTab);
|
|
33727
|
+
}
|
|
33728
|
+
}
|
|
33729
|
+
onTabClick(tab) {
|
|
33730
|
+
// If drawer is collapsed, open it (but never close on tab click)
|
|
33731
|
+
if (!this.expanded) {
|
|
33732
|
+
this.expandToggle.emit();
|
|
33733
|
+
}
|
|
33734
|
+
// Select the tab
|
|
33735
|
+
if (tab.value !== this.activeTab) {
|
|
33736
|
+
this.activeTab = tab.value;
|
|
33737
|
+
this.activeTabChange.emit(this.activeTab);
|
|
33738
|
+
}
|
|
33739
|
+
}
|
|
33740
|
+
onExpandToggle() {
|
|
33741
|
+
this.expandToggle.emit();
|
|
33742
|
+
}
|
|
33743
|
+
onClose() {
|
|
33744
|
+
this.close.emit();
|
|
33745
|
+
}
|
|
33746
|
+
trackByValue(_i, tab) {
|
|
33747
|
+
return tab.value;
|
|
33748
|
+
}
|
|
33749
|
+
isTabActive(tab) {
|
|
33750
|
+
return tab.value === this.activeTab;
|
|
33751
|
+
}
|
|
33752
|
+
}
|
|
33753
|
+
DetailDrawerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DetailDrawerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
33754
|
+
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 });
|
|
33755
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DetailDrawerComponent, decorators: [{
|
|
33756
|
+
type: Component,
|
|
33757
|
+
args: [{ selector: 'cqa-detail-drawer', changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
33758
|
+
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)]',
|
|
33759
|
+
style: 'transition: width 0.3s ease-in-out',
|
|
33760
|
+
}, 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: [] }]
|
|
33761
|
+
}], propDecorators: { tabComponents: [{
|
|
33762
|
+
type: ContentChildren,
|
|
33763
|
+
args: [DetailDrawerTabComponent]
|
|
33764
|
+
}], activeTab: [{
|
|
33765
|
+
type: Input
|
|
33766
|
+
}], showCloseButton: [{
|
|
33767
|
+
type: Input
|
|
33768
|
+
}], expanded: [{
|
|
33769
|
+
type: Input
|
|
33770
|
+
}], expandedWidth: [{
|
|
33771
|
+
type: Input
|
|
33772
|
+
}], minExpandedWidth: [{
|
|
33773
|
+
type: Input
|
|
33774
|
+
}], maxExpandedWidth: [{
|
|
33775
|
+
type: Input
|
|
33776
|
+
}], collapsedWidth: [{
|
|
33777
|
+
type: Input
|
|
33778
|
+
}], hostWidth: [{
|
|
33779
|
+
type: HostBinding,
|
|
33780
|
+
args: ['style.width']
|
|
33781
|
+
}], hostMinWidth: [{
|
|
33782
|
+
type: HostBinding,
|
|
33783
|
+
args: ['style.min-width']
|
|
33784
|
+
}], hostMaxWidth: [{
|
|
33785
|
+
type: HostBinding,
|
|
33786
|
+
args: ['style.max-width']
|
|
33787
|
+
}], expandTooltip: [{
|
|
33788
|
+
type: Input
|
|
33789
|
+
}], collapseTooltip: [{
|
|
33790
|
+
type: Input
|
|
33791
|
+
}], closeTooltip: [{
|
|
33792
|
+
type: Input
|
|
33793
|
+
}], activeTabChange: [{
|
|
33794
|
+
type: Output
|
|
33795
|
+
}], expandToggle: [{
|
|
33796
|
+
type: Output
|
|
33797
|
+
}], close: [{
|
|
33798
|
+
type: Output
|
|
33799
|
+
}] } });
|
|
33800
|
+
|
|
33801
|
+
/** Keys for each dynamic select in test-case-details-edit. Use these with selectConfigOverrides. */
|
|
33802
|
+
const TEST_CASE_DETAILS_SELECT_KEYS = {
|
|
33803
|
+
status: 'status',
|
|
33804
|
+
priority: 'priority',
|
|
33805
|
+
type: 'type',
|
|
33806
|
+
labels: 'labels',
|
|
33807
|
+
prerequisiteCases: 'prerequisiteCases',
|
|
33808
|
+
testDataProfile: 'testDataProfile',
|
|
33809
|
+
testDataSet: 'testDataSet',
|
|
33810
|
+
videoRecording: 'videoRecording',
|
|
33811
|
+
enableAiSmartness: 'enableAiSmartness',
|
|
33812
|
+
defaultAiAction: 'defaultAiAction',
|
|
33813
|
+
knowledgeBaseDefaultTestCase: 'knowledgeBaseDefaultTestCase',
|
|
33814
|
+
useAiMetadata: 'useAiMetadata',
|
|
33815
|
+
defaultBrowser: 'defaultBrowser',
|
|
33816
|
+
defaultViewport: 'defaultViewport',
|
|
33817
|
+
deviceType: 'deviceType',
|
|
33818
|
+
deviceOS: 'deviceOS',
|
|
33819
|
+
};
|
|
33820
|
+
const FREQUENTLY_USED_LABELS = [
|
|
33821
|
+
'Case',
|
|
33822
|
+
'Critical',
|
|
33823
|
+
'PO',
|
|
33824
|
+
'Upload',
|
|
33825
|
+
'Validation',
|
|
33826
|
+
'Review',
|
|
33827
|
+
'Edge-cases',
|
|
33828
|
+
'Security',
|
|
33829
|
+
'Integration',
|
|
33830
|
+
'Smoke',
|
|
33831
|
+
];
|
|
33832
|
+
class TestCaseDetailsEditComponent {
|
|
33833
|
+
constructor(cdr) {
|
|
33834
|
+
this.cdr = cdr;
|
|
33835
|
+
this.descriptionTitle = 'Description';
|
|
33836
|
+
this.descriptionContent = '';
|
|
33837
|
+
/** When true, description uses Trix rich text editor (Bold, Italic, etc.). Host app must load Trix. */
|
|
33838
|
+
this.enableMarkdown = false;
|
|
33839
|
+
this.metadataItems = [];
|
|
33840
|
+
this.labels = [];
|
|
33841
|
+
this.configTitle = 'Configuration';
|
|
33842
|
+
this.configSections = [];
|
|
33843
|
+
this.configSectionsRow2 = [];
|
|
33844
|
+
/** Optional list of prerequisite test case options for the multi-select. If not provided, uses default sample options. */
|
|
33845
|
+
this.prerequisiteCaseOptions = [];
|
|
33846
|
+
/** Platform: 'web' shows Default Browser + Viewport; 'mobile' shows Device Type + OS. Defaults to 'web'. */
|
|
33847
|
+
this.platform = 'web';
|
|
33848
|
+
/** When true, hides Priority, Type, and Test Data Set fields (step groups don't have these). Defaults to false. */
|
|
33849
|
+
this.isStepGroup = false;
|
|
33850
|
+
/**
|
|
33851
|
+
* Override config per select key. Use for:
|
|
33852
|
+
* - API-driven options: pass options array (update when API returns)
|
|
33853
|
+
* - Server-side search: serverSearch: true, onSearch in override or listen to selectSearch
|
|
33854
|
+
* - Infinite scroll: hasMore: true, onLoadMore in override or listen to selectLoadMore
|
|
33855
|
+
* - Initial fetch on open: initialFetchOnOpen: true
|
|
33856
|
+
*/
|
|
33857
|
+
this.selectConfigOverrides = {};
|
|
33858
|
+
this.save = new EventEmitter();
|
|
33859
|
+
this.cancel = new EventEmitter();
|
|
33860
|
+
/** Emitted when user searches in a select (serverSearch mode). Call API and update options via selectConfigOverrides. */
|
|
33861
|
+
this.selectSearch = new EventEmitter();
|
|
33862
|
+
/** Emitted when user scrolls to load more. Call API, append to options via selectConfigOverrides. */
|
|
33863
|
+
this.selectLoadMore = new EventEmitter();
|
|
33864
|
+
/** Emitted when a select panel is opened. Use to call API for initial load (e.g. when initialFetchOnOpen). */
|
|
33865
|
+
this.selectOpened = new EventEmitter();
|
|
33866
|
+
/** Emitted when selection changes in any select. */
|
|
33867
|
+
this.selectionChange = new EventEmitter();
|
|
33868
|
+
/** Emitted when user adds a new custom label via the "New" option. */
|
|
33869
|
+
this.labelAdded = new EventEmitter();
|
|
33870
|
+
/** Form state */
|
|
33871
|
+
this.editDescription = '';
|
|
33872
|
+
this.editStatus = '';
|
|
33873
|
+
this.editPriority = '';
|
|
33874
|
+
this.editLabels = [];
|
|
33875
|
+
this.testCaseTimeout = '';
|
|
33876
|
+
this.waitTimeoutLocators = '';
|
|
33877
|
+
this.autoWaitEnabled = false;
|
|
33878
|
+
this.retryFailedSteps = '';
|
|
33879
|
+
this.configExpanded = true;
|
|
33880
|
+
this.executionExpanded = true;
|
|
33881
|
+
this.aiConfigExpanded = true;
|
|
33882
|
+
this.waitsRetriesExpanded = true;
|
|
33883
|
+
this.deviceExpanded = true;
|
|
33884
|
+
this.keyFlagsExpanded = true;
|
|
33885
|
+
this.mobileTestingEnabled = false;
|
|
33886
|
+
this.extensionUseEnabled = false;
|
|
33887
|
+
this.dataDrivenEnabled = false;
|
|
33888
|
+
this.frequentlyUsedLabels = FREQUENTLY_USED_LABELS;
|
|
33889
|
+
/** FormGroup for cqa-dynamic-select bindings */
|
|
33890
|
+
this.editForm = new FormGroup({
|
|
33891
|
+
status: new FormControl(''),
|
|
33892
|
+
priority: new FormControl(''),
|
|
33893
|
+
type: new FormControl(''),
|
|
33894
|
+
labels: new FormControl([]),
|
|
33895
|
+
prerequisiteCases: new FormControl([]),
|
|
33896
|
+
testDataProfile: new FormControl(''),
|
|
33897
|
+
testDataSet: new FormControl(''),
|
|
33898
|
+
defaultBrowser: new FormControl(''),
|
|
33899
|
+
videoRecording: new FormControl(''),
|
|
33900
|
+
defaultViewport: new FormControl(''),
|
|
33901
|
+
deviceType: new FormControl(''),
|
|
33902
|
+
deviceOS: new FormControl(''),
|
|
33903
|
+
enableAiSmartness: new FormControl(''),
|
|
33904
|
+
defaultAiAction: new FormControl(''),
|
|
33905
|
+
knowledgeBaseDefaultTestCase: new FormControl(''),
|
|
33906
|
+
useAiMetadata: new FormControl(''),
|
|
33907
|
+
});
|
|
33908
|
+
/** Cached configs to avoid new object refs each change detection (prevents infinite loops) */
|
|
33909
|
+
this.statusSelectConfig = {
|
|
33910
|
+
key: 'status',
|
|
33911
|
+
label: '',
|
|
33912
|
+
placeholder: 'Status',
|
|
33913
|
+
searchable: false,
|
|
33914
|
+
options: [
|
|
33915
|
+
{ value: 'Draft', name: 'Draft' },
|
|
33916
|
+
{ value: 'In Review', name: 'In Review' },
|
|
33917
|
+
{ value: 'Approved', name: 'Approved' },
|
|
33918
|
+
{ value: 'Active', name: 'Active' },
|
|
33919
|
+
{ value: 'Inactive', name: 'Inactive' },
|
|
33920
|
+
{ value: 'Blocked', name: 'Blocked' },
|
|
33921
|
+
],
|
|
33922
|
+
};
|
|
33923
|
+
this.typeSelectConfig = {
|
|
33924
|
+
key: 'type',
|
|
33925
|
+
label: '',
|
|
33926
|
+
placeholder: 'Type',
|
|
33927
|
+
searchable: true,
|
|
33928
|
+
options: [],
|
|
33929
|
+
};
|
|
33930
|
+
this.testDataProfileSelectConfig = {
|
|
33931
|
+
key: 'testDataProfile',
|
|
33932
|
+
label: '',
|
|
33933
|
+
placeholder: 'Test Data Profile',
|
|
33934
|
+
searchable: true,
|
|
33935
|
+
options: [],
|
|
33936
|
+
};
|
|
33937
|
+
this.testDataSetSelectConfig = {
|
|
33938
|
+
key: 'testDataSet',
|
|
33939
|
+
label: '',
|
|
33940
|
+
placeholder: 'Test Data Set',
|
|
33941
|
+
searchable: true,
|
|
33942
|
+
options: [],
|
|
33943
|
+
};
|
|
33944
|
+
this.defaultPrerequisiteCaseOptions = [
|
|
33945
|
+
{ value: 'TC-001', name: 'TC-001: Login flow' },
|
|
33946
|
+
{ value: 'TC-002', name: 'TC-002: User registration' },
|
|
33947
|
+
{ value: 'TC-003', name: 'TC-003: Password reset' },
|
|
33948
|
+
{ value: 'TC-004', name: 'TC-004: Dashboard load' },
|
|
33949
|
+
{ value: 'TC-005', name: 'TC-005: API health check' },
|
|
33950
|
+
];
|
|
33951
|
+
this.videoRecordingSelectConfig = {
|
|
33952
|
+
key: 'videoRecording',
|
|
33953
|
+
label: 'Record test execution video',
|
|
33954
|
+
placeholder: 'Select',
|
|
33955
|
+
searchable: false,
|
|
33956
|
+
options: [
|
|
33957
|
+
{ value: 'true', name: 'True' },
|
|
33958
|
+
{ value: 'false', name: 'False' },
|
|
33959
|
+
{ value: 'Org level', name: 'Org level' },
|
|
33960
|
+
],
|
|
33961
|
+
};
|
|
33962
|
+
this.aiMetadataCollectionSelectConfig = {
|
|
33963
|
+
key: 'useAiMetadata',
|
|
33964
|
+
label: 'Enable AI metadata collection',
|
|
33965
|
+
placeholder: 'Select',
|
|
33966
|
+
searchable: false,
|
|
33967
|
+
options: [
|
|
33968
|
+
{ value: 'true', name: 'True' },
|
|
33969
|
+
{ value: 'false', name: 'False' },
|
|
33970
|
+
{ value: 'Org level', name: 'Org level' },
|
|
33971
|
+
],
|
|
33972
|
+
};
|
|
33973
|
+
/** Cached labels config to avoid new object on every CD (prevents freeze) */
|
|
33974
|
+
this._labelsSelectConfigCache = null;
|
|
33975
|
+
this._labelsSelectConfigDirty = true;
|
|
33976
|
+
this.prerequisiteCaseSelectConfig = {
|
|
33977
|
+
key: 'prerequisiteCases',
|
|
33978
|
+
label: 'Prerequisite Case',
|
|
33979
|
+
placeholder: 'Select',
|
|
33980
|
+
searchable: true,
|
|
33981
|
+
multiple: true,
|
|
33982
|
+
optionStyle: 'checkbox',
|
|
33983
|
+
showSelectAll: true,
|
|
33984
|
+
selectAllLabel: 'All',
|
|
33985
|
+
options: [
|
|
33986
|
+
{ value: 'TC-001', name: 'TC-001: Login flow' },
|
|
33987
|
+
{ value: 'TC-002', name: 'TC-002: User registration' },
|
|
33988
|
+
{ value: 'TC-003', name: 'TC-003: Password reset' },
|
|
33989
|
+
{ value: 'TC-004', name: 'TC-004: Dashboard load' },
|
|
33990
|
+
{ value: 'TC-005', name: 'TC-005: API health check' },
|
|
33991
|
+
],
|
|
33992
|
+
};
|
|
33993
|
+
this.defaultViewportSelectConfig = {
|
|
33994
|
+
key: 'defaultViewport',
|
|
33995
|
+
label: 'Default Viewport',
|
|
33996
|
+
placeholder: 'Select',
|
|
33997
|
+
searchable: false,
|
|
33998
|
+
options: [
|
|
33999
|
+
{ value: '1280x720', name: '1280x720' },
|
|
34000
|
+
],
|
|
34001
|
+
};
|
|
34002
|
+
this.deviceTypeSelectConfig = {
|
|
34003
|
+
key: 'deviceType',
|
|
34004
|
+
label: 'Device Type',
|
|
34005
|
+
placeholder: 'Select',
|
|
34006
|
+
searchable: false,
|
|
34007
|
+
options: [
|
|
34008
|
+
{ value: 'iPhone 14', name: 'iPhone 14' },
|
|
34009
|
+
{ value: 'iPhone 15', name: 'iPhone 15' },
|
|
34010
|
+
{ value: 'iPhone 17', name: 'iPhone 17' },
|
|
34011
|
+
{ value: 'Iphone 17', name: 'Iphone 17' },
|
|
34012
|
+
{ value: 'Samsung Galaxy', name: 'Samsung Galaxy' },
|
|
34013
|
+
{ value: 'Pixel', name: 'Pixel' },
|
|
34014
|
+
],
|
|
34015
|
+
};
|
|
34016
|
+
this.deviceOSSelectConfig = {
|
|
34017
|
+
key: 'deviceOS',
|
|
34018
|
+
label: 'OS',
|
|
34019
|
+
placeholder: 'Select',
|
|
34020
|
+
searchable: false,
|
|
34021
|
+
options: [
|
|
34022
|
+
{ value: 'ipa', name: 'iOS (ipa)' },
|
|
34023
|
+
{ value: 'apk', name: 'Android (apk)' },
|
|
34024
|
+
{ value: 'iOS 16', name: 'iOS 16' },
|
|
34025
|
+
{ value: 'iOS 17', name: 'iOS 17' },
|
|
34026
|
+
{ value: 'Android 13', name: 'Android 13' },
|
|
34027
|
+
{ value: 'Android 14', name: 'Android 14' },
|
|
34028
|
+
],
|
|
34029
|
+
};
|
|
34030
|
+
this.defaultBrowserSelectConfig = {
|
|
34031
|
+
key: 'defaultBrowser',
|
|
34032
|
+
label: 'Default Browser',
|
|
34033
|
+
placeholder: 'Chrome',
|
|
34034
|
+
searchable: false,
|
|
34035
|
+
options: [
|
|
34036
|
+
{ value: 'Chrome', name: 'Chrome' },
|
|
34037
|
+
{ value: 'Firefox', name: 'Firefox' },
|
|
34038
|
+
{ value: 'Safari', name: 'Safari' },
|
|
34039
|
+
{ value: 'Edge', name: 'Edge' },
|
|
34040
|
+
],
|
|
34041
|
+
};
|
|
34042
|
+
this.prioritySelectConfig = {
|
|
34043
|
+
key: 'priority',
|
|
34044
|
+
label: '',
|
|
34045
|
+
placeholder: 'Priority',
|
|
34046
|
+
searchable: false,
|
|
33762
34047
|
options: [
|
|
33763
34048
|
{ value: 'Critical', name: 'Critical' },
|
|
33764
34049
|
{ value: 'Major', name: 'Major' },
|
|
@@ -34448,231 +34733,40 @@ class TestCaseDetailsComponent {
|
|
|
34448
34733
|
if (this.startInEditMode) {
|
|
34449
34734
|
this._editing = true;
|
|
34450
34735
|
}
|
|
34451
|
-
}
|
|
34452
|
-
/** Filtered metadata items - excludes Priority and Type for step groups */
|
|
34453
|
-
get filteredMetadataItems() {
|
|
34454
|
-
if (!this.isStepGroup) {
|
|
34455
|
-
return this.metadataItems;
|
|
34456
|
-
}
|
|
34457
|
-
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 : ''); });
|
|
34458
|
-
}
|
|
34459
|
-
onEditClick() {
|
|
34460
|
-
if (this.editing === undefined) {
|
|
34461
|
-
this._editing = true;
|
|
34462
|
-
this.cdr.detectChanges();
|
|
34463
|
-
}
|
|
34464
|
-
this.editDescription.emit();
|
|
34465
|
-
}
|
|
34466
|
-
onSaveChanges(data) {
|
|
34467
|
-
if (this.editing === undefined) {
|
|
34468
|
-
this._editing = false;
|
|
34469
|
-
}
|
|
34470
|
-
this.cdr.detectChanges();
|
|
34471
|
-
this.saveChanges.emit(data);
|
|
34472
|
-
}
|
|
34473
|
-
onCancelEdit() {
|
|
34474
|
-
this.cancel.emit();
|
|
34475
|
-
if (this.editing === undefined) {
|
|
34476
|
-
this._editing = false;
|
|
34477
|
-
}
|
|
34478
|
-
this.cdr.detectChanges();
|
|
34479
|
-
}
|
|
34480
|
-
trackByConfigTitle(_i, section) {
|
|
34481
|
-
return section.title;
|
|
34482
|
-
}
|
|
34483
|
-
trackByMetadataLabel(_i, item) {
|
|
34484
|
-
return item.label;
|
|
34485
|
-
}
|
|
34486
|
-
onMetadataLinkClick(item) {
|
|
34487
|
-
if (item.link) {
|
|
34488
|
-
this.metadataLinkClick.emit(item);
|
|
34489
|
-
}
|
|
34490
|
-
}
|
|
34491
|
-
getStatusDotClass(item) {
|
|
34492
|
-
if (!item.statusColor)
|
|
34493
|
-
return '';
|
|
34494
|
-
switch (item.statusColor) {
|
|
34495
|
-
case 'yellow':
|
|
34496
|
-
return 'cqa-bg-[#EAB308]';
|
|
34497
|
-
case 'red':
|
|
34498
|
-
return 'cqa-bg-[#DC2626]';
|
|
34499
|
-
case 'green':
|
|
34500
|
-
return 'cqa-bg-[#16A34A]';
|
|
34501
|
-
case 'gray':
|
|
34502
|
-
default:
|
|
34503
|
-
return 'cqa-bg-[#94A3B8]';
|
|
34504
|
-
}
|
|
34505
|
-
}
|
|
34506
|
-
/** Text color for metadata value (e.g. red for critical priority) */
|
|
34507
|
-
getValueTextClass(item) {
|
|
34508
|
-
if (item.statusColor === 'red') {
|
|
34509
|
-
return 'cqa-text-[#DC2626]';
|
|
34510
|
-
}
|
|
34511
|
-
return 'cqa-text-[#111827]';
|
|
34512
|
-
}
|
|
34513
|
-
}
|
|
34514
|
-
TestCaseDetailsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TestCaseDetailsComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
34515
|
-
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 });
|
|
34516
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TestCaseDetailsComponent, decorators: [{
|
|
34517
|
-
type: Component,
|
|
34518
|
-
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: [] }]
|
|
34519
|
-
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { editing: [{
|
|
34520
|
-
type: Input
|
|
34521
|
-
}], startInEditMode: [{
|
|
34522
|
-
type: Input
|
|
34523
|
-
}], descriptionTitle: [{
|
|
34524
|
-
type: Input
|
|
34525
|
-
}], descriptionContent: [{
|
|
34526
|
-
type: Input
|
|
34527
|
-
}], enableMarkdown: [{
|
|
34528
|
-
type: Input
|
|
34529
|
-
}], showEditButton: [{
|
|
34530
|
-
type: Input
|
|
34531
|
-
}], metadataItems: [{
|
|
34532
|
-
type: Input
|
|
34533
|
-
}], labels: [{
|
|
34534
|
-
type: Input
|
|
34535
|
-
}], configTitle: [{
|
|
34536
|
-
type: Input
|
|
34537
|
-
}], configSections: [{
|
|
34538
|
-
type: Input
|
|
34539
|
-
}], configSectionsRow2: [{
|
|
34540
|
-
type: Input
|
|
34541
|
-
}], platform: [{
|
|
34542
|
-
type: Input
|
|
34543
|
-
}], isStepGroup: [{
|
|
34544
|
-
type: Input
|
|
34545
|
-
}], selectConfigOverrides: [{
|
|
34546
|
-
type: Input
|
|
34547
|
-
}], editDescription: [{
|
|
34548
|
-
type: Output
|
|
34549
|
-
}], cancel: [{
|
|
34550
|
-
type: Output
|
|
34551
|
-
}], saveChanges: [{
|
|
34552
|
-
type: Output
|
|
34553
|
-
}], metadataLinkClick: [{
|
|
34554
|
-
type: Output
|
|
34555
|
-
}], selectSearch: [{
|
|
34556
|
-
type: Output
|
|
34557
|
-
}], selectLoadMore: [{
|
|
34558
|
-
type: Output
|
|
34559
|
-
}], selectOpened: [{
|
|
34560
|
-
type: Output
|
|
34561
|
-
}], selectionChange: [{
|
|
34562
|
-
type: Output
|
|
34563
|
-
}], labelAdded: [{
|
|
34564
|
-
type: Output
|
|
34565
|
-
}] } });
|
|
34566
|
-
|
|
34567
|
-
class DetailSidePanelComponent {
|
|
34568
|
-
constructor(cdr) {
|
|
34569
|
-
this.cdr = cdr;
|
|
34570
|
-
/** Tabs - each tab has a side panel icon button; tabs and buttons are 1:1 */
|
|
34571
|
-
this.tabs = [
|
|
34572
|
-
{ label: 'Test Case', value: 'test-case', icon: 'description' },
|
|
34573
|
-
{ label: 'Data Library', value: 'data-library', icon: 'folder' },
|
|
34574
|
-
{ label: 'Variables', value: 'variables', icon: 'code' },
|
|
34575
|
-
];
|
|
34576
|
-
/** Currently active tab value */
|
|
34577
|
-
this.activeTab = 'test-case';
|
|
34578
|
-
/** Description section title */
|
|
34579
|
-
this.descriptionTitle = 'Description';
|
|
34580
|
-
/** Description text content */
|
|
34581
|
-
this.descriptionContent = '';
|
|
34582
|
-
/** When true, description uses rich text editor and renders as HTML. Host app must load Trix. */
|
|
34583
|
-
this.enableMarkdown = false;
|
|
34584
|
-
/** Whether to show the Edit button in the Description header */
|
|
34585
|
-
this.showEditButton = true;
|
|
34586
|
-
/** Metadata items (Created on, Status, Priority, etc.) */
|
|
34587
|
-
this.metadataItems = [];
|
|
34588
|
-
/** Labels/tags (e.g. Automation, API, SDK, UI/UX) */
|
|
34589
|
-
this.labels = [];
|
|
34590
|
-
/** Configuration sections - full width (e.g. Execution, AI Configuration) */
|
|
34591
|
-
this.configSections = [];
|
|
34592
|
-
/** Optional config sections displayed in a 2-column row (e.g. Waits & Retries, Device) */
|
|
34593
|
-
this.configSectionsRow2 = [];
|
|
34594
|
-
/** Platform: 'web' or 'mobile'. Defaults to 'web'. Used for Device Settings. */
|
|
34595
|
-
this.platform = 'web';
|
|
34596
|
-
/** When true, hides Priority, Type, Test Data Set, and Prerequisite Case (step groups don't have these). Defaults to false. */
|
|
34597
|
-
this.isStepGroup = false;
|
|
34598
|
-
/** Configuration section title */
|
|
34599
|
-
this.configTitle = 'Configuration';
|
|
34600
|
-
/** Whether to show the close button in the side menu */
|
|
34601
|
-
this.showCloseButton = false;
|
|
34602
|
-
/** When true, test case details start in edit mode (useful for Storybook). */
|
|
34603
|
-
this.startInEditMode = false;
|
|
34604
|
-
/** Override config per select for API-driven options, server search, load more. */
|
|
34605
|
-
this.selectConfigOverrides = {};
|
|
34606
|
-
/** Whether the panel is expanded (affects expand button icon and panel width) */
|
|
34607
|
-
this.expanded = true;
|
|
34608
|
-
/** Panel width when expanded (e.g. '480px', '25%') */
|
|
34609
|
-
this.expandedWidth = '380px';
|
|
34610
|
-
/** Panel width when collapsed (e.g. '56px' - fits icon bar + back button) */
|
|
34611
|
-
this.collapsedWidth = '56px';
|
|
34612
|
-
this.hostOverflow = 'hidden';
|
|
34613
|
-
/** Tooltip for expand button when panel is collapsed */
|
|
34614
|
-
this.expandTooltip = 'Expand';
|
|
34615
|
-
/** Tooltip for expand button when panel is expanded (collapse) */
|
|
34616
|
-
this.collapseTooltip = 'Collapse';
|
|
34617
|
-
/** Tooltip for close button */
|
|
34618
|
-
this.closeTooltip = 'Close';
|
|
34619
|
-
this.back = new EventEmitter();
|
|
34620
|
-
this.tabChange = new EventEmitter();
|
|
34621
|
-
this.editDescription = new EventEmitter();
|
|
34622
|
-
this.cancel = new EventEmitter();
|
|
34623
|
-
this.saveChanges = new EventEmitter();
|
|
34624
|
-
this.metadataLinkClick = new EventEmitter();
|
|
34625
|
-
this.selectSearch = new EventEmitter();
|
|
34626
|
-
this.selectLoadMore = new EventEmitter();
|
|
34627
|
-
this.selectOpened = new EventEmitter();
|
|
34628
|
-
this.selectionChange = new EventEmitter();
|
|
34629
|
-
this.labelAdded = new EventEmitter();
|
|
34630
|
-
this.expandToggle = new EventEmitter();
|
|
34631
|
-
this.close = new EventEmitter();
|
|
34632
|
-
}
|
|
34633
|
-
get hostWidth() {
|
|
34634
|
-
return this.expanded ? this.expandedWidth : this.collapsedWidth;
|
|
34635
|
-
}
|
|
34636
|
-
get hostMinWidth() {
|
|
34637
|
-
return this.expanded ? this.expandedWidth : this.collapsedWidth;
|
|
34638
|
-
}
|
|
34639
|
-
get hostMaxWidth() {
|
|
34640
|
-
return this.expanded ? this.expandedWidth : this.collapsedWidth;
|
|
34641
|
-
}
|
|
34642
|
-
trackByTabValue(_i, tab) {
|
|
34643
|
-
return tab.value;
|
|
34644
|
-
}
|
|
34645
|
-
trackByMetadataLabel(_i, item) {
|
|
34646
|
-
return item.label;
|
|
34647
|
-
}
|
|
34648
|
-
trackByConfigTitle(_i, section) {
|
|
34649
|
-
return section.title;
|
|
34650
|
-
}
|
|
34651
|
-
onBack() {
|
|
34652
|
-
this.back.emit();
|
|
34653
|
-
}
|
|
34654
|
-
onTabClick(tab) {
|
|
34655
|
-
if (!this.expanded) {
|
|
34656
|
-
this.expandToggle.emit();
|
|
34657
|
-
}
|
|
34658
|
-
if (tab.value !== this.activeTab) {
|
|
34659
|
-
this.tabChange.emit(tab.value);
|
|
34736
|
+
}
|
|
34737
|
+
/** Filtered metadata items - excludes Priority and Type for step groups */
|
|
34738
|
+
get filteredMetadataItems() {
|
|
34739
|
+
if (!this.isStepGroup) {
|
|
34740
|
+
return this.metadataItems;
|
|
34660
34741
|
}
|
|
34742
|
+
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 : ''); });
|
|
34661
34743
|
}
|
|
34662
|
-
|
|
34744
|
+
onEditClick() {
|
|
34745
|
+
if (this.editing === undefined) {
|
|
34746
|
+
this._editing = true;
|
|
34747
|
+
this.cdr.detectChanges();
|
|
34748
|
+
}
|
|
34663
34749
|
this.editDescription.emit();
|
|
34664
34750
|
}
|
|
34665
34751
|
onSaveChanges(data) {
|
|
34752
|
+
if (this.editing === undefined) {
|
|
34753
|
+
this._editing = false;
|
|
34754
|
+
}
|
|
34755
|
+
this.cdr.detectChanges();
|
|
34666
34756
|
this.saveChanges.emit(data);
|
|
34667
34757
|
}
|
|
34668
|
-
|
|
34758
|
+
onCancelEdit() {
|
|
34669
34759
|
this.cancel.emit();
|
|
34760
|
+
if (this.editing === undefined) {
|
|
34761
|
+
this._editing = false;
|
|
34762
|
+
}
|
|
34763
|
+
this.cdr.detectChanges();
|
|
34670
34764
|
}
|
|
34671
|
-
|
|
34672
|
-
|
|
34765
|
+
trackByConfigTitle(_i, section) {
|
|
34766
|
+
return section.title;
|
|
34673
34767
|
}
|
|
34674
|
-
|
|
34675
|
-
|
|
34768
|
+
trackByMetadataLabel(_i, item) {
|
|
34769
|
+
return item.label;
|
|
34676
34770
|
}
|
|
34677
34771
|
onMetadataLinkClick(item) {
|
|
34678
34772
|
if (item.link) {
|
|
@@ -34694,18 +34788,22 @@ class DetailSidePanelComponent {
|
|
|
34694
34788
|
return 'cqa-bg-[#94A3B8]';
|
|
34695
34789
|
}
|
|
34696
34790
|
}
|
|
34791
|
+
/** Text color for metadata value (e.g. red for critical priority) */
|
|
34792
|
+
getValueTextClass(item) {
|
|
34793
|
+
if (item.statusColor === 'red') {
|
|
34794
|
+
return 'cqa-text-[#DC2626]';
|
|
34795
|
+
}
|
|
34796
|
+
return 'cqa-text-[#111827]';
|
|
34797
|
+
}
|
|
34697
34798
|
}
|
|
34698
|
-
|
|
34699
|
-
|
|
34700
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type:
|
|
34799
|
+
TestCaseDetailsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TestCaseDetailsComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
34800
|
+
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 });
|
|
34801
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TestCaseDetailsComponent, decorators: [{
|
|
34701
34802
|
type: Component,
|
|
34702
|
-
args: [{ selector: 'cqa-
|
|
34703
|
-
|
|
34704
|
-
style: 'transition: width 0.3s ease-in-out',
|
|
34705
|
-
}, 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" }]
|
|
34706
|
-
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { tabs: [{
|
|
34803
|
+
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: [] }]
|
|
34804
|
+
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { editing: [{
|
|
34707
34805
|
type: Input
|
|
34708
|
-
}],
|
|
34806
|
+
}], startInEditMode: [{
|
|
34709
34807
|
type: Input
|
|
34710
34808
|
}], descriptionTitle: [{
|
|
34711
34809
|
type: Input
|
|
@@ -34719,6 +34817,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
|
|
|
34719
34817
|
type: Input
|
|
34720
34818
|
}], labels: [{
|
|
34721
34819
|
type: Input
|
|
34820
|
+
}], configTitle: [{
|
|
34821
|
+
type: Input
|
|
34722
34822
|
}], configSections: [{
|
|
34723
34823
|
type: Input
|
|
34724
34824
|
}], configSectionsRow2: [{
|
|
@@ -34727,44 +34827,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
|
|
|
34727
34827
|
type: Input
|
|
34728
34828
|
}], isStepGroup: [{
|
|
34729
34829
|
type: Input
|
|
34730
|
-
}], configTitle: [{
|
|
34731
|
-
type: Input
|
|
34732
|
-
}], showCloseButton: [{
|
|
34733
|
-
type: Input
|
|
34734
|
-
}], startInEditMode: [{
|
|
34735
|
-
type: Input
|
|
34736
|
-
}], editing: [{
|
|
34737
|
-
type: Input
|
|
34738
34830
|
}], selectConfigOverrides: [{
|
|
34739
34831
|
type: Input
|
|
34740
|
-
}], expanded: [{
|
|
34741
|
-
type: Input
|
|
34742
|
-
}], expandedWidth: [{
|
|
34743
|
-
type: Input
|
|
34744
|
-
}], collapsedWidth: [{
|
|
34745
|
-
type: Input
|
|
34746
|
-
}], hostWidth: [{
|
|
34747
|
-
type: HostBinding,
|
|
34748
|
-
args: ['style.width']
|
|
34749
|
-
}], hostMinWidth: [{
|
|
34750
|
-
type: HostBinding,
|
|
34751
|
-
args: ['style.min-width']
|
|
34752
|
-
}], hostMaxWidth: [{
|
|
34753
|
-
type: HostBinding,
|
|
34754
|
-
args: ['style.max-width']
|
|
34755
|
-
}], hostOverflow: [{
|
|
34756
|
-
type: HostBinding,
|
|
34757
|
-
args: ['style.overflow']
|
|
34758
|
-
}], expandTooltip: [{
|
|
34759
|
-
type: Input
|
|
34760
|
-
}], collapseTooltip: [{
|
|
34761
|
-
type: Input
|
|
34762
|
-
}], closeTooltip: [{
|
|
34763
|
-
type: Input
|
|
34764
|
-
}], back: [{
|
|
34765
|
-
type: Output
|
|
34766
|
-
}], tabChange: [{
|
|
34767
|
-
type: Output
|
|
34768
34832
|
}], editDescription: [{
|
|
34769
34833
|
type: Output
|
|
34770
34834
|
}], cancel: [{
|
|
@@ -34783,176 +34847,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
|
|
|
34783
34847
|
type: Output
|
|
34784
34848
|
}], labelAdded: [{
|
|
34785
34849
|
type: Output
|
|
34786
|
-
}], expandToggle: [{
|
|
34787
|
-
type: Output
|
|
34788
|
-
}], close: [{
|
|
34789
|
-
type: Output
|
|
34790
|
-
}] } });
|
|
34791
|
-
|
|
34792
|
-
class DetailDrawerTabContentDirective {
|
|
34793
|
-
constructor(templateRef) {
|
|
34794
|
-
this.templateRef = templateRef;
|
|
34795
|
-
}
|
|
34796
|
-
}
|
|
34797
|
-
DetailDrawerTabContentDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DetailDrawerTabContentDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
|
|
34798
|
-
DetailDrawerTabContentDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.4.0", type: DetailDrawerTabContentDirective, selector: "[cqaTabContent]", ngImport: i0 });
|
|
34799
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DetailDrawerTabContentDirective, decorators: [{
|
|
34800
|
-
type: Directive,
|
|
34801
|
-
args: [{
|
|
34802
|
-
selector: '[cqaTabContent]',
|
|
34803
|
-
}]
|
|
34804
|
-
}], ctorParameters: function () { return [{ type: i0.TemplateRef }]; } });
|
|
34805
|
-
|
|
34806
|
-
class DetailDrawerTabComponent {
|
|
34807
|
-
constructor() {
|
|
34808
|
-
/** Tab label (shown in tooltip on icon button) */
|
|
34809
|
-
this.label = '';
|
|
34810
|
-
/** Tab value (unique identifier) */
|
|
34811
|
-
this.value = '';
|
|
34812
|
-
/** Material icon name for the tab button */
|
|
34813
|
-
this.icon = 'folder';
|
|
34814
|
-
}
|
|
34815
|
-
get contentTemplate() {
|
|
34816
|
-
var _a, _b;
|
|
34817
|
-
return (_b = (_a = this.contentDirective) === null || _a === void 0 ? void 0 : _a.templateRef) !== null && _b !== void 0 ? _b : null;
|
|
34818
|
-
}
|
|
34819
|
-
}
|
|
34820
|
-
DetailDrawerTabComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DetailDrawerTabComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
34821
|
-
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 });
|
|
34822
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DetailDrawerTabComponent, decorators: [{
|
|
34823
|
-
type: Component,
|
|
34824
|
-
args: [{
|
|
34825
|
-
selector: 'cqa-detail-drawer-tab',
|
|
34826
|
-
template: '',
|
|
34827
|
-
host: {
|
|
34828
|
-
style: 'display: contents',
|
|
34829
|
-
},
|
|
34830
|
-
}]
|
|
34831
|
-
}], propDecorators: { label: [{
|
|
34832
|
-
type: Input
|
|
34833
|
-
}], value: [{
|
|
34834
|
-
type: Input
|
|
34835
|
-
}], icon: [{
|
|
34836
|
-
type: Input
|
|
34837
|
-
}], contentDirective: [{
|
|
34838
|
-
type: ContentChild,
|
|
34839
|
-
args: [DetailDrawerTabContentDirective]
|
|
34840
|
-
}] } });
|
|
34841
|
-
|
|
34842
|
-
class DetailDrawerComponent {
|
|
34843
|
-
constructor() {
|
|
34844
|
-
/** Currently active tab value */
|
|
34845
|
-
this.activeTab = '';
|
|
34846
|
-
/** Whether to show the close button */
|
|
34847
|
-
this.showCloseButton = true;
|
|
34848
|
-
/** Whether the drawer is expanded */
|
|
34849
|
-
this.expanded = true;
|
|
34850
|
-
/** Panel width when expanded */
|
|
34851
|
-
this.expandedWidth = '280px';
|
|
34852
|
-
/** Maximum width when expanded (e.g. '600px', '30vw'). Default: 30% of viewport */
|
|
34853
|
-
this.maxExpandedWidth = '30vw';
|
|
34854
|
-
/** Panel width when collapsed */
|
|
34855
|
-
this.collapsedWidth = '56px';
|
|
34856
|
-
this.expandTooltip = 'Expand';
|
|
34857
|
-
this.collapseTooltip = 'Collapse';
|
|
34858
|
-
this.closeTooltip = 'Close';
|
|
34859
|
-
this.activeTabChange = new EventEmitter();
|
|
34860
|
-
this.expandToggle = new EventEmitter();
|
|
34861
|
-
this.close = new EventEmitter();
|
|
34862
|
-
}
|
|
34863
|
-
get hostWidth() {
|
|
34864
|
-
return this.expanded ? this.expandedWidth : this.collapsedWidth;
|
|
34865
|
-
}
|
|
34866
|
-
get hostMinWidth() {
|
|
34867
|
-
return this.expanded && this.minExpandedWidth ? this.minExpandedWidth : null;
|
|
34868
|
-
}
|
|
34869
|
-
get hostMaxWidth() {
|
|
34870
|
-
return this.expanded ? this.maxExpandedWidth : null;
|
|
34871
|
-
}
|
|
34872
|
-
ngAfterContentInit() {
|
|
34873
|
-
this.ensureActiveTab();
|
|
34874
|
-
}
|
|
34875
|
-
ngAfterContentChecked() {
|
|
34876
|
-
this.ensureActiveTab();
|
|
34877
|
-
}
|
|
34878
|
-
ensureActiveTab() {
|
|
34879
|
-
var _a, _b;
|
|
34880
|
-
const tabs = (_b = (_a = this.tabComponents) === null || _a === void 0 ? void 0 : _a.toArray()) !== null && _b !== void 0 ? _b : [];
|
|
34881
|
-
if (tabs.length > 0 && !this.activeTab) {
|
|
34882
|
-
this.activeTab = tabs[0].value;
|
|
34883
|
-
this.activeTabChange.emit(this.activeTab);
|
|
34884
|
-
}
|
|
34885
|
-
}
|
|
34886
|
-
onTabClick(tab) {
|
|
34887
|
-
// If drawer is collapsed, open it (but never close on tab click)
|
|
34888
|
-
if (!this.expanded) {
|
|
34889
|
-
this.expandToggle.emit();
|
|
34890
|
-
}
|
|
34891
|
-
// Select the tab
|
|
34892
|
-
if (tab.value !== this.activeTab) {
|
|
34893
|
-
this.activeTab = tab.value;
|
|
34894
|
-
this.activeTabChange.emit(this.activeTab);
|
|
34895
|
-
}
|
|
34896
|
-
}
|
|
34897
|
-
onExpandToggle() {
|
|
34898
|
-
this.expandToggle.emit();
|
|
34899
|
-
}
|
|
34900
|
-
onClose() {
|
|
34901
|
-
this.close.emit();
|
|
34902
|
-
}
|
|
34903
|
-
trackByValue(_i, tab) {
|
|
34904
|
-
return tab.value;
|
|
34905
|
-
}
|
|
34906
|
-
isTabActive(tab) {
|
|
34907
|
-
return tab.value === this.activeTab;
|
|
34908
|
-
}
|
|
34909
|
-
}
|
|
34910
|
-
DetailDrawerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DetailDrawerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
34911
|
-
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 });
|
|
34912
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: DetailDrawerComponent, decorators: [{
|
|
34913
|
-
type: Component,
|
|
34914
|
-
args: [{ selector: 'cqa-detail-drawer', changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
34915
|
-
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)]',
|
|
34916
|
-
style: 'transition: width 0.3s ease-in-out',
|
|
34917
|
-
}, 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: [] }]
|
|
34918
|
-
}], propDecorators: { tabComponents: [{
|
|
34919
|
-
type: ContentChildren,
|
|
34920
|
-
args: [DetailDrawerTabComponent]
|
|
34921
|
-
}], activeTab: [{
|
|
34922
|
-
type: Input
|
|
34923
|
-
}], showCloseButton: [{
|
|
34924
|
-
type: Input
|
|
34925
|
-
}], expanded: [{
|
|
34926
|
-
type: Input
|
|
34927
|
-
}], expandedWidth: [{
|
|
34928
|
-
type: Input
|
|
34929
|
-
}], minExpandedWidth: [{
|
|
34930
|
-
type: Input
|
|
34931
|
-
}], maxExpandedWidth: [{
|
|
34932
|
-
type: Input
|
|
34933
|
-
}], collapsedWidth: [{
|
|
34934
|
-
type: Input
|
|
34935
|
-
}], hostWidth: [{
|
|
34936
|
-
type: HostBinding,
|
|
34937
|
-
args: ['style.width']
|
|
34938
|
-
}], hostMinWidth: [{
|
|
34939
|
-
type: HostBinding,
|
|
34940
|
-
args: ['style.min-width']
|
|
34941
|
-
}], hostMaxWidth: [{
|
|
34942
|
-
type: HostBinding,
|
|
34943
|
-
args: ['style.max-width']
|
|
34944
|
-
}], expandTooltip: [{
|
|
34945
|
-
type: Input
|
|
34946
|
-
}], collapseTooltip: [{
|
|
34947
|
-
type: Input
|
|
34948
|
-
}], closeTooltip: [{
|
|
34949
|
-
type: Input
|
|
34950
|
-
}], activeTabChange: [{
|
|
34951
|
-
type: Output
|
|
34952
|
-
}], expandToggle: [{
|
|
34953
|
-
type: Output
|
|
34954
|
-
}], close: [{
|
|
34955
|
-
type: Output
|
|
34956
34850
|
}] } });
|
|
34957
34851
|
|
|
34958
34852
|
class StepBuilderGroupComponent {
|