@cqa-lib/cqa-ui 1.1.225 → 1.1.227
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/simulator/simulator.component.mjs +28 -45
- 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 +1118 -444
- package/fesm2015/cqa-lib-cqa-ui.mjs.map +1 -1
- package/fesm2020/cqa-lib-cqa-ui.mjs +1103 -440
- 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';
|
|
@@ -14924,13 +14924,12 @@ class SimulatorComponent {
|
|
|
14924
14924
|
this.playerState = 'paused';
|
|
14925
14925
|
this.videoPause.emit();
|
|
14926
14926
|
this.isVideoPlayingChange.emit(false);
|
|
14927
|
-
// Switch to next video and
|
|
14927
|
+
// Switch to next video and auto-play it
|
|
14928
14928
|
if (this.hasMultipleVideos && this.videoUrls && this.currentVideoIndex < this.videoUrls.length - 1) {
|
|
14929
|
-
this.currentVideoIndex
|
|
14929
|
+
const nextIndex = this.currentVideoIndex + 1;
|
|
14930
14930
|
this.enqueueOperation(() => __awaiter(this, void 0, void 0, function* () {
|
|
14931
14931
|
var _a;
|
|
14932
|
-
yield this.
|
|
14933
|
-
yield new Promise(resolve => setTimeout(resolve, 100));
|
|
14932
|
+
yield this.switchToVideoAndResetInternal(nextIndex);
|
|
14934
14933
|
if (((_a = this.vplayer) === null || _a === void 0 ? void 0 : _a.nativeElement) && this.currentVideoUrl) {
|
|
14935
14934
|
yield this.playVideoInternal();
|
|
14936
14935
|
}
|
|
@@ -15451,31 +15450,23 @@ class SimulatorComponent {
|
|
|
15451
15450
|
this.playPromise = null;
|
|
15452
15451
|
this.videoPause.emit();
|
|
15453
15452
|
this.isVideoPlayingChange.emit(false);
|
|
15454
|
-
|
|
15455
|
-
|
|
15456
|
-
|
|
15457
|
-
|
|
15458
|
-
if (resolved)
|
|
15453
|
+
const metadataLoaded = new Promise((resolve, reject) => {
|
|
15454
|
+
let settled = false;
|
|
15455
|
+
const settle = (fn) => {
|
|
15456
|
+
if (settled)
|
|
15459
15457
|
return;
|
|
15460
|
-
|
|
15458
|
+
settled = true;
|
|
15461
15459
|
video.removeEventListener('loadedmetadata', onLoadedMetadata);
|
|
15462
15460
|
video.removeEventListener('error', onError);
|
|
15461
|
+
fn();
|
|
15463
15462
|
};
|
|
15464
|
-
const onLoadedMetadata = () =>
|
|
15465
|
-
|
|
15466
|
-
|
|
15467
|
-
};
|
|
15468
|
-
const onError = () => {
|
|
15469
|
-
cleanup();
|
|
15470
|
-
reject(new Error('Failed to load video'));
|
|
15471
|
-
};
|
|
15472
|
-
setTimeout(() => {
|
|
15473
|
-
if (resolved)
|
|
15474
|
-
return;
|
|
15475
|
-
video.addEventListener('loadedmetadata', onLoadedMetadata, { once: true });
|
|
15476
|
-
video.addEventListener('error', onError, { once: true });
|
|
15477
|
-
}, 100);
|
|
15463
|
+
const onLoadedMetadata = () => settle(resolve);
|
|
15464
|
+
const onError = () => settle(() => reject(new Error('Failed to load video')));
|
|
15465
|
+
video.addEventListener('loadedmetadata', onLoadedMetadata, { once: true });
|
|
15466
|
+
video.addEventListener('error', onError, { once: true });
|
|
15478
15467
|
});
|
|
15468
|
+
this.currentVideoIndex = targetVideoIndex;
|
|
15469
|
+
yield metadataLoaded;
|
|
15479
15470
|
video.currentTime = 0;
|
|
15480
15471
|
this.progress = 0;
|
|
15481
15472
|
this.playPromise = null;
|
|
@@ -15526,31 +15517,23 @@ class SimulatorComponent {
|
|
|
15526
15517
|
this.playPromise = null;
|
|
15527
15518
|
this.videoPause.emit();
|
|
15528
15519
|
this.isVideoPlayingChange.emit(false);
|
|
15529
|
-
|
|
15530
|
-
|
|
15531
|
-
|
|
15532
|
-
|
|
15533
|
-
if (resolved)
|
|
15520
|
+
const metadataLoaded = new Promise((resolve, reject) => {
|
|
15521
|
+
let settled = false;
|
|
15522
|
+
const settle = (fn) => {
|
|
15523
|
+
if (settled)
|
|
15534
15524
|
return;
|
|
15535
|
-
|
|
15525
|
+
settled = true;
|
|
15536
15526
|
video.removeEventListener('loadedmetadata', onLoadedMetadata);
|
|
15537
15527
|
video.removeEventListener('error', onError);
|
|
15528
|
+
fn();
|
|
15538
15529
|
};
|
|
15539
|
-
const onLoadedMetadata = () =>
|
|
15540
|
-
|
|
15541
|
-
|
|
15542
|
-
};
|
|
15543
|
-
const onError = () => {
|
|
15544
|
-
cleanup();
|
|
15545
|
-
reject(new Error('Failed to load video'));
|
|
15546
|
-
};
|
|
15547
|
-
setTimeout(() => {
|
|
15548
|
-
if (resolved)
|
|
15549
|
-
return;
|
|
15550
|
-
video.addEventListener('loadedmetadata', onLoadedMetadata, { once: true });
|
|
15551
|
-
video.addEventListener('error', onError, { once: true });
|
|
15552
|
-
}, 100);
|
|
15530
|
+
const onLoadedMetadata = () => settle(resolve);
|
|
15531
|
+
const onError = () => settle(() => reject(new Error('Failed to load video')));
|
|
15532
|
+
video.addEventListener('loadedmetadata', onLoadedMetadata, { once: true });
|
|
15533
|
+
video.addEventListener('error', onError, { once: true });
|
|
15553
15534
|
});
|
|
15535
|
+
this.currentVideoIndex = targetVideoIndex;
|
|
15536
|
+
yield metadataLoaded;
|
|
15554
15537
|
const seekSeconds = relativeTimestamp / 1000;
|
|
15555
15538
|
const targetTime = Math.max(0, Math.min(seekSeconds, video.duration || seekSeconds));
|
|
15556
15539
|
yield new Promise((resolve) => {
|
|
@@ -18442,146 +18425,25 @@ class ElementPopupRef {
|
|
|
18442
18425
|
}
|
|
18443
18426
|
const CUSTOM_ELEMENT_POPUP_REF = new InjectionToken('CUSTOM_ELEMENT_POPUP_REF');
|
|
18444
18427
|
|
|
18445
|
-
class
|
|
18446
|
-
constructor() {
|
|
18447
|
-
/** Array of items to display */
|
|
18448
|
-
this.items = [];
|
|
18449
|
-
/** Key to access the title property from each item (default: 'title') */
|
|
18450
|
-
this.titleKey = 'title';
|
|
18451
|
-
/** Key to access the selector property from each item (default: 'selector') */
|
|
18452
|
-
this.selectorKey = 'selector';
|
|
18453
|
-
/** Key to access the labels array from each item (default: 'labels') */
|
|
18454
|
-
this.labelsKey = 'labels';
|
|
18455
|
-
/** Maximum height for the scrollable container (default: '200px') */
|
|
18456
|
-
this.maxHeight = '200px';
|
|
18457
|
-
/** Whether more items can be loaded */
|
|
18458
|
-
this.hasMore = false;
|
|
18459
|
-
/** Emitted when an item is clicked */
|
|
18460
|
-
this.itemClick = new EventEmitter();
|
|
18461
|
-
/** Emitted when user scrolls near the bottom and more items should be loaded */
|
|
18462
|
-
this.loadMore = new EventEmitter();
|
|
18463
|
-
/** Skip the first intersection callback (fires immediately when observe() is called) to prevent duplicate API calls on load */
|
|
18464
|
-
this.skipNextIntersection = false;
|
|
18465
|
-
}
|
|
18466
|
-
/**
|
|
18467
|
-
* Get the value from an item using the specified key
|
|
18468
|
-
*/
|
|
18469
|
-
getItemValue(item, key) {
|
|
18470
|
-
return item === null || item === void 0 ? void 0 : item[key];
|
|
18471
|
-
}
|
|
18472
|
-
/**
|
|
18473
|
-
* Handle item click
|
|
18474
|
-
*/
|
|
18475
|
-
onItemClick(item) {
|
|
18476
|
-
this.itemClick.emit(item);
|
|
18477
|
-
}
|
|
18478
|
-
ngAfterViewInit() {
|
|
18479
|
-
if (this.hasMore) {
|
|
18480
|
-
setTimeout(() => this.setupScrollObserver(), 0);
|
|
18481
|
-
}
|
|
18482
|
-
}
|
|
18483
|
-
ngOnChanges(changes) {
|
|
18484
|
-
if (changes['hasMore'] && this.hasMore && this.scrollContainer) {
|
|
18485
|
-
setTimeout(() => this.setupScrollObserver(), 0);
|
|
18486
|
-
}
|
|
18487
|
-
}
|
|
18488
|
-
ngOnDestroy() {
|
|
18489
|
-
if (this.scrollObserver) {
|
|
18490
|
-
this.scrollObserver.disconnect();
|
|
18491
|
-
}
|
|
18492
|
-
}
|
|
18493
|
-
setupScrollObserver() {
|
|
18494
|
-
if (!this.hasMore || !this.scrollContainer) {
|
|
18495
|
-
return;
|
|
18496
|
-
}
|
|
18497
|
-
// Find the sentinel element (loading indicator)
|
|
18498
|
-
const sentinel = this.scrollContainer.nativeElement.querySelector('.load-more-sentinel');
|
|
18499
|
-
if (!sentinel) {
|
|
18500
|
-
return;
|
|
18501
|
-
}
|
|
18502
|
-
// Disconnect existing observer if any
|
|
18503
|
-
if (this.scrollObserver) {
|
|
18504
|
-
this.scrollObserver.disconnect();
|
|
18505
|
-
}
|
|
18506
|
-
// Skip the first intersection callback - it fires immediately when observe() is called
|
|
18507
|
-
// if the sentinel is already in view, causing duplicate API calls (page 0 + page 1) on load
|
|
18508
|
-
this.skipNextIntersection = true;
|
|
18509
|
-
// Create IntersectionObserver to detect when sentinel comes into view
|
|
18510
|
-
this.scrollObserver = new IntersectionObserver((entries) => {
|
|
18511
|
-
for (const entry of entries) {
|
|
18512
|
-
if (entry.isIntersecting && this.hasMore) {
|
|
18513
|
-
if (this.skipNextIntersection) {
|
|
18514
|
-
this.skipNextIntersection = false;
|
|
18515
|
-
return;
|
|
18516
|
-
}
|
|
18517
|
-
this.loadMore.emit();
|
|
18518
|
-
}
|
|
18519
|
-
}
|
|
18520
|
-
}, {
|
|
18521
|
-
root: this.scrollContainer.nativeElement,
|
|
18522
|
-
rootMargin: '50px',
|
|
18523
|
-
threshold: 0.1
|
|
18524
|
-
});
|
|
18525
|
-
this.scrollObserver.observe(sentinel);
|
|
18526
|
-
}
|
|
18527
|
-
}
|
|
18528
|
-
ElementListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: ElementListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
18529
|
-
ElementListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: ElementListComponent, selector: "cqa-element-list", inputs: { items: "items", titleKey: "titleKey", selectorKey: "selectorKey", labelsKey: "labelsKey", maxHeight: "maxHeight", hasMore: "hasMore" }, outputs: { itemClick: "itemClick", loadMore: "loadMore" }, host: { classAttribute: "cqa-ui-root" }, viewQueries: [{ propertyName: "scrollContainer", first: true, predicate: ["scrollContainer"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div \n #scrollContainer\n class=\"cqa-max-h-[200px] cqa-overflow-y-auto cqa-scrollbar-thin cqa-scrollbar-track-transparent cqa-scrollbar-thumb-[#E5E7EB] cqa-scrollbar-thumb-rounded-full cqa-scrollbar-thumb-hover:cqa-bg-[#D1D5DB] cqa-flex cqa-flex-col cqa-gap-2\"\n [style.max-height]=\"maxHeight\">\n <div *ngFor=\"let item of items\" (click)=\"onItemClick(item)\">\n <div class=\"hover:cqa-bg-[#F5F5F5] cqa-flex cqa-items-center cqa-justify-between cqa-border cqa-border-[#FDE68A]\n cqa-rounded-lg cqa-p-3 cqa-cursor-pointer cqa-gap-1\" style=\"word-break: break-word;\">\n <div>\n <h6 class=\"cqa-text-[12px] cqa-leading-[100%] cqa-font-[400] cqa-text-[#171717]\">\n {{ getItemValue(item, titleKey) }}\n </h6>\n <span class=\"cqa-text-[10px] cqa-leading-[100%] cqa-text-[#6B7280]\">\n {{ getItemValue(item, selectorKey) }}\n </span>\n </div>\n <div class=\"cqa-flex cqa-gap-1\">\n <span \n *ngFor=\"let tag of getItemValue(item, labelsKey)\" \n class=\"cqa-text-[11px] cqa-text-[#4b74ec] cqa-rounded-full cqa-px-2 cqa-bg-[#eff6ff] cqa-border cqa-border-solid cqa-border-[#c8e0ff]\">\n {{ tag }}\n </span>\n </div>\n </div>\n </div>\n <!-- No elements found message -->\n <div *ngIf=\"items.length === 0 && !hasMore\" class=\"cqa-flex cqa-justify-center cqa-items-center cqa-py-4 cqa-text-[12px] cqa-text-[#6B7280]\">\n No elements found\n </div>\n <!-- Sentinel element for infinite scroll -->\n <div *ngIf=\"hasMore\" class=\"load-more-sentinel cqa-flex cqa-flex-col cqa-items-center cqa-justify-center cqa-gap-3 cqa-py-2\">\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-[12px] cqa-text-[#6B7280]\">{{ items.length === 0 ? 'Loading...' : 'Loading more...' }}</span>\n </div>\n</div>\n\n", directives: [{ type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
18530
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: ElementListComponent, decorators: [{
|
|
18531
|
-
type: Component,
|
|
18532
|
-
args: [{ selector: 'cqa-element-list', host: { class: 'cqa-ui-root' }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div \n #scrollContainer\n class=\"cqa-max-h-[200px] cqa-overflow-y-auto cqa-scrollbar-thin cqa-scrollbar-track-transparent cqa-scrollbar-thumb-[#E5E7EB] cqa-scrollbar-thumb-rounded-full cqa-scrollbar-thumb-hover:cqa-bg-[#D1D5DB] cqa-flex cqa-flex-col cqa-gap-2\"\n [style.max-height]=\"maxHeight\">\n <div *ngFor=\"let item of items\" (click)=\"onItemClick(item)\">\n <div class=\"hover:cqa-bg-[#F5F5F5] cqa-flex cqa-items-center cqa-justify-between cqa-border cqa-border-[#FDE68A]\n cqa-rounded-lg cqa-p-3 cqa-cursor-pointer cqa-gap-1\" style=\"word-break: break-word;\">\n <div>\n <h6 class=\"cqa-text-[12px] cqa-leading-[100%] cqa-font-[400] cqa-text-[#171717]\">\n {{ getItemValue(item, titleKey) }}\n </h6>\n <span class=\"cqa-text-[10px] cqa-leading-[100%] cqa-text-[#6B7280]\">\n {{ getItemValue(item, selectorKey) }}\n </span>\n </div>\n <div class=\"cqa-flex cqa-gap-1\">\n <span \n *ngFor=\"let tag of getItemValue(item, labelsKey)\" \n class=\"cqa-text-[11px] cqa-text-[#4b74ec] cqa-rounded-full cqa-px-2 cqa-bg-[#eff6ff] cqa-border cqa-border-solid cqa-border-[#c8e0ff]\">\n {{ tag }}\n </span>\n </div>\n </div>\n </div>\n <!-- No elements found message -->\n <div *ngIf=\"items.length === 0 && !hasMore\" class=\"cqa-flex cqa-justify-center cqa-items-center cqa-py-4 cqa-text-[12px] cqa-text-[#6B7280]\">\n No elements found\n </div>\n <!-- Sentinel element for infinite scroll -->\n <div *ngIf=\"hasMore\" class=\"load-more-sentinel cqa-flex cqa-flex-col cqa-items-center cqa-justify-center cqa-gap-3 cqa-py-2\">\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-[12px] cqa-text-[#6B7280]\">{{ items.length === 0 ? 'Loading...' : 'Loading more...' }}</span>\n </div>\n</div>\n\n" }]
|
|
18533
|
-
}], propDecorators: { scrollContainer: [{
|
|
18534
|
-
type: ViewChild,
|
|
18535
|
-
args: ['scrollContainer', { static: false }]
|
|
18536
|
-
}], items: [{
|
|
18537
|
-
type: Input
|
|
18538
|
-
}], titleKey: [{
|
|
18539
|
-
type: Input
|
|
18540
|
-
}], selectorKey: [{
|
|
18541
|
-
type: Input
|
|
18542
|
-
}], labelsKey: [{
|
|
18543
|
-
type: Input
|
|
18544
|
-
}], maxHeight: [{
|
|
18545
|
-
type: Input
|
|
18546
|
-
}], hasMore: [{
|
|
18547
|
-
type: Input
|
|
18548
|
-
}], itemClick: [{
|
|
18549
|
-
type: Output
|
|
18550
|
-
}], loadMore: [{
|
|
18551
|
-
type: Output
|
|
18552
|
-
}] } });
|
|
18553
|
-
|
|
18554
|
-
class ElementPopupComponent {
|
|
18555
|
-
constructor(ref, data, fb, cdr) {
|
|
18556
|
-
this.ref = ref;
|
|
18428
|
+
class ElementFormComponent {
|
|
18429
|
+
constructor(fb, cdr) {
|
|
18557
18430
|
this.cdr = cdr;
|
|
18558
|
-
|
|
18559
|
-
this.helpUrl = '';
|
|
18560
|
-
this.labels = [];
|
|
18431
|
+
/** Current element data (for edit mode) */
|
|
18561
18432
|
this.element = { title: '', selector: '', labels: [] };
|
|
18562
|
-
this.elements = [];
|
|
18563
|
-
this.enableForm = false;
|
|
18564
|
-
this.isOnRecord = false;
|
|
18565
|
-
this.hasMoreElements = false;
|
|
18566
18433
|
/** Screen name options for autocomplete (from API) */
|
|
18567
18434
|
this.screenNameOptions = [];
|
|
18568
18435
|
/** Whether more screen names are available for infinite scroll */
|
|
18569
18436
|
this.hasMoreScreenNames = false;
|
|
18570
18437
|
/** True while parent is loading screen names (search or load more) */
|
|
18571
18438
|
this.isLoadingScreenNames = false;
|
|
18572
|
-
/** Suggested tags from API for labels field */
|
|
18573
|
-
this.suggestedTags = [];
|
|
18574
18439
|
/** True while parent is fetching latest element data for edit (shows loading state) */
|
|
18575
18440
|
this.isElementLoading = false;
|
|
18576
|
-
/**
|
|
18577
|
-
this.
|
|
18578
|
-
|
|
18579
|
-
this.
|
|
18580
|
-
|
|
18581
|
-
this.
|
|
18582
|
-
/** Emitted when user clicks on a recent searched item */
|
|
18583
|
-
this.recentItemClick = new EventEmitter();
|
|
18584
|
-
this.loadMoreElements = new EventEmitter();
|
|
18441
|
+
/** Whether we're in edit mode */
|
|
18442
|
+
this.isEditMode = false;
|
|
18443
|
+
/** Whether we're in create mode */
|
|
18444
|
+
this.isCreateMode = false;
|
|
18445
|
+
/** Whether edit in depth is available */
|
|
18446
|
+
this.isEditInDepthAvailable = true;
|
|
18585
18447
|
/** Emitted when user creates a new element (parent should call API) */
|
|
18586
18448
|
this.createElement = new EventEmitter();
|
|
18587
18449
|
/** Emitted when user updates an element (parent should call API) */
|
|
@@ -18592,26 +18454,16 @@ class ElementPopupComponent {
|
|
|
18592
18454
|
this.searchScreenName = new EventEmitter();
|
|
18593
18455
|
/** Emitted when user scrolls to load more screen names (passes current search query) */
|
|
18594
18456
|
this.loadMoreScreenNames = new EventEmitter();
|
|
18595
|
-
/** Emitted when
|
|
18596
|
-
this.
|
|
18597
|
-
/** Emitted when user
|
|
18598
|
-
this.
|
|
18599
|
-
/** Emitted when user clicks Record - parent should check extension and call installPlugin or openSidePanelAndListSteps */
|
|
18600
|
-
this.toggleRecord = new EventEmitter();
|
|
18601
|
-
this.helpTooltipText = 'Not sure what to do? Click to go to our detailed step creation documentation';
|
|
18602
|
-
this.showHelpTooltip = false;
|
|
18603
|
-
this.isEditMode = false;
|
|
18604
|
-
/** Whether we're in create mode (no elementId) */
|
|
18605
|
-
this.isCreateMode = false;
|
|
18457
|
+
/** Emitted when user clicks "Select from Element list" or "Cancel" */
|
|
18458
|
+
this.cancel = new EventEmitter();
|
|
18459
|
+
/** Emitted when user clicks "Edit in depth" */
|
|
18460
|
+
this.editInDepth = new EventEmitter();
|
|
18606
18461
|
/** Labels (tags) as string array for multi-tag input */
|
|
18607
18462
|
this.formLabels = [];
|
|
18608
18463
|
/** Current tag input value */
|
|
18609
18464
|
this.tagInputValue = '';
|
|
18610
|
-
/** Current search input value (bound to search bar) */
|
|
18611
|
-
this.searchValue = '';
|
|
18612
18465
|
/** Whether we're saving (disable buttons) */
|
|
18613
18466
|
this.saving = false;
|
|
18614
|
-
this.injectedData = data;
|
|
18615
18467
|
this.fb = fb || new FormBuilder();
|
|
18616
18468
|
this.initializeForm();
|
|
18617
18469
|
}
|
|
@@ -18619,31 +18471,19 @@ class ElementPopupComponent {
|
|
|
18619
18471
|
if (changes['screenNameOptions'] || changes['hasMoreScreenNames'] || changes['isLoadingScreenNames']) {
|
|
18620
18472
|
this.updateScreenNameSelectConfig();
|
|
18621
18473
|
}
|
|
18622
|
-
if ((changes['element'] || changes['elementId']) && this.
|
|
18623
|
-
|
|
18624
|
-
|
|
18625
|
-
|
|
18626
|
-
|
|
18627
|
-
else {
|
|
18628
|
-
this.isCreateMode = true;
|
|
18629
|
-
this.isEditMode = false;
|
|
18630
|
-
}
|
|
18474
|
+
if ((changes['element'] || changes['elementId']) && this.elementId) {
|
|
18475
|
+
this.populateFormForEdit();
|
|
18476
|
+
}
|
|
18477
|
+
else if (changes['element'] && !this.elementId && this.isCreateMode) {
|
|
18478
|
+
this.populateFormForCreateWithElement();
|
|
18631
18479
|
}
|
|
18632
18480
|
}
|
|
18633
18481
|
ngOnInit() {
|
|
18634
|
-
|
|
18635
|
-
|
|
18636
|
-
|
|
18637
|
-
|
|
18638
|
-
|
|
18639
|
-
this.helpUrl = (_b = this.injectedData.helpUrl) !== null && _b !== void 0 ? _b : '';
|
|
18640
|
-
if (this.labels.length === 0)
|
|
18641
|
-
this.labels = (_c = this.injectedData.labels) !== null && _c !== void 0 ? _c : [];
|
|
18642
|
-
if (this.elements.length === 0)
|
|
18643
|
-
this.elements = (_d = this.injectedData.elements) !== null && _d !== void 0 ? _d : [];
|
|
18644
|
-
if (!this.element || !this.element.title) {
|
|
18645
|
-
this.element = (_e = this.injectedData.element) !== null && _e !== void 0 ? _e : { title: '', selector: '', labels: [] };
|
|
18646
|
-
}
|
|
18482
|
+
if (this.elementId) {
|
|
18483
|
+
this.populateFormForEdit();
|
|
18484
|
+
}
|
|
18485
|
+
else if (this.isCreateMode && this.element) {
|
|
18486
|
+
this.populateFormForCreateWithElement();
|
|
18647
18487
|
}
|
|
18648
18488
|
}
|
|
18649
18489
|
initializeForm() {
|
|
@@ -18729,18 +18569,6 @@ class ElementPopupComponent {
|
|
|
18729
18569
|
}
|
|
18730
18570
|
(_d = this.cdr) === null || _d === void 0 ? void 0 : _d.markForCheck();
|
|
18731
18571
|
}
|
|
18732
|
-
resetForm() {
|
|
18733
|
-
this.isEditMode = false;
|
|
18734
|
-
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
|
-
}
|
|
18744
18572
|
/** Called by parent when a new screen name was created (so we can set the selected value) */
|
|
18745
18573
|
setCreatedScreenName(opt) {
|
|
18746
18574
|
var _a, _b;
|
|
@@ -18782,8 +18610,6 @@ class ElementPopupComponent {
|
|
|
18782
18610
|
onCreateOrUpdateSuccess() {
|
|
18783
18611
|
var _a;
|
|
18784
18612
|
this.saving = false;
|
|
18785
|
-
this.enableForm = false;
|
|
18786
|
-
this.resetForm();
|
|
18787
18613
|
(_a = this.cdr) === null || _a === void 0 ? void 0 : _a.markForCheck();
|
|
18788
18614
|
}
|
|
18789
18615
|
onCreateOrUpdateError() {
|
|
@@ -18791,50 +18617,350 @@ class ElementPopupComponent {
|
|
|
18791
18617
|
this.saving = false;
|
|
18792
18618
|
(_a = this.cdr) === null || _a === void 0 ? void 0 : _a.markForCheck();
|
|
18793
18619
|
}
|
|
18794
|
-
|
|
18620
|
+
onCancel() {
|
|
18621
|
+
this.cancel.emit();
|
|
18622
|
+
}
|
|
18623
|
+
onEditInDepth(event) {
|
|
18624
|
+
event.preventDefault();
|
|
18625
|
+
this.editInDepth.emit();
|
|
18626
|
+
}
|
|
18627
|
+
getFormControl(controlName) {
|
|
18628
|
+
return this.form.get(controlName);
|
|
18629
|
+
}
|
|
18630
|
+
getFormControlValue(controlName) {
|
|
18795
18631
|
var _a;
|
|
18796
|
-
|
|
18797
|
-
// If no elementId, go to create mode instead of edit mode
|
|
18798
|
-
if (!this.elementId) {
|
|
18799
|
-
this.isCreateMode = true;
|
|
18800
|
-
this.isEditMode = false;
|
|
18801
|
-
// Patch form with current element values when Edit clicked without elementId
|
|
18802
|
-
this.populateFormForCreateWithElement();
|
|
18803
|
-
this.formOpenRequest.emit({ mode: 'create' });
|
|
18804
|
-
}
|
|
18805
|
-
else {
|
|
18806
|
-
// Has elementId, go to edit mode
|
|
18807
|
-
this.isCreateMode = false;
|
|
18808
|
-
this.isEditMode = true;
|
|
18809
|
-
this.formOpenRequest.emit({ mode: 'edit', elementId: this.elementId });
|
|
18810
|
-
}
|
|
18811
|
-
}
|
|
18812
|
-
else {
|
|
18813
|
-
// Closing form - reset everything
|
|
18814
|
-
// If in create mode, reset labels when going back to element list
|
|
18815
|
-
if (this.isCreateMode) {
|
|
18816
|
-
this.labels = [];
|
|
18817
|
-
}
|
|
18818
|
-
this.resetForm();
|
|
18819
|
-
this.isCreateMode = false;
|
|
18820
|
-
}
|
|
18821
|
-
this.enableForm = !this.enableForm;
|
|
18822
|
-
(_a = this.cdr) === null || _a === void 0 ? void 0 : _a.markForCheck();
|
|
18632
|
+
return ((_a = this.form.get(controlName)) === null || _a === void 0 ? void 0 : _a.value) || '';
|
|
18823
18633
|
}
|
|
18824
|
-
|
|
18634
|
+
onFormControlChange(controlName, value) {
|
|
18825
18635
|
var _a;
|
|
18826
|
-
this.
|
|
18827
|
-
this.isEditMode = false;
|
|
18828
|
-
this.resetForm();
|
|
18829
|
-
this.enableForm = true;
|
|
18830
|
-
this.formOpenRequest.emit({ mode: 'create' });
|
|
18636
|
+
this.form.patchValue({ [controlName]: value });
|
|
18831
18637
|
(_a = this.cdr) === null || _a === void 0 ? void 0 : _a.markForCheck();
|
|
18832
18638
|
}
|
|
18833
|
-
|
|
18834
|
-
|
|
18835
|
-
|
|
18836
|
-
|
|
18837
|
-
|
|
18639
|
+
/** Add a tag (label) */
|
|
18640
|
+
addTag(tag) {
|
|
18641
|
+
var _a;
|
|
18642
|
+
const t = (tag || this.tagInputValue || '').trim();
|
|
18643
|
+
if (t && !this.formLabels.includes(t)) {
|
|
18644
|
+
this.formLabels = [...this.formLabels, t];
|
|
18645
|
+
this.tagInputValue = '';
|
|
18646
|
+
(_a = this.cdr) === null || _a === void 0 ? void 0 : _a.markForCheck();
|
|
18647
|
+
}
|
|
18648
|
+
}
|
|
18649
|
+
removeTag(tag) {
|
|
18650
|
+
var _a;
|
|
18651
|
+
this.formLabels = this.formLabels.filter((l) => l !== tag);
|
|
18652
|
+
(_a = this.cdr) === null || _a === void 0 ? void 0 : _a.markForCheck();
|
|
18653
|
+
}
|
|
18654
|
+
onTagInputKeydown(event) {
|
|
18655
|
+
if (event.key === 'Enter' || event.key === ',') {
|
|
18656
|
+
event.preventDefault();
|
|
18657
|
+
this.addTag();
|
|
18658
|
+
}
|
|
18659
|
+
}
|
|
18660
|
+
}
|
|
18661
|
+
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 });
|
|
18662
|
+
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 });
|
|
18663
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: ElementFormComponent, decorators: [{
|
|
18664
|
+
type: Component,
|
|
18665
|
+
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" }]
|
|
18666
|
+
}], ctorParameters: function () {
|
|
18667
|
+
return [{ type: i1$1.FormBuilder, decorators: [{
|
|
18668
|
+
type: Optional
|
|
18669
|
+
}] }, { type: i0.ChangeDetectorRef, decorators: [{
|
|
18670
|
+
type: Optional
|
|
18671
|
+
}] }];
|
|
18672
|
+
}, propDecorators: { elementId: [{
|
|
18673
|
+
type: Input
|
|
18674
|
+
}], element: [{
|
|
18675
|
+
type: Input
|
|
18676
|
+
}], screenNameOptions: [{
|
|
18677
|
+
type: Input
|
|
18678
|
+
}], hasMoreScreenNames: [{
|
|
18679
|
+
type: Input
|
|
18680
|
+
}], isLoadingScreenNames: [{
|
|
18681
|
+
type: Input
|
|
18682
|
+
}], isElementLoading: [{
|
|
18683
|
+
type: Input
|
|
18684
|
+
}], isEditMode: [{
|
|
18685
|
+
type: Input
|
|
18686
|
+
}], isCreateMode: [{
|
|
18687
|
+
type: Input
|
|
18688
|
+
}], isEditInDepthAvailable: [{
|
|
18689
|
+
type: Input
|
|
18690
|
+
}], createElement: [{
|
|
18691
|
+
type: Output
|
|
18692
|
+
}], updateElement: [{
|
|
18693
|
+
type: Output
|
|
18694
|
+
}], createScreenNameRequest: [{
|
|
18695
|
+
type: Output
|
|
18696
|
+
}], searchScreenName: [{
|
|
18697
|
+
type: Output
|
|
18698
|
+
}], loadMoreScreenNames: [{
|
|
18699
|
+
type: Output
|
|
18700
|
+
}], cancel: [{
|
|
18701
|
+
type: Output
|
|
18702
|
+
}], editInDepth: [{
|
|
18703
|
+
type: Output
|
|
18704
|
+
}] } });
|
|
18705
|
+
|
|
18706
|
+
class ElementListComponent {
|
|
18707
|
+
constructor() {
|
|
18708
|
+
/** Array of items to display */
|
|
18709
|
+
this.items = [];
|
|
18710
|
+
/** Key to access the title property from each item (default: 'title') */
|
|
18711
|
+
this.titleKey = 'title';
|
|
18712
|
+
/** Key to access the selector property from each item (default: 'selector') */
|
|
18713
|
+
this.selectorKey = 'selector';
|
|
18714
|
+
/** Key to access the labels array from each item (default: 'labels') */
|
|
18715
|
+
this.labelsKey = 'labels';
|
|
18716
|
+
/** Maximum height for the scrollable container (default: '200px') */
|
|
18717
|
+
this.maxHeight = '200px';
|
|
18718
|
+
/** Whether more items can be loaded */
|
|
18719
|
+
this.hasMore = false;
|
|
18720
|
+
/** Emitted when an item is clicked */
|
|
18721
|
+
this.itemClick = new EventEmitter();
|
|
18722
|
+
/** Emitted when user scrolls near the bottom and more items should be loaded */
|
|
18723
|
+
this.loadMore = new EventEmitter();
|
|
18724
|
+
/** Skip the first intersection callback (fires immediately when observe() is called) to prevent duplicate API calls on load */
|
|
18725
|
+
this.skipNextIntersection = false;
|
|
18726
|
+
}
|
|
18727
|
+
/**
|
|
18728
|
+
* Get the value from an item using the specified key
|
|
18729
|
+
*/
|
|
18730
|
+
getItemValue(item, key) {
|
|
18731
|
+
return item === null || item === void 0 ? void 0 : item[key];
|
|
18732
|
+
}
|
|
18733
|
+
/**
|
|
18734
|
+
* Handle item click
|
|
18735
|
+
*/
|
|
18736
|
+
onItemClick(item) {
|
|
18737
|
+
this.itemClick.emit(item);
|
|
18738
|
+
}
|
|
18739
|
+
ngAfterViewInit() {
|
|
18740
|
+
if (this.hasMore) {
|
|
18741
|
+
setTimeout(() => this.setupScrollObserver(), 0);
|
|
18742
|
+
}
|
|
18743
|
+
}
|
|
18744
|
+
ngOnChanges(changes) {
|
|
18745
|
+
if (changes['hasMore'] && this.hasMore && this.scrollContainer) {
|
|
18746
|
+
setTimeout(() => this.setupScrollObserver(), 0);
|
|
18747
|
+
}
|
|
18748
|
+
}
|
|
18749
|
+
ngOnDestroy() {
|
|
18750
|
+
if (this.scrollObserver) {
|
|
18751
|
+
this.scrollObserver.disconnect();
|
|
18752
|
+
}
|
|
18753
|
+
}
|
|
18754
|
+
setupScrollObserver() {
|
|
18755
|
+
if (!this.hasMore || !this.scrollContainer) {
|
|
18756
|
+
return;
|
|
18757
|
+
}
|
|
18758
|
+
// Find the sentinel element (loading indicator)
|
|
18759
|
+
const sentinel = this.scrollContainer.nativeElement.querySelector('.load-more-sentinel');
|
|
18760
|
+
if (!sentinel) {
|
|
18761
|
+
return;
|
|
18762
|
+
}
|
|
18763
|
+
// Disconnect existing observer if any
|
|
18764
|
+
if (this.scrollObserver) {
|
|
18765
|
+
this.scrollObserver.disconnect();
|
|
18766
|
+
}
|
|
18767
|
+
// Skip the first intersection callback - it fires immediately when observe() is called
|
|
18768
|
+
// if the sentinel is already in view, causing duplicate API calls (page 0 + page 1) on load
|
|
18769
|
+
this.skipNextIntersection = true;
|
|
18770
|
+
// Create IntersectionObserver to detect when sentinel comes into view
|
|
18771
|
+
this.scrollObserver = new IntersectionObserver((entries) => {
|
|
18772
|
+
for (const entry of entries) {
|
|
18773
|
+
if (entry.isIntersecting && this.hasMore) {
|
|
18774
|
+
if (this.skipNextIntersection) {
|
|
18775
|
+
this.skipNextIntersection = false;
|
|
18776
|
+
return;
|
|
18777
|
+
}
|
|
18778
|
+
this.loadMore.emit();
|
|
18779
|
+
}
|
|
18780
|
+
}
|
|
18781
|
+
}, {
|
|
18782
|
+
root: this.scrollContainer.nativeElement,
|
|
18783
|
+
rootMargin: '50px',
|
|
18784
|
+
threshold: 0.1
|
|
18785
|
+
});
|
|
18786
|
+
this.scrollObserver.observe(sentinel);
|
|
18787
|
+
}
|
|
18788
|
+
}
|
|
18789
|
+
ElementListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: ElementListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
18790
|
+
ElementListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: ElementListComponent, selector: "cqa-element-list", inputs: { items: "items", titleKey: "titleKey", selectorKey: "selectorKey", labelsKey: "labelsKey", maxHeight: "maxHeight", hasMore: "hasMore" }, outputs: { itemClick: "itemClick", loadMore: "loadMore" }, host: { classAttribute: "cqa-ui-root" }, viewQueries: [{ propertyName: "scrollContainer", first: true, predicate: ["scrollContainer"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div \n #scrollContainer\n class=\"cqa-max-h-[200px] cqa-overflow-y-auto cqa-scrollbar-thin cqa-scrollbar-track-transparent cqa-scrollbar-thumb-[#E5E7EB] cqa-scrollbar-thumb-rounded-full cqa-scrollbar-thumb-hover:cqa-bg-[#D1D5DB] cqa-flex cqa-flex-col cqa-gap-2\"\n [style.max-height]=\"maxHeight\">\n <div *ngFor=\"let item of items\" (click)=\"onItemClick(item)\">\n <div class=\"hover:cqa-bg-[#F5F5F5] cqa-flex cqa-items-center cqa-justify-between cqa-border cqa-border-[#FDE68A]\n cqa-rounded-lg cqa-p-3 cqa-cursor-pointer cqa-gap-1\" style=\"word-break: break-word;\">\n <div>\n <h6 class=\"cqa-text-[12px] cqa-leading-[100%] cqa-font-[400] cqa-text-[#171717]\">\n {{ getItemValue(item, titleKey) }}\n </h6>\n <span class=\"cqa-text-[10px] cqa-leading-[100%] cqa-text-[#6B7280]\">\n {{ getItemValue(item, selectorKey) }}\n </span>\n </div>\n <div class=\"cqa-flex cqa-gap-1\">\n <span \n *ngFor=\"let tag of getItemValue(item, labelsKey)\" \n class=\"cqa-text-[11px] cqa-text-[#4b74ec] cqa-rounded-full cqa-px-2 cqa-bg-[#eff6ff] cqa-border cqa-border-solid cqa-border-[#c8e0ff]\">\n {{ tag }}\n </span>\n </div>\n </div>\n </div>\n <!-- No elements found message -->\n <div *ngIf=\"items.length === 0 && !hasMore\" class=\"cqa-flex cqa-justify-center cqa-items-center cqa-py-4 cqa-text-[12px] cqa-text-[#6B7280]\">\n No elements found\n </div>\n <!-- Sentinel element for infinite scroll -->\n <div *ngIf=\"hasMore\" class=\"load-more-sentinel cqa-flex cqa-flex-col cqa-items-center cqa-justify-center cqa-gap-3 cqa-py-2\">\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-[12px] cqa-text-[#6B7280]\">{{ items.length === 0 ? 'Loading...' : 'Loading more...' }}</span>\n </div>\n</div>\n\n", directives: [{ type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
18791
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: ElementListComponent, decorators: [{
|
|
18792
|
+
type: Component,
|
|
18793
|
+
args: [{ selector: 'cqa-element-list', host: { class: 'cqa-ui-root' }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div \n #scrollContainer\n class=\"cqa-max-h-[200px] cqa-overflow-y-auto cqa-scrollbar-thin cqa-scrollbar-track-transparent cqa-scrollbar-thumb-[#E5E7EB] cqa-scrollbar-thumb-rounded-full cqa-scrollbar-thumb-hover:cqa-bg-[#D1D5DB] cqa-flex cqa-flex-col cqa-gap-2\"\n [style.max-height]=\"maxHeight\">\n <div *ngFor=\"let item of items\" (click)=\"onItemClick(item)\">\n <div class=\"hover:cqa-bg-[#F5F5F5] cqa-flex cqa-items-center cqa-justify-between cqa-border cqa-border-[#FDE68A]\n cqa-rounded-lg cqa-p-3 cqa-cursor-pointer cqa-gap-1\" style=\"word-break: break-word;\">\n <div>\n <h6 class=\"cqa-text-[12px] cqa-leading-[100%] cqa-font-[400] cqa-text-[#171717]\">\n {{ getItemValue(item, titleKey) }}\n </h6>\n <span class=\"cqa-text-[10px] cqa-leading-[100%] cqa-text-[#6B7280]\">\n {{ getItemValue(item, selectorKey) }}\n </span>\n </div>\n <div class=\"cqa-flex cqa-gap-1\">\n <span \n *ngFor=\"let tag of getItemValue(item, labelsKey)\" \n class=\"cqa-text-[11px] cqa-text-[#4b74ec] cqa-rounded-full cqa-px-2 cqa-bg-[#eff6ff] cqa-border cqa-border-solid cqa-border-[#c8e0ff]\">\n {{ tag }}\n </span>\n </div>\n </div>\n </div>\n <!-- No elements found message -->\n <div *ngIf=\"items.length === 0 && !hasMore\" class=\"cqa-flex cqa-justify-center cqa-items-center cqa-py-4 cqa-text-[12px] cqa-text-[#6B7280]\">\n No elements found\n </div>\n <!-- Sentinel element for infinite scroll -->\n <div *ngIf=\"hasMore\" class=\"load-more-sentinel cqa-flex cqa-flex-col cqa-items-center cqa-justify-center cqa-gap-3 cqa-py-2\">\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-[12px] cqa-text-[#6B7280]\">{{ items.length === 0 ? 'Loading...' : 'Loading more...' }}</span>\n </div>\n</div>\n\n" }]
|
|
18794
|
+
}], propDecorators: { scrollContainer: [{
|
|
18795
|
+
type: ViewChild,
|
|
18796
|
+
args: ['scrollContainer', { static: false }]
|
|
18797
|
+
}], items: [{
|
|
18798
|
+
type: Input
|
|
18799
|
+
}], titleKey: [{
|
|
18800
|
+
type: Input
|
|
18801
|
+
}], selectorKey: [{
|
|
18802
|
+
type: Input
|
|
18803
|
+
}], labelsKey: [{
|
|
18804
|
+
type: Input
|
|
18805
|
+
}], maxHeight: [{
|
|
18806
|
+
type: Input
|
|
18807
|
+
}], hasMore: [{
|
|
18808
|
+
type: Input
|
|
18809
|
+
}], itemClick: [{
|
|
18810
|
+
type: Output
|
|
18811
|
+
}], loadMore: [{
|
|
18812
|
+
type: Output
|
|
18813
|
+
}] } });
|
|
18814
|
+
|
|
18815
|
+
class ElementPopupComponent {
|
|
18816
|
+
constructor(ref, data, cdr) {
|
|
18817
|
+
this.ref = ref;
|
|
18818
|
+
this.cdr = cdr;
|
|
18819
|
+
this.value = '';
|
|
18820
|
+
this.helpUrl = '';
|
|
18821
|
+
this.labels = [];
|
|
18822
|
+
this.element = { title: '', selector: '', labels: [] };
|
|
18823
|
+
this.elements = [];
|
|
18824
|
+
this.enableForm = false;
|
|
18825
|
+
this.isOnRecord = false;
|
|
18826
|
+
this.hasMoreElements = false;
|
|
18827
|
+
/** Screen name options for autocomplete (from API) */
|
|
18828
|
+
this.screenNameOptions = [];
|
|
18829
|
+
/** Whether more screen names are available for infinite scroll */
|
|
18830
|
+
this.hasMoreScreenNames = false;
|
|
18831
|
+
/** True while parent is loading screen names (search or load more) */
|
|
18832
|
+
this.isLoadingScreenNames = false;
|
|
18833
|
+
/** Suggested tags from API for labels field */
|
|
18834
|
+
this.suggestedTags = [];
|
|
18835
|
+
/** True while parent is fetching latest element data for edit (shows loading state) */
|
|
18836
|
+
this.isElementLoading = false;
|
|
18837
|
+
/** Recent searched items to display in Recent section */
|
|
18838
|
+
this.recentSearchedItems = [];
|
|
18839
|
+
this.apply = new EventEmitter();
|
|
18840
|
+
this.cancel = new EventEmitter();
|
|
18841
|
+
this.editInDepth = new EventEmitter();
|
|
18842
|
+
this.searchElement = new EventEmitter();
|
|
18843
|
+
/** Emitted when user clicks on a recent searched item */
|
|
18844
|
+
this.recentItemClick = new EventEmitter();
|
|
18845
|
+
this.loadMoreElements = new EventEmitter();
|
|
18846
|
+
/** Emitted when user creates a new element (parent should call API) */
|
|
18847
|
+
this.createElement = new EventEmitter();
|
|
18848
|
+
/** Emitted when user updates an element (parent should call API) */
|
|
18849
|
+
this.updateElement = new EventEmitter();
|
|
18850
|
+
/** Emitted when user requests to create a new screen name */
|
|
18851
|
+
this.createScreenNameRequest = new EventEmitter();
|
|
18852
|
+
/** Emitted when user searches screen names (server search) */
|
|
18853
|
+
this.searchScreenName = new EventEmitter();
|
|
18854
|
+
/** Emitted when user scrolls to load more screen names (passes current search query) */
|
|
18855
|
+
this.loadMoreScreenNames = new EventEmitter();
|
|
18856
|
+
/** Emitted when Create or Edit form is opened - parent should fetch screen names and (for edit) latest element */
|
|
18857
|
+
this.formOpenRequest = new EventEmitter();
|
|
18858
|
+
/** Emitted when user selects an element from the list - parent should set element and editingElementId for Edit flow */
|
|
18859
|
+
this.elementSelect = new EventEmitter();
|
|
18860
|
+
/** Emitted when user clicks Record - parent should check extension and call installPlugin or openSidePanelAndListSteps */
|
|
18861
|
+
this.toggleRecord = new EventEmitter();
|
|
18862
|
+
this.helpTooltipText = 'Not sure what to do? Click to go to our detailed step creation documentation';
|
|
18863
|
+
this.showHelpTooltip = false;
|
|
18864
|
+
this.isEditMode = false;
|
|
18865
|
+
/** Whether we're in create mode (no elementId) */
|
|
18866
|
+
this.isCreateMode = false;
|
|
18867
|
+
/** Current search input value (bound to search bar) */
|
|
18868
|
+
this.searchValue = '';
|
|
18869
|
+
this.injectedData = data;
|
|
18870
|
+
}
|
|
18871
|
+
ngOnChanges(changes) {
|
|
18872
|
+
if ((changes['element'] || changes['elementId']) && this.enableForm) {
|
|
18873
|
+
if (this.elementId) {
|
|
18874
|
+
this.isCreateMode = false;
|
|
18875
|
+
this.isEditMode = true;
|
|
18876
|
+
}
|
|
18877
|
+
else {
|
|
18878
|
+
this.isCreateMode = true;
|
|
18879
|
+
this.isEditMode = false;
|
|
18880
|
+
}
|
|
18881
|
+
}
|
|
18882
|
+
}
|
|
18883
|
+
ngOnInit() {
|
|
18884
|
+
var _a, _b, _c, _d, _e;
|
|
18885
|
+
if (this.injectedData) {
|
|
18886
|
+
if (!this.value)
|
|
18887
|
+
this.value = (_a = this.injectedData.description) !== null && _a !== void 0 ? _a : '';
|
|
18888
|
+
if (!this.helpUrl)
|
|
18889
|
+
this.helpUrl = (_b = this.injectedData.helpUrl) !== null && _b !== void 0 ? _b : '';
|
|
18890
|
+
if (this.labels.length === 0)
|
|
18891
|
+
this.labels = (_c = this.injectedData.labels) !== null && _c !== void 0 ? _c : [];
|
|
18892
|
+
if (this.elements.length === 0)
|
|
18893
|
+
this.elements = (_d = this.injectedData.elements) !== null && _d !== void 0 ? _d : [];
|
|
18894
|
+
if (!this.element || !this.element.title) {
|
|
18895
|
+
this.element = (_e = this.injectedData.element) !== null && _e !== void 0 ? _e : { title: '', selector: '', labels: [] };
|
|
18896
|
+
}
|
|
18897
|
+
}
|
|
18898
|
+
}
|
|
18899
|
+
resetForm() {
|
|
18900
|
+
this.isEditMode = false;
|
|
18901
|
+
this.isCreateMode = false;
|
|
18902
|
+
}
|
|
18903
|
+
onElementFormCreate(payload) {
|
|
18904
|
+
this.createElement.emit(payload);
|
|
18905
|
+
}
|
|
18906
|
+
onElementFormUpdate(payload) {
|
|
18907
|
+
this.updateElement.emit(payload);
|
|
18908
|
+
}
|
|
18909
|
+
onElementFormCancel() {
|
|
18910
|
+
this.toggleForm();
|
|
18911
|
+
}
|
|
18912
|
+
onCreateOrUpdateSuccess() {
|
|
18913
|
+
var _a;
|
|
18914
|
+
this.enableForm = false;
|
|
18915
|
+
this.resetForm();
|
|
18916
|
+
(_a = this.cdr) === null || _a === void 0 ? void 0 : _a.markForCheck();
|
|
18917
|
+
}
|
|
18918
|
+
onCreateOrUpdateError() {
|
|
18919
|
+
var _a;
|
|
18920
|
+
(_a = this.cdr) === null || _a === void 0 ? void 0 : _a.markForCheck();
|
|
18921
|
+
}
|
|
18922
|
+
toggleForm() {
|
|
18923
|
+
var _a;
|
|
18924
|
+
if (!this.enableForm) {
|
|
18925
|
+
// If no elementId, go to create mode instead of edit mode
|
|
18926
|
+
if (!this.elementId) {
|
|
18927
|
+
this.isCreateMode = true;
|
|
18928
|
+
this.isEditMode = false;
|
|
18929
|
+
this.formOpenRequest.emit({ mode: 'create' });
|
|
18930
|
+
}
|
|
18931
|
+
else {
|
|
18932
|
+
// Has elementId, go to edit mode
|
|
18933
|
+
this.isCreateMode = false;
|
|
18934
|
+
this.isEditMode = true;
|
|
18935
|
+
this.formOpenRequest.emit({ mode: 'edit', elementId: this.elementId });
|
|
18936
|
+
}
|
|
18937
|
+
}
|
|
18938
|
+
else {
|
|
18939
|
+
// Closing form - reset everything
|
|
18940
|
+
// If in create mode, reset labels when going back to element list
|
|
18941
|
+
if (this.isCreateMode) {
|
|
18942
|
+
this.labels = [];
|
|
18943
|
+
}
|
|
18944
|
+
this.resetForm();
|
|
18945
|
+
this.isCreateMode = false;
|
|
18946
|
+
}
|
|
18947
|
+
this.enableForm = !this.enableForm;
|
|
18948
|
+
(_a = this.cdr) === null || _a === void 0 ? void 0 : _a.markForCheck();
|
|
18949
|
+
}
|
|
18950
|
+
openCreateForm() {
|
|
18951
|
+
var _a;
|
|
18952
|
+
this.isCreateMode = true;
|
|
18953
|
+
this.isEditMode = false;
|
|
18954
|
+
this.resetForm();
|
|
18955
|
+
this.enableForm = true;
|
|
18956
|
+
this.formOpenRequest.emit({ mode: 'create' });
|
|
18957
|
+
(_a = this.cdr) === null || _a === void 0 ? void 0 : _a.markForCheck();
|
|
18958
|
+
}
|
|
18959
|
+
onToggleRecordClick() {
|
|
18960
|
+
this.toggleRecord.emit();
|
|
18961
|
+
}
|
|
18962
|
+
onCancel() {
|
|
18963
|
+
var _a;
|
|
18838
18964
|
if (this.enableForm) {
|
|
18839
18965
|
// If in create mode, go back to element list and reset labels
|
|
18840
18966
|
if (this.isCreateMode) {
|
|
@@ -18858,8 +18984,7 @@ class ElementPopupComponent {
|
|
|
18858
18984
|
onClose() {
|
|
18859
18985
|
this.onCancel();
|
|
18860
18986
|
}
|
|
18861
|
-
onEditInDepth(
|
|
18862
|
-
event.preventDefault();
|
|
18987
|
+
onEditInDepth() {
|
|
18863
18988
|
this.editInDepth.emit();
|
|
18864
18989
|
if (this.ref)
|
|
18865
18990
|
this.ref.close(ELEMENT_POPUP_EDIT_IN_DEPTH);
|
|
@@ -18877,39 +19002,6 @@ class ElementPopupComponent {
|
|
|
18877
19002
|
window.open(this.helpUrl, '_blank');
|
|
18878
19003
|
}
|
|
18879
19004
|
}
|
|
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
19005
|
onElementClick(element) {
|
|
18914
19006
|
var _a;
|
|
18915
19007
|
this.element = element;
|
|
@@ -18933,12 +19025,17 @@ class ElementPopupComponent {
|
|
|
18933
19025
|
this.searchElement.emit(item);
|
|
18934
19026
|
(_a = this.cdr) === null || _a === void 0 ? void 0 : _a.markForCheck();
|
|
18935
19027
|
}
|
|
19028
|
+
/** Called by parent when a new screen name was created (so we can set the selected value) */
|
|
19029
|
+
setCreatedScreenName(opt) {
|
|
19030
|
+
var _a;
|
|
19031
|
+
(_a = this.elementFormComponent) === null || _a === void 0 ? void 0 : _a.setCreatedScreenName(opt);
|
|
19032
|
+
}
|
|
18936
19033
|
}
|
|
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 });
|
|
19034
|
+
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 });
|
|
19035
|
+
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
19036
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: ElementPopupComponent, decorators: [{
|
|
18940
19037
|
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" }]
|
|
19038
|
+
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
19039
|
}], ctorParameters: function () {
|
|
18943
19040
|
return [{ type: ElementPopupRef, decorators: [{
|
|
18944
19041
|
type: Optional
|
|
@@ -18950,8 +19047,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
|
|
|
18950
19047
|
}, {
|
|
18951
19048
|
type: Inject,
|
|
18952
19049
|
args: [ELEMENT_POPUP_DATA]
|
|
18953
|
-
}] }, { type: i1$1.FormBuilder, decorators: [{
|
|
18954
|
-
type: Optional
|
|
18955
19050
|
}] }, { type: i0.ChangeDetectorRef, decorators: [{
|
|
18956
19051
|
type: Optional
|
|
18957
19052
|
}] }];
|
|
@@ -19013,6 +19108,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
|
|
|
19013
19108
|
type: Output
|
|
19014
19109
|
}], toggleRecord: [{
|
|
19015
19110
|
type: Output
|
|
19111
|
+
}], elementFormComponent: [{
|
|
19112
|
+
type: ViewChild,
|
|
19113
|
+
args: [ElementFormComponent]
|
|
19016
19114
|
}] } });
|
|
19017
19115
|
|
|
19018
19116
|
class ElementPopupService {
|
|
@@ -25346,13 +25444,30 @@ class TemplateVariablesFormComponent {
|
|
|
25346
25444
|
constructor(cdr) {
|
|
25347
25445
|
this.cdr = cdr;
|
|
25348
25446
|
this.templateVariables = [];
|
|
25349
|
-
this.variablesForm = new
|
|
25447
|
+
this.variablesForm = new FormArray([]);
|
|
25350
25448
|
this.metadata = '';
|
|
25351
25449
|
this.description = '';
|
|
25450
|
+
this.elementOptions = []; // Element objects for element dropdown
|
|
25451
|
+
this.hasMoreElements = false; // Whether more elements are available
|
|
25452
|
+
this.isLoadingElements = false; // Loading state for elements
|
|
25453
|
+
/** Screen name options for element form autocomplete (from API) */
|
|
25454
|
+
this.screenNameOptions = [];
|
|
25455
|
+
/** Whether more screen names are available for infinite scroll */
|
|
25456
|
+
this.hasMoreScreenNames = false;
|
|
25457
|
+
/** True while parent is loading screen names (search or load more) */
|
|
25458
|
+
this.isLoadingScreenNames = false;
|
|
25352
25459
|
this.variableValueChange = new EventEmitter();
|
|
25353
25460
|
this.variableBooleanChange = new EventEmitter();
|
|
25354
25461
|
this.metadataChange = new EventEmitter();
|
|
25355
25462
|
this.descriptionChange = new EventEmitter();
|
|
25463
|
+
this.loadMoreElements = new EventEmitter(); // Emit when load more is requested
|
|
25464
|
+
this.searchElements = new EventEmitter(); // Emit when user searches for elements
|
|
25465
|
+
this.createElement = new EventEmitter(); // Emit when element is created with payload
|
|
25466
|
+
this.searchScreenName = new EventEmitter(); // Emit when user searches screen names
|
|
25467
|
+
this.loadMoreScreenNames = new EventEmitter(); // Emit when user scrolls to load more screen names
|
|
25468
|
+
this.createScreenNameRequest = new EventEmitter(); // Emit when user requests to create a new screen name
|
|
25469
|
+
this.cancelElementForm = new EventEmitter(); // Emit when element form is cancelled
|
|
25470
|
+
this.elementFormVisibilityChange = new EventEmitter(); // Emit when element form visibility changes
|
|
25356
25471
|
// Cache for select configs to avoid recalculating on every change detection
|
|
25357
25472
|
this.selectConfigCache = new Map();
|
|
25358
25473
|
// Cache for data type select configs
|
|
@@ -25371,9 +25486,29 @@ class TemplateVariablesFormComponent {
|
|
|
25371
25486
|
{ id: 'runtime', value: 'runtime', name: '$|Runtime|', label: '$|Runtime|' },
|
|
25372
25487
|
{ id: 'environment', value: 'environment', name: '*|Environment|', label: '*|Environment|' }
|
|
25373
25488
|
];
|
|
25489
|
+
this.createElementVisible = false;
|
|
25490
|
+
}
|
|
25491
|
+
onCreateElement(payload) {
|
|
25492
|
+
console.log('onCreateElement', payload);
|
|
25493
|
+
this.createElement.emit(payload);
|
|
25494
|
+
this.createElementVisible = false;
|
|
25495
|
+
this.elementFormVisibilityChange.emit(false);
|
|
25496
|
+
this.cdr.markForCheck();
|
|
25497
|
+
}
|
|
25498
|
+
onCancelElementForm() {
|
|
25499
|
+
this.createElementVisible = false;
|
|
25500
|
+
this.elementFormVisibilityChange.emit(false);
|
|
25501
|
+
this.cancelElementForm.emit();
|
|
25502
|
+
this.cdr.markForCheck();
|
|
25503
|
+
}
|
|
25504
|
+
onShowElementForm() {
|
|
25505
|
+
this.createElementVisible = true;
|
|
25506
|
+
this.elementFormVisibilityChange.emit(true);
|
|
25507
|
+
this.cdr.markForCheck();
|
|
25374
25508
|
}
|
|
25375
25509
|
ngOnChanges(changes) {
|
|
25376
|
-
if (changes['templateVariables'] || changes['variablesForm']
|
|
25510
|
+
if (changes['templateVariables'] || changes['variablesForm'] || changes['elementOptions'] ||
|
|
25511
|
+
changes['hasMoreElements'] || changes['isLoadingElements']) {
|
|
25377
25512
|
// Clear all caches when inputs change
|
|
25378
25513
|
this.selectConfigCache.clear();
|
|
25379
25514
|
this.dataTypeSelectConfigCache.clear();
|
|
@@ -25390,35 +25525,52 @@ class TemplateVariablesFormComponent {
|
|
|
25390
25525
|
}
|
|
25391
25526
|
}
|
|
25392
25527
|
initializeTestDataVariables() {
|
|
25393
|
-
this.templateVariables.forEach(variable => {
|
|
25528
|
+
this.templateVariables.forEach((variable, index) => {
|
|
25394
25529
|
var _a;
|
|
25395
25530
|
if (this.needsDataTypeDropdown(variable)) {
|
|
25396
25531
|
const { dataType, rawValue } = this.parseTestDataValue(variable.value || '');
|
|
25397
25532
|
this.variableDataTypes.set(variable.name, dataType);
|
|
25398
25533
|
this.variableRawValues.set(variable.name, rawValue);
|
|
25399
|
-
// Ensure form control exists for data type
|
|
25400
|
-
const
|
|
25401
|
-
if (
|
|
25402
|
-
|
|
25403
|
-
|
|
25404
|
-
|
|
25405
|
-
|
|
25534
|
+
// Ensure form control exists for data type in the FormArray
|
|
25535
|
+
const variableGroup = this.getVariableFormGroup(variable.name);
|
|
25536
|
+
if (variableGroup) {
|
|
25537
|
+
if (!variableGroup.get('dataType')) {
|
|
25538
|
+
variableGroup.addControl('dataType', new FormControl(dataType));
|
|
25539
|
+
}
|
|
25540
|
+
else {
|
|
25541
|
+
(_a = variableGroup.get('dataType')) === null || _a === void 0 ? void 0 : _a.setValue(dataType, { emitEvent: false });
|
|
25542
|
+
}
|
|
25406
25543
|
}
|
|
25407
25544
|
}
|
|
25408
25545
|
});
|
|
25409
25546
|
}
|
|
25547
|
+
/** Get form group for a variable by name from FormArray */
|
|
25548
|
+
getVariableFormGroup(variableName) {
|
|
25549
|
+
const variableIndex = this.variablesForm.controls.findIndex(control => { var _a; return ((_a = control.get('name')) === null || _a === void 0 ? void 0 : _a.value) === variableName; });
|
|
25550
|
+
if (variableIndex !== -1) {
|
|
25551
|
+
return this.variablesForm.at(variableIndex);
|
|
25552
|
+
}
|
|
25553
|
+
return null;
|
|
25554
|
+
}
|
|
25555
|
+
/** Get form group at a specific index from FormArray (for template use) */
|
|
25556
|
+
getFormGroupAt(index) {
|
|
25557
|
+
if (index >= 0 && index < this.variablesForm.length) {
|
|
25558
|
+
return this.variablesForm.at(index);
|
|
25559
|
+
}
|
|
25560
|
+
return null;
|
|
25561
|
+
}
|
|
25410
25562
|
precomputeConfigs() {
|
|
25411
25563
|
if (!this.templateVariables)
|
|
25412
25564
|
return;
|
|
25413
25565
|
// Pre-compute all select configs
|
|
25414
|
-
this.templateVariables.forEach(variable => {
|
|
25566
|
+
this.templateVariables.forEach((variable, index) => {
|
|
25415
25567
|
// Pre-compute regular select configs
|
|
25416
25568
|
if (this.shouldShowDropdown(variable)) {
|
|
25417
|
-
this.getSelectConfig(variable);
|
|
25569
|
+
this.getSelectConfig(variable, index);
|
|
25418
25570
|
}
|
|
25419
25571
|
// Pre-compute data type select configs
|
|
25420
25572
|
if (this.needsDataTypeDropdown(variable)) {
|
|
25421
|
-
this.getDataTypeSelectConfig(variable);
|
|
25573
|
+
this.getDataTypeSelectConfig(variable, index);
|
|
25422
25574
|
}
|
|
25423
25575
|
});
|
|
25424
25576
|
}
|
|
@@ -25462,34 +25614,73 @@ class TemplateVariablesFormComponent {
|
|
|
25462
25614
|
trackByVariable(index, variable) {
|
|
25463
25615
|
return variable.name || index;
|
|
25464
25616
|
}
|
|
25465
|
-
getSelectConfig(variable) {
|
|
25466
|
-
var _a;
|
|
25617
|
+
getSelectConfig(variable, index) {
|
|
25618
|
+
var _a, _b;
|
|
25467
25619
|
// Use cache to avoid recalculating on every change detection
|
|
25468
|
-
|
|
25620
|
+
// For element variables, include elementOptions, hasMoreElements, and isLoadingElements in cache key
|
|
25621
|
+
const optionsKey = variable.dataKey === 'element' || variable.dataKey === 'label'
|
|
25622
|
+
? this.elementOptions.map(el => String(el.name || '')).join(',')
|
|
25623
|
+
: (((_a = variable.options) === null || _a === void 0 ? void 0 : _a.join(',')) || '');
|
|
25624
|
+
// Include hasMoreElements and isLoadingElements in cache key for selector variables
|
|
25625
|
+
const cacheKey = variable.dataKey === 'element' || variable.dataKey === 'label'
|
|
25626
|
+
? `${variable.name}_${optionsKey}_${this.hasMoreElements}_${this.isLoadingElements}`
|
|
25627
|
+
: `${variable.name}_${optionsKey}`;
|
|
25469
25628
|
if (this.selectConfigCache.has(cacheKey)) {
|
|
25470
25629
|
return this.selectConfigCache.get(cacheKey);
|
|
25471
25630
|
}
|
|
25472
|
-
|
|
25473
|
-
|
|
25474
|
-
|
|
25475
|
-
|
|
25476
|
-
|
|
25477
|
-
|
|
25631
|
+
// Use elementOptions if variable name is 'selector', otherwise use variable.options
|
|
25632
|
+
// Extract element names from Element objects
|
|
25633
|
+
let optionsArray = [];
|
|
25634
|
+
if (variable.dataKey === 'element' || variable.dataKey === 'label') {
|
|
25635
|
+
// For element options, use locatorValue as both id and value so the component returns locatorValue
|
|
25636
|
+
// This ensures the selected value is the locatorValue (not the element id)
|
|
25637
|
+
optionsArray = this.elementOptions
|
|
25638
|
+
.map(el => {
|
|
25639
|
+
var _a;
|
|
25640
|
+
const locatorValue = el.locatorValue || '';
|
|
25641
|
+
return {
|
|
25642
|
+
id: locatorValue,
|
|
25643
|
+
elementId: ((_a = el.id) === null || _a === void 0 ? void 0 : _a.toString()) || '',
|
|
25644
|
+
value: locatorValue,
|
|
25645
|
+
name: el.name,
|
|
25646
|
+
label: el.name
|
|
25647
|
+
};
|
|
25648
|
+
});
|
|
25649
|
+
}
|
|
25650
|
+
else {
|
|
25651
|
+
optionsArray = ((_b = variable.options) === null || _b === void 0 ? void 0 : _b.map(opt => { return { id: opt, value: opt, name: opt, label: opt }; })) || [];
|
|
25652
|
+
}
|
|
25653
|
+
console.log('optionsArray', optionsArray);
|
|
25478
25654
|
const config = {
|
|
25479
|
-
key:
|
|
25655
|
+
key: 'value',
|
|
25480
25656
|
placeholder: `Select ${variable.label}`,
|
|
25481
25657
|
multiple: false,
|
|
25482
25658
|
searchable: false,
|
|
25483
|
-
options:
|
|
25659
|
+
options: optionsArray,
|
|
25484
25660
|
onChange: (value) => {
|
|
25485
25661
|
this.onVariableValueChange(variable.name, value);
|
|
25486
25662
|
}
|
|
25487
25663
|
};
|
|
25664
|
+
// Add load more and search support for selector variables
|
|
25665
|
+
if (variable.dataKey === 'element' || variable.dataKey === 'label') {
|
|
25666
|
+
config.searchable = true; // Enable search for selector dropdown
|
|
25667
|
+
config.serverSearch = true; // Enable server-side search
|
|
25668
|
+
config.hasMore = this.hasMoreElements;
|
|
25669
|
+
config.isLoading = this.isLoadingElements;
|
|
25670
|
+
config.onLoadMore = () => {
|
|
25671
|
+
this.loadMoreElements.emit();
|
|
25672
|
+
};
|
|
25673
|
+
config.onSearch = (query) => {
|
|
25674
|
+
// Emit search event when user types in the search box
|
|
25675
|
+
this.searchElements.emit(query);
|
|
25676
|
+
};
|
|
25677
|
+
}
|
|
25488
25678
|
this.selectConfigCache.set(cacheKey, config);
|
|
25489
25679
|
return config;
|
|
25490
25680
|
}
|
|
25491
25681
|
onVariableValueChange(variableName, value) {
|
|
25492
25682
|
var _a, _b;
|
|
25683
|
+
console.log("onVariableValueChange", variableName, value);
|
|
25493
25684
|
const variable = this.templateVariables.find(v => v.name === variableName);
|
|
25494
25685
|
if (!variable)
|
|
25495
25686
|
return;
|
|
@@ -25498,17 +25689,18 @@ class TemplateVariablesFormComponent {
|
|
|
25498
25689
|
const { dataType, rawValue } = this.parseTestDataValue(value || '');
|
|
25499
25690
|
this.variableDataTypes.set(variableName, dataType);
|
|
25500
25691
|
this.variableRawValues.set(variableName, rawValue);
|
|
25501
|
-
// Update data type form control
|
|
25502
|
-
const
|
|
25503
|
-
if (
|
|
25504
|
-
(_a =
|
|
25692
|
+
// Update data type form control in FormArray
|
|
25693
|
+
const variableGroup = this.getVariableFormGroup(variableName);
|
|
25694
|
+
if (variableGroup && variableGroup.get('dataType')) {
|
|
25695
|
+
(_a = variableGroup.get('dataType')) === null || _a === void 0 ? void 0 : _a.setValue(dataType, { emitEvent: false });
|
|
25505
25696
|
}
|
|
25506
25697
|
}
|
|
25507
25698
|
// Update the variable in templateVariables array
|
|
25508
25699
|
variable.value = value;
|
|
25509
|
-
// Also update form control (use emitEvent: false to prevent triggering valueChanges)
|
|
25510
|
-
|
|
25511
|
-
|
|
25700
|
+
// Also update form control in FormArray (use emitEvent: false to prevent triggering valueChanges)
|
|
25701
|
+
const variableGroup = this.getVariableFormGroup(variableName);
|
|
25702
|
+
if (variableGroup && variableGroup.get('value')) {
|
|
25703
|
+
(_b = variableGroup.get('value')) === null || _b === void 0 ? void 0 : _b.setValue(value, { emitEvent: false });
|
|
25512
25704
|
}
|
|
25513
25705
|
// Mark for check since we're using OnPush
|
|
25514
25706
|
this.cdr.markForCheck();
|
|
@@ -25522,14 +25714,12 @@ class TemplateVariablesFormComponent {
|
|
|
25522
25714
|
if (variable) {
|
|
25523
25715
|
variable.value = value;
|
|
25524
25716
|
}
|
|
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));
|
|
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
|
+
(_a = variableGroup.get('value')) === null || _a === void 0 ? void 0 : _a.setValue(value, { emitEvent: false });
|
|
25532
25721
|
}
|
|
25722
|
+
// Note: If variable doesn't exist in FormArray, it should be added by parent component
|
|
25533
25723
|
// Mark for check since we're using OnPush
|
|
25534
25724
|
this.cdr.markForCheck();
|
|
25535
25725
|
// Emit the change event
|
|
@@ -25540,7 +25730,7 @@ class TemplateVariablesFormComponent {
|
|
|
25540
25730
|
if (this.shouldShowDropdownCache.has(variable.name)) {
|
|
25541
25731
|
return this.shouldShowDropdownCache.get(variable.name);
|
|
25542
25732
|
}
|
|
25543
|
-
const result = variable.name === 'type' || variable.name === 'scrollTo';
|
|
25733
|
+
const result = variable.name === 'type' || variable.name === 'scrollTo' || variable.dataKey === 'element' || variable.dataKey === 'label';
|
|
25544
25734
|
this.shouldShowDropdownCache.set(variable.name, result);
|
|
25545
25735
|
return result;
|
|
25546
25736
|
}
|
|
@@ -25550,8 +25740,8 @@ class TemplateVariablesFormComponent {
|
|
|
25550
25740
|
if (this.needsDataTypeDropdownCache.has(variable.name)) {
|
|
25551
25741
|
return this.needsDataTypeDropdownCache.get(variable.name);
|
|
25552
25742
|
}
|
|
25553
|
-
const
|
|
25554
|
-
const result =
|
|
25743
|
+
const dataKey = ((_a = variable.dataKey) === null || _a === void 0 ? void 0 : _a.toLowerCase()) || '';
|
|
25744
|
+
const result = dataKey === 'test-data' || dataKey === 'source_value' || dataKey === 'target_value';
|
|
25555
25745
|
this.needsDataTypeDropdownCache.set(variable.name, result);
|
|
25556
25746
|
return result;
|
|
25557
25747
|
}
|
|
@@ -25559,20 +25749,20 @@ class TemplateVariablesFormComponent {
|
|
|
25559
25749
|
// Return cached static array
|
|
25560
25750
|
return this.dataTypeOptions;
|
|
25561
25751
|
}
|
|
25562
|
-
getDataTypeSelectConfig(variable) {
|
|
25752
|
+
getDataTypeSelectConfig(variable, index) {
|
|
25563
25753
|
// Use cache to avoid recalculating on every change detection
|
|
25564
25754
|
const cacheKey = `${variable.name}_dataType`;
|
|
25565
25755
|
if (this.dataTypeSelectConfigCache.has(cacheKey)) {
|
|
25566
25756
|
return this.dataTypeSelectConfigCache.get(cacheKey);
|
|
25567
25757
|
}
|
|
25568
|
-
|
|
25569
|
-
|
|
25570
|
-
if (!
|
|
25758
|
+
// Ensure form control exists in FormArray
|
|
25759
|
+
const variableGroup = this.getVariableFormGroup(variable.name);
|
|
25760
|
+
if (variableGroup && !variableGroup.get('dataType')) {
|
|
25571
25761
|
const currentDataType = this.variableDataTypes.get(variable.name) || 'plain-text';
|
|
25572
|
-
|
|
25762
|
+
variableGroup.addControl('dataType', new FormControl(currentDataType));
|
|
25573
25763
|
}
|
|
25574
25764
|
const config = {
|
|
25575
|
-
key:
|
|
25765
|
+
key: 'dataType',
|
|
25576
25766
|
placeholder: 'Select Type',
|
|
25577
25767
|
multiple: false,
|
|
25578
25768
|
searchable: false,
|
|
@@ -25592,6 +25782,40 @@ class TemplateVariablesFormComponent {
|
|
|
25592
25782
|
// Simple getter - already cached in Map, no computation needed
|
|
25593
25783
|
return this.variableRawValues.get(variable.name) || '';
|
|
25594
25784
|
}
|
|
25785
|
+
/**
|
|
25786
|
+
* Check if selector variable is available in templateVariables
|
|
25787
|
+
*/
|
|
25788
|
+
get selectorVariableAvailable() {
|
|
25789
|
+
return this.templateVariables.some(v => v.dataKey === 'element' || v.dataKey === 'label');
|
|
25790
|
+
}
|
|
25791
|
+
/**
|
|
25792
|
+
* Check if parameter variable is available (testData with parameter type)
|
|
25793
|
+
*/
|
|
25794
|
+
get parameterVariableAvailable() {
|
|
25795
|
+
return this.templateVariables.some(v => {
|
|
25796
|
+
var _a;
|
|
25797
|
+
const dataKey = ((_a = v.dataKey) === null || _a === void 0 ? void 0 : _a.toLowerCase()) || '';
|
|
25798
|
+
if (dataKey === 'test-data' || dataKey === 'source_value' || dataKey === 'target_value') {
|
|
25799
|
+
const dataType = this.variableDataTypes.get(v.name) || 'plain-text';
|
|
25800
|
+
return dataType === 'parameter';
|
|
25801
|
+
}
|
|
25802
|
+
return false;
|
|
25803
|
+
});
|
|
25804
|
+
}
|
|
25805
|
+
/**
|
|
25806
|
+
* Check if environment variable is available (testData with environment type)
|
|
25807
|
+
*/
|
|
25808
|
+
get environmentVariableAvailable() {
|
|
25809
|
+
return this.templateVariables.some(v => {
|
|
25810
|
+
var _a;
|
|
25811
|
+
const dataKey = ((_a = v.name) === null || _a === void 0 ? void 0 : _a.toLowerCase()) || '';
|
|
25812
|
+
if (dataKey === 'test-data' || dataKey === 'source_value' || dataKey === 'target_value') {
|
|
25813
|
+
const dataType = this.variableDataTypes.get(v.name) || 'plain-text';
|
|
25814
|
+
return dataType === 'environment';
|
|
25815
|
+
}
|
|
25816
|
+
return false;
|
|
25817
|
+
});
|
|
25818
|
+
}
|
|
25595
25819
|
onDataTypeChange(variableName, dataType) {
|
|
25596
25820
|
var _a;
|
|
25597
25821
|
// Update stored data type
|
|
@@ -25605,9 +25829,10 @@ class TemplateVariablesFormComponent {
|
|
|
25605
25829
|
if (variable) {
|
|
25606
25830
|
variable.value = formattedValue;
|
|
25607
25831
|
}
|
|
25608
|
-
// Update form control
|
|
25609
|
-
|
|
25610
|
-
|
|
25832
|
+
// Update form control in FormArray
|
|
25833
|
+
const variableGroup = this.getVariableFormGroup(variableName);
|
|
25834
|
+
if (variableGroup && variableGroup.get('value')) {
|
|
25835
|
+
(_a = variableGroup.get('value')) === null || _a === void 0 ? void 0 : _a.setValue(formattedValue, { emitEvent: false });
|
|
25611
25836
|
}
|
|
25612
25837
|
// Mark for check since we're using OnPush
|
|
25613
25838
|
this.cdr.markForCheck();
|
|
@@ -25615,6 +25840,12 @@ class TemplateVariablesFormComponent {
|
|
|
25615
25840
|
// Emit the change event
|
|
25616
25841
|
this.variableValueChange.emit({ name: variableName, value: formattedValue });
|
|
25617
25842
|
}
|
|
25843
|
+
onElementSearch(event) {
|
|
25844
|
+
// Only handle search for selector variables
|
|
25845
|
+
// The key will be 'value' since that's what we set in the config
|
|
25846
|
+
// Emit the search query to parent component
|
|
25847
|
+
this.searchElements.emit(event.query);
|
|
25848
|
+
}
|
|
25618
25849
|
onTestDataValueChange(variableName, rawValue) {
|
|
25619
25850
|
var _a;
|
|
25620
25851
|
// Update stored raw value
|
|
@@ -25628,9 +25859,10 @@ class TemplateVariablesFormComponent {
|
|
|
25628
25859
|
if (variable) {
|
|
25629
25860
|
variable.value = formattedValue;
|
|
25630
25861
|
}
|
|
25631
|
-
// Update form control
|
|
25632
|
-
|
|
25633
|
-
|
|
25862
|
+
// Update form control in FormArray
|
|
25863
|
+
const variableGroup = this.getVariableFormGroup(variableName);
|
|
25864
|
+
if (variableGroup && variableGroup.get('value')) {
|
|
25865
|
+
(_a = variableGroup.get('value')) === null || _a === void 0 ? void 0 : _a.setValue(formattedValue, { emitEvent: false });
|
|
25634
25866
|
}
|
|
25635
25867
|
// Mark for check since we're using OnPush
|
|
25636
25868
|
this.cdr.markForCheck();
|
|
@@ -25639,10 +25871,10 @@ class TemplateVariablesFormComponent {
|
|
|
25639
25871
|
}
|
|
25640
25872
|
}
|
|
25641
25873
|
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
|
|
25874
|
+
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
25875
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TemplateVariablesFormComponent, decorators: [{
|
|
25644
25876
|
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
|
|
25877
|
+
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
25878
|
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { templateVariables: [{
|
|
25647
25879
|
type: Input
|
|
25648
25880
|
}], variablesForm: [{
|
|
@@ -25651,6 +25883,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
|
|
|
25651
25883
|
type: Input
|
|
25652
25884
|
}], description: [{
|
|
25653
25885
|
type: Input
|
|
25886
|
+
}], elementOptions: [{
|
|
25887
|
+
type: Input
|
|
25888
|
+
}], hasMoreElements: [{
|
|
25889
|
+
type: Input
|
|
25890
|
+
}], isLoadingElements: [{
|
|
25891
|
+
type: Input
|
|
25892
|
+
}], screenNameOptions: [{
|
|
25893
|
+
type: Input
|
|
25894
|
+
}], hasMoreScreenNames: [{
|
|
25895
|
+
type: Input
|
|
25896
|
+
}], isLoadingScreenNames: [{
|
|
25897
|
+
type: Input
|
|
25654
25898
|
}], variableValueChange: [{
|
|
25655
25899
|
type: Output
|
|
25656
25900
|
}], variableBooleanChange: [{
|
|
@@ -25659,6 +25903,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
|
|
|
25659
25903
|
type: Output
|
|
25660
25904
|
}], descriptionChange: [{
|
|
25661
25905
|
type: Output
|
|
25906
|
+
}], loadMoreElements: [{
|
|
25907
|
+
type: Output
|
|
25908
|
+
}], searchElements: [{
|
|
25909
|
+
type: Output
|
|
25910
|
+
}], createElement: [{
|
|
25911
|
+
type: Output
|
|
25912
|
+
}], searchScreenName: [{
|
|
25913
|
+
type: Output
|
|
25914
|
+
}], loadMoreScreenNames: [{
|
|
25915
|
+
type: Output
|
|
25916
|
+
}], createScreenNameRequest: [{
|
|
25917
|
+
type: Output
|
|
25918
|
+
}], cancelElementForm: [{
|
|
25919
|
+
type: Output
|
|
25920
|
+
}], elementFormVisibilityChange: [{
|
|
25921
|
+
type: Output
|
|
25662
25922
|
}] } });
|
|
25663
25923
|
|
|
25664
25924
|
class StepBuilderActionComponent {
|
|
@@ -25672,7 +25932,22 @@ class StepBuilderActionComponent {
|
|
|
25672
25932
|
/** Function to handle variable processing or custom logic. Can be passed from parent component. */
|
|
25673
25933
|
this.setTemplateVariables = () => { return []; };
|
|
25674
25934
|
this.preventSelectTemplate = ['databaseverification'];
|
|
25935
|
+
this.elementOptions = []; // Element objects for element dropdown
|
|
25936
|
+
this.hasMoreElements = false; // Whether more elements are available
|
|
25937
|
+
this.isLoadingElements = false; // Loading state for elements
|
|
25938
|
+
/** Screen name options for element form autocomplete (from API) */
|
|
25939
|
+
this.screenNameOptions = [];
|
|
25940
|
+
/** Whether more screen names are available for infinite scroll */
|
|
25941
|
+
this.hasMoreScreenNames = false;
|
|
25942
|
+
/** True while parent is loading screen names (search or load more) */
|
|
25943
|
+
this.isLoadingScreenNames = false;
|
|
25675
25944
|
this.templateChanged = new EventEmitter();
|
|
25945
|
+
this.loadMoreElements = new EventEmitter(); // Emit when load more is requested
|
|
25946
|
+
this.searchElements = new EventEmitter(); // Emit when user searches for elements
|
|
25947
|
+
this.createElement = new EventEmitter(); // Emit when element is created
|
|
25948
|
+
this.searchScreenName = new EventEmitter(); // Emit when user searches screen names
|
|
25949
|
+
this.loadMoreScreenNames = new EventEmitter(); // Emit when user scrolls to load more screen names
|
|
25950
|
+
this.createScreenNameRequest = new EventEmitter(); // Emit when user requests to create a new screen name
|
|
25676
25951
|
/** Emit when step is created */
|
|
25677
25952
|
this.createStep = new EventEmitter();
|
|
25678
25953
|
/** Emit when cancelled */
|
|
@@ -25684,12 +25959,21 @@ class StepBuilderActionComponent {
|
|
|
25684
25959
|
this.description = '';
|
|
25685
25960
|
this.advancedExpanded = false;
|
|
25686
25961
|
this.templateVariables = [];
|
|
25962
|
+
this.updatedHtmlGrammar = ''; // Updated HTML grammar with variable values
|
|
25963
|
+
// Track element form visibility
|
|
25964
|
+
this.isElementFormVisible = false;
|
|
25687
25965
|
// Cache for select configs to avoid recalculating on every change detection
|
|
25688
25966
|
this.selectConfigCache = new Map();
|
|
25689
25967
|
this.formValidCache = false;
|
|
25690
25968
|
this.lastFormValidationTime = 0;
|
|
25691
25969
|
this.FORM_VALIDATION_CACHE_MS = 100; // Cache for 100ms
|
|
25692
|
-
this.variablesForm = this.fb.
|
|
25970
|
+
this.variablesForm = this.fb.array([]);
|
|
25971
|
+
}
|
|
25972
|
+
/**
|
|
25973
|
+
* Handle element form visibility change
|
|
25974
|
+
*/
|
|
25975
|
+
onElementFormVisibilityChange(visible) {
|
|
25976
|
+
this.isElementFormVisible = visible;
|
|
25693
25977
|
}
|
|
25694
25978
|
ngOnInit() {
|
|
25695
25979
|
this.filteredTemplates = [...this.templates];
|
|
@@ -25718,16 +26002,40 @@ class StepBuilderActionComponent {
|
|
|
25718
26002
|
}
|
|
25719
26003
|
const searchTerm = this.searchValue.toLowerCase().trim();
|
|
25720
26004
|
this.filteredTemplates = this.templates.filter(template => {
|
|
25721
|
-
var _a, _b
|
|
26005
|
+
var _a, _b;
|
|
25722
26006
|
const naturalText = ((_a = template.naturalText) === null || _a === void 0 ? void 0 : _a.toLowerCase()) || '';
|
|
25723
|
-
|
|
25724
|
-
const
|
|
26007
|
+
// Strip HTML tags from htmlGrammar for searching (only search text content, not HTML markup)
|
|
26008
|
+
const htmlGrammarText = this.stripHtmlTags(template.htmlGrammar || '').toLowerCase();
|
|
26009
|
+
const searchableGrammar = ((_b = template.searchableGrammar) === null || _b === void 0 ? void 0 : _b.toLowerCase()) || '';
|
|
25725
26010
|
return naturalText.includes(searchTerm) ||
|
|
25726
|
-
|
|
26011
|
+
htmlGrammarText.includes(searchTerm) ||
|
|
25727
26012
|
searchableGrammar.includes(searchTerm);
|
|
25728
26013
|
});
|
|
25729
26014
|
console.log("filteredTemplates", this.filteredTemplates);
|
|
25730
26015
|
}
|
|
26016
|
+
/**
|
|
26017
|
+
* Strip HTML tags from a string, returning only the text content
|
|
26018
|
+
* @param htmlString - HTML string to strip tags from
|
|
26019
|
+
* @returns Plain text without HTML tags
|
|
26020
|
+
*/
|
|
26021
|
+
stripHtmlTags(htmlString) {
|
|
26022
|
+
if (!htmlString)
|
|
26023
|
+
return '';
|
|
26024
|
+
// Use browser's DOMParser if available
|
|
26025
|
+
if (typeof document !== 'undefined' && document.createElement) {
|
|
26026
|
+
try {
|
|
26027
|
+
const tempDiv = document.createElement('div');
|
|
26028
|
+
tempDiv.innerHTML = htmlString;
|
|
26029
|
+
return tempDiv.textContent || tempDiv.innerText || '';
|
|
26030
|
+
}
|
|
26031
|
+
catch (error) {
|
|
26032
|
+
// Fallback to regex if DOM parsing fails
|
|
26033
|
+
return htmlString.replace(/<[^>]*>/g, '');
|
|
26034
|
+
}
|
|
26035
|
+
}
|
|
26036
|
+
// Fallback: regex-based tag removal for server-side rendering
|
|
26037
|
+
return htmlString.replace(/<[^>]*>/g, '');
|
|
26038
|
+
}
|
|
25731
26039
|
selectTemplate(template) {
|
|
25732
26040
|
if (this.preventSelectTemplate.includes(template.displayName || '')) {
|
|
25733
26041
|
this.templateChanged.emit(template);
|
|
@@ -25744,20 +26052,26 @@ class StepBuilderActionComponent {
|
|
|
25744
26052
|
setTimeout(() => {
|
|
25745
26053
|
try {
|
|
25746
26054
|
this.templateVariables = this.setTemplateVariables(template);
|
|
26055
|
+
console.log("templateVariables", this.templateVariables);
|
|
25747
26056
|
this.buildVariablesForm();
|
|
26057
|
+
// Initialize updated HTML grammar
|
|
26058
|
+
this.updateHtmlGrammar();
|
|
25748
26059
|
}
|
|
25749
26060
|
catch (error) {
|
|
25750
26061
|
console.error('Error processing template variables:', error);
|
|
25751
26062
|
}
|
|
25752
26063
|
}, 0);
|
|
25753
26064
|
}
|
|
26065
|
+
else {
|
|
26066
|
+
// Initialize with template's HTML grammar if no variables
|
|
26067
|
+
this.updatedHtmlGrammar = template.htmlGrammar || template.naturalText || '';
|
|
26068
|
+
}
|
|
25754
26069
|
}
|
|
25755
26070
|
buildVariablesForm() {
|
|
25756
|
-
// Clear existing form
|
|
25757
|
-
|
|
25758
|
-
|
|
25759
|
-
|
|
25760
|
-
});
|
|
26071
|
+
// Clear existing form array
|
|
26072
|
+
while (this.variablesForm.length !== 0) {
|
|
26073
|
+
this.variablesForm.removeAt(0);
|
|
26074
|
+
}
|
|
25761
26075
|
// Clear cache when form is rebuilt
|
|
25762
26076
|
this.selectConfigCache.clear();
|
|
25763
26077
|
this.formValidCache = false;
|
|
@@ -25765,13 +26079,40 @@ class StepBuilderActionComponent {
|
|
|
25765
26079
|
if (this.formValueChangesSubscription) {
|
|
25766
26080
|
this.formValueChangesSubscription.unsubscribe();
|
|
25767
26081
|
}
|
|
25768
|
-
// Add form
|
|
26082
|
+
// Add form groups for each variable
|
|
25769
26083
|
this.templateVariables.forEach(variable => {
|
|
26084
|
+
var _a;
|
|
25770
26085
|
// Handle boolean variables - use boolean value, others use string
|
|
25771
26086
|
const defaultValue = variable.type === 'boolean'
|
|
25772
26087
|
? (variable.value === true || variable.value === 'true' || variable.value === 1)
|
|
25773
26088
|
: (variable.value || '');
|
|
25774
|
-
|
|
26089
|
+
// Create a FormGroup for each variable with name and value
|
|
26090
|
+
const variableGroup = this.fb.group({
|
|
26091
|
+
name: [variable.name],
|
|
26092
|
+
value: [defaultValue],
|
|
26093
|
+
type: [variable.type || 'string'],
|
|
26094
|
+
label: [variable.label || ''],
|
|
26095
|
+
options: [variable.options || []]
|
|
26096
|
+
});
|
|
26097
|
+
// Add dataType control for test-data variables if needed
|
|
26098
|
+
const label = ((_a = variable.label) === null || _a === void 0 ? void 0 : _a.toLowerCase()) || '';
|
|
26099
|
+
if (label === 'test-data' || label === 'source-value' || label === 'target-value' ||
|
|
26100
|
+
label === 'source_value' || label === 'target_value') {
|
|
26101
|
+
// Parse the value to determine data type
|
|
26102
|
+
const valueStr = String(defaultValue || '');
|
|
26103
|
+
let dataType = 'plain-text';
|
|
26104
|
+
if (valueStr.startsWith('@|') && valueStr.endsWith('|')) {
|
|
26105
|
+
dataType = 'parameter';
|
|
26106
|
+
}
|
|
26107
|
+
else if (valueStr.startsWith('$|') && valueStr.endsWith('|')) {
|
|
26108
|
+
dataType = 'runtime';
|
|
26109
|
+
}
|
|
26110
|
+
else if (valueStr.startsWith('*|') && valueStr.endsWith('|')) {
|
|
26111
|
+
dataType = 'environment';
|
|
26112
|
+
}
|
|
26113
|
+
variableGroup.addControl('dataType', new FormControl(dataType));
|
|
26114
|
+
}
|
|
26115
|
+
this.variablesForm.push(variableGroup);
|
|
25775
26116
|
});
|
|
25776
26117
|
// Subscribe to form value changes to invalidate cache (only when user actually changes values)
|
|
25777
26118
|
// Note: We use emitEvent: false when programmatically setting values, so this won't fire unnecessarily
|
|
@@ -25785,7 +26126,7 @@ class StepBuilderActionComponent {
|
|
|
25785
26126
|
this.formValueChangesSubscription.unsubscribe();
|
|
25786
26127
|
}
|
|
25787
26128
|
}
|
|
25788
|
-
getSelectConfig(variable) {
|
|
26129
|
+
getSelectConfig(variable, index) {
|
|
25789
26130
|
var _a;
|
|
25790
26131
|
// Use cache to avoid recalculating on every change detection
|
|
25791
26132
|
const cacheKey = `${variable.name}_${((_a = variable.options) === null || _a === void 0 ? void 0 : _a.join(',')) || ''}`;
|
|
@@ -25799,7 +26140,7 @@ class StepBuilderActionComponent {
|
|
|
25799
26140
|
label: opt
|
|
25800
26141
|
}));
|
|
25801
26142
|
const config = {
|
|
25802
|
-
key:
|
|
26143
|
+
key: `value`,
|
|
25803
26144
|
placeholder: `Select ${variable.label}`,
|
|
25804
26145
|
multiple: false,
|
|
25805
26146
|
searchable: false,
|
|
@@ -25811,19 +26152,64 @@ class StepBuilderActionComponent {
|
|
|
25811
26152
|
this.selectConfigCache.set(cacheKey, config);
|
|
25812
26153
|
return config;
|
|
25813
26154
|
}
|
|
26155
|
+
/** Get form group for a variable by name */
|
|
26156
|
+
getVariableFormGroup(variableName) {
|
|
26157
|
+
const variableIndex = this.variablesForm.controls.findIndex(control => { var _a; return ((_a = control.get('name')) === null || _a === void 0 ? void 0 : _a.value) === variableName; });
|
|
26158
|
+
if (variableIndex !== -1) {
|
|
26159
|
+
return this.variablesForm.at(variableIndex);
|
|
26160
|
+
}
|
|
26161
|
+
return null;
|
|
26162
|
+
}
|
|
26163
|
+
/** Add a new variable to the form array dynamically */
|
|
26164
|
+
addVariable(variable) {
|
|
26165
|
+
var _a;
|
|
26166
|
+
const defaultValue = variable.type === 'boolean'
|
|
26167
|
+
? (variable.value === true || variable.value === 'true' || variable.value === 1)
|
|
26168
|
+
: (variable.value || '');
|
|
26169
|
+
const variableGroup = this.fb.group({
|
|
26170
|
+
name: [variable.name],
|
|
26171
|
+
value: [defaultValue],
|
|
26172
|
+
type: [variable.type || 'string'],
|
|
26173
|
+
label: [variable.label || ''],
|
|
26174
|
+
options: [variable.options || []]
|
|
26175
|
+
});
|
|
26176
|
+
// Add dataType control for test-data variables if needed
|
|
26177
|
+
const label = ((_a = variable.label) === null || _a === void 0 ? void 0 : _a.toLowerCase()) || '';
|
|
26178
|
+
if (label === 'test-data' || label === 'source-value' || label === 'target-value' ||
|
|
26179
|
+
label === 'source_value' || label === 'target_value') {
|
|
26180
|
+
const valueStr = String(defaultValue || '');
|
|
26181
|
+
let dataType = 'plain-text';
|
|
26182
|
+
if (valueStr.startsWith('@|') && valueStr.endsWith('|')) {
|
|
26183
|
+
dataType = 'parameter';
|
|
26184
|
+
}
|
|
26185
|
+
else if (valueStr.startsWith('$|') && valueStr.endsWith('|')) {
|
|
26186
|
+
dataType = 'runtime';
|
|
26187
|
+
}
|
|
26188
|
+
else if (valueStr.startsWith('*|') && valueStr.endsWith('|')) {
|
|
26189
|
+
dataType = 'environment';
|
|
26190
|
+
}
|
|
26191
|
+
variableGroup.addControl('dataType', new FormControl(dataType));
|
|
26192
|
+
}
|
|
26193
|
+
this.variablesForm.push(variableGroup);
|
|
26194
|
+
this.formValidCache = false;
|
|
26195
|
+
}
|
|
25814
26196
|
onVariableValueChange(variableName, value) {
|
|
25815
26197
|
var _a;
|
|
26198
|
+
console.log("onVariableValueChange", variableName, value);
|
|
25816
26199
|
// Update the variable in templateVariables array
|
|
25817
26200
|
const variable = this.templateVariables.find(v => v.name === variableName);
|
|
25818
26201
|
if (variable) {
|
|
25819
26202
|
variable.value = value;
|
|
25820
26203
|
}
|
|
25821
|
-
// Also update form
|
|
25822
|
-
|
|
25823
|
-
|
|
26204
|
+
// Also update form array (use emitEvent: false to prevent triggering valueChanges)
|
|
26205
|
+
const variableIndex = this.variablesForm.controls.findIndex(control => { var _a; return ((_a = control.get('name')) === null || _a === void 0 ? void 0 : _a.value) === variableName; });
|
|
26206
|
+
if (variableIndex !== -1) {
|
|
26207
|
+
(_a = this.variablesForm.at(variableIndex).get('value')) === null || _a === void 0 ? void 0 : _a.setValue(value, { emitEvent: false });
|
|
25824
26208
|
}
|
|
25825
26209
|
// Invalidate form validation cache
|
|
25826
26210
|
this.formValidCache = false;
|
|
26211
|
+
// Update HTML grammar with new value
|
|
26212
|
+
this.updateHtmlGrammar();
|
|
25827
26213
|
}
|
|
25828
26214
|
onVariableBooleanChange(variableName, value) {
|
|
25829
26215
|
var _a;
|
|
@@ -25832,16 +26218,26 @@ class StepBuilderActionComponent {
|
|
|
25832
26218
|
if (variable) {
|
|
25833
26219
|
variable.value = value;
|
|
25834
26220
|
}
|
|
25835
|
-
// Also update form
|
|
25836
|
-
|
|
25837
|
-
|
|
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 });
|
|
25838
26225
|
}
|
|
25839
26226
|
else {
|
|
25840
|
-
// Create form
|
|
25841
|
-
this.
|
|
26227
|
+
// Create new form group if it doesn't exist
|
|
26228
|
+
const variableGroup = this.fb.group({
|
|
26229
|
+
name: [variableName],
|
|
26230
|
+
value: [value],
|
|
26231
|
+
type: ['boolean'],
|
|
26232
|
+
label: [(variable === null || variable === void 0 ? void 0 : variable.label) || ''],
|
|
26233
|
+
options: [(variable === null || variable === void 0 ? void 0 : variable.options) || []]
|
|
26234
|
+
});
|
|
26235
|
+
this.variablesForm.push(variableGroup);
|
|
25842
26236
|
}
|
|
25843
26237
|
// Invalidate form validation cache
|
|
25844
26238
|
this.formValidCache = false;
|
|
26239
|
+
// Update HTML grammar with new value
|
|
26240
|
+
this.updateHtmlGrammar();
|
|
25845
26241
|
}
|
|
25846
26242
|
onBack() {
|
|
25847
26243
|
this.selectedTemplate = null;
|
|
@@ -25849,10 +26245,11 @@ class StepBuilderActionComponent {
|
|
|
25849
26245
|
this.description = '';
|
|
25850
26246
|
this.advancedExpanded = false;
|
|
25851
26247
|
this.templateVariables = [];
|
|
25852
|
-
|
|
25853
|
-
|
|
25854
|
-
|
|
25855
|
-
|
|
26248
|
+
this.updatedHtmlGrammar = '';
|
|
26249
|
+
// Clear form array
|
|
26250
|
+
while (this.variablesForm.length !== 0) {
|
|
26251
|
+
this.variablesForm.removeAt(0);
|
|
26252
|
+
}
|
|
25856
26253
|
// Reapply filter to maintain search state
|
|
25857
26254
|
this.applyFilter();
|
|
25858
26255
|
}
|
|
@@ -25870,22 +26267,22 @@ class StepBuilderActionComponent {
|
|
|
25870
26267
|
return this.formValidCache;
|
|
25871
26268
|
}
|
|
25872
26269
|
// 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
|
-
}
|
|
26270
|
+
// let isValid = true;
|
|
26271
|
+
// if (this.templateVariables && this.templateVariables.length > 0) {
|
|
26272
|
+
// isValid = this.templateVariables.every(variable => {
|
|
26273
|
+
// // Boolean variables are always valid (they have a default value)
|
|
26274
|
+
// if (variable.type === 'boolean') {
|
|
26275
|
+
// return true;
|
|
26276
|
+
// }
|
|
26277
|
+
// // Check if variable has a value
|
|
26278
|
+
// const value = variable.value;
|
|
26279
|
+
// return value !== null && value !== undefined && value !== '';
|
|
26280
|
+
// });
|
|
26281
|
+
// }
|
|
25885
26282
|
// Cache the result
|
|
25886
|
-
this.formValidCache =
|
|
26283
|
+
this.formValidCache = this.variablesForm.valid;
|
|
25887
26284
|
this.lastFormValidationTime = now;
|
|
25888
|
-
return
|
|
26285
|
+
return this.variablesForm.valid;
|
|
25889
26286
|
}
|
|
25890
26287
|
trackByTemplate(index, template) {
|
|
25891
26288
|
return template.id || template.displayName || index;
|
|
@@ -25903,6 +26300,8 @@ class StepBuilderActionComponent {
|
|
|
25903
26300
|
description: this.description,
|
|
25904
26301
|
templateVariables: this.templateVariables
|
|
25905
26302
|
};
|
|
26303
|
+
console.log("stepData", stepData);
|
|
26304
|
+
console.log("variablesForm", this.variablesForm.value);
|
|
25906
26305
|
this.createStep.emit(stepData);
|
|
25907
26306
|
}
|
|
25908
26307
|
toggleAdvanced() {
|
|
@@ -25918,12 +26317,75 @@ class StepBuilderActionComponent {
|
|
|
25918
26317
|
onTestDataValueChange(key, value) {
|
|
25919
26318
|
console.log(key, value);
|
|
25920
26319
|
}
|
|
26320
|
+
/**
|
|
26321
|
+
* Update HTML grammar by replacing placeholder spans with actual variable values
|
|
26322
|
+
*/
|
|
26323
|
+
updateHtmlGrammar() {
|
|
26324
|
+
if (!this.selectedTemplate) {
|
|
26325
|
+
this.updatedHtmlGrammar = '';
|
|
26326
|
+
return;
|
|
26327
|
+
}
|
|
26328
|
+
const htmlGrammar = this.selectedTemplate.htmlGrammar || this.selectedTemplate.naturalText || '';
|
|
26329
|
+
if (!htmlGrammar) {
|
|
26330
|
+
this.updatedHtmlGrammar = '';
|
|
26331
|
+
return;
|
|
26332
|
+
}
|
|
26333
|
+
// Create a map of variable values by name for quick lookup
|
|
26334
|
+
const valueMap = new Map();
|
|
26335
|
+
if (this.templateVariables && Array.isArray(this.templateVariables)) {
|
|
26336
|
+
this.templateVariables.forEach((variable) => {
|
|
26337
|
+
if (variable.name && variable.value !== undefined && variable.value !== null) {
|
|
26338
|
+
// Convert value to string, handling boolean values
|
|
26339
|
+
const valueStr = typeof variable.value === 'boolean'
|
|
26340
|
+
? (variable.value ? 'true' : 'false')
|
|
26341
|
+
: String(variable.value || '');
|
|
26342
|
+
valueMap.set(variable.name, valueStr);
|
|
26343
|
+
}
|
|
26344
|
+
});
|
|
26345
|
+
}
|
|
26346
|
+
// Use browser's DOMParser if available, otherwise fallback to string replacement
|
|
26347
|
+
if (typeof document !== 'undefined' && document.createElement) {
|
|
26348
|
+
try {
|
|
26349
|
+
const tempDiv = document.createElement('div');
|
|
26350
|
+
tempDiv.innerHTML = String(htmlGrammar);
|
|
26351
|
+
// Find all spans with data-event-key attribute
|
|
26352
|
+
const spans = tempDiv.querySelectorAll('span[data-event-key]');
|
|
26353
|
+
spans.forEach((span) => {
|
|
26354
|
+
const eventKey = span.getAttribute('data-event-key');
|
|
26355
|
+
if (eventKey && valueMap.has(eventKey)) {
|
|
26356
|
+
const value = valueMap.get(eventKey);
|
|
26357
|
+
// Preserve the span structure but update the content
|
|
26358
|
+
span.innerHTML = value || '';
|
|
26359
|
+
}
|
|
26360
|
+
});
|
|
26361
|
+
this.updatedHtmlGrammar = tempDiv.innerHTML;
|
|
26362
|
+
}
|
|
26363
|
+
catch (error) {
|
|
26364
|
+
console.error('Error updating HTML grammar:', error);
|
|
26365
|
+
// Fallback to original HTML grammar
|
|
26366
|
+
this.updatedHtmlGrammar = String(htmlGrammar);
|
|
26367
|
+
}
|
|
26368
|
+
}
|
|
26369
|
+
else {
|
|
26370
|
+
// Fallback: simple string replacement for server-side rendering
|
|
26371
|
+
let updatedHtml = String(htmlGrammar);
|
|
26372
|
+
valueMap.forEach((value, key) => {
|
|
26373
|
+
// Replace spans with data-event-key matching the variable name
|
|
26374
|
+
const regex = new RegExp(`<span[^>]*data-event-key="${key}"[^>]*>.*?</span>`, 'gi');
|
|
26375
|
+
updatedHtml = updatedHtml.replace(regex, (match) => {
|
|
26376
|
+
// Replace the content inside the span
|
|
26377
|
+
return match.replace(/>.*?</, `>${value}<`);
|
|
26378
|
+
});
|
|
26379
|
+
});
|
|
26380
|
+
this.updatedHtmlGrammar = updatedHtml;
|
|
26381
|
+
}
|
|
26382
|
+
}
|
|
25921
26383
|
}
|
|
25922
26384
|
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-
|
|
26385
|
+
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
26386
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: StepBuilderActionComponent, decorators: [{
|
|
25925
26387
|
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-
|
|
26388
|
+
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
26389
|
}], ctorParameters: function () { return [{ type: i1$1.FormBuilder }]; }, propDecorators: { showHeader: [{
|
|
25928
26390
|
type: Input
|
|
25929
26391
|
}], templates: [{
|
|
@@ -25934,8 +26396,32 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
|
|
|
25934
26396
|
type: Input
|
|
25935
26397
|
}], preventSelectTemplate: [{
|
|
25936
26398
|
type: Input
|
|
26399
|
+
}], elementOptions: [{
|
|
26400
|
+
type: Input
|
|
26401
|
+
}], hasMoreElements: [{
|
|
26402
|
+
type: Input
|
|
26403
|
+
}], isLoadingElements: [{
|
|
26404
|
+
type: Input
|
|
26405
|
+
}], screenNameOptions: [{
|
|
26406
|
+
type: Input
|
|
26407
|
+
}], hasMoreScreenNames: [{
|
|
26408
|
+
type: Input
|
|
26409
|
+
}], isLoadingScreenNames: [{
|
|
26410
|
+
type: Input
|
|
25937
26411
|
}], templateChanged: [{
|
|
25938
26412
|
type: Output
|
|
26413
|
+
}], loadMoreElements: [{
|
|
26414
|
+
type: Output
|
|
26415
|
+
}], searchElements: [{
|
|
26416
|
+
type: Output
|
|
26417
|
+
}], createElement: [{
|
|
26418
|
+
type: Output
|
|
26419
|
+
}], searchScreenName: [{
|
|
26420
|
+
type: Output
|
|
26421
|
+
}], loadMoreScreenNames: [{
|
|
26422
|
+
type: Output
|
|
26423
|
+
}], createScreenNameRequest: [{
|
|
26424
|
+
type: Output
|
|
25939
26425
|
}], createStep: [{
|
|
25940
26426
|
type: Output
|
|
25941
26427
|
}], cancelled: [{
|
|
@@ -25972,6 +26458,21 @@ class StepBuilderLoopComponent {
|
|
|
25972
26458
|
this.whileTemplates = [];
|
|
25973
26459
|
this.whileSearchPlaceholder = 'Search While';
|
|
25974
26460
|
this.whileSearchValue = '';
|
|
26461
|
+
// Element fetching properties
|
|
26462
|
+
this.elementOptions = [];
|
|
26463
|
+
this.hasMoreElements = false;
|
|
26464
|
+
this.isLoadingElements = false;
|
|
26465
|
+
// Screen name fetching properties
|
|
26466
|
+
this.screenNameOptions = [];
|
|
26467
|
+
this.hasMoreScreenNames = false;
|
|
26468
|
+
this.isLoadingScreenNames = false;
|
|
26469
|
+
this.loadMoreElements = new EventEmitter();
|
|
26470
|
+
this.searchElements = new EventEmitter();
|
|
26471
|
+
this.createElement = new EventEmitter();
|
|
26472
|
+
this.searchScreenName = new EventEmitter();
|
|
26473
|
+
this.loadMoreScreenNames = new EventEmitter();
|
|
26474
|
+
this.createScreenNameRequest = new EventEmitter();
|
|
26475
|
+
this.cancelElementForm = new EventEmitter();
|
|
25975
26476
|
this.selectedWhileTemplate = null;
|
|
25976
26477
|
this.selectedLoopType = 'for';
|
|
25977
26478
|
// Internal state for managing loop indices
|
|
@@ -26298,10 +26799,10 @@ class StepBuilderLoopComponent {
|
|
|
26298
26799
|
}
|
|
26299
26800
|
}
|
|
26300
26801
|
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\"
|
|
26802
|
+
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
26803
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: StepBuilderLoopComponent, decorators: [{
|
|
26303
26804
|
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\"
|
|
26805
|
+
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
26806
|
}], ctorParameters: function () { return []; }, propDecorators: { loopType: [{
|
|
26306
26807
|
type: Input
|
|
26307
26808
|
}], selectOptions: [{
|
|
@@ -26330,6 +26831,32 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
|
|
|
26330
26831
|
type: Input
|
|
26331
26832
|
}], whileSearchValue: [{
|
|
26332
26833
|
type: Input
|
|
26834
|
+
}], elementOptions: [{
|
|
26835
|
+
type: Input
|
|
26836
|
+
}], hasMoreElements: [{
|
|
26837
|
+
type: Input
|
|
26838
|
+
}], isLoadingElements: [{
|
|
26839
|
+
type: Input
|
|
26840
|
+
}], screenNameOptions: [{
|
|
26841
|
+
type: Input
|
|
26842
|
+
}], hasMoreScreenNames: [{
|
|
26843
|
+
type: Input
|
|
26844
|
+
}], isLoadingScreenNames: [{
|
|
26845
|
+
type: Input
|
|
26846
|
+
}], loadMoreElements: [{
|
|
26847
|
+
type: Output
|
|
26848
|
+
}], searchElements: [{
|
|
26849
|
+
type: Output
|
|
26850
|
+
}], createElement: [{
|
|
26851
|
+
type: Output
|
|
26852
|
+
}], searchScreenName: [{
|
|
26853
|
+
type: Output
|
|
26854
|
+
}], loadMoreScreenNames: [{
|
|
26855
|
+
type: Output
|
|
26856
|
+
}], createScreenNameRequest: [{
|
|
26857
|
+
type: Output
|
|
26858
|
+
}], cancelElementForm: [{
|
|
26859
|
+
type: Output
|
|
26333
26860
|
}] } });
|
|
26334
26861
|
|
|
26335
26862
|
class StepBuilderConditionComponent {
|
|
@@ -26349,10 +26876,25 @@ class StepBuilderConditionComponent {
|
|
|
26349
26876
|
this.conditionTemplates = [];
|
|
26350
26877
|
/** Function to handle variable processing or custom logic. Can be passed from parent component. */
|
|
26351
26878
|
this.setConditionTemplateVariables = () => { return []; };
|
|
26879
|
+
this.elementOptions = []; // Element objects for element dropdown
|
|
26880
|
+
this.hasMoreElements = false; // Whether more elements are available
|
|
26881
|
+
this.isLoadingElements = false; // Loading state for elements
|
|
26882
|
+
/** Screen name options for element form autocomplete (from API) */
|
|
26883
|
+
this.screenNameOptions = [];
|
|
26884
|
+
/** Whether more screen names are available for infinite scroll */
|
|
26885
|
+
this.hasMoreScreenNames = false;
|
|
26886
|
+
/** True while parent is loading screen names (search or load more) */
|
|
26887
|
+
this.isLoadingScreenNames = false;
|
|
26352
26888
|
/** Emit when step is created */
|
|
26353
26889
|
this.createStep = new EventEmitter();
|
|
26354
26890
|
/** Emit when cancelled */
|
|
26355
26891
|
this.cancelled = new EventEmitter();
|
|
26892
|
+
this.loadMoreElements = new EventEmitter(); // Emit when load more is requested
|
|
26893
|
+
this.searchElements = new EventEmitter(); // Emit when user searches for elements
|
|
26894
|
+
this.createElement = new EventEmitter(); // Emit when element is created
|
|
26895
|
+
this.searchScreenName = new EventEmitter(); // Emit when user searches screen names
|
|
26896
|
+
this.loadMoreScreenNames = new EventEmitter(); // Emit when user scrolls to load more screen names
|
|
26897
|
+
this.createScreenNameRequest = new EventEmitter(); // Emit when user requests to create a new screen name
|
|
26356
26898
|
this.includeElse = false;
|
|
26357
26899
|
// Cache for value configs to avoid recreating on every change detection
|
|
26358
26900
|
this.valueConfigCache = null;
|
|
@@ -26364,6 +26906,7 @@ class StepBuilderConditionComponent {
|
|
|
26364
26906
|
this.selectedTemplates = new Map();
|
|
26365
26907
|
this.conditionTemplateVariables = new Map();
|
|
26366
26908
|
this.conditionVariablesForms = new Map();
|
|
26909
|
+
this.conditionUpdatedHtmlGrammar = new Map(); // Updated HTML grammar per condition
|
|
26367
26910
|
// Cache for condition form groups to avoid repeated lookups
|
|
26368
26911
|
this.conditionFormGroupCache = new Map();
|
|
26369
26912
|
this.conditionForm = this.fb.group({
|
|
@@ -26412,8 +26955,8 @@ class StepBuilderConditionComponent {
|
|
|
26412
26955
|
});
|
|
26413
26956
|
const index = this.conditionsFormArray.length;
|
|
26414
26957
|
this.conditionsFormArray.push(conditionGroup);
|
|
26415
|
-
// Initialize variables form for this condition
|
|
26416
|
-
this.conditionVariablesForms.set(index, this.fb.
|
|
26958
|
+
// Initialize variables form for this condition (FormArray)
|
|
26959
|
+
this.conditionVariablesForms.set(index, this.fb.array([]));
|
|
26417
26960
|
// Cache the form group
|
|
26418
26961
|
this.conditionFormGroupCache.set(index, conditionGroup);
|
|
26419
26962
|
// Mark for check since we're using OnPush
|
|
@@ -26441,6 +26984,7 @@ class StepBuilderConditionComponent {
|
|
|
26441
26984
|
const newVariablesForms = new Map();
|
|
26442
26985
|
const newFormGroupCache = new Map();
|
|
26443
26986
|
const newValueConfigs = new Map();
|
|
26987
|
+
const newUpdatedHtmlGrammar = new Map();
|
|
26444
26988
|
this.selectedTemplates.forEach((template, oldIndex) => {
|
|
26445
26989
|
if (oldIndex < removedIndex) {
|
|
26446
26990
|
newSelectedTemplates.set(oldIndex, template);
|
|
@@ -26485,11 +27029,20 @@ class StepBuilderConditionComponent {
|
|
|
26485
27029
|
newValueConfigs.set(oldIndex - 1, newConfig);
|
|
26486
27030
|
}
|
|
26487
27031
|
});
|
|
27032
|
+
this.conditionUpdatedHtmlGrammar.forEach((grammar, oldIndex) => {
|
|
27033
|
+
if (oldIndex < removedIndex) {
|
|
27034
|
+
newUpdatedHtmlGrammar.set(oldIndex, grammar);
|
|
27035
|
+
}
|
|
27036
|
+
else if (oldIndex > removedIndex) {
|
|
27037
|
+
newUpdatedHtmlGrammar.set(oldIndex - 1, grammar);
|
|
27038
|
+
}
|
|
27039
|
+
});
|
|
26488
27040
|
this.selectedTemplates = newSelectedTemplates;
|
|
26489
27041
|
this.conditionTemplateVariables = newTemplateVariables;
|
|
26490
27042
|
this.conditionVariablesForms = newVariablesForms;
|
|
26491
27043
|
this.conditionFormGroupCache = newFormGroupCache;
|
|
26492
27044
|
this.valueConfigsWithHandlers = newValueConfigs;
|
|
27045
|
+
this.conditionUpdatedHtmlGrammar = newUpdatedHtmlGrammar;
|
|
26493
27046
|
}
|
|
26494
27047
|
getOperatorConfig(index) {
|
|
26495
27048
|
// Return cached config (static, same for all conditions)
|
|
@@ -26545,54 +27098,99 @@ class StepBuilderConditionComponent {
|
|
|
26545
27098
|
this.conditionTemplateVariables.set(index, variables);
|
|
26546
27099
|
// Build form for template variables
|
|
26547
27100
|
this.buildConditionVariablesForm(index, variables);
|
|
27101
|
+
// Initialize updated HTML grammar
|
|
27102
|
+
this.updateConditionHtmlGrammar(index);
|
|
26548
27103
|
}
|
|
26549
27104
|
else {
|
|
26550
27105
|
// Clear template and variables if no template selected
|
|
26551
27106
|
this.selectedTemplates.delete(index);
|
|
26552
27107
|
this.conditionTemplateVariables.delete(index);
|
|
26553
|
-
|
|
26554
|
-
|
|
26555
|
-
|
|
26556
|
-
|
|
26557
|
-
|
|
27108
|
+
this.conditionUpdatedHtmlGrammar.delete(index);
|
|
27109
|
+
const formArray = this.conditionVariablesForms.get(index);
|
|
27110
|
+
if (formArray) {
|
|
27111
|
+
while (formArray.length !== 0) {
|
|
27112
|
+
formArray.removeAt(0);
|
|
27113
|
+
}
|
|
26558
27114
|
}
|
|
26559
27115
|
}
|
|
26560
27116
|
// Mark for check since we're using OnPush
|
|
26561
27117
|
this.cdr.markForCheck();
|
|
26562
27118
|
}
|
|
26563
27119
|
buildConditionVariablesForm(index, variables) {
|
|
26564
|
-
let
|
|
26565
|
-
if (!
|
|
26566
|
-
|
|
26567
|
-
this.conditionVariablesForms.set(index,
|
|
27120
|
+
let formArray = this.conditionVariablesForms.get(index);
|
|
27121
|
+
if (!formArray) {
|
|
27122
|
+
formArray = this.fb.array([]);
|
|
27123
|
+
this.conditionVariablesForms.set(index, formArray);
|
|
26568
27124
|
}
|
|
26569
|
-
// Ensure
|
|
26570
|
-
if (!
|
|
27125
|
+
// Ensure formArray is not undefined (TypeScript guard)
|
|
27126
|
+
if (!formArray) {
|
|
26571
27127
|
return;
|
|
26572
27128
|
}
|
|
26573
|
-
//
|
|
26574
|
-
|
|
26575
|
-
|
|
26576
|
-
|
|
26577
|
-
|
|
27129
|
+
// Store reference to avoid TypeScript issues in forEach callback
|
|
27130
|
+
// TypeScript knows formArray is defined here due to the early return above
|
|
27131
|
+
const formArrayRef = formArray;
|
|
27132
|
+
// Clear existing form array
|
|
27133
|
+
while (formArrayRef.length !== 0) {
|
|
27134
|
+
formArrayRef.removeAt(0);
|
|
27135
|
+
}
|
|
27136
|
+
// Add form groups for each variable
|
|
26578
27137
|
variables.forEach(variable => {
|
|
27138
|
+
var _a;
|
|
26579
27139
|
// Handle boolean variables - use boolean value, others use string
|
|
26580
27140
|
const defaultValue = variable.type === 'boolean'
|
|
26581
27141
|
? (variable.value === true || variable.value === 'true' || variable.value === 1)
|
|
26582
27142
|
: (variable.value || '');
|
|
26583
|
-
|
|
27143
|
+
// Create a FormGroup for each variable with name and value
|
|
27144
|
+
const variableGroup = this.fb.group({
|
|
27145
|
+
name: [variable.name],
|
|
27146
|
+
value: [defaultValue],
|
|
27147
|
+
type: [variable.type || 'string'],
|
|
27148
|
+
label: [variable.label || ''],
|
|
27149
|
+
options: [variable.options || []]
|
|
27150
|
+
});
|
|
27151
|
+
// Add dataType control for test-data variables if needed
|
|
27152
|
+
const label = ((_a = variable.label) === null || _a === void 0 ? void 0 : _a.toLowerCase()) || '';
|
|
27153
|
+
if (label === 'test-data' || label === 'source-value' || label === 'target-value' ||
|
|
27154
|
+
label === 'source_value' || label === 'target_value') {
|
|
27155
|
+
// Parse the value to determine data type
|
|
27156
|
+
const valueStr = String(defaultValue || '');
|
|
27157
|
+
let dataType = 'plain-text';
|
|
27158
|
+
if (valueStr.startsWith('@|') && valueStr.endsWith('|')) {
|
|
27159
|
+
dataType = 'parameter';
|
|
27160
|
+
}
|
|
27161
|
+
else if (valueStr.startsWith('$|') && valueStr.endsWith('|')) {
|
|
27162
|
+
dataType = 'runtime';
|
|
27163
|
+
}
|
|
27164
|
+
else if (valueStr.startsWith('*|') && valueStr.endsWith('|')) {
|
|
27165
|
+
dataType = 'environment';
|
|
27166
|
+
}
|
|
27167
|
+
variableGroup.addControl('dataType', new FormControl(dataType));
|
|
27168
|
+
}
|
|
27169
|
+
formArrayRef.push(variableGroup);
|
|
26584
27170
|
});
|
|
27171
|
+
// Initialize updated HTML grammar for this condition
|
|
27172
|
+
this.updateConditionHtmlGrammar(index);
|
|
26585
27173
|
}
|
|
26586
27174
|
getConditionTemplateVariables(index) {
|
|
26587
27175
|
return this.conditionTemplateVariables.get(index) || [];
|
|
26588
27176
|
}
|
|
26589
27177
|
getConditionVariablesForm(index) {
|
|
26590
|
-
let
|
|
26591
|
-
if (!
|
|
26592
|
-
|
|
26593
|
-
this.conditionVariablesForms.set(index,
|
|
27178
|
+
let formArray = this.conditionVariablesForms.get(index);
|
|
27179
|
+
if (!formArray) {
|
|
27180
|
+
formArray = this.fb.array([]);
|
|
27181
|
+
this.conditionVariablesForms.set(index, formArray);
|
|
26594
27182
|
}
|
|
26595
|
-
return
|
|
27183
|
+
return formArray;
|
|
27184
|
+
}
|
|
27185
|
+
getConditionFormGroupAt(index, variableIndex) {
|
|
27186
|
+
const formArray = this.getConditionVariablesForm(index);
|
|
27187
|
+
return formArray.at(variableIndex);
|
|
27188
|
+
}
|
|
27189
|
+
getConditionUpdatedHtmlGrammar(index) {
|
|
27190
|
+
const template = this.selectedTemplates.get(index);
|
|
27191
|
+
if (!template)
|
|
27192
|
+
return '';
|
|
27193
|
+
return this.conditionUpdatedHtmlGrammar.get(index) || template.htmlGrammar || template.naturalText || '';
|
|
26596
27194
|
}
|
|
26597
27195
|
getSelectedTemplate(index) {
|
|
26598
27196
|
return this.selectedTemplates.get(index) || null;
|
|
@@ -26623,11 +27221,16 @@ class StepBuilderConditionComponent {
|
|
|
26623
27221
|
if (variable) {
|
|
26624
27222
|
variable.value = value;
|
|
26625
27223
|
}
|
|
26626
|
-
// Also update form
|
|
26627
|
-
const
|
|
26628
|
-
if (
|
|
26629
|
-
(_a =
|
|
27224
|
+
// Also update form array
|
|
27225
|
+
const formArray = this.conditionVariablesForms.get(conditionIndex);
|
|
27226
|
+
if (formArray) {
|
|
27227
|
+
const variableIndex = formArray.controls.findIndex(control => { var _a; return ((_a = control.get('name')) === null || _a === void 0 ? void 0 : _a.value) === variableName; });
|
|
27228
|
+
if (variableIndex !== -1) {
|
|
27229
|
+
(_a = formArray.at(variableIndex).get('value')) === null || _a === void 0 ? void 0 : _a.setValue(value, { emitEvent: false });
|
|
27230
|
+
}
|
|
26630
27231
|
}
|
|
27232
|
+
// Update HTML grammar for this condition
|
|
27233
|
+
this.updateConditionHtmlGrammar(conditionIndex);
|
|
26631
27234
|
// Mark for check since we're using OnPush
|
|
26632
27235
|
this.cdr.markForCheck();
|
|
26633
27236
|
}
|
|
@@ -26653,20 +27256,63 @@ class StepBuilderConditionComponent {
|
|
|
26653
27256
|
if (variable) {
|
|
26654
27257
|
variable.value = value;
|
|
26655
27258
|
}
|
|
26656
|
-
// Also update form
|
|
26657
|
-
const
|
|
26658
|
-
if (
|
|
26659
|
-
|
|
26660
|
-
|
|
26661
|
-
|
|
26662
|
-
|
|
26663
|
-
|
|
26664
|
-
form.addControl(variableName, new FormControl(value));
|
|
26665
|
-
}
|
|
27259
|
+
// Also update form array
|
|
27260
|
+
const formArray = this.conditionVariablesForms.get(conditionIndex);
|
|
27261
|
+
if (!formArray) {
|
|
27262
|
+
return;
|
|
27263
|
+
}
|
|
27264
|
+
const variableIndex = formArray.controls.findIndex(control => { var _a; return ((_a = control.get('name')) === null || _a === void 0 ? void 0 : _a.value) === variableName; });
|
|
27265
|
+
if (variableIndex !== -1) {
|
|
27266
|
+
(_a = formArray.at(variableIndex).get('value')) === null || _a === void 0 ? void 0 : _a.setValue(value, { emitEvent: false });
|
|
26666
27267
|
}
|
|
27268
|
+
else {
|
|
27269
|
+
// Create new form group if it doesn't exist
|
|
27270
|
+
const variableGroup = this.fb.group({
|
|
27271
|
+
name: [variableName],
|
|
27272
|
+
value: [value],
|
|
27273
|
+
type: ['boolean'],
|
|
27274
|
+
label: [(variable === null || variable === void 0 ? void 0 : variable.label) || ''],
|
|
27275
|
+
options: [(variable === null || variable === void 0 ? void 0 : variable.options) || []]
|
|
27276
|
+
});
|
|
27277
|
+
// formArray is guaranteed to be defined here due to the early return above
|
|
27278
|
+
formArray.push(variableGroup);
|
|
27279
|
+
}
|
|
27280
|
+
// Update HTML grammar for this condition
|
|
27281
|
+
this.updateConditionHtmlGrammar(conditionIndex);
|
|
26667
27282
|
// Mark for check since we're using OnPush
|
|
26668
27283
|
this.cdr.markForCheck();
|
|
26669
27284
|
}
|
|
27285
|
+
/**
|
|
27286
|
+
* Strip HTML tags from a string for search functionality
|
|
27287
|
+
*/
|
|
27288
|
+
stripHtmlTags(htmlString) {
|
|
27289
|
+
if (!htmlString)
|
|
27290
|
+
return '';
|
|
27291
|
+
// Create a temporary div element to parse HTML
|
|
27292
|
+
const tmp = document.createElement('DIV');
|
|
27293
|
+
tmp.innerHTML = htmlString;
|
|
27294
|
+
return tmp.textContent || tmp.innerText || '';
|
|
27295
|
+
}
|
|
27296
|
+
/**
|
|
27297
|
+
* Update HTML grammar for a specific condition with actual variable values
|
|
27298
|
+
*/
|
|
27299
|
+
updateConditionHtmlGrammar(conditionIndex) {
|
|
27300
|
+
const template = this.selectedTemplates.get(conditionIndex);
|
|
27301
|
+
if (!template || !template.htmlGrammar) {
|
|
27302
|
+
return;
|
|
27303
|
+
}
|
|
27304
|
+
let updatedGrammar = template.htmlGrammar;
|
|
27305
|
+
const variables = this.conditionTemplateVariables.get(conditionIndex) || [];
|
|
27306
|
+
// Replace placeholders with actual values
|
|
27307
|
+
variables.forEach(variable => {
|
|
27308
|
+
const placeholder = new RegExp(`<span[^>]*data-event-key="${variable.name}"[^>]*>.*?</span>`, 'gi');
|
|
27309
|
+
const value = variable.value || '';
|
|
27310
|
+
// Escape HTML in value to prevent XSS
|
|
27311
|
+
const escapedValue = String(value).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
27312
|
+
updatedGrammar = updatedGrammar.replace(placeholder, escapedValue);
|
|
27313
|
+
});
|
|
27314
|
+
this.conditionUpdatedHtmlGrammar.set(conditionIndex, updatedGrammar);
|
|
27315
|
+
}
|
|
26670
27316
|
getConditionFormGroup(index) {
|
|
26671
27317
|
// Use cache to avoid repeated lookups
|
|
26672
27318
|
if (this.conditionFormGroupCache.has(index)) {
|
|
@@ -26736,20 +27382,44 @@ class StepBuilderConditionComponent {
|
|
|
26736
27382
|
}
|
|
26737
27383
|
}
|
|
26738
27384
|
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
|
|
27385
|
+
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
27386
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: StepBuilderConditionComponent, decorators: [{
|
|
26741
27387
|
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
|
|
27388
|
+
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
27389
|
}], ctorParameters: function () { return [{ type: i1$1.FormBuilder }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { operatorOptions: [{
|
|
26744
27390
|
type: Input
|
|
26745
27391
|
}], conditionTemplates: [{
|
|
26746
27392
|
type: Input
|
|
26747
27393
|
}], setConditionTemplateVariables: [{
|
|
26748
27394
|
type: Input
|
|
27395
|
+
}], elementOptions: [{
|
|
27396
|
+
type: Input
|
|
27397
|
+
}], hasMoreElements: [{
|
|
27398
|
+
type: Input
|
|
27399
|
+
}], isLoadingElements: [{
|
|
27400
|
+
type: Input
|
|
27401
|
+
}], screenNameOptions: [{
|
|
27402
|
+
type: Input
|
|
27403
|
+
}], hasMoreScreenNames: [{
|
|
27404
|
+
type: Input
|
|
27405
|
+
}], isLoadingScreenNames: [{
|
|
27406
|
+
type: Input
|
|
26749
27407
|
}], createStep: [{
|
|
26750
27408
|
type: Output
|
|
26751
27409
|
}], cancelled: [{
|
|
26752
27410
|
type: Output
|
|
27411
|
+
}], loadMoreElements: [{
|
|
27412
|
+
type: Output
|
|
27413
|
+
}], searchElements: [{
|
|
27414
|
+
type: Output
|
|
27415
|
+
}], createElement: [{
|
|
27416
|
+
type: Output
|
|
27417
|
+
}], searchScreenName: [{
|
|
27418
|
+
type: Output
|
|
27419
|
+
}], loadMoreScreenNames: [{
|
|
27420
|
+
type: Output
|
|
27421
|
+
}], createScreenNameRequest: [{
|
|
27422
|
+
type: Output
|
|
26753
27423
|
}] } });
|
|
26754
27424
|
|
|
26755
27425
|
class StepBuilderDatabaseComponent {
|
|
@@ -30469,6 +31139,7 @@ UiKitModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "1
|
|
|
30469
31139
|
StepBuilderActionComponent,
|
|
30470
31140
|
StepBuilderLoopComponent,
|
|
30471
31141
|
ElementPopupComponent,
|
|
31142
|
+
ElementFormComponent,
|
|
30472
31143
|
StepBuilderConditionComponent,
|
|
30473
31144
|
StepBuilderDatabaseComponent,
|
|
30474
31145
|
StepBuilderAiAgentComponent,
|
|
@@ -30612,6 +31283,7 @@ UiKitModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "1
|
|
|
30612
31283
|
StepBuilderActionComponent,
|
|
30613
31284
|
StepBuilderLoopComponent,
|
|
30614
31285
|
ElementPopupComponent,
|
|
31286
|
+
ElementFormComponent,
|
|
30615
31287
|
StepBuilderConditionComponent,
|
|
30616
31288
|
StepBuilderDatabaseComponent,
|
|
30617
31289
|
StepBuilderAiAgentComponent,
|
|
@@ -30804,6 +31476,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
|
|
|
30804
31476
|
StepBuilderActionComponent,
|
|
30805
31477
|
StepBuilderLoopComponent,
|
|
30806
31478
|
ElementPopupComponent,
|
|
31479
|
+
ElementFormComponent,
|
|
30807
31480
|
StepBuilderConditionComponent,
|
|
30808
31481
|
StepBuilderDatabaseComponent,
|
|
30809
31482
|
StepBuilderAiAgentComponent,
|
|
@@ -30953,6 +31626,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
|
|
|
30953
31626
|
StepBuilderActionComponent,
|
|
30954
31627
|
StepBuilderLoopComponent,
|
|
30955
31628
|
ElementPopupComponent,
|
|
31629
|
+
ElementFormComponent,
|
|
30956
31630
|
StepBuilderConditionComponent,
|
|
30957
31631
|
StepBuilderDatabaseComponent,
|
|
30958
31632
|
StepBuilderAiAgentComponent,
|
|
@@ -31647,5 +32321,5 @@ function buildTestCaseDetailsFromApi(data, options) {
|
|
|
31647
32321
|
* Generated bundle index. Do not edit.
|
|
31648
32322
|
*/
|
|
31649
32323
|
|
|
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 };
|
|
32324
|
+
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
32325
|
//# sourceMappingURL=cqa-lib-cqa-ui.mjs.map
|