@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
|
@@ -9587,6 +9587,13 @@ class SelfHealAnalysisComponent {
|
|
|
9587
9587
|
this.isLoadingAccept = false;
|
|
9588
9588
|
this.isLoadingModifyAccept = false;
|
|
9589
9589
|
this.action = new EventEmitter();
|
|
9590
|
+
this.isEditMode = false;
|
|
9591
|
+
// Set when Accept is clicked in edit mode; gates the ngOnChanges reset so that
|
|
9592
|
+
// unrelated isLoadingModifyAccept changes (initial binding, parent pre-set) don't exit edit mode.
|
|
9593
|
+
this.awaitingModifyAcceptResponse = false;
|
|
9594
|
+
}
|
|
9595
|
+
get isAcceptLoading() {
|
|
9596
|
+
return this.isLoadingAccept || (this.isEditMode && this.isLoadingModifyAccept);
|
|
9590
9597
|
}
|
|
9591
9598
|
ngOnInit() {
|
|
9592
9599
|
// Build data from individual inputs
|
|
@@ -9596,22 +9603,42 @@ class SelfHealAnalysisComponent {
|
|
|
9596
9603
|
confidence: this.confidence,
|
|
9597
9604
|
healMethod: this.healMethod,
|
|
9598
9605
|
};
|
|
9606
|
+
this.initialHealedLocator = this.healedLocator;
|
|
9607
|
+
}
|
|
9608
|
+
ngOnChanges(changes) {
|
|
9609
|
+
const modifyChange = changes['isLoadingModifyAccept'];
|
|
9610
|
+
if (this.awaitingModifyAcceptResponse &&
|
|
9611
|
+
modifyChange &&
|
|
9612
|
+
modifyChange.previousValue === true &&
|
|
9613
|
+
modifyChange.currentValue === false) {
|
|
9614
|
+
this.awaitingModifyAcceptResponse = false;
|
|
9615
|
+
this.initialHealedLocator = this.data.healedLocator;
|
|
9616
|
+
this.isEditMode = false;
|
|
9617
|
+
}
|
|
9599
9618
|
}
|
|
9600
9619
|
onAccept() {
|
|
9601
|
-
|
|
9620
|
+
const type = this.isEditMode ? 'modify-accept' : 'accept';
|
|
9621
|
+
if (type === 'modify-accept') {
|
|
9622
|
+
this.awaitingModifyAcceptResponse = true;
|
|
9623
|
+
}
|
|
9624
|
+
this.action.emit({ type, id: this.id, healedLocator: this.data.healedLocator, testStepId: this.id });
|
|
9602
9625
|
}
|
|
9603
9626
|
onReject() {
|
|
9604
9627
|
this.action.emit({ type: 'reject', id: this.id, healedLocator: this.data.healedLocator, testStepId: this.id });
|
|
9605
9628
|
}
|
|
9606
9629
|
onModifyAccept() {
|
|
9607
|
-
this.
|
|
9630
|
+
this.isEditMode = true;
|
|
9631
|
+
}
|
|
9632
|
+
onCancelModify() {
|
|
9633
|
+
this.data.healedLocator = this.initialHealedLocator;
|
|
9634
|
+
this.isEditMode = false;
|
|
9608
9635
|
}
|
|
9609
9636
|
}
|
|
9610
9637
|
SelfHealAnalysisComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: SelfHealAnalysisComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
9611
|
-
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"] }] });
|
|
9638
|
+
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"] }] });
|
|
9612
9639
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: SelfHealAnalysisComponent, decorators: [{
|
|
9613
9640
|
type: Component,
|
|
9614
|
-
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: [] }]
|
|
9641
|
+
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: [] }]
|
|
9615
9642
|
}], propDecorators: { id: [{
|
|
9616
9643
|
type: Input
|
|
9617
9644
|
}], originalLocator: [{
|
|
@@ -19437,8 +19464,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
|
|
|
19437
19464
|
type: Input
|
|
19438
19465
|
}] } });
|
|
19439
19466
|
|
|
19440
|
-
const
|
|
19441
|
-
const
|
|
19467
|
+
const VAR_PATH = '[A-Za-z_][A-Za-z0-9_]*(?:\\.[A-Za-z_][A-Za-z0-9_]*|\\[\\d+\\])*';
|
|
19468
|
+
const VAR_NAME_REGEX = new RegExp('^' + VAR_PATH + '$');
|
|
19469
|
+
const VAR_TOKEN_REGEX = new RegExp('\\$\\{(' + VAR_PATH + ')\\}', 'g');
|
|
19470
|
+
const VAR_PATH_TAIL_REGEX = new RegExp('(' + VAR_PATH + ')$');
|
|
19471
|
+
const INVALID_VAR_MESSAGE = 'Invalid variable name.';
|
|
19472
|
+
const BLUR_HIDE_DELAY_MS = 150;
|
|
19442
19473
|
class MixedVariableInputComponent {
|
|
19443
19474
|
constructor(cdr, hostRef) {
|
|
19444
19475
|
this.cdr = cdr;
|
|
@@ -19447,43 +19478,58 @@ class MixedVariableInputComponent {
|
|
|
19447
19478
|
this.placeholder = 'Text Input';
|
|
19448
19479
|
this.disabled = false;
|
|
19449
19480
|
this.valueChange = new EventEmitter();
|
|
19481
|
+
this.validityChange = new EventEmitter();
|
|
19450
19482
|
this.showSuggestion = false;
|
|
19451
19483
|
this.pendingWord = '';
|
|
19484
|
+
this.canAddAsVariable = false;
|
|
19485
|
+
this.errorMessage = null;
|
|
19486
|
+
this.selectionRange = null;
|
|
19487
|
+
this.selectionMode = false;
|
|
19452
19488
|
this.lastEmitted = '';
|
|
19489
|
+
this.lastValid = null;
|
|
19453
19490
|
}
|
|
19454
|
-
|
|
19455
|
-
if (!this.showSuggestion)
|
|
19456
|
-
return;
|
|
19457
|
-
const target = event.target;
|
|
19458
|
-
if (this.hostRef.nativeElement.contains(target))
|
|
19459
|
-
return;
|
|
19460
|
-
this.hideSuggestion();
|
|
19461
|
-
}
|
|
19491
|
+
// ---- Lifecycle ------------------------------------------------------------
|
|
19462
19492
|
ngOnChanges(changes) {
|
|
19463
19493
|
var _a;
|
|
19464
|
-
if (changes['value']
|
|
19465
|
-
|
|
19466
|
-
|
|
19467
|
-
|
|
19468
|
-
|
|
19469
|
-
|
|
19494
|
+
if (!changes['value'] || !this.editorRef)
|
|
19495
|
+
return;
|
|
19496
|
+
const incoming = (_a = changes['value'].currentValue) !== null && _a !== void 0 ? _a : '';
|
|
19497
|
+
if (incoming === this.lastEmitted)
|
|
19498
|
+
return;
|
|
19499
|
+
this.render(incoming);
|
|
19500
|
+
this.validate(incoming);
|
|
19470
19501
|
}
|
|
19471
19502
|
ngAfterViewInit() {
|
|
19472
|
-
this.
|
|
19503
|
+
const initial = this.value || '';
|
|
19504
|
+
this.render(initial);
|
|
19505
|
+
this.validate(initial);
|
|
19473
19506
|
}
|
|
19507
|
+
// ---- Editor event handlers -----------------------------------------------
|
|
19474
19508
|
onInput() {
|
|
19475
|
-
|
|
19476
|
-
this.
|
|
19477
|
-
this.valueChange.emit(str);
|
|
19509
|
+
this.flattenStructure();
|
|
19510
|
+
this.sanitizeChips();
|
|
19478
19511
|
this.autoChipify();
|
|
19512
|
+
this.emitValue();
|
|
19513
|
+
this.refreshSuggestion();
|
|
19514
|
+
}
|
|
19515
|
+
onEditorFocus() {
|
|
19479
19516
|
this.refreshSuggestion();
|
|
19480
19517
|
}
|
|
19518
|
+
onEditorBlur() {
|
|
19519
|
+
// Delay so clicks on suggestion buttons register before we hide them.
|
|
19520
|
+
setTimeout(() => {
|
|
19521
|
+
this.autoChipify(true);
|
|
19522
|
+
this.hideSuggestion();
|
|
19523
|
+
}, BLUR_HIDE_DELAY_MS);
|
|
19524
|
+
}
|
|
19481
19525
|
onKeyDown(event) {
|
|
19482
19526
|
var _a;
|
|
19483
19527
|
if (event.key === 'Enter') {
|
|
19484
19528
|
event.preventDefault();
|
|
19485
19529
|
return;
|
|
19486
19530
|
}
|
|
19531
|
+
if (event.key === 'Tab')
|
|
19532
|
+
return;
|
|
19487
19533
|
if (event.key === 'Escape') {
|
|
19488
19534
|
if (this.showSuggestion) {
|
|
19489
19535
|
event.preventDefault();
|
|
@@ -19500,36 +19546,122 @@ class MixedVariableInputComponent {
|
|
|
19500
19546
|
}
|
|
19501
19547
|
}
|
|
19502
19548
|
}
|
|
19503
|
-
|
|
19504
|
-
|
|
19505
|
-
|
|
19549
|
+
onPaste(event) {
|
|
19550
|
+
var _a, _b;
|
|
19551
|
+
event.preventDefault();
|
|
19552
|
+
const text = (_b = (_a = event.clipboardData) === null || _a === void 0 ? void 0 : _a.getData('text/plain')) !== null && _b !== void 0 ? _b : '';
|
|
19553
|
+
if (!text)
|
|
19554
|
+
return;
|
|
19555
|
+
this.insertPlainTextAtCaret(text);
|
|
19556
|
+
this.onInput();
|
|
19557
|
+
}
|
|
19558
|
+
onDrop(event) {
|
|
19559
|
+
var _a, _b;
|
|
19560
|
+
event.preventDefault();
|
|
19561
|
+
const text = (_b = (_a = event.dataTransfer) === null || _a === void 0 ? void 0 : _a.getData('text/plain')) !== null && _b !== void 0 ? _b : '';
|
|
19562
|
+
if (text) {
|
|
19563
|
+
this.editorRef.nativeElement.focus();
|
|
19564
|
+
this.insertPlainTextAtCaret(text);
|
|
19565
|
+
}
|
|
19566
|
+
this.onInput();
|
|
19567
|
+
}
|
|
19568
|
+
onDragStart(event) {
|
|
19569
|
+
event.preventDefault();
|
|
19570
|
+
}
|
|
19571
|
+
onDocumentMouseDown(event) {
|
|
19572
|
+
if (!this.showSuggestion)
|
|
19573
|
+
return;
|
|
19574
|
+
if (this.hostRef.nativeElement.contains(event.target))
|
|
19575
|
+
return;
|
|
19576
|
+
this.hideSuggestion();
|
|
19577
|
+
}
|
|
19578
|
+
onDocumentSelectionChange() {
|
|
19579
|
+
var _a;
|
|
19580
|
+
if (document.activeElement !== ((_a = this.editorRef) === null || _a === void 0 ? void 0 : _a.nativeElement))
|
|
19581
|
+
return;
|
|
19582
|
+
this.refreshSuggestion();
|
|
19506
19583
|
}
|
|
19584
|
+
// ---- Suggestion actions ---------------------------------------------------
|
|
19507
19585
|
addAsText() {
|
|
19508
19586
|
this.hideSuggestion();
|
|
19509
19587
|
this.editorRef.nativeElement.focus();
|
|
19510
19588
|
}
|
|
19511
19589
|
addAsVariable() {
|
|
19512
|
-
const name = (this.pendingWord || '')
|
|
19590
|
+
const name = this.normalizeCandidate(this.pendingWord || '');
|
|
19513
19591
|
if (!name || !VAR_NAME_REGEX.test(name)) {
|
|
19514
19592
|
this.hideSuggestion();
|
|
19515
19593
|
return;
|
|
19516
19594
|
}
|
|
19517
|
-
this.
|
|
19595
|
+
if (this.selectionMode && this.selectionRange) {
|
|
19596
|
+
if (this.rangeCrossesChip(this.selectionRange)) {
|
|
19597
|
+
this.hideSuggestion();
|
|
19598
|
+
return;
|
|
19599
|
+
}
|
|
19600
|
+
this.insertChipReplacingRange(name, this.selectionRange);
|
|
19601
|
+
}
|
|
19602
|
+
else {
|
|
19603
|
+
this.insertChipReplacingCurrentWord(name);
|
|
19604
|
+
}
|
|
19518
19605
|
this.hideSuggestion();
|
|
19606
|
+
this.emitValue();
|
|
19607
|
+
}
|
|
19608
|
+
// ---- Value emission / validation -----------------------------------------
|
|
19609
|
+
emitValue() {
|
|
19519
19610
|
const str = this.serialize();
|
|
19520
|
-
this.lastEmitted
|
|
19521
|
-
|
|
19611
|
+
if (str !== this.lastEmitted) {
|
|
19612
|
+
this.lastEmitted = str;
|
|
19613
|
+
this.valueChange.emit(str);
|
|
19614
|
+
}
|
|
19615
|
+
this.validate(str);
|
|
19616
|
+
}
|
|
19617
|
+
validate(str) {
|
|
19618
|
+
const error = this.findValidationError(str);
|
|
19619
|
+
const valid = error === null;
|
|
19620
|
+
if (this.lastValid === valid && this.errorMessage === error)
|
|
19621
|
+
return;
|
|
19622
|
+
this.lastValid = valid;
|
|
19623
|
+
this.errorMessage = error;
|
|
19624
|
+
this.validityChange.emit({ valid, error });
|
|
19625
|
+
this.cdr.markForCheck();
|
|
19626
|
+
}
|
|
19627
|
+
findValidationError(str) {
|
|
19628
|
+
if (!str)
|
|
19629
|
+
return null;
|
|
19630
|
+
const braceBody = /\$\{([^}]*)\}/g;
|
|
19631
|
+
let m;
|
|
19632
|
+
braceBody.lastIndex = 0;
|
|
19633
|
+
while ((m = braceBody.exec(str)) !== null) {
|
|
19634
|
+
const body = m[1];
|
|
19635
|
+
if (body !== body.trim() || !VAR_NAME_REGEX.test(body)) {
|
|
19636
|
+
return INVALID_VAR_MESSAGE;
|
|
19637
|
+
}
|
|
19638
|
+
}
|
|
19639
|
+
const openCount = (str.match(/\$\{/g) || []).length;
|
|
19640
|
+
const closedCount = (str.match(braceBody) || []).length;
|
|
19641
|
+
if (openCount > closedCount)
|
|
19642
|
+
return INVALID_VAR_MESSAGE;
|
|
19643
|
+
return null;
|
|
19522
19644
|
}
|
|
19645
|
+
// ---- Suggestion state -----------------------------------------------------
|
|
19523
19646
|
refreshSuggestion() {
|
|
19524
|
-
const
|
|
19525
|
-
if (
|
|
19526
|
-
|
|
19647
|
+
const selInfo = this.getSelectedInfo();
|
|
19648
|
+
if (selInfo) {
|
|
19649
|
+
const normalized = this.normalizeCandidate(selInfo.text);
|
|
19650
|
+
this.pendingWord = normalized;
|
|
19651
|
+
this.selectionRange = selInfo.range;
|
|
19652
|
+
this.selectionMode = true;
|
|
19527
19653
|
this.showSuggestion = true;
|
|
19654
|
+
this.canAddAsVariable =
|
|
19655
|
+
!!normalized && VAR_NAME_REGEX.test(normalized) && !this.rangeCrossesChip(selInfo.range);
|
|
19656
|
+
this.cdr.markForCheck();
|
|
19657
|
+
return;
|
|
19528
19658
|
}
|
|
19529
|
-
|
|
19530
|
-
|
|
19531
|
-
|
|
19532
|
-
|
|
19659
|
+
this.selectionMode = false;
|
|
19660
|
+
this.selectionRange = null;
|
|
19661
|
+
const word = this.getCurrentWord();
|
|
19662
|
+
this.pendingWord = word;
|
|
19663
|
+
this.showSuggestion = !!word;
|
|
19664
|
+
this.canAddAsVariable = !!word && VAR_NAME_REGEX.test(word);
|
|
19533
19665
|
this.cdr.markForCheck();
|
|
19534
19666
|
}
|
|
19535
19667
|
hideSuggestion() {
|
|
@@ -19537,45 +19669,129 @@ class MixedVariableInputComponent {
|
|
|
19537
19669
|
return;
|
|
19538
19670
|
this.showSuggestion = false;
|
|
19539
19671
|
this.pendingWord = '';
|
|
19672
|
+
this.canAddAsVariable = false;
|
|
19540
19673
|
this.cdr.markForCheck();
|
|
19541
19674
|
}
|
|
19542
|
-
|
|
19675
|
+
normalizeCandidate(text) {
|
|
19676
|
+
let t = text.trim();
|
|
19677
|
+
if (t.startsWith('${') && t.endsWith('}')) {
|
|
19678
|
+
t = t.slice(2, -1).trim();
|
|
19679
|
+
}
|
|
19680
|
+
return t;
|
|
19681
|
+
}
|
|
19682
|
+
// ---- DOM sanitization -----------------------------------------------------
|
|
19683
|
+
flattenStructure() {
|
|
19684
|
+
var _a, _b;
|
|
19543
19685
|
const editor = this.editorRef.nativeElement;
|
|
19544
|
-
const
|
|
19545
|
-
editor.
|
|
19546
|
-
|
|
19547
|
-
|
|
19548
|
-
|
|
19549
|
-
|
|
19686
|
+
const wrappers = Array.from(editor.querySelectorAll('div, p'));
|
|
19687
|
+
const strayInlines = Array.from(editor.querySelectorAll('span')).filter((s) => !s.classList.contains('cqa-var-chip') && !s.closest('.cqa-var-chip'));
|
|
19688
|
+
for (const el of [...wrappers, ...strayInlines]) {
|
|
19689
|
+
if (el.closest('.cqa-var-chip'))
|
|
19690
|
+
continue;
|
|
19691
|
+
while (el.firstChild)
|
|
19692
|
+
(_a = el.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(el.firstChild, el);
|
|
19693
|
+
el.remove();
|
|
19694
|
+
}
|
|
19695
|
+
const brs = Array.from(editor.querySelectorAll('br'));
|
|
19696
|
+
for (const br of brs) {
|
|
19697
|
+
if (br.closest('.cqa-var-chip'))
|
|
19698
|
+
continue;
|
|
19699
|
+
(_b = br.parentNode) === null || _b === void 0 ? void 0 : _b.replaceChild(document.createTextNode(' '), br);
|
|
19700
|
+
}
|
|
19701
|
+
}
|
|
19702
|
+
sanitizeChips() {
|
|
19703
|
+
var _a, _b;
|
|
19704
|
+
const editor = this.editorRef.nativeElement;
|
|
19705
|
+
const chips = Array.from(editor.querySelectorAll('.cqa-var-chip'));
|
|
19706
|
+
for (const chip of chips) {
|
|
19707
|
+
const name = (chip.getAttribute('data-var') || '').trim();
|
|
19708
|
+
if (!name || !VAR_NAME_REGEX.test(name)) {
|
|
19709
|
+
(_a = chip.parentNode) === null || _a === void 0 ? void 0 : _a.replaceChild(document.createTextNode(chip.textContent || ''), chip);
|
|
19710
|
+
continue;
|
|
19711
|
+
}
|
|
19712
|
+
const structureBroken = chip.getAttribute('contenteditable') !== 'false' ||
|
|
19713
|
+
!chip.querySelector('.cqa-var-chip__remove');
|
|
19714
|
+
if (structureBroken) {
|
|
19715
|
+
(_b = chip.parentNode) === null || _b === void 0 ? void 0 : _b.replaceChild(this.buildChip(name), chip);
|
|
19716
|
+
}
|
|
19717
|
+
}
|
|
19718
|
+
// Remove stray remove icons left from partial undo/redo states.
|
|
19719
|
+
const orphans = Array.from(editor.querySelectorAll('.cqa-var-chip__remove'));
|
|
19720
|
+
for (const o of orphans) {
|
|
19721
|
+
if (!o.closest('.cqa-var-chip'))
|
|
19722
|
+
o.remove();
|
|
19723
|
+
}
|
|
19724
|
+
}
|
|
19725
|
+
// ---- Chipification --------------------------------------------------------
|
|
19726
|
+
autoChipify(force = false) {
|
|
19727
|
+
const editor = this.editorRef.nativeElement;
|
|
19728
|
+
const caretRange = this.getSelectionRange();
|
|
19729
|
+
let changed = false;
|
|
19730
|
+
let lastChip = null;
|
|
19731
|
+
for (const tn of this.collectDescendantTextNodes(editor)) {
|
|
19732
|
+
if (!tn.parentNode)
|
|
19733
|
+
continue;
|
|
19550
19734
|
const text = tn.nodeValue || '';
|
|
19551
19735
|
VAR_TOKEN_REGEX.lastIndex = 0;
|
|
19552
19736
|
if (!VAR_TOKEN_REGEX.test(text))
|
|
19553
19737
|
continue;
|
|
19554
19738
|
VAR_TOKEN_REGEX.lastIndex = 0;
|
|
19555
|
-
const
|
|
19556
|
-
|
|
19557
|
-
|
|
19558
|
-
const
|
|
19559
|
-
let lastIndex = 0;
|
|
19739
|
+
const caretOffset = !force && caretRange && caretRange.collapsed && caretRange.startContainer === tn
|
|
19740
|
+
? caretRange.startOffset
|
|
19741
|
+
: -1;
|
|
19742
|
+
const matches = [];
|
|
19560
19743
|
let m;
|
|
19561
19744
|
while ((m = VAR_TOKEN_REGEX.exec(text)) !== null) {
|
|
19562
|
-
|
|
19563
|
-
|
|
19745
|
+
const start = m.index;
|
|
19746
|
+
const end = start + m[0].length;
|
|
19747
|
+
// Keep the token as plain text while the caret is strictly inside.
|
|
19748
|
+
if (caretOffset > start && caretOffset < end)
|
|
19749
|
+
continue;
|
|
19750
|
+
matches.push({ start, end, name: m[1] });
|
|
19751
|
+
}
|
|
19752
|
+
if (!matches.length)
|
|
19753
|
+
continue;
|
|
19754
|
+
const frag = document.createDocumentFragment();
|
|
19755
|
+
let cursor = 0;
|
|
19756
|
+
for (const mt of matches) {
|
|
19757
|
+
if (mt.start > cursor) {
|
|
19758
|
+
frag.appendChild(document.createTextNode(text.slice(cursor, mt.start)));
|
|
19564
19759
|
}
|
|
19565
|
-
|
|
19566
|
-
|
|
19760
|
+
const chip = this.buildChip(mt.name);
|
|
19761
|
+
frag.appendChild(chip);
|
|
19762
|
+
lastChip = chip;
|
|
19763
|
+
cursor = mt.end;
|
|
19567
19764
|
}
|
|
19568
|
-
if (
|
|
19569
|
-
frag.appendChild(document.createTextNode(text.slice(
|
|
19765
|
+
if (cursor < text.length) {
|
|
19766
|
+
frag.appendChild(document.createTextNode(text.slice(cursor)));
|
|
19570
19767
|
}
|
|
19571
|
-
|
|
19572
|
-
|
|
19573
|
-
const str = this.serialize();
|
|
19574
|
-
this.lastEmitted = str;
|
|
19575
|
-
this.valueChange.emit(str);
|
|
19576
|
-
return;
|
|
19768
|
+
tn.parentNode.replaceChild(frag, tn);
|
|
19769
|
+
changed = true;
|
|
19577
19770
|
}
|
|
19771
|
+
if (changed && lastChip)
|
|
19772
|
+
this.placeCaretAfter(lastChip);
|
|
19773
|
+
}
|
|
19774
|
+
collectDescendantTextNodes(root) {
|
|
19775
|
+
const out = [];
|
|
19776
|
+
const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, {
|
|
19777
|
+
acceptNode: (node) => {
|
|
19778
|
+
var _a, _b;
|
|
19779
|
+
let p = node.parentNode;
|
|
19780
|
+
while (p && p !== root) {
|
|
19781
|
+
if ((_b = (_a = p.classList) === null || _a === void 0 ? void 0 : _a.contains) === null || _b === void 0 ? void 0 : _b.call(_a, 'cqa-var-chip')) {
|
|
19782
|
+
return NodeFilter.FILTER_REJECT;
|
|
19783
|
+
}
|
|
19784
|
+
p = p.parentNode;
|
|
19785
|
+
}
|
|
19786
|
+
return NodeFilter.FILTER_ACCEPT;
|
|
19787
|
+
},
|
|
19788
|
+
});
|
|
19789
|
+
let n;
|
|
19790
|
+
while ((n = walker.nextNode()))
|
|
19791
|
+
out.push(n);
|
|
19792
|
+
return out;
|
|
19578
19793
|
}
|
|
19794
|
+
// ---- Render / serialize ---------------------------------------------------
|
|
19579
19795
|
render(value) {
|
|
19580
19796
|
const editor = this.editorRef.nativeElement;
|
|
19581
19797
|
editor.innerHTML = '';
|
|
@@ -19598,22 +19814,30 @@ class MixedVariableInputComponent {
|
|
|
19598
19814
|
serialize() {
|
|
19599
19815
|
const editor = this.editorRef.nativeElement;
|
|
19600
19816
|
let out = '';
|
|
19601
|
-
|
|
19602
|
-
if (
|
|
19603
|
-
out += (
|
|
19817
|
+
const walk = (node) => {
|
|
19818
|
+
if (node.nodeType === Node.TEXT_NODE) {
|
|
19819
|
+
out += (node.nodeValue || '').replace(/\u00a0/g, ' ');
|
|
19820
|
+
return;
|
|
19604
19821
|
}
|
|
19605
|
-
|
|
19606
|
-
|
|
19607
|
-
|
|
19608
|
-
|
|
19609
|
-
|
|
19610
|
-
|
|
19611
|
-
|
|
19612
|
-
|
|
19613
|
-
out += el.textContent || '';
|
|
19614
|
-
}
|
|
19822
|
+
if (node.nodeType !== Node.ELEMENT_NODE)
|
|
19823
|
+
return;
|
|
19824
|
+
const el = node;
|
|
19825
|
+
if (el.classList.contains('cqa-var-chip')) {
|
|
19826
|
+
const name = el.getAttribute('data-var') || '';
|
|
19827
|
+
if (name)
|
|
19828
|
+
out += '${' + name + '}';
|
|
19829
|
+
return;
|
|
19615
19830
|
}
|
|
19616
|
-
|
|
19831
|
+
if (el.tagName === 'BR') {
|
|
19832
|
+
out += '\n';
|
|
19833
|
+
return;
|
|
19834
|
+
}
|
|
19835
|
+
const isBlock = el.tagName === 'DIV' || el.tagName === 'P';
|
|
19836
|
+
if (isBlock && out.length > 0 && !out.endsWith('\n'))
|
|
19837
|
+
out += '\n';
|
|
19838
|
+
el.childNodes.forEach(walk);
|
|
19839
|
+
};
|
|
19840
|
+
editor.childNodes.forEach(walk);
|
|
19617
19841
|
return out;
|
|
19618
19842
|
}
|
|
19619
19843
|
buildChip(name) {
|
|
@@ -19638,6 +19862,7 @@ class MixedVariableInputComponent {
|
|
|
19638
19862
|
chip.appendChild(remove);
|
|
19639
19863
|
return chip;
|
|
19640
19864
|
}
|
|
19865
|
+
// ---- Selection / caret helpers -------------------------------------------
|
|
19641
19866
|
getSelectionRange() {
|
|
19642
19867
|
const sel = window.getSelection();
|
|
19643
19868
|
if (!sel || sel.rangeCount === 0)
|
|
@@ -19647,6 +19872,26 @@ class MixedVariableInputComponent {
|
|
|
19647
19872
|
return null;
|
|
19648
19873
|
return range;
|
|
19649
19874
|
}
|
|
19875
|
+
getSelectedInfo() {
|
|
19876
|
+
const sel = window.getSelection();
|
|
19877
|
+
if (!sel || sel.rangeCount === 0)
|
|
19878
|
+
return null;
|
|
19879
|
+
const range = sel.getRangeAt(0);
|
|
19880
|
+
if (range.collapsed)
|
|
19881
|
+
return null;
|
|
19882
|
+
const editor = this.editorRef.nativeElement;
|
|
19883
|
+
if (!editor.contains(range.startContainer) || !editor.contains(range.endContainer))
|
|
19884
|
+
return null;
|
|
19885
|
+
const text = range.toString();
|
|
19886
|
+
if (!text)
|
|
19887
|
+
return null;
|
|
19888
|
+
return { text, range: range.cloneRange() };
|
|
19889
|
+
}
|
|
19890
|
+
rangeCrossesChip(range) {
|
|
19891
|
+
var _a;
|
|
19892
|
+
const contents = range.cloneContents();
|
|
19893
|
+
return !!((_a = contents.querySelector) === null || _a === void 0 ? void 0 : _a.call(contents, '.cqa-var-chip'));
|
|
19894
|
+
}
|
|
19650
19895
|
getNodeBeforeCaret() {
|
|
19651
19896
|
const range = this.getSelectionRange();
|
|
19652
19897
|
if (!range || !range.collapsed)
|
|
@@ -19661,16 +19906,39 @@ class MixedVariableInputComponent {
|
|
|
19661
19906
|
}
|
|
19662
19907
|
getCurrentWord() {
|
|
19663
19908
|
const range = this.getSelectionRange();
|
|
19664
|
-
if (!range)
|
|
19665
|
-
return '';
|
|
19666
|
-
const node = range.startContainer;
|
|
19667
|
-
if (node.nodeType !== Node.TEXT_NODE)
|
|
19909
|
+
if (!range || !range.collapsed)
|
|
19668
19910
|
return '';
|
|
19911
|
+
let node = range.startContainer;
|
|
19912
|
+
let offset = range.startOffset;
|
|
19913
|
+
if (node.nodeType !== Node.TEXT_NODE) {
|
|
19914
|
+
const prev = node.childNodes[offset - 1];
|
|
19915
|
+
if (!prev || prev.nodeType !== Node.TEXT_NODE)
|
|
19916
|
+
return '';
|
|
19917
|
+
node = prev;
|
|
19918
|
+
offset = (prev.nodeValue || '').length;
|
|
19919
|
+
}
|
|
19669
19920
|
const text = node.nodeValue || '';
|
|
19670
|
-
const
|
|
19671
|
-
|
|
19921
|
+
const braceOpen = text.lastIndexOf('${', offset - 1);
|
|
19922
|
+
if (braceOpen !== -1) {
|
|
19923
|
+
const closeIdx = text.indexOf('}', braceOpen + 2);
|
|
19924
|
+
const tokenClosedBeforeCaret = closeIdx !== -1 && closeIdx < offset;
|
|
19925
|
+
if (!tokenClosedBeforeCaret) {
|
|
19926
|
+
const start = braceOpen + 2;
|
|
19927
|
+
const end = closeIdx === -1 ? text.length : closeIdx;
|
|
19928
|
+
return text.slice(start, end);
|
|
19929
|
+
}
|
|
19930
|
+
}
|
|
19931
|
+
const match = text.slice(0, offset).match(VAR_PATH_TAIL_REGEX);
|
|
19672
19932
|
return match ? match[1] : '';
|
|
19673
19933
|
}
|
|
19934
|
+
// ---- Chip insertion -------------------------------------------------------
|
|
19935
|
+
insertChipReplacingRange(name, range) {
|
|
19936
|
+
const chip = this.buildChip(name);
|
|
19937
|
+
range.deleteContents();
|
|
19938
|
+
range.insertNode(chip);
|
|
19939
|
+
this.stripBracesAround(chip);
|
|
19940
|
+
this.placeCaretAfter(chip);
|
|
19941
|
+
}
|
|
19674
19942
|
insertChipReplacingCurrentWord(name) {
|
|
19675
19943
|
const range = this.getSelectionRange();
|
|
19676
19944
|
const chip = this.buildChip(name);
|
|
@@ -19680,26 +19948,59 @@ class MixedVariableInputComponent {
|
|
|
19680
19948
|
return;
|
|
19681
19949
|
}
|
|
19682
19950
|
const node = range.startContainer;
|
|
19683
|
-
if (node.nodeType
|
|
19684
|
-
const text = node.nodeValue || '';
|
|
19685
|
-
const before = text.slice(0, range.startOffset);
|
|
19686
|
-
const after = text.slice(range.startOffset);
|
|
19687
|
-
const wordMatch = before.match(/([A-Za-z_][A-Za-z0-9_]*)$/);
|
|
19688
|
-
const beforeKept = wordMatch ? before.slice(0, before.length - wordMatch[1].length) : before;
|
|
19689
|
-
const parent = node.parentNode;
|
|
19690
|
-
const frag = document.createDocumentFragment();
|
|
19691
|
-
if (beforeKept)
|
|
19692
|
-
frag.appendChild(document.createTextNode(beforeKept));
|
|
19693
|
-
frag.appendChild(chip);
|
|
19694
|
-
if (after)
|
|
19695
|
-
frag.appendChild(document.createTextNode(after));
|
|
19696
|
-
parent.replaceChild(frag, node);
|
|
19697
|
-
}
|
|
19698
|
-
else {
|
|
19951
|
+
if (node.nodeType !== Node.TEXT_NODE) {
|
|
19699
19952
|
range.insertNode(chip);
|
|
19953
|
+
this.placeCaretAfter(chip);
|
|
19954
|
+
return;
|
|
19700
19955
|
}
|
|
19956
|
+
const text = node.nodeValue || '';
|
|
19957
|
+
const before = text.slice(0, range.startOffset);
|
|
19958
|
+
const after = text.slice(range.startOffset);
|
|
19959
|
+
const wordMatch = before.match(VAR_PATH_TAIL_REGEX);
|
|
19960
|
+
let beforeKept = wordMatch ? before.slice(0, before.length - wordMatch[1].length) : before;
|
|
19961
|
+
let afterKept = after;
|
|
19962
|
+
if (beforeKept.endsWith('${') && afterKept.startsWith('}')) {
|
|
19963
|
+
beforeKept = beforeKept.slice(0, -2);
|
|
19964
|
+
afterKept = afterKept.slice(1);
|
|
19965
|
+
}
|
|
19966
|
+
else if (beforeKept.endsWith('${')) {
|
|
19967
|
+
beforeKept = beforeKept.slice(0, -2);
|
|
19968
|
+
}
|
|
19969
|
+
const frag = document.createDocumentFragment();
|
|
19970
|
+
if (beforeKept)
|
|
19971
|
+
frag.appendChild(document.createTextNode(beforeKept));
|
|
19972
|
+
frag.appendChild(chip);
|
|
19973
|
+
if (afterKept)
|
|
19974
|
+
frag.appendChild(document.createTextNode(afterKept));
|
|
19975
|
+
node.parentNode.replaceChild(frag, node);
|
|
19701
19976
|
this.placeCaretAfter(chip);
|
|
19702
19977
|
}
|
|
19978
|
+
stripBracesAround(chip) {
|
|
19979
|
+
const prev = chip.previousSibling;
|
|
19980
|
+
const next = chip.nextSibling;
|
|
19981
|
+
if (prev && prev.nodeType === Node.TEXT_NODE) {
|
|
19982
|
+
const t = prev.nodeValue || '';
|
|
19983
|
+
if (t.endsWith('${'))
|
|
19984
|
+
prev.nodeValue = t.slice(0, -2);
|
|
19985
|
+
}
|
|
19986
|
+
if (next && next.nodeType === Node.TEXT_NODE) {
|
|
19987
|
+
const t = next.nodeValue || '';
|
|
19988
|
+
if (t.startsWith('}'))
|
|
19989
|
+
next.nodeValue = t.slice(1);
|
|
19990
|
+
}
|
|
19991
|
+
}
|
|
19992
|
+
insertPlainTextAtCaret(text) {
|
|
19993
|
+
const range = this.getSelectionRange();
|
|
19994
|
+
if (!range) {
|
|
19995
|
+
this.editorRef.nativeElement.appendChild(document.createTextNode(text));
|
|
19996
|
+
this.placeCaretAtEnd();
|
|
19997
|
+
return;
|
|
19998
|
+
}
|
|
19999
|
+
range.deleteContents();
|
|
20000
|
+
const node = document.createTextNode(text);
|
|
20001
|
+
range.insertNode(node);
|
|
20002
|
+
this.placeCaretAfter(node);
|
|
20003
|
+
}
|
|
19703
20004
|
placeCaretAfter(node) {
|
|
19704
20005
|
const sel = window.getSelection();
|
|
19705
20006
|
if (!sel)
|
|
@@ -19711,22 +20012,21 @@ class MixedVariableInputComponent {
|
|
|
19711
20012
|
sel.addRange(range);
|
|
19712
20013
|
}
|
|
19713
20014
|
placeCaretAtEnd() {
|
|
19714
|
-
const editor = this.editorRef.nativeElement;
|
|
19715
20015
|
const sel = window.getSelection();
|
|
19716
20016
|
if (!sel)
|
|
19717
20017
|
return;
|
|
19718
20018
|
const range = document.createRange();
|
|
19719
|
-
range.selectNodeContents(
|
|
20019
|
+
range.selectNodeContents(this.editorRef.nativeElement);
|
|
19720
20020
|
range.collapse(false);
|
|
19721
20021
|
sel.removeAllRanges();
|
|
19722
20022
|
sel.addRange(range);
|
|
19723
20023
|
}
|
|
19724
20024
|
}
|
|
19725
20025
|
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 });
|
|
19726
|
-
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\"
|
|
20026
|
+
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 });
|
|
19727
20027
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: MixedVariableInputComponent, decorators: [{
|
|
19728
20028
|
type: Component,
|
|
19729
|
-
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\"
|
|
20029
|
+
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: [] }]
|
|
19730
20030
|
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.ElementRef }]; }, propDecorators: { value: [{
|
|
19731
20031
|
type: Input
|
|
19732
20032
|
}], placeholder: [{
|
|
@@ -19735,12 +20035,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
|
|
|
19735
20035
|
type: Input
|
|
19736
20036
|
}], valueChange: [{
|
|
19737
20037
|
type: Output
|
|
20038
|
+
}], validityChange: [{
|
|
20039
|
+
type: Output
|
|
19738
20040
|
}], editorRef: [{
|
|
19739
20041
|
type: ViewChild,
|
|
19740
20042
|
args: ['editor', { static: true }]
|
|
20043
|
+
}], onDragStart: [{
|
|
20044
|
+
type: HostListener,
|
|
20045
|
+
args: ['dragstart', ['$event']]
|
|
19741
20046
|
}], onDocumentMouseDown: [{
|
|
19742
20047
|
type: HostListener,
|
|
19743
20048
|
args: ['document:mousedown', ['$event']]
|
|
20049
|
+
}], onDocumentSelectionChange: [{
|
|
20050
|
+
type: HostListener,
|
|
20051
|
+
args: ['document:selectionchange']
|
|
19744
20052
|
}] } });
|
|
19745
20053
|
|
|
19746
20054
|
class CustomTextareaComponent {
|
|
@@ -32732,6 +33040,10 @@ class TemplateVariablesFormComponent {
|
|
|
32732
33040
|
{ id: 'environment', value: 'environment', name: '*|Environment|', label: '*|Environment|' }
|
|
32733
33041
|
];
|
|
32734
33042
|
this.createElementVisible = false;
|
|
33043
|
+
// Tracks active variable-syntax errors by variable name. The validator below
|
|
33044
|
+
// reads from this map so errors survive control re-validation on setValue().
|
|
33045
|
+
this.variableSyntaxErrors = new Map();
|
|
33046
|
+
this.controlsWithSyntaxValidator = new WeakSet();
|
|
32735
33047
|
}
|
|
32736
33048
|
onCreateElement(payload) {
|
|
32737
33049
|
this.createElement.emit(payload);
|
|
@@ -34109,6 +34421,31 @@ class TemplateVariablesFormComponent {
|
|
|
34109
34421
|
// Emit the search query to parent component
|
|
34110
34422
|
this.searchElements.emit(event.query);
|
|
34111
34423
|
}
|
|
34424
|
+
makeSyntaxValidator(variableName) {
|
|
34425
|
+
return () => {
|
|
34426
|
+
const err = this.variableSyntaxErrors.get(variableName);
|
|
34427
|
+
return err ? { invalidVariableSyntax: err } : null;
|
|
34428
|
+
};
|
|
34429
|
+
}
|
|
34430
|
+
onTestDataValidityChange(variableName, event) {
|
|
34431
|
+
var _a;
|
|
34432
|
+
const valueControl = (_a = this.getVariableFormGroup(variableName)) === null || _a === void 0 ? void 0 : _a.get('value');
|
|
34433
|
+
if (!valueControl)
|
|
34434
|
+
return;
|
|
34435
|
+
if (event.valid) {
|
|
34436
|
+
this.variableSyntaxErrors.delete(variableName);
|
|
34437
|
+
}
|
|
34438
|
+
else {
|
|
34439
|
+
this.variableSyntaxErrors.set(variableName, event.error || 'Invalid variable name.');
|
|
34440
|
+
}
|
|
34441
|
+
if (!this.controlsWithSyntaxValidator.has(valueControl)) {
|
|
34442
|
+
valueControl.addValidators(this.makeSyntaxValidator(variableName));
|
|
34443
|
+
this.controlsWithSyntaxValidator.add(valueControl);
|
|
34444
|
+
}
|
|
34445
|
+
valueControl.updateValueAndValidity({ emitEvent: false });
|
|
34446
|
+
valueControl.markAsTouched();
|
|
34447
|
+
this.cdr.markForCheck();
|
|
34448
|
+
}
|
|
34112
34449
|
onTestDataValueChange(variableName, rawValue) {
|
|
34113
34450
|
var _a;
|
|
34114
34451
|
// Find the variable
|
|
@@ -35269,10 +35606,10 @@ class TemplateVariablesFormComponent {
|
|
|
35269
35606
|
}
|
|
35270
35607
|
}
|
|
35271
35608
|
TemplateVariablesFormComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TemplateVariablesFormComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
35272
|
-
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 });
|
|
35609
|
+
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 });
|
|
35273
35610
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TemplateVariablesFormComponent, decorators: [{
|
|
35274
35611
|
type: Component,
|
|
35275
|
-
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"] }]
|
|
35612
|
+
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"] }]
|
|
35276
35613
|
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { templateVariables: [{
|
|
35277
35614
|
type: Input
|
|
35278
35615
|
}], variablesForm: [{
|