@memberjunction/ng-core-entity-forms 6.2.0-edge.1 → 6.2.0-edge.2
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/dist/lib/custom/AIAgents/agent-form-tabs.d.ts +1 -0
- package/dist/lib/custom/AIAgents/agent-form-tabs.d.ts.map +1 -1
- package/dist/lib/custom/AIAgents/agent-form-tabs.js +2 -0
- package/dist/lib/custom/AIAgents/agent-form-tabs.js.map +1 -1
- package/dist/lib/custom/AIAgents/ai-agent-form.component.js +528 -521
- package/dist/lib/custom/AIAgents/ai-agent-form.component.js.map +1 -1
- package/dist/lib/custom/AIPrompts/ai-prompt-form.component.d.ts.map +1 -1
- package/dist/lib/custom/AIPrompts/ai-prompt-form.component.js +10 -16
- package/dist/lib/custom/AIPrompts/ai-prompt-form.component.js.map +1 -1
- package/dist/lib/custom/AIPrompts/pending-records.d.ts +11 -0
- package/dist/lib/custom/AIPrompts/pending-records.d.ts.map +1 -0
- package/dist/lib/custom/AIPrompts/pending-records.js +21 -0
- package/dist/lib/custom/AIPrompts/pending-records.js.map +1 -0
- package/dist/lib/custom/Entities/entity-form.component.d.ts +8 -1
- package/dist/lib/custom/Entities/entity-form.component.d.ts.map +1 -1
- package/dist/lib/custom/Entities/entity-form.component.js +240 -147
- package/dist/lib/custom/Entities/entity-form.component.js.map +1 -1
- package/dist/lib/custom/RecordProcesses/record-process-form.component.d.ts +19 -0
- package/dist/lib/custom/RecordProcesses/record-process-form.component.d.ts.map +1 -1
- package/dist/lib/custom/RecordProcesses/record-process-form.component.js +50 -8
- package/dist/lib/custom/RecordProcesses/record-process-form.component.js.map +1 -1
- package/dist/lib/custom/Rubrics/evaluation-form.component.d.ts +37 -0
- package/dist/lib/custom/Rubrics/evaluation-form.component.d.ts.map +1 -0
- package/dist/lib/custom/Rubrics/evaluation-form.component.js +399 -0
- package/dist/lib/custom/Rubrics/evaluation-form.component.js.map +1 -0
- package/dist/lib/custom/Rubrics/record-forms.component.d.ts +69 -0
- package/dist/lib/custom/Rubrics/record-forms.component.d.ts.map +1 -0
- package/dist/lib/custom/Rubrics/record-forms.component.js +587 -0
- package/dist/lib/custom/Rubrics/record-forms.component.js.map +1 -0
- package/dist/lib/custom/Rubrics/rubric-form.component.d.ts +67 -0
- package/dist/lib/custom/Rubrics/rubric-form.component.d.ts.map +1 -0
- package/dist/lib/custom/Rubrics/rubric-form.component.js +534 -0
- package/dist/lib/custom/Rubrics/rubric-form.component.js.map +1 -0
- package/dist/lib/custom/Rubrics/rubric-form.panels.d.ts +25 -0
- package/dist/lib/custom/Rubrics/rubric-form.panels.d.ts.map +1 -0
- package/dist/lib/custom/Rubrics/rubric-form.panels.js +299 -0
- package/dist/lib/custom/Rubrics/rubric-form.panels.js.map +1 -0
- package/dist/lib/custom/Rubrics/scale-form.component.d.ts +31 -0
- package/dist/lib/custom/Rubrics/scale-form.component.d.ts.map +1 -0
- package/dist/lib/custom/Rubrics/scale-form.component.js +395 -0
- package/dist/lib/custom/Rubrics/scale-form.component.js.map +1 -0
- package/dist/lib/custom/Templates/templates-form.component.d.ts +13 -4
- package/dist/lib/custom/Templates/templates-form.component.d.ts.map +1 -1
- package/dist/lib/custom/Templates/templates-form.component.js +110 -113
- package/dist/lib/custom/Templates/templates-form.component.js.map +1 -1
- package/dist/lib/custom/Tests/test-form.component.d.ts +6 -0
- package/dist/lib/custom/Tests/test-form.component.d.ts.map +1 -1
- package/dist/lib/custom/Tests/test-form.component.js +402 -361
- package/dist/lib/custom/Tests/test-form.component.js.map +1 -1
- package/dist/lib/custom/Tests/test-suite-form.component.d.ts +5 -0
- package/dist/lib/custom/Tests/test-suite-form.component.d.ts.map +1 -1
- package/dist/lib/custom/Tests/test-suite-form.component.js +704 -664
- package/dist/lib/custom/Tests/test-suite-form.component.js.map +1 -1
- package/dist/lib/custom/Users/user-overview.panel.js +1 -1
- package/dist/lib/custom/Users/user-overview.panel.js.map +1 -1
- package/dist/lib/custom/custom-forms.module.d.ts +56 -48
- package/dist/lib/custom/custom-forms.module.d.ts.map +1 -1
- package/dist/lib/custom/custom-forms.module.js +60 -0
- package/dist/lib/custom/custom-forms.module.js.map +1 -1
- package/dist/lib/generated/Entities/MJAIAgent/mjaiagent.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJAIAgent/mjaiagent.form.component.js +61 -43
- package/dist/lib/generated/Entities/MJAIAgent/mjaiagent.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJAIAgentRubric/mjaiagentrubric.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJAIAgentRubric/mjaiagentrubric.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJAIAgentRubric/mjaiagentrubric.form.component.js +74 -0
- package/dist/lib/generated/Entities/MJAIAgentRubric/mjaiagentrubric.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJAIAgentRun/mjaiagentrun.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJAIAgentRun/mjaiagentrun.form.component.js +37 -19
- package/dist/lib/generated/Entities/MJAIAgentRun/mjaiagentrun.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJAIPromptRun/mjaipromptrun.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJAIPromptRun/mjaipromptrun.form.component.js +31 -13
- package/dist/lib/generated/Entities/MJAIPromptRun/mjaipromptrun.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.js +156 -84
- package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJFeaturePipelineType/mjfeaturepipelinetype.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJFeaturePipelineType/mjfeaturepipelinetype.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJFeaturePipelineType/mjfeaturepipelinetype.form.component.js +62 -0
- package/dist/lib/generated/Entities/MJFeaturePipelineType/mjfeaturepipelinetype.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJProcessRun/mjprocessrun.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJProcessRun/mjprocessrun.form.component.js +24 -6
- package/dist/lib/generated/Entities/MJProcessRun/mjprocessrun.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJRecordChange/mjrecordchange.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJRecordChange/mjrecordchange.form.component.js +24 -16
- package/dist/lib/generated/Entities/MJRecordChange/mjrecordchange.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJRecordCloneLog/mjrecordclonelog.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJRecordCloneLog/mjrecordclonelog.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJRecordCloneLog/mjrecordclonelog.form.component.js +107 -0
- package/dist/lib/generated/Entities/MJRecordCloneLog/mjrecordclonelog.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJRecordCloneLogItem/mjrecordclonelogitem.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJRecordCloneLogItem/mjrecordclonelogitem.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJRecordCloneLogItem/mjrecordclonelogitem.form.component.js +74 -0
- package/dist/lib/generated/Entities/MJRecordCloneLogItem/mjrecordclonelogitem.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJRubric/mjrubric.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJRubric/mjrubric.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJRubric/mjrubric.form.component.js +135 -0
- package/dist/lib/generated/Entities/MJRubric/mjrubric.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJRubricBand/mjrubricband.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJRubricBand/mjrubricband.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJRubricBand/mjrubricband.form.component.js +87 -0
- package/dist/lib/generated/Entities/MJRubricBand/mjrubricband.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJRubricCategory/mjrubriccategory.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJRubricCategory/mjrubriccategory.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJRubricCategory/mjrubriccategory.form.component.js +107 -0
- package/dist/lib/generated/Entities/MJRubricCategory/mjrubriccategory.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJRubricCriterion/mjrubriccriterion.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJRubricCriterion/mjrubriccriterion.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJRubricCriterion/mjrubriccriterion.form.component.js +155 -0
- package/dist/lib/generated/Entities/MJRubricCriterion/mjrubriccriterion.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJRubricCriterionLevel/mjrubriccriterionlevel.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJRubricCriterionLevel/mjrubriccriterionlevel.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJRubricCriterionLevel/mjrubriccriterionlevel.form.component.js +62 -0
- package/dist/lib/generated/Entities/MJRubricCriterionLevel/mjrubriccriterionlevel.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJRubricEvaluation/mjrubricevaluation.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJRubricEvaluation/mjrubricevaluation.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJRubricEvaluation/mjrubricevaluation.form.component.js +183 -0
- package/dist/lib/generated/Entities/MJRubricEvaluation/mjrubricevaluation.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJRubricEvaluationScore/mjrubricevaluationscore.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJRubricEvaluationScore/mjrubricevaluationscore.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJRubricEvaluationScore/mjrubricevaluationscore.form.component.js +120 -0
- package/dist/lib/generated/Entities/MJRubricEvaluationScore/mjrubricevaluationscore.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJRubricScale/mjrubricscale.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJRubricScale/mjrubricscale.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJRubricScale/mjrubricscale.form.component.js +107 -0
- package/dist/lib/generated/Entities/MJRubricScale/mjrubricscale.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJRubricScaleLevel/mjrubricscalelevel.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJRubricScaleLevel/mjrubricscalelevel.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJRubricScaleLevel/mjrubricscalelevel.form.component.js +103 -0
- package/dist/lib/generated/Entities/MJRubricScaleLevel/mjrubricscalelevel.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJRubricVersion/mjrubricversion.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJRubricVersion/mjrubricversion.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJRubricVersion/mjrubricversion.form.component.js +171 -0
- package/dist/lib/generated/Entities/MJRubricVersion/mjrubricversion.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJTest/mjtest.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJTest/mjtest.form.component.js +24 -16
- package/dist/lib/generated/Entities/MJTest/mjtest.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJTestSuite/mjtestsuite.form.component.js +27 -25
- package/dist/lib/generated/Entities/MJTestSuite/mjtestsuite.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJTestSuiteRun/mjtestsuiterun.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJTestSuiteRun/mjtestsuiterun.form.component.js +19 -11
- package/dist/lib/generated/Entities/MJTestSuiteRun/mjtestsuiterun.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJUser/mjuser.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJUser/mjuser.form.component.js +172 -118
- package/dist/lib/generated/Entities/MJUser/mjuser.form.component.js.map +1 -1
- package/dist/lib/generated/generated-forms.module.d.ts +436 -422
- package/dist/lib/generated/generated-forms.module.d.ts.map +1 -1
- package/dist/lib/generated/generated-forms.module.js +44 -2
- package/dist/lib/generated/generated-forms.module.js.map +1 -1
- package/dist/lib/panels/record-clone/entity-clone-config-editor.component.d.ts +116 -0
- package/dist/lib/panels/record-clone/entity-clone-config-editor.component.d.ts.map +1 -0
- package/dist/lib/panels/record-clone/entity-clone-config-editor.component.js +820 -0
- package/dist/lib/panels/record-clone/entity-clone-config-editor.component.js.map +1 -0
- package/dist/lib/shared/components/template-editor.component.d.ts +25 -1
- package/dist/lib/shared/components/template-editor.component.d.ts.map +1 -1
- package/dist/lib/shared/components/template-editor.component.js +67 -3
- package/dist/lib/shared/components/template-editor.component.js.map +1 -1
- package/dist/public-api.d.ts +5 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +5 -0
- package/dist/public-api.js.map +1 -1
- package/package.json +47 -43
|
@@ -17,7 +17,7 @@ import { SharedService, NavigationService } from '@memberjunction/ng-shared';
|
|
|
17
17
|
import { ApplicationManager } from '@memberjunction/ng-base-application';
|
|
18
18
|
import { MJConfirmService } from '@memberjunction/ng-ui-components';
|
|
19
19
|
import { MJTestSuiteFormComponent } from '../../generated/Entities/MJTestSuite/mjtestsuite.form.component';
|
|
20
|
-
import { TestingDialogService, TagsHelper, EvaluationPreferencesService } from '@memberjunction/ng-testing';
|
|
20
|
+
import { TestingDialogService, TagsHelper, EvaluationPreferencesService, RubricPickerOptions } from '@memberjunction/ng-testing';
|
|
21
21
|
import * as i0 from "@angular/core";
|
|
22
22
|
import * as i1 from "@angular/common";
|
|
23
23
|
import * as i2 from "@angular/forms";
|
|
@@ -34,7 +34,8 @@ const _c5 = (a0, a1, a2) => ({ "high": a0, "medium": a1, "low": a2 });
|
|
|
34
34
|
const _c6 = (a0, a1) => ({ "positive": a0, "negative": a1 });
|
|
35
35
|
const _c7 = (a0, a1, a2) => ({ "fa-arrow-down": a0, "fa-arrow-up": a1, "fa-minus": a2 });
|
|
36
36
|
const _c8 = (a0, a1) => ({ "improved": a0, "regressed": a1 });
|
|
37
|
-
const _forTrack0 = ($index, $item) => $item.
|
|
37
|
+
const _forTrack0 = ($index, $item) => $item.id;
|
|
38
|
+
const _forTrack1 = ($index, $item) => $item.ID;
|
|
38
39
|
function MJTestSuiteFormComponentExtended_Conditional_21_Template(rf, ctx) { if (rf & 1) {
|
|
39
40
|
i0.ɵɵelementStart(0, "span", 16);
|
|
40
41
|
i0.ɵɵtext(1, "\u25CF");
|
|
@@ -98,25 +99,35 @@ function MJTestSuiteFormComponentExtended_Conditional_60_For_33_Template(rf, ctx
|
|
|
98
99
|
i0.ɵɵtext(1);
|
|
99
100
|
i0.ɵɵelementEnd();
|
|
100
101
|
} if (rf & 2) {
|
|
101
|
-
const
|
|
102
|
-
i0.ɵɵproperty("ngValue",
|
|
102
|
+
const rubric_r4 = ctx.$implicit;
|
|
103
|
+
i0.ɵɵproperty("ngValue", rubric_r4.id);
|
|
103
104
|
i0.ɵɵadvance();
|
|
104
|
-
i0.ɵɵtextInterpolate(
|
|
105
|
+
i0.ɵɵtextInterpolate(rubric_r4.name);
|
|
105
106
|
} }
|
|
106
|
-
function
|
|
107
|
-
|
|
108
|
-
i0.ɵɵ
|
|
107
|
+
function MJTestSuiteFormComponentExtended_Conditional_60_For_41_Template(rf, ctx) { if (rf & 1) {
|
|
108
|
+
i0.ɵɵelementStart(0, "option", 73);
|
|
109
|
+
i0.ɵɵtext(1);
|
|
110
|
+
i0.ɵɵelementEnd();
|
|
111
|
+
} if (rf & 2) {
|
|
112
|
+
const s_r5 = ctx.$implicit;
|
|
113
|
+
i0.ɵɵproperty("ngValue", s_r5.ID);
|
|
114
|
+
i0.ɵɵadvance();
|
|
115
|
+
i0.ɵɵtextInterpolate(s_r5.Name);
|
|
116
|
+
} }
|
|
117
|
+
function MJTestSuiteFormComponentExtended_Conditional_60_For_47_Template(rf, ctx) { if (rf & 1) {
|
|
118
|
+
const _r7 = i0.ɵɵgetCurrentView();
|
|
119
|
+
i0.ɵɵelementStart(0, "span", 80);
|
|
109
120
|
i0.ɵɵtext(1);
|
|
110
|
-
i0.ɵɵelementStart(2, "button",
|
|
111
|
-
i0.ɵɵlistener("click", function
|
|
112
|
-
i0.ɵɵelement(3, "i",
|
|
121
|
+
i0.ɵɵelementStart(2, "button", 92);
|
|
122
|
+
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_60_For_47_Template_button_click_2_listener($event) { const tag_r8 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r0 = i0.ɵɵnextContext(2); ctx_r0.removeTag(tag_r8); return i0.ɵɵresetView($event.stopPropagation()); });
|
|
123
|
+
i0.ɵɵelement(3, "i", 93);
|
|
113
124
|
i0.ɵɵelementEnd()();
|
|
114
125
|
} if (rf & 2) {
|
|
115
|
-
const
|
|
126
|
+
const tag_r8 = ctx.$implicit;
|
|
116
127
|
i0.ɵɵadvance();
|
|
117
|
-
i0.ɵɵtextInterpolate1(" ",
|
|
128
|
+
i0.ɵɵtextInterpolate1(" ", tag_r8, " ");
|
|
118
129
|
i0.ɵɵadvance();
|
|
119
|
-
i0.ɵɵattribute("aria-label", "Remove tag " +
|
|
130
|
+
i0.ɵɵattribute("aria-label", "Remove tag " + tag_r8);
|
|
120
131
|
} }
|
|
121
132
|
function MJTestSuiteFormComponentExtended_Conditional_60_Template(rf, ctx) { if (rf & 1) {
|
|
122
133
|
const _r2 = i0.ɵɵgetCurrentView();
|
|
@@ -149,60 +160,70 @@ function MJTestSuiteFormComponentExtended_Conditional_60_Template(rf, ctx) { if
|
|
|
149
160
|
i0.ɵɵrepeaterCreate(24, MJTestSuiteFormComponentExtended_Conditional_60_For_25_Template, 2, 2, "option", 73, i0.ɵɵrepeaterTrackByIdentity);
|
|
150
161
|
i0.ɵɵelementEnd()()();
|
|
151
162
|
i0.ɵɵelementStart(26, "div", 69)(27, "label", 74);
|
|
152
|
-
i0.ɵɵtext(28, "
|
|
163
|
+
i0.ɵɵtext(28, "Rubric");
|
|
153
164
|
i0.ɵɵelementEnd();
|
|
154
165
|
i0.ɵɵelementStart(29, "select", 75);
|
|
155
|
-
i0.ɵɵlistener("ngModelChange", function MJTestSuiteFormComponentExtended_Conditional_60_Template_select_ngModelChange_29_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.record.
|
|
166
|
+
i0.ɵɵlistener("ngModelChange", function MJTestSuiteFormComponentExtended_Conditional_60_Template_select_ngModelChange_29_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.record.RubricID = $event || null); });
|
|
156
167
|
i0.ɵɵelementStart(30, "option", 73);
|
|
157
|
-
i0.ɵɵtext(31, "\u2014 None
|
|
168
|
+
i0.ɵɵtext(31, "\u2014 None \u2014");
|
|
158
169
|
i0.ɵɵelementEnd();
|
|
159
170
|
i0.ɵɵrepeaterCreate(32, MJTestSuiteFormComponentExtended_Conditional_60_For_33_Template, 2, 2, "option", 73, _forTrack0);
|
|
160
171
|
i0.ɵɵelementEnd()();
|
|
161
|
-
i0.ɵɵelementStart(34, "div",
|
|
162
|
-
i0.ɵɵtext(36, "
|
|
163
|
-
i0.ɵɵelementEnd();
|
|
164
|
-
i0.ɵɵelementStart(37, "
|
|
165
|
-
i0.ɵɵlistener("
|
|
166
|
-
i0.ɵɵ
|
|
167
|
-
i0.ɵɵ
|
|
168
|
-
i0.ɵɵ
|
|
169
|
-
i0.ɵɵ
|
|
172
|
+
i0.ɵɵelementStart(34, "div", 69)(35, "label", 76);
|
|
173
|
+
i0.ɵɵtext(36, "Parent Suite");
|
|
174
|
+
i0.ɵɵelementEnd();
|
|
175
|
+
i0.ɵɵelementStart(37, "select", 77);
|
|
176
|
+
i0.ɵɵlistener("ngModelChange", function MJTestSuiteFormComponentExtended_Conditional_60_Template_select_ngModelChange_37_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.record.ParentID = $event || null); });
|
|
177
|
+
i0.ɵɵelementStart(38, "option", 73);
|
|
178
|
+
i0.ɵɵtext(39, "\u2014 None (top-level) \u2014");
|
|
179
|
+
i0.ɵɵelementEnd();
|
|
180
|
+
i0.ɵɵrepeaterCreate(40, MJTestSuiteFormComponentExtended_Conditional_60_For_41_Template, 2, 2, "option", 73, _forTrack1);
|
|
181
|
+
i0.ɵɵelementEnd()();
|
|
182
|
+
i0.ɵɵelementStart(42, "div", 63)(43, "label", 78);
|
|
183
|
+
i0.ɵɵtext(44, "Tags");
|
|
184
|
+
i0.ɵɵelementEnd();
|
|
185
|
+
i0.ɵɵelementStart(45, "div", 79);
|
|
186
|
+
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_60_Template_div_click_45_listener() { i0.ɵɵrestoreView(_r2); const tagInput_r6 = i0.ɵɵreference(49); return i0.ɵɵresetView(tagInput_r6.focus()); });
|
|
187
|
+
i0.ɵɵrepeaterCreate(46, MJTestSuiteFormComponentExtended_Conditional_60_For_47_Template, 4, 2, "span", 80, i0.ɵɵrepeaterTrackByIdentity);
|
|
188
|
+
i0.ɵɵelementStart(48, "input", 81, 0);
|
|
189
|
+
i0.ɵɵtwoWayListener("ngModelChange", function MJTestSuiteFormComponentExtended_Conditional_60_Template_input_ngModelChange_48_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r0.tagDraft, $event) || (ctx_r0.tagDraft = $event); return i0.ɵɵresetView($event); });
|
|
190
|
+
i0.ɵɵlistener("keydown", function MJTestSuiteFormComponentExtended_Conditional_60_Template_input_keydown_48_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onTagInputKeydown($event)); })("blur", function MJTestSuiteFormComponentExtended_Conditional_60_Template_input_blur_48_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.addTagFromDraft()); });
|
|
170
191
|
i0.ɵɵelementEnd()();
|
|
171
|
-
i0.ɵɵelementStart(
|
|
172
|
-
i0.ɵɵtext(
|
|
192
|
+
i0.ɵɵelementStart(50, "span", 82);
|
|
193
|
+
i0.ɵɵtext(51, "Press Enter or comma to add a tag. Backspace on empty input removes the last tag.");
|
|
173
194
|
i0.ɵɵelementEnd()()()();
|
|
174
|
-
i0.ɵɵelementStart(
|
|
175
|
-
i0.ɵɵelement(
|
|
176
|
-
i0.ɵɵtext(
|
|
195
|
+
i0.ɵɵelementStart(52, "section", 58)(53, "header", 59)(54, "h3");
|
|
196
|
+
i0.ɵɵelement(55, "i", 83);
|
|
197
|
+
i0.ɵɵtext(56, " Execution Settings");
|
|
177
198
|
i0.ɵɵelementEnd()();
|
|
178
|
-
i0.ɵɵelementStart(
|
|
179
|
-
i0.ɵɵtext(
|
|
199
|
+
i0.ɵɵelementStart(57, "div", 62)(58, "div", 69)(59, "label", 84);
|
|
200
|
+
i0.ɵɵtext(60, "Max Execution Time (ms)");
|
|
180
201
|
i0.ɵɵelementEnd();
|
|
181
|
-
i0.ɵɵelementStart(
|
|
182
|
-
i0.ɵɵlistener("ngModelChange", function
|
|
202
|
+
i0.ɵɵelementStart(61, "input", 85);
|
|
203
|
+
i0.ɵɵlistener("ngModelChange", function MJTestSuiteFormComponentExtended_Conditional_60_Template_input_ngModelChange_61_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.record.MaxExecutionTimeMS = $event === "" || $event === null ? null : +$event); });
|
|
183
204
|
i0.ɵɵelementEnd();
|
|
184
|
-
i0.ɵɵelementStart(
|
|
185
|
-
i0.ɵɵtext(
|
|
205
|
+
i0.ɵɵelementStart(62, "span", 82);
|
|
206
|
+
i0.ɵɵtext(63);
|
|
186
207
|
i0.ɵɵelementEnd()()()();
|
|
187
|
-
i0.ɵɵelementStart(
|
|
188
|
-
i0.ɵɵtext(
|
|
208
|
+
i0.ɵɵelementStart(64, "section", 86)(65, "div", 87)(66, "div", 88)(67, "div", 89);
|
|
209
|
+
i0.ɵɵtext(68, "Created");
|
|
189
210
|
i0.ɵɵelementEnd();
|
|
190
|
-
i0.ɵɵelementStart(
|
|
191
|
-
i0.ɵɵtext(
|
|
192
|
-
i0.ɵɵpipe(
|
|
211
|
+
i0.ɵɵelementStart(69, "div", 90);
|
|
212
|
+
i0.ɵɵtext(70);
|
|
213
|
+
i0.ɵɵpipe(71, "date");
|
|
193
214
|
i0.ɵɵelementEnd()();
|
|
194
|
-
i0.ɵɵelementStart(
|
|
195
|
-
i0.ɵɵtext(
|
|
215
|
+
i0.ɵɵelementStart(72, "div", 88)(73, "div", 89);
|
|
216
|
+
i0.ɵɵtext(74, "Last updated");
|
|
196
217
|
i0.ɵɵelementEnd();
|
|
197
|
-
i0.ɵɵelementStart(
|
|
198
|
-
i0.ɵɵtext(
|
|
199
|
-
i0.ɵɵpipe(
|
|
218
|
+
i0.ɵɵelementStart(75, "div", 90);
|
|
219
|
+
i0.ɵɵtext(76);
|
|
220
|
+
i0.ɵɵpipe(77, "date");
|
|
200
221
|
i0.ɵɵelementEnd()();
|
|
201
|
-
i0.ɵɵelementStart(
|
|
202
|
-
i0.ɵɵtext(
|
|
222
|
+
i0.ɵɵelementStart(78, "div", 88)(79, "div", 89);
|
|
223
|
+
i0.ɵɵtext(80, "Suite ID");
|
|
203
224
|
i0.ɵɵelementEnd();
|
|
204
|
-
i0.ɵɵelementStart(
|
|
205
|
-
i0.ɵɵtext(
|
|
225
|
+
i0.ɵɵelementStart(81, "div", 91);
|
|
226
|
+
i0.ɵɵtext(82);
|
|
206
227
|
i0.ɵɵelementEnd()()()()();
|
|
207
228
|
} if (rf & 2) {
|
|
208
229
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
@@ -215,6 +236,12 @@ function MJTestSuiteFormComponentExtended_Conditional_60_Template(rf, ctx) { if
|
|
|
215
236
|
i0.ɵɵadvance();
|
|
216
237
|
i0.ɵɵrepeater(ctx_r0.statusOptions);
|
|
217
238
|
i0.ɵɵadvance(5);
|
|
239
|
+
i0.ɵɵproperty("ngModel", ctx_r0.record.RubricID);
|
|
240
|
+
i0.ɵɵadvance();
|
|
241
|
+
i0.ɵɵproperty("ngValue", null);
|
|
242
|
+
i0.ɵɵadvance(2);
|
|
243
|
+
i0.ɵɵrepeater(ctx_r0.RubricOptions);
|
|
244
|
+
i0.ɵɵadvance(5);
|
|
218
245
|
i0.ɵɵproperty("ngModel", ctx_r0.record.ParentID);
|
|
219
246
|
i0.ɵɵadvance();
|
|
220
247
|
i0.ɵɵproperty("ngValue", null);
|
|
@@ -230,14 +257,14 @@ function MJTestSuiteFormComponentExtended_Conditional_60_Template(rf, ctx) { if
|
|
|
230
257
|
i0.ɵɵadvance(2);
|
|
231
258
|
i0.ɵɵtextInterpolate1("Default timeout for tests in this suite. Currently: ", ctx_r0.formatTimeout(ctx_r0.record.MaxExecutionTimeMS));
|
|
232
259
|
i0.ɵɵadvance(7);
|
|
233
|
-
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(
|
|
260
|
+
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(71, 14, ctx_r0.record.__mj_CreatedAt, "medium"));
|
|
234
261
|
i0.ɵɵadvance(6);
|
|
235
|
-
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(
|
|
262
|
+
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(77, 17, ctx_r0.record.__mj_UpdatedAt, "medium"));
|
|
236
263
|
i0.ɵɵadvance(6);
|
|
237
264
|
i0.ɵɵtextInterpolate(ctx_r0.record.ID);
|
|
238
265
|
} }
|
|
239
266
|
function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
240
|
-
i0.ɵɵelementStart(0, "span",
|
|
267
|
+
i0.ɵɵelementStart(0, "span", 96);
|
|
241
268
|
i0.ɵɵtext(1);
|
|
242
269
|
i0.ɵɵelementEnd();
|
|
243
270
|
} if (rf & 2) {
|
|
@@ -246,15 +273,15 @@ function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_5_Template(
|
|
|
246
273
|
i0.ɵɵtextInterpolate(ctx_r0.suiteTests.length);
|
|
247
274
|
} }
|
|
248
275
|
function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_12_For_3_Template(rf, ctx) { if (rf & 1) {
|
|
249
|
-
i0.ɵɵelementStart(0, "div",
|
|
250
|
-
i0.ɵɵelement(1, "div",
|
|
251
|
-
i0.ɵɵelementStart(3, "div",
|
|
252
|
-
i0.ɵɵelement(4, "div",
|
|
276
|
+
i0.ɵɵelementStart(0, "div", 105);
|
|
277
|
+
i0.ɵɵelement(1, "div", 106)(2, "div", 107);
|
|
278
|
+
i0.ɵɵelementStart(3, "div", 108);
|
|
279
|
+
i0.ɵɵelement(4, "div", 109)(5, "div", 110);
|
|
253
280
|
i0.ɵɵelementEnd()();
|
|
254
281
|
} }
|
|
255
282
|
function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_12_Template(rf, ctx) { if (rf & 1) {
|
|
256
|
-
i0.ɵɵelementStart(0, "div",
|
|
257
|
-
i0.ɵɵrepeaterCreate(2, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_12_For_3_Template, 6, 0, "div",
|
|
283
|
+
i0.ɵɵelementStart(0, "div", 101)(1, "div", 104);
|
|
284
|
+
i0.ɵɵrepeaterCreate(2, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_12_For_3_Template, 6, 0, "div", 105, i0.ɵɵrepeaterTrackByIdentity);
|
|
258
285
|
i0.ɵɵelementEnd()();
|
|
259
286
|
} if (rf & 2) {
|
|
260
287
|
i0.ɵɵadvance(2);
|
|
@@ -262,33 +289,33 @@ function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_12_Template
|
|
|
262
289
|
} }
|
|
263
290
|
function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_11_Template(rf, ctx) { if (rf & 1) {
|
|
264
291
|
i0.ɵɵelementStart(0, "span");
|
|
265
|
-
i0.ɵɵelement(1, "i",
|
|
292
|
+
i0.ɵɵelement(1, "i", 121);
|
|
266
293
|
i0.ɵɵtext(2);
|
|
267
294
|
i0.ɵɵelementEnd();
|
|
268
295
|
} if (rf & 2) {
|
|
269
|
-
const
|
|
296
|
+
const test_r12 = i0.ɵɵnextContext().$implicit;
|
|
270
297
|
i0.ɵɵadvance(2);
|
|
271
|
-
i0.ɵɵtextInterpolate1(" ",
|
|
298
|
+
i0.ɵɵtextInterpolate1(" ", test_r12.Status);
|
|
272
299
|
} }
|
|
273
300
|
function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_12_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
274
|
-
i0.ɵɵelement(0, "i",
|
|
301
|
+
i0.ɵɵelement(0, "i", 125);
|
|
275
302
|
} }
|
|
276
303
|
function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_12_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
277
304
|
i0.ɵɵtext(0, " Remove ");
|
|
278
305
|
} }
|
|
279
306
|
function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_12_Template(rf, ctx) { if (rf & 1) {
|
|
280
|
-
const
|
|
281
|
-
i0.ɵɵelementStart(0, "div",
|
|
307
|
+
const _r13 = i0.ɵɵgetCurrentView();
|
|
308
|
+
i0.ɵɵelementStart(0, "div", 122);
|
|
282
309
|
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_12_Template_div_click_0_listener($event) { return $event.stopPropagation(); });
|
|
283
|
-
i0.ɵɵelementStart(1, "span",
|
|
310
|
+
i0.ɵɵelementStart(1, "span", 123);
|
|
284
311
|
i0.ɵɵtext(2, "Remove from suite?");
|
|
285
312
|
i0.ɵɵelementEnd();
|
|
286
|
-
i0.ɵɵelementStart(3, "button",
|
|
287
|
-
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_12_Template_button_click_3_listener($event) { i0.ɵɵrestoreView(
|
|
288
|
-
i0.ɵɵconditionalCreate(4, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_12_Conditional_4_Template, 1, 0, "i",
|
|
313
|
+
i0.ɵɵelementStart(3, "button", 124);
|
|
314
|
+
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_12_Template_button_click_3_listener($event) { i0.ɵɵrestoreView(_r13); const test_r12 = i0.ɵɵnextContext().$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.confirmRemoveTest(test_r12, $event)); });
|
|
315
|
+
i0.ɵɵconditionalCreate(4, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_12_Conditional_4_Template, 1, 0, "i", 125)(5, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_12_Conditional_5_Template, 1, 0);
|
|
289
316
|
i0.ɵɵelementEnd();
|
|
290
|
-
i0.ɵɵelementStart(6, "button",
|
|
291
|
-
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_12_Template_button_click_6_listener($event) { i0.ɵɵrestoreView(
|
|
317
|
+
i0.ɵɵelementStart(6, "button", 126);
|
|
318
|
+
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_12_Template_button_click_6_listener($event) { i0.ɵɵrestoreView(_r13); const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.cancelRemoveTest($event)); });
|
|
292
319
|
i0.ɵɵtext(7, " Cancel ");
|
|
293
320
|
i0.ɵɵelementEnd()();
|
|
294
321
|
} if (rf & 2) {
|
|
@@ -301,54 +328,54 @@ function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Co
|
|
|
301
328
|
i0.ɵɵproperty("disabled", ctx_r0.isRemovingTest);
|
|
302
329
|
} }
|
|
303
330
|
function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_13_Template(rf, ctx) { if (rf & 1) {
|
|
304
|
-
const
|
|
305
|
-
i0.ɵɵelementStart(0, "button",
|
|
306
|
-
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_13_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(
|
|
307
|
-
i0.ɵɵelement(1, "i",
|
|
331
|
+
const _r14 = i0.ɵɵgetCurrentView();
|
|
332
|
+
i0.ɵɵelementStart(0, "button", 127);
|
|
333
|
+
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_13_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r14); const test_r12 = i0.ɵɵnextContext().$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.requestRemoveTest(test_r12, $event)); });
|
|
334
|
+
i0.ɵɵelement(1, "i", 93);
|
|
308
335
|
i0.ɵɵelementEnd();
|
|
309
|
-
i0.ɵɵelementStart(2, "i",
|
|
310
|
-
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_13_Template_i_click_2_listener() { i0.ɵɵrestoreView(
|
|
336
|
+
i0.ɵɵelementStart(2, "i", 128);
|
|
337
|
+
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_13_Template_i_click_2_listener() { i0.ɵɵrestoreView(_r14); const test_r12 = i0.ɵɵnextContext().$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.openTest(test_r12.TestID)); });
|
|
311
338
|
i0.ɵɵelementEnd();
|
|
312
339
|
} }
|
|
313
340
|
function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
314
|
-
const
|
|
315
|
-
i0.ɵɵelementStart(0, "div",
|
|
316
|
-
i0.ɵɵelement(2, "i",
|
|
341
|
+
const _r11 = i0.ɵɵgetCurrentView();
|
|
342
|
+
i0.ɵɵelementStart(0, "div", 112)(1, "span", 113);
|
|
343
|
+
i0.ɵɵelement(2, "i", 114);
|
|
317
344
|
i0.ɵɵelementEnd();
|
|
318
|
-
i0.ɵɵelementStart(3, "div",
|
|
345
|
+
i0.ɵɵelementStart(3, "div", 115);
|
|
319
346
|
i0.ɵɵtext(4);
|
|
320
347
|
i0.ɵɵelementEnd();
|
|
321
|
-
i0.ɵɵelementStart(5, "div",
|
|
348
|
+
i0.ɵɵelementStart(5, "div", 116);
|
|
322
349
|
i0.ɵɵelement(6, "i", 33);
|
|
323
350
|
i0.ɵɵelementEnd();
|
|
324
|
-
i0.ɵɵelementStart(7, "div",
|
|
325
|
-
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Template_div_click_7_listener() { const
|
|
326
|
-
i0.ɵɵelementStart(8, "div",
|
|
351
|
+
i0.ɵɵelementStart(7, "div", 117);
|
|
352
|
+
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Template_div_click_7_listener() { const test_r12 = i0.ɵɵrestoreView(_r11).$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.openTest(test_r12.TestID)); });
|
|
353
|
+
i0.ɵɵelementStart(8, "div", 118);
|
|
327
354
|
i0.ɵɵtext(9);
|
|
328
355
|
i0.ɵɵelementEnd();
|
|
329
|
-
i0.ɵɵelementStart(10, "div",
|
|
356
|
+
i0.ɵɵelementStart(10, "div", 119);
|
|
330
357
|
i0.ɵɵconditionalCreate(11, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_11_Template, 3, 1, "span");
|
|
331
358
|
i0.ɵɵelementEnd()();
|
|
332
|
-
i0.ɵɵconditionalCreate(12, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_12_Template, 8, 3, "div",
|
|
359
|
+
i0.ɵɵconditionalCreate(12, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_12_Template, 8, 3, "div", 120)(13, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_13_Template, 3, 0);
|
|
333
360
|
i0.ɵɵelementEnd();
|
|
334
361
|
} if (rf & 2) {
|
|
335
|
-
const
|
|
362
|
+
const test_r12 = ctx.$implicit;
|
|
336
363
|
const ctx_r0 = i0.ɵɵnextContext(3);
|
|
337
364
|
i0.ɵɵproperty("cdkDragDisabled", ctx_r0.isReorderingTests || ctx_r0.isRemovingTest);
|
|
338
365
|
i0.ɵɵadvance(4);
|
|
339
|
-
i0.ɵɵtextInterpolate(
|
|
366
|
+
i0.ɵɵtextInterpolate(test_r12.Sequence);
|
|
340
367
|
i0.ɵɵadvance(5);
|
|
341
|
-
i0.ɵɵtextInterpolate(
|
|
368
|
+
i0.ɵɵtextInterpolate(test_r12.Test);
|
|
342
369
|
i0.ɵɵadvance(2);
|
|
343
|
-
i0.ɵɵconditional(
|
|
370
|
+
i0.ɵɵconditional(test_r12.Status ? 11 : -1);
|
|
344
371
|
i0.ɵɵadvance();
|
|
345
|
-
i0.ɵɵconditional(ctx_r0.confirmingRemoveSuiteTestId ===
|
|
372
|
+
i0.ɵɵconditional(ctx_r0.confirmingRemoveSuiteTestId === test_r12.ID ? 12 : 13);
|
|
346
373
|
} }
|
|
347
374
|
function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_Template(rf, ctx) { if (rf & 1) {
|
|
348
|
-
const
|
|
349
|
-
i0.ɵɵelementStart(0, "div",
|
|
350
|
-
i0.ɵɵlistener("cdkDropListDropped", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_Template_div_cdkDropListDropped_0_listener($event) { i0.ɵɵrestoreView(
|
|
351
|
-
i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Template, 14, 5, "div",
|
|
375
|
+
const _r10 = i0.ɵɵgetCurrentView();
|
|
376
|
+
i0.ɵɵelementStart(0, "div", 111);
|
|
377
|
+
i0.ɵɵlistener("cdkDropListDropped", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_Template_div_cdkDropListDropped_0_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.onTestDrop($event)); });
|
|
378
|
+
i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Template, 14, 5, "div", 112, _forTrack1);
|
|
352
379
|
i0.ɵɵelementEnd();
|
|
353
380
|
} if (rf & 2) {
|
|
354
381
|
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
@@ -356,28 +383,28 @@ function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_Template
|
|
|
356
383
|
i0.ɵɵrepeater(ctx_r0.suiteTests);
|
|
357
384
|
} }
|
|
358
385
|
function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_14_Template(rf, ctx) { if (rf & 1) {
|
|
359
|
-
const
|
|
360
|
-
i0.ɵɵelementStart(0, "mj-empty-state",
|
|
361
|
-
i0.ɵɵlistener("Action", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_14_Template_mj_empty_state_Action_0_listener() { i0.ɵɵrestoreView(
|
|
386
|
+
const _r15 = i0.ɵɵgetCurrentView();
|
|
387
|
+
i0.ɵɵelementStart(0, "mj-empty-state", 129);
|
|
388
|
+
i0.ɵɵlistener("Action", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_14_Template_mj_empty_state_Action_0_listener() { i0.ɵɵrestoreView(_r15); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.openAddTestsDialog()); });
|
|
362
389
|
i0.ɵɵelementEnd();
|
|
363
390
|
} }
|
|
364
391
|
function MJTestSuiteFormComponentExtended_Conditional_61_Template(rf, ctx) { if (rf & 1) {
|
|
365
|
-
const
|
|
366
|
-
i0.ɵɵelementStart(0, "div", 40)(1, "div",
|
|
392
|
+
const _r9 = i0.ɵɵgetCurrentView();
|
|
393
|
+
i0.ɵɵelementStart(0, "div", 40)(1, "div", 94)(2, "div", 95)(3, "strong");
|
|
367
394
|
i0.ɵɵtext(4, "Suite tests");
|
|
368
395
|
i0.ɵɵelementEnd();
|
|
369
|
-
i0.ɵɵconditionalCreate(5, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_5_Template, 2, 1, "span",
|
|
370
|
-
i0.ɵɵelementStart(6, "span",
|
|
396
|
+
i0.ɵɵconditionalCreate(5, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_5_Template, 2, 1, "span", 96);
|
|
397
|
+
i0.ɵɵelementStart(6, "span", 97);
|
|
371
398
|
i0.ɵɵtext(7, "Drag to reorder \u00B7 Hover a row to remove");
|
|
372
399
|
i0.ɵɵelementEnd()();
|
|
373
|
-
i0.ɵɵelementStart(8, "div",
|
|
374
|
-
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Template_button_click_9_listener() { i0.ɵɵrestoreView(
|
|
375
|
-
i0.ɵɵelement(10, "i",
|
|
400
|
+
i0.ɵɵelementStart(8, "div", 98)(9, "button", 99);
|
|
401
|
+
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Template_button_click_9_listener() { i0.ɵɵrestoreView(_r9); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.openAddTestsDialog()); });
|
|
402
|
+
i0.ɵɵelement(10, "i", 100);
|
|
376
403
|
i0.ɵɵtext(11, " Add tests ");
|
|
377
404
|
i0.ɵɵelementEnd()()();
|
|
378
|
-
i0.ɵɵconditionalCreate(12, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_12_Template, 4, 1, "div",
|
|
379
|
-
i0.ɵɵconditionalCreate(13, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_Template, 3, 0, "div",
|
|
380
|
-
i0.ɵɵconditionalCreate(14, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_14_Template, 1, 0, "mj-empty-state",
|
|
405
|
+
i0.ɵɵconditionalCreate(12, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_12_Template, 4, 1, "div", 101);
|
|
406
|
+
i0.ɵɵconditionalCreate(13, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_Template, 3, 0, "div", 102);
|
|
407
|
+
i0.ɵɵconditionalCreate(14, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_14_Template, 1, 0, "mj-empty-state", 103);
|
|
381
408
|
i0.ɵɵelementEnd();
|
|
382
409
|
} if (rf & 2) {
|
|
383
410
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
@@ -393,15 +420,15 @@ function MJTestSuiteFormComponentExtended_Conditional_61_Template(rf, ctx) { if
|
|
|
393
420
|
i0.ɵɵconditional(ctx_r0.testsLoaded && !ctx_r0.loadingTests && ctx_r0.suiteTests.length === 0 ? 14 : -1);
|
|
394
421
|
} }
|
|
395
422
|
function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_1_For_3_Template(rf, ctx) { if (rf & 1) {
|
|
396
|
-
i0.ɵɵelementStart(0, "div",
|
|
397
|
-
i0.ɵɵelement(1, "div",
|
|
398
|
-
i0.ɵɵelementStart(2, "div",
|
|
399
|
-
i0.ɵɵelement(3, "div",
|
|
423
|
+
i0.ɵɵelementStart(0, "div", 105);
|
|
424
|
+
i0.ɵɵelement(1, "div", 107);
|
|
425
|
+
i0.ɵɵelementStart(2, "div", 108);
|
|
426
|
+
i0.ɵɵelement(3, "div", 109)(4, "div", 110);
|
|
400
427
|
i0.ɵɵelementEnd()();
|
|
401
428
|
} }
|
|
402
429
|
function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
403
|
-
i0.ɵɵelementStart(0, "div",
|
|
404
|
-
i0.ɵɵrepeaterCreate(2, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_1_For_3_Template, 5, 0, "div",
|
|
430
|
+
i0.ɵɵelementStart(0, "div", 101)(1, "div", 104);
|
|
431
|
+
i0.ɵɵrepeaterCreate(2, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_1_For_3_Template, 5, 0, "div", 105, i0.ɵɵrepeaterTrackByIdentity);
|
|
405
432
|
i0.ɵɵelementEnd()();
|
|
406
433
|
} if (rf & 2) {
|
|
407
434
|
i0.ɵɵadvance(2);
|
|
@@ -409,121 +436,121 @@ function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_1_Template(
|
|
|
409
436
|
} }
|
|
410
437
|
function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Conditional_13_Template(rf, ctx) { if (rf & 1) {
|
|
411
438
|
i0.ɵɵelementStart(0, "span");
|
|
412
|
-
i0.ɵɵelement(1, "i",
|
|
439
|
+
i0.ɵɵelement(1, "i", 148);
|
|
413
440
|
i0.ɵɵtext(2);
|
|
414
441
|
i0.ɵɵelementEnd();
|
|
415
442
|
} if (rf & 2) {
|
|
416
|
-
const
|
|
443
|
+
const run_r17 = i0.ɵɵnextContext().$implicit;
|
|
417
444
|
const ctx_r0 = i0.ɵɵnextContext(3);
|
|
418
445
|
i0.ɵɵadvance(2);
|
|
419
|
-
i0.ɵɵtextInterpolate3(" ",
|
|
446
|
+
i0.ɵɵtextInterpolate3(" ", run_r17.PassedTests, "/", run_r17.TotalTests, " (", ctx_r0.getPassRate(run_r17).toFixed(0), "%) ");
|
|
420
447
|
} }
|
|
421
448
|
function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Conditional_15_Template(rf, ctx) { if (rf & 1) {
|
|
422
|
-
i0.ɵɵelementStart(0, "span",
|
|
423
|
-
i0.ɵɵelement(1, "i",
|
|
449
|
+
i0.ɵɵelementStart(0, "span", 149);
|
|
450
|
+
i0.ɵɵelement(1, "i", 135);
|
|
424
451
|
i0.ɵɵelementEnd();
|
|
425
452
|
} if (rf & 2) {
|
|
426
|
-
const
|
|
427
|
-
i0.ɵɵclassMap("status-" +
|
|
453
|
+
const run_r17 = i0.ɵɵnextContext().$implicit;
|
|
454
|
+
i0.ɵɵclassMap("status-" + run_r17.Status.toLowerCase());
|
|
428
455
|
i0.ɵɵadvance();
|
|
429
|
-
i0.ɵɵclassProp("fa-circle-check",
|
|
456
|
+
i0.ɵɵclassProp("fa-circle-check", run_r17.Status === "Completed")("fa-circle-xmark", run_r17.Status === "Failed")("fa-spinner", run_r17.Status === "Running")("fa-clock", run_r17.Status === "Pending")("fa-ban", run_r17.Status === "Cancelled");
|
|
430
457
|
} }
|
|
431
458
|
function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Conditional_16_Template(rf, ctx) { if (rf & 1) {
|
|
432
|
-
i0.ɵɵelementStart(0, "span",
|
|
433
|
-
i0.ɵɵelement(1, "i",
|
|
434
|
-
i0.ɵɵelementStart(2, "span",
|
|
435
|
-
i0.ɵɵelement(3, "i",
|
|
459
|
+
i0.ɵɵelementStart(0, "span", 144);
|
|
460
|
+
i0.ɵɵelement(1, "i", 150);
|
|
461
|
+
i0.ɵɵelementStart(2, "span", 151);
|
|
462
|
+
i0.ɵɵelement(3, "i", 152);
|
|
436
463
|
i0.ɵɵelementEnd()();
|
|
437
464
|
} }
|
|
438
465
|
function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Conditional_17_Template(rf, ctx) { if (rf & 1) {
|
|
439
|
-
i0.ɵɵelementStart(0, "span",
|
|
440
|
-
i0.ɵɵelement(1, "i",
|
|
466
|
+
i0.ɵɵelementStart(0, "span", 153);
|
|
467
|
+
i0.ɵɵelement(1, "i", 154);
|
|
441
468
|
i0.ɵɵelementStart(2, "span");
|
|
442
469
|
i0.ɵɵtext(3);
|
|
443
470
|
i0.ɵɵelementEnd()();
|
|
444
471
|
} if (rf & 2) {
|
|
445
|
-
const
|
|
472
|
+
const run_r17 = i0.ɵɵnextContext().$implicit;
|
|
446
473
|
const ctx_r0 = i0.ɵɵnextContext(3);
|
|
447
|
-
i0.ɵɵclassProp("high", ctx_r0.getPassRate(
|
|
474
|
+
i0.ɵɵclassProp("high", ctx_r0.getPassRate(run_r17) >= 80)("medium", ctx_r0.getPassRate(run_r17) >= 50 && ctx_r0.getPassRate(run_r17) < 80)("low", ctx_r0.getPassRate(run_r17) < 50);
|
|
448
475
|
i0.ɵɵadvance(3);
|
|
449
|
-
i0.ɵɵtextInterpolate1("", ctx_r0.getPassRate(
|
|
476
|
+
i0.ɵɵtextInterpolate1("", ctx_r0.getPassRate(run_r17).toFixed(0), "%");
|
|
450
477
|
} }
|
|
451
478
|
function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Conditional_18_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
452
|
-
i0.ɵɵelementStart(0, "span",
|
|
479
|
+
i0.ɵɵelementStart(0, "span", 155);
|
|
453
480
|
i0.ɵɵtext(1);
|
|
454
481
|
i0.ɵɵelementEnd();
|
|
455
482
|
} if (rf & 2) {
|
|
456
|
-
const
|
|
483
|
+
const tag_r18 = ctx.$implicit;
|
|
457
484
|
i0.ɵɵadvance();
|
|
458
|
-
i0.ɵɵtextInterpolate(
|
|
485
|
+
i0.ɵɵtextInterpolate(tag_r18);
|
|
459
486
|
} }
|
|
460
487
|
function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Conditional_18_Template(rf, ctx) { if (rf & 1) {
|
|
461
|
-
i0.ɵɵelementStart(0, "div",
|
|
462
|
-
i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Conditional_18_For_2_Template, 2, 1, "span",
|
|
488
|
+
i0.ɵɵelementStart(0, "div", 146);
|
|
489
|
+
i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Conditional_18_For_2_Template, 2, 1, "span", 155, i0.ɵɵrepeaterTrackByIdentity);
|
|
463
490
|
i0.ɵɵelementEnd();
|
|
464
491
|
} if (rf & 2) {
|
|
465
|
-
const
|
|
492
|
+
const run_r17 = i0.ɵɵnextContext().$implicit;
|
|
466
493
|
const ctx_r0 = i0.ɵɵnextContext(3);
|
|
467
494
|
i0.ɵɵadvance();
|
|
468
|
-
i0.ɵɵrepeater(ctx_r0.getRunTags(
|
|
495
|
+
i0.ɵɵrepeater(ctx_r0.getRunTags(run_r17));
|
|
469
496
|
} }
|
|
470
497
|
function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
471
|
-
const
|
|
472
|
-
i0.ɵɵelementStart(0, "div",
|
|
473
|
-
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Template_div_click_0_listener() { const
|
|
474
|
-
i0.ɵɵelementStart(1, "div",
|
|
475
|
-
i0.ɵɵelement(2, "i",
|
|
498
|
+
const _r16 = i0.ɵɵgetCurrentView();
|
|
499
|
+
i0.ɵɵelementStart(0, "div", 133);
|
|
500
|
+
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Template_div_click_0_listener() { const run_r17 = i0.ɵɵrestoreView(_r16).$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.openSuiteRun(run_r17.ID)); });
|
|
501
|
+
i0.ɵɵelementStart(1, "div", 134);
|
|
502
|
+
i0.ɵɵelement(2, "i", 135);
|
|
476
503
|
i0.ɵɵelementEnd();
|
|
477
|
-
i0.ɵɵelementStart(3, "div",
|
|
504
|
+
i0.ɵɵelementStart(3, "div", 136)(4, "div", 137)(5, "span", 138);
|
|
478
505
|
i0.ɵɵtext(6);
|
|
479
506
|
i0.ɵɵelementEnd();
|
|
480
|
-
i0.ɵɵelementStart(7, "span",
|
|
507
|
+
i0.ɵɵelementStart(7, "span", 139);
|
|
481
508
|
i0.ɵɵtext(8);
|
|
482
509
|
i0.ɵɵelementEnd()();
|
|
483
|
-
i0.ɵɵelementStart(9, "div",
|
|
484
|
-
i0.ɵɵelement(11, "i",
|
|
510
|
+
i0.ɵɵelementStart(9, "div", 140)(10, "span");
|
|
511
|
+
i0.ɵɵelement(11, "i", 141);
|
|
485
512
|
i0.ɵɵtext(12);
|
|
486
513
|
i0.ɵɵelementEnd();
|
|
487
514
|
i0.ɵɵconditionalCreate(13, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Conditional_13_Template, 3, 3, "span");
|
|
488
515
|
i0.ɵɵelementEnd();
|
|
489
|
-
i0.ɵɵelementStart(14, "div",
|
|
490
|
-
i0.ɵɵconditionalCreate(15, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Conditional_15_Template, 2, 12, "span",
|
|
491
|
-
i0.ɵɵconditionalCreate(16, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Conditional_16_Template, 4, 0, "span",
|
|
492
|
-
i0.ɵɵconditionalCreate(17, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Conditional_17_Template, 4, 7, "span",
|
|
516
|
+
i0.ɵɵelementStart(14, "div", 142);
|
|
517
|
+
i0.ɵɵconditionalCreate(15, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Conditional_15_Template, 2, 12, "span", 143);
|
|
518
|
+
i0.ɵɵconditionalCreate(16, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Conditional_16_Template, 4, 0, "span", 144);
|
|
519
|
+
i0.ɵɵconditionalCreate(17, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Conditional_17_Template, 4, 7, "span", 145);
|
|
493
520
|
i0.ɵɵelementEnd();
|
|
494
|
-
i0.ɵɵconditionalCreate(18, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Conditional_18_Template, 3, 0, "div",
|
|
521
|
+
i0.ɵɵconditionalCreate(18, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Conditional_18_Template, 3, 0, "div", 146);
|
|
495
522
|
i0.ɵɵelementEnd();
|
|
496
|
-
i0.ɵɵelement(19, "i",
|
|
523
|
+
i0.ɵɵelement(19, "i", 147);
|
|
497
524
|
i0.ɵɵelementEnd();
|
|
498
525
|
} if (rf & 2) {
|
|
499
|
-
const
|
|
526
|
+
const run_r17 = ctx.$implicit;
|
|
500
527
|
const ctx_r0 = i0.ɵɵnextContext(3);
|
|
501
528
|
i0.ɵɵadvance();
|
|
502
|
-
i0.ɵɵstyleProp("background-color", ctx_r0.getRunStatusColor(
|
|
529
|
+
i0.ɵɵstyleProp("background-color", ctx_r0.getRunStatusColor(run_r17.Status));
|
|
503
530
|
i0.ɵɵadvance();
|
|
504
|
-
i0.ɵɵclassProp("fa-check",
|
|
531
|
+
i0.ɵɵclassProp("fa-check", run_r17.Status === "Completed")("fa-times", run_r17.Status === "Failed")("fa-spinner", run_r17.Status === "Running")("fa-clock", run_r17.Status === "Pending")("fa-ban", run_r17.Status === "Cancelled");
|
|
505
532
|
i0.ɵɵadvance(4);
|
|
506
|
-
i0.ɵɵtextInterpolate1("Run #",
|
|
533
|
+
i0.ɵɵtextInterpolate1("Run #", run_r17.ID.substring(0, 8));
|
|
507
534
|
i0.ɵɵadvance();
|
|
508
|
-
i0.ɵɵstyleProp("color", ctx_r0.getRunStatusColor(
|
|
535
|
+
i0.ɵɵstyleProp("color", ctx_r0.getRunStatusColor(run_r17.Status));
|
|
509
536
|
i0.ɵɵadvance();
|
|
510
|
-
i0.ɵɵtextInterpolate(
|
|
537
|
+
i0.ɵɵtextInterpolate(run_r17.Status);
|
|
511
538
|
i0.ɵɵadvance(4);
|
|
512
|
-
i0.ɵɵtextInterpolate1(" ", ctx_r0.getRelativeTime(
|
|
539
|
+
i0.ɵɵtextInterpolate1(" ", ctx_r0.getRelativeTime(run_r17.StartedAt));
|
|
513
540
|
i0.ɵɵadvance();
|
|
514
|
-
i0.ɵɵconditional(
|
|
541
|
+
i0.ɵɵconditional(run_r17.TotalTests ? 13 : -1);
|
|
515
542
|
i0.ɵɵadvance(2);
|
|
516
543
|
i0.ɵɵconditional(ctx_r0.evalPreferences.showExecution ? 15 : -1);
|
|
517
544
|
i0.ɵɵadvance();
|
|
518
545
|
i0.ɵɵconditional(ctx_r0.evalPreferences.showHuman ? 16 : -1);
|
|
519
546
|
i0.ɵɵadvance();
|
|
520
|
-
i0.ɵɵconditional(ctx_r0.evalPreferences.showAuto &&
|
|
547
|
+
i0.ɵɵconditional(ctx_r0.evalPreferences.showAuto && run_r17.TotalTests ? 17 : -1);
|
|
521
548
|
i0.ɵɵadvance();
|
|
522
|
-
i0.ɵɵconditional(ctx_r0.getRunTags(
|
|
549
|
+
i0.ɵɵconditional(ctx_r0.getRunTags(run_r17).length > 0 ? 18 : -1);
|
|
523
550
|
} }
|
|
524
551
|
function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
525
|
-
i0.ɵɵelementStart(0, "div",
|
|
526
|
-
i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Template, 20, 22, "div",
|
|
552
|
+
i0.ɵɵelementStart(0, "div", 130);
|
|
553
|
+
i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Template, 20, 22, "div", 132, i0.ɵɵrepeaterTrackByIdentity);
|
|
527
554
|
i0.ɵɵelementEnd();
|
|
528
555
|
} if (rf & 2) {
|
|
529
556
|
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
@@ -531,16 +558,16 @@ function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_Template(
|
|
|
531
558
|
i0.ɵɵrepeater(ctx_r0.suiteRuns);
|
|
532
559
|
} }
|
|
533
560
|
function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
534
|
-
const
|
|
535
|
-
i0.ɵɵelementStart(0, "mj-empty-state",
|
|
536
|
-
i0.ɵɵlistener("Action", function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_3_Template_mj_empty_state_Action_0_listener() { i0.ɵɵrestoreView(
|
|
561
|
+
const _r19 = i0.ɵɵgetCurrentView();
|
|
562
|
+
i0.ɵɵelementStart(0, "mj-empty-state", 156);
|
|
563
|
+
i0.ɵɵlistener("Action", function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_3_Template_mj_empty_state_Action_0_listener() { i0.ɵɵrestoreView(_r19); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.runSuite()); });
|
|
537
564
|
i0.ɵɵelementEnd();
|
|
538
565
|
} }
|
|
539
566
|
function MJTestSuiteFormComponentExtended_Conditional_62_Template(rf, ctx) { if (rf & 1) {
|
|
540
567
|
i0.ɵɵelementStart(0, "div", 41);
|
|
541
|
-
i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_1_Template, 4, 1, "div",
|
|
542
|
-
i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_Template, 3, 0, "div",
|
|
543
|
-
i0.ɵɵconditionalCreate(3, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_3_Template, 1, 0, "mj-empty-state",
|
|
568
|
+
i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_1_Template, 4, 1, "div", 101);
|
|
569
|
+
i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_Template, 3, 0, "div", 130);
|
|
570
|
+
i0.ɵɵconditionalCreate(3, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_3_Template, 1, 0, "mj-empty-state", 131);
|
|
544
571
|
i0.ɵɵelementEnd();
|
|
545
572
|
} if (rf & 2) {
|
|
546
573
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
@@ -552,8 +579,8 @@ function MJTestSuiteFormComponentExtended_Conditional_62_Template(rf, ctx) { if
|
|
|
552
579
|
i0.ɵɵconditional(ctx_r0.runsLoaded && !ctx_r0.loadingRuns && ctx_r0.suiteRuns.length === 0 ? 3 : -1);
|
|
553
580
|
} }
|
|
554
581
|
function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
555
|
-
i0.ɵɵelementStart(0, "div",
|
|
556
|
-
i0.ɵɵelement(1, "mj-loading",
|
|
582
|
+
i0.ɵɵelementStart(0, "div", 101);
|
|
583
|
+
i0.ɵɵelement(1, "mj-loading", 158);
|
|
557
584
|
i0.ɵɵelementEnd();
|
|
558
585
|
} }
|
|
559
586
|
function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_15_Conditional_2_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
@@ -566,7 +593,7 @@ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_templa
|
|
|
566
593
|
i0.ɵɵtextInterpolate1(" \u00B7 ", ctx_r0.selectedTags.length, " tags");
|
|
567
594
|
} }
|
|
568
595
|
function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_15_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
569
|
-
i0.ɵɵelementStart(0, "span",
|
|
596
|
+
i0.ɵɵelementStart(0, "span", 169);
|
|
570
597
|
i0.ɵɵtext(1);
|
|
571
598
|
i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_15_Conditional_2_Conditional_2_Template, 2, 1, "span");
|
|
572
599
|
i0.ɵɵelementEnd();
|
|
@@ -578,16 +605,16 @@ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_templa
|
|
|
578
605
|
i0.ɵɵconditional(ctx_r0.selectedTags.length > 0 ? 2 : -1);
|
|
579
606
|
} }
|
|
580
607
|
function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_15_Template(rf, ctx) { if (rf & 1) {
|
|
581
|
-
i0.ɵɵelement(0, "i",
|
|
608
|
+
i0.ɵɵelement(0, "i", 168);
|
|
582
609
|
i0.ɵɵtext(1, " Filters ");
|
|
583
|
-
i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_15_Conditional_2_Template, 3, 2, "span",
|
|
610
|
+
i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_15_Conditional_2_Template, 3, 2, "span", 169);
|
|
584
611
|
} if (rf & 2) {
|
|
585
612
|
const ctx_r0 = i0.ɵɵnextContext(3);
|
|
586
613
|
i0.ɵɵadvance(2);
|
|
587
614
|
i0.ɵɵconditional(ctx_r0.filtersCollapsed ? 2 : -1);
|
|
588
615
|
} }
|
|
589
616
|
function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Conditional_13_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
590
|
-
i0.ɵɵelementStart(0, "span",
|
|
617
|
+
i0.ɵɵelementStart(0, "span", 174);
|
|
591
618
|
i0.ɵɵtext(1);
|
|
592
619
|
i0.ɵɵelementEnd();
|
|
593
620
|
} if (rf & 2) {
|
|
@@ -596,36 +623,36 @@ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_templa
|
|
|
596
623
|
i0.ɵɵtextInterpolate1("(", ctx_r0.selectedTags.length, " selected)");
|
|
597
624
|
} }
|
|
598
625
|
function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Conditional_13_For_9_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
599
|
-
i0.ɵɵelement(0, "i",
|
|
626
|
+
i0.ɵɵelement(0, "i", 179);
|
|
600
627
|
} }
|
|
601
628
|
function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Conditional_13_For_9_Template(rf, ctx) { if (rf & 1) {
|
|
602
|
-
const
|
|
603
|
-
i0.ɵɵelementStart(0, "button",
|
|
604
|
-
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Conditional_13_For_9_Template_button_click_0_listener() { const
|
|
605
|
-
i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Conditional_13_For_9_Conditional_1_Template, 1, 0, "i",
|
|
629
|
+
const _r23 = i0.ɵɵgetCurrentView();
|
|
630
|
+
i0.ɵɵelementStart(0, "button", 178);
|
|
631
|
+
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Conditional_13_For_9_Template_button_click_0_listener() { const tag_r24 = i0.ɵɵrestoreView(_r23).$implicit; const ctx_r0 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r0.toggleTagFilter(tag_r24)); });
|
|
632
|
+
i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Conditional_13_For_9_Conditional_1_Template, 1, 0, "i", 179);
|
|
606
633
|
i0.ɵɵtext(2);
|
|
607
634
|
i0.ɵɵelementEnd();
|
|
608
635
|
} if (rf & 2) {
|
|
609
|
-
const
|
|
636
|
+
const tag_r24 = ctx.$implicit;
|
|
610
637
|
const ctx_r0 = i0.ɵɵnextContext(5);
|
|
611
|
-
i0.ɵɵclassProp("active", ctx_r0.isTagSelected(
|
|
638
|
+
i0.ɵɵclassProp("active", ctx_r0.isTagSelected(tag_r24));
|
|
612
639
|
i0.ɵɵadvance();
|
|
613
|
-
i0.ɵɵconditional(ctx_r0.isTagSelected(
|
|
640
|
+
i0.ɵɵconditional(ctx_r0.isTagSelected(tag_r24) ? 1 : -1);
|
|
614
641
|
i0.ɵɵadvance();
|
|
615
|
-
i0.ɵɵtextInterpolate1(" ",
|
|
642
|
+
i0.ɵɵtextInterpolate1(" ", tag_r24, " ");
|
|
616
643
|
} }
|
|
617
644
|
function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Conditional_13_Template(rf, ctx) { if (rf & 1) {
|
|
618
|
-
const
|
|
619
|
-
i0.ɵɵelementStart(0, "div",
|
|
645
|
+
const _r22 = i0.ɵɵgetCurrentView();
|
|
646
|
+
i0.ɵɵelementStart(0, "div", 171)(1, "label");
|
|
620
647
|
i0.ɵɵtext(2, "Filter by Tag ");
|
|
621
|
-
i0.ɵɵconditionalCreate(3, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Conditional_13_Conditional_3_Template, 2, 1, "span",
|
|
648
|
+
i0.ɵɵconditionalCreate(3, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Conditional_13_Conditional_3_Template, 2, 1, "span", 174);
|
|
622
649
|
i0.ɵɵelementEnd();
|
|
623
|
-
i0.ɵɵelementStart(4, "div",
|
|
624
|
-
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Conditional_13_Template_button_click_5_listener() { i0.ɵɵrestoreView(
|
|
650
|
+
i0.ɵɵelementStart(4, "div", 175)(5, "button", 176);
|
|
651
|
+
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Conditional_13_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r22); const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.toggleTagFilter(null)); });
|
|
625
652
|
i0.ɵɵelement(6, "i", 11);
|
|
626
653
|
i0.ɵɵtext(7, " All Tags ");
|
|
627
654
|
i0.ɵɵelementEnd();
|
|
628
|
-
i0.ɵɵrepeaterCreate(8, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Conditional_13_For_9_Template, 3, 4, "button",
|
|
655
|
+
i0.ɵɵrepeaterCreate(8, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Conditional_13_For_9_Template, 3, 4, "button", 177, i0.ɵɵrepeaterTrackByIdentity);
|
|
629
656
|
i0.ɵɵelementEnd()();
|
|
630
657
|
} if (rf & 2) {
|
|
631
658
|
const ctx_r0 = i0.ɵɵnextContext(4);
|
|
@@ -637,27 +664,27 @@ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_templa
|
|
|
637
664
|
i0.ɵɵrepeater(ctx_r0.uniqueTags);
|
|
638
665
|
} }
|
|
639
666
|
function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Template(rf, ctx) { if (rf & 1) {
|
|
640
|
-
const
|
|
641
|
-
i0.ɵɵelementStart(0, "div",
|
|
667
|
+
const _r21 = i0.ɵɵgetCurrentView();
|
|
668
|
+
i0.ɵɵelementStart(0, "div", 170)(1, "div", 171)(2, "label");
|
|
642
669
|
i0.ɵɵtext(3, "Time Range");
|
|
643
670
|
i0.ɵɵelementEnd();
|
|
644
|
-
i0.ɵɵelementStart(4, "div",
|
|
645
|
-
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Template_button_click_5_listener() { i0.ɵɵrestoreView(
|
|
671
|
+
i0.ɵɵelementStart(4, "div", 172)(5, "button", 173);
|
|
672
|
+
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r21); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.setTimeRange("7d")); });
|
|
646
673
|
i0.ɵɵtext(6, "7 Days");
|
|
647
674
|
i0.ɵɵelementEnd();
|
|
648
|
-
i0.ɵɵelementStart(7, "button",
|
|
649
|
-
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Template_button_click_7_listener() { i0.ɵɵrestoreView(
|
|
675
|
+
i0.ɵɵelementStart(7, "button", 173);
|
|
676
|
+
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r21); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.setTimeRange("30d")); });
|
|
650
677
|
i0.ɵɵtext(8, "30 Days");
|
|
651
678
|
i0.ɵɵelementEnd();
|
|
652
|
-
i0.ɵɵelementStart(9, "button",
|
|
653
|
-
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Template_button_click_9_listener() { i0.ɵɵrestoreView(
|
|
679
|
+
i0.ɵɵelementStart(9, "button", 173);
|
|
680
|
+
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Template_button_click_9_listener() { i0.ɵɵrestoreView(_r21); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.setTimeRange("90d")); });
|
|
654
681
|
i0.ɵɵtext(10, "90 Days");
|
|
655
682
|
i0.ɵɵelementEnd();
|
|
656
|
-
i0.ɵɵelementStart(11, "button",
|
|
657
|
-
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Template_button_click_11_listener() { i0.ɵɵrestoreView(
|
|
683
|
+
i0.ɵɵelementStart(11, "button", 173);
|
|
684
|
+
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Template_button_click_11_listener() { i0.ɵɵrestoreView(_r21); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.setTimeRange("all")); });
|
|
658
685
|
i0.ɵɵtext(12, "All Time");
|
|
659
686
|
i0.ɵɵelementEnd()()();
|
|
660
|
-
i0.ɵɵconditionalCreate(13, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Conditional_13_Template, 10, 3, "div",
|
|
687
|
+
i0.ɵɵconditionalCreate(13, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Conditional_13_Template, 10, 3, "div", 171);
|
|
661
688
|
i0.ɵɵelementEnd();
|
|
662
689
|
} if (rf & 2) {
|
|
663
690
|
const ctx_r0 = i0.ɵɵnextContext(3);
|
|
@@ -673,36 +700,36 @@ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_templa
|
|
|
673
700
|
i0.ɵɵconditional(ctx_r0.uniqueTags.length > 0 ? 13 : -1);
|
|
674
701
|
} }
|
|
675
702
|
function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_17_For_60_For_21_Template(rf, ctx) { if (rf & 1) {
|
|
676
|
-
i0.ɵɵelementStart(0, "span",
|
|
703
|
+
i0.ɵɵelementStart(0, "span", 203);
|
|
677
704
|
i0.ɵɵtext(1);
|
|
678
705
|
i0.ɵɵelementEnd();
|
|
679
706
|
} if (rf & 2) {
|
|
680
|
-
const
|
|
707
|
+
const tag_r27 = ctx.$implicit;
|
|
681
708
|
i0.ɵɵadvance();
|
|
682
|
-
i0.ɵɵtextInterpolate(
|
|
709
|
+
i0.ɵɵtextInterpolate(tag_r27);
|
|
683
710
|
} }
|
|
684
711
|
function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_17_For_60_Conditional_22_Template(rf, ctx) { if (rf & 1) {
|
|
685
|
-
i0.ɵɵelementStart(0, "span",
|
|
712
|
+
i0.ɵɵelementStart(0, "span", 204);
|
|
686
713
|
i0.ɵɵtext(1);
|
|
687
714
|
i0.ɵɵelementEnd();
|
|
688
715
|
} if (rf & 2) {
|
|
689
|
-
const
|
|
716
|
+
const dp_r26 = i0.ɵɵnextContext().$implicit;
|
|
690
717
|
i0.ɵɵadvance();
|
|
691
|
-
i0.ɵɵtextInterpolate1("+",
|
|
718
|
+
i0.ɵɵtextInterpolate1("+", dp_r26.tags.length - 2);
|
|
692
719
|
} }
|
|
693
720
|
function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_17_For_60_Template(rf, ctx) { if (rf & 1) {
|
|
694
|
-
const
|
|
695
|
-
i0.ɵɵelementStart(0, "tr",
|
|
696
|
-
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_17_For_60_Template_tr_click_0_listener() { const
|
|
721
|
+
const _r25 = i0.ɵɵgetCurrentView();
|
|
722
|
+
i0.ɵɵelementStart(0, "tr", 198);
|
|
723
|
+
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_17_For_60_Template_tr_click_0_listener() { const dp_r26 = i0.ɵɵrestoreView(_r25).$implicit; const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.openSuiteRun(dp_r26.runId)); });
|
|
697
724
|
i0.ɵɵelementStart(1, "td");
|
|
698
725
|
i0.ɵɵtext(2);
|
|
699
726
|
i0.ɵɵpipe(3, "date");
|
|
700
727
|
i0.ɵɵelementEnd();
|
|
701
|
-
i0.ɵɵelementStart(4, "td")(5, "span",
|
|
728
|
+
i0.ɵɵelementStart(4, "td")(5, "span", 199);
|
|
702
729
|
i0.ɵɵtext(6);
|
|
703
730
|
i0.ɵɵelementEnd()();
|
|
704
|
-
i0.ɵɵelementStart(7, "td")(8, "div",
|
|
705
|
-
i0.ɵɵelement(9, "div",
|
|
731
|
+
i0.ɵɵelementStart(7, "td")(8, "div", 200);
|
|
732
|
+
i0.ɵɵelement(9, "div", 201);
|
|
706
733
|
i0.ɵɵelementStart(10, "span");
|
|
707
734
|
i0.ɵɵtext(11);
|
|
708
735
|
i0.ɵɵelementEnd()()();
|
|
@@ -715,84 +742,84 @@ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Condition
|
|
|
715
742
|
i0.ɵɵelementStart(16, "td");
|
|
716
743
|
i0.ɵɵtext(17);
|
|
717
744
|
i0.ɵɵelementEnd();
|
|
718
|
-
i0.ɵɵelementStart(18, "td")(19, "div",
|
|
719
|
-
i0.ɵɵrepeaterCreate(20, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_17_For_60_For_21_Template, 2, 1, "span",
|
|
720
|
-
i0.ɵɵconditionalCreate(22, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_17_For_60_Conditional_22_Template, 2, 1, "span",
|
|
745
|
+
i0.ɵɵelementStart(18, "td")(19, "div", 202);
|
|
746
|
+
i0.ɵɵrepeaterCreate(20, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_17_For_60_For_21_Template, 2, 1, "span", 203, i0.ɵɵrepeaterTrackByIdentity);
|
|
747
|
+
i0.ɵɵconditionalCreate(22, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_17_For_60_Conditional_22_Template, 2, 1, "span", 204);
|
|
721
748
|
i0.ɵɵelementEnd()()();
|
|
722
749
|
} if (rf & 2) {
|
|
723
|
-
const
|
|
750
|
+
const dp_r26 = ctx.$implicit;
|
|
724
751
|
const ctx_r0 = i0.ɵɵnextContext(4);
|
|
725
752
|
i0.ɵɵadvance(2);
|
|
726
|
-
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(3, 12,
|
|
753
|
+
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(3, 12, dp_r26.date, "short"));
|
|
727
754
|
i0.ɵɵadvance(3);
|
|
728
|
-
i0.ɵɵproperty("ngClass", "status-" +
|
|
755
|
+
i0.ɵɵproperty("ngClass", "status-" + dp_r26.status.toLowerCase());
|
|
729
756
|
i0.ɵɵadvance();
|
|
730
|
-
i0.ɵɵtextInterpolate(
|
|
757
|
+
i0.ɵɵtextInterpolate(dp_r26.status);
|
|
731
758
|
i0.ɵɵadvance(3);
|
|
732
|
-
i0.ɵɵstyleProp("width",
|
|
733
|
-
i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction3(15, _c5,
|
|
759
|
+
i0.ɵɵstyleProp("width", dp_r26.passRate, "%");
|
|
760
|
+
i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction3(15, _c5, dp_r26.passRate >= 80, dp_r26.passRate >= 50 && dp_r26.passRate < 80, dp_r26.passRate < 50));
|
|
734
761
|
i0.ɵɵadvance(2);
|
|
735
|
-
i0.ɵɵtextInterpolate1("",
|
|
762
|
+
i0.ɵɵtextInterpolate1("", dp_r26.passRate.toFixed(0), "%");
|
|
736
763
|
i0.ɵɵadvance(2);
|
|
737
|
-
i0.ɵɵtextInterpolate2("",
|
|
764
|
+
i0.ɵɵtextInterpolate2("", dp_r26.passedTests, "/", dp_r26.totalTests);
|
|
738
765
|
i0.ɵɵadvance(2);
|
|
739
|
-
i0.ɵɵtextInterpolate(ctx_r0.formatDuration(
|
|
766
|
+
i0.ɵɵtextInterpolate(ctx_r0.formatDuration(dp_r26.duration));
|
|
740
767
|
i0.ɵɵadvance(2);
|
|
741
|
-
i0.ɵɵtextInterpolate(ctx_r0.formatCost(
|
|
768
|
+
i0.ɵɵtextInterpolate(ctx_r0.formatCost(dp_r26.cost));
|
|
742
769
|
i0.ɵɵadvance(3);
|
|
743
|
-
i0.ɵɵrepeater(
|
|
770
|
+
i0.ɵɵrepeater(dp_r26.tags.slice(0, 2));
|
|
744
771
|
i0.ɵɵadvance(2);
|
|
745
|
-
i0.ɵɵconditional(
|
|
772
|
+
i0.ɵɵconditional(dp_r26.tags.length > 2 ? 22 : -1);
|
|
746
773
|
} }
|
|
747
774
|
function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_17_Conditional_61_Template(rf, ctx) { if (rf & 1) {
|
|
748
|
-
i0.ɵɵelement(0, "mj-empty-state",
|
|
775
|
+
i0.ɵɵelement(0, "mj-empty-state", 197);
|
|
749
776
|
} }
|
|
750
777
|
function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_17_Template(rf, ctx) { if (rf & 1) {
|
|
751
|
-
i0.ɵɵelementStart(0, "div",
|
|
752
|
-
i0.ɵɵelement(3, "i",
|
|
778
|
+
i0.ɵɵelementStart(0, "div", 180)(1, "div", 181)(2, "div", 182);
|
|
779
|
+
i0.ɵɵelement(3, "i", 183);
|
|
753
780
|
i0.ɵɵelementEnd();
|
|
754
|
-
i0.ɵɵelementStart(4, "div",
|
|
781
|
+
i0.ɵɵelementStart(4, "div", 184)(5, "div", 185);
|
|
755
782
|
i0.ɵɵtext(6);
|
|
756
783
|
i0.ɵɵelementEnd();
|
|
757
|
-
i0.ɵɵelementStart(7, "div",
|
|
784
|
+
i0.ɵɵelementStart(7, "div", 186);
|
|
758
785
|
i0.ɵɵtext(8, "Total Runs");
|
|
759
786
|
i0.ɵɵelementEnd()()();
|
|
760
|
-
i0.ɵɵelementStart(9, "div",
|
|
761
|
-
i0.ɵɵelement(11, "i",
|
|
787
|
+
i0.ɵɵelementStart(9, "div", 181)(10, "div", 187);
|
|
788
|
+
i0.ɵɵelement(11, "i", 148);
|
|
762
789
|
i0.ɵɵelementEnd();
|
|
763
|
-
i0.ɵɵelementStart(12, "div",
|
|
790
|
+
i0.ɵɵelementStart(12, "div", 184)(13, "div", 185);
|
|
764
791
|
i0.ɵɵtext(14);
|
|
765
792
|
i0.ɵɵelementEnd();
|
|
766
|
-
i0.ɵɵelementStart(15, "div",
|
|
793
|
+
i0.ɵɵelementStart(15, "div", 186);
|
|
767
794
|
i0.ɵɵtext(16, "Avg Pass Rate");
|
|
768
795
|
i0.ɵɵelementEnd();
|
|
769
|
-
i0.ɵɵelementStart(17, "div",
|
|
796
|
+
i0.ɵɵelementStart(17, "div", 188);
|
|
770
797
|
i0.ɵɵelement(18, "i", 19);
|
|
771
798
|
i0.ɵɵtext(19);
|
|
772
799
|
i0.ɵɵelementEnd()()();
|
|
773
|
-
i0.ɵɵelementStart(20, "div",
|
|
774
|
-
i0.ɵɵelement(22, "i",
|
|
800
|
+
i0.ɵɵelementStart(20, "div", 181)(21, "div", 189);
|
|
801
|
+
i0.ɵɵelement(22, "i", 152);
|
|
775
802
|
i0.ɵɵelementEnd();
|
|
776
|
-
i0.ɵɵelementStart(23, "div",
|
|
803
|
+
i0.ɵɵelementStart(23, "div", 184)(24, "div", 185);
|
|
777
804
|
i0.ɵɵtext(25);
|
|
778
805
|
i0.ɵɵelementEnd();
|
|
779
|
-
i0.ɵɵelementStart(26, "div",
|
|
806
|
+
i0.ɵɵelementStart(26, "div", 186);
|
|
780
807
|
i0.ɵɵtext(27, "Avg Duration");
|
|
781
808
|
i0.ɵɵelementEnd()()();
|
|
782
|
-
i0.ɵɵelementStart(28, "div",
|
|
783
|
-
i0.ɵɵelement(30, "i",
|
|
809
|
+
i0.ɵɵelementStart(28, "div", 181)(29, "div", 190);
|
|
810
|
+
i0.ɵɵelement(30, "i", 191);
|
|
784
811
|
i0.ɵɵelementEnd();
|
|
785
|
-
i0.ɵɵelementStart(31, "div",
|
|
812
|
+
i0.ɵɵelementStart(31, "div", 184)(32, "div", 185);
|
|
786
813
|
i0.ɵɵtext(33);
|
|
787
814
|
i0.ɵɵelementEnd();
|
|
788
|
-
i0.ɵɵelementStart(34, "div",
|
|
815
|
+
i0.ɵɵelementStart(34, "div", 186);
|
|
789
816
|
i0.ɵɵtext(35, "Total Cost");
|
|
790
817
|
i0.ɵɵelementEnd()()()();
|
|
791
|
-
i0.ɵɵelementStart(36, "div",
|
|
792
|
-
i0.ɵɵelement(38, "i",
|
|
818
|
+
i0.ɵɵelementStart(36, "div", 192)(37, "h3");
|
|
819
|
+
i0.ɵɵelement(38, "i", 193);
|
|
793
820
|
i0.ɵɵtext(39, " Run History");
|
|
794
821
|
i0.ɵɵelementEnd();
|
|
795
|
-
i0.ɵɵelementStart(40, "div",
|
|
822
|
+
i0.ɵɵelementStart(40, "div", 194)(41, "table", 195)(42, "thead")(43, "tr")(44, "th");
|
|
796
823
|
i0.ɵɵtext(45, "Date");
|
|
797
824
|
i0.ɵɵelementEnd();
|
|
798
825
|
i0.ɵɵelementStart(46, "th");
|
|
@@ -814,9 +841,9 @@ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Condition
|
|
|
814
841
|
i0.ɵɵtext(57, "Tags");
|
|
815
842
|
i0.ɵɵelementEnd()()();
|
|
816
843
|
i0.ɵɵelementStart(58, "tbody");
|
|
817
|
-
i0.ɵɵrepeaterCreate(59, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_17_For_60_Template, 23, 19, "tr",
|
|
844
|
+
i0.ɵɵrepeaterCreate(59, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_17_For_60_Template, 23, 19, "tr", 196, i0.ɵɵrepeaterTrackByIdentity);
|
|
818
845
|
i0.ɵɵelementEnd()()();
|
|
819
|
-
i0.ɵɵconditionalCreate(61, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_17_Conditional_61_Template, 1, 0, "mj-empty-state",
|
|
846
|
+
i0.ɵɵconditionalCreate(61, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_17_Conditional_61_Template, 1, 0, "mj-empty-state", 197);
|
|
820
847
|
i0.ɵɵelementEnd();
|
|
821
848
|
} if (rf & 2) {
|
|
822
849
|
const ctx_r0 = i0.ɵɵnextContext(3);
|
|
@@ -840,259 +867,259 @@ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Condition
|
|
|
840
867
|
i0.ɵɵconditional(ctx_r0.getFilteredAnalyticsData().length === 0 ? 61 : -1);
|
|
841
868
|
} }
|
|
842
869
|
function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
843
|
-
i0.ɵɵelementStart(0, "div",
|
|
844
|
-
i0.ɵɵelement(1, "mj-loading",
|
|
870
|
+
i0.ɵɵelementStart(0, "div", 101);
|
|
871
|
+
i0.ɵɵelement(1, "mj-loading", 207);
|
|
845
872
|
i0.ɵɵelementEnd();
|
|
846
873
|
} }
|
|
847
874
|
function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
848
|
-
const
|
|
849
|
-
i0.ɵɵelementStart(0, "button",
|
|
850
|
-
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_Conditional_9_Template_button_click_0_listener() { i0.ɵɵrestoreView(
|
|
851
|
-
i0.ɵɵelement(1, "i",
|
|
875
|
+
const _r29 = i0.ɵɵgetCurrentView();
|
|
876
|
+
i0.ɵɵelementStart(0, "button", 229);
|
|
877
|
+
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_Conditional_9_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r29); const ctx_r0 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r0.clearMatrixFilter()); });
|
|
878
|
+
i0.ɵɵelement(1, "i", 93);
|
|
852
879
|
i0.ɵɵelementEnd();
|
|
853
880
|
} }
|
|
854
881
|
function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_26_Conditional_3_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
855
|
-
i0.ɵɵelementStart(0, "span",
|
|
882
|
+
i0.ɵɵelementStart(0, "span", 235);
|
|
856
883
|
i0.ɵɵtext(1);
|
|
857
884
|
i0.ɵɵelementEnd();
|
|
858
885
|
} if (rf & 2) {
|
|
859
|
-
const
|
|
886
|
+
const tag_r32 = ctx.$implicit;
|
|
860
887
|
i0.ɵɵadvance();
|
|
861
|
-
i0.ɵɵtextInterpolate(
|
|
888
|
+
i0.ɵɵtextInterpolate(tag_r32);
|
|
862
889
|
} }
|
|
863
890
|
function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_26_Conditional_3_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
864
|
-
i0.ɵɵelementStart(0, "span",
|
|
891
|
+
i0.ɵɵelementStart(0, "span", 236);
|
|
865
892
|
i0.ɵɵtext(1);
|
|
866
893
|
i0.ɵɵelementEnd();
|
|
867
894
|
} if (rf & 2) {
|
|
868
|
-
const
|
|
895
|
+
const run_r31 = i0.ɵɵnextContext(2).$implicit;
|
|
869
896
|
i0.ɵɵadvance();
|
|
870
|
-
i0.ɵɵtextInterpolate1("+",
|
|
897
|
+
i0.ɵɵtextInterpolate1("+", run_r31.tags.length - 2);
|
|
871
898
|
} }
|
|
872
899
|
function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_26_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
873
|
-
i0.ɵɵelementStart(0, "div",
|
|
874
|
-
i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_26_Conditional_3_For_2_Template, 2, 1, "span",
|
|
875
|
-
i0.ɵɵconditionalCreate(3, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_26_Conditional_3_Conditional_3_Template, 2, 1, "span",
|
|
900
|
+
i0.ɵɵelementStart(0, "div", 232);
|
|
901
|
+
i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_26_Conditional_3_For_2_Template, 2, 1, "span", 235, i0.ɵɵrepeaterTrackByIdentity);
|
|
902
|
+
i0.ɵɵconditionalCreate(3, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_26_Conditional_3_Conditional_3_Template, 2, 1, "span", 236);
|
|
876
903
|
i0.ɵɵelementEnd();
|
|
877
904
|
} if (rf & 2) {
|
|
878
|
-
const
|
|
905
|
+
const run_r31 = i0.ɵɵnextContext().$implicit;
|
|
879
906
|
i0.ɵɵadvance();
|
|
880
|
-
i0.ɵɵrepeater(
|
|
907
|
+
i0.ɵɵrepeater(run_r31.tags.slice(0, 2));
|
|
881
908
|
i0.ɵɵadvance(2);
|
|
882
|
-
i0.ɵɵconditional(
|
|
909
|
+
i0.ɵɵconditional(run_r31.tags.length > 2 ? 3 : -1);
|
|
883
910
|
} }
|
|
884
911
|
function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_26_Template(rf, ctx) { if (rf & 1) {
|
|
885
|
-
const
|
|
886
|
-
i0.ɵɵelementStart(0, "th",
|
|
912
|
+
const _r30 = i0.ɵɵgetCurrentView();
|
|
913
|
+
i0.ɵɵelementStart(0, "th", 230);
|
|
887
914
|
i0.ɵɵpipe(1, "date");
|
|
888
|
-
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_26_Template_th_click_0_listener() { const
|
|
889
|
-
i0.ɵɵelementStart(2, "div",
|
|
890
|
-
i0.ɵɵconditionalCreate(3, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_26_Conditional_3_Template, 4, 1, "div",
|
|
891
|
-
i0.ɵɵelementStart(4, "div",
|
|
915
|
+
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_26_Template_th_click_0_listener() { const run_r31 = i0.ɵɵrestoreView(_r30).$implicit; const ctx_r0 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r0.openSuiteRun(run_r31.runId)); });
|
|
916
|
+
i0.ɵɵelementStart(2, "div", 231);
|
|
917
|
+
i0.ɵɵconditionalCreate(3, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_26_Conditional_3_Template, 4, 1, "div", 232);
|
|
918
|
+
i0.ɵɵelementStart(4, "div", 233);
|
|
892
919
|
i0.ɵɵtext(5);
|
|
893
920
|
i0.ɵɵelementEnd();
|
|
894
|
-
i0.ɵɵelementStart(6, "div",
|
|
921
|
+
i0.ɵɵelementStart(6, "div", 234);
|
|
895
922
|
i0.ɵɵtext(7);
|
|
896
923
|
i0.ɵɵelementEnd()()();
|
|
897
924
|
} if (rf & 2) {
|
|
898
|
-
const
|
|
925
|
+
const run_r31 = ctx.$implicit;
|
|
899
926
|
const ctx_r0 = i0.ɵɵnextContext(5);
|
|
900
|
-
i0.ɵɵproperty("title", "Click to view suite run - " + i0.ɵɵpipeBind2(1, 5,
|
|
927
|
+
i0.ɵɵproperty("title", "Click to view suite run - " + i0.ɵɵpipeBind2(1, 5, run_r31.date, "medium"));
|
|
901
928
|
i0.ɵɵadvance(3);
|
|
902
|
-
i0.ɵɵconditional(
|
|
929
|
+
i0.ɵɵconditional(run_r31.tags.length > 0 ? 3 : -1);
|
|
903
930
|
i0.ɵɵadvance(2);
|
|
904
|
-
i0.ɵɵtextInterpolate(ctx_r0.getRelativeTime(
|
|
931
|
+
i0.ɵɵtextInterpolate(ctx_r0.getRelativeTime(run_r31.date));
|
|
905
932
|
i0.ɵɵadvance();
|
|
906
|
-
i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction3(8, _c5,
|
|
933
|
+
i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction3(8, _c5, run_r31.passRate >= 80, run_r31.passRate >= 50 && run_r31.passRate < 80, run_r31.passRate < 50));
|
|
907
934
|
i0.ɵɵadvance();
|
|
908
|
-
i0.ɵɵtextInterpolate1(" ",
|
|
935
|
+
i0.ɵɵtextInterpolate1(" ", run_r31.passRate.toFixed(0), "% ");
|
|
909
936
|
} }
|
|
910
937
|
function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Conditional_1_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
911
|
-
i0.ɵɵelementStart(0, "span",
|
|
912
|
-
i0.ɵɵelement(1, "i",
|
|
938
|
+
i0.ɵɵelementStart(0, "span", 250);
|
|
939
|
+
i0.ɵɵelement(1, "i", 135);
|
|
913
940
|
i0.ɵɵelementEnd();
|
|
914
941
|
} if (rf & 2) {
|
|
915
|
-
const
|
|
942
|
+
const result_r37 = i0.ɵɵnextContext();
|
|
916
943
|
const ctx_r0 = i0.ɵɵnextContext(7);
|
|
917
|
-
i0.ɵɵclassProp("cell-skipped-status",
|
|
918
|
-
i0.ɵɵproperty("ngClass", "status-" +
|
|
944
|
+
i0.ɵɵclassProp("cell-skipped-status", result_r37.status === "Skipped" || result_r37.status === "Pending");
|
|
945
|
+
i0.ɵɵproperty("ngClass", "status-" + result_r37.status.toLowerCase())("title", ctx_r0.getStatusTooltip(result_r37.status));
|
|
919
946
|
i0.ɵɵadvance();
|
|
920
|
-
i0.ɵɵclassProp("fa-check",
|
|
947
|
+
i0.ɵɵclassProp("fa-check", result_r37.status === "Passed")("fa-times", result_r37.status === "Failed")("fa-exclamation", result_r37.status === "Error")("fa-hourglass-end", result_r37.status === "Timeout")("fa-forward", result_r37.status === "Skipped")("fa-spinner", result_r37.status === "Running")("fa-clock", result_r37.status === "Pending");
|
|
921
948
|
} }
|
|
922
949
|
function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Conditional_1_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
923
|
-
i0.ɵɵelementStart(0, "span",
|
|
924
|
-
i0.ɵɵelement(1, "i",
|
|
950
|
+
i0.ɵɵelementStart(0, "span", 246);
|
|
951
|
+
i0.ɵɵelement(1, "i", 251);
|
|
925
952
|
i0.ɵɵelementEnd();
|
|
926
953
|
} }
|
|
927
954
|
function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Conditional_1_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
928
|
-
i0.ɵɵelementStart(0, "span",
|
|
929
|
-
i0.ɵɵelement(1, "i",
|
|
930
|
-
i0.ɵɵelementStart(2, "span",
|
|
955
|
+
i0.ɵɵelementStart(0, "span", 252);
|
|
956
|
+
i0.ɵɵelement(1, "i", 150);
|
|
957
|
+
i0.ɵɵelementStart(2, "span", 253);
|
|
931
958
|
i0.ɵɵtext(3);
|
|
932
959
|
i0.ɵɵelementEnd()();
|
|
933
960
|
} if (rf & 2) {
|
|
934
|
-
const
|
|
961
|
+
const result_r37 = i0.ɵɵnextContext();
|
|
935
962
|
const ctx_r0 = i0.ɵɵnextContext(7);
|
|
936
|
-
i0.ɵɵclassProp("rating-low",
|
|
937
|
-
i0.ɵɵproperty("title", ctx_r0.getHumanTooltip(
|
|
963
|
+
i0.ɵɵclassProp("rating-low", result_r37.humanRating <= 4)("rating-medium", result_r37.humanRating >= 5 && result_r37.humanRating <= 6)("rating-good", result_r37.humanRating >= 7 && result_r37.humanRating <= 8)("rating-excellent", result_r37.humanRating >= 9);
|
|
964
|
+
i0.ɵɵproperty("title", ctx_r0.getHumanTooltip(result_r37.humanRating, result_r37.humanComments));
|
|
938
965
|
i0.ɵɵadvance(3);
|
|
939
|
-
i0.ɵɵtextInterpolate(
|
|
966
|
+
i0.ɵɵtextInterpolate(result_r37.humanRating);
|
|
940
967
|
} }
|
|
941
968
|
function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Conditional_1_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
942
|
-
i0.ɵɵelementStart(0, "span",
|
|
943
|
-
i0.ɵɵelement(1, "i",
|
|
944
|
-
i0.ɵɵelementStart(2, "span",
|
|
969
|
+
i0.ɵɵelementStart(0, "span", 254);
|
|
970
|
+
i0.ɵɵelement(1, "i", 154);
|
|
971
|
+
i0.ɵɵelementStart(2, "span", 255);
|
|
945
972
|
i0.ɵɵtext(3);
|
|
946
973
|
i0.ɵɵelementEnd()();
|
|
947
974
|
} if (rf & 2) {
|
|
948
|
-
const
|
|
949
|
-
i0.ɵɵclassProp("score-low",
|
|
950
|
-
i0.ɵɵproperty("title", "Auto Score: " + (
|
|
975
|
+
const result_r37 = i0.ɵɵnextContext();
|
|
976
|
+
i0.ɵɵclassProp("score-low", result_r37.score < 0.5)("score-medium", result_r37.score >= 0.5 && result_r37.score < 0.7)("score-good", result_r37.score >= 0.7 && result_r37.score < 0.85)("score-excellent", result_r37.score >= 0.85);
|
|
977
|
+
i0.ɵɵproperty("title", "Auto Score: " + (result_r37.score * 100).toFixed(0) + "% automated evaluation");
|
|
951
978
|
i0.ɵɵadvance(3);
|
|
952
|
-
i0.ɵɵtextInterpolate((
|
|
979
|
+
i0.ɵɵtextInterpolate((result_r37.score * 100).toFixed(0));
|
|
953
980
|
} }
|
|
954
981
|
function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Conditional_1_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
955
|
-
i0.ɵɵelementStart(0, "span",
|
|
956
|
-
i0.ɵɵelement(1, "i",
|
|
982
|
+
i0.ɵɵelementStart(0, "span", 249);
|
|
983
|
+
i0.ɵɵelement(1, "i", 154);
|
|
957
984
|
i0.ɵɵelementEnd();
|
|
958
985
|
} }
|
|
959
986
|
function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
960
|
-
i0.ɵɵelementStart(0, "div",
|
|
961
|
-
i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Conditional_1_Conditional_1_Template, 2, 18, "span",
|
|
962
|
-
i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Conditional_1_Conditional_2_Template, 2, 0, "span",
|
|
963
|
-
i0.ɵɵconditionalCreate(3, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Conditional_1_Conditional_3_Template, 4, 10, "span",
|
|
964
|
-
i0.ɵɵconditionalCreate(4, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Conditional_1_Conditional_4_Template, 4, 10, "span",
|
|
965
|
-
i0.ɵɵconditionalCreate(5, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Conditional_1_Conditional_5_Template, 2, 0, "span",
|
|
987
|
+
i0.ɵɵelementStart(0, "div", 243);
|
|
988
|
+
i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Conditional_1_Conditional_1_Template, 2, 18, "span", 245);
|
|
989
|
+
i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Conditional_1_Conditional_2_Template, 2, 0, "span", 246);
|
|
990
|
+
i0.ɵɵconditionalCreate(3, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Conditional_1_Conditional_3_Template, 4, 10, "span", 247);
|
|
991
|
+
i0.ɵɵconditionalCreate(4, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Conditional_1_Conditional_4_Template, 4, 10, "span", 248);
|
|
992
|
+
i0.ɵɵconditionalCreate(5, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Conditional_1_Conditional_5_Template, 2, 0, "span", 249);
|
|
966
993
|
i0.ɵɵelementEnd();
|
|
967
994
|
} if (rf & 2) {
|
|
968
|
-
const
|
|
995
|
+
const result_r37 = ctx;
|
|
969
996
|
const ctx_r0 = i0.ɵɵnextContext(7);
|
|
970
997
|
i0.ɵɵadvance();
|
|
971
998
|
i0.ɵɵconditional(ctx_r0.evalPreferences.showExecution ? 1 : -1);
|
|
972
999
|
i0.ɵɵadvance();
|
|
973
|
-
i0.ɵɵconditional(ctx_r0.evalPreferences.showHuman && !
|
|
1000
|
+
i0.ɵɵconditional(ctx_r0.evalPreferences.showHuman && !result_r37.humanRating ? 2 : -1);
|
|
974
1001
|
i0.ɵɵadvance();
|
|
975
|
-
i0.ɵɵconditional(ctx_r0.evalPreferences.showHuman &&
|
|
1002
|
+
i0.ɵɵconditional(ctx_r0.evalPreferences.showHuman && result_r37.humanRating ? 3 : -1);
|
|
976
1003
|
i0.ɵɵadvance();
|
|
977
|
-
i0.ɵɵconditional(ctx_r0.evalPreferences.showAuto &&
|
|
1004
|
+
i0.ɵɵconditional(ctx_r0.evalPreferences.showAuto && result_r37.score != null ? 4 : -1);
|
|
978
1005
|
i0.ɵɵadvance();
|
|
979
|
-
i0.ɵɵconditional(ctx_r0.evalPreferences.showAuto &&
|
|
1006
|
+
i0.ɵɵconditional(ctx_r0.evalPreferences.showAuto && result_r37.score == null ? 5 : -1);
|
|
980
1007
|
} }
|
|
981
1008
|
function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
982
|
-
i0.ɵɵelementStart(0, "span",
|
|
983
|
-
i0.ɵɵelement(1, "i",
|
|
1009
|
+
i0.ɵɵelementStart(0, "span", 244);
|
|
1010
|
+
i0.ɵɵelement(1, "i", 256);
|
|
984
1011
|
i0.ɵɵelementEnd();
|
|
985
1012
|
} }
|
|
986
1013
|
function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Template(rf, ctx) { if (rf & 1) {
|
|
987
|
-
const
|
|
988
|
-
i0.ɵɵelementStart(0, "td",
|
|
989
|
-
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Template_td_click_0_listener($event) { const
|
|
990
|
-
i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Conditional_1_Template, 6, 5, "div",
|
|
991
|
-
i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Conditional_2_Template, 2, 0, "span",
|
|
1014
|
+
const _r35 = i0.ɵɵgetCurrentView();
|
|
1015
|
+
i0.ɵɵelementStart(0, "td", 242);
|
|
1016
|
+
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Template_td_click_0_listener($event) { const run_r36 = i0.ɵɵrestoreView(_r35).$implicit; const test_r34 = i0.ɵɵnextContext().$implicit; const ctx_r0 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r0.onMatrixCellClick(ctx_r0.getTestResultForRun(run_r36.runId, test_r34.testId), $event)); });
|
|
1017
|
+
i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Conditional_1_Template, 6, 5, "div", 243);
|
|
1018
|
+
i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Conditional_2_Template, 2, 0, "span", 244);
|
|
992
1019
|
i0.ɵɵelementEnd();
|
|
993
1020
|
} if (rf & 2) {
|
|
994
1021
|
let tmp_27_0;
|
|
995
1022
|
let tmp_28_0;
|
|
996
|
-
const
|
|
997
|
-
const
|
|
1023
|
+
const run_r36 = ctx.$implicit;
|
|
1024
|
+
const test_r34 = i0.ɵɵnextContext().$implicit;
|
|
998
1025
|
const ctx_r0 = i0.ɵɵnextContext(5);
|
|
999
|
-
i0.ɵɵclassProp("clickable", ctx_r0.getTestResultForRun(
|
|
1000
|
-
i0.ɵɵproperty("ngClass", ctx_r0.getMatrixCellClass(ctx_r0.getTestResultForRun(
|
|
1026
|
+
i0.ɵɵclassProp("clickable", ctx_r0.getTestResultForRun(run_r36.runId, test_r34.testId))("cell-not-run", !ctx_r0.getTestResultForRun(run_r36.runId, test_r34.testId));
|
|
1027
|
+
i0.ɵɵproperty("ngClass", ctx_r0.getMatrixCellClass(ctx_r0.getTestResultForRun(run_r36.runId, test_r34.testId)))("title", ((tmp_27_0 = ctx_r0.getTestResultForRun(run_r36.runId, test_r34.testId)) == null ? null : tmp_27_0.status) + " - Click to view test run" || "Not Run");
|
|
1001
1028
|
i0.ɵɵadvance();
|
|
1002
|
-
i0.ɵɵconditional((tmp_28_0 = ctx_r0.getTestResultForRun(
|
|
1029
|
+
i0.ɵɵconditional((tmp_28_0 = ctx_r0.getTestResultForRun(run_r36.runId, test_r34.testId)) ? 1 : -1, tmp_28_0);
|
|
1003
1030
|
i0.ɵɵadvance();
|
|
1004
|
-
i0.ɵɵconditional(!ctx_r0.getTestResultForRun(
|
|
1031
|
+
i0.ɵɵconditional(!ctx_r0.getTestResultForRun(run_r36.runId, test_r34.testId) ? 2 : -1);
|
|
1005
1032
|
} }
|
|
1006
1033
|
function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_Template(rf, ctx) { if (rf & 1) {
|
|
1007
|
-
const
|
|
1008
|
-
i0.ɵɵelementStart(0, "tr",
|
|
1009
|
-
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_Template_tr_click_0_listener() { const
|
|
1010
|
-
i0.ɵɵelementStart(1, "td",
|
|
1034
|
+
const _r33 = i0.ɵɵgetCurrentView();
|
|
1035
|
+
i0.ɵɵelementStart(0, "tr", 237);
|
|
1036
|
+
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_Template_tr_click_0_listener() { const test_r34 = i0.ɵɵrestoreView(_r33).$implicit; const ctx_r0 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r0.selectMatrixRow(test_r34.testId)); });
|
|
1037
|
+
i0.ɵɵelementStart(1, "td", 238);
|
|
1011
1038
|
i0.ɵɵtext(2);
|
|
1012
1039
|
i0.ɵɵelementEnd();
|
|
1013
|
-
i0.ɵɵelementStart(3, "td",
|
|
1040
|
+
i0.ɵɵelementStart(3, "td", 239)(4, "span", 240);
|
|
1014
1041
|
i0.ɵɵtext(5);
|
|
1015
1042
|
i0.ɵɵelementEnd()();
|
|
1016
|
-
i0.ɵɵrepeaterCreate(6, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Template, 3, 8, "td",
|
|
1017
|
-
i0.ɵɵelement(8, "td",
|
|
1043
|
+
i0.ɵɵrepeaterCreate(6, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Template, 3, 8, "td", 241, i0.ɵɵrepeaterTrackByIdentity);
|
|
1044
|
+
i0.ɵɵelement(8, "td", 228);
|
|
1018
1045
|
i0.ɵɵelementEnd();
|
|
1019
1046
|
} if (rf & 2) {
|
|
1020
|
-
const
|
|
1047
|
+
const test_r34 = ctx.$implicit;
|
|
1021
1048
|
const ctx_r0 = i0.ɵɵnextContext(5);
|
|
1022
|
-
i0.ɵɵclassProp("row-selected", ctx_r0.selectedMatrixTestId ===
|
|
1049
|
+
i0.ɵɵclassProp("row-selected", ctx_r0.selectedMatrixTestId === test_r34.testId);
|
|
1023
1050
|
i0.ɵɵadvance(2);
|
|
1024
|
-
i0.ɵɵtextInterpolate(
|
|
1051
|
+
i0.ɵɵtextInterpolate(test_r34.sequence);
|
|
1025
1052
|
i0.ɵɵadvance(2);
|
|
1026
|
-
i0.ɵɵproperty("title",
|
|
1053
|
+
i0.ɵɵproperty("title", test_r34.testName);
|
|
1027
1054
|
i0.ɵɵadvance();
|
|
1028
|
-
i0.ɵɵtextInterpolate(
|
|
1055
|
+
i0.ɵɵtextInterpolate(test_r34.testName);
|
|
1029
1056
|
i0.ɵɵadvance();
|
|
1030
1057
|
i0.ɵɵrepeater(ctx_r0.matrixData);
|
|
1031
1058
|
} }
|
|
1032
1059
|
function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_38_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
1033
|
-
i0.ɵɵelementStart(0, "span",
|
|
1060
|
+
i0.ɵɵelementStart(0, "span", 258)(1, "span", 261);
|
|
1034
1061
|
i0.ɵɵtext(2);
|
|
1035
1062
|
i0.ɵɵelementEnd()();
|
|
1036
1063
|
} if (rf & 2) {
|
|
1037
|
-
const
|
|
1064
|
+
const run_r38 = i0.ɵɵnextContext().$implicit;
|
|
1038
1065
|
const ctx_r0 = i0.ɵɵnextContext(5);
|
|
1039
1066
|
i0.ɵɵadvance(2);
|
|
1040
|
-
i0.ɵɵtextInterpolate2("", ctx_r0.getRunPassedCount(
|
|
1067
|
+
i0.ɵɵtextInterpolate2("", ctx_r0.getRunPassedCount(run_r38), "/", ctx_r0.getRunTotalCount(run_r38));
|
|
1041
1068
|
} }
|
|
1042
1069
|
function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_38_Conditional_3_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
1043
|
-
i0.ɵɵelementStart(0, "span",
|
|
1070
|
+
i0.ɵɵelementStart(0, "span", 262);
|
|
1044
1071
|
i0.ɵɵtext(1);
|
|
1045
1072
|
i0.ɵɵelementEnd();
|
|
1046
1073
|
} if (rf & 2) {
|
|
1047
1074
|
let tmp_16_0;
|
|
1048
|
-
const
|
|
1075
|
+
const run_r38 = i0.ɵɵnextContext(2).$implicit;
|
|
1049
1076
|
const ctx_r0 = i0.ɵɵnextContext(5);
|
|
1050
1077
|
i0.ɵɵadvance();
|
|
1051
|
-
i0.ɵɵtextInterpolate((tmp_16_0 = ctx_r0.getRunHumanAvg(
|
|
1078
|
+
i0.ɵɵtextInterpolate((tmp_16_0 = ctx_r0.getRunHumanAvg(run_r38)) == null ? null : tmp_16_0.toFixed(1));
|
|
1052
1079
|
} }
|
|
1053
1080
|
function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_38_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
1054
|
-
i0.ɵɵelementStart(0, "span",
|
|
1055
|
-
i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_38_Conditional_3_Conditional_1_Template, 2, 1, "span",
|
|
1056
|
-
i0.ɵɵelementStart(2, "span",
|
|
1081
|
+
i0.ɵɵelementStart(0, "span", 259);
|
|
1082
|
+
i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_38_Conditional_3_Conditional_1_Template, 2, 1, "span", 262);
|
|
1083
|
+
i0.ɵɵelementStart(2, "span", 263);
|
|
1057
1084
|
i0.ɵɵtext(3);
|
|
1058
1085
|
i0.ɵɵelementEnd()();
|
|
1059
1086
|
} if (rf & 2) {
|
|
1060
|
-
const
|
|
1087
|
+
const run_r38 = i0.ɵɵnextContext().$implicit;
|
|
1061
1088
|
const ctx_r0 = i0.ɵɵnextContext(5);
|
|
1062
1089
|
i0.ɵɵadvance();
|
|
1063
|
-
i0.ɵɵconditional(ctx_r0.getRunHumanAvg(
|
|
1090
|
+
i0.ɵɵconditional(ctx_r0.getRunHumanAvg(run_r38) != null ? 1 : -1);
|
|
1064
1091
|
i0.ɵɵadvance(2);
|
|
1065
|
-
i0.ɵɵtextInterpolate1("(", ctx_r0.getRunHumanCount(
|
|
1092
|
+
i0.ɵɵtextInterpolate1("(", ctx_r0.getRunHumanCount(run_r38), ")");
|
|
1066
1093
|
} }
|
|
1067
1094
|
function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_38_Conditional_4_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
1068
|
-
i0.ɵɵelementStart(0, "span",
|
|
1095
|
+
i0.ɵɵelementStart(0, "span", 262);
|
|
1069
1096
|
i0.ɵɵtext(1);
|
|
1070
1097
|
i0.ɵɵelementEnd();
|
|
1071
1098
|
} if (rf & 2) {
|
|
1072
|
-
const
|
|
1099
|
+
const run_r38 = i0.ɵɵnextContext(2).$implicit;
|
|
1073
1100
|
const ctx_r0 = i0.ɵɵnextContext(5);
|
|
1074
1101
|
i0.ɵɵadvance();
|
|
1075
|
-
i0.ɵɵtextInterpolate1("", (ctx_r0.getRunAutoAvg(
|
|
1102
|
+
i0.ɵɵtextInterpolate1("", (ctx_r0.getRunAutoAvg(run_r38) * 100).toFixed(0), "%");
|
|
1076
1103
|
} }
|
|
1077
1104
|
function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_38_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
1078
|
-
i0.ɵɵelementStart(0, "span",
|
|
1079
|
-
i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_38_Conditional_4_Conditional_1_Template, 2, 1, "span",
|
|
1080
|
-
i0.ɵɵelementStart(2, "span",
|
|
1105
|
+
i0.ɵɵelementStart(0, "span", 260);
|
|
1106
|
+
i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_38_Conditional_4_Conditional_1_Template, 2, 1, "span", 262);
|
|
1107
|
+
i0.ɵɵelementStart(2, "span", 263);
|
|
1081
1108
|
i0.ɵɵtext(3);
|
|
1082
1109
|
i0.ɵɵelementEnd()();
|
|
1083
1110
|
} if (rf & 2) {
|
|
1084
|
-
const
|
|
1111
|
+
const run_r38 = i0.ɵɵnextContext().$implicit;
|
|
1085
1112
|
const ctx_r0 = i0.ɵɵnextContext(5);
|
|
1086
1113
|
i0.ɵɵadvance();
|
|
1087
|
-
i0.ɵɵconditional(ctx_r0.getRunAutoAvg(
|
|
1114
|
+
i0.ɵɵconditional(ctx_r0.getRunAutoAvg(run_r38) != null ? 1 : -1);
|
|
1088
1115
|
i0.ɵɵadvance(2);
|
|
1089
|
-
i0.ɵɵtextInterpolate1("(", ctx_r0.getRunAutoCount(
|
|
1116
|
+
i0.ɵɵtextInterpolate1("(", ctx_r0.getRunAutoCount(run_r38), ")");
|
|
1090
1117
|
} }
|
|
1091
1118
|
function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_38_Template(rf, ctx) { if (rf & 1) {
|
|
1092
|
-
i0.ɵɵelementStart(0, "td",
|
|
1093
|
-
i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_38_Conditional_2_Template, 3, 2, "span",
|
|
1094
|
-
i0.ɵɵconditionalCreate(3, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_38_Conditional_3_Template, 4, 2, "span",
|
|
1095
|
-
i0.ɵɵconditionalCreate(4, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_38_Conditional_4_Template, 4, 2, "span",
|
|
1119
|
+
i0.ɵɵelementStart(0, "td", 227)(1, "div", 257);
|
|
1120
|
+
i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_38_Conditional_2_Template, 3, 2, "span", 258);
|
|
1121
|
+
i0.ɵɵconditionalCreate(3, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_38_Conditional_3_Template, 4, 2, "span", 259);
|
|
1122
|
+
i0.ɵɵconditionalCreate(4, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_38_Conditional_4_Template, 4, 2, "span", 260);
|
|
1096
1123
|
i0.ɵɵelementEnd()();
|
|
1097
1124
|
} if (rf & 2) {
|
|
1098
1125
|
const ctx_r0 = i0.ɵɵnextContext(5);
|
|
@@ -1104,49 +1131,49 @@ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Condition
|
|
|
1104
1131
|
i0.ɵɵconditional(ctx_r0.evalPreferences.showAuto ? 4 : -1);
|
|
1105
1132
|
} }
|
|
1106
1133
|
function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
1107
|
-
const
|
|
1108
|
-
i0.ɵɵelementStart(0, "div",
|
|
1109
|
-
i0.ɵɵelement(3, "i",
|
|
1134
|
+
const _r28 = i0.ɵɵgetCurrentView();
|
|
1135
|
+
i0.ɵɵelementStart(0, "div", 205)(1, "div", 208)(2, "h3");
|
|
1136
|
+
i0.ɵɵelement(3, "i", 163);
|
|
1110
1137
|
i0.ɵɵtext(4, " Test Results Matrix");
|
|
1111
1138
|
i0.ɵɵelementEnd();
|
|
1112
|
-
i0.ɵɵelementStart(5, "div",
|
|
1113
|
-
i0.ɵɵelement(7, "i",
|
|
1114
|
-
i0.ɵɵelementStart(8, "input",
|
|
1115
|
-
i0.ɵɵlistener("input", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_Template_input_input_8_listener($event) { i0.ɵɵrestoreView(
|
|
1139
|
+
i0.ɵɵelementStart(5, "div", 209)(6, "div", 210);
|
|
1140
|
+
i0.ɵɵelement(7, "i", 211);
|
|
1141
|
+
i0.ɵɵelementStart(8, "input", 212);
|
|
1142
|
+
i0.ɵɵlistener("input", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_Template_input_input_8_listener($event) { i0.ɵɵrestoreView(_r28); const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.onMatrixFilterInput($event)); });
|
|
1116
1143
|
i0.ɵɵelementEnd();
|
|
1117
|
-
i0.ɵɵconditionalCreate(9, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_Conditional_9_Template, 2, 0, "button",
|
|
1144
|
+
i0.ɵɵconditionalCreate(9, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_Conditional_9_Template, 2, 0, "button", 213);
|
|
1118
1145
|
i0.ɵɵelementEnd();
|
|
1119
|
-
i0.ɵɵelementStart(10, "span",
|
|
1146
|
+
i0.ɵɵelementStart(10, "span", 214);
|
|
1120
1147
|
i0.ɵɵtext(11);
|
|
1121
1148
|
i0.ɵɵelementEnd();
|
|
1122
|
-
i0.ɵɵelementStart(12, "button",
|
|
1123
|
-
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_Template_button_click_12_listener() { i0.ɵɵrestoreView(
|
|
1124
|
-
i0.ɵɵelement(13, "i",
|
|
1149
|
+
i0.ɵɵelementStart(12, "button", 215);
|
|
1150
|
+
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_Template_button_click_12_listener() { i0.ɵɵrestoreView(_r28); const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.exportMatrixToCSV()); });
|
|
1151
|
+
i0.ɵɵelement(13, "i", 216);
|
|
1125
1152
|
i0.ɵɵtext(14, " Export ");
|
|
1126
1153
|
i0.ɵɵelementEnd()()();
|
|
1127
|
-
i0.ɵɵelementStart(15, "div",
|
|
1128
|
-
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_Template_th_click_19_listener() { i0.ɵɵrestoreView(
|
|
1154
|
+
i0.ɵɵelementStart(15, "div", 217)(16, "table", 218)(17, "thead")(18, "tr")(19, "th", 219);
|
|
1155
|
+
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_Template_th_click_19_listener() { i0.ɵɵrestoreView(_r28); const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.toggleMatrixSort("sequence")); });
|
|
1129
1156
|
i0.ɵɵtext(20, " # ");
|
|
1130
1157
|
i0.ɵɵelement(21, "i", 19);
|
|
1131
1158
|
i0.ɵɵelementEnd();
|
|
1132
|
-
i0.ɵɵelementStart(22, "th",
|
|
1133
|
-
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_Template_th_click_22_listener() { i0.ɵɵrestoreView(
|
|
1159
|
+
i0.ɵɵelementStart(22, "th", 220);
|
|
1160
|
+
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_Template_th_click_22_listener() { i0.ɵɵrestoreView(_r28); const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.toggleMatrixSort("name")); });
|
|
1134
1161
|
i0.ɵɵtext(23, " Test ");
|
|
1135
1162
|
i0.ɵɵelement(24, "i", 19);
|
|
1136
1163
|
i0.ɵɵelementEnd();
|
|
1137
|
-
i0.ɵɵrepeaterCreate(25, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_26_Template, 8, 12, "th",
|
|
1138
|
-
i0.ɵɵelement(27, "th",
|
|
1164
|
+
i0.ɵɵrepeaterCreate(25, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_26_Template, 8, 12, "th", 221, i0.ɵɵrepeaterTrackByIdentity);
|
|
1165
|
+
i0.ɵɵelement(27, "th", 222);
|
|
1139
1166
|
i0.ɵɵelementEnd()();
|
|
1140
1167
|
i0.ɵɵelementStart(28, "tbody");
|
|
1141
|
-
i0.ɵɵrepeaterCreate(29, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_Template, 9, 5, "tr",
|
|
1168
|
+
i0.ɵɵrepeaterCreate(29, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_Template, 9, 5, "tr", 223, i0.ɵɵrepeaterTrackByIdentity);
|
|
1142
1169
|
i0.ɵɵelementEnd();
|
|
1143
|
-
i0.ɵɵelementStart(31, "tfoot")(32, "tr",
|
|
1144
|
-
i0.ɵɵelement(33, "td",
|
|
1145
|
-
i0.ɵɵelementStart(34, "td",
|
|
1170
|
+
i0.ɵɵelementStart(31, "tfoot")(32, "tr", 224);
|
|
1171
|
+
i0.ɵɵelement(33, "td", 225);
|
|
1172
|
+
i0.ɵɵelementStart(34, "td", 226)(35, "strong");
|
|
1146
1173
|
i0.ɵɵtext(36, "Totals");
|
|
1147
1174
|
i0.ɵɵelementEnd()();
|
|
1148
|
-
i0.ɵɵrepeaterCreate(37, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_38_Template, 5, 3, "td",
|
|
1149
|
-
i0.ɵɵelement(39, "td",
|
|
1175
|
+
i0.ɵɵrepeaterCreate(37, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_38_Template, 5, 3, "td", 227, i0.ɵɵrepeaterTrackByIdentity);
|
|
1176
|
+
i0.ɵɵelement(39, "td", 228);
|
|
1150
1177
|
i0.ɵɵelementEnd()()()()();
|
|
1151
1178
|
} if (rf & 2) {
|
|
1152
1179
|
const ctx_r0 = i0.ɵɵnextContext(4);
|
|
@@ -1170,12 +1197,12 @@ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Condition
|
|
|
1170
1197
|
i0.ɵɵrepeater(ctx_r0.matrixData);
|
|
1171
1198
|
} }
|
|
1172
1199
|
function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
1173
|
-
i0.ɵɵelement(0, "mj-empty-state",
|
|
1200
|
+
i0.ɵɵelement(0, "mj-empty-state", 206);
|
|
1174
1201
|
} }
|
|
1175
1202
|
function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Template(rf, ctx) { if (rf & 1) {
|
|
1176
|
-
i0.ɵɵconditionalCreate(0, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_0_Template, 2, 0, "div",
|
|
1177
|
-
i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_Template, 40, 7, "div",
|
|
1178
|
-
i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_2_Template, 1, 0, "mj-empty-state",
|
|
1203
|
+
i0.ɵɵconditionalCreate(0, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_0_Template, 2, 0, "div", 101);
|
|
1204
|
+
i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_Template, 40, 7, "div", 205);
|
|
1205
|
+
i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_2_Template, 1, 0, "mj-empty-state", 206);
|
|
1179
1206
|
} if (rf & 2) {
|
|
1180
1207
|
const ctx_r0 = i0.ɵɵnextContext(3);
|
|
1181
1208
|
i0.ɵɵconditional(ctx_r0.loadingMatrix ? 0 : -1);
|
|
@@ -1185,36 +1212,36 @@ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Condition
|
|
|
1185
1212
|
i0.ɵɵconditional(!ctx_r0.loadingMatrix && ctx_r0.matrixLoaded && ctx_r0.matrixData.length === 0 ? 2 : -1);
|
|
1186
1213
|
} }
|
|
1187
1214
|
function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_19_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
1188
|
-
i0.ɵɵelementStart(0, "div",
|
|
1189
|
-
i0.ɵɵelement(1, "mj-loading",
|
|
1215
|
+
i0.ɵɵelementStart(0, "div", 101);
|
|
1216
|
+
i0.ɵɵelement(1, "mj-loading", 266);
|
|
1190
1217
|
i0.ɵɵelementEnd();
|
|
1191
1218
|
} }
|
|
1192
1219
|
function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_19_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
1193
|
-
i0.ɵɵelementStart(0, "div",
|
|
1194
|
-
i0.ɵɵelement(3, "i",
|
|
1220
|
+
i0.ɵɵelementStart(0, "div", 264)(1, "div", 267)(2, "h3");
|
|
1221
|
+
i0.ɵɵelement(3, "i", 164);
|
|
1195
1222
|
i0.ɵɵtext(4, " Test Results Flow");
|
|
1196
1223
|
i0.ɵɵelementEnd();
|
|
1197
|
-
i0.ɵɵelementStart(5, "div",
|
|
1198
|
-
i0.ɵɵelement(7, "i",
|
|
1224
|
+
i0.ɵɵelementStart(5, "div", 268)(6, "span", 269);
|
|
1225
|
+
i0.ɵɵelement(7, "i", 179);
|
|
1199
1226
|
i0.ɵɵtext(8, " Passed");
|
|
1200
1227
|
i0.ɵɵelementEnd();
|
|
1201
|
-
i0.ɵɵelementStart(9, "span",
|
|
1202
|
-
i0.ɵɵelement(10, "i",
|
|
1228
|
+
i0.ɵɵelementStart(9, "span", 270);
|
|
1229
|
+
i0.ɵɵelement(10, "i", 93);
|
|
1203
1230
|
i0.ɵɵtext(11, " Failed");
|
|
1204
1231
|
i0.ɵɵelementEnd();
|
|
1205
|
-
i0.ɵɵelementStart(12, "span",
|
|
1206
|
-
i0.ɵɵelement(13, "i",
|
|
1232
|
+
i0.ɵɵelementStart(12, "span", 271);
|
|
1233
|
+
i0.ɵɵelement(13, "i", 272);
|
|
1207
1234
|
i0.ɵɵtext(14, " Error");
|
|
1208
1235
|
i0.ɵɵelementEnd();
|
|
1209
|
-
i0.ɵɵelementStart(15, "span",
|
|
1210
|
-
i0.ɵɵelement(16, "i",
|
|
1236
|
+
i0.ɵɵelementStart(15, "span", 273);
|
|
1237
|
+
i0.ɵɵelement(16, "i", 274);
|
|
1211
1238
|
i0.ɵɵtext(17, " Skipped");
|
|
1212
1239
|
i0.ɵɵelementEnd()()();
|
|
1213
|
-
i0.ɵɵelementStart(18, "div",
|
|
1214
|
-
i0.ɵɵelement(19, "div",
|
|
1240
|
+
i0.ɵɵelementStart(18, "div", 275);
|
|
1241
|
+
i0.ɵɵelement(19, "div", 276, 1);
|
|
1215
1242
|
i0.ɵɵelementEnd();
|
|
1216
|
-
i0.ɵɵelementStart(21, "div",
|
|
1217
|
-
i0.ɵɵelement(22, "i",
|
|
1243
|
+
i0.ɵɵelementStart(21, "div", 277);
|
|
1244
|
+
i0.ɵɵelement(22, "i", 121);
|
|
1218
1245
|
i0.ɵɵtext(23);
|
|
1219
1246
|
i0.ɵɵelementEnd()();
|
|
1220
1247
|
} if (rf & 2) {
|
|
@@ -1223,12 +1250,12 @@ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Condition
|
|
|
1223
1250
|
i0.ɵɵtextInterpolate1(" Interactive visualization showing test results across ", ctx_r0.matrixData.length, " runs. Hover over elements for details, click nodes to navigate. ");
|
|
1224
1251
|
} }
|
|
1225
1252
|
function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_19_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
1226
|
-
i0.ɵɵelement(0, "mj-empty-state",
|
|
1253
|
+
i0.ɵɵelement(0, "mj-empty-state", 265);
|
|
1227
1254
|
} }
|
|
1228
1255
|
function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_19_Template(rf, ctx) { if (rf & 1) {
|
|
1229
|
-
i0.ɵɵconditionalCreate(0, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_19_Conditional_0_Template, 2, 0, "div",
|
|
1230
|
-
i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_19_Conditional_1_Template, 24, 1, "div",
|
|
1231
|
-
i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_19_Conditional_2_Template, 1, 0, "mj-empty-state",
|
|
1256
|
+
i0.ɵɵconditionalCreate(0, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_19_Conditional_0_Template, 2, 0, "div", 101);
|
|
1257
|
+
i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_19_Conditional_1_Template, 24, 1, "div", 264);
|
|
1258
|
+
i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_19_Conditional_2_Template, 1, 0, "mj-empty-state", 265);
|
|
1232
1259
|
} if (rf & 2) {
|
|
1233
1260
|
const ctx_r0 = i0.ɵɵnextContext(3);
|
|
1234
1261
|
i0.ɵɵconditional(ctx_r0.loadingMatrix ? 0 : -1);
|
|
@@ -1238,28 +1265,28 @@ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Condition
|
|
|
1238
1265
|
i0.ɵɵconditional(!ctx_r0.loadingMatrix && ctx_r0.matrixLoaded && ctx_r0.matrixData.length === 0 ? 2 : -1);
|
|
1239
1266
|
} }
|
|
1240
1267
|
function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
1241
|
-
const
|
|
1242
|
-
i0.ɵɵelementStart(0, "div",
|
|
1243
|
-
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Template_button_click_2_listener() { i0.ɵɵrestoreView(
|
|
1244
|
-
i0.ɵɵelement(3, "i",
|
|
1268
|
+
const _r20 = i0.ɵɵgetCurrentView();
|
|
1269
|
+
i0.ɵɵelementStart(0, "div", 159)(1, "div", 160)(2, "button", 161);
|
|
1270
|
+
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Template_button_click_2_listener() { i0.ɵɵrestoreView(_r20); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.setAnalyticsView("summary")); });
|
|
1271
|
+
i0.ɵɵelement(3, "i", 162);
|
|
1245
1272
|
i0.ɵɵelementStart(4, "span");
|
|
1246
1273
|
i0.ɵɵtext(5, "Summary");
|
|
1247
1274
|
i0.ɵɵelementEnd()();
|
|
1248
|
-
i0.ɵɵelementStart(6, "button",
|
|
1249
|
-
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Template_button_click_6_listener() { i0.ɵɵrestoreView(
|
|
1250
|
-
i0.ɵɵelement(7, "i",
|
|
1275
|
+
i0.ɵɵelementStart(6, "button", 161);
|
|
1276
|
+
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r20); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.setAnalyticsView("matrix")); });
|
|
1277
|
+
i0.ɵɵelement(7, "i", 163);
|
|
1251
1278
|
i0.ɵɵelementStart(8, "span");
|
|
1252
1279
|
i0.ɵɵtext(9, "Matrix");
|
|
1253
1280
|
i0.ɵɵelementEnd()();
|
|
1254
|
-
i0.ɵɵelementStart(10, "button",
|
|
1255
|
-
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Template_button_click_10_listener() { i0.ɵɵrestoreView(
|
|
1256
|
-
i0.ɵɵelement(11, "i",
|
|
1281
|
+
i0.ɵɵelementStart(10, "button", 161);
|
|
1282
|
+
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Template_button_click_10_listener() { i0.ɵɵrestoreView(_r20); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.setAnalyticsView("chart")); });
|
|
1283
|
+
i0.ɵɵelement(11, "i", 164);
|
|
1257
1284
|
i0.ɵɵelementStart(12, "span");
|
|
1258
1285
|
i0.ɵɵtext(13, "Chart");
|
|
1259
1286
|
i0.ɵɵelementEnd()()()();
|
|
1260
|
-
i0.ɵɵelementStart(14, "mj-accordion-panel",
|
|
1261
|
-
i0.ɵɵlistener("ExpandedChange", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Template_mj_accordion_panel_ExpandedChange_14_listener($event) { i0.ɵɵrestoreView(
|
|
1262
|
-
i0.ɵɵtemplate(15, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_15_Template, 3, 1, "ng-template",
|
|
1287
|
+
i0.ɵɵelementStart(14, "mj-accordion-panel", 165);
|
|
1288
|
+
i0.ɵɵlistener("ExpandedChange", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Template_mj_accordion_panel_ExpandedChange_14_listener($event) { i0.ɵɵrestoreView(_r20); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.onFiltersExpandedChange($event)); });
|
|
1289
|
+
i0.ɵɵtemplate(15, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_15_Template, 3, 1, "ng-template", 166)(16, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Template, 14, 9, "ng-template", 167);
|
|
1263
1290
|
i0.ɵɵelementEnd();
|
|
1264
1291
|
i0.ɵɵconditionalCreate(17, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_17_Template, 62, 15);
|
|
1265
1292
|
i0.ɵɵconditionalCreate(18, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Template, 3, 3);
|
|
@@ -1282,16 +1309,16 @@ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Template(
|
|
|
1282
1309
|
i0.ɵɵconditional(ctx_r0.analyticsView === "chart" ? 19 : -1);
|
|
1283
1310
|
} }
|
|
1284
1311
|
function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
1285
|
-
const
|
|
1286
|
-
i0.ɵɵelementStart(0, "mj-empty-state",
|
|
1287
|
-
i0.ɵɵlistener("Action", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_3_Template_mj_empty_state_Action_0_listener() { i0.ɵɵrestoreView(
|
|
1312
|
+
const _r39 = i0.ɵɵgetCurrentView();
|
|
1313
|
+
i0.ɵɵelementStart(0, "mj-empty-state", 278);
|
|
1314
|
+
i0.ɵɵlistener("Action", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_3_Template_mj_empty_state_Action_0_listener() { i0.ɵɵrestoreView(_r39); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.runSuite()); });
|
|
1288
1315
|
i0.ɵɵelementEnd();
|
|
1289
1316
|
} }
|
|
1290
1317
|
function MJTestSuiteFormComponentExtended_Conditional_63_Template(rf, ctx) { if (rf & 1) {
|
|
1291
1318
|
i0.ɵɵelementStart(0, "div", 42);
|
|
1292
|
-
i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_1_Template, 2, 0, "div",
|
|
1319
|
+
i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_1_Template, 2, 0, "div", 101);
|
|
1293
1320
|
i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Template, 20, 11);
|
|
1294
|
-
i0.ɵɵconditionalCreate(3, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_3_Template, 1, 0, "mj-empty-state",
|
|
1321
|
+
i0.ɵɵconditionalCreate(3, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_3_Template, 1, 0, "mj-empty-state", 157);
|
|
1295
1322
|
i0.ɵɵelementEnd();
|
|
1296
1323
|
} if (rf & 2) {
|
|
1297
1324
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
@@ -1303,54 +1330,54 @@ function MJTestSuiteFormComponentExtended_Conditional_63_Template(rf, ctx) { if
|
|
|
1303
1330
|
i0.ɵɵconditional(!ctx_r0.loadingAnalytics && ctx_r0.analyticsLoaded && ctx_r0.analyticsData.length === 0 ? 3 : -1);
|
|
1304
1331
|
} }
|
|
1305
1332
|
function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_5_For_2_Conditional_8_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
1306
|
-
i0.ɵɵelementStart(0, "span",
|
|
1333
|
+
i0.ɵɵelementStart(0, "span", 295);
|
|
1307
1334
|
i0.ɵɵtext(1);
|
|
1308
1335
|
i0.ɵɵelementEnd();
|
|
1309
1336
|
} if (rf & 2) {
|
|
1310
|
-
const
|
|
1337
|
+
const tag_r42 = ctx.$implicit;
|
|
1311
1338
|
i0.ɵɵadvance();
|
|
1312
|
-
i0.ɵɵtextInterpolate(
|
|
1339
|
+
i0.ɵɵtextInterpolate(tag_r42);
|
|
1313
1340
|
} }
|
|
1314
1341
|
function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_5_For_2_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
1315
|
-
i0.ɵɵelementStart(0, "div",
|
|
1316
|
-
i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_5_For_2_Conditional_8_For_2_Template, 2, 1, "span",
|
|
1342
|
+
i0.ɵɵelementStart(0, "div", 294);
|
|
1343
|
+
i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_5_For_2_Conditional_8_For_2_Template, 2, 1, "span", 295, i0.ɵɵrepeaterTrackByIdentity);
|
|
1317
1344
|
i0.ɵɵelementEnd();
|
|
1318
1345
|
} if (rf & 2) {
|
|
1319
|
-
const
|
|
1346
|
+
const run_r41 = i0.ɵɵnextContext().$implicit;
|
|
1320
1347
|
const ctx_r0 = i0.ɵɵnextContext(3);
|
|
1321
1348
|
i0.ɵɵadvance();
|
|
1322
|
-
i0.ɵɵrepeater(ctx_r0.getRunTags(
|
|
1349
|
+
i0.ɵɵrepeater(ctx_r0.getRunTags(run_r41).slice(0, 2));
|
|
1323
1350
|
} }
|
|
1324
1351
|
function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_5_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
1325
|
-
const
|
|
1326
|
-
i0.ɵɵelementStart(0, "div",
|
|
1327
|
-
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_5_For_2_Template_div_click_0_listener() { const
|
|
1328
|
-
i0.ɵɵelement(1, "div",
|
|
1329
|
-
i0.ɵɵelementStart(2, "div",
|
|
1352
|
+
const _r40 = i0.ɵɵgetCurrentView();
|
|
1353
|
+
i0.ɵɵelementStart(0, "div", 289);
|
|
1354
|
+
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_5_For_2_Template_div_click_0_listener() { const run_r41 = i0.ɵɵrestoreView(_r40).$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.selectCompareRunA(run_r41)); });
|
|
1355
|
+
i0.ɵɵelement(1, "div", 290);
|
|
1356
|
+
i0.ɵɵelementStart(2, "div", 291)(3, "div", 292);
|
|
1330
1357
|
i0.ɵɵtext(4);
|
|
1331
1358
|
i0.ɵɵpipe(5, "date");
|
|
1332
1359
|
i0.ɵɵelementEnd();
|
|
1333
|
-
i0.ɵɵelementStart(6, "div",
|
|
1360
|
+
i0.ɵɵelementStart(6, "div", 293);
|
|
1334
1361
|
i0.ɵɵtext(7);
|
|
1335
1362
|
i0.ɵɵelementEnd()();
|
|
1336
|
-
i0.ɵɵconditionalCreate(8, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_5_For_2_Conditional_8_Template, 3, 0, "div",
|
|
1363
|
+
i0.ɵɵconditionalCreate(8, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_5_For_2_Conditional_8_Template, 3, 0, "div", 294);
|
|
1337
1364
|
i0.ɵɵelementEnd();
|
|
1338
1365
|
} if (rf & 2) {
|
|
1339
|
-
const
|
|
1366
|
+
const run_r41 = ctx.$implicit;
|
|
1340
1367
|
const ctx_r0 = i0.ɵɵnextContext(3);
|
|
1341
|
-
i0.ɵɵclassProp("selected", ctx_r0.IsCompareRunA(
|
|
1368
|
+
i0.ɵɵclassProp("selected", ctx_r0.IsCompareRunA(run_r41));
|
|
1342
1369
|
i0.ɵɵadvance();
|
|
1343
|
-
i0.ɵɵstyleProp("background-color", ctx_r0.getRunStatusColor(
|
|
1370
|
+
i0.ɵɵstyleProp("background-color", ctx_r0.getRunStatusColor(run_r41.Status));
|
|
1344
1371
|
i0.ɵɵadvance(3);
|
|
1345
|
-
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(5, 7,
|
|
1372
|
+
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(5, 7, run_r41.StartedAt, "short"));
|
|
1346
1373
|
i0.ɵɵadvance(3);
|
|
1347
|
-
i0.ɵɵtextInterpolate1("", ctx_r0.getPassRate(
|
|
1374
|
+
i0.ɵɵtextInterpolate1("", ctx_r0.getPassRate(run_r41).toFixed(0), "% pass");
|
|
1348
1375
|
i0.ɵɵadvance();
|
|
1349
|
-
i0.ɵɵconditional(ctx_r0.getRunTags(
|
|
1376
|
+
i0.ɵɵconditional(ctx_r0.getRunTags(run_r41).length > 0 ? 8 : -1);
|
|
1350
1377
|
} }
|
|
1351
1378
|
function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
1352
|
-
i0.ɵɵelementStart(0, "div",
|
|
1353
|
-
i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_5_For_2_Template, 9, 10, "div",
|
|
1379
|
+
i0.ɵɵelementStart(0, "div", 281);
|
|
1380
|
+
i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_5_For_2_Template, 9, 10, "div", 288, i0.ɵɵrepeaterTrackByIdentity);
|
|
1354
1381
|
i0.ɵɵelementEnd();
|
|
1355
1382
|
} if (rf & 2) {
|
|
1356
1383
|
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
@@ -1358,19 +1385,19 @@ function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_5_Template(
|
|
|
1358
1385
|
i0.ɵɵrepeater(ctx_r0.suiteRuns);
|
|
1359
1386
|
} }
|
|
1360
1387
|
function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
1361
|
-
const
|
|
1362
|
-
i0.ɵɵelementStart(0, "div",
|
|
1388
|
+
const _r43 = i0.ɵɵgetCurrentView();
|
|
1389
|
+
i0.ɵɵelementStart(0, "div", 282)(1, "div", 296)(2, "span", 297);
|
|
1363
1390
|
i0.ɵɵtext(3, "Selected:");
|
|
1364
1391
|
i0.ɵɵelementEnd();
|
|
1365
|
-
i0.ɵɵelementStart(4, "button",
|
|
1366
|
-
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_6_Template_button_click_4_listener() { i0.ɵɵrestoreView(
|
|
1392
|
+
i0.ɵɵelementStart(4, "button", 298);
|
|
1393
|
+
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_6_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r43); const ctx_r0 = i0.ɵɵnextContext(2); ctx_r0.compareRunA = null; return i0.ɵɵresetView(ctx_r0.compareResults = []); });
|
|
1367
1394
|
i0.ɵɵtext(5, "Clear");
|
|
1368
1395
|
i0.ɵɵelementEnd()();
|
|
1369
|
-
i0.ɵɵelementStart(6, "div",
|
|
1396
|
+
i0.ɵɵelementStart(6, "div", 299)(7, "span");
|
|
1370
1397
|
i0.ɵɵtext(8);
|
|
1371
1398
|
i0.ɵɵpipe(9, "date");
|
|
1372
1399
|
i0.ɵɵelementEnd();
|
|
1373
|
-
i0.ɵɵelementStart(10, "span",
|
|
1400
|
+
i0.ɵɵelementStart(10, "span", 300);
|
|
1374
1401
|
i0.ɵɵtext(11);
|
|
1375
1402
|
i0.ɵɵelementEnd()()();
|
|
1376
1403
|
} if (rf & 2) {
|
|
@@ -1381,54 +1408,54 @@ function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_6_Template(
|
|
|
1381
1408
|
i0.ɵɵtextInterpolate1("", ctx_r0.getPassRate(ctx_r0.compareRunA).toFixed(1), "%");
|
|
1382
1409
|
} }
|
|
1383
1410
|
function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_12_For_2_Conditional_8_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
1384
|
-
i0.ɵɵelementStart(0, "span",
|
|
1411
|
+
i0.ɵɵelementStart(0, "span", 295);
|
|
1385
1412
|
i0.ɵɵtext(1);
|
|
1386
1413
|
i0.ɵɵelementEnd();
|
|
1387
1414
|
} if (rf & 2) {
|
|
1388
|
-
const
|
|
1415
|
+
const tag_r46 = ctx.$implicit;
|
|
1389
1416
|
i0.ɵɵadvance();
|
|
1390
|
-
i0.ɵɵtextInterpolate(
|
|
1417
|
+
i0.ɵɵtextInterpolate(tag_r46);
|
|
1391
1418
|
} }
|
|
1392
1419
|
function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_12_For_2_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
1393
|
-
i0.ɵɵelementStart(0, "div",
|
|
1394
|
-
i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_12_For_2_Conditional_8_For_2_Template, 2, 1, "span",
|
|
1420
|
+
i0.ɵɵelementStart(0, "div", 294);
|
|
1421
|
+
i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_12_For_2_Conditional_8_For_2_Template, 2, 1, "span", 295, i0.ɵɵrepeaterTrackByIdentity);
|
|
1395
1422
|
i0.ɵɵelementEnd();
|
|
1396
1423
|
} if (rf & 2) {
|
|
1397
|
-
const
|
|
1424
|
+
const run_r45 = i0.ɵɵnextContext().$implicit;
|
|
1398
1425
|
const ctx_r0 = i0.ɵɵnextContext(3);
|
|
1399
1426
|
i0.ɵɵadvance();
|
|
1400
|
-
i0.ɵɵrepeater(ctx_r0.getRunTags(
|
|
1427
|
+
i0.ɵɵrepeater(ctx_r0.getRunTags(run_r45).slice(0, 2));
|
|
1401
1428
|
} }
|
|
1402
1429
|
function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_12_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
1403
|
-
const
|
|
1404
|
-
i0.ɵɵelementStart(0, "div",
|
|
1405
|
-
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_12_For_2_Template_div_click_0_listener() { const
|
|
1406
|
-
i0.ɵɵelement(1, "div",
|
|
1407
|
-
i0.ɵɵelementStart(2, "div",
|
|
1430
|
+
const _r44 = i0.ɵɵgetCurrentView();
|
|
1431
|
+
i0.ɵɵelementStart(0, "div", 289);
|
|
1432
|
+
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_12_For_2_Template_div_click_0_listener() { const run_r45 = i0.ɵɵrestoreView(_r44).$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(!ctx_r0.IsCompareRunA(run_r45) && ctx_r0.selectCompareRunB(run_r45)); });
|
|
1433
|
+
i0.ɵɵelement(1, "div", 290);
|
|
1434
|
+
i0.ɵɵelementStart(2, "div", 291)(3, "div", 292);
|
|
1408
1435
|
i0.ɵɵtext(4);
|
|
1409
1436
|
i0.ɵɵpipe(5, "date");
|
|
1410
1437
|
i0.ɵɵelementEnd();
|
|
1411
|
-
i0.ɵɵelementStart(6, "div",
|
|
1438
|
+
i0.ɵɵelementStart(6, "div", 293);
|
|
1412
1439
|
i0.ɵɵtext(7);
|
|
1413
1440
|
i0.ɵɵelementEnd()();
|
|
1414
|
-
i0.ɵɵconditionalCreate(8, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_12_For_2_Conditional_8_Template, 3, 0, "div",
|
|
1441
|
+
i0.ɵɵconditionalCreate(8, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_12_For_2_Conditional_8_Template, 3, 0, "div", 294);
|
|
1415
1442
|
i0.ɵɵelementEnd();
|
|
1416
1443
|
} if (rf & 2) {
|
|
1417
|
-
const
|
|
1444
|
+
const run_r45 = ctx.$implicit;
|
|
1418
1445
|
const ctx_r0 = i0.ɵɵnextContext(3);
|
|
1419
|
-
i0.ɵɵclassProp("selected", ctx_r0.IsCompareRunB(
|
|
1446
|
+
i0.ɵɵclassProp("selected", ctx_r0.IsCompareRunB(run_r45))("disabled", ctx_r0.IsCompareRunA(run_r45));
|
|
1420
1447
|
i0.ɵɵadvance();
|
|
1421
|
-
i0.ɵɵstyleProp("background-color", ctx_r0.getRunStatusColor(
|
|
1448
|
+
i0.ɵɵstyleProp("background-color", ctx_r0.getRunStatusColor(run_r45.Status));
|
|
1422
1449
|
i0.ɵɵadvance(3);
|
|
1423
|
-
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(5, 9,
|
|
1450
|
+
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(5, 9, run_r45.StartedAt, "short"));
|
|
1424
1451
|
i0.ɵɵadvance(3);
|
|
1425
|
-
i0.ɵɵtextInterpolate1("", ctx_r0.getPassRate(
|
|
1452
|
+
i0.ɵɵtextInterpolate1("", ctx_r0.getPassRate(run_r45).toFixed(0), "% pass");
|
|
1426
1453
|
i0.ɵɵadvance();
|
|
1427
|
-
i0.ɵɵconditional(ctx_r0.getRunTags(
|
|
1454
|
+
i0.ɵɵconditional(ctx_r0.getRunTags(run_r45).length > 0 ? 8 : -1);
|
|
1428
1455
|
} }
|
|
1429
1456
|
function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_12_Template(rf, ctx) { if (rf & 1) {
|
|
1430
|
-
i0.ɵɵelementStart(0, "div",
|
|
1431
|
-
i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_12_For_2_Template, 9, 12, "div",
|
|
1457
|
+
i0.ɵɵelementStart(0, "div", 281);
|
|
1458
|
+
i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_12_For_2_Template, 9, 12, "div", 301, i0.ɵɵrepeaterTrackByIdentity);
|
|
1432
1459
|
i0.ɵɵelementEnd();
|
|
1433
1460
|
} if (rf & 2) {
|
|
1434
1461
|
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
@@ -1436,19 +1463,19 @@ function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_12_Template
|
|
|
1436
1463
|
i0.ɵɵrepeater(ctx_r0.suiteRuns);
|
|
1437
1464
|
} }
|
|
1438
1465
|
function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_13_Template(rf, ctx) { if (rf & 1) {
|
|
1439
|
-
const
|
|
1440
|
-
i0.ɵɵelementStart(0, "div",
|
|
1466
|
+
const _r47 = i0.ɵɵgetCurrentView();
|
|
1467
|
+
i0.ɵɵelementStart(0, "div", 282)(1, "div", 296)(2, "span", 297);
|
|
1441
1468
|
i0.ɵɵtext(3, "Selected:");
|
|
1442
1469
|
i0.ɵɵelementEnd();
|
|
1443
|
-
i0.ɵɵelementStart(4, "button",
|
|
1444
|
-
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_13_Template_button_click_4_listener() { i0.ɵɵrestoreView(
|
|
1470
|
+
i0.ɵɵelementStart(4, "button", 298);
|
|
1471
|
+
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_13_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r47); const ctx_r0 = i0.ɵɵnextContext(2); ctx_r0.compareRunB = null; return i0.ɵɵresetView(ctx_r0.compareResults = []); });
|
|
1445
1472
|
i0.ɵɵtext(5, "Clear");
|
|
1446
1473
|
i0.ɵɵelementEnd()();
|
|
1447
|
-
i0.ɵɵelementStart(6, "div",
|
|
1474
|
+
i0.ɵɵelementStart(6, "div", 299)(7, "span");
|
|
1448
1475
|
i0.ɵɵtext(8);
|
|
1449
1476
|
i0.ɵɵpipe(9, "date");
|
|
1450
1477
|
i0.ɵɵelementEnd();
|
|
1451
|
-
i0.ɵɵelementStart(10, "span",
|
|
1478
|
+
i0.ɵɵelementStart(10, "span", 300);
|
|
1452
1479
|
i0.ɵɵtext(11);
|
|
1453
1480
|
i0.ɵɵelementEnd()()();
|
|
1454
1481
|
} if (rf & 2) {
|
|
@@ -1459,167 +1486,167 @@ function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_13_Template
|
|
|
1459
1486
|
i0.ɵɵtextInterpolate1("", ctx_r0.getPassRate(ctx_r0.compareRunB).toFixed(1), "%");
|
|
1460
1487
|
} }
|
|
1461
1488
|
function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
1462
|
-
i0.ɵɵelementStart(0, "span",
|
|
1489
|
+
i0.ɵɵelementStart(0, "span", 199);
|
|
1463
1490
|
i0.ɵɵtext(1);
|
|
1464
1491
|
i0.ɵɵelementEnd();
|
|
1465
1492
|
} if (rf & 2) {
|
|
1466
|
-
const
|
|
1467
|
-
i0.ɵɵproperty("ngClass", "status-" +
|
|
1493
|
+
const result_r48 = i0.ɵɵnextContext().$implicit;
|
|
1494
|
+
i0.ɵɵproperty("ngClass", "status-" + result_r48.runA.status.toLowerCase());
|
|
1468
1495
|
i0.ɵɵadvance();
|
|
1469
|
-
i0.ɵɵtextInterpolate(
|
|
1496
|
+
i0.ɵɵtextInterpolate(result_r48.runA.status);
|
|
1470
1497
|
} }
|
|
1471
1498
|
function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
1472
|
-
i0.ɵɵelementStart(0, "span",
|
|
1499
|
+
i0.ɵɵelementStart(0, "span", 314);
|
|
1473
1500
|
i0.ɵɵtext(1, "N/A");
|
|
1474
1501
|
i0.ɵɵelementEnd();
|
|
1475
1502
|
} }
|
|
1476
1503
|
function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
1477
|
-
i0.ɵɵelementStart(0, "span",
|
|
1504
|
+
i0.ɵɵelementStart(0, "span", 199);
|
|
1478
1505
|
i0.ɵɵtext(1);
|
|
1479
1506
|
i0.ɵɵelementEnd();
|
|
1480
1507
|
} if (rf & 2) {
|
|
1481
|
-
const
|
|
1482
|
-
i0.ɵɵproperty("ngClass", "status-" +
|
|
1508
|
+
const result_r48 = i0.ɵɵnextContext().$implicit;
|
|
1509
|
+
i0.ɵɵproperty("ngClass", "status-" + result_r48.runB.status.toLowerCase());
|
|
1483
1510
|
i0.ɵɵadvance();
|
|
1484
|
-
i0.ɵɵtextInterpolate(
|
|
1511
|
+
i0.ɵɵtextInterpolate(result_r48.runB.status);
|
|
1485
1512
|
} }
|
|
1486
1513
|
function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
1487
|
-
i0.ɵɵelementStart(0, "span",
|
|
1514
|
+
i0.ɵɵelementStart(0, "span", 314);
|
|
1488
1515
|
i0.ɵɵtext(1, "N/A");
|
|
1489
1516
|
i0.ɵɵelementEnd();
|
|
1490
1517
|
} }
|
|
1491
1518
|
function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_10_Template(rf, ctx) { if (rf & 1) {
|
|
1492
|
-
i0.ɵɵelementStart(0, "span",
|
|
1519
|
+
i0.ɵɵelementStart(0, "span", 313);
|
|
1493
1520
|
i0.ɵɵtext(1);
|
|
1494
1521
|
i0.ɵɵelementEnd();
|
|
1495
1522
|
} if (rf & 2) {
|
|
1496
|
-
const
|
|
1497
|
-
i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction2(3, _c6,
|
|
1523
|
+
const result_r48 = i0.ɵɵnextContext().$implicit;
|
|
1524
|
+
i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction2(3, _c6, result_r48.scoreDiff > 0, result_r48.scoreDiff < 0));
|
|
1498
1525
|
i0.ɵɵadvance();
|
|
1499
|
-
i0.ɵɵtextInterpolate2(" ",
|
|
1526
|
+
i0.ɵɵtextInterpolate2(" ", result_r48.scoreDiff > 0 ? "+" : "", "", (result_r48.scoreDiff * 100).toFixed(1), "% ");
|
|
1500
1527
|
} }
|
|
1501
1528
|
function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_11_Template(rf, ctx) { if (rf & 1) {
|
|
1502
|
-
i0.ɵɵelementStart(0, "span",
|
|
1529
|
+
i0.ɵɵelementStart(0, "span", 315);
|
|
1503
1530
|
i0.ɵɵtext(1, "-");
|
|
1504
1531
|
i0.ɵɵelementEnd();
|
|
1505
1532
|
} }
|
|
1506
1533
|
function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_13_Template(rf, ctx) { if (rf & 1) {
|
|
1507
|
-
i0.ɵɵelementStart(0, "span",
|
|
1534
|
+
i0.ɵɵelementStart(0, "span", 313);
|
|
1508
1535
|
i0.ɵɵtext(1);
|
|
1509
1536
|
i0.ɵɵelementEnd();
|
|
1510
1537
|
} if (rf & 2) {
|
|
1511
|
-
const
|
|
1512
|
-
i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction2(3, _c6,
|
|
1538
|
+
const result_r48 = i0.ɵɵnextContext().$implicit;
|
|
1539
|
+
i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction2(3, _c6, result_r48.durationDiff < 0, result_r48.durationDiff > 0));
|
|
1513
1540
|
i0.ɵɵadvance();
|
|
1514
|
-
i0.ɵɵtextInterpolate2(" ",
|
|
1541
|
+
i0.ɵɵtextInterpolate2(" ", result_r48.durationDiff > 0 ? "+" : "", "", result_r48.durationDiff.toFixed(1), "s ");
|
|
1515
1542
|
} }
|
|
1516
1543
|
function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_14_Template(rf, ctx) { if (rf & 1) {
|
|
1517
|
-
i0.ɵɵelementStart(0, "span",
|
|
1544
|
+
i0.ɵɵelementStart(0, "span", 315);
|
|
1518
1545
|
i0.ɵɵtext(1, "-");
|
|
1519
1546
|
i0.ɵɵelementEnd();
|
|
1520
1547
|
} }
|
|
1521
1548
|
function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_16_Template(rf, ctx) { if (rf & 1) {
|
|
1522
|
-
i0.ɵɵelementStart(0, "span",
|
|
1523
|
-
i0.ɵɵelement(1, "i",
|
|
1549
|
+
i0.ɵɵelementStart(0, "span", 316);
|
|
1550
|
+
i0.ɵɵelement(1, "i", 319);
|
|
1524
1551
|
i0.ɵɵtext(2, " Fixed ");
|
|
1525
1552
|
i0.ɵɵelementEnd();
|
|
1526
1553
|
} }
|
|
1527
1554
|
function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_17_Template(rf, ctx) { if (rf & 1) {
|
|
1528
|
-
i0.ɵɵelementStart(0, "span",
|
|
1529
|
-
i0.ɵɵelement(1, "i",
|
|
1555
|
+
i0.ɵɵelementStart(0, "span", 317);
|
|
1556
|
+
i0.ɵɵelement(1, "i", 320);
|
|
1530
1557
|
i0.ɵɵtext(2, " Broke ");
|
|
1531
1558
|
i0.ɵɵelementEnd();
|
|
1532
1559
|
} }
|
|
1533
1560
|
function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_18_Template(rf, ctx) { if (rf & 1) {
|
|
1534
|
-
i0.ɵɵelementStart(0, "span",
|
|
1535
|
-
i0.ɵɵelement(1, "i",
|
|
1561
|
+
i0.ɵɵelementStart(0, "span", 318);
|
|
1562
|
+
i0.ɵɵelement(1, "i", 256);
|
|
1536
1563
|
i0.ɵɵelementEnd();
|
|
1537
1564
|
} }
|
|
1538
1565
|
function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Template(rf, ctx) { if (rf & 1) {
|
|
1539
|
-
i0.ɵɵelementStart(0, "tr",
|
|
1566
|
+
i0.ɵɵelementStart(0, "tr", 313)(1, "td", 239);
|
|
1540
1567
|
i0.ɵɵtext(2);
|
|
1541
1568
|
i0.ɵɵelementEnd();
|
|
1542
1569
|
i0.ɵɵelementStart(3, "td");
|
|
1543
|
-
i0.ɵɵconditionalCreate(4, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_4_Template, 2, 2, "span",
|
|
1544
|
-
i0.ɵɵconditionalCreate(5, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_5_Template, 2, 0, "span",
|
|
1570
|
+
i0.ɵɵconditionalCreate(4, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_4_Template, 2, 2, "span", 199);
|
|
1571
|
+
i0.ɵɵconditionalCreate(5, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_5_Template, 2, 0, "span", 314);
|
|
1545
1572
|
i0.ɵɵelementEnd();
|
|
1546
1573
|
i0.ɵɵelementStart(6, "td");
|
|
1547
|
-
i0.ɵɵconditionalCreate(7, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_7_Template, 2, 2, "span",
|
|
1548
|
-
i0.ɵɵconditionalCreate(8, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_8_Template, 2, 0, "span",
|
|
1574
|
+
i0.ɵɵconditionalCreate(7, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_7_Template, 2, 2, "span", 199);
|
|
1575
|
+
i0.ɵɵconditionalCreate(8, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_8_Template, 2, 0, "span", 314);
|
|
1549
1576
|
i0.ɵɵelementEnd();
|
|
1550
1577
|
i0.ɵɵelementStart(9, "td");
|
|
1551
|
-
i0.ɵɵconditionalCreate(10, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_10_Template, 2, 6, "span",
|
|
1552
|
-
i0.ɵɵconditionalCreate(11, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_11_Template, 2, 0, "span",
|
|
1578
|
+
i0.ɵɵconditionalCreate(10, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_10_Template, 2, 6, "span", 313);
|
|
1579
|
+
i0.ɵɵconditionalCreate(11, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_11_Template, 2, 0, "span", 315);
|
|
1553
1580
|
i0.ɵɵelementEnd();
|
|
1554
1581
|
i0.ɵɵelementStart(12, "td");
|
|
1555
|
-
i0.ɵɵconditionalCreate(13, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_13_Template, 2, 6, "span",
|
|
1556
|
-
i0.ɵɵconditionalCreate(14, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_14_Template, 2, 0, "span",
|
|
1582
|
+
i0.ɵɵconditionalCreate(13, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_13_Template, 2, 6, "span", 313);
|
|
1583
|
+
i0.ɵɵconditionalCreate(14, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_14_Template, 2, 0, "span", 315);
|
|
1557
1584
|
i0.ɵɵelementEnd();
|
|
1558
1585
|
i0.ɵɵelementStart(15, "td");
|
|
1559
|
-
i0.ɵɵconditionalCreate(16, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_16_Template, 3, 0, "span",
|
|
1560
|
-
i0.ɵɵconditionalCreate(17, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_17_Template, 3, 0, "span",
|
|
1561
|
-
i0.ɵɵconditionalCreate(18, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_18_Template, 2, 0, "span",
|
|
1586
|
+
i0.ɵɵconditionalCreate(16, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_16_Template, 3, 0, "span", 316);
|
|
1587
|
+
i0.ɵɵconditionalCreate(17, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_17_Template, 3, 0, "span", 317);
|
|
1588
|
+
i0.ɵɵconditionalCreate(18, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_18_Template, 2, 0, "span", 318);
|
|
1562
1589
|
i0.ɵɵelementEnd()();
|
|
1563
1590
|
} if (rf & 2) {
|
|
1564
|
-
const
|
|
1565
|
-
i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction2(13, _c8,
|
|
1591
|
+
const result_r48 = ctx.$implicit;
|
|
1592
|
+
i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction2(13, _c8, result_r48.runA && result_r48.runB && result_r48.runA.status !== "Passed" && result_r48.runB.status === "Passed", result_r48.runA && result_r48.runB && result_r48.runA.status === "Passed" && result_r48.runB.status !== "Passed"));
|
|
1566
1593
|
i0.ɵɵadvance(2);
|
|
1567
|
-
i0.ɵɵtextInterpolate(
|
|
1594
|
+
i0.ɵɵtextInterpolate(result_r48.testName);
|
|
1568
1595
|
i0.ɵɵadvance(2);
|
|
1569
|
-
i0.ɵɵconditional(
|
|
1596
|
+
i0.ɵɵconditional(result_r48.runA ? 4 : -1);
|
|
1570
1597
|
i0.ɵɵadvance();
|
|
1571
|
-
i0.ɵɵconditional(!
|
|
1598
|
+
i0.ɵɵconditional(!result_r48.runA ? 5 : -1);
|
|
1572
1599
|
i0.ɵɵadvance(2);
|
|
1573
|
-
i0.ɵɵconditional(
|
|
1600
|
+
i0.ɵɵconditional(result_r48.runB ? 7 : -1);
|
|
1574
1601
|
i0.ɵɵadvance();
|
|
1575
|
-
i0.ɵɵconditional(!
|
|
1602
|
+
i0.ɵɵconditional(!result_r48.runB ? 8 : -1);
|
|
1576
1603
|
i0.ɵɵadvance(2);
|
|
1577
|
-
i0.ɵɵconditional(
|
|
1604
|
+
i0.ɵɵconditional(result_r48.scoreDiff != null ? 10 : -1);
|
|
1578
1605
|
i0.ɵɵadvance();
|
|
1579
|
-
i0.ɵɵconditional(
|
|
1606
|
+
i0.ɵɵconditional(result_r48.scoreDiff == null ? 11 : -1);
|
|
1580
1607
|
i0.ɵɵadvance(2);
|
|
1581
|
-
i0.ɵɵconditional(
|
|
1608
|
+
i0.ɵɵconditional(result_r48.durationDiff != null ? 13 : -1);
|
|
1582
1609
|
i0.ɵɵadvance();
|
|
1583
|
-
i0.ɵɵconditional(
|
|
1610
|
+
i0.ɵɵconditional(result_r48.durationDiff == null ? 14 : -1);
|
|
1584
1611
|
i0.ɵɵadvance(2);
|
|
1585
|
-
i0.ɵɵconditional(
|
|
1612
|
+
i0.ɵɵconditional(result_r48.runA && result_r48.runB && result_r48.runA.status !== "Passed" && result_r48.runB.status === "Passed" ? 16 : -1);
|
|
1586
1613
|
i0.ɵɵadvance();
|
|
1587
|
-
i0.ɵɵconditional(
|
|
1614
|
+
i0.ɵɵconditional(result_r48.runA && result_r48.runB && result_r48.runA.status === "Passed" && result_r48.runB.status !== "Passed" ? 17 : -1);
|
|
1588
1615
|
i0.ɵɵadvance();
|
|
1589
|
-
i0.ɵɵconditional(!
|
|
1616
|
+
i0.ɵɵconditional(!result_r48.statusChanged ? 18 : -1);
|
|
1590
1617
|
} }
|
|
1591
1618
|
function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_Template(rf, ctx) { if (rf & 1) {
|
|
1592
|
-
i0.ɵɵelementStart(0, "div",
|
|
1619
|
+
i0.ɵɵelementStart(0, "div", 285)(1, "div", 302)(2, "div", 303)(3, "div", 304);
|
|
1593
1620
|
i0.ɵɵtext(4, "Pass Rate Change");
|
|
1594
1621
|
i0.ɵɵelementEnd();
|
|
1595
|
-
i0.ɵɵelementStart(5, "div",
|
|
1622
|
+
i0.ɵɵelementStart(5, "div", 305);
|
|
1596
1623
|
i0.ɵɵelement(6, "i", 19);
|
|
1597
1624
|
i0.ɵɵtext(7);
|
|
1598
1625
|
i0.ɵɵelementEnd()();
|
|
1599
|
-
i0.ɵɵelementStart(8, "div",
|
|
1626
|
+
i0.ɵɵelementStart(8, "div", 303)(9, "div", 304);
|
|
1600
1627
|
i0.ɵɵtext(10, "Duration Change");
|
|
1601
1628
|
i0.ɵɵelementEnd();
|
|
1602
|
-
i0.ɵɵelementStart(11, "div",
|
|
1629
|
+
i0.ɵɵelementStart(11, "div", 305);
|
|
1603
1630
|
i0.ɵɵelement(12, "i", 19);
|
|
1604
1631
|
i0.ɵɵtext(13);
|
|
1605
1632
|
i0.ɵɵelementEnd()();
|
|
1606
|
-
i0.ɵɵelementStart(14, "div",
|
|
1633
|
+
i0.ɵɵelementStart(14, "div", 306)(15, "div", 304);
|
|
1607
1634
|
i0.ɵɵtext(16, "Improved");
|
|
1608
1635
|
i0.ɵɵelementEnd();
|
|
1609
|
-
i0.ɵɵelementStart(17, "div",
|
|
1636
|
+
i0.ɵɵelementStart(17, "div", 307);
|
|
1610
1637
|
i0.ɵɵtext(18);
|
|
1611
1638
|
i0.ɵɵelementEnd()();
|
|
1612
|
-
i0.ɵɵelementStart(19, "div",
|
|
1639
|
+
i0.ɵɵelementStart(19, "div", 308)(20, "div", 304);
|
|
1613
1640
|
i0.ɵɵtext(21, "Regressed");
|
|
1614
1641
|
i0.ɵɵelementEnd();
|
|
1615
|
-
i0.ɵɵelementStart(22, "div",
|
|
1642
|
+
i0.ɵɵelementStart(22, "div", 307);
|
|
1616
1643
|
i0.ɵɵtext(23);
|
|
1617
1644
|
i0.ɵɵelementEnd()()();
|
|
1618
|
-
i0.ɵɵelementStart(24, "div",
|
|
1619
|
-
i0.ɵɵelement(26, "i",
|
|
1645
|
+
i0.ɵɵelementStart(24, "div", 309)(25, "h3");
|
|
1646
|
+
i0.ɵɵelement(26, "i", 310);
|
|
1620
1647
|
i0.ɵɵtext(27, " Test-by-Test Comparison");
|
|
1621
1648
|
i0.ɵɵelementEnd();
|
|
1622
|
-
i0.ɵɵelementStart(28, "div",
|
|
1649
|
+
i0.ɵɵelementStart(28, "div", 311)(29, "table", 312)(30, "thead")(31, "tr")(32, "th");
|
|
1623
1650
|
i0.ɵɵtext(33, "Test");
|
|
1624
1651
|
i0.ɵɵelementEnd();
|
|
1625
1652
|
i0.ɵɵelementStart(34, "th");
|
|
@@ -1638,7 +1665,7 @@ function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_Template
|
|
|
1638
1665
|
i0.ɵɵtext(43, "Change");
|
|
1639
1666
|
i0.ɵɵelementEnd()()();
|
|
1640
1667
|
i0.ɵɵelementStart(44, "tbody");
|
|
1641
|
-
i0.ɵɵrepeaterCreate(45, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Template, 19, 16, "tr",
|
|
1668
|
+
i0.ɵɵrepeaterCreate(45, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Template, 19, 16, "tr", 313, i0.ɵɵrepeaterTrackByIdentity);
|
|
1642
1669
|
i0.ɵɵelementEnd()()()()();
|
|
1643
1670
|
} if (rf & 2) {
|
|
1644
1671
|
let tmp_4_0;
|
|
@@ -1663,39 +1690,39 @@ function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_Template
|
|
|
1663
1690
|
i0.ɵɵrepeater(ctx_r0.compareResults);
|
|
1664
1691
|
} }
|
|
1665
1692
|
function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_15_Template(rf, ctx) { if (rf & 1) {
|
|
1666
|
-
i0.ɵɵelementStart(0, "div",
|
|
1667
|
-
i0.ɵɵelement(1, "mj-loading",
|
|
1693
|
+
i0.ɵɵelementStart(0, "div", 101);
|
|
1694
|
+
i0.ɵɵelement(1, "mj-loading", 321);
|
|
1668
1695
|
i0.ɵɵelementEnd();
|
|
1669
1696
|
} }
|
|
1670
1697
|
function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_16_Template(rf, ctx) { if (rf & 1) {
|
|
1671
|
-
i0.ɵɵelement(0, "mj-empty-state",
|
|
1698
|
+
i0.ɵɵelement(0, "mj-empty-state", 286);
|
|
1672
1699
|
} }
|
|
1673
1700
|
function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_17_Template(rf, ctx) { if (rf & 1) {
|
|
1674
|
-
const
|
|
1675
|
-
i0.ɵɵelementStart(0, "mj-empty-state",
|
|
1676
|
-
i0.ɵɵlistener("Action", function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_17_Template_mj_empty_state_Action_0_listener() { i0.ɵɵrestoreView(
|
|
1701
|
+
const _r49 = i0.ɵɵgetCurrentView();
|
|
1702
|
+
i0.ɵɵelementStart(0, "mj-empty-state", 322);
|
|
1703
|
+
i0.ɵɵlistener("Action", function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_17_Template_mj_empty_state_Action_0_listener() { i0.ɵɵrestoreView(_r49); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.runSuite()); });
|
|
1677
1704
|
i0.ɵɵelementEnd();
|
|
1678
1705
|
} }
|
|
1679
1706
|
function MJTestSuiteFormComponentExtended_Conditional_64_Template(rf, ctx) { if (rf & 1) {
|
|
1680
|
-
i0.ɵɵelementStart(0, "div", 43)(1, "div",
|
|
1707
|
+
i0.ɵɵelementStart(0, "div", 43)(1, "div", 279)(2, "div", 280)(3, "h4");
|
|
1681
1708
|
i0.ɵɵtext(4, "Run A (Baseline)");
|
|
1682
1709
|
i0.ɵɵelementEnd();
|
|
1683
|
-
i0.ɵɵconditionalCreate(5, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_5_Template, 3, 0, "div",
|
|
1684
|
-
i0.ɵɵconditionalCreate(6, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_6_Template, 12, 5, "div",
|
|
1710
|
+
i0.ɵɵconditionalCreate(5, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_5_Template, 3, 0, "div", 281);
|
|
1711
|
+
i0.ɵɵconditionalCreate(6, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_6_Template, 12, 5, "div", 282);
|
|
1685
1712
|
i0.ɵɵelementEnd();
|
|
1686
|
-
i0.ɵɵelementStart(7, "div",
|
|
1687
|
-
i0.ɵɵelement(8, "i",
|
|
1713
|
+
i0.ɵɵelementStart(7, "div", 283);
|
|
1714
|
+
i0.ɵɵelement(8, "i", 284);
|
|
1688
1715
|
i0.ɵɵelementEnd();
|
|
1689
|
-
i0.ɵɵelementStart(9, "div",
|
|
1716
|
+
i0.ɵɵelementStart(9, "div", 280)(10, "h4");
|
|
1690
1717
|
i0.ɵɵtext(11, "Run B (Compare)");
|
|
1691
1718
|
i0.ɵɵelementEnd();
|
|
1692
|
-
i0.ɵɵconditionalCreate(12, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_12_Template, 3, 0, "div",
|
|
1693
|
-
i0.ɵɵconditionalCreate(13, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_13_Template, 12, 5, "div",
|
|
1719
|
+
i0.ɵɵconditionalCreate(12, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_12_Template, 3, 0, "div", 281);
|
|
1720
|
+
i0.ɵɵconditionalCreate(13, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_13_Template, 12, 5, "div", 282);
|
|
1694
1721
|
i0.ɵɵelementEnd()();
|
|
1695
|
-
i0.ɵɵconditionalCreate(14, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_Template, 47, 23, "div",
|
|
1696
|
-
i0.ɵɵconditionalCreate(15, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_15_Template, 2, 0, "div",
|
|
1697
|
-
i0.ɵɵconditionalCreate(16, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_16_Template, 1, 0, "mj-empty-state",
|
|
1698
|
-
i0.ɵɵconditionalCreate(17, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_17_Template, 1, 0, "mj-empty-state",
|
|
1722
|
+
i0.ɵɵconditionalCreate(14, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_Template, 47, 23, "div", 285);
|
|
1723
|
+
i0.ɵɵconditionalCreate(15, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_15_Template, 2, 0, "div", 101);
|
|
1724
|
+
i0.ɵɵconditionalCreate(16, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_16_Template, 1, 0, "mj-empty-state", 286);
|
|
1725
|
+
i0.ɵɵconditionalCreate(17, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_17_Template, 1, 0, "mj-empty-state", 287);
|
|
1699
1726
|
i0.ɵɵelementEnd();
|
|
1700
1727
|
} if (rf & 2) {
|
|
1701
1728
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
@@ -1717,45 +1744,45 @@ function MJTestSuiteFormComponentExtended_Conditional_64_Template(rf, ctx) { if
|
|
|
1717
1744
|
i0.ɵɵconditional(ctx_r0.runsLoaded && ctx_r0.suiteRuns.length < 2 ? 17 : -1);
|
|
1718
1745
|
} }
|
|
1719
1746
|
function MJTestSuiteFormComponentExtended_Conditional_67_Template(rf, ctx) { if (rf & 1) {
|
|
1720
|
-
const
|
|
1721
|
-
i0.ɵɵelementStart(0, "div", 46)(1, "div",
|
|
1747
|
+
const _r50 = i0.ɵɵgetCurrentView();
|
|
1748
|
+
i0.ɵɵelementStart(0, "div", 46)(1, "div", 323);
|
|
1722
1749
|
i0.ɵɵelement(2, "i", 45);
|
|
1723
1750
|
i0.ɵɵtext(3, " Shortcuts ");
|
|
1724
|
-
i0.ɵɵelementStart(4, "button",
|
|
1725
|
-
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_67_Template_button_click_4_listener() { i0.ɵɵrestoreView(
|
|
1726
|
-
i0.ɵɵelement(5, "i",
|
|
1751
|
+
i0.ɵɵelementStart(4, "button", 324);
|
|
1752
|
+
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_67_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r50); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.toggleShortcuts()); });
|
|
1753
|
+
i0.ɵɵelement(5, "i", 93);
|
|
1727
1754
|
i0.ɵɵelementEnd()();
|
|
1728
|
-
i0.ɵɵelementStart(6, "div",
|
|
1755
|
+
i0.ɵɵelementStart(6, "div", 325)(7, "div", 326)(8, "span");
|
|
1729
1756
|
i0.ɵɵtext(9, "Save changes");
|
|
1730
1757
|
i0.ɵɵelementEnd();
|
|
1731
|
-
i0.ɵɵelementStart(10, "span",
|
|
1758
|
+
i0.ɵɵelementStart(10, "span", 327)(11, "kbd");
|
|
1732
1759
|
i0.ɵɵtext(12, "Cmd");
|
|
1733
1760
|
i0.ɵɵelementEnd();
|
|
1734
1761
|
i0.ɵɵelementStart(13, "kbd");
|
|
1735
1762
|
i0.ɵɵtext(14, "S");
|
|
1736
1763
|
i0.ɵɵelementEnd()()();
|
|
1737
|
-
i0.ɵɵelementStart(15, "div",
|
|
1764
|
+
i0.ɵɵelementStart(15, "div", 326)(16, "span");
|
|
1738
1765
|
i0.ɵɵtext(17, "Refresh");
|
|
1739
1766
|
i0.ɵɵelementEnd();
|
|
1740
|
-
i0.ɵɵelementStart(18, "span",
|
|
1767
|
+
i0.ɵɵelementStart(18, "span", 327)(19, "kbd");
|
|
1741
1768
|
i0.ɵɵtext(20, "Cmd");
|
|
1742
1769
|
i0.ɵɵelementEnd();
|
|
1743
1770
|
i0.ɵɵelementStart(21, "kbd");
|
|
1744
1771
|
i0.ɵɵtext(22, "R");
|
|
1745
1772
|
i0.ɵɵelementEnd()()();
|
|
1746
|
-
i0.ɵɵelementStart(23, "div",
|
|
1773
|
+
i0.ɵɵelementStart(23, "div", 326)(24, "span");
|
|
1747
1774
|
i0.ɵɵtext(25, "Run Suite");
|
|
1748
1775
|
i0.ɵɵelementEnd();
|
|
1749
|
-
i0.ɵɵelementStart(26, "span",
|
|
1776
|
+
i0.ɵɵelementStart(26, "span", 327)(27, "kbd");
|
|
1750
1777
|
i0.ɵɵtext(28, "Cmd");
|
|
1751
1778
|
i0.ɵɵelementEnd();
|
|
1752
1779
|
i0.ɵɵelementStart(29, "kbd");
|
|
1753
1780
|
i0.ɵɵtext(30, "Enter");
|
|
1754
1781
|
i0.ɵɵelementEnd()()();
|
|
1755
|
-
i0.ɵɵelementStart(31, "div",
|
|
1782
|
+
i0.ɵɵelementStart(31, "div", 326)(32, "span");
|
|
1756
1783
|
i0.ɵɵtext(33, "Switch Tabs");
|
|
1757
1784
|
i0.ɵɵelementEnd();
|
|
1758
|
-
i0.ɵɵelementStart(34, "span",
|
|
1785
|
+
i0.ɵɵelementStart(34, "span", 327)(35, "kbd");
|
|
1759
1786
|
i0.ɵɵtext(36, "1");
|
|
1760
1787
|
i0.ɵɵelementEnd();
|
|
1761
1788
|
i0.ɵɵtext(37, "-");
|
|
@@ -1764,11 +1791,11 @@ function MJTestSuiteFormComponentExtended_Conditional_67_Template(rf, ctx) { if
|
|
|
1764
1791
|
i0.ɵɵelementEnd()()()()();
|
|
1765
1792
|
} }
|
|
1766
1793
|
function MJTestSuiteFormComponentExtended_Conditional_68_Template(rf, ctx) { if (rf & 1) {
|
|
1767
|
-
const
|
|
1768
|
-
i0.ɵɵelementStart(0, "mj-slide-panel",
|
|
1769
|
-
i0.ɵɵlistener("Closed", function MJTestSuiteFormComponentExtended_Conditional_68_Template_mj_slide_panel_Closed_0_listener() { i0.ɵɵrestoreView(
|
|
1770
|
-
i0.ɵɵelementStart(1, "app-test-run-dialog",
|
|
1771
|
-
i0.ɵɵlistener("PanelClose", function MJTestSuiteFormComponentExtended_Conditional_68_Template_app_test_run_dialog_PanelClose_1_listener() { i0.ɵɵrestoreView(
|
|
1794
|
+
const _r51 = i0.ɵɵgetCurrentView();
|
|
1795
|
+
i0.ɵɵelementStart(0, "mj-slide-panel", 328);
|
|
1796
|
+
i0.ɵɵlistener("Closed", function MJTestSuiteFormComponentExtended_Conditional_68_Template_mj_slide_panel_Closed_0_listener() { i0.ɵɵrestoreView(_r51); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnPanelClosed()); });
|
|
1797
|
+
i0.ɵɵelementStart(1, "app-test-run-dialog", 329);
|
|
1798
|
+
i0.ɵɵlistener("PanelClose", function MJTestSuiteFormComponentExtended_Conditional_68_Template_app_test_run_dialog_PanelClose_1_listener() { i0.ɵɵrestoreView(_r51); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnPanelClosed()); });
|
|
1772
1799
|
i0.ɵɵelementEnd()();
|
|
1773
1800
|
} if (rf & 2) {
|
|
1774
1801
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
@@ -1777,10 +1804,10 @@ function MJTestSuiteFormComponentExtended_Conditional_68_Template(rf, ctx) { if
|
|
|
1777
1804
|
i0.ɵɵproperty("PanelMode", true)("selectedTestId", (ctx_r0.testingDialogService.PanelOptions == null ? null : ctx_r0.testingDialogService.PanelOptions.testId) ?? null)("selectedSuiteId", (ctx_r0.testingDialogService.PanelOptions == null ? null : ctx_r0.testingDialogService.PanelOptions.suiteId) ?? null)("runMode", (ctx_r0.testingDialogService.PanelOptions == null ? null : ctx_r0.testingDialogService.PanelOptions.mode) ?? "suite");
|
|
1778
1805
|
} }
|
|
1779
1806
|
function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_12_Template(rf, ctx) { if (rf & 1) {
|
|
1780
|
-
const
|
|
1781
|
-
i0.ɵɵelementStart(0, "button",
|
|
1782
|
-
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_12_Template_button_click_0_listener() { i0.ɵɵrestoreView(
|
|
1783
|
-
i0.ɵɵelement(1, "i",
|
|
1807
|
+
const _r53 = i0.ɵɵgetCurrentView();
|
|
1808
|
+
i0.ɵɵelementStart(0, "button", 350);
|
|
1809
|
+
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_12_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r53); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.addTestsSearch = ""); });
|
|
1810
|
+
i0.ɵɵelement(1, "i", 93);
|
|
1784
1811
|
i0.ɵɵelementEnd();
|
|
1785
1812
|
} }
|
|
1786
1813
|
function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_15_Template(rf, ctx) { if (rf & 1) {
|
|
@@ -1800,84 +1827,84 @@ function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_16_Template
|
|
|
1800
1827
|
i0.ɵɵtextInterpolate2(" ", ctx_r0.filteredAvailableTests.length, " test", ctx_r0.filteredAvailableTests.length === 1 ? "" : "s", " available ");
|
|
1801
1828
|
} }
|
|
1802
1829
|
function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_23_Template(rf, ctx) { if (rf & 1) {
|
|
1803
|
-
i0.ɵɵelementStart(0, "div",
|
|
1804
|
-
i0.ɵɵelement(1, "mj-loading",
|
|
1830
|
+
i0.ɵɵelementStart(0, "div", 345);
|
|
1831
|
+
i0.ɵɵelement(1, "mj-loading", 351);
|
|
1805
1832
|
i0.ɵɵelementEnd();
|
|
1806
1833
|
} }
|
|
1807
1834
|
function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_24_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
1808
|
-
i0.ɵɵelement(0, "mj-empty-state",
|
|
1835
|
+
i0.ɵɵelement(0, "mj-empty-state", 352);
|
|
1809
1836
|
} }
|
|
1810
1837
|
function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_24_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
1811
|
-
i0.ɵɵelement(0, "mj-empty-state",
|
|
1838
|
+
i0.ɵɵelement(0, "mj-empty-state", 353);
|
|
1812
1839
|
} if (rf & 2) {
|
|
1813
1840
|
const ctx_r0 = i0.ɵɵnextContext(3);
|
|
1814
1841
|
i0.ɵɵproperty("Message", ctx_r0.AddTestsNoMatchMessage);
|
|
1815
1842
|
} }
|
|
1816
1843
|
function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_24_Template(rf, ctx) { if (rf & 1) {
|
|
1817
|
-
i0.ɵɵconditionalCreate(0, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_24_Conditional_0_Template, 1, 0, "mj-empty-state",
|
|
1844
|
+
i0.ɵɵconditionalCreate(0, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_24_Conditional_0_Template, 1, 0, "mj-empty-state", 352)(1, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_24_Conditional_1_Template, 1, 1, "mj-empty-state", 353);
|
|
1818
1845
|
} if (rf & 2) {
|
|
1819
1846
|
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
1820
1847
|
i0.ɵɵconditional(ctx_r0.availableTests.length === 0 ? 0 : 1);
|
|
1821
1848
|
} }
|
|
1822
1849
|
function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_25_For_2_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
1823
|
-
i0.ɵɵelement(0, "i",
|
|
1850
|
+
i0.ɵɵelement(0, "i", 179);
|
|
1824
1851
|
} }
|
|
1825
1852
|
function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_25_For_2_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
1826
|
-
i0.ɵɵelementStart(0, "div",
|
|
1853
|
+
i0.ɵɵelementStart(0, "div", 359);
|
|
1827
1854
|
i0.ɵɵtext(1);
|
|
1828
1855
|
i0.ɵɵelementEnd();
|
|
1829
1856
|
} if (rf & 2) {
|
|
1830
|
-
const
|
|
1857
|
+
const t_r55 = i0.ɵɵnextContext().$implicit;
|
|
1831
1858
|
i0.ɵɵadvance();
|
|
1832
|
-
i0.ɵɵtextInterpolate(
|
|
1859
|
+
i0.ɵɵtextInterpolate(t_r55.Description);
|
|
1833
1860
|
} }
|
|
1834
1861
|
function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_25_For_2_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
1835
|
-
i0.ɵɵelementStart(0, "span",
|
|
1862
|
+
i0.ɵɵelementStart(0, "span", 361);
|
|
1836
1863
|
i0.ɵɵtext(1);
|
|
1837
1864
|
i0.ɵɵelementEnd();
|
|
1838
1865
|
} if (rf & 2) {
|
|
1839
|
-
const
|
|
1866
|
+
const t_r55 = i0.ɵɵnextContext().$implicit;
|
|
1840
1867
|
i0.ɵɵadvance();
|
|
1841
|
-
i0.ɵɵtextInterpolate(
|
|
1868
|
+
i0.ɵɵtextInterpolate(t_r55.Type);
|
|
1842
1869
|
} }
|
|
1843
1870
|
function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_25_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
1844
|
-
const
|
|
1845
|
-
i0.ɵɵelementStart(0, "li",
|
|
1846
|
-
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_25_For_2_Template_li_click_0_listener() { const
|
|
1847
|
-
i0.ɵɵelementStart(1, "span",
|
|
1848
|
-
i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_25_For_2_Conditional_2_Template, 1, 0, "i",
|
|
1871
|
+
const _r54 = i0.ɵɵgetCurrentView();
|
|
1872
|
+
i0.ɵɵelementStart(0, "li", 355);
|
|
1873
|
+
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_25_For_2_Template_li_click_0_listener() { const t_r55 = i0.ɵɵrestoreView(_r54).$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.toggleAddSelection(t_r55.ID)); });
|
|
1874
|
+
i0.ɵɵelementStart(1, "span", 356);
|
|
1875
|
+
i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_25_For_2_Conditional_2_Template, 1, 0, "i", 179);
|
|
1849
1876
|
i0.ɵɵelementEnd();
|
|
1850
|
-
i0.ɵɵelementStart(3, "div",
|
|
1877
|
+
i0.ɵɵelementStart(3, "div", 357)(4, "div", 358);
|
|
1851
1878
|
i0.ɵɵtext(5);
|
|
1852
1879
|
i0.ɵɵelementEnd();
|
|
1853
|
-
i0.ɵɵconditionalCreate(6, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_25_For_2_Conditional_6_Template, 2, 1, "div",
|
|
1880
|
+
i0.ɵɵconditionalCreate(6, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_25_For_2_Conditional_6_Template, 2, 1, "div", 359);
|
|
1854
1881
|
i0.ɵɵelementEnd();
|
|
1855
|
-
i0.ɵɵelementStart(7, "div",
|
|
1856
|
-
i0.ɵɵconditionalCreate(8, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_25_For_2_Conditional_8_Template, 2, 1, "span",
|
|
1857
|
-
i0.ɵɵelementStart(9, "span",
|
|
1882
|
+
i0.ɵɵelementStart(7, "div", 360);
|
|
1883
|
+
i0.ɵɵconditionalCreate(8, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_25_For_2_Conditional_8_Template, 2, 1, "span", 361);
|
|
1884
|
+
i0.ɵɵelementStart(9, "span", 362);
|
|
1858
1885
|
i0.ɵɵtext(10);
|
|
1859
1886
|
i0.ɵɵelementEnd()()();
|
|
1860
1887
|
} if (rf & 2) {
|
|
1861
|
-
const
|
|
1888
|
+
const t_r55 = ctx.$implicit;
|
|
1862
1889
|
const ctx_r0 = i0.ɵɵnextContext(3);
|
|
1863
|
-
i0.ɵɵclassProp("picker-row--selected", ctx_r0.isAddSelected(
|
|
1864
|
-
i0.ɵɵattribute("aria-checked", ctx_r0.isAddSelected(
|
|
1890
|
+
i0.ɵɵclassProp("picker-row--selected", ctx_r0.isAddSelected(t_r55.ID));
|
|
1891
|
+
i0.ɵɵattribute("aria-checked", ctx_r0.isAddSelected(t_r55.ID));
|
|
1865
1892
|
i0.ɵɵadvance(2);
|
|
1866
|
-
i0.ɵɵconditional(ctx_r0.isAddSelected(
|
|
1893
|
+
i0.ɵɵconditional(ctx_r0.isAddSelected(t_r55.ID) ? 2 : -1);
|
|
1867
1894
|
i0.ɵɵadvance(3);
|
|
1868
|
-
i0.ɵɵtextInterpolate(
|
|
1895
|
+
i0.ɵɵtextInterpolate(t_r55.Name);
|
|
1869
1896
|
i0.ɵɵadvance();
|
|
1870
|
-
i0.ɵɵconditional(
|
|
1897
|
+
i0.ɵɵconditional(t_r55.Description ? 6 : -1);
|
|
1871
1898
|
i0.ɵɵadvance(2);
|
|
1872
|
-
i0.ɵɵconditional(
|
|
1899
|
+
i0.ɵɵconditional(t_r55.Type ? 8 : -1);
|
|
1873
1900
|
i0.ɵɵadvance();
|
|
1874
|
-
i0.ɵɵattribute("data-status",
|
|
1901
|
+
i0.ɵɵattribute("data-status", t_r55.Status == null ? null : t_r55.Status.toLowerCase());
|
|
1875
1902
|
i0.ɵɵadvance();
|
|
1876
|
-
i0.ɵɵtextInterpolate(
|
|
1903
|
+
i0.ɵɵtextInterpolate(t_r55.Status);
|
|
1877
1904
|
} }
|
|
1878
1905
|
function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_25_Template(rf, ctx) { if (rf & 1) {
|
|
1879
|
-
i0.ɵɵelementStart(0, "ul",
|
|
1880
|
-
i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_25_For_2_Template, 11, 9, "li",
|
|
1906
|
+
i0.ɵɵelementStart(0, "ul", 346);
|
|
1907
|
+
i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_25_For_2_Template, 11, 9, "li", 354, _forTrack1);
|
|
1881
1908
|
i0.ɵɵelementEnd();
|
|
1882
1909
|
} if (rf & 2) {
|
|
1883
1910
|
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
@@ -1885,7 +1912,7 @@ function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_25_Template
|
|
|
1885
1912
|
i0.ɵɵrepeater(ctx_r0.filteredAvailableTests);
|
|
1886
1913
|
} }
|
|
1887
1914
|
function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_28_Template(rf, ctx) { if (rf & 1) {
|
|
1888
|
-
i0.ɵɵelement(0, "i",
|
|
1915
|
+
i0.ɵɵelement(0, "i", 125);
|
|
1889
1916
|
i0.ɵɵtext(1, " Adding\u2026 ");
|
|
1890
1917
|
} }
|
|
1891
1918
|
function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_29_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
@@ -1901,7 +1928,7 @@ function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_29_Conditio
|
|
|
1901
1928
|
i0.ɵɵtextInterpolate1(" Add ", ctx_r0.selectedTestIdsToAdd.size, " tests ");
|
|
1902
1929
|
} }
|
|
1903
1930
|
function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_29_Template(rf, ctx) { if (rf & 1) {
|
|
1904
|
-
i0.ɵɵelement(0, "i",
|
|
1931
|
+
i0.ɵɵelement(0, "i", 179);
|
|
1905
1932
|
i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_29_Conditional_1_Template, 1, 0)(2, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_29_Conditional_2_Template, 1, 0)(3, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_29_Conditional_3_Template, 1, 1);
|
|
1906
1933
|
} if (rf & 2) {
|
|
1907
1934
|
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
@@ -1909,47 +1936,47 @@ function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_29_Template
|
|
|
1909
1936
|
i0.ɵɵconditional(ctx_r0.selectedTestIdsToAdd.size === 0 ? 1 : ctx_r0.selectedTestIdsToAdd.size === 1 ? 2 : 3);
|
|
1910
1937
|
} }
|
|
1911
1938
|
function MJTestSuiteFormComponentExtended_Conditional_69_Template(rf, ctx) { if (rf & 1) {
|
|
1912
|
-
const
|
|
1913
|
-
i0.ɵɵelementStart(0, "div",
|
|
1914
|
-
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_69_Template_div_click_0_listener() { i0.ɵɵrestoreView(
|
|
1939
|
+
const _r52 = i0.ɵɵgetCurrentView();
|
|
1940
|
+
i0.ɵɵelementStart(0, "div", 330);
|
|
1941
|
+
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_69_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r52); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.closeAddTestsDialog()); });
|
|
1915
1942
|
i0.ɵɵelementEnd();
|
|
1916
|
-
i0.ɵɵelementStart(1, "div",
|
|
1943
|
+
i0.ɵɵelementStart(1, "div", 331);
|
|
1917
1944
|
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_69_Template_div_click_1_listener($event) { return $event.stopPropagation(); });
|
|
1918
|
-
i0.ɵɵelementStart(2, "div",
|
|
1919
|
-
i0.ɵɵelement(4, "i",
|
|
1945
|
+
i0.ɵɵelementStart(2, "div", 332)(3, "h2", 333);
|
|
1946
|
+
i0.ɵɵelement(4, "i", 334);
|
|
1920
1947
|
i0.ɵɵtext(5, " Add tests to suite ");
|
|
1921
1948
|
i0.ɵɵelementEnd();
|
|
1922
|
-
i0.ɵɵelementStart(6, "button",
|
|
1923
|
-
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_69_Template_button_click_6_listener() { i0.ɵɵrestoreView(
|
|
1924
|
-
i0.ɵɵelement(7, "i",
|
|
1949
|
+
i0.ɵɵelementStart(6, "button", 335);
|
|
1950
|
+
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_69_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r52); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.closeAddTestsDialog()); });
|
|
1951
|
+
i0.ɵɵelement(7, "i", 93);
|
|
1925
1952
|
i0.ɵɵelementEnd()();
|
|
1926
|
-
i0.ɵɵelementStart(8, "div",
|
|
1927
|
-
i0.ɵɵelement(9, "i",
|
|
1928
|
-
i0.ɵɵelementStart(10, "input",
|
|
1929
|
-
i0.ɵɵtwoWayListener("ngModelChange", function MJTestSuiteFormComponentExtended_Conditional_69_Template_input_ngModelChange_10_listener($event) { i0.ɵɵrestoreView(
|
|
1953
|
+
i0.ɵɵelementStart(8, "div", 336);
|
|
1954
|
+
i0.ɵɵelement(9, "i", 337);
|
|
1955
|
+
i0.ɵɵelementStart(10, "input", 338, 2);
|
|
1956
|
+
i0.ɵɵtwoWayListener("ngModelChange", function MJTestSuiteFormComponentExtended_Conditional_69_Template_input_ngModelChange_10_listener($event) { i0.ɵɵrestoreView(_r52); const ctx_r0 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r0.addTestsSearch, $event) || (ctx_r0.addTestsSearch = $event); return i0.ɵɵresetView($event); });
|
|
1930
1957
|
i0.ɵɵelementEnd();
|
|
1931
|
-
i0.ɵɵconditionalCreate(12, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_12_Template, 2, 0, "button",
|
|
1958
|
+
i0.ɵɵconditionalCreate(12, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_12_Template, 2, 0, "button", 339);
|
|
1932
1959
|
i0.ɵɵelementEnd();
|
|
1933
|
-
i0.ɵɵelementStart(13, "div",
|
|
1960
|
+
i0.ɵɵelementStart(13, "div", 340)(14, "span", 341);
|
|
1934
1961
|
i0.ɵɵconditionalCreate(15, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_15_Template, 3, 1)(16, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_16_Template, 1, 2);
|
|
1935
1962
|
i0.ɵɵelementEnd();
|
|
1936
|
-
i0.ɵɵelementStart(17, "div",
|
|
1937
|
-
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_69_Template_button_click_18_listener() { i0.ɵɵrestoreView(
|
|
1963
|
+
i0.ɵɵelementStart(17, "div", 342)(18, "button", 343);
|
|
1964
|
+
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_69_Template_button_click_18_listener() { i0.ɵɵrestoreView(_r52); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.selectAllFiltered()); });
|
|
1938
1965
|
i0.ɵɵtext(19, " Select all ");
|
|
1939
1966
|
i0.ɵɵelementEnd();
|
|
1940
|
-
i0.ɵɵelementStart(20, "button",
|
|
1941
|
-
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_69_Template_button_click_20_listener() { i0.ɵɵrestoreView(
|
|
1967
|
+
i0.ɵɵelementStart(20, "button", 343);
|
|
1968
|
+
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_69_Template_button_click_20_listener() { i0.ɵɵrestoreView(_r52); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.clearAddSelection()); });
|
|
1942
1969
|
i0.ɵɵtext(21, " Clear ");
|
|
1943
1970
|
i0.ɵɵelementEnd()()();
|
|
1944
|
-
i0.ɵɵelementStart(22, "div",
|
|
1945
|
-
i0.ɵɵconditionalCreate(23, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_23_Template, 2, 0, "div",
|
|
1971
|
+
i0.ɵɵelementStart(22, "div", 344);
|
|
1972
|
+
i0.ɵɵconditionalCreate(23, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_23_Template, 2, 0, "div", 345)(24, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_24_Template, 2, 1)(25, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_25_Template, 3, 0, "ul", 346);
|
|
1946
1973
|
i0.ɵɵelementEnd();
|
|
1947
|
-
i0.ɵɵelementStart(26, "div",
|
|
1948
|
-
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_69_Template_button_click_27_listener() { i0.ɵɵrestoreView(
|
|
1974
|
+
i0.ɵɵelementStart(26, "div", 347)(27, "button", 348);
|
|
1975
|
+
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_69_Template_button_click_27_listener() { i0.ɵɵrestoreView(_r52); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.confirmAddTests()); });
|
|
1949
1976
|
i0.ɵɵconditionalCreate(28, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_28_Template, 2, 0)(29, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_29_Template, 4, 1);
|
|
1950
1977
|
i0.ɵɵelementEnd();
|
|
1951
|
-
i0.ɵɵelementStart(30, "button",
|
|
1952
|
-
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_69_Template_button_click_30_listener() { i0.ɵɵrestoreView(
|
|
1978
|
+
i0.ɵɵelementStart(30, "button", 349);
|
|
1979
|
+
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_69_Template_button_click_30_listener() { i0.ɵɵrestoreView(_r52); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.closeAddTestsDialog()); });
|
|
1953
1980
|
i0.ɵɵtext(31, " Cancel ");
|
|
1954
1981
|
i0.ɵɵelementEnd()()();
|
|
1955
1982
|
} if (rf & 2) {
|
|
@@ -1988,13 +2015,13 @@ function MJTestSuiteFormComponentExtended_Conditional_79_Template(rf, ctx) { if
|
|
|
1988
2015
|
i0.ɵɵtextInterpolate1(" ", ctx_r0.dirtyFieldNames.length, " fields edited ");
|
|
1989
2016
|
} }
|
|
1990
2017
|
function MJTestSuiteFormComponentExtended_Conditional_82_Template(rf, ctx) { if (rf & 1) {
|
|
1991
|
-
i0.ɵɵelement(0, "i",
|
|
2018
|
+
i0.ɵɵelement(0, "i", 125);
|
|
1992
2019
|
i0.ɵɵtext(1, " Saving\u2026 ");
|
|
1993
2020
|
} }
|
|
1994
2021
|
function MJTestSuiteFormComponentExtended_Conditional_83_Template(rf, ctx) { if (rf & 1) {
|
|
1995
|
-
i0.ɵɵelement(0, "i",
|
|
2022
|
+
i0.ɵɵelement(0, "i", 179);
|
|
1996
2023
|
i0.ɵɵtext(1, " Save changes ");
|
|
1997
|
-
i0.ɵɵelementStart(2, "span",
|
|
2024
|
+
i0.ɵɵelementStart(2, "span", 363)(3, "kbd");
|
|
1998
2025
|
i0.ɵɵtext(4, "\u2318");
|
|
1999
2026
|
i0.ɵɵelementEnd();
|
|
2000
2027
|
i0.ɵɵelementStart(5, "kbd");
|
|
@@ -2057,6 +2084,7 @@ let MJTestSuiteFormComponentExtended = class MJTestSuiteFormComponentExtended ex
|
|
|
2057
2084
|
// Edit state
|
|
2058
2085
|
this.IsSaving = false;
|
|
2059
2086
|
this.ParentSuiteOptions = [];
|
|
2087
|
+
this.RubricOptions = [];
|
|
2060
2088
|
this.TagDraft = '';
|
|
2061
2089
|
this.StatusOptions = ['Active', 'Pending', 'Disabled'];
|
|
2062
2090
|
// Add Tests picker state
|
|
@@ -2457,6 +2485,7 @@ let MJTestSuiteFormComponentExtended = class MJTestSuiteFormComponentExtended ex
|
|
|
2457
2485
|
this.loadShortcutsSetting();
|
|
2458
2486
|
// Fire-and-forget: parent suite list for the edit form
|
|
2459
2487
|
this.loadParentSuiteOptions();
|
|
2488
|
+
void this.loadRubricOptions();
|
|
2460
2489
|
// Subscribe to evaluation preferences
|
|
2461
2490
|
this.evalPrefsService.preferences$
|
|
2462
2491
|
.pipe(takeUntil(this.destroy$))
|
|
@@ -4391,6 +4420,17 @@ let MJTestSuiteFormComponentExtended = class MJTestSuiteFormComponentExtended ex
|
|
|
4391
4420
|
* Load all suites for the Parent Suite dropdown. Excludes the current
|
|
4392
4421
|
* suite (a suite cannot be its own parent).
|
|
4393
4422
|
*/
|
|
4423
|
+
async loadRubricOptions() {
|
|
4424
|
+
try {
|
|
4425
|
+
const rv = RunView.FromMetadataProvider(this.ProviderToUse);
|
|
4426
|
+
const result = await rv.RunView({ EntityName: 'MJ: Rubrics', ExtraFilter: `Status='Active'`, OrderBy: 'Name', ResultType: 'simple', MaxRows: 500 });
|
|
4427
|
+
this.RubricOptions = RubricPickerOptions((result.Results ?? []));
|
|
4428
|
+
this.cdr.markForCheck();
|
|
4429
|
+
}
|
|
4430
|
+
catch (error) {
|
|
4431
|
+
console.warn('Failed to load rubric options:', error);
|
|
4432
|
+
}
|
|
4433
|
+
}
|
|
4394
4434
|
async loadParentSuiteOptions() {
|
|
4395
4435
|
try {
|
|
4396
4436
|
const rv = RunView.FromMetadataProvider(this.ProviderToUse);
|
|
@@ -4795,7 +4835,7 @@ let MJTestSuiteFormComponentExtended = class MJTestSuiteFormComponentExtended ex
|
|
|
4795
4835
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.ChartContainer = _t.first);
|
|
4796
4836
|
} }, hostBindings: function MJTestSuiteFormComponentExtended_HostBindings(rf, ctx) { if (rf & 1) {
|
|
4797
4837
|
i0.ɵɵlistener("keydown", function MJTestSuiteFormComponentExtended_keydown_HostBindingHandler($event) { return ctx.handleKeyboardShortcut($event); }, i0.ɵɵresolveDocument)("beforeunload", function MJTestSuiteFormComponentExtended_beforeunload_HostBindingHandler($event) { return ctx.handleBeforeUnload($event); }, i0.ɵɵresolveWindow);
|
|
4798
|
-
} }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 87, vars: 51, consts: [["tagInput", ""], ["chartContainer", ""], ["pickerSearch", ""], [1, "test-suite-form"], [1, "suite-header"], ["aria-label", "Breadcrumb", 1, "breadcrumb"], ["href", "javascript:void(0)", 3, "click"], [1, "fas", "fa-vial"], [1, "breadcrumb-text"], [1, "current"], [1, "fas", "fa-chevron-right", "separator"], [1, "fas", "fa-layer-group"], [1, "header-content"], [1, "header-left"], [1, "suite-icon"], [1, "suite-info"], ["title", "You have unsaved changes", "aria-label", "Unsaved changes", 1, "dirty-indicator"], [1, "suite-meta"], [1, "status-badge", 3, "ngClass"], [1, "fas", 3, "ngClass"], [1, "test-count"], ["title", "You have unsaved changes", 1, "unsaved-pill"], [1, "header-actions"], ["mjButton", "", "title", "Export to CSV", 3, "click"], [1, "fas", "fa-file-excel"], ["mjButton", "", "variant", "primary", 3, "click"], [1, "fas", "fa-play"], ["mjButton", "", 3, "click", "disabled"], [1, "suite-description"], [1, "tabs-container"], ["role", "tablist", 1, "tabs"], ["role", "tab", 1, "tab", 3, "click"], [1, "fas", "fa-th-large"], [1, "fas", "fa-flask"], [1, "tab-badge"], [1, "fas", "fa-history"], [1, "fas", "fa-chart-line"], [1, "fas", "fa-balance-scale"], [1, "tab-content"], [1, "overview-tab"], [1, "tests-tab"], [1, "runs-tab"], [1, "analytics-tab"], [1, "compare-tab"], [1, "shortcuts-toggle", 3, "click", "title"], [1, "fas", "fa-keyboard"], [1, "keyboard-shortcuts"], ["Mode", "slide", 3, "Title", "Resizable"], ["role", "region", "aria-label", "Unsaved changes", 1, "save-bar"], [1, "save-bar-message"], ["aria-hidden", "true", 1, "save-bar-dot"], [1, "save-bar-text"], [1, "save-bar-fields"], [1, "save-bar-actions"], ["type", "button", "title", "Save changes (\u2318S)", 1, "save-bar-btn", "save-bar-btn--primary", 3, "click", "disabled"], ["type", "button", "title", "Discard changes", 1, "save-bar-btn", "save-bar-btn--ghost", 3, "click", "disabled"], [1, "fas", "fa-undo"], [1, "fas", "fa-circle"], [1, "edit-section"], [1, "edit-section-header"], [1, "fas", "fa-pen-to-square"], [1, "edit-section-sub"], [1, "edit-grid"], [1, "edit-field", "edit-field--full"], ["for", "suite-name"], [1, "required"], ["id", "suite-name", "type", "text", "placeholder", "e.g., Core Agent Test Suite", 1, "config-input", 3, "ngModelChange", "ngModel"], ["for", "suite-description"], ["id", "suite-description", "rows", "3", "placeholder", "What does this suite cover?", 1, "config-input", "config-textarea", 3, "ngModelChange", "ngModel"], [1, "edit-field"], ["for", "suite-status"], [1, "select-wrapper"], ["id", "suite-status", 1, "config-input", 3, "ngModelChange", "ngModel"], [3, "ngValue"], ["for", "suite-parent"], ["id", "suite-parent", 1, "config-input", 3, "ngModelChange", "ngModel"], ["for", "suite-tags"], [1, "tag-editor", 3, "click"], [1, "tag-chip-editable"], ["id", "suite-tags", "type", "text", 1, "tag-input-inline", 3, "ngModelChange", "keydown", "blur", "placeholder", "ngModel"], [1, "config-hint"], [1, "fas", "fa-cogs"], ["for", "suite-timeout"], ["id", "suite-timeout", "type", "number", "placeholder", "Default: 300000 (5 min)", 1, "config-input", 3, "ngModelChange", "ngModel"], [1, "meta-section"], [1, "meta-grid"], [1, "meta-item"], [1, "meta-label"], [1, "meta-value"], [1, "meta-value", "meta-mono"], ["type", "button", 1, "tag-remove", 3, "click"], [1, "fas", "fa-times"], [1, "tests-actionbar"], [1, "tests-actionbar-text"], [1, "tests-actionbar-count"], [1, "tests-actionbar-hint"], [1, "tests-actionbar-actions"], ["mjButton", "", "variant", "primary", 3, "click", "disabled"], [1, "fas", "fa-plus"], [1, "loading-state"], ["cdkDropList", "", 1, "tests-list"], ["Icon", "fa-solid fa-flask", "Title", "No Tests in Suite", "Message", "Add tests to this suite to start running them together.", "ActionText", "Add tests", "ActionIcon", "fa-solid fa-plus"], [1, "skeleton-list"], [1, "skeleton-card"], [1, "skeleton-sequence"], [1, "skeleton-icon"], [1, "skeleton-content"], [1, "skeleton-line", "wide"], [1, "skeleton-line", "narrow"], ["cdkDropList", "", 1, "tests-list", 3, "cdkDropListDropped"], ["cdkDrag", "", 1, "test-item", 3, "cdkDragDisabled"], ["cdkDragHandle", "", "title", "Drag to reorder", "aria-label", "Drag to reorder", 1, "test-drag-handle"], [1, "fas", "fa-grip-vertical"], [1, "test-sequence"], [1, "test-icon"], [1, "test-content", 3, "click"], [1, "test-name"], [1, "test-status"], [1, "test-remove-confirm"], [1, "fas", "fa-info-circle"], [1, "test-remove-confirm", 3, "click"], [1, "test-remove-confirm-text"], ["type", "button", 1, "test-remove-confirm-btn", "test-remove-confirm-btn--danger", 3, "click", "disabled"], [1, "fas", "fa-spinner", "fa-spin"], ["type", "button", 1, "test-remove-confirm-btn", "test-remove-confirm-btn--ghost", 3, "click", "disabled"], ["type", "button", "title", "Remove from suite", "aria-label", "Remove from suite", 1, "test-remove-btn", 3, "click"], [1, "fas", "fa-chevron-right", "test-chevron", 3, "click"], ["Icon", "fa-solid fa-flask", "Title", "No Tests in Suite", "Message", "Add tests to this suite to start running them together.", "ActionText", "Add tests", "ActionIcon", "fa-solid fa-plus", 3, "Action"], [1, "runs-list"], ["Icon", "fa-solid fa-circle-play", "Title", "No Suite Runs Yet", "Message", "Run this suite to see execution history and results here.", "ActionText", "Run Suite Now", "ActionIcon", "fa-solid fa-play"], [1, "run-item"], [1, "run-item", 3, "click"], [1, "run-icon"], [1, "fas"], [1, "run-content"], [1, "run-header"], [1, "run-id"], [1, "run-status"], [1, "run-meta"], [1, "fas", "fa-calendar"], [1, "run-eval-metrics"], [1, "eval-metric", "status", 3, "class"], ["title", "Human evaluation", 1, "eval-metric", "human"], ["title", "Auto score (pass rate)", 1, "eval-metric", "auto", 3, "high", "medium", "low"], [1, "run-tags"], [1, "fas", "fa-chevron-right"], [1, "fas", "fa-check-circle"], [1, "eval-metric", "status"], [1, "fas", "fa-user"], [1, "eval-pending"], [1, "fas", "fa-clock"], ["title", "Auto score (pass rate)", 1, "eval-metric", "auto"], [1, "fas", "fa-robot"], [1, "tag-chip"], ["Icon", "fa-solid fa-circle-play", "Title", "No Suite Runs Yet", "Message", "Run this suite to see execution history and results here.", "ActionText", "Run Suite Now", "ActionIcon", "fa-solid fa-play", 3, "Action"], ["Icon", "fa-solid fa-chart-line", "Title", "No Analytics Data", "Message", "Run this suite to start collecting analytics data.", "ActionText", "Run Suite Now", "ActionIcon", "fa-solid fa-play"], ["text", "Loading analytics data..."], [1, "analytics-subnav"], [1, "subnav-tabs"], [1, "subnav-tab", 3, "click"], [1, "fas", "fa-chart-bar"], [1, "fas", "fa-th"], [1, "fas", "fa-project-diagram"], ["Size", "sm", 3, "ExpandedChange", "FlushBody", "Expanded"], ["mjAccordionTitle", ""], ["mjAccordionBody", ""], [1, "fas", "fa-filter", 2, "color", "var(--test-primary)"], [1, "mj-accordion-badge", "mj-accordion-badge--right", "mj-accordion-badge--muted"], [1, "filters-content"], [1, "filter-group"], [1, "filter-buttons"], [1, "filter-btn", 3, "click"], [1, "filter-hint"], [1, "filter-buttons", "tag-filters"], [1, "filter-btn", "tag-btn", "all-tags-btn", 3, "click"], [1, "filter-btn", "tag-btn", 3, "active"], [1, "filter-btn", "tag-btn", 3, "click"], [1, "fas", "fa-check"], [1, "analytics-kpis"], [1, "kpi-card"], [1, "kpi-icon"], [1, "fas", "fa-play-circle"], [1, "kpi-content"], [1, "kpi-value"], [1, "kpi-label"], [1, "kpi-icon", "success"], [1, "kpi-trend", 3, "ngClass"], [1, "kpi-icon", "info"], [1, "kpi-icon", "warning"], [1, "fas", "fa-dollar-sign"], [1, "analytics-table-section"], [1, "fas", "fa-table"], [1, "analytics-table-wrapper"], [1, "analytics-table"], [1, "clickable-row"], ["Variant", "no-results", "Size", "compact", "Title", "No runs match the current filters."], [1, "clickable-row", 3, "click"], [1, "status-chip", 3, "ngClass"], [1, "pass-rate-cell"], [1, "pass-rate-bar", 3, "ngClass"], [1, "tag-cell"], [1, "tag-chip-table"], [1, "tag-more"], [1, "matrix-section"], ["Variant", "no-results", "Icon", "fa-solid fa-table-cells", "Title", "No Matrix Data", "Message", "No suite runs match the current filters."], ["text", "Loading test matrix..."], [1, "matrix-header"], [1, "matrix-header-right"], [1, "matrix-filter-input"], [1, "fas", "fa-search"], ["type", "text", "placeholder", "Filter tests...", 1, "filter-input", 3, "input", "value"], ["title", "Clear filter", 1, "clear-filter-btn"], [1, "matrix-run-count"], ["mjButton", "", "title", "Export matrix to CSV", 3, "click", "disabled"], [1, "fas", "fa-download"], [1, "matrix-scroll-container"], [1, "test-matrix"], ["title", "Sort by sequence", 1, "seq-header", 3, "click"], ["title", "Sort by name", 1, "test-name-header", 3, "click"], [1, "run-header", 3, "title"], [1, "spacer-header"], [3, "row-selected"], [1, "totals-row"], [1, "seq-cell", "totals-label"], [1, "test-name-cell", "totals-label"], [1, "result-cell", "totals-cell"], [1, "spacer-cell"], ["title", "Clear filter", 1, "clear-filter-btn", 3, "click"], [1, "run-header", 3, "click", "title"], [1, "run-header-content"], [1, "run-tags-header"], [1, "run-date"], [1, "run-pass-rate", 3, "ngClass"], [1, "tag-chip-header"], [1, "tag-more-header"], [3, "click"], [1, "seq-cell"], [1, "test-name-cell"], [1, "test-name", 3, "title"], [1, "result-cell", 3, "ngClass", "clickable", "cell-not-run", "title"], [1, "result-cell", 3, "click", "ngClass", "title"], [1, "cell-eval-stack"], [1, "cell-not-run-indicator"], [1, "cell-status", 3, "ngClass", "cell-skipped-status", "title"], ["title", "Human Review: No rating submitted yet", 1, "cell-human", "no-feedback"], [1, "cell-human", "has-feedback", 3, "rating-low", "rating-medium", "rating-good", "rating-excellent", "title"], [1, "cell-auto", "has-score", 3, "score-low", "score-medium", "score-good", "score-excellent", "title"], ["title", "Auto Score: No automated score available", 1, "cell-auto", "no-score"], [1, "cell-status", 3, "ngClass", "title"], [1, "fas", "fa-user-slash"], [1, "cell-human", "has-feedback", 3, "title"], [1, "rating-value"], [1, "cell-auto", "has-score", 3, "title"], [1, "score-value"], [1, "fas", "fa-minus"], [1, "cell-eval-stack", "totals-stack"], [1, "totals-status"], [1, "totals-human"], [1, "totals-auto"], [1, "pass-count"], [1, "avg-label"], [1, "count-label"], [1, "chart-section"], ["Variant", "no-results", "Icon", "fa-solid fa-diagram-project", "Title", "No Chart Data", "Message", "No suite runs match the current filters."], ["text", "Loading chart data..."], [1, "chart-header"], [1, "chart-legend"], [1, "legend-item", "chart-passed"], [1, "legend-item", "chart-failed"], [1, "legend-item", "chart-error"], [1, "fas", "fa-exclamation"], [1, "legend-item", "chart-skipped"], [1, "fas", "fa-forward"], [1, "chart-container"], [1, "d3-chart"], [1, "chart-info"], ["Icon", "fa-solid fa-chart-line", "Title", "No Analytics Data", "Message", "Run this suite to start collecting analytics data.", "ActionText", "Run Suite Now", "ActionIcon", "fa-solid fa-play", 3, "Action"], [1, "compare-selection"], [1, "compare-run-selector"], [1, "run-selector-list"], [1, "selected-run-preview"], [1, "compare-vs"], [1, "fas", "fa-exchange-alt"], [1, "compare-results"], ["Icon", "fa-solid fa-scale-balanced", "Title", "Select Two Runs to Compare", "Message", "Choose a baseline run (A) and a comparison run (B) from the lists above to see a detailed side-by-side comparison."], ["Icon", "fa-solid fa-scale-balanced", "Title", "Not Enough Runs to Compare", "Message", "You need at least 2 suite runs to use the comparison feature.", "ActionText", "Run Suite Now", "ActionIcon", "fa-solid fa-play"], [1, "run-selector-item", 3, "selected"], [1, "run-selector-item", 3, "click"], [1, "selector-status"], [1, "selector-content"], [1, "selector-date"], [1, "selector-rate"], [1, "selector-tags"], [1, "tag-mini"], [1, "preview-header"], [1, "preview-label"], [1, "clear-btn", 3, "click"], [1, "preview-details"], [1, "preview-rate"], [1, "run-selector-item", 3, "selected", "disabled"], [1, "compare-summary"], [1, "compare-summary-card"], [1, "summary-label"], [1, "summary-value", 3, "ngClass"], [1, "compare-summary-card", "improved"], [1, "summary-value"], [1, "compare-summary-card", "regressed"], [1, "compare-table-section"], [1, "fas", "fa-list"], [1, "compare-table-wrapper"], [1, "compare-table"], [3, "ngClass"], [1, "status-chip", "status-missing"], [1, "muted"], [1, "change-indicator", "improved"], [1, "change-indicator", "regressed"], [1, "change-indicator", "unchanged"], [1, "fas", "fa-arrow-up"], [1, "fas", "fa-arrow-down"], ["text", "Loading comparison data..."], ["Icon", "fa-solid fa-scale-balanced", "Title", "Not Enough Runs to Compare", "Message", "You need at least 2 suite runs to use the comparison feature.", "ActionText", "Run Suite Now", "ActionIcon", "fa-solid fa-play", 3, "Action"], [1, "shortcuts-header"], ["title", "Hide shortcuts", 1, "shortcuts-close", 3, "click"], [1, "shortcut-list"], [1, "shortcut-item"], [1, "shortcut-keys"], ["Mode", "slide", 3, "Closed", "Title", "Resizable"], [3, "PanelClose", "PanelMode", "selectedTestId", "selectedSuiteId", "runMode"], [1, "picker-backdrop", 3, "click"], ["role", "dialog", "aria-modal", "true", "aria-labelledby", "add-tests-dialog-title", 1, "picker-dialog", 3, "click"], [1, "picker-header"], ["id", "add-tests-dialog-title", 1, "picker-title"], [1, "fas", "fa-plus-circle"], ["type", "button", "aria-label", "Close", 1, "picker-close", 3, "click", "disabled"], [1, "picker-search"], [1, "fas", "fa-search", "picker-search-icon"], ["type", "text", "placeholder", "Search tests by name, description, or type...", "autofocus", "", 1, "picker-search-input", 3, "ngModelChange", "ngModel"], ["type", "button", "aria-label", "Clear search", 1, "picker-search-clear"], [1, "picker-toolbar"], [1, "picker-toolbar-status"], [1, "picker-toolbar-actions"], ["type", "button", 1, "picker-link-btn", 3, "click", "disabled"], [1, "picker-body"], [1, "picker-loading"], [1, "picker-list"], [1, "picker-footer"], ["type", "button", 1, "picker-btn", "picker-btn--primary", 3, "click", "disabled"], ["type", "button", 1, "picker-btn", "picker-btn--ghost", 3, "click", "disabled"], ["type", "button", "aria-label", "Clear search", 1, "picker-search-clear", 3, "click"], ["text", "Loading tests..."], ["Variant", "success", "Size", "compact", "Title", "Everything's already in the suite", "Message", "This suite contains every available test. Create a new test first to add more."], ["Variant", "no-results", "Size", "compact", "Title", "No matches", 3, "Message"], ["role", "checkbox", "tabindex", "0", 1, "picker-row", 3, "picker-row--selected"], ["role", "checkbox", "tabindex", "0", 1, "picker-row", 3, "click"], [1, "picker-check"], [1, "picker-row-main"], [1, "picker-row-name"], [1, "picker-row-desc"], [1, "picker-row-meta"], [1, "picker-row-pill"], [1, "picker-row-pill", "picker-row-pill--status"], [1, "save-bar-kbd"]], template: function MJTestSuiteFormComponentExtended_Template(rf, ctx) { if (rf & 1) {
|
|
4838
|
+
} }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 87, vars: 51, consts: [["tagInput", ""], ["chartContainer", ""], ["pickerSearch", ""], [1, "test-suite-form"], [1, "suite-header"], ["aria-label", "Breadcrumb", 1, "breadcrumb"], ["href", "javascript:void(0)", 3, "click"], [1, "fas", "fa-vial"], [1, "breadcrumb-text"], [1, "current"], [1, "fas", "fa-chevron-right", "separator"], [1, "fas", "fa-layer-group"], [1, "header-content"], [1, "header-left"], [1, "suite-icon"], [1, "suite-info"], ["title", "You have unsaved changes", "aria-label", "Unsaved changes", 1, "dirty-indicator"], [1, "suite-meta"], [1, "status-badge", 3, "ngClass"], [1, "fas", 3, "ngClass"], [1, "test-count"], ["title", "You have unsaved changes", 1, "unsaved-pill"], [1, "header-actions"], ["mjButton", "", "title", "Export to CSV", 3, "click"], [1, "fas", "fa-file-excel"], ["mjButton", "", "variant", "primary", 3, "click"], [1, "fas", "fa-play"], ["mjButton", "", 3, "click", "disabled"], [1, "suite-description"], [1, "tabs-container"], ["role", "tablist", 1, "tabs"], ["role", "tab", 1, "tab", 3, "click"], [1, "fas", "fa-th-large"], [1, "fas", "fa-flask"], [1, "tab-badge"], [1, "fas", "fa-history"], [1, "fas", "fa-chart-line"], [1, "fas", "fa-balance-scale"], [1, "tab-content"], [1, "overview-tab"], [1, "tests-tab"], [1, "runs-tab"], [1, "analytics-tab"], [1, "compare-tab"], [1, "shortcuts-toggle", 3, "click", "title"], [1, "fas", "fa-keyboard"], [1, "keyboard-shortcuts"], ["Mode", "slide", 3, "Title", "Resizable"], ["role", "region", "aria-label", "Unsaved changes", 1, "save-bar"], [1, "save-bar-message"], ["aria-hidden", "true", 1, "save-bar-dot"], [1, "save-bar-text"], [1, "save-bar-fields"], [1, "save-bar-actions"], ["type", "button", "title", "Save changes (\u2318S)", 1, "save-bar-btn", "save-bar-btn--primary", 3, "click", "disabled"], ["type", "button", "title", "Discard changes", 1, "save-bar-btn", "save-bar-btn--ghost", 3, "click", "disabled"], [1, "fas", "fa-undo"], [1, "fas", "fa-circle"], [1, "edit-section"], [1, "edit-section-header"], [1, "fas", "fa-pen-to-square"], [1, "edit-section-sub"], [1, "edit-grid"], [1, "edit-field", "edit-field--full"], ["for", "suite-name"], [1, "required"], ["id", "suite-name", "type", "text", "placeholder", "e.g., Core Agent Test Suite", 1, "config-input", 3, "ngModelChange", "ngModel"], ["for", "suite-description"], ["id", "suite-description", "rows", "3", "placeholder", "What does this suite cover?", 1, "config-input", "config-textarea", 3, "ngModelChange", "ngModel"], [1, "edit-field"], ["for", "suite-status"], [1, "select-wrapper"], ["id", "suite-status", 1, "config-input", 3, "ngModelChange", "ngModel"], [3, "ngValue"], ["for", "suite-rubric"], ["id", "suite-rubric", 1, "config-input", 3, "ngModelChange", "ngModel"], ["for", "suite-parent"], ["id", "suite-parent", 1, "config-input", 3, "ngModelChange", "ngModel"], ["for", "suite-tags"], [1, "tag-editor", 3, "click"], [1, "tag-chip-editable"], ["id", "suite-tags", "type", "text", 1, "tag-input-inline", 3, "ngModelChange", "keydown", "blur", "placeholder", "ngModel"], [1, "config-hint"], [1, "fas", "fa-cogs"], ["for", "suite-timeout"], ["id", "suite-timeout", "type", "number", "placeholder", "Default: 300000 (5 min)", 1, "config-input", 3, "ngModelChange", "ngModel"], [1, "meta-section"], [1, "meta-grid"], [1, "meta-item"], [1, "meta-label"], [1, "meta-value"], [1, "meta-value", "meta-mono"], ["type", "button", 1, "tag-remove", 3, "click"], [1, "fas", "fa-times"], [1, "tests-actionbar"], [1, "tests-actionbar-text"], [1, "tests-actionbar-count"], [1, "tests-actionbar-hint"], [1, "tests-actionbar-actions"], ["mjButton", "", "variant", "primary", 3, "click", "disabled"], [1, "fas", "fa-plus"], [1, "loading-state"], ["cdkDropList", "", 1, "tests-list"], ["Icon", "fa-solid fa-flask", "Title", "No Tests in Suite", "Message", "Add tests to this suite to start running them together.", "ActionText", "Add tests", "ActionIcon", "fa-solid fa-plus"], [1, "skeleton-list"], [1, "skeleton-card"], [1, "skeleton-sequence"], [1, "skeleton-icon"], [1, "skeleton-content"], [1, "skeleton-line", "wide"], [1, "skeleton-line", "narrow"], ["cdkDropList", "", 1, "tests-list", 3, "cdkDropListDropped"], ["cdkDrag", "", 1, "test-item", 3, "cdkDragDisabled"], ["cdkDragHandle", "", "title", "Drag to reorder", "aria-label", "Drag to reorder", 1, "test-drag-handle"], [1, "fas", "fa-grip-vertical"], [1, "test-sequence"], [1, "test-icon"], [1, "test-content", 3, "click"], [1, "test-name"], [1, "test-status"], [1, "test-remove-confirm"], [1, "fas", "fa-info-circle"], [1, "test-remove-confirm", 3, "click"], [1, "test-remove-confirm-text"], ["type", "button", 1, "test-remove-confirm-btn", "test-remove-confirm-btn--danger", 3, "click", "disabled"], [1, "fas", "fa-spinner", "fa-spin"], ["type", "button", 1, "test-remove-confirm-btn", "test-remove-confirm-btn--ghost", 3, "click", "disabled"], ["type", "button", "title", "Remove from suite", "aria-label", "Remove from suite", 1, "test-remove-btn", 3, "click"], [1, "fas", "fa-chevron-right", "test-chevron", 3, "click"], ["Icon", "fa-solid fa-flask", "Title", "No Tests in Suite", "Message", "Add tests to this suite to start running them together.", "ActionText", "Add tests", "ActionIcon", "fa-solid fa-plus", 3, "Action"], [1, "runs-list"], ["Icon", "fa-solid fa-circle-play", "Title", "No Suite Runs Yet", "Message", "Run this suite to see execution history and results here.", "ActionText", "Run Suite Now", "ActionIcon", "fa-solid fa-play"], [1, "run-item"], [1, "run-item", 3, "click"], [1, "run-icon"], [1, "fas"], [1, "run-content"], [1, "run-header"], [1, "run-id"], [1, "run-status"], [1, "run-meta"], [1, "fas", "fa-calendar"], [1, "run-eval-metrics"], [1, "eval-metric", "status", 3, "class"], ["title", "Human evaluation", 1, "eval-metric", "human"], ["title", "Auto score (pass rate)", 1, "eval-metric", "auto", 3, "high", "medium", "low"], [1, "run-tags"], [1, "fas", "fa-chevron-right"], [1, "fas", "fa-check-circle"], [1, "eval-metric", "status"], [1, "fas", "fa-user"], [1, "eval-pending"], [1, "fas", "fa-clock"], ["title", "Auto score (pass rate)", 1, "eval-metric", "auto"], [1, "fas", "fa-robot"], [1, "tag-chip"], ["Icon", "fa-solid fa-circle-play", "Title", "No Suite Runs Yet", "Message", "Run this suite to see execution history and results here.", "ActionText", "Run Suite Now", "ActionIcon", "fa-solid fa-play", 3, "Action"], ["Icon", "fa-solid fa-chart-line", "Title", "No Analytics Data", "Message", "Run this suite to start collecting analytics data.", "ActionText", "Run Suite Now", "ActionIcon", "fa-solid fa-play"], ["text", "Loading analytics data..."], [1, "analytics-subnav"], [1, "subnav-tabs"], [1, "subnav-tab", 3, "click"], [1, "fas", "fa-chart-bar"], [1, "fas", "fa-th"], [1, "fas", "fa-project-diagram"], ["Size", "sm", 3, "ExpandedChange", "FlushBody", "Expanded"], ["mjAccordionTitle", ""], ["mjAccordionBody", ""], [1, "fas", "fa-filter", 2, "color", "var(--test-primary)"], [1, "mj-accordion-badge", "mj-accordion-badge--right", "mj-accordion-badge--muted"], [1, "filters-content"], [1, "filter-group"], [1, "filter-buttons"], [1, "filter-btn", 3, "click"], [1, "filter-hint"], [1, "filter-buttons", "tag-filters"], [1, "filter-btn", "tag-btn", "all-tags-btn", 3, "click"], [1, "filter-btn", "tag-btn", 3, "active"], [1, "filter-btn", "tag-btn", 3, "click"], [1, "fas", "fa-check"], [1, "analytics-kpis"], [1, "kpi-card"], [1, "kpi-icon"], [1, "fas", "fa-play-circle"], [1, "kpi-content"], [1, "kpi-value"], [1, "kpi-label"], [1, "kpi-icon", "success"], [1, "kpi-trend", 3, "ngClass"], [1, "kpi-icon", "info"], [1, "kpi-icon", "warning"], [1, "fas", "fa-dollar-sign"], [1, "analytics-table-section"], [1, "fas", "fa-table"], [1, "analytics-table-wrapper"], [1, "analytics-table"], [1, "clickable-row"], ["Variant", "no-results", "Size", "compact", "Title", "No runs match the current filters."], [1, "clickable-row", 3, "click"], [1, "status-chip", 3, "ngClass"], [1, "pass-rate-cell"], [1, "pass-rate-bar", 3, "ngClass"], [1, "tag-cell"], [1, "tag-chip-table"], [1, "tag-more"], [1, "matrix-section"], ["Variant", "no-results", "Icon", "fa-solid fa-table-cells", "Title", "No Matrix Data", "Message", "No suite runs match the current filters."], ["text", "Loading test matrix..."], [1, "matrix-header"], [1, "matrix-header-right"], [1, "matrix-filter-input"], [1, "fas", "fa-search"], ["type", "text", "placeholder", "Filter tests...", 1, "filter-input", 3, "input", "value"], ["title", "Clear filter", 1, "clear-filter-btn"], [1, "matrix-run-count"], ["mjButton", "", "title", "Export matrix to CSV", 3, "click", "disabled"], [1, "fas", "fa-download"], [1, "matrix-scroll-container"], [1, "test-matrix"], ["title", "Sort by sequence", 1, "seq-header", 3, "click"], ["title", "Sort by name", 1, "test-name-header", 3, "click"], [1, "run-header", 3, "title"], [1, "spacer-header"], [3, "row-selected"], [1, "totals-row"], [1, "seq-cell", "totals-label"], [1, "test-name-cell", "totals-label"], [1, "result-cell", "totals-cell"], [1, "spacer-cell"], ["title", "Clear filter", 1, "clear-filter-btn", 3, "click"], [1, "run-header", 3, "click", "title"], [1, "run-header-content"], [1, "run-tags-header"], [1, "run-date"], [1, "run-pass-rate", 3, "ngClass"], [1, "tag-chip-header"], [1, "tag-more-header"], [3, "click"], [1, "seq-cell"], [1, "test-name-cell"], [1, "test-name", 3, "title"], [1, "result-cell", 3, "ngClass", "clickable", "cell-not-run", "title"], [1, "result-cell", 3, "click", "ngClass", "title"], [1, "cell-eval-stack"], [1, "cell-not-run-indicator"], [1, "cell-status", 3, "ngClass", "cell-skipped-status", "title"], ["title", "Human Review: No rating submitted yet", 1, "cell-human", "no-feedback"], [1, "cell-human", "has-feedback", 3, "rating-low", "rating-medium", "rating-good", "rating-excellent", "title"], [1, "cell-auto", "has-score", 3, "score-low", "score-medium", "score-good", "score-excellent", "title"], ["title", "Auto Score: No automated score available", 1, "cell-auto", "no-score"], [1, "cell-status", 3, "ngClass", "title"], [1, "fas", "fa-user-slash"], [1, "cell-human", "has-feedback", 3, "title"], [1, "rating-value"], [1, "cell-auto", "has-score", 3, "title"], [1, "score-value"], [1, "fas", "fa-minus"], [1, "cell-eval-stack", "totals-stack"], [1, "totals-status"], [1, "totals-human"], [1, "totals-auto"], [1, "pass-count"], [1, "avg-label"], [1, "count-label"], [1, "chart-section"], ["Variant", "no-results", "Icon", "fa-solid fa-diagram-project", "Title", "No Chart Data", "Message", "No suite runs match the current filters."], ["text", "Loading chart data..."], [1, "chart-header"], [1, "chart-legend"], [1, "legend-item", "chart-passed"], [1, "legend-item", "chart-failed"], [1, "legend-item", "chart-error"], [1, "fas", "fa-exclamation"], [1, "legend-item", "chart-skipped"], [1, "fas", "fa-forward"], [1, "chart-container"], [1, "d3-chart"], [1, "chart-info"], ["Icon", "fa-solid fa-chart-line", "Title", "No Analytics Data", "Message", "Run this suite to start collecting analytics data.", "ActionText", "Run Suite Now", "ActionIcon", "fa-solid fa-play", 3, "Action"], [1, "compare-selection"], [1, "compare-run-selector"], [1, "run-selector-list"], [1, "selected-run-preview"], [1, "compare-vs"], [1, "fas", "fa-exchange-alt"], [1, "compare-results"], ["Icon", "fa-solid fa-scale-balanced", "Title", "Select Two Runs to Compare", "Message", "Choose a baseline run (A) and a comparison run (B) from the lists above to see a detailed side-by-side comparison."], ["Icon", "fa-solid fa-scale-balanced", "Title", "Not Enough Runs to Compare", "Message", "You need at least 2 suite runs to use the comparison feature.", "ActionText", "Run Suite Now", "ActionIcon", "fa-solid fa-play"], [1, "run-selector-item", 3, "selected"], [1, "run-selector-item", 3, "click"], [1, "selector-status"], [1, "selector-content"], [1, "selector-date"], [1, "selector-rate"], [1, "selector-tags"], [1, "tag-mini"], [1, "preview-header"], [1, "preview-label"], [1, "clear-btn", 3, "click"], [1, "preview-details"], [1, "preview-rate"], [1, "run-selector-item", 3, "selected", "disabled"], [1, "compare-summary"], [1, "compare-summary-card"], [1, "summary-label"], [1, "summary-value", 3, "ngClass"], [1, "compare-summary-card", "improved"], [1, "summary-value"], [1, "compare-summary-card", "regressed"], [1, "compare-table-section"], [1, "fas", "fa-list"], [1, "compare-table-wrapper"], [1, "compare-table"], [3, "ngClass"], [1, "status-chip", "status-missing"], [1, "muted"], [1, "change-indicator", "improved"], [1, "change-indicator", "regressed"], [1, "change-indicator", "unchanged"], [1, "fas", "fa-arrow-up"], [1, "fas", "fa-arrow-down"], ["text", "Loading comparison data..."], ["Icon", "fa-solid fa-scale-balanced", "Title", "Not Enough Runs to Compare", "Message", "You need at least 2 suite runs to use the comparison feature.", "ActionText", "Run Suite Now", "ActionIcon", "fa-solid fa-play", 3, "Action"], [1, "shortcuts-header"], ["title", "Hide shortcuts", 1, "shortcuts-close", 3, "click"], [1, "shortcut-list"], [1, "shortcut-item"], [1, "shortcut-keys"], ["Mode", "slide", 3, "Closed", "Title", "Resizable"], [3, "PanelClose", "PanelMode", "selectedTestId", "selectedSuiteId", "runMode"], [1, "picker-backdrop", 3, "click"], ["role", "dialog", "aria-modal", "true", "aria-labelledby", "add-tests-dialog-title", 1, "picker-dialog", 3, "click"], [1, "picker-header"], ["id", "add-tests-dialog-title", 1, "picker-title"], [1, "fas", "fa-plus-circle"], ["type", "button", "aria-label", "Close", 1, "picker-close", 3, "click", "disabled"], [1, "picker-search"], [1, "fas", "fa-search", "picker-search-icon"], ["type", "text", "placeholder", "Search tests by name, description, or type...", "autofocus", "", 1, "picker-search-input", 3, "ngModelChange", "ngModel"], ["type", "button", "aria-label", "Clear search", 1, "picker-search-clear"], [1, "picker-toolbar"], [1, "picker-toolbar-status"], [1, "picker-toolbar-actions"], ["type", "button", 1, "picker-link-btn", 3, "click", "disabled"], [1, "picker-body"], [1, "picker-loading"], [1, "picker-list"], [1, "picker-footer"], ["type", "button", 1, "picker-btn", "picker-btn--primary", 3, "click", "disabled"], ["type", "button", 1, "picker-btn", "picker-btn--ghost", 3, "click", "disabled"], ["type", "button", "aria-label", "Clear search", 1, "picker-search-clear", 3, "click"], ["text", "Loading tests..."], ["Variant", "success", "Size", "compact", "Title", "Everything's already in the suite", "Message", "This suite contains every available test. Create a new test first to add more."], ["Variant", "no-results", "Size", "compact", "Title", "No matches", 3, "Message"], ["role", "checkbox", "tabindex", "0", 1, "picker-row", 3, "picker-row--selected"], ["role", "checkbox", "tabindex", "0", 1, "picker-row", 3, "click"], [1, "picker-check"], [1, "picker-row-main"], [1, "picker-row-name"], [1, "picker-row-desc"], [1, "picker-row-meta"], [1, "picker-row-pill"], [1, "picker-row-pill", "picker-row-pill--status"], [1, "save-bar-kbd"]], template: function MJTestSuiteFormComponentExtended_Template(rf, ctx) { if (rf & 1) {
|
|
4799
4839
|
i0.ɵɵelementStart(0, "div", 3)(1, "div", 4)(2, "nav", 5)(3, "ol")(4, "li")(5, "a", 6);
|
|
4800
4840
|
i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Template_a_click_5_listener() { return ctx.navigateToTestingDashboard(); });
|
|
4801
4841
|
i0.ɵɵelement(6, "i", 7);
|
|
@@ -4868,7 +4908,7 @@ let MJTestSuiteFormComponentExtended = class MJTestSuiteFormComponentExtended ex
|
|
|
4868
4908
|
i0.ɵɵtext(58, " Compare ");
|
|
4869
4909
|
i0.ɵɵelementEnd()()();
|
|
4870
4910
|
i0.ɵɵelementStart(59, "div", 38);
|
|
4871
|
-
i0.ɵɵconditionalCreate(60, MJTestSuiteFormComponentExtended_Conditional_60_Template,
|
|
4911
|
+
i0.ɵɵconditionalCreate(60, MJTestSuiteFormComponentExtended_Conditional_60_Template, 83, 20, "div", 39);
|
|
4872
4912
|
i0.ɵɵconditionalCreate(61, MJTestSuiteFormComponentExtended_Conditional_61_Template, 15, 5, "div", 40);
|
|
4873
4913
|
i0.ɵɵconditionalCreate(62, MJTestSuiteFormComponentExtended_Conditional_62_Template, 4, 3, "div", 41);
|
|
4874
4914
|
i0.ɵɵconditionalCreate(63, MJTestSuiteFormComponentExtended_Conditional_63_Template, 4, 3, "div", 42);
|
|
@@ -4986,7 +5026,7 @@ MJTestSuiteFormComponentExtended = __decorate([
|
|
|
4986
5026
|
export { MJTestSuiteFormComponentExtended };
|
|
4987
5027
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJTestSuiteFormComponentExtended, [{
|
|
4988
5028
|
type: Component,
|
|
4989
|
-
args: [{ standalone: false, selector: 'mj-test-suite-form', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"test-suite-form\">\n <!-- Header Section -->\n <div class=\"suite-header\">\n <!-- Breadcrumb Navigation -->\n <nav class=\"breadcrumb\" aria-label=\"Breadcrumb\">\n <ol>\n <li>\n <a href=\"javascript:void(0)\" (click)=\"navigateToTestingDashboard()\">\n <i class=\"fas fa-vial\"></i>\n <span class=\"breadcrumb-text\">Testing</span>\n </a>\n </li>\n <li class=\"current\">\n <i class=\"fas fa-chevron-right separator\"></i>\n <i class=\"fas fa-layer-group\"></i>\n <span>{{ record.Name }}</span>\n </li>\n </ol>\n </nav>\n\n <div class=\"header-content\">\n <div class=\"header-left\">\n <div class=\"suite-icon\" [style.background-color]=\"getStatusColor()\">\n <i class=\"fas fa-layer-group\"></i>\n </div>\n <div class=\"suite-info\">\n <h1>\n {{ record.Name }}\n @if (isDirty) {\n <span class=\"dirty-indicator\" title=\"You have unsaved changes\" aria-label=\"Unsaved changes\">\u25CF</span>\n }\n </h1>\n <div class=\"suite-meta\">\n <span class=\"status-badge\" [ngClass]=\"getStatusClass()\">\n <i class=\"fas\" [ngClass]=\"record.Status === 'Active' ? 'fa-circle-check' : 'fa-circle-pause'\"></i>\n {{ record.Status }}\n </span>\n @if (testsLoaded) {\n <span class=\"test-count\">\n <i class=\"fas fa-flask\"></i>\n {{ suiteTests.length }} tests\n </span>\n }\n @if (isDirty) {\n <span class=\"unsaved-pill\" title=\"You have unsaved changes\">\n <i class=\"fas fa-circle\"></i> Unsaved\n </span>\n }\n </div>\n </div>\n </div>\n <div class=\"header-actions\">\n <app-evaluation-mode-toggle></app-evaluation-mode-toggle>\n <button mjButton (click)=\"exportToExcel()\" title=\"Export to CSV\">\n <i class=\"fas fa-file-excel\"></i> Export\n </button>\n <button mjButton (click)=\"runSuite()\" variant=\"primary\">\n <i class=\"fas fa-play\"></i> Run Suite\n </button>\n <button mjButton (click)=\"refresh()\" [disabled]=\"isRefreshing\">\n <i class=\"fas\" [ngClass]=\"isRefreshing ? 'fa-sync fa-spin' : 'fa-sync'\"></i>\n {{ isRefreshing ? 'Refreshing...' : 'Refresh' }}\n </button>\n </div>\n </div>\n @if (record.Description) {\n <div class=\"suite-description\">\n <p>{{ record.Description }}</p>\n </div>\n }\n </div>\n\n <!-- Tabs -->\n <div class=\"tabs-container\">\n <div class=\"tabs\" role=\"tablist\">\n <button class=\"tab\"\n [class.active]=\"activeTab === 'overview'\"\n (click)=\"changeTab('overview')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'overview'\">\n <i class=\"fas fa-th-large\"></i> Overview\n </button>\n <button class=\"tab\"\n [class.active]=\"activeTab === 'tests'\"\n (click)=\"changeTab('tests')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'tests'\">\n <i class=\"fas fa-flask\"></i> Tests\n @if (testsLoaded) {\n <span class=\"tab-badge\">{{ suiteTests.length }}</span>\n }\n </button>\n <button class=\"tab\"\n [class.active]=\"activeTab === 'runs'\"\n (click)=\"changeTab('runs')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'runs'\">\n <i class=\"fas fa-history\"></i> Runs\n @if (runsLoaded) {\n <span class=\"tab-badge\">{{ suiteRuns.length }}</span>\n }\n </button>\n <button class=\"tab\"\n [class.active]=\"activeTab === 'analytics'\"\n (click)=\"changeTab('analytics')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'analytics'\">\n <i class=\"fas fa-chart-line\"></i> Analytics\n </button>\n <button class=\"tab\"\n [class.active]=\"activeTab === 'compare'\"\n (click)=\"changeTab('compare')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'compare'\">\n <i class=\"fas fa-balance-scale\"></i> Compare\n </button>\n </div>\n </div>\n\n <!-- Tab Content -->\n <div class=\"tab-content\" [class.has-savebar]=\"isDirty\">\n <!-- Overview Tab -->\n @if (activeTab === 'overview') {\n <div class=\"overview-tab\">\n <!-- Editable Details -->\n <section class=\"edit-section\">\n <header class=\"edit-section-header\">\n <h3><i class=\"fas fa-pen-to-square\"></i> Details</h3>\n <p class=\"edit-section-sub\">Edit any field \u2014 changes are saved with the bar at the bottom.</p>\n </header>\n <div class=\"edit-grid\">\n <div class=\"edit-field edit-field--full\">\n <label for=\"suite-name\">Name <span class=\"required\">*</span></label>\n <input\n id=\"suite-name\"\n type=\"text\"\n class=\"config-input\"\n placeholder=\"e.g., Core Agent Test Suite\"\n [(ngModel)]=\"record.Name\"\n />\n </div>\n\n <div class=\"edit-field edit-field--full\">\n <label for=\"suite-description\">Description</label>\n <textarea\n id=\"suite-description\"\n class=\"config-input config-textarea\"\n rows=\"3\"\n placeholder=\"What does this suite cover?\"\n [ngModel]=\"record.Description\"\n (ngModelChange)=\"record.Description = $event || null\"\n ></textarea>\n </div>\n\n <div class=\"edit-field\">\n <label for=\"suite-status\">Status</label>\n <div class=\"select-wrapper\">\n <select\n id=\"suite-status\"\n class=\"config-input\"\n [(ngModel)]=\"record.Status\"\n >\n @for (opt of statusOptions; track opt) {\n <option [ngValue]=\"opt\">{{ opt }}</option>\n }\n </select>\n </div>\n </div>\n\n <div class=\"edit-field\">\n <label for=\"suite-parent\">Parent Suite</label>\n <select\n id=\"suite-parent\"\n class=\"config-input\"\n [ngModel]=\"record.ParentID\"\n (ngModelChange)=\"record.ParentID = $event || null\"\n >\n <option [ngValue]=\"null\">\u2014 None (top-level) \u2014</option>\n @for (s of parentSuiteOptions; track s.ID) {\n <option [ngValue]=\"s.ID\">{{ s.Name }}</option>\n }\n </select>\n </div>\n\n <div class=\"edit-field edit-field--full\">\n <label for=\"suite-tags\">Tags</label>\n <div class=\"tag-editor\" (click)=\"tagInput.focus()\">\n @for (tag of tags; track tag) {\n <span class=\"tag-chip-editable\">\n {{ tag }}\n <button type=\"button\" class=\"tag-remove\" (click)=\"removeTag(tag); $event.stopPropagation()\" [attr.aria-label]=\"'Remove tag ' + tag\">\n <i class=\"fas fa-times\"></i>\n </button>\n </span>\n }\n <input\n #tagInput\n id=\"suite-tags\"\n type=\"text\"\n class=\"tag-input-inline\"\n [placeholder]=\"tags.length === 0 ? 'Add tags, press Enter or comma...' : ''\"\n [(ngModel)]=\"tagDraft\"\n (keydown)=\"onTagInputKeydown($event)\"\n (blur)=\"addTagFromDraft()\"\n />\n </div>\n <span class=\"config-hint\">Press Enter or comma to add a tag. Backspace on empty input removes the last tag.</span>\n </div>\n </div>\n </section>\n\n <!-- Execution Settings -->\n <section class=\"edit-section\">\n <header class=\"edit-section-header\">\n <h3><i class=\"fas fa-cogs\"></i> Execution Settings</h3>\n </header>\n <div class=\"edit-grid\">\n <div class=\"edit-field\">\n <label for=\"suite-timeout\">Max Execution Time (ms)</label>\n <input\n id=\"suite-timeout\"\n type=\"number\"\n class=\"config-input\"\n placeholder=\"Default: 300000 (5 min)\"\n [ngModel]=\"record.MaxExecutionTimeMS\"\n (ngModelChange)=\"record.MaxExecutionTimeMS = $event === '' || $event === null ? null : +$event\"\n />\n <span class=\"config-hint\">Default timeout for tests in this suite. Currently: {{ formatTimeout(record.MaxExecutionTimeMS) }}</span>\n </div>\n </div>\n </section>\n\n <!-- Metadata (read-only) -->\n <section class=\"meta-section\">\n <div class=\"meta-grid\">\n <div class=\"meta-item\">\n <div class=\"meta-label\">Created</div>\n <div class=\"meta-value\">{{ record.__mj_CreatedAt | date:'medium' }}</div>\n </div>\n <div class=\"meta-item\">\n <div class=\"meta-label\">Last updated</div>\n <div class=\"meta-value\">{{ record.__mj_UpdatedAt | date:'medium' }}</div>\n </div>\n <div class=\"meta-item\">\n <div class=\"meta-label\">Suite ID</div>\n <div class=\"meta-value meta-mono\">{{ record.ID }}</div>\n </div>\n </div>\n </section>\n </div>\n }\n\n <!-- Tests Tab -->\n @if (activeTab === 'tests') {\n <div class=\"tests-tab\">\n <!-- Header: action bar -->\n <div class=\"tests-actionbar\">\n <div class=\"tests-actionbar-text\">\n <strong>Suite tests</strong>\n @if (testsLoaded) {\n <span class=\"tests-actionbar-count\">{{ suiteTests.length }}</span>\n }\n <span class=\"tests-actionbar-hint\">Drag to reorder \u00B7 Hover a row to remove</span>\n </div>\n <div class=\"tests-actionbar-actions\">\n <button mjButton variant=\"primary\" (click)=\"openAddTestsDialog()\" [disabled]=\"isReorderingTests\">\n <i class=\"fas fa-plus\"></i> Add tests\n </button>\n </div>\n </div>\n\n <!-- Loading State -->\n @if (loadingTests) {\n <div class=\"loading-state\">\n <div class=\"skeleton-list\">\n @for (i of [1,2,3,4,5]; track i) {\n <div class=\"skeleton-card\">\n <div class=\"skeleton-sequence\"></div>\n <div class=\"skeleton-icon\"></div>\n <div class=\"skeleton-content\">\n <div class=\"skeleton-line wide\"></div>\n <div class=\"skeleton-line narrow\"></div>\n </div>\n </div>\n }\n </div>\n </div>\n }\n <!-- Tests List -->\n @if (!loadingTests && suiteTests.length > 0) {\n <div class=\"tests-list\" cdkDropList (cdkDropListDropped)=\"onTestDrop($event)\">\n @for (test of suiteTests; track test.ID) {\n <div class=\"test-item\" cdkDrag [cdkDragDisabled]=\"isReorderingTests || isRemovingTest\">\n <span class=\"test-drag-handle\" cdkDragHandle title=\"Drag to reorder\" aria-label=\"Drag to reorder\">\n <i class=\"fas fa-grip-vertical\"></i>\n </span>\n <div class=\"test-sequence\">{{ test.Sequence }}</div>\n <div class=\"test-icon\"><i class=\"fas fa-flask\"></i></div>\n <div class=\"test-content\" (click)=\"openTest(test.TestID)\">\n <div class=\"test-name\">{{ test.Test }}</div>\n <div class=\"test-status\">\n @if (test.Status) {\n <span><i class=\"fas fa-info-circle\"></i> {{ test.Status }}</span>\n }\n </div>\n </div>\n <!-- Inline remove confirm OR hover-reveal X -->\n @if (confirmingRemoveSuiteTestId === test.ID) {\n <div class=\"test-remove-confirm\" (click)=\"$event.stopPropagation()\">\n <span class=\"test-remove-confirm-text\">Remove from suite?</span>\n <button\n type=\"button\"\n class=\"test-remove-confirm-btn test-remove-confirm-btn--danger\"\n (click)=\"confirmRemoveTest(test, $event)\"\n [disabled]=\"isRemovingTest\"\n >\n @if (isRemovingTest) {\n <i class=\"fas fa-spinner fa-spin\"></i>\n } @else {\n Remove\n }\n </button>\n <button\n type=\"button\"\n class=\"test-remove-confirm-btn test-remove-confirm-btn--ghost\"\n (click)=\"cancelRemoveTest($event)\"\n [disabled]=\"isRemovingTest\"\n >\n Cancel\n </button>\n </div>\n } @else {\n <button\n type=\"button\"\n class=\"test-remove-btn\"\n title=\"Remove from suite\"\n aria-label=\"Remove from suite\"\n (click)=\"requestRemoveTest(test, $event)\"\n >\n <i class=\"fas fa-times\"></i>\n </button>\n <i class=\"fas fa-chevron-right test-chevron\" (click)=\"openTest(test.TestID)\"></i>\n }\n </div>\n }\n </div>\n }\n <!-- Empty State -->\n @if (testsLoaded && !loadingTests && suiteTests.length === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-flask\"\n Title=\"No Tests in Suite\"\n Message=\"Add tests to this suite to start running them together.\"\n ActionText=\"Add tests\"\n ActionIcon=\"fa-solid fa-plus\"\n (Action)=\"openAddTestsDialog()\" />\n }\n </div>\n }\n\n <!-- Runs Tab -->\n @if (activeTab === 'runs') {\n <div class=\"runs-tab\">\n <!-- Loading State -->\n @if (loadingRuns) {\n <div class=\"loading-state\">\n <div class=\"skeleton-list\">\n @for (i of [1,2,3]; track i) {\n <div class=\"skeleton-card\">\n <div class=\"skeleton-icon\"></div>\n <div class=\"skeleton-content\">\n <div class=\"skeleton-line wide\"></div>\n <div class=\"skeleton-line narrow\"></div>\n </div>\n </div>\n }\n </div>\n </div>\n }\n <!-- Runs List -->\n @if (!loadingRuns && suiteRuns.length > 0) {\n <div class=\"runs-list\">\n @for (run of suiteRuns; track run) {\n <div class=\"run-item\" (click)=\"openSuiteRun(run.ID)\">\n <div class=\"run-icon\" [style.background-color]=\"getRunStatusColor(run.Status)\">\n <i class=\"fas\"\n [class.fa-check]=\"run.Status === 'Completed'\"\n [class.fa-times]=\"run.Status === 'Failed'\"\n [class.fa-spinner]=\"run.Status === 'Running'\"\n [class.fa-clock]=\"run.Status === 'Pending'\"\n [class.fa-ban]=\"run.Status === 'Cancelled'\"></i>\n </div>\n <div class=\"run-content\">\n <div class=\"run-header\">\n <span class=\"run-id\">Run #{{ run.ID.substring(0, 8) }}</span>\n <span class=\"run-status\" [style.color]=\"getRunStatusColor(run.Status)\">{{ run.Status }}</span>\n </div>\n <div class=\"run-meta\">\n <span><i class=\"fas fa-calendar\"></i> {{ getRelativeTime(run.StartedAt) }}</span>\n @if (run.TotalTests) {\n <span>\n <i class=\"fas fa-check-circle\"></i> {{ run.PassedTests }}/{{ run.TotalTests }}\n ({{ getPassRate(run).toFixed(0) }}%)\n </span>\n }\n </div>\n <!-- Evaluation metrics row -->\n <div class=\"run-eval-metrics\">\n <!-- Status badge -->\n @if (evalPreferences.showExecution) {\n <span class=\"eval-metric status\" [class]=\"'status-' + run.Status.toLowerCase()\">\n <i class=\"fas\"\n [class.fa-circle-check]=\"run.Status === 'Completed'\"\n [class.fa-circle-xmark]=\"run.Status === 'Failed'\"\n [class.fa-spinner]=\"run.Status === 'Running'\"\n [class.fa-clock]=\"run.Status === 'Pending'\"\n [class.fa-ban]=\"run.Status === 'Cancelled'\"></i>\n </span>\n }\n <!-- Human score (placeholder - need avg from suite run) -->\n @if (evalPreferences.showHuman) {\n <span class=\"eval-metric human\" title=\"Human evaluation\">\n <i class=\"fas fa-user\"></i>\n <span class=\"eval-pending\"><i class=\"fas fa-clock\"></i></span>\n </span>\n }\n <!-- Auto score (pass rate as proxy) -->\n @if (evalPreferences.showAuto && run.TotalTests) {\n <span class=\"eval-metric auto\"\n [class.high]=\"getPassRate(run) >= 80\"\n [class.medium]=\"getPassRate(run) >= 50 && getPassRate(run) < 80\"\n [class.low]=\"getPassRate(run) < 50\"\n title=\"Auto score (pass rate)\">\n <i class=\"fas fa-robot\"></i>\n <span>{{ getPassRate(run).toFixed(0) }}%</span>\n </span>\n }\n </div>\n <!-- Tags display -->\n @if (getRunTags(run).length > 0) {\n <div class=\"run-tags\">\n @for (tag of getRunTags(run); track tag) {\n <span class=\"tag-chip\">{{ tag }}</span>\n }\n </div>\n }\n </div>\n <i class=\"fas fa-chevron-right\"></i>\n </div>\n }\n </div>\n }\n <!-- Empty State -->\n @if (runsLoaded && !loadingRuns && suiteRuns.length === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-circle-play\"\n Title=\"No Suite Runs Yet\"\n Message=\"Run this suite to see execution history and results here.\"\n ActionText=\"Run Suite Now\"\n ActionIcon=\"fa-solid fa-play\"\n (Action)=\"runSuite()\" />\n }\n </div>\n }\n\n <!-- Analytics Tab -->\n @if (activeTab === 'analytics') {\n <div class=\"analytics-tab\">\n <!-- Loading State -->\n @if (loadingAnalytics) {\n <div class=\"loading-state\">\n <mj-loading text=\"Loading analytics data...\"></mj-loading>\n </div>\n }\n @if (!loadingAnalytics && analyticsLoaded) {\n <!-- View Toggle Sub-nav -->\n <div class=\"analytics-subnav\">\n <div class=\"subnav-tabs\">\n <button class=\"subnav-tab\"\n [class.active]=\"analyticsView === 'summary'\"\n (click)=\"setAnalyticsView('summary')\">\n <i class=\"fas fa-chart-bar\"></i>\n <span>Summary</span>\n </button>\n <button class=\"subnav-tab\"\n [class.active]=\"analyticsView === 'matrix'\"\n (click)=\"setAnalyticsView('matrix')\">\n <i class=\"fas fa-th\"></i>\n <span>Matrix</span>\n </button>\n <button class=\"subnav-tab\"\n [class.active]=\"analyticsView === 'chart'\"\n (click)=\"setAnalyticsView('chart')\">\n <i class=\"fas fa-project-diagram\"></i>\n <span>Chart</span>\n </button>\n </div>\n </div>\n <!-- Collapsible Filters (shared by both views) -->\n <mj-accordion-panel Size=\"sm\" [FlushBody]=\"true\"\n [Expanded]=\"!filtersCollapsed\" (ExpandedChange)=\"onFiltersExpandedChange($event)\">\n <ng-template mjAccordionTitle>\n <i class=\"fas fa-filter\" style=\"color: var(--test-primary);\"></i>\n Filters\n @if (filtersCollapsed) {\n <span class=\"mj-accordion-badge mj-accordion-badge--right mj-accordion-badge--muted\">\n {{ analyticsTimeRange === 'all' ? 'All Time' : analyticsTimeRange }}\n @if (selectedTags.length > 0) {\n <span> \u00B7 {{ selectedTags.length }} tags</span>\n }\n </span>\n }\n </ng-template>\n <ng-template mjAccordionBody>\n <div class=\"filters-content\">\n <div class=\"filter-group\">\n <label>Time Range</label>\n <div class=\"filter-buttons\">\n <button class=\"filter-btn\" [class.active]=\"analyticsTimeRange === '7d'\" (click)=\"setTimeRange('7d')\">7 Days</button>\n <button class=\"filter-btn\" [class.active]=\"analyticsTimeRange === '30d'\" (click)=\"setTimeRange('30d')\">30 Days</button>\n <button class=\"filter-btn\" [class.active]=\"analyticsTimeRange === '90d'\" (click)=\"setTimeRange('90d')\">90 Days</button>\n <button class=\"filter-btn\" [class.active]=\"analyticsTimeRange === 'all'\" (click)=\"setTimeRange('all')\">All Time</button>\n </div>\n </div>\n @if (uniqueTags.length > 0) {\n <div class=\"filter-group\">\n <label>Filter by Tag @if (selectedTags.length > 0) {\n <span class=\"filter-hint\">({{ selectedTags.length }} selected)</span>\n }</label>\n <div class=\"filter-buttons tag-filters\">\n <button class=\"filter-btn tag-btn all-tags-btn\"\n [class.active]=\"selectedTags.length === 0\"\n (click)=\"toggleTagFilter(null)\">\n <i class=\"fas fa-layer-group\"></i> All Tags\n </button>\n @for (tag of uniqueTags; track tag) {\n <button class=\"filter-btn tag-btn\"\n [class.active]=\"isTagSelected(tag)\"\n (click)=\"toggleTagFilter(tag)\">\n @if (isTagSelected(tag)) {\n <i class=\"fas fa-check\"></i>\n }\n {{ tag }}\n </button>\n }\n </div>\n </div>\n }\n </div>\n </ng-template>\n </mj-accordion-panel>\n <!-- Summary View -->\n @if (analyticsView === 'summary') {\n <!-- KPI Cards -->\n <div class=\"analytics-kpis\">\n <div class=\"kpi-card\">\n <div class=\"kpi-icon\"><i class=\"fas fa-play-circle\"></i></div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ getTotalRuns() }}</div>\n <div class=\"kpi-label\">Total Runs</div>\n </div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-icon success\"><i class=\"fas fa-check-circle\"></i></div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ getAveragePassRate().toFixed(1) }}%</div>\n <div class=\"kpi-label\">Avg Pass Rate</div>\n <div class=\"kpi-trend\" [ngClass]=\"{'trend-up': getPassRateTrend().direction === 'up', 'trend-down': getPassRateTrend().direction === 'down'}\">\n <i class=\"fas\" [ngClass]=\"{'fa-arrow-up': getPassRateTrend().direction === 'up', 'fa-arrow-down': getPassRateTrend().direction === 'down', 'fa-minus': getPassRateTrend().direction === 'stable'}\"></i>\n {{ getPassRateTrend().value.toFixed(1) }}%\n </div>\n </div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-icon info\"><i class=\"fas fa-clock\"></i></div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ formatDuration(getAverageDuration()) }}</div>\n <div class=\"kpi-label\">Avg Duration</div>\n </div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-icon warning\"><i class=\"fas fa-dollar-sign\"></i></div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ formatCost(getTotalCost()) }}</div>\n <div class=\"kpi-label\">Total Cost</div>\n </div>\n </div>\n </div>\n <!-- Runs Table -->\n <div class=\"analytics-table-section\">\n <h3><i class=\"fas fa-table\"></i> Run History</h3>\n <div class=\"analytics-table-wrapper\">\n <table class=\"analytics-table\">\n <thead>\n <tr>\n <th>Date</th>\n <th>Status</th>\n <th>Pass Rate</th>\n <th>Tests</th>\n <th>Duration</th>\n <th>Cost</th>\n <th>Tags</th>\n </tr>\n </thead>\n <tbody>\n @for (dp of getFilteredAnalyticsData(); track dp) {\n <tr (click)=\"openSuiteRun(dp.runId)\" class=\"clickable-row\">\n <td>{{ dp.date | date:'short' }}</td>\n <td>\n <span class=\"status-chip\" [ngClass]=\"'status-' + dp.status.toLowerCase()\">{{ dp.status }}</span>\n </td>\n <td>\n <div class=\"pass-rate-cell\">\n <div class=\"pass-rate-bar\" [style.width.%]=\"dp.passRate\" [ngClass]=\"{'high': dp.passRate >= 80, 'medium': dp.passRate >= 50 && dp.passRate < 80, 'low': dp.passRate < 50}\"></div>\n <span>{{ dp.passRate.toFixed(0) }}%</span>\n </div>\n </td>\n <td>{{ dp.passedTests }}/{{ dp.totalTests }}</td>\n <td>{{ formatDuration(dp.duration) }}</td>\n <td>{{ formatCost(dp.cost) }}</td>\n <td>\n <div class=\"tag-cell\">\n @for (tag of dp.tags.slice(0, 2); track tag) {\n <span class=\"tag-chip-table\">{{ tag }}</span>\n }\n @if (dp.tags.length > 2) {\n <span class=\"tag-more\">+{{ dp.tags.length - 2 }}</span>\n }\n </div>\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n @if (getFilteredAnalyticsData().length === 0) {\n <mj-empty-state\n Variant=\"no-results\"\n Size=\"compact\"\n Title=\"No runs match the current filters.\" />\n }\n </div>\n }\n <!-- Matrix View -->\n @if (analyticsView === 'matrix') {\n <!-- Loading Matrix -->\n @if (loadingMatrix) {\n <div class=\"loading-state\">\n <mj-loading text=\"Loading test matrix...\"></mj-loading>\n </div>\n }\n <!-- Matrix Content -->\n @if (!loadingMatrix && matrixLoaded && matrixData.length > 0) {\n <div class=\"matrix-section\">\n <div class=\"matrix-header\">\n <h3><i class=\"fas fa-th\"></i> Test Results Matrix</h3>\n <div class=\"matrix-header-right\">\n <div class=\"matrix-filter-input\">\n <i class=\"fas fa-search\"></i>\n <input type=\"text\"\n placeholder=\"Filter tests...\"\n [value]=\"matrixTestFilter\"\n (input)=\"onMatrixFilterInput($event)\"\n class=\"filter-input\">\n @if (matrixTestFilter) {\n <button class=\"clear-filter-btn\" (click)=\"clearMatrixFilter()\" title=\"Clear filter\">\n <i class=\"fas fa-times\"></i>\n </button>\n }\n </div>\n <span class=\"matrix-run-count\">{{ matrixData.length }} runs \u00B7 {{ getUniqueTestsFromMatrix().length }} tests</span>\n <button mjButton (click)=\"exportMatrixToCSV()\" [disabled]=\"matrixData.length === 0\" title=\"Export matrix to CSV\">\n <i class=\"fas fa-download\"></i> Export\n </button>\n </div>\n </div>\n <div class=\"matrix-scroll-container\">\n <table class=\"test-matrix\">\n <thead>\n <tr>\n <th class=\"seq-header\" (click)=\"toggleMatrixSort('sequence')\" title=\"Sort by sequence\">\n #\n <i class=\"fas\" [ngClass]=\"matrixSortBy === 'sequence' ? (matrixSortAsc ? 'fa-sort-up' : 'fa-sort-down') : 'fa-sort'\"></i>\n </th>\n <th class=\"test-name-header\" (click)=\"toggleMatrixSort('name')\" title=\"Sort by name\">\n Test\n <i class=\"fas\" [ngClass]=\"matrixSortBy === 'name' ? (matrixSortAsc ? 'fa-sort-up' : 'fa-sort-down') : 'fa-sort'\"></i>\n </th>\n @for (run of matrixData; track run) {\n <th class=\"run-header\" (click)=\"openSuiteRun(run.runId)\" [title]=\"'Click to view suite run - ' + (run.date | date:'medium')\">\n <div class=\"run-header-content\">\n @if (run.tags.length > 0) {\n <div class=\"run-tags-header\">\n @for (tag of run.tags.slice(0, 2); track tag) {\n <span class=\"tag-chip-header\">{{ tag }}</span>\n }\n @if (run.tags.length > 2) {\n <span class=\"tag-more-header\">+{{ run.tags.length - 2 }}</span>\n }\n </div>\n }\n <div class=\"run-date\">{{ getRelativeTime(run.date) }}</div>\n <div class=\"run-pass-rate\" [ngClass]=\"{'high': run.passRate >= 80, 'medium': run.passRate >= 50 && run.passRate < 80, 'low': run.passRate < 50}\">\n {{ run.passRate.toFixed(0) }}%\n </div>\n </div>\n </th>\n }\n <th class=\"spacer-header\"></th>\n </tr>\n </thead>\n <tbody>\n @for (test of getUniqueTestsFromMatrix(); track test) {\n <tr\n [class.row-selected]=\"selectedMatrixTestId === test.testId\"\n (click)=\"selectMatrixRow(test.testId)\">\n <td class=\"seq-cell\">{{ test.sequence }}</td>\n <td class=\"test-name-cell\">\n <span class=\"test-name\" [title]=\"test.testName\">{{ test.testName }}</span>\n </td>\n @for (run of matrixData; track run) {\n <td class=\"result-cell\"\n [ngClass]=\"getMatrixCellClass(getTestResultForRun(run.runId, test.testId))\"\n [class.clickable]=\"getTestResultForRun(run.runId, test.testId)\"\n [class.cell-not-run]=\"!getTestResultForRun(run.runId, test.testId)\"\n [title]=\"getTestResultForRun(run.runId, test.testId)?.status + ' - Click to view test run' || 'Not Run'\"\n (click)=\"onMatrixCellClick(getTestResultForRun(run.runId, test.testId), $event)\">\n @if (getTestResultForRun(run.runId, test.testId); as result) {\n <div class=\"cell-eval-stack\">\n <!-- Status indicator -->\n @if (evalPreferences.showExecution) {\n <span class=\"cell-status\"\n [ngClass]=\"'status-' + result.status.toLowerCase()\"\n [class.cell-skipped-status]=\"result.status === 'Skipped' || result.status === 'Pending'\"\n [title]=\"getStatusTooltip(result.status)\">\n <i class=\"fas\"\n [class.fa-check]=\"result.status === 'Passed'\"\n [class.fa-times]=\"result.status === 'Failed'\"\n [class.fa-exclamation]=\"result.status === 'Error'\"\n [class.fa-hourglass-end]=\"result.status === 'Timeout'\"\n [class.fa-forward]=\"result.status === 'Skipped'\"\n [class.fa-spinner]=\"result.status === 'Running'\"\n [class.fa-clock]=\"result.status === 'Pending'\"></i>\n </span>\n }\n <!-- Human score - slashed icon if no feedback, colored by rating if has feedback -->\n @if (evalPreferences.showHuman && !result.humanRating) {\n <span class=\"cell-human no-feedback\"\n title=\"Human Review: No rating submitted yet\">\n <i class=\"fas fa-user-slash\"></i>\n </span>\n }\n @if (evalPreferences.showHuman && result.humanRating) {\n <span class=\"cell-human has-feedback\"\n [class.rating-low]=\"result.humanRating <= 4\"\n [class.rating-medium]=\"result.humanRating >= 5 && result.humanRating <= 6\"\n [class.rating-good]=\"result.humanRating >= 7 && result.humanRating <= 8\"\n [class.rating-excellent]=\"result.humanRating >= 9\"\n [title]=\"getHumanTooltip(result.humanRating, result.humanComments)\">\n <i class=\"fas fa-user\"></i>\n <span class=\"rating-value\">{{ result.humanRating }}</span>\n </span>\n }\n <!-- Auto score - colored by percentage -->\n @if (evalPreferences.showAuto && result.score != null) {\n <span class=\"cell-auto has-score\"\n [class.score-low]=\"result.score < 0.5\"\n [class.score-medium]=\"result.score >= 0.5 && result.score < 0.7\"\n [class.score-good]=\"result.score >= 0.7 && result.score < 0.85\"\n [class.score-excellent]=\"result.score >= 0.85\"\n [title]=\"'Auto Score: ' + (result.score * 100).toFixed(0) + '% automated evaluation'\">\n <i class=\"fas fa-robot\"></i>\n <span class=\"score-value\">{{ (result.score * 100).toFixed(0) }}</span>\n </span>\n }\n @if (evalPreferences.showAuto && result.score == null) {\n <span class=\"cell-auto no-score\"\n title=\"Auto Score: No automated score available\">\n <i class=\"fas fa-robot\"></i>\n </span>\n }\n </div>\n }\n @if (!getTestResultForRun(run.runId, test.testId)) {\n <span class=\"cell-not-run-indicator\">\n <i class=\"fas fa-minus\"></i>\n </span>\n }\n </td>\n }\n <td class=\"spacer-cell\"></td>\n </tr>\n }\n </tbody>\n <!-- Footer row with totals -->\n <tfoot>\n <tr class=\"totals-row\">\n <td class=\"seq-cell totals-label\"></td>\n <td class=\"test-name-cell totals-label\">\n <strong>Totals</strong>\n </td>\n @for (run of matrixData; track run) {\n <td class=\"result-cell totals-cell\">\n <div class=\"cell-eval-stack totals-stack\">\n <!-- Status totals -->\n @if (evalPreferences.showExecution) {\n <span class=\"totals-status\">\n <span class=\"pass-count\">{{ getRunPassedCount(run) }}/{{ getRunTotalCount(run) }}</span>\n </span>\n }\n <!-- Human totals -->\n @if (evalPreferences.showHuman) {\n <span class=\"totals-human\">\n @if (getRunHumanAvg(run) != null) {\n <span class=\"avg-label\">{{ getRunHumanAvg(run)?.toFixed(1) }}</span>\n }\n <span class=\"count-label\">({{ getRunHumanCount(run) }})</span>\n </span>\n }\n <!-- Auto totals -->\n @if (evalPreferences.showAuto) {\n <span class=\"totals-auto\">\n @if (getRunAutoAvg(run) != null) {\n <span class=\"avg-label\">{{ (getRunAutoAvg(run)! * 100).toFixed(0) }}%</span>\n }\n <span class=\"count-label\">({{ getRunAutoCount(run) }})</span>\n </span>\n }\n </div>\n </td>\n }\n <td class=\"spacer-cell\"></td>\n </tr>\n </tfoot>\n </table>\n </div>\n </div>\n }\n <!-- Empty Matrix State -->\n @if (!loadingMatrix && matrixLoaded && matrixData.length === 0) {\n <mj-empty-state\n Variant=\"no-results\"\n Icon=\"fa-solid fa-table-cells\"\n Title=\"No Matrix Data\"\n Message=\"No suite runs match the current filters.\" />\n }\n }\n <!-- Chart View -->\n @if (analyticsView === 'chart') {\n <!-- Loading Chart -->\n @if (loadingMatrix) {\n <div class=\"loading-state\">\n <mj-loading text=\"Loading chart data...\"></mj-loading>\n </div>\n }\n <!-- Chart Content -->\n @if (!loadingMatrix && matrixLoaded && matrixData.length > 0) {\n <div class=\"chart-section\">\n <div class=\"chart-header\">\n <h3><i class=\"fas fa-project-diagram\"></i> Test Results Flow</h3>\n <div class=\"chart-legend\">\n <span class=\"legend-item chart-passed\"><i class=\"fas fa-check\"></i> Passed</span>\n <span class=\"legend-item chart-failed\"><i class=\"fas fa-times\"></i> Failed</span>\n <span class=\"legend-item chart-error\"><i class=\"fas fa-exclamation\"></i> Error</span>\n <span class=\"legend-item chart-skipped\"><i class=\"fas fa-forward\"></i> Skipped</span>\n </div>\n </div>\n <div class=\"chart-container\">\n <div #chartContainer class=\"d3-chart\"></div>\n </div>\n <div class=\"chart-info\">\n <i class=\"fas fa-info-circle\"></i>\n Interactive visualization showing test results across {{ matrixData.length }} runs.\n Hover over elements for details, click nodes to navigate.\n </div>\n </div>\n }\n <!-- Empty Chart State -->\n @if (!loadingMatrix && matrixLoaded && matrixData.length === 0) {\n <mj-empty-state\n Variant=\"no-results\"\n Icon=\"fa-solid fa-diagram-project\"\n Title=\"No Chart Data\"\n Message=\"No suite runs match the current filters.\" />\n }\n }\n }\n <!-- Empty State -->\n @if (!loadingAnalytics && analyticsLoaded && analyticsData.length === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-chart-line\"\n Title=\"No Analytics Data\"\n Message=\"Run this suite to start collecting analytics data.\"\n ActionText=\"Run Suite Now\"\n ActionIcon=\"fa-solid fa-play\"\n (Action)=\"runSuite()\" />\n }\n </div>\n }\n\n <!-- Compare Tab -->\n @if (activeTab === 'compare') {\n <div class=\"compare-tab\">\n <!-- Run Selection -->\n <div class=\"compare-selection\">\n <div class=\"compare-run-selector\">\n <h4>Run A (Baseline)</h4>\n @if (!loadingRuns && suiteRuns.length > 0) {\n <div class=\"run-selector-list\">\n @for (run of suiteRuns; track run) {\n <div class=\"run-selector-item\"\n [class.selected]=\"IsCompareRunA(run)\"\n (click)=\"selectCompareRunA(run)\">\n <div class=\"selector-status\" [style.background-color]=\"getRunStatusColor(run.Status)\"></div>\n <div class=\"selector-content\">\n <div class=\"selector-date\">{{ run.StartedAt | date:'short' }}</div>\n <div class=\"selector-rate\">{{ getPassRate(run).toFixed(0) }}% pass</div>\n </div>\n @if (getRunTags(run).length > 0) {\n <div class=\"selector-tags\">\n @for (tag of getRunTags(run).slice(0, 2); track tag) {\n <span class=\"tag-mini\">{{ tag }}</span>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n @if (compareRunA) {\n <div class=\"selected-run-preview\">\n <div class=\"preview-header\">\n <span class=\"preview-label\">Selected:</span>\n <button class=\"clear-btn\" (click)=\"compareRunA = null; compareResults = []\">Clear</button>\n </div>\n <div class=\"preview-details\">\n <span>{{ compareRunA.StartedAt | date:'medium' }}</span>\n <span class=\"preview-rate\">{{ getPassRate(compareRunA).toFixed(1) }}%</span>\n </div>\n </div>\n }\n </div>\n <div class=\"compare-vs\"><i class=\"fas fa-exchange-alt\"></i></div>\n <div class=\"compare-run-selector\">\n <h4>Run B (Compare)</h4>\n @if (!loadingRuns && suiteRuns.length > 0) {\n <div class=\"run-selector-list\">\n @for (run of suiteRuns; track run) {\n <div class=\"run-selector-item\"\n [class.selected]=\"IsCompareRunB(run)\"\n [class.disabled]=\"IsCompareRunA(run)\"\n (click)=\"!IsCompareRunA(run) && selectCompareRunB(run)\">\n <div class=\"selector-status\" [style.background-color]=\"getRunStatusColor(run.Status)\"></div>\n <div class=\"selector-content\">\n <div class=\"selector-date\">{{ run.StartedAt | date:'short' }}</div>\n <div class=\"selector-rate\">{{ getPassRate(run).toFixed(0) }}% pass</div>\n </div>\n @if (getRunTags(run).length > 0) {\n <div class=\"selector-tags\">\n @for (tag of getRunTags(run).slice(0, 2); track tag) {\n <span class=\"tag-mini\">{{ tag }}</span>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n @if (compareRunB) {\n <div class=\"selected-run-preview\">\n <div class=\"preview-header\">\n <span class=\"preview-label\">Selected:</span>\n <button class=\"clear-btn\" (click)=\"compareRunB = null; compareResults = []\">Clear</button>\n </div>\n <div class=\"preview-details\">\n <span>{{ compareRunB.StartedAt | date:'medium' }}</span>\n <span class=\"preview-rate\">{{ getPassRate(compareRunB).toFixed(1) }}%</span>\n </div>\n </div>\n }\n </div>\n </div>\n <!-- Comparison Results -->\n @if (compareRunA && compareRunB && !loadingCompare) {\n <div class=\"compare-results\">\n <!-- Summary Cards -->\n <div class=\"compare-summary\">\n <div class=\"compare-summary-card\">\n <div class=\"summary-label\">Pass Rate Change</div>\n <div class=\"summary-value\" [ngClass]=\"{'positive': getComparePassRateDiff()! > 0, 'negative': getComparePassRateDiff()! < 0}\">\n <i class=\"fas\" [ngClass]=\"{'fa-arrow-up': getComparePassRateDiff()! > 0, 'fa-arrow-down': getComparePassRateDiff()! < 0, 'fa-minus': getComparePassRateDiff() === 0}\"></i>\n {{ getComparePassRateDiff()! > 0 ? '+' : '' }}{{ getComparePassRateDiff()?.toFixed(1) }}%\n </div>\n </div>\n <div class=\"compare-summary-card\">\n <div class=\"summary-label\">Duration Change</div>\n <div class=\"summary-value\" [ngClass]=\"{'positive': getCompareDurationDiff()! < 0, 'negative': getCompareDurationDiff()! > 0}\">\n <i class=\"fas\" [ngClass]=\"{'fa-arrow-down': getCompareDurationDiff()! < 0, 'fa-arrow-up': getCompareDurationDiff()! > 0, 'fa-minus': getCompareDurationDiff() === 0}\"></i>\n {{ formatDuration(getAbsCompareDurationDiff()) }}\n </div>\n </div>\n <div class=\"compare-summary-card improved\">\n <div class=\"summary-label\">Improved</div>\n <div class=\"summary-value\">{{ getCompareImprovedCount() }}</div>\n </div>\n <div class=\"compare-summary-card regressed\">\n <div class=\"summary-label\">Regressed</div>\n <div class=\"summary-value\">{{ getCompareRegressedCount() }}</div>\n </div>\n </div>\n <!-- Detailed Comparison Table -->\n <div class=\"compare-table-section\">\n <h3><i class=\"fas fa-list\"></i> Test-by-Test Comparison</h3>\n <div class=\"compare-table-wrapper\">\n <table class=\"compare-table\">\n <thead>\n <tr>\n <th>Test</th>\n <th>Run A Status</th>\n <th>Run B Status</th>\n <th>Score Diff</th>\n <th>Duration Diff</th>\n <th>Change</th>\n </tr>\n </thead>\n <tbody>\n @for (result of compareResults; track result) {\n <tr [ngClass]=\"{'improved': result.runA && result.runB && result.runA.status !== 'Passed' && result.runB.status === 'Passed', 'regressed': result.runA && result.runB && result.runA.status === 'Passed' && result.runB.status !== 'Passed'}\">\n <td class=\"test-name-cell\">{{ result.testName }}</td>\n <td>\n @if (result.runA) {\n <span class=\"status-chip\" [ngClass]=\"'status-' + result.runA.status.toLowerCase()\">{{ result.runA.status }}</span>\n }\n @if (!result.runA) {\n <span class=\"status-chip status-missing\">N/A</span>\n }\n </td>\n <td>\n @if (result.runB) {\n <span class=\"status-chip\" [ngClass]=\"'status-' + result.runB.status.toLowerCase()\">{{ result.runB.status }}</span>\n }\n @if (!result.runB) {\n <span class=\"status-chip status-missing\">N/A</span>\n }\n </td>\n <td>\n @if (result.scoreDiff != null) {\n <span [ngClass]=\"{'positive': result.scoreDiff > 0, 'negative': result.scoreDiff < 0}\">\n {{ result.scoreDiff > 0 ? '+' : '' }}{{ (result.scoreDiff * 100).toFixed(1) }}%\n </span>\n }\n @if (result.scoreDiff == null) {\n <span class=\"muted\">-</span>\n }\n </td>\n <td>\n @if (result.durationDiff != null) {\n <span [ngClass]=\"{'positive': result.durationDiff < 0, 'negative': result.durationDiff > 0}\">\n {{ result.durationDiff > 0 ? '+' : '' }}{{ result.durationDiff.toFixed(1) }}s\n </span>\n }\n @if (result.durationDiff == null) {\n <span class=\"muted\">-</span>\n }\n </td>\n <td>\n @if (result.runA && result.runB && result.runA.status !== 'Passed' && result.runB.status === 'Passed') {\n <span class=\"change-indicator improved\">\n <i class=\"fas fa-arrow-up\"></i> Fixed\n </span>\n }\n @if (result.runA && result.runB && result.runA.status === 'Passed' && result.runB.status !== 'Passed') {\n <span class=\"change-indicator regressed\">\n <i class=\"fas fa-arrow-down\"></i> Broke\n </span>\n }\n @if (!result.statusChanged) {\n <span class=\"change-indicator unchanged\">\n <i class=\"fas fa-minus\"></i>\n </span>\n }\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </div>\n </div>\n }\n <!-- Loading State for Compare -->\n @if (loadingCompare) {\n <div class=\"loading-state\">\n <mj-loading text=\"Loading comparison data...\"></mj-loading>\n </div>\n }\n <!-- Empty State -->\n @if (!compareRunA || !compareRunB) {\n <mj-empty-state\n Icon=\"fa-solid fa-scale-balanced\"\n Title=\"Select Two Runs to Compare\"\n Message=\"Choose a baseline run (A) and a comparison run (B) from the lists above to see a detailed side-by-side comparison.\" />\n }\n <!-- No Runs State -->\n @if (runsLoaded && suiteRuns.length < 2) {\n <mj-empty-state\n Icon=\"fa-solid fa-scale-balanced\"\n Title=\"Not Enough Runs to Compare\"\n Message=\"You need at least 2 suite runs to use the comparison feature.\"\n ActionText=\"Run Suite Now\"\n ActionIcon=\"fa-solid fa-play\"\n (Action)=\"runSuite()\" />\n }\n </div>\n }\n </div>\n\n <!-- Keyboard Shortcuts Toggle Button -->\n <button class=\"shortcuts-toggle\" (click)=\"toggleShortcuts()\" [title]=\"showShortcuts ? 'Hide keyboard shortcuts' : 'Show keyboard shortcuts'\">\n <i class=\"fas fa-keyboard\"></i>\n </button>\n\n <!-- Keyboard Shortcuts Hint (Desktop Only) -->\n @if (showShortcuts) {\n <div class=\"keyboard-shortcuts\">\n <div class=\"shortcuts-header\">\n <i class=\"fas fa-keyboard\"></i>\n Shortcuts\n <button class=\"shortcuts-close\" (click)=\"toggleShortcuts()\" title=\"Hide shortcuts\">\n <i class=\"fas fa-times\"></i>\n </button>\n </div>\n <div class=\"shortcut-list\">\n <div class=\"shortcut-item\">\n <span>Save changes</span>\n <span class=\"shortcut-keys\"><kbd>Cmd</kbd><kbd>S</kbd></span>\n </div>\n <div class=\"shortcut-item\">\n <span>Refresh</span>\n <span class=\"shortcut-keys\"><kbd>Cmd</kbd><kbd>R</kbd></span>\n </div>\n <div class=\"shortcut-item\">\n <span>Run Suite</span>\n <span class=\"shortcut-keys\"><kbd>Cmd</kbd><kbd>Enter</kbd></span>\n </div>\n <div class=\"shortcut-item\">\n <span>Switch Tabs</span>\n <span class=\"shortcut-keys\"><kbd>1</kbd>-<kbd>5</kbd></span>\n </div>\n </div>\n </div>\n }\n\n <!-- Slide Panel for Suite Execution -->\n @if (testingDialogService.IsPanelOpen) {\n <mj-slide-panel\n Mode=\"slide\"\n [Title]=\"testingDialogService.PanelOptions?.suiteId ? 'Suite Execution' : 'Run Suite'\"\n [Resizable]=\"true\"\n (Closed)=\"OnPanelClosed()\">\n <app-test-run-dialog\n [PanelMode]=\"true\"\n [selectedTestId]=\"testingDialogService.PanelOptions?.testId ?? null\"\n [selectedSuiteId]=\"testingDialogService.PanelOptions?.suiteId ?? null\"\n [runMode]=\"testingDialogService.PanelOptions?.mode ?? 'suite'\"\n (PanelClose)=\"OnPanelClosed()\">\n </app-test-run-dialog>\n </mj-slide-panel>\n }\n\n <!-- Add Tests Picker Dialog -->\n @if (showAddTestsDialog) {\n <div class=\"picker-backdrop\" (click)=\"closeAddTestsDialog()\"></div>\n <div class=\"picker-dialog\" role=\"dialog\" aria-modal=\"true\" aria-labelledby=\"add-tests-dialog-title\" (click)=\"$event.stopPropagation()\">\n <div class=\"picker-header\">\n <h2 id=\"add-tests-dialog-title\" class=\"picker-title\">\n <i class=\"fas fa-plus-circle\"></i> Add tests to suite\n </h2>\n <button type=\"button\" class=\"picker-close\" (click)=\"closeAddTestsDialog()\" [disabled]=\"isAddingTests\" aria-label=\"Close\">\n <i class=\"fas fa-times\"></i>\n </button>\n </div>\n\n <div class=\"picker-search\">\n <i class=\"fas fa-search picker-search-icon\"></i>\n <input\n #pickerSearch\n type=\"text\"\n class=\"picker-search-input\"\n placeholder=\"Search tests by name, description, or type...\"\n [(ngModel)]=\"addTestsSearch\"\n autofocus\n />\n @if (addTestsSearch) {\n <button type=\"button\" class=\"picker-search-clear\" (click)=\"addTestsSearch = ''\" aria-label=\"Clear search\">\n <i class=\"fas fa-times\"></i>\n </button>\n }\n </div>\n\n <div class=\"picker-toolbar\">\n <span class=\"picker-toolbar-status\">\n @if (selectedTestIdsToAdd.size > 0) {\n <strong>{{ selectedTestIdsToAdd.size }}</strong> selected\n } @else if (!loadingAvailableTests) {\n {{ filteredAvailableTests.length }} test{{ filteredAvailableTests.length === 1 ? '' : 's' }} available\n }\n </span>\n <div class=\"picker-toolbar-actions\">\n <button type=\"button\" class=\"picker-link-btn\" (click)=\"selectAllFiltered()\" [disabled]=\"loadingAvailableTests || filteredAvailableTests.length === 0\">\n Select all\n </button>\n <button type=\"button\" class=\"picker-link-btn\" (click)=\"clearAddSelection()\" [disabled]=\"selectedTestIdsToAdd.size === 0\">\n Clear\n </button>\n </div>\n </div>\n\n <div class=\"picker-body\">\n @if (loadingAvailableTests) {\n <div class=\"picker-loading\">\n <mj-loading text=\"Loading tests...\"></mj-loading>\n </div>\n } @else if (filteredAvailableTests.length === 0) {\n @if (availableTests.length === 0) {\n <mj-empty-state\n Variant=\"success\"\n Size=\"compact\"\n Title=\"Everything's already in the suite\"\n Message=\"This suite contains every available test. Create a new test first to add more.\" />\n } @else {\n <mj-empty-state\n Variant=\"no-results\"\n Size=\"compact\"\n Title=\"No matches\"\n [Message]=\"AddTestsNoMatchMessage\" />\n }\n } @else {\n <ul class=\"picker-list\">\n @for (t of filteredAvailableTests; track t.ID) {\n <li\n class=\"picker-row\"\n [class.picker-row--selected]=\"isAddSelected(t.ID)\"\n (click)=\"toggleAddSelection(t.ID)\"\n role=\"checkbox\"\n [attr.aria-checked]=\"isAddSelected(t.ID)\"\n tabindex=\"0\"\n >\n <span class=\"picker-check\">\n @if (isAddSelected(t.ID)) {\n <i class=\"fas fa-check\"></i>\n }\n </span>\n <div class=\"picker-row-main\">\n <div class=\"picker-row-name\">{{ t.Name }}</div>\n @if (t.Description) {\n <div class=\"picker-row-desc\">{{ t.Description }}</div>\n }\n </div>\n <div class=\"picker-row-meta\">\n @if (t.Type) {\n <span class=\"picker-row-pill\">{{ t.Type }}</span>\n }\n <span class=\"picker-row-pill picker-row-pill--status\" [attr.data-status]=\"t.Status?.toLowerCase()\">{{ t.Status }}</span>\n </div>\n </li>\n }\n </ul>\n }\n </div>\n\n <div class=\"picker-footer\">\n <button\n type=\"button\"\n class=\"picker-btn picker-btn--primary\"\n (click)=\"confirmAddTests()\"\n [disabled]=\"selectedTestIdsToAdd.size === 0 || isAddingTests\"\n >\n @if (isAddingTests) {\n <i class=\"fas fa-spinner fa-spin\"></i> Adding\u2026\n } @else {\n <i class=\"fas fa-check\"></i>\n @if (selectedTestIdsToAdd.size === 0) {\n Add tests\n } @else if (selectedTestIdsToAdd.size === 1) {\n Add 1 test\n } @else {\n Add {{ selectedTestIdsToAdd.size }} tests\n }\n }\n </button>\n <button\n type=\"button\"\n class=\"picker-btn picker-btn--ghost\"\n (click)=\"closeAddTestsDialog()\"\n [disabled]=\"isAddingTests\"\n >\n Cancel\n </button>\n </div>\n </div>\n }\n\n <!-- Sticky Save Bar \u2014 always in the DOM so CSS transitions can fire reliably.\n Visibility is controlled by the .save-bar--visible class, driven by isDirty. -->\n <div\n class=\"save-bar\"\n [class.save-bar--visible]=\"isDirty\"\n [attr.aria-hidden]=\"!isDirty\"\n role=\"region\"\n aria-label=\"Unsaved changes\"\n >\n <div class=\"save-bar-message\">\n <span class=\"save-bar-dot\" aria-hidden=\"true\">\u25CF</span>\n <span class=\"save-bar-text\">\n <strong>Unsaved changes</strong>\n <span class=\"save-bar-fields\">\n @if (dirtyFieldNames.length === 1) {\n {{ dirtyFieldNames[0] }} edited\n } @else if (dirtyFieldNames.length > 1) {\n {{ dirtyFieldNames.length }} fields edited\n }\n </span>\n </span>\n </div>\n <div class=\"save-bar-actions\">\n <button\n type=\"button\"\n class=\"save-bar-btn save-bar-btn--primary\"\n (click)=\"saveChanges()\"\n [disabled]=\"isSaving || !isDirty\"\n [attr.tabindex]=\"isDirty ? 0 : -1\"\n title=\"Save changes (\u2318S)\"\n >\n @if (isSaving) {\n <i class=\"fas fa-spinner fa-spin\"></i> Saving\u2026\n } @else {\n <i class=\"fas fa-check\"></i> Save changes\n <span class=\"save-bar-kbd\"><kbd>\u2318</kbd><kbd>S</kbd></span>\n }\n </button>\n <button\n type=\"button\"\n class=\"save-bar-btn save-bar-btn--ghost\"\n (click)=\"discardChanges()\"\n [disabled]=\"isSaving || !isDirty\"\n [attr.tabindex]=\"isDirty ? 0 : -1\"\n title=\"Discard changes\"\n >\n <i class=\"fas fa-undo\"></i> Discard\n </button>\n </div>\n </div>\n</div>\n", styles: ["/* ===========================\n Test Suite Form - World-Class UX\n =========================== */\n\n/* CSS Custom Properties for Theming - using :host for Angular encapsulation */\n:host {\n --test-primary: var(--mj-brand-primary);\n --test-primary-light: var(--mj-brand-primary);\n --test-success: var(--mj-status-success);\n --test-error: var(--mj-status-error);\n --test-warning: var(--mj-status-warning);\n --test-disabled: var(--mj-text-muted);\n --test-bg: var(--mj-bg-surface-card);\n --test-surface: var(--mj-bg-surface);\n --test-border: var(--mj-border-default);\n --test-text: var(--mj-text-primary);\n --test-text-secondary: var(--mj-text-secondary);\n --test-text-muted: var(--mj-text-disabled);\n --test-radius-sm: 6px;\n --test-radius-md: 10px;\n --test-radius-lg: 16px;\n --test-shadow-sm: var(--mj-shadow-sm);\n --test-shadow-md: var(--mj-shadow-md);\n --test-shadow-lg: var(--mj-shadow-lg);\n --test-transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n display: block;\n height: 100%;\n}\n\n.test-suite-form {\n position: relative;\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--test-bg);\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n}\n\n/* Breadcrumb */\n.breadcrumb {\n margin-bottom: 16px;\n}\n\n.breadcrumb ol {\n display: flex;\n align-items: center;\n gap: 4px;\n list-style: none;\n margin: 0;\n padding: 0;\n font-size: 13px;\n}\n\n.breadcrumb li {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.breadcrumb a {\n color: var(--test-primary);\n text-decoration: none;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 8px;\n border-radius: 6px;\n transition: background 0.15s;\n}\n\n.breadcrumb a:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n text-decoration: none;\n}\n\n.breadcrumb .separator {\n font-size: 10px;\n color: var(--test-text-muted);\n margin: 0 4px;\n}\n\n.breadcrumb .current {\n color: var(--test-text-secondary);\n font-weight: 500;\n}\n\n.breadcrumb-text {\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* Header */\n.suite-header {\n background: var(--test-surface);\n border-bottom: 1px solid var(--test-border);\n padding: 20px;\n}\n\n.header-content {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 16px;\n gap: 16px;\n}\n\n.header-left {\n display: flex;\n gap: 16px;\n flex: 1;\n min-width: 0;\n}\n\n.suite-icon {\n width: 56px;\n height: 56px;\n border-radius: var(--test-radius-md);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-inverse);\n font-size: 24px;\n flex-shrink: 0;\n box-shadow: var(--test-shadow-md);\n transition: var(--test-transition);\n}\n\n.suite-icon:hover { transform: scale(1.05); }\n\n.suite-info { flex: 1; min-width: 0; }\n\n.suite-info h1 {\n margin: 0 0 8px 0;\n font-size: clamp(18px, 4vw, 24px);\n font-weight: 700;\n color: var(--test-text);\n word-wrap: break-word;\n}\n\n.suite-meta {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n.status-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border-radius: 20px;\n color: var(--mj-text-inverse);\n font-size: 12px;\n font-weight: 600;\n text-transform: uppercase;\n}\n\n.status-badge.status-active { background: var(--test-success); }\n.status-badge.status-disabled { background: var(--test-disabled); }\n.status-badge.status-pending { background: var(--test-warning); }\n\n.status-badge-inline {\n display: inline-flex;\n padding: 2px 10px;\n border-radius: 10px;\n color: var(--mj-text-inverse);\n font-size: 11px;\n font-weight: 600;\n}\n\n.status-badge-inline.status-active { background: var(--test-success); }\n.status-badge-inline.status-disabled { background: var(--test-disabled); }\n.status-badge-inline.status-pending { background: var(--test-warning); }\n\n.test-count {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 14px;\n color: var(--test-text-secondary);\n padding: 4px 10px;\n background: var(--test-bg);\n border-radius: var(--test-radius-sm);\n}\n\n.header-actions {\n display: flex;\n gap: 8px;\n flex-shrink: 0;\n}\n\n.suite-description {\n padding: 16px;\n background: var(--mj-bg-surface-card);\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n}\n\n.suite-description p {\n margin: 0;\n color: var(--test-text-secondary);\n line-height: 1.6;\n font-size: 14px;\n}\n\n/* Tabs */\n.tabs-container {\n background: var(--test-surface);\n border-bottom: 1px solid var(--test-border);\n position: sticky;\n top: 0;\n z-index: 10;\n}\n\n.tabs {\n display: flex;\n padding: 0 20px;\n overflow-x: auto;\n scrollbar-width: none;\n}\n\n.tabs::-webkit-scrollbar { display: none; }\n\n.tab {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 14px 18px;\n border: none;\n background: transparent;\n border-bottom: 3px solid transparent;\n color: var(--test-text-secondary);\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n white-space: nowrap;\n}\n\n.tab:hover {\n color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.tab.active {\n color: var(--test-primary);\n border-bottom-color: var(--test-primary);\n font-weight: 600;\n}\n\n.tab-badge {\n background: var(--test-border);\n color: var(--test-text-secondary);\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.tab.active .tab-badge {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n color: var(--test-primary);\n}\n\n.tab-shortcut {\n font-size: 10px;\n color: var(--test-text-muted);\n background: var(--test-bg);\n padding: 2px 6px;\n border-radius: 4px;\n font-weight: 600;\n}\n\n/* Tab Content */\n.tab-content {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n}\n\n/* Overview Tab */\n.overview-tab {\n display: flex;\n flex-direction: column;\n gap: 20px;\n animation: fadeIn 0.3s ease-out;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; transform: translateY(10px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n.info-section, .config-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.info-section h3, .config-section h3 {\n margin: 0 0 20px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.info-section h3 i, .config-section h3 i {\n color: var(--test-primary);\n}\n\n.info-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 16px;\n}\n\n.info-item {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.info-label {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.info-value {\n font-size: 14px;\n color: var(--test-text);\n font-weight: 500;\n}\n\n.config-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n gap: 20px;\n}\n\n.config-item {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.config-item label {\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.config-input {\n padding: 10px 14px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n font-size: 14px;\n transition: var(--test-transition);\n}\n\n.config-input:focus {\n outline: none;\n border-color: var(--test-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.config-hint {\n font-size: 11px;\n color: var(--test-text-muted);\n}\n\n/* Tests Tab */\n.tests-tab, .runs-tab {\n animation: fadeIn 0.3s ease-out;\n}\n\n.loading-state { padding: 0; }\n\n.skeleton-list {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.skeleton-card {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-surface);\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n}\n\n.skeleton-sequence {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n background: linear-gradient(90deg, var(--mj-border-default) 25%, var(--mj-bg-surface-sunken) 50%, var(--mj-border-default) 75%);\n background-size: 200% 100%;\n animation: shimmer 1.5s infinite;\n}\n\n.skeleton-icon {\n width: 40px;\n height: 40px;\n border-radius: var(--test-radius-md);\n background: linear-gradient(90deg, var(--mj-border-default) 25%, var(--mj-bg-surface-sunken) 50%, var(--mj-border-default) 75%);\n background-size: 200% 100%;\n animation: shimmer 1.5s infinite;\n}\n\n.skeleton-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.skeleton-line {\n height: 14px;\n border-radius: 4px;\n background: linear-gradient(90deg, var(--mj-border-default) 25%, var(--mj-bg-surface-sunken) 50%, var(--mj-border-default) 75%);\n background-size: 200% 100%;\n animation: shimmer 1.5s infinite;\n}\n\n.skeleton-line.wide { width: 70%; }\n.skeleton-line.narrow { width: 40%; }\n\n@keyframes shimmer {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n}\n\n.tests-list, .runs-list {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.test-item, .run-item {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.test-item:hover, .run-item:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n border-color: var(--test-primary-light);\n transform: translateX(4px);\n}\n\n.test-sequence {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-bg);\n border-radius: 50%;\n font-size: 14px;\n font-weight: 700;\n color: var(--test-text-secondary);\n flex-shrink: 0;\n}\n\n.test-icon, .run-icon {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: var(--test-radius-md);\n color: var(--mj-text-inverse);\n font-size: 18px;\n flex-shrink: 0;\n box-shadow: var(--test-shadow-sm);\n}\n\n.test-icon {\n background: var(--test-primary);\n}\n\n.test-content, .run-content { flex: 1; min-width: 0; }\n\n.test-name, .run-header {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n margin-bottom: 4px;\n}\n\n.run-header {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.run-id { font-weight: 600; }\n\n.run-status {\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n}\n\n.test-status, .run-meta {\n display: flex;\n gap: 12px;\n font-size: 12px;\n color: var(--test-text-secondary);\n}\n\n.test-status span, .run-meta span {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n}\n\n.test-item > i, .run-item > i {\n color: var(--test-text-muted);\n font-size: 14px;\n transition: var(--test-transition);\n}\n\n.test-item:hover > i, .run-item:hover > i {\n color: var(--test-primary);\n transform: translateX(2px);\n}\n\n/* Keyboard Shortcuts */\n/* Keyboard shortcuts toggle button - visible when shortcuts are hidden */\n.shortcuts-toggle {\n position: fixed;\n bottom: 20px;\n right: 20px;\n width: 36px;\n height: 36px;\n border-radius: 50%;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n box-shadow: var(--test-shadow-md);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--test-text-secondary);\n font-size: 14px;\n z-index: 99;\n transition: var(--test-transition);\n opacity: 0.7;\n}\n\n.shortcuts-toggle:hover {\n opacity: 1;\n transform: scale(1.1);\n color: var(--test-primary);\n border-color: var(--test-primary);\n}\n\n.keyboard-shortcuts {\n position: fixed;\n bottom: 20px;\n right: 20px;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n padding: 12px 16px;\n box-shadow: var(--test-shadow-lg);\n font-size: 12px;\n z-index: 100;\n max-width: 260px;\n}\n\n.shortcuts-header {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-bottom: 10px;\n padding-bottom: 8px;\n border-bottom: 1px solid var(--test-border);\n font-weight: 600;\n color: var(--test-text);\n}\n\n.shortcuts-close {\n margin-left: auto;\n background: none;\n border: none;\n cursor: pointer;\n color: var(--test-text-muted);\n font-size: 12px;\n padding: 2px 4px;\n border-radius: 4px;\n transition: var(--test-transition);\n}\n\n.shortcuts-close:hover {\n color: var(--test-text);\n background: var(--test-border);\n}\n\n.shortcut-list {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.shortcut-item {\n display: flex;\n justify-content: space-between;\n align-items: center;\n color: var(--test-text-secondary);\n}\n\n.shortcut-keys {\n display: flex;\n gap: 4px;\n}\n\n.shortcut-keys kbd {\n background: var(--test-bg);\n border: 1px solid var(--test-border);\n border-radius: 4px;\n padding: 2px 6px;\n font-size: 11px;\n color: var(--test-text);\n}\n\n/* Responsive */\n@media (max-width: 1024px) {\n .keyboard-shortcuts, .shortcuts-toggle { display: none; }\n}\n\n@media (max-width: 768px) {\n .suite-header { padding: 16px; }\n\n .header-content {\n flex-direction: column;\n gap: 16px;\n }\n\n .header-actions {\n width: 100%;\n justify-content: stretch;\n }\n\n .header-actions button { flex: 1; }\n\n .tab-shortcut { display: none; }\n\n .info-grid { grid-template-columns: 1fr; }\n\n .test-item, .run-item { padding: 14px; }\n}\n\n@media (max-width: 480px) {\n .suite-icon {\n width: 40px;\n height: 40px;\n font-size: 18px;\n }\n\n .suite-info h1 { font-size: 16px; }\n\n .tab-badge { display: none; }\n\n .test-sequence { display: none; }\n}\n\n@media (hover: none) and (pointer: coarse) {\n .test-item:active, .run-item:active {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n transform: scale(0.98);\n }\n\n .tab { min-height: 48px; }\n .test-item, .run-item { min-height: 64px; }\n}\n\n@media (prefers-reduced-motion: reduce) {\n *, *::before, *::after {\n animation-duration: 0.01ms !important;\n transition-duration: 0.01ms !important;\n }\n}\n\n@media print {\n .header-actions, .tabs-container, .keyboard-shortcuts {\n display: none !important;\n }\n}\n\n/* ===========================\n Tags UI\n =========================== */\n.run-tags {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n margin-top: 8px;\n}\n\n.tag-chip {\n display: inline-flex;\n align-items: center;\n padding: 3px 10px;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n color: var(--mj-brand-primary-hover);\n}\n\n.tag-mini {\n display: inline-flex;\n align-items: center;\n padding: 2px 6px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 4px;\n font-size: 10px;\n font-weight: 500;\n color: var(--mj-text-muted);\n}\n\n.tag-more {\n font-size: 10px;\n color: var(--mj-text-disabled);\n font-weight: 500;\n}\n\n/* Evaluation metrics row for Runs list */\n.run-eval-metrics {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 8px;\n}\n\n.eval-metric {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 3px 8px;\n border-radius: 6px;\n font-size: 11px;\n font-weight: 500;\n}\n\n.eval-metric.status {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n}\n\n.eval-metric.status.status-completed {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.eval-metric.status.status-failed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.eval-metric.status.status-running {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n}\n\n.eval-metric.status.status-pending {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.eval-metric.human {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n border: 1px solid var(--mj-status-warning);\n color: var(--mj-status-warning);\n}\n\n.eval-metric.human .eval-pending {\n font-size: 9px;\n color: var(--mj-status-warning);\n}\n\n.eval-metric.auto {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n color: var(--mj-brand-primary-hover);\n}\n\n.eval-metric.auto.high {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-success) 30%, transparent);\n color: var(--mj-status-success);\n}\n\n.eval-metric.auto.medium {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 30%, transparent);\n color: var(--mj-status-warning);\n}\n\n.eval-metric.auto.low {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-error) 30%, transparent);\n color: var(--mj-status-error);\n}\n\n.tag-cell {\n display: flex;\n align-items: center;\n gap: 4px;\n flex-wrap: wrap;\n}\n\n.tag-chip-table {\n display: inline-block;\n padding: 3px 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n color: var(--mj-brand-primary-hover);\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n white-space: nowrap;\n max-width: 80px;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* ===========================\n Analytics Tab\n =========================== */\n.analytics-tab {\n animation: fadeIn 0.3s ease-out;\n}\n\n/* Collapsible filters */\n/* Filters disclosure migrated to <mj-accordion-panel>. The bespoke\n .analytics-filters wrapper card chrome, the .filters-header bar (+ hover),\n and the .filters-header > i chevron are now owned by the accordion and were\n removed. The title-slot layout (.filters-title flex row) and font are now\n provided by the accordion title + Size=\"sm\"; the collapsed summary uses the\n shared .mj-accordion-badge (--muted --right). Only the body content\n (.filters-content) styling is kept below. */\n\n.filters-content {\n display: flex;\n flex-direction: column;\n gap: 16px;\n padding: 12px 16px 16px 16px;\n border-top: 1px solid var(--test-border);\n}\n\n.filter-group {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.filter-group label {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.filter-buttons {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.filter-btn {\n padding: 8px 16px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n background: var(--test-surface);\n color: var(--test-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.filter-btn:hover {\n border-color: var(--test-primary);\n color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.filter-btn.active {\n background: var(--test-primary);\n border-color: var(--test-primary);\n color: var(--mj-text-inverse);\n}\n\n.filter-btn.tag-btn {\n padding: 6px 12px;\n font-size: 12px;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n}\n\n.filter-btn.tag-btn i.fa-check {\n font-size: 10px;\n}\n\n.filter-btn.tag-btn.all-tags-btn {\n font-weight: 600;\n}\n\n.filter-btn.tag-btn.all-tags-btn i {\n font-size: 11px;\n}\n\n.filter-hint {\n font-weight: 400;\n font-size: 10px;\n color: var(--test-primary);\n text-transform: none;\n letter-spacing: normal;\n}\n\n.tag-filters {\n max-height: 120px;\n overflow-y: auto;\n}\n\n/* KPI Cards */\n.analytics-kpis {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 16px;\n margin-bottom: 24px;\n}\n\n.kpi-card {\n display: flex;\n align-items: center;\n gap: 16px;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 20px;\n box-shadow: var(--test-shadow-sm);\n transition: var(--test-transition);\n}\n\n.kpi-card:hover {\n transform: translateY(-2px);\n box-shadow: var(--test-shadow-md);\n}\n\n.kpi-icon {\n width: 48px;\n height: 48px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border-radius: var(--test-radius-md);\n color: var(--test-primary);\n font-size: 20px;\n}\n\n.kpi-icon.success {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--test-success);\n}\n\n.kpi-icon.info {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.kpi-icon.warning {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--test-warning);\n}\n\n.kpi-content {\n flex: 1;\n min-width: 0;\n}\n\n.kpi-value {\n font-size: 24px;\n font-weight: 700;\n color: var(--test-text);\n line-height: 1.2;\n}\n\n.kpi-label {\n font-size: 12px;\n color: var(--test-text-secondary);\n margin-top: 2px;\n}\n\n.kpi-trend {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 12px;\n font-weight: 600;\n margin-top: 4px;\n padding: 2px 8px;\n border-radius: 10px;\n background: var(--mj-bg-surface-sunken);\n color: var(--test-text-secondary);\n}\n\n.kpi-trend.trend-up {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--test-success);\n}\n\n.kpi-trend.trend-down {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--test-error);\n}\n\n/* Analytics Table */\n.analytics-table-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.analytics-table-section h3 {\n margin: 0 0 16px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.analytics-table-section h3 i {\n color: var(--test-primary);\n}\n\n.analytics-table-wrapper {\n overflow-x: auto;\n margin: 0 -24px;\n padding: 0 24px;\n}\n\n.analytics-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.analytics-table th {\n text-align: left;\n padding: 12px 16px;\n background: var(--mj-bg-surface-card);\n border-bottom: 2px solid var(--test-border);\n font-weight: 600;\n color: var(--test-text-secondary);\n text-transform: uppercase;\n font-size: 11px;\n letter-spacing: 0.5px;\n white-space: nowrap;\n}\n\n.analytics-table td {\n padding: 14px 16px;\n border-bottom: 1px solid var(--test-border);\n color: var(--test-text);\n}\n\n.analytics-table tbody tr.clickable-row {\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.analytics-table tbody tr.clickable-row:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.status-chip {\n display: inline-flex;\n align-items: center;\n padding: 4px 10px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n}\n\n.status-chip.status-completed { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--test-success); }\n.status-chip.status-passed { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--test-success); }\n.status-chip.status-failed { background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface)); color: var(--test-error); }\n.status-chip.status-error { background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface)); color: var(--test-warning); }\n.status-chip.status-running { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--test-primary); }\n.status-chip.status-pending { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--mj-brand-primary); }\n.status-chip.status-cancelled { background: var(--mj-bg-surface-sunken); color: var(--test-disabled); }\n.status-chip.status-missing { background: var(--mj-bg-surface-sunken); color: var(--test-text-muted); }\n.status-chip.status-timeout { background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface)); color: var(--test-warning); }\n.status-chip.status-skipped { background: var(--mj-bg-surface-sunken); color: var(--test-disabled); }\n\n.pass-rate-cell {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 100px;\n}\n\n.pass-rate-bar {\n height: 6px;\n border-radius: 3px;\n background: var(--test-success);\n transition: width 0.3s ease;\n max-width: 60px;\n}\n\n.pass-rate-bar.medium { background: var(--test-warning); }\n.pass-rate-bar.low { background: var(--test-error); }\n\n/* Analytics Sub-navigation */\n.analytics-subnav {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 8px;\n margin-bottom: 20px;\n box-shadow: var(--test-shadow-sm);\n display: inline-flex;\n}\n\n.subnav-tabs {\n display: flex;\n gap: 4px;\n background: var(--test-bg);\n border-radius: var(--test-radius-md);\n padding: 4px;\n}\n\n.subnav-tab {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n border: none;\n border-radius: var(--test-radius-sm);\n background: transparent;\n color: var(--test-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.subnav-tab:hover {\n color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.subnav-tab.active {\n background: var(--test-surface);\n color: var(--test-primary);\n box-shadow: var(--test-shadow-sm);\n}\n\n.subnav-tab i {\n font-size: 14px;\n}\n\n/* Matrix View */\n.matrix-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 16px;\n box-shadow: var(--test-shadow-sm);\n display: flex;\n flex-direction: column;\n max-height: calc(100vh - 280px);\n min-height: 300px;\n}\n\n.matrix-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-wrap: wrap;\n gap: 12px;\n margin-bottom: 12px;\n padding-bottom: 12px;\n border-bottom: 1px solid var(--test-border);\n flex-shrink: 0;\n}\n\n.matrix-header-right {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.matrix-header h3 {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 0;\n font-size: 15px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.matrix-header h3 i {\n color: var(--test-primary);\n}\n\n.matrix-run-count {\n font-size: 12px;\n color: var(--test-text-muted);\n font-weight: 500;\n}\n\n/* Matrix filter input */\n.matrix-filter-input {\n display: flex;\n align-items: center;\n gap: 8px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--test-border);\n border-radius: 6px;\n padding: 4px 10px;\n min-width: 180px;\n}\n\n.matrix-filter-input i.fa-search {\n color: var(--mj-text-disabled);\n font-size: 12px;\n}\n\n.matrix-filter-input .filter-input {\n border: none;\n background: transparent;\n outline: none;\n font-size: 12px;\n color: var(--test-text);\n width: 100%;\n}\n\n.matrix-filter-input .filter-input::placeholder {\n color: var(--mj-text-disabled);\n}\n\n.clear-filter-btn {\n border: none;\n background: none;\n padding: 2px 4px;\n cursor: pointer;\n color: var(--mj-text-disabled);\n font-size: 10px;\n border-radius: 3px;\n transition: all 0.15s ease;\n}\n\n.clear-filter-btn:hover {\n background: var(--mj-border-default);\n color: var(--mj-text-muted);\n}\n\n/* Scrollable matrix container with fixed height */\n.matrix-scroll-container {\n flex: 1;\n overflow: auto;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n}\n\n.test-matrix {\n display: table;\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.test-matrix thead {\n display: table-header-group;\n}\n\n.test-matrix thead tr {\n display: table-row;\n}\n\n.test-matrix tbody {\n display: table-row-group;\n}\n\n.test-matrix tbody tr {\n display: table-row;\n cursor: pointer;\n transition: background-color 0.15s ease;\n}\n\n.test-matrix tbody tr:hover {\n background-color: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.test-matrix tbody tr.row-selected {\n background-color: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent) !important;\n}\n\n.test-matrix tbody tr.row-selected td {\n border-top: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n border-bottom: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n.test-matrix tbody tr.row-selected .seq-cell,\n.test-matrix tbody tr.row-selected .test-name-cell {\n background-color: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent) !important;\n}\n\n.test-matrix tfoot {\n display: table-footer-group;\n}\n\n.test-matrix th,\n.test-matrix td {\n display: table-cell;\n border: 1px solid var(--test-border);\n padding: 8px 12px;\n text-align: center;\n vertical-align: middle;\n}\n\n.test-matrix th {\n background: var(--test-bg);\n font-weight: 600;\n font-size: 11px;\n color: var(--test-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n position: sticky;\n top: 0;\n z-index: 10;\n border-bottom: 3px solid var(--mj-text-secondary) !important;\n}\n\n/* Sequence column - shared styles */\n.test-matrix .seq-header,\n.test-matrix .seq-cell {\n width: 36px;\n min-width: 36px;\n max-width: 36px;\n text-align: center;\n position: sticky;\n left: 0;\n font-size: 11px;\n color: var(--mj-text-muted);\n border-right: 1px solid var(--test-border);\n padding: 6px 4px !important;\n}\n\n/* Seq header - sticky top AND left, highest z-index */\n.test-matrix .seq-header {\n cursor: pointer;\n font-weight: 600;\n background: var(--test-bg);\n z-index: 12; /* Higher than other headers */\n top: 0;\n}\n\n/* Seq body cells - sticky left only, lower z-index */\n.test-matrix .seq-cell {\n background: var(--test-surface);\n z-index: 2;\n}\n\n.test-matrix .seq-header i {\n font-size: 9px;\n margin-left: 2px;\n opacity: 0.6;\n}\n\n.test-matrix .seq-header:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.test-matrix .test-name-header {\n text-align: left;\n min-width: 150px;\n max-width: 500px;\n width: auto;\n position: sticky;\n left: 36px;\n background: var(--test-bg);\n z-index: 11;\n border-right: 2px solid var(--test-border);\n cursor: pointer;\n}\n\n.test-matrix .test-name-header i {\n font-size: 9px;\n margin-left: 4px;\n opacity: 0.6;\n}\n\n.test-matrix .test-name-header:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.test-matrix .run-header {\n min-width: 120px;\n width: 120px;\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n/* Spacer column absorbs extra width */\n.test-matrix .spacer-header,\n.test-matrix .spacer-cell {\n width: 100%;\n min-width: 20px;\n background: var(--test-bg);\n border: none;\n}\n\n.test-matrix .spacer-cell {\n background: var(--test-surface);\n}\n\n.test-matrix .run-header:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.run-header-content {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n}\n\n.run-date {\n font-size: 12px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.run-pass-rate {\n font-size: 11px;\n font-weight: 700;\n padding: 2px 8px;\n border-radius: 10px;\n}\n\n.run-pass-rate.high {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--test-success);\n}\n\n.run-pass-rate.medium {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--test-warning);\n}\n\n.run-pass-rate.low {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--test-error);\n}\n\n.run-tags {\n display: flex;\n gap: 4px;\n}\n\n.tag-tiny {\n font-size: 9px;\n padding: 2px 6px;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--test-primary);\n border-radius: 8px;\n white-space: nowrap;\n max-width: 60px;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* Matrix column header tags - emphasized */\n.run-tags-header {\n display: flex;\n flex-wrap: wrap;\n gap: 3px;\n justify-content: center;\n margin-bottom: 4px;\n}\n\n.tag-chip-header {\n display: inline-block;\n padding: 3px 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n color: var(--mj-brand-primary-hover);\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n white-space: nowrap;\n max-width: 70px;\n overflow: hidden;\n text-overflow: ellipsis;\n text-transform: none;\n letter-spacing: normal;\n}\n\n.tag-more-header {\n font-size: 9px;\n color: var(--test-text-secondary);\n padding: 2px 4px;\n}\n\n.test-matrix .test-name-cell {\n text-align: left;\n min-width: 150px;\n max-width: 500px;\n width: auto;\n position: sticky;\n left: 36px;\n background: var(--test-surface);\n z-index: 2;\n border-right: 2px solid var(--test-border);\n padding: 6px 10px !important;\n}\n\n.test-name {\n display: block;\n white-space: nowrap;\n font-weight: 500;\n color: var(--test-text);\n font-size: 12px;\n}\n\n.result-cell {\n position: relative;\n min-width: 120px;\n width: 120px;\n transition: var(--test-transition);\n}\n\n.result-cell.clickable {\n cursor: pointer;\n}\n\n.result-cell.clickable:hover {\n transform: scale(1.1);\n box-shadow: var(--mj-shadow-md);\n z-index: 5;\n}\n\n.result-cell i {\n font-size: 14px;\n}\n\n/* Completed cells have neutral white background - pills tell the story */\n.result-cell.cell-passed,\n.result-cell.cell-failed,\n.result-cell.cell-error,\n.result-cell.cell-timeout,\n.result-cell.cell-running,\n.result-cell.cell-pending {\n background: var(--mj-bg-surface);\n color: var(--test-text);\n}\n\n/* Skipped/not-run cells get hatched background */\n.result-cell.cell-skipped {\n background: repeating-linear-gradient(\n 45deg,\n var(--mj-bg-surface-card),\n var(--mj-bg-surface-card) 4px,\n var(--mj-border-default) 4px,\n var(--mj-border-default) 8px\n );\n color: var(--test-disabled);\n}\n\n.result-cell.cell-none {\n background: var(--mj-bg-surface-card);\n color: var(--test-text-muted);\n}\n\n.cell-score {\n display: block;\n font-size: 10px;\n font-weight: 600;\n margin-top: 2px;\n}\n\n/* Matrix cell evaluation stack - shows multiple eval types horizontally */\n.cell-eval-stack {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n flex-wrap: nowrap;\n}\n\n.result-cell.multi-eval {\n min-width: 120px;\n width: auto;\n}\n\n/* Add timeout status icon */\n.cell-status.status-timeout {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-status {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n border-radius: 50%;\n font-size: 11px;\n}\n\n.cell-status.status-passed {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.cell-status.status-failed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.cell-status.status-error {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-status.status-skipped {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n}\n\n.cell-status.status-running {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n}\n\n.cell-status.status-pending {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.cell-human {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n border-radius: 50%;\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n font-size: 10px;\n}\n\n.cell-auto {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 2px 6px;\n border-radius: 4px;\n font-size: 10px;\n font-weight: 600;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n}\n\n.cell-auto.high {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.cell-auto.medium {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-auto.low {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.cell-none-indicator {\n color: var(--test-text-muted);\n opacity: 0.5;\n}\n\n.matrix-info {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n color: var(--test-text-muted);\n padding: 12px;\n background: var(--test-bg);\n border-radius: var(--test-radius-sm);\n}\n\n.matrix-info i {\n color: var(--test-primary);\n}\n\n/* ===========================\n Chart View\n =========================== */\n.chart-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.chart-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-wrap: wrap;\n gap: 16px;\n margin-bottom: 20px;\n padding-bottom: 16px;\n border-bottom: 1px solid var(--test-border);\n}\n\n.chart-header h3 {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.chart-header h3 i {\n color: var(--test-primary);\n}\n\n.chart-legend {\n display: flex;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.chart-legend .legend-item {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 500;\n padding: 4px 10px;\n border-radius: 12px;\n}\n\n.chart-legend .legend-item.chart-passed {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--test-success);\n}\n\n.chart-legend .legend-item.chart-failed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--test-error);\n}\n\n.chart-legend .legend-item.chart-error {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--test-warning);\n}\n\n.chart-legend .legend-item.chart-skipped {\n background: var(--mj-bg-surface-sunken);\n color: var(--test-disabled);\n}\n\n.chart-container {\n min-height: 500px;\n position: relative;\n overflow: hidden;\n background: var(--mj-bg-surface-card);\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n}\n\n.d3-chart {\n width: 100%;\n height: 500px;\n}\n\n.d3-chart svg {\n width: 100%;\n height: 100%;\n}\n\n/* D3 Chart Node Styles */\n.d3-chart .node {\n cursor: pointer;\n transition: transform 0.2s ease;\n}\n\n.d3-chart .node:hover {\n transform: scale(1.05);\n}\n\n.d3-chart .node-label {\n font-size: 11px;\n font-weight: 500;\n fill: var(--test-text);\n pointer-events: none;\n}\n\n.d3-chart .link {\n fill: none;\n stroke-opacity: 0.4;\n transition: stroke-opacity 0.2s ease;\n}\n\n.d3-chart .link:hover {\n stroke-opacity: 0.8;\n}\n\n.d3-chart .tooltip {\n position: absolute;\n padding: 10px 14px;\n background: var(--mj-bg-overlay);\n color: var(--mj-text-inverse);\n border-radius: 8px;\n font-size: 12px;\n pointer-events: none;\n z-index: 100;\n box-shadow: var(--mj-shadow-lg);\n max-width: 250px;\n}\n\n.d3-chart .tooltip-title {\n font-weight: 600;\n margin-bottom: 4px;\n}\n\n.d3-chart .tooltip-value {\n opacity: 0.8;\n}\n\n.chart-info {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n color: var(--test-text-muted);\n padding: 12px;\n background: var(--test-bg);\n border-radius: var(--test-radius-sm);\n margin-top: 16px;\n}\n\n.chart-info i {\n color: var(--test-primary);\n}\n\n/* ===========================\n Compare Tab\n =========================== */\n.compare-tab {\n animation: fadeIn 0.3s ease-out;\n}\n\n.compare-selection {\n display: grid;\n grid-template-columns: 1fr auto 1fr;\n gap: 24px;\n align-items: flex-start;\n margin-bottom: 24px;\n}\n\n.compare-run-selector {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 20px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.compare-run-selector h4 {\n margin: 0 0 16px 0;\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.run-selector-list {\n max-height: 200px;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-bottom: 12px;\n}\n\n.run-selector-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 12px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.run-selector-item:hover {\n border-color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.run-selector-item.selected {\n border-color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n}\n\n.run-selector-item.disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.selector-status {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n}\n\n.selector-content {\n flex: 1;\n min-width: 0;\n}\n\n.selector-date {\n font-size: 12px;\n font-weight: 500;\n color: var(--test-text);\n}\n\n.selector-rate {\n font-size: 11px;\n color: var(--test-text-secondary);\n}\n\n.selector-tags {\n display: flex;\n gap: 4px;\n flex-wrap: wrap;\n}\n\n.selected-run-preview {\n padding: 12px;\n background: var(--mj-bg-surface-card);\n border-radius: var(--test-radius-sm);\n border: 1px solid var(--test-border);\n}\n\n.preview-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 8px;\n}\n\n.preview-label {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n color: var(--test-text-muted);\n}\n\n.clear-btn {\n padding: 4px 8px;\n border: none;\n background: transparent;\n color: var(--test-error);\n font-size: 11px;\n font-weight: 500;\n cursor: pointer;\n}\n\n.clear-btn:hover { text-decoration: underline; }\n\n.preview-details {\n display: flex;\n justify-content: space-between;\n font-size: 12px;\n color: var(--test-text);\n}\n\n.preview-rate {\n font-weight: 600;\n color: var(--test-success);\n}\n\n.compare-vs {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n background: var(--test-bg);\n border-radius: 50%;\n color: var(--test-text-muted);\n font-size: 16px;\n align-self: center;\n margin-top: 60px;\n}\n\n/* Compare Results */\n.compare-results {\n animation: fadeIn 0.3s ease-out;\n}\n\n.compare-summary {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n gap: 16px;\n margin-bottom: 24px;\n}\n\n.compare-summary-card {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 20px;\n box-shadow: var(--test-shadow-sm);\n text-align: center;\n}\n\n.compare-summary-card .summary-label {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n color: var(--test-text-muted);\n margin-bottom: 8px;\n}\n\n.compare-summary-card .summary-value {\n font-size: 24px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n}\n\n.compare-summary-card .summary-value.positive { color: var(--test-success); }\n.compare-summary-card .summary-value.negative { color: var(--test-error); }\n\n.compare-summary-card.improved {\n border-left: 4px solid var(--test-success);\n}\n\n.compare-summary-card.improved .summary-value { color: var(--test-success); }\n\n.compare-summary-card.regressed {\n border-left: 4px solid var(--test-error);\n}\n\n.compare-summary-card.regressed .summary-value { color: var(--test-error); }\n\n/* Compare Table */\n.compare-table-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.compare-table-section h3 {\n margin: 0 0 16px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.compare-table-section h3 i {\n color: var(--test-primary);\n}\n\n.compare-table-wrapper {\n overflow-x: auto;\n}\n\n.compare-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.compare-table th {\n text-align: left;\n padding: 12px 16px;\n background: var(--mj-bg-surface-card);\n border-bottom: 2px solid var(--test-border);\n font-weight: 600;\n color: var(--test-text-secondary);\n text-transform: uppercase;\n font-size: 11px;\n letter-spacing: 0.5px;\n white-space: nowrap;\n}\n\n.compare-table td {\n padding: 14px 16px;\n border-bottom: 1px solid var(--test-border);\n color: var(--test-text);\n}\n\n.compare-table tbody tr.improved {\n background: color-mix(in srgb, var(--mj-status-success) 5%, transparent);\n}\n\n.compare-table tbody tr.regressed {\n background: color-mix(in srgb, var(--mj-status-error) 5%, transparent);\n}\n\n.test-name-cell {\n font-weight: 500;\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.positive { color: var(--test-success); }\n.negative { color: var(--test-error); }\n.muted { color: var(--test-text-muted); }\n\n.change-indicator {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.change-indicator.improved {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--test-success);\n}\n\n.change-indicator.regressed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--test-error);\n}\n\n.change-indicator.unchanged {\n background: var(--mj-bg-surface-sunken);\n color: var(--test-text-muted);\n}\n\n/* ===========================\n Responsive Analytics/Compare\n =========================== */\n@media (max-width: 1024px) {\n .compare-selection {\n grid-template-columns: 1fr;\n gap: 16px;\n }\n\n .compare-vs {\n margin: 0;\n align-self: center;\n justify-self: center;\n }\n\n .analytics-kpis {\n grid-template-columns: repeat(2, 1fr);\n }\n}\n\n@media (max-width: 768px) {\n .filter-buttons {\n flex-direction: column;\n }\n\n .filter-btn {\n width: 100%;\n text-align: center;\n }\n\n .analytics-kpis {\n grid-template-columns: 1fr;\n }\n\n .kpi-card {\n padding: 16px;\n }\n\n .kpi-value {\n font-size: 20px;\n }\n\n .compare-summary {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .analytics-table-wrapper,\n .compare-table-wrapper {\n margin: 0 -20px;\n padding: 0 20px;\n }\n\n .run-selector-list {\n max-height: 150px;\n }\n}\n\n@media (max-width: 480px) {\n .compare-summary {\n grid-template-columns: 1fr;\n }\n\n .compare-summary-card .summary-value {\n font-size: 20px;\n }\n\n .analytics-table th,\n .analytics-table td,\n .compare-table th,\n .compare-table td {\n padding: 10px 12px;\n font-size: 12px;\n }\n}\n\n/* ===========================\n Matrix Evaluation Indicators\n =========================== */\n\n/* Human Feedback Indicators */\n.cell-human {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 3px;\n min-width: 22px;\n height: 22px;\n border-radius: 50%;\n font-size: 10px;\n}\n\n.cell-human.no-feedback {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-disabled);\n}\n\n.cell-human.no-feedback i {\n font-size: 11px;\n}\n\n.cell-human.has-feedback {\n padding: 0 6px;\n border-radius: 12px;\n min-width: 36px;\n}\n\n.cell-human.has-feedback i {\n font-size: 9px;\n}\n\n.cell-human.has-feedback .rating-value {\n font-weight: 700;\n font-size: 11px;\n}\n\n/* Human rating color coding: red \u22644, yellow 5-6, light-green 7-8, green 9-10 */\n.cell-human.rating-low {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.cell-human.rating-medium {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-human.rating-good {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.cell-human.rating-excellent {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n/* Auto Score Indicators */\n.cell-auto {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 3px;\n min-width: 22px;\n height: 22px;\n border-radius: 50%;\n font-size: 10px;\n}\n\n.cell-auto.no-score {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-disabled);\n}\n\n.cell-auto.no-score i {\n font-size: 11px;\n}\n\n.cell-auto.has-score {\n padding: 0 6px;\n border-radius: 12px;\n min-width: 36px;\n}\n\n.cell-auto.has-score i {\n font-size: 9px;\n}\n\n.cell-auto.has-score .score-value {\n font-weight: 700;\n font-size: 10px;\n}\n\n/* Auto score color coding (0-100%): red <50, yellow 50-69, light-green 70-84, green 85+ */\n.cell-auto.score-low {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.cell-auto.score-medium {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-auto.score-good {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.cell-auto.score-excellent {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n/* Status indicators in matrix cells */\n.cell-status {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n border-radius: 50%;\n font-size: 11px;\n}\n\n.cell-status.status-passed {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.cell-status.status-failed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.cell-status.status-error {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-status.status-timeout {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-status.status-skipped,\n.cell-status.status-pending {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n}\n\n.cell-status.status-running {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n/* Not-run / Skipped cells with hatch pattern */\n.result-cell.cell-not-run {\n background: repeating-linear-gradient(\n 45deg,\n var(--mj-bg-surface-card),\n var(--mj-bg-surface-card) 4px,\n var(--mj-border-default) 4px,\n var(--mj-border-default) 8px\n );\n color: var(--mj-text-disabled);\n}\n\n.result-cell.cell-not-run .cell-eval-stack {\n opacity: 0.6;\n}\n\n.cell-not-run-indicator {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n color: var(--mj-text-disabled);\n font-size: 11px;\n}\n\n/* ===========================\n Matrix Totals Footer Row\n =========================== */\n.test-matrix tfoot {\n position: sticky;\n bottom: 0;\n z-index: 2;\n}\n\n.totals-row {\n background: var(--mj-bg-surface-sunken);\n border-top: 2px solid var(--test-border);\n}\n\n.totals-row td {\n padding: 10px 12px;\n font-weight: 600;\n}\n\n.totals-row .totals-label {\n background: var(--mj-bg-surface-sunken);\n font-size: 12px;\n color: var(--test-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.totals-row .totals-cell {\n background: var(--mj-bg-surface-sunken);\n}\n\n.totals-stack {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n}\n\n.totals-status,\n.totals-human,\n.totals-auto {\n display: flex;\n align-items: center;\n gap: 4px;\n font-size: 11px;\n padding: 2px 8px;\n border-radius: 10px;\n white-space: nowrap;\n}\n\n.totals-status {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.totals-status .pass-count {\n font-weight: 700;\n}\n\n.totals-human {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.totals-human .avg-label {\n font-weight: 700;\n}\n\n.totals-human .count-label {\n font-size: 10px;\n opacity: 0.8;\n}\n\n.totals-auto {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n}\n\n.totals-auto .avg-label {\n font-weight: 700;\n}\n\n.totals-auto .count-label {\n font-size: 10px;\n opacity: 0.8;\n}\n\n/* ===========================\n Editable Overview Form\n =========================== */\n\n.edit-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.edit-section-header {\n margin: 0 0 18px 0;\n}\n\n.edit-section-header h3 {\n margin: 0 0 4px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.edit-section-header h3 i {\n color: var(--test-primary);\n}\n\n.edit-section-sub {\n margin: 0;\n font-size: 12px;\n color: var(--test-text-muted);\n}\n\n.edit-grid {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 18px;\n}\n\n@media (max-width: 720px) {\n .edit-grid {\n grid-template-columns: 1fr;\n }\n}\n\n.edit-field {\n display: flex;\n flex-direction: column;\n gap: 6px;\n min-width: 0;\n}\n\n.edit-field--full {\n grid-column: 1 / -1;\n}\n\n.edit-field label {\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.edit-field .required {\n color: var(--mj-status-error);\n margin-left: 2px;\n}\n\n.config-textarea {\n resize: vertical;\n min-height: 72px;\n font-family: inherit;\n line-height: 1.5;\n}\n\n.select-wrapper {\n position: relative;\n}\n\n.select-wrapper select.config-input {\n padding-right: 36px;\n appearance: none;\n background-color: var(--test-surface);\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%2364748b' d='M1.41 0L6 4.59 10.59 0 12 1.41l-6 6-6-6z'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: right 14px center;\n background-size: 10px 7px;\n}\n\n/* Tag editor (chips + inline input) */\n.tag-editor {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n padding: 8px 10px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n background: var(--test-surface);\n transition: var(--test-transition);\n cursor: text;\n min-height: 42px;\n align-items: center;\n}\n\n.tag-editor:focus-within {\n border-color: var(--test-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.tag-chip-editable {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 3px 4px 3px 10px;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n border-radius: 999px;\n font-size: 12px;\n font-weight: 600;\n line-height: 1;\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, transparent);\n}\n\n.tag-chip-editable .tag-remove {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 18px;\n height: 18px;\n border-radius: 50%;\n border: none;\n background: transparent;\n color: var(--mj-brand-primary);\n cursor: pointer;\n font-size: 10px;\n transition: background 0.15s;\n}\n\n.tag-chip-editable .tag-remove:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 25%, transparent);\n color: var(--mj-brand-primary-hover);\n}\n\n.tag-input-inline {\n flex: 1;\n min-width: 140px;\n border: none;\n background: transparent;\n outline: none;\n font-size: 13px;\n color: var(--test-text);\n padding: 4px 2px;\n}\n\n.tag-input-inline::placeholder {\n color: var(--test-text-muted);\n}\n\n/* Read-only metadata section */\n.meta-section {\n background: var(--mj-bg-surface-sunken);\n border-radius: var(--test-radius-md);\n padding: 14px 18px;\n border: 1px solid var(--test-border);\n}\n\n.meta-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n gap: 14px;\n}\n\n.meta-item {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n.meta-label {\n font-size: 10px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.meta-value {\n font-size: 12px;\n color: var(--test-text-secondary);\n font-weight: 500;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.meta-mono {\n font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, monospace;\n font-size: 11px;\n}\n\n/* Dirty indicator next to the title */\n.dirty-indicator {\n display: inline-block;\n margin-left: 8px;\n font-size: 14px;\n color: var(--mj-status-warning);\n line-height: 1;\n animation: pulseDot 1.8s ease-in-out infinite;\n vertical-align: middle;\n}\n\n@keyframes pulseDot {\n 0%, 100% { opacity: 1; transform: scale(1); }\n 50% { opacity: 0.5; transform: scale(0.85); }\n}\n\n.unsaved-pill {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning-text, var(--mj-status-warning));\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 30%, transparent);\n border-radius: 999px;\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.4px;\n}\n\n.unsaved-pill i {\n font-size: 6px;\n animation: pulseDot 1.8s ease-in-out infinite;\n}\n\n/* Pad the bottom of the tab content when the save bar is visible\n so the bar doesn't cover the last form field. */\n.tab-content.has-savebar {\n padding-bottom: 84px;\n}\n\n/* ===========================\n Sticky Save Bar\n =========================== */\n\n.save-bar {\n position: absolute;\n left: 16px;\n right: 96px; /* leaves room for the bottom-right chat launcher */\n bottom: 16px;\n z-index: 50;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n padding: 12px 16px 12px 20px;\n background: var(--mj-bg-surface-elevated, var(--test-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 25%, var(--test-border));\n border-radius: 14px;\n box-shadow: 0 12px 32px color-mix(in srgb, var(--mj-status-warning) 10%, rgba(0, 0, 0, 0.18));\n backdrop-filter: blur(8px);\n /* Hidden / off-screen state by default. The .save-bar--visible class\n animates it up into view. Using `transition` (not `animation`)\n guarantees the change runs every time isDirty toggles. */\n opacity: 0;\n transform: translateY(calc(100% + 32px));\n pointer-events: none;\n transition:\n transform 420ms cubic-bezier(0.16, 1, 0.3, 1),\n opacity 260ms cubic-bezier(0.16, 1, 0.3, 1);\n will-change: transform, opacity;\n}\n\n.save-bar--visible {\n opacity: 1;\n transform: translateY(0);\n pointer-events: auto;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .save-bar {\n transition: opacity 180ms ease-out;\n transform: none;\n }\n .save-bar--visible {\n transform: none;\n }\n}\n\n.save-bar-message {\n display: flex;\n align-items: center;\n gap: 12px;\n min-width: 0;\n}\n\n.save-bar-dot {\n color: var(--mj-status-warning);\n font-size: 12px;\n line-height: 1;\n animation: pulseDot 1.8s ease-in-out infinite;\n}\n\n.save-bar-text {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n.save-bar-text strong {\n font-size: 14px;\n color: var(--test-text);\n font-weight: 700;\n}\n\n.save-bar-fields {\n font-size: 12px;\n color: var(--test-text-muted);\n}\n\n.save-bar-actions {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-shrink: 0;\n}\n\n.save-bar-btn {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 9px 16px;\n font-size: 13px;\n font-weight: 600;\n border-radius: 8px;\n border: 1px solid transparent;\n cursor: pointer;\n transition: var(--test-transition);\n font-family: inherit;\n}\n\n.save-bar-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.save-bar-btn--primary {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse, white);\n border-color: var(--mj-brand-primary);\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-brand-primary) 35%, transparent);\n}\n\n.save-bar-btn--primary:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover, var(--mj-brand-primary));\n transform: translateY(-1px);\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 45%, transparent);\n}\n\n.save-bar-btn--primary:active:not(:disabled) {\n transform: translateY(0);\n}\n\n.save-bar-btn--ghost {\n background: transparent;\n color: var(--test-text-secondary);\n border-color: var(--test-border);\n}\n\n.save-bar-btn--ghost:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover, var(--mj-bg-surface-card));\n color: var(--test-text);\n border-color: var(--test-text-muted);\n}\n\n.save-bar-kbd {\n display: inline-flex;\n gap: 3px;\n margin-left: 6px;\n opacity: 0.85;\n}\n\n.save-bar-kbd kbd {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 18px;\n height: 18px;\n padding: 0 4px;\n font-size: 10px;\n font-weight: 600;\n font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, monospace;\n background: color-mix(in srgb, white 18%, transparent);\n border: 1px solid color-mix(in srgb, white 35%, transparent);\n border-radius: 4px;\n color: inherit;\n}\n\n@media (max-width: 640px) {\n .save-bar {\n left: 8px;\n right: 8px;\n bottom: 88px; /* push above the chat launcher on small screens */\n flex-direction: column;\n align-items: stretch;\n padding: 12px;\n }\n .save-bar-actions {\n justify-content: space-between;\n }\n .save-bar-kbd {\n display: none;\n }\n}\n\n/* ===========================\n Tests Tab \u2014 Action Bar + Drag/Remove\n =========================== */\n\n.tests-actionbar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding: 12px 16px;\n margin-bottom: 16px;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n}\n\n.tests-actionbar-text {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n min-width: 0;\n}\n\n.tests-actionbar-text strong {\n font-size: 14px;\n color: var(--test-text);\n font-weight: 700;\n}\n\n.tests-actionbar-count {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 22px;\n height: 22px;\n padding: 0 8px;\n border-radius: 999px;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n font-size: 12px;\n font-weight: 700;\n}\n\n.tests-actionbar-hint {\n font-size: 12px;\n color: var(--test-text-muted);\n}\n\n.tests-actionbar-actions {\n display: flex;\n gap: 8px;\n flex-shrink: 0;\n}\n\n/* Override the default test-item hover translate so drag transforms don't fight it. */\n.tests-list[cdk-drop-list] .test-item:hover,\n.tests-list .test-item.cdk-drag:hover {\n transform: none;\n}\n\n/* The whole row is draggable. .test-content keeps the click-to-open behavior. */\n.test-item.cdk-drag {\n position: relative;\n}\n\n.test-item .test-content {\n cursor: pointer;\n}\n\n/* Drag handle */\n.test-drag-handle {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 28px;\n border-radius: 4px;\n color: var(--test-text-muted);\n cursor: grab;\n flex-shrink: 0;\n transition: background 0.15s, color 0.15s;\n user-select: none;\n}\n\n.test-drag-handle:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n color: var(--test-primary);\n}\n\n.test-drag-handle:active,\n.cdk-drag-preview .test-drag-handle {\n cursor: grabbing;\n}\n\n/* Remove (X) button \u2014 hover-revealed */\n.test-remove-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border-radius: 50%;\n border: none;\n background: transparent;\n color: var(--test-text-muted);\n cursor: pointer;\n flex-shrink: 0;\n opacity: 0;\n transition: opacity 0.15s, background 0.15s, color 0.15s;\n}\n\n.test-item:hover .test-remove-btn,\n.test-remove-btn:focus-visible {\n opacity: 1;\n}\n\n.test-remove-btn:hover {\n background: color-mix(in srgb, var(--mj-status-error) 12%, transparent);\n color: var(--mj-status-error);\n}\n\n.test-chevron {\n cursor: pointer;\n}\n\n/* Inline remove-confirm */\n.test-remove-confirm {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 4px 8px 4px 12px;\n border-radius: 999px;\n background: color-mix(in srgb, var(--mj-status-error) 8%, var(--test-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-error) 30%, transparent);\n flex-shrink: 0;\n}\n\n.test-remove-confirm-text {\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-status-error-text, var(--mj-status-error));\n}\n\n.test-remove-confirm-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 4px 10px;\n border-radius: 6px;\n border: 1px solid transparent;\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n font-family: inherit;\n transition: var(--test-transition);\n}\n\n.test-remove-confirm-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.test-remove-confirm-btn--danger {\n background: var(--mj-status-error);\n color: var(--mj-text-inverse, white);\n}\n\n.test-remove-confirm-btn--danger:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-status-error) 88%, black);\n}\n\n.test-remove-confirm-btn--ghost {\n background: transparent;\n color: var(--test-text-secondary);\n border-color: var(--test-border);\n}\n\n.test-remove-confirm-btn--ghost:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover, var(--mj-bg-surface-card));\n color: var(--test-text);\n}\n\n/* CDK drag-drop visuals */\n.cdk-drag-preview {\n box-shadow: 0 12px 32px rgba(0, 0, 0, 0.25);\n border-radius: var(--test-radius-md);\n background: var(--test-surface);\n opacity: 0.95;\n}\n\n.cdk-drag-placeholder {\n opacity: 0;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n border: 2px dashed var(--test-primary);\n border-radius: var(--test-radius-md);\n}\n\n.cdk-drag-placeholder * {\n visibility: hidden;\n}\n\n.cdk-drag-animating {\n transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);\n}\n\n.tests-list.cdk-drop-list-dragging .test-item:not(.cdk-drag-placeholder) {\n transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);\n}\n\n/* ===========================\n Add Tests Picker Dialog\n =========================== */\n\n.picker-backdrop {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.45);\n z-index: 200;\n animation: pickerFadeIn 180ms ease-out;\n backdrop-filter: blur(2px);\n}\n\n@keyframes pickerFadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n.picker-dialog {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: min(720px, calc(100vw - 32px));\n max-height: min(80vh, 720px);\n z-index: 201;\n display: flex;\n flex-direction: column;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n box-shadow: 0 24px 64px rgba(0, 0, 0, 0.28);\n animation: pickerSlideUp 220ms cubic-bezier(0.16, 1, 0.3, 1);\n overflow: hidden;\n}\n\n@keyframes pickerSlideUp {\n from {\n opacity: 0;\n transform: translate(-50%, calc(-50% + 16px));\n }\n to {\n opacity: 1;\n transform: translate(-50%, -50%);\n }\n}\n\n.picker-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 18px 20px;\n border-bottom: 1px solid var(--test-border);\n}\n\n.picker-title {\n margin: 0;\n font-size: 16px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.picker-title i {\n color: var(--test-primary);\n}\n\n.picker-close {\n width: 32px;\n height: 32px;\n border-radius: 8px;\n border: none;\n background: transparent;\n color: var(--test-text-muted);\n cursor: pointer;\n font-size: 14px;\n transition: background 0.15s, color 0.15s;\n}\n\n.picker-close:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover, var(--mj-bg-surface-card));\n color: var(--test-text);\n}\n\n.picker-close:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.picker-search {\n position: relative;\n padding: 14px 20px 0 20px;\n}\n\n.picker-search-icon {\n position: absolute;\n top: 50%;\n left: 32px;\n transform: translateY(-30%);\n color: var(--test-text-muted);\n font-size: 13px;\n pointer-events: none;\n}\n\n.picker-search-input {\n width: 100%;\n padding: 10px 36px 10px 36px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n background: var(--test-surface);\n font-size: 14px;\n color: var(--test-text);\n font-family: inherit;\n transition: var(--test-transition);\n}\n\n.picker-search-input:focus {\n outline: none;\n border-color: var(--test-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.picker-search-clear {\n position: absolute;\n top: 50%;\n right: 32px;\n transform: translateY(-30%);\n width: 22px;\n height: 22px;\n border-radius: 50%;\n border: none;\n background: transparent;\n color: var(--test-text-muted);\n cursor: pointer;\n font-size: 11px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n\n.picker-search-clear:hover {\n background: var(--mj-bg-surface-hover, var(--mj-bg-surface-card));\n color: var(--test-text);\n}\n\n.picker-toolbar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 20px;\n border-bottom: 1px solid var(--test-border);\n}\n\n.picker-toolbar-status {\n font-size: 12px;\n color: var(--test-text-secondary);\n}\n\n.picker-toolbar-status strong {\n color: var(--mj-brand-primary-hover);\n font-weight: 700;\n}\n\n.picker-toolbar-actions {\n display: flex;\n gap: 14px;\n}\n\n.picker-link-btn {\n border: none;\n background: transparent;\n color: var(--test-primary);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n padding: 0;\n font-family: inherit;\n}\n\n.picker-link-btn:hover:not(:disabled) {\n text-decoration: underline;\n}\n\n.picker-link-btn:disabled {\n color: var(--test-text-muted);\n cursor: not-allowed;\n}\n\n.picker-body {\n flex: 1;\n overflow-y: auto;\n padding: 8px 12px;\n min-height: 200px;\n}\n\n.picker-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 40px;\n}\n\n.picker-list {\n list-style: none;\n padding: 0;\n margin: 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.picker-row {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 12px;\n border-radius: 8px;\n cursor: pointer;\n transition: background 0.12s, border-color 0.12s;\n border: 1px solid transparent;\n}\n\n.picker-row:hover {\n background: var(--mj-bg-surface-hover, var(--mj-bg-surface-card));\n}\n\n.picker-row:focus-visible {\n outline: none;\n border-color: var(--test-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.picker-row--selected {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--test-surface));\n border-color: color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n.picker-row--selected:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--test-surface));\n}\n\n.picker-check {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n border-radius: 5px;\n border: 1.5px solid var(--test-border);\n background: var(--test-surface);\n color: var(--mj-text-inverse, white);\n font-size: 11px;\n flex-shrink: 0;\n transition: background 0.12s, border-color 0.12s;\n}\n\n.picker-row--selected .picker-check {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n}\n\n.picker-row-main {\n flex: 1;\n min-width: 0;\n}\n\n.picker-row-name {\n font-size: 13px;\n font-weight: 600;\n color: var(--test-text);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.picker-row-desc {\n font-size: 12px;\n color: var(--test-text-muted);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n margin-top: 2px;\n}\n\n.picker-row-meta {\n display: flex;\n align-items: center;\n gap: 6px;\n flex-shrink: 0;\n}\n\n.picker-row-pill {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n border-radius: 999px;\n font-size: 10px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n background: var(--mj-bg-surface-sunken, var(--test-bg));\n color: var(--test-text-secondary);\n border: 1px solid var(--test-border);\n}\n\n.picker-row-pill--status[data-status=\"active\"] {\n background: color-mix(in srgb, var(--mj-status-success) 12%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n border-color: color-mix(in srgb, var(--mj-status-success) 30%, transparent);\n}\n\n.picker-row-pill--status[data-status=\"disabled\"] {\n background: var(--mj-bg-surface-sunken, var(--test-bg));\n color: var(--test-text-muted);\n}\n\n.picker-row-pill--status[data-status=\"pending\"] {\n background: color-mix(in srgb, var(--mj-status-warning) 12%, var(--mj-bg-surface));\n color: var(--mj-status-warning-text, var(--mj-status-warning));\n border-color: color-mix(in srgb, var(--mj-status-warning) 30%, transparent);\n}\n\n.picker-footer {\n display: flex;\n gap: 8px;\n padding: 14px 20px;\n border-top: 1px solid var(--test-border);\n background: var(--mj-bg-surface-sunken, var(--test-bg));\n}\n\n.picker-btn {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 9px 16px;\n font-size: 13px;\n font-weight: 600;\n border-radius: 8px;\n border: 1px solid transparent;\n cursor: pointer;\n font-family: inherit;\n transition: var(--test-transition);\n}\n\n.picker-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.picker-btn--primary {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse, white);\n border-color: var(--mj-brand-primary);\n}\n\n.picker-btn--primary:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover, var(--mj-brand-primary));\n}\n\n.picker-btn--ghost {\n background: transparent;\n color: var(--test-text-secondary);\n border-color: var(--test-border);\n}\n\n.picker-btn--ghost:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover, var(--mj-bg-surface-card));\n color: var(--test-text);\n}\n\n@media (max-width: 640px) {\n .picker-dialog {\n width: calc(100vw - 16px);\n max-height: calc(100vh - 32px);\n }\n .tests-actionbar {\n flex-direction: column;\n align-items: stretch;\n }\n .tests-actionbar-actions {\n justify-content: flex-end;\n }\n .test-remove-btn {\n opacity: 1; /* always visible on touch */\n }\n}\n\n"] }]
|
|
5029
|
+
args: [{ standalone: false, selector: 'mj-test-suite-form', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"test-suite-form\">\n <!-- Header Section -->\n <div class=\"suite-header\">\n <!-- Breadcrumb Navigation -->\n <nav class=\"breadcrumb\" aria-label=\"Breadcrumb\">\n <ol>\n <li>\n <a href=\"javascript:void(0)\" (click)=\"navigateToTestingDashboard()\">\n <i class=\"fas fa-vial\"></i>\n <span class=\"breadcrumb-text\">Testing</span>\n </a>\n </li>\n <li class=\"current\">\n <i class=\"fas fa-chevron-right separator\"></i>\n <i class=\"fas fa-layer-group\"></i>\n <span>{{ record.Name }}</span>\n </li>\n </ol>\n </nav>\n\n <div class=\"header-content\">\n <div class=\"header-left\">\n <div class=\"suite-icon\" [style.background-color]=\"getStatusColor()\">\n <i class=\"fas fa-layer-group\"></i>\n </div>\n <div class=\"suite-info\">\n <h1>\n {{ record.Name }}\n @if (isDirty) {\n <span class=\"dirty-indicator\" title=\"You have unsaved changes\" aria-label=\"Unsaved changes\">\u25CF</span>\n }\n </h1>\n <div class=\"suite-meta\">\n <span class=\"status-badge\" [ngClass]=\"getStatusClass()\">\n <i class=\"fas\" [ngClass]=\"record.Status === 'Active' ? 'fa-circle-check' : 'fa-circle-pause'\"></i>\n {{ record.Status }}\n </span>\n @if (testsLoaded) {\n <span class=\"test-count\">\n <i class=\"fas fa-flask\"></i>\n {{ suiteTests.length }} tests\n </span>\n }\n @if (isDirty) {\n <span class=\"unsaved-pill\" title=\"You have unsaved changes\">\n <i class=\"fas fa-circle\"></i> Unsaved\n </span>\n }\n </div>\n </div>\n </div>\n <div class=\"header-actions\">\n <app-evaluation-mode-toggle></app-evaluation-mode-toggle>\n <button mjButton (click)=\"exportToExcel()\" title=\"Export to CSV\">\n <i class=\"fas fa-file-excel\"></i> Export\n </button>\n <button mjButton (click)=\"runSuite()\" variant=\"primary\">\n <i class=\"fas fa-play\"></i> Run Suite\n </button>\n <button mjButton (click)=\"refresh()\" [disabled]=\"isRefreshing\">\n <i class=\"fas\" [ngClass]=\"isRefreshing ? 'fa-sync fa-spin' : 'fa-sync'\"></i>\n {{ isRefreshing ? 'Refreshing...' : 'Refresh' }}\n </button>\n </div>\n </div>\n @if (record.Description) {\n <div class=\"suite-description\">\n <p>{{ record.Description }}</p>\n </div>\n }\n </div>\n\n <!-- Tabs -->\n <div class=\"tabs-container\">\n <div class=\"tabs\" role=\"tablist\">\n <button class=\"tab\"\n [class.active]=\"activeTab === 'overview'\"\n (click)=\"changeTab('overview')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'overview'\">\n <i class=\"fas fa-th-large\"></i> Overview\n </button>\n <button class=\"tab\"\n [class.active]=\"activeTab === 'tests'\"\n (click)=\"changeTab('tests')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'tests'\">\n <i class=\"fas fa-flask\"></i> Tests\n @if (testsLoaded) {\n <span class=\"tab-badge\">{{ suiteTests.length }}</span>\n }\n </button>\n <button class=\"tab\"\n [class.active]=\"activeTab === 'runs'\"\n (click)=\"changeTab('runs')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'runs'\">\n <i class=\"fas fa-history\"></i> Runs\n @if (runsLoaded) {\n <span class=\"tab-badge\">{{ suiteRuns.length }}</span>\n }\n </button>\n <button class=\"tab\"\n [class.active]=\"activeTab === 'analytics'\"\n (click)=\"changeTab('analytics')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'analytics'\">\n <i class=\"fas fa-chart-line\"></i> Analytics\n </button>\n <button class=\"tab\"\n [class.active]=\"activeTab === 'compare'\"\n (click)=\"changeTab('compare')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'compare'\">\n <i class=\"fas fa-balance-scale\"></i> Compare\n </button>\n </div>\n </div>\n\n <!-- Tab Content -->\n <div class=\"tab-content\" [class.has-savebar]=\"isDirty\">\n <!-- Overview Tab -->\n @if (activeTab === 'overview') {\n <div class=\"overview-tab\">\n <!-- Editable Details -->\n <section class=\"edit-section\">\n <header class=\"edit-section-header\">\n <h3><i class=\"fas fa-pen-to-square\"></i> Details</h3>\n <p class=\"edit-section-sub\">Edit any field \u2014 changes are saved with the bar at the bottom.</p>\n </header>\n <div class=\"edit-grid\">\n <div class=\"edit-field edit-field--full\">\n <label for=\"suite-name\">Name <span class=\"required\">*</span></label>\n <input\n id=\"suite-name\"\n type=\"text\"\n class=\"config-input\"\n placeholder=\"e.g., Core Agent Test Suite\"\n [(ngModel)]=\"record.Name\"\n />\n </div>\n\n <div class=\"edit-field edit-field--full\">\n <label for=\"suite-description\">Description</label>\n <textarea\n id=\"suite-description\"\n class=\"config-input config-textarea\"\n rows=\"3\"\n placeholder=\"What does this suite cover?\"\n [ngModel]=\"record.Description\"\n (ngModelChange)=\"record.Description = $event || null\"\n ></textarea>\n </div>\n\n <div class=\"edit-field\">\n <label for=\"suite-status\">Status</label>\n <div class=\"select-wrapper\">\n <select\n id=\"suite-status\"\n class=\"config-input\"\n [(ngModel)]=\"record.Status\"\n >\n @for (opt of statusOptions; track opt) {\n <option [ngValue]=\"opt\">{{ opt }}</option>\n }\n </select>\n </div>\n </div>\n\n <div class=\"edit-field\">\n <label for=\"suite-rubric\">Rubric</label>\n <select\n id=\"suite-rubric\"\n class=\"config-input\"\n [ngModel]=\"record.RubricID\"\n (ngModelChange)=\"record.RubricID = $event || null\"\n >\n <option [ngValue]=\"null\">\u2014 None \u2014</option>\n @for (rubric of RubricOptions; track rubric.id) {\n <option [ngValue]=\"rubric.id\">{{ rubric.name }}</option>\n }\n </select>\n </div>\n\n <div class=\"edit-field\">\n <label for=\"suite-parent\">Parent Suite</label>\n <select\n id=\"suite-parent\"\n class=\"config-input\"\n [ngModel]=\"record.ParentID\"\n (ngModelChange)=\"record.ParentID = $event || null\"\n >\n <option [ngValue]=\"null\">\u2014 None (top-level) \u2014</option>\n @for (s of parentSuiteOptions; track s.ID) {\n <option [ngValue]=\"s.ID\">{{ s.Name }}</option>\n }\n </select>\n </div>\n\n <div class=\"edit-field edit-field--full\">\n <label for=\"suite-tags\">Tags</label>\n <div class=\"tag-editor\" (click)=\"tagInput.focus()\">\n @for (tag of tags; track tag) {\n <span class=\"tag-chip-editable\">\n {{ tag }}\n <button type=\"button\" class=\"tag-remove\" (click)=\"removeTag(tag); $event.stopPropagation()\" [attr.aria-label]=\"'Remove tag ' + tag\">\n <i class=\"fas fa-times\"></i>\n </button>\n </span>\n }\n <input\n #tagInput\n id=\"suite-tags\"\n type=\"text\"\n class=\"tag-input-inline\"\n [placeholder]=\"tags.length === 0 ? 'Add tags, press Enter or comma...' : ''\"\n [(ngModel)]=\"tagDraft\"\n (keydown)=\"onTagInputKeydown($event)\"\n (blur)=\"addTagFromDraft()\"\n />\n </div>\n <span class=\"config-hint\">Press Enter or comma to add a tag. Backspace on empty input removes the last tag.</span>\n </div>\n </div>\n </section>\n\n <!-- Execution Settings -->\n <section class=\"edit-section\">\n <header class=\"edit-section-header\">\n <h3><i class=\"fas fa-cogs\"></i> Execution Settings</h3>\n </header>\n <div class=\"edit-grid\">\n <div class=\"edit-field\">\n <label for=\"suite-timeout\">Max Execution Time (ms)</label>\n <input\n id=\"suite-timeout\"\n type=\"number\"\n class=\"config-input\"\n placeholder=\"Default: 300000 (5 min)\"\n [ngModel]=\"record.MaxExecutionTimeMS\"\n (ngModelChange)=\"record.MaxExecutionTimeMS = $event === '' || $event === null ? null : +$event\"\n />\n <span class=\"config-hint\">Default timeout for tests in this suite. Currently: {{ formatTimeout(record.MaxExecutionTimeMS) }}</span>\n </div>\n </div>\n </section>\n\n <!-- Metadata (read-only) -->\n <section class=\"meta-section\">\n <div class=\"meta-grid\">\n <div class=\"meta-item\">\n <div class=\"meta-label\">Created</div>\n <div class=\"meta-value\">{{ record.__mj_CreatedAt | date:'medium' }}</div>\n </div>\n <div class=\"meta-item\">\n <div class=\"meta-label\">Last updated</div>\n <div class=\"meta-value\">{{ record.__mj_UpdatedAt | date:'medium' }}</div>\n </div>\n <div class=\"meta-item\">\n <div class=\"meta-label\">Suite ID</div>\n <div class=\"meta-value meta-mono\">{{ record.ID }}</div>\n </div>\n </div>\n </section>\n </div>\n }\n\n <!-- Tests Tab -->\n @if (activeTab === 'tests') {\n <div class=\"tests-tab\">\n <!-- Header: action bar -->\n <div class=\"tests-actionbar\">\n <div class=\"tests-actionbar-text\">\n <strong>Suite tests</strong>\n @if (testsLoaded) {\n <span class=\"tests-actionbar-count\">{{ suiteTests.length }}</span>\n }\n <span class=\"tests-actionbar-hint\">Drag to reorder \u00B7 Hover a row to remove</span>\n </div>\n <div class=\"tests-actionbar-actions\">\n <button mjButton variant=\"primary\" (click)=\"openAddTestsDialog()\" [disabled]=\"isReorderingTests\">\n <i class=\"fas fa-plus\"></i> Add tests\n </button>\n </div>\n </div>\n\n <!-- Loading State -->\n @if (loadingTests) {\n <div class=\"loading-state\">\n <div class=\"skeleton-list\">\n @for (i of [1,2,3,4,5]; track i) {\n <div class=\"skeleton-card\">\n <div class=\"skeleton-sequence\"></div>\n <div class=\"skeleton-icon\"></div>\n <div class=\"skeleton-content\">\n <div class=\"skeleton-line wide\"></div>\n <div class=\"skeleton-line narrow\"></div>\n </div>\n </div>\n }\n </div>\n </div>\n }\n <!-- Tests List -->\n @if (!loadingTests && suiteTests.length > 0) {\n <div class=\"tests-list\" cdkDropList (cdkDropListDropped)=\"onTestDrop($event)\">\n @for (test of suiteTests; track test.ID) {\n <div class=\"test-item\" cdkDrag [cdkDragDisabled]=\"isReorderingTests || isRemovingTest\">\n <span class=\"test-drag-handle\" cdkDragHandle title=\"Drag to reorder\" aria-label=\"Drag to reorder\">\n <i class=\"fas fa-grip-vertical\"></i>\n </span>\n <div class=\"test-sequence\">{{ test.Sequence }}</div>\n <div class=\"test-icon\"><i class=\"fas fa-flask\"></i></div>\n <div class=\"test-content\" (click)=\"openTest(test.TestID)\">\n <div class=\"test-name\">{{ test.Test }}</div>\n <div class=\"test-status\">\n @if (test.Status) {\n <span><i class=\"fas fa-info-circle\"></i> {{ test.Status }}</span>\n }\n </div>\n </div>\n <!-- Inline remove confirm OR hover-reveal X -->\n @if (confirmingRemoveSuiteTestId === test.ID) {\n <div class=\"test-remove-confirm\" (click)=\"$event.stopPropagation()\">\n <span class=\"test-remove-confirm-text\">Remove from suite?</span>\n <button\n type=\"button\"\n class=\"test-remove-confirm-btn test-remove-confirm-btn--danger\"\n (click)=\"confirmRemoveTest(test, $event)\"\n [disabled]=\"isRemovingTest\"\n >\n @if (isRemovingTest) {\n <i class=\"fas fa-spinner fa-spin\"></i>\n } @else {\n Remove\n }\n </button>\n <button\n type=\"button\"\n class=\"test-remove-confirm-btn test-remove-confirm-btn--ghost\"\n (click)=\"cancelRemoveTest($event)\"\n [disabled]=\"isRemovingTest\"\n >\n Cancel\n </button>\n </div>\n } @else {\n <button\n type=\"button\"\n class=\"test-remove-btn\"\n title=\"Remove from suite\"\n aria-label=\"Remove from suite\"\n (click)=\"requestRemoveTest(test, $event)\"\n >\n <i class=\"fas fa-times\"></i>\n </button>\n <i class=\"fas fa-chevron-right test-chevron\" (click)=\"openTest(test.TestID)\"></i>\n }\n </div>\n }\n </div>\n }\n <!-- Empty State -->\n @if (testsLoaded && !loadingTests && suiteTests.length === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-flask\"\n Title=\"No Tests in Suite\"\n Message=\"Add tests to this suite to start running them together.\"\n ActionText=\"Add tests\"\n ActionIcon=\"fa-solid fa-plus\"\n (Action)=\"openAddTestsDialog()\" />\n }\n </div>\n }\n\n <!-- Runs Tab -->\n @if (activeTab === 'runs') {\n <div class=\"runs-tab\">\n <!-- Loading State -->\n @if (loadingRuns) {\n <div class=\"loading-state\">\n <div class=\"skeleton-list\">\n @for (i of [1,2,3]; track i) {\n <div class=\"skeleton-card\">\n <div class=\"skeleton-icon\"></div>\n <div class=\"skeleton-content\">\n <div class=\"skeleton-line wide\"></div>\n <div class=\"skeleton-line narrow\"></div>\n </div>\n </div>\n }\n </div>\n </div>\n }\n <!-- Runs List -->\n @if (!loadingRuns && suiteRuns.length > 0) {\n <div class=\"runs-list\">\n @for (run of suiteRuns; track run) {\n <div class=\"run-item\" (click)=\"openSuiteRun(run.ID)\">\n <div class=\"run-icon\" [style.background-color]=\"getRunStatusColor(run.Status)\">\n <i class=\"fas\"\n [class.fa-check]=\"run.Status === 'Completed'\"\n [class.fa-times]=\"run.Status === 'Failed'\"\n [class.fa-spinner]=\"run.Status === 'Running'\"\n [class.fa-clock]=\"run.Status === 'Pending'\"\n [class.fa-ban]=\"run.Status === 'Cancelled'\"></i>\n </div>\n <div class=\"run-content\">\n <div class=\"run-header\">\n <span class=\"run-id\">Run #{{ run.ID.substring(0, 8) }}</span>\n <span class=\"run-status\" [style.color]=\"getRunStatusColor(run.Status)\">{{ run.Status }}</span>\n </div>\n <div class=\"run-meta\">\n <span><i class=\"fas fa-calendar\"></i> {{ getRelativeTime(run.StartedAt) }}</span>\n @if (run.TotalTests) {\n <span>\n <i class=\"fas fa-check-circle\"></i> {{ run.PassedTests }}/{{ run.TotalTests }}\n ({{ getPassRate(run).toFixed(0) }}%)\n </span>\n }\n </div>\n <!-- Evaluation metrics row -->\n <div class=\"run-eval-metrics\">\n <!-- Status badge -->\n @if (evalPreferences.showExecution) {\n <span class=\"eval-metric status\" [class]=\"'status-' + run.Status.toLowerCase()\">\n <i class=\"fas\"\n [class.fa-circle-check]=\"run.Status === 'Completed'\"\n [class.fa-circle-xmark]=\"run.Status === 'Failed'\"\n [class.fa-spinner]=\"run.Status === 'Running'\"\n [class.fa-clock]=\"run.Status === 'Pending'\"\n [class.fa-ban]=\"run.Status === 'Cancelled'\"></i>\n </span>\n }\n <!-- Human score (placeholder - need avg from suite run) -->\n @if (evalPreferences.showHuman) {\n <span class=\"eval-metric human\" title=\"Human evaluation\">\n <i class=\"fas fa-user\"></i>\n <span class=\"eval-pending\"><i class=\"fas fa-clock\"></i></span>\n </span>\n }\n <!-- Auto score (pass rate as proxy) -->\n @if (evalPreferences.showAuto && run.TotalTests) {\n <span class=\"eval-metric auto\"\n [class.high]=\"getPassRate(run) >= 80\"\n [class.medium]=\"getPassRate(run) >= 50 && getPassRate(run) < 80\"\n [class.low]=\"getPassRate(run) < 50\"\n title=\"Auto score (pass rate)\">\n <i class=\"fas fa-robot\"></i>\n <span>{{ getPassRate(run).toFixed(0) }}%</span>\n </span>\n }\n </div>\n <!-- Tags display -->\n @if (getRunTags(run).length > 0) {\n <div class=\"run-tags\">\n @for (tag of getRunTags(run); track tag) {\n <span class=\"tag-chip\">{{ tag }}</span>\n }\n </div>\n }\n </div>\n <i class=\"fas fa-chevron-right\"></i>\n </div>\n }\n </div>\n }\n <!-- Empty State -->\n @if (runsLoaded && !loadingRuns && suiteRuns.length === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-circle-play\"\n Title=\"No Suite Runs Yet\"\n Message=\"Run this suite to see execution history and results here.\"\n ActionText=\"Run Suite Now\"\n ActionIcon=\"fa-solid fa-play\"\n (Action)=\"runSuite()\" />\n }\n </div>\n }\n\n <!-- Analytics Tab -->\n @if (activeTab === 'analytics') {\n <div class=\"analytics-tab\">\n <!-- Loading State -->\n @if (loadingAnalytics) {\n <div class=\"loading-state\">\n <mj-loading text=\"Loading analytics data...\"></mj-loading>\n </div>\n }\n @if (!loadingAnalytics && analyticsLoaded) {\n <!-- View Toggle Sub-nav -->\n <div class=\"analytics-subnav\">\n <div class=\"subnav-tabs\">\n <button class=\"subnav-tab\"\n [class.active]=\"analyticsView === 'summary'\"\n (click)=\"setAnalyticsView('summary')\">\n <i class=\"fas fa-chart-bar\"></i>\n <span>Summary</span>\n </button>\n <button class=\"subnav-tab\"\n [class.active]=\"analyticsView === 'matrix'\"\n (click)=\"setAnalyticsView('matrix')\">\n <i class=\"fas fa-th\"></i>\n <span>Matrix</span>\n </button>\n <button class=\"subnav-tab\"\n [class.active]=\"analyticsView === 'chart'\"\n (click)=\"setAnalyticsView('chart')\">\n <i class=\"fas fa-project-diagram\"></i>\n <span>Chart</span>\n </button>\n </div>\n </div>\n <!-- Collapsible Filters (shared by both views) -->\n <mj-accordion-panel Size=\"sm\" [FlushBody]=\"true\"\n [Expanded]=\"!filtersCollapsed\" (ExpandedChange)=\"onFiltersExpandedChange($event)\">\n <ng-template mjAccordionTitle>\n <i class=\"fas fa-filter\" style=\"color: var(--test-primary);\"></i>\n Filters\n @if (filtersCollapsed) {\n <span class=\"mj-accordion-badge mj-accordion-badge--right mj-accordion-badge--muted\">\n {{ analyticsTimeRange === 'all' ? 'All Time' : analyticsTimeRange }}\n @if (selectedTags.length > 0) {\n <span> \u00B7 {{ selectedTags.length }} tags</span>\n }\n </span>\n }\n </ng-template>\n <ng-template mjAccordionBody>\n <div class=\"filters-content\">\n <div class=\"filter-group\">\n <label>Time Range</label>\n <div class=\"filter-buttons\">\n <button class=\"filter-btn\" [class.active]=\"analyticsTimeRange === '7d'\" (click)=\"setTimeRange('7d')\">7 Days</button>\n <button class=\"filter-btn\" [class.active]=\"analyticsTimeRange === '30d'\" (click)=\"setTimeRange('30d')\">30 Days</button>\n <button class=\"filter-btn\" [class.active]=\"analyticsTimeRange === '90d'\" (click)=\"setTimeRange('90d')\">90 Days</button>\n <button class=\"filter-btn\" [class.active]=\"analyticsTimeRange === 'all'\" (click)=\"setTimeRange('all')\">All Time</button>\n </div>\n </div>\n @if (uniqueTags.length > 0) {\n <div class=\"filter-group\">\n <label>Filter by Tag @if (selectedTags.length > 0) {\n <span class=\"filter-hint\">({{ selectedTags.length }} selected)</span>\n }</label>\n <div class=\"filter-buttons tag-filters\">\n <button class=\"filter-btn tag-btn all-tags-btn\"\n [class.active]=\"selectedTags.length === 0\"\n (click)=\"toggleTagFilter(null)\">\n <i class=\"fas fa-layer-group\"></i> All Tags\n </button>\n @for (tag of uniqueTags; track tag) {\n <button class=\"filter-btn tag-btn\"\n [class.active]=\"isTagSelected(tag)\"\n (click)=\"toggleTagFilter(tag)\">\n @if (isTagSelected(tag)) {\n <i class=\"fas fa-check\"></i>\n }\n {{ tag }}\n </button>\n }\n </div>\n </div>\n }\n </div>\n </ng-template>\n </mj-accordion-panel>\n <!-- Summary View -->\n @if (analyticsView === 'summary') {\n <!-- KPI Cards -->\n <div class=\"analytics-kpis\">\n <div class=\"kpi-card\">\n <div class=\"kpi-icon\"><i class=\"fas fa-play-circle\"></i></div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ getTotalRuns() }}</div>\n <div class=\"kpi-label\">Total Runs</div>\n </div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-icon success\"><i class=\"fas fa-check-circle\"></i></div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ getAveragePassRate().toFixed(1) }}%</div>\n <div class=\"kpi-label\">Avg Pass Rate</div>\n <div class=\"kpi-trend\" [ngClass]=\"{'trend-up': getPassRateTrend().direction === 'up', 'trend-down': getPassRateTrend().direction === 'down'}\">\n <i class=\"fas\" [ngClass]=\"{'fa-arrow-up': getPassRateTrend().direction === 'up', 'fa-arrow-down': getPassRateTrend().direction === 'down', 'fa-minus': getPassRateTrend().direction === 'stable'}\"></i>\n {{ getPassRateTrend().value.toFixed(1) }}%\n </div>\n </div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-icon info\"><i class=\"fas fa-clock\"></i></div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ formatDuration(getAverageDuration()) }}</div>\n <div class=\"kpi-label\">Avg Duration</div>\n </div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-icon warning\"><i class=\"fas fa-dollar-sign\"></i></div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ formatCost(getTotalCost()) }}</div>\n <div class=\"kpi-label\">Total Cost</div>\n </div>\n </div>\n </div>\n <!-- Runs Table -->\n <div class=\"analytics-table-section\">\n <h3><i class=\"fas fa-table\"></i> Run History</h3>\n <div class=\"analytics-table-wrapper\">\n <table class=\"analytics-table\">\n <thead>\n <tr>\n <th>Date</th>\n <th>Status</th>\n <th>Pass Rate</th>\n <th>Tests</th>\n <th>Duration</th>\n <th>Cost</th>\n <th>Tags</th>\n </tr>\n </thead>\n <tbody>\n @for (dp of getFilteredAnalyticsData(); track dp) {\n <tr (click)=\"openSuiteRun(dp.runId)\" class=\"clickable-row\">\n <td>{{ dp.date | date:'short' }}</td>\n <td>\n <span class=\"status-chip\" [ngClass]=\"'status-' + dp.status.toLowerCase()\">{{ dp.status }}</span>\n </td>\n <td>\n <div class=\"pass-rate-cell\">\n <div class=\"pass-rate-bar\" [style.width.%]=\"dp.passRate\" [ngClass]=\"{'high': dp.passRate >= 80, 'medium': dp.passRate >= 50 && dp.passRate < 80, 'low': dp.passRate < 50}\"></div>\n <span>{{ dp.passRate.toFixed(0) }}%</span>\n </div>\n </td>\n <td>{{ dp.passedTests }}/{{ dp.totalTests }}</td>\n <td>{{ formatDuration(dp.duration) }}</td>\n <td>{{ formatCost(dp.cost) }}</td>\n <td>\n <div class=\"tag-cell\">\n @for (tag of dp.tags.slice(0, 2); track tag) {\n <span class=\"tag-chip-table\">{{ tag }}</span>\n }\n @if (dp.tags.length > 2) {\n <span class=\"tag-more\">+{{ dp.tags.length - 2 }}</span>\n }\n </div>\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n @if (getFilteredAnalyticsData().length === 0) {\n <mj-empty-state\n Variant=\"no-results\"\n Size=\"compact\"\n Title=\"No runs match the current filters.\" />\n }\n </div>\n }\n <!-- Matrix View -->\n @if (analyticsView === 'matrix') {\n <!-- Loading Matrix -->\n @if (loadingMatrix) {\n <div class=\"loading-state\">\n <mj-loading text=\"Loading test matrix...\"></mj-loading>\n </div>\n }\n <!-- Matrix Content -->\n @if (!loadingMatrix && matrixLoaded && matrixData.length > 0) {\n <div class=\"matrix-section\">\n <div class=\"matrix-header\">\n <h3><i class=\"fas fa-th\"></i> Test Results Matrix</h3>\n <div class=\"matrix-header-right\">\n <div class=\"matrix-filter-input\">\n <i class=\"fas fa-search\"></i>\n <input type=\"text\"\n placeholder=\"Filter tests...\"\n [value]=\"matrixTestFilter\"\n (input)=\"onMatrixFilterInput($event)\"\n class=\"filter-input\">\n @if (matrixTestFilter) {\n <button class=\"clear-filter-btn\" (click)=\"clearMatrixFilter()\" title=\"Clear filter\">\n <i class=\"fas fa-times\"></i>\n </button>\n }\n </div>\n <span class=\"matrix-run-count\">{{ matrixData.length }} runs \u00B7 {{ getUniqueTestsFromMatrix().length }} tests</span>\n <button mjButton (click)=\"exportMatrixToCSV()\" [disabled]=\"matrixData.length === 0\" title=\"Export matrix to CSV\">\n <i class=\"fas fa-download\"></i> Export\n </button>\n </div>\n </div>\n <div class=\"matrix-scroll-container\">\n <table class=\"test-matrix\">\n <thead>\n <tr>\n <th class=\"seq-header\" (click)=\"toggleMatrixSort('sequence')\" title=\"Sort by sequence\">\n #\n <i class=\"fas\" [ngClass]=\"matrixSortBy === 'sequence' ? (matrixSortAsc ? 'fa-sort-up' : 'fa-sort-down') : 'fa-sort'\"></i>\n </th>\n <th class=\"test-name-header\" (click)=\"toggleMatrixSort('name')\" title=\"Sort by name\">\n Test\n <i class=\"fas\" [ngClass]=\"matrixSortBy === 'name' ? (matrixSortAsc ? 'fa-sort-up' : 'fa-sort-down') : 'fa-sort'\"></i>\n </th>\n @for (run of matrixData; track run) {\n <th class=\"run-header\" (click)=\"openSuiteRun(run.runId)\" [title]=\"'Click to view suite run - ' + (run.date | date:'medium')\">\n <div class=\"run-header-content\">\n @if (run.tags.length > 0) {\n <div class=\"run-tags-header\">\n @for (tag of run.tags.slice(0, 2); track tag) {\n <span class=\"tag-chip-header\">{{ tag }}</span>\n }\n @if (run.tags.length > 2) {\n <span class=\"tag-more-header\">+{{ run.tags.length - 2 }}</span>\n }\n </div>\n }\n <div class=\"run-date\">{{ getRelativeTime(run.date) }}</div>\n <div class=\"run-pass-rate\" [ngClass]=\"{'high': run.passRate >= 80, 'medium': run.passRate >= 50 && run.passRate < 80, 'low': run.passRate < 50}\">\n {{ run.passRate.toFixed(0) }}%\n </div>\n </div>\n </th>\n }\n <th class=\"spacer-header\"></th>\n </tr>\n </thead>\n <tbody>\n @for (test of getUniqueTestsFromMatrix(); track test) {\n <tr\n [class.row-selected]=\"selectedMatrixTestId === test.testId\"\n (click)=\"selectMatrixRow(test.testId)\">\n <td class=\"seq-cell\">{{ test.sequence }}</td>\n <td class=\"test-name-cell\">\n <span class=\"test-name\" [title]=\"test.testName\">{{ test.testName }}</span>\n </td>\n @for (run of matrixData; track run) {\n <td class=\"result-cell\"\n [ngClass]=\"getMatrixCellClass(getTestResultForRun(run.runId, test.testId))\"\n [class.clickable]=\"getTestResultForRun(run.runId, test.testId)\"\n [class.cell-not-run]=\"!getTestResultForRun(run.runId, test.testId)\"\n [title]=\"getTestResultForRun(run.runId, test.testId)?.status + ' - Click to view test run' || 'Not Run'\"\n (click)=\"onMatrixCellClick(getTestResultForRun(run.runId, test.testId), $event)\">\n @if (getTestResultForRun(run.runId, test.testId); as result) {\n <div class=\"cell-eval-stack\">\n <!-- Status indicator -->\n @if (evalPreferences.showExecution) {\n <span class=\"cell-status\"\n [ngClass]=\"'status-' + result.status.toLowerCase()\"\n [class.cell-skipped-status]=\"result.status === 'Skipped' || result.status === 'Pending'\"\n [title]=\"getStatusTooltip(result.status)\">\n <i class=\"fas\"\n [class.fa-check]=\"result.status === 'Passed'\"\n [class.fa-times]=\"result.status === 'Failed'\"\n [class.fa-exclamation]=\"result.status === 'Error'\"\n [class.fa-hourglass-end]=\"result.status === 'Timeout'\"\n [class.fa-forward]=\"result.status === 'Skipped'\"\n [class.fa-spinner]=\"result.status === 'Running'\"\n [class.fa-clock]=\"result.status === 'Pending'\"></i>\n </span>\n }\n <!-- Human score - slashed icon if no feedback, colored by rating if has feedback -->\n @if (evalPreferences.showHuman && !result.humanRating) {\n <span class=\"cell-human no-feedback\"\n title=\"Human Review: No rating submitted yet\">\n <i class=\"fas fa-user-slash\"></i>\n </span>\n }\n @if (evalPreferences.showHuman && result.humanRating) {\n <span class=\"cell-human has-feedback\"\n [class.rating-low]=\"result.humanRating <= 4\"\n [class.rating-medium]=\"result.humanRating >= 5 && result.humanRating <= 6\"\n [class.rating-good]=\"result.humanRating >= 7 && result.humanRating <= 8\"\n [class.rating-excellent]=\"result.humanRating >= 9\"\n [title]=\"getHumanTooltip(result.humanRating, result.humanComments)\">\n <i class=\"fas fa-user\"></i>\n <span class=\"rating-value\">{{ result.humanRating }}</span>\n </span>\n }\n <!-- Auto score - colored by percentage -->\n @if (evalPreferences.showAuto && result.score != null) {\n <span class=\"cell-auto has-score\"\n [class.score-low]=\"result.score < 0.5\"\n [class.score-medium]=\"result.score >= 0.5 && result.score < 0.7\"\n [class.score-good]=\"result.score >= 0.7 && result.score < 0.85\"\n [class.score-excellent]=\"result.score >= 0.85\"\n [title]=\"'Auto Score: ' + (result.score * 100).toFixed(0) + '% automated evaluation'\">\n <i class=\"fas fa-robot\"></i>\n <span class=\"score-value\">{{ (result.score * 100).toFixed(0) }}</span>\n </span>\n }\n @if (evalPreferences.showAuto && result.score == null) {\n <span class=\"cell-auto no-score\"\n title=\"Auto Score: No automated score available\">\n <i class=\"fas fa-robot\"></i>\n </span>\n }\n </div>\n }\n @if (!getTestResultForRun(run.runId, test.testId)) {\n <span class=\"cell-not-run-indicator\">\n <i class=\"fas fa-minus\"></i>\n </span>\n }\n </td>\n }\n <td class=\"spacer-cell\"></td>\n </tr>\n }\n </tbody>\n <!-- Footer row with totals -->\n <tfoot>\n <tr class=\"totals-row\">\n <td class=\"seq-cell totals-label\"></td>\n <td class=\"test-name-cell totals-label\">\n <strong>Totals</strong>\n </td>\n @for (run of matrixData; track run) {\n <td class=\"result-cell totals-cell\">\n <div class=\"cell-eval-stack totals-stack\">\n <!-- Status totals -->\n @if (evalPreferences.showExecution) {\n <span class=\"totals-status\">\n <span class=\"pass-count\">{{ getRunPassedCount(run) }}/{{ getRunTotalCount(run) }}</span>\n </span>\n }\n <!-- Human totals -->\n @if (evalPreferences.showHuman) {\n <span class=\"totals-human\">\n @if (getRunHumanAvg(run) != null) {\n <span class=\"avg-label\">{{ getRunHumanAvg(run)?.toFixed(1) }}</span>\n }\n <span class=\"count-label\">({{ getRunHumanCount(run) }})</span>\n </span>\n }\n <!-- Auto totals -->\n @if (evalPreferences.showAuto) {\n <span class=\"totals-auto\">\n @if (getRunAutoAvg(run) != null) {\n <span class=\"avg-label\">{{ (getRunAutoAvg(run)! * 100).toFixed(0) }}%</span>\n }\n <span class=\"count-label\">({{ getRunAutoCount(run) }})</span>\n </span>\n }\n </div>\n </td>\n }\n <td class=\"spacer-cell\"></td>\n </tr>\n </tfoot>\n </table>\n </div>\n </div>\n }\n <!-- Empty Matrix State -->\n @if (!loadingMatrix && matrixLoaded && matrixData.length === 0) {\n <mj-empty-state\n Variant=\"no-results\"\n Icon=\"fa-solid fa-table-cells\"\n Title=\"No Matrix Data\"\n Message=\"No suite runs match the current filters.\" />\n }\n }\n <!-- Chart View -->\n @if (analyticsView === 'chart') {\n <!-- Loading Chart -->\n @if (loadingMatrix) {\n <div class=\"loading-state\">\n <mj-loading text=\"Loading chart data...\"></mj-loading>\n </div>\n }\n <!-- Chart Content -->\n @if (!loadingMatrix && matrixLoaded && matrixData.length > 0) {\n <div class=\"chart-section\">\n <div class=\"chart-header\">\n <h3><i class=\"fas fa-project-diagram\"></i> Test Results Flow</h3>\n <div class=\"chart-legend\">\n <span class=\"legend-item chart-passed\"><i class=\"fas fa-check\"></i> Passed</span>\n <span class=\"legend-item chart-failed\"><i class=\"fas fa-times\"></i> Failed</span>\n <span class=\"legend-item chart-error\"><i class=\"fas fa-exclamation\"></i> Error</span>\n <span class=\"legend-item chart-skipped\"><i class=\"fas fa-forward\"></i> Skipped</span>\n </div>\n </div>\n <div class=\"chart-container\">\n <div #chartContainer class=\"d3-chart\"></div>\n </div>\n <div class=\"chart-info\">\n <i class=\"fas fa-info-circle\"></i>\n Interactive visualization showing test results across {{ matrixData.length }} runs.\n Hover over elements for details, click nodes to navigate.\n </div>\n </div>\n }\n <!-- Empty Chart State -->\n @if (!loadingMatrix && matrixLoaded && matrixData.length === 0) {\n <mj-empty-state\n Variant=\"no-results\"\n Icon=\"fa-solid fa-diagram-project\"\n Title=\"No Chart Data\"\n Message=\"No suite runs match the current filters.\" />\n }\n }\n }\n <!-- Empty State -->\n @if (!loadingAnalytics && analyticsLoaded && analyticsData.length === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-chart-line\"\n Title=\"No Analytics Data\"\n Message=\"Run this suite to start collecting analytics data.\"\n ActionText=\"Run Suite Now\"\n ActionIcon=\"fa-solid fa-play\"\n (Action)=\"runSuite()\" />\n }\n </div>\n }\n\n <!-- Compare Tab -->\n @if (activeTab === 'compare') {\n <div class=\"compare-tab\">\n <!-- Run Selection -->\n <div class=\"compare-selection\">\n <div class=\"compare-run-selector\">\n <h4>Run A (Baseline)</h4>\n @if (!loadingRuns && suiteRuns.length > 0) {\n <div class=\"run-selector-list\">\n @for (run of suiteRuns; track run) {\n <div class=\"run-selector-item\"\n [class.selected]=\"IsCompareRunA(run)\"\n (click)=\"selectCompareRunA(run)\">\n <div class=\"selector-status\" [style.background-color]=\"getRunStatusColor(run.Status)\"></div>\n <div class=\"selector-content\">\n <div class=\"selector-date\">{{ run.StartedAt | date:'short' }}</div>\n <div class=\"selector-rate\">{{ getPassRate(run).toFixed(0) }}% pass</div>\n </div>\n @if (getRunTags(run).length > 0) {\n <div class=\"selector-tags\">\n @for (tag of getRunTags(run).slice(0, 2); track tag) {\n <span class=\"tag-mini\">{{ tag }}</span>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n @if (compareRunA) {\n <div class=\"selected-run-preview\">\n <div class=\"preview-header\">\n <span class=\"preview-label\">Selected:</span>\n <button class=\"clear-btn\" (click)=\"compareRunA = null; compareResults = []\">Clear</button>\n </div>\n <div class=\"preview-details\">\n <span>{{ compareRunA.StartedAt | date:'medium' }}</span>\n <span class=\"preview-rate\">{{ getPassRate(compareRunA).toFixed(1) }}%</span>\n </div>\n </div>\n }\n </div>\n <div class=\"compare-vs\"><i class=\"fas fa-exchange-alt\"></i></div>\n <div class=\"compare-run-selector\">\n <h4>Run B (Compare)</h4>\n @if (!loadingRuns && suiteRuns.length > 0) {\n <div class=\"run-selector-list\">\n @for (run of suiteRuns; track run) {\n <div class=\"run-selector-item\"\n [class.selected]=\"IsCompareRunB(run)\"\n [class.disabled]=\"IsCompareRunA(run)\"\n (click)=\"!IsCompareRunA(run) && selectCompareRunB(run)\">\n <div class=\"selector-status\" [style.background-color]=\"getRunStatusColor(run.Status)\"></div>\n <div class=\"selector-content\">\n <div class=\"selector-date\">{{ run.StartedAt | date:'short' }}</div>\n <div class=\"selector-rate\">{{ getPassRate(run).toFixed(0) }}% pass</div>\n </div>\n @if (getRunTags(run).length > 0) {\n <div class=\"selector-tags\">\n @for (tag of getRunTags(run).slice(0, 2); track tag) {\n <span class=\"tag-mini\">{{ tag }}</span>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n @if (compareRunB) {\n <div class=\"selected-run-preview\">\n <div class=\"preview-header\">\n <span class=\"preview-label\">Selected:</span>\n <button class=\"clear-btn\" (click)=\"compareRunB = null; compareResults = []\">Clear</button>\n </div>\n <div class=\"preview-details\">\n <span>{{ compareRunB.StartedAt | date:'medium' }}</span>\n <span class=\"preview-rate\">{{ getPassRate(compareRunB).toFixed(1) }}%</span>\n </div>\n </div>\n }\n </div>\n </div>\n <!-- Comparison Results -->\n @if (compareRunA && compareRunB && !loadingCompare) {\n <div class=\"compare-results\">\n <!-- Summary Cards -->\n <div class=\"compare-summary\">\n <div class=\"compare-summary-card\">\n <div class=\"summary-label\">Pass Rate Change</div>\n <div class=\"summary-value\" [ngClass]=\"{'positive': getComparePassRateDiff()! > 0, 'negative': getComparePassRateDiff()! < 0}\">\n <i class=\"fas\" [ngClass]=\"{'fa-arrow-up': getComparePassRateDiff()! > 0, 'fa-arrow-down': getComparePassRateDiff()! < 0, 'fa-minus': getComparePassRateDiff() === 0}\"></i>\n {{ getComparePassRateDiff()! > 0 ? '+' : '' }}{{ getComparePassRateDiff()?.toFixed(1) }}%\n </div>\n </div>\n <div class=\"compare-summary-card\">\n <div class=\"summary-label\">Duration Change</div>\n <div class=\"summary-value\" [ngClass]=\"{'positive': getCompareDurationDiff()! < 0, 'negative': getCompareDurationDiff()! > 0}\">\n <i class=\"fas\" [ngClass]=\"{'fa-arrow-down': getCompareDurationDiff()! < 0, 'fa-arrow-up': getCompareDurationDiff()! > 0, 'fa-minus': getCompareDurationDiff() === 0}\"></i>\n {{ formatDuration(getAbsCompareDurationDiff()) }}\n </div>\n </div>\n <div class=\"compare-summary-card improved\">\n <div class=\"summary-label\">Improved</div>\n <div class=\"summary-value\">{{ getCompareImprovedCount() }}</div>\n </div>\n <div class=\"compare-summary-card regressed\">\n <div class=\"summary-label\">Regressed</div>\n <div class=\"summary-value\">{{ getCompareRegressedCount() }}</div>\n </div>\n </div>\n <!-- Detailed Comparison Table -->\n <div class=\"compare-table-section\">\n <h3><i class=\"fas fa-list\"></i> Test-by-Test Comparison</h3>\n <div class=\"compare-table-wrapper\">\n <table class=\"compare-table\">\n <thead>\n <tr>\n <th>Test</th>\n <th>Run A Status</th>\n <th>Run B Status</th>\n <th>Score Diff</th>\n <th>Duration Diff</th>\n <th>Change</th>\n </tr>\n </thead>\n <tbody>\n @for (result of compareResults; track result) {\n <tr [ngClass]=\"{'improved': result.runA && result.runB && result.runA.status !== 'Passed' && result.runB.status === 'Passed', 'regressed': result.runA && result.runB && result.runA.status === 'Passed' && result.runB.status !== 'Passed'}\">\n <td class=\"test-name-cell\">{{ result.testName }}</td>\n <td>\n @if (result.runA) {\n <span class=\"status-chip\" [ngClass]=\"'status-' + result.runA.status.toLowerCase()\">{{ result.runA.status }}</span>\n }\n @if (!result.runA) {\n <span class=\"status-chip status-missing\">N/A</span>\n }\n </td>\n <td>\n @if (result.runB) {\n <span class=\"status-chip\" [ngClass]=\"'status-' + result.runB.status.toLowerCase()\">{{ result.runB.status }}</span>\n }\n @if (!result.runB) {\n <span class=\"status-chip status-missing\">N/A</span>\n }\n </td>\n <td>\n @if (result.scoreDiff != null) {\n <span [ngClass]=\"{'positive': result.scoreDiff > 0, 'negative': result.scoreDiff < 0}\">\n {{ result.scoreDiff > 0 ? '+' : '' }}{{ (result.scoreDiff * 100).toFixed(1) }}%\n </span>\n }\n @if (result.scoreDiff == null) {\n <span class=\"muted\">-</span>\n }\n </td>\n <td>\n @if (result.durationDiff != null) {\n <span [ngClass]=\"{'positive': result.durationDiff < 0, 'negative': result.durationDiff > 0}\">\n {{ result.durationDiff > 0 ? '+' : '' }}{{ result.durationDiff.toFixed(1) }}s\n </span>\n }\n @if (result.durationDiff == null) {\n <span class=\"muted\">-</span>\n }\n </td>\n <td>\n @if (result.runA && result.runB && result.runA.status !== 'Passed' && result.runB.status === 'Passed') {\n <span class=\"change-indicator improved\">\n <i class=\"fas fa-arrow-up\"></i> Fixed\n </span>\n }\n @if (result.runA && result.runB && result.runA.status === 'Passed' && result.runB.status !== 'Passed') {\n <span class=\"change-indicator regressed\">\n <i class=\"fas fa-arrow-down\"></i> Broke\n </span>\n }\n @if (!result.statusChanged) {\n <span class=\"change-indicator unchanged\">\n <i class=\"fas fa-minus\"></i>\n </span>\n }\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </div>\n </div>\n }\n <!-- Loading State for Compare -->\n @if (loadingCompare) {\n <div class=\"loading-state\">\n <mj-loading text=\"Loading comparison data...\"></mj-loading>\n </div>\n }\n <!-- Empty State -->\n @if (!compareRunA || !compareRunB) {\n <mj-empty-state\n Icon=\"fa-solid fa-scale-balanced\"\n Title=\"Select Two Runs to Compare\"\n Message=\"Choose a baseline run (A) and a comparison run (B) from the lists above to see a detailed side-by-side comparison.\" />\n }\n <!-- No Runs State -->\n @if (runsLoaded && suiteRuns.length < 2) {\n <mj-empty-state\n Icon=\"fa-solid fa-scale-balanced\"\n Title=\"Not Enough Runs to Compare\"\n Message=\"You need at least 2 suite runs to use the comparison feature.\"\n ActionText=\"Run Suite Now\"\n ActionIcon=\"fa-solid fa-play\"\n (Action)=\"runSuite()\" />\n }\n </div>\n }\n </div>\n\n <!-- Keyboard Shortcuts Toggle Button -->\n <button class=\"shortcuts-toggle\" (click)=\"toggleShortcuts()\" [title]=\"showShortcuts ? 'Hide keyboard shortcuts' : 'Show keyboard shortcuts'\">\n <i class=\"fas fa-keyboard\"></i>\n </button>\n\n <!-- Keyboard Shortcuts Hint (Desktop Only) -->\n @if (showShortcuts) {\n <div class=\"keyboard-shortcuts\">\n <div class=\"shortcuts-header\">\n <i class=\"fas fa-keyboard\"></i>\n Shortcuts\n <button class=\"shortcuts-close\" (click)=\"toggleShortcuts()\" title=\"Hide shortcuts\">\n <i class=\"fas fa-times\"></i>\n </button>\n </div>\n <div class=\"shortcut-list\">\n <div class=\"shortcut-item\">\n <span>Save changes</span>\n <span class=\"shortcut-keys\"><kbd>Cmd</kbd><kbd>S</kbd></span>\n </div>\n <div class=\"shortcut-item\">\n <span>Refresh</span>\n <span class=\"shortcut-keys\"><kbd>Cmd</kbd><kbd>R</kbd></span>\n </div>\n <div class=\"shortcut-item\">\n <span>Run Suite</span>\n <span class=\"shortcut-keys\"><kbd>Cmd</kbd><kbd>Enter</kbd></span>\n </div>\n <div class=\"shortcut-item\">\n <span>Switch Tabs</span>\n <span class=\"shortcut-keys\"><kbd>1</kbd>-<kbd>5</kbd></span>\n </div>\n </div>\n </div>\n }\n\n <!-- Slide Panel for Suite Execution -->\n @if (testingDialogService.IsPanelOpen) {\n <mj-slide-panel\n Mode=\"slide\"\n [Title]=\"testingDialogService.PanelOptions?.suiteId ? 'Suite Execution' : 'Run Suite'\"\n [Resizable]=\"true\"\n (Closed)=\"OnPanelClosed()\">\n <app-test-run-dialog\n [PanelMode]=\"true\"\n [selectedTestId]=\"testingDialogService.PanelOptions?.testId ?? null\"\n [selectedSuiteId]=\"testingDialogService.PanelOptions?.suiteId ?? null\"\n [runMode]=\"testingDialogService.PanelOptions?.mode ?? 'suite'\"\n (PanelClose)=\"OnPanelClosed()\">\n </app-test-run-dialog>\n </mj-slide-panel>\n }\n\n <!-- Add Tests Picker Dialog -->\n @if (showAddTestsDialog) {\n <div class=\"picker-backdrop\" (click)=\"closeAddTestsDialog()\"></div>\n <div class=\"picker-dialog\" role=\"dialog\" aria-modal=\"true\" aria-labelledby=\"add-tests-dialog-title\" (click)=\"$event.stopPropagation()\">\n <div class=\"picker-header\">\n <h2 id=\"add-tests-dialog-title\" class=\"picker-title\">\n <i class=\"fas fa-plus-circle\"></i> Add tests to suite\n </h2>\n <button type=\"button\" class=\"picker-close\" (click)=\"closeAddTestsDialog()\" [disabled]=\"isAddingTests\" aria-label=\"Close\">\n <i class=\"fas fa-times\"></i>\n </button>\n </div>\n\n <div class=\"picker-search\">\n <i class=\"fas fa-search picker-search-icon\"></i>\n <input\n #pickerSearch\n type=\"text\"\n class=\"picker-search-input\"\n placeholder=\"Search tests by name, description, or type...\"\n [(ngModel)]=\"addTestsSearch\"\n autofocus\n />\n @if (addTestsSearch) {\n <button type=\"button\" class=\"picker-search-clear\" (click)=\"addTestsSearch = ''\" aria-label=\"Clear search\">\n <i class=\"fas fa-times\"></i>\n </button>\n }\n </div>\n\n <div class=\"picker-toolbar\">\n <span class=\"picker-toolbar-status\">\n @if (selectedTestIdsToAdd.size > 0) {\n <strong>{{ selectedTestIdsToAdd.size }}</strong> selected\n } @else if (!loadingAvailableTests) {\n {{ filteredAvailableTests.length }} test{{ filteredAvailableTests.length === 1 ? '' : 's' }} available\n }\n </span>\n <div class=\"picker-toolbar-actions\">\n <button type=\"button\" class=\"picker-link-btn\" (click)=\"selectAllFiltered()\" [disabled]=\"loadingAvailableTests || filteredAvailableTests.length === 0\">\n Select all\n </button>\n <button type=\"button\" class=\"picker-link-btn\" (click)=\"clearAddSelection()\" [disabled]=\"selectedTestIdsToAdd.size === 0\">\n Clear\n </button>\n </div>\n </div>\n\n <div class=\"picker-body\">\n @if (loadingAvailableTests) {\n <div class=\"picker-loading\">\n <mj-loading text=\"Loading tests...\"></mj-loading>\n </div>\n } @else if (filteredAvailableTests.length === 0) {\n @if (availableTests.length === 0) {\n <mj-empty-state\n Variant=\"success\"\n Size=\"compact\"\n Title=\"Everything's already in the suite\"\n Message=\"This suite contains every available test. Create a new test first to add more.\" />\n } @else {\n <mj-empty-state\n Variant=\"no-results\"\n Size=\"compact\"\n Title=\"No matches\"\n [Message]=\"AddTestsNoMatchMessage\" />\n }\n } @else {\n <ul class=\"picker-list\">\n @for (t of filteredAvailableTests; track t.ID) {\n <li\n class=\"picker-row\"\n [class.picker-row--selected]=\"isAddSelected(t.ID)\"\n (click)=\"toggleAddSelection(t.ID)\"\n role=\"checkbox\"\n [attr.aria-checked]=\"isAddSelected(t.ID)\"\n tabindex=\"0\"\n >\n <span class=\"picker-check\">\n @if (isAddSelected(t.ID)) {\n <i class=\"fas fa-check\"></i>\n }\n </span>\n <div class=\"picker-row-main\">\n <div class=\"picker-row-name\">{{ t.Name }}</div>\n @if (t.Description) {\n <div class=\"picker-row-desc\">{{ t.Description }}</div>\n }\n </div>\n <div class=\"picker-row-meta\">\n @if (t.Type) {\n <span class=\"picker-row-pill\">{{ t.Type }}</span>\n }\n <span class=\"picker-row-pill picker-row-pill--status\" [attr.data-status]=\"t.Status?.toLowerCase()\">{{ t.Status }}</span>\n </div>\n </li>\n }\n </ul>\n }\n </div>\n\n <div class=\"picker-footer\">\n <button\n type=\"button\"\n class=\"picker-btn picker-btn--primary\"\n (click)=\"confirmAddTests()\"\n [disabled]=\"selectedTestIdsToAdd.size === 0 || isAddingTests\"\n >\n @if (isAddingTests) {\n <i class=\"fas fa-spinner fa-spin\"></i> Adding\u2026\n } @else {\n <i class=\"fas fa-check\"></i>\n @if (selectedTestIdsToAdd.size === 0) {\n Add tests\n } @else if (selectedTestIdsToAdd.size === 1) {\n Add 1 test\n } @else {\n Add {{ selectedTestIdsToAdd.size }} tests\n }\n }\n </button>\n <button\n type=\"button\"\n class=\"picker-btn picker-btn--ghost\"\n (click)=\"closeAddTestsDialog()\"\n [disabled]=\"isAddingTests\"\n >\n Cancel\n </button>\n </div>\n </div>\n }\n\n <!-- Sticky Save Bar \u2014 always in the DOM so CSS transitions can fire reliably.\n Visibility is controlled by the .save-bar--visible class, driven by isDirty. -->\n <div\n class=\"save-bar\"\n [class.save-bar--visible]=\"isDirty\"\n [attr.aria-hidden]=\"!isDirty\"\n role=\"region\"\n aria-label=\"Unsaved changes\"\n >\n <div class=\"save-bar-message\">\n <span class=\"save-bar-dot\" aria-hidden=\"true\">\u25CF</span>\n <span class=\"save-bar-text\">\n <strong>Unsaved changes</strong>\n <span class=\"save-bar-fields\">\n @if (dirtyFieldNames.length === 1) {\n {{ dirtyFieldNames[0] }} edited\n } @else if (dirtyFieldNames.length > 1) {\n {{ dirtyFieldNames.length }} fields edited\n }\n </span>\n </span>\n </div>\n <div class=\"save-bar-actions\">\n <button\n type=\"button\"\n class=\"save-bar-btn save-bar-btn--primary\"\n (click)=\"saveChanges()\"\n [disabled]=\"isSaving || !isDirty\"\n [attr.tabindex]=\"isDirty ? 0 : -1\"\n title=\"Save changes (\u2318S)\"\n >\n @if (isSaving) {\n <i class=\"fas fa-spinner fa-spin\"></i> Saving\u2026\n } @else {\n <i class=\"fas fa-check\"></i> Save changes\n <span class=\"save-bar-kbd\"><kbd>\u2318</kbd><kbd>S</kbd></span>\n }\n </button>\n <button\n type=\"button\"\n class=\"save-bar-btn save-bar-btn--ghost\"\n (click)=\"discardChanges()\"\n [disabled]=\"isSaving || !isDirty\"\n [attr.tabindex]=\"isDirty ? 0 : -1\"\n title=\"Discard changes\"\n >\n <i class=\"fas fa-undo\"></i> Discard\n </button>\n </div>\n </div>\n</div>\n", styles: ["/* ===========================\n Test Suite Form - World-Class UX\n =========================== */\n\n/* CSS Custom Properties for Theming - using :host for Angular encapsulation */\n:host {\n --test-primary: var(--mj-brand-primary);\n --test-primary-light: var(--mj-brand-primary);\n --test-success: var(--mj-status-success);\n --test-error: var(--mj-status-error);\n --test-warning: var(--mj-status-warning);\n --test-disabled: var(--mj-text-muted);\n --test-bg: var(--mj-bg-surface-card);\n --test-surface: var(--mj-bg-surface);\n --test-border: var(--mj-border-default);\n --test-text: var(--mj-text-primary);\n --test-text-secondary: var(--mj-text-secondary);\n --test-text-muted: var(--mj-text-disabled);\n --test-radius-sm: 6px;\n --test-radius-md: 10px;\n --test-radius-lg: 16px;\n --test-shadow-sm: var(--mj-shadow-sm);\n --test-shadow-md: var(--mj-shadow-md);\n --test-shadow-lg: var(--mj-shadow-lg);\n --test-transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n display: block;\n height: 100%;\n}\n\n.test-suite-form {\n position: relative;\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--test-bg);\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n}\n\n/* Breadcrumb */\n.breadcrumb {\n margin-bottom: 16px;\n}\n\n.breadcrumb ol {\n display: flex;\n align-items: center;\n gap: 4px;\n list-style: none;\n margin: 0;\n padding: 0;\n font-size: 13px;\n}\n\n.breadcrumb li {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.breadcrumb a {\n color: var(--test-primary);\n text-decoration: none;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 8px;\n border-radius: 6px;\n transition: background 0.15s;\n}\n\n.breadcrumb a:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n text-decoration: none;\n}\n\n.breadcrumb .separator {\n font-size: 10px;\n color: var(--test-text-muted);\n margin: 0 4px;\n}\n\n.breadcrumb .current {\n color: var(--test-text-secondary);\n font-weight: 500;\n}\n\n.breadcrumb-text {\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* Header */\n.suite-header {\n background: var(--test-surface);\n border-bottom: 1px solid var(--test-border);\n padding: 20px;\n}\n\n.header-content {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 16px;\n gap: 16px;\n}\n\n.header-left {\n display: flex;\n gap: 16px;\n flex: 1;\n min-width: 0;\n}\n\n.suite-icon {\n width: 56px;\n height: 56px;\n border-radius: var(--test-radius-md);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-inverse);\n font-size: 24px;\n flex-shrink: 0;\n box-shadow: var(--test-shadow-md);\n transition: var(--test-transition);\n}\n\n.suite-icon:hover { transform: scale(1.05); }\n\n.suite-info { flex: 1; min-width: 0; }\n\n.suite-info h1 {\n margin: 0 0 8px 0;\n font-size: clamp(18px, 4vw, 24px);\n font-weight: 700;\n color: var(--test-text);\n word-wrap: break-word;\n}\n\n.suite-meta {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n.status-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border-radius: 20px;\n color: var(--mj-text-inverse);\n font-size: 12px;\n font-weight: 600;\n text-transform: uppercase;\n}\n\n.status-badge.status-active { background: var(--test-success); }\n.status-badge.status-disabled { background: var(--test-disabled); }\n.status-badge.status-pending { background: var(--test-warning); }\n\n.status-badge-inline {\n display: inline-flex;\n padding: 2px 10px;\n border-radius: 10px;\n color: var(--mj-text-inverse);\n font-size: 11px;\n font-weight: 600;\n}\n\n.status-badge-inline.status-active { background: var(--test-success); }\n.status-badge-inline.status-disabled { background: var(--test-disabled); }\n.status-badge-inline.status-pending { background: var(--test-warning); }\n\n.test-count {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 14px;\n color: var(--test-text-secondary);\n padding: 4px 10px;\n background: var(--test-bg);\n border-radius: var(--test-radius-sm);\n}\n\n.header-actions {\n display: flex;\n gap: 8px;\n flex-shrink: 0;\n}\n\n.suite-description {\n padding: 16px;\n background: var(--mj-bg-surface-card);\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n}\n\n.suite-description p {\n margin: 0;\n color: var(--test-text-secondary);\n line-height: 1.6;\n font-size: 14px;\n}\n\n/* Tabs */\n.tabs-container {\n background: var(--test-surface);\n border-bottom: 1px solid var(--test-border);\n position: sticky;\n top: 0;\n z-index: 10;\n}\n\n.tabs {\n display: flex;\n padding: 0 20px;\n overflow-x: auto;\n scrollbar-width: none;\n}\n\n.tabs::-webkit-scrollbar { display: none; }\n\n.tab {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 14px 18px;\n border: none;\n background: transparent;\n border-bottom: 3px solid transparent;\n color: var(--test-text-secondary);\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n white-space: nowrap;\n}\n\n.tab:hover {\n color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.tab.active {\n color: var(--test-primary);\n border-bottom-color: var(--test-primary);\n font-weight: 600;\n}\n\n.tab-badge {\n background: var(--test-border);\n color: var(--test-text-secondary);\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.tab.active .tab-badge {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n color: var(--test-primary);\n}\n\n.tab-shortcut {\n font-size: 10px;\n color: var(--test-text-muted);\n background: var(--test-bg);\n padding: 2px 6px;\n border-radius: 4px;\n font-weight: 600;\n}\n\n/* Tab Content */\n.tab-content {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n}\n\n/* Overview Tab */\n.overview-tab {\n display: flex;\n flex-direction: column;\n gap: 20px;\n animation: fadeIn 0.3s ease-out;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; transform: translateY(10px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n.info-section, .config-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.info-section h3, .config-section h3 {\n margin: 0 0 20px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.info-section h3 i, .config-section h3 i {\n color: var(--test-primary);\n}\n\n.info-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 16px;\n}\n\n.info-item {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.info-label {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.info-value {\n font-size: 14px;\n color: var(--test-text);\n font-weight: 500;\n}\n\n.config-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n gap: 20px;\n}\n\n.config-item {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.config-item label {\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.config-input {\n padding: 10px 14px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n font-size: 14px;\n transition: var(--test-transition);\n}\n\n.config-input:focus {\n outline: none;\n border-color: var(--test-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.config-hint {\n font-size: 11px;\n color: var(--test-text-muted);\n}\n\n/* Tests Tab */\n.tests-tab, .runs-tab {\n animation: fadeIn 0.3s ease-out;\n}\n\n.loading-state { padding: 0; }\n\n.skeleton-list {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.skeleton-card {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-surface);\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n}\n\n.skeleton-sequence {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n background: linear-gradient(90deg, var(--mj-border-default) 25%, var(--mj-bg-surface-sunken) 50%, var(--mj-border-default) 75%);\n background-size: 200% 100%;\n animation: shimmer 1.5s infinite;\n}\n\n.skeleton-icon {\n width: 40px;\n height: 40px;\n border-radius: var(--test-radius-md);\n background: linear-gradient(90deg, var(--mj-border-default) 25%, var(--mj-bg-surface-sunken) 50%, var(--mj-border-default) 75%);\n background-size: 200% 100%;\n animation: shimmer 1.5s infinite;\n}\n\n.skeleton-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.skeleton-line {\n height: 14px;\n border-radius: 4px;\n background: linear-gradient(90deg, var(--mj-border-default) 25%, var(--mj-bg-surface-sunken) 50%, var(--mj-border-default) 75%);\n background-size: 200% 100%;\n animation: shimmer 1.5s infinite;\n}\n\n.skeleton-line.wide { width: 70%; }\n.skeleton-line.narrow { width: 40%; }\n\n@keyframes shimmer {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n}\n\n.tests-list, .runs-list {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.test-item, .run-item {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.test-item:hover, .run-item:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n border-color: var(--test-primary-light);\n transform: translateX(4px);\n}\n\n.test-sequence {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-bg);\n border-radius: 50%;\n font-size: 14px;\n font-weight: 700;\n color: var(--test-text-secondary);\n flex-shrink: 0;\n}\n\n.test-icon, .run-icon {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: var(--test-radius-md);\n color: var(--mj-text-inverse);\n font-size: 18px;\n flex-shrink: 0;\n box-shadow: var(--test-shadow-sm);\n}\n\n.test-icon {\n background: var(--test-primary);\n}\n\n.test-content, .run-content { flex: 1; min-width: 0; }\n\n.test-name, .run-header {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n margin-bottom: 4px;\n}\n\n.run-header {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.run-id { font-weight: 600; }\n\n.run-status {\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n}\n\n.test-status, .run-meta {\n display: flex;\n gap: 12px;\n font-size: 12px;\n color: var(--test-text-secondary);\n}\n\n.test-status span, .run-meta span {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n}\n\n.test-item > i, .run-item > i {\n color: var(--test-text-muted);\n font-size: 14px;\n transition: var(--test-transition);\n}\n\n.test-item:hover > i, .run-item:hover > i {\n color: var(--test-primary);\n transform: translateX(2px);\n}\n\n/* Keyboard Shortcuts */\n/* Keyboard shortcuts toggle button - visible when shortcuts are hidden */\n.shortcuts-toggle {\n position: fixed;\n bottom: 20px;\n right: 20px;\n width: 36px;\n height: 36px;\n border-radius: 50%;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n box-shadow: var(--test-shadow-md);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--test-text-secondary);\n font-size: 14px;\n z-index: 99;\n transition: var(--test-transition);\n opacity: 0.7;\n}\n\n.shortcuts-toggle:hover {\n opacity: 1;\n transform: scale(1.1);\n color: var(--test-primary);\n border-color: var(--test-primary);\n}\n\n.keyboard-shortcuts {\n position: fixed;\n bottom: 20px;\n right: 20px;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n padding: 12px 16px;\n box-shadow: var(--test-shadow-lg);\n font-size: 12px;\n z-index: 100;\n max-width: 260px;\n}\n\n.shortcuts-header {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-bottom: 10px;\n padding-bottom: 8px;\n border-bottom: 1px solid var(--test-border);\n font-weight: 600;\n color: var(--test-text);\n}\n\n.shortcuts-close {\n margin-left: auto;\n background: none;\n border: none;\n cursor: pointer;\n color: var(--test-text-muted);\n font-size: 12px;\n padding: 2px 4px;\n border-radius: 4px;\n transition: var(--test-transition);\n}\n\n.shortcuts-close:hover {\n color: var(--test-text);\n background: var(--test-border);\n}\n\n.shortcut-list {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.shortcut-item {\n display: flex;\n justify-content: space-between;\n align-items: center;\n color: var(--test-text-secondary);\n}\n\n.shortcut-keys {\n display: flex;\n gap: 4px;\n}\n\n.shortcut-keys kbd {\n background: var(--test-bg);\n border: 1px solid var(--test-border);\n border-radius: 4px;\n padding: 2px 6px;\n font-size: 11px;\n color: var(--test-text);\n}\n\n/* Responsive */\n@media (max-width: 1024px) {\n .keyboard-shortcuts, .shortcuts-toggle { display: none; }\n}\n\n@media (max-width: 768px) {\n .suite-header { padding: 16px; }\n\n .header-content {\n flex-direction: column;\n gap: 16px;\n }\n\n .header-actions {\n width: 100%;\n justify-content: stretch;\n }\n\n .header-actions button { flex: 1; }\n\n .tab-shortcut { display: none; }\n\n .info-grid { grid-template-columns: 1fr; }\n\n .test-item, .run-item { padding: 14px; }\n}\n\n@media (max-width: 480px) {\n .suite-icon {\n width: 40px;\n height: 40px;\n font-size: 18px;\n }\n\n .suite-info h1 { font-size: 16px; }\n\n .tab-badge { display: none; }\n\n .test-sequence { display: none; }\n}\n\n@media (hover: none) and (pointer: coarse) {\n .test-item:active, .run-item:active {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n transform: scale(0.98);\n }\n\n .tab { min-height: 48px; }\n .test-item, .run-item { min-height: 64px; }\n}\n\n@media (prefers-reduced-motion: reduce) {\n *, *::before, *::after {\n animation-duration: 0.01ms !important;\n transition-duration: 0.01ms !important;\n }\n}\n\n@media print {\n .header-actions, .tabs-container, .keyboard-shortcuts {\n display: none !important;\n }\n}\n\n/* ===========================\n Tags UI\n =========================== */\n.run-tags {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n margin-top: 8px;\n}\n\n.tag-chip {\n display: inline-flex;\n align-items: center;\n padding: 3px 10px;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n color: var(--mj-brand-primary-hover);\n}\n\n.tag-mini {\n display: inline-flex;\n align-items: center;\n padding: 2px 6px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 4px;\n font-size: 10px;\n font-weight: 500;\n color: var(--mj-text-muted);\n}\n\n.tag-more {\n font-size: 10px;\n color: var(--mj-text-disabled);\n font-weight: 500;\n}\n\n/* Evaluation metrics row for Runs list */\n.run-eval-metrics {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 8px;\n}\n\n.eval-metric {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 3px 8px;\n border-radius: 6px;\n font-size: 11px;\n font-weight: 500;\n}\n\n.eval-metric.status {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n}\n\n.eval-metric.status.status-completed {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.eval-metric.status.status-failed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.eval-metric.status.status-running {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n}\n\n.eval-metric.status.status-pending {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.eval-metric.human {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n border: 1px solid var(--mj-status-warning);\n color: var(--mj-status-warning);\n}\n\n.eval-metric.human .eval-pending {\n font-size: 9px;\n color: var(--mj-status-warning);\n}\n\n.eval-metric.auto {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n color: var(--mj-brand-primary-hover);\n}\n\n.eval-metric.auto.high {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-success) 30%, transparent);\n color: var(--mj-status-success);\n}\n\n.eval-metric.auto.medium {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 30%, transparent);\n color: var(--mj-status-warning);\n}\n\n.eval-metric.auto.low {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-error) 30%, transparent);\n color: var(--mj-status-error);\n}\n\n.tag-cell {\n display: flex;\n align-items: center;\n gap: 4px;\n flex-wrap: wrap;\n}\n\n.tag-chip-table {\n display: inline-block;\n padding: 3px 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n color: var(--mj-brand-primary-hover);\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n white-space: nowrap;\n max-width: 80px;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* ===========================\n Analytics Tab\n =========================== */\n.analytics-tab {\n animation: fadeIn 0.3s ease-out;\n}\n\n/* Collapsible filters */\n/* Filters disclosure migrated to <mj-accordion-panel>. The bespoke\n .analytics-filters wrapper card chrome, the .filters-header bar (+ hover),\n and the .filters-header > i chevron are now owned by the accordion and were\n removed. The title-slot layout (.filters-title flex row) and font are now\n provided by the accordion title + Size=\"sm\"; the collapsed summary uses the\n shared .mj-accordion-badge (--muted --right). Only the body content\n (.filters-content) styling is kept below. */\n\n.filters-content {\n display: flex;\n flex-direction: column;\n gap: 16px;\n padding: 12px 16px 16px 16px;\n border-top: 1px solid var(--test-border);\n}\n\n.filter-group {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.filter-group label {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.filter-buttons {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.filter-btn {\n padding: 8px 16px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n background: var(--test-surface);\n color: var(--test-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.filter-btn:hover {\n border-color: var(--test-primary);\n color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.filter-btn.active {\n background: var(--test-primary);\n border-color: var(--test-primary);\n color: var(--mj-text-inverse);\n}\n\n.filter-btn.tag-btn {\n padding: 6px 12px;\n font-size: 12px;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n}\n\n.filter-btn.tag-btn i.fa-check {\n font-size: 10px;\n}\n\n.filter-btn.tag-btn.all-tags-btn {\n font-weight: 600;\n}\n\n.filter-btn.tag-btn.all-tags-btn i {\n font-size: 11px;\n}\n\n.filter-hint {\n font-weight: 400;\n font-size: 10px;\n color: var(--test-primary);\n text-transform: none;\n letter-spacing: normal;\n}\n\n.tag-filters {\n max-height: 120px;\n overflow-y: auto;\n}\n\n/* KPI Cards */\n.analytics-kpis {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 16px;\n margin-bottom: 24px;\n}\n\n.kpi-card {\n display: flex;\n align-items: center;\n gap: 16px;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 20px;\n box-shadow: var(--test-shadow-sm);\n transition: var(--test-transition);\n}\n\n.kpi-card:hover {\n transform: translateY(-2px);\n box-shadow: var(--test-shadow-md);\n}\n\n.kpi-icon {\n width: 48px;\n height: 48px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border-radius: var(--test-radius-md);\n color: var(--test-primary);\n font-size: 20px;\n}\n\n.kpi-icon.success {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--test-success);\n}\n\n.kpi-icon.info {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.kpi-icon.warning {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--test-warning);\n}\n\n.kpi-content {\n flex: 1;\n min-width: 0;\n}\n\n.kpi-value {\n font-size: 24px;\n font-weight: 700;\n color: var(--test-text);\n line-height: 1.2;\n}\n\n.kpi-label {\n font-size: 12px;\n color: var(--test-text-secondary);\n margin-top: 2px;\n}\n\n.kpi-trend {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 12px;\n font-weight: 600;\n margin-top: 4px;\n padding: 2px 8px;\n border-radius: 10px;\n background: var(--mj-bg-surface-sunken);\n color: var(--test-text-secondary);\n}\n\n.kpi-trend.trend-up {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--test-success);\n}\n\n.kpi-trend.trend-down {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--test-error);\n}\n\n/* Analytics Table */\n.analytics-table-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.analytics-table-section h3 {\n margin: 0 0 16px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.analytics-table-section h3 i {\n color: var(--test-primary);\n}\n\n.analytics-table-wrapper {\n overflow-x: auto;\n margin: 0 -24px;\n padding: 0 24px;\n}\n\n.analytics-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.analytics-table th {\n text-align: left;\n padding: 12px 16px;\n background: var(--mj-bg-surface-card);\n border-bottom: 2px solid var(--test-border);\n font-weight: 600;\n color: var(--test-text-secondary);\n text-transform: uppercase;\n font-size: 11px;\n letter-spacing: 0.5px;\n white-space: nowrap;\n}\n\n.analytics-table td {\n padding: 14px 16px;\n border-bottom: 1px solid var(--test-border);\n color: var(--test-text);\n}\n\n.analytics-table tbody tr.clickable-row {\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.analytics-table tbody tr.clickable-row:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.status-chip {\n display: inline-flex;\n align-items: center;\n padding: 4px 10px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n}\n\n.status-chip.status-completed { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--test-success); }\n.status-chip.status-passed { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--test-success); }\n.status-chip.status-failed { background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface)); color: var(--test-error); }\n.status-chip.status-error { background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface)); color: var(--test-warning); }\n.status-chip.status-running { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--test-primary); }\n.status-chip.status-pending { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--mj-brand-primary); }\n.status-chip.status-cancelled { background: var(--mj-bg-surface-sunken); color: var(--test-disabled); }\n.status-chip.status-missing { background: var(--mj-bg-surface-sunken); color: var(--test-text-muted); }\n.status-chip.status-timeout { background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface)); color: var(--test-warning); }\n.status-chip.status-skipped { background: var(--mj-bg-surface-sunken); color: var(--test-disabled); }\n\n.pass-rate-cell {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 100px;\n}\n\n.pass-rate-bar {\n height: 6px;\n border-radius: 3px;\n background: var(--test-success);\n transition: width 0.3s ease;\n max-width: 60px;\n}\n\n.pass-rate-bar.medium { background: var(--test-warning); }\n.pass-rate-bar.low { background: var(--test-error); }\n\n/* Analytics Sub-navigation */\n.analytics-subnav {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 8px;\n margin-bottom: 20px;\n box-shadow: var(--test-shadow-sm);\n display: inline-flex;\n}\n\n.subnav-tabs {\n display: flex;\n gap: 4px;\n background: var(--test-bg);\n border-radius: var(--test-radius-md);\n padding: 4px;\n}\n\n.subnav-tab {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n border: none;\n border-radius: var(--test-radius-sm);\n background: transparent;\n color: var(--test-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.subnav-tab:hover {\n color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.subnav-tab.active {\n background: var(--test-surface);\n color: var(--test-primary);\n box-shadow: var(--test-shadow-sm);\n}\n\n.subnav-tab i {\n font-size: 14px;\n}\n\n/* Matrix View */\n.matrix-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 16px;\n box-shadow: var(--test-shadow-sm);\n display: flex;\n flex-direction: column;\n max-height: calc(100vh - 280px);\n min-height: 300px;\n}\n\n.matrix-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-wrap: wrap;\n gap: 12px;\n margin-bottom: 12px;\n padding-bottom: 12px;\n border-bottom: 1px solid var(--test-border);\n flex-shrink: 0;\n}\n\n.matrix-header-right {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.matrix-header h3 {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 0;\n font-size: 15px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.matrix-header h3 i {\n color: var(--test-primary);\n}\n\n.matrix-run-count {\n font-size: 12px;\n color: var(--test-text-muted);\n font-weight: 500;\n}\n\n/* Matrix filter input */\n.matrix-filter-input {\n display: flex;\n align-items: center;\n gap: 8px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--test-border);\n border-radius: 6px;\n padding: 4px 10px;\n min-width: 180px;\n}\n\n.matrix-filter-input i.fa-search {\n color: var(--mj-text-disabled);\n font-size: 12px;\n}\n\n.matrix-filter-input .filter-input {\n border: none;\n background: transparent;\n outline: none;\n font-size: 12px;\n color: var(--test-text);\n width: 100%;\n}\n\n.matrix-filter-input .filter-input::placeholder {\n color: var(--mj-text-disabled);\n}\n\n.clear-filter-btn {\n border: none;\n background: none;\n padding: 2px 4px;\n cursor: pointer;\n color: var(--mj-text-disabled);\n font-size: 10px;\n border-radius: 3px;\n transition: all 0.15s ease;\n}\n\n.clear-filter-btn:hover {\n background: var(--mj-border-default);\n color: var(--mj-text-muted);\n}\n\n/* Scrollable matrix container with fixed height */\n.matrix-scroll-container {\n flex: 1;\n overflow: auto;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n}\n\n.test-matrix {\n display: table;\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.test-matrix thead {\n display: table-header-group;\n}\n\n.test-matrix thead tr {\n display: table-row;\n}\n\n.test-matrix tbody {\n display: table-row-group;\n}\n\n.test-matrix tbody tr {\n display: table-row;\n cursor: pointer;\n transition: background-color 0.15s ease;\n}\n\n.test-matrix tbody tr:hover {\n background-color: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.test-matrix tbody tr.row-selected {\n background-color: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent) !important;\n}\n\n.test-matrix tbody tr.row-selected td {\n border-top: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n border-bottom: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n.test-matrix tbody tr.row-selected .seq-cell,\n.test-matrix tbody tr.row-selected .test-name-cell {\n background-color: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent) !important;\n}\n\n.test-matrix tfoot {\n display: table-footer-group;\n}\n\n.test-matrix th,\n.test-matrix td {\n display: table-cell;\n border: 1px solid var(--test-border);\n padding: 8px 12px;\n text-align: center;\n vertical-align: middle;\n}\n\n.test-matrix th {\n background: var(--test-bg);\n font-weight: 600;\n font-size: 11px;\n color: var(--test-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n position: sticky;\n top: 0;\n z-index: 10;\n border-bottom: 3px solid var(--mj-text-secondary) !important;\n}\n\n/* Sequence column - shared styles */\n.test-matrix .seq-header,\n.test-matrix .seq-cell {\n width: 36px;\n min-width: 36px;\n max-width: 36px;\n text-align: center;\n position: sticky;\n left: 0;\n font-size: 11px;\n color: var(--mj-text-muted);\n border-right: 1px solid var(--test-border);\n padding: 6px 4px !important;\n}\n\n/* Seq header - sticky top AND left, highest z-index */\n.test-matrix .seq-header {\n cursor: pointer;\n font-weight: 600;\n background: var(--test-bg);\n z-index: 12; /* Higher than other headers */\n top: 0;\n}\n\n/* Seq body cells - sticky left only, lower z-index */\n.test-matrix .seq-cell {\n background: var(--test-surface);\n z-index: 2;\n}\n\n.test-matrix .seq-header i {\n font-size: 9px;\n margin-left: 2px;\n opacity: 0.6;\n}\n\n.test-matrix .seq-header:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.test-matrix .test-name-header {\n text-align: left;\n min-width: 150px;\n max-width: 500px;\n width: auto;\n position: sticky;\n left: 36px;\n background: var(--test-bg);\n z-index: 11;\n border-right: 2px solid var(--test-border);\n cursor: pointer;\n}\n\n.test-matrix .test-name-header i {\n font-size: 9px;\n margin-left: 4px;\n opacity: 0.6;\n}\n\n.test-matrix .test-name-header:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.test-matrix .run-header {\n min-width: 120px;\n width: 120px;\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n/* Spacer column absorbs extra width */\n.test-matrix .spacer-header,\n.test-matrix .spacer-cell {\n width: 100%;\n min-width: 20px;\n background: var(--test-bg);\n border: none;\n}\n\n.test-matrix .spacer-cell {\n background: var(--test-surface);\n}\n\n.test-matrix .run-header:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.run-header-content {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n}\n\n.run-date {\n font-size: 12px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.run-pass-rate {\n font-size: 11px;\n font-weight: 700;\n padding: 2px 8px;\n border-radius: 10px;\n}\n\n.run-pass-rate.high {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--test-success);\n}\n\n.run-pass-rate.medium {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--test-warning);\n}\n\n.run-pass-rate.low {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--test-error);\n}\n\n.run-tags {\n display: flex;\n gap: 4px;\n}\n\n.tag-tiny {\n font-size: 9px;\n padding: 2px 6px;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--test-primary);\n border-radius: 8px;\n white-space: nowrap;\n max-width: 60px;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* Matrix column header tags - emphasized */\n.run-tags-header {\n display: flex;\n flex-wrap: wrap;\n gap: 3px;\n justify-content: center;\n margin-bottom: 4px;\n}\n\n.tag-chip-header {\n display: inline-block;\n padding: 3px 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n color: var(--mj-brand-primary-hover);\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n white-space: nowrap;\n max-width: 70px;\n overflow: hidden;\n text-overflow: ellipsis;\n text-transform: none;\n letter-spacing: normal;\n}\n\n.tag-more-header {\n font-size: 9px;\n color: var(--test-text-secondary);\n padding: 2px 4px;\n}\n\n.test-matrix .test-name-cell {\n text-align: left;\n min-width: 150px;\n max-width: 500px;\n width: auto;\n position: sticky;\n left: 36px;\n background: var(--test-surface);\n z-index: 2;\n border-right: 2px solid var(--test-border);\n padding: 6px 10px !important;\n}\n\n.test-name {\n display: block;\n white-space: nowrap;\n font-weight: 500;\n color: var(--test-text);\n font-size: 12px;\n}\n\n.result-cell {\n position: relative;\n min-width: 120px;\n width: 120px;\n transition: var(--test-transition);\n}\n\n.result-cell.clickable {\n cursor: pointer;\n}\n\n.result-cell.clickable:hover {\n transform: scale(1.1);\n box-shadow: var(--mj-shadow-md);\n z-index: 5;\n}\n\n.result-cell i {\n font-size: 14px;\n}\n\n/* Completed cells have neutral white background - pills tell the story */\n.result-cell.cell-passed,\n.result-cell.cell-failed,\n.result-cell.cell-error,\n.result-cell.cell-timeout,\n.result-cell.cell-running,\n.result-cell.cell-pending {\n background: var(--mj-bg-surface);\n color: var(--test-text);\n}\n\n/* Skipped/not-run cells get hatched background */\n.result-cell.cell-skipped {\n background: repeating-linear-gradient(\n 45deg,\n var(--mj-bg-surface-card),\n var(--mj-bg-surface-card) 4px,\n var(--mj-border-default) 4px,\n var(--mj-border-default) 8px\n );\n color: var(--test-disabled);\n}\n\n.result-cell.cell-none {\n background: var(--mj-bg-surface-card);\n color: var(--test-text-muted);\n}\n\n.cell-score {\n display: block;\n font-size: 10px;\n font-weight: 600;\n margin-top: 2px;\n}\n\n/* Matrix cell evaluation stack - shows multiple eval types horizontally */\n.cell-eval-stack {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n flex-wrap: nowrap;\n}\n\n.result-cell.multi-eval {\n min-width: 120px;\n width: auto;\n}\n\n/* Add timeout status icon */\n.cell-status.status-timeout {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-status {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n border-radius: 50%;\n font-size: 11px;\n}\n\n.cell-status.status-passed {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.cell-status.status-failed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.cell-status.status-error {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-status.status-skipped {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n}\n\n.cell-status.status-running {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n}\n\n.cell-status.status-pending {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.cell-human {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n border-radius: 50%;\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n font-size: 10px;\n}\n\n.cell-auto {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 2px 6px;\n border-radius: 4px;\n font-size: 10px;\n font-weight: 600;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n}\n\n.cell-auto.high {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.cell-auto.medium {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-auto.low {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.cell-none-indicator {\n color: var(--test-text-muted);\n opacity: 0.5;\n}\n\n.matrix-info {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n color: var(--test-text-muted);\n padding: 12px;\n background: var(--test-bg);\n border-radius: var(--test-radius-sm);\n}\n\n.matrix-info i {\n color: var(--test-primary);\n}\n\n/* ===========================\n Chart View\n =========================== */\n.chart-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.chart-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-wrap: wrap;\n gap: 16px;\n margin-bottom: 20px;\n padding-bottom: 16px;\n border-bottom: 1px solid var(--test-border);\n}\n\n.chart-header h3 {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.chart-header h3 i {\n color: var(--test-primary);\n}\n\n.chart-legend {\n display: flex;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.chart-legend .legend-item {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 500;\n padding: 4px 10px;\n border-radius: 12px;\n}\n\n.chart-legend .legend-item.chart-passed {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--test-success);\n}\n\n.chart-legend .legend-item.chart-failed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--test-error);\n}\n\n.chart-legend .legend-item.chart-error {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--test-warning);\n}\n\n.chart-legend .legend-item.chart-skipped {\n background: var(--mj-bg-surface-sunken);\n color: var(--test-disabled);\n}\n\n.chart-container {\n min-height: 500px;\n position: relative;\n overflow: hidden;\n background: var(--mj-bg-surface-card);\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n}\n\n.d3-chart {\n width: 100%;\n height: 500px;\n}\n\n.d3-chart svg {\n width: 100%;\n height: 100%;\n}\n\n/* D3 Chart Node Styles */\n.d3-chart .node {\n cursor: pointer;\n transition: transform 0.2s ease;\n}\n\n.d3-chart .node:hover {\n transform: scale(1.05);\n}\n\n.d3-chart .node-label {\n font-size: 11px;\n font-weight: 500;\n fill: var(--test-text);\n pointer-events: none;\n}\n\n.d3-chart .link {\n fill: none;\n stroke-opacity: 0.4;\n transition: stroke-opacity 0.2s ease;\n}\n\n.d3-chart .link:hover {\n stroke-opacity: 0.8;\n}\n\n.d3-chart .tooltip {\n position: absolute;\n padding: 10px 14px;\n background: var(--mj-bg-overlay);\n color: var(--mj-text-inverse);\n border-radius: 8px;\n font-size: 12px;\n pointer-events: none;\n z-index: 100;\n box-shadow: var(--mj-shadow-lg);\n max-width: 250px;\n}\n\n.d3-chart .tooltip-title {\n font-weight: 600;\n margin-bottom: 4px;\n}\n\n.d3-chart .tooltip-value {\n opacity: 0.8;\n}\n\n.chart-info {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n color: var(--test-text-muted);\n padding: 12px;\n background: var(--test-bg);\n border-radius: var(--test-radius-sm);\n margin-top: 16px;\n}\n\n.chart-info i {\n color: var(--test-primary);\n}\n\n/* ===========================\n Compare Tab\n =========================== */\n.compare-tab {\n animation: fadeIn 0.3s ease-out;\n}\n\n.compare-selection {\n display: grid;\n grid-template-columns: 1fr auto 1fr;\n gap: 24px;\n align-items: flex-start;\n margin-bottom: 24px;\n}\n\n.compare-run-selector {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 20px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.compare-run-selector h4 {\n margin: 0 0 16px 0;\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.run-selector-list {\n max-height: 200px;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-bottom: 12px;\n}\n\n.run-selector-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 12px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.run-selector-item:hover {\n border-color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.run-selector-item.selected {\n border-color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n}\n\n.run-selector-item.disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.selector-status {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n}\n\n.selector-content {\n flex: 1;\n min-width: 0;\n}\n\n.selector-date {\n font-size: 12px;\n font-weight: 500;\n color: var(--test-text);\n}\n\n.selector-rate {\n font-size: 11px;\n color: var(--test-text-secondary);\n}\n\n.selector-tags {\n display: flex;\n gap: 4px;\n flex-wrap: wrap;\n}\n\n.selected-run-preview {\n padding: 12px;\n background: var(--mj-bg-surface-card);\n border-radius: var(--test-radius-sm);\n border: 1px solid var(--test-border);\n}\n\n.preview-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 8px;\n}\n\n.preview-label {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n color: var(--test-text-muted);\n}\n\n.clear-btn {\n padding: 4px 8px;\n border: none;\n background: transparent;\n color: var(--test-error);\n font-size: 11px;\n font-weight: 500;\n cursor: pointer;\n}\n\n.clear-btn:hover { text-decoration: underline; }\n\n.preview-details {\n display: flex;\n justify-content: space-between;\n font-size: 12px;\n color: var(--test-text);\n}\n\n.preview-rate {\n font-weight: 600;\n color: var(--test-success);\n}\n\n.compare-vs {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n background: var(--test-bg);\n border-radius: 50%;\n color: var(--test-text-muted);\n font-size: 16px;\n align-self: center;\n margin-top: 60px;\n}\n\n/* Compare Results */\n.compare-results {\n animation: fadeIn 0.3s ease-out;\n}\n\n.compare-summary {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n gap: 16px;\n margin-bottom: 24px;\n}\n\n.compare-summary-card {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 20px;\n box-shadow: var(--test-shadow-sm);\n text-align: center;\n}\n\n.compare-summary-card .summary-label {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n color: var(--test-text-muted);\n margin-bottom: 8px;\n}\n\n.compare-summary-card .summary-value {\n font-size: 24px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n}\n\n.compare-summary-card .summary-value.positive { color: var(--test-success); }\n.compare-summary-card .summary-value.negative { color: var(--test-error); }\n\n.compare-summary-card.improved {\n border-left: 4px solid var(--test-success);\n}\n\n.compare-summary-card.improved .summary-value { color: var(--test-success); }\n\n.compare-summary-card.regressed {\n border-left: 4px solid var(--test-error);\n}\n\n.compare-summary-card.regressed .summary-value { color: var(--test-error); }\n\n/* Compare Table */\n.compare-table-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.compare-table-section h3 {\n margin: 0 0 16px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.compare-table-section h3 i {\n color: var(--test-primary);\n}\n\n.compare-table-wrapper {\n overflow-x: auto;\n}\n\n.compare-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.compare-table th {\n text-align: left;\n padding: 12px 16px;\n background: var(--mj-bg-surface-card);\n border-bottom: 2px solid var(--test-border);\n font-weight: 600;\n color: var(--test-text-secondary);\n text-transform: uppercase;\n font-size: 11px;\n letter-spacing: 0.5px;\n white-space: nowrap;\n}\n\n.compare-table td {\n padding: 14px 16px;\n border-bottom: 1px solid var(--test-border);\n color: var(--test-text);\n}\n\n.compare-table tbody tr.improved {\n background: color-mix(in srgb, var(--mj-status-success) 5%, transparent);\n}\n\n.compare-table tbody tr.regressed {\n background: color-mix(in srgb, var(--mj-status-error) 5%, transparent);\n}\n\n.test-name-cell {\n font-weight: 500;\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.positive { color: var(--test-success); }\n.negative { color: var(--test-error); }\n.muted { color: var(--test-text-muted); }\n\n.change-indicator {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.change-indicator.improved {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--test-success);\n}\n\n.change-indicator.regressed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--test-error);\n}\n\n.change-indicator.unchanged {\n background: var(--mj-bg-surface-sunken);\n color: var(--test-text-muted);\n}\n\n/* ===========================\n Responsive Analytics/Compare\n =========================== */\n@media (max-width: 1024px) {\n .compare-selection {\n grid-template-columns: 1fr;\n gap: 16px;\n }\n\n .compare-vs {\n margin: 0;\n align-self: center;\n justify-self: center;\n }\n\n .analytics-kpis {\n grid-template-columns: repeat(2, 1fr);\n }\n}\n\n@media (max-width: 768px) {\n .filter-buttons {\n flex-direction: column;\n }\n\n .filter-btn {\n width: 100%;\n text-align: center;\n }\n\n .analytics-kpis {\n grid-template-columns: 1fr;\n }\n\n .kpi-card {\n padding: 16px;\n }\n\n .kpi-value {\n font-size: 20px;\n }\n\n .compare-summary {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .analytics-table-wrapper,\n .compare-table-wrapper {\n margin: 0 -20px;\n padding: 0 20px;\n }\n\n .run-selector-list {\n max-height: 150px;\n }\n}\n\n@media (max-width: 480px) {\n .compare-summary {\n grid-template-columns: 1fr;\n }\n\n .compare-summary-card .summary-value {\n font-size: 20px;\n }\n\n .analytics-table th,\n .analytics-table td,\n .compare-table th,\n .compare-table td {\n padding: 10px 12px;\n font-size: 12px;\n }\n}\n\n/* ===========================\n Matrix Evaluation Indicators\n =========================== */\n\n/* Human Feedback Indicators */\n.cell-human {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 3px;\n min-width: 22px;\n height: 22px;\n border-radius: 50%;\n font-size: 10px;\n}\n\n.cell-human.no-feedback {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-disabled);\n}\n\n.cell-human.no-feedback i {\n font-size: 11px;\n}\n\n.cell-human.has-feedback {\n padding: 0 6px;\n border-radius: 12px;\n min-width: 36px;\n}\n\n.cell-human.has-feedback i {\n font-size: 9px;\n}\n\n.cell-human.has-feedback .rating-value {\n font-weight: 700;\n font-size: 11px;\n}\n\n/* Human rating color coding: red \u22644, yellow 5-6, light-green 7-8, green 9-10 */\n.cell-human.rating-low {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.cell-human.rating-medium {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-human.rating-good {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.cell-human.rating-excellent {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n/* Auto Score Indicators */\n.cell-auto {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 3px;\n min-width: 22px;\n height: 22px;\n border-radius: 50%;\n font-size: 10px;\n}\n\n.cell-auto.no-score {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-disabled);\n}\n\n.cell-auto.no-score i {\n font-size: 11px;\n}\n\n.cell-auto.has-score {\n padding: 0 6px;\n border-radius: 12px;\n min-width: 36px;\n}\n\n.cell-auto.has-score i {\n font-size: 9px;\n}\n\n.cell-auto.has-score .score-value {\n font-weight: 700;\n font-size: 10px;\n}\n\n/* Auto score color coding (0-100%): red <50, yellow 50-69, light-green 70-84, green 85+ */\n.cell-auto.score-low {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.cell-auto.score-medium {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-auto.score-good {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.cell-auto.score-excellent {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n/* Status indicators in matrix cells */\n.cell-status {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n border-radius: 50%;\n font-size: 11px;\n}\n\n.cell-status.status-passed {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.cell-status.status-failed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.cell-status.status-error {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-status.status-timeout {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-status.status-skipped,\n.cell-status.status-pending {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n}\n\n.cell-status.status-running {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n/* Not-run / Skipped cells with hatch pattern */\n.result-cell.cell-not-run {\n background: repeating-linear-gradient(\n 45deg,\n var(--mj-bg-surface-card),\n var(--mj-bg-surface-card) 4px,\n var(--mj-border-default) 4px,\n var(--mj-border-default) 8px\n );\n color: var(--mj-text-disabled);\n}\n\n.result-cell.cell-not-run .cell-eval-stack {\n opacity: 0.6;\n}\n\n.cell-not-run-indicator {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n color: var(--mj-text-disabled);\n font-size: 11px;\n}\n\n/* ===========================\n Matrix Totals Footer Row\n =========================== */\n.test-matrix tfoot {\n position: sticky;\n bottom: 0;\n z-index: 2;\n}\n\n.totals-row {\n background: var(--mj-bg-surface-sunken);\n border-top: 2px solid var(--test-border);\n}\n\n.totals-row td {\n padding: 10px 12px;\n font-weight: 600;\n}\n\n.totals-row .totals-label {\n background: var(--mj-bg-surface-sunken);\n font-size: 12px;\n color: var(--test-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.totals-row .totals-cell {\n background: var(--mj-bg-surface-sunken);\n}\n\n.totals-stack {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n}\n\n.totals-status,\n.totals-human,\n.totals-auto {\n display: flex;\n align-items: center;\n gap: 4px;\n font-size: 11px;\n padding: 2px 8px;\n border-radius: 10px;\n white-space: nowrap;\n}\n\n.totals-status {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.totals-status .pass-count {\n font-weight: 700;\n}\n\n.totals-human {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.totals-human .avg-label {\n font-weight: 700;\n}\n\n.totals-human .count-label {\n font-size: 10px;\n opacity: 0.8;\n}\n\n.totals-auto {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n}\n\n.totals-auto .avg-label {\n font-weight: 700;\n}\n\n.totals-auto .count-label {\n font-size: 10px;\n opacity: 0.8;\n}\n\n/* ===========================\n Editable Overview Form\n =========================== */\n\n.edit-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.edit-section-header {\n margin: 0 0 18px 0;\n}\n\n.edit-section-header h3 {\n margin: 0 0 4px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.edit-section-header h3 i {\n color: var(--test-primary);\n}\n\n.edit-section-sub {\n margin: 0;\n font-size: 12px;\n color: var(--test-text-muted);\n}\n\n.edit-grid {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 18px;\n}\n\n@media (max-width: 720px) {\n .edit-grid {\n grid-template-columns: 1fr;\n }\n}\n\n.edit-field {\n display: flex;\n flex-direction: column;\n gap: 6px;\n min-width: 0;\n}\n\n.edit-field--full {\n grid-column: 1 / -1;\n}\n\n.edit-field label {\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.edit-field .required {\n color: var(--mj-status-error);\n margin-left: 2px;\n}\n\n.config-textarea {\n resize: vertical;\n min-height: 72px;\n font-family: inherit;\n line-height: 1.5;\n}\n\n.select-wrapper {\n position: relative;\n}\n\n.select-wrapper select.config-input {\n padding-right: 36px;\n appearance: none;\n background-color: var(--test-surface);\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%2364748b' d='M1.41 0L6 4.59 10.59 0 12 1.41l-6 6-6-6z'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: right 14px center;\n background-size: 10px 7px;\n}\n\n/* Tag editor (chips + inline input) */\n.tag-editor {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n padding: 8px 10px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n background: var(--test-surface);\n transition: var(--test-transition);\n cursor: text;\n min-height: 42px;\n align-items: center;\n}\n\n.tag-editor:focus-within {\n border-color: var(--test-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.tag-chip-editable {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 3px 4px 3px 10px;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n border-radius: 999px;\n font-size: 12px;\n font-weight: 600;\n line-height: 1;\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, transparent);\n}\n\n.tag-chip-editable .tag-remove {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 18px;\n height: 18px;\n border-radius: 50%;\n border: none;\n background: transparent;\n color: var(--mj-brand-primary);\n cursor: pointer;\n font-size: 10px;\n transition: background 0.15s;\n}\n\n.tag-chip-editable .tag-remove:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 25%, transparent);\n color: var(--mj-brand-primary-hover);\n}\n\n.tag-input-inline {\n flex: 1;\n min-width: 140px;\n border: none;\n background: transparent;\n outline: none;\n font-size: 13px;\n color: var(--test-text);\n padding: 4px 2px;\n}\n\n.tag-input-inline::placeholder {\n color: var(--test-text-muted);\n}\n\n/* Read-only metadata section */\n.meta-section {\n background: var(--mj-bg-surface-sunken);\n border-radius: var(--test-radius-md);\n padding: 14px 18px;\n border: 1px solid var(--test-border);\n}\n\n.meta-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n gap: 14px;\n}\n\n.meta-item {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n.meta-label {\n font-size: 10px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.meta-value {\n font-size: 12px;\n color: var(--test-text-secondary);\n font-weight: 500;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.meta-mono {\n font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, monospace;\n font-size: 11px;\n}\n\n/* Dirty indicator next to the title */\n.dirty-indicator {\n display: inline-block;\n margin-left: 8px;\n font-size: 14px;\n color: var(--mj-status-warning);\n line-height: 1;\n animation: pulseDot 1.8s ease-in-out infinite;\n vertical-align: middle;\n}\n\n@keyframes pulseDot {\n 0%, 100% { opacity: 1; transform: scale(1); }\n 50% { opacity: 0.5; transform: scale(0.85); }\n}\n\n.unsaved-pill {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning-text, var(--mj-status-warning));\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 30%, transparent);\n border-radius: 999px;\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.4px;\n}\n\n.unsaved-pill i {\n font-size: 6px;\n animation: pulseDot 1.8s ease-in-out infinite;\n}\n\n/* Pad the bottom of the tab content when the save bar is visible\n so the bar doesn't cover the last form field. */\n.tab-content.has-savebar {\n padding-bottom: 84px;\n}\n\n/* ===========================\n Sticky Save Bar\n =========================== */\n\n.save-bar {\n position: absolute;\n left: 16px;\n right: 96px; /* leaves room for the bottom-right chat launcher */\n bottom: 16px;\n z-index: 50;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n padding: 12px 16px 12px 20px;\n background: var(--mj-bg-surface-elevated, var(--test-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 25%, var(--test-border));\n border-radius: 14px;\n box-shadow: 0 12px 32px color-mix(in srgb, var(--mj-status-warning) 10%, rgba(0, 0, 0, 0.18));\n backdrop-filter: blur(8px);\n /* Hidden / off-screen state by default. The .save-bar--visible class\n animates it up into view. Using `transition` (not `animation`)\n guarantees the change runs every time isDirty toggles. */\n opacity: 0;\n transform: translateY(calc(100% + 32px));\n pointer-events: none;\n transition:\n transform 420ms cubic-bezier(0.16, 1, 0.3, 1),\n opacity 260ms cubic-bezier(0.16, 1, 0.3, 1);\n will-change: transform, opacity;\n}\n\n.save-bar--visible {\n opacity: 1;\n transform: translateY(0);\n pointer-events: auto;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .save-bar {\n transition: opacity 180ms ease-out;\n transform: none;\n }\n .save-bar--visible {\n transform: none;\n }\n}\n\n.save-bar-message {\n display: flex;\n align-items: center;\n gap: 12px;\n min-width: 0;\n}\n\n.save-bar-dot {\n color: var(--mj-status-warning);\n font-size: 12px;\n line-height: 1;\n animation: pulseDot 1.8s ease-in-out infinite;\n}\n\n.save-bar-text {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n.save-bar-text strong {\n font-size: 14px;\n color: var(--test-text);\n font-weight: 700;\n}\n\n.save-bar-fields {\n font-size: 12px;\n color: var(--test-text-muted);\n}\n\n.save-bar-actions {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-shrink: 0;\n}\n\n.save-bar-btn {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 9px 16px;\n font-size: 13px;\n font-weight: 600;\n border-radius: 8px;\n border: 1px solid transparent;\n cursor: pointer;\n transition: var(--test-transition);\n font-family: inherit;\n}\n\n.save-bar-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.save-bar-btn--primary {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse, white);\n border-color: var(--mj-brand-primary);\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-brand-primary) 35%, transparent);\n}\n\n.save-bar-btn--primary:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover, var(--mj-brand-primary));\n transform: translateY(-1px);\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 45%, transparent);\n}\n\n.save-bar-btn--primary:active:not(:disabled) {\n transform: translateY(0);\n}\n\n.save-bar-btn--ghost {\n background: transparent;\n color: var(--test-text-secondary);\n border-color: var(--test-border);\n}\n\n.save-bar-btn--ghost:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover, var(--mj-bg-surface-card));\n color: var(--test-text);\n border-color: var(--test-text-muted);\n}\n\n.save-bar-kbd {\n display: inline-flex;\n gap: 3px;\n margin-left: 6px;\n opacity: 0.85;\n}\n\n.save-bar-kbd kbd {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 18px;\n height: 18px;\n padding: 0 4px;\n font-size: 10px;\n font-weight: 600;\n font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, monospace;\n background: color-mix(in srgb, white 18%, transparent);\n border: 1px solid color-mix(in srgb, white 35%, transparent);\n border-radius: 4px;\n color: inherit;\n}\n\n@media (max-width: 640px) {\n .save-bar {\n left: 8px;\n right: 8px;\n bottom: 88px; /* push above the chat launcher on small screens */\n flex-direction: column;\n align-items: stretch;\n padding: 12px;\n }\n .save-bar-actions {\n justify-content: space-between;\n }\n .save-bar-kbd {\n display: none;\n }\n}\n\n/* ===========================\n Tests Tab \u2014 Action Bar + Drag/Remove\n =========================== */\n\n.tests-actionbar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding: 12px 16px;\n margin-bottom: 16px;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n}\n\n.tests-actionbar-text {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n min-width: 0;\n}\n\n.tests-actionbar-text strong {\n font-size: 14px;\n color: var(--test-text);\n font-weight: 700;\n}\n\n.tests-actionbar-count {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 22px;\n height: 22px;\n padding: 0 8px;\n border-radius: 999px;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n font-size: 12px;\n font-weight: 700;\n}\n\n.tests-actionbar-hint {\n font-size: 12px;\n color: var(--test-text-muted);\n}\n\n.tests-actionbar-actions {\n display: flex;\n gap: 8px;\n flex-shrink: 0;\n}\n\n/* Override the default test-item hover translate so drag transforms don't fight it. */\n.tests-list[cdk-drop-list] .test-item:hover,\n.tests-list .test-item.cdk-drag:hover {\n transform: none;\n}\n\n/* The whole row is draggable. .test-content keeps the click-to-open behavior. */\n.test-item.cdk-drag {\n position: relative;\n}\n\n.test-item .test-content {\n cursor: pointer;\n}\n\n/* Drag handle */\n.test-drag-handle {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 28px;\n border-radius: 4px;\n color: var(--test-text-muted);\n cursor: grab;\n flex-shrink: 0;\n transition: background 0.15s, color 0.15s;\n user-select: none;\n}\n\n.test-drag-handle:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n color: var(--test-primary);\n}\n\n.test-drag-handle:active,\n.cdk-drag-preview .test-drag-handle {\n cursor: grabbing;\n}\n\n/* Remove (X) button \u2014 hover-revealed */\n.test-remove-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border-radius: 50%;\n border: none;\n background: transparent;\n color: var(--test-text-muted);\n cursor: pointer;\n flex-shrink: 0;\n opacity: 0;\n transition: opacity 0.15s, background 0.15s, color 0.15s;\n}\n\n.test-item:hover .test-remove-btn,\n.test-remove-btn:focus-visible {\n opacity: 1;\n}\n\n.test-remove-btn:hover {\n background: color-mix(in srgb, var(--mj-status-error) 12%, transparent);\n color: var(--mj-status-error);\n}\n\n.test-chevron {\n cursor: pointer;\n}\n\n/* Inline remove-confirm */\n.test-remove-confirm {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 4px 8px 4px 12px;\n border-radius: 999px;\n background: color-mix(in srgb, var(--mj-status-error) 8%, var(--test-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-error) 30%, transparent);\n flex-shrink: 0;\n}\n\n.test-remove-confirm-text {\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-status-error-text, var(--mj-status-error));\n}\n\n.test-remove-confirm-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 4px 10px;\n border-radius: 6px;\n border: 1px solid transparent;\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n font-family: inherit;\n transition: var(--test-transition);\n}\n\n.test-remove-confirm-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.test-remove-confirm-btn--danger {\n background: var(--mj-status-error);\n color: var(--mj-text-inverse, white);\n}\n\n.test-remove-confirm-btn--danger:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-status-error) 88%, black);\n}\n\n.test-remove-confirm-btn--ghost {\n background: transparent;\n color: var(--test-text-secondary);\n border-color: var(--test-border);\n}\n\n.test-remove-confirm-btn--ghost:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover, var(--mj-bg-surface-card));\n color: var(--test-text);\n}\n\n/* CDK drag-drop visuals */\n.cdk-drag-preview {\n box-shadow: 0 12px 32px rgba(0, 0, 0, 0.25);\n border-radius: var(--test-radius-md);\n background: var(--test-surface);\n opacity: 0.95;\n}\n\n.cdk-drag-placeholder {\n opacity: 0;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n border: 2px dashed var(--test-primary);\n border-radius: var(--test-radius-md);\n}\n\n.cdk-drag-placeholder * {\n visibility: hidden;\n}\n\n.cdk-drag-animating {\n transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);\n}\n\n.tests-list.cdk-drop-list-dragging .test-item:not(.cdk-drag-placeholder) {\n transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);\n}\n\n/* ===========================\n Add Tests Picker Dialog\n =========================== */\n\n.picker-backdrop {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.45);\n z-index: 200;\n animation: pickerFadeIn 180ms ease-out;\n backdrop-filter: blur(2px);\n}\n\n@keyframes pickerFadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n.picker-dialog {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: min(720px, calc(100vw - 32px));\n max-height: min(80vh, 720px);\n z-index: 201;\n display: flex;\n flex-direction: column;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n box-shadow: 0 24px 64px rgba(0, 0, 0, 0.28);\n animation: pickerSlideUp 220ms cubic-bezier(0.16, 1, 0.3, 1);\n overflow: hidden;\n}\n\n@keyframes pickerSlideUp {\n from {\n opacity: 0;\n transform: translate(-50%, calc(-50% + 16px));\n }\n to {\n opacity: 1;\n transform: translate(-50%, -50%);\n }\n}\n\n.picker-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 18px 20px;\n border-bottom: 1px solid var(--test-border);\n}\n\n.picker-title {\n margin: 0;\n font-size: 16px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.picker-title i {\n color: var(--test-primary);\n}\n\n.picker-close {\n width: 32px;\n height: 32px;\n border-radius: 8px;\n border: none;\n background: transparent;\n color: var(--test-text-muted);\n cursor: pointer;\n font-size: 14px;\n transition: background 0.15s, color 0.15s;\n}\n\n.picker-close:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover, var(--mj-bg-surface-card));\n color: var(--test-text);\n}\n\n.picker-close:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.picker-search {\n position: relative;\n padding: 14px 20px 0 20px;\n}\n\n.picker-search-icon {\n position: absolute;\n top: 50%;\n left: 32px;\n transform: translateY(-30%);\n color: var(--test-text-muted);\n font-size: 13px;\n pointer-events: none;\n}\n\n.picker-search-input {\n width: 100%;\n padding: 10px 36px 10px 36px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n background: var(--test-surface);\n font-size: 14px;\n color: var(--test-text);\n font-family: inherit;\n transition: var(--test-transition);\n}\n\n.picker-search-input:focus {\n outline: none;\n border-color: var(--test-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.picker-search-clear {\n position: absolute;\n top: 50%;\n right: 32px;\n transform: translateY(-30%);\n width: 22px;\n height: 22px;\n border-radius: 50%;\n border: none;\n background: transparent;\n color: var(--test-text-muted);\n cursor: pointer;\n font-size: 11px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n\n.picker-search-clear:hover {\n background: var(--mj-bg-surface-hover, var(--mj-bg-surface-card));\n color: var(--test-text);\n}\n\n.picker-toolbar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 20px;\n border-bottom: 1px solid var(--test-border);\n}\n\n.picker-toolbar-status {\n font-size: 12px;\n color: var(--test-text-secondary);\n}\n\n.picker-toolbar-status strong {\n color: var(--mj-brand-primary-hover);\n font-weight: 700;\n}\n\n.picker-toolbar-actions {\n display: flex;\n gap: 14px;\n}\n\n.picker-link-btn {\n border: none;\n background: transparent;\n color: var(--test-primary);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n padding: 0;\n font-family: inherit;\n}\n\n.picker-link-btn:hover:not(:disabled) {\n text-decoration: underline;\n}\n\n.picker-link-btn:disabled {\n color: var(--test-text-muted);\n cursor: not-allowed;\n}\n\n.picker-body {\n flex: 1;\n overflow-y: auto;\n padding: 8px 12px;\n min-height: 200px;\n}\n\n.picker-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 40px;\n}\n\n.picker-list {\n list-style: none;\n padding: 0;\n margin: 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.picker-row {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 12px;\n border-radius: 8px;\n cursor: pointer;\n transition: background 0.12s, border-color 0.12s;\n border: 1px solid transparent;\n}\n\n.picker-row:hover {\n background: var(--mj-bg-surface-hover, var(--mj-bg-surface-card));\n}\n\n.picker-row:focus-visible {\n outline: none;\n border-color: var(--test-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.picker-row--selected {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--test-surface));\n border-color: color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n.picker-row--selected:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--test-surface));\n}\n\n.picker-check {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n border-radius: 5px;\n border: 1.5px solid var(--test-border);\n background: var(--test-surface);\n color: var(--mj-text-inverse, white);\n font-size: 11px;\n flex-shrink: 0;\n transition: background 0.12s, border-color 0.12s;\n}\n\n.picker-row--selected .picker-check {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n}\n\n.picker-row-main {\n flex: 1;\n min-width: 0;\n}\n\n.picker-row-name {\n font-size: 13px;\n font-weight: 600;\n color: var(--test-text);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.picker-row-desc {\n font-size: 12px;\n color: var(--test-text-muted);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n margin-top: 2px;\n}\n\n.picker-row-meta {\n display: flex;\n align-items: center;\n gap: 6px;\n flex-shrink: 0;\n}\n\n.picker-row-pill {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n border-radius: 999px;\n font-size: 10px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n background: var(--mj-bg-surface-sunken, var(--test-bg));\n color: var(--test-text-secondary);\n border: 1px solid var(--test-border);\n}\n\n.picker-row-pill--status[data-status=\"active\"] {\n background: color-mix(in srgb, var(--mj-status-success) 12%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n border-color: color-mix(in srgb, var(--mj-status-success) 30%, transparent);\n}\n\n.picker-row-pill--status[data-status=\"disabled\"] {\n background: var(--mj-bg-surface-sunken, var(--test-bg));\n color: var(--test-text-muted);\n}\n\n.picker-row-pill--status[data-status=\"pending\"] {\n background: color-mix(in srgb, var(--mj-status-warning) 12%, var(--mj-bg-surface));\n color: var(--mj-status-warning-text, var(--mj-status-warning));\n border-color: color-mix(in srgb, var(--mj-status-warning) 30%, transparent);\n}\n\n.picker-footer {\n display: flex;\n gap: 8px;\n padding: 14px 20px;\n border-top: 1px solid var(--test-border);\n background: var(--mj-bg-surface-sunken, var(--test-bg));\n}\n\n.picker-btn {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 9px 16px;\n font-size: 13px;\n font-weight: 600;\n border-radius: 8px;\n border: 1px solid transparent;\n cursor: pointer;\n font-family: inherit;\n transition: var(--test-transition);\n}\n\n.picker-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.picker-btn--primary {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse, white);\n border-color: var(--mj-brand-primary);\n}\n\n.picker-btn--primary:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover, var(--mj-brand-primary));\n}\n\n.picker-btn--ghost {\n background: transparent;\n color: var(--test-text-secondary);\n border-color: var(--test-border);\n}\n\n.picker-btn--ghost:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover, var(--mj-bg-surface-card));\n color: var(--test-text);\n}\n\n@media (max-width: 640px) {\n .picker-dialog {\n width: calc(100vw - 16px);\n max-height: calc(100vh - 32px);\n }\n .tests-actionbar {\n flex-direction: column;\n align-items: stretch;\n }\n .tests-actionbar-actions {\n justify-content: flex-end;\n }\n .test-remove-btn {\n opacity: 1; /* always visible on touch */\n }\n}\n\n"] }]
|
|
4990
5030
|
}], null, { ChartContainer: [{
|
|
4991
5031
|
type: ViewChild,
|
|
4992
5032
|
args: ['chartContainer']
|
|
@@ -4997,5 +5037,5 @@ export { MJTestSuiteFormComponentExtended };
|
|
|
4997
5037
|
type: HostListener,
|
|
4998
5038
|
args: ['window:beforeunload', ['$event']]
|
|
4999
5039
|
}] }); })();
|
|
5000
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJTestSuiteFormComponentExtended, { className: "MJTestSuiteFormComponentExtended", filePath: "src/lib/custom/Tests/test-suite-form.component.ts", lineNumber:
|
|
5040
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJTestSuiteFormComponentExtended, { className: "MJTestSuiteFormComponentExtended", filePath: "src/lib/custom/Tests/test-suite-form.component.ts", lineNumber: 34 }); })();
|
|
5001
5041
|
//# sourceMappingURL=test-suite-form.component.js.map
|