@cqa-lib/cqa-ui 1.1.493 → 1.1.495
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/execution-screen/self-heal-analysis/self-heal-analysis.component.mjs +32 -5
- package/esm2020/lib/mixed-variable-input/mixed-variable-input.component.mjs +372 -98
- package/esm2020/lib/step-builder/template-variables-form/template-variables-form.component.mjs +31 -3
- package/fesm2015/cqa-lib-cqa-ui.mjs +441 -104
- package/fesm2015/cqa-lib-cqa-ui.mjs.map +1 -1
- package/fesm2020/cqa-lib-cqa-ui.mjs +435 -106
- package/fesm2020/cqa-lib-cqa-ui.mjs.map +1 -1
- package/lib/execution-screen/self-heal-analysis/self-heal-analysis.component.d.ts +8 -2
- package/lib/mixed-variable-input/mixed-variable-input.component.d.ts +30 -3
- package/lib/step-builder/template-variables-form/template-variables-form.component.d.ts +7 -0
- package/package.json +1 -1
- package/styles.css +1 -1
|
@@ -9462,6 +9462,13 @@ class SelfHealAnalysisComponent {
|
|
|
9462
9462
|
this.isLoadingAccept = false;
|
|
9463
9463
|
this.isLoadingModifyAccept = false;
|
|
9464
9464
|
this.action = new EventEmitter();
|
|
9465
|
+
this.isEditMode = false;
|
|
9466
|
+
// Set when Accept is clicked in edit mode; gates the ngOnChanges reset so that
|
|
9467
|
+
// unrelated isLoadingModifyAccept changes (initial binding, parent pre-set) don't exit edit mode.
|
|
9468
|
+
this.awaitingModifyAcceptResponse = false;
|
|
9469
|
+
}
|
|
9470
|
+
get isAcceptLoading() {
|
|
9471
|
+
return this.isLoadingAccept || (this.isEditMode && this.isLoadingModifyAccept);
|
|
9465
9472
|
}
|
|
9466
9473
|
ngOnInit() {
|
|
9467
9474
|
// Build data from individual inputs
|
|
@@ -9471,22 +9478,42 @@ class SelfHealAnalysisComponent {
|
|
|
9471
9478
|
confidence: this.confidence,
|
|
9472
9479
|
healMethod: this.healMethod,
|
|
9473
9480
|
};
|
|
9481
|
+
this.initialHealedLocator = this.healedLocator;
|
|
9482
|
+
}
|
|
9483
|
+
ngOnChanges(changes) {
|
|
9484
|
+
const modifyChange = changes['isLoadingModifyAccept'];
|
|
9485
|
+
if (this.awaitingModifyAcceptResponse &&
|
|
9486
|
+
modifyChange &&
|
|
9487
|
+
modifyChange.previousValue === true &&
|
|
9488
|
+
modifyChange.currentValue === false) {
|
|
9489
|
+
this.awaitingModifyAcceptResponse = false;
|
|
9490
|
+
this.initialHealedLocator = this.data.healedLocator;
|
|
9491
|
+
this.isEditMode = false;
|
|
9492
|
+
}
|
|
9474
9493
|
}
|
|
9475
9494
|
onAccept() {
|
|
9476
|
-
|
|
9495
|
+
const type = this.isEditMode ? 'modify-accept' : 'accept';
|
|
9496
|
+
if (type === 'modify-accept') {
|
|
9497
|
+
this.awaitingModifyAcceptResponse = true;
|
|
9498
|
+
}
|
|
9499
|
+
this.action.emit({ type, id: this.id, healedLocator: this.data.healedLocator, testStepId: this.id });
|
|
9477
9500
|
}
|
|
9478
9501
|
onReject() {
|
|
9479
9502
|
this.action.emit({ type: 'reject', id: this.id, healedLocator: this.data.healedLocator, testStepId: this.id });
|
|
9480
9503
|
}
|
|
9481
9504
|
onModifyAccept() {
|
|
9482
|
-
this.
|
|
9505
|
+
this.isEditMode = true;
|
|
9506
|
+
}
|
|
9507
|
+
onCancelModify() {
|
|
9508
|
+
this.data.healedLocator = this.initialHealedLocator;
|
|
9509
|
+
this.isEditMode = false;
|
|
9483
9510
|
}
|
|
9484
9511
|
}
|
|
9485
9512
|
SelfHealAnalysisComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: SelfHealAnalysisComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
9486
|
-
SelfHealAnalysisComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: SelfHealAnalysisComponent, selector: "cqa-self-heal-analysis", inputs: { id: "id", originalLocator: "originalLocator", healedLocator: "healedLocator", confidence: "confidence", healMethod: "healMethod", isLoadingAccept: "isLoadingAccept", isLoadingModifyAccept: "isLoadingModifyAccept" }, outputs: { action: "action" }, host: { classAttribute: "cqa-ui-root" }, ngImport: i0, template: "<div class=\"cqa-bg-[#E7F8F2] cqa-border cqa-border-solid cqa-border-[#0B9D68] cqa-mt-1.5 cqa-ml-9 cqa-mr-6 cqa-px-4 cqa-py-3 cqa-rounded-lg\">\n <!-- Header -->\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-2 cqa-mb-1.5\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-1.5\">\n <div><svg width=\"17\" height=\"17\" viewBox=\"0 0 17 17\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><rect width=\"17\" height=\"17\" rx=\"8.5\" fill=\"#AEE9D4\"/><path d=\"M8.50941 4C8.56489 4.02274 8.58859 4.07827 8.61131 4.12985C8.62269 4.1599 8.63314 4.19012 8.64329 4.22058C8.64726 4.23225 8.65123 4.24392 8.65532 4.25594C8.70806 4.413 8.75504 4.57175 8.80229 4.73038C8.81297 4.76619 8.82369 4.80199 8.83442 4.83778C8.88905 5.02004 8.94327 5.2024 8.99719 5.38484C9.00476 5.41047 9.01234 5.43609 9.01992 5.46171C9.04128 5.53395 9.06262 5.60619 9.08383 5.67847C9.12867 5.8312 9.17473 5.98347 9.22378 6.13501C9.22807 6.14827 9.23236 6.16152 9.23677 6.17518C9.3642 6.565 9.54482 6.91437 9.8409 7.21196C9.84823 7.2197 9.85556 7.22744 9.86312 7.23541C9.9895 7.36437 10.1517 7.46771 10.3138 7.55111C10.3221 7.55542 10.3303 7.55974 10.3388 7.56419C10.8159 7.80925 11.3895 7.91704 11.9062 8.0605C12.1326 8.1234 12.3583 8.18829 12.5832 8.25603C12.599 8.26079 12.6148 8.26554 12.6306 8.27028C12.6778 8.28445 12.725 8.29887 12.7721 8.31347C12.7831 8.31679 12.7941 8.32011 12.8054 8.32353C12.8703 8.34406 12.9324 8.36829 12.9857 8.41027C13.0019 8.44418 13.0019 8.44418 12.9975 8.4781C12.9456 8.52736 12.8942 8.55046 12.8258 8.573C12.816 8.57632 12.8062 8.57965 12.7961 8.58308C12.6806 8.62183 12.5635 8.65575 12.4463 8.68935C12.4222 8.6963 12.3981 8.70326 12.3741 8.71021C12.2257 8.75301 12.0771 8.7949 11.9283 8.83632C11.7323 8.89088 11.5366 8.94634 11.3411 9.00243C11.3091 9.01162 11.2771 9.02078 11.245 9.02991C11.0767 9.07786 10.9092 9.12753 10.7431 9.18208C10.7294 9.18659 10.7156 9.1911 10.7014 9.19574C10.1451 9.38082 9.7211 9.72609 9.45571 10.231C9.31263 10.5148 9.22823 10.8216 9.14214 11.1245C9.11884 11.2062 9.09409 11.2875 9.06905 11.3687C9.0494 11.4326 9.0302 11.4966 9.01149 11.5608C9.00926 11.5684 9.00703 11.5761 9.00473 11.5839C8.99394 11.6209 8.98319 11.6579 8.97252 11.695C8.94519 11.7888 8.91578 11.8819 8.88555 11.9749C8.83191 12.1402 8.7831 12.3067 8.73459 12.4735C8.66144 12.7246 8.66144 12.7246 8.61997 12.8453C8.61721 12.8534 8.61446 12.8615 8.61163 12.8698C8.59649 12.9128 8.58092 12.9523 8.55226 12.9887C8.50867 12.9979 8.50867 12.9979 8.46951 13C8.42473 12.9376 8.39508 12.8771 8.37133 12.8051C8.36787 12.7949 8.36441 12.7847 8.36085 12.7741C8.31684 12.6425 8.27751 12.5095 8.23817 12.3765C8.22916 12.346 8.22011 12.3156 8.21105 12.2852C8.1436 12.0586 8.07725 11.8317 8.01101 11.6048C7.73507 10.4822 7.73507 10.4822 7.039 9.57466C7.02784 9.56596 7.01669 9.55726 7.00519 9.5483C6.54913 9.19902 5.94834 9.06969 5.39815 8.91813C5.26207 8.88062 5.12605 8.84293 4.99003 8.80523C4.97814 8.80193 4.97814 8.80193 4.966 8.79857C4.76981 8.74417 4.57367 8.68963 4.37822 8.63283C4.36996 8.63045 4.36169 8.62806 4.35317 8.62561C4.0529 8.53883 4.0529 8.53883 4.00065 8.4781C3.99917 8.45054 3.99917 8.45054 4.01247 8.42157C4.06708 8.3704 4.12008 8.34848 4.19216 8.32619C4.2026 8.32284 4.21303 8.31948 4.22379 8.31603C4.25575 8.30582 4.28779 8.29584 4.31985 8.28592C4.329 8.28305 4.33815 8.28017 4.34758 8.27722C4.41228 8.25693 4.47722 8.2374 4.54226 8.21809C4.55824 8.21332 4.55824 8.21332 4.57454 8.20846C4.85227 8.12587 5.13181 8.049 5.41126 7.97196C5.6195 7.91455 5.82738 7.85618 6.0346 7.79548C6.04413 7.79271 6.05365 7.78993 6.06346 7.78707C6.5435 7.64696 7.01278 7.44816 7.32274 7.0537C7.32738 7.04785 7.33202 7.042 7.3368 7.03597C7.68197 6.59815 7.81658 6.06572 7.96695 5.54621C8.01643 5.37534 8.06649 5.20464 8.11673 5.03399C8.13064 4.98673 8.14453 4.93947 8.15836 4.89219C8.21394 4.70229 8.27035 4.51264 8.33 4.32386C8.33558 4.30619 8.34114 4.2885 8.34666 4.27081C8.43017 4.00399 8.43017 4.00399 8.50941 4Z\" fill=\"#0DBD7D\"/><path d=\"M11.236 4.55535C11.2902 4.61409 11.3011 4.68312 11.318 4.75813C11.3744 4.99376 11.4393 5.21042 11.6647 5.3473C11.8037 5.42083 11.9694 5.4543 12.1235 5.4859C12.1885 5.49951 12.2435 5.51758 12.2992 5.5537C12.3118 5.57278 12.3118 5.57278 12.3111 5.60598C12.2981 5.64637 12.2868 5.65939 12.2527 5.68582C12.2154 5.69775 12.2154 5.69775 12.1707 5.70702C12.1537 5.71074 12.1368 5.71449 12.1199 5.71828C12.1109 5.72029 12.1018 5.7223 12.0925 5.72437C11.817 5.78531 11.817 5.78531 11.5788 5.92322C11.5711 5.92918 11.5633 5.93514 11.5554 5.94128C11.3852 6.08479 11.3492 6.32351 11.2979 6.5235C11.295 6.53448 11.2921 6.54546 11.289 6.55678C11.2865 6.5665 11.284 6.57622 11.2813 6.58624C11.2703 6.61593 11.2588 6.63528 11.236 6.65803C11.1723 6.66576 11.1723 6.66576 11.1414 6.65803C11.0922 6.62155 11.0811 6.57999 11.0683 6.52414C11.0661 6.51549 11.064 6.50685 11.0618 6.49794C11.0549 6.47032 11.0482 6.44266 11.0416 6.41498C10.9898 6.19946 10.9313 5.988 10.7245 5.86167C10.5629 5.7755 10.3665 5.73475 10.1859 5.70185C10.1364 5.69199 10.108 5.6796 10.0774 5.6406C10.0707 5.60104 10.0707 5.60104 10.0774 5.56147C10.1245 5.51486 10.174 5.50348 10.2377 5.4894C10.2578 5.48465 10.2778 5.47987 10.2979 5.47505C10.3083 5.47258 10.3186 5.47011 10.3293 5.46756C10.3821 5.45456 10.4344 5.43998 10.4867 5.42511C10.4962 5.42247 10.5057 5.41984 10.5155 5.41712C10.6218 5.38673 10.7136 5.34786 10.7985 5.27885C10.8065 5.27261 10.8144 5.26638 10.8226 5.25995C10.9548 5.14614 10.9997 4.97516 11.0405 4.81562C11.0436 4.80351 11.0467 4.7914 11.0499 4.77892C11.0561 4.75459 11.0622 4.73023 11.0682 4.70585C11.0724 4.68888 11.0724 4.68888 11.0768 4.67157C11.0793 4.66144 11.0818 4.6513 11.0843 4.64086C11.0952 4.6086 11.1095 4.58326 11.1296 4.55535C11.1681 4.53692 11.1951 4.54525 11.236 4.55535Z\" fill=\"#075F3F\"/><path d=\"M5.79542 10.2472C5.80948 10.2473 5.80948 10.2473 5.82383 10.2474C5.92474 10.2503 5.99301 10.2813 6.06733 10.3461C6.15381 10.4355 6.19374 10.5362 6.19146 10.6566C6.18175 10.7542 6.12155 10.8395 6.0477 10.9055C5.96078 10.9725 5.8731 10.9947 5.76203 10.9916C5.66838 10.9812 5.58027 10.9386 5.51389 10.8746C5.43135 10.7669 5.40722 10.6682 5.41932 10.5355C5.4443 10.431 5.51634 10.3463 5.60847 10.2868C5.67248 10.2558 5.72396 10.2466 5.79542 10.2472Z\" fill=\"#0DBD7D\"/></svg></div>\n <span class=\"cqa-text-[12px] cqa-leading-[15px] cqa-font-medium cqa-text-[#075F3F]\">Self Heal Analysis</span>\n </div>\n <span class=\"cqa-px-1.5 cqa-rounded-full cqa-font-medium cqa-text-[#043F2A] cqa-bg-[#AEE9D4] cqa-text-[8px] cqa-leading-[12px]\" *ngIf=\"data?.confidence\">\n Confidence : {{ data.confidence }}%\n </span>\n </div>\n\n <!-- Locators Comparison -->\n <div class=\"cqa-grid cqa-grid-cols-2 cqa-gap-3 cqa-mb-1.5\">\n <!-- Original Locator -->\n <div>\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-1 cqa-mb-1 cqa-text-[8px] cqa-leading-[12px]\">\n <div class=\"cqa-text-[#075F3F]\">Original Locator</div>\n <div class=\"cqa-text-[#F87171]\">Failed</div>\n </div>\n <input \n type=\"text\" \n [(ngModel)]=\"data.originalLocator\" \n readonly\n class=\"cqa-w-full cqa-py-1 cqa-px-3 !cqa-border !cqa-border-solid !cqa-border-[#FEF3C7] cqa-rounded !cqa-bg-white cqa-text-[8px] cqa-leading-[12px] cqa-text-[#64748B]\"\n />\n </div>\n\n <!-- Healed Locator -->\n <div>\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-1 cqa-mb-1 cqa-text-[8px] cqa-leading-[12px]\">\n <div class=\"cqa-text-[#075F3F]\">Current Locator</div>\n <div class=\"cqa-flex cqa-items-center cqa-gap-[2px] cqa-text-[#10B981]\">\n <div><svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M5.00001 9.16671C7.3012 9.16671 9.16668 7.30123 9.16668 5.00004C9.16668 2.69885 7.3012 0.833374 5.00001 0.833374C2.69882 0.833374 0.833344 2.69885 0.833344 5.00004C0.833344 7.30123 2.69882 9.16671 5.00001 9.16671Z\" stroke=\"#10B981\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M3.75 4.99996L4.58333 5.83329L6.25 4.16663\" stroke=\"#10B981\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg></div>\n <span>Applied</span>\n </div>\n </div>\n <input \n type=\"text\" \n [(ngModel)]=\"data.healedLocator\" \n class=\"cqa-w-full cqa-py-1 cqa-px-3 !cqa-border !cqa-border-solid !cqa-border-[#A7F3D0] cqa-rounded !cqa-bg-white cqa-text-[8px] cqa-leading-[12px] cqa-text-[#047857]\"\n />\n </div>\n </div>\n\n <!-- Heal Method -->\n <!-- <div class=\"cqa-mb-1.5 cqa-flex cqa-items-center cqa-gap-2\">\n <span class=\"cqa-text-[8px] cqa-leading-[12px] cqa-text-[#0B9D68]\">Heal Method:</span>\n <span class=\"cqa-px-2 cqa-py-[2px] cqa-rounded cqa-text-[8px] cqa-leading-[12px] cqa-bg-[#AEE9D4] cqa-text-[#075F3F] cqa-border cqa-border-solid cqa-border-[#0DBD7D]\">\n {{ data.healMethod }}\n </span>\n </div> -->\n\n <!-- Action Buttons -->\n <div class=\"cqa-flex cqa-items-center cqa-justify-end cqa-gap-2 cqa-flex-wrap\">\n <button \n (click)=\"onAccept()\"\n [disabled]=\"isLoadingAccept || isLoadingModifyAccept\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-pl-2 cqa-pr-4 cqa-py-[2px] cqa-rounded-lg cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-bg-transparent cqa-text-[#097E53] cqa-border cqa-border-solid cqa-border-[#097E53]\">\n <svg *ngIf=\"!isLoadingAccept\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4.39748 7.93746L2.31248 5.85246L1.60248 6.55746L4.39748 9.35246L10.3975 3.35246L9.69248 2.64746L4.39748 7.93746Z\" fill=\"#097E53\"/></svg>\n <svg *ngIf=\"isLoadingAccept\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-dasharray=\"8 4\" opacity=\"0.3\"/>\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-dasharray=\"8 4\" stroke-dashoffset=\"2\">\n <animateTransform attributeName=\"transform\" type=\"rotate\" values=\"0 6 6;360 6 6\" dur=\"1s\" repeatCount=\"indefinite\"/>\n </circle>\n </svg>\n <span>{{ isLoadingAccept ? 'Loading...' : 'Accept' }}</span>\n </button>\n <!-- <button \n (click)=\"onReject()\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-pl-2 cqa-pr-4 cqa-py-[2px] cqa-rounded-lg cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-bg-transparent cqa-text-[#9F2A2A] cqa-border cqa-border-solid cqa-border-[#9F2A2A]\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M9.5 3.205L8.795 2.5L6 5.295L3.205 2.5L2.5 3.205L5.295 6L2.5 8.795L3.205 9.5L6 6.705L8.795 9.5L9.5 8.795L6.705 6L9.5 3.205Z\" fill=\"#9F2A2A\"/></svg>\n Reject\n </button> -->\n <button \n (click)=\"onModifyAccept()\"\n [disabled]=\"isLoadingAccept || isLoadingModifyAccept\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-pl-2 cqa-pr-4 cqa-py-[2px] cqa-rounded-lg cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-bg-transparent cqa-text-[#B18618] cqa-border cqa-border-solid cqa-border-[#B18618]\">\n <svg *ngIf=\"!isLoadingModifyAccept\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M7.02939 4.51L7.48939 4.97L2.95939 9.5H2.49939V9.04L7.02939 4.51ZM8.82939 1.5C8.70439 1.5 8.57439 1.55 8.47939 1.645L7.56439 2.56L9.43939 4.435L10.3544 3.52C10.5494 3.325 10.5494 3.01 10.3544 2.815L9.18439 1.645C9.08439 1.545 8.95939 1.5 8.82939 1.5ZM7.02939 3.095L1.49939 8.625V10.5H3.37439L8.90439 4.97L7.02939 3.095Z\" fill=\"#B18618\"/></svg>\n <svg *ngIf=\"isLoadingModifyAccept\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-dasharray=\"8 4\" opacity=\"0.3\"/>\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-dasharray=\"8 4\" stroke-dashoffset=\"2\">\n <animateTransform attributeName=\"transform\" type=\"rotate\" values=\"0 6 6;360 6 6\" dur=\"1s\" repeatCount=\"indefinite\"/>\n </circle>\n </svg>\n <span>{{ isLoadingModifyAccept ? 'Loading...' : 'Modify & Accept' }}</span>\n </button>\n </div>\n</div>\n", directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { 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"] }] });
|
|
9513
|
+
SelfHealAnalysisComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: SelfHealAnalysisComponent, selector: "cqa-self-heal-analysis", inputs: { id: "id", originalLocator: "originalLocator", healedLocator: "healedLocator", confidence: "confidence", healMethod: "healMethod", isLoadingAccept: "isLoadingAccept", isLoadingModifyAccept: "isLoadingModifyAccept" }, outputs: { action: "action" }, host: { classAttribute: "cqa-ui-root" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"cqa-bg-[#E7F8F2] cqa-border cqa-border-solid cqa-border-[#0B9D68] cqa-mt-1.5 cqa-ml-9 cqa-mr-6 cqa-px-4 cqa-py-3 cqa-rounded-lg\">\n <!-- Header -->\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-2 cqa-mb-1.5\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-1.5\">\n <div><svg width=\"17\" height=\"17\" viewBox=\"0 0 17 17\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><rect width=\"17\" height=\"17\" rx=\"8.5\" fill=\"#AEE9D4\"/><path d=\"M8.50941 4C8.56489 4.02274 8.58859 4.07827 8.61131 4.12985C8.62269 4.1599 8.63314 4.19012 8.64329 4.22058C8.64726 4.23225 8.65123 4.24392 8.65532 4.25594C8.70806 4.413 8.75504 4.57175 8.80229 4.73038C8.81297 4.76619 8.82369 4.80199 8.83442 4.83778C8.88905 5.02004 8.94327 5.2024 8.99719 5.38484C9.00476 5.41047 9.01234 5.43609 9.01992 5.46171C9.04128 5.53395 9.06262 5.60619 9.08383 5.67847C9.12867 5.8312 9.17473 5.98347 9.22378 6.13501C9.22807 6.14827 9.23236 6.16152 9.23677 6.17518C9.3642 6.565 9.54482 6.91437 9.8409 7.21196C9.84823 7.2197 9.85556 7.22744 9.86312 7.23541C9.9895 7.36437 10.1517 7.46771 10.3138 7.55111C10.3221 7.55542 10.3303 7.55974 10.3388 7.56419C10.8159 7.80925 11.3895 7.91704 11.9062 8.0605C12.1326 8.1234 12.3583 8.18829 12.5832 8.25603C12.599 8.26079 12.6148 8.26554 12.6306 8.27028C12.6778 8.28445 12.725 8.29887 12.7721 8.31347C12.7831 8.31679 12.7941 8.32011 12.8054 8.32353C12.8703 8.34406 12.9324 8.36829 12.9857 8.41027C13.0019 8.44418 13.0019 8.44418 12.9975 8.4781C12.9456 8.52736 12.8942 8.55046 12.8258 8.573C12.816 8.57632 12.8062 8.57965 12.7961 8.58308C12.6806 8.62183 12.5635 8.65575 12.4463 8.68935C12.4222 8.6963 12.3981 8.70326 12.3741 8.71021C12.2257 8.75301 12.0771 8.7949 11.9283 8.83632C11.7323 8.89088 11.5366 8.94634 11.3411 9.00243C11.3091 9.01162 11.2771 9.02078 11.245 9.02991C11.0767 9.07786 10.9092 9.12753 10.7431 9.18208C10.7294 9.18659 10.7156 9.1911 10.7014 9.19574C10.1451 9.38082 9.7211 9.72609 9.45571 10.231C9.31263 10.5148 9.22823 10.8216 9.14214 11.1245C9.11884 11.2062 9.09409 11.2875 9.06905 11.3687C9.0494 11.4326 9.0302 11.4966 9.01149 11.5608C9.00926 11.5684 9.00703 11.5761 9.00473 11.5839C8.99394 11.6209 8.98319 11.6579 8.97252 11.695C8.94519 11.7888 8.91578 11.8819 8.88555 11.9749C8.83191 12.1402 8.7831 12.3067 8.73459 12.4735C8.66144 12.7246 8.66144 12.7246 8.61997 12.8453C8.61721 12.8534 8.61446 12.8615 8.61163 12.8698C8.59649 12.9128 8.58092 12.9523 8.55226 12.9887C8.50867 12.9979 8.50867 12.9979 8.46951 13C8.42473 12.9376 8.39508 12.8771 8.37133 12.8051C8.36787 12.7949 8.36441 12.7847 8.36085 12.7741C8.31684 12.6425 8.27751 12.5095 8.23817 12.3765C8.22916 12.346 8.22011 12.3156 8.21105 12.2852C8.1436 12.0586 8.07725 11.8317 8.01101 11.6048C7.73507 10.4822 7.73507 10.4822 7.039 9.57466C7.02784 9.56596 7.01669 9.55726 7.00519 9.5483C6.54913 9.19902 5.94834 9.06969 5.39815 8.91813C5.26207 8.88062 5.12605 8.84293 4.99003 8.80523C4.97814 8.80193 4.97814 8.80193 4.966 8.79857C4.76981 8.74417 4.57367 8.68963 4.37822 8.63283C4.36996 8.63045 4.36169 8.62806 4.35317 8.62561C4.0529 8.53883 4.0529 8.53883 4.00065 8.4781C3.99917 8.45054 3.99917 8.45054 4.01247 8.42157C4.06708 8.3704 4.12008 8.34848 4.19216 8.32619C4.2026 8.32284 4.21303 8.31948 4.22379 8.31603C4.25575 8.30582 4.28779 8.29584 4.31985 8.28592C4.329 8.28305 4.33815 8.28017 4.34758 8.27722C4.41228 8.25693 4.47722 8.2374 4.54226 8.21809C4.55824 8.21332 4.55824 8.21332 4.57454 8.20846C4.85227 8.12587 5.13181 8.049 5.41126 7.97196C5.6195 7.91455 5.82738 7.85618 6.0346 7.79548C6.04413 7.79271 6.05365 7.78993 6.06346 7.78707C6.5435 7.64696 7.01278 7.44816 7.32274 7.0537C7.32738 7.04785 7.33202 7.042 7.3368 7.03597C7.68197 6.59815 7.81658 6.06572 7.96695 5.54621C8.01643 5.37534 8.06649 5.20464 8.11673 5.03399C8.13064 4.98673 8.14453 4.93947 8.15836 4.89219C8.21394 4.70229 8.27035 4.51264 8.33 4.32386C8.33558 4.30619 8.34114 4.2885 8.34666 4.27081C8.43017 4.00399 8.43017 4.00399 8.50941 4Z\" fill=\"#0DBD7D\"/><path d=\"M11.236 4.55535C11.2902 4.61409 11.3011 4.68312 11.318 4.75813C11.3744 4.99376 11.4393 5.21042 11.6647 5.3473C11.8037 5.42083 11.9694 5.4543 12.1235 5.4859C12.1885 5.49951 12.2435 5.51758 12.2992 5.5537C12.3118 5.57278 12.3118 5.57278 12.3111 5.60598C12.2981 5.64637 12.2868 5.65939 12.2527 5.68582C12.2154 5.69775 12.2154 5.69775 12.1707 5.70702C12.1537 5.71074 12.1368 5.71449 12.1199 5.71828C12.1109 5.72029 12.1018 5.7223 12.0925 5.72437C11.817 5.78531 11.817 5.78531 11.5788 5.92322C11.5711 5.92918 11.5633 5.93514 11.5554 5.94128C11.3852 6.08479 11.3492 6.32351 11.2979 6.5235C11.295 6.53448 11.2921 6.54546 11.289 6.55678C11.2865 6.5665 11.284 6.57622 11.2813 6.58624C11.2703 6.61593 11.2588 6.63528 11.236 6.65803C11.1723 6.66576 11.1723 6.66576 11.1414 6.65803C11.0922 6.62155 11.0811 6.57999 11.0683 6.52414C11.0661 6.51549 11.064 6.50685 11.0618 6.49794C11.0549 6.47032 11.0482 6.44266 11.0416 6.41498C10.9898 6.19946 10.9313 5.988 10.7245 5.86167C10.5629 5.7755 10.3665 5.73475 10.1859 5.70185C10.1364 5.69199 10.108 5.6796 10.0774 5.6406C10.0707 5.60104 10.0707 5.60104 10.0774 5.56147C10.1245 5.51486 10.174 5.50348 10.2377 5.4894C10.2578 5.48465 10.2778 5.47987 10.2979 5.47505C10.3083 5.47258 10.3186 5.47011 10.3293 5.46756C10.3821 5.45456 10.4344 5.43998 10.4867 5.42511C10.4962 5.42247 10.5057 5.41984 10.5155 5.41712C10.6218 5.38673 10.7136 5.34786 10.7985 5.27885C10.8065 5.27261 10.8144 5.26638 10.8226 5.25995C10.9548 5.14614 10.9997 4.97516 11.0405 4.81562C11.0436 4.80351 11.0467 4.7914 11.0499 4.77892C11.0561 4.75459 11.0622 4.73023 11.0682 4.70585C11.0724 4.68888 11.0724 4.68888 11.0768 4.67157C11.0793 4.66144 11.0818 4.6513 11.0843 4.64086C11.0952 4.6086 11.1095 4.58326 11.1296 4.55535C11.1681 4.53692 11.1951 4.54525 11.236 4.55535Z\" fill=\"#075F3F\"/><path d=\"M5.79542 10.2472C5.80948 10.2473 5.80948 10.2473 5.82383 10.2474C5.92474 10.2503 5.99301 10.2813 6.06733 10.3461C6.15381 10.4355 6.19374 10.5362 6.19146 10.6566C6.18175 10.7542 6.12155 10.8395 6.0477 10.9055C5.96078 10.9725 5.8731 10.9947 5.76203 10.9916C5.66838 10.9812 5.58027 10.9386 5.51389 10.8746C5.43135 10.7669 5.40722 10.6682 5.41932 10.5355C5.4443 10.431 5.51634 10.3463 5.60847 10.2868C5.67248 10.2558 5.72396 10.2466 5.79542 10.2472Z\" fill=\"#0DBD7D\"/></svg></div>\n <span class=\"cqa-text-[12px] cqa-leading-[15px] cqa-font-medium cqa-text-[#075F3F]\">Self Heal Analysis</span>\n </div>\n <span class=\"cqa-px-1.5 cqa-rounded-full cqa-font-medium cqa-text-[#043F2A] cqa-bg-[#AEE9D4] cqa-text-[8px] cqa-leading-[12px]\" *ngIf=\"data?.confidence\">\n Confidence : {{ data.confidence }}%\n </span>\n </div>\n\n <!-- Locators Comparison -->\n <div class=\"cqa-grid cqa-grid-cols-2 cqa-gap-3 cqa-mb-1.5\">\n <!-- Original Locator -->\n <div>\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-1 cqa-mb-1 cqa-text-[8px] cqa-leading-[12px]\">\n <div class=\"cqa-text-[#075F3F]\">Original Locator</div>\n <div class=\"cqa-text-[#F87171]\">Failed</div>\n </div>\n <input \n type=\"text\" \n [(ngModel)]=\"data.originalLocator\" \n readonly\n class=\"cqa-w-full cqa-py-1 cqa-px-3 !cqa-border !cqa-border-solid !cqa-border-[#FEF3C7] cqa-rounded !cqa-bg-white cqa-text-[8px] cqa-leading-[12px] cqa-text-[#64748B]\"\n />\n </div>\n\n <!-- Healed Locator -->\n <div>\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-1 cqa-mb-1 cqa-text-[8px] cqa-leading-[12px]\">\n <div class=\"cqa-text-[#075F3F]\">Current Locator</div>\n <div class=\"cqa-flex cqa-items-center cqa-gap-[2px] cqa-text-[#10B981]\">\n <div><svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M5.00001 9.16671C7.3012 9.16671 9.16668 7.30123 9.16668 5.00004C9.16668 2.69885 7.3012 0.833374 5.00001 0.833374C2.69882 0.833374 0.833344 2.69885 0.833344 5.00004C0.833344 7.30123 2.69882 9.16671 5.00001 9.16671Z\" stroke=\"#10B981\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M3.75 4.99996L4.58333 5.83329L6.25 4.16663\" stroke=\"#10B981\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg></div>\n <span>Applied</span>\n </div>\n </div>\n <input \n type=\"text\" \n [(ngModel)]=\"data.healedLocator\" \n [readonly]=\"!isEditMode\"\n [ngClass]=\"isEditMode ? '!cqa-bg-white cqa-text-[#047857] cqa-cursor-text' : '!cqa-bg-[#F3F4F6] cqa-text-[#64748B] cqa-cursor-not-allowed'\"\n class=\"cqa-w-full cqa-py-1 cqa-px-3 !cqa-border !cqa-border-solid !cqa-border-[#A7F3D0] cqa-rounded cqa-text-[8px] cqa-leading-[12px]\"\n />\n </div>\n </div>\n\n <!-- Heal Method -->\n <!-- <div class=\"cqa-mb-1.5 cqa-flex cqa-items-center cqa-gap-2\">\n <span class=\"cqa-text-[8px] cqa-leading-[12px] cqa-text-[#0B9D68]\">Heal Method:</span>\n <span class=\"cqa-px-2 cqa-py-[2px] cqa-rounded cqa-text-[8px] cqa-leading-[12px] cqa-bg-[#AEE9D4] cqa-text-[#075F3F] cqa-border cqa-border-solid cqa-border-[#0DBD7D]\">\n {{ data.healMethod }}\n </span>\n </div> -->\n\n <!-- Action Buttons -->\n <div class=\"cqa-flex cqa-items-center cqa-justify-end cqa-gap-2 cqa-flex-wrap\">\n <button \n (click)=\"onAccept()\"\n [disabled]=\"isLoadingAccept || isLoadingModifyAccept\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-pl-2 cqa-pr-4 cqa-py-[2px] cqa-rounded-lg cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-bg-transparent cqa-text-[#097E53] cqa-border cqa-border-solid cqa-border-[#097E53]\">\n <svg *ngIf=\"!isAcceptLoading\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4.39748 7.93746L2.31248 5.85246L1.60248 6.55746L4.39748 9.35246L10.3975 3.35246L9.69248 2.64746L4.39748 7.93746Z\" fill=\"#097E53\"/></svg>\n <svg *ngIf=\"isAcceptLoading\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-dasharray=\"8 4\" opacity=\"0.3\"/>\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-dasharray=\"8 4\" stroke-dashoffset=\"2\">\n <animateTransform attributeName=\"transform\" type=\"rotate\" values=\"0 6 6;360 6 6\" dur=\"1s\" repeatCount=\"indefinite\"/>\n </circle>\n </svg>\n <span>{{ isAcceptLoading ? 'Loading...' : 'Accept' }}</span>\n </button>\n <!-- <button \n (click)=\"onReject()\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-pl-2 cqa-pr-4 cqa-py-[2px] cqa-rounded-lg cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-bg-transparent cqa-text-[#9F2A2A] cqa-border cqa-border-solid cqa-border-[#9F2A2A]\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M9.5 3.205L8.795 2.5L6 5.295L3.205 2.5L2.5 3.205L5.295 6L2.5 8.795L3.205 9.5L6 6.705L8.795 9.5L9.5 8.795L6.705 6L9.5 3.205Z\" fill=\"#9F2A2A\"/></svg>\n Reject\n </button> -->\n <button \n *ngIf=\"!isEditMode\"\n (click)=\"onModifyAccept()\"\n [disabled]=\"isLoadingAccept || isLoadingModifyAccept\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-pl-2 cqa-pr-4 cqa-py-[2px] cqa-rounded-lg cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-bg-transparent cqa-text-[#B18618] cqa-border cqa-border-solid cqa-border-[#B18618]\">\n <svg *ngIf=\"!isLoadingModifyAccept\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M7.02939 4.51L7.48939 4.97L2.95939 9.5H2.49939V9.04L7.02939 4.51ZM8.82939 1.5C8.70439 1.5 8.57439 1.55 8.47939 1.645L7.56439 2.56L9.43939 4.435L10.3544 3.52C10.5494 3.325 10.5494 3.01 10.3544 2.815L9.18439 1.645C9.08439 1.545 8.95939 1.5 8.82939 1.5ZM7.02939 3.095L1.49939 8.625V10.5H3.37439L8.90439 4.97L7.02939 3.095Z\" fill=\"#B18618\"/></svg>\n <svg *ngIf=\"isLoadingModifyAccept\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-dasharray=\"8 4\" opacity=\"0.3\"/>\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-dasharray=\"8 4\" stroke-dashoffset=\"2\">\n <animateTransform attributeName=\"transform\" type=\"rotate\" values=\"0 6 6;360 6 6\" dur=\"1s\" repeatCount=\"indefinite\"/>\n </circle>\n </svg>\n <span>{{ isLoadingModifyAccept ? 'Loading...' : 'Modify & Accept' }}</span>\n </button>\n <button\n *ngIf=\"isEditMode\"\n (click)=\"onCancelModify()\"\n [disabled]=\"isLoadingAccept || isLoadingModifyAccept\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-pl-2 cqa-pr-4 cqa-py-[2px] cqa-rounded-lg cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-bg-transparent cqa-text-[#9F2A2A] cqa-border cqa-border-solid cqa-border-[#9F2A2A]\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M9.5 3.205L8.795 2.5L6 5.295L3.205 2.5L2.5 3.205L5.295 6L2.5 8.795L3.205 9.5L6 6.705L8.795 9.5L9.5 8.795L6.705 6L9.5 3.205Z\" fill=\"#9F2A2A\"/></svg>\n <span>Cancel</span>\n </button>\n </div>\n</div>\n", directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { 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"] }, { type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
|
|
9487
9514
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: SelfHealAnalysisComponent, decorators: [{
|
|
9488
9515
|
type: Component,
|
|
9489
|
-
args: [{ selector: 'cqa-self-heal-analysis', host: { class: 'cqa-ui-root' }, template: "<div class=\"cqa-bg-[#E7F8F2] cqa-border cqa-border-solid cqa-border-[#0B9D68] cqa-mt-1.5 cqa-ml-9 cqa-mr-6 cqa-px-4 cqa-py-3 cqa-rounded-lg\">\n <!-- Header -->\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-2 cqa-mb-1.5\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-1.5\">\n <div><svg width=\"17\" height=\"17\" viewBox=\"0 0 17 17\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><rect width=\"17\" height=\"17\" rx=\"8.5\" fill=\"#AEE9D4\"/><path d=\"M8.50941 4C8.56489 4.02274 8.58859 4.07827 8.61131 4.12985C8.62269 4.1599 8.63314 4.19012 8.64329 4.22058C8.64726 4.23225 8.65123 4.24392 8.65532 4.25594C8.70806 4.413 8.75504 4.57175 8.80229 4.73038C8.81297 4.76619 8.82369 4.80199 8.83442 4.83778C8.88905 5.02004 8.94327 5.2024 8.99719 5.38484C9.00476 5.41047 9.01234 5.43609 9.01992 5.46171C9.04128 5.53395 9.06262 5.60619 9.08383 5.67847C9.12867 5.8312 9.17473 5.98347 9.22378 6.13501C9.22807 6.14827 9.23236 6.16152 9.23677 6.17518C9.3642 6.565 9.54482 6.91437 9.8409 7.21196C9.84823 7.2197 9.85556 7.22744 9.86312 7.23541C9.9895 7.36437 10.1517 7.46771 10.3138 7.55111C10.3221 7.55542 10.3303 7.55974 10.3388 7.56419C10.8159 7.80925 11.3895 7.91704 11.9062 8.0605C12.1326 8.1234 12.3583 8.18829 12.5832 8.25603C12.599 8.26079 12.6148 8.26554 12.6306 8.27028C12.6778 8.28445 12.725 8.29887 12.7721 8.31347C12.7831 8.31679 12.7941 8.32011 12.8054 8.32353C12.8703 8.34406 12.9324 8.36829 12.9857 8.41027C13.0019 8.44418 13.0019 8.44418 12.9975 8.4781C12.9456 8.52736 12.8942 8.55046 12.8258 8.573C12.816 8.57632 12.8062 8.57965 12.7961 8.58308C12.6806 8.62183 12.5635 8.65575 12.4463 8.68935C12.4222 8.6963 12.3981 8.70326 12.3741 8.71021C12.2257 8.75301 12.0771 8.7949 11.9283 8.83632C11.7323 8.89088 11.5366 8.94634 11.3411 9.00243C11.3091 9.01162 11.2771 9.02078 11.245 9.02991C11.0767 9.07786 10.9092 9.12753 10.7431 9.18208C10.7294 9.18659 10.7156 9.1911 10.7014 9.19574C10.1451 9.38082 9.7211 9.72609 9.45571 10.231C9.31263 10.5148 9.22823 10.8216 9.14214 11.1245C9.11884 11.2062 9.09409 11.2875 9.06905 11.3687C9.0494 11.4326 9.0302 11.4966 9.01149 11.5608C9.00926 11.5684 9.00703 11.5761 9.00473 11.5839C8.99394 11.6209 8.98319 11.6579 8.97252 11.695C8.94519 11.7888 8.91578 11.8819 8.88555 11.9749C8.83191 12.1402 8.7831 12.3067 8.73459 12.4735C8.66144 12.7246 8.66144 12.7246 8.61997 12.8453C8.61721 12.8534 8.61446 12.8615 8.61163 12.8698C8.59649 12.9128 8.58092 12.9523 8.55226 12.9887C8.50867 12.9979 8.50867 12.9979 8.46951 13C8.42473 12.9376 8.39508 12.8771 8.37133 12.8051C8.36787 12.7949 8.36441 12.7847 8.36085 12.7741C8.31684 12.6425 8.27751 12.5095 8.23817 12.3765C8.22916 12.346 8.22011 12.3156 8.21105 12.2852C8.1436 12.0586 8.07725 11.8317 8.01101 11.6048C7.73507 10.4822 7.73507 10.4822 7.039 9.57466C7.02784 9.56596 7.01669 9.55726 7.00519 9.5483C6.54913 9.19902 5.94834 9.06969 5.39815 8.91813C5.26207 8.88062 5.12605 8.84293 4.99003 8.80523C4.97814 8.80193 4.97814 8.80193 4.966 8.79857C4.76981 8.74417 4.57367 8.68963 4.37822 8.63283C4.36996 8.63045 4.36169 8.62806 4.35317 8.62561C4.0529 8.53883 4.0529 8.53883 4.00065 8.4781C3.99917 8.45054 3.99917 8.45054 4.01247 8.42157C4.06708 8.3704 4.12008 8.34848 4.19216 8.32619C4.2026 8.32284 4.21303 8.31948 4.22379 8.31603C4.25575 8.30582 4.28779 8.29584 4.31985 8.28592C4.329 8.28305 4.33815 8.28017 4.34758 8.27722C4.41228 8.25693 4.47722 8.2374 4.54226 8.21809C4.55824 8.21332 4.55824 8.21332 4.57454 8.20846C4.85227 8.12587 5.13181 8.049 5.41126 7.97196C5.6195 7.91455 5.82738 7.85618 6.0346 7.79548C6.04413 7.79271 6.05365 7.78993 6.06346 7.78707C6.5435 7.64696 7.01278 7.44816 7.32274 7.0537C7.32738 7.04785 7.33202 7.042 7.3368 7.03597C7.68197 6.59815 7.81658 6.06572 7.96695 5.54621C8.01643 5.37534 8.06649 5.20464 8.11673 5.03399C8.13064 4.98673 8.14453 4.93947 8.15836 4.89219C8.21394 4.70229 8.27035 4.51264 8.33 4.32386C8.33558 4.30619 8.34114 4.2885 8.34666 4.27081C8.43017 4.00399 8.43017 4.00399 8.50941 4Z\" fill=\"#0DBD7D\"/><path d=\"M11.236 4.55535C11.2902 4.61409 11.3011 4.68312 11.318 4.75813C11.3744 4.99376 11.4393 5.21042 11.6647 5.3473C11.8037 5.42083 11.9694 5.4543 12.1235 5.4859C12.1885 5.49951 12.2435 5.51758 12.2992 5.5537C12.3118 5.57278 12.3118 5.57278 12.3111 5.60598C12.2981 5.64637 12.2868 5.65939 12.2527 5.68582C12.2154 5.69775 12.2154 5.69775 12.1707 5.70702C12.1537 5.71074 12.1368 5.71449 12.1199 5.71828C12.1109 5.72029 12.1018 5.7223 12.0925 5.72437C11.817 5.78531 11.817 5.78531 11.5788 5.92322C11.5711 5.92918 11.5633 5.93514 11.5554 5.94128C11.3852 6.08479 11.3492 6.32351 11.2979 6.5235C11.295 6.53448 11.2921 6.54546 11.289 6.55678C11.2865 6.5665 11.284 6.57622 11.2813 6.58624C11.2703 6.61593 11.2588 6.63528 11.236 6.65803C11.1723 6.66576 11.1723 6.66576 11.1414 6.65803C11.0922 6.62155 11.0811 6.57999 11.0683 6.52414C11.0661 6.51549 11.064 6.50685 11.0618 6.49794C11.0549 6.47032 11.0482 6.44266 11.0416 6.41498C10.9898 6.19946 10.9313 5.988 10.7245 5.86167C10.5629 5.7755 10.3665 5.73475 10.1859 5.70185C10.1364 5.69199 10.108 5.6796 10.0774 5.6406C10.0707 5.60104 10.0707 5.60104 10.0774 5.56147C10.1245 5.51486 10.174 5.50348 10.2377 5.4894C10.2578 5.48465 10.2778 5.47987 10.2979 5.47505C10.3083 5.47258 10.3186 5.47011 10.3293 5.46756C10.3821 5.45456 10.4344 5.43998 10.4867 5.42511C10.4962 5.42247 10.5057 5.41984 10.5155 5.41712C10.6218 5.38673 10.7136 5.34786 10.7985 5.27885C10.8065 5.27261 10.8144 5.26638 10.8226 5.25995C10.9548 5.14614 10.9997 4.97516 11.0405 4.81562C11.0436 4.80351 11.0467 4.7914 11.0499 4.77892C11.0561 4.75459 11.0622 4.73023 11.0682 4.70585C11.0724 4.68888 11.0724 4.68888 11.0768 4.67157C11.0793 4.66144 11.0818 4.6513 11.0843 4.64086C11.0952 4.6086 11.1095 4.58326 11.1296 4.55535C11.1681 4.53692 11.1951 4.54525 11.236 4.55535Z\" fill=\"#075F3F\"/><path d=\"M5.79542 10.2472C5.80948 10.2473 5.80948 10.2473 5.82383 10.2474C5.92474 10.2503 5.99301 10.2813 6.06733 10.3461C6.15381 10.4355 6.19374 10.5362 6.19146 10.6566C6.18175 10.7542 6.12155 10.8395 6.0477 10.9055C5.96078 10.9725 5.8731 10.9947 5.76203 10.9916C5.66838 10.9812 5.58027 10.9386 5.51389 10.8746C5.43135 10.7669 5.40722 10.6682 5.41932 10.5355C5.4443 10.431 5.51634 10.3463 5.60847 10.2868C5.67248 10.2558 5.72396 10.2466 5.79542 10.2472Z\" fill=\"#0DBD7D\"/></svg></div>\n <span class=\"cqa-text-[12px] cqa-leading-[15px] cqa-font-medium cqa-text-[#075F3F]\">Self Heal Analysis</span>\n </div>\n <span class=\"cqa-px-1.5 cqa-rounded-full cqa-font-medium cqa-text-[#043F2A] cqa-bg-[#AEE9D4] cqa-text-[8px] cqa-leading-[12px]\" *ngIf=\"data?.confidence\">\n Confidence : {{ data.confidence }}%\n </span>\n </div>\n\n <!-- Locators Comparison -->\n <div class=\"cqa-grid cqa-grid-cols-2 cqa-gap-3 cqa-mb-1.5\">\n <!-- Original Locator -->\n <div>\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-1 cqa-mb-1 cqa-text-[8px] cqa-leading-[12px]\">\n <div class=\"cqa-text-[#075F3F]\">Original Locator</div>\n <div class=\"cqa-text-[#F87171]\">Failed</div>\n </div>\n <input \n type=\"text\" \n [(ngModel)]=\"data.originalLocator\" \n readonly\n class=\"cqa-w-full cqa-py-1 cqa-px-3 !cqa-border !cqa-border-solid !cqa-border-[#FEF3C7] cqa-rounded !cqa-bg-white cqa-text-[8px] cqa-leading-[12px] cqa-text-[#64748B]\"\n />\n </div>\n\n <!-- Healed Locator -->\n <div>\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-1 cqa-mb-1 cqa-text-[8px] cqa-leading-[12px]\">\n <div class=\"cqa-text-[#075F3F]\">Current Locator</div>\n <div class=\"cqa-flex cqa-items-center cqa-gap-[2px] cqa-text-[#10B981]\">\n <div><svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M5.00001 9.16671C7.3012 9.16671 9.16668 7.30123 9.16668 5.00004C9.16668 2.69885 7.3012 0.833374 5.00001 0.833374C2.69882 0.833374 0.833344 2.69885 0.833344 5.00004C0.833344 7.30123 2.69882 9.16671 5.00001 9.16671Z\" stroke=\"#10B981\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M3.75 4.99996L4.58333 5.83329L6.25 4.16663\" stroke=\"#10B981\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg></div>\n <span>Applied</span>\n </div>\n </div>\n <input \n type=\"text\" \n [(ngModel)]=\"data.healedLocator\" \n class=\"cqa-w-full cqa-py-1 cqa-px-3 !cqa-border !cqa-border-solid !cqa-border-[#A7F3D0] cqa-rounded !cqa-bg-white cqa-text-[8px] cqa-leading-[12px] cqa-text-[#047857]\"\n />\n </div>\n </div>\n\n <!-- Heal Method -->\n <!-- <div class=\"cqa-mb-1.5 cqa-flex cqa-items-center cqa-gap-2\">\n <span class=\"cqa-text-[8px] cqa-leading-[12px] cqa-text-[#0B9D68]\">Heal Method:</span>\n <span class=\"cqa-px-2 cqa-py-[2px] cqa-rounded cqa-text-[8px] cqa-leading-[12px] cqa-bg-[#AEE9D4] cqa-text-[#075F3F] cqa-border cqa-border-solid cqa-border-[#0DBD7D]\">\n {{ data.healMethod }}\n </span>\n </div> -->\n\n <!-- Action Buttons -->\n <div class=\"cqa-flex cqa-items-center cqa-justify-end cqa-gap-2 cqa-flex-wrap\">\n <button \n (click)=\"onAccept()\"\n [disabled]=\"isLoadingAccept || isLoadingModifyAccept\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-pl-2 cqa-pr-4 cqa-py-[2px] cqa-rounded-lg cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-bg-transparent cqa-text-[#097E53] cqa-border cqa-border-solid cqa-border-[#097E53]\">\n <svg *ngIf=\"!isLoadingAccept\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4.39748 7.93746L2.31248 5.85246L1.60248 6.55746L4.39748 9.35246L10.3975 3.35246L9.69248 2.64746L4.39748 7.93746Z\" fill=\"#097E53\"/></svg>\n <svg *ngIf=\"isLoadingAccept\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-dasharray=\"8 4\" opacity=\"0.3\"/>\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-dasharray=\"8 4\" stroke-dashoffset=\"2\">\n <animateTransform attributeName=\"transform\" type=\"rotate\" values=\"0 6 6;360 6 6\" dur=\"1s\" repeatCount=\"indefinite\"/>\n </circle>\n </svg>\n <span>{{ isLoadingAccept ? 'Loading...' : 'Accept' }}</span>\n </button>\n <!-- <button \n (click)=\"onReject()\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-pl-2 cqa-pr-4 cqa-py-[2px] cqa-rounded-lg cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-bg-transparent cqa-text-[#9F2A2A] cqa-border cqa-border-solid cqa-border-[#9F2A2A]\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M9.5 3.205L8.795 2.5L6 5.295L3.205 2.5L2.5 3.205L5.295 6L2.5 8.795L3.205 9.5L6 6.705L8.795 9.5L9.5 8.795L6.705 6L9.5 3.205Z\" fill=\"#9F2A2A\"/></svg>\n Reject\n </button> -->\n <button \n (click)=\"onModifyAccept()\"\n [disabled]=\"isLoadingAccept || isLoadingModifyAccept\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-pl-2 cqa-pr-4 cqa-py-[2px] cqa-rounded-lg cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-bg-transparent cqa-text-[#B18618] cqa-border cqa-border-solid cqa-border-[#B18618]\">\n <svg *ngIf=\"!isLoadingModifyAccept\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M7.02939 4.51L7.48939 4.97L2.95939 9.5H2.49939V9.04L7.02939 4.51ZM8.82939 1.5C8.70439 1.5 8.57439 1.55 8.47939 1.645L7.56439 2.56L9.43939 4.435L10.3544 3.52C10.5494 3.325 10.5494 3.01 10.3544 2.815L9.18439 1.645C9.08439 1.545 8.95939 1.5 8.82939 1.5ZM7.02939 3.095L1.49939 8.625V10.5H3.37439L8.90439 4.97L7.02939 3.095Z\" fill=\"#B18618\"/></svg>\n <svg *ngIf=\"isLoadingModifyAccept\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-dasharray=\"8 4\" opacity=\"0.3\"/>\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-dasharray=\"8 4\" stroke-dashoffset=\"2\">\n <animateTransform attributeName=\"transform\" type=\"rotate\" values=\"0 6 6;360 6 6\" dur=\"1s\" repeatCount=\"indefinite\"/>\n </circle>\n </svg>\n <span>{{ isLoadingModifyAccept ? 'Loading...' : 'Modify & Accept' }}</span>\n </button>\n </div>\n</div>\n", styles: [] }]
|
|
9516
|
+
args: [{ selector: 'cqa-self-heal-analysis', host: { class: 'cqa-ui-root' }, template: "<div class=\"cqa-bg-[#E7F8F2] cqa-border cqa-border-solid cqa-border-[#0B9D68] cqa-mt-1.5 cqa-ml-9 cqa-mr-6 cqa-px-4 cqa-py-3 cqa-rounded-lg\">\n <!-- Header -->\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-2 cqa-mb-1.5\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-1.5\">\n <div><svg width=\"17\" height=\"17\" viewBox=\"0 0 17 17\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><rect width=\"17\" height=\"17\" rx=\"8.5\" fill=\"#AEE9D4\"/><path d=\"M8.50941 4C8.56489 4.02274 8.58859 4.07827 8.61131 4.12985C8.62269 4.1599 8.63314 4.19012 8.64329 4.22058C8.64726 4.23225 8.65123 4.24392 8.65532 4.25594C8.70806 4.413 8.75504 4.57175 8.80229 4.73038C8.81297 4.76619 8.82369 4.80199 8.83442 4.83778C8.88905 5.02004 8.94327 5.2024 8.99719 5.38484C9.00476 5.41047 9.01234 5.43609 9.01992 5.46171C9.04128 5.53395 9.06262 5.60619 9.08383 5.67847C9.12867 5.8312 9.17473 5.98347 9.22378 6.13501C9.22807 6.14827 9.23236 6.16152 9.23677 6.17518C9.3642 6.565 9.54482 6.91437 9.8409 7.21196C9.84823 7.2197 9.85556 7.22744 9.86312 7.23541C9.9895 7.36437 10.1517 7.46771 10.3138 7.55111C10.3221 7.55542 10.3303 7.55974 10.3388 7.56419C10.8159 7.80925 11.3895 7.91704 11.9062 8.0605C12.1326 8.1234 12.3583 8.18829 12.5832 8.25603C12.599 8.26079 12.6148 8.26554 12.6306 8.27028C12.6778 8.28445 12.725 8.29887 12.7721 8.31347C12.7831 8.31679 12.7941 8.32011 12.8054 8.32353C12.8703 8.34406 12.9324 8.36829 12.9857 8.41027C13.0019 8.44418 13.0019 8.44418 12.9975 8.4781C12.9456 8.52736 12.8942 8.55046 12.8258 8.573C12.816 8.57632 12.8062 8.57965 12.7961 8.58308C12.6806 8.62183 12.5635 8.65575 12.4463 8.68935C12.4222 8.6963 12.3981 8.70326 12.3741 8.71021C12.2257 8.75301 12.0771 8.7949 11.9283 8.83632C11.7323 8.89088 11.5366 8.94634 11.3411 9.00243C11.3091 9.01162 11.2771 9.02078 11.245 9.02991C11.0767 9.07786 10.9092 9.12753 10.7431 9.18208C10.7294 9.18659 10.7156 9.1911 10.7014 9.19574C10.1451 9.38082 9.7211 9.72609 9.45571 10.231C9.31263 10.5148 9.22823 10.8216 9.14214 11.1245C9.11884 11.2062 9.09409 11.2875 9.06905 11.3687C9.0494 11.4326 9.0302 11.4966 9.01149 11.5608C9.00926 11.5684 9.00703 11.5761 9.00473 11.5839C8.99394 11.6209 8.98319 11.6579 8.97252 11.695C8.94519 11.7888 8.91578 11.8819 8.88555 11.9749C8.83191 12.1402 8.7831 12.3067 8.73459 12.4735C8.66144 12.7246 8.66144 12.7246 8.61997 12.8453C8.61721 12.8534 8.61446 12.8615 8.61163 12.8698C8.59649 12.9128 8.58092 12.9523 8.55226 12.9887C8.50867 12.9979 8.50867 12.9979 8.46951 13C8.42473 12.9376 8.39508 12.8771 8.37133 12.8051C8.36787 12.7949 8.36441 12.7847 8.36085 12.7741C8.31684 12.6425 8.27751 12.5095 8.23817 12.3765C8.22916 12.346 8.22011 12.3156 8.21105 12.2852C8.1436 12.0586 8.07725 11.8317 8.01101 11.6048C7.73507 10.4822 7.73507 10.4822 7.039 9.57466C7.02784 9.56596 7.01669 9.55726 7.00519 9.5483C6.54913 9.19902 5.94834 9.06969 5.39815 8.91813C5.26207 8.88062 5.12605 8.84293 4.99003 8.80523C4.97814 8.80193 4.97814 8.80193 4.966 8.79857C4.76981 8.74417 4.57367 8.68963 4.37822 8.63283C4.36996 8.63045 4.36169 8.62806 4.35317 8.62561C4.0529 8.53883 4.0529 8.53883 4.00065 8.4781C3.99917 8.45054 3.99917 8.45054 4.01247 8.42157C4.06708 8.3704 4.12008 8.34848 4.19216 8.32619C4.2026 8.32284 4.21303 8.31948 4.22379 8.31603C4.25575 8.30582 4.28779 8.29584 4.31985 8.28592C4.329 8.28305 4.33815 8.28017 4.34758 8.27722C4.41228 8.25693 4.47722 8.2374 4.54226 8.21809C4.55824 8.21332 4.55824 8.21332 4.57454 8.20846C4.85227 8.12587 5.13181 8.049 5.41126 7.97196C5.6195 7.91455 5.82738 7.85618 6.0346 7.79548C6.04413 7.79271 6.05365 7.78993 6.06346 7.78707C6.5435 7.64696 7.01278 7.44816 7.32274 7.0537C7.32738 7.04785 7.33202 7.042 7.3368 7.03597C7.68197 6.59815 7.81658 6.06572 7.96695 5.54621C8.01643 5.37534 8.06649 5.20464 8.11673 5.03399C8.13064 4.98673 8.14453 4.93947 8.15836 4.89219C8.21394 4.70229 8.27035 4.51264 8.33 4.32386C8.33558 4.30619 8.34114 4.2885 8.34666 4.27081C8.43017 4.00399 8.43017 4.00399 8.50941 4Z\" fill=\"#0DBD7D\"/><path d=\"M11.236 4.55535C11.2902 4.61409 11.3011 4.68312 11.318 4.75813C11.3744 4.99376 11.4393 5.21042 11.6647 5.3473C11.8037 5.42083 11.9694 5.4543 12.1235 5.4859C12.1885 5.49951 12.2435 5.51758 12.2992 5.5537C12.3118 5.57278 12.3118 5.57278 12.3111 5.60598C12.2981 5.64637 12.2868 5.65939 12.2527 5.68582C12.2154 5.69775 12.2154 5.69775 12.1707 5.70702C12.1537 5.71074 12.1368 5.71449 12.1199 5.71828C12.1109 5.72029 12.1018 5.7223 12.0925 5.72437C11.817 5.78531 11.817 5.78531 11.5788 5.92322C11.5711 5.92918 11.5633 5.93514 11.5554 5.94128C11.3852 6.08479 11.3492 6.32351 11.2979 6.5235C11.295 6.53448 11.2921 6.54546 11.289 6.55678C11.2865 6.5665 11.284 6.57622 11.2813 6.58624C11.2703 6.61593 11.2588 6.63528 11.236 6.65803C11.1723 6.66576 11.1723 6.66576 11.1414 6.65803C11.0922 6.62155 11.0811 6.57999 11.0683 6.52414C11.0661 6.51549 11.064 6.50685 11.0618 6.49794C11.0549 6.47032 11.0482 6.44266 11.0416 6.41498C10.9898 6.19946 10.9313 5.988 10.7245 5.86167C10.5629 5.7755 10.3665 5.73475 10.1859 5.70185C10.1364 5.69199 10.108 5.6796 10.0774 5.6406C10.0707 5.60104 10.0707 5.60104 10.0774 5.56147C10.1245 5.51486 10.174 5.50348 10.2377 5.4894C10.2578 5.48465 10.2778 5.47987 10.2979 5.47505C10.3083 5.47258 10.3186 5.47011 10.3293 5.46756C10.3821 5.45456 10.4344 5.43998 10.4867 5.42511C10.4962 5.42247 10.5057 5.41984 10.5155 5.41712C10.6218 5.38673 10.7136 5.34786 10.7985 5.27885C10.8065 5.27261 10.8144 5.26638 10.8226 5.25995C10.9548 5.14614 10.9997 4.97516 11.0405 4.81562C11.0436 4.80351 11.0467 4.7914 11.0499 4.77892C11.0561 4.75459 11.0622 4.73023 11.0682 4.70585C11.0724 4.68888 11.0724 4.68888 11.0768 4.67157C11.0793 4.66144 11.0818 4.6513 11.0843 4.64086C11.0952 4.6086 11.1095 4.58326 11.1296 4.55535C11.1681 4.53692 11.1951 4.54525 11.236 4.55535Z\" fill=\"#075F3F\"/><path d=\"M5.79542 10.2472C5.80948 10.2473 5.80948 10.2473 5.82383 10.2474C5.92474 10.2503 5.99301 10.2813 6.06733 10.3461C6.15381 10.4355 6.19374 10.5362 6.19146 10.6566C6.18175 10.7542 6.12155 10.8395 6.0477 10.9055C5.96078 10.9725 5.8731 10.9947 5.76203 10.9916C5.66838 10.9812 5.58027 10.9386 5.51389 10.8746C5.43135 10.7669 5.40722 10.6682 5.41932 10.5355C5.4443 10.431 5.51634 10.3463 5.60847 10.2868C5.67248 10.2558 5.72396 10.2466 5.79542 10.2472Z\" fill=\"#0DBD7D\"/></svg></div>\n <span class=\"cqa-text-[12px] cqa-leading-[15px] cqa-font-medium cqa-text-[#075F3F]\">Self Heal Analysis</span>\n </div>\n <span class=\"cqa-px-1.5 cqa-rounded-full cqa-font-medium cqa-text-[#043F2A] cqa-bg-[#AEE9D4] cqa-text-[8px] cqa-leading-[12px]\" *ngIf=\"data?.confidence\">\n Confidence : {{ data.confidence }}%\n </span>\n </div>\n\n <!-- Locators Comparison -->\n <div class=\"cqa-grid cqa-grid-cols-2 cqa-gap-3 cqa-mb-1.5\">\n <!-- Original Locator -->\n <div>\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-1 cqa-mb-1 cqa-text-[8px] cqa-leading-[12px]\">\n <div class=\"cqa-text-[#075F3F]\">Original Locator</div>\n <div class=\"cqa-text-[#F87171]\">Failed</div>\n </div>\n <input \n type=\"text\" \n [(ngModel)]=\"data.originalLocator\" \n readonly\n class=\"cqa-w-full cqa-py-1 cqa-px-3 !cqa-border !cqa-border-solid !cqa-border-[#FEF3C7] cqa-rounded !cqa-bg-white cqa-text-[8px] cqa-leading-[12px] cqa-text-[#64748B]\"\n />\n </div>\n\n <!-- Healed Locator -->\n <div>\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-1 cqa-mb-1 cqa-text-[8px] cqa-leading-[12px]\">\n <div class=\"cqa-text-[#075F3F]\">Current Locator</div>\n <div class=\"cqa-flex cqa-items-center cqa-gap-[2px] cqa-text-[#10B981]\">\n <div><svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M5.00001 9.16671C7.3012 9.16671 9.16668 7.30123 9.16668 5.00004C9.16668 2.69885 7.3012 0.833374 5.00001 0.833374C2.69882 0.833374 0.833344 2.69885 0.833344 5.00004C0.833344 7.30123 2.69882 9.16671 5.00001 9.16671Z\" stroke=\"#10B981\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M3.75 4.99996L4.58333 5.83329L6.25 4.16663\" stroke=\"#10B981\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg></div>\n <span>Applied</span>\n </div>\n </div>\n <input \n type=\"text\" \n [(ngModel)]=\"data.healedLocator\" \n [readonly]=\"!isEditMode\"\n [ngClass]=\"isEditMode ? '!cqa-bg-white cqa-text-[#047857] cqa-cursor-text' : '!cqa-bg-[#F3F4F6] cqa-text-[#64748B] cqa-cursor-not-allowed'\"\n class=\"cqa-w-full cqa-py-1 cqa-px-3 !cqa-border !cqa-border-solid !cqa-border-[#A7F3D0] cqa-rounded cqa-text-[8px] cqa-leading-[12px]\"\n />\n </div>\n </div>\n\n <!-- Heal Method -->\n <!-- <div class=\"cqa-mb-1.5 cqa-flex cqa-items-center cqa-gap-2\">\n <span class=\"cqa-text-[8px] cqa-leading-[12px] cqa-text-[#0B9D68]\">Heal Method:</span>\n <span class=\"cqa-px-2 cqa-py-[2px] cqa-rounded cqa-text-[8px] cqa-leading-[12px] cqa-bg-[#AEE9D4] cqa-text-[#075F3F] cqa-border cqa-border-solid cqa-border-[#0DBD7D]\">\n {{ data.healMethod }}\n </span>\n </div> -->\n\n <!-- Action Buttons -->\n <div class=\"cqa-flex cqa-items-center cqa-justify-end cqa-gap-2 cqa-flex-wrap\">\n <button \n (click)=\"onAccept()\"\n [disabled]=\"isLoadingAccept || isLoadingModifyAccept\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-pl-2 cqa-pr-4 cqa-py-[2px] cqa-rounded-lg cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-bg-transparent cqa-text-[#097E53] cqa-border cqa-border-solid cqa-border-[#097E53]\">\n <svg *ngIf=\"!isAcceptLoading\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4.39748 7.93746L2.31248 5.85246L1.60248 6.55746L4.39748 9.35246L10.3975 3.35246L9.69248 2.64746L4.39748 7.93746Z\" fill=\"#097E53\"/></svg>\n <svg *ngIf=\"isAcceptLoading\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-dasharray=\"8 4\" opacity=\"0.3\"/>\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-dasharray=\"8 4\" stroke-dashoffset=\"2\">\n <animateTransform attributeName=\"transform\" type=\"rotate\" values=\"0 6 6;360 6 6\" dur=\"1s\" repeatCount=\"indefinite\"/>\n </circle>\n </svg>\n <span>{{ isAcceptLoading ? 'Loading...' : 'Accept' }}</span>\n </button>\n <!-- <button \n (click)=\"onReject()\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-pl-2 cqa-pr-4 cqa-py-[2px] cqa-rounded-lg cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-bg-transparent cqa-text-[#9F2A2A] cqa-border cqa-border-solid cqa-border-[#9F2A2A]\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M9.5 3.205L8.795 2.5L6 5.295L3.205 2.5L2.5 3.205L5.295 6L2.5 8.795L3.205 9.5L6 6.705L8.795 9.5L9.5 8.795L6.705 6L9.5 3.205Z\" fill=\"#9F2A2A\"/></svg>\n Reject\n </button> -->\n <button \n *ngIf=\"!isEditMode\"\n (click)=\"onModifyAccept()\"\n [disabled]=\"isLoadingAccept || isLoadingModifyAccept\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-pl-2 cqa-pr-4 cqa-py-[2px] cqa-rounded-lg cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-bg-transparent cqa-text-[#B18618] cqa-border cqa-border-solid cqa-border-[#B18618]\">\n <svg *ngIf=\"!isLoadingModifyAccept\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M7.02939 4.51L7.48939 4.97L2.95939 9.5H2.49939V9.04L7.02939 4.51ZM8.82939 1.5C8.70439 1.5 8.57439 1.55 8.47939 1.645L7.56439 2.56L9.43939 4.435L10.3544 3.52C10.5494 3.325 10.5494 3.01 10.3544 2.815L9.18439 1.645C9.08439 1.545 8.95939 1.5 8.82939 1.5ZM7.02939 3.095L1.49939 8.625V10.5H3.37439L8.90439 4.97L7.02939 3.095Z\" fill=\"#B18618\"/></svg>\n <svg *ngIf=\"isLoadingModifyAccept\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-dasharray=\"8 4\" opacity=\"0.3\"/>\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-dasharray=\"8 4\" stroke-dashoffset=\"2\">\n <animateTransform attributeName=\"transform\" type=\"rotate\" values=\"0 6 6;360 6 6\" dur=\"1s\" repeatCount=\"indefinite\"/>\n </circle>\n </svg>\n <span>{{ isLoadingModifyAccept ? 'Loading...' : 'Modify & Accept' }}</span>\n </button>\n <button\n *ngIf=\"isEditMode\"\n (click)=\"onCancelModify()\"\n [disabled]=\"isLoadingAccept || isLoadingModifyAccept\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-pl-2 cqa-pr-4 cqa-py-[2px] cqa-rounded-lg cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-bg-transparent cqa-text-[#9F2A2A] cqa-border cqa-border-solid cqa-border-[#9F2A2A]\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M9.5 3.205L8.795 2.5L6 5.295L3.205 2.5L2.5 3.205L5.295 6L2.5 8.795L3.205 9.5L6 6.705L8.795 9.5L9.5 8.795L6.705 6L9.5 3.205Z\" fill=\"#9F2A2A\"/></svg>\n <span>Cancel</span>\n </button>\n </div>\n</div>\n", styles: [] }]
|
|
9490
9517
|
}], propDecorators: { id: [{
|
|
9491
9518
|
type: Input
|
|
9492
9519
|
}], originalLocator: [{
|
|
@@ -19456,8 +19483,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
|
|
|
19456
19483
|
type: Input
|
|
19457
19484
|
}] } });
|
|
19458
19485
|
|
|
19459
|
-
const
|
|
19460
|
-
const
|
|
19486
|
+
const VAR_PATH = '[A-Za-z_][A-Za-z0-9_]*(?:\\.[A-Za-z_][A-Za-z0-9_]*|\\[\\d+\\])*';
|
|
19487
|
+
const VAR_NAME_REGEX = new RegExp('^' + VAR_PATH + '$');
|
|
19488
|
+
const VAR_TOKEN_REGEX = new RegExp('\\$\\{(' + VAR_PATH + ')\\}', 'g');
|
|
19489
|
+
const VAR_PATH_TAIL_REGEX = new RegExp('(' + VAR_PATH + ')$');
|
|
19490
|
+
const INVALID_VAR_MESSAGE = 'Invalid variable name.';
|
|
19491
|
+
const BLUR_HIDE_DELAY_MS = 150;
|
|
19461
19492
|
class MixedVariableInputComponent {
|
|
19462
19493
|
constructor(cdr, hostRef) {
|
|
19463
19494
|
this.cdr = cdr;
|
|
@@ -19466,41 +19497,56 @@ class MixedVariableInputComponent {
|
|
|
19466
19497
|
this.placeholder = 'Text Input';
|
|
19467
19498
|
this.disabled = false;
|
|
19468
19499
|
this.valueChange = new EventEmitter();
|
|
19500
|
+
this.validityChange = new EventEmitter();
|
|
19469
19501
|
this.showSuggestion = false;
|
|
19470
19502
|
this.pendingWord = '';
|
|
19503
|
+
this.canAddAsVariable = false;
|
|
19504
|
+
this.errorMessage = null;
|
|
19505
|
+
this.selectionRange = null;
|
|
19506
|
+
this.selectionMode = false;
|
|
19471
19507
|
this.lastEmitted = '';
|
|
19508
|
+
this.lastValid = null;
|
|
19472
19509
|
}
|
|
19473
|
-
|
|
19474
|
-
|
|
19510
|
+
// ---- Lifecycle ------------------------------------------------------------
|
|
19511
|
+
ngOnChanges(changes) {
|
|
19512
|
+
if (!changes['value'] || !this.editorRef)
|
|
19475
19513
|
return;
|
|
19476
|
-
const
|
|
19477
|
-
if (this.
|
|
19514
|
+
const incoming = changes['value'].currentValue ?? '';
|
|
19515
|
+
if (incoming === this.lastEmitted)
|
|
19478
19516
|
return;
|
|
19479
|
-
this.
|
|
19480
|
-
|
|
19481
|
-
ngOnChanges(changes) {
|
|
19482
|
-
if (changes['value'] && this.editorRef) {
|
|
19483
|
-
const incoming = changes['value'].currentValue ?? '';
|
|
19484
|
-
if (incoming !== this.lastEmitted) {
|
|
19485
|
-
this.render(incoming);
|
|
19486
|
-
}
|
|
19487
|
-
}
|
|
19517
|
+
this.render(incoming);
|
|
19518
|
+
this.validate(incoming);
|
|
19488
19519
|
}
|
|
19489
19520
|
ngAfterViewInit() {
|
|
19490
|
-
this.
|
|
19521
|
+
const initial = this.value || '';
|
|
19522
|
+
this.render(initial);
|
|
19523
|
+
this.validate(initial);
|
|
19491
19524
|
}
|
|
19525
|
+
// ---- Editor event handlers -----------------------------------------------
|
|
19492
19526
|
onInput() {
|
|
19493
|
-
|
|
19494
|
-
this.
|
|
19495
|
-
this.valueChange.emit(str);
|
|
19527
|
+
this.flattenStructure();
|
|
19528
|
+
this.sanitizeChips();
|
|
19496
19529
|
this.autoChipify();
|
|
19530
|
+
this.emitValue();
|
|
19531
|
+
this.refreshSuggestion();
|
|
19532
|
+
}
|
|
19533
|
+
onEditorFocus() {
|
|
19497
19534
|
this.refreshSuggestion();
|
|
19498
19535
|
}
|
|
19536
|
+
onEditorBlur() {
|
|
19537
|
+
// Delay so clicks on suggestion buttons register before we hide them.
|
|
19538
|
+
setTimeout(() => {
|
|
19539
|
+
this.autoChipify(true);
|
|
19540
|
+
this.hideSuggestion();
|
|
19541
|
+
}, BLUR_HIDE_DELAY_MS);
|
|
19542
|
+
}
|
|
19499
19543
|
onKeyDown(event) {
|
|
19500
19544
|
if (event.key === 'Enter') {
|
|
19501
19545
|
event.preventDefault();
|
|
19502
19546
|
return;
|
|
19503
19547
|
}
|
|
19548
|
+
if (event.key === 'Tab')
|
|
19549
|
+
return;
|
|
19504
19550
|
if (event.key === 'Escape') {
|
|
19505
19551
|
if (this.showSuggestion) {
|
|
19506
19552
|
event.preventDefault();
|
|
@@ -19517,36 +19563,119 @@ class MixedVariableInputComponent {
|
|
|
19517
19563
|
}
|
|
19518
19564
|
}
|
|
19519
19565
|
}
|
|
19520
|
-
|
|
19521
|
-
|
|
19522
|
-
|
|
19566
|
+
onPaste(event) {
|
|
19567
|
+
event.preventDefault();
|
|
19568
|
+
const text = event.clipboardData?.getData('text/plain') ?? '';
|
|
19569
|
+
if (!text)
|
|
19570
|
+
return;
|
|
19571
|
+
this.insertPlainTextAtCaret(text);
|
|
19572
|
+
this.onInput();
|
|
19573
|
+
}
|
|
19574
|
+
onDrop(event) {
|
|
19575
|
+
event.preventDefault();
|
|
19576
|
+
const text = event.dataTransfer?.getData('text/plain') ?? '';
|
|
19577
|
+
if (text) {
|
|
19578
|
+
this.editorRef.nativeElement.focus();
|
|
19579
|
+
this.insertPlainTextAtCaret(text);
|
|
19580
|
+
}
|
|
19581
|
+
this.onInput();
|
|
19582
|
+
}
|
|
19583
|
+
onDragStart(event) {
|
|
19584
|
+
event.preventDefault();
|
|
19585
|
+
}
|
|
19586
|
+
onDocumentMouseDown(event) {
|
|
19587
|
+
if (!this.showSuggestion)
|
|
19588
|
+
return;
|
|
19589
|
+
if (this.hostRef.nativeElement.contains(event.target))
|
|
19590
|
+
return;
|
|
19591
|
+
this.hideSuggestion();
|
|
19523
19592
|
}
|
|
19593
|
+
onDocumentSelectionChange() {
|
|
19594
|
+
if (document.activeElement !== this.editorRef?.nativeElement)
|
|
19595
|
+
return;
|
|
19596
|
+
this.refreshSuggestion();
|
|
19597
|
+
}
|
|
19598
|
+
// ---- Suggestion actions ---------------------------------------------------
|
|
19524
19599
|
addAsText() {
|
|
19525
19600
|
this.hideSuggestion();
|
|
19526
19601
|
this.editorRef.nativeElement.focus();
|
|
19527
19602
|
}
|
|
19528
19603
|
addAsVariable() {
|
|
19529
|
-
const name = (this.pendingWord || '')
|
|
19604
|
+
const name = this.normalizeCandidate(this.pendingWord || '');
|
|
19530
19605
|
if (!name || !VAR_NAME_REGEX.test(name)) {
|
|
19531
19606
|
this.hideSuggestion();
|
|
19532
19607
|
return;
|
|
19533
19608
|
}
|
|
19534
|
-
this.
|
|
19609
|
+
if (this.selectionMode && this.selectionRange) {
|
|
19610
|
+
if (this.rangeCrossesChip(this.selectionRange)) {
|
|
19611
|
+
this.hideSuggestion();
|
|
19612
|
+
return;
|
|
19613
|
+
}
|
|
19614
|
+
this.insertChipReplacingRange(name, this.selectionRange);
|
|
19615
|
+
}
|
|
19616
|
+
else {
|
|
19617
|
+
this.insertChipReplacingCurrentWord(name);
|
|
19618
|
+
}
|
|
19535
19619
|
this.hideSuggestion();
|
|
19620
|
+
this.emitValue();
|
|
19621
|
+
}
|
|
19622
|
+
// ---- Value emission / validation -----------------------------------------
|
|
19623
|
+
emitValue() {
|
|
19536
19624
|
const str = this.serialize();
|
|
19537
|
-
this.lastEmitted
|
|
19538
|
-
|
|
19625
|
+
if (str !== this.lastEmitted) {
|
|
19626
|
+
this.lastEmitted = str;
|
|
19627
|
+
this.valueChange.emit(str);
|
|
19628
|
+
}
|
|
19629
|
+
this.validate(str);
|
|
19630
|
+
}
|
|
19631
|
+
validate(str) {
|
|
19632
|
+
const error = this.findValidationError(str);
|
|
19633
|
+
const valid = error === null;
|
|
19634
|
+
if (this.lastValid === valid && this.errorMessage === error)
|
|
19635
|
+
return;
|
|
19636
|
+
this.lastValid = valid;
|
|
19637
|
+
this.errorMessage = error;
|
|
19638
|
+
this.validityChange.emit({ valid, error });
|
|
19639
|
+
this.cdr.markForCheck();
|
|
19539
19640
|
}
|
|
19641
|
+
findValidationError(str) {
|
|
19642
|
+
if (!str)
|
|
19643
|
+
return null;
|
|
19644
|
+
const braceBody = /\$\{([^}]*)\}/g;
|
|
19645
|
+
let m;
|
|
19646
|
+
braceBody.lastIndex = 0;
|
|
19647
|
+
while ((m = braceBody.exec(str)) !== null) {
|
|
19648
|
+
const body = m[1];
|
|
19649
|
+
if (body !== body.trim() || !VAR_NAME_REGEX.test(body)) {
|
|
19650
|
+
return INVALID_VAR_MESSAGE;
|
|
19651
|
+
}
|
|
19652
|
+
}
|
|
19653
|
+
const openCount = (str.match(/\$\{/g) || []).length;
|
|
19654
|
+
const closedCount = (str.match(braceBody) || []).length;
|
|
19655
|
+
if (openCount > closedCount)
|
|
19656
|
+
return INVALID_VAR_MESSAGE;
|
|
19657
|
+
return null;
|
|
19658
|
+
}
|
|
19659
|
+
// ---- Suggestion state -----------------------------------------------------
|
|
19540
19660
|
refreshSuggestion() {
|
|
19541
|
-
const
|
|
19542
|
-
if (
|
|
19543
|
-
|
|
19661
|
+
const selInfo = this.getSelectedInfo();
|
|
19662
|
+
if (selInfo) {
|
|
19663
|
+
const normalized = this.normalizeCandidate(selInfo.text);
|
|
19664
|
+
this.pendingWord = normalized;
|
|
19665
|
+
this.selectionRange = selInfo.range;
|
|
19666
|
+
this.selectionMode = true;
|
|
19544
19667
|
this.showSuggestion = true;
|
|
19668
|
+
this.canAddAsVariable =
|
|
19669
|
+
!!normalized && VAR_NAME_REGEX.test(normalized) && !this.rangeCrossesChip(selInfo.range);
|
|
19670
|
+
this.cdr.markForCheck();
|
|
19671
|
+
return;
|
|
19545
19672
|
}
|
|
19546
|
-
|
|
19547
|
-
|
|
19548
|
-
|
|
19549
|
-
|
|
19673
|
+
this.selectionMode = false;
|
|
19674
|
+
this.selectionRange = null;
|
|
19675
|
+
const word = this.getCurrentWord();
|
|
19676
|
+
this.pendingWord = word;
|
|
19677
|
+
this.showSuggestion = !!word;
|
|
19678
|
+
this.canAddAsVariable = !!word && VAR_NAME_REGEX.test(word);
|
|
19550
19679
|
this.cdr.markForCheck();
|
|
19551
19680
|
}
|
|
19552
19681
|
hideSuggestion() {
|
|
@@ -19554,45 +19683,126 @@ class MixedVariableInputComponent {
|
|
|
19554
19683
|
return;
|
|
19555
19684
|
this.showSuggestion = false;
|
|
19556
19685
|
this.pendingWord = '';
|
|
19686
|
+
this.canAddAsVariable = false;
|
|
19557
19687
|
this.cdr.markForCheck();
|
|
19558
19688
|
}
|
|
19559
|
-
|
|
19689
|
+
normalizeCandidate(text) {
|
|
19690
|
+
let t = text.trim();
|
|
19691
|
+
if (t.startsWith('${') && t.endsWith('}')) {
|
|
19692
|
+
t = t.slice(2, -1).trim();
|
|
19693
|
+
}
|
|
19694
|
+
return t;
|
|
19695
|
+
}
|
|
19696
|
+
// ---- DOM sanitization -----------------------------------------------------
|
|
19697
|
+
flattenStructure() {
|
|
19560
19698
|
const editor = this.editorRef.nativeElement;
|
|
19561
|
-
const
|
|
19562
|
-
editor.
|
|
19563
|
-
|
|
19564
|
-
|
|
19565
|
-
|
|
19566
|
-
|
|
19699
|
+
const wrappers = Array.from(editor.querySelectorAll('div, p'));
|
|
19700
|
+
const strayInlines = Array.from(editor.querySelectorAll('span')).filter((s) => !s.classList.contains('cqa-var-chip') && !s.closest('.cqa-var-chip'));
|
|
19701
|
+
for (const el of [...wrappers, ...strayInlines]) {
|
|
19702
|
+
if (el.closest('.cqa-var-chip'))
|
|
19703
|
+
continue;
|
|
19704
|
+
while (el.firstChild)
|
|
19705
|
+
el.parentNode?.insertBefore(el.firstChild, el);
|
|
19706
|
+
el.remove();
|
|
19707
|
+
}
|
|
19708
|
+
const brs = Array.from(editor.querySelectorAll('br'));
|
|
19709
|
+
for (const br of brs) {
|
|
19710
|
+
if (br.closest('.cqa-var-chip'))
|
|
19711
|
+
continue;
|
|
19712
|
+
br.parentNode?.replaceChild(document.createTextNode(' '), br);
|
|
19713
|
+
}
|
|
19714
|
+
}
|
|
19715
|
+
sanitizeChips() {
|
|
19716
|
+
const editor = this.editorRef.nativeElement;
|
|
19717
|
+
const chips = Array.from(editor.querySelectorAll('.cqa-var-chip'));
|
|
19718
|
+
for (const chip of chips) {
|
|
19719
|
+
const name = (chip.getAttribute('data-var') || '').trim();
|
|
19720
|
+
if (!name || !VAR_NAME_REGEX.test(name)) {
|
|
19721
|
+
chip.parentNode?.replaceChild(document.createTextNode(chip.textContent || ''), chip);
|
|
19722
|
+
continue;
|
|
19723
|
+
}
|
|
19724
|
+
const structureBroken = chip.getAttribute('contenteditable') !== 'false' ||
|
|
19725
|
+
!chip.querySelector('.cqa-var-chip__remove');
|
|
19726
|
+
if (structureBroken) {
|
|
19727
|
+
chip.parentNode?.replaceChild(this.buildChip(name), chip);
|
|
19728
|
+
}
|
|
19729
|
+
}
|
|
19730
|
+
// Remove stray remove icons left from partial undo/redo states.
|
|
19731
|
+
const orphans = Array.from(editor.querySelectorAll('.cqa-var-chip__remove'));
|
|
19732
|
+
for (const o of orphans) {
|
|
19733
|
+
if (!o.closest('.cqa-var-chip'))
|
|
19734
|
+
o.remove();
|
|
19735
|
+
}
|
|
19736
|
+
}
|
|
19737
|
+
// ---- Chipification --------------------------------------------------------
|
|
19738
|
+
autoChipify(force = false) {
|
|
19739
|
+
const editor = this.editorRef.nativeElement;
|
|
19740
|
+
const caretRange = this.getSelectionRange();
|
|
19741
|
+
let changed = false;
|
|
19742
|
+
let lastChip = null;
|
|
19743
|
+
for (const tn of this.collectDescendantTextNodes(editor)) {
|
|
19744
|
+
if (!tn.parentNode)
|
|
19745
|
+
continue;
|
|
19567
19746
|
const text = tn.nodeValue || '';
|
|
19568
19747
|
VAR_TOKEN_REGEX.lastIndex = 0;
|
|
19569
19748
|
if (!VAR_TOKEN_REGEX.test(text))
|
|
19570
19749
|
continue;
|
|
19571
19750
|
VAR_TOKEN_REGEX.lastIndex = 0;
|
|
19572
|
-
const
|
|
19573
|
-
|
|
19574
|
-
|
|
19575
|
-
const
|
|
19576
|
-
let lastIndex = 0;
|
|
19751
|
+
const caretOffset = !force && caretRange && caretRange.collapsed && caretRange.startContainer === tn
|
|
19752
|
+
? caretRange.startOffset
|
|
19753
|
+
: -1;
|
|
19754
|
+
const matches = [];
|
|
19577
19755
|
let m;
|
|
19578
19756
|
while ((m = VAR_TOKEN_REGEX.exec(text)) !== null) {
|
|
19579
|
-
|
|
19580
|
-
|
|
19581
|
-
|
|
19582
|
-
|
|
19583
|
-
|
|
19584
|
-
|
|
19585
|
-
if (lastIndex < text.length) {
|
|
19586
|
-
frag.appendChild(document.createTextNode(text.slice(lastIndex)));
|
|
19757
|
+
const start = m.index;
|
|
19758
|
+
const end = start + m[0].length;
|
|
19759
|
+
// Keep the token as plain text while the caret is strictly inside.
|
|
19760
|
+
if (caretOffset > start && caretOffset < end)
|
|
19761
|
+
continue;
|
|
19762
|
+
matches.push({ start, end, name: m[1] });
|
|
19587
19763
|
}
|
|
19588
|
-
|
|
19589
|
-
|
|
19590
|
-
const
|
|
19591
|
-
|
|
19592
|
-
|
|
19593
|
-
|
|
19594
|
-
|
|
19764
|
+
if (!matches.length)
|
|
19765
|
+
continue;
|
|
19766
|
+
const frag = document.createDocumentFragment();
|
|
19767
|
+
let cursor = 0;
|
|
19768
|
+
for (const mt of matches) {
|
|
19769
|
+
if (mt.start > cursor) {
|
|
19770
|
+
frag.appendChild(document.createTextNode(text.slice(cursor, mt.start)));
|
|
19771
|
+
}
|
|
19772
|
+
const chip = this.buildChip(mt.name);
|
|
19773
|
+
frag.appendChild(chip);
|
|
19774
|
+
lastChip = chip;
|
|
19775
|
+
cursor = mt.end;
|
|
19776
|
+
}
|
|
19777
|
+
if (cursor < text.length) {
|
|
19778
|
+
frag.appendChild(document.createTextNode(text.slice(cursor)));
|
|
19779
|
+
}
|
|
19780
|
+
tn.parentNode.replaceChild(frag, tn);
|
|
19781
|
+
changed = true;
|
|
19782
|
+
}
|
|
19783
|
+
if (changed && lastChip)
|
|
19784
|
+
this.placeCaretAfter(lastChip);
|
|
19785
|
+
}
|
|
19786
|
+
collectDescendantTextNodes(root) {
|
|
19787
|
+
const out = [];
|
|
19788
|
+
const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, {
|
|
19789
|
+
acceptNode: (node) => {
|
|
19790
|
+
let p = node.parentNode;
|
|
19791
|
+
while (p && p !== root) {
|
|
19792
|
+
if (p.classList?.contains?.('cqa-var-chip')) {
|
|
19793
|
+
return NodeFilter.FILTER_REJECT;
|
|
19794
|
+
}
|
|
19795
|
+
p = p.parentNode;
|
|
19796
|
+
}
|
|
19797
|
+
return NodeFilter.FILTER_ACCEPT;
|
|
19798
|
+
},
|
|
19799
|
+
});
|
|
19800
|
+
let n;
|
|
19801
|
+
while ((n = walker.nextNode()))
|
|
19802
|
+
out.push(n);
|
|
19803
|
+
return out;
|
|
19595
19804
|
}
|
|
19805
|
+
// ---- Render / serialize ---------------------------------------------------
|
|
19596
19806
|
render(value) {
|
|
19597
19807
|
const editor = this.editorRef.nativeElement;
|
|
19598
19808
|
editor.innerHTML = '';
|
|
@@ -19615,22 +19825,30 @@ class MixedVariableInputComponent {
|
|
|
19615
19825
|
serialize() {
|
|
19616
19826
|
const editor = this.editorRef.nativeElement;
|
|
19617
19827
|
let out = '';
|
|
19618
|
-
|
|
19619
|
-
if (
|
|
19620
|
-
out += (
|
|
19828
|
+
const walk = (node) => {
|
|
19829
|
+
if (node.nodeType === Node.TEXT_NODE) {
|
|
19830
|
+
out += (node.nodeValue || '').replace(/\u00a0/g, ' ');
|
|
19831
|
+
return;
|
|
19621
19832
|
}
|
|
19622
|
-
|
|
19623
|
-
|
|
19624
|
-
|
|
19625
|
-
|
|
19626
|
-
|
|
19627
|
-
|
|
19628
|
-
|
|
19629
|
-
|
|
19630
|
-
out += el.textContent || '';
|
|
19631
|
-
}
|
|
19833
|
+
if (node.nodeType !== Node.ELEMENT_NODE)
|
|
19834
|
+
return;
|
|
19835
|
+
const el = node;
|
|
19836
|
+
if (el.classList.contains('cqa-var-chip')) {
|
|
19837
|
+
const name = el.getAttribute('data-var') || '';
|
|
19838
|
+
if (name)
|
|
19839
|
+
out += '${' + name + '}';
|
|
19840
|
+
return;
|
|
19632
19841
|
}
|
|
19633
|
-
|
|
19842
|
+
if (el.tagName === 'BR') {
|
|
19843
|
+
out += '\n';
|
|
19844
|
+
return;
|
|
19845
|
+
}
|
|
19846
|
+
const isBlock = el.tagName === 'DIV' || el.tagName === 'P';
|
|
19847
|
+
if (isBlock && out.length > 0 && !out.endsWith('\n'))
|
|
19848
|
+
out += '\n';
|
|
19849
|
+
el.childNodes.forEach(walk);
|
|
19850
|
+
};
|
|
19851
|
+
editor.childNodes.forEach(walk);
|
|
19634
19852
|
return out;
|
|
19635
19853
|
}
|
|
19636
19854
|
buildChip(name) {
|
|
@@ -19655,6 +19873,7 @@ class MixedVariableInputComponent {
|
|
|
19655
19873
|
chip.appendChild(remove);
|
|
19656
19874
|
return chip;
|
|
19657
19875
|
}
|
|
19876
|
+
// ---- Selection / caret helpers -------------------------------------------
|
|
19658
19877
|
getSelectionRange() {
|
|
19659
19878
|
const sel = window.getSelection();
|
|
19660
19879
|
if (!sel || sel.rangeCount === 0)
|
|
@@ -19664,6 +19883,25 @@ class MixedVariableInputComponent {
|
|
|
19664
19883
|
return null;
|
|
19665
19884
|
return range;
|
|
19666
19885
|
}
|
|
19886
|
+
getSelectedInfo() {
|
|
19887
|
+
const sel = window.getSelection();
|
|
19888
|
+
if (!sel || sel.rangeCount === 0)
|
|
19889
|
+
return null;
|
|
19890
|
+
const range = sel.getRangeAt(0);
|
|
19891
|
+
if (range.collapsed)
|
|
19892
|
+
return null;
|
|
19893
|
+
const editor = this.editorRef.nativeElement;
|
|
19894
|
+
if (!editor.contains(range.startContainer) || !editor.contains(range.endContainer))
|
|
19895
|
+
return null;
|
|
19896
|
+
const text = range.toString();
|
|
19897
|
+
if (!text)
|
|
19898
|
+
return null;
|
|
19899
|
+
return { text, range: range.cloneRange() };
|
|
19900
|
+
}
|
|
19901
|
+
rangeCrossesChip(range) {
|
|
19902
|
+
const contents = range.cloneContents();
|
|
19903
|
+
return !!contents.querySelector?.('.cqa-var-chip');
|
|
19904
|
+
}
|
|
19667
19905
|
getNodeBeforeCaret() {
|
|
19668
19906
|
const range = this.getSelectionRange();
|
|
19669
19907
|
if (!range || !range.collapsed)
|
|
@@ -19678,16 +19916,39 @@ class MixedVariableInputComponent {
|
|
|
19678
19916
|
}
|
|
19679
19917
|
getCurrentWord() {
|
|
19680
19918
|
const range = this.getSelectionRange();
|
|
19681
|
-
if (!range)
|
|
19682
|
-
return '';
|
|
19683
|
-
const node = range.startContainer;
|
|
19684
|
-
if (node.nodeType !== Node.TEXT_NODE)
|
|
19919
|
+
if (!range || !range.collapsed)
|
|
19685
19920
|
return '';
|
|
19921
|
+
let node = range.startContainer;
|
|
19922
|
+
let offset = range.startOffset;
|
|
19923
|
+
if (node.nodeType !== Node.TEXT_NODE) {
|
|
19924
|
+
const prev = node.childNodes[offset - 1];
|
|
19925
|
+
if (!prev || prev.nodeType !== Node.TEXT_NODE)
|
|
19926
|
+
return '';
|
|
19927
|
+
node = prev;
|
|
19928
|
+
offset = (prev.nodeValue || '').length;
|
|
19929
|
+
}
|
|
19686
19930
|
const text = node.nodeValue || '';
|
|
19687
|
-
const
|
|
19688
|
-
|
|
19931
|
+
const braceOpen = text.lastIndexOf('${', offset - 1);
|
|
19932
|
+
if (braceOpen !== -1) {
|
|
19933
|
+
const closeIdx = text.indexOf('}', braceOpen + 2);
|
|
19934
|
+
const tokenClosedBeforeCaret = closeIdx !== -1 && closeIdx < offset;
|
|
19935
|
+
if (!tokenClosedBeforeCaret) {
|
|
19936
|
+
const start = braceOpen + 2;
|
|
19937
|
+
const end = closeIdx === -1 ? text.length : closeIdx;
|
|
19938
|
+
return text.slice(start, end);
|
|
19939
|
+
}
|
|
19940
|
+
}
|
|
19941
|
+
const match = text.slice(0, offset).match(VAR_PATH_TAIL_REGEX);
|
|
19689
19942
|
return match ? match[1] : '';
|
|
19690
19943
|
}
|
|
19944
|
+
// ---- Chip insertion -------------------------------------------------------
|
|
19945
|
+
insertChipReplacingRange(name, range) {
|
|
19946
|
+
const chip = this.buildChip(name);
|
|
19947
|
+
range.deleteContents();
|
|
19948
|
+
range.insertNode(chip);
|
|
19949
|
+
this.stripBracesAround(chip);
|
|
19950
|
+
this.placeCaretAfter(chip);
|
|
19951
|
+
}
|
|
19691
19952
|
insertChipReplacingCurrentWord(name) {
|
|
19692
19953
|
const range = this.getSelectionRange();
|
|
19693
19954
|
const chip = this.buildChip(name);
|
|
@@ -19697,26 +19958,59 @@ class MixedVariableInputComponent {
|
|
|
19697
19958
|
return;
|
|
19698
19959
|
}
|
|
19699
19960
|
const node = range.startContainer;
|
|
19700
|
-
if (node.nodeType
|
|
19701
|
-
const text = node.nodeValue || '';
|
|
19702
|
-
const before = text.slice(0, range.startOffset);
|
|
19703
|
-
const after = text.slice(range.startOffset);
|
|
19704
|
-
const wordMatch = before.match(/([A-Za-z_][A-Za-z0-9_]*)$/);
|
|
19705
|
-
const beforeKept = wordMatch ? before.slice(0, before.length - wordMatch[1].length) : before;
|
|
19706
|
-
const parent = node.parentNode;
|
|
19707
|
-
const frag = document.createDocumentFragment();
|
|
19708
|
-
if (beforeKept)
|
|
19709
|
-
frag.appendChild(document.createTextNode(beforeKept));
|
|
19710
|
-
frag.appendChild(chip);
|
|
19711
|
-
if (after)
|
|
19712
|
-
frag.appendChild(document.createTextNode(after));
|
|
19713
|
-
parent.replaceChild(frag, node);
|
|
19714
|
-
}
|
|
19715
|
-
else {
|
|
19961
|
+
if (node.nodeType !== Node.TEXT_NODE) {
|
|
19716
19962
|
range.insertNode(chip);
|
|
19963
|
+
this.placeCaretAfter(chip);
|
|
19964
|
+
return;
|
|
19717
19965
|
}
|
|
19966
|
+
const text = node.nodeValue || '';
|
|
19967
|
+
const before = text.slice(0, range.startOffset);
|
|
19968
|
+
const after = text.slice(range.startOffset);
|
|
19969
|
+
const wordMatch = before.match(VAR_PATH_TAIL_REGEX);
|
|
19970
|
+
let beforeKept = wordMatch ? before.slice(0, before.length - wordMatch[1].length) : before;
|
|
19971
|
+
let afterKept = after;
|
|
19972
|
+
if (beforeKept.endsWith('${') && afterKept.startsWith('}')) {
|
|
19973
|
+
beforeKept = beforeKept.slice(0, -2);
|
|
19974
|
+
afterKept = afterKept.slice(1);
|
|
19975
|
+
}
|
|
19976
|
+
else if (beforeKept.endsWith('${')) {
|
|
19977
|
+
beforeKept = beforeKept.slice(0, -2);
|
|
19978
|
+
}
|
|
19979
|
+
const frag = document.createDocumentFragment();
|
|
19980
|
+
if (beforeKept)
|
|
19981
|
+
frag.appendChild(document.createTextNode(beforeKept));
|
|
19982
|
+
frag.appendChild(chip);
|
|
19983
|
+
if (afterKept)
|
|
19984
|
+
frag.appendChild(document.createTextNode(afterKept));
|
|
19985
|
+
node.parentNode.replaceChild(frag, node);
|
|
19718
19986
|
this.placeCaretAfter(chip);
|
|
19719
19987
|
}
|
|
19988
|
+
stripBracesAround(chip) {
|
|
19989
|
+
const prev = chip.previousSibling;
|
|
19990
|
+
const next = chip.nextSibling;
|
|
19991
|
+
if (prev && prev.nodeType === Node.TEXT_NODE) {
|
|
19992
|
+
const t = prev.nodeValue || '';
|
|
19993
|
+
if (t.endsWith('${'))
|
|
19994
|
+
prev.nodeValue = t.slice(0, -2);
|
|
19995
|
+
}
|
|
19996
|
+
if (next && next.nodeType === Node.TEXT_NODE) {
|
|
19997
|
+
const t = next.nodeValue || '';
|
|
19998
|
+
if (t.startsWith('}'))
|
|
19999
|
+
next.nodeValue = t.slice(1);
|
|
20000
|
+
}
|
|
20001
|
+
}
|
|
20002
|
+
insertPlainTextAtCaret(text) {
|
|
20003
|
+
const range = this.getSelectionRange();
|
|
20004
|
+
if (!range) {
|
|
20005
|
+
this.editorRef.nativeElement.appendChild(document.createTextNode(text));
|
|
20006
|
+
this.placeCaretAtEnd();
|
|
20007
|
+
return;
|
|
20008
|
+
}
|
|
20009
|
+
range.deleteContents();
|
|
20010
|
+
const node = document.createTextNode(text);
|
|
20011
|
+
range.insertNode(node);
|
|
20012
|
+
this.placeCaretAfter(node);
|
|
20013
|
+
}
|
|
19720
20014
|
placeCaretAfter(node) {
|
|
19721
20015
|
const sel = window.getSelection();
|
|
19722
20016
|
if (!sel)
|
|
@@ -19728,22 +20022,21 @@ class MixedVariableInputComponent {
|
|
|
19728
20022
|
sel.addRange(range);
|
|
19729
20023
|
}
|
|
19730
20024
|
placeCaretAtEnd() {
|
|
19731
|
-
const editor = this.editorRef.nativeElement;
|
|
19732
20025
|
const sel = window.getSelection();
|
|
19733
20026
|
if (!sel)
|
|
19734
20027
|
return;
|
|
19735
20028
|
const range = document.createRange();
|
|
19736
|
-
range.selectNodeContents(
|
|
20029
|
+
range.selectNodeContents(this.editorRef.nativeElement);
|
|
19737
20030
|
range.collapse(false);
|
|
19738
20031
|
sel.removeAllRanges();
|
|
19739
20032
|
sel.addRange(range);
|
|
19740
20033
|
}
|
|
19741
20034
|
}
|
|
19742
20035
|
MixedVariableInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: MixedVariableInputComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
19743
|
-
MixedVariableInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: MixedVariableInputComponent, selector: "cqa-mixed-variable-input", inputs: { value: "value", placeholder: "placeholder", disabled: "disabled" }, outputs: { valueChange: "valueChange" }, host: { listeners: { "document:mousedown": "onDocumentMouseDown($event)" }, classAttribute: "cqa-ui-root" }, viewQueries: [{ propertyName: "editorRef", first: true, predicate: ["editor"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"cqa-mixed-var-wrapper\">\n <div\n #editor\n class=\"cqa-mixed-var-editor\"\n role=\"textbox\"\n spellcheck=\"false\"\n [attr.contenteditable]=\"!disabled\"\n [attr.data-placeholder]=\"placeholder\"\n (input)=\"onInput()\"\n (keydown)=\"onKeyDown($event)\"\n (blur)=\"onEditorBlur()\">\n </div>\n\n <div\n *ngIf=\"showSuggestion\"\n class=\"cqa-mixed-var-suggest\"\n (mousedown)=\"$event.preventDefault()\">\n <button type=\"button\" class=\"cqa-mixed-var-suggest__item\" (click)=\"addAsText()\">\n Add as Text <span class=\"cqa-mixed-var-suggest__hint\">\"{{ pendingWord }}\"</span>\n </button>\n <button type=\"button\"
|
|
20036
|
+
MixedVariableInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: MixedVariableInputComponent, selector: "cqa-mixed-variable-input", inputs: { value: "value", placeholder: "placeholder", disabled: "disabled" }, outputs: { valueChange: "valueChange", validityChange: "validityChange" }, host: { listeners: { "dragstart": "onDragStart($event)", "document:mousedown": "onDocumentMouseDown($event)", "document:selectionchange": "onDocumentSelectionChange()" }, classAttribute: "cqa-ui-root" }, viewQueries: [{ propertyName: "editorRef", first: true, predicate: ["editor"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"cqa-mixed-var-wrapper\">\n <div\n #editor\n class=\"cqa-mixed-var-editor\"\n role=\"textbox\"\n spellcheck=\"false\"\n [attr.contenteditable]=\"!disabled\"\n [attr.data-placeholder]=\"placeholder\"\n [attr.aria-invalid]=\"errorMessage ? 'true' : null\"\n [class.cqa-mixed-var-editor--invalid]=\"errorMessage\"\n (input)=\"onInput()\"\n (keydown)=\"onKeyDown($event)\"\n (focus)=\"onEditorFocus()\"\n (paste)=\"onPaste($event)\"\n (drop)=\"onDrop($event)\"\n (blur)=\"onEditorBlur()\">\n </div>\n <p *ngIf=\"errorMessage\" class=\"cqa-mixed-var-error\" role=\"alert\">{{ errorMessage }}</p>\n\n <div\n *ngIf=\"showSuggestion\"\n class=\"cqa-mixed-var-suggest\"\n (mousedown)=\"$event.preventDefault()\">\n <button type=\"button\" class=\"cqa-mixed-var-suggest__item\" (click)=\"addAsText()\">\n Add as Text <span *ngIf=\"pendingWord\" class=\"cqa-mixed-var-suggest__hint\">\"{{ pendingWord }}\"</span>\n </button>\n <button *ngIf=\"canAddAsVariable\" type=\"button\"\n class=\"cqa-mixed-var-suggest__item cqa-mixed-var-suggest__item--primary\"\n (click)=\"addAsVariable()\">\n Add as local variable <span class=\"cqa-mixed-var-suggest__hint\">${{ '{' }}{{ pendingWord }}{{ '}' }}</span>\n </button>\n </div>\n</div>\n", directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
19744
20037
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: MixedVariableInputComponent, decorators: [{
|
|
19745
20038
|
type: Component,
|
|
19746
|
-
args: [{ selector: 'cqa-mixed-variable-input', changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'cqa-ui-root' }, template: "<div class=\"cqa-mixed-var-wrapper\">\n <div\n #editor\n class=\"cqa-mixed-var-editor\"\n role=\"textbox\"\n spellcheck=\"false\"\n [attr.contenteditable]=\"!disabled\"\n [attr.data-placeholder]=\"placeholder\"\n (input)=\"onInput()\"\n (keydown)=\"onKeyDown($event)\"\n (blur)=\"onEditorBlur()\">\n </div>\n\n <div\n *ngIf=\"showSuggestion\"\n class=\"cqa-mixed-var-suggest\"\n (mousedown)=\"$event.preventDefault()\">\n <button type=\"button\" class=\"cqa-mixed-var-suggest__item\" (click)=\"addAsText()\">\n Add as Text <span class=\"cqa-mixed-var-suggest__hint\">\"{{ pendingWord }}\"</span>\n </button>\n <button type=\"button\"
|
|
20039
|
+
args: [{ selector: 'cqa-mixed-variable-input', changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'cqa-ui-root' }, template: "<div class=\"cqa-mixed-var-wrapper\">\n <div\n #editor\n class=\"cqa-mixed-var-editor\"\n role=\"textbox\"\n spellcheck=\"false\"\n [attr.contenteditable]=\"!disabled\"\n [attr.data-placeholder]=\"placeholder\"\n [attr.aria-invalid]=\"errorMessage ? 'true' : null\"\n [class.cqa-mixed-var-editor--invalid]=\"errorMessage\"\n (input)=\"onInput()\"\n (keydown)=\"onKeyDown($event)\"\n (focus)=\"onEditorFocus()\"\n (paste)=\"onPaste($event)\"\n (drop)=\"onDrop($event)\"\n (blur)=\"onEditorBlur()\">\n </div>\n <p *ngIf=\"errorMessage\" class=\"cqa-mixed-var-error\" role=\"alert\">{{ errorMessage }}</p>\n\n <div\n *ngIf=\"showSuggestion\"\n class=\"cqa-mixed-var-suggest\"\n (mousedown)=\"$event.preventDefault()\">\n <button type=\"button\" class=\"cqa-mixed-var-suggest__item\" (click)=\"addAsText()\">\n Add as Text <span *ngIf=\"pendingWord\" class=\"cqa-mixed-var-suggest__hint\">\"{{ pendingWord }}\"</span>\n </button>\n <button *ngIf=\"canAddAsVariable\" type=\"button\"\n class=\"cqa-mixed-var-suggest__item cqa-mixed-var-suggest__item--primary\"\n (click)=\"addAsVariable()\">\n Add as local variable <span class=\"cqa-mixed-var-suggest__hint\">${{ '{' }}{{ pendingWord }}{{ '}' }}</span>\n </button>\n </div>\n</div>\n", styles: [] }]
|
|
19747
20040
|
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.ElementRef }]; }, propDecorators: { value: [{
|
|
19748
20041
|
type: Input
|
|
19749
20042
|
}], placeholder: [{
|
|
@@ -19752,12 +20045,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
|
|
|
19752
20045
|
type: Input
|
|
19753
20046
|
}], valueChange: [{
|
|
19754
20047
|
type: Output
|
|
20048
|
+
}], validityChange: [{
|
|
20049
|
+
type: Output
|
|
19755
20050
|
}], editorRef: [{
|
|
19756
20051
|
type: ViewChild,
|
|
19757
20052
|
args: ['editor', { static: true }]
|
|
20053
|
+
}], onDragStart: [{
|
|
20054
|
+
type: HostListener,
|
|
20055
|
+
args: ['dragstart', ['$event']]
|
|
19758
20056
|
}], onDocumentMouseDown: [{
|
|
19759
20057
|
type: HostListener,
|
|
19760
20058
|
args: ['document:mousedown', ['$event']]
|
|
20059
|
+
}], onDocumentSelectionChange: [{
|
|
20060
|
+
type: HostListener,
|
|
20061
|
+
args: ['document:selectionchange']
|
|
19761
20062
|
}] } });
|
|
19762
20063
|
|
|
19763
20064
|
class CustomTextareaComponent {
|
|
@@ -32672,6 +32973,10 @@ class TemplateVariablesFormComponent {
|
|
|
32672
32973
|
{ id: 'environment', value: 'environment', name: '*|Environment|', label: '*|Environment|' }
|
|
32673
32974
|
];
|
|
32674
32975
|
this.createElementVisible = false;
|
|
32976
|
+
// Tracks active variable-syntax errors by variable name. The validator below
|
|
32977
|
+
// reads from this map so errors survive control re-validation on setValue().
|
|
32978
|
+
this.variableSyntaxErrors = new Map();
|
|
32979
|
+
this.controlsWithSyntaxValidator = new WeakSet();
|
|
32675
32980
|
}
|
|
32676
32981
|
onCreateElement(payload) {
|
|
32677
32982
|
this.createElement.emit(payload);
|
|
@@ -34036,6 +34341,30 @@ class TemplateVariablesFormComponent {
|
|
|
34036
34341
|
// Emit the search query to parent component
|
|
34037
34342
|
this.searchElements.emit(event.query);
|
|
34038
34343
|
}
|
|
34344
|
+
makeSyntaxValidator(variableName) {
|
|
34345
|
+
return () => {
|
|
34346
|
+
const err = this.variableSyntaxErrors.get(variableName);
|
|
34347
|
+
return err ? { invalidVariableSyntax: err } : null;
|
|
34348
|
+
};
|
|
34349
|
+
}
|
|
34350
|
+
onTestDataValidityChange(variableName, event) {
|
|
34351
|
+
const valueControl = this.getVariableFormGroup(variableName)?.get('value');
|
|
34352
|
+
if (!valueControl)
|
|
34353
|
+
return;
|
|
34354
|
+
if (event.valid) {
|
|
34355
|
+
this.variableSyntaxErrors.delete(variableName);
|
|
34356
|
+
}
|
|
34357
|
+
else {
|
|
34358
|
+
this.variableSyntaxErrors.set(variableName, event.error || 'Invalid variable name.');
|
|
34359
|
+
}
|
|
34360
|
+
if (!this.controlsWithSyntaxValidator.has(valueControl)) {
|
|
34361
|
+
valueControl.addValidators(this.makeSyntaxValidator(variableName));
|
|
34362
|
+
this.controlsWithSyntaxValidator.add(valueControl);
|
|
34363
|
+
}
|
|
34364
|
+
valueControl.updateValueAndValidity({ emitEvent: false });
|
|
34365
|
+
valueControl.markAsTouched();
|
|
34366
|
+
this.cdr.markForCheck();
|
|
34367
|
+
}
|
|
34039
34368
|
onTestDataValueChange(variableName, rawValue) {
|
|
34040
34369
|
// Find the variable
|
|
34041
34370
|
const variable = this.templateVariables.find(v => v.name === variableName);
|
|
@@ -35178,10 +35507,10 @@ class TemplateVariablesFormComponent {
|
|
|
35178
35507
|
}
|
|
35179
35508
|
}
|
|
35180
35509
|
TemplateVariablesFormComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TemplateVariablesFormComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
35181
|
-
TemplateVariablesFormComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: TemplateVariablesFormComponent, selector: "cqa-template-variables-form", inputs: { templateVariables: "templateVariables", variablesForm: "variablesForm", metadata: "metadata", description: "description", elementOptions: "elementOptions", hasMoreElements: "hasMoreElements", isLoadingElements: "isLoadingElements", screenNameOptions: "screenNameOptions", hasMoreScreenNames: "hasMoreScreenNames", isLoadingScreenNames: "isLoadingScreenNames", parameterOptions: "parameterOptions", hasMoreParameters: "hasMoreParameters", isLoadingParameters: "isLoadingParameters", uploadOptions: "uploadOptions", hasMoreUploads: "hasMoreUploads", isLoadingUploads: "isLoadingUploads", environmentOptions: "environmentOptions", hasMoreEnvironments: "hasMoreEnvironments", isLoadingEnvironments: "isLoadingEnvironments", defaultTestDataProfileId: "defaultTestDataProfileId", defaultTestDataStartIndex: "defaultTestDataStartIndex", defaultTestDataEndIndex: "defaultTestDataEndIndex", isInsideForLoopStep: "isInsideForLoopStep", hasTestDataProfile: "hasTestDataProfile", isEditInDepth: "isEditInDepth", isDebug: "isDebug", createElementVisible: "createElementVisible" }, outputs: { variableValueChange: "variableValueChange", variableBooleanChange: "variableBooleanChange", metadataChange: "metadataChange", descriptionChange: "descriptionChange", loadMoreElements: "loadMoreElements", searchElements: "searchElements", searchElementsByScreenName: "searchElementsByScreenName", createElement: "createElement", searchScreenName: "searchScreenName", loadMoreScreenNames: "loadMoreScreenNames", createScreenNameRequest: "createScreenNameRequest", searchParameters: "searchParameters", loadMoreParameters: "loadMoreParameters", searchUploads: "searchUploads", loadMoreUploads: "loadMoreUploads", searchEnvironments: "searchEnvironments", loadMoreEnvironments: "loadMoreEnvironments", cancelElementForm: "cancelElementForm", elementFormVisibilityChange: "elementFormVisibilityChange" }, host: { classAttribute: "cqa-ui-root" }, usesOnChanges: true, ngImport: i0, template: "<style>\n .capitalize-first::first-letter {\n text-transform: uppercase;\n }\n</style>\n<div class=\"cqa-flex cqa-gap-x-6 cqa-gap-y-4 cqa-flex-wrap template-variables-form\" [ngClass]=\"{'cqa-flex-col': isEditInDepth}\" *ngIf=\"!createElementVisible\">\n \n <!-- Metadata - Only show if element is available in form -->\n <div *ngIf=\"selectorVariableAvailable\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Metadata\n </label>\n <cqa-custom-input [placeholder]=\"'Text Input'\" [value]=\"metadata\" [fullWidth]=\"true\"\n (valueChange)=\"metadataChange.emit($event)\">\n </cqa-custom-input>\n </div>\n\n <!-- Description -->\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Description\n </label>\n <cqa-custom-input [placeholder]=\"'Text Input'\" [value]=\"description\" [fullWidth]=\"true\"\n (valueChange)=\"descriptionChange.emit($event)\">\n </cqa-custom-input>\n </div>\n \n <ng-container *ngFor=\"let variable of templateVariables; let i = index; trackBy: trackByVariable\">\n <!-- Boolean variables with mat-slide-toggle -->\n <ng-container *ngIf=\"variable.type === 'boolean'\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }}\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 <ng-container *ngIf=\"variable.type === 'dropdown'\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }}\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n </ng-container>\n\n <!-- Textarea variables -->\n <ng-container *ngIf=\"variable.type === 'textarea'\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }}\n </label>\n <textarea class=\"cqa-w-full cqa-border cqa-border-gray-300 cqa-rounded-lg cqa-px-3 cqa-py-2 cqa-text-sm cqa-text-gray-900 cqa-resize-y focus:cqa-outline-none focus:cqa-ring-1 focus:cqa-ring-indigo-500 focus:cqa-border-indigo-500\"\n [value]=\"variable.value || ''\"\n rows=\"4\"\n style=\"min-height: 42px;\"\n (input)=\"onVariableValueChange(variable.name, $any($event.target).value)\"></textarea>\n </div>\n </ng-container>\n\n <!-- Number variables with number input -->\n <ng-container *ngIf=\"variable.type === 'number' && variable.dataKey !== 'element'\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }}\n </label>\n <cqa-custom-input [type]=\"'number'\" [placeholder]=\"'Number Input'\" [value]=\"variable.value\" [fullWidth]=\"true\"\n (valueChange)=\"onVariableValueChange(variable.name, $event)\">\n </cqa-custom-input>\n </div>\n </ng-container>\n\n <!-- Non-boolean, non-custom_code variables -->\n <ng-container *ngIf=\"variable.name !== 'custom_code' && variable.type !== 'boolean' && variable.type !== 'dropdown' && variable.type !== 'textarea' && !(variable.type === 'number' && variable.dataKey !== 'element')\">\n <!-- Element variables with cascading dropdowns (screen name + element) -->\n <ng-container *ngIf=\"isElementType(variable)\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }} Screen Name<span class=\"cqa-text-red-500\">*</span>\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getScreenNameSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n <div *ngIf=\"hasSelectedScreenName(variable); else elementManualInput\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }}<span class=\"cqa-text-red-500\">*</span>\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getElementSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n <ng-template #elementManualInput>\n <ng-container *ngIf=\"variable.type === 'number'\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }}<span class=\"cqa-text-red-500\">*</span>\n </label>\n <cqa-custom-input [type]=\"'number'\" [placeholder]=\"'Number Input'\" [value]=\"variable.value\" [fullWidth]=\"true\"\n (valueChange)=\"onVariableValueChange(variable.name, $event)\">\n </cqa-custom-input>\n </div>\n </ng-container>\n <ng-container *ngIf=\"variable.type !== 'number'\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }}<span class=\"cqa-text-red-500\">*</span>\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-container>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"!isElementType(variable)\">\n <!-- Other dropdown variables (type, scrollTo, label) -->\n <ng-container *ngIf=\"shouldShowDropdown(variable); else defaultInput\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }}\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n </ng-container>\n </ng-container>\n <ng-template #defaultInput>\n <!-- Test-data, source-value, or target-value with data type dropdown -->\n <ng-container *ngIf=\"needsDataTypeDropdown(variable); else regularInput\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }} Type<span class=\"cqa-text-red-500\">*</span>\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getDataTypeSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n <ng-container *ngIf=\"isEnvironmentType(variable)\">\n <div *ngIf=\"isEnvironmentType(variable)\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Environment Name<span class=\"cqa-text-red-500\">*</span>\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getEnvironmentSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n <div *ngIf=\"hasSelectedEnvironment(variable)\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Environment Value<span class=\"cqa-text-red-500\">*</span>\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getEnvironmentParameterSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n </ng-container>\n <ng-container *ngIf=\"isParameterType(variable)\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Test Data Profile<span class=\"cqa-text-red-500\">*</span>\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getTestDataProfileSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n <div *ngIf=\"hasSelectedTestDataProfile(variable) && !isInsideForLoopStep\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Data Set<span class=\"cqa-text-red-500\">*</span>\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getDataSetSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n <div *ngIf=\"hasSelectedTestDataProfile(variable) && isInsideForLoopStep\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Data Set Start<span class=\"cqa-text-red-500\">*</span>\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getDataSetRangeSelectConfig(variable, i, 'start')\">\n </cqa-dynamic-select>\n </div>\n <div *ngIf=\"hasSelectedTestDataProfile(variable) && isInsideForLoopStep\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Data Set End<span class=\"cqa-text-red-500\">*</span>\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getDataSetRangeSelectConfig(variable, i, 'end')\">\n </cqa-dynamic-select>\n </div>\n <div *ngIf=\"hasSelectedDataSet(variable)\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }}<span class=\"cqa-text-red-500\">*</span>\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getParameterSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div> \n </ng-container>\n <div *ngIf=\"isPlainTextType(variable) || isRuntimeType(variable)\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }}<span class=\"cqa-text-red-500\">*</span>\n </label>\n <ng-container *ngIf=\"isPlainTextType(variable); else runtimePlainInput\">\n <cqa-mixed-variable-input\n [placeholder]=\"'Text Input'\"\n [value]=\"getRawValue(variable)\"\n (valueChange)=\"onTestDataValueChange(variable.name, $event)\">\n </cqa-mixed-variable-input>\n </ng-container>\n <ng-template #runtimePlainInput>\n <cqa-custom-input [placeholder]=\"'Text Input'\" [value]=\"getRawValue(variable)\" [fullWidth]=\"true\"\n (valueChange)=\"onTestDataValueChange(variable.name, $event)\">\n </cqa-custom-input>\n </ng-template>\n </div>\n </ng-container>\n <ng-template #regularInput>\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }}\n </label>\n <cqa-custom-input [placeholder]=\"'Text Input'\" [value]=\"variable.value\" [fullWidth]=\"true\"\n (valueChange)=\"onVariableValueChange(variable.name, $event)\">\n </cqa-custom-input>\n </div>\n </ng-template>\n </ng-template>\n </ng-container>\n </ng-container>\n</div>\n\n<div *ngIf=\"createElementVisible\">\n <cqa-element-form\n [isCreateMode]=\"true\"\n [screenNameOptions]=\"screenNameOptions\"\n [hasMoreScreenNames]=\"hasMoreScreenNames\"\n [isLoadingScreenNames]=\"isLoadingScreenNames\"\n [isEditInDepthAvailable]=\"false\"\n (createElement)=\"onCreateElement($event)\"\n (cancel)=\"onCancelElementForm()\"\n (searchScreenName)=\"searchScreenName.emit($event)\"\n (loadMoreScreenNames)=\"loadMoreScreenNames.emit($event)\"\n (createScreenNameRequest)=\"createScreenNameRequest.emit($event)\">\n </cqa-element-form>\n</div>", styles: ["\n .capitalize-first::first-letter {\n text-transform: uppercase;\n }\n"], components: [{ type: CustomInputComponent, selector: "cqa-custom-input", inputs: ["inputId", "label", "type", "placeholder", "value", "disabled", "errors", "required", "ariaLabel", "size", "fullWidth", "maxLength", "showCharCount", "inputInlineStyle", "labelInlineStyle"], outputs: ["valueChange", "blurred", "focused", "enterPressed"] }, { type: i3$4.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: MixedVariableInputComponent, selector: "cqa-mixed-variable-input", inputs: ["value", "placeholder", "disabled"], outputs: ["valueChange"] }, { type: ElementFormComponent, selector: "cqa-element-form", inputs: ["elementId", "element", "screenNameOptions", "elements", "hasMoreScreenNames", "isLoadingScreenNames", "hasMoreElements", "isLoadingElements", "isElementLoading", "isEditMode", "isCreateMode", "isEditInDepthAvailable"], outputs: ["createElement", "updateElement", "createScreenNameRequest", "searchScreenName", "loadMoreScreenNames", "searchElements", "loadMoreElements", "searchElementsByScreenName", "cancel", "editInDepth"] }], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], pipes: { "cqaCamelToTitle": CamelToTitlePipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
35510
|
+
TemplateVariablesFormComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: TemplateVariablesFormComponent, selector: "cqa-template-variables-form", inputs: { templateVariables: "templateVariables", variablesForm: "variablesForm", metadata: "metadata", description: "description", elementOptions: "elementOptions", hasMoreElements: "hasMoreElements", isLoadingElements: "isLoadingElements", screenNameOptions: "screenNameOptions", hasMoreScreenNames: "hasMoreScreenNames", isLoadingScreenNames: "isLoadingScreenNames", parameterOptions: "parameterOptions", hasMoreParameters: "hasMoreParameters", isLoadingParameters: "isLoadingParameters", uploadOptions: "uploadOptions", hasMoreUploads: "hasMoreUploads", isLoadingUploads: "isLoadingUploads", environmentOptions: "environmentOptions", hasMoreEnvironments: "hasMoreEnvironments", isLoadingEnvironments: "isLoadingEnvironments", defaultTestDataProfileId: "defaultTestDataProfileId", defaultTestDataStartIndex: "defaultTestDataStartIndex", defaultTestDataEndIndex: "defaultTestDataEndIndex", isInsideForLoopStep: "isInsideForLoopStep", hasTestDataProfile: "hasTestDataProfile", isEditInDepth: "isEditInDepth", isDebug: "isDebug", createElementVisible: "createElementVisible" }, outputs: { variableValueChange: "variableValueChange", variableBooleanChange: "variableBooleanChange", metadataChange: "metadataChange", descriptionChange: "descriptionChange", loadMoreElements: "loadMoreElements", searchElements: "searchElements", searchElementsByScreenName: "searchElementsByScreenName", createElement: "createElement", searchScreenName: "searchScreenName", loadMoreScreenNames: "loadMoreScreenNames", createScreenNameRequest: "createScreenNameRequest", searchParameters: "searchParameters", loadMoreParameters: "loadMoreParameters", searchUploads: "searchUploads", loadMoreUploads: "loadMoreUploads", searchEnvironments: "searchEnvironments", loadMoreEnvironments: "loadMoreEnvironments", cancelElementForm: "cancelElementForm", elementFormVisibilityChange: "elementFormVisibilityChange" }, host: { classAttribute: "cqa-ui-root" }, usesOnChanges: true, ngImport: i0, template: "<style>\n .capitalize-first::first-letter {\n text-transform: uppercase;\n }\n</style>\n<div class=\"cqa-flex cqa-gap-x-6 cqa-gap-y-4 cqa-flex-wrap template-variables-form\" [ngClass]=\"{'cqa-flex-col': isEditInDepth}\" *ngIf=\"!createElementVisible\">\n \n <!-- Metadata - Only show if element is available in form -->\n <div *ngIf=\"selectorVariableAvailable\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Metadata\n </label>\n <cqa-custom-input [placeholder]=\"'Text Input'\" [value]=\"metadata\" [fullWidth]=\"true\"\n (valueChange)=\"metadataChange.emit($event)\">\n </cqa-custom-input>\n </div>\n\n <!-- Description -->\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Description\n </label>\n <cqa-custom-input [placeholder]=\"'Text Input'\" [value]=\"description\" [fullWidth]=\"true\"\n (valueChange)=\"descriptionChange.emit($event)\">\n </cqa-custom-input>\n </div>\n \n <ng-container *ngFor=\"let variable of templateVariables; let i = index; trackBy: trackByVariable\">\n <!-- Boolean variables with mat-slide-toggle -->\n <ng-container *ngIf=\"variable.type === 'boolean'\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }}\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 <ng-container *ngIf=\"variable.type === 'dropdown'\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }}\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n </ng-container>\n\n <!-- Textarea variables -->\n <ng-container *ngIf=\"variable.type === 'textarea'\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }}\n </label>\n <textarea class=\"cqa-w-full cqa-border cqa-border-gray-300 cqa-rounded-lg cqa-px-3 cqa-py-2 cqa-text-sm cqa-text-gray-900 cqa-resize-y focus:cqa-outline-none focus:cqa-ring-1 focus:cqa-ring-indigo-500 focus:cqa-border-indigo-500\"\n [value]=\"variable.value || ''\"\n rows=\"4\"\n style=\"min-height: 42px;\"\n (input)=\"onVariableValueChange(variable.name, $any($event.target).value)\"></textarea>\n </div>\n </ng-container>\n\n <!-- Number variables with number input -->\n <ng-container *ngIf=\"variable.type === 'number' && variable.dataKey !== 'element'\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }}\n </label>\n <cqa-custom-input [type]=\"'number'\" [placeholder]=\"'Number Input'\" [value]=\"variable.value\" [fullWidth]=\"true\"\n (valueChange)=\"onVariableValueChange(variable.name, $event)\">\n </cqa-custom-input>\n </div>\n </ng-container>\n\n <!-- Non-boolean, non-custom_code variables -->\n <ng-container *ngIf=\"variable.name !== 'custom_code' && variable.type !== 'boolean' && variable.type !== 'dropdown' && variable.type !== 'textarea' && !(variable.type === 'number' && variable.dataKey !== 'element')\">\n <!-- Element variables with cascading dropdowns (screen name + element) -->\n <ng-container *ngIf=\"isElementType(variable)\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }} Screen Name<span class=\"cqa-text-red-500\">*</span>\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getScreenNameSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n <div *ngIf=\"hasSelectedScreenName(variable); else elementManualInput\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }}<span class=\"cqa-text-red-500\">*</span>\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getElementSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n <ng-template #elementManualInput>\n <ng-container *ngIf=\"variable.type === 'number'\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }}<span class=\"cqa-text-red-500\">*</span>\n </label>\n <cqa-custom-input [type]=\"'number'\" [placeholder]=\"'Number Input'\" [value]=\"variable.value\" [fullWidth]=\"true\"\n (valueChange)=\"onVariableValueChange(variable.name, $event)\">\n </cqa-custom-input>\n </div>\n </ng-container>\n <ng-container *ngIf=\"variable.type !== 'number'\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }}<span class=\"cqa-text-red-500\">*</span>\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-container>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"!isElementType(variable)\">\n <!-- Other dropdown variables (type, scrollTo, label) -->\n <ng-container *ngIf=\"shouldShowDropdown(variable); else defaultInput\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }}\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n </ng-container>\n </ng-container>\n <ng-template #defaultInput>\n <!-- Test-data, source-value, or target-value with data type dropdown -->\n <ng-container *ngIf=\"needsDataTypeDropdown(variable); else regularInput\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }} Type<span class=\"cqa-text-red-500\">*</span>\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getDataTypeSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n <ng-container *ngIf=\"isEnvironmentType(variable)\">\n <div *ngIf=\"isEnvironmentType(variable)\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Environment Name<span class=\"cqa-text-red-500\">*</span>\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getEnvironmentSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n <div *ngIf=\"hasSelectedEnvironment(variable)\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Environment Value<span class=\"cqa-text-red-500\">*</span>\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getEnvironmentParameterSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n </ng-container>\n <ng-container *ngIf=\"isParameterType(variable)\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Test Data Profile<span class=\"cqa-text-red-500\">*</span>\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getTestDataProfileSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n <div *ngIf=\"hasSelectedTestDataProfile(variable) && !isInsideForLoopStep\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Data Set<span class=\"cqa-text-red-500\">*</span>\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getDataSetSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n <div *ngIf=\"hasSelectedTestDataProfile(variable) && isInsideForLoopStep\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Data Set Start<span class=\"cqa-text-red-500\">*</span>\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getDataSetRangeSelectConfig(variable, i, 'start')\">\n </cqa-dynamic-select>\n </div>\n <div *ngIf=\"hasSelectedTestDataProfile(variable) && isInsideForLoopStep\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Data Set End<span class=\"cqa-text-red-500\">*</span>\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getDataSetRangeSelectConfig(variable, i, 'end')\">\n </cqa-dynamic-select>\n </div>\n <div *ngIf=\"hasSelectedDataSet(variable)\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }}<span class=\"cqa-text-red-500\">*</span>\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getParameterSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div> \n </ng-container>\n <div *ngIf=\"isPlainTextType(variable) || isRuntimeType(variable)\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }}<span class=\"cqa-text-red-500\">*</span>\n </label>\n <ng-container *ngIf=\"isPlainTextType(variable); else runtimePlainInput\">\n <cqa-mixed-variable-input\n [placeholder]=\"'Text Input'\"\n [value]=\"getRawValue(variable)\"\n (valueChange)=\"onTestDataValueChange(variable.name, $event)\"\n (validityChange)=\"onTestDataValidityChange(variable.name, $event)\">\n </cqa-mixed-variable-input>\n </ng-container>\n <ng-template #runtimePlainInput>\n <cqa-custom-input [placeholder]=\"'Text Input'\" [value]=\"getRawValue(variable)\" [fullWidth]=\"true\"\n (valueChange)=\"onTestDataValueChange(variable.name, $event)\">\n </cqa-custom-input>\n </ng-template>\n </div>\n </ng-container>\n <ng-template #regularInput>\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }}\n </label>\n <cqa-custom-input [placeholder]=\"'Text Input'\" [value]=\"variable.value\" [fullWidth]=\"true\"\n (valueChange)=\"onVariableValueChange(variable.name, $event)\">\n </cqa-custom-input>\n </div>\n </ng-template>\n </ng-template>\n </ng-container>\n </ng-container>\n</div>\n\n<div *ngIf=\"createElementVisible\">\n <cqa-element-form\n [isCreateMode]=\"true\"\n [screenNameOptions]=\"screenNameOptions\"\n [hasMoreScreenNames]=\"hasMoreScreenNames\"\n [isLoadingScreenNames]=\"isLoadingScreenNames\"\n [isEditInDepthAvailable]=\"false\"\n (createElement)=\"onCreateElement($event)\"\n (cancel)=\"onCancelElementForm()\"\n (searchScreenName)=\"searchScreenName.emit($event)\"\n (loadMoreScreenNames)=\"loadMoreScreenNames.emit($event)\"\n (createScreenNameRequest)=\"createScreenNameRequest.emit($event)\">\n </cqa-element-form>\n</div>", styles: ["\n .capitalize-first::first-letter {\n text-transform: uppercase;\n }\n"], components: [{ type: CustomInputComponent, selector: "cqa-custom-input", inputs: ["inputId", "label", "type", "placeholder", "value", "disabled", "errors", "required", "ariaLabel", "size", "fullWidth", "maxLength", "showCharCount", "inputInlineStyle", "labelInlineStyle"], outputs: ["valueChange", "blurred", "focused", "enterPressed"] }, { type: i3$4.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: MixedVariableInputComponent, selector: "cqa-mixed-variable-input", inputs: ["value", "placeholder", "disabled"], outputs: ["valueChange", "validityChange"] }, { type: ElementFormComponent, selector: "cqa-element-form", inputs: ["elementId", "element", "screenNameOptions", "elements", "hasMoreScreenNames", "isLoadingScreenNames", "hasMoreElements", "isLoadingElements", "isElementLoading", "isEditMode", "isCreateMode", "isEditInDepthAvailable"], outputs: ["createElement", "updateElement", "createScreenNameRequest", "searchScreenName", "loadMoreScreenNames", "searchElements", "loadMoreElements", "searchElementsByScreenName", "cancel", "editInDepth"] }], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], pipes: { "cqaCamelToTitle": CamelToTitlePipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
35182
35511
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TemplateVariablesFormComponent, decorators: [{
|
|
35183
35512
|
type: Component,
|
|
35184
|
-
args: [{ selector: 'cqa-template-variables-form', host: { class: 'cqa-ui-root' }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<style>\n .capitalize-first::first-letter {\n text-transform: uppercase;\n }\n</style>\n<div class=\"cqa-flex cqa-gap-x-6 cqa-gap-y-4 cqa-flex-wrap template-variables-form\" [ngClass]=\"{'cqa-flex-col': isEditInDepth}\" *ngIf=\"!createElementVisible\">\n \n <!-- Metadata - Only show if element is available in form -->\n <div *ngIf=\"selectorVariableAvailable\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Metadata\n </label>\n <cqa-custom-input [placeholder]=\"'Text Input'\" [value]=\"metadata\" [fullWidth]=\"true\"\n (valueChange)=\"metadataChange.emit($event)\">\n </cqa-custom-input>\n </div>\n\n <!-- Description -->\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Description\n </label>\n <cqa-custom-input [placeholder]=\"'Text Input'\" [value]=\"description\" [fullWidth]=\"true\"\n (valueChange)=\"descriptionChange.emit($event)\">\n </cqa-custom-input>\n </div>\n \n <ng-container *ngFor=\"let variable of templateVariables; let i = index; trackBy: trackByVariable\">\n <!-- Boolean variables with mat-slide-toggle -->\n <ng-container *ngIf=\"variable.type === 'boolean'\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }}\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 <ng-container *ngIf=\"variable.type === 'dropdown'\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }}\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n </ng-container>\n\n <!-- Textarea variables -->\n <ng-container *ngIf=\"variable.type === 'textarea'\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }}\n </label>\n <textarea class=\"cqa-w-full cqa-border cqa-border-gray-300 cqa-rounded-lg cqa-px-3 cqa-py-2 cqa-text-sm cqa-text-gray-900 cqa-resize-y focus:cqa-outline-none focus:cqa-ring-1 focus:cqa-ring-indigo-500 focus:cqa-border-indigo-500\"\n [value]=\"variable.value || ''\"\n rows=\"4\"\n style=\"min-height: 42px;\"\n (input)=\"onVariableValueChange(variable.name, $any($event.target).value)\"></textarea>\n </div>\n </ng-container>\n\n <!-- Number variables with number input -->\n <ng-container *ngIf=\"variable.type === 'number' && variable.dataKey !== 'element'\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }}\n </label>\n <cqa-custom-input [type]=\"'number'\" [placeholder]=\"'Number Input'\" [value]=\"variable.value\" [fullWidth]=\"true\"\n (valueChange)=\"onVariableValueChange(variable.name, $event)\">\n </cqa-custom-input>\n </div>\n </ng-container>\n\n <!-- Non-boolean, non-custom_code variables -->\n <ng-container *ngIf=\"variable.name !== 'custom_code' && variable.type !== 'boolean' && variable.type !== 'dropdown' && variable.type !== 'textarea' && !(variable.type === 'number' && variable.dataKey !== 'element')\">\n <!-- Element variables with cascading dropdowns (screen name + element) -->\n <ng-container *ngIf=\"isElementType(variable)\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }} Screen Name<span class=\"cqa-text-red-500\">*</span>\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getScreenNameSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n <div *ngIf=\"hasSelectedScreenName(variable); else elementManualInput\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }}<span class=\"cqa-text-red-500\">*</span>\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getElementSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n <ng-template #elementManualInput>\n <ng-container *ngIf=\"variable.type === 'number'\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }}<span class=\"cqa-text-red-500\">*</span>\n </label>\n <cqa-custom-input [type]=\"'number'\" [placeholder]=\"'Number Input'\" [value]=\"variable.value\" [fullWidth]=\"true\"\n (valueChange)=\"onVariableValueChange(variable.name, $event)\">\n </cqa-custom-input>\n </div>\n </ng-container>\n <ng-container *ngIf=\"variable.type !== 'number'\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }}<span class=\"cqa-text-red-500\">*</span>\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-container>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"!isElementType(variable)\">\n <!-- Other dropdown variables (type, scrollTo, label) -->\n <ng-container *ngIf=\"shouldShowDropdown(variable); else defaultInput\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }}\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n </ng-container>\n </ng-container>\n <ng-template #defaultInput>\n <!-- Test-data, source-value, or target-value with data type dropdown -->\n <ng-container *ngIf=\"needsDataTypeDropdown(variable); else regularInput\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }} Type<span class=\"cqa-text-red-500\">*</span>\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getDataTypeSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n <ng-container *ngIf=\"isEnvironmentType(variable)\">\n <div *ngIf=\"isEnvironmentType(variable)\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Environment Name<span class=\"cqa-text-red-500\">*</span>\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getEnvironmentSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n <div *ngIf=\"hasSelectedEnvironment(variable)\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Environment Value<span class=\"cqa-text-red-500\">*</span>\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getEnvironmentParameterSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n </ng-container>\n <ng-container *ngIf=\"isParameterType(variable)\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Test Data Profile<span class=\"cqa-text-red-500\">*</span>\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getTestDataProfileSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n <div *ngIf=\"hasSelectedTestDataProfile(variable) && !isInsideForLoopStep\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Data Set<span class=\"cqa-text-red-500\">*</span>\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getDataSetSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n <div *ngIf=\"hasSelectedTestDataProfile(variable) && isInsideForLoopStep\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Data Set Start<span class=\"cqa-text-red-500\">*</span>\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getDataSetRangeSelectConfig(variable, i, 'start')\">\n </cqa-dynamic-select>\n </div>\n <div *ngIf=\"hasSelectedTestDataProfile(variable) && isInsideForLoopStep\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Data Set End<span class=\"cqa-text-red-500\">*</span>\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getDataSetRangeSelectConfig(variable, i, 'end')\">\n </cqa-dynamic-select>\n </div>\n <div *ngIf=\"hasSelectedDataSet(variable)\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }}<span class=\"cqa-text-red-500\">*</span>\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getParameterSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div> \n </ng-container>\n <div *ngIf=\"isPlainTextType(variable) || isRuntimeType(variable)\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }}<span class=\"cqa-text-red-500\">*</span>\n </label>\n <ng-container *ngIf=\"isPlainTextType(variable); else runtimePlainInput\">\n <cqa-mixed-variable-input\n [placeholder]=\"'Text Input'\"\n [value]=\"getRawValue(variable)\"\n (valueChange)=\"onTestDataValueChange(variable.name, $event)\">\n </cqa-mixed-variable-input>\n </ng-container>\n <ng-template #runtimePlainInput>\n <cqa-custom-input [placeholder]=\"'Text Input'\" [value]=\"getRawValue(variable)\" [fullWidth]=\"true\"\n (valueChange)=\"onTestDataValueChange(variable.name, $event)\">\n </cqa-custom-input>\n </ng-template>\n </div>\n </ng-container>\n <ng-template #regularInput>\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }}\n </label>\n <cqa-custom-input [placeholder]=\"'Text Input'\" [value]=\"variable.value\" [fullWidth]=\"true\"\n (valueChange)=\"onVariableValueChange(variable.name, $event)\">\n </cqa-custom-input>\n </div>\n </ng-template>\n </ng-template>\n </ng-container>\n </ng-container>\n</div>\n\n<div *ngIf=\"createElementVisible\">\n <cqa-element-form\n [isCreateMode]=\"true\"\n [screenNameOptions]=\"screenNameOptions\"\n [hasMoreScreenNames]=\"hasMoreScreenNames\"\n [isLoadingScreenNames]=\"isLoadingScreenNames\"\n [isEditInDepthAvailable]=\"false\"\n (createElement)=\"onCreateElement($event)\"\n (cancel)=\"onCancelElementForm()\"\n (searchScreenName)=\"searchScreenName.emit($event)\"\n (loadMoreScreenNames)=\"loadMoreScreenNames.emit($event)\"\n (createScreenNameRequest)=\"createScreenNameRequest.emit($event)\">\n </cqa-element-form>\n</div>", styles: ["\n .capitalize-first::first-letter {\n text-transform: uppercase;\n }\n"] }]
|
|
35513
|
+
args: [{ selector: 'cqa-template-variables-form', host: { class: 'cqa-ui-root' }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<style>\n .capitalize-first::first-letter {\n text-transform: uppercase;\n }\n</style>\n<div class=\"cqa-flex cqa-gap-x-6 cqa-gap-y-4 cqa-flex-wrap template-variables-form\" [ngClass]=\"{'cqa-flex-col': isEditInDepth}\" *ngIf=\"!createElementVisible\">\n \n <!-- Metadata - Only show if element is available in form -->\n <div *ngIf=\"selectorVariableAvailable\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Metadata\n </label>\n <cqa-custom-input [placeholder]=\"'Text Input'\" [value]=\"metadata\" [fullWidth]=\"true\"\n (valueChange)=\"metadataChange.emit($event)\">\n </cqa-custom-input>\n </div>\n\n <!-- Description -->\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Description\n </label>\n <cqa-custom-input [placeholder]=\"'Text Input'\" [value]=\"description\" [fullWidth]=\"true\"\n (valueChange)=\"descriptionChange.emit($event)\">\n </cqa-custom-input>\n </div>\n \n <ng-container *ngFor=\"let variable of templateVariables; let i = index; trackBy: trackByVariable\">\n <!-- Boolean variables with mat-slide-toggle -->\n <ng-container *ngIf=\"variable.type === 'boolean'\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }}\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 <ng-container *ngIf=\"variable.type === 'dropdown'\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }}\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n </ng-container>\n\n <!-- Textarea variables -->\n <ng-container *ngIf=\"variable.type === 'textarea'\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }}\n </label>\n <textarea class=\"cqa-w-full cqa-border cqa-border-gray-300 cqa-rounded-lg cqa-px-3 cqa-py-2 cqa-text-sm cqa-text-gray-900 cqa-resize-y focus:cqa-outline-none focus:cqa-ring-1 focus:cqa-ring-indigo-500 focus:cqa-border-indigo-500\"\n [value]=\"variable.value || ''\"\n rows=\"4\"\n style=\"min-height: 42px;\"\n (input)=\"onVariableValueChange(variable.name, $any($event.target).value)\"></textarea>\n </div>\n </ng-container>\n\n <!-- Number variables with number input -->\n <ng-container *ngIf=\"variable.type === 'number' && variable.dataKey !== 'element'\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }}\n </label>\n <cqa-custom-input [type]=\"'number'\" [placeholder]=\"'Number Input'\" [value]=\"variable.value\" [fullWidth]=\"true\"\n (valueChange)=\"onVariableValueChange(variable.name, $event)\">\n </cqa-custom-input>\n </div>\n </ng-container>\n\n <!-- Non-boolean, non-custom_code variables -->\n <ng-container *ngIf=\"variable.name !== 'custom_code' && variable.type !== 'boolean' && variable.type !== 'dropdown' && variable.type !== 'textarea' && !(variable.type === 'number' && variable.dataKey !== 'element')\">\n <!-- Element variables with cascading dropdowns (screen name + element) -->\n <ng-container *ngIf=\"isElementType(variable)\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }} Screen Name<span class=\"cqa-text-red-500\">*</span>\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getScreenNameSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n <div *ngIf=\"hasSelectedScreenName(variable); else elementManualInput\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }}<span class=\"cqa-text-red-500\">*</span>\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getElementSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n <ng-template #elementManualInput>\n <ng-container *ngIf=\"variable.type === 'number'\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }}<span class=\"cqa-text-red-500\">*</span>\n </label>\n <cqa-custom-input [type]=\"'number'\" [placeholder]=\"'Number Input'\" [value]=\"variable.value\" [fullWidth]=\"true\"\n (valueChange)=\"onVariableValueChange(variable.name, $event)\">\n </cqa-custom-input>\n </div>\n </ng-container>\n <ng-container *ngIf=\"variable.type !== 'number'\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }}<span class=\"cqa-text-red-500\">*</span>\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-container>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"!isElementType(variable)\">\n <!-- Other dropdown variables (type, scrollTo, label) -->\n <ng-container *ngIf=\"shouldShowDropdown(variable); else defaultInput\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }}\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n </ng-container>\n </ng-container>\n <ng-template #defaultInput>\n <!-- Test-data, source-value, or target-value with data type dropdown -->\n <ng-container *ngIf=\"needsDataTypeDropdown(variable); else regularInput\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }} Type<span class=\"cqa-text-red-500\">*</span>\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getDataTypeSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n <ng-container *ngIf=\"isEnvironmentType(variable)\">\n <div *ngIf=\"isEnvironmentType(variable)\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Environment Name<span class=\"cqa-text-red-500\">*</span>\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getEnvironmentSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n <div *ngIf=\"hasSelectedEnvironment(variable)\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Environment Value<span class=\"cqa-text-red-500\">*</span>\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getEnvironmentParameterSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n </ng-container>\n <ng-container *ngIf=\"isParameterType(variable)\">\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Test Data Profile<span class=\"cqa-text-red-500\">*</span>\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getTestDataProfileSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n <div *ngIf=\"hasSelectedTestDataProfile(variable) && !isInsideForLoopStep\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Data Set<span class=\"cqa-text-red-500\">*</span>\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getDataSetSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div>\n <div *ngIf=\"hasSelectedTestDataProfile(variable) && isInsideForLoopStep\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Data Set Start<span class=\"cqa-text-red-500\">*</span>\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getDataSetRangeSelectConfig(variable, i, 'start')\">\n </cqa-dynamic-select>\n </div>\n <div *ngIf=\"hasSelectedTestDataProfile(variable) && isInsideForLoopStep\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1\">\n Data Set End<span class=\"cqa-text-red-500\">*</span>\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getDataSetRangeSelectConfig(variable, i, 'end')\">\n </cqa-dynamic-select>\n </div>\n <div *ngIf=\"hasSelectedDataSet(variable)\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }}<span class=\"cqa-text-red-500\">*</span>\n </label>\n <cqa-dynamic-select [form]=\"getFormGroupAt(i)!\" [config]=\"getParameterSelectConfig(variable, i)\">\n </cqa-dynamic-select>\n </div> \n </ng-container>\n <div *ngIf=\"isPlainTextType(variable) || isRuntimeType(variable)\" class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }}<span class=\"cqa-text-red-500\">*</span>\n </label>\n <ng-container *ngIf=\"isPlainTextType(variable); else runtimePlainInput\">\n <cqa-mixed-variable-input\n [placeholder]=\"'Text Input'\"\n [value]=\"getRawValue(variable)\"\n (valueChange)=\"onTestDataValueChange(variable.name, $event)\"\n (validityChange)=\"onTestDataValidityChange(variable.name, $event)\">\n </cqa-mixed-variable-input>\n </ng-container>\n <ng-template #runtimePlainInput>\n <cqa-custom-input [placeholder]=\"'Text Input'\" [value]=\"getRawValue(variable)\" [fullWidth]=\"true\"\n (valueChange)=\"onTestDataValueChange(variable.name, $event)\">\n </cqa-custom-input>\n </ng-template>\n </div>\n </ng-container>\n <ng-template #regularInput>\n <div class=\"cqa-flex cqa-flex-col\" [style.width]=\"isEditInDepth ? null : 'calc(50% - 12px)'\" [ngClass]=\"{'cqa-w-full': isEditInDepth}\">\n <label class=\"cqa-text-sm cqa-font-medium cqa-text-gray-700 cqa-mb-1 capitalize-first\">\n {{ variable.label | cqaCamelToTitle }}\n </label>\n <cqa-custom-input [placeholder]=\"'Text Input'\" [value]=\"variable.value\" [fullWidth]=\"true\"\n (valueChange)=\"onVariableValueChange(variable.name, $event)\">\n </cqa-custom-input>\n </div>\n </ng-template>\n </ng-template>\n </ng-container>\n </ng-container>\n</div>\n\n<div *ngIf=\"createElementVisible\">\n <cqa-element-form\n [isCreateMode]=\"true\"\n [screenNameOptions]=\"screenNameOptions\"\n [hasMoreScreenNames]=\"hasMoreScreenNames\"\n [isLoadingScreenNames]=\"isLoadingScreenNames\"\n [isEditInDepthAvailable]=\"false\"\n (createElement)=\"onCreateElement($event)\"\n (cancel)=\"onCancelElementForm()\"\n (searchScreenName)=\"searchScreenName.emit($event)\"\n (loadMoreScreenNames)=\"loadMoreScreenNames.emit($event)\"\n (createScreenNameRequest)=\"createScreenNameRequest.emit($event)\">\n </cqa-element-form>\n</div>", styles: ["\n .capitalize-first::first-letter {\n text-transform: uppercase;\n }\n"] }]
|
|
35185
35514
|
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { templateVariables: [{
|
|
35186
35515
|
type: Input
|
|
35187
35516
|
}], variablesForm: [{
|