@cqa-lib/cqa-ui 1.1.225 → 1.1.226
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/step-builder/step-builder-action/step-builder-action.component.mjs +267 -44
- package/esm2020/lib/step-builder/step-builder-condition/step-builder-condition.component.mjs +183 -41
- package/esm2020/lib/step-builder/step-builder-loop/step-builder-loop.component.mjs +44 -3
- package/esm2020/lib/step-builder/template-variables-form/template-variables-form.component.mjs +218 -57
- package/esm2020/lib/test-case-details/element-popup/element-form/element-form.component.mjs +277 -0
- package/esm2020/lib/test-case-details/element-popup/element-popup.component.mjs +32 -192
- package/esm2020/lib/ui-kit.module.mjs +6 -1
- package/esm2020/public-api.mjs +2 -1
- package/fesm2015/cqa-lib-cqa-ui.mjs +1016 -325
- package/fesm2015/cqa-lib-cqa-ui.mjs.map +1 -1
- package/fesm2020/cqa-lib-cqa-ui.mjs +996 -316
- package/fesm2020/cqa-lib-cqa-ui.mjs.map +1 -1
- package/lib/step-builder/step-builder-action/step-builder-action.component.d.ts +50 -4
- package/lib/step-builder/step-builder-condition/step-builder-condition.component.d.ts +39 -2
- package/lib/step-builder/step-builder-loop/step-builder-loop.component.d.ts +17 -1
- package/lib/step-builder/template-variables-form/template-variables-form.component.d.ts +56 -5
- package/lib/test-case-details/element-popup/element-form/element-form.component.d.ts +77 -0
- package/lib/test-case-details/element-popup/element-popup.component.d.ts +13 -32
- package/lib/ui-kit.module.d.ts +42 -41
- package/package.json +1 -1
- package/public-api.d.ts +1 -0
- package/styles.css +1 -1
|
@@ -3,7 +3,7 @@ import { EventEmitter, Component, Input, Output, HostListener, ViewChildren, Vie
|
|
|
3
3
|
import * as i2 from '@angular/common';
|
|
4
4
|
import { CommonModule } from '@angular/common';
|
|
5
5
|
import * as i1$1 from '@angular/forms';
|
|
6
|
-
import { NG_VALUE_ACCESSOR, FormControl, FormGroup, Validators, FormBuilder, FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|
6
|
+
import { NG_VALUE_ACCESSOR, FormControl, FormGroup, Validators, FormBuilder, FormArray, FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|
7
7
|
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
|
8
8
|
import * as i1 from '@angular/material/icon';
|
|
9
9
|
import { MatIconModule } from '@angular/material/icon';
|
|
@@ -18442,6 +18442,284 @@ class ElementPopupRef {
|
|
|
18442
18442
|
}
|
|
18443
18443
|
const CUSTOM_ELEMENT_POPUP_REF = new InjectionToken('CUSTOM_ELEMENT_POPUP_REF');
|
|
18444
18444
|
|
|
18445
|
+
class ElementFormComponent {
|
|
18446
|
+
constructor(fb, cdr) {
|
|
18447
|
+
this.cdr = cdr;
|
|
18448
|
+
/** Current element data (for edit mode) */
|
|
18449
|
+
this.element = { title: '', selector: '', labels: [] };
|
|
18450
|
+
/** Screen name options for autocomplete (from API) */
|
|
18451
|
+
this.screenNameOptions = [];
|
|
18452
|
+
/** Whether more screen names are available for infinite scroll */
|
|
18453
|
+
this.hasMoreScreenNames = false;
|
|
18454
|
+
/** True while parent is loading screen names (search or load more) */
|
|
18455
|
+
this.isLoadingScreenNames = false;
|
|
18456
|
+
/** True while parent is fetching latest element data for edit (shows loading state) */
|
|
18457
|
+
this.isElementLoading = false;
|
|
18458
|
+
/** Whether we're in edit mode */
|
|
18459
|
+
this.isEditMode = false;
|
|
18460
|
+
/** Whether we're in create mode */
|
|
18461
|
+
this.isCreateMode = false;
|
|
18462
|
+
/** Whether edit in depth is available */
|
|
18463
|
+
this.isEditInDepthAvailable = true;
|
|
18464
|
+
/** Emitted when user creates a new element (parent should call API) */
|
|
18465
|
+
this.createElement = new EventEmitter();
|
|
18466
|
+
/** Emitted when user updates an element (parent should call API) */
|
|
18467
|
+
this.updateElement = new EventEmitter();
|
|
18468
|
+
/** Emitted when user requests to create a new screen name */
|
|
18469
|
+
this.createScreenNameRequest = new EventEmitter();
|
|
18470
|
+
/** Emitted when user searches screen names (server search) */
|
|
18471
|
+
this.searchScreenName = new EventEmitter();
|
|
18472
|
+
/** Emitted when user scrolls to load more screen names (passes current search query) */
|
|
18473
|
+
this.loadMoreScreenNames = new EventEmitter();
|
|
18474
|
+
/** Emitted when user clicks "Select from Element list" or "Cancel" */
|
|
18475
|
+
this.cancel = new EventEmitter();
|
|
18476
|
+
/** Emitted when user clicks "Edit in depth" */
|
|
18477
|
+
this.editInDepth = new EventEmitter();
|
|
18478
|
+
/** Labels (tags) as string array for multi-tag input */
|
|
18479
|
+
this.formLabels = [];
|
|
18480
|
+
/** Current tag input value */
|
|
18481
|
+
this.tagInputValue = '';
|
|
18482
|
+
/** Whether we're saving (disable buttons) */
|
|
18483
|
+
this.saving = false;
|
|
18484
|
+
this.fb = fb || new FormBuilder();
|
|
18485
|
+
this.initializeForm();
|
|
18486
|
+
}
|
|
18487
|
+
ngOnChanges(changes) {
|
|
18488
|
+
if (changes['screenNameOptions'] || changes['hasMoreScreenNames'] || changes['isLoadingScreenNames']) {
|
|
18489
|
+
this.updateScreenNameSelectConfig();
|
|
18490
|
+
}
|
|
18491
|
+
if ((changes['element'] || changes['elementId']) && this.elementId) {
|
|
18492
|
+
this.populateFormForEdit();
|
|
18493
|
+
}
|
|
18494
|
+
else if (changes['element'] && !this.elementId && this.isCreateMode) {
|
|
18495
|
+
this.populateFormForCreateWithElement();
|
|
18496
|
+
}
|
|
18497
|
+
}
|
|
18498
|
+
ngOnInit() {
|
|
18499
|
+
if (this.elementId) {
|
|
18500
|
+
this.populateFormForEdit();
|
|
18501
|
+
}
|
|
18502
|
+
else if (this.isCreateMode && this.element) {
|
|
18503
|
+
this.populateFormForCreateWithElement();
|
|
18504
|
+
}
|
|
18505
|
+
}
|
|
18506
|
+
initializeForm() {
|
|
18507
|
+
this.form = this.fb.group({
|
|
18508
|
+
name: ['', [Validators.required]],
|
|
18509
|
+
screenNameId: [null, [Validators.required]],
|
|
18510
|
+
value: ['', [Validators.required]],
|
|
18511
|
+
});
|
|
18512
|
+
this.updateScreenNameSelectConfig();
|
|
18513
|
+
}
|
|
18514
|
+
updateScreenNameSelectConfig() {
|
|
18515
|
+
var _a, _b, _c, _d, _e;
|
|
18516
|
+
const opts = (this.screenNameOptions || []).map((o) => ({
|
|
18517
|
+
id: o.id,
|
|
18518
|
+
value: o.id,
|
|
18519
|
+
name: o.name,
|
|
18520
|
+
label: o.name,
|
|
18521
|
+
}));
|
|
18522
|
+
const currentId = (_b = (_a = this.form) === null || _a === void 0 ? void 0 : _a.get('screenNameId')) === null || _b === void 0 ? void 0 : _b.value;
|
|
18523
|
+
if (currentId && ((_c = this.element) === null || _c === void 0 ? void 0 : _c.screenNameId) === currentId && ((_d = this.element) === null || _d === void 0 ? void 0 : _d.screenName)) {
|
|
18524
|
+
const exists = opts.some((o) => o.id === currentId);
|
|
18525
|
+
if (!exists) {
|
|
18526
|
+
opts.unshift({
|
|
18527
|
+
id: currentId,
|
|
18528
|
+
value: currentId,
|
|
18529
|
+
name: String(this.element.screenName),
|
|
18530
|
+
label: String(this.element.screenName),
|
|
18531
|
+
});
|
|
18532
|
+
}
|
|
18533
|
+
}
|
|
18534
|
+
this.screenNameSelectConfig = {
|
|
18535
|
+
key: 'screenNameId',
|
|
18536
|
+
label: 'Screen Name',
|
|
18537
|
+
placeholder: 'Select or create screen',
|
|
18538
|
+
searchable: true,
|
|
18539
|
+
serverSearch: true,
|
|
18540
|
+
allowCustomValue: true,
|
|
18541
|
+
options: opts,
|
|
18542
|
+
hasMore: this.hasMoreScreenNames,
|
|
18543
|
+
isLoading: this.isLoadingScreenNames,
|
|
18544
|
+
onSearch: (q) => this.searchScreenName.emit(q || ''),
|
|
18545
|
+
onLoadMore: (q) => this.loadMoreScreenNames.emit(q || ''),
|
|
18546
|
+
};
|
|
18547
|
+
(_e = this.cdr) === null || _e === void 0 ? void 0 : _e.markForCheck();
|
|
18548
|
+
}
|
|
18549
|
+
populateFormForEdit() {
|
|
18550
|
+
var _a, _b, _c, _d;
|
|
18551
|
+
if (this.element && this.elementId != null) {
|
|
18552
|
+
this.isEditMode = true;
|
|
18553
|
+
this.isCreateMode = false;
|
|
18554
|
+
this.form.patchValue({
|
|
18555
|
+
name: (_a = this.element.title) !== null && _a !== void 0 ? _a : '',
|
|
18556
|
+
screenNameId: (_b = this.element.screenNameId) !== null && _b !== void 0 ? _b : null,
|
|
18557
|
+
value: (_c = this.element.selector) !== null && _c !== void 0 ? _c : '',
|
|
18558
|
+
});
|
|
18559
|
+
this.formLabels = [...(this.element.labels || [])];
|
|
18560
|
+
this.updateScreenNameSelectConfig();
|
|
18561
|
+
}
|
|
18562
|
+
else {
|
|
18563
|
+
this.isEditMode = false;
|
|
18564
|
+
this.isCreateMode = false;
|
|
18565
|
+
this.formLabels = [];
|
|
18566
|
+
}
|
|
18567
|
+
(_d = this.cdr) === null || _d === void 0 ? void 0 : _d.markForCheck();
|
|
18568
|
+
}
|
|
18569
|
+
populateFormForCreateWithElement() {
|
|
18570
|
+
var _a, _b, _c, _d;
|
|
18571
|
+
if (this.element) {
|
|
18572
|
+
this.isCreateMode = true;
|
|
18573
|
+
this.isEditMode = false;
|
|
18574
|
+
this.form.patchValue({
|
|
18575
|
+
name: (_a = this.element.title) !== null && _a !== void 0 ? _a : '',
|
|
18576
|
+
screenNameId: (_b = this.element.screenNameId) !== null && _b !== void 0 ? _b : null,
|
|
18577
|
+
value: (_c = this.element.selector) !== null && _c !== void 0 ? _c : '',
|
|
18578
|
+
});
|
|
18579
|
+
this.formLabels = [...(this.element.labels || [])];
|
|
18580
|
+
this.updateScreenNameSelectConfig();
|
|
18581
|
+
}
|
|
18582
|
+
else {
|
|
18583
|
+
this.isCreateMode = true;
|
|
18584
|
+
this.isEditMode = false;
|
|
18585
|
+
this.formLabels = [];
|
|
18586
|
+
}
|
|
18587
|
+
(_d = this.cdr) === null || _d === void 0 ? void 0 : _d.markForCheck();
|
|
18588
|
+
}
|
|
18589
|
+
/** Called by parent when a new screen name was created (so we can set the selected value) */
|
|
18590
|
+
setCreatedScreenName(opt) {
|
|
18591
|
+
var _a, _b;
|
|
18592
|
+
(_a = this.form.get('screenNameId')) === null || _a === void 0 ? void 0 : _a.setValue(opt.id);
|
|
18593
|
+
this.updateScreenNameSelectConfig();
|
|
18594
|
+
(_b = this.cdr) === null || _b === void 0 ? void 0 : _b.markForCheck();
|
|
18595
|
+
}
|
|
18596
|
+
onApply() {
|
|
18597
|
+
var _a, _b, _c;
|
|
18598
|
+
if (this.form.invalid) {
|
|
18599
|
+
Object.keys(this.form.controls).forEach((key) => { var _a; return (_a = this.form.get(key)) === null || _a === void 0 ? void 0 : _a.markAsTouched(); });
|
|
18600
|
+
return;
|
|
18601
|
+
}
|
|
18602
|
+
const formValue = this.form.value;
|
|
18603
|
+
const screenNameId = formValue.screenNameId;
|
|
18604
|
+
const selectedOpt = this.screenNameOptions.find((o) => o.id === screenNameId);
|
|
18605
|
+
const screenNameName = (selectedOpt === null || selectedOpt === void 0 ? void 0 : selectedOpt.name) ? String(selectedOpt.name).trim() : '';
|
|
18606
|
+
if (!screenNameId || !screenNameName) {
|
|
18607
|
+
(_a = this.form.get('screenNameId')) === null || _a === void 0 ? void 0 : _a.setErrors({ required: true });
|
|
18608
|
+
(_b = this.form.get('screenNameId')) === null || _b === void 0 ? void 0 : _b.markAsTouched();
|
|
18609
|
+
return;
|
|
18610
|
+
}
|
|
18611
|
+
this.saving = true;
|
|
18612
|
+
(_c = this.cdr) === null || _c === void 0 ? void 0 : _c.markForCheck();
|
|
18613
|
+
const payload = {
|
|
18614
|
+
name: formValue.name.trim(),
|
|
18615
|
+
screenNameId,
|
|
18616
|
+
screenNameName,
|
|
18617
|
+
locatorValue: formValue.value.trim(),
|
|
18618
|
+
labels: [...this.formLabels],
|
|
18619
|
+
};
|
|
18620
|
+
if (this.isEditMode && this.elementId) {
|
|
18621
|
+
this.updateElement.emit(Object.assign(Object.assign({}, payload), { elementId: this.elementId }));
|
|
18622
|
+
}
|
|
18623
|
+
else {
|
|
18624
|
+
this.createElement.emit(payload);
|
|
18625
|
+
}
|
|
18626
|
+
}
|
|
18627
|
+
onCreateOrUpdateSuccess() {
|
|
18628
|
+
var _a;
|
|
18629
|
+
this.saving = false;
|
|
18630
|
+
(_a = this.cdr) === null || _a === void 0 ? void 0 : _a.markForCheck();
|
|
18631
|
+
}
|
|
18632
|
+
onCreateOrUpdateError() {
|
|
18633
|
+
var _a;
|
|
18634
|
+
this.saving = false;
|
|
18635
|
+
(_a = this.cdr) === null || _a === void 0 ? void 0 : _a.markForCheck();
|
|
18636
|
+
}
|
|
18637
|
+
onCancel() {
|
|
18638
|
+
this.cancel.emit();
|
|
18639
|
+
}
|
|
18640
|
+
onEditInDepth(event) {
|
|
18641
|
+
event.preventDefault();
|
|
18642
|
+
this.editInDepth.emit();
|
|
18643
|
+
}
|
|
18644
|
+
getFormControl(controlName) {
|
|
18645
|
+
return this.form.get(controlName);
|
|
18646
|
+
}
|
|
18647
|
+
getFormControlValue(controlName) {
|
|
18648
|
+
var _a;
|
|
18649
|
+
return ((_a = this.form.get(controlName)) === null || _a === void 0 ? void 0 : _a.value) || '';
|
|
18650
|
+
}
|
|
18651
|
+
onFormControlChange(controlName, value) {
|
|
18652
|
+
var _a;
|
|
18653
|
+
this.form.patchValue({ [controlName]: value });
|
|
18654
|
+
(_a = this.cdr) === null || _a === void 0 ? void 0 : _a.markForCheck();
|
|
18655
|
+
}
|
|
18656
|
+
/** Add a tag (label) */
|
|
18657
|
+
addTag(tag) {
|
|
18658
|
+
var _a;
|
|
18659
|
+
const t = (tag || this.tagInputValue || '').trim();
|
|
18660
|
+
if (t && !this.formLabels.includes(t)) {
|
|
18661
|
+
this.formLabels = [...this.formLabels, t];
|
|
18662
|
+
this.tagInputValue = '';
|
|
18663
|
+
(_a = this.cdr) === null || _a === void 0 ? void 0 : _a.markForCheck();
|
|
18664
|
+
}
|
|
18665
|
+
}
|
|
18666
|
+
removeTag(tag) {
|
|
18667
|
+
var _a;
|
|
18668
|
+
this.formLabels = this.formLabels.filter((l) => l !== tag);
|
|
18669
|
+
(_a = this.cdr) === null || _a === void 0 ? void 0 : _a.markForCheck();
|
|
18670
|
+
}
|
|
18671
|
+
onTagInputKeydown(event) {
|
|
18672
|
+
if (event.key === 'Enter' || event.key === ',') {
|
|
18673
|
+
event.preventDefault();
|
|
18674
|
+
this.addTag();
|
|
18675
|
+
}
|
|
18676
|
+
}
|
|
18677
|
+
}
|
|
18678
|
+
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 });
|
|
18679
|
+
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 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 <span *ngFor=\"let tag of formLabels\"\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-full cqa-text-[12px] cqa-text-[#3F43EE]\">\n {{ tag }}\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 </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: 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 });
|
|
18680
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: ElementFormComponent, decorators: [{
|
|
18681
|
+
type: Component,
|
|
18682
|
+
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 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 <span *ngFor=\"let tag of formLabels\"\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-full cqa-text-[12px] cqa-text-[#3F43EE]\">\n {{ tag }}\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 </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" }]
|
|
18683
|
+
}], ctorParameters: function () {
|
|
18684
|
+
return [{ type: i1$1.FormBuilder, decorators: [{
|
|
18685
|
+
type: Optional
|
|
18686
|
+
}] }, { type: i0.ChangeDetectorRef, decorators: [{
|
|
18687
|
+
type: Optional
|
|
18688
|
+
}] }];
|
|
18689
|
+
}, propDecorators: { elementId: [{
|
|
18690
|
+
type: Input
|
|
18691
|
+
}], element: [{
|
|
18692
|
+
type: Input
|
|
18693
|
+
}], screenNameOptions: [{
|
|
18694
|
+
type: Input
|
|
18695
|
+
}], hasMoreScreenNames: [{
|
|
18696
|
+
type: Input
|
|
18697
|
+
}], isLoadingScreenNames: [{
|
|
18698
|
+
type: Input
|
|
18699
|
+
}], isElementLoading: [{
|
|
18700
|
+
type: Input
|
|
18701
|
+
}], isEditMode: [{
|
|
18702
|
+
type: Input
|
|
18703
|
+
}], isCreateMode: [{
|
|
18704
|
+
type: Input
|
|
18705
|
+
}], isEditInDepthAvailable: [{
|
|
18706
|
+
type: Input
|
|
18707
|
+
}], createElement: [{
|
|
18708
|
+
type: Output
|
|
18709
|
+
}], updateElement: [{
|
|
18710
|
+
type: Output
|
|
18711
|
+
}], createScreenNameRequest: [{
|
|
18712
|
+
type: Output
|
|
18713
|
+
}], searchScreenName: [{
|
|
18714
|
+
type: Output
|
|
18715
|
+
}], loadMoreScreenNames: [{
|
|
18716
|
+
type: Output
|
|
18717
|
+
}], cancel: [{
|
|
18718
|
+
type: Output
|
|
18719
|
+
}], editInDepth: [{
|
|
18720
|
+
type: Output
|
|
18721
|
+
}] } });
|
|
18722
|
+
|
|
18445
18723
|
class ElementListComponent {
|
|
18446
18724
|
constructor() {
|
|
18447
18725
|
/** Array of items to display */
|
|
@@ -18552,7 +18830,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
|
|
|
18552
18830
|
}] } });
|
|
18553
18831
|
|
|
18554
18832
|
class ElementPopupComponent {
|
|
18555
|
-
constructor(ref, data,
|
|
18833
|
+
constructor(ref, data, cdr) {
|
|
18556
18834
|
this.ref = ref;
|
|
18557
18835
|
this.cdr = cdr;
|
|
18558
18836
|
this.value = '';
|
|
@@ -18603,26 +18881,15 @@ class ElementPopupComponent {
|
|
|
18603
18881
|
this.isEditMode = false;
|
|
18604
18882
|
/** Whether we're in create mode (no elementId) */
|
|
18605
18883
|
this.isCreateMode = false;
|
|
18606
|
-
/** Labels (tags) as string array for multi-tag input */
|
|
18607
|
-
this.formLabels = [];
|
|
18608
|
-
/** Current tag input value */
|
|
18609
|
-
this.tagInputValue = '';
|
|
18610
18884
|
/** Current search input value (bound to search bar) */
|
|
18611
18885
|
this.searchValue = '';
|
|
18612
|
-
/** Whether we're saving (disable buttons) */
|
|
18613
|
-
this.saving = false;
|
|
18614
18886
|
this.injectedData = data;
|
|
18615
|
-
this.fb = fb || new FormBuilder();
|
|
18616
|
-
this.initializeForm();
|
|
18617
18887
|
}
|
|
18618
18888
|
ngOnChanges(changes) {
|
|
18619
|
-
if (changes['screenNameOptions'] || changes['hasMoreScreenNames'] || changes['isLoadingScreenNames']) {
|
|
18620
|
-
this.updateScreenNameSelectConfig();
|
|
18621
|
-
}
|
|
18622
18889
|
if ((changes['element'] || changes['elementId']) && this.enableForm) {
|
|
18623
18890
|
if (this.elementId) {
|
|
18624
18891
|
this.isCreateMode = false;
|
|
18625
|
-
this.
|
|
18892
|
+
this.isEditMode = true;
|
|
18626
18893
|
}
|
|
18627
18894
|
else {
|
|
18628
18895
|
this.isCreateMode = true;
|
|
@@ -18646,149 +18913,27 @@ class ElementPopupComponent {
|
|
|
18646
18913
|
}
|
|
18647
18914
|
}
|
|
18648
18915
|
}
|
|
18649
|
-
initializeForm() {
|
|
18650
|
-
this.form = this.fb.group({
|
|
18651
|
-
name: ['', [Validators.required]],
|
|
18652
|
-
screenNameId: [null, [Validators.required]],
|
|
18653
|
-
value: ['', [Validators.required]],
|
|
18654
|
-
});
|
|
18655
|
-
this.updateScreenNameSelectConfig();
|
|
18656
|
-
}
|
|
18657
|
-
updateScreenNameSelectConfig() {
|
|
18658
|
-
var _a, _b, _c, _d, _e;
|
|
18659
|
-
const opts = (this.screenNameOptions || []).map((o) => ({
|
|
18660
|
-
id: o.id,
|
|
18661
|
-
value: o.id,
|
|
18662
|
-
name: o.name,
|
|
18663
|
-
label: o.name,
|
|
18664
|
-
}));
|
|
18665
|
-
const currentId = (_b = (_a = this.form) === null || _a === void 0 ? void 0 : _a.get('screenNameId')) === null || _b === void 0 ? void 0 : _b.value;
|
|
18666
|
-
if (currentId && ((_c = this.element) === null || _c === void 0 ? void 0 : _c.screenNameId) === currentId && ((_d = this.element) === null || _d === void 0 ? void 0 : _d.screenName)) {
|
|
18667
|
-
const exists = opts.some((o) => o.id === currentId);
|
|
18668
|
-
if (!exists) {
|
|
18669
|
-
opts.unshift({
|
|
18670
|
-
id: currentId,
|
|
18671
|
-
value: currentId,
|
|
18672
|
-
name: String(this.element.screenName),
|
|
18673
|
-
label: String(this.element.screenName),
|
|
18674
|
-
});
|
|
18675
|
-
}
|
|
18676
|
-
}
|
|
18677
|
-
this.screenNameSelectConfig = {
|
|
18678
|
-
key: 'screenNameId',
|
|
18679
|
-
label: 'Screen Name',
|
|
18680
|
-
placeholder: 'Select or create screen',
|
|
18681
|
-
searchable: true,
|
|
18682
|
-
serverSearch: true,
|
|
18683
|
-
allowCustomValue: true,
|
|
18684
|
-
options: opts,
|
|
18685
|
-
hasMore: this.hasMoreScreenNames,
|
|
18686
|
-
isLoading: this.isLoadingScreenNames,
|
|
18687
|
-
onSearch: (q) => this.searchScreenName.emit(q || ''),
|
|
18688
|
-
onLoadMore: (q) => this.loadMoreScreenNames.emit(q || ''),
|
|
18689
|
-
};
|
|
18690
|
-
(_e = this.cdr) === null || _e === void 0 ? void 0 : _e.markForCheck();
|
|
18691
|
-
}
|
|
18692
|
-
populateFormForEdit() {
|
|
18693
|
-
var _a, _b, _c, _d;
|
|
18694
|
-
if (this.element && this.elementId != null) {
|
|
18695
|
-
this.isEditMode = true;
|
|
18696
|
-
this.isCreateMode = false;
|
|
18697
|
-
this.form.patchValue({
|
|
18698
|
-
name: (_a = this.element.title) !== null && _a !== void 0 ? _a : '',
|
|
18699
|
-
screenNameId: (_b = this.element.screenNameId) !== null && _b !== void 0 ? _b : null,
|
|
18700
|
-
value: (_c = this.element.selector) !== null && _c !== void 0 ? _c : '',
|
|
18701
|
-
});
|
|
18702
|
-
this.formLabels = [...(this.element.labels || [])];
|
|
18703
|
-
this.updateScreenNameSelectConfig();
|
|
18704
|
-
}
|
|
18705
|
-
else {
|
|
18706
|
-
this.isEditMode = false;
|
|
18707
|
-
this.isCreateMode = false;
|
|
18708
|
-
this.formLabels = [];
|
|
18709
|
-
}
|
|
18710
|
-
(_d = this.cdr) === null || _d === void 0 ? void 0 : _d.markForCheck();
|
|
18711
|
-
}
|
|
18712
|
-
populateFormForCreateWithElement() {
|
|
18713
|
-
var _a, _b, _c, _d;
|
|
18714
|
-
if (this.element) {
|
|
18715
|
-
this.isCreateMode = true;
|
|
18716
|
-
this.isEditMode = false;
|
|
18717
|
-
this.form.patchValue({
|
|
18718
|
-
name: (_a = this.element.title) !== null && _a !== void 0 ? _a : '',
|
|
18719
|
-
screenNameId: (_b = this.element.screenNameId) !== null && _b !== void 0 ? _b : null,
|
|
18720
|
-
value: (_c = this.element.selector) !== null && _c !== void 0 ? _c : '',
|
|
18721
|
-
});
|
|
18722
|
-
this.formLabels = [...(this.element.labels || [])];
|
|
18723
|
-
this.updateScreenNameSelectConfig();
|
|
18724
|
-
}
|
|
18725
|
-
else {
|
|
18726
|
-
this.isCreateMode = true;
|
|
18727
|
-
this.isEditMode = false;
|
|
18728
|
-
this.formLabels = [];
|
|
18729
|
-
}
|
|
18730
|
-
(_d = this.cdr) === null || _d === void 0 ? void 0 : _d.markForCheck();
|
|
18731
|
-
}
|
|
18732
18916
|
resetForm() {
|
|
18733
18917
|
this.isEditMode = false;
|
|
18734
18918
|
this.isCreateMode = false;
|
|
18735
|
-
this.formLabels = [];
|
|
18736
|
-
this.tagInputValue = '';
|
|
18737
|
-
this.form.reset({
|
|
18738
|
-
name: '',
|
|
18739
|
-
screenNameId: null,
|
|
18740
|
-
value: '',
|
|
18741
|
-
});
|
|
18742
|
-
this.updateScreenNameSelectConfig();
|
|
18743
18919
|
}
|
|
18744
|
-
|
|
18745
|
-
|
|
18746
|
-
var _a, _b;
|
|
18747
|
-
(_a = this.form.get('screenNameId')) === null || _a === void 0 ? void 0 : _a.setValue(opt.id);
|
|
18748
|
-
this.updateScreenNameSelectConfig();
|
|
18749
|
-
(_b = this.cdr) === null || _b === void 0 ? void 0 : _b.markForCheck();
|
|
18920
|
+
onElementFormCreate(payload) {
|
|
18921
|
+
this.createElement.emit(payload);
|
|
18750
18922
|
}
|
|
18751
|
-
|
|
18752
|
-
|
|
18753
|
-
|
|
18754
|
-
|
|
18755
|
-
|
|
18756
|
-
}
|
|
18757
|
-
const formValue = this.form.value;
|
|
18758
|
-
const screenNameId = formValue.screenNameId;
|
|
18759
|
-
const selectedOpt = this.screenNameOptions.find((o) => o.id === screenNameId);
|
|
18760
|
-
const screenNameName = (selectedOpt === null || selectedOpt === void 0 ? void 0 : selectedOpt.name) ? String(selectedOpt.name).trim() : '';
|
|
18761
|
-
if (!screenNameId || !screenNameName) {
|
|
18762
|
-
(_a = this.form.get('screenNameId')) === null || _a === void 0 ? void 0 : _a.setErrors({ required: true });
|
|
18763
|
-
(_b = this.form.get('screenNameId')) === null || _b === void 0 ? void 0 : _b.markAsTouched();
|
|
18764
|
-
return;
|
|
18765
|
-
}
|
|
18766
|
-
this.saving = true;
|
|
18767
|
-
(_c = this.cdr) === null || _c === void 0 ? void 0 : _c.markForCheck();
|
|
18768
|
-
const payload = {
|
|
18769
|
-
name: formValue.name.trim(),
|
|
18770
|
-
screenNameId,
|
|
18771
|
-
screenNameName,
|
|
18772
|
-
locatorValue: formValue.value.trim(),
|
|
18773
|
-
labels: [...this.formLabels],
|
|
18774
|
-
};
|
|
18775
|
-
if (this.isEditMode && this.elementId) {
|
|
18776
|
-
this.updateElement.emit(Object.assign(Object.assign({}, payload), { elementId: this.elementId }));
|
|
18777
|
-
}
|
|
18778
|
-
else {
|
|
18779
|
-
this.createElement.emit(payload);
|
|
18780
|
-
}
|
|
18923
|
+
onElementFormUpdate(payload) {
|
|
18924
|
+
this.updateElement.emit(payload);
|
|
18925
|
+
}
|
|
18926
|
+
onElementFormCancel() {
|
|
18927
|
+
this.toggleForm();
|
|
18781
18928
|
}
|
|
18782
18929
|
onCreateOrUpdateSuccess() {
|
|
18783
18930
|
var _a;
|
|
18784
|
-
this.saving = false;
|
|
18785
18931
|
this.enableForm = false;
|
|
18786
18932
|
this.resetForm();
|
|
18787
18933
|
(_a = this.cdr) === null || _a === void 0 ? void 0 : _a.markForCheck();
|
|
18788
18934
|
}
|
|
18789
18935
|
onCreateOrUpdateError() {
|
|
18790
18936
|
var _a;
|
|
18791
|
-
this.saving = false;
|
|
18792
18937
|
(_a = this.cdr) === null || _a === void 0 ? void 0 : _a.markForCheck();
|
|
18793
18938
|
}
|
|
18794
18939
|
toggleForm() {
|
|
@@ -18798,8 +18943,6 @@ class ElementPopupComponent {
|
|
|
18798
18943
|
if (!this.elementId) {
|
|
18799
18944
|
this.isCreateMode = true;
|
|
18800
18945
|
this.isEditMode = false;
|
|
18801
|
-
// Patch form with current element values when Edit clicked without elementId
|
|
18802
|
-
this.populateFormForCreateWithElement();
|
|
18803
18946
|
this.formOpenRequest.emit({ mode: 'create' });
|
|
18804
18947
|
}
|
|
18805
18948
|
else {
|
|
@@ -18858,8 +19001,7 @@ class ElementPopupComponent {
|
|
|
18858
19001
|
onClose() {
|
|
18859
19002
|
this.onCancel();
|
|
18860
19003
|
}
|
|
18861
|
-
onEditInDepth(
|
|
18862
|
-
event.preventDefault();
|
|
19004
|
+
onEditInDepth() {
|
|
18863
19005
|
this.editInDepth.emit();
|
|
18864
19006
|
if (this.ref)
|
|
18865
19007
|
this.ref.close(ELEMENT_POPUP_EDIT_IN_DEPTH);
|
|
@@ -18877,39 +19019,6 @@ class ElementPopupComponent {
|
|
|
18877
19019
|
window.open(this.helpUrl, '_blank');
|
|
18878
19020
|
}
|
|
18879
19021
|
}
|
|
18880
|
-
getFormControl(controlName) {
|
|
18881
|
-
return this.form.get(controlName);
|
|
18882
|
-
}
|
|
18883
|
-
getFormControlValue(controlName) {
|
|
18884
|
-
var _a;
|
|
18885
|
-
return ((_a = this.form.get(controlName)) === null || _a === void 0 ? void 0 : _a.value) || '';
|
|
18886
|
-
}
|
|
18887
|
-
onFormControlChange(controlName, value) {
|
|
18888
|
-
var _a;
|
|
18889
|
-
this.form.patchValue({ [controlName]: value });
|
|
18890
|
-
(_a = this.cdr) === null || _a === void 0 ? void 0 : _a.markForCheck();
|
|
18891
|
-
}
|
|
18892
|
-
/** Add a tag (label) */
|
|
18893
|
-
addTag(tag) {
|
|
18894
|
-
var _a;
|
|
18895
|
-
const t = (tag || this.tagInputValue || '').trim();
|
|
18896
|
-
if (t && !this.formLabels.includes(t)) {
|
|
18897
|
-
this.formLabels = [...this.formLabels, t];
|
|
18898
|
-
this.tagInputValue = '';
|
|
18899
|
-
(_a = this.cdr) === null || _a === void 0 ? void 0 : _a.markForCheck();
|
|
18900
|
-
}
|
|
18901
|
-
}
|
|
18902
|
-
removeTag(tag) {
|
|
18903
|
-
var _a;
|
|
18904
|
-
this.formLabels = this.formLabels.filter((l) => l !== tag);
|
|
18905
|
-
(_a = this.cdr) === null || _a === void 0 ? void 0 : _a.markForCheck();
|
|
18906
|
-
}
|
|
18907
|
-
onTagInputKeydown(event) {
|
|
18908
|
-
if (event.key === 'Enter' || event.key === ',') {
|
|
18909
|
-
event.preventDefault();
|
|
18910
|
-
this.addTag();
|
|
18911
|
-
}
|
|
18912
|
-
}
|
|
18913
19022
|
onElementClick(element) {
|
|
18914
19023
|
var _a;
|
|
18915
19024
|
this.element = element;
|
|
@@ -18933,12 +19042,17 @@ class ElementPopupComponent {
|
|
|
18933
19042
|
this.searchElement.emit(item);
|
|
18934
19043
|
(_a = this.cdr) === null || _a === void 0 ? void 0 : _a.markForCheck();
|
|
18935
19044
|
}
|
|
19045
|
+
/** Called by parent when a new screen name was created (so we can set the selected value) */
|
|
19046
|
+
setCreatedScreenName(opt) {
|
|
19047
|
+
var _a;
|
|
19048
|
+
(_a = this.elementFormComponent) === null || _a === void 0 ? void 0 : _a.setCreatedScreenName(opt);
|
|
19049
|
+
}
|
|
18936
19050
|
}
|
|
18937
|
-
ElementPopupComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: ElementPopupComponent, deps: [{ token: CUSTOM_ELEMENT_POPUP_REF, optional: true }, { token: ELEMENT_POPUP_DATA, optional: true }, { token:
|
|
18938
|
-
ElementPopupComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: ElementPopupComponent, selector: "cqa-element-popup", inputs: { value: "value", helpUrl: "helpUrl", labels: "labels", element: "element", elements: "elements", enableForm: "enableForm", isOnRecord: "isOnRecord", hasMoreElements: "hasMoreElements", elementId: "elementId", screenNameOptions: "screenNameOptions", hasMoreScreenNames: "hasMoreScreenNames", isLoadingScreenNames: "isLoadingScreenNames", suggestedTags: "suggestedTags", isElementLoading: "isElementLoading", recentSearchedItems: "recentSearchedItems" }, outputs: { apply: "apply", cancel: "cancel", editInDepth: "editInDepth", searchElement: "searchElement", recentItemClick: "recentItemClick", loadMoreElements: "loadMoreElements", createElement: "createElement", updateElement: "updateElement", createScreenNameRequest: "createScreenNameRequest", searchScreenName: "searchScreenName", loadMoreScreenNames: "loadMoreScreenNames", formOpenRequest: "formOpenRequest", elementSelect: "elementSelect", toggleRecord: "toggleRecord" }, host: { classAttribute: "cqa-ui-root" }, usesOnChanges: true, ngImport: i0, template: "<div\n class=\"cqa-bg-white cqa-rounded-[12px] cqa-shadow-lg cqa-border cqa-border-solid cqa-border-[#E5E7EB] cqa-w-[500px] cqa-flex cqa-flex-col cqa-gap-[12px] cqa-p-2 cqa-box-border\">\n <!-- Header: title left; Need help? + close icon right -->\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-2 cqa-px-4\">\n <h2 class=\"cqa-text-[16px] cqa-leading-[24px] cqa-font-bold cqa-text-[#111827] cqa-m-0 cqa-font-[600]\">\n Element\n </h2>\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <!-- Need help? with custom tooltip (works inside overlay) -->\n <div class=\"cqa-relative cqa-inline-flex\"\n (mouseenter)=\"showHelpTooltip = true\" (mouseleave)=\"showHelpTooltip = false\">\n <a *ngIf=\"helpUrl\" href=\"#\" (click)=\"onHelp($event)\"\n class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-text-[#3F43EE] cqa-text-[12px] cqa-leading-[21px] cqa-no-underline cqa-cursor-pointer\">\n <svg width=\"17\" height=\"16\" viewBox=\"0 0 17 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" class=\"cqa-flex-shrink-0\" aria-hidden=\"true\">\n <g clip-path=\"url(#help-icon-clip)\">\n <path d=\"M8.50033 14.6663C12.4123 14.6663 15.5837 11.6816 15.5837 7.99967C15.5837 4.31778 12.4123 1.33301 8.50033 1.33301C4.58831 1.33301 1.41699 4.31778 1.41699 7.99967C1.41699 11.6816 4.58831 14.6663 8.50033 14.6663Z\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M6.43848 6.00038C6.60501 5.55483 6.93371 5.17912 7.36636 4.9398C7.79901 4.70049 8.30769 4.61301 8.80231 4.69285C9.29693 4.7727 9.74556 5.01473 10.0687 5.37607C10.3919 5.7374 10.5688 6.19473 10.5681 6.66705C10.5681 8.00038 8.44306 8.66705 8.44306 8.66705\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M8.5 11.333H8.50966\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </g>\n <defs>\n <clipPath id=\"help-icon-clip\">\n <rect width=\"17\" height=\"16\" fill=\"white\"/>\n </clipPath>\n </defs>\n </svg>\n Need help ?\n </a>\n <span *ngIf=\"!helpUrl\" class=\"cqa-flex cqa-items-center cqa-gap-1.5 cqa-font-[500] cqa-text-[10px] cqa-cursor-default\">\n <svg width=\"17\" height=\"16\" viewBox=\"0 0 17 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" class=\"cqa-flex-shrink-0 cqa-text-[#3F43EE]\" aria-hidden=\"true\">\n <g clip-path=\"url(#help-icon-clip-nolink)\">\n <path d=\"M8.50033 14.6663C12.4123 14.6663 15.5837 11.6816 15.5837 7.99967C15.5837 4.31778 12.4123 1.33301 8.50033 1.33301C4.58831 1.33301 1.41699 4.31778 1.41699 7.99967C1.41699 11.6816 4.58831 14.6663 8.50033 14.6663Z\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M6.43848 6.00038C6.60501 5.55483 6.93371 5.17912 7.36636 4.9398C7.79901 4.70049 8.30769 4.61301 8.80231 4.69285C9.29693 4.7727 9.74556 5.01473 10.0687 5.37607C10.3919 5.7374 10.5688 6.19473 10.5681 6.66705C10.5681 8.00038 8.44306 8.66705 8.44306 8.66705\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M8.5 11.333H8.50966\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </g>\n <defs>\n <clipPath id=\"help-icon-clip-nolink\">\n <rect width=\"17\" height=\"16\" fill=\"white\"/>\n </clipPath>\n </defs>\n </svg>\n Need help ?\n </span>\n <!-- Custom tooltip (exact spec: 306\u00D720 content, 6px radius, #0A0A0A, no arrow) -->\n <div *ngIf=\"showHelpTooltip\" class=\"cqa-absolute cqa-pointer-events-none cqa-z-[100]\"\n style=\"top: -24px; left: -125px;\"\n role=\"tooltip\">\n <div class=\"cqa-text-white cqa-text-center cqa-whitespace-nowrap\"\n style=\"width: 306px; min-height: 20px; border-radius: 6px; opacity: 1; padding: 4px 8px; background-color: #0A0A0A; line-height: 20px; font-size: 8px;\">\n {{ helpTooltipText }}\n </div>\n </div>\n </div>\n <button type=\"button\" (click)=\"onClose()\"\n class=\"cqa-p-1 cqa-rounded cqa-text-[#6B7280] hover:cqa-bg-[#F3F4F6] cqa-flex cqa-items-center cqa-justify-center\"\n title=\"Close\" aria-label=\"Close\">\n <mat-icon class=\"!cqa-w-5 !cqa-h-5 !cqa-text-[20px]\">close</mat-icon>\n </button>\n </div>\n </div>\n\n <!-- Line below header (full width of modal, no side margin) -->\n <div class=\"cqa--mx-2 cqa-w-[calc(100%+1rem)] cqa-flex-shrink-0\">\n <div class=\"cqa-h-px cqa-w-full cqa-bg-[#E5E7EB]\" role=\"presentation\"></div>\n </div>\n\n <ng-container *ngIf=\"enableForm && !isOnRecord\">\n <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 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 <span *ngFor=\"let tag of formLabels\"\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-full cqa-text-[12px] cqa-text-[#3F43EE]\">\n {{ tag }}\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 </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)=\"toggleForm()\"\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=\"#\" (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 </ng-container>\n\n<ng-container *ngIf=\"isOnRecord && !enableForm\">\n <div\n class=\"cqa-flex cqa-flex-col cqa-items-center cqa-justify-center cqa-text-center cqa-gap-3 cqa-pt-10\">\n\n <!-- Video Icon -->\n <div\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-[64px] cqa-h-[64px] cqa-rounded-full cqa-bg-[#FEE2E2]\">\n <svg width=\"32\" height=\"32\" viewBox=\"0 0 32 32\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M21.333 17.3333L28.297 21.9759C28.3974 22.0428 28.514 22.0811 28.6345 22.0868C28.7549 22.0926 28.8747 22.0656 28.981 22.0087C29.0873 21.9517 29.1762 21.8671 29.2382 21.7636C29.3002 21.6602 29.3329 21.5419 29.333 21.4213V10.4933C29.333 10.376 29.3021 10.2607 29.2434 10.1592C29.1846 10.0577 29.1001 9.97344 28.9984 9.91501C28.8967 9.85658 28.7814 9.82602 28.6641 9.82642C28.5468 9.82682 28.4317 9.85816 28.3303 9.91728L21.333 13.9999\" stroke=\"#E7000B\" stroke-width=\"2.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M18.667 8H5.33366C3.8609 8 2.66699 9.19391 2.66699 10.6667V21.3333C2.66699 22.8061 3.8609 24 5.33366 24H18.667C20.1398 24 21.3337 22.8061 21.3337 21.3333V10.6667C21.3337 9.19391 20.1398 8 18.667 8Z\" stroke=\"#E7000B\" stroke-width=\"2.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n \n </div>\n\n <!-- Title -->\n <h4 class=\"cqa-m-0 cqa-text-[16px] cqa-leading-[24px] cqa-font-[600] cqa-text-[#0A0A0A]\">\n Recording Mode Active\n </h4>\n\n <!-- Subtitle -->\n <p class=\"cqa-m-0 cqa-text-[12px] cqa-leading-[18px] cqa-text-[#6B7280]\">\n Click on any element in the browser to capture it\n </p>\n </div>\n\n <!-- Footer -->\n <div class=\"cqa-flex cqa-justify-center cqa-pb-4\">\n <cqa-button\n variant=\"outlined\"\n btnSize=\"lg\"\n [text]=\"'Cancel Recording'\"\n (clicked)=\"onToggleRecordClick()\"\n [customClass]=\"'cqa-text-[14px] cqa-px-16 cqa-py-[9px] cqa-border-[#414146]'\">\n </cqa-button>\n </div>\n</ng-container>\n\n\n <ng-container *ngIf=\"!enableForm && !isOnRecord\">\n<div class=\"cqa-flex cqa-flex-col cqa-gap-4 cqa-px-1 cqa-pt-3\">\n\n <!-- Selected -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-2\">\n <span class=\"cqa-text-[12px] cqa-text-[#6B7280]\">Selected</span>\n\n <div\n class=\"cqa-flex cqa-items-center cqa-justify-between\n cqa-bg-[#FFFBEB] cqa-border cqa-border-[#fadfba]\n cqa-rounded-lg cqa-p-3 cqa-border-solid cqa-gap-3\">\n\n <div class=\"cqa-flex cqa-px-3 cqa-py-2 cqa-rounded-lg cqa-flex-col cqa-gap-0.5 cqa-bg-[#f5f5f5] cqa-flex-1\">\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-2\">\n <span class=\"cqa-text-[14px] cqa-font-[600] cqa-text-[#111827]\">\n {{element.title}}\n </span>\n\n <div class=\"cqa-flex cqa-gap-2\">\n <span *ngFor=\"let l of element.labels\"\n class=\"cqa-text-[10px] cqa-px-1.5 cqa-py-0.5\n cqa-rounded cqa-bg-[#EEF2FF] cqa-text-[#3F43EE] cqa-rounded-full cqa-px-2 cqa-bg-[#eff6ff] cqa-border cqa-border-solid cqa-border-[#c8e0ff]\">\n {{l}}\n </span>\n </div>\n </div>\n\n <span class=\"cqa-text-[11px] cqa-text-[#6B7280]\">\n {{element.selector}}\n </span>\n </div>\n <cqa-button variant=\"outlined\" icon=\"edit\" btnSize=\"lg\" [text]=\"'Edit'\" [fullWidth]=\"true\" (clicked)=\"toggleForm()\"\n [customClass]=\"'cqa-text-[14px] cqa-py-[9px] cqa-border-[#414146]'\"></cqa-button>\n </div>\n </div>\n\n <!-- Recent -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-2\" *ngIf=\"recentSearchedItems.length > 0\">\n <span class=\"cqa-text-[12px] cqa-text-[#6B7280]\">Recent</span>\n\n <div class=\"cqa-flex cqa-gap-2 cqa-overflow-x-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\n <div *ngFor=\"let item of recentSearchedItems\" \n class=\"cqa-cursor-pointer cqa-inline-block\"\n (click)=\"onRecentItemClick(item)\">\n <cqa-badge \n class=\"cqa-element-badge cqa-mb-2 cqa-chip !cqa-bg-white !cqa-text-[12px] cqa-whitespace-nowrap\" \n [label]=\"item\"></cqa-badge>\n </div>\n </div>\n </div>\n\n <!-- Element Library -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-2\">\n <span class=\"cqa-text-[12px] cqa-text-[#6B7280]\">Element Library</span>\n <cqa-search-bar [fullWidth]=\"true\" [value]=\"searchValue\" placeholder=\"Search library\" (valueChange)=\"search($event)\"></cqa-search-bar> \n </div>\n\n <cqa-element-list \n [items]=\"elements\"\n [titleKey]=\"'title'\"\n [selectorKey]=\"'selector'\"\n [labelsKey]=\"'labels'\"\n [maxHeight]=\"'200px'\"\n [hasMore]=\"hasMoreElements\"\n (itemClick)=\"onElementClick($event)\"\n (loadMore)=\"onLoadMoreElements()\">\n </cqa-element-list>\n</div>\n\n\n <!-- Footer: Cancel, Apply (full width in one row) -->\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\" icon=\"radio_button_checked\" btnSize=\"lg\" [text]=\"'Record'\" [fullWidth]=\"true\" (clicked)=\"onToggleRecordClick()\"\n [customClass]=\"'cqa-text-[14px] cqa-py-[9px] cqa-border-[#414146]'\"></cqa-button>\n </div>\n <div class=\"cqa-flex-1 cqa-min-w-0\">\n <cqa-button variant=\"outlined\" icon=\"add\" btnSize=\"lg\" [text]=\"'Create New'\" [fullWidth]=\"true\" (clicked)=\"openCreateForm()\"\n [customClass]=\"'cqa-text-[14px] cqa-py-[9px] cqa-border-[#414146]'\"></cqa-button>\n </div>\n </div>\n </div>\n </ng-container>\n\n</div>\n", components: [{ type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { 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: ButtonComponent, selector: "cqa-button", inputs: ["variant", "btnSize", "disabled", "icon", "iconPosition", "fullWidth", "iconColor", "type", "text", "customClass", "inlineStyles", "tooltip", "tooltipPosition"], outputs: ["clicked"] }, { 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: SearchBarComponent, selector: "cqa-search-bar", inputs: ["placeholder", "value", "disabled", "showClear", "ariaLabel", "autoFocus", "size", "fullWidth"], outputs: ["valueChange", "search", "cleared"] }, { type: ElementListComponent, selector: "cqa-element-list", inputs: ["items", "titleKey", "selectorKey", "labelsKey", "maxHeight", "hasMore"], outputs: ["itemClick", "loadMore"] }], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { 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 });
|
|
19051
|
+
ElementPopupComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: ElementPopupComponent, deps: [{ token: CUSTOM_ELEMENT_POPUP_REF, optional: true }, { token: ELEMENT_POPUP_DATA, optional: true }, { token: i0.ChangeDetectorRef, optional: true }], target: i0.ɵɵFactoryTarget.Component });
|
|
19052
|
+
ElementPopupComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: ElementPopupComponent, selector: "cqa-element-popup", inputs: { value: "value", helpUrl: "helpUrl", labels: "labels", element: "element", elements: "elements", enableForm: "enableForm", isOnRecord: "isOnRecord", hasMoreElements: "hasMoreElements", elementId: "elementId", screenNameOptions: "screenNameOptions", hasMoreScreenNames: "hasMoreScreenNames", isLoadingScreenNames: "isLoadingScreenNames", suggestedTags: "suggestedTags", isElementLoading: "isElementLoading", recentSearchedItems: "recentSearchedItems" }, outputs: { apply: "apply", cancel: "cancel", editInDepth: "editInDepth", searchElement: "searchElement", recentItemClick: "recentItemClick", loadMoreElements: "loadMoreElements", createElement: "createElement", updateElement: "updateElement", createScreenNameRequest: "createScreenNameRequest", searchScreenName: "searchScreenName", loadMoreScreenNames: "loadMoreScreenNames", formOpenRequest: "formOpenRequest", elementSelect: "elementSelect", toggleRecord: "toggleRecord" }, host: { classAttribute: "cqa-ui-root" }, viewQueries: [{ propertyName: "elementFormComponent", first: true, predicate: ElementFormComponent, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div\n class=\"cqa-bg-white cqa-rounded-[12px] cqa-shadow-lg cqa-border cqa-border-solid cqa-border-[#E5E7EB] cqa-w-[500px] cqa-flex cqa-flex-col cqa-gap-[12px] cqa-p-2 cqa-box-border\">\n <!-- Header: title left; Need help? + close icon right -->\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-2 cqa-px-4\">\n <h2 class=\"cqa-text-[16px] cqa-leading-[24px] cqa-font-bold cqa-text-[#111827] cqa-m-0 cqa-font-[600]\">\n Element\n </h2>\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <!-- Need help? with custom tooltip (works inside overlay) -->\n <div class=\"cqa-relative cqa-inline-flex\"\n (mouseenter)=\"showHelpTooltip = true\" (mouseleave)=\"showHelpTooltip = false\">\n <a *ngIf=\"helpUrl\" href=\"#\" (click)=\"onHelp($event)\"\n class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-text-[#3F43EE] cqa-text-[12px] cqa-leading-[21px] cqa-no-underline cqa-cursor-pointer\">\n <svg width=\"17\" height=\"16\" viewBox=\"0 0 17 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" class=\"cqa-flex-shrink-0\" aria-hidden=\"true\">\n <g clip-path=\"url(#help-icon-clip)\">\n <path d=\"M8.50033 14.6663C12.4123 14.6663 15.5837 11.6816 15.5837 7.99967C15.5837 4.31778 12.4123 1.33301 8.50033 1.33301C4.58831 1.33301 1.41699 4.31778 1.41699 7.99967C1.41699 11.6816 4.58831 14.6663 8.50033 14.6663Z\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M6.43848 6.00038C6.60501 5.55483 6.93371 5.17912 7.36636 4.9398C7.79901 4.70049 8.30769 4.61301 8.80231 4.69285C9.29693 4.7727 9.74556 5.01473 10.0687 5.37607C10.3919 5.7374 10.5688 6.19473 10.5681 6.66705C10.5681 8.00038 8.44306 8.66705 8.44306 8.66705\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M8.5 11.333H8.50966\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </g>\n <defs>\n <clipPath id=\"help-icon-clip\">\n <rect width=\"17\" height=\"16\" fill=\"white\"/>\n </clipPath>\n </defs>\n </svg>\n Need help ?\n </a>\n <span *ngIf=\"!helpUrl\" class=\"cqa-flex cqa-items-center cqa-gap-1.5 cqa-font-[500] cqa-text-[10px] cqa-cursor-default\">\n <svg width=\"17\" height=\"16\" viewBox=\"0 0 17 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" class=\"cqa-flex-shrink-0 cqa-text-[#3F43EE]\" aria-hidden=\"true\">\n <g clip-path=\"url(#help-icon-clip-nolink)\">\n <path d=\"M8.50033 14.6663C12.4123 14.6663 15.5837 11.6816 15.5837 7.99967C15.5837 4.31778 12.4123 1.33301 8.50033 1.33301C4.58831 1.33301 1.41699 4.31778 1.41699 7.99967C1.41699 11.6816 4.58831 14.6663 8.50033 14.6663Z\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M6.43848 6.00038C6.60501 5.55483 6.93371 5.17912 7.36636 4.9398C7.79901 4.70049 8.30769 4.61301 8.80231 4.69285C9.29693 4.7727 9.74556 5.01473 10.0687 5.37607C10.3919 5.7374 10.5688 6.19473 10.5681 6.66705C10.5681 8.00038 8.44306 8.66705 8.44306 8.66705\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M8.5 11.333H8.50966\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </g>\n <defs>\n <clipPath id=\"help-icon-clip-nolink\">\n <rect width=\"17\" height=\"16\" fill=\"white\"/>\n </clipPath>\n </defs>\n </svg>\n Need help ?\n </span>\n <!-- Custom tooltip (exact spec: 306\u00D720 content, 6px radius, #0A0A0A, no arrow) -->\n <div *ngIf=\"showHelpTooltip\" class=\"cqa-absolute cqa-pointer-events-none cqa-z-[100]\"\n style=\"top: -24px; left: -125px;\"\n role=\"tooltip\">\n <div class=\"cqa-text-white cqa-text-center cqa-whitespace-nowrap\"\n style=\"width: 306px; min-height: 20px; border-radius: 6px; opacity: 1; padding: 4px 8px; background-color: #0A0A0A; line-height: 20px; font-size: 8px;\">\n {{ helpTooltipText }}\n </div>\n </div>\n </div>\n <button type=\"button\" (click)=\"onClose()\"\n class=\"cqa-p-1 cqa-rounded cqa-text-[#6B7280] hover:cqa-bg-[#F3F4F6] cqa-flex cqa-items-center cqa-justify-center\"\n title=\"Close\" aria-label=\"Close\">\n <mat-icon class=\"!cqa-w-5 !cqa-h-5 !cqa-text-[20px]\">close</mat-icon>\n </button>\n </div>\n </div>\n\n <!-- Line below header (full width of modal, no side margin) -->\n <div class=\"cqa--mx-2 cqa-w-[calc(100%+1rem)] cqa-flex-shrink-0\">\n <div class=\"cqa-h-px cqa-w-full cqa-bg-[#E5E7EB]\" role=\"presentation\"></div>\n </div>\n\n <ng-container *ngIf=\"enableForm && !isOnRecord\">\n <cqa-element-form\n #elementForm\n [elementId]=\"elementId\"\n [element]=\"element\"\n [screenNameOptions]=\"screenNameOptions\"\n [hasMoreScreenNames]=\"hasMoreScreenNames\"\n [isLoadingScreenNames]=\"isLoadingScreenNames\"\n [isElementLoading]=\"isElementLoading\"\n [isEditMode]=\"isEditMode\"\n [isCreateMode]=\"isCreateMode\"\n (createElement)=\"onElementFormCreate($event)\"\n (updateElement)=\"onElementFormUpdate($event)\"\n (createScreenNameRequest)=\"createScreenNameRequest.emit($event)\"\n (searchScreenName)=\"searchScreenName.emit($event)\"\n (loadMoreScreenNames)=\"loadMoreScreenNames.emit($event)\"\n (cancel)=\"onElementFormCancel()\"\n (editInDepth)=\"onEditInDepth()\">\n </cqa-element-form>\n </ng-container>\n\n<ng-container *ngIf=\"isOnRecord && !enableForm\">\n <div\n class=\"cqa-flex cqa-flex-col cqa-items-center cqa-justify-center cqa-text-center cqa-gap-3 cqa-pt-10\">\n\n <!-- Video Icon -->\n <div\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-[64px] cqa-h-[64px] cqa-rounded-full cqa-bg-[#FEE2E2]\">\n <svg width=\"32\" height=\"32\" viewBox=\"0 0 32 32\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M21.333 17.3333L28.297 21.9759C28.3974 22.0428 28.514 22.0811 28.6345 22.0868C28.7549 22.0926 28.8747 22.0656 28.981 22.0087C29.0873 21.9517 29.1762 21.8671 29.2382 21.7636C29.3002 21.6602 29.3329 21.5419 29.333 21.4213V10.4933C29.333 10.376 29.3021 10.2607 29.2434 10.1592C29.1846 10.0577 29.1001 9.97344 28.9984 9.91501C28.8967 9.85658 28.7814 9.82602 28.6641 9.82642C28.5468 9.82682 28.4317 9.85816 28.3303 9.91728L21.333 13.9999\" stroke=\"#E7000B\" stroke-width=\"2.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M18.667 8H5.33366C3.8609 8 2.66699 9.19391 2.66699 10.6667V21.3333C2.66699 22.8061 3.8609 24 5.33366 24H18.667C20.1398 24 21.3337 22.8061 21.3337 21.3333V10.6667C21.3337 9.19391 20.1398 8 18.667 8Z\" stroke=\"#E7000B\" stroke-width=\"2.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n \n </div>\n\n <!-- Title -->\n <h4 class=\"cqa-m-0 cqa-text-[16px] cqa-leading-[24px] cqa-font-[600] cqa-text-[#0A0A0A]\">\n Recording Mode Active\n </h4>\n\n <!-- Subtitle -->\n <p class=\"cqa-m-0 cqa-text-[12px] cqa-leading-[18px] cqa-text-[#6B7280]\">\n Click on any element in the browser to capture it\n </p>\n </div>\n\n <!-- Footer -->\n <div class=\"cqa-flex cqa-justify-center cqa-pb-4\">\n <cqa-button\n variant=\"outlined\"\n btnSize=\"lg\"\n [text]=\"'Cancel Recording'\"\n (clicked)=\"onToggleRecordClick()\"\n [customClass]=\"'cqa-text-[14px] cqa-px-16 cqa-py-[9px] cqa-border-[#414146]'\">\n </cqa-button>\n </div>\n</ng-container>\n\n\n <ng-container *ngIf=\"!enableForm && !isOnRecord\">\n<div class=\"cqa-flex cqa-flex-col cqa-gap-4 cqa-px-1 cqa-pt-3\">\n\n <!-- Selected -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-2\">\n <span class=\"cqa-text-[12px] cqa-text-[#6B7280]\">Selected</span>\n\n <div\n class=\"cqa-flex cqa-items-center cqa-justify-between\n cqa-bg-[#FFFBEB] cqa-border cqa-border-[#fadfba]\n cqa-rounded-lg cqa-p-3 cqa-border-solid cqa-gap-3\">\n\n <div class=\"cqa-flex cqa-px-3 cqa-py-2 cqa-rounded-lg cqa-flex-col cqa-gap-0.5 cqa-bg-[#f5f5f5] cqa-flex-1\">\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-2\">\n <span class=\"cqa-text-[14px] cqa-font-[600] cqa-text-[#111827]\">\n {{element.title}}\n </span>\n\n <div class=\"cqa-flex cqa-gap-2\">\n <span *ngFor=\"let l of element.labels\"\n class=\"cqa-text-[10px] cqa-px-1.5 cqa-py-0.5\n cqa-rounded cqa-bg-[#EEF2FF] cqa-text-[#3F43EE] cqa-rounded-full cqa-px-2 cqa-bg-[#eff6ff] cqa-border cqa-border-solid cqa-border-[#c8e0ff]\">\n {{l}}\n </span>\n </div>\n </div>\n\n <span class=\"cqa-text-[11px] cqa-text-[#6B7280]\">\n {{element.selector}}\n </span>\n </div>\n <cqa-button variant=\"outlined\" icon=\"edit\" btnSize=\"lg\" [text]=\"'Edit'\" [fullWidth]=\"true\" (clicked)=\"toggleForm()\"\n [customClass]=\"'cqa-text-[14px] cqa-py-[9px] cqa-border-[#414146]'\"></cqa-button>\n </div>\n </div>\n\n <!-- Recent -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-2\" *ngIf=\"recentSearchedItems.length > 0\">\n <span class=\"cqa-text-[12px] cqa-text-[#6B7280]\">Recent</span>\n\n <div class=\"cqa-flex cqa-gap-2 cqa-overflow-x-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\n <div *ngFor=\"let item of recentSearchedItems\" \n class=\"cqa-cursor-pointer cqa-inline-block\"\n (click)=\"onRecentItemClick(item)\">\n <cqa-badge \n class=\"cqa-element-badge cqa-mb-2 cqa-chip !cqa-bg-white !cqa-text-[12px] cqa-whitespace-nowrap\" \n [label]=\"item\"></cqa-badge>\n </div>\n </div>\n </div>\n\n <!-- Element Library -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-2\">\n <span class=\"cqa-text-[12px] cqa-text-[#6B7280]\">Element Library</span>\n <cqa-search-bar [fullWidth]=\"true\" [value]=\"searchValue\" placeholder=\"Search library\" (valueChange)=\"search($event)\"></cqa-search-bar> \n </div>\n\n <cqa-element-list \n [items]=\"elements\"\n [titleKey]=\"'title'\"\n [selectorKey]=\"'selector'\"\n [labelsKey]=\"'labels'\"\n [maxHeight]=\"'200px'\"\n [hasMore]=\"hasMoreElements\"\n (itemClick)=\"onElementClick($event)\"\n (loadMore)=\"onLoadMoreElements()\">\n </cqa-element-list>\n</div>\n\n\n <!-- Footer: Cancel, Apply (full width in one row) -->\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\" icon=\"radio_button_checked\" btnSize=\"lg\" [text]=\"'Record'\" [fullWidth]=\"true\" (clicked)=\"onToggleRecordClick()\"\n [customClass]=\"'cqa-text-[14px] cqa-py-[9px] cqa-border-[#414146]'\"></cqa-button>\n </div>\n <div class=\"cqa-flex-1 cqa-min-w-0\">\n <cqa-button variant=\"outlined\" icon=\"add\" btnSize=\"lg\" [text]=\"'Create New'\" [fullWidth]=\"true\" (clicked)=\"openCreateForm()\"\n [customClass]=\"'cqa-text-[14px] cqa-py-[9px] cqa-border-[#414146]'\"></cqa-button>\n </div>\n </div>\n </div>\n </ng-container>\n\n</div>\n", components: [{ type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: ElementFormComponent, selector: "cqa-element-form", inputs: ["elementId", "element", "screenNameOptions", "hasMoreScreenNames", "isLoadingScreenNames", "isElementLoading", "isEditMode", "isCreateMode", "isEditInDepthAvailable"], outputs: ["createElement", "updateElement", "createScreenNameRequest", "searchScreenName", "loadMoreScreenNames", "cancel", "editInDepth"] }, { type: ButtonComponent, selector: "cqa-button", inputs: ["variant", "btnSize", "disabled", "icon", "iconPosition", "fullWidth", "iconColor", "type", "text", "customClass", "inlineStyles", "tooltip", "tooltipPosition"], outputs: ["clicked"] }, { 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: SearchBarComponent, selector: "cqa-search-bar", inputs: ["placeholder", "value", "disabled", "showClear", "ariaLabel", "autoFocus", "size", "fullWidth"], outputs: ["valueChange", "search", "cleared"] }, { type: ElementListComponent, selector: "cqa-element-list", inputs: ["items", "titleKey", "selectorKey", "labelsKey", "maxHeight", "hasMore"], outputs: ["itemClick", "loadMore"] }], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
18939
19053
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: ElementPopupComponent, decorators: [{
|
|
18940
19054
|
type: Component,
|
|
18941
|
-
args: [{ selector: 'cqa-element-popup', host: { class: 'cqa-ui-root' }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"cqa-bg-white cqa-rounded-[12px] cqa-shadow-lg cqa-border cqa-border-solid cqa-border-[#E5E7EB] cqa-w-[500px] cqa-flex cqa-flex-col cqa-gap-[12px] cqa-p-2 cqa-box-border\">\n <!-- Header: title left; Need help? + close icon right -->\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-2 cqa-px-4\">\n <h2 class=\"cqa-text-[16px] cqa-leading-[24px] cqa-font-bold cqa-text-[#111827] cqa-m-0 cqa-font-[600]\">\n Element\n </h2>\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <!-- Need help? with custom tooltip (works inside overlay) -->\n <div class=\"cqa-relative cqa-inline-flex\"\n (mouseenter)=\"showHelpTooltip = true\" (mouseleave)=\"showHelpTooltip = false\">\n <a *ngIf=\"helpUrl\" href=\"#\" (click)=\"onHelp($event)\"\n class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-text-[#3F43EE] cqa-text-[12px] cqa-leading-[21px] cqa-no-underline cqa-cursor-pointer\">\n <svg width=\"17\" height=\"16\" viewBox=\"0 0 17 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" class=\"cqa-flex-shrink-0\" aria-hidden=\"true\">\n <g clip-path=\"url(#help-icon-clip)\">\n <path d=\"M8.50033 14.6663C12.4123 14.6663 15.5837 11.6816 15.5837 7.99967C15.5837 4.31778 12.4123 1.33301 8.50033 1.33301C4.58831 1.33301 1.41699 4.31778 1.41699 7.99967C1.41699 11.6816 4.58831 14.6663 8.50033 14.6663Z\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M6.43848 6.00038C6.60501 5.55483 6.93371 5.17912 7.36636 4.9398C7.79901 4.70049 8.30769 4.61301 8.80231 4.69285C9.29693 4.7727 9.74556 5.01473 10.0687 5.37607C10.3919 5.7374 10.5688 6.19473 10.5681 6.66705C10.5681 8.00038 8.44306 8.66705 8.44306 8.66705\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M8.5 11.333H8.50966\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </g>\n <defs>\n <clipPath id=\"help-icon-clip\">\n <rect width=\"17\" height=\"16\" fill=\"white\"/>\n </clipPath>\n </defs>\n </svg>\n Need help ?\n </a>\n <span *ngIf=\"!helpUrl\" class=\"cqa-flex cqa-items-center cqa-gap-1.5 cqa-font-[500] cqa-text-[10px] cqa-cursor-default\">\n <svg width=\"17\" height=\"16\" viewBox=\"0 0 17 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" class=\"cqa-flex-shrink-0 cqa-text-[#3F43EE]\" aria-hidden=\"true\">\n <g clip-path=\"url(#help-icon-clip-nolink)\">\n <path d=\"M8.50033 14.6663C12.4123 14.6663 15.5837 11.6816 15.5837 7.99967C15.5837 4.31778 12.4123 1.33301 8.50033 1.33301C4.58831 1.33301 1.41699 4.31778 1.41699 7.99967C1.41699 11.6816 4.58831 14.6663 8.50033 14.6663Z\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M6.43848 6.00038C6.60501 5.55483 6.93371 5.17912 7.36636 4.9398C7.79901 4.70049 8.30769 4.61301 8.80231 4.69285C9.29693 4.7727 9.74556 5.01473 10.0687 5.37607C10.3919 5.7374 10.5688 6.19473 10.5681 6.66705C10.5681 8.00038 8.44306 8.66705 8.44306 8.66705\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M8.5 11.333H8.50966\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </g>\n <defs>\n <clipPath id=\"help-icon-clip-nolink\">\n <rect width=\"17\" height=\"16\" fill=\"white\"/>\n </clipPath>\n </defs>\n </svg>\n Need help ?\n </span>\n <!-- Custom tooltip (exact spec: 306\u00D720 content, 6px radius, #0A0A0A, no arrow) -->\n <div *ngIf=\"showHelpTooltip\" class=\"cqa-absolute cqa-pointer-events-none cqa-z-[100]\"\n style=\"top: -24px; left: -125px;\"\n role=\"tooltip\">\n <div class=\"cqa-text-white cqa-text-center cqa-whitespace-nowrap\"\n style=\"width: 306px; min-height: 20px; border-radius: 6px; opacity: 1; padding: 4px 8px; background-color: #0A0A0A; line-height: 20px; font-size: 8px;\">\n {{ helpTooltipText }}\n </div>\n </div>\n </div>\n <button type=\"button\" (click)=\"onClose()\"\n class=\"cqa-p-1 cqa-rounded cqa-text-[#6B7280] hover:cqa-bg-[#F3F4F6] cqa-flex cqa-items-center cqa-justify-center\"\n title=\"Close\" aria-label=\"Close\">\n <mat-icon class=\"!cqa-w-5 !cqa-h-5 !cqa-text-[20px]\">close</mat-icon>\n </button>\n </div>\n </div>\n\n <!-- Line below header (full width of modal, no side margin) -->\n <div class=\"cqa--mx-2 cqa-w-[calc(100%+1rem)] cqa-flex-shrink-0\">\n <div class=\"cqa-h-px cqa-w-full cqa-bg-[#E5E7EB]\" role=\"presentation\"></div>\n </div>\n\n <ng-container *ngIf=\"enableForm && !isOnRecord\">\n <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 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 <span *ngFor=\"let tag of formLabels\"\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-full cqa-text-[12px] cqa-text-[#3F43EE]\">\n {{ tag }}\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 </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)=\"toggleForm()\"\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=\"#\" (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 </ng-container>\n\n<ng-container *ngIf=\"isOnRecord && !enableForm\">\n <div\n class=\"cqa-flex cqa-flex-col cqa-items-center cqa-justify-center cqa-text-center cqa-gap-3 cqa-pt-10\">\n\n <!-- Video Icon -->\n <div\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-[64px] cqa-h-[64px] cqa-rounded-full cqa-bg-[#FEE2E2]\">\n <svg width=\"32\" height=\"32\" viewBox=\"0 0 32 32\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M21.333 17.3333L28.297 21.9759C28.3974 22.0428 28.514 22.0811 28.6345 22.0868C28.7549 22.0926 28.8747 22.0656 28.981 22.0087C29.0873 21.9517 29.1762 21.8671 29.2382 21.7636C29.3002 21.6602 29.3329 21.5419 29.333 21.4213V10.4933C29.333 10.376 29.3021 10.2607 29.2434 10.1592C29.1846 10.0577 29.1001 9.97344 28.9984 9.91501C28.8967 9.85658 28.7814 9.82602 28.6641 9.82642C28.5468 9.82682 28.4317 9.85816 28.3303 9.91728L21.333 13.9999\" stroke=\"#E7000B\" stroke-width=\"2.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M18.667 8H5.33366C3.8609 8 2.66699 9.19391 2.66699 10.6667V21.3333C2.66699 22.8061 3.8609 24 5.33366 24H18.667C20.1398 24 21.3337 22.8061 21.3337 21.3333V10.6667C21.3337 9.19391 20.1398 8 18.667 8Z\" stroke=\"#E7000B\" stroke-width=\"2.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n \n </div>\n\n <!-- Title -->\n <h4 class=\"cqa-m-0 cqa-text-[16px] cqa-leading-[24px] cqa-font-[600] cqa-text-[#0A0A0A]\">\n Recording Mode Active\n </h4>\n\n <!-- Subtitle -->\n <p class=\"cqa-m-0 cqa-text-[12px] cqa-leading-[18px] cqa-text-[#6B7280]\">\n Click on any element in the browser to capture it\n </p>\n </div>\n\n <!-- Footer -->\n <div class=\"cqa-flex cqa-justify-center cqa-pb-4\">\n <cqa-button\n variant=\"outlined\"\n btnSize=\"lg\"\n [text]=\"'Cancel Recording'\"\n (clicked)=\"onToggleRecordClick()\"\n [customClass]=\"'cqa-text-[14px] cqa-px-16 cqa-py-[9px] cqa-border-[#414146]'\">\n </cqa-button>\n </div>\n</ng-container>\n\n\n <ng-container *ngIf=\"!enableForm && !isOnRecord\">\n<div class=\"cqa-flex cqa-flex-col cqa-gap-4 cqa-px-1 cqa-pt-3\">\n\n <!-- Selected -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-2\">\n <span class=\"cqa-text-[12px] cqa-text-[#6B7280]\">Selected</span>\n\n <div\n class=\"cqa-flex cqa-items-center cqa-justify-between\n cqa-bg-[#FFFBEB] cqa-border cqa-border-[#fadfba]\n cqa-rounded-lg cqa-p-3 cqa-border-solid cqa-gap-3\">\n\n <div class=\"cqa-flex cqa-px-3 cqa-py-2 cqa-rounded-lg cqa-flex-col cqa-gap-0.5 cqa-bg-[#f5f5f5] cqa-flex-1\">\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-2\">\n <span class=\"cqa-text-[14px] cqa-font-[600] cqa-text-[#111827]\">\n {{element.title}}\n </span>\n\n <div class=\"cqa-flex cqa-gap-2\">\n <span *ngFor=\"let l of element.labels\"\n class=\"cqa-text-[10px] cqa-px-1.5 cqa-py-0.5\n cqa-rounded cqa-bg-[#EEF2FF] cqa-text-[#3F43EE] cqa-rounded-full cqa-px-2 cqa-bg-[#eff6ff] cqa-border cqa-border-solid cqa-border-[#c8e0ff]\">\n {{l}}\n </span>\n </div>\n </div>\n\n <span class=\"cqa-text-[11px] cqa-text-[#6B7280]\">\n {{element.selector}}\n </span>\n </div>\n <cqa-button variant=\"outlined\" icon=\"edit\" btnSize=\"lg\" [text]=\"'Edit'\" [fullWidth]=\"true\" (clicked)=\"toggleForm()\"\n [customClass]=\"'cqa-text-[14px] cqa-py-[9px] cqa-border-[#414146]'\"></cqa-button>\n </div>\n </div>\n\n <!-- Recent -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-2\" *ngIf=\"recentSearchedItems.length > 0\">\n <span class=\"cqa-text-[12px] cqa-text-[#6B7280]\">Recent</span>\n\n <div class=\"cqa-flex cqa-gap-2 cqa-overflow-x-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\n <div *ngFor=\"let item of recentSearchedItems\" \n class=\"cqa-cursor-pointer cqa-inline-block\"\n (click)=\"onRecentItemClick(item)\">\n <cqa-badge \n class=\"cqa-element-badge cqa-mb-2 cqa-chip !cqa-bg-white !cqa-text-[12px] cqa-whitespace-nowrap\" \n [label]=\"item\"></cqa-badge>\n </div>\n </div>\n </div>\n\n <!-- Element Library -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-2\">\n <span class=\"cqa-text-[12px] cqa-text-[#6B7280]\">Element Library</span>\n <cqa-search-bar [fullWidth]=\"true\" [value]=\"searchValue\" placeholder=\"Search library\" (valueChange)=\"search($event)\"></cqa-search-bar> \n </div>\n\n <cqa-element-list \n [items]=\"elements\"\n [titleKey]=\"'title'\"\n [selectorKey]=\"'selector'\"\n [labelsKey]=\"'labels'\"\n [maxHeight]=\"'200px'\"\n [hasMore]=\"hasMoreElements\"\n (itemClick)=\"onElementClick($event)\"\n (loadMore)=\"onLoadMoreElements()\">\n </cqa-element-list>\n</div>\n\n\n <!-- Footer: Cancel, Apply (full width in one row) -->\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\" icon=\"radio_button_checked\" btnSize=\"lg\" [text]=\"'Record'\" [fullWidth]=\"true\" (clicked)=\"onToggleRecordClick()\"\n [customClass]=\"'cqa-text-[14px] cqa-py-[9px] cqa-border-[#414146]'\"></cqa-button>\n </div>\n <div class=\"cqa-flex-1 cqa-min-w-0\">\n <cqa-button variant=\"outlined\" icon=\"add\" btnSize=\"lg\" [text]=\"'Create New'\" [fullWidth]=\"true\" (clicked)=\"openCreateForm()\"\n [customClass]=\"'cqa-text-[14px] cqa-py-[9px] cqa-border-[#414146]'\"></cqa-button>\n </div>\n </div>\n </div>\n </ng-container>\n\n</div>\n" }]
|
|
19055
|
+
args: [{ selector: 'cqa-element-popup', host: { class: 'cqa-ui-root' }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"cqa-bg-white cqa-rounded-[12px] cqa-shadow-lg cqa-border cqa-border-solid cqa-border-[#E5E7EB] cqa-w-[500px] cqa-flex cqa-flex-col cqa-gap-[12px] cqa-p-2 cqa-box-border\">\n <!-- Header: title left; Need help? + close icon right -->\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-2 cqa-px-4\">\n <h2 class=\"cqa-text-[16px] cqa-leading-[24px] cqa-font-bold cqa-text-[#111827] cqa-m-0 cqa-font-[600]\">\n Element\n </h2>\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <!-- Need help? with custom tooltip (works inside overlay) -->\n <div class=\"cqa-relative cqa-inline-flex\"\n (mouseenter)=\"showHelpTooltip = true\" (mouseleave)=\"showHelpTooltip = false\">\n <a *ngIf=\"helpUrl\" href=\"#\" (click)=\"onHelp($event)\"\n class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-text-[#3F43EE] cqa-text-[12px] cqa-leading-[21px] cqa-no-underline cqa-cursor-pointer\">\n <svg width=\"17\" height=\"16\" viewBox=\"0 0 17 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" class=\"cqa-flex-shrink-0\" aria-hidden=\"true\">\n <g clip-path=\"url(#help-icon-clip)\">\n <path d=\"M8.50033 14.6663C12.4123 14.6663 15.5837 11.6816 15.5837 7.99967C15.5837 4.31778 12.4123 1.33301 8.50033 1.33301C4.58831 1.33301 1.41699 4.31778 1.41699 7.99967C1.41699 11.6816 4.58831 14.6663 8.50033 14.6663Z\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M6.43848 6.00038C6.60501 5.55483 6.93371 5.17912 7.36636 4.9398C7.79901 4.70049 8.30769 4.61301 8.80231 4.69285C9.29693 4.7727 9.74556 5.01473 10.0687 5.37607C10.3919 5.7374 10.5688 6.19473 10.5681 6.66705C10.5681 8.00038 8.44306 8.66705 8.44306 8.66705\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M8.5 11.333H8.50966\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </g>\n <defs>\n <clipPath id=\"help-icon-clip\">\n <rect width=\"17\" height=\"16\" fill=\"white\"/>\n </clipPath>\n </defs>\n </svg>\n Need help ?\n </a>\n <span *ngIf=\"!helpUrl\" class=\"cqa-flex cqa-items-center cqa-gap-1.5 cqa-font-[500] cqa-text-[10px] cqa-cursor-default\">\n <svg width=\"17\" height=\"16\" viewBox=\"0 0 17 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" class=\"cqa-flex-shrink-0 cqa-text-[#3F43EE]\" aria-hidden=\"true\">\n <g clip-path=\"url(#help-icon-clip-nolink)\">\n <path d=\"M8.50033 14.6663C12.4123 14.6663 15.5837 11.6816 15.5837 7.99967C15.5837 4.31778 12.4123 1.33301 8.50033 1.33301C4.58831 1.33301 1.41699 4.31778 1.41699 7.99967C1.41699 11.6816 4.58831 14.6663 8.50033 14.6663Z\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M6.43848 6.00038C6.60501 5.55483 6.93371 5.17912 7.36636 4.9398C7.79901 4.70049 8.30769 4.61301 8.80231 4.69285C9.29693 4.7727 9.74556 5.01473 10.0687 5.37607C10.3919 5.7374 10.5688 6.19473 10.5681 6.66705C10.5681 8.00038 8.44306 8.66705 8.44306 8.66705\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M8.5 11.333H8.50966\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </g>\n <defs>\n <clipPath id=\"help-icon-clip-nolink\">\n <rect width=\"17\" height=\"16\" fill=\"white\"/>\n </clipPath>\n </defs>\n </svg>\n Need help ?\n </span>\n <!-- Custom tooltip (exact spec: 306\u00D720 content, 6px radius, #0A0A0A, no arrow) -->\n <div *ngIf=\"showHelpTooltip\" class=\"cqa-absolute cqa-pointer-events-none cqa-z-[100]\"\n style=\"top: -24px; left: -125px;\"\n role=\"tooltip\">\n <div class=\"cqa-text-white cqa-text-center cqa-whitespace-nowrap\"\n style=\"width: 306px; min-height: 20px; border-radius: 6px; opacity: 1; padding: 4px 8px; background-color: #0A0A0A; line-height: 20px; font-size: 8px;\">\n {{ helpTooltipText }}\n </div>\n </div>\n </div>\n <button type=\"button\" (click)=\"onClose()\"\n class=\"cqa-p-1 cqa-rounded cqa-text-[#6B7280] hover:cqa-bg-[#F3F4F6] cqa-flex cqa-items-center cqa-justify-center\"\n title=\"Close\" aria-label=\"Close\">\n <mat-icon class=\"!cqa-w-5 !cqa-h-5 !cqa-text-[20px]\">close</mat-icon>\n </button>\n </div>\n </div>\n\n <!-- Line below header (full width of modal, no side margin) -->\n <div class=\"cqa--mx-2 cqa-w-[calc(100%+1rem)] cqa-flex-shrink-0\">\n <div class=\"cqa-h-px cqa-w-full cqa-bg-[#E5E7EB]\" role=\"presentation\"></div>\n </div>\n\n <ng-container *ngIf=\"enableForm && !isOnRecord\">\n <cqa-element-form\n #elementForm\n [elementId]=\"elementId\"\n [element]=\"element\"\n [screenNameOptions]=\"screenNameOptions\"\n [hasMoreScreenNames]=\"hasMoreScreenNames\"\n [isLoadingScreenNames]=\"isLoadingScreenNames\"\n [isElementLoading]=\"isElementLoading\"\n [isEditMode]=\"isEditMode\"\n [isCreateMode]=\"isCreateMode\"\n (createElement)=\"onElementFormCreate($event)\"\n (updateElement)=\"onElementFormUpdate($event)\"\n (createScreenNameRequest)=\"createScreenNameRequest.emit($event)\"\n (searchScreenName)=\"searchScreenName.emit($event)\"\n (loadMoreScreenNames)=\"loadMoreScreenNames.emit($event)\"\n (cancel)=\"onElementFormCancel()\"\n (editInDepth)=\"onEditInDepth()\">\n </cqa-element-form>\n </ng-container>\n\n<ng-container *ngIf=\"isOnRecord && !enableForm\">\n <div\n class=\"cqa-flex cqa-flex-col cqa-items-center cqa-justify-center cqa-text-center cqa-gap-3 cqa-pt-10\">\n\n <!-- Video Icon -->\n <div\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-[64px] cqa-h-[64px] cqa-rounded-full cqa-bg-[#FEE2E2]\">\n <svg width=\"32\" height=\"32\" viewBox=\"0 0 32 32\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M21.333 17.3333L28.297 21.9759C28.3974 22.0428 28.514 22.0811 28.6345 22.0868C28.7549 22.0926 28.8747 22.0656 28.981 22.0087C29.0873 21.9517 29.1762 21.8671 29.2382 21.7636C29.3002 21.6602 29.3329 21.5419 29.333 21.4213V10.4933C29.333 10.376 29.3021 10.2607 29.2434 10.1592C29.1846 10.0577 29.1001 9.97344 28.9984 9.91501C28.8967 9.85658 28.7814 9.82602 28.6641 9.82642C28.5468 9.82682 28.4317 9.85816 28.3303 9.91728L21.333 13.9999\" stroke=\"#E7000B\" stroke-width=\"2.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M18.667 8H5.33366C3.8609 8 2.66699 9.19391 2.66699 10.6667V21.3333C2.66699 22.8061 3.8609 24 5.33366 24H18.667C20.1398 24 21.3337 22.8061 21.3337 21.3333V10.6667C21.3337 9.19391 20.1398 8 18.667 8Z\" stroke=\"#E7000B\" stroke-width=\"2.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n \n </div>\n\n <!-- Title -->\n <h4 class=\"cqa-m-0 cqa-text-[16px] cqa-leading-[24px] cqa-font-[600] cqa-text-[#0A0A0A]\">\n Recording Mode Active\n </h4>\n\n <!-- Subtitle -->\n <p class=\"cqa-m-0 cqa-text-[12px] cqa-leading-[18px] cqa-text-[#6B7280]\">\n Click on any element in the browser to capture it\n </p>\n </div>\n\n <!-- Footer -->\n <div class=\"cqa-flex cqa-justify-center cqa-pb-4\">\n <cqa-button\n variant=\"outlined\"\n btnSize=\"lg\"\n [text]=\"'Cancel Recording'\"\n (clicked)=\"onToggleRecordClick()\"\n [customClass]=\"'cqa-text-[14px] cqa-px-16 cqa-py-[9px] cqa-border-[#414146]'\">\n </cqa-button>\n </div>\n</ng-container>\n\n\n <ng-container *ngIf=\"!enableForm && !isOnRecord\">\n<div class=\"cqa-flex cqa-flex-col cqa-gap-4 cqa-px-1 cqa-pt-3\">\n\n <!-- Selected -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-2\">\n <span class=\"cqa-text-[12px] cqa-text-[#6B7280]\">Selected</span>\n\n <div\n class=\"cqa-flex cqa-items-center cqa-justify-between\n cqa-bg-[#FFFBEB] cqa-border cqa-border-[#fadfba]\n cqa-rounded-lg cqa-p-3 cqa-border-solid cqa-gap-3\">\n\n <div class=\"cqa-flex cqa-px-3 cqa-py-2 cqa-rounded-lg cqa-flex-col cqa-gap-0.5 cqa-bg-[#f5f5f5] cqa-flex-1\">\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-2\">\n <span class=\"cqa-text-[14px] cqa-font-[600] cqa-text-[#111827]\">\n {{element.title}}\n </span>\n\n <div class=\"cqa-flex cqa-gap-2\">\n <span *ngFor=\"let l of element.labels\"\n class=\"cqa-text-[10px] cqa-px-1.5 cqa-py-0.5\n cqa-rounded cqa-bg-[#EEF2FF] cqa-text-[#3F43EE] cqa-rounded-full cqa-px-2 cqa-bg-[#eff6ff] cqa-border cqa-border-solid cqa-border-[#c8e0ff]\">\n {{l}}\n </span>\n </div>\n </div>\n\n <span class=\"cqa-text-[11px] cqa-text-[#6B7280]\">\n {{element.selector}}\n </span>\n </div>\n <cqa-button variant=\"outlined\" icon=\"edit\" btnSize=\"lg\" [text]=\"'Edit'\" [fullWidth]=\"true\" (clicked)=\"toggleForm()\"\n [customClass]=\"'cqa-text-[14px] cqa-py-[9px] cqa-border-[#414146]'\"></cqa-button>\n </div>\n </div>\n\n <!-- Recent -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-2\" *ngIf=\"recentSearchedItems.length > 0\">\n <span class=\"cqa-text-[12px] cqa-text-[#6B7280]\">Recent</span>\n\n <div class=\"cqa-flex cqa-gap-2 cqa-overflow-x-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\n <div *ngFor=\"let item of recentSearchedItems\" \n class=\"cqa-cursor-pointer cqa-inline-block\"\n (click)=\"onRecentItemClick(item)\">\n <cqa-badge \n class=\"cqa-element-badge cqa-mb-2 cqa-chip !cqa-bg-white !cqa-text-[12px] cqa-whitespace-nowrap\" \n [label]=\"item\"></cqa-badge>\n </div>\n </div>\n </div>\n\n <!-- Element Library -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-2\">\n <span class=\"cqa-text-[12px] cqa-text-[#6B7280]\">Element Library</span>\n <cqa-search-bar [fullWidth]=\"true\" [value]=\"searchValue\" placeholder=\"Search library\" (valueChange)=\"search($event)\"></cqa-search-bar> \n </div>\n\n <cqa-element-list \n [items]=\"elements\"\n [titleKey]=\"'title'\"\n [selectorKey]=\"'selector'\"\n [labelsKey]=\"'labels'\"\n [maxHeight]=\"'200px'\"\n [hasMore]=\"hasMoreElements\"\n (itemClick)=\"onElementClick($event)\"\n (loadMore)=\"onLoadMoreElements()\">\n </cqa-element-list>\n</div>\n\n\n <!-- Footer: Cancel, Apply (full width in one row) -->\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\" icon=\"radio_button_checked\" btnSize=\"lg\" [text]=\"'Record'\" [fullWidth]=\"true\" (clicked)=\"onToggleRecordClick()\"\n [customClass]=\"'cqa-text-[14px] cqa-py-[9px] cqa-border-[#414146]'\"></cqa-button>\n </div>\n <div class=\"cqa-flex-1 cqa-min-w-0\">\n <cqa-button variant=\"outlined\" icon=\"add\" btnSize=\"lg\" [text]=\"'Create New'\" [fullWidth]=\"true\" (clicked)=\"openCreateForm()\"\n [customClass]=\"'cqa-text-[14px] cqa-py-[9px] cqa-border-[#414146]'\"></cqa-button>\n </div>\n </div>\n </div>\n </ng-container>\n\n</div>\n" }]
|
|
18942
19056
|
}], ctorParameters: function () {
|
|
18943
19057
|
return [{ type: ElementPopupRef, decorators: [{
|
|
18944
19058
|
type: Optional
|
|
@@ -18950,8 +19064,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
|
|
|
18950
19064
|
}, {
|
|
18951
19065
|
type: Inject,
|
|
18952
19066
|
args: [ELEMENT_POPUP_DATA]
|
|
18953
|
-
}] }, { type: i1$1.FormBuilder, decorators: [{
|
|
18954
|
-
type: Optional
|
|
18955
19067
|
}] }, { type: i0.ChangeDetectorRef, decorators: [{
|
|
18956
19068
|
type: Optional
|
|
18957
19069
|
}] }];
|
|
@@ -19013,6 +19125,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
|
|
|
19013
19125
|
type: Output
|
|
19014
19126
|
}], toggleRecord: [{
|
|
19015
19127
|
type: Output
|
|
19128
|
+
}], elementFormComponent: [{
|
|
19129
|
+
type: ViewChild,
|
|
19130
|
+
args: [ElementFormComponent]
|
|
19016
19131
|
}] } });
|
|
19017
19132
|
|
|
19018
19133
|
class ElementPopupService {
|
|
@@ -25346,13 +25461,30 @@ class TemplateVariablesFormComponent {
|
|
|
25346
25461
|
constructor(cdr) {
|
|
25347
25462
|
this.cdr = cdr;
|
|
25348
25463
|
this.templateVariables = [];
|
|
25349
|
-
this.variablesForm = new
|
|
25464
|
+
this.variablesForm = new FormArray([]);
|
|
25350
25465
|
this.metadata = '';
|
|
25351
25466
|
this.description = '';
|
|
25467
|
+
this.elementOptions = []; // Element objects for element dropdown
|
|
25468
|
+
this.hasMoreElements = false; // Whether more elements are available
|
|
25469
|
+
this.isLoadingElements = false; // Loading state for elements
|
|
25470
|
+
/** Screen name options for element form autocomplete (from API) */
|
|
25471
|
+
this.screenNameOptions = [];
|
|
25472
|
+
/** Whether more screen names are available for infinite scroll */
|
|
25473
|
+
this.hasMoreScreenNames = false;
|
|
25474
|
+
/** True while parent is loading screen names (search or load more) */
|
|
25475
|
+
this.isLoadingScreenNames = false;
|
|
25352
25476
|
this.variableValueChange = new EventEmitter();
|
|
25353
25477
|
this.variableBooleanChange = new EventEmitter();
|
|
25354
25478
|
this.metadataChange = new EventEmitter();
|
|
25355
25479
|
this.descriptionChange = new EventEmitter();
|
|
25480
|
+
this.loadMoreElements = new EventEmitter(); // Emit when load more is requested
|
|
25481
|
+
this.searchElements = new EventEmitter(); // Emit when user searches for elements
|
|
25482
|
+
this.createElement = new EventEmitter(); // Emit when element is created with payload
|
|
25483
|
+
this.searchScreenName = new EventEmitter(); // Emit when user searches screen names
|
|
25484
|
+
this.loadMoreScreenNames = new EventEmitter(); // Emit when user scrolls to load more screen names
|
|
25485
|
+
this.createScreenNameRequest = new EventEmitter(); // Emit when user requests to create a new screen name
|
|
25486
|
+
this.cancelElementForm = new EventEmitter(); // Emit when element form is cancelled
|
|
25487
|
+
this.elementFormVisibilityChange = new EventEmitter(); // Emit when element form visibility changes
|
|
25356
25488
|
// Cache for select configs to avoid recalculating on every change detection
|
|
25357
25489
|
this.selectConfigCache = new Map();
|
|
25358
25490
|
// Cache for data type select configs
|
|
@@ -25371,9 +25503,29 @@ class TemplateVariablesFormComponent {
|
|
|
25371
25503
|
{ id: 'runtime', value: 'runtime', name: '$|Runtime|', label: '$|Runtime|' },
|
|
25372
25504
|
{ id: 'environment', value: 'environment', name: '*|Environment|', label: '*|Environment|' }
|
|
25373
25505
|
];
|
|
25506
|
+
this.createElementVisible = false;
|
|
25507
|
+
}
|
|
25508
|
+
onCreateElement(payload) {
|
|
25509
|
+
console.log('onCreateElement', payload);
|
|
25510
|
+
this.createElement.emit(payload);
|
|
25511
|
+
this.createElementVisible = false;
|
|
25512
|
+
this.elementFormVisibilityChange.emit(false);
|
|
25513
|
+
this.cdr.markForCheck();
|
|
25514
|
+
}
|
|
25515
|
+
onCancelElementForm() {
|
|
25516
|
+
this.createElementVisible = false;
|
|
25517
|
+
this.elementFormVisibilityChange.emit(false);
|
|
25518
|
+
this.cancelElementForm.emit();
|
|
25519
|
+
this.cdr.markForCheck();
|
|
25520
|
+
}
|
|
25521
|
+
onShowElementForm() {
|
|
25522
|
+
this.createElementVisible = true;
|
|
25523
|
+
this.elementFormVisibilityChange.emit(true);
|
|
25524
|
+
this.cdr.markForCheck();
|
|
25374
25525
|
}
|
|
25375
25526
|
ngOnChanges(changes) {
|
|
25376
|
-
if (changes['templateVariables'] || changes['variablesForm']
|
|
25527
|
+
if (changes['templateVariables'] || changes['variablesForm'] || changes['elementOptions'] ||
|
|
25528
|
+
changes['hasMoreElements'] || changes['isLoadingElements']) {
|
|
25377
25529
|
// Clear all caches when inputs change
|
|
25378
25530
|
this.selectConfigCache.clear();
|
|
25379
25531
|
this.dataTypeSelectConfigCache.clear();
|
|
@@ -25390,35 +25542,52 @@ class TemplateVariablesFormComponent {
|
|
|
25390
25542
|
}
|
|
25391
25543
|
}
|
|
25392
25544
|
initializeTestDataVariables() {
|
|
25393
|
-
this.templateVariables.forEach(variable => {
|
|
25545
|
+
this.templateVariables.forEach((variable, index) => {
|
|
25394
25546
|
var _a;
|
|
25395
25547
|
if (this.needsDataTypeDropdown(variable)) {
|
|
25396
25548
|
const { dataType, rawValue } = this.parseTestDataValue(variable.value || '');
|
|
25397
25549
|
this.variableDataTypes.set(variable.name, dataType);
|
|
25398
25550
|
this.variableRawValues.set(variable.name, rawValue);
|
|
25399
|
-
// Ensure form control exists for data type
|
|
25400
|
-
const
|
|
25401
|
-
if (
|
|
25402
|
-
|
|
25403
|
-
|
|
25404
|
-
|
|
25405
|
-
|
|
25551
|
+
// Ensure form control exists for data type in the FormArray
|
|
25552
|
+
const variableGroup = this.getVariableFormGroup(variable.name);
|
|
25553
|
+
if (variableGroup) {
|
|
25554
|
+
if (!variableGroup.get('dataType')) {
|
|
25555
|
+
variableGroup.addControl('dataType', new FormControl(dataType));
|
|
25556
|
+
}
|
|
25557
|
+
else {
|
|
25558
|
+
(_a = variableGroup.get('dataType')) === null || _a === void 0 ? void 0 : _a.setValue(dataType, { emitEvent: false });
|
|
25559
|
+
}
|
|
25406
25560
|
}
|
|
25407
25561
|
}
|
|
25408
25562
|
});
|
|
25409
25563
|
}
|
|
25564
|
+
/** Get form group for a variable by name from FormArray */
|
|
25565
|
+
getVariableFormGroup(variableName) {
|
|
25566
|
+
const variableIndex = this.variablesForm.controls.findIndex(control => { var _a; return ((_a = control.get('name')) === null || _a === void 0 ? void 0 : _a.value) === variableName; });
|
|
25567
|
+
if (variableIndex !== -1) {
|
|
25568
|
+
return this.variablesForm.at(variableIndex);
|
|
25569
|
+
}
|
|
25570
|
+
return null;
|
|
25571
|
+
}
|
|
25572
|
+
/** Get form group at a specific index from FormArray (for template use) */
|
|
25573
|
+
getFormGroupAt(index) {
|
|
25574
|
+
if (index >= 0 && index < this.variablesForm.length) {
|
|
25575
|
+
return this.variablesForm.at(index);
|
|
25576
|
+
}
|
|
25577
|
+
return null;
|
|
25578
|
+
}
|
|
25410
25579
|
precomputeConfigs() {
|
|
25411
25580
|
if (!this.templateVariables)
|
|
25412
25581
|
return;
|
|
25413
25582
|
// Pre-compute all select configs
|
|
25414
|
-
this.templateVariables.forEach(variable => {
|
|
25583
|
+
this.templateVariables.forEach((variable, index) => {
|
|
25415
25584
|
// Pre-compute regular select configs
|
|
25416
25585
|
if (this.shouldShowDropdown(variable)) {
|
|
25417
|
-
this.getSelectConfig(variable);
|
|
25586
|
+
this.getSelectConfig(variable, index);
|
|
25418
25587
|
}
|
|
25419
25588
|
// Pre-compute data type select configs
|
|
25420
25589
|
if (this.needsDataTypeDropdown(variable)) {
|
|
25421
|
-
this.getDataTypeSelectConfig(variable);
|
|
25590
|
+
this.getDataTypeSelectConfig(variable, index);
|
|
25422
25591
|
}
|
|
25423
25592
|
});
|
|
25424
25593
|
}
|
|
@@ -25462,34 +25631,73 @@ class TemplateVariablesFormComponent {
|
|
|
25462
25631
|
trackByVariable(index, variable) {
|
|
25463
25632
|
return variable.name || index;
|
|
25464
25633
|
}
|
|
25465
|
-
getSelectConfig(variable) {
|
|
25466
|
-
var _a;
|
|
25634
|
+
getSelectConfig(variable, index) {
|
|
25635
|
+
var _a, _b;
|
|
25467
25636
|
// Use cache to avoid recalculating on every change detection
|
|
25468
|
-
|
|
25637
|
+
// For element variables, include elementOptions, hasMoreElements, and isLoadingElements in cache key
|
|
25638
|
+
const optionsKey = variable.dataKey === 'element' || variable.dataKey === 'label'
|
|
25639
|
+
? this.elementOptions.map(el => String(el.name || '')).join(',')
|
|
25640
|
+
: (((_a = variable.options) === null || _a === void 0 ? void 0 : _a.join(',')) || '');
|
|
25641
|
+
// Include hasMoreElements and isLoadingElements in cache key for selector variables
|
|
25642
|
+
const cacheKey = variable.dataKey === 'element' || variable.dataKey === 'label'
|
|
25643
|
+
? `${variable.name}_${optionsKey}_${this.hasMoreElements}_${this.isLoadingElements}`
|
|
25644
|
+
: `${variable.name}_${optionsKey}`;
|
|
25469
25645
|
if (this.selectConfigCache.has(cacheKey)) {
|
|
25470
25646
|
return this.selectConfigCache.get(cacheKey);
|
|
25471
25647
|
}
|
|
25472
|
-
|
|
25473
|
-
|
|
25474
|
-
|
|
25475
|
-
|
|
25476
|
-
|
|
25477
|
-
|
|
25648
|
+
// Use elementOptions if variable name is 'selector', otherwise use variable.options
|
|
25649
|
+
// Extract element names from Element objects
|
|
25650
|
+
let optionsArray = [];
|
|
25651
|
+
if (variable.dataKey === 'element' || variable.dataKey === 'label') {
|
|
25652
|
+
// For element options, use locatorValue as both id and value so the component returns locatorValue
|
|
25653
|
+
// This ensures the selected value is the locatorValue (not the element id)
|
|
25654
|
+
optionsArray = this.elementOptions
|
|
25655
|
+
.map(el => {
|
|
25656
|
+
var _a;
|
|
25657
|
+
const locatorValue = el.locatorValue || '';
|
|
25658
|
+
return {
|
|
25659
|
+
id: locatorValue,
|
|
25660
|
+
elementId: ((_a = el.id) === null || _a === void 0 ? void 0 : _a.toString()) || '',
|
|
25661
|
+
value: locatorValue,
|
|
25662
|
+
name: el.name,
|
|
25663
|
+
label: el.name
|
|
25664
|
+
};
|
|
25665
|
+
});
|
|
25666
|
+
}
|
|
25667
|
+
else {
|
|
25668
|
+
optionsArray = ((_b = variable.options) === null || _b === void 0 ? void 0 : _b.map(opt => { return { id: opt, value: opt, name: opt, label: opt }; })) || [];
|
|
25669
|
+
}
|
|
25670
|
+
console.log('optionsArray', optionsArray);
|
|
25478
25671
|
const config = {
|
|
25479
|
-
key:
|
|
25672
|
+
key: 'value',
|
|
25480
25673
|
placeholder: `Select ${variable.label}`,
|
|
25481
25674
|
multiple: false,
|
|
25482
25675
|
searchable: false,
|
|
25483
|
-
options:
|
|
25676
|
+
options: optionsArray,
|
|
25484
25677
|
onChange: (value) => {
|
|
25485
25678
|
this.onVariableValueChange(variable.name, value);
|
|
25486
25679
|
}
|
|
25487
25680
|
};
|
|
25681
|
+
// Add load more and search support for selector variables
|
|
25682
|
+
if (variable.dataKey === 'element' || variable.dataKey === 'label') {
|
|
25683
|
+
config.searchable = true; // Enable search for selector dropdown
|
|
25684
|
+
config.serverSearch = true; // Enable server-side search
|
|
25685
|
+
config.hasMore = this.hasMoreElements;
|
|
25686
|
+
config.isLoading = this.isLoadingElements;
|
|
25687
|
+
config.onLoadMore = () => {
|
|
25688
|
+
this.loadMoreElements.emit();
|
|
25689
|
+
};
|
|
25690
|
+
config.onSearch = (query) => {
|
|
25691
|
+
// Emit search event when user types in the search box
|
|
25692
|
+
this.searchElements.emit(query);
|
|
25693
|
+
};
|
|
25694
|
+
}
|
|
25488
25695
|
this.selectConfigCache.set(cacheKey, config);
|
|
25489
25696
|
return config;
|
|
25490
25697
|
}
|
|
25491
25698
|
onVariableValueChange(variableName, value) {
|
|
25492
25699
|
var _a, _b;
|
|
25700
|
+
console.log("onVariableValueChange", variableName, value);
|
|
25493
25701
|
const variable = this.templateVariables.find(v => v.name === variableName);
|
|
25494
25702
|
if (!variable)
|
|
25495
25703
|
return;
|
|
@@ -25498,17 +25706,18 @@ class TemplateVariablesFormComponent {
|
|
|
25498
25706
|
const { dataType, rawValue } = this.parseTestDataValue(value || '');
|
|
25499
25707
|
this.variableDataTypes.set(variableName, dataType);
|
|
25500
25708
|
this.variableRawValues.set(variableName, rawValue);
|
|
25501
|
-
// Update data type form control
|
|
25502
|
-
const
|
|
25503
|
-
if (
|
|
25504
|
-
(_a =
|
|
25709
|
+
// Update data type form control in FormArray
|
|
25710
|
+
const variableGroup = this.getVariableFormGroup(variableName);
|
|
25711
|
+
if (variableGroup && variableGroup.get('dataType')) {
|
|
25712
|
+
(_a = variableGroup.get('dataType')) === null || _a === void 0 ? void 0 : _a.setValue(dataType, { emitEvent: false });
|
|
25505
25713
|
}
|
|
25506
25714
|
}
|
|
25507
25715
|
// Update the variable in templateVariables array
|
|
25508
25716
|
variable.value = value;
|
|
25509
|
-
// Also update form control (use emitEvent: false to prevent triggering valueChanges)
|
|
25510
|
-
|
|
25511
|
-
|
|
25717
|
+
// Also update form control in FormArray (use emitEvent: false to prevent triggering valueChanges)
|
|
25718
|
+
const variableGroup = this.getVariableFormGroup(variableName);
|
|
25719
|
+
if (variableGroup && variableGroup.get('value')) {
|
|
25720
|
+
(_b = variableGroup.get('value')) === null || _b === void 0 ? void 0 : _b.setValue(value, { emitEvent: false });
|
|
25512
25721
|
}
|
|
25513
25722
|
// Mark for check since we're using OnPush
|
|
25514
25723
|
this.cdr.markForCheck();
|
|
@@ -25522,14 +25731,12 @@ class TemplateVariablesFormComponent {
|
|
|
25522
25731
|
if (variable) {
|
|
25523
25732
|
variable.value = value;
|
|
25524
25733
|
}
|
|
25525
|
-
// Also update form control (use emitEvent: false to prevent triggering valueChanges)
|
|
25526
|
-
|
|
25527
|
-
|
|
25528
|
-
|
|
25529
|
-
else {
|
|
25530
|
-
// Create form control if it doesn't exist
|
|
25531
|
-
this.variablesForm.addControl(variableName, new FormControl(value));
|
|
25734
|
+
// Also update form control in FormArray (use emitEvent: false to prevent triggering valueChanges)
|
|
25735
|
+
const variableGroup = this.getVariableFormGroup(variableName);
|
|
25736
|
+
if (variableGroup && variableGroup.get('value')) {
|
|
25737
|
+
(_a = variableGroup.get('value')) === null || _a === void 0 ? void 0 : _a.setValue(value, { emitEvent: false });
|
|
25532
25738
|
}
|
|
25739
|
+
// Note: If variable doesn't exist in FormArray, it should be added by parent component
|
|
25533
25740
|
// Mark for check since we're using OnPush
|
|
25534
25741
|
this.cdr.markForCheck();
|
|
25535
25742
|
// Emit the change event
|
|
@@ -25540,7 +25747,7 @@ class TemplateVariablesFormComponent {
|
|
|
25540
25747
|
if (this.shouldShowDropdownCache.has(variable.name)) {
|
|
25541
25748
|
return this.shouldShowDropdownCache.get(variable.name);
|
|
25542
25749
|
}
|
|
25543
|
-
const result = variable.name === 'type' || variable.name === 'scrollTo';
|
|
25750
|
+
const result = variable.name === 'type' || variable.name === 'scrollTo' || variable.dataKey === 'element' || variable.dataKey === 'label';
|
|
25544
25751
|
this.shouldShowDropdownCache.set(variable.name, result);
|
|
25545
25752
|
return result;
|
|
25546
25753
|
}
|
|
@@ -25550,8 +25757,8 @@ class TemplateVariablesFormComponent {
|
|
|
25550
25757
|
if (this.needsDataTypeDropdownCache.has(variable.name)) {
|
|
25551
25758
|
return this.needsDataTypeDropdownCache.get(variable.name);
|
|
25552
25759
|
}
|
|
25553
|
-
const
|
|
25554
|
-
const result =
|
|
25760
|
+
const dataKey = ((_a = variable.dataKey) === null || _a === void 0 ? void 0 : _a.toLowerCase()) || '';
|
|
25761
|
+
const result = dataKey === 'test-data' || dataKey === 'source_value' || dataKey === 'target_value';
|
|
25555
25762
|
this.needsDataTypeDropdownCache.set(variable.name, result);
|
|
25556
25763
|
return result;
|
|
25557
25764
|
}
|
|
@@ -25559,20 +25766,20 @@ class TemplateVariablesFormComponent {
|
|
|
25559
25766
|
// Return cached static array
|
|
25560
25767
|
return this.dataTypeOptions;
|
|
25561
25768
|
}
|
|
25562
|
-
getDataTypeSelectConfig(variable) {
|
|
25769
|
+
getDataTypeSelectConfig(variable, index) {
|
|
25563
25770
|
// Use cache to avoid recalculating on every change detection
|
|
25564
25771
|
const cacheKey = `${variable.name}_dataType`;
|
|
25565
25772
|
if (this.dataTypeSelectConfigCache.has(cacheKey)) {
|
|
25566
25773
|
return this.dataTypeSelectConfigCache.get(cacheKey);
|
|
25567
25774
|
}
|
|
25568
|
-
|
|
25569
|
-
|
|
25570
|
-
if (!
|
|
25775
|
+
// Ensure form control exists in FormArray
|
|
25776
|
+
const variableGroup = this.getVariableFormGroup(variable.name);
|
|
25777
|
+
if (variableGroup && !variableGroup.get('dataType')) {
|
|
25571
25778
|
const currentDataType = this.variableDataTypes.get(variable.name) || 'plain-text';
|
|
25572
|
-
|
|
25779
|
+
variableGroup.addControl('dataType', new FormControl(currentDataType));
|
|
25573
25780
|
}
|
|
25574
25781
|
const config = {
|
|
25575
|
-
key:
|
|
25782
|
+
key: 'dataType',
|
|
25576
25783
|
placeholder: 'Select Type',
|
|
25577
25784
|
multiple: false,
|
|
25578
25785
|
searchable: false,
|
|
@@ -25592,6 +25799,40 @@ class TemplateVariablesFormComponent {
|
|
|
25592
25799
|
// Simple getter - already cached in Map, no computation needed
|
|
25593
25800
|
return this.variableRawValues.get(variable.name) || '';
|
|
25594
25801
|
}
|
|
25802
|
+
/**
|
|
25803
|
+
* Check if selector variable is available in templateVariables
|
|
25804
|
+
*/
|
|
25805
|
+
get selectorVariableAvailable() {
|
|
25806
|
+
return this.templateVariables.some(v => v.dataKey === 'element' || v.dataKey === 'label');
|
|
25807
|
+
}
|
|
25808
|
+
/**
|
|
25809
|
+
* Check if parameter variable is available (testData with parameter type)
|
|
25810
|
+
*/
|
|
25811
|
+
get parameterVariableAvailable() {
|
|
25812
|
+
return this.templateVariables.some(v => {
|
|
25813
|
+
var _a;
|
|
25814
|
+
const dataKey = ((_a = v.dataKey) === null || _a === void 0 ? void 0 : _a.toLowerCase()) || '';
|
|
25815
|
+
if (dataKey === 'test-data' || dataKey === 'source_value' || dataKey === 'target_value') {
|
|
25816
|
+
const dataType = this.variableDataTypes.get(v.name) || 'plain-text';
|
|
25817
|
+
return dataType === 'parameter';
|
|
25818
|
+
}
|
|
25819
|
+
return false;
|
|
25820
|
+
});
|
|
25821
|
+
}
|
|
25822
|
+
/**
|
|
25823
|
+
* Check if environment variable is available (testData with environment type)
|
|
25824
|
+
*/
|
|
25825
|
+
get environmentVariableAvailable() {
|
|
25826
|
+
return this.templateVariables.some(v => {
|
|
25827
|
+
var _a;
|
|
25828
|
+
const dataKey = ((_a = v.name) === null || _a === void 0 ? void 0 : _a.toLowerCase()) || '';
|
|
25829
|
+
if (dataKey === 'test-data' || dataKey === 'source_value' || dataKey === 'target_value') {
|
|
25830
|
+
const dataType = this.variableDataTypes.get(v.name) || 'plain-text';
|
|
25831
|
+
return dataType === 'environment';
|
|
25832
|
+
}
|
|
25833
|
+
return false;
|
|
25834
|
+
});
|
|
25835
|
+
}
|
|
25595
25836
|
onDataTypeChange(variableName, dataType) {
|
|
25596
25837
|
var _a;
|
|
25597
25838
|
// Update stored data type
|
|
@@ -25605,9 +25846,10 @@ class TemplateVariablesFormComponent {
|
|
|
25605
25846
|
if (variable) {
|
|
25606
25847
|
variable.value = formattedValue;
|
|
25607
25848
|
}
|
|
25608
|
-
// Update form control
|
|
25609
|
-
|
|
25610
|
-
|
|
25849
|
+
// Update form control in FormArray
|
|
25850
|
+
const variableGroup = this.getVariableFormGroup(variableName);
|
|
25851
|
+
if (variableGroup && variableGroup.get('value')) {
|
|
25852
|
+
(_a = variableGroup.get('value')) === null || _a === void 0 ? void 0 : _a.setValue(formattedValue, { emitEvent: false });
|
|
25611
25853
|
}
|
|
25612
25854
|
// Mark for check since we're using OnPush
|
|
25613
25855
|
this.cdr.markForCheck();
|
|
@@ -25615,6 +25857,12 @@ class TemplateVariablesFormComponent {
|
|
|
25615
25857
|
// Emit the change event
|
|
25616
25858
|
this.variableValueChange.emit({ name: variableName, value: formattedValue });
|
|
25617
25859
|
}
|
|
25860
|
+
onElementSearch(event) {
|
|
25861
|
+
// Only handle search for selector variables
|
|
25862
|
+
// The key will be 'value' since that's what we set in the config
|
|
25863
|
+
// Emit the search query to parent component
|
|
25864
|
+
this.searchElements.emit(event.query);
|
|
25865
|
+
}
|
|
25618
25866
|
onTestDataValueChange(variableName, rawValue) {
|
|
25619
25867
|
var _a;
|
|
25620
25868
|
// Update stored raw value
|
|
@@ -25628,9 +25876,10 @@ class TemplateVariablesFormComponent {
|
|
|
25628
25876
|
if (variable) {
|
|
25629
25877
|
variable.value = formattedValue;
|
|
25630
25878
|
}
|
|
25631
|
-
// Update form control
|
|
25632
|
-
|
|
25633
|
-
|
|
25879
|
+
// Update form control in FormArray
|
|
25880
|
+
const variableGroup = this.getVariableFormGroup(variableName);
|
|
25881
|
+
if (variableGroup && variableGroup.get('value')) {
|
|
25882
|
+
(_a = variableGroup.get('value')) === null || _a === void 0 ? void 0 : _a.setValue(formattedValue, { emitEvent: false });
|
|
25634
25883
|
}
|
|
25635
25884
|
// Mark for check since we're using OnPush
|
|
25636
25885
|
this.cdr.markForCheck();
|
|
@@ -25639,10 +25888,10 @@ class TemplateVariablesFormComponent {
|
|
|
25639
25888
|
}
|
|
25640
25889
|
}
|
|
25641
25890
|
TemplateVariablesFormComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TemplateVariablesFormComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
25642
|
-
TemplateVariablesFormComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: TemplateVariablesFormComponent, selector: "cqa-template-variables-form", inputs: { templateVariables: "templateVariables", variablesForm: "variablesForm", metadata: "metadata", description: "description" }, outputs: { variableValueChange: "variableValueChange", variableBooleanChange: "variableBooleanChange", metadataChange: "metadataChange", descriptionChange: "descriptionChange" }, host: { classAttribute: "cqa-ui-root" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"cqa-flex cqa-gap-x-6 cqa-flex-wrap\">\n <ng-container *ngFor=\"let variable of templateVariables; trackBy: trackByVariable\">\n <!-- Boolean variables with mat-slide-toggle -->\n <ng-container *ngIf=\"variable.type === 'boolean'\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\" style=\"width: calc(50% - 12px);\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700\">\n {{ variable.label }}\n </label>\n <mat-slide-toggle
|
|
25891
|
+
TemplateVariablesFormComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: TemplateVariablesFormComponent, selector: "cqa-template-variables-form", inputs: { templateVariables: "templateVariables", variablesForm: "variablesForm", metadata: "metadata", description: "description", elementOptions: "elementOptions", hasMoreElements: "hasMoreElements", isLoadingElements: "isLoadingElements", screenNameOptions: "screenNameOptions", hasMoreScreenNames: "hasMoreScreenNames", isLoadingScreenNames: "isLoadingScreenNames" }, outputs: { variableValueChange: "variableValueChange", variableBooleanChange: "variableBooleanChange", metadataChange: "metadataChange", descriptionChange: "descriptionChange", loadMoreElements: "loadMoreElements", searchElements: "searchElements", createElement: "createElement", searchScreenName: "searchScreenName", loadMoreScreenNames: "loadMoreScreenNames", createScreenNameRequest: "createScreenNameRequest", cancelElementForm: "cancelElementForm", elementFormVisibilityChange: "elementFormVisibilityChange" }, host: { classAttribute: "cqa-ui-root" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"cqa-flex cqa-gap-x-6 cqa-gap-y-4 cqa-flex-wrap\" *ngIf=\"!createElementVisible\">\n <ng-container *ngFor=\"let variable of templateVariables; let i = index; trackBy: trackByVariable\">\n <!-- Boolean variables with mat-slide-toggle -->\n <ng-container *ngIf=\"variable.type === 'boolean'\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\" style=\"width: calc(50% - 12px);\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700\">\n {{ variable.label }}\n </label>\n <mat-slide-toggle [checked]=\"variablesForm.at(i)?.get('value')?.value || variable.value || false\"\n (change)=\"onVariableBooleanChange(variable.name, $event.checked)\" color=\"primary\">\n </mat-slide-toggle>\n </div>\n </ng-container>\n\n <!-- Non-boolean, non-custom_code variables -->\n <ng-container *ngIf=\"variable.name !== 'custom_code' && variable.type !== 'boolean'\">\n <ng-container *ngIf=\"shouldShowDropdown(variable); else defaultInput\">\n <div class=\"cqa-flex cqa-flex-col\" style=\"width: calc(50% - 12px);\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n {{ variable.label }}\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n </ng-container>\n <ng-template #defaultInput>\n <!-- Test-data, source-value, or target-value with data type dropdown -->\n <ng-container *ngIf=\"needsDataTypeDropdown(variable); else regularInput\">\n <div class=\"cqa-flex cqa-flex-col\" style=\"width: calc(50% - 12px);\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n {{ variable.label }} Type\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getDataTypeSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n <div class=\"cqa-flex cqa-flex-col\" style=\"width: calc(50% - 12px);\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n {{ variable.label }}\n </label>\n <cqa-custom-input [placeholder]=\"'Text Input'\" [value]=\"getRawValue(variable)\" [fullWidth]=\"true\"\n (valueChange)=\"onTestDataValueChange(variable.name, $event)\">\n </cqa-custom-input>\n </div>\n </ng-container>\n <ng-template #regularInput>\n <div class=\"cqa-flex cqa-flex-col\" style=\"width: calc(50% - 12px);\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n {{ variable.label }}\n </label>\n <cqa-custom-input [placeholder]=\"'Text Input'\" [value]=\"variable.value\" [fullWidth]=\"true\"\n (valueChange)=\"onVariableValueChange(variable.name, $event)\">\n </cqa-custom-input>\n </div>\n </ng-template>\n </ng-template>\n </ng-container>\n </ng-container>\n\n <!-- Metadata -->\n <div class=\"cqa-flex cqa-flex-col\" style=\"width: calc(50% - 12px);\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Metadata\n </label>\n <cqa-custom-input [placeholder]=\"'Text Input'\" [value]=\"metadata\" [fullWidth]=\"true\"\n (valueChange)=\"metadataChange.emit($event)\">\n </cqa-custom-input>\n </div>\n\n <!-- Description -->\n <div class=\"cqa-flex cqa-flex-col\" style=\"width: calc(50% - 12px);\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Description\n </label>\n <cqa-custom-input [placeholder]=\"'Text Input'\" [value]=\"description\" [fullWidth]=\"true\"\n (valueChange)=\"descriptionChange.emit($event)\">\n </cqa-custom-input>\n </div>\n</div>\n\n<div *ngIf=\"createElementVisible\">\n <cqa-element-form\n [isCreateMode]=\"true\"\n [screenNameOptions]=\"screenNameOptions\"\n [hasMoreScreenNames]=\"hasMoreScreenNames\"\n [isLoadingScreenNames]=\"isLoadingScreenNames\"\n [isEditInDepthAvailable]=\"false\"\n (createElement)=\"onCreateElement($event)\"\n (cancel)=\"onCancelElementForm()\"\n (searchScreenName)=\"searchScreenName.emit($event)\"\n (loadMoreScreenNames)=\"loadMoreScreenNames.emit($event)\"\n (createScreenNameRequest)=\"createScreenNameRequest.emit($event)\">\n </cqa-element-form>\n</div>\n<div class=\"cqa-flex cqa-justify-end cqa-pt-2\" *ngIf=\"!createElementVisible\">\n <cqa-button \n *ngIf=\"selectorVariableAvailable\"\n variant=\"text\" \n size=\"sm\"\n text=\"Create Element\"\n (clicked)=\"onShowElementForm()\">\n </cqa-button>\n <!-- <cqa-button \n *ngIf=\"parameterVariableAvailable\"\n variant=\"filled\" \n text=\"Create Parameter\"\n (clicked)=\"onCreateParameter()\">\n </cqa-button>\n <cqa-button \n *ngIf=\"environmentVariableAvailable\"\n variant=\"filled\" \n text=\"Create Environment\"\n (clicked)=\"onCreateEnvironment()\">\n </cqa-button> -->\n</div>", components: [{ type: i5$1.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["disabled", "disableRipple", "color", "tabIndex", "name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "checked"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { type: DynamicSelectFieldComponent, selector: "cqa-dynamic-select", inputs: ["form", "config"], outputs: ["selectionChange", "selectClick", "searchChange", "loadMore", "addCustomValue"] }, { type: 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: ElementFormComponent, selector: "cqa-element-form", inputs: ["elementId", "element", "screenNameOptions", "hasMoreScreenNames", "isLoadingScreenNames", "isElementLoading", "isEditMode", "isCreateMode", "isEditInDepthAvailable"], outputs: ["createElement", "updateElement", "createScreenNameRequest", "searchScreenName", "loadMoreScreenNames", "cancel", "editInDepth"] }, { type: ButtonComponent, selector: "cqa-button", inputs: ["variant", "btnSize", "disabled", "icon", "iconPosition", "fullWidth", "iconColor", "type", "text", "customClass", "inlineStyles", "tooltip", "tooltipPosition"], outputs: ["clicked"] }], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
25643
25892
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TemplateVariablesFormComponent, decorators: [{
|
|
25644
25893
|
type: Component,
|
|
25645
|
-
args: [{ selector: 'cqa-template-variables-form', host: { class: 'cqa-ui-root' }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"cqa-flex cqa-gap-x-6 cqa-flex-wrap\">\n <ng-container *ngFor=\"let variable of templateVariables; trackBy: trackByVariable\">\n <!-- Boolean variables with mat-slide-toggle -->\n <ng-container *ngIf=\"variable.type === 'boolean'\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\" style=\"width: calc(50% - 12px);\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700\">\n {{ variable.label }}\n </label>\n <mat-slide-toggle
|
|
25894
|
+
args: [{ selector: 'cqa-template-variables-form', host: { class: 'cqa-ui-root' }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"cqa-flex cqa-gap-x-6 cqa-gap-y-4 cqa-flex-wrap\" *ngIf=\"!createElementVisible\">\n <ng-container *ngFor=\"let variable of templateVariables; let i = index; trackBy: trackByVariable\">\n <!-- Boolean variables with mat-slide-toggle -->\n <ng-container *ngIf=\"variable.type === 'boolean'\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\" style=\"width: calc(50% - 12px);\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700\">\n {{ variable.label }}\n </label>\n <mat-slide-toggle [checked]=\"variablesForm.at(i)?.get('value')?.value || variable.value || false\"\n (change)=\"onVariableBooleanChange(variable.name, $event.checked)\" color=\"primary\">\n </mat-slide-toggle>\n </div>\n </ng-container>\n\n <!-- Non-boolean, non-custom_code variables -->\n <ng-container *ngIf=\"variable.name !== 'custom_code' && variable.type !== 'boolean'\">\n <ng-container *ngIf=\"shouldShowDropdown(variable); else defaultInput\">\n <div class=\"cqa-flex cqa-flex-col\" style=\"width: calc(50% - 12px);\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n {{ variable.label }}\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n </ng-container>\n <ng-template #defaultInput>\n <!-- Test-data, source-value, or target-value with data type dropdown -->\n <ng-container *ngIf=\"needsDataTypeDropdown(variable); else regularInput\">\n <div class=\"cqa-flex cqa-flex-col\" style=\"width: calc(50% - 12px);\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n {{ variable.label }} Type\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getDataTypeSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n <div class=\"cqa-flex cqa-flex-col\" style=\"width: calc(50% - 12px);\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n {{ variable.label }}\n </label>\n <cqa-custom-input [placeholder]=\"'Text Input'\" [value]=\"getRawValue(variable)\" [fullWidth]=\"true\"\n (valueChange)=\"onTestDataValueChange(variable.name, $event)\">\n </cqa-custom-input>\n </div>\n </ng-container>\n <ng-template #regularInput>\n <div class=\"cqa-flex cqa-flex-col\" style=\"width: calc(50% - 12px);\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n {{ variable.label }}\n </label>\n <cqa-custom-input [placeholder]=\"'Text Input'\" [value]=\"variable.value\" [fullWidth]=\"true\"\n (valueChange)=\"onVariableValueChange(variable.name, $event)\">\n </cqa-custom-input>\n </div>\n </ng-template>\n </ng-template>\n </ng-container>\n </ng-container>\n\n <!-- Metadata -->\n <div class=\"cqa-flex cqa-flex-col\" style=\"width: calc(50% - 12px);\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Metadata\n </label>\n <cqa-custom-input [placeholder]=\"'Text Input'\" [value]=\"metadata\" [fullWidth]=\"true\"\n (valueChange)=\"metadataChange.emit($event)\">\n </cqa-custom-input>\n </div>\n\n <!-- Description -->\n <div class=\"cqa-flex cqa-flex-col\" style=\"width: calc(50% - 12px);\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Description\n </label>\n <cqa-custom-input [placeholder]=\"'Text Input'\" [value]=\"description\" [fullWidth]=\"true\"\n (valueChange)=\"descriptionChange.emit($event)\">\n </cqa-custom-input>\n </div>\n</div>\n\n<div *ngIf=\"createElementVisible\">\n <cqa-element-form\n [isCreateMode]=\"true\"\n [screenNameOptions]=\"screenNameOptions\"\n [hasMoreScreenNames]=\"hasMoreScreenNames\"\n [isLoadingScreenNames]=\"isLoadingScreenNames\"\n [isEditInDepthAvailable]=\"false\"\n (createElement)=\"onCreateElement($event)\"\n (cancel)=\"onCancelElementForm()\"\n (searchScreenName)=\"searchScreenName.emit($event)\"\n (loadMoreScreenNames)=\"loadMoreScreenNames.emit($event)\"\n (createScreenNameRequest)=\"createScreenNameRequest.emit($event)\">\n </cqa-element-form>\n</div>\n<div class=\"cqa-flex cqa-justify-end cqa-pt-2\" *ngIf=\"!createElementVisible\">\n <cqa-button \n *ngIf=\"selectorVariableAvailable\"\n variant=\"text\" \n size=\"sm\"\n text=\"Create Element\"\n (clicked)=\"onShowElementForm()\">\n </cqa-button>\n <!-- <cqa-button \n *ngIf=\"parameterVariableAvailable\"\n variant=\"filled\" \n text=\"Create Parameter\"\n (clicked)=\"onCreateParameter()\">\n </cqa-button>\n <cqa-button \n *ngIf=\"environmentVariableAvailable\"\n variant=\"filled\" \n text=\"Create Environment\"\n (clicked)=\"onCreateEnvironment()\">\n </cqa-button> -->\n</div>", styles: [] }]
|
|
25646
25895
|
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { templateVariables: [{
|
|
25647
25896
|
type: Input
|
|
25648
25897
|
}], variablesForm: [{
|
|
@@ -25651,6 +25900,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
|
|
|
25651
25900
|
type: Input
|
|
25652
25901
|
}], description: [{
|
|
25653
25902
|
type: Input
|
|
25903
|
+
}], elementOptions: [{
|
|
25904
|
+
type: Input
|
|
25905
|
+
}], hasMoreElements: [{
|
|
25906
|
+
type: Input
|
|
25907
|
+
}], isLoadingElements: [{
|
|
25908
|
+
type: Input
|
|
25909
|
+
}], screenNameOptions: [{
|
|
25910
|
+
type: Input
|
|
25911
|
+
}], hasMoreScreenNames: [{
|
|
25912
|
+
type: Input
|
|
25913
|
+
}], isLoadingScreenNames: [{
|
|
25914
|
+
type: Input
|
|
25654
25915
|
}], variableValueChange: [{
|
|
25655
25916
|
type: Output
|
|
25656
25917
|
}], variableBooleanChange: [{
|
|
@@ -25659,6 +25920,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
|
|
|
25659
25920
|
type: Output
|
|
25660
25921
|
}], descriptionChange: [{
|
|
25661
25922
|
type: Output
|
|
25923
|
+
}], loadMoreElements: [{
|
|
25924
|
+
type: Output
|
|
25925
|
+
}], searchElements: [{
|
|
25926
|
+
type: Output
|
|
25927
|
+
}], createElement: [{
|
|
25928
|
+
type: Output
|
|
25929
|
+
}], searchScreenName: [{
|
|
25930
|
+
type: Output
|
|
25931
|
+
}], loadMoreScreenNames: [{
|
|
25932
|
+
type: Output
|
|
25933
|
+
}], createScreenNameRequest: [{
|
|
25934
|
+
type: Output
|
|
25935
|
+
}], cancelElementForm: [{
|
|
25936
|
+
type: Output
|
|
25937
|
+
}], elementFormVisibilityChange: [{
|
|
25938
|
+
type: Output
|
|
25662
25939
|
}] } });
|
|
25663
25940
|
|
|
25664
25941
|
class StepBuilderActionComponent {
|
|
@@ -25672,7 +25949,22 @@ class StepBuilderActionComponent {
|
|
|
25672
25949
|
/** Function to handle variable processing or custom logic. Can be passed from parent component. */
|
|
25673
25950
|
this.setTemplateVariables = () => { return []; };
|
|
25674
25951
|
this.preventSelectTemplate = ['databaseverification'];
|
|
25952
|
+
this.elementOptions = []; // Element objects for element dropdown
|
|
25953
|
+
this.hasMoreElements = false; // Whether more elements are available
|
|
25954
|
+
this.isLoadingElements = false; // Loading state for elements
|
|
25955
|
+
/** Screen name options for element form autocomplete (from API) */
|
|
25956
|
+
this.screenNameOptions = [];
|
|
25957
|
+
/** Whether more screen names are available for infinite scroll */
|
|
25958
|
+
this.hasMoreScreenNames = false;
|
|
25959
|
+
/** True while parent is loading screen names (search or load more) */
|
|
25960
|
+
this.isLoadingScreenNames = false;
|
|
25675
25961
|
this.templateChanged = new EventEmitter();
|
|
25962
|
+
this.loadMoreElements = new EventEmitter(); // Emit when load more is requested
|
|
25963
|
+
this.searchElements = new EventEmitter(); // Emit when user searches for elements
|
|
25964
|
+
this.createElement = new EventEmitter(); // Emit when element is created
|
|
25965
|
+
this.searchScreenName = new EventEmitter(); // Emit when user searches screen names
|
|
25966
|
+
this.loadMoreScreenNames = new EventEmitter(); // Emit when user scrolls to load more screen names
|
|
25967
|
+
this.createScreenNameRequest = new EventEmitter(); // Emit when user requests to create a new screen name
|
|
25676
25968
|
/** Emit when step is created */
|
|
25677
25969
|
this.createStep = new EventEmitter();
|
|
25678
25970
|
/** Emit when cancelled */
|
|
@@ -25684,12 +25976,21 @@ class StepBuilderActionComponent {
|
|
|
25684
25976
|
this.description = '';
|
|
25685
25977
|
this.advancedExpanded = false;
|
|
25686
25978
|
this.templateVariables = [];
|
|
25979
|
+
this.updatedHtmlGrammar = ''; // Updated HTML grammar with variable values
|
|
25980
|
+
// Track element form visibility
|
|
25981
|
+
this.isElementFormVisible = false;
|
|
25687
25982
|
// Cache for select configs to avoid recalculating on every change detection
|
|
25688
25983
|
this.selectConfigCache = new Map();
|
|
25689
25984
|
this.formValidCache = false;
|
|
25690
25985
|
this.lastFormValidationTime = 0;
|
|
25691
25986
|
this.FORM_VALIDATION_CACHE_MS = 100; // Cache for 100ms
|
|
25692
|
-
this.variablesForm = this.fb.
|
|
25987
|
+
this.variablesForm = this.fb.array([]);
|
|
25988
|
+
}
|
|
25989
|
+
/**
|
|
25990
|
+
* Handle element form visibility change
|
|
25991
|
+
*/
|
|
25992
|
+
onElementFormVisibilityChange(visible) {
|
|
25993
|
+
this.isElementFormVisible = visible;
|
|
25693
25994
|
}
|
|
25694
25995
|
ngOnInit() {
|
|
25695
25996
|
this.filteredTemplates = [...this.templates];
|
|
@@ -25718,16 +26019,40 @@ class StepBuilderActionComponent {
|
|
|
25718
26019
|
}
|
|
25719
26020
|
const searchTerm = this.searchValue.toLowerCase().trim();
|
|
25720
26021
|
this.filteredTemplates = this.templates.filter(template => {
|
|
25721
|
-
var _a, _b
|
|
26022
|
+
var _a, _b;
|
|
25722
26023
|
const naturalText = ((_a = template.naturalText) === null || _a === void 0 ? void 0 : _a.toLowerCase()) || '';
|
|
25723
|
-
|
|
25724
|
-
const
|
|
26024
|
+
// Strip HTML tags from htmlGrammar for searching (only search text content, not HTML markup)
|
|
26025
|
+
const htmlGrammarText = this.stripHtmlTags(template.htmlGrammar || '').toLowerCase();
|
|
26026
|
+
const searchableGrammar = ((_b = template.searchableGrammar) === null || _b === void 0 ? void 0 : _b.toLowerCase()) || '';
|
|
25725
26027
|
return naturalText.includes(searchTerm) ||
|
|
25726
|
-
|
|
26028
|
+
htmlGrammarText.includes(searchTerm) ||
|
|
25727
26029
|
searchableGrammar.includes(searchTerm);
|
|
25728
26030
|
});
|
|
25729
26031
|
console.log("filteredTemplates", this.filteredTemplates);
|
|
25730
26032
|
}
|
|
26033
|
+
/**
|
|
26034
|
+
* Strip HTML tags from a string, returning only the text content
|
|
26035
|
+
* @param htmlString - HTML string to strip tags from
|
|
26036
|
+
* @returns Plain text without HTML tags
|
|
26037
|
+
*/
|
|
26038
|
+
stripHtmlTags(htmlString) {
|
|
26039
|
+
if (!htmlString)
|
|
26040
|
+
return '';
|
|
26041
|
+
// Use browser's DOMParser if available
|
|
26042
|
+
if (typeof document !== 'undefined' && document.createElement) {
|
|
26043
|
+
try {
|
|
26044
|
+
const tempDiv = document.createElement('div');
|
|
26045
|
+
tempDiv.innerHTML = htmlString;
|
|
26046
|
+
return tempDiv.textContent || tempDiv.innerText || '';
|
|
26047
|
+
}
|
|
26048
|
+
catch (error) {
|
|
26049
|
+
// Fallback to regex if DOM parsing fails
|
|
26050
|
+
return htmlString.replace(/<[^>]*>/g, '');
|
|
26051
|
+
}
|
|
26052
|
+
}
|
|
26053
|
+
// Fallback: regex-based tag removal for server-side rendering
|
|
26054
|
+
return htmlString.replace(/<[^>]*>/g, '');
|
|
26055
|
+
}
|
|
25731
26056
|
selectTemplate(template) {
|
|
25732
26057
|
if (this.preventSelectTemplate.includes(template.displayName || '')) {
|
|
25733
26058
|
this.templateChanged.emit(template);
|
|
@@ -25744,20 +26069,26 @@ class StepBuilderActionComponent {
|
|
|
25744
26069
|
setTimeout(() => {
|
|
25745
26070
|
try {
|
|
25746
26071
|
this.templateVariables = this.setTemplateVariables(template);
|
|
26072
|
+
console.log("templateVariables", this.templateVariables);
|
|
25747
26073
|
this.buildVariablesForm();
|
|
26074
|
+
// Initialize updated HTML grammar
|
|
26075
|
+
this.updateHtmlGrammar();
|
|
25748
26076
|
}
|
|
25749
26077
|
catch (error) {
|
|
25750
26078
|
console.error('Error processing template variables:', error);
|
|
25751
26079
|
}
|
|
25752
26080
|
}, 0);
|
|
25753
26081
|
}
|
|
26082
|
+
else {
|
|
26083
|
+
// Initialize with template's HTML grammar if no variables
|
|
26084
|
+
this.updatedHtmlGrammar = template.htmlGrammar || template.naturalText || '';
|
|
26085
|
+
}
|
|
25754
26086
|
}
|
|
25755
26087
|
buildVariablesForm() {
|
|
25756
|
-
// Clear existing form
|
|
25757
|
-
|
|
25758
|
-
|
|
25759
|
-
|
|
25760
|
-
});
|
|
26088
|
+
// Clear existing form array
|
|
26089
|
+
while (this.variablesForm.length !== 0) {
|
|
26090
|
+
this.variablesForm.removeAt(0);
|
|
26091
|
+
}
|
|
25761
26092
|
// Clear cache when form is rebuilt
|
|
25762
26093
|
this.selectConfigCache.clear();
|
|
25763
26094
|
this.formValidCache = false;
|
|
@@ -25765,13 +26096,40 @@ class StepBuilderActionComponent {
|
|
|
25765
26096
|
if (this.formValueChangesSubscription) {
|
|
25766
26097
|
this.formValueChangesSubscription.unsubscribe();
|
|
25767
26098
|
}
|
|
25768
|
-
// Add form
|
|
26099
|
+
// Add form groups for each variable
|
|
25769
26100
|
this.templateVariables.forEach(variable => {
|
|
26101
|
+
var _a;
|
|
25770
26102
|
// Handle boolean variables - use boolean value, others use string
|
|
25771
26103
|
const defaultValue = variable.type === 'boolean'
|
|
25772
26104
|
? (variable.value === true || variable.value === 'true' || variable.value === 1)
|
|
25773
26105
|
: (variable.value || '');
|
|
25774
|
-
|
|
26106
|
+
// Create a FormGroup for each variable with name and value
|
|
26107
|
+
const variableGroup = this.fb.group({
|
|
26108
|
+
name: [variable.name],
|
|
26109
|
+
value: [defaultValue],
|
|
26110
|
+
type: [variable.type || 'string'],
|
|
26111
|
+
label: [variable.label || ''],
|
|
26112
|
+
options: [variable.options || []]
|
|
26113
|
+
});
|
|
26114
|
+
// Add dataType control for test-data variables if needed
|
|
26115
|
+
const label = ((_a = variable.label) === null || _a === void 0 ? void 0 : _a.toLowerCase()) || '';
|
|
26116
|
+
if (label === 'test-data' || label === 'source-value' || label === 'target-value' ||
|
|
26117
|
+
label === 'source_value' || label === 'target_value') {
|
|
26118
|
+
// Parse the value to determine data type
|
|
26119
|
+
const valueStr = String(defaultValue || '');
|
|
26120
|
+
let dataType = 'plain-text';
|
|
26121
|
+
if (valueStr.startsWith('@|') && valueStr.endsWith('|')) {
|
|
26122
|
+
dataType = 'parameter';
|
|
26123
|
+
}
|
|
26124
|
+
else if (valueStr.startsWith('$|') && valueStr.endsWith('|')) {
|
|
26125
|
+
dataType = 'runtime';
|
|
26126
|
+
}
|
|
26127
|
+
else if (valueStr.startsWith('*|') && valueStr.endsWith('|')) {
|
|
26128
|
+
dataType = 'environment';
|
|
26129
|
+
}
|
|
26130
|
+
variableGroup.addControl('dataType', new FormControl(dataType));
|
|
26131
|
+
}
|
|
26132
|
+
this.variablesForm.push(variableGroup);
|
|
25775
26133
|
});
|
|
25776
26134
|
// Subscribe to form value changes to invalidate cache (only when user actually changes values)
|
|
25777
26135
|
// Note: We use emitEvent: false when programmatically setting values, so this won't fire unnecessarily
|
|
@@ -25785,7 +26143,7 @@ class StepBuilderActionComponent {
|
|
|
25785
26143
|
this.formValueChangesSubscription.unsubscribe();
|
|
25786
26144
|
}
|
|
25787
26145
|
}
|
|
25788
|
-
getSelectConfig(variable) {
|
|
26146
|
+
getSelectConfig(variable, index) {
|
|
25789
26147
|
var _a;
|
|
25790
26148
|
// Use cache to avoid recalculating on every change detection
|
|
25791
26149
|
const cacheKey = `${variable.name}_${((_a = variable.options) === null || _a === void 0 ? void 0 : _a.join(',')) || ''}`;
|
|
@@ -25799,7 +26157,7 @@ class StepBuilderActionComponent {
|
|
|
25799
26157
|
label: opt
|
|
25800
26158
|
}));
|
|
25801
26159
|
const config = {
|
|
25802
|
-
key:
|
|
26160
|
+
key: `value`,
|
|
25803
26161
|
placeholder: `Select ${variable.label}`,
|
|
25804
26162
|
multiple: false,
|
|
25805
26163
|
searchable: false,
|
|
@@ -25811,19 +26169,64 @@ class StepBuilderActionComponent {
|
|
|
25811
26169
|
this.selectConfigCache.set(cacheKey, config);
|
|
25812
26170
|
return config;
|
|
25813
26171
|
}
|
|
26172
|
+
/** Get form group for a variable by name */
|
|
26173
|
+
getVariableFormGroup(variableName) {
|
|
26174
|
+
const variableIndex = this.variablesForm.controls.findIndex(control => { var _a; return ((_a = control.get('name')) === null || _a === void 0 ? void 0 : _a.value) === variableName; });
|
|
26175
|
+
if (variableIndex !== -1) {
|
|
26176
|
+
return this.variablesForm.at(variableIndex);
|
|
26177
|
+
}
|
|
26178
|
+
return null;
|
|
26179
|
+
}
|
|
26180
|
+
/** Add a new variable to the form array dynamically */
|
|
26181
|
+
addVariable(variable) {
|
|
26182
|
+
var _a;
|
|
26183
|
+
const defaultValue = variable.type === 'boolean'
|
|
26184
|
+
? (variable.value === true || variable.value === 'true' || variable.value === 1)
|
|
26185
|
+
: (variable.value || '');
|
|
26186
|
+
const variableGroup = this.fb.group({
|
|
26187
|
+
name: [variable.name],
|
|
26188
|
+
value: [defaultValue],
|
|
26189
|
+
type: [variable.type || 'string'],
|
|
26190
|
+
label: [variable.label || ''],
|
|
26191
|
+
options: [variable.options || []]
|
|
26192
|
+
});
|
|
26193
|
+
// Add dataType control for test-data variables if needed
|
|
26194
|
+
const label = ((_a = variable.label) === null || _a === void 0 ? void 0 : _a.toLowerCase()) || '';
|
|
26195
|
+
if (label === 'test-data' || label === 'source-value' || label === 'target-value' ||
|
|
26196
|
+
label === 'source_value' || label === 'target_value') {
|
|
26197
|
+
const valueStr = String(defaultValue || '');
|
|
26198
|
+
let dataType = 'plain-text';
|
|
26199
|
+
if (valueStr.startsWith('@|') && valueStr.endsWith('|')) {
|
|
26200
|
+
dataType = 'parameter';
|
|
26201
|
+
}
|
|
26202
|
+
else if (valueStr.startsWith('$|') && valueStr.endsWith('|')) {
|
|
26203
|
+
dataType = 'runtime';
|
|
26204
|
+
}
|
|
26205
|
+
else if (valueStr.startsWith('*|') && valueStr.endsWith('|')) {
|
|
26206
|
+
dataType = 'environment';
|
|
26207
|
+
}
|
|
26208
|
+
variableGroup.addControl('dataType', new FormControl(dataType));
|
|
26209
|
+
}
|
|
26210
|
+
this.variablesForm.push(variableGroup);
|
|
26211
|
+
this.formValidCache = false;
|
|
26212
|
+
}
|
|
25814
26213
|
onVariableValueChange(variableName, value) {
|
|
25815
26214
|
var _a;
|
|
26215
|
+
console.log("onVariableValueChange", variableName, value);
|
|
25816
26216
|
// Update the variable in templateVariables array
|
|
25817
26217
|
const variable = this.templateVariables.find(v => v.name === variableName);
|
|
25818
26218
|
if (variable) {
|
|
25819
26219
|
variable.value = value;
|
|
25820
26220
|
}
|
|
25821
|
-
// Also update form
|
|
25822
|
-
|
|
25823
|
-
|
|
26221
|
+
// Also update form array (use emitEvent: false to prevent triggering valueChanges)
|
|
26222
|
+
const variableIndex = this.variablesForm.controls.findIndex(control => { var _a; return ((_a = control.get('name')) === null || _a === void 0 ? void 0 : _a.value) === variableName; });
|
|
26223
|
+
if (variableIndex !== -1) {
|
|
26224
|
+
(_a = this.variablesForm.at(variableIndex).get('value')) === null || _a === void 0 ? void 0 : _a.setValue(value, { emitEvent: false });
|
|
25824
26225
|
}
|
|
25825
26226
|
// Invalidate form validation cache
|
|
25826
26227
|
this.formValidCache = false;
|
|
26228
|
+
// Update HTML grammar with new value
|
|
26229
|
+
this.updateHtmlGrammar();
|
|
25827
26230
|
}
|
|
25828
26231
|
onVariableBooleanChange(variableName, value) {
|
|
25829
26232
|
var _a;
|
|
@@ -25832,16 +26235,26 @@ class StepBuilderActionComponent {
|
|
|
25832
26235
|
if (variable) {
|
|
25833
26236
|
variable.value = value;
|
|
25834
26237
|
}
|
|
25835
|
-
// Also update form
|
|
25836
|
-
|
|
25837
|
-
|
|
26238
|
+
// Also update form array (use emitEvent: false to prevent triggering valueChanges)
|
|
26239
|
+
const variableIndex = this.variablesForm.controls.findIndex(control => { var _a; return ((_a = control.get('name')) === null || _a === void 0 ? void 0 : _a.value) === variableName; });
|
|
26240
|
+
if (variableIndex !== -1) {
|
|
26241
|
+
(_a = this.variablesForm.at(variableIndex).get('value')) === null || _a === void 0 ? void 0 : _a.setValue(value, { emitEvent: false });
|
|
25838
26242
|
}
|
|
25839
26243
|
else {
|
|
25840
|
-
// Create form
|
|
25841
|
-
this.
|
|
26244
|
+
// Create new form group if it doesn't exist
|
|
26245
|
+
const variableGroup = this.fb.group({
|
|
26246
|
+
name: [variableName],
|
|
26247
|
+
value: [value],
|
|
26248
|
+
type: ['boolean'],
|
|
26249
|
+
label: [(variable === null || variable === void 0 ? void 0 : variable.label) || ''],
|
|
26250
|
+
options: [(variable === null || variable === void 0 ? void 0 : variable.options) || []]
|
|
26251
|
+
});
|
|
26252
|
+
this.variablesForm.push(variableGroup);
|
|
25842
26253
|
}
|
|
25843
26254
|
// Invalidate form validation cache
|
|
25844
26255
|
this.formValidCache = false;
|
|
26256
|
+
// Update HTML grammar with new value
|
|
26257
|
+
this.updateHtmlGrammar();
|
|
25845
26258
|
}
|
|
25846
26259
|
onBack() {
|
|
25847
26260
|
this.selectedTemplate = null;
|
|
@@ -25849,10 +26262,11 @@ class StepBuilderActionComponent {
|
|
|
25849
26262
|
this.description = '';
|
|
25850
26263
|
this.advancedExpanded = false;
|
|
25851
26264
|
this.templateVariables = [];
|
|
25852
|
-
|
|
25853
|
-
|
|
25854
|
-
|
|
25855
|
-
|
|
26265
|
+
this.updatedHtmlGrammar = '';
|
|
26266
|
+
// Clear form array
|
|
26267
|
+
while (this.variablesForm.length !== 0) {
|
|
26268
|
+
this.variablesForm.removeAt(0);
|
|
26269
|
+
}
|
|
25856
26270
|
// Reapply filter to maintain search state
|
|
25857
26271
|
this.applyFilter();
|
|
25858
26272
|
}
|
|
@@ -25870,22 +26284,22 @@ class StepBuilderActionComponent {
|
|
|
25870
26284
|
return this.formValidCache;
|
|
25871
26285
|
}
|
|
25872
26286
|
// Check if all required variables are filled
|
|
25873
|
-
let isValid = true;
|
|
25874
|
-
if (this.templateVariables && this.templateVariables.length > 0) {
|
|
25875
|
-
|
|
25876
|
-
|
|
25877
|
-
|
|
25878
|
-
|
|
25879
|
-
|
|
25880
|
-
|
|
25881
|
-
|
|
25882
|
-
|
|
25883
|
-
|
|
25884
|
-
}
|
|
26287
|
+
// let isValid = true;
|
|
26288
|
+
// if (this.templateVariables && this.templateVariables.length > 0) {
|
|
26289
|
+
// isValid = this.templateVariables.every(variable => {
|
|
26290
|
+
// // Boolean variables are always valid (they have a default value)
|
|
26291
|
+
// if (variable.type === 'boolean') {
|
|
26292
|
+
// return true;
|
|
26293
|
+
// }
|
|
26294
|
+
// // Check if variable has a value
|
|
26295
|
+
// const value = variable.value;
|
|
26296
|
+
// return value !== null && value !== undefined && value !== '';
|
|
26297
|
+
// });
|
|
26298
|
+
// }
|
|
25885
26299
|
// Cache the result
|
|
25886
|
-
this.formValidCache =
|
|
26300
|
+
this.formValidCache = this.variablesForm.valid;
|
|
25887
26301
|
this.lastFormValidationTime = now;
|
|
25888
|
-
return
|
|
26302
|
+
return this.variablesForm.valid;
|
|
25889
26303
|
}
|
|
25890
26304
|
trackByTemplate(index, template) {
|
|
25891
26305
|
return template.id || template.displayName || index;
|
|
@@ -25903,6 +26317,8 @@ class StepBuilderActionComponent {
|
|
|
25903
26317
|
description: this.description,
|
|
25904
26318
|
templateVariables: this.templateVariables
|
|
25905
26319
|
};
|
|
26320
|
+
console.log("stepData", stepData);
|
|
26321
|
+
console.log("variablesForm", this.variablesForm.value);
|
|
25906
26322
|
this.createStep.emit(stepData);
|
|
25907
26323
|
}
|
|
25908
26324
|
toggleAdvanced() {
|
|
@@ -25918,12 +26334,75 @@ class StepBuilderActionComponent {
|
|
|
25918
26334
|
onTestDataValueChange(key, value) {
|
|
25919
26335
|
console.log(key, value);
|
|
25920
26336
|
}
|
|
26337
|
+
/**
|
|
26338
|
+
* Update HTML grammar by replacing placeholder spans with actual variable values
|
|
26339
|
+
*/
|
|
26340
|
+
updateHtmlGrammar() {
|
|
26341
|
+
if (!this.selectedTemplate) {
|
|
26342
|
+
this.updatedHtmlGrammar = '';
|
|
26343
|
+
return;
|
|
26344
|
+
}
|
|
26345
|
+
const htmlGrammar = this.selectedTemplate.htmlGrammar || this.selectedTemplate.naturalText || '';
|
|
26346
|
+
if (!htmlGrammar) {
|
|
26347
|
+
this.updatedHtmlGrammar = '';
|
|
26348
|
+
return;
|
|
26349
|
+
}
|
|
26350
|
+
// Create a map of variable values by name for quick lookup
|
|
26351
|
+
const valueMap = new Map();
|
|
26352
|
+
if (this.templateVariables && Array.isArray(this.templateVariables)) {
|
|
26353
|
+
this.templateVariables.forEach((variable) => {
|
|
26354
|
+
if (variable.name && variable.value !== undefined && variable.value !== null) {
|
|
26355
|
+
// Convert value to string, handling boolean values
|
|
26356
|
+
const valueStr = typeof variable.value === 'boolean'
|
|
26357
|
+
? (variable.value ? 'true' : 'false')
|
|
26358
|
+
: String(variable.value || '');
|
|
26359
|
+
valueMap.set(variable.name, valueStr);
|
|
26360
|
+
}
|
|
26361
|
+
});
|
|
26362
|
+
}
|
|
26363
|
+
// Use browser's DOMParser if available, otherwise fallback to string replacement
|
|
26364
|
+
if (typeof document !== 'undefined' && document.createElement) {
|
|
26365
|
+
try {
|
|
26366
|
+
const tempDiv = document.createElement('div');
|
|
26367
|
+
tempDiv.innerHTML = String(htmlGrammar);
|
|
26368
|
+
// Find all spans with data-event-key attribute
|
|
26369
|
+
const spans = tempDiv.querySelectorAll('span[data-event-key]');
|
|
26370
|
+
spans.forEach((span) => {
|
|
26371
|
+
const eventKey = span.getAttribute('data-event-key');
|
|
26372
|
+
if (eventKey && valueMap.has(eventKey)) {
|
|
26373
|
+
const value = valueMap.get(eventKey);
|
|
26374
|
+
// Preserve the span structure but update the content
|
|
26375
|
+
span.innerHTML = value || '';
|
|
26376
|
+
}
|
|
26377
|
+
});
|
|
26378
|
+
this.updatedHtmlGrammar = tempDiv.innerHTML;
|
|
26379
|
+
}
|
|
26380
|
+
catch (error) {
|
|
26381
|
+
console.error('Error updating HTML grammar:', error);
|
|
26382
|
+
// Fallback to original HTML grammar
|
|
26383
|
+
this.updatedHtmlGrammar = String(htmlGrammar);
|
|
26384
|
+
}
|
|
26385
|
+
}
|
|
26386
|
+
else {
|
|
26387
|
+
// Fallback: simple string replacement for server-side rendering
|
|
26388
|
+
let updatedHtml = String(htmlGrammar);
|
|
26389
|
+
valueMap.forEach((value, key) => {
|
|
26390
|
+
// Replace spans with data-event-key matching the variable name
|
|
26391
|
+
const regex = new RegExp(`<span[^>]*data-event-key="${key}"[^>]*>.*?</span>`, 'gi');
|
|
26392
|
+
updatedHtml = updatedHtml.replace(regex, (match) => {
|
|
26393
|
+
// Replace the content inside the span
|
|
26394
|
+
return match.replace(/>.*?</, `>${value}<`);
|
|
26395
|
+
});
|
|
26396
|
+
});
|
|
26397
|
+
this.updatedHtmlGrammar = updatedHtml;
|
|
26398
|
+
}
|
|
26399
|
+
}
|
|
25921
26400
|
}
|
|
25922
26401
|
StepBuilderActionComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: StepBuilderActionComponent, deps: [{ token: i1$1.FormBuilder }], target: i0.ɵɵFactoryTarget.Component });
|
|
25923
|
-
StepBuilderActionComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: StepBuilderActionComponent, selector: "cqa-step-builder-action", inputs: { showHeader: "showHeader", templates: "templates", searchPlaceholder: "searchPlaceholder", setTemplateVariables: "setTemplateVariables", preventSelectTemplate: "preventSelectTemplate" }, outputs: { templateChanged: "templateChanged", createStep: "createStep", cancelled: "cancelled" }, host: { classAttribute: "cqa-ui-root" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"cqa-flex cqa-flex-col cqa-h-full cqa-bg-white\" [ngClass]=\"{'cqa-px-4 cqa-py-2': showHeader}\">\n <!-- Header -->\n <h2 *ngIf=\"showHeader\" class=\"cqa-text-[12px] cqa-font-semibold cqa-text-black-100 cqa-mb-1\">\n Create an action step\n </h2>\n <div *ngIf=\"!selectedTemplate\" class=\"cqa-flex cqa-flex-col cqa-h-full cqa-flex-1\"\n [ngClass]=\"{'cqa-px-3': showHeader}\">\n\n <!-- Search Bar -->\n <div class=\"cqa-pb-1\">\n <div class=\"cqa-pb-1\" *ngIf=\"showHeader\">\n <p class=\"cqa-text-[12px] cqa-text-gray-500\">\n Template library\n </p>\n </div>\n <cqa-search-bar [placeholder]=\"searchPlaceholder\" [fullWidth]=\"true\" [value]=\"searchValue\"\n (valueChange)=\"onSearchChange($event)\" (search)=\"onSearchSubmit($event)\" (cleared)=\"onSearchCleared()\">\n </cqa-search-bar>\n </div>\n\n <!-- Template List -->\n <div class=\"cqa-flex-1 cqa-overflow-y-auto cqa-px-2\">\n <div class=\"cqa-py-2\">\n <div *ngFor=\"let template of filteredTemplates; trackBy: trackByTemplate\"\n class=\"cqa-action-format cqa-bg-white cqa-cursor-pointer cqa-transition-all hover:cqa-border-blue-500 hover:cqa-shadow-sm mb-6\"\n (click)=\"selectTemplate(template)\">\n <div class=\"cqa-text-[12px] cqa-leading-[23px] cqa-text-black-100\"\n [innerHTML]=\"template.htmlGrammar || template.naturalText || ''\">\n </div>\n </div>\n\n <div *ngIf=\"filteredTemplates.length === 0\" class=\"cqa-text-center cqa-py-8 cqa-text-gray-400 cqa-text-[12px]\">\n No templates found\n </div>\n </div>\n </div>\n </div>\n\n <div *ngIf=\"selectedTemplate\" class=\"cqa-flex cqa-flex-col cqa-
|
|
26402
|
+
StepBuilderActionComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: StepBuilderActionComponent, selector: "cqa-step-builder-action", inputs: { showHeader: "showHeader", templates: "templates", searchPlaceholder: "searchPlaceholder", setTemplateVariables: "setTemplateVariables", preventSelectTemplate: "preventSelectTemplate", elementOptions: "elementOptions", hasMoreElements: "hasMoreElements", isLoadingElements: "isLoadingElements", screenNameOptions: "screenNameOptions", hasMoreScreenNames: "hasMoreScreenNames", isLoadingScreenNames: "isLoadingScreenNames" }, outputs: { templateChanged: "templateChanged", loadMoreElements: "loadMoreElements", searchElements: "searchElements", createElement: "createElement", searchScreenName: "searchScreenName", loadMoreScreenNames: "loadMoreScreenNames", createScreenNameRequest: "createScreenNameRequest", createStep: "createStep", cancelled: "cancelled" }, host: { styleAttribute: "display: block;height: 100%;width: 100%;", classAttribute: "cqa-ui-root" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"cqa-flex cqa-flex-col cqa-h-full cqa-bg-white\" [ngClass]=\"{'cqa-px-4': showHeader, 'cqa-py-2': showHeader && !selectedTemplate}\">\n <!-- Header -->\n <h2 *ngIf=\"showHeader\" class=\"cqa-text-[12px] cqa-font-semibold cqa-text-black-100 cqa-mb-1\">\n Create an action step\n </h2>\n <div *ngIf=\"!selectedTemplate\" class=\"cqa-flex cqa-flex-col cqa-h-full cqa-flex-1\"\n [ngClass]=\"{'cqa-px-3': showHeader}\">\n\n <!-- Search Bar -->\n <div class=\"cqa-pb-1\">\n <div class=\"cqa-pb-1\" *ngIf=\"showHeader\">\n <p class=\"cqa-text-[12px] cqa-text-gray-500\">\n Template library\n </p>\n </div>\n <cqa-search-bar [placeholder]=\"searchPlaceholder\" [fullWidth]=\"true\" [value]=\"searchValue\"\n (valueChange)=\"onSearchChange($event)\" (search)=\"onSearchSubmit($event)\" (cleared)=\"onSearchCleared()\">\n </cqa-search-bar>\n </div>\n\n <!-- Template List -->\n <div class=\"cqa-flex-1 cqa-overflow-y-auto cqa-px-2\">\n <div class=\"cqa-py-2\">\n <div *ngFor=\"let template of filteredTemplates; trackBy: trackByTemplate\"\n class=\"cqa-action-format cqa-bg-white cqa-cursor-pointer cqa-transition-all hover:cqa-border-blue-500 hover:cqa-shadow-sm mb-6\"\n (click)=\"selectTemplate(template)\">\n <div class=\"cqa-text-[12px] cqa-leading-[23px] cqa-text-black-100\"\n [innerHTML]=\"template.htmlGrammar || template.naturalText || ''\">\n </div>\n </div>\n\n <div *ngIf=\"filteredTemplates.length === 0\" class=\"cqa-text-center cqa-py-8 cqa-text-gray-400 cqa-text-[12px]\">\n No templates found\n </div>\n </div>\n </div>\n </div>\n\n <div *ngIf=\"selectedTemplate\" class=\"cqa-flex cqa-flex-col cqa-overflow-y-auto\" style=\"flex: 1 1 0 !important;\">\n <!-- Instruction Text with Element Buttons -->\n <div class=\"cqa-mb-4 cqa-flex cqa-items-center cqa-flex-wrap cqa-gap-1 cqa-text-sm cqa-text-gray-700\">\n <div class=\"cqa-action-format cqa-text-[12px] cqa-leading-[23px] cqa-text-black-100\"\n [innerHTML]=\"updatedHtmlGrammar || selectedTemplate.htmlGrammar || selectedTemplate.naturalText || ''\">\n </div>\n </div>\n\n <!-- Form Fields in Two Columns -->\n <div class=\"cqa-flex cqa-overflow-y-auto cqa-flex-1 cqa-pb-2\">\n <div class=\"cqa-flex-1 cqa-flex cqa-flex-col cqa-gap-1\">\n <div class=\"cqa-flex cqa-gap-x-6 cqa-flex-wrap cqa-pb-4\">\n <!-- Template Variables Form Component -->\n <cqa-template-variables-form\n style=\"width: 100%;\"\n [templateVariables]=\"templateVariables\"\n [variablesForm]=\"variablesForm\"\n [metadata]=\"metadata\"\n [description]=\"description\"\n [elementOptions]=\"elementOptions\"\n [hasMoreElements]=\"hasMoreElements\"\n [isLoadingElements]=\"isLoadingElements\"\n [screenNameOptions]=\"screenNameOptions\"\n [hasMoreScreenNames]=\"hasMoreScreenNames\"\n [isLoadingScreenNames]=\"isLoadingScreenNames\"\n (variableValueChange)=\"onVariableValueChange($event.name, $event.value)\"\n (variableBooleanChange)=\"onVariableBooleanChange($event.name, $event.value)\"\n (metadataChange)=\"metadata = $event\"\n (descriptionChange)=\"description = $event\"\n (loadMoreElements)=\"loadMoreElements.emit()\"\n (searchElements)=\"searchElements.emit($event)\"\n (createElement)=\"createElement.emit($event)\"\n (searchScreenName)=\"searchScreenName.emit($event)\"\n (loadMoreScreenNames)=\"loadMoreScreenNames.emit($event)\"\n (createScreenNameRequest)=\"createScreenNameRequest.emit($event)\"\n (elementFormVisibilityChange)=\"onElementFormVisibilityChange($event)\">\n </cqa-template-variables-form>\n </div>\n\n <!-- Advanced (Expandable) -->\n <!-- <div class=\"cqa-flex cqa-flex-col cqa-w-full\">\n <button type=\"button\"\n class=\"cqa-flex cqa-w-full cqa-items-center cqa-justify-between cqa-gap-2 cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-bg-transparent cqa-border-none cqa-cursor-pointer cqa-p-0 cqa-mb-1.5\"\n (click)=\"toggleAdvanced()\">\n <span class=\"cqa-text-[10px]\">Advanced</span>\n <mat-icon class=\"cqa-text-base\" [class.cqa-rotate-180]=\"advancedExpanded\">\n expand_more\n </mat-icon>\n </button>\n <div *ngIf=\"advancedExpanded\" class=\"cqa-mt-2\">\n </div>\n </div> -->\n <div>\n \n </div>\n </div>\n\n\n </div>\n\n <!-- Action Buttons -->\n <div *ngIf=\"!isElementFormVisible\" class=\"cqa-flex cqa-w-full cqa-gap-2 cqa-border-t cqa-border-gray-200 cqa-pb-2\">\n <cqa-button class=\"cqa-w-1/2\" variant=\"outlined\" text=\"Cancel\" [customClass]=\"'cqa-flex-1 cqa-w-full'\"\n (clicked)=\"onCancel()\">\n </cqa-button>\n <cqa-button class=\"cqa-w-1/2\" variant=\"filled\" text=\"Create Step\" [customClass]=\"'cqa-flex-1 cqa-w-full'\"\n [disabled]=\"!isFormValid()\"\n (clicked)=\"onCreateStep()\">\n </cqa-button>\n </div>\n </div>\n</div>", components: [{ type: SearchBarComponent, selector: "cqa-search-bar", inputs: ["placeholder", "value", "disabled", "showClear", "ariaLabel", "autoFocus", "size", "fullWidth"], outputs: ["valueChange", "search", "cleared"] }, { type: TemplateVariablesFormComponent, selector: "cqa-template-variables-form", inputs: ["templateVariables", "variablesForm", "metadata", "description", "elementOptions", "hasMoreElements", "isLoadingElements", "screenNameOptions", "hasMoreScreenNames", "isLoadingScreenNames"], outputs: ["variableValueChange", "variableBooleanChange", "metadataChange", "descriptionChange", "loadMoreElements", "searchElements", "createElement", "searchScreenName", "loadMoreScreenNames", "createScreenNameRequest", "cancelElementForm", "elementFormVisibilityChange"] }, { type: ButtonComponent, selector: "cqa-button", inputs: ["variant", "btnSize", "disabled", "icon", "iconPosition", "fullWidth", "iconColor", "type", "text", "customClass", "inlineStyles", "tooltip", "tooltipPosition"], outputs: ["clicked"] }], directives: [{ type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] });
|
|
25924
26403
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: StepBuilderActionComponent, decorators: [{
|
|
25925
26404
|
type: Component,
|
|
25926
|
-
args: [{ selector: 'cqa-step-builder-action', host: { class: 'cqa-ui-root' }, template: "<div class=\"cqa-flex cqa-flex-col cqa-h-full cqa-bg-white\" [ngClass]=\"{'cqa-px-4 cqa-py-2': showHeader}\">\n <!-- Header -->\n <h2 *ngIf=\"showHeader\" class=\"cqa-text-[12px] cqa-font-semibold cqa-text-black-100 cqa-mb-1\">\n Create an action step\n </h2>\n <div *ngIf=\"!selectedTemplate\" class=\"cqa-flex cqa-flex-col cqa-h-full cqa-flex-1\"\n [ngClass]=\"{'cqa-px-3': showHeader}\">\n\n <!-- Search Bar -->\n <div class=\"cqa-pb-1\">\n <div class=\"cqa-pb-1\" *ngIf=\"showHeader\">\n <p class=\"cqa-text-[12px] cqa-text-gray-500\">\n Template library\n </p>\n </div>\n <cqa-search-bar [placeholder]=\"searchPlaceholder\" [fullWidth]=\"true\" [value]=\"searchValue\"\n (valueChange)=\"onSearchChange($event)\" (search)=\"onSearchSubmit($event)\" (cleared)=\"onSearchCleared()\">\n </cqa-search-bar>\n </div>\n\n <!-- Template List -->\n <div class=\"cqa-flex-1 cqa-overflow-y-auto cqa-px-2\">\n <div class=\"cqa-py-2\">\n <div *ngFor=\"let template of filteredTemplates; trackBy: trackByTemplate\"\n class=\"cqa-action-format cqa-bg-white cqa-cursor-pointer cqa-transition-all hover:cqa-border-blue-500 hover:cqa-shadow-sm mb-6\"\n (click)=\"selectTemplate(template)\">\n <div class=\"cqa-text-[12px] cqa-leading-[23px] cqa-text-black-100\"\n [innerHTML]=\"template.htmlGrammar || template.naturalText || ''\">\n </div>\n </div>\n\n <div *ngIf=\"filteredTemplates.length === 0\" class=\"cqa-text-center cqa-py-8 cqa-text-gray-400 cqa-text-[12px]\">\n No templates found\n </div>\n </div>\n </div>\n </div>\n\n <div *ngIf=\"selectedTemplate\" class=\"cqa-flex cqa-flex-col cqa-
|
|
26405
|
+
args: [{ selector: 'cqa-step-builder-action', host: { class: 'cqa-ui-root', style: 'display: block;height: 100%;width: 100%;' }, template: "<div class=\"cqa-flex cqa-flex-col cqa-h-full cqa-bg-white\" [ngClass]=\"{'cqa-px-4': showHeader, 'cqa-py-2': showHeader && !selectedTemplate}\">\n <!-- Header -->\n <h2 *ngIf=\"showHeader\" class=\"cqa-text-[12px] cqa-font-semibold cqa-text-black-100 cqa-mb-1\">\n Create an action step\n </h2>\n <div *ngIf=\"!selectedTemplate\" class=\"cqa-flex cqa-flex-col cqa-h-full cqa-flex-1\"\n [ngClass]=\"{'cqa-px-3': showHeader}\">\n\n <!-- Search Bar -->\n <div class=\"cqa-pb-1\">\n <div class=\"cqa-pb-1\" *ngIf=\"showHeader\">\n <p class=\"cqa-text-[12px] cqa-text-gray-500\">\n Template library\n </p>\n </div>\n <cqa-search-bar [placeholder]=\"searchPlaceholder\" [fullWidth]=\"true\" [value]=\"searchValue\"\n (valueChange)=\"onSearchChange($event)\" (search)=\"onSearchSubmit($event)\" (cleared)=\"onSearchCleared()\">\n </cqa-search-bar>\n </div>\n\n <!-- Template List -->\n <div class=\"cqa-flex-1 cqa-overflow-y-auto cqa-px-2\">\n <div class=\"cqa-py-2\">\n <div *ngFor=\"let template of filteredTemplates; trackBy: trackByTemplate\"\n class=\"cqa-action-format cqa-bg-white cqa-cursor-pointer cqa-transition-all hover:cqa-border-blue-500 hover:cqa-shadow-sm mb-6\"\n (click)=\"selectTemplate(template)\">\n <div class=\"cqa-text-[12px] cqa-leading-[23px] cqa-text-black-100\"\n [innerHTML]=\"template.htmlGrammar || template.naturalText || ''\">\n </div>\n </div>\n\n <div *ngIf=\"filteredTemplates.length === 0\" class=\"cqa-text-center cqa-py-8 cqa-text-gray-400 cqa-text-[12px]\">\n No templates found\n </div>\n </div>\n </div>\n </div>\n\n <div *ngIf=\"selectedTemplate\" class=\"cqa-flex cqa-flex-col cqa-overflow-y-auto\" style=\"flex: 1 1 0 !important;\">\n <!-- Instruction Text with Element Buttons -->\n <div class=\"cqa-mb-4 cqa-flex cqa-items-center cqa-flex-wrap cqa-gap-1 cqa-text-sm cqa-text-gray-700\">\n <div class=\"cqa-action-format cqa-text-[12px] cqa-leading-[23px] cqa-text-black-100\"\n [innerHTML]=\"updatedHtmlGrammar || selectedTemplate.htmlGrammar || selectedTemplate.naturalText || ''\">\n </div>\n </div>\n\n <!-- Form Fields in Two Columns -->\n <div class=\"cqa-flex cqa-overflow-y-auto cqa-flex-1 cqa-pb-2\">\n <div class=\"cqa-flex-1 cqa-flex cqa-flex-col cqa-gap-1\">\n <div class=\"cqa-flex cqa-gap-x-6 cqa-flex-wrap cqa-pb-4\">\n <!-- Template Variables Form Component -->\n <cqa-template-variables-form\n style=\"width: 100%;\"\n [templateVariables]=\"templateVariables\"\n [variablesForm]=\"variablesForm\"\n [metadata]=\"metadata\"\n [description]=\"description\"\n [elementOptions]=\"elementOptions\"\n [hasMoreElements]=\"hasMoreElements\"\n [isLoadingElements]=\"isLoadingElements\"\n [screenNameOptions]=\"screenNameOptions\"\n [hasMoreScreenNames]=\"hasMoreScreenNames\"\n [isLoadingScreenNames]=\"isLoadingScreenNames\"\n (variableValueChange)=\"onVariableValueChange($event.name, $event.value)\"\n (variableBooleanChange)=\"onVariableBooleanChange($event.name, $event.value)\"\n (metadataChange)=\"metadata = $event\"\n (descriptionChange)=\"description = $event\"\n (loadMoreElements)=\"loadMoreElements.emit()\"\n (searchElements)=\"searchElements.emit($event)\"\n (createElement)=\"createElement.emit($event)\"\n (searchScreenName)=\"searchScreenName.emit($event)\"\n (loadMoreScreenNames)=\"loadMoreScreenNames.emit($event)\"\n (createScreenNameRequest)=\"createScreenNameRequest.emit($event)\"\n (elementFormVisibilityChange)=\"onElementFormVisibilityChange($event)\">\n </cqa-template-variables-form>\n </div>\n\n <!-- Advanced (Expandable) -->\n <!-- <div class=\"cqa-flex cqa-flex-col cqa-w-full\">\n <button type=\"button\"\n class=\"cqa-flex cqa-w-full cqa-items-center cqa-justify-between cqa-gap-2 cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-bg-transparent cqa-border-none cqa-cursor-pointer cqa-p-0 cqa-mb-1.5\"\n (click)=\"toggleAdvanced()\">\n <span class=\"cqa-text-[10px]\">Advanced</span>\n <mat-icon class=\"cqa-text-base\" [class.cqa-rotate-180]=\"advancedExpanded\">\n expand_more\n </mat-icon>\n </button>\n <div *ngIf=\"advancedExpanded\" class=\"cqa-mt-2\">\n </div>\n </div> -->\n <div>\n \n </div>\n </div>\n\n\n </div>\n\n <!-- Action Buttons -->\n <div *ngIf=\"!isElementFormVisible\" class=\"cqa-flex cqa-w-full cqa-gap-2 cqa-border-t cqa-border-gray-200 cqa-pb-2\">\n <cqa-button class=\"cqa-w-1/2\" variant=\"outlined\" text=\"Cancel\" [customClass]=\"'cqa-flex-1 cqa-w-full'\"\n (clicked)=\"onCancel()\">\n </cqa-button>\n <cqa-button class=\"cqa-w-1/2\" variant=\"filled\" text=\"Create Step\" [customClass]=\"'cqa-flex-1 cqa-w-full'\"\n [disabled]=\"!isFormValid()\"\n (clicked)=\"onCreateStep()\">\n </cqa-button>\n </div>\n </div>\n</div>", styles: [] }]
|
|
25927
26406
|
}], ctorParameters: function () { return [{ type: i1$1.FormBuilder }]; }, propDecorators: { showHeader: [{
|
|
25928
26407
|
type: Input
|
|
25929
26408
|
}], templates: [{
|
|
@@ -25934,8 +26413,32 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
|
|
|
25934
26413
|
type: Input
|
|
25935
26414
|
}], preventSelectTemplate: [{
|
|
25936
26415
|
type: Input
|
|
26416
|
+
}], elementOptions: [{
|
|
26417
|
+
type: Input
|
|
26418
|
+
}], hasMoreElements: [{
|
|
26419
|
+
type: Input
|
|
26420
|
+
}], isLoadingElements: [{
|
|
26421
|
+
type: Input
|
|
26422
|
+
}], screenNameOptions: [{
|
|
26423
|
+
type: Input
|
|
26424
|
+
}], hasMoreScreenNames: [{
|
|
26425
|
+
type: Input
|
|
26426
|
+
}], isLoadingScreenNames: [{
|
|
26427
|
+
type: Input
|
|
25937
26428
|
}], templateChanged: [{
|
|
25938
26429
|
type: Output
|
|
26430
|
+
}], loadMoreElements: [{
|
|
26431
|
+
type: Output
|
|
26432
|
+
}], searchElements: [{
|
|
26433
|
+
type: Output
|
|
26434
|
+
}], createElement: [{
|
|
26435
|
+
type: Output
|
|
26436
|
+
}], searchScreenName: [{
|
|
26437
|
+
type: Output
|
|
26438
|
+
}], loadMoreScreenNames: [{
|
|
26439
|
+
type: Output
|
|
26440
|
+
}], createScreenNameRequest: [{
|
|
26441
|
+
type: Output
|
|
25939
26442
|
}], createStep: [{
|
|
25940
26443
|
type: Output
|
|
25941
26444
|
}], cancelled: [{
|
|
@@ -25972,6 +26475,21 @@ class StepBuilderLoopComponent {
|
|
|
25972
26475
|
this.whileTemplates = [];
|
|
25973
26476
|
this.whileSearchPlaceholder = 'Search While';
|
|
25974
26477
|
this.whileSearchValue = '';
|
|
26478
|
+
// Element fetching properties
|
|
26479
|
+
this.elementOptions = [];
|
|
26480
|
+
this.hasMoreElements = false;
|
|
26481
|
+
this.isLoadingElements = false;
|
|
26482
|
+
// Screen name fetching properties
|
|
26483
|
+
this.screenNameOptions = [];
|
|
26484
|
+
this.hasMoreScreenNames = false;
|
|
26485
|
+
this.isLoadingScreenNames = false;
|
|
26486
|
+
this.loadMoreElements = new EventEmitter();
|
|
26487
|
+
this.searchElements = new EventEmitter();
|
|
26488
|
+
this.createElement = new EventEmitter();
|
|
26489
|
+
this.searchScreenName = new EventEmitter();
|
|
26490
|
+
this.loadMoreScreenNames = new EventEmitter();
|
|
26491
|
+
this.createScreenNameRequest = new EventEmitter();
|
|
26492
|
+
this.cancelElementForm = new EventEmitter();
|
|
25975
26493
|
this.selectedWhileTemplate = null;
|
|
25976
26494
|
this.selectedLoopType = 'for';
|
|
25977
26495
|
// Internal state for managing loop indices
|
|
@@ -26298,10 +26816,10 @@ class StepBuilderLoopComponent {
|
|
|
26298
26816
|
}
|
|
26299
26817
|
}
|
|
26300
26818
|
StepBuilderLoopComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: StepBuilderLoopComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
26301
|
-
StepBuilderLoopComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: StepBuilderLoopComponent, selector: "cqa-step-builder-loop", inputs: { loopType: "loopType", selectOptions: "selectOptions", dataProfileOptions: "dataProfileOptions", hasMoreDataProfiles: "hasMoreDataProfiles", isLoadingDataProfiles: "isLoadingDataProfiles", setWhileTemplateVariables: "setWhileTemplateVariables", whileTemplates: "whileTemplates", whileSearchPlaceholder: "whileSearchPlaceholder", whileSearchValue: "whileSearchValue" }, outputs: { createStep: "createStep", cancelled: "cancelled", loopTypeChange: "loopTypeChange", loadMoreDataProfiles: "loadMoreDataProfiles", searchDataProfiles: "searchDataProfiles" }, host: { classAttribute: "cqa-ui-root" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"cqa-flex cqa-flex-col cqa-h-full cqa-bg-white cqa-px-4 cqa-py-2\">\n <!-- Header -->\n <h2 class=\"cqa-text-[12px] cqa-font-semibold cqa-text-black-100 cqa-mb-4\">\n Create Loop Test Step\n </h2>\n\n <!-- Loop Type Selection -->\n <div class=\"cqa-mb-4 cqa-w-full\">\n <div class=\"cqa-w-full cqa-inline-flex cqa-items-center cqa-bg-gray-100 cqa-rounded-lg cqa-p-1 cqa-gap-0\" style=\"height: 30px; background-color: #F3F4F6;\">\n <!-- For Button -->\n <button\n type=\"button\"\n class=\"cqa-w-1/2 cqa-text-[12px] cqa-rounded-md cqa-font-medium cqa-transition-all cqa-duration-200 cqa-ease-in-out cqa-min-w-[80px] cqa-text-center cqa-cursor-pointer\"\n [style.background-color]=\"selectedLoopType === 'for' ? '#3F43EE' : 'transparent'\"\n [style.color]=\"selectedLoopType === 'for' ? '#FFFFFF' : '#6B7280'\"\n [style.border-radius]=\"'8px'\"\n [style.height]=\"'22px'\"\n (click)=\"onLoopTypeChange('for')\">\n For\n </button>\n <!-- While Button -->\n <button\n type=\"button\"\n class=\"cqa-w-1/2 cqa-text-[12px] cqa-rounded-md cqa-font-medium cqa-transition-all cqa-duration-200 cqa-ease-in-out cqa-min-w-[80px] cqa-text-center cqa-cursor-pointer\"\n [style.background-color]=\"selectedLoopType === 'while' ? '#3F43EE' : 'transparent'\"\n [style.color]=\"selectedLoopType === 'while' ? '#FFFFFF' : '#6B7280'\"\n [style.border-radius]=\"'8px'\"\n [style.height]=\"'22px'\"\n (click)=\"onLoopTypeChange('while')\">\n While\n </button>\n </div>\n </div>\n\n <!-- Form Fields -->\n <ng-container *ngIf=\"selectedLoopType === 'for'\">\n <div class=\"cqa-flex cqa-flex-col cqa-gap-4 cqa-flex-1 cqa-overflow-y-auto\">\n <!-- Dropdown Fields Row -->\n <div class=\"cqa-flex cqa-gap-4 cqa-flex-wrap\">\n <!-- Select Option -->\n <div class=\"cqa-flex cqa-flex-col cqa-flex-1\" style=\"min-width: calc(25% - 12px);\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1.5\">\n Select Option\n </label>\n <cqa-dynamic-select\n [form]=\"loopForm\"\n [config]=\"selectOptionConfig\">\n </cqa-dynamic-select>\n </div>\n\n <ng-container *ngIf=\"loopForm.get('selectOption')?.value === 'dataProfile'\">\n <!-- Data Profile -->\n <div class=\"cqa-flex cqa-flex-col cqa-flex-1\" style=\"min-width: calc(25% - 12px);\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1.5\">\n Data Profile\n </label>\n <cqa-dynamic-select\n [form]=\"loopForm\"\n [config]=\"dataProfileConfig\"\n (searchChange)=\"onSearchDataProfiles($event.query)\"\n (loadMore)=\"onLoadMoreDataProfiles($event)\">\n </cqa-dynamic-select>\n </div>\n\n <!-- Loop Start -->\n <div class=\"cqa-flex cqa-flex-col cqa-flex-1\" style=\"min-width: calc(25% - 12px);\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1.5\">\n Loop Start\n </label>\n <cqa-dynamic-select\n [form]=\"loopForm\"\n [config]=\"loopStartConfig\">\n </cqa-dynamic-select>\n </div>\n\n <!-- Loop End -->\n <div class=\"cqa-flex cqa-flex-col cqa-flex-1\" style=\"min-width: calc(25% - 12px);\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1.5\">\n Loop End\n </label>\n <cqa-dynamic-select\n [form]=\"loopForm\"\n [config]=\"loopEndConfig\">\n </cqa-dynamic-select>\n </div>\n </ng-container>\n <ng-container *ngIf=\"loopForm.get('selectOption')?.value === 'runTime'\">\n <!-- Run Time Input Field -->\n <div class=\"cqa-flex cqa-flex-col cqa-flex-1\" style=\"min-width: calc(25% - 12px);\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1.5\">\n Run Time\n </label>\n <cqa-custom-input\n [placeholder]=\"'Enter Run Time'\"\n [value]=\"loopForm.get('runTime')?.value\"\n [fullWidth]=\"true\"\n (valueChange)=\"loopForm.get('runTime')?.setValue($event)\">\n </cqa-custom-input>\n </div>\n </ng-container>\n </div>\n </div>\n</ng-container>\n <ng-container *ngIf=\"selectedLoopType === 'while'\">\n <cqa-step-builder-action [showHeader]=\"false\" [templates]=\"whileTemplates\" [setTemplateVariables]=\"setWhileTemplateVariables\" [searchPlaceholder]=\"whileSearchPlaceholder\"
|
|
26819
|
+
StepBuilderLoopComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: StepBuilderLoopComponent, selector: "cqa-step-builder-loop", inputs: { loopType: "loopType", selectOptions: "selectOptions", dataProfileOptions: "dataProfileOptions", hasMoreDataProfiles: "hasMoreDataProfiles", isLoadingDataProfiles: "isLoadingDataProfiles", setWhileTemplateVariables: "setWhileTemplateVariables", whileTemplates: "whileTemplates", whileSearchPlaceholder: "whileSearchPlaceholder", whileSearchValue: "whileSearchValue", elementOptions: "elementOptions", hasMoreElements: "hasMoreElements", isLoadingElements: "isLoadingElements", screenNameOptions: "screenNameOptions", hasMoreScreenNames: "hasMoreScreenNames", isLoadingScreenNames: "isLoadingScreenNames" }, outputs: { createStep: "createStep", cancelled: "cancelled", loopTypeChange: "loopTypeChange", loadMoreDataProfiles: "loadMoreDataProfiles", searchDataProfiles: "searchDataProfiles", loadMoreElements: "loadMoreElements", searchElements: "searchElements", createElement: "createElement", searchScreenName: "searchScreenName", loadMoreScreenNames: "loadMoreScreenNames", createScreenNameRequest: "createScreenNameRequest", cancelElementForm: "cancelElementForm" }, host: { classAttribute: "cqa-ui-root" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"cqa-flex cqa-flex-col cqa-h-full cqa-bg-white cqa-px-4 cqa-py-2\">\n <!-- Header -->\n <h2 class=\"cqa-text-[12px] cqa-font-semibold cqa-text-black-100 cqa-mb-4\">\n Create Loop Test Step\n </h2>\n\n <!-- Loop Type Selection -->\n <div class=\"cqa-mb-4 cqa-w-full\">\n <div class=\"cqa-w-full cqa-inline-flex cqa-items-center cqa-bg-gray-100 cqa-rounded-lg cqa-p-1 cqa-gap-0\" style=\"height: 30px; background-color: #F3F4F6;\">\n <!-- For Button -->\n <button\n type=\"button\"\n class=\"cqa-w-1/2 cqa-text-[12px] cqa-rounded-md cqa-font-medium cqa-transition-all cqa-duration-200 cqa-ease-in-out cqa-min-w-[80px] cqa-text-center cqa-cursor-pointer\"\n [style.background-color]=\"selectedLoopType === 'for' ? '#3F43EE' : 'transparent'\"\n [style.color]=\"selectedLoopType === 'for' ? '#FFFFFF' : '#6B7280'\"\n [style.border-radius]=\"'8px'\"\n [style.height]=\"'22px'\"\n (click)=\"onLoopTypeChange('for')\">\n For\n </button>\n <!-- While Button -->\n <button\n type=\"button\"\n class=\"cqa-w-1/2 cqa-text-[12px] cqa-rounded-md cqa-font-medium cqa-transition-all cqa-duration-200 cqa-ease-in-out cqa-min-w-[80px] cqa-text-center cqa-cursor-pointer\"\n [style.background-color]=\"selectedLoopType === 'while' ? '#3F43EE' : 'transparent'\"\n [style.color]=\"selectedLoopType === 'while' ? '#FFFFFF' : '#6B7280'\"\n [style.border-radius]=\"'8px'\"\n [style.height]=\"'22px'\"\n (click)=\"onLoopTypeChange('while')\">\n While\n </button>\n </div>\n </div>\n\n <!-- Form Fields -->\n <ng-container *ngIf=\"selectedLoopType === 'for'\">\n <div class=\"cqa-flex cqa-flex-col cqa-gap-4 cqa-flex-1 cqa-overflow-y-auto\">\n <!-- Dropdown Fields Row -->\n <div class=\"cqa-flex cqa-gap-4 cqa-flex-wrap\">\n <!-- Select Option -->\n <div class=\"cqa-flex cqa-flex-col cqa-flex-1\" style=\"min-width: calc(25% - 12px);\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1.5\">\n Select Option\n </label>\n <cqa-dynamic-select\n [form]=\"loopForm\"\n [config]=\"selectOptionConfig\">\n </cqa-dynamic-select>\n </div>\n\n <ng-container *ngIf=\"loopForm.get('selectOption')?.value === 'dataProfile'\">\n <!-- Data Profile -->\n <div class=\"cqa-flex cqa-flex-col cqa-flex-1\" style=\"min-width: calc(25% - 12px);\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1.5\">\n Data Profile\n </label>\n <cqa-dynamic-select\n [form]=\"loopForm\"\n [config]=\"dataProfileConfig\"\n (searchChange)=\"onSearchDataProfiles($event.query)\"\n (loadMore)=\"onLoadMoreDataProfiles($event)\">\n </cqa-dynamic-select>\n </div>\n\n <!-- Loop Start -->\n <div class=\"cqa-flex cqa-flex-col cqa-flex-1\" style=\"min-width: calc(25% - 12px);\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1.5\">\n Loop Start\n </label>\n <cqa-dynamic-select\n [form]=\"loopForm\"\n [config]=\"loopStartConfig\">\n </cqa-dynamic-select>\n </div>\n\n <!-- Loop End -->\n <div class=\"cqa-flex cqa-flex-col cqa-flex-1\" style=\"min-width: calc(25% - 12px);\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1.5\">\n Loop End\n </label>\n <cqa-dynamic-select\n [form]=\"loopForm\"\n [config]=\"loopEndConfig\">\n </cqa-dynamic-select>\n </div>\n </ng-container>\n <ng-container *ngIf=\"loopForm.get('selectOption')?.value === 'runTime'\">\n <!-- Run Time Input Field -->\n <div class=\"cqa-flex cqa-flex-col cqa-flex-1\" style=\"min-width: calc(25% - 12px);\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1.5\">\n Run Time\n </label>\n <cqa-custom-input\n [placeholder]=\"'Enter Run Time'\"\n [value]=\"loopForm.get('runTime')?.value\"\n [fullWidth]=\"true\"\n (valueChange)=\"loopForm.get('runTime')?.setValue($event)\">\n </cqa-custom-input>\n </div>\n </ng-container>\n </div>\n </div>\n</ng-container>\n <ng-container *ngIf=\"selectedLoopType === 'while'\">\n <cqa-step-builder-action \n [showHeader]=\"false\" \n [templates]=\"whileTemplates\" \n [setTemplateVariables]=\"setWhileTemplateVariables\" \n [searchPlaceholder]=\"whileSearchPlaceholder\"\n [elementOptions]=\"elementOptions\"\n [hasMoreElements]=\"hasMoreElements\"\n [isLoadingElements]=\"isLoadingElements\"\n [screenNameOptions]=\"screenNameOptions\"\n [hasMoreScreenNames]=\"hasMoreScreenNames\"\n [isLoadingScreenNames]=\"isLoadingScreenNames\"\n (templateChanged)=\"selectWhileTemplate($event)\" \n (createStep)=\"createWhileStep($event)\"\n (loadMoreElements)=\"loadMoreElements.emit()\"\n (searchElements)=\"searchElements.emit($event)\"\n (createElement)=\"createElement.emit($event)\"\n (searchScreenName)=\"searchScreenName.emit($event)\"\n (loadMoreScreenNames)=\"loadMoreScreenNames.emit($event)\"\n (createScreenNameRequest)=\"createScreenNameRequest.emit($event)\"\n (cancelElementForm)=\"cancelElementForm.emit()\">\n </cqa-step-builder-action>\n </ng-container>\n\n <!-- Action Buttons -->\n <div *ngIf=\"selectedLoopType === 'for'\" class=\"cqa-flex cqa-w-full cqa-gap-2 cqa-mt-6 cqa-pt-4 cqa-border-t cqa-border-gray-200\">\n <cqa-button\n class=\"cqa-w-1/2\"\n variant=\"outlined\"\n text=\"Cancel\"\n [customClass]=\"'cqa-flex-1 cqa-w-full'\"\n (clicked)=\"onCancel()\">\n </cqa-button>\n <cqa-button\n class=\"cqa-w-1/2\"\n variant=\"filled\"\n text=\"Create Step\"\n [customClass]=\"'cqa-flex-1 cqa-w-full'\"\n [disabled]=\"!isFormValid()\"\n (clicked)=\"onCreateStep()\">\n </cqa-button>\n </div>\n</div>\n\n", components: [{ type: DynamicSelectFieldComponent, selector: "cqa-dynamic-select", inputs: ["form", "config"], outputs: ["selectionChange", "selectClick", "searchChange", "loadMore", "addCustomValue"] }, { 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: StepBuilderActionComponent, selector: "cqa-step-builder-action", inputs: ["showHeader", "templates", "searchPlaceholder", "setTemplateVariables", "preventSelectTemplate", "elementOptions", "hasMoreElements", "isLoadingElements", "screenNameOptions", "hasMoreScreenNames", "isLoadingScreenNames"], outputs: ["templateChanged", "loadMoreElements", "searchElements", "createElement", "searchScreenName", "loadMoreScreenNames", "createScreenNameRequest", "createStep", "cancelled"] }, { 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"] }] });
|
|
26302
26820
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: StepBuilderLoopComponent, decorators: [{
|
|
26303
26821
|
type: Component,
|
|
26304
|
-
args: [{ selector: 'cqa-step-builder-loop', host: { class: 'cqa-ui-root' }, template: "<div class=\"cqa-flex cqa-flex-col cqa-h-full cqa-bg-white cqa-px-4 cqa-py-2\">\n <!-- Header -->\n <h2 class=\"cqa-text-[12px] cqa-font-semibold cqa-text-black-100 cqa-mb-4\">\n Create Loop Test Step\n </h2>\n\n <!-- Loop Type Selection -->\n <div class=\"cqa-mb-4 cqa-w-full\">\n <div class=\"cqa-w-full cqa-inline-flex cqa-items-center cqa-bg-gray-100 cqa-rounded-lg cqa-p-1 cqa-gap-0\" style=\"height: 30px; background-color: #F3F4F6;\">\n <!-- For Button -->\n <button\n type=\"button\"\n class=\"cqa-w-1/2 cqa-text-[12px] cqa-rounded-md cqa-font-medium cqa-transition-all cqa-duration-200 cqa-ease-in-out cqa-min-w-[80px] cqa-text-center cqa-cursor-pointer\"\n [style.background-color]=\"selectedLoopType === 'for' ? '#3F43EE' : 'transparent'\"\n [style.color]=\"selectedLoopType === 'for' ? '#FFFFFF' : '#6B7280'\"\n [style.border-radius]=\"'8px'\"\n [style.height]=\"'22px'\"\n (click)=\"onLoopTypeChange('for')\">\n For\n </button>\n <!-- While Button -->\n <button\n type=\"button\"\n class=\"cqa-w-1/2 cqa-text-[12px] cqa-rounded-md cqa-font-medium cqa-transition-all cqa-duration-200 cqa-ease-in-out cqa-min-w-[80px] cqa-text-center cqa-cursor-pointer\"\n [style.background-color]=\"selectedLoopType === 'while' ? '#3F43EE' : 'transparent'\"\n [style.color]=\"selectedLoopType === 'while' ? '#FFFFFF' : '#6B7280'\"\n [style.border-radius]=\"'8px'\"\n [style.height]=\"'22px'\"\n (click)=\"onLoopTypeChange('while')\">\n While\n </button>\n </div>\n </div>\n\n <!-- Form Fields -->\n <ng-container *ngIf=\"selectedLoopType === 'for'\">\n <div class=\"cqa-flex cqa-flex-col cqa-gap-4 cqa-flex-1 cqa-overflow-y-auto\">\n <!-- Dropdown Fields Row -->\n <div class=\"cqa-flex cqa-gap-4 cqa-flex-wrap\">\n <!-- Select Option -->\n <div class=\"cqa-flex cqa-flex-col cqa-flex-1\" style=\"min-width: calc(25% - 12px);\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1.5\">\n Select Option\n </label>\n <cqa-dynamic-select\n [form]=\"loopForm\"\n [config]=\"selectOptionConfig\">\n </cqa-dynamic-select>\n </div>\n\n <ng-container *ngIf=\"loopForm.get('selectOption')?.value === 'dataProfile'\">\n <!-- Data Profile -->\n <div class=\"cqa-flex cqa-flex-col cqa-flex-1\" style=\"min-width: calc(25% - 12px);\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1.5\">\n Data Profile\n </label>\n <cqa-dynamic-select\n [form]=\"loopForm\"\n [config]=\"dataProfileConfig\"\n (searchChange)=\"onSearchDataProfiles($event.query)\"\n (loadMore)=\"onLoadMoreDataProfiles($event)\">\n </cqa-dynamic-select>\n </div>\n\n <!-- Loop Start -->\n <div class=\"cqa-flex cqa-flex-col cqa-flex-1\" style=\"min-width: calc(25% - 12px);\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1.5\">\n Loop Start\n </label>\n <cqa-dynamic-select\n [form]=\"loopForm\"\n [config]=\"loopStartConfig\">\n </cqa-dynamic-select>\n </div>\n\n <!-- Loop End -->\n <div class=\"cqa-flex cqa-flex-col cqa-flex-1\" style=\"min-width: calc(25% - 12px);\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1.5\">\n Loop End\n </label>\n <cqa-dynamic-select\n [form]=\"loopForm\"\n [config]=\"loopEndConfig\">\n </cqa-dynamic-select>\n </div>\n </ng-container>\n <ng-container *ngIf=\"loopForm.get('selectOption')?.value === 'runTime'\">\n <!-- Run Time Input Field -->\n <div class=\"cqa-flex cqa-flex-col cqa-flex-1\" style=\"min-width: calc(25% - 12px);\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1.5\">\n Run Time\n </label>\n <cqa-custom-input\n [placeholder]=\"'Enter Run Time'\"\n [value]=\"loopForm.get('runTime')?.value\"\n [fullWidth]=\"true\"\n (valueChange)=\"loopForm.get('runTime')?.setValue($event)\">\n </cqa-custom-input>\n </div>\n </ng-container>\n </div>\n </div>\n</ng-container>\n <ng-container *ngIf=\"selectedLoopType === 'while'\">\n <cqa-step-builder-action [showHeader]=\"false\" [templates]=\"whileTemplates\" [setTemplateVariables]=\"setWhileTemplateVariables\" [searchPlaceholder]=\"whileSearchPlaceholder\"
|
|
26822
|
+
args: [{ selector: 'cqa-step-builder-loop', host: { class: 'cqa-ui-root' }, template: "<div class=\"cqa-flex cqa-flex-col cqa-h-full cqa-bg-white cqa-px-4 cqa-py-2\">\n <!-- Header -->\n <h2 class=\"cqa-text-[12px] cqa-font-semibold cqa-text-black-100 cqa-mb-4\">\n Create Loop Test Step\n </h2>\n\n <!-- Loop Type Selection -->\n <div class=\"cqa-mb-4 cqa-w-full\">\n <div class=\"cqa-w-full cqa-inline-flex cqa-items-center cqa-bg-gray-100 cqa-rounded-lg cqa-p-1 cqa-gap-0\" style=\"height: 30px; background-color: #F3F4F6;\">\n <!-- For Button -->\n <button\n type=\"button\"\n class=\"cqa-w-1/2 cqa-text-[12px] cqa-rounded-md cqa-font-medium cqa-transition-all cqa-duration-200 cqa-ease-in-out cqa-min-w-[80px] cqa-text-center cqa-cursor-pointer\"\n [style.background-color]=\"selectedLoopType === 'for' ? '#3F43EE' : 'transparent'\"\n [style.color]=\"selectedLoopType === 'for' ? '#FFFFFF' : '#6B7280'\"\n [style.border-radius]=\"'8px'\"\n [style.height]=\"'22px'\"\n (click)=\"onLoopTypeChange('for')\">\n For\n </button>\n <!-- While Button -->\n <button\n type=\"button\"\n class=\"cqa-w-1/2 cqa-text-[12px] cqa-rounded-md cqa-font-medium cqa-transition-all cqa-duration-200 cqa-ease-in-out cqa-min-w-[80px] cqa-text-center cqa-cursor-pointer\"\n [style.background-color]=\"selectedLoopType === 'while' ? '#3F43EE' : 'transparent'\"\n [style.color]=\"selectedLoopType === 'while' ? '#FFFFFF' : '#6B7280'\"\n [style.border-radius]=\"'8px'\"\n [style.height]=\"'22px'\"\n (click)=\"onLoopTypeChange('while')\">\n While\n </button>\n </div>\n </div>\n\n <!-- Form Fields -->\n <ng-container *ngIf=\"selectedLoopType === 'for'\">\n <div class=\"cqa-flex cqa-flex-col cqa-gap-4 cqa-flex-1 cqa-overflow-y-auto\">\n <!-- Dropdown Fields Row -->\n <div class=\"cqa-flex cqa-gap-4 cqa-flex-wrap\">\n <!-- Select Option -->\n <div class=\"cqa-flex cqa-flex-col cqa-flex-1\" style=\"min-width: calc(25% - 12px);\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1.5\">\n Select Option\n </label>\n <cqa-dynamic-select\n [form]=\"loopForm\"\n [config]=\"selectOptionConfig\">\n </cqa-dynamic-select>\n </div>\n\n <ng-container *ngIf=\"loopForm.get('selectOption')?.value === 'dataProfile'\">\n <!-- Data Profile -->\n <div class=\"cqa-flex cqa-flex-col cqa-flex-1\" style=\"min-width: calc(25% - 12px);\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1.5\">\n Data Profile\n </label>\n <cqa-dynamic-select\n [form]=\"loopForm\"\n [config]=\"dataProfileConfig\"\n (searchChange)=\"onSearchDataProfiles($event.query)\"\n (loadMore)=\"onLoadMoreDataProfiles($event)\">\n </cqa-dynamic-select>\n </div>\n\n <!-- Loop Start -->\n <div class=\"cqa-flex cqa-flex-col cqa-flex-1\" style=\"min-width: calc(25% - 12px);\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1.5\">\n Loop Start\n </label>\n <cqa-dynamic-select\n [form]=\"loopForm\"\n [config]=\"loopStartConfig\">\n </cqa-dynamic-select>\n </div>\n\n <!-- Loop End -->\n <div class=\"cqa-flex cqa-flex-col cqa-flex-1\" style=\"min-width: calc(25% - 12px);\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1.5\">\n Loop End\n </label>\n <cqa-dynamic-select\n [form]=\"loopForm\"\n [config]=\"loopEndConfig\">\n </cqa-dynamic-select>\n </div>\n </ng-container>\n <ng-container *ngIf=\"loopForm.get('selectOption')?.value === 'runTime'\">\n <!-- Run Time Input Field -->\n <div class=\"cqa-flex cqa-flex-col cqa-flex-1\" style=\"min-width: calc(25% - 12px);\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1.5\">\n Run Time\n </label>\n <cqa-custom-input\n [placeholder]=\"'Enter Run Time'\"\n [value]=\"loopForm.get('runTime')?.value\"\n [fullWidth]=\"true\"\n (valueChange)=\"loopForm.get('runTime')?.setValue($event)\">\n </cqa-custom-input>\n </div>\n </ng-container>\n </div>\n </div>\n</ng-container>\n <ng-container *ngIf=\"selectedLoopType === 'while'\">\n <cqa-step-builder-action \n [showHeader]=\"false\" \n [templates]=\"whileTemplates\" \n [setTemplateVariables]=\"setWhileTemplateVariables\" \n [searchPlaceholder]=\"whileSearchPlaceholder\"\n [elementOptions]=\"elementOptions\"\n [hasMoreElements]=\"hasMoreElements\"\n [isLoadingElements]=\"isLoadingElements\"\n [screenNameOptions]=\"screenNameOptions\"\n [hasMoreScreenNames]=\"hasMoreScreenNames\"\n [isLoadingScreenNames]=\"isLoadingScreenNames\"\n (templateChanged)=\"selectWhileTemplate($event)\" \n (createStep)=\"createWhileStep($event)\"\n (loadMoreElements)=\"loadMoreElements.emit()\"\n (searchElements)=\"searchElements.emit($event)\"\n (createElement)=\"createElement.emit($event)\"\n (searchScreenName)=\"searchScreenName.emit($event)\"\n (loadMoreScreenNames)=\"loadMoreScreenNames.emit($event)\"\n (createScreenNameRequest)=\"createScreenNameRequest.emit($event)\"\n (cancelElementForm)=\"cancelElementForm.emit()\">\n </cqa-step-builder-action>\n </ng-container>\n\n <!-- Action Buttons -->\n <div *ngIf=\"selectedLoopType === 'for'\" class=\"cqa-flex cqa-w-full cqa-gap-2 cqa-mt-6 cqa-pt-4 cqa-border-t cqa-border-gray-200\">\n <cqa-button\n class=\"cqa-w-1/2\"\n variant=\"outlined\"\n text=\"Cancel\"\n [customClass]=\"'cqa-flex-1 cqa-w-full'\"\n (clicked)=\"onCancel()\">\n </cqa-button>\n <cqa-button\n class=\"cqa-w-1/2\"\n variant=\"filled\"\n text=\"Create Step\"\n [customClass]=\"'cqa-flex-1 cqa-w-full'\"\n [disabled]=\"!isFormValid()\"\n (clicked)=\"onCreateStep()\">\n </cqa-button>\n </div>\n</div>\n\n", styles: [] }]
|
|
26305
26823
|
}], ctorParameters: function () { return []; }, propDecorators: { loopType: [{
|
|
26306
26824
|
type: Input
|
|
26307
26825
|
}], selectOptions: [{
|
|
@@ -26330,6 +26848,32 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
|
|
|
26330
26848
|
type: Input
|
|
26331
26849
|
}], whileSearchValue: [{
|
|
26332
26850
|
type: Input
|
|
26851
|
+
}], elementOptions: [{
|
|
26852
|
+
type: Input
|
|
26853
|
+
}], hasMoreElements: [{
|
|
26854
|
+
type: Input
|
|
26855
|
+
}], isLoadingElements: [{
|
|
26856
|
+
type: Input
|
|
26857
|
+
}], screenNameOptions: [{
|
|
26858
|
+
type: Input
|
|
26859
|
+
}], hasMoreScreenNames: [{
|
|
26860
|
+
type: Input
|
|
26861
|
+
}], isLoadingScreenNames: [{
|
|
26862
|
+
type: Input
|
|
26863
|
+
}], loadMoreElements: [{
|
|
26864
|
+
type: Output
|
|
26865
|
+
}], searchElements: [{
|
|
26866
|
+
type: Output
|
|
26867
|
+
}], createElement: [{
|
|
26868
|
+
type: Output
|
|
26869
|
+
}], searchScreenName: [{
|
|
26870
|
+
type: Output
|
|
26871
|
+
}], loadMoreScreenNames: [{
|
|
26872
|
+
type: Output
|
|
26873
|
+
}], createScreenNameRequest: [{
|
|
26874
|
+
type: Output
|
|
26875
|
+
}], cancelElementForm: [{
|
|
26876
|
+
type: Output
|
|
26333
26877
|
}] } });
|
|
26334
26878
|
|
|
26335
26879
|
class StepBuilderConditionComponent {
|
|
@@ -26349,10 +26893,25 @@ class StepBuilderConditionComponent {
|
|
|
26349
26893
|
this.conditionTemplates = [];
|
|
26350
26894
|
/** Function to handle variable processing or custom logic. Can be passed from parent component. */
|
|
26351
26895
|
this.setConditionTemplateVariables = () => { return []; };
|
|
26896
|
+
this.elementOptions = []; // Element objects for element dropdown
|
|
26897
|
+
this.hasMoreElements = false; // Whether more elements are available
|
|
26898
|
+
this.isLoadingElements = false; // Loading state for elements
|
|
26899
|
+
/** Screen name options for element form autocomplete (from API) */
|
|
26900
|
+
this.screenNameOptions = [];
|
|
26901
|
+
/** Whether more screen names are available for infinite scroll */
|
|
26902
|
+
this.hasMoreScreenNames = false;
|
|
26903
|
+
/** True while parent is loading screen names (search or load more) */
|
|
26904
|
+
this.isLoadingScreenNames = false;
|
|
26352
26905
|
/** Emit when step is created */
|
|
26353
26906
|
this.createStep = new EventEmitter();
|
|
26354
26907
|
/** Emit when cancelled */
|
|
26355
26908
|
this.cancelled = new EventEmitter();
|
|
26909
|
+
this.loadMoreElements = new EventEmitter(); // Emit when load more is requested
|
|
26910
|
+
this.searchElements = new EventEmitter(); // Emit when user searches for elements
|
|
26911
|
+
this.createElement = new EventEmitter(); // Emit when element is created
|
|
26912
|
+
this.searchScreenName = new EventEmitter(); // Emit when user searches screen names
|
|
26913
|
+
this.loadMoreScreenNames = new EventEmitter(); // Emit when user scrolls to load more screen names
|
|
26914
|
+
this.createScreenNameRequest = new EventEmitter(); // Emit when user requests to create a new screen name
|
|
26356
26915
|
this.includeElse = false;
|
|
26357
26916
|
// Cache for value configs to avoid recreating on every change detection
|
|
26358
26917
|
this.valueConfigCache = null;
|
|
@@ -26364,6 +26923,7 @@ class StepBuilderConditionComponent {
|
|
|
26364
26923
|
this.selectedTemplates = new Map();
|
|
26365
26924
|
this.conditionTemplateVariables = new Map();
|
|
26366
26925
|
this.conditionVariablesForms = new Map();
|
|
26926
|
+
this.conditionUpdatedHtmlGrammar = new Map(); // Updated HTML grammar per condition
|
|
26367
26927
|
// Cache for condition form groups to avoid repeated lookups
|
|
26368
26928
|
this.conditionFormGroupCache = new Map();
|
|
26369
26929
|
this.conditionForm = this.fb.group({
|
|
@@ -26412,8 +26972,8 @@ class StepBuilderConditionComponent {
|
|
|
26412
26972
|
});
|
|
26413
26973
|
const index = this.conditionsFormArray.length;
|
|
26414
26974
|
this.conditionsFormArray.push(conditionGroup);
|
|
26415
|
-
// Initialize variables form for this condition
|
|
26416
|
-
this.conditionVariablesForms.set(index, this.fb.
|
|
26975
|
+
// Initialize variables form for this condition (FormArray)
|
|
26976
|
+
this.conditionVariablesForms.set(index, this.fb.array([]));
|
|
26417
26977
|
// Cache the form group
|
|
26418
26978
|
this.conditionFormGroupCache.set(index, conditionGroup);
|
|
26419
26979
|
// Mark for check since we're using OnPush
|
|
@@ -26441,6 +27001,7 @@ class StepBuilderConditionComponent {
|
|
|
26441
27001
|
const newVariablesForms = new Map();
|
|
26442
27002
|
const newFormGroupCache = new Map();
|
|
26443
27003
|
const newValueConfigs = new Map();
|
|
27004
|
+
const newUpdatedHtmlGrammar = new Map();
|
|
26444
27005
|
this.selectedTemplates.forEach((template, oldIndex) => {
|
|
26445
27006
|
if (oldIndex < removedIndex) {
|
|
26446
27007
|
newSelectedTemplates.set(oldIndex, template);
|
|
@@ -26485,11 +27046,20 @@ class StepBuilderConditionComponent {
|
|
|
26485
27046
|
newValueConfigs.set(oldIndex - 1, newConfig);
|
|
26486
27047
|
}
|
|
26487
27048
|
});
|
|
27049
|
+
this.conditionUpdatedHtmlGrammar.forEach((grammar, oldIndex) => {
|
|
27050
|
+
if (oldIndex < removedIndex) {
|
|
27051
|
+
newUpdatedHtmlGrammar.set(oldIndex, grammar);
|
|
27052
|
+
}
|
|
27053
|
+
else if (oldIndex > removedIndex) {
|
|
27054
|
+
newUpdatedHtmlGrammar.set(oldIndex - 1, grammar);
|
|
27055
|
+
}
|
|
27056
|
+
});
|
|
26488
27057
|
this.selectedTemplates = newSelectedTemplates;
|
|
26489
27058
|
this.conditionTemplateVariables = newTemplateVariables;
|
|
26490
27059
|
this.conditionVariablesForms = newVariablesForms;
|
|
26491
27060
|
this.conditionFormGroupCache = newFormGroupCache;
|
|
26492
27061
|
this.valueConfigsWithHandlers = newValueConfigs;
|
|
27062
|
+
this.conditionUpdatedHtmlGrammar = newUpdatedHtmlGrammar;
|
|
26493
27063
|
}
|
|
26494
27064
|
getOperatorConfig(index) {
|
|
26495
27065
|
// Return cached config (static, same for all conditions)
|
|
@@ -26545,54 +27115,99 @@ class StepBuilderConditionComponent {
|
|
|
26545
27115
|
this.conditionTemplateVariables.set(index, variables);
|
|
26546
27116
|
// Build form for template variables
|
|
26547
27117
|
this.buildConditionVariablesForm(index, variables);
|
|
27118
|
+
// Initialize updated HTML grammar
|
|
27119
|
+
this.updateConditionHtmlGrammar(index);
|
|
26548
27120
|
}
|
|
26549
27121
|
else {
|
|
26550
27122
|
// Clear template and variables if no template selected
|
|
26551
27123
|
this.selectedTemplates.delete(index);
|
|
26552
27124
|
this.conditionTemplateVariables.delete(index);
|
|
26553
|
-
|
|
26554
|
-
|
|
26555
|
-
|
|
26556
|
-
|
|
26557
|
-
|
|
27125
|
+
this.conditionUpdatedHtmlGrammar.delete(index);
|
|
27126
|
+
const formArray = this.conditionVariablesForms.get(index);
|
|
27127
|
+
if (formArray) {
|
|
27128
|
+
while (formArray.length !== 0) {
|
|
27129
|
+
formArray.removeAt(0);
|
|
27130
|
+
}
|
|
26558
27131
|
}
|
|
26559
27132
|
}
|
|
26560
27133
|
// Mark for check since we're using OnPush
|
|
26561
27134
|
this.cdr.markForCheck();
|
|
26562
27135
|
}
|
|
26563
27136
|
buildConditionVariablesForm(index, variables) {
|
|
26564
|
-
let
|
|
26565
|
-
if (!
|
|
26566
|
-
|
|
26567
|
-
this.conditionVariablesForms.set(index,
|
|
27137
|
+
let formArray = this.conditionVariablesForms.get(index);
|
|
27138
|
+
if (!formArray) {
|
|
27139
|
+
formArray = this.fb.array([]);
|
|
27140
|
+
this.conditionVariablesForms.set(index, formArray);
|
|
26568
27141
|
}
|
|
26569
|
-
// Ensure
|
|
26570
|
-
if (!
|
|
27142
|
+
// Ensure formArray is not undefined (TypeScript guard)
|
|
27143
|
+
if (!formArray) {
|
|
26571
27144
|
return;
|
|
26572
27145
|
}
|
|
26573
|
-
//
|
|
26574
|
-
|
|
26575
|
-
|
|
26576
|
-
|
|
26577
|
-
|
|
27146
|
+
// Store reference to avoid TypeScript issues in forEach callback
|
|
27147
|
+
// TypeScript knows formArray is defined here due to the early return above
|
|
27148
|
+
const formArrayRef = formArray;
|
|
27149
|
+
// Clear existing form array
|
|
27150
|
+
while (formArrayRef.length !== 0) {
|
|
27151
|
+
formArrayRef.removeAt(0);
|
|
27152
|
+
}
|
|
27153
|
+
// Add form groups for each variable
|
|
26578
27154
|
variables.forEach(variable => {
|
|
27155
|
+
var _a;
|
|
26579
27156
|
// Handle boolean variables - use boolean value, others use string
|
|
26580
27157
|
const defaultValue = variable.type === 'boolean'
|
|
26581
27158
|
? (variable.value === true || variable.value === 'true' || variable.value === 1)
|
|
26582
27159
|
: (variable.value || '');
|
|
26583
|
-
|
|
27160
|
+
// Create a FormGroup for each variable with name and value
|
|
27161
|
+
const variableGroup = this.fb.group({
|
|
27162
|
+
name: [variable.name],
|
|
27163
|
+
value: [defaultValue],
|
|
27164
|
+
type: [variable.type || 'string'],
|
|
27165
|
+
label: [variable.label || ''],
|
|
27166
|
+
options: [variable.options || []]
|
|
27167
|
+
});
|
|
27168
|
+
// Add dataType control for test-data variables if needed
|
|
27169
|
+
const label = ((_a = variable.label) === null || _a === void 0 ? void 0 : _a.toLowerCase()) || '';
|
|
27170
|
+
if (label === 'test-data' || label === 'source-value' || label === 'target-value' ||
|
|
27171
|
+
label === 'source_value' || label === 'target_value') {
|
|
27172
|
+
// Parse the value to determine data type
|
|
27173
|
+
const valueStr = String(defaultValue || '');
|
|
27174
|
+
let dataType = 'plain-text';
|
|
27175
|
+
if (valueStr.startsWith('@|') && valueStr.endsWith('|')) {
|
|
27176
|
+
dataType = 'parameter';
|
|
27177
|
+
}
|
|
27178
|
+
else if (valueStr.startsWith('$|') && valueStr.endsWith('|')) {
|
|
27179
|
+
dataType = 'runtime';
|
|
27180
|
+
}
|
|
27181
|
+
else if (valueStr.startsWith('*|') && valueStr.endsWith('|')) {
|
|
27182
|
+
dataType = 'environment';
|
|
27183
|
+
}
|
|
27184
|
+
variableGroup.addControl('dataType', new FormControl(dataType));
|
|
27185
|
+
}
|
|
27186
|
+
formArrayRef.push(variableGroup);
|
|
26584
27187
|
});
|
|
27188
|
+
// Initialize updated HTML grammar for this condition
|
|
27189
|
+
this.updateConditionHtmlGrammar(index);
|
|
26585
27190
|
}
|
|
26586
27191
|
getConditionTemplateVariables(index) {
|
|
26587
27192
|
return this.conditionTemplateVariables.get(index) || [];
|
|
26588
27193
|
}
|
|
26589
27194
|
getConditionVariablesForm(index) {
|
|
26590
|
-
let
|
|
26591
|
-
if (!
|
|
26592
|
-
|
|
26593
|
-
this.conditionVariablesForms.set(index,
|
|
27195
|
+
let formArray = this.conditionVariablesForms.get(index);
|
|
27196
|
+
if (!formArray) {
|
|
27197
|
+
formArray = this.fb.array([]);
|
|
27198
|
+
this.conditionVariablesForms.set(index, formArray);
|
|
26594
27199
|
}
|
|
26595
|
-
return
|
|
27200
|
+
return formArray;
|
|
27201
|
+
}
|
|
27202
|
+
getConditionFormGroupAt(index, variableIndex) {
|
|
27203
|
+
const formArray = this.getConditionVariablesForm(index);
|
|
27204
|
+
return formArray.at(variableIndex);
|
|
27205
|
+
}
|
|
27206
|
+
getConditionUpdatedHtmlGrammar(index) {
|
|
27207
|
+
const template = this.selectedTemplates.get(index);
|
|
27208
|
+
if (!template)
|
|
27209
|
+
return '';
|
|
27210
|
+
return this.conditionUpdatedHtmlGrammar.get(index) || template.htmlGrammar || template.naturalText || '';
|
|
26596
27211
|
}
|
|
26597
27212
|
getSelectedTemplate(index) {
|
|
26598
27213
|
return this.selectedTemplates.get(index) || null;
|
|
@@ -26623,11 +27238,16 @@ class StepBuilderConditionComponent {
|
|
|
26623
27238
|
if (variable) {
|
|
26624
27239
|
variable.value = value;
|
|
26625
27240
|
}
|
|
26626
|
-
// Also update form
|
|
26627
|
-
const
|
|
26628
|
-
if (
|
|
26629
|
-
(_a =
|
|
27241
|
+
// Also update form array
|
|
27242
|
+
const formArray = this.conditionVariablesForms.get(conditionIndex);
|
|
27243
|
+
if (formArray) {
|
|
27244
|
+
const variableIndex = formArray.controls.findIndex(control => { var _a; return ((_a = control.get('name')) === null || _a === void 0 ? void 0 : _a.value) === variableName; });
|
|
27245
|
+
if (variableIndex !== -1) {
|
|
27246
|
+
(_a = formArray.at(variableIndex).get('value')) === null || _a === void 0 ? void 0 : _a.setValue(value, { emitEvent: false });
|
|
27247
|
+
}
|
|
26630
27248
|
}
|
|
27249
|
+
// Update HTML grammar for this condition
|
|
27250
|
+
this.updateConditionHtmlGrammar(conditionIndex);
|
|
26631
27251
|
// Mark for check since we're using OnPush
|
|
26632
27252
|
this.cdr.markForCheck();
|
|
26633
27253
|
}
|
|
@@ -26653,20 +27273,63 @@ class StepBuilderConditionComponent {
|
|
|
26653
27273
|
if (variable) {
|
|
26654
27274
|
variable.value = value;
|
|
26655
27275
|
}
|
|
26656
|
-
// Also update form
|
|
26657
|
-
const
|
|
26658
|
-
if (
|
|
26659
|
-
|
|
26660
|
-
|
|
26661
|
-
|
|
26662
|
-
|
|
26663
|
-
|
|
26664
|
-
form.addControl(variableName, new FormControl(value));
|
|
26665
|
-
}
|
|
27276
|
+
// Also update form array
|
|
27277
|
+
const formArray = this.conditionVariablesForms.get(conditionIndex);
|
|
27278
|
+
if (!formArray) {
|
|
27279
|
+
return;
|
|
27280
|
+
}
|
|
27281
|
+
const variableIndex = formArray.controls.findIndex(control => { var _a; return ((_a = control.get('name')) === null || _a === void 0 ? void 0 : _a.value) === variableName; });
|
|
27282
|
+
if (variableIndex !== -1) {
|
|
27283
|
+
(_a = formArray.at(variableIndex).get('value')) === null || _a === void 0 ? void 0 : _a.setValue(value, { emitEvent: false });
|
|
26666
27284
|
}
|
|
27285
|
+
else {
|
|
27286
|
+
// Create new form group if it doesn't exist
|
|
27287
|
+
const variableGroup = this.fb.group({
|
|
27288
|
+
name: [variableName],
|
|
27289
|
+
value: [value],
|
|
27290
|
+
type: ['boolean'],
|
|
27291
|
+
label: [(variable === null || variable === void 0 ? void 0 : variable.label) || ''],
|
|
27292
|
+
options: [(variable === null || variable === void 0 ? void 0 : variable.options) || []]
|
|
27293
|
+
});
|
|
27294
|
+
// formArray is guaranteed to be defined here due to the early return above
|
|
27295
|
+
formArray.push(variableGroup);
|
|
27296
|
+
}
|
|
27297
|
+
// Update HTML grammar for this condition
|
|
27298
|
+
this.updateConditionHtmlGrammar(conditionIndex);
|
|
26667
27299
|
// Mark for check since we're using OnPush
|
|
26668
27300
|
this.cdr.markForCheck();
|
|
26669
27301
|
}
|
|
27302
|
+
/**
|
|
27303
|
+
* Strip HTML tags from a string for search functionality
|
|
27304
|
+
*/
|
|
27305
|
+
stripHtmlTags(htmlString) {
|
|
27306
|
+
if (!htmlString)
|
|
27307
|
+
return '';
|
|
27308
|
+
// Create a temporary div element to parse HTML
|
|
27309
|
+
const tmp = document.createElement('DIV');
|
|
27310
|
+
tmp.innerHTML = htmlString;
|
|
27311
|
+
return tmp.textContent || tmp.innerText || '';
|
|
27312
|
+
}
|
|
27313
|
+
/**
|
|
27314
|
+
* Update HTML grammar for a specific condition with actual variable values
|
|
27315
|
+
*/
|
|
27316
|
+
updateConditionHtmlGrammar(conditionIndex) {
|
|
27317
|
+
const template = this.selectedTemplates.get(conditionIndex);
|
|
27318
|
+
if (!template || !template.htmlGrammar) {
|
|
27319
|
+
return;
|
|
27320
|
+
}
|
|
27321
|
+
let updatedGrammar = template.htmlGrammar;
|
|
27322
|
+
const variables = this.conditionTemplateVariables.get(conditionIndex) || [];
|
|
27323
|
+
// Replace placeholders with actual values
|
|
27324
|
+
variables.forEach(variable => {
|
|
27325
|
+
const placeholder = new RegExp(`<span[^>]*data-event-key="${variable.name}"[^>]*>.*?</span>`, 'gi');
|
|
27326
|
+
const value = variable.value || '';
|
|
27327
|
+
// Escape HTML in value to prevent XSS
|
|
27328
|
+
const escapedValue = String(value).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
27329
|
+
updatedGrammar = updatedGrammar.replace(placeholder, escapedValue);
|
|
27330
|
+
});
|
|
27331
|
+
this.conditionUpdatedHtmlGrammar.set(conditionIndex, updatedGrammar);
|
|
27332
|
+
}
|
|
26670
27333
|
getConditionFormGroup(index) {
|
|
26671
27334
|
// Use cache to avoid repeated lookups
|
|
26672
27335
|
if (this.conditionFormGroupCache.has(index)) {
|
|
@@ -26736,20 +27399,44 @@ class StepBuilderConditionComponent {
|
|
|
26736
27399
|
}
|
|
26737
27400
|
}
|
|
26738
27401
|
StepBuilderConditionComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: StepBuilderConditionComponent, deps: [{ token: i1$1.FormBuilder }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
26739
|
-
StepBuilderConditionComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: StepBuilderConditionComponent, selector: "cqa-step-builder-condition", inputs: { operatorOptions: "operatorOptions", conditionTemplates: "conditionTemplates", setConditionTemplateVariables: "setConditionTemplateVariables" }, outputs: { createStep: "createStep", cancelled: "cancelled" }, host: { classAttribute: "cqa-ui-root" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"cqa-flex cqa-flex-col cqa-h-full cqa-bg-white cqa-px-4 cqa-py-2\">\n <!-- Header -->\n <h2 class=\"cqa-text-[12px] cqa-font-semibold cqa-text-black-100 cqa-mb-4\">\n Create Condition Step\n </h2>\n\n <div class=\"cqa-flex cqa-flex-col cqa-flex-1 cqa-overflow-y-auto\">\n <!-- Condition Builder Section -->\n <div class=\"cqa-mb-6\">\n <h3 class=\"cqa-text-sm cqa-text-[12px] cqa-font-semibold cqa-text-gray-900 cqa-mb-3\">\n Condition Builder\n </h3>\n\n <!-- Condition Rows -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-3 cqa-mb-3\">\n <ng-container *ngFor=\"let condition of conditionsFormArray.controls; let i = index; trackBy: trackByConditionIndex\">\n <div\n *ngIf=\"isConditionIf(i) || isConditionElseIf(i)\"\n class=\"cqa-flex cqa-flex-col cqa-gap-2\">\n <!-- Condition Row -->\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <!-- Condition Label -->\n <div class=\"cqa-text-[12px] cqa-font-semibold\">\n {{ getConditionLabel(i) }}\n </div>\n\n <!-- Operator Dropdown -->\n <!-- <div class=\"cqa-flex-1 cqa-max-w-[100px] cqa-text-[10px]\">\n <cqa-dynamic-select [form]=\"getConditionFormGroup(i)\" [config]=\"getOperatorConfig(i)\">\n </cqa-dynamic-select>\n </div> -->\n\n <!-- Value Template Dropdown -->\n <div class=\"cqa-flex-1 cqa-min-w-[150px] cqa-text-[10px]\">\n <cqa-dynamic-select [form]=\"getConditionFormGroup(i)\" [config]=\"getValueConfig(i)\">\n </cqa-dynamic-select>\n </div>\n\n <!-- Remove Button -->\n <cqa-button\n *ngIf=\"i >= 1\"\n variant=\"text\"\n icon=\"close\"\n iconPosition=\"start\"\n [customClass]=\"'cqa-w-full cqa-flex cqa-items-center cqa-justify-center'\"\n (click)=\"removeCondition(i)\"\n [attr.aria-label]=\"'Remove condition'\">\n </cqa-button>\n <!-- <button type=\"button\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-8 cqa-h-8 cqa-rounded cqa-text-gray-500 hover:cqa-text-gray-700 hover:cqa-bg-gray-100 cqa-transition-colors\"\n (click)=\"removeCondition(i)\" *ngIf=\"i >= 1\"\n [attr.aria-label]=\"'Remove condition'\">\n <mat-icon class=\"cqa-text-lg cqa-text-[24px]\">close</mat-icon>\n </button> -->\n </div>\n\n <!-- Template Variables Section (shown when template is selected) -->\n <div *ngIf=\"getSelectedTemplate(i)\">\n <!-- Template Grammar Display -->\n
|
|
27402
|
+
StepBuilderConditionComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: StepBuilderConditionComponent, selector: "cqa-step-builder-condition", inputs: { operatorOptions: "operatorOptions", conditionTemplates: "conditionTemplates", setConditionTemplateVariables: "setConditionTemplateVariables", elementOptions: "elementOptions", hasMoreElements: "hasMoreElements", isLoadingElements: "isLoadingElements", screenNameOptions: "screenNameOptions", hasMoreScreenNames: "hasMoreScreenNames", isLoadingScreenNames: "isLoadingScreenNames" }, outputs: { createStep: "createStep", cancelled: "cancelled", loadMoreElements: "loadMoreElements", searchElements: "searchElements", createElement: "createElement", searchScreenName: "searchScreenName", loadMoreScreenNames: "loadMoreScreenNames", createScreenNameRequest: "createScreenNameRequest" }, host: { classAttribute: "cqa-ui-root" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"cqa-flex cqa-flex-col cqa-h-full cqa-bg-white cqa-px-4 cqa-py-2\">\n <!-- Header -->\n <h2 class=\"cqa-text-[12px] cqa-font-semibold cqa-text-black-100 cqa-mb-4\">\n Create Condition Step\n </h2>\n\n <div class=\"cqa-flex cqa-flex-col cqa-flex-1 cqa-overflow-y-auto\">\n <!-- Condition Builder Section -->\n <div class=\"cqa-mb-6\">\n <h3 class=\"cqa-text-sm cqa-text-[12px] cqa-font-semibold cqa-text-gray-900 cqa-mb-3\">\n Condition Builder\n </h3>\n\n <!-- Condition Rows -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-3 cqa-mb-3\">\n <ng-container *ngFor=\"let condition of conditionsFormArray.controls; let i = index; trackBy: trackByConditionIndex\">\n <div\n *ngIf=\"isConditionIf(i) || isConditionElseIf(i)\"\n class=\"cqa-flex cqa-flex-col cqa-gap-2\">\n <!-- Condition Row -->\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <!-- Condition Label -->\n <div class=\"cqa-text-[12px] cqa-font-semibold\">\n {{ getConditionLabel(i) }}\n </div>\n\n <!-- Operator Dropdown -->\n <!-- <div class=\"cqa-flex-1 cqa-max-w-[100px] cqa-text-[10px]\">\n <cqa-dynamic-select [form]=\"getConditionFormGroup(i)\" [config]=\"getOperatorConfig(i)\">\n </cqa-dynamic-select>\n </div> -->\n\n <!-- Value Template Dropdown -->\n <div class=\"cqa-flex-1 cqa-min-w-[150px] cqa-text-[10px]\">\n <cqa-dynamic-select [form]=\"getConditionFormGroup(i)\" [config]=\"getValueConfig(i)\">\n </cqa-dynamic-select>\n </div>\n\n <!-- Remove Button -->\n <cqa-button\n *ngIf=\"i >= 1\"\n variant=\"text\"\n icon=\"close\"\n iconPosition=\"start\"\n [customClass]=\"'cqa-w-full cqa-flex cqa-items-center cqa-justify-center'\"\n (click)=\"removeCondition(i)\"\n [attr.aria-label]=\"'Remove condition'\">\n </cqa-button>\n <!-- <button type=\"button\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-8 cqa-h-8 cqa-rounded cqa-text-gray-500 hover:cqa-text-gray-700 hover:cqa-bg-gray-100 cqa-transition-colors\"\n (click)=\"removeCondition(i)\" *ngIf=\"i >= 1\"\n [attr.aria-label]=\"'Remove condition'\">\n <mat-icon class=\"cqa-text-lg cqa-text-[24px]\">close</mat-icon>\n </button> -->\n </div>\n\n <!-- Template Variables Section (shown when template is selected) -->\n <div *ngIf=\"getSelectedTemplate(i)\" class=\"cqa-mt-2\">\n <!-- Template Grammar Display -->\n <div class=\"cqa-mb-4 cqa-flex cqa-items-center cqa-flex-wrap cqa-gap-1 cqa-text-sm cqa-text-gray-700\">\n <div class=\"cqa-action-format cqa-text-[12px] cqa-leading-[23px] cqa-text-black-100\"\n [innerHTML]=\"getConditionUpdatedHtmlGrammar(i) || getSelectedTemplate(i)?.htmlGrammar || getSelectedTemplate(i)?.naturalText || ''\">\n </div>\n </div>\n \n <!-- Template Variables Form Component (includes Description and Metadata) -->\n <cqa-template-variables-form\n style=\"width: 100%;\"\n [templateVariables]=\"getConditionTemplateVariables(i)\"\n [variablesForm]=\"getConditionVariablesForm(i)\"\n [metadata]=\"getConditionFormGroup(i).get('metadata')?.value || ''\"\n [description]=\"getConditionFormGroup(i).get('description')?.value || ''\"\n [elementOptions]=\"elementOptions\"\n [hasMoreElements]=\"hasMoreElements\"\n [isLoadingElements]=\"isLoadingElements\"\n [screenNameOptions]=\"screenNameOptions\"\n [hasMoreScreenNames]=\"hasMoreScreenNames\"\n [isLoadingScreenNames]=\"isLoadingScreenNames\"\n (variableValueChange)=\"onConditionVariableValueChange(i, $event.name, $event.value)\"\n (variableBooleanChange)=\"onConditionVariableBooleanChange(i, $event.name, $event.value)\"\n (metadataChange)=\"getConditionFormGroup(i).get('metadata')?.setValue($event)\"\n (descriptionChange)=\"getConditionFormGroup(i).get('description')?.setValue($event)\"\n (loadMoreElements)=\"loadMoreElements.emit()\"\n (searchElements)=\"searchElements.emit($event)\"\n (createElement)=\"createElement.emit($event)\"\n (searchScreenName)=\"searchScreenName.emit($event)\"\n (loadMoreScreenNames)=\"loadMoreScreenNames.emit($event)\"\n (createScreenNameRequest)=\"createScreenNameRequest.emit($event)\">\n </cqa-template-variables-form>\n </div>\n </div>\n </ng-container>\n </div>\n\n <!-- Add Condition Button -->\n <div class=\"cqa-border-2 cqa-border-dashed cqa-border-gray-300 cqa-rounded-lg cqa-p-1 cqa-mt-3\">\n <cqa-button\n variant=\"text\"\n icon=\"add\"\n iconPosition=\"start\"\n [customClass]=\"'cqa-w-full cqa-flex cqa-items-center cqa-justify-center'\"\n [text]=\"'Add Condition'\"\n (clicked)=\"addCondition('CONDITION_ELSE_IF')\">\n </cqa-button>\n </div>\n </div>\n\n <!-- Include ELSE Branch Section -->\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-mb-6 cqa-p-3 cqa-bg-gray-50 cqa-rounded-lg\">\n <div class=\"cqa-flex cqa-flex-col\">\n <h3 class=\"cqa-text-[14px] cqa-font-semibold cqa-text-gray-900 cqa-mb-1\">\n Include ELSE branch\n </h3>\n <p class=\"cqa-text-[12px] cqa-text-gray-600\">\n Execute alternative steps when condition is not met.\n </p>\n </div>\n <mat-slide-toggle [checked]=\"includeElse\" (change)=\"onIncludeElseChange($event.checked)\" color=\"primary\">\n </mat-slide-toggle>\n </div>\n </div>\n <!-- Action Buttons -->\n <div class=\"cqa-flex cqa-w-full cqa-gap-2 cqa-mt-auto cqa-pt-4 cqa-border-t cqa-border-gray-200\">\n <cqa-button class=\"cqa-w-1/2\" variant=\"outlined\" text=\"Cancel\" [customClass]=\"'cqa-flex-1 cqa-w-full'\"\n (clicked)=\"onCancel()\">\n </cqa-button>\n <cqa-button class=\"cqa-w-1/2\" variant=\"filled\" text=\"Create Step\" [customClass]=\"'cqa-flex-1 cqa-w-full'\"\n [disabled]=\"!conditionForm.valid\"\n (clicked)=\"onCreateStep()\">\n </cqa-button>\n </div>\n</div>", components: [{ type: DynamicSelectFieldComponent, selector: "cqa-dynamic-select", inputs: ["form", "config"], outputs: ["selectionChange", "selectClick", "searchChange", "loadMore", "addCustomValue"] }, { type: ButtonComponent, selector: "cqa-button", inputs: ["variant", "btnSize", "disabled", "icon", "iconPosition", "fullWidth", "iconColor", "type", "text", "customClass", "inlineStyles", "tooltip", "tooltipPosition"], outputs: ["clicked"] }, { type: TemplateVariablesFormComponent, selector: "cqa-template-variables-form", inputs: ["templateVariables", "variablesForm", "metadata", "description", "elementOptions", "hasMoreElements", "isLoadingElements", "screenNameOptions", "hasMoreScreenNames", "isLoadingScreenNames"], outputs: ["variableValueChange", "variableBooleanChange", "metadataChange", "descriptionChange", "loadMoreElements", "searchElements", "createElement", "searchScreenName", "loadMoreScreenNames", "createScreenNameRequest", "cancelElementForm", "elementFormVisibilityChange"] }, { type: i5$1.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["disabled", "disableRipple", "color", "tabIndex", "name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "checked"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }], directives: [{ type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
26740
27403
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: StepBuilderConditionComponent, decorators: [{
|
|
26741
27404
|
type: Component,
|
|
26742
|
-
args: [{ selector: 'cqa-step-builder-condition', host: { class: 'cqa-ui-root' }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"cqa-flex cqa-flex-col cqa-h-full cqa-bg-white cqa-px-4 cqa-py-2\">\n <!-- Header -->\n <h2 class=\"cqa-text-[12px] cqa-font-semibold cqa-text-black-100 cqa-mb-4\">\n Create Condition Step\n </h2>\n\n <div class=\"cqa-flex cqa-flex-col cqa-flex-1 cqa-overflow-y-auto\">\n <!-- Condition Builder Section -->\n <div class=\"cqa-mb-6\">\n <h3 class=\"cqa-text-sm cqa-text-[12px] cqa-font-semibold cqa-text-gray-900 cqa-mb-3\">\n Condition Builder\n </h3>\n\n <!-- Condition Rows -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-3 cqa-mb-3\">\n <ng-container *ngFor=\"let condition of conditionsFormArray.controls; let i = index; trackBy: trackByConditionIndex\">\n <div\n *ngIf=\"isConditionIf(i) || isConditionElseIf(i)\"\n class=\"cqa-flex cqa-flex-col cqa-gap-2\">\n <!-- Condition Row -->\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <!-- Condition Label -->\n <div class=\"cqa-text-[12px] cqa-font-semibold\">\n {{ getConditionLabel(i) }}\n </div>\n\n <!-- Operator Dropdown -->\n <!-- <div class=\"cqa-flex-1 cqa-max-w-[100px] cqa-text-[10px]\">\n <cqa-dynamic-select [form]=\"getConditionFormGroup(i)\" [config]=\"getOperatorConfig(i)\">\n </cqa-dynamic-select>\n </div> -->\n\n <!-- Value Template Dropdown -->\n <div class=\"cqa-flex-1 cqa-min-w-[150px] cqa-text-[10px]\">\n <cqa-dynamic-select [form]=\"getConditionFormGroup(i)\" [config]=\"getValueConfig(i)\">\n </cqa-dynamic-select>\n </div>\n\n <!-- Remove Button -->\n <cqa-button\n *ngIf=\"i >= 1\"\n variant=\"text\"\n icon=\"close\"\n iconPosition=\"start\"\n [customClass]=\"'cqa-w-full cqa-flex cqa-items-center cqa-justify-center'\"\n (click)=\"removeCondition(i)\"\n [attr.aria-label]=\"'Remove condition'\">\n </cqa-button>\n <!-- <button type=\"button\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-8 cqa-h-8 cqa-rounded cqa-text-gray-500 hover:cqa-text-gray-700 hover:cqa-bg-gray-100 cqa-transition-colors\"\n (click)=\"removeCondition(i)\" *ngIf=\"i >= 1\"\n [attr.aria-label]=\"'Remove condition'\">\n <mat-icon class=\"cqa-text-lg cqa-text-[24px]\">close</mat-icon>\n </button> -->\n </div>\n\n <!-- Template Variables Section (shown when template is selected) -->\n <div *ngIf=\"getSelectedTemplate(i)\">\n <!-- Template Grammar Display -->\n
|
|
27405
|
+
args: [{ selector: 'cqa-step-builder-condition', host: { class: 'cqa-ui-root' }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"cqa-flex cqa-flex-col cqa-h-full cqa-bg-white cqa-px-4 cqa-py-2\">\n <!-- Header -->\n <h2 class=\"cqa-text-[12px] cqa-font-semibold cqa-text-black-100 cqa-mb-4\">\n Create Condition Step\n </h2>\n\n <div class=\"cqa-flex cqa-flex-col cqa-flex-1 cqa-overflow-y-auto\">\n <!-- Condition Builder Section -->\n <div class=\"cqa-mb-6\">\n <h3 class=\"cqa-text-sm cqa-text-[12px] cqa-font-semibold cqa-text-gray-900 cqa-mb-3\">\n Condition Builder\n </h3>\n\n <!-- Condition Rows -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-3 cqa-mb-3\">\n <ng-container *ngFor=\"let condition of conditionsFormArray.controls; let i = index; trackBy: trackByConditionIndex\">\n <div\n *ngIf=\"isConditionIf(i) || isConditionElseIf(i)\"\n class=\"cqa-flex cqa-flex-col cqa-gap-2\">\n <!-- Condition Row -->\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <!-- Condition Label -->\n <div class=\"cqa-text-[12px] cqa-font-semibold\">\n {{ getConditionLabel(i) }}\n </div>\n\n <!-- Operator Dropdown -->\n <!-- <div class=\"cqa-flex-1 cqa-max-w-[100px] cqa-text-[10px]\">\n <cqa-dynamic-select [form]=\"getConditionFormGroup(i)\" [config]=\"getOperatorConfig(i)\">\n </cqa-dynamic-select>\n </div> -->\n\n <!-- Value Template Dropdown -->\n <div class=\"cqa-flex-1 cqa-min-w-[150px] cqa-text-[10px]\">\n <cqa-dynamic-select [form]=\"getConditionFormGroup(i)\" [config]=\"getValueConfig(i)\">\n </cqa-dynamic-select>\n </div>\n\n <!-- Remove Button -->\n <cqa-button\n *ngIf=\"i >= 1\"\n variant=\"text\"\n icon=\"close\"\n iconPosition=\"start\"\n [customClass]=\"'cqa-w-full cqa-flex cqa-items-center cqa-justify-center'\"\n (click)=\"removeCondition(i)\"\n [attr.aria-label]=\"'Remove condition'\">\n </cqa-button>\n <!-- <button type=\"button\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-8 cqa-h-8 cqa-rounded cqa-text-gray-500 hover:cqa-text-gray-700 hover:cqa-bg-gray-100 cqa-transition-colors\"\n (click)=\"removeCondition(i)\" *ngIf=\"i >= 1\"\n [attr.aria-label]=\"'Remove condition'\">\n <mat-icon class=\"cqa-text-lg cqa-text-[24px]\">close</mat-icon>\n </button> -->\n </div>\n\n <!-- Template Variables Section (shown when template is selected) -->\n <div *ngIf=\"getSelectedTemplate(i)\" class=\"cqa-mt-2\">\n <!-- Template Grammar Display -->\n <div class=\"cqa-mb-4 cqa-flex cqa-items-center cqa-flex-wrap cqa-gap-1 cqa-text-sm cqa-text-gray-700\">\n <div class=\"cqa-action-format cqa-text-[12px] cqa-leading-[23px] cqa-text-black-100\"\n [innerHTML]=\"getConditionUpdatedHtmlGrammar(i) || getSelectedTemplate(i)?.htmlGrammar || getSelectedTemplate(i)?.naturalText || ''\">\n </div>\n </div>\n \n <!-- Template Variables Form Component (includes Description and Metadata) -->\n <cqa-template-variables-form\n style=\"width: 100%;\"\n [templateVariables]=\"getConditionTemplateVariables(i)\"\n [variablesForm]=\"getConditionVariablesForm(i)\"\n [metadata]=\"getConditionFormGroup(i).get('metadata')?.value || ''\"\n [description]=\"getConditionFormGroup(i).get('description')?.value || ''\"\n [elementOptions]=\"elementOptions\"\n [hasMoreElements]=\"hasMoreElements\"\n [isLoadingElements]=\"isLoadingElements\"\n [screenNameOptions]=\"screenNameOptions\"\n [hasMoreScreenNames]=\"hasMoreScreenNames\"\n [isLoadingScreenNames]=\"isLoadingScreenNames\"\n (variableValueChange)=\"onConditionVariableValueChange(i, $event.name, $event.value)\"\n (variableBooleanChange)=\"onConditionVariableBooleanChange(i, $event.name, $event.value)\"\n (metadataChange)=\"getConditionFormGroup(i).get('metadata')?.setValue($event)\"\n (descriptionChange)=\"getConditionFormGroup(i).get('description')?.setValue($event)\"\n (loadMoreElements)=\"loadMoreElements.emit()\"\n (searchElements)=\"searchElements.emit($event)\"\n (createElement)=\"createElement.emit($event)\"\n (searchScreenName)=\"searchScreenName.emit($event)\"\n (loadMoreScreenNames)=\"loadMoreScreenNames.emit($event)\"\n (createScreenNameRequest)=\"createScreenNameRequest.emit($event)\">\n </cqa-template-variables-form>\n </div>\n </div>\n </ng-container>\n </div>\n\n <!-- Add Condition Button -->\n <div class=\"cqa-border-2 cqa-border-dashed cqa-border-gray-300 cqa-rounded-lg cqa-p-1 cqa-mt-3\">\n <cqa-button\n variant=\"text\"\n icon=\"add\"\n iconPosition=\"start\"\n [customClass]=\"'cqa-w-full cqa-flex cqa-items-center cqa-justify-center'\"\n [text]=\"'Add Condition'\"\n (clicked)=\"addCondition('CONDITION_ELSE_IF')\">\n </cqa-button>\n </div>\n </div>\n\n <!-- Include ELSE Branch Section -->\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-mb-6 cqa-p-3 cqa-bg-gray-50 cqa-rounded-lg\">\n <div class=\"cqa-flex cqa-flex-col\">\n <h3 class=\"cqa-text-[14px] cqa-font-semibold cqa-text-gray-900 cqa-mb-1\">\n Include ELSE branch\n </h3>\n <p class=\"cqa-text-[12px] cqa-text-gray-600\">\n Execute alternative steps when condition is not met.\n </p>\n </div>\n <mat-slide-toggle [checked]=\"includeElse\" (change)=\"onIncludeElseChange($event.checked)\" color=\"primary\">\n </mat-slide-toggle>\n </div>\n </div>\n <!-- Action Buttons -->\n <div class=\"cqa-flex cqa-w-full cqa-gap-2 cqa-mt-auto cqa-pt-4 cqa-border-t cqa-border-gray-200\">\n <cqa-button class=\"cqa-w-1/2\" variant=\"outlined\" text=\"Cancel\" [customClass]=\"'cqa-flex-1 cqa-w-full'\"\n (clicked)=\"onCancel()\">\n </cqa-button>\n <cqa-button class=\"cqa-w-1/2\" variant=\"filled\" text=\"Create Step\" [customClass]=\"'cqa-flex-1 cqa-w-full'\"\n [disabled]=\"!conditionForm.valid\"\n (clicked)=\"onCreateStep()\">\n </cqa-button>\n </div>\n</div>", styles: [] }]
|
|
26743
27406
|
}], ctorParameters: function () { return [{ type: i1$1.FormBuilder }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { operatorOptions: [{
|
|
26744
27407
|
type: Input
|
|
26745
27408
|
}], conditionTemplates: [{
|
|
26746
27409
|
type: Input
|
|
26747
27410
|
}], setConditionTemplateVariables: [{
|
|
26748
27411
|
type: Input
|
|
27412
|
+
}], elementOptions: [{
|
|
27413
|
+
type: Input
|
|
27414
|
+
}], hasMoreElements: [{
|
|
27415
|
+
type: Input
|
|
27416
|
+
}], isLoadingElements: [{
|
|
27417
|
+
type: Input
|
|
27418
|
+
}], screenNameOptions: [{
|
|
27419
|
+
type: Input
|
|
27420
|
+
}], hasMoreScreenNames: [{
|
|
27421
|
+
type: Input
|
|
27422
|
+
}], isLoadingScreenNames: [{
|
|
27423
|
+
type: Input
|
|
26749
27424
|
}], createStep: [{
|
|
26750
27425
|
type: Output
|
|
26751
27426
|
}], cancelled: [{
|
|
26752
27427
|
type: Output
|
|
27428
|
+
}], loadMoreElements: [{
|
|
27429
|
+
type: Output
|
|
27430
|
+
}], searchElements: [{
|
|
27431
|
+
type: Output
|
|
27432
|
+
}], createElement: [{
|
|
27433
|
+
type: Output
|
|
27434
|
+
}], searchScreenName: [{
|
|
27435
|
+
type: Output
|
|
27436
|
+
}], loadMoreScreenNames: [{
|
|
27437
|
+
type: Output
|
|
27438
|
+
}], createScreenNameRequest: [{
|
|
27439
|
+
type: Output
|
|
26753
27440
|
}] } });
|
|
26754
27441
|
|
|
26755
27442
|
class StepBuilderDatabaseComponent {
|
|
@@ -30469,6 +31156,7 @@ UiKitModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "1
|
|
|
30469
31156
|
StepBuilderActionComponent,
|
|
30470
31157
|
StepBuilderLoopComponent,
|
|
30471
31158
|
ElementPopupComponent,
|
|
31159
|
+
ElementFormComponent,
|
|
30472
31160
|
StepBuilderConditionComponent,
|
|
30473
31161
|
StepBuilderDatabaseComponent,
|
|
30474
31162
|
StepBuilderAiAgentComponent,
|
|
@@ -30612,6 +31300,7 @@ UiKitModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "1
|
|
|
30612
31300
|
StepBuilderActionComponent,
|
|
30613
31301
|
StepBuilderLoopComponent,
|
|
30614
31302
|
ElementPopupComponent,
|
|
31303
|
+
ElementFormComponent,
|
|
30615
31304
|
StepBuilderConditionComponent,
|
|
30616
31305
|
StepBuilderDatabaseComponent,
|
|
30617
31306
|
StepBuilderAiAgentComponent,
|
|
@@ -30804,6 +31493,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
|
|
|
30804
31493
|
StepBuilderActionComponent,
|
|
30805
31494
|
StepBuilderLoopComponent,
|
|
30806
31495
|
ElementPopupComponent,
|
|
31496
|
+
ElementFormComponent,
|
|
30807
31497
|
StepBuilderConditionComponent,
|
|
30808
31498
|
StepBuilderDatabaseComponent,
|
|
30809
31499
|
StepBuilderAiAgentComponent,
|
|
@@ -30953,6 +31643,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
|
|
|
30953
31643
|
StepBuilderActionComponent,
|
|
30954
31644
|
StepBuilderLoopComponent,
|
|
30955
31645
|
ElementPopupComponent,
|
|
31646
|
+
ElementFormComponent,
|
|
30956
31647
|
StepBuilderConditionComponent,
|
|
30957
31648
|
StepBuilderDatabaseComponent,
|
|
30958
31649
|
StepBuilderAiAgentComponent,
|
|
@@ -31647,5 +32338,5 @@ function buildTestCaseDetailsFromApi(data, options) {
|
|
|
31647
32338
|
* Generated bundle index. Do not edit.
|
|
31648
32339
|
*/
|
|
31649
32340
|
|
|
31650
|
-
export { ADVANCED_SUBFIELDS_BY_TYPE, ADVANCED_TOGGLE_KEYS, AIActionStepComponent, AIAgentStepComponent, API_EDIT_STEP_LABELS, ActionMenuButtonComponent, AddPrerequisiteCasesSectionComponent, AiDebugAlertComponent, AiLogsWithReasoningComponent, AiReasoningComponent, ApiEditStepComponent, ApiStepComponent, AutocompleteComponent, BadgeComponent, BasicStepComponent, BreakpointsModalComponent, ButtonComponent, CUSTOM_EDIT_STEP_DATA, CUSTOM_EDIT_STEP_EDIT_IN_DEPTH, CUSTOM_EDIT_STEP_REF, CUSTOM_ELEMENT_POPUP_REF, ChartCardComponent, ColumnVisibilityComponent, CompareRunsComponent, ConditionStepComponent, ConfigurationCardComponent, ConsoleAlertComponent, CoverageModuleCardComponent, CreateStepGroupComponent, CustomEditStepComponent, CustomEditStepRef, CustomEditStepService, CustomInputComponent, CustomTextareaComponent, CustomToggleComponent, DEFAULT_METADATA_COLOR, DEFAULT_PRIORITY_COLOR_CONFIG, DEFAULT_STATUS_COLOR_CONFIG, DIALOG_DATA, DIALOG_REF, DashboardHeaderComponent, DaterangepickerComponent, DaterangepickerDirective, DbQueryExecutionItemComponent, DbVerificationStepComponent, DeleteStepsComponent, DetailDrawerComponent, DetailDrawerTabComponent, DetailDrawerTabContentDirective, DetailSidePanelComponent, DialogComponent, DialogRef, DialogService, DocumentVerificationStepComponent, DropdownButtonComponent, DynamicCellContainerDirective, DynamicCellTemplateDirective, DynamicFilterComponent, DynamicHeaderTemplateDirective, DynamicSelectFieldComponent, DynamicTableComponent, ELEMENT_POPUP_DATA, ELEMENT_POPUP_EDIT_IN_DEPTH, EMPTY_STATE_IMAGES, EMPTY_STATE_PRESETS, ElementListComponent, ElementPopupComponent, ElementPopupRef, ElementPopupService, EmptyStateComponent, ErrorModalComponent, ExecutionResultModalComponent, ExportCodeModalComponent, FailedStepCardComponent, FailedStepComponent, FailedTestCasesCardComponent, FileDownloadStepComponent, FileUploadComponent, FullTableLoaderComponent, HeatErrorMapCellComponent, InsightCardComponent, ItemListComponent, IterationsLoopComponent, JumpToStepModalComponent, LiveConversationComponent, LiveExecutionStepComponent, LoopStepComponent, MainStepCollapseComponent, MetricsCardComponent, NetworkRequestComponent, OtherButtonComponent, PRIORITY_COLORS, PaginationComponent, ProgressIndicatorComponent, ProgressTextCardComponent, RESULT_COLORS, RunHistoryCardComponent, STATUS_COLORS, STEP_DETAILS_DRAWER_DATA, STEP_DETAILS_DRAWER_REF, STEP_DETAILS_FIELDS_BY_TYPE, STEP_DETAILS_FIELD_META, SearchBarComponent, SegmentControlComponent, SelectedFiltersComponent, SelfHealAnalysisComponent, SessionChangesModalComponent, SimulatorComponent, StepBuilderActionComponent, StepBuilderAiAgentComponent, StepBuilderConditionComponent, StepBuilderCustomCodeComponent, StepBuilderDatabaseComponent, StepBuilderDocumentComponent, StepBuilderDocumentGenerationTemplateStepComponent, StepBuilderGroupComponent, StepBuilderLoopComponent, StepBuilderRecordStepComponent, StepDetailsDrawerComponent, StepDetailsDrawerRef, StepDetailsDrawerService, StepGroupComponent, StepProgressCardComponent, StepRendererComponent, StepStatusCardComponent, StepTypes, TEST_CASE_DETAILS_FIELD_MAP, TEST_CASE_DETAILS_SELECT_KEYS, TEST_DATA_MODAL_DATA, TEST_DATA_MODAL_EDIT_IN_DEPTH, TEST_DATA_MODAL_REF, TableActionToolbarComponent, TableDataLoaderComponent, TableTemplateComponent, TailwindOverlayContainer, TemplateVariablesFormComponent, TestCaseAiAgentStepComponent, TestCaseAiVerifyStepComponent, TestCaseApiStepComponent, TestCaseConditionStepComponent, TestCaseCustomCodeStepComponent, TestCaseDatabaseStepComponent, TestCaseDetailsComponent, TestCaseDetailsEditComponent, TestCaseDetailsRendererComponent, TestCaseLoopStepComponent, TestCaseNormalStepComponent, TestCaseRestoreSessionStepComponent, TestCaseScreenshotStepComponent, TestCaseScrollStepComponent, TestCaseStepGroupComponent, TestCaseUploadStepComponent, TestCaseVerifyUrlStepComponent, TestDataModalComponent, TestDataModalRef, TestDataModalService, TestDistributionCardComponent, UiKitModule, UpdatedFailedStepComponent, ViewMoreFailedStepButtonComponent, VisualComparisonComponent, VisualDifferenceModalComponent, buildTestCaseDetailsFromApi, getDynamicFieldsFromLegacyConfig, getEmptyStatePreset, getMetadataColor, getMetadataValueStyle, getStepDetailsStepType, humanizeVariableKey, isAiAgentStepConfig, isAiVerifyStepConfig, isApiStepConfig, isConditionStepConfig, isCustomCodeStepConfig, isDatabaseStepConfig, isLoopStepConfig, isNormalStepConfig, isRestoreSessionStepConfig, isScreenshotStepConfig, isScrollStepConfig, isStepGroupConfig, isUploadStepConfig, isVerifyUrlStepConfig, mapApiVariablesToDynamicFields };
|
|
32341
|
+
export { ADVANCED_SUBFIELDS_BY_TYPE, ADVANCED_TOGGLE_KEYS, AIActionStepComponent, AIAgentStepComponent, API_EDIT_STEP_LABELS, ActionMenuButtonComponent, AddPrerequisiteCasesSectionComponent, AiDebugAlertComponent, AiLogsWithReasoningComponent, AiReasoningComponent, ApiEditStepComponent, ApiStepComponent, AutocompleteComponent, BadgeComponent, BasicStepComponent, BreakpointsModalComponent, ButtonComponent, CUSTOM_EDIT_STEP_DATA, CUSTOM_EDIT_STEP_EDIT_IN_DEPTH, CUSTOM_EDIT_STEP_REF, CUSTOM_ELEMENT_POPUP_REF, ChartCardComponent, ColumnVisibilityComponent, CompareRunsComponent, ConditionStepComponent, ConfigurationCardComponent, ConsoleAlertComponent, CoverageModuleCardComponent, CreateStepGroupComponent, CustomEditStepComponent, CustomEditStepRef, CustomEditStepService, CustomInputComponent, CustomTextareaComponent, CustomToggleComponent, DEFAULT_METADATA_COLOR, DEFAULT_PRIORITY_COLOR_CONFIG, DEFAULT_STATUS_COLOR_CONFIG, DIALOG_DATA, DIALOG_REF, DashboardHeaderComponent, DaterangepickerComponent, DaterangepickerDirective, DbQueryExecutionItemComponent, DbVerificationStepComponent, DeleteStepsComponent, DetailDrawerComponent, DetailDrawerTabComponent, DetailDrawerTabContentDirective, DetailSidePanelComponent, DialogComponent, DialogRef, DialogService, DocumentVerificationStepComponent, DropdownButtonComponent, DynamicCellContainerDirective, DynamicCellTemplateDirective, DynamicFilterComponent, DynamicHeaderTemplateDirective, DynamicSelectFieldComponent, DynamicTableComponent, ELEMENT_POPUP_DATA, ELEMENT_POPUP_EDIT_IN_DEPTH, EMPTY_STATE_IMAGES, EMPTY_STATE_PRESETS, ElementFormComponent, ElementListComponent, ElementPopupComponent, ElementPopupRef, ElementPopupService, EmptyStateComponent, ErrorModalComponent, ExecutionResultModalComponent, ExportCodeModalComponent, FailedStepCardComponent, FailedStepComponent, FailedTestCasesCardComponent, FileDownloadStepComponent, FileUploadComponent, FullTableLoaderComponent, HeatErrorMapCellComponent, InsightCardComponent, ItemListComponent, IterationsLoopComponent, JumpToStepModalComponent, LiveConversationComponent, LiveExecutionStepComponent, LoopStepComponent, MainStepCollapseComponent, MetricsCardComponent, NetworkRequestComponent, OtherButtonComponent, PRIORITY_COLORS, PaginationComponent, ProgressIndicatorComponent, ProgressTextCardComponent, RESULT_COLORS, RunHistoryCardComponent, STATUS_COLORS, STEP_DETAILS_DRAWER_DATA, STEP_DETAILS_DRAWER_REF, STEP_DETAILS_FIELDS_BY_TYPE, STEP_DETAILS_FIELD_META, SearchBarComponent, SegmentControlComponent, SelectedFiltersComponent, SelfHealAnalysisComponent, SessionChangesModalComponent, SimulatorComponent, StepBuilderActionComponent, StepBuilderAiAgentComponent, StepBuilderConditionComponent, StepBuilderCustomCodeComponent, StepBuilderDatabaseComponent, StepBuilderDocumentComponent, StepBuilderDocumentGenerationTemplateStepComponent, StepBuilderGroupComponent, StepBuilderLoopComponent, StepBuilderRecordStepComponent, StepDetailsDrawerComponent, StepDetailsDrawerRef, StepDetailsDrawerService, StepGroupComponent, StepProgressCardComponent, StepRendererComponent, StepStatusCardComponent, StepTypes, TEST_CASE_DETAILS_FIELD_MAP, TEST_CASE_DETAILS_SELECT_KEYS, TEST_DATA_MODAL_DATA, TEST_DATA_MODAL_EDIT_IN_DEPTH, TEST_DATA_MODAL_REF, TableActionToolbarComponent, TableDataLoaderComponent, TableTemplateComponent, TailwindOverlayContainer, TemplateVariablesFormComponent, TestCaseAiAgentStepComponent, TestCaseAiVerifyStepComponent, TestCaseApiStepComponent, TestCaseConditionStepComponent, TestCaseCustomCodeStepComponent, TestCaseDatabaseStepComponent, TestCaseDetailsComponent, TestCaseDetailsEditComponent, TestCaseDetailsRendererComponent, TestCaseLoopStepComponent, TestCaseNormalStepComponent, TestCaseRestoreSessionStepComponent, TestCaseScreenshotStepComponent, TestCaseScrollStepComponent, TestCaseStepGroupComponent, TestCaseUploadStepComponent, TestCaseVerifyUrlStepComponent, TestDataModalComponent, TestDataModalRef, TestDataModalService, TestDistributionCardComponent, UiKitModule, UpdatedFailedStepComponent, ViewMoreFailedStepButtonComponent, VisualComparisonComponent, VisualDifferenceModalComponent, buildTestCaseDetailsFromApi, getDynamicFieldsFromLegacyConfig, getEmptyStatePreset, getMetadataColor, getMetadataValueStyle, getStepDetailsStepType, humanizeVariableKey, isAiAgentStepConfig, isAiVerifyStepConfig, isApiStepConfig, isConditionStepConfig, isCustomCodeStepConfig, isDatabaseStepConfig, isLoopStepConfig, isNormalStepConfig, isRestoreSessionStepConfig, isScreenshotStepConfig, isScrollStepConfig, isStepGroupConfig, isUploadStepConfig, isVerifyUrlStepConfig, mapApiVariablesToDynamicFields };
|
|
31651
32342
|
//# sourceMappingURL=cqa-lib-cqa-ui.mjs.map
|