@memberjunction/ng-dashboards 5.0.0 → 5.2.0
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/AI/components/agents/agent-configuration.component.d.ts +12 -12
- package/dist/AI/components/agents/agent-configuration.component.d.ts.map +1 -1
- package/dist/AI/components/agents/agent-configuration.component.js +1 -1
- package/dist/AI/components/agents/agent-configuration.component.js.map +1 -1
- package/dist/AI/components/agents/agent-editor.component.d.ts +4 -4
- package/dist/AI/components/agents/agent-editor.component.d.ts.map +1 -1
- package/dist/AI/components/agents/agent-editor.component.js +1 -1
- package/dist/AI/components/agents/agent-editor.component.js.map +1 -1
- package/dist/AI/components/agents/agent-filter-panel.component.d.ts +3 -3
- package/dist/AI/components/agents/agent-filter-panel.component.d.ts.map +1 -1
- package/dist/AI/components/agents/agent-filter-panel.component.js +1 -1
- package/dist/AI/components/agents/agent-filter-panel.component.js.map +1 -1
- package/dist/AI/components/charts/performance-heatmap.component.js +1 -1
- package/dist/AI/components/charts/time-series-chart.component.js +1 -1
- package/dist/AI/components/execution-monitoring.component.js +1 -1
- package/dist/AI/components/execution-monitoring.component.js.map +1 -1
- package/dist/AI/components/models/model-management.component.d.ts +5 -5
- package/dist/AI/components/models/model-management.component.d.ts.map +1 -1
- package/dist/AI/components/models/model-management.component.js +2 -2
- package/dist/AI/components/models/model-management.component.js.map +1 -1
- package/dist/AI/components/prompts/model-prompt-priority-matrix.component.d.ts +7 -7
- package/dist/AI/components/prompts/model-prompt-priority-matrix.component.d.ts.map +1 -1
- package/dist/AI/components/prompts/model-prompt-priority-matrix.component.js +1 -1
- package/dist/AI/components/prompts/model-prompt-priority-matrix.component.js.map +1 -1
- package/dist/AI/components/prompts/prompt-filter-panel.component.js +1 -1
- package/dist/AI/components/prompts/prompt-management.component.d.ts +4 -4
- package/dist/AI/components/prompts/prompt-management.component.d.ts.map +1 -1
- package/dist/AI/components/prompts/prompt-management.component.js +2 -2
- package/dist/AI/components/prompts/prompt-management.component.js.map +1 -1
- package/dist/AI/components/prompts/prompt-version-control.component.d.ts +6 -6
- package/dist/AI/components/prompts/prompt-version-control.component.d.ts.map +1 -1
- package/dist/AI/components/prompts/prompt-version-control.component.js +1 -1
- package/dist/AI/components/prompts/prompt-version-control.component.js.map +1 -1
- package/dist/AI/components/system/system-config-filter-panel.component.js +1 -1
- package/dist/AI/components/system/system-configuration.component.d.ts +4 -4
- package/dist/AI/components/system/system-configuration.component.d.ts.map +1 -1
- package/dist/AI/components/system/system-configuration.component.js +1 -1
- package/dist/AI/components/system/system-configuration.component.js.map +1 -1
- package/dist/AI/components/widgets/kpi-card.component.js +1 -1
- package/dist/AI/components/widgets/live-execution-widget.component.js +1 -1
- package/dist/AI/services/ai-instrumentation.service.js.map +1 -1
- package/dist/APIKeys/api-applications-panel.component.js +1 -1
- package/dist/APIKeys/api-key-create-dialog.component.js +1 -1
- package/dist/APIKeys/api-key-edit-panel.component.js +1 -1
- package/dist/APIKeys/api-key-list.component.js +1 -1
- package/dist/APIKeys/api-keys-resource.component.js +1 -1
- package/dist/APIKeys/api-scopes-panel.component.js +1 -1
- package/dist/APIKeys/api-usage-panel.component.js +1 -1
- package/dist/Actions/components/actions-list-view.component.js +1 -1
- package/dist/Actions/components/actions-overview.component.js +1 -1
- package/dist/Actions/components/categories-list-view.component.js +1 -1
- package/dist/Actions/components/code-management.component.js +1 -1
- package/dist/Actions/components/entity-integration.component.js +1 -1
- package/dist/Actions/components/execution-monitoring.component.js +1 -1
- package/dist/Actions/components/executions-list-view.component.js +1 -1
- package/dist/Actions/components/explorer/action-breadcrumb.component.js +1 -1
- package/dist/Actions/components/explorer/action-card.component.d.ts +5 -5
- package/dist/Actions/components/explorer/action-card.component.d.ts.map +1 -1
- package/dist/Actions/components/explorer/action-card.component.js +1 -1
- package/dist/Actions/components/explorer/action-card.component.js.map +1 -1
- package/dist/Actions/components/explorer/action-explorer.component.d.ts +6 -6
- package/dist/Actions/components/explorer/action-explorer.component.d.ts.map +1 -1
- package/dist/Actions/components/explorer/action-explorer.component.js +2 -2
- package/dist/Actions/components/explorer/action-explorer.component.js.map +1 -1
- package/dist/Actions/components/explorer/action-list-item.component.d.ts +5 -5
- package/dist/Actions/components/explorer/action-list-item.component.d.ts.map +1 -1
- package/dist/Actions/components/explorer/action-list-item.component.js +1 -1
- package/dist/Actions/components/explorer/action-list-item.component.js.map +1 -1
- package/dist/Actions/components/explorer/action-toolbar.component.js +1 -1
- package/dist/Actions/components/explorer/action-tree-panel.component.d.ts +2 -2
- package/dist/Actions/components/explorer/action-tree-panel.component.d.ts.map +1 -1
- package/dist/Actions/components/explorer/action-tree-panel.component.js +1 -1
- package/dist/Actions/components/explorer/action-tree-panel.component.js.map +1 -1
- package/dist/Actions/components/explorer/new-action-panel.component.js +1 -1
- package/dist/Actions/components/explorer/new-category-panel.component.js +1 -1
- package/dist/Actions/components/scheduled-actions.component.js +1 -1
- package/dist/Actions/components/security-permissions.component.js +1 -1
- package/dist/Communication/communication-dashboard.component.js +1 -1
- package/dist/Communication/communication-logs-resource.component.js +1 -1
- package/dist/Communication/communication-monitor-resource.component.js +1 -1
- package/dist/Communication/communication-providers-resource.component.js +1 -1
- package/dist/Communication/communication-runs-resource.component.js +1 -1
- package/dist/Communication/communication-templates-resource.component.js +1 -1
- package/dist/ComponentStudio/component-studio-dashboard.component.js +1 -1
- package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.js +1 -1
- package/dist/ComponentStudio/components/artifact-load-dialog.component.js +1 -1
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.js +1 -1
- package/dist/ComponentStudio/components/browser/component-browser.component.js +1 -1
- package/dist/ComponentStudio/components/editors/code-editor-panel.component.js +1 -1
- package/dist/ComponentStudio/components/editors/data-requirements-editor.component.js +1 -1
- package/dist/ComponentStudio/components/editors/requirements-editor.component.js +1 -1
- package/dist/ComponentStudio/components/editors/spec-editor.component.js +1 -1
- package/dist/ComponentStudio/components/new-component-dialog/new-component-dialog.component.js +1 -1
- package/dist/ComponentStudio/components/save-version-dialog/save-version-dialog.component.js +1 -1
- package/dist/ComponentStudio/components/text-import-dialog.component.js +1 -1
- package/dist/ComponentStudio/components/workspace/component-preview.component.js +1 -1
- package/dist/ComponentStudio/components/workspace/editor-tabs.component.js +1 -1
- package/dist/ComponentStudio/services/component-studio-state.service.d.ts +3 -3
- package/dist/ComponentStudio/services/component-studio-state.service.d.ts.map +1 -1
- package/dist/ComponentStudio/services/component-studio-state.service.js.map +1 -1
- package/dist/Credentials/components/credentials-audit-resource.component.js +1 -1
- package/dist/Credentials/components/credentials-categories-resource.component.js +1 -1
- package/dist/Credentials/components/credentials-list-resource.component.js +1 -1
- package/dist/Credentials/components/credentials-overview-resource.component.js +1 -1
- package/dist/Credentials/components/credentials-types-resource.component.js +1 -1
- package/dist/Credentials/credentials-dashboard.component.js +1 -1
- package/dist/DashboardBrowser/dashboard-browser-resource.component.d.ts +4 -0
- package/dist/DashboardBrowser/dashboard-browser-resource.component.d.ts.map +1 -1
- package/dist/DashboardBrowser/dashboard-browser-resource.component.js +17 -1
- package/dist/DashboardBrowser/dashboard-browser-resource.component.js.map +1 -1
- package/dist/DashboardBrowser/dashboard-share-dialog.component.js +1 -1
- package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.js +1 -1
- package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.js +1 -1
- package/dist/DataExplorer/components/view-selector/view-selector.component.d.ts +4 -4
- package/dist/DataExplorer/components/view-selector/view-selector.component.d.ts.map +1 -1
- package/dist/DataExplorer/components/view-selector/view-selector.component.js +1 -1
- package/dist/DataExplorer/components/view-selector/view-selector.component.js.map +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts +2 -2
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.js +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
- package/dist/DataExplorer/data-explorer-resource.component.js +1 -1
- package/dist/EntityAdmin/entity-admin-dashboard.component.js +1 -1
- package/dist/Home/home-dashboard.component.js +1 -1
- package/dist/Lists/components/lists-browse-resource.component.js +1 -1
- package/dist/Lists/components/lists-categories-resource.component.js +1 -1
- package/dist/Lists/components/lists-my-lists-resource.component.js +1 -1
- package/dist/Lists/components/lists-operations-resource.component.js +1 -1
- package/dist/Lists/components/venn-diagram/venn-diagram.component.js +1 -1
- package/dist/MCP/components/mcp-connection-dialog.component.js +1 -1
- package/dist/MCP/components/mcp-log-detail-panel.component.js +1 -1
- package/dist/MCP/components/mcp-server-dialog.component.js +1 -1
- package/dist/MCP/components/mcp-test-tool-dialog.component.js +1 -1
- package/dist/MCP/mcp-dashboard.component.js +1 -1
- package/dist/MCP/mcp-filter-panel.component.js +1 -1
- package/dist/MCP/mcp-resource.component.js +1 -1
- package/dist/QueryBrowser/query-browser-resource.component.d.ts +22 -2
- package/dist/QueryBrowser/query-browser-resource.component.d.ts.map +1 -1
- package/dist/QueryBrowser/query-browser-resource.component.js +147 -63
- package/dist/QueryBrowser/query-browser-resource.component.js.map +1 -1
- package/dist/Scheduling/components/job-slideout.component.js +1 -1
- package/dist/Scheduling/components/scheduling-activity-resource.component.js +1 -1
- package/dist/Scheduling/components/scheduling-activity.component.js +1 -1
- package/dist/Scheduling/components/scheduling-jobs-resource.component.js +1 -1
- package/dist/Scheduling/components/scheduling-jobs.component.js +1 -1
- package/dist/Scheduling/components/scheduling-overview-resource.component.js +1 -1
- package/dist/Scheduling/components/scheduling-overview.component.js +1 -1
- package/dist/Scheduling/scheduling-dashboard.component.js +1 -1
- package/dist/SystemDiagnostics/system-diagnostics.component.js +1 -1
- package/dist/Testing/components/testing-analytics-resource.component.js +1 -1
- package/dist/Testing/components/testing-analytics.component.js +1 -1
- package/dist/Testing/components/testing-dashboard-tab-resource.component.js +1 -1
- package/dist/Testing/components/testing-dashboard-tab.component.js +1 -1
- package/dist/Testing/components/testing-explorer-resource.component.js +1 -1
- package/dist/Testing/components/testing-explorer.component.js +1 -1
- package/dist/Testing/components/testing-review-resource.component.js +1 -1
- package/dist/Testing/components/testing-review.component.js +1 -1
- package/dist/Testing/components/testing-runs-resource.component.js +1 -1
- package/dist/Testing/components/testing-runs.component.js +1 -1
- package/dist/Testing/components/widgets/oracle-breakdown-table.component.js +1 -1
- package/dist/Testing/components/widgets/suite-tree.component.js +2 -2
- package/dist/Testing/components/widgets/test-run-detail-panel.component.js +1 -1
- package/dist/Testing/services/testing-instrumentation.service.js.map +1 -1
- package/dist/Testing/testing-dashboard.component.js +1 -1
- package/dist/VersionHistory/components/diff-resource.component.js +1 -1
- package/dist/VersionHistory/components/graph-resource.component.js +1 -1
- package/dist/VersionHistory/components/labels-resource.component.js +1 -1
- package/dist/VersionHistory/components/restore-resource.component.js +1 -1
- package/package.json +38 -38
- package/dist/AI/ai-dashboard.component.d.ts +0 -62
- package/dist/AI/ai-dashboard.component.d.ts.map +0 -1
- package/dist/AI/ai-dashboard.component.js +0 -338
- package/dist/AI/ai-dashboard.component.js.map +0 -1
- package/dist/AI/components/models/model-management-v2.component.d.ts +0 -96
- package/dist/AI/components/models/model-management-v2.component.d.ts.map +0 -1
- package/dist/AI/components/models/model-management-v2.component.js +0 -981
- package/dist/AI/components/models/model-management-v2.component.js.map +0 -1
- package/dist/AI/components/prompts/prompt-management-v2.component.d.ts +0 -97
- package/dist/AI/components/prompts/prompt-management-v2.component.d.ts.map +0 -1
- package/dist/AI/components/prompts/prompt-management-v2.component.js +0 -811
- package/dist/AI/components/prompts/prompt-management-v2.component.js.map +0 -1
- package/dist/Actions/actions-management-dashboard.component.d.ts +0 -52
- package/dist/Actions/actions-management-dashboard.component.d.ts.map +0 -1
- package/dist/Actions/actions-management-dashboard.component.js +0 -308
- package/dist/Actions/actions-management-dashboard.component.js.map +0 -1
- package/dist/Credentials/components/credential-category-edit-panel.component.d.ts +0 -44
- package/dist/Credentials/components/credential-category-edit-panel.component.d.ts.map +0 -1
- package/dist/Credentials/components/credential-category-edit-panel.component.js +0 -456
- package/dist/Credentials/components/credential-category-edit-panel.component.js.map +0 -1
- package/dist/Credentials/components/credential-edit-panel.component.d.ts +0 -70
- package/dist/Credentials/components/credential-edit-panel.component.d.ts.map +0 -1
- package/dist/Credentials/components/credential-edit-panel.component.js +0 -694
- package/dist/Credentials/components/credential-edit-panel.component.js.map +0 -1
- package/dist/Credentials/components/credential-type-edit-panel.component.d.ts +0 -56
- package/dist/Credentials/components/credential-type-edit-panel.component.d.ts.map +0 -1
- package/dist/Credentials/components/credential-type-edit-panel.component.js +0 -563
- package/dist/Credentials/components/credential-type-edit-panel.component.js.map +0 -1
- package/dist/DataExplorer/components/view-config-panel/view-config-panel.component.d.ts +0 -245
- package/dist/DataExplorer/components/view-config-panel/view-config-panel.component.d.ts.map +0 -1
- package/dist/DataExplorer/components/view-config-panel/view-config-panel.component.js +0 -1143
- package/dist/DataExplorer/components/view-config-panel/view-config-panel.component.js.map +0 -1
- package/dist/EntityAdmin/components/entity-details.component.d.ts +0 -50
- package/dist/EntityAdmin/components/entity-details.component.d.ts.map +0 -1
- package/dist/EntityAdmin/components/entity-details.component.js +0 -680
- package/dist/EntityAdmin/components/entity-details.component.js.map +0 -1
- package/dist/EntityAdmin/components/entity-filter-panel.component.d.ts +0 -31
- package/dist/EntityAdmin/components/entity-filter-panel.component.d.ts.map +0 -1
- package/dist/EntityAdmin/components/entity-filter-panel.component.js +0 -160
- package/dist/EntityAdmin/components/entity-filter-panel.component.js.map +0 -1
- package/dist/EntityAdmin/components/erd-composite.component.d.ts +0 -73
- package/dist/EntityAdmin/components/erd-composite.component.d.ts.map +0 -1
- package/dist/EntityAdmin/components/erd-composite.component.js +0 -271
- package/dist/EntityAdmin/components/erd-composite.component.js.map +0 -1
- package/dist/EntityAdmin/components/erd-diagram.component.d.ts +0 -47
- package/dist/EntityAdmin/components/erd-diagram.component.d.ts.map +0 -1
- package/dist/EntityAdmin/components/erd-diagram.component.js +0 -618
- package/dist/EntityAdmin/components/erd-diagram.component.js.map +0 -1
- package/dist/Scheduling/components/scheduling-health-resource.component.d.ts +0 -20
- package/dist/Scheduling/components/scheduling-health-resource.component.d.ts.map +0 -1
- package/dist/Scheduling/components/scheduling-health-resource.component.js +0 -55
- package/dist/Scheduling/components/scheduling-health-resource.component.js.map +0 -1
- package/dist/Scheduling/components/scheduling-health.component.d.ts +0 -30
- package/dist/Scheduling/components/scheduling-health.component.d.ts.map +0 -1
- package/dist/Scheduling/components/scheduling-health.component.js +0 -315
- package/dist/Scheduling/components/scheduling-health.component.js.map +0 -1
- package/dist/Scheduling/components/scheduling-history-resource.component.d.ts +0 -20
- package/dist/Scheduling/components/scheduling-history-resource.component.d.ts.map +0 -1
- package/dist/Scheduling/components/scheduling-history-resource.component.js +0 -55
- package/dist/Scheduling/components/scheduling-history-resource.component.js.map +0 -1
- package/dist/Scheduling/components/scheduling-history.component.d.ts +0 -48
- package/dist/Scheduling/components/scheduling-history.component.d.ts.map +0 -1
- package/dist/Scheduling/components/scheduling-history.component.js +0 -377
- package/dist/Scheduling/components/scheduling-history.component.js.map +0 -1
- package/dist/Scheduling/components/scheduling-monitor-resource.component.d.ts +0 -20
- package/dist/Scheduling/components/scheduling-monitor-resource.component.d.ts.map +0 -1
- package/dist/Scheduling/components/scheduling-monitor-resource.component.js +0 -55
- package/dist/Scheduling/components/scheduling-monitor-resource.component.js.map +0 -1
- package/dist/Scheduling/components/scheduling-monitoring.component.d.ts +0 -37
- package/dist/Scheduling/components/scheduling-monitoring.component.d.ts.map +0 -1
- package/dist/Scheduling/components/scheduling-monitoring.component.js +0 -488
- package/dist/Scheduling/components/scheduling-monitoring.component.js.map +0 -1
- package/dist/Scheduling/components/scheduling-types-resource.component.d.ts +0 -20
- package/dist/Scheduling/components/scheduling-types-resource.component.d.ts.map +0 -1
- package/dist/Scheduling/components/scheduling-types-resource.component.js +0 -55
- package/dist/Scheduling/components/scheduling-types-resource.component.js.map +0 -1
- package/dist/Scheduling/components/scheduling-types.component.d.ts +0 -22
- package/dist/Scheduling/components/scheduling-types.component.d.ts.map +0 -1
- package/dist/Scheduling/components/scheduling-types.component.js +0 -165
- package/dist/Scheduling/components/scheduling-types.component.js.map +0 -1
- package/dist/Testing/components/testing-execution-resource.component.d.ts +0 -20
- package/dist/Testing/components/testing-execution-resource.component.d.ts.map +0 -1
- package/dist/Testing/components/testing-execution-resource.component.js +0 -55
- package/dist/Testing/components/testing-execution-resource.component.js.map +0 -1
- package/dist/Testing/components/testing-execution.component.d.ts +0 -71
- package/dist/Testing/components/testing-execution.component.d.ts.map +0 -1
- package/dist/Testing/components/testing-execution.component.js +0 -845
- package/dist/Testing/components/testing-execution.component.js.map +0 -1
- package/dist/Testing/components/testing-feedback-resource.component.d.ts +0 -20
- package/dist/Testing/components/testing-feedback-resource.component.d.ts.map +0 -1
- package/dist/Testing/components/testing-feedback-resource.component.js +0 -55
- package/dist/Testing/components/testing-feedback-resource.component.js.map +0 -1
- package/dist/Testing/components/testing-feedback.component.d.ts +0 -111
- package/dist/Testing/components/testing-feedback.component.d.ts.map +0 -1
- package/dist/Testing/components/testing-feedback.component.js +0 -1486
- package/dist/Testing/components/testing-feedback.component.js.map +0 -1
- package/dist/Testing/components/testing-overview-resource.component.d.ts +0 -20
- package/dist/Testing/components/testing-overview-resource.component.d.ts.map +0 -1
- package/dist/Testing/components/testing-overview-resource.component.js +0 -55
- package/dist/Testing/components/testing-overview-resource.component.js.map +0 -1
- package/dist/Testing/components/testing-overview.component.d.ts +0 -30
- package/dist/Testing/components/testing-overview.component.d.ts.map +0 -1
- package/dist/Testing/components/testing-overview.component.js +0 -361
- package/dist/Testing/components/testing-overview.component.js.map +0 -1
- package/dist/Testing/components/testing-version-comparison.component.d.ts +0 -62
- package/dist/Testing/components/testing-version-comparison.component.d.ts.map +0 -1
- package/dist/Testing/components/testing-version-comparison.component.js +0 -815
- package/dist/Testing/components/testing-version-comparison.component.js.map +0 -1
- package/dist/Testing/components/testing-version-resource.component.d.ts +0 -20
- package/dist/Testing/components/testing-version-resource.component.d.ts.map +0 -1
- package/dist/Testing/components/testing-version-resource.component.js +0 -55
- package/dist/Testing/components/testing-version-resource.component.js.map +0 -1
- package/dist/generic/base-dashboard.d.ts +0 -65
- package/dist/generic/base-dashboard.d.ts.map +0 -1
- package/dist/generic/base-dashboard.js +0 -74
- package/dist/generic/base-dashboard.js.map +0 -1
|
@@ -1,1486 +0,0 @@
|
|
|
1
|
-
import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy } from '@angular/core';
|
|
2
|
-
import { BehaviorSubject, Observable, Subject, combineLatest } from 'rxjs';
|
|
3
|
-
import { takeUntil, map, shareReplay, switchMap } from 'rxjs/operators';
|
|
4
|
-
import { CompositeKey, Metadata, RunView } from '@memberjunction/core';
|
|
5
|
-
import { SharedService } from '@memberjunction/ng-shared';
|
|
6
|
-
import * as i0 from "@angular/core";
|
|
7
|
-
import * as i1 from "../services/testing-instrumentation.service";
|
|
8
|
-
import * as i2 from "@angular/common";
|
|
9
|
-
import * as i3 from "@angular/forms";
|
|
10
|
-
const _c0 = () => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
|
11
|
-
function TestingFeedbackComponent_div_6_span_1_Template(rf, ctx) { if (rf & 1) {
|
|
12
|
-
i0.ɵɵelementStart(0, "span", 48);
|
|
13
|
-
i0.ɵɵtext(1);
|
|
14
|
-
i0.ɵɵelementEnd();
|
|
15
|
-
} if (rf & 2) {
|
|
16
|
-
const count_r1 = i0.ɵɵnextContext().ngIf;
|
|
17
|
-
i0.ɵɵadvance();
|
|
18
|
-
i0.ɵɵtextInterpolate(count_r1);
|
|
19
|
-
} }
|
|
20
|
-
function TestingFeedbackComponent_div_6_Template(rf, ctx) { if (rf & 1) {
|
|
21
|
-
i0.ɵɵelementStart(0, "div", 45);
|
|
22
|
-
i0.ɵɵtemplate(1, TestingFeedbackComponent_div_6_span_1_Template, 2, 1, "span", 46);
|
|
23
|
-
i0.ɵɵelementStart(2, "span", 47);
|
|
24
|
-
i0.ɵɵtext(3);
|
|
25
|
-
i0.ɵɵelementEnd()();
|
|
26
|
-
} if (rf & 2) {
|
|
27
|
-
const count_r1 = ctx.ngIf;
|
|
28
|
-
i0.ɵɵadvance();
|
|
29
|
-
i0.ɵɵproperty("ngIf", count_r1 > 0);
|
|
30
|
-
i0.ɵɵadvance(2);
|
|
31
|
-
i0.ɵɵtextInterpolate(count_r1 > 0 ? "Pending Review" : "All Reviewed");
|
|
32
|
-
} }
|
|
33
|
-
function TestingFeedbackComponent_div_64_Template(rf, ctx) { if (rf & 1) {
|
|
34
|
-
const _r2 = i0.ɵɵgetCurrentView();
|
|
35
|
-
i0.ɵɵelementStart(0, "div", 27)(1, "label");
|
|
36
|
-
i0.ɵɵtext(2, "Reason");
|
|
37
|
-
i0.ɵɵelementEnd();
|
|
38
|
-
i0.ɵɵelementStart(3, "select", 28);
|
|
39
|
-
i0.ɵɵtwoWayListener("ngModelChange", function TestingFeedbackComponent_div_64_Template_select_ngModelChange_3_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r2.filters.reason, $event) || (ctx_r2.filters.reason = $event); return i0.ɵɵresetView($event); });
|
|
40
|
-
i0.ɵɵlistener("change", function TestingFeedbackComponent_div_64_Template_select_change_3_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onFilterChange()); });
|
|
41
|
-
i0.ɵɵelementStart(4, "option", 49);
|
|
42
|
-
i0.ɵɵtext(5, "All Reasons");
|
|
43
|
-
i0.ɵɵelementEnd();
|
|
44
|
-
i0.ɵɵelementStart(6, "option", 50);
|
|
45
|
-
i0.ɵɵtext(7, "No Feedback");
|
|
46
|
-
i0.ɵɵelementEnd();
|
|
47
|
-
i0.ɵɵelementStart(8, "option", 51);
|
|
48
|
-
i0.ɵɵtext(9, "High Score but Failed");
|
|
49
|
-
i0.ɵɵelementEnd();
|
|
50
|
-
i0.ɵɵelementStart(10, "option", 52);
|
|
51
|
-
i0.ɵɵtext(11, "Low Score but Passed");
|
|
52
|
-
i0.ɵɵelementEnd()()();
|
|
53
|
-
} if (rf & 2) {
|
|
54
|
-
const ctx_r2 = i0.ɵɵnextContext();
|
|
55
|
-
i0.ɵɵadvance(3);
|
|
56
|
-
i0.ɵɵtwoWayProperty("ngModel", ctx_r2.filters.reason);
|
|
57
|
-
} }
|
|
58
|
-
function TestingFeedbackComponent_div_65_option_6_Template(rf, ctx) { if (rf & 1) {
|
|
59
|
-
i0.ɵɵelementStart(0, "option", 53);
|
|
60
|
-
i0.ɵɵtext(1);
|
|
61
|
-
i0.ɵɵelementEnd();
|
|
62
|
-
} if (rf & 2) {
|
|
63
|
-
const suite_r5 = ctx.$implicit;
|
|
64
|
-
i0.ɵɵproperty("ngValue", suite_r5.ID);
|
|
65
|
-
i0.ɵɵadvance();
|
|
66
|
-
i0.ɵɵtextInterpolate(suite_r5.Name);
|
|
67
|
-
} }
|
|
68
|
-
function TestingFeedbackComponent_div_65_Template(rf, ctx) { if (rf & 1) {
|
|
69
|
-
const _r4 = i0.ɵɵgetCurrentView();
|
|
70
|
-
i0.ɵɵelementStart(0, "div", 27)(1, "label");
|
|
71
|
-
i0.ɵɵtext(2, "Test Suite");
|
|
72
|
-
i0.ɵɵelementEnd();
|
|
73
|
-
i0.ɵɵelementStart(3, "select", 28);
|
|
74
|
-
i0.ɵɵtwoWayListener("ngModelChange", function TestingFeedbackComponent_div_65_Template_select_ngModelChange_3_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r2.filters.suiteId, $event) || (ctx_r2.filters.suiteId = $event); return i0.ɵɵresetView($event); });
|
|
75
|
-
i0.ɵɵlistener("change", function TestingFeedbackComponent_div_65_Template_select_change_3_listener() { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onFilterChange()); });
|
|
76
|
-
i0.ɵɵelementStart(4, "option", 53);
|
|
77
|
-
i0.ɵɵtext(5, "All Suites");
|
|
78
|
-
i0.ɵɵelementEnd();
|
|
79
|
-
i0.ɵɵtemplate(6, TestingFeedbackComponent_div_65_option_6_Template, 2, 2, "option", 54);
|
|
80
|
-
i0.ɵɵpipe(7, "async");
|
|
81
|
-
i0.ɵɵelementEnd()();
|
|
82
|
-
} if (rf & 2) {
|
|
83
|
-
const ctx_r2 = i0.ɵɵnextContext();
|
|
84
|
-
i0.ɵɵadvance(3);
|
|
85
|
-
i0.ɵɵtwoWayProperty("ngModel", ctx_r2.filters.suiteId);
|
|
86
|
-
i0.ɵɵadvance();
|
|
87
|
-
i0.ɵɵproperty("ngValue", null);
|
|
88
|
-
i0.ɵɵadvance(2);
|
|
89
|
-
i0.ɵɵproperty("ngForOf", i0.ɵɵpipeBind1(7, 3, ctx_r2.testSuites$));
|
|
90
|
-
} }
|
|
91
|
-
function TestingFeedbackComponent_button_72_Template(rf, ctx) { if (rf & 1) {
|
|
92
|
-
const _r6 = i0.ɵɵgetCurrentView();
|
|
93
|
-
i0.ɵɵelementStart(0, "button", 55);
|
|
94
|
-
i0.ɵɵlistener("click", function TestingFeedbackComponent_button_72_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r6); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.clearSearch()); });
|
|
95
|
-
i0.ɵɵelement(1, "i", 56);
|
|
96
|
-
i0.ɵɵelementEnd();
|
|
97
|
-
} }
|
|
98
|
-
function TestingFeedbackComponent_div_73_div_15_ng_container_1_div_1_div_23_button_9_Template(rf, ctx) { if (rf & 1) {
|
|
99
|
-
const _r11 = i0.ɵɵgetCurrentView();
|
|
100
|
-
i0.ɵɵelementStart(0, "button", 101);
|
|
101
|
-
i0.ɵɵlistener("click", function TestingFeedbackComponent_div_73_div_15_ng_container_1_div_1_div_23_button_9_Template_button_click_0_listener() { const star_r12 = i0.ɵɵrestoreView(_r11).$implicit; const item_r9 = i0.ɵɵnextContext(2).$implicit; const ctx_r2 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r2.setRating(item_r9, star_r12)); });
|
|
102
|
-
i0.ɵɵelement(1, "i", 102);
|
|
103
|
-
i0.ɵɵelementEnd();
|
|
104
|
-
} if (rf & 2) {
|
|
105
|
-
const star_r12 = ctx.$implicit;
|
|
106
|
-
const item_r9 = i0.ɵɵnextContext(2).$implicit;
|
|
107
|
-
i0.ɵɵclassProp("filled", star_r12 <= item_r9.feedbackRating);
|
|
108
|
-
} }
|
|
109
|
-
function TestingFeedbackComponent_div_73_div_15_ng_container_1_div_1_div_23_Template(rf, ctx) { if (rf & 1) {
|
|
110
|
-
const _r10 = i0.ɵɵgetCurrentView();
|
|
111
|
-
i0.ɵɵelementStart(0, "div", 82)(1, "div", 83)(2, "div", 84)(3, "h4");
|
|
112
|
-
i0.ɵɵtext(4, "Provide Your Feedback");
|
|
113
|
-
i0.ɵɵelementEnd();
|
|
114
|
-
i0.ɵɵelementStart(5, "div", 85)(6, "label");
|
|
115
|
-
i0.ɵɵtext(7, "Human Rating");
|
|
116
|
-
i0.ɵɵelementEnd();
|
|
117
|
-
i0.ɵɵelementStart(8, "div", 86);
|
|
118
|
-
i0.ɵɵtemplate(9, TestingFeedbackComponent_div_73_div_15_ng_container_1_div_1_div_23_button_9_Template, 2, 2, "button", 87);
|
|
119
|
-
i0.ɵɵelementStart(10, "span", 88);
|
|
120
|
-
i0.ɵɵtext(11);
|
|
121
|
-
i0.ɵɵelementEnd()()();
|
|
122
|
-
i0.ɵɵelementStart(12, "div", 89)(13, "label");
|
|
123
|
-
i0.ɵɵtext(14, "Is the Automated Result Correct?");
|
|
124
|
-
i0.ɵɵelementEnd();
|
|
125
|
-
i0.ɵɵelementStart(15, "div", 90)(16, "button", 91);
|
|
126
|
-
i0.ɵɵlistener("click", function TestingFeedbackComponent_div_73_div_15_ng_container_1_div_1_div_23_Template_button_click_16_listener() { i0.ɵɵrestoreView(_r10); const item_r9 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r2.setCorrectness(item_r9, true)); });
|
|
127
|
-
i0.ɵɵelement(17, "i", 92);
|
|
128
|
-
i0.ɵɵtext(18, " Correct ");
|
|
129
|
-
i0.ɵɵelementEnd();
|
|
130
|
-
i0.ɵɵelementStart(19, "button", 93);
|
|
131
|
-
i0.ɵɵlistener("click", function TestingFeedbackComponent_div_73_div_15_ng_container_1_div_1_div_23_Template_button_click_19_listener() { i0.ɵɵrestoreView(_r10); const item_r9 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r2.setCorrectness(item_r9, false)); });
|
|
132
|
-
i0.ɵɵelement(20, "i", 56);
|
|
133
|
-
i0.ɵɵtext(21, " Incorrect ");
|
|
134
|
-
i0.ɵɵelementEnd()()();
|
|
135
|
-
i0.ɵɵelementStart(22, "div", 94)(23, "label");
|
|
136
|
-
i0.ɵɵtext(24, "Comments / Correction Notes");
|
|
137
|
-
i0.ɵɵelementEnd();
|
|
138
|
-
i0.ɵɵelementStart(25, "textarea", 95);
|
|
139
|
-
i0.ɵɵtwoWayListener("ngModelChange", function TestingFeedbackComponent_div_73_div_15_ng_container_1_div_1_div_23_Template_textarea_ngModelChange_25_listener($event) { i0.ɵɵrestoreView(_r10); const item_r9 = i0.ɵɵnextContext().$implicit; i0.ɵɵtwoWayBindingSet(item_r9.feedbackComments, $event) || (item_r9.feedbackComments = $event); return i0.ɵɵresetView($event); });
|
|
140
|
-
i0.ɵɵelementEnd()();
|
|
141
|
-
i0.ɵɵelementStart(26, "div", 96)(27, "button", 97);
|
|
142
|
-
i0.ɵɵlistener("click", function TestingFeedbackComponent_div_73_div_15_ng_container_1_div_1_div_23_Template_button_click_27_listener() { i0.ɵɵrestoreView(_r10); const item_r9 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r2.submitFeedback(item_r9)); });
|
|
143
|
-
i0.ɵɵelement(28, "i", 98);
|
|
144
|
-
i0.ɵɵtext(29);
|
|
145
|
-
i0.ɵɵelementEnd();
|
|
146
|
-
i0.ɵɵelementStart(30, "button", 99);
|
|
147
|
-
i0.ɵɵlistener("click", function TestingFeedbackComponent_div_73_div_15_ng_container_1_div_1_div_23_Template_button_click_30_listener() { i0.ɵɵrestoreView(_r10); const item_r9 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r2.viewFullDetails(item_r9)); });
|
|
148
|
-
i0.ɵɵelement(31, "i", 100);
|
|
149
|
-
i0.ɵɵtext(32, " View Full Details ");
|
|
150
|
-
i0.ɵɵelementEnd()()()()();
|
|
151
|
-
} if (rf & 2) {
|
|
152
|
-
const item_r9 = i0.ɵɵnextContext().$implicit;
|
|
153
|
-
const ctx_r2 = i0.ɵɵnextContext(4);
|
|
154
|
-
i0.ɵɵproperty("@slideDown", undefined);
|
|
155
|
-
i0.ɵɵadvance(9);
|
|
156
|
-
i0.ɵɵproperty("ngForOf", i0.ɵɵpureFunction0(10, _c0));
|
|
157
|
-
i0.ɵɵadvance(2);
|
|
158
|
-
i0.ɵɵtextInterpolate1("", item_r9.feedbackRating, "/10");
|
|
159
|
-
i0.ɵɵadvance(5);
|
|
160
|
-
i0.ɵɵclassProp("active", item_r9.feedbackIsCorrect === true);
|
|
161
|
-
i0.ɵɵadvance(3);
|
|
162
|
-
i0.ɵɵclassProp("active", item_r9.feedbackIsCorrect === false);
|
|
163
|
-
i0.ɵɵadvance(6);
|
|
164
|
-
i0.ɵɵtwoWayProperty("ngModel", item_r9.feedbackComments);
|
|
165
|
-
i0.ɵɵadvance(2);
|
|
166
|
-
i0.ɵɵproperty("disabled", ctx_r2.isSubmitting);
|
|
167
|
-
i0.ɵɵadvance(2);
|
|
168
|
-
i0.ɵɵtextInterpolate1(" ", ctx_r2.isSubmitting ? "Submitting..." : "Submit Feedback", " ");
|
|
169
|
-
} }
|
|
170
|
-
function TestingFeedbackComponent_div_73_div_15_ng_container_1_div_1_Template(rf, ctx) { if (rf & 1) {
|
|
171
|
-
const _r8 = i0.ɵɵgetCurrentView();
|
|
172
|
-
i0.ɵɵelementStart(0, "div", 68)(1, "div", 69);
|
|
173
|
-
i0.ɵɵlistener("click", function TestingFeedbackComponent_div_73_div_15_ng_container_1_div_1_Template_div_click_1_listener() { const item_r9 = i0.ɵɵrestoreView(_r8).$implicit; const ctx_r2 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r2.toggleExpanded(item_r9.testRunID)); });
|
|
174
|
-
i0.ɵɵelementStart(2, "div", 70)(3, "div", 71);
|
|
175
|
-
i0.ɵɵtext(4);
|
|
176
|
-
i0.ɵɵelementEnd();
|
|
177
|
-
i0.ɵɵelementStart(5, "div", 72)(6, "span", 73);
|
|
178
|
-
i0.ɵɵelement(7, "i", 74);
|
|
179
|
-
i0.ɵɵtext(8);
|
|
180
|
-
i0.ɵɵpipe(9, "date");
|
|
181
|
-
i0.ɵɵelementEnd();
|
|
182
|
-
i0.ɵɵelementStart(10, "span", 75);
|
|
183
|
-
i0.ɵɵtext(11, " Score: ");
|
|
184
|
-
i0.ɵɵelementStart(12, "strong");
|
|
185
|
-
i0.ɵɵtext(13);
|
|
186
|
-
i0.ɵɵelementEnd();
|
|
187
|
-
i0.ɵɵtext(14, "/10 ");
|
|
188
|
-
i0.ɵɵelementEnd();
|
|
189
|
-
i0.ɵɵelementStart(15, "span", 76);
|
|
190
|
-
i0.ɵɵtext(16);
|
|
191
|
-
i0.ɵɵelementEnd()()();
|
|
192
|
-
i0.ɵɵelementStart(17, "div", 77)(18, "span", 78);
|
|
193
|
-
i0.ɵɵelement(19, "i", 79);
|
|
194
|
-
i0.ɵɵtext(20);
|
|
195
|
-
i0.ɵɵelementEnd()();
|
|
196
|
-
i0.ɵɵelementStart(21, "button", 80);
|
|
197
|
-
i0.ɵɵelement(22, "i", 79);
|
|
198
|
-
i0.ɵɵelementEnd()();
|
|
199
|
-
i0.ɵɵtemplate(23, TestingFeedbackComponent_div_73_div_15_ng_container_1_div_1_div_23_Template, 33, 11, "div", 81);
|
|
200
|
-
i0.ɵɵelementEnd();
|
|
201
|
-
} if (rf & 2) {
|
|
202
|
-
const item_r9 = ctx.$implicit;
|
|
203
|
-
const ctx_r2 = i0.ɵɵnextContext(4);
|
|
204
|
-
i0.ɵɵclassProp("expanded", ctx_r2.expandedItem === item_r9.testRunID);
|
|
205
|
-
i0.ɵɵadvance(4);
|
|
206
|
-
i0.ɵɵtextInterpolate(item_r9.testName);
|
|
207
|
-
i0.ɵɵadvance(4);
|
|
208
|
-
i0.ɵɵtextInterpolate1(" ", i0.ɵɵpipeBind2(9, 22, item_r9.runDateTime, "short"), " ");
|
|
209
|
-
i0.ɵɵadvance(5);
|
|
210
|
-
i0.ɵɵtextInterpolate((item_r9.automatedScore * 10).toFixed(2));
|
|
211
|
-
i0.ɵɵadvance(2);
|
|
212
|
-
i0.ɵɵclassMap("status-" + item_r9.automatedStatus.toLowerCase());
|
|
213
|
-
i0.ɵɵadvance();
|
|
214
|
-
i0.ɵɵtextInterpolate1(" ", item_r9.automatedStatus, " ");
|
|
215
|
-
i0.ɵɵadvance(2);
|
|
216
|
-
i0.ɵɵclassMap(item_r9.reason);
|
|
217
|
-
i0.ɵɵadvance();
|
|
218
|
-
i0.ɵɵclassProp("fa-circle-info", item_r9.reason === "no-feedback")("fa-arrow-up", item_r9.reason === "high-score-failed")("fa-arrow-down", item_r9.reason === "low-score-passed");
|
|
219
|
-
i0.ɵɵadvance();
|
|
220
|
-
i0.ɵɵtextInterpolate1(" ", ctx_r2.formatReason(item_r9.reason), " ");
|
|
221
|
-
i0.ɵɵadvance(2);
|
|
222
|
-
i0.ɵɵclassProp("fa-chevron-down", ctx_r2.expandedItem !== item_r9.testRunID)("fa-chevron-up", ctx_r2.expandedItem === item_r9.testRunID);
|
|
223
|
-
i0.ɵɵadvance();
|
|
224
|
-
i0.ɵɵproperty("ngIf", ctx_r2.expandedItem === item_r9.testRunID);
|
|
225
|
-
} }
|
|
226
|
-
function TestingFeedbackComponent_div_73_div_15_ng_container_1_Template(rf, ctx) { if (rf & 1) {
|
|
227
|
-
i0.ɵɵelementContainerStart(0);
|
|
228
|
-
i0.ɵɵtemplate(1, TestingFeedbackComponent_div_73_div_15_ng_container_1_div_1_Template, 24, 25, "div", 67);
|
|
229
|
-
i0.ɵɵelementContainerEnd();
|
|
230
|
-
} if (rf & 2) {
|
|
231
|
-
const items_r13 = i0.ɵɵnextContext().ngIf;
|
|
232
|
-
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
233
|
-
i0.ɵɵadvance();
|
|
234
|
-
i0.ɵɵproperty("ngForOf", items_r13)("ngForTrackBy", ctx_r2.trackByTestRunId);
|
|
235
|
-
} }
|
|
236
|
-
function TestingFeedbackComponent_div_73_div_15_ng_template_2_Template(rf, ctx) { if (rf & 1) {
|
|
237
|
-
i0.ɵɵelementStart(0, "div", 103);
|
|
238
|
-
i0.ɵɵelement(1, "i", 104);
|
|
239
|
-
i0.ɵɵelementStart(2, "h3");
|
|
240
|
-
i0.ɵɵtext(3, "All Caught Up!");
|
|
241
|
-
i0.ɵɵelementEnd();
|
|
242
|
-
i0.ɵɵelementStart(4, "p");
|
|
243
|
-
i0.ɵɵtext(5, "No tests currently require feedback review.");
|
|
244
|
-
i0.ɵɵelementEnd()();
|
|
245
|
-
} }
|
|
246
|
-
function TestingFeedbackComponent_div_73_div_15_Template(rf, ctx) { if (rf & 1) {
|
|
247
|
-
i0.ɵɵelementStart(0, "div", 65);
|
|
248
|
-
i0.ɵɵtemplate(1, TestingFeedbackComponent_div_73_div_15_ng_container_1_Template, 2, 2, "ng-container", 66)(2, TestingFeedbackComponent_div_73_div_15_ng_template_2_Template, 6, 0, "ng-template", null, 0, i0.ɵɵtemplateRefExtractor);
|
|
249
|
-
i0.ɵɵelementEnd();
|
|
250
|
-
} if (rf & 2) {
|
|
251
|
-
const items_r13 = ctx.ngIf;
|
|
252
|
-
const emptyPending_r14 = i0.ɵɵreference(3);
|
|
253
|
-
i0.ɵɵadvance();
|
|
254
|
-
i0.ɵɵproperty("ngIf", items_r13.length > 0)("ngIfElse", emptyPending_r14);
|
|
255
|
-
} }
|
|
256
|
-
function TestingFeedbackComponent_div_73_Template(rf, ctx) { if (rf & 1) {
|
|
257
|
-
const _r7 = i0.ɵɵgetCurrentView();
|
|
258
|
-
i0.ɵɵelementStart(0, "div", 57)(1, "div", 58)(2, "h3");
|
|
259
|
-
i0.ɵɵelement(3, "i", 59);
|
|
260
|
-
i0.ɵɵtext(4, " Tests Requiring Review ");
|
|
261
|
-
i0.ɵɵelementEnd();
|
|
262
|
-
i0.ɵɵelementStart(5, "div", 60)(6, "label");
|
|
263
|
-
i0.ɵɵtext(7, "Sort by:");
|
|
264
|
-
i0.ɵɵelementEnd();
|
|
265
|
-
i0.ɵɵelementStart(8, "select", 28);
|
|
266
|
-
i0.ɵɵtwoWayListener("ngModelChange", function TestingFeedbackComponent_div_73_Template_select_ngModelChange_8_listener($event) { i0.ɵɵrestoreView(_r7); const ctx_r2 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r2.sortBy, $event) || (ctx_r2.sortBy = $event); return i0.ɵɵresetView($event); });
|
|
267
|
-
i0.ɵɵlistener("change", function TestingFeedbackComponent_div_73_Template_select_change_8_listener() { i0.ɵɵrestoreView(_r7); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onSortChange()); });
|
|
268
|
-
i0.ɵɵelementStart(9, "option", 61);
|
|
269
|
-
i0.ɵɵtext(10, "Date");
|
|
270
|
-
i0.ɵɵelementEnd();
|
|
271
|
-
i0.ɵɵelementStart(11, "option", 62);
|
|
272
|
-
i0.ɵɵtext(12, "Priority");
|
|
273
|
-
i0.ɵɵelementEnd();
|
|
274
|
-
i0.ɵɵelementStart(13, "option", 63);
|
|
275
|
-
i0.ɵɵtext(14, "Test Name");
|
|
276
|
-
i0.ɵɵelementEnd()()()();
|
|
277
|
-
i0.ɵɵtemplate(15, TestingFeedbackComponent_div_73_div_15_Template, 4, 2, "div", 64);
|
|
278
|
-
i0.ɵɵpipe(16, "async");
|
|
279
|
-
i0.ɵɵelementEnd();
|
|
280
|
-
} if (rf & 2) {
|
|
281
|
-
const ctx_r2 = i0.ɵɵnextContext();
|
|
282
|
-
i0.ɵɵadvance(8);
|
|
283
|
-
i0.ɵɵtwoWayProperty("ngModel", ctx_r2.sortBy);
|
|
284
|
-
i0.ɵɵadvance(7);
|
|
285
|
-
i0.ɵɵproperty("ngIf", i0.ɵɵpipeBind1(16, 2, ctx_r2.filteredPending$));
|
|
286
|
-
} }
|
|
287
|
-
function TestingFeedbackComponent_div_74_div_15_ng_container_1_div_1_i_15_Template(rf, ctx) { if (rf & 1) {
|
|
288
|
-
i0.ɵɵelement(0, "i", 102);
|
|
289
|
-
} if (rf & 2) {
|
|
290
|
-
const s_r17 = ctx.$implicit;
|
|
291
|
-
const item_r18 = i0.ɵɵnextContext().$implicit;
|
|
292
|
-
i0.ɵɵclassProp("filled", s_r17 <= item_r18.rating);
|
|
293
|
-
} }
|
|
294
|
-
function TestingFeedbackComponent_div_74_div_15_ng_container_1_div_1_div_24_Template(rf, ctx) { if (rf & 1) {
|
|
295
|
-
i0.ɵɵelementStart(0, "div", 124)(1, "p");
|
|
296
|
-
i0.ɵɵtext(2);
|
|
297
|
-
i0.ɵɵelementEnd()();
|
|
298
|
-
} if (rf & 2) {
|
|
299
|
-
const item_r18 = i0.ɵɵnextContext().$implicit;
|
|
300
|
-
i0.ɵɵadvance(2);
|
|
301
|
-
i0.ɵɵtextInterpolate(item_r18.comments);
|
|
302
|
-
} }
|
|
303
|
-
function TestingFeedbackComponent_div_74_div_15_ng_container_1_div_1_Template(rf, ctx) { if (rf & 1) {
|
|
304
|
-
const _r16 = i0.ɵɵgetCurrentView();
|
|
305
|
-
i0.ɵɵelementStart(0, "div", 108)(1, "div", 109)(2, "div", 110)(3, "div", 111);
|
|
306
|
-
i0.ɵɵtext(4);
|
|
307
|
-
i0.ɵɵelementEnd();
|
|
308
|
-
i0.ɵɵelementStart(5, "div", 112)(6, "span", 113);
|
|
309
|
-
i0.ɵɵelement(7, "i", 114);
|
|
310
|
-
i0.ɵɵtext(8);
|
|
311
|
-
i0.ɵɵelementEnd();
|
|
312
|
-
i0.ɵɵelementStart(9, "span", 73);
|
|
313
|
-
i0.ɵɵelement(10, "i", 115);
|
|
314
|
-
i0.ɵɵtext(11);
|
|
315
|
-
i0.ɵɵpipe(12, "date");
|
|
316
|
-
i0.ɵɵelementEnd()()();
|
|
317
|
-
i0.ɵɵelementStart(13, "div", 116)(14, "div", 117);
|
|
318
|
-
i0.ɵɵtemplate(15, TestingFeedbackComponent_div_74_div_15_ng_container_1_div_1_i_15_Template, 1, 2, "i", 118);
|
|
319
|
-
i0.ɵɵelementEnd();
|
|
320
|
-
i0.ɵɵelementStart(16, "span", 119);
|
|
321
|
-
i0.ɵɵtext(17);
|
|
322
|
-
i0.ɵɵelementEnd()();
|
|
323
|
-
i0.ɵɵelementStart(18, "div", 120)(19, "span", 121);
|
|
324
|
-
i0.ɵɵelement(20, "i", 79);
|
|
325
|
-
i0.ɵɵtext(21);
|
|
326
|
-
i0.ɵɵelementEnd()();
|
|
327
|
-
i0.ɵɵelementStart(22, "button", 122);
|
|
328
|
-
i0.ɵɵlistener("click", function TestingFeedbackComponent_div_74_div_15_ng_container_1_div_1_Template_button_click_22_listener() { const item_r18 = i0.ɵɵrestoreView(_r16).$implicit; const ctx_r2 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r2.viewTestRun(item_r18.testRunID)); });
|
|
329
|
-
i0.ɵɵelement(23, "i", 100);
|
|
330
|
-
i0.ɵɵelementEnd()();
|
|
331
|
-
i0.ɵɵtemplate(24, TestingFeedbackComponent_div_74_div_15_ng_container_1_div_1_div_24_Template, 3, 1, "div", 123);
|
|
332
|
-
i0.ɵɵelementEnd();
|
|
333
|
-
} if (rf & 2) {
|
|
334
|
-
const item_r18 = ctx.$implicit;
|
|
335
|
-
i0.ɵɵadvance(4);
|
|
336
|
-
i0.ɵɵtextInterpolate(item_r18.testName);
|
|
337
|
-
i0.ɵɵadvance(4);
|
|
338
|
-
i0.ɵɵtextInterpolate1(" ", item_r18.reviewerName, " ");
|
|
339
|
-
i0.ɵɵadvance(3);
|
|
340
|
-
i0.ɵɵtextInterpolate1(" ", i0.ɵɵpipeBind2(12, 15, item_r18.reviewedAt, "short"), " ");
|
|
341
|
-
i0.ɵɵadvance(4);
|
|
342
|
-
i0.ɵɵproperty("ngForOf", i0.ɵɵpureFunction0(18, _c0));
|
|
343
|
-
i0.ɵɵadvance(2);
|
|
344
|
-
i0.ɵɵtextInterpolate1("", item_r18.rating, "/10");
|
|
345
|
-
i0.ɵɵadvance(2);
|
|
346
|
-
i0.ɵɵclassProp("correct", item_r18.isCorrect)("incorrect", !item_r18.isCorrect);
|
|
347
|
-
i0.ɵɵadvance();
|
|
348
|
-
i0.ɵɵclassProp("fa-check", item_r18.isCorrect)("fa-times", !item_r18.isCorrect);
|
|
349
|
-
i0.ɵɵadvance();
|
|
350
|
-
i0.ɵɵtextInterpolate1(" ", item_r18.isCorrect ? "Correct" : "Incorrect", " ");
|
|
351
|
-
i0.ɵɵadvance(3);
|
|
352
|
-
i0.ɵɵproperty("ngIf", item_r18.comments);
|
|
353
|
-
} }
|
|
354
|
-
function TestingFeedbackComponent_div_74_div_15_ng_container_1_Template(rf, ctx) { if (rf & 1) {
|
|
355
|
-
i0.ɵɵelementContainerStart(0);
|
|
356
|
-
i0.ɵɵtemplate(1, TestingFeedbackComponent_div_74_div_15_ng_container_1_div_1_Template, 25, 19, "div", 107);
|
|
357
|
-
i0.ɵɵelementContainerEnd();
|
|
358
|
-
} if (rf & 2) {
|
|
359
|
-
const items_r19 = i0.ɵɵnextContext().ngIf;
|
|
360
|
-
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
361
|
-
i0.ɵɵadvance();
|
|
362
|
-
i0.ɵɵproperty("ngForOf", items_r19)("ngForTrackBy", ctx_r2.trackByReviewedId);
|
|
363
|
-
} }
|
|
364
|
-
function TestingFeedbackComponent_div_74_div_15_ng_template_2_Template(rf, ctx) { if (rf & 1) {
|
|
365
|
-
i0.ɵɵelementStart(0, "div", 125);
|
|
366
|
-
i0.ɵɵelement(1, "i", 126);
|
|
367
|
-
i0.ɵɵelementStart(2, "h3");
|
|
368
|
-
i0.ɵɵtext(3, "No Reviews Yet");
|
|
369
|
-
i0.ɵɵelementEnd();
|
|
370
|
-
i0.ɵɵelementStart(4, "p");
|
|
371
|
-
i0.ɵɵtext(5, "No feedback has been submitted yet. Start by reviewing pending tests.");
|
|
372
|
-
i0.ɵɵelementEnd()();
|
|
373
|
-
} }
|
|
374
|
-
function TestingFeedbackComponent_div_74_div_15_Template(rf, ctx) { if (rf & 1) {
|
|
375
|
-
i0.ɵɵelementStart(0, "div", 65);
|
|
376
|
-
i0.ɵɵtemplate(1, TestingFeedbackComponent_div_74_div_15_ng_container_1_Template, 2, 2, "ng-container", 66)(2, TestingFeedbackComponent_div_74_div_15_ng_template_2_Template, 6, 0, "ng-template", null, 1, i0.ɵɵtemplateRefExtractor);
|
|
377
|
-
i0.ɵɵelementEnd();
|
|
378
|
-
} if (rf & 2) {
|
|
379
|
-
const items_r19 = ctx.ngIf;
|
|
380
|
-
const emptyReviewed_r20 = i0.ɵɵreference(3);
|
|
381
|
-
i0.ɵɵadvance();
|
|
382
|
-
i0.ɵɵproperty("ngIf", items_r19.length > 0)("ngIfElse", emptyReviewed_r20);
|
|
383
|
-
} }
|
|
384
|
-
function TestingFeedbackComponent_div_74_Template(rf, ctx) { if (rf & 1) {
|
|
385
|
-
const _r15 = i0.ɵɵgetCurrentView();
|
|
386
|
-
i0.ɵɵelementStart(0, "div", 57)(1, "div", 58)(2, "h3");
|
|
387
|
-
i0.ɵɵelement(3, "i", 105);
|
|
388
|
-
i0.ɵɵtext(4, " Reviewed Feedback History ");
|
|
389
|
-
i0.ɵɵelementEnd();
|
|
390
|
-
i0.ɵɵelementStart(5, "div", 60)(6, "label");
|
|
391
|
-
i0.ɵɵtext(7, "Sort by:");
|
|
392
|
-
i0.ɵɵelementEnd();
|
|
393
|
-
i0.ɵɵelementStart(8, "select", 28);
|
|
394
|
-
i0.ɵɵtwoWayListener("ngModelChange", function TestingFeedbackComponent_div_74_Template_select_ngModelChange_8_listener($event) { i0.ɵɵrestoreView(_r15); const ctx_r2 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r2.reviewedSortBy, $event) || (ctx_r2.reviewedSortBy = $event); return i0.ɵɵresetView($event); });
|
|
395
|
-
i0.ɵɵlistener("change", function TestingFeedbackComponent_div_74_Template_select_change_8_listener() { i0.ɵɵrestoreView(_r15); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onReviewedSortChange()); });
|
|
396
|
-
i0.ɵɵelementStart(9, "option", 61);
|
|
397
|
-
i0.ɵɵtext(10, "Review Date");
|
|
398
|
-
i0.ɵɵelementEnd();
|
|
399
|
-
i0.ɵɵelementStart(11, "option", 106);
|
|
400
|
-
i0.ɵɵtext(12, "Rating");
|
|
401
|
-
i0.ɵɵelementEnd();
|
|
402
|
-
i0.ɵɵelementStart(13, "option", 63);
|
|
403
|
-
i0.ɵɵtext(14, "Test Name");
|
|
404
|
-
i0.ɵɵelementEnd()()()();
|
|
405
|
-
i0.ɵɵtemplate(15, TestingFeedbackComponent_div_74_div_15_Template, 4, 2, "div", 64);
|
|
406
|
-
i0.ɵɵpipe(16, "async");
|
|
407
|
-
i0.ɵɵelementEnd();
|
|
408
|
-
} if (rf & 2) {
|
|
409
|
-
const ctx_r2 = i0.ɵɵnextContext();
|
|
410
|
-
i0.ɵɵadvance(8);
|
|
411
|
-
i0.ɵɵtwoWayProperty("ngModel", ctx_r2.reviewedSortBy);
|
|
412
|
-
i0.ɵɵadvance(7);
|
|
413
|
-
i0.ɵɵproperty("ngIf", i0.ɵɵpipeBind1(16, 2, ctx_r2.filteredReviewed$));
|
|
414
|
-
} }
|
|
415
|
-
function TestingFeedbackComponent_div_75_div_5_ng_container_1_div_1_Template(rf, ctx) { if (rf & 1) {
|
|
416
|
-
const _r21 = i0.ɵɵgetCurrentView();
|
|
417
|
-
i0.ɵɵelementStart(0, "div", 130);
|
|
418
|
-
i0.ɵɵlistener("click", function TestingFeedbackComponent_div_75_div_5_ng_container_1_div_1_Template_div_click_0_listener() { const suite_r22 = i0.ɵɵrestoreView(_r21).$implicit; const ctx_r2 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r2.selectSuite(suite_r22.suiteId)); });
|
|
419
|
-
i0.ɵɵelementStart(1, "div", 131)(2, "div", 132);
|
|
420
|
-
i0.ɵɵelement(3, "i", 22);
|
|
421
|
-
i0.ɵɵelementEnd();
|
|
422
|
-
i0.ɵɵelementStart(4, "div", 133)(5, "h4");
|
|
423
|
-
i0.ɵɵtext(6);
|
|
424
|
-
i0.ɵɵelementEnd();
|
|
425
|
-
i0.ɵɵelementStart(7, "div", 134)(8, "span");
|
|
426
|
-
i0.ɵɵtext(9);
|
|
427
|
-
i0.ɵɵelementEnd()()()();
|
|
428
|
-
i0.ɵɵelementStart(10, "div", 135)(11, "div", 136)(12, "div", 137);
|
|
429
|
-
i0.ɵɵtext(13);
|
|
430
|
-
i0.ɵɵelementEnd();
|
|
431
|
-
i0.ɵɵelementStart(14, "div", 43);
|
|
432
|
-
i0.ɵɵtext(15, "Pending");
|
|
433
|
-
i0.ɵɵelementEnd()();
|
|
434
|
-
i0.ɵɵelementStart(16, "div", 136)(17, "div", 138);
|
|
435
|
-
i0.ɵɵtext(18);
|
|
436
|
-
i0.ɵɵelementEnd();
|
|
437
|
-
i0.ɵɵelementStart(19, "div", 43);
|
|
438
|
-
i0.ɵɵtext(20, "Reviewed");
|
|
439
|
-
i0.ɵɵelementEnd()();
|
|
440
|
-
i0.ɵɵelementStart(21, "div", 136)(22, "div", 44);
|
|
441
|
-
i0.ɵɵtext(23);
|
|
442
|
-
i0.ɵɵpipe(24, "number");
|
|
443
|
-
i0.ɵɵelementEnd();
|
|
444
|
-
i0.ɵɵelementStart(25, "div", 43);
|
|
445
|
-
i0.ɵɵtext(26, "Avg Rating");
|
|
446
|
-
i0.ɵɵelementEnd()();
|
|
447
|
-
i0.ɵɵelementStart(27, "div", 136)(28, "div", 44);
|
|
448
|
-
i0.ɵɵtext(29);
|
|
449
|
-
i0.ɵɵpipe(30, "number");
|
|
450
|
-
i0.ɵɵelementEnd();
|
|
451
|
-
i0.ɵɵelementStart(31, "div", 43);
|
|
452
|
-
i0.ɵɵtext(32, "Agreement");
|
|
453
|
-
i0.ɵɵelementEnd()();
|
|
454
|
-
i0.ɵɵelementStart(33, "div", 136)(34, "div", 44);
|
|
455
|
-
i0.ɵɵtext(35);
|
|
456
|
-
i0.ɵɵpipe(36, "number");
|
|
457
|
-
i0.ɵɵelementEnd();
|
|
458
|
-
i0.ɵɵelementStart(37, "div", 43);
|
|
459
|
-
i0.ɵɵtext(38, "Pass Rate");
|
|
460
|
-
i0.ɵɵelementEnd()()();
|
|
461
|
-
i0.ɵɵelement(39, "i", 139);
|
|
462
|
-
i0.ɵɵelementEnd();
|
|
463
|
-
} if (rf & 2) {
|
|
464
|
-
const suite_r22 = ctx.$implicit;
|
|
465
|
-
i0.ɵɵadvance(6);
|
|
466
|
-
i0.ɵɵtextInterpolate(suite_r22.suiteName);
|
|
467
|
-
i0.ɵɵadvance(3);
|
|
468
|
-
i0.ɵɵtextInterpolate1("", suite_r22.totalRuns, " test runs");
|
|
469
|
-
i0.ɵɵadvance(4);
|
|
470
|
-
i0.ɵɵtextInterpolate(suite_r22.pendingCount);
|
|
471
|
-
i0.ɵɵadvance(5);
|
|
472
|
-
i0.ɵɵtextInterpolate(suite_r22.reviewedCount);
|
|
473
|
-
i0.ɵɵadvance(5);
|
|
474
|
-
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(24, 15, suite_r22.avgRating, "1.1-1"));
|
|
475
|
-
i0.ɵɵadvance(5);
|
|
476
|
-
i0.ɵɵclassProp("good", suite_r22.agreementRate >= 70)("bad", suite_r22.agreementRate < 50);
|
|
477
|
-
i0.ɵɵadvance();
|
|
478
|
-
i0.ɵɵtextInterpolate1(" ", i0.ɵɵpipeBind2(30, 18, suite_r22.agreementRate, "1.0-0"), "% ");
|
|
479
|
-
i0.ɵɵadvance(5);
|
|
480
|
-
i0.ɵɵclassProp("good", suite_r22.passRate >= 80)("bad", suite_r22.passRate < 50);
|
|
481
|
-
i0.ɵɵadvance();
|
|
482
|
-
i0.ɵɵtextInterpolate1(" ", i0.ɵɵpipeBind2(36, 21, suite_r22.passRate, "1.0-0"), "% ");
|
|
483
|
-
} }
|
|
484
|
-
function TestingFeedbackComponent_div_75_div_5_ng_container_1_Template(rf, ctx) { if (rf & 1) {
|
|
485
|
-
i0.ɵɵelementContainerStart(0);
|
|
486
|
-
i0.ɵɵtemplate(1, TestingFeedbackComponent_div_75_div_5_ng_container_1_div_1_Template, 40, 24, "div", 129);
|
|
487
|
-
i0.ɵɵelementContainerEnd();
|
|
488
|
-
} if (rf & 2) {
|
|
489
|
-
const suites_r23 = i0.ɵɵnextContext().ngIf;
|
|
490
|
-
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
491
|
-
i0.ɵɵadvance();
|
|
492
|
-
i0.ɵɵproperty("ngForOf", suites_r23)("ngForTrackBy", ctx_r2.trackBySuiteId);
|
|
493
|
-
} }
|
|
494
|
-
function TestingFeedbackComponent_div_75_div_5_ng_template_2_Template(rf, ctx) { if (rf & 1) {
|
|
495
|
-
i0.ɵɵelementStart(0, "div", 125);
|
|
496
|
-
i0.ɵɵelement(1, "i", 22);
|
|
497
|
-
i0.ɵɵelementStart(2, "h3");
|
|
498
|
-
i0.ɵɵtext(3, "No Test Suites");
|
|
499
|
-
i0.ɵɵelementEnd();
|
|
500
|
-
i0.ɵɵelementStart(4, "p");
|
|
501
|
-
i0.ɵɵtext(5, "No test suites have been created yet.");
|
|
502
|
-
i0.ɵɵelementEnd()();
|
|
503
|
-
} }
|
|
504
|
-
function TestingFeedbackComponent_div_75_div_5_Template(rf, ctx) { if (rf & 1) {
|
|
505
|
-
i0.ɵɵelementStart(0, "div", 128);
|
|
506
|
-
i0.ɵɵtemplate(1, TestingFeedbackComponent_div_75_div_5_ng_container_1_Template, 2, 2, "ng-container", 66)(2, TestingFeedbackComponent_div_75_div_5_ng_template_2_Template, 6, 0, "ng-template", null, 2, i0.ɵɵtemplateRefExtractor);
|
|
507
|
-
i0.ɵɵelementEnd();
|
|
508
|
-
} if (rf & 2) {
|
|
509
|
-
const suites_r23 = ctx.ngIf;
|
|
510
|
-
const emptySuites_r24 = i0.ɵɵreference(3);
|
|
511
|
-
i0.ɵɵadvance();
|
|
512
|
-
i0.ɵɵproperty("ngIf", suites_r23.length > 0)("ngIfElse", emptySuites_r24);
|
|
513
|
-
} }
|
|
514
|
-
function TestingFeedbackComponent_div_75_Template(rf, ctx) { if (rf & 1) {
|
|
515
|
-
i0.ɵɵelementStart(0, "div", 57)(1, "div", 58)(2, "h3");
|
|
516
|
-
i0.ɵɵelement(3, "i", 22);
|
|
517
|
-
i0.ɵɵtext(4, " Feedback by Test Suite ");
|
|
518
|
-
i0.ɵɵelementEnd()();
|
|
519
|
-
i0.ɵɵtemplate(5, TestingFeedbackComponent_div_75_div_5_Template, 4, 2, "div", 127);
|
|
520
|
-
i0.ɵɵpipe(6, "async");
|
|
521
|
-
i0.ɵɵelementEnd();
|
|
522
|
-
} if (rf & 2) {
|
|
523
|
-
const ctx_r2 = i0.ɵɵnextContext();
|
|
524
|
-
i0.ɵɵadvance(5);
|
|
525
|
-
i0.ɵɵproperty("ngIf", i0.ɵɵpipeBind1(6, 1, ctx_r2.suiteAggregations$));
|
|
526
|
-
} }
|
|
527
|
-
export class TestingFeedbackComponent {
|
|
528
|
-
instrumentationService;
|
|
529
|
-
cdr;
|
|
530
|
-
initialState;
|
|
531
|
-
stateChange = new EventEmitter();
|
|
532
|
-
destroy$ = new Subject();
|
|
533
|
-
filterTrigger$ = new BehaviorSubject(undefined);
|
|
534
|
-
metadata = new Metadata();
|
|
535
|
-
viewMode = 'pending';
|
|
536
|
-
isRefreshing = false;
|
|
537
|
-
isSubmitting = false;
|
|
538
|
-
expandedItem = null;
|
|
539
|
-
filters = {
|
|
540
|
-
status: 'all',
|
|
541
|
-
reason: 'all',
|
|
542
|
-
suiteId: null,
|
|
543
|
-
searchText: ''
|
|
544
|
-
};
|
|
545
|
-
sortBy = 'date';
|
|
546
|
-
reviewedSortBy = 'date';
|
|
547
|
-
// Observables
|
|
548
|
-
pendingCount$;
|
|
549
|
-
reviewedCount$;
|
|
550
|
-
suiteCount$;
|
|
551
|
-
accuracyRate$;
|
|
552
|
-
totalFeedback$;
|
|
553
|
-
avgRating$;
|
|
554
|
-
agreementRate$;
|
|
555
|
-
discrepancyCount$;
|
|
556
|
-
filteredPending$;
|
|
557
|
-
filteredReviewed$;
|
|
558
|
-
suiteAggregations$;
|
|
559
|
-
testSuites$;
|
|
560
|
-
// Local data cache for filtering
|
|
561
|
-
pendingData = [];
|
|
562
|
-
reviewedData = [];
|
|
563
|
-
constructor(instrumentationService, cdr) {
|
|
564
|
-
this.instrumentationService = instrumentationService;
|
|
565
|
-
this.cdr = cdr;
|
|
566
|
-
}
|
|
567
|
-
ngOnInit() {
|
|
568
|
-
if (this.initialState) {
|
|
569
|
-
if (this.initialState.filters) {
|
|
570
|
-
this.filters = { ...this.filters, ...this.initialState.filters };
|
|
571
|
-
}
|
|
572
|
-
if (this.initialState.viewMode) {
|
|
573
|
-
this.viewMode = this.initialState.viewMode;
|
|
574
|
-
}
|
|
575
|
-
if (this.initialState.sortBy) {
|
|
576
|
-
this.sortBy = this.initialState.sortBy;
|
|
577
|
-
}
|
|
578
|
-
}
|
|
579
|
-
this.setupObservables();
|
|
580
|
-
this.loadTestSuites();
|
|
581
|
-
}
|
|
582
|
-
ngOnDestroy() {
|
|
583
|
-
this.destroy$.next();
|
|
584
|
-
this.destroy$.complete();
|
|
585
|
-
}
|
|
586
|
-
setupObservables() {
|
|
587
|
-
// Stats from service
|
|
588
|
-
const feedbackStats$ = this.instrumentationService.feedbackStats$.pipe(takeUntil(this.destroy$), shareReplay(1));
|
|
589
|
-
this.pendingCount$ = this.instrumentationService.pendingFeedback$.pipe(map(items => items.length), takeUntil(this.destroy$));
|
|
590
|
-
this.reviewedCount$ = feedbackStats$.pipe(map(stats => stats.reviewedCount));
|
|
591
|
-
this.accuracyRate$ = feedbackStats$.pipe(map(stats => stats.accuracyRate));
|
|
592
|
-
this.totalFeedback$ = feedbackStats$.pipe(map(stats => stats.totalFeedback));
|
|
593
|
-
this.avgRating$ = feedbackStats$.pipe(map(stats => stats.avgRating));
|
|
594
|
-
this.agreementRate$ = feedbackStats$.pipe(map(stats => stats.agreementRate));
|
|
595
|
-
this.discrepancyCount$ = this.instrumentationService.pendingFeedback$.pipe(map(items => items.filter(f => f.reason === 'high-score-failed' || f.reason === 'low-score-passed').length), takeUntil(this.destroy$));
|
|
596
|
-
// Filtered pending items
|
|
597
|
-
this.filteredPending$ = combineLatest([
|
|
598
|
-
this.instrumentationService.pendingFeedback$,
|
|
599
|
-
this.filterTrigger$
|
|
600
|
-
]).pipe(map(([items]) => {
|
|
601
|
-
const enhanced = items.map(f => ({
|
|
602
|
-
...f,
|
|
603
|
-
feedbackRating: 5,
|
|
604
|
-
feedbackIsCorrect: true,
|
|
605
|
-
feedbackComments: ''
|
|
606
|
-
}));
|
|
607
|
-
this.pendingData = enhanced;
|
|
608
|
-
return this.filterAndSortPending(enhanced);
|
|
609
|
-
}), takeUntil(this.destroy$));
|
|
610
|
-
// Load and filter reviewed feedback
|
|
611
|
-
this.filteredReviewed$ = combineLatest([
|
|
612
|
-
this.loadReviewedFeedback(),
|
|
613
|
-
this.filterTrigger$
|
|
614
|
-
]).pipe(map(([items]) => {
|
|
615
|
-
this.reviewedData = items;
|
|
616
|
-
return this.filterAndSortReviewed(items);
|
|
617
|
-
}), takeUntil(this.destroy$));
|
|
618
|
-
// Suite aggregations
|
|
619
|
-
this.suiteAggregations$ = this.loadSuiteAggregations().pipe(takeUntil(this.destroy$));
|
|
620
|
-
this.suiteCount$ = this.suiteAggregations$.pipe(map(suites => suites.length));
|
|
621
|
-
}
|
|
622
|
-
async loadTestSuites() {
|
|
623
|
-
const rv = new RunView();
|
|
624
|
-
const result = await rv.RunView({
|
|
625
|
-
EntityName: 'MJ: Test Suites',
|
|
626
|
-
ExtraFilter: "Status = 'Active'",
|
|
627
|
-
OrderBy: 'Name',
|
|
628
|
-
ResultType: 'entity_object'
|
|
629
|
-
});
|
|
630
|
-
this.testSuites$ = new BehaviorSubject(result.Results || []).asObservable();
|
|
631
|
-
this.cdr.markForCheck();
|
|
632
|
-
}
|
|
633
|
-
loadReviewedFeedback() {
|
|
634
|
-
return combineLatest([
|
|
635
|
-
this.instrumentationService.dateRange$,
|
|
636
|
-
this.instrumentationService.isLoading$
|
|
637
|
-
]).pipe(switchMap(([dateRange]) => {
|
|
638
|
-
return new Observable(observer => {
|
|
639
|
-
this.loadReviewedFeedbackAsync(dateRange.start, dateRange.end).then(data => {
|
|
640
|
-
observer.next(data);
|
|
641
|
-
observer.complete();
|
|
642
|
-
}, error => observer.error(error));
|
|
643
|
-
});
|
|
644
|
-
}), shareReplay(1));
|
|
645
|
-
}
|
|
646
|
-
async loadReviewedFeedbackAsync(start, end) {
|
|
647
|
-
const rv = new RunView();
|
|
648
|
-
const result = await rv.RunView({
|
|
649
|
-
EntityName: 'MJ: Test Run Feedbacks',
|
|
650
|
-
ExtraFilter: `__mj_CreatedAt >= '${start.toISOString()}' AND __mj_CreatedAt <= '${end.toISOString()}'`,
|
|
651
|
-
OrderBy: '__mj_CreatedAt DESC',
|
|
652
|
-
MaxRows: 500,
|
|
653
|
-
ResultType: 'entity_object'
|
|
654
|
-
});
|
|
655
|
-
const feedbacks = result.Results || [];
|
|
656
|
-
// Get test run details for each feedback
|
|
657
|
-
if (feedbacks.length === 0)
|
|
658
|
-
return [];
|
|
659
|
-
const testRunIds = feedbacks.map(f => f.TestRunID);
|
|
660
|
-
const testRunResult = await rv.RunView({
|
|
661
|
-
EntityName: 'MJ: Test Runs',
|
|
662
|
-
ExtraFilter: `ID IN ('${testRunIds.join("','")}')`,
|
|
663
|
-
ResultType: 'entity_object'
|
|
664
|
-
});
|
|
665
|
-
const testRunMap = new Map();
|
|
666
|
-
(testRunResult.Results || []).forEach(tr => testRunMap.set(tr.ID, tr));
|
|
667
|
-
return feedbacks.map(f => {
|
|
668
|
-
const testRun = testRunMap.get(f.TestRunID);
|
|
669
|
-
return {
|
|
670
|
-
id: f.ID,
|
|
671
|
-
testRunID: f.TestRunID,
|
|
672
|
-
testName: testRun?.Test || 'Unknown Test',
|
|
673
|
-
rating: f.Rating || 0,
|
|
674
|
-
isCorrect: f.IsCorrect ?? true,
|
|
675
|
-
comments: f.CorrectionSummary || '',
|
|
676
|
-
reviewerName: f.ReviewerUser || 'Unknown',
|
|
677
|
-
reviewedAt: f.__mj_CreatedAt ? new Date(f.__mj_CreatedAt) : new Date(),
|
|
678
|
-
automatedScore: testRun?.Score || 0,
|
|
679
|
-
automatedStatus: testRun?.Status || 'Unknown'
|
|
680
|
-
};
|
|
681
|
-
});
|
|
682
|
-
}
|
|
683
|
-
loadSuiteAggregations() {
|
|
684
|
-
return combineLatest([
|
|
685
|
-
this.instrumentationService.dateRange$,
|
|
686
|
-
this.instrumentationService.isLoading$
|
|
687
|
-
]).pipe(switchMap(([dateRange]) => {
|
|
688
|
-
return new Observable(observer => {
|
|
689
|
-
this.loadSuiteAggregationsAsync(dateRange.start, dateRange.end).then(data => {
|
|
690
|
-
observer.next(data);
|
|
691
|
-
observer.complete();
|
|
692
|
-
}, error => observer.error(error));
|
|
693
|
-
});
|
|
694
|
-
}), shareReplay(1));
|
|
695
|
-
}
|
|
696
|
-
async loadSuiteAggregationsAsync(start, end) {
|
|
697
|
-
const rv = new RunView();
|
|
698
|
-
// Get all test suites
|
|
699
|
-
const suitesResult = await rv.RunView({
|
|
700
|
-
EntityName: 'MJ: Test Suites',
|
|
701
|
-
ExtraFilter: "Status = 'Active'",
|
|
702
|
-
ResultType: 'entity_object'
|
|
703
|
-
});
|
|
704
|
-
const suites = suitesResult.Results || [];
|
|
705
|
-
if (suites.length === 0)
|
|
706
|
-
return [];
|
|
707
|
-
// Get test runs in date range
|
|
708
|
-
const runsResult = await rv.RunView({
|
|
709
|
-
EntityName: 'MJ: Test Runs',
|
|
710
|
-
ExtraFilter: `StartedAt >= '${start.toISOString()}' AND StartedAt <= '${end.toISOString()}'`,
|
|
711
|
-
ResultType: 'entity_object'
|
|
712
|
-
});
|
|
713
|
-
const runs = runsResult.Results || [];
|
|
714
|
-
// Get feedback in date range
|
|
715
|
-
const feedbackResult = await rv.RunView({
|
|
716
|
-
EntityName: 'MJ: Test Run Feedbacks',
|
|
717
|
-
ExtraFilter: `__mj_CreatedAt >= '${start.toISOString()}'`,
|
|
718
|
-
ResultType: 'entity_object'
|
|
719
|
-
});
|
|
720
|
-
const feedbacks = feedbackResult.Results || [];
|
|
721
|
-
const feedbackMap = new Map();
|
|
722
|
-
feedbacks.forEach(f => feedbackMap.set(f.TestRunID, f));
|
|
723
|
-
// Aggregate by suite (simplified - would need TestSuiteTest join for accuracy)
|
|
724
|
-
const aggregations = suites.map(suite => {
|
|
725
|
-
// Filter runs by test suite (simplified)
|
|
726
|
-
const suiteRuns = runs; // In reality, need to join through TestSuiteTest
|
|
727
|
-
const totalRuns = suiteRuns.length;
|
|
728
|
-
const passedRuns = suiteRuns.filter(r => r.Status === 'Passed').length;
|
|
729
|
-
const reviewedRuns = suiteRuns.filter(r => feedbackMap.has(r.ID));
|
|
730
|
-
const reviewedCount = reviewedRuns.length;
|
|
731
|
-
const pendingCount = totalRuns - reviewedCount;
|
|
732
|
-
const ratings = reviewedRuns
|
|
733
|
-
.map(r => feedbackMap.get(r.ID)?.Rating || 0)
|
|
734
|
-
.filter(r => r > 0);
|
|
735
|
-
const avgRating = ratings.length > 0
|
|
736
|
-
? ratings.reduce((sum, r) => sum + r, 0) / ratings.length
|
|
737
|
-
: 0;
|
|
738
|
-
const correctCount = reviewedRuns
|
|
739
|
-
.filter(r => feedbackMap.get(r.ID)?.IsCorrect === true).length;
|
|
740
|
-
const agreementRate = reviewedCount > 0
|
|
741
|
-
? (correctCount / reviewedCount) * 100
|
|
742
|
-
: 0;
|
|
743
|
-
const passRate = totalRuns > 0 ? (passedRuns / totalRuns) * 100 : 0;
|
|
744
|
-
return {
|
|
745
|
-
suiteId: suite.ID,
|
|
746
|
-
suiteName: suite.Name,
|
|
747
|
-
totalRuns,
|
|
748
|
-
reviewedCount,
|
|
749
|
-
pendingCount,
|
|
750
|
-
avgRating,
|
|
751
|
-
agreementRate,
|
|
752
|
-
passRate
|
|
753
|
-
};
|
|
754
|
-
});
|
|
755
|
-
return aggregations.sort((a, b) => b.pendingCount - a.pendingCount);
|
|
756
|
-
}
|
|
757
|
-
filterAndSortPending(items) {
|
|
758
|
-
let filtered = [...items];
|
|
759
|
-
// Filter by reason
|
|
760
|
-
if (this.filters.reason !== 'all') {
|
|
761
|
-
filtered = filtered.filter(f => f.reason === this.filters.reason);
|
|
762
|
-
}
|
|
763
|
-
// Filter by search text
|
|
764
|
-
if (this.filters.searchText) {
|
|
765
|
-
const searchLower = this.filters.searchText.toLowerCase();
|
|
766
|
-
filtered = filtered.filter(f => f.testName.toLowerCase().includes(searchLower));
|
|
767
|
-
}
|
|
768
|
-
// Sort
|
|
769
|
-
filtered.sort((a, b) => {
|
|
770
|
-
if (this.sortBy === 'date') {
|
|
771
|
-
return b.runDateTime.getTime() - a.runDateTime.getTime();
|
|
772
|
-
}
|
|
773
|
-
else if (this.sortBy === 'priority') {
|
|
774
|
-
const priorityOrder = { 'high-score-failed': 1, 'low-score-passed': 2, 'no-feedback': 3 };
|
|
775
|
-
return (priorityOrder[a.reason] || 99) - (priorityOrder[b.reason] || 99);
|
|
776
|
-
}
|
|
777
|
-
else {
|
|
778
|
-
return a.testName.localeCompare(b.testName);
|
|
779
|
-
}
|
|
780
|
-
});
|
|
781
|
-
return filtered;
|
|
782
|
-
}
|
|
783
|
-
filterAndSortReviewed(items) {
|
|
784
|
-
let filtered = [...items];
|
|
785
|
-
// Filter by search text
|
|
786
|
-
if (this.filters.searchText) {
|
|
787
|
-
const searchLower = this.filters.searchText.toLowerCase();
|
|
788
|
-
filtered = filtered.filter(f => f.testName.toLowerCase().includes(searchLower) ||
|
|
789
|
-
f.reviewerName.toLowerCase().includes(searchLower));
|
|
790
|
-
}
|
|
791
|
-
// Sort
|
|
792
|
-
filtered.sort((a, b) => {
|
|
793
|
-
if (this.reviewedSortBy === 'date') {
|
|
794
|
-
return b.reviewedAt.getTime() - a.reviewedAt.getTime();
|
|
795
|
-
}
|
|
796
|
-
else if (this.reviewedSortBy === 'rating') {
|
|
797
|
-
return b.rating - a.rating;
|
|
798
|
-
}
|
|
799
|
-
else {
|
|
800
|
-
return a.testName.localeCompare(b.testName);
|
|
801
|
-
}
|
|
802
|
-
});
|
|
803
|
-
return filtered;
|
|
804
|
-
}
|
|
805
|
-
// Event handlers
|
|
806
|
-
setViewMode(mode) {
|
|
807
|
-
this.viewMode = mode;
|
|
808
|
-
this.expandedItem = null;
|
|
809
|
-
this.emitStateChange();
|
|
810
|
-
this.cdr.markForCheck();
|
|
811
|
-
}
|
|
812
|
-
onViewModeChange() {
|
|
813
|
-
this.expandedItem = null;
|
|
814
|
-
this.emitStateChange();
|
|
815
|
-
this.cdr.markForCheck();
|
|
816
|
-
}
|
|
817
|
-
onFilterChange() {
|
|
818
|
-
this.filterTrigger$.next();
|
|
819
|
-
this.emitStateChange();
|
|
820
|
-
this.cdr.markForCheck();
|
|
821
|
-
}
|
|
822
|
-
onSortChange() {
|
|
823
|
-
this.filterTrigger$.next();
|
|
824
|
-
this.emitStateChange();
|
|
825
|
-
this.cdr.markForCheck();
|
|
826
|
-
}
|
|
827
|
-
onReviewedSortChange() {
|
|
828
|
-
this.filterTrigger$.next();
|
|
829
|
-
this.cdr.markForCheck();
|
|
830
|
-
}
|
|
831
|
-
clearSearch() {
|
|
832
|
-
this.filters.searchText = '';
|
|
833
|
-
this.onFilterChange();
|
|
834
|
-
}
|
|
835
|
-
toggleExpanded(testRunID) {
|
|
836
|
-
this.expandedItem = this.expandedItem === testRunID ? null : testRunID;
|
|
837
|
-
}
|
|
838
|
-
setRating(item, rating) {
|
|
839
|
-
item.feedbackRating = rating;
|
|
840
|
-
}
|
|
841
|
-
setCorrectness(item, isCorrect) {
|
|
842
|
-
item.feedbackIsCorrect = isCorrect;
|
|
843
|
-
}
|
|
844
|
-
async submitFeedback(item) {
|
|
845
|
-
if (this.isSubmitting)
|
|
846
|
-
return;
|
|
847
|
-
this.isSubmitting = true;
|
|
848
|
-
this.cdr.markForCheck();
|
|
849
|
-
try {
|
|
850
|
-
const success = await this.instrumentationService.submitFeedback(item.testRunID, item.feedbackRating, item.feedbackIsCorrect, item.feedbackComments);
|
|
851
|
-
if (success) {
|
|
852
|
-
this.expandedItem = null;
|
|
853
|
-
// Refresh will happen via the service
|
|
854
|
-
}
|
|
855
|
-
else {
|
|
856
|
-
console.error('Failed to submit feedback');
|
|
857
|
-
}
|
|
858
|
-
}
|
|
859
|
-
catch (error) {
|
|
860
|
-
console.error('Error submitting feedback:', error);
|
|
861
|
-
}
|
|
862
|
-
finally {
|
|
863
|
-
this.isSubmitting = false;
|
|
864
|
-
this.cdr.markForCheck();
|
|
865
|
-
}
|
|
866
|
-
}
|
|
867
|
-
viewFullDetails(item) {
|
|
868
|
-
SharedService.Instance.OpenEntityRecord('MJ: Test Runs', CompositeKey.FromID(item.testRunID));
|
|
869
|
-
}
|
|
870
|
-
viewTestRun(testRunId) {
|
|
871
|
-
SharedService.Instance.OpenEntityRecord('MJ: Test Runs', CompositeKey.FromID(testRunId));
|
|
872
|
-
}
|
|
873
|
-
selectSuite(suiteId) {
|
|
874
|
-
this.filters.suiteId = suiteId;
|
|
875
|
-
this.viewMode = 'pending';
|
|
876
|
-
this.onFilterChange();
|
|
877
|
-
}
|
|
878
|
-
refresh() {
|
|
879
|
-
this.isRefreshing = true;
|
|
880
|
-
this.cdr.markForCheck();
|
|
881
|
-
this.instrumentationService.refresh();
|
|
882
|
-
setTimeout(() => {
|
|
883
|
-
this.isRefreshing = false;
|
|
884
|
-
this.cdr.markForCheck();
|
|
885
|
-
}, 1500);
|
|
886
|
-
}
|
|
887
|
-
formatReason(reason) {
|
|
888
|
-
switch (reason) {
|
|
889
|
-
case 'no-feedback': return 'No Feedback';
|
|
890
|
-
case 'high-score-failed': return 'High Score Failed';
|
|
891
|
-
case 'low-score-passed': return 'Low Score Passed';
|
|
892
|
-
default: return reason;
|
|
893
|
-
}
|
|
894
|
-
}
|
|
895
|
-
// Track by functions
|
|
896
|
-
trackByTestRunId(index, item) {
|
|
897
|
-
return item.testRunID;
|
|
898
|
-
}
|
|
899
|
-
trackByReviewedId(index, item) {
|
|
900
|
-
return item.id;
|
|
901
|
-
}
|
|
902
|
-
trackBySuiteId(index, item) {
|
|
903
|
-
return item.suiteId;
|
|
904
|
-
}
|
|
905
|
-
emitStateChange() {
|
|
906
|
-
this.stateChange.emit({
|
|
907
|
-
filters: this.filters,
|
|
908
|
-
viewMode: this.viewMode,
|
|
909
|
-
sortBy: this.sortBy
|
|
910
|
-
});
|
|
911
|
-
}
|
|
912
|
-
static ɵfac = function TestingFeedbackComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || TestingFeedbackComponent)(i0.ɵɵdirectiveInject(i1.TestingInstrumentationService), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
|
|
913
|
-
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: TestingFeedbackComponent, selectors: [["app-testing-feedback"]], inputs: { initialState: "initialState" }, outputs: { stateChange: "stateChange" }, decls: 107, vars: 54, consts: [["emptyPending", ""], ["emptyReviewed", ""], ["emptySuites", ""], [1, "testing-feedback"], [1, "feedback-header"], [1, "header-left"], [1, "fa-solid", "fa-clipboard-check"], ["class", "pending-badge", 4, "ngIf"], [1, "header-actions"], [1, "action-btn", "refresh-btn", 3, "click", "disabled"], [1, "fa-solid", "fa-refresh"], [1, "feedback-summary"], [1, "summary-card", "clickable", 3, "click"], [1, "summary-icon", "pending"], [1, "fa-solid", "fa-hourglass-half"], [1, "summary-content"], [1, "summary-value"], [1, "summary-label"], [1, "fa-solid", "fa-chevron-right", "summary-arrow"], [1, "summary-icon", "reviewed"], [1, "fa-solid", "fa-check-circle"], [1, "summary-icon", "suites"], [1, "fa-solid", "fa-layer-group"], [1, "summary-card"], [1, "summary-icon", "accuracy"], [1, "fa-solid", "fa-bullseye"], [1, "feedback-filters"], [1, "filter-group"], [3, "ngModelChange", "change", "ngModel"], ["value", "pending"], ["value", "reviewed"], ["value", "suites"], ["class", "filter-group", 4, "ngIf"], [1, "filter-group", "search"], [1, "search-input-wrapper"], [1, "fa-solid", "fa-search"], ["type", "text", "placeholder", "Search tests...", 3, "ngModelChange", "input", "ngModel"], ["class", "clear-btn", 3, "click", 4, "ngIf"], ["class", "feedback-content", 4, "ngIf"], [1, "feedback-stats"], [1, "fa-solid", "fa-chart-pie"], [1, "stats-grid"], [1, "stat-card"], [1, "stat-label"], [1, "stat-value"], [1, "pending-badge"], ["class", "badge-count", 4, "ngIf"], [1, "badge-text"], [1, "badge-count"], ["value", "all"], ["value", "no-feedback"], ["value", "high-score-failed"], ["value", "low-score-passed"], [3, "ngValue"], [3, "ngValue", 4, "ngFor", "ngForOf"], [1, "clear-btn", 3, "click"], [1, "fa-solid", "fa-times"], [1, "feedback-content"], [1, "content-header"], [1, "fa-solid", "fa-list-check"], [1, "sort-controls"], ["value", "date"], ["value", "priority"], ["value", "test-name"], ["class", "feedback-list", 4, "ngIf"], [1, "feedback-list"], [4, "ngIf", "ngIfElse"], ["class", "feedback-item", 3, "expanded", 4, "ngFor", "ngForOf", "ngForTrackBy"], [1, "feedback-item"], [1, "item-header", 3, "click"], [1, "item-main"], [1, "item-title"], [1, "item-meta"], [1, "meta-date"], [1, "fa-solid", "fa-clock"], [1, "meta-score"], [1, "meta-status"], [1, "item-reason"], [1, "reason-badge"], [1, "fa-solid"], [1, "expand-btn"], ["class", "item-content", 4, "ngIf"], [1, "item-content"], [1, "feedback-form"], [1, "form-section"], [1, "rating-section"], [1, "rating-stars-input"], ["class", "star-btn", 3, "filled", "click", 4, "ngFor", "ngForOf"], [1, "rating-display"], [1, "correctness-section"], [1, "correctness-buttons"], [1, "correctness-btn", "correct", 3, "click"], [1, "fa-solid", "fa-check"], [1, "correctness-btn", "incorrect", 3, "click"], [1, "form-group"], ["rows", "3", "placeholder", "Explain your assessment or provide correction notes...", 1, "comments-textarea", 3, "ngModelChange", "ngModel"], [1, "form-actions"], [1, "submit-btn", 3, "click", "disabled"], [1, "fa-solid", "fa-paper-plane"], [1, "view-btn", 3, "click"], [1, "fa-solid", "fa-external-link"], [1, "star-btn", 3, "click"], [1, "fa-solid", "fa-star"], [1, "empty-state", "success"], [1, "fa-solid", "fa-check-double"], [1, "fa-solid", "fa-history"], ["value", "rating"], ["class", "reviewed-item", 4, "ngFor", "ngForOf", "ngForTrackBy"], [1, "reviewed-item"], [1, "reviewed-header"], [1, "reviewed-main"], [1, "reviewed-title"], [1, "reviewed-meta"], [1, "meta-reviewer"], [1, "fa-solid", "fa-user"], [1, "fa-solid", "fa-calendar"], [1, "reviewed-rating"], [1, "rating-stars"], ["class", "fa-solid fa-star", 3, "filled", 4, "ngFor", "ngForOf"], [1, "rating-text"], [1, "reviewed-verdict"], [1, "verdict-badge"], [1, "view-btn-small", 3, "click"], ["class", "reviewed-comments", 4, "ngIf"], [1, "reviewed-comments"], [1, "empty-state"], [1, "fa-solid", "fa-clipboard"], ["class", "suites-list", 4, "ngIf"], [1, "suites-list"], ["class", "suite-card", 3, "click", 4, "ngFor", "ngForOf", "ngForTrackBy"], [1, "suite-card", 3, "click"], [1, "suite-header"], [1, "suite-icon"], [1, "suite-info"], [1, "suite-meta"], [1, "suite-stats"], [1, "suite-stat"], [1, "stat-value", "pending"], [1, "stat-value", "reviewed"], [1, "fa-solid", "fa-chevron-right", "suite-arrow"]], template: function TestingFeedbackComponent_Template(rf, ctx) { if (rf & 1) {
|
|
914
|
-
i0.ɵɵelementStart(0, "div", 3)(1, "div", 4)(2, "div", 5)(3, "h2");
|
|
915
|
-
i0.ɵɵelement(4, "i", 6);
|
|
916
|
-
i0.ɵɵtext(5, " Human Feedback Review ");
|
|
917
|
-
i0.ɵɵelementEnd();
|
|
918
|
-
i0.ɵɵtemplate(6, TestingFeedbackComponent_div_6_Template, 4, 2, "div", 7);
|
|
919
|
-
i0.ɵɵpipe(7, "async");
|
|
920
|
-
i0.ɵɵelementEnd();
|
|
921
|
-
i0.ɵɵelementStart(8, "div", 8)(9, "button", 9);
|
|
922
|
-
i0.ɵɵlistener("click", function TestingFeedbackComponent_Template_button_click_9_listener() { return ctx.refresh(); });
|
|
923
|
-
i0.ɵɵelement(10, "i", 10);
|
|
924
|
-
i0.ɵɵtext(11);
|
|
925
|
-
i0.ɵɵelementEnd()()();
|
|
926
|
-
i0.ɵɵelementStart(12, "div", 11)(13, "div", 12);
|
|
927
|
-
i0.ɵɵlistener("click", function TestingFeedbackComponent_Template_div_click_13_listener() { return ctx.setViewMode("pending"); });
|
|
928
|
-
i0.ɵɵelementStart(14, "div", 13);
|
|
929
|
-
i0.ɵɵelement(15, "i", 14);
|
|
930
|
-
i0.ɵɵelementEnd();
|
|
931
|
-
i0.ɵɵelementStart(16, "div", 15)(17, "div", 16);
|
|
932
|
-
i0.ɵɵtext(18);
|
|
933
|
-
i0.ɵɵpipe(19, "async");
|
|
934
|
-
i0.ɵɵelementEnd();
|
|
935
|
-
i0.ɵɵelementStart(20, "div", 17);
|
|
936
|
-
i0.ɵɵtext(21, "Pending Review");
|
|
937
|
-
i0.ɵɵelementEnd()();
|
|
938
|
-
i0.ɵɵelement(22, "i", 18);
|
|
939
|
-
i0.ɵɵelementEnd();
|
|
940
|
-
i0.ɵɵelementStart(23, "div", 12);
|
|
941
|
-
i0.ɵɵlistener("click", function TestingFeedbackComponent_Template_div_click_23_listener() { return ctx.setViewMode("reviewed"); });
|
|
942
|
-
i0.ɵɵelementStart(24, "div", 19);
|
|
943
|
-
i0.ɵɵelement(25, "i", 20);
|
|
944
|
-
i0.ɵɵelementEnd();
|
|
945
|
-
i0.ɵɵelementStart(26, "div", 15)(27, "div", 16);
|
|
946
|
-
i0.ɵɵtext(28);
|
|
947
|
-
i0.ɵɵpipe(29, "async");
|
|
948
|
-
i0.ɵɵelementEnd();
|
|
949
|
-
i0.ɵɵelementStart(30, "div", 17);
|
|
950
|
-
i0.ɵɵtext(31, "Reviewed");
|
|
951
|
-
i0.ɵɵelementEnd()();
|
|
952
|
-
i0.ɵɵelement(32, "i", 18);
|
|
953
|
-
i0.ɵɵelementEnd();
|
|
954
|
-
i0.ɵɵelementStart(33, "div", 12);
|
|
955
|
-
i0.ɵɵlistener("click", function TestingFeedbackComponent_Template_div_click_33_listener() { return ctx.setViewMode("suites"); });
|
|
956
|
-
i0.ɵɵelementStart(34, "div", 21);
|
|
957
|
-
i0.ɵɵelement(35, "i", 22);
|
|
958
|
-
i0.ɵɵelementEnd();
|
|
959
|
-
i0.ɵɵelementStart(36, "div", 15)(37, "div", 16);
|
|
960
|
-
i0.ɵɵtext(38);
|
|
961
|
-
i0.ɵɵpipe(39, "async");
|
|
962
|
-
i0.ɵɵelementEnd();
|
|
963
|
-
i0.ɵɵelementStart(40, "div", 17);
|
|
964
|
-
i0.ɵɵtext(41, "Test Suites");
|
|
965
|
-
i0.ɵɵelementEnd()();
|
|
966
|
-
i0.ɵɵelement(42, "i", 18);
|
|
967
|
-
i0.ɵɵelementEnd();
|
|
968
|
-
i0.ɵɵelementStart(43, "div", 23)(44, "div", 24);
|
|
969
|
-
i0.ɵɵelement(45, "i", 25);
|
|
970
|
-
i0.ɵɵelementEnd();
|
|
971
|
-
i0.ɵɵelementStart(46, "div", 15)(47, "div", 16);
|
|
972
|
-
i0.ɵɵtext(48);
|
|
973
|
-
i0.ɵɵpipe(49, "async");
|
|
974
|
-
i0.ɵɵpipe(50, "number");
|
|
975
|
-
i0.ɵɵelementEnd();
|
|
976
|
-
i0.ɵɵelementStart(51, "div", 17);
|
|
977
|
-
i0.ɵɵtext(52, "Human-AI Agreement");
|
|
978
|
-
i0.ɵɵelementEnd()()()();
|
|
979
|
-
i0.ɵɵelementStart(53, "div", 26)(54, "div", 27)(55, "label");
|
|
980
|
-
i0.ɵɵtext(56, "View");
|
|
981
|
-
i0.ɵɵelementEnd();
|
|
982
|
-
i0.ɵɵelementStart(57, "select", 28);
|
|
983
|
-
i0.ɵɵtwoWayListener("ngModelChange", function TestingFeedbackComponent_Template_select_ngModelChange_57_listener($event) { i0.ɵɵtwoWayBindingSet(ctx.viewMode, $event) || (ctx.viewMode = $event); return $event; });
|
|
984
|
-
i0.ɵɵlistener("change", function TestingFeedbackComponent_Template_select_change_57_listener() { return ctx.onViewModeChange(); });
|
|
985
|
-
i0.ɵɵelementStart(58, "option", 29);
|
|
986
|
-
i0.ɵɵtext(59, "Pending Reviews");
|
|
987
|
-
i0.ɵɵelementEnd();
|
|
988
|
-
i0.ɵɵelementStart(60, "option", 30);
|
|
989
|
-
i0.ɵɵtext(61, "Reviewed Feedback");
|
|
990
|
-
i0.ɵɵelementEnd();
|
|
991
|
-
i0.ɵɵelementStart(62, "option", 31);
|
|
992
|
-
i0.ɵɵtext(63, "By Test Suite");
|
|
993
|
-
i0.ɵɵelementEnd()()();
|
|
994
|
-
i0.ɵɵtemplate(64, TestingFeedbackComponent_div_64_Template, 12, 1, "div", 32)(65, TestingFeedbackComponent_div_65_Template, 8, 5, "div", 32);
|
|
995
|
-
i0.ɵɵelementStart(66, "div", 33)(67, "label");
|
|
996
|
-
i0.ɵɵtext(68, "Search");
|
|
997
|
-
i0.ɵɵelementEnd();
|
|
998
|
-
i0.ɵɵelementStart(69, "div", 34);
|
|
999
|
-
i0.ɵɵelement(70, "i", 35);
|
|
1000
|
-
i0.ɵɵelementStart(71, "input", 36);
|
|
1001
|
-
i0.ɵɵtwoWayListener("ngModelChange", function TestingFeedbackComponent_Template_input_ngModelChange_71_listener($event) { i0.ɵɵtwoWayBindingSet(ctx.filters.searchText, $event) || (ctx.filters.searchText = $event); return $event; });
|
|
1002
|
-
i0.ɵɵlistener("input", function TestingFeedbackComponent_Template_input_input_71_listener() { return ctx.onFilterChange(); });
|
|
1003
|
-
i0.ɵɵelementEnd();
|
|
1004
|
-
i0.ɵɵtemplate(72, TestingFeedbackComponent_button_72_Template, 2, 0, "button", 37);
|
|
1005
|
-
i0.ɵɵelementEnd()()();
|
|
1006
|
-
i0.ɵɵtemplate(73, TestingFeedbackComponent_div_73_Template, 17, 4, "div", 38)(74, TestingFeedbackComponent_div_74_Template, 17, 4, "div", 38)(75, TestingFeedbackComponent_div_75_Template, 7, 3, "div", 38);
|
|
1007
|
-
i0.ɵɵelementStart(76, "div", 39)(77, "h3");
|
|
1008
|
-
i0.ɵɵelement(78, "i", 40);
|
|
1009
|
-
i0.ɵɵtext(79, " Feedback Statistics ");
|
|
1010
|
-
i0.ɵɵelementEnd();
|
|
1011
|
-
i0.ɵɵelementStart(80, "div", 41)(81, "div", 42)(82, "div", 43);
|
|
1012
|
-
i0.ɵɵtext(83, "Total Feedback");
|
|
1013
|
-
i0.ɵɵelementEnd();
|
|
1014
|
-
i0.ɵɵelementStart(84, "div", 44);
|
|
1015
|
-
i0.ɵɵtext(85);
|
|
1016
|
-
i0.ɵɵpipe(86, "async");
|
|
1017
|
-
i0.ɵɵelementEnd()();
|
|
1018
|
-
i0.ɵɵelementStart(87, "div", 42)(88, "div", 43);
|
|
1019
|
-
i0.ɵɵtext(89, "Avg Rating");
|
|
1020
|
-
i0.ɵɵelementEnd();
|
|
1021
|
-
i0.ɵɵelementStart(90, "div", 44);
|
|
1022
|
-
i0.ɵɵtext(91);
|
|
1023
|
-
i0.ɵɵpipe(92, "async");
|
|
1024
|
-
i0.ɵɵpipe(93, "number");
|
|
1025
|
-
i0.ɵɵelementEnd()();
|
|
1026
|
-
i0.ɵɵelementStart(94, "div", 42)(95, "div", 43);
|
|
1027
|
-
i0.ɵɵtext(96, "Agreement Rate");
|
|
1028
|
-
i0.ɵɵelementEnd();
|
|
1029
|
-
i0.ɵɵelementStart(97, "div", 44);
|
|
1030
|
-
i0.ɵɵtext(98);
|
|
1031
|
-
i0.ɵɵpipe(99, "async");
|
|
1032
|
-
i0.ɵɵpipe(100, "number");
|
|
1033
|
-
i0.ɵɵelementEnd()();
|
|
1034
|
-
i0.ɵɵelementStart(101, "div", 42)(102, "div", 43);
|
|
1035
|
-
i0.ɵɵtext(103, "Discrepancy Count");
|
|
1036
|
-
i0.ɵɵelementEnd();
|
|
1037
|
-
i0.ɵɵelementStart(104, "div", 44);
|
|
1038
|
-
i0.ɵɵtext(105);
|
|
1039
|
-
i0.ɵɵpipe(106, "async");
|
|
1040
|
-
i0.ɵɵelementEnd()()()()();
|
|
1041
|
-
} if (rf & 2) {
|
|
1042
|
-
let tmp_5_0;
|
|
1043
|
-
let tmp_7_0;
|
|
1044
|
-
let tmp_9_0;
|
|
1045
|
-
let tmp_10_0;
|
|
1046
|
-
let tmp_19_0;
|
|
1047
|
-
let tmp_20_0;
|
|
1048
|
-
let tmp_21_0;
|
|
1049
|
-
let tmp_22_0;
|
|
1050
|
-
i0.ɵɵadvance(6);
|
|
1051
|
-
i0.ɵɵproperty("ngIf", i0.ɵɵpipeBind1(7, 27, ctx.pendingCount$));
|
|
1052
|
-
i0.ɵɵadvance(3);
|
|
1053
|
-
i0.ɵɵproperty("disabled", ctx.isRefreshing);
|
|
1054
|
-
i0.ɵɵadvance();
|
|
1055
|
-
i0.ɵɵclassProp("fa-spin", ctx.isRefreshing);
|
|
1056
|
-
i0.ɵɵadvance();
|
|
1057
|
-
i0.ɵɵtextInterpolate1(" ", ctx.isRefreshing ? "Refreshing..." : "Refresh", " ");
|
|
1058
|
-
i0.ɵɵadvance(2);
|
|
1059
|
-
i0.ɵɵclassProp("active", ctx.viewMode === "pending");
|
|
1060
|
-
i0.ɵɵadvance(5);
|
|
1061
|
-
i0.ɵɵtextInterpolate((tmp_5_0 = i0.ɵɵpipeBind1(19, 29, ctx.pendingCount$)) !== null && tmp_5_0 !== undefined ? tmp_5_0 : 0);
|
|
1062
|
-
i0.ɵɵadvance(5);
|
|
1063
|
-
i0.ɵɵclassProp("active", ctx.viewMode === "reviewed");
|
|
1064
|
-
i0.ɵɵadvance(5);
|
|
1065
|
-
i0.ɵɵtextInterpolate((tmp_7_0 = i0.ɵɵpipeBind1(29, 31, ctx.reviewedCount$)) !== null && tmp_7_0 !== undefined ? tmp_7_0 : 0);
|
|
1066
|
-
i0.ɵɵadvance(5);
|
|
1067
|
-
i0.ɵɵclassProp("active", ctx.viewMode === "suites");
|
|
1068
|
-
i0.ɵɵadvance(5);
|
|
1069
|
-
i0.ɵɵtextInterpolate((tmp_9_0 = i0.ɵɵpipeBind1(39, 33, ctx.suiteCount$)) !== null && tmp_9_0 !== undefined ? tmp_9_0 : 0);
|
|
1070
|
-
i0.ɵɵadvance(10);
|
|
1071
|
-
i0.ɵɵtextInterpolate1("", i0.ɵɵpipeBind2(50, 37, (tmp_10_0 = i0.ɵɵpipeBind1(49, 35, ctx.accuracyRate$)) !== null && tmp_10_0 !== undefined ? tmp_10_0 : 0, "1.1-1"), "%");
|
|
1072
|
-
i0.ɵɵadvance(9);
|
|
1073
|
-
i0.ɵɵtwoWayProperty("ngModel", ctx.viewMode);
|
|
1074
|
-
i0.ɵɵadvance(7);
|
|
1075
|
-
i0.ɵɵproperty("ngIf", ctx.viewMode === "pending");
|
|
1076
|
-
i0.ɵɵadvance();
|
|
1077
|
-
i0.ɵɵproperty("ngIf", ctx.viewMode !== "suites");
|
|
1078
|
-
i0.ɵɵadvance(6);
|
|
1079
|
-
i0.ɵɵtwoWayProperty("ngModel", ctx.filters.searchText);
|
|
1080
|
-
i0.ɵɵadvance();
|
|
1081
|
-
i0.ɵɵproperty("ngIf", ctx.filters.searchText);
|
|
1082
|
-
i0.ɵɵadvance();
|
|
1083
|
-
i0.ɵɵproperty("ngIf", ctx.viewMode === "pending");
|
|
1084
|
-
i0.ɵɵadvance();
|
|
1085
|
-
i0.ɵɵproperty("ngIf", ctx.viewMode === "reviewed");
|
|
1086
|
-
i0.ɵɵadvance();
|
|
1087
|
-
i0.ɵɵproperty("ngIf", ctx.viewMode === "suites");
|
|
1088
|
-
i0.ɵɵadvance(10);
|
|
1089
|
-
i0.ɵɵtextInterpolate((tmp_19_0 = i0.ɵɵpipeBind1(86, 40, ctx.totalFeedback$)) !== null && tmp_19_0 !== undefined ? tmp_19_0 : 0);
|
|
1090
|
-
i0.ɵɵadvance(6);
|
|
1091
|
-
i0.ɵɵtextInterpolate1("", i0.ɵɵpipeBind2(93, 44, (tmp_20_0 = i0.ɵɵpipeBind1(92, 42, ctx.avgRating$)) !== null && tmp_20_0 !== undefined ? tmp_20_0 : 0, "1.1-1"), "/10");
|
|
1092
|
-
i0.ɵɵadvance(7);
|
|
1093
|
-
i0.ɵɵtextInterpolate1("", i0.ɵɵpipeBind2(100, 49, (tmp_21_0 = i0.ɵɵpipeBind1(99, 47, ctx.agreementRate$)) !== null && tmp_21_0 !== undefined ? tmp_21_0 : 0, "1.1-1"), "%");
|
|
1094
|
-
i0.ɵɵadvance(7);
|
|
1095
|
-
i0.ɵɵtextInterpolate((tmp_22_0 = i0.ɵɵpipeBind1(106, 52, ctx.discrepancyCount$)) !== null && tmp_22_0 !== undefined ? tmp_22_0 : 0);
|
|
1096
|
-
} }, dependencies: [i2.NgForOf, i2.NgIf, i3.NgSelectOption, i3.ɵNgSelectMultipleOption, i3.DefaultValueAccessor, i3.SelectControlValueAccessor, i3.NgControlStatus, i3.NgModel, i2.AsyncPipe, i2.DecimalPipe, i2.DatePipe], styles: ["[_nghost-%COMP%] {\n display: block;\n height: 100%;\n }\n\n .testing-feedback[_ngcontent-%COMP%] {\n padding: 20px;\n height: 100%;\n overflow-y: auto;\n background: #f8f9fa;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n }\n\n \n\n .feedback-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 20px;\n background: white;\n padding: 20px;\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n }\n\n .header-left[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 16px;\n }\n\n .header-left[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 22px;\n font-weight: 700;\n color: #1e293b;\n display: flex;\n align-items: center;\n gap: 12px;\n }\n\n .header-left[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #3b82f6;\n }\n\n .pending-badge[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 14px;\n background: linear-gradient(135deg, #fff7ed 0%, #ffedd5 100%);\n border: 1px solid #fb923c;\n border-radius: 20px;\n }\n\n .badge-count[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #f97316 0%, #ea580c 100%);\n color: white;\n min-width: 24px;\n height: 24px;\n padding: 0 6px;\n border-radius: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n font-weight: 700;\n }\n\n .badge-text[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 600;\n color: #ea580c;\n }\n\n .action-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 18px;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n background: white;\n color: #64748b;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s ease;\n }\n\n .action-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #f8fafc;\n border-color: #cbd5e1;\n }\n\n .action-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n \n\n .feedback-summary[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 16px;\n margin-bottom: 20px;\n }\n\n .summary-card[_ngcontent-%COMP%] {\n background: white;\n padding: 20px;\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n display: flex;\n align-items: center;\n gap: 16px;\n transition: all 0.2s ease;\n position: relative;\n }\n\n .summary-card.clickable[_ngcontent-%COMP%] {\n cursor: pointer;\n }\n\n .summary-card.clickable[_ngcontent-%COMP%]:hover {\n transform: translateY(-2px);\n box-shadow: 0 6px 20px rgba(0, 0, 0, 0.12);\n }\n\n .summary-card.active[_ngcontent-%COMP%] {\n border: 2px solid #3b82f6;\n background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);\n }\n\n .summary-icon[_ngcontent-%COMP%] {\n width: 52px;\n height: 52px;\n border-radius: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 22px;\n color: white;\n flex-shrink: 0;\n }\n\n .summary-icon.pending[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #f97316 0%, #ea580c 100%);\n }\n\n .summary-icon.reviewed[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #22c55e 0%, #16a34a 100%);\n }\n\n .summary-icon.suites[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #8b5cf6 0%, #7c3aed 100%);\n }\n\n .summary-icon.accuracy[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);\n }\n\n .summary-content[_ngcontent-%COMP%] {\n flex: 1;\n }\n\n .summary-value[_ngcontent-%COMP%] {\n font-size: 28px;\n font-weight: 700;\n color: #1e293b;\n line-height: 1;\n margin-bottom: 4px;\n }\n\n .summary-label[_ngcontent-%COMP%] {\n font-size: 11px;\n color: #64748b;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n }\n\n .summary-arrow[_ngcontent-%COMP%] {\n color: #94a3b8;\n font-size: 14px;\n }\n\n \n\n .feedback-filters[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n margin-bottom: 20px;\n background: white;\n padding: 16px 20px;\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n flex-wrap: wrap;\n }\n\n .filter-group[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n min-width: 140px;\n }\n\n .filter-group.search[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 200px;\n }\n\n .filter-group[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n font-size: 10px;\n font-weight: 700;\n color: #64748b;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n }\n\n .filter-group[_ngcontent-%COMP%] select[_ngcontent-%COMP%] {\n padding: 10px 12px;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n font-size: 13px;\n background: white;\n color: #1e293b;\n cursor: pointer;\n }\n\n .filter-group[_ngcontent-%COMP%] select[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: #3b82f6;\n box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);\n }\n\n .search-input-wrapper[_ngcontent-%COMP%] {\n position: relative;\n display: flex;\n align-items: center;\n }\n\n .search-input-wrapper[_ngcontent-%COMP%] > i[_ngcontent-%COMP%] {\n position: absolute;\n left: 12px;\n color: #94a3b8;\n font-size: 13px;\n }\n\n .search-input-wrapper[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n flex: 1;\n padding: 10px 40px 10px 36px;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n font-size: 13px;\n }\n\n .search-input-wrapper[_ngcontent-%COMP%] input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: #3b82f6;\n box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);\n }\n\n .clear-btn[_ngcontent-%COMP%] {\n position: absolute;\n right: 8px;\n background: none;\n border: none;\n color: #94a3b8;\n cursor: pointer;\n padding: 6px;\n border-radius: 4px;\n }\n\n .clear-btn[_ngcontent-%COMP%]:hover {\n color: #64748b;\n background: #f1f5f9;\n }\n\n \n\n .feedback-content[_ngcontent-%COMP%] {\n background: white;\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n overflow: hidden;\n margin-bottom: 20px;\n }\n\n .content-header[_ngcontent-%COMP%] {\n padding: 20px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border-bottom: 1px solid #e2e8f0;\n display: flex;\n justify-content: space-between;\n align-items: center;\n }\n\n .content-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: #1e293b;\n display: flex;\n align-items: center;\n gap: 10px;\n }\n\n .content-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #3b82f6;\n }\n\n .sort-controls[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n color: #64748b;\n }\n\n .sort-controls[_ngcontent-%COMP%] select[_ngcontent-%COMP%] {\n padding: 6px 10px;\n border: 1px solid #e2e8f0;\n border-radius: 6px;\n font-size: 12px;\n background: white;\n }\n\n \n\n .feedback-list[_ngcontent-%COMP%] {\n max-height: 600px;\n overflow-y: auto;\n }\n\n .feedback-item[_ngcontent-%COMP%] {\n border-bottom: 1px solid #f1f5f9;\n transition: all 0.2s ease;\n }\n\n .feedback-item.expanded[_ngcontent-%COMP%] {\n background: #f8fafc;\n }\n\n .item-header[_ngcontent-%COMP%] {\n padding: 16px 20px;\n display: flex;\n align-items: center;\n gap: 16px;\n cursor: pointer;\n transition: background 0.2s ease;\n }\n\n .item-header[_ngcontent-%COMP%]:hover {\n background: rgba(59, 130, 246, 0.04);\n }\n\n .item-main[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n }\n\n .item-title[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: #1e293b;\n margin-bottom: 6px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .item-meta[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n font-size: 12px;\n color: #64748b;\n flex-wrap: wrap;\n }\n\n .item-meta[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 5px;\n }\n\n .meta-status[_ngcontent-%COMP%] {\n padding: 2px 8px;\n border-radius: 4px;\n font-weight: 600;\n font-size: 11px;\n }\n\n .meta-status.status-passed[_ngcontent-%COMP%] { background: #dcfce7; color: #16a34a; }\n .meta-status.status-failed[_ngcontent-%COMP%] { background: #fee2e2; color: #dc2626; }\n .meta-status.status-error[_ngcontent-%COMP%] { background: #fef3c7; color: #d97706; }\n .meta-status.status-running[_ngcontent-%COMP%] { background: #dbeafe; color: #2563eb; }\n\n .item-reason[_ngcontent-%COMP%] {\n flex-shrink: 0;\n }\n\n .reason-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n border-radius: 16px;\n font-size: 11px;\n font-weight: 600;\n }\n\n .reason-badge.no-feedback[_ngcontent-%COMP%] {\n background: #dbeafe;\n color: #2563eb;\n }\n\n .reason-badge.high-score-failed[_ngcontent-%COMP%] {\n background: #fee2e2;\n color: #dc2626;\n }\n\n .reason-badge.low-score-passed[_ngcontent-%COMP%] {\n background: #fef3c7;\n color: #d97706;\n }\n\n .expand-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n color: #94a3b8;\n cursor: pointer;\n padding: 8px;\n border-radius: 6px;\n transition: all 0.2s ease;\n font-size: 14px;\n }\n\n .expand-btn[_ngcontent-%COMP%]:hover {\n background: #e2e8f0;\n color: #64748b;\n }\n\n \n\n .item-content[_ngcontent-%COMP%] {\n padding: 20px;\n border-top: 1px solid #e2e8f0;\n background: white;\n }\n\n .feedback-form[_ngcontent-%COMP%] {\n max-width: 600px;\n }\n\n .form-section[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0 0 20px 0;\n font-size: 15px;\n font-weight: 600;\n color: #1e293b;\n }\n\n .rating-section[_ngcontent-%COMP%], \n .correctness-section[_ngcontent-%COMP%] {\n margin-bottom: 20px;\n }\n\n .rating-section[_ngcontent-%COMP%] label[_ngcontent-%COMP%], \n .correctness-section[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n display: block;\n font-size: 12px;\n font-weight: 600;\n color: #64748b;\n margin-bottom: 10px;\n }\n\n .rating-stars-input[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n }\n\n .star-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n font-size: 22px;\n color: #e2e8f0;\n cursor: pointer;\n padding: 2px;\n transition: all 0.15s ease;\n }\n\n .star-btn[_ngcontent-%COMP%]:hover {\n transform: scale(1.2);\n }\n\n .star-btn.filled[_ngcontent-%COMP%] {\n color: #f59e0b;\n }\n\n .rating-display[_ngcontent-%COMP%] {\n margin-left: 12px;\n font-size: 16px;\n font-weight: 700;\n color: #1e293b;\n }\n\n .correctness-buttons[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n }\n\n .correctness-btn[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 12px 20px;\n border: 2px solid #e2e8f0;\n border-radius: 10px;\n background: white;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s ease;\n }\n\n .correctness-btn.correct[_ngcontent-%COMP%]:hover, \n .correctness-btn.correct.active[_ngcontent-%COMP%] {\n border-color: #22c55e;\n background: #f0fdf4;\n color: #16a34a;\n }\n\n .correctness-btn.incorrect[_ngcontent-%COMP%]:hover, \n .correctness-btn.incorrect.active[_ngcontent-%COMP%] {\n border-color: #ef4444;\n background: #fef2f2;\n color: #dc2626;\n }\n\n .form-group[_ngcontent-%COMP%] {\n margin-bottom: 16px;\n }\n\n .form-group[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n display: block;\n font-size: 12px;\n font-weight: 600;\n color: #64748b;\n margin-bottom: 8px;\n }\n\n .comments-textarea[_ngcontent-%COMP%] {\n width: 100%;\n padding: 12px;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n font-size: 14px;\n font-family: inherit;\n resize: vertical;\n min-height: 80px;\n }\n\n .comments-textarea[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: #3b82f6;\n box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);\n }\n\n .form-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n margin-top: 20px;\n }\n\n .submit-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 24px;\n border: none;\n border-radius: 8px;\n background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);\n color: white;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s ease;\n }\n\n .submit-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(37, 99, 235, 0.3);\n }\n\n .submit-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n .view-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 20px;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n background: white;\n color: #64748b;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s ease;\n }\n\n .view-btn[_ngcontent-%COMP%]:hover {\n border-color: #cbd5e1;\n background: #f8fafc;\n }\n\n \n\n .reviewed-item[_ngcontent-%COMP%] {\n padding: 16px 20px;\n border-bottom: 1px solid #f1f5f9;\n }\n\n .reviewed-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 16px;\n }\n\n .reviewed-main[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n }\n\n .reviewed-title[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: #1e293b;\n margin-bottom: 4px;\n }\n\n .reviewed-meta[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n font-size: 12px;\n color: #64748b;\n }\n\n .reviewed-meta[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 5px;\n }\n\n .reviewed-rating[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n }\n\n .rating-stars[_ngcontent-%COMP%] {\n display: flex;\n gap: 2px;\n }\n\n .rating-stars[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n color: #e2e8f0;\n }\n\n .rating-stars[_ngcontent-%COMP%] i.filled[_ngcontent-%COMP%] {\n color: #f59e0b;\n }\n\n .rating-text[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 600;\n color: #64748b;\n }\n\n .reviewed-verdict[_ngcontent-%COMP%] {\n flex-shrink: 0;\n }\n\n .verdict-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n border-radius: 16px;\n font-size: 11px;\n font-weight: 600;\n }\n\n .verdict-badge.correct[_ngcontent-%COMP%] {\n background: #dcfce7;\n color: #16a34a;\n }\n\n .verdict-badge.incorrect[_ngcontent-%COMP%] {\n background: #fee2e2;\n color: #dc2626;\n }\n\n .view-btn-small[_ngcontent-%COMP%] {\n background: none;\n border: 1px solid #e2e8f0;\n border-radius: 6px;\n padding: 8px;\n color: #64748b;\n cursor: pointer;\n transition: all 0.2s ease;\n }\n\n .view-btn-small[_ngcontent-%COMP%]:hover {\n background: #f8fafc;\n border-color: #cbd5e1;\n }\n\n .reviewed-comments[_ngcontent-%COMP%] {\n margin-top: 12px;\n padding: 12px;\n background: #f8fafc;\n border-radius: 8px;\n border-left: 3px solid #3b82f6;\n }\n\n .reviewed-comments[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 13px;\n color: #475569;\n line-height: 1.5;\n }\n\n \n\n .suites-list[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .suite-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 16px;\n padding: 20px;\n background: #f8fafc;\n border: 1px solid #e2e8f0;\n border-radius: 12px;\n cursor: pointer;\n transition: all 0.2s ease;\n margin-bottom: 12px;\n }\n\n .suite-card[_ngcontent-%COMP%]:hover {\n border-color: #3b82f6;\n background: white;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);\n }\n\n .suite-card[_ngcontent-%COMP%]:last-child {\n margin-bottom: 0;\n }\n\n .suite-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 14px;\n flex: 1;\n min-width: 0;\n }\n\n .suite-icon[_ngcontent-%COMP%] {\n width: 44px;\n height: 44px;\n border-radius: 10px;\n background: linear-gradient(135deg, #8b5cf6 0%, #7c3aed 100%);\n display: flex;\n align-items: center;\n justify-content: center;\n color: white;\n font-size: 18px;\n flex-shrink: 0;\n }\n\n .suite-info[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0 0 4px 0;\n font-size: 15px;\n font-weight: 600;\n color: #1e293b;\n }\n\n .suite-meta[_ngcontent-%COMP%] {\n font-size: 12px;\n color: #64748b;\n }\n\n .suite-stats[_ngcontent-%COMP%] {\n display: flex;\n gap: 20px;\n }\n\n .suite-stat[_ngcontent-%COMP%] {\n text-align: center;\n min-width: 60px;\n }\n\n .suite-stat[_ngcontent-%COMP%] .stat-value[_ngcontent-%COMP%] {\n font-size: 18px;\n font-weight: 700;\n color: #1e293b;\n }\n\n .suite-stat[_ngcontent-%COMP%] .stat-value.pending[_ngcontent-%COMP%] {\n color: #f97316;\n }\n\n .suite-stat[_ngcontent-%COMP%] .stat-value.reviewed[_ngcontent-%COMP%] {\n color: #22c55e;\n }\n\n .suite-stat[_ngcontent-%COMP%] .stat-value.good[_ngcontent-%COMP%] {\n color: #22c55e;\n }\n\n .suite-stat[_ngcontent-%COMP%] .stat-value.bad[_ngcontent-%COMP%] {\n color: #ef4444;\n }\n\n .suite-stat[_ngcontent-%COMP%] .stat-label[_ngcontent-%COMP%] {\n font-size: 10px;\n color: #94a3b8;\n font-weight: 600;\n text-transform: uppercase;\n }\n\n .suite-arrow[_ngcontent-%COMP%] {\n color: #94a3b8;\n font-size: 14px;\n }\n\n \n\n .empty-state[_ngcontent-%COMP%] {\n padding: 60px 20px;\n text-align: center;\n }\n\n .empty-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 56px;\n margin-bottom: 16px;\n color: #cbd5e1;\n }\n\n .empty-state.success[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #22c55e;\n }\n\n .empty-state[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n font-size: 18px;\n color: #475569;\n margin: 0 0 8px 0;\n font-weight: 600;\n }\n\n .empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n font-size: 14px;\n color: #94a3b8;\n margin: 0;\n }\n\n \n\n .feedback-stats[_ngcontent-%COMP%] {\n background: white;\n padding: 20px;\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n }\n\n .feedback-stats[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 20px 0;\n font-size: 16px;\n font-weight: 600;\n color: #1e293b;\n display: flex;\n align-items: center;\n gap: 10px;\n }\n\n .feedback-stats[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #3b82f6;\n }\n\n .stats-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));\n gap: 16px;\n }\n\n .stat-card[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n padding: 16px;\n border-radius: 10px;\n text-align: center;\n }\n\n .stat-card[_ngcontent-%COMP%] .stat-label[_ngcontent-%COMP%] {\n font-size: 10px;\n font-weight: 700;\n color: #64748b;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 8px;\n }\n\n .stat-card[_ngcontent-%COMP%] .stat-value[_ngcontent-%COMP%] {\n font-size: 24px;\n font-weight: 700;\n color: #1e293b;\n }\n\n \n\n @media (max-width: 1024px) {\n .feedback-summary[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .suite-stats[_ngcontent-%COMP%] {\n flex-wrap: wrap;\n gap: 12px;\n }\n }\n\n @media (max-width: 768px) {\n .testing-feedback[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .feedback-header[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 16px;\n align-items: flex-start;\n }\n\n .feedback-summary[_ngcontent-%COMP%] {\n grid-template-columns: 1fr 1fr;\n }\n\n .summary-card[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .summary-value[_ngcontent-%COMP%] {\n font-size: 22px;\n }\n\n .feedback-filters[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n\n .filter-group[_ngcontent-%COMP%] {\n min-width: 100%;\n }\n\n .item-header[_ngcontent-%COMP%] {\n flex-wrap: wrap;\n }\n\n .item-reason[_ngcontent-%COMP%] {\n width: 100%;\n margin-top: 8px;\n }\n\n .correctness-buttons[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n\n .form-actions[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n\n .reviewed-header[_ngcontent-%COMP%] {\n flex-wrap: wrap;\n }\n\n .suite-card[_ngcontent-%COMP%] {\n flex-direction: column;\n align-items: flex-start;\n }\n\n .suite-stats[_ngcontent-%COMP%] {\n width: 100%;\n justify-content: space-between;\n }\n }"], data: { animation: [] }, changeDetection: 0 });
|
|
1097
|
-
}
|
|
1098
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(TestingFeedbackComponent, [{
|
|
1099
|
-
type: Component,
|
|
1100
|
-
args: [{ selector: 'app-testing-feedback', changeDetection: ChangeDetectionStrategy.OnPush, template: `
|
|
1101
|
-
<div class="testing-feedback">
|
|
1102
|
-
<!-- Header -->
|
|
1103
|
-
<div class="feedback-header">
|
|
1104
|
-
<div class="header-left">
|
|
1105
|
-
<h2>
|
|
1106
|
-
<i class="fa-solid fa-clipboard-check"></i>
|
|
1107
|
-
Human Feedback Review
|
|
1108
|
-
</h2>
|
|
1109
|
-
<div class="pending-badge" *ngIf="(pendingCount$ | async) as count">
|
|
1110
|
-
<span class="badge-count" *ngIf="count > 0">{{ count }}</span>
|
|
1111
|
-
<span class="badge-text">{{ count > 0 ? 'Pending Review' : 'All Reviewed' }}</span>
|
|
1112
|
-
</div>
|
|
1113
|
-
</div>
|
|
1114
|
-
<div class="header-actions">
|
|
1115
|
-
<button class="action-btn refresh-btn" (click)="refresh()" [disabled]="isRefreshing">
|
|
1116
|
-
<i class="fa-solid fa-refresh" [class.fa-spin]="isRefreshing"></i>
|
|
1117
|
-
{{ isRefreshing ? 'Refreshing...' : 'Refresh' }}
|
|
1118
|
-
</button>
|
|
1119
|
-
</div>
|
|
1120
|
-
</div>
|
|
1121
|
-
|
|
1122
|
-
<!-- KPI Summary Cards - Clickable -->
|
|
1123
|
-
<div class="feedback-summary">
|
|
1124
|
-
<div class="summary-card clickable" [class.active]="viewMode === 'pending'" (click)="setViewMode('pending')">
|
|
1125
|
-
<div class="summary-icon pending">
|
|
1126
|
-
<i class="fa-solid fa-hourglass-half"></i>
|
|
1127
|
-
</div>
|
|
1128
|
-
<div class="summary-content">
|
|
1129
|
-
<div class="summary-value">{{ (pendingCount$ | async) ?? 0 }}</div>
|
|
1130
|
-
<div class="summary-label">Pending Review</div>
|
|
1131
|
-
</div>
|
|
1132
|
-
<i class="fa-solid fa-chevron-right summary-arrow"></i>
|
|
1133
|
-
</div>
|
|
1134
|
-
<div class="summary-card clickable" [class.active]="viewMode === 'reviewed'" (click)="setViewMode('reviewed')">
|
|
1135
|
-
<div class="summary-icon reviewed">
|
|
1136
|
-
<i class="fa-solid fa-check-circle"></i>
|
|
1137
|
-
</div>
|
|
1138
|
-
<div class="summary-content">
|
|
1139
|
-
<div class="summary-value">{{ (reviewedCount$ | async) ?? 0 }}</div>
|
|
1140
|
-
<div class="summary-label">Reviewed</div>
|
|
1141
|
-
</div>
|
|
1142
|
-
<i class="fa-solid fa-chevron-right summary-arrow"></i>
|
|
1143
|
-
</div>
|
|
1144
|
-
<div class="summary-card clickable" [class.active]="viewMode === 'suites'" (click)="setViewMode('suites')">
|
|
1145
|
-
<div class="summary-icon suites">
|
|
1146
|
-
<i class="fa-solid fa-layer-group"></i>
|
|
1147
|
-
</div>
|
|
1148
|
-
<div class="summary-content">
|
|
1149
|
-
<div class="summary-value">{{ (suiteCount$ | async) ?? 0 }}</div>
|
|
1150
|
-
<div class="summary-label">Test Suites</div>
|
|
1151
|
-
</div>
|
|
1152
|
-
<i class="fa-solid fa-chevron-right summary-arrow"></i>
|
|
1153
|
-
</div>
|
|
1154
|
-
<div class="summary-card">
|
|
1155
|
-
<div class="summary-icon accuracy">
|
|
1156
|
-
<i class="fa-solid fa-bullseye"></i>
|
|
1157
|
-
</div>
|
|
1158
|
-
<div class="summary-content">
|
|
1159
|
-
<div class="summary-value">{{ (accuracyRate$ | async) ?? 0 | number:'1.1-1' }}%</div>
|
|
1160
|
-
<div class="summary-label">Human-AI Agreement</div>
|
|
1161
|
-
</div>
|
|
1162
|
-
</div>
|
|
1163
|
-
</div>
|
|
1164
|
-
|
|
1165
|
-
<!-- Filters Bar -->
|
|
1166
|
-
<div class="feedback-filters">
|
|
1167
|
-
<div class="filter-group">
|
|
1168
|
-
<label>View</label>
|
|
1169
|
-
<select [(ngModel)]="viewMode" (change)="onViewModeChange()">
|
|
1170
|
-
<option value="pending">Pending Reviews</option>
|
|
1171
|
-
<option value="reviewed">Reviewed Feedback</option>
|
|
1172
|
-
<option value="suites">By Test Suite</option>
|
|
1173
|
-
</select>
|
|
1174
|
-
</div>
|
|
1175
|
-
<div class="filter-group" *ngIf="viewMode === 'pending'">
|
|
1176
|
-
<label>Reason</label>
|
|
1177
|
-
<select [(ngModel)]="filters.reason" (change)="onFilterChange()">
|
|
1178
|
-
<option value="all">All Reasons</option>
|
|
1179
|
-
<option value="no-feedback">No Feedback</option>
|
|
1180
|
-
<option value="high-score-failed">High Score but Failed</option>
|
|
1181
|
-
<option value="low-score-passed">Low Score but Passed</option>
|
|
1182
|
-
</select>
|
|
1183
|
-
</div>
|
|
1184
|
-
<div class="filter-group" *ngIf="viewMode !== 'suites'">
|
|
1185
|
-
<label>Test Suite</label>
|
|
1186
|
-
<select [(ngModel)]="filters.suiteId" (change)="onFilterChange()">
|
|
1187
|
-
<option [ngValue]="null">All Suites</option>
|
|
1188
|
-
<option *ngFor="let suite of testSuites$ | async" [ngValue]="suite.ID">{{ suite.Name }}</option>
|
|
1189
|
-
</select>
|
|
1190
|
-
</div>
|
|
1191
|
-
<div class="filter-group search">
|
|
1192
|
-
<label>Search</label>
|
|
1193
|
-
<div class="search-input-wrapper">
|
|
1194
|
-
<i class="fa-solid fa-search"></i>
|
|
1195
|
-
<input
|
|
1196
|
-
type="text"
|
|
1197
|
-
[(ngModel)]="filters.searchText"
|
|
1198
|
-
(input)="onFilterChange()"
|
|
1199
|
-
placeholder="Search tests..."
|
|
1200
|
-
/>
|
|
1201
|
-
<button class="clear-btn" *ngIf="filters.searchText" (click)="clearSearch()">
|
|
1202
|
-
<i class="fa-solid fa-times"></i>
|
|
1203
|
-
</button>
|
|
1204
|
-
</div>
|
|
1205
|
-
</div>
|
|
1206
|
-
</div>
|
|
1207
|
-
|
|
1208
|
-
<!-- Pending Reviews View -->
|
|
1209
|
-
<div class="feedback-content" *ngIf="viewMode === 'pending'">
|
|
1210
|
-
<div class="content-header">
|
|
1211
|
-
<h3>
|
|
1212
|
-
<i class="fa-solid fa-list-check"></i>
|
|
1213
|
-
Tests Requiring Review
|
|
1214
|
-
</h3>
|
|
1215
|
-
<div class="sort-controls">
|
|
1216
|
-
<label>Sort by:</label>
|
|
1217
|
-
<select [(ngModel)]="sortBy" (change)="onSortChange()">
|
|
1218
|
-
<option value="date">Date</option>
|
|
1219
|
-
<option value="priority">Priority</option>
|
|
1220
|
-
<option value="test-name">Test Name</option>
|
|
1221
|
-
</select>
|
|
1222
|
-
</div>
|
|
1223
|
-
</div>
|
|
1224
|
-
|
|
1225
|
-
<div class="feedback-list" *ngIf="(filteredPending$ | async) as items">
|
|
1226
|
-
<ng-container *ngIf="items.length > 0; else emptyPending">
|
|
1227
|
-
<div class="feedback-item" *ngFor="let item of items; trackBy: trackByTestRunId"
|
|
1228
|
-
[class.expanded]="expandedItem === item.testRunID">
|
|
1229
|
-
<div class="item-header" (click)="toggleExpanded(item.testRunID)">
|
|
1230
|
-
<div class="item-main">
|
|
1231
|
-
<div class="item-title">{{ item.testName }}</div>
|
|
1232
|
-
<div class="item-meta">
|
|
1233
|
-
<span class="meta-date">
|
|
1234
|
-
<i class="fa-solid fa-clock"></i>
|
|
1235
|
-
{{ item.runDateTime | date:'short' }}
|
|
1236
|
-
</span>
|
|
1237
|
-
<span class="meta-score">
|
|
1238
|
-
Score: <strong>{{ (item.automatedScore * 10).toFixed(2) }}</strong>/10
|
|
1239
|
-
</span>
|
|
1240
|
-
<span class="meta-status" [class]="'status-' + item.automatedStatus.toLowerCase()">
|
|
1241
|
-
{{ item.automatedStatus }}
|
|
1242
|
-
</span>
|
|
1243
|
-
</div>
|
|
1244
|
-
</div>
|
|
1245
|
-
<div class="item-reason">
|
|
1246
|
-
<span class="reason-badge" [class]="item.reason">
|
|
1247
|
-
<i class="fa-solid" [class.fa-circle-info]="item.reason === 'no-feedback'"
|
|
1248
|
-
[class.fa-arrow-up]="item.reason === 'high-score-failed'"
|
|
1249
|
-
[class.fa-arrow-down]="item.reason === 'low-score-passed'"></i>
|
|
1250
|
-
{{ formatReason(item.reason) }}
|
|
1251
|
-
</span>
|
|
1252
|
-
</div>
|
|
1253
|
-
<button class="expand-btn">
|
|
1254
|
-
<i class="fa-solid" [class.fa-chevron-down]="expandedItem !== item.testRunID"
|
|
1255
|
-
[class.fa-chevron-up]="expandedItem === item.testRunID"></i>
|
|
1256
|
-
</button>
|
|
1257
|
-
</div>
|
|
1258
|
-
|
|
1259
|
-
<div class="item-content" *ngIf="expandedItem === item.testRunID" [@slideDown]>
|
|
1260
|
-
<div class="feedback-form">
|
|
1261
|
-
<div class="form-section">
|
|
1262
|
-
<h4>Provide Your Feedback</h4>
|
|
1263
|
-
<div class="rating-section">
|
|
1264
|
-
<label>Human Rating</label>
|
|
1265
|
-
<div class="rating-stars-input">
|
|
1266
|
-
<button *ngFor="let star of [1,2,3,4,5,6,7,8,9,10]"
|
|
1267
|
-
class="star-btn"
|
|
1268
|
-
[class.filled]="star <= item.feedbackRating"
|
|
1269
|
-
(click)="setRating(item, star)">
|
|
1270
|
-
<i class="fa-solid fa-star"></i>
|
|
1271
|
-
</button>
|
|
1272
|
-
<span class="rating-display">{{ item.feedbackRating }}/10</span>
|
|
1273
|
-
</div>
|
|
1274
|
-
</div>
|
|
1275
|
-
<div class="correctness-section">
|
|
1276
|
-
<label>Is the Automated Result Correct?</label>
|
|
1277
|
-
<div class="correctness-buttons">
|
|
1278
|
-
<button class="correctness-btn correct" [class.active]="item.feedbackIsCorrect === true"
|
|
1279
|
-
(click)="setCorrectness(item, true)">
|
|
1280
|
-
<i class="fa-solid fa-check"></i>
|
|
1281
|
-
Correct
|
|
1282
|
-
</button>
|
|
1283
|
-
<button class="correctness-btn incorrect" [class.active]="item.feedbackIsCorrect === false"
|
|
1284
|
-
(click)="setCorrectness(item, false)">
|
|
1285
|
-
<i class="fa-solid fa-times"></i>
|
|
1286
|
-
Incorrect
|
|
1287
|
-
</button>
|
|
1288
|
-
</div>
|
|
1289
|
-
</div>
|
|
1290
|
-
<div class="form-group">
|
|
1291
|
-
<label>Comments / Correction Notes</label>
|
|
1292
|
-
<textarea
|
|
1293
|
-
[(ngModel)]="item.feedbackComments"
|
|
1294
|
-
rows="3"
|
|
1295
|
-
class="comments-textarea"
|
|
1296
|
-
placeholder="Explain your assessment or provide correction notes..."
|
|
1297
|
-
></textarea>
|
|
1298
|
-
</div>
|
|
1299
|
-
<div class="form-actions">
|
|
1300
|
-
<button class="submit-btn" (click)="submitFeedback(item)" [disabled]="isSubmitting">
|
|
1301
|
-
<i class="fa-solid fa-paper-plane"></i>
|
|
1302
|
-
{{ isSubmitting ? 'Submitting...' : 'Submit Feedback' }}
|
|
1303
|
-
</button>
|
|
1304
|
-
<button class="view-btn" (click)="viewFullDetails(item)">
|
|
1305
|
-
<i class="fa-solid fa-external-link"></i>
|
|
1306
|
-
View Full Details
|
|
1307
|
-
</button>
|
|
1308
|
-
</div>
|
|
1309
|
-
</div>
|
|
1310
|
-
</div>
|
|
1311
|
-
</div>
|
|
1312
|
-
</div>
|
|
1313
|
-
</ng-container>
|
|
1314
|
-
<ng-template #emptyPending>
|
|
1315
|
-
<div class="empty-state success">
|
|
1316
|
-
<i class="fa-solid fa-check-double"></i>
|
|
1317
|
-
<h3>All Caught Up!</h3>
|
|
1318
|
-
<p>No tests currently require feedback review.</p>
|
|
1319
|
-
</div>
|
|
1320
|
-
</ng-template>
|
|
1321
|
-
</div>
|
|
1322
|
-
</div>
|
|
1323
|
-
|
|
1324
|
-
<!-- Reviewed Feedback View -->
|
|
1325
|
-
<div class="feedback-content" *ngIf="viewMode === 'reviewed'">
|
|
1326
|
-
<div class="content-header">
|
|
1327
|
-
<h3>
|
|
1328
|
-
<i class="fa-solid fa-history"></i>
|
|
1329
|
-
Reviewed Feedback History
|
|
1330
|
-
</h3>
|
|
1331
|
-
<div class="sort-controls">
|
|
1332
|
-
<label>Sort by:</label>
|
|
1333
|
-
<select [(ngModel)]="reviewedSortBy" (change)="onReviewedSortChange()">
|
|
1334
|
-
<option value="date">Review Date</option>
|
|
1335
|
-
<option value="rating">Rating</option>
|
|
1336
|
-
<option value="test-name">Test Name</option>
|
|
1337
|
-
</select>
|
|
1338
|
-
</div>
|
|
1339
|
-
</div>
|
|
1340
|
-
|
|
1341
|
-
<div class="feedback-list" *ngIf="(filteredReviewed$ | async) as items">
|
|
1342
|
-
<ng-container *ngIf="items.length > 0; else emptyReviewed">
|
|
1343
|
-
<div class="reviewed-item" *ngFor="let item of items; trackBy: trackByReviewedId">
|
|
1344
|
-
<div class="reviewed-header">
|
|
1345
|
-
<div class="reviewed-main">
|
|
1346
|
-
<div class="reviewed-title">{{ item.testName }}</div>
|
|
1347
|
-
<div class="reviewed-meta">
|
|
1348
|
-
<span class="meta-reviewer">
|
|
1349
|
-
<i class="fa-solid fa-user"></i>
|
|
1350
|
-
{{ item.reviewerName }}
|
|
1351
|
-
</span>
|
|
1352
|
-
<span class="meta-date">
|
|
1353
|
-
<i class="fa-solid fa-calendar"></i>
|
|
1354
|
-
{{ item.reviewedAt | date:'short' }}
|
|
1355
|
-
</span>
|
|
1356
|
-
</div>
|
|
1357
|
-
</div>
|
|
1358
|
-
<div class="reviewed-rating">
|
|
1359
|
-
<div class="rating-stars">
|
|
1360
|
-
<i class="fa-solid fa-star" *ngFor="let s of [1,2,3,4,5,6,7,8,9,10]"
|
|
1361
|
-
[class.filled]="s <= item.rating"></i>
|
|
1362
|
-
</div>
|
|
1363
|
-
<span class="rating-text">{{ item.rating }}/10</span>
|
|
1364
|
-
</div>
|
|
1365
|
-
<div class="reviewed-verdict">
|
|
1366
|
-
<span class="verdict-badge" [class.correct]="item.isCorrect" [class.incorrect]="!item.isCorrect">
|
|
1367
|
-
<i class="fa-solid" [class.fa-check]="item.isCorrect" [class.fa-times]="!item.isCorrect"></i>
|
|
1368
|
-
{{ item.isCorrect ? 'Correct' : 'Incorrect' }}
|
|
1369
|
-
</span>
|
|
1370
|
-
</div>
|
|
1371
|
-
<button class="view-btn-small" (click)="viewTestRun(item.testRunID)">
|
|
1372
|
-
<i class="fa-solid fa-external-link"></i>
|
|
1373
|
-
</button>
|
|
1374
|
-
</div>
|
|
1375
|
-
<div class="reviewed-comments" *ngIf="item.comments">
|
|
1376
|
-
<p>{{ item.comments }}</p>
|
|
1377
|
-
</div>
|
|
1378
|
-
</div>
|
|
1379
|
-
</ng-container>
|
|
1380
|
-
<ng-template #emptyReviewed>
|
|
1381
|
-
<div class="empty-state">
|
|
1382
|
-
<i class="fa-solid fa-clipboard"></i>
|
|
1383
|
-
<h3>No Reviews Yet</h3>
|
|
1384
|
-
<p>No feedback has been submitted yet. Start by reviewing pending tests.</p>
|
|
1385
|
-
</div>
|
|
1386
|
-
</ng-template>
|
|
1387
|
-
</div>
|
|
1388
|
-
</div>
|
|
1389
|
-
|
|
1390
|
-
<!-- Test Suite Aggregation View -->
|
|
1391
|
-
<div class="feedback-content" *ngIf="viewMode === 'suites'">
|
|
1392
|
-
<div class="content-header">
|
|
1393
|
-
<h3>
|
|
1394
|
-
<i class="fa-solid fa-layer-group"></i>
|
|
1395
|
-
Feedback by Test Suite
|
|
1396
|
-
</h3>
|
|
1397
|
-
</div>
|
|
1398
|
-
|
|
1399
|
-
<div class="suites-list" *ngIf="(suiteAggregations$ | async) as suites">
|
|
1400
|
-
<ng-container *ngIf="suites.length > 0; else emptySuites">
|
|
1401
|
-
<div class="suite-card" *ngFor="let suite of suites; trackBy: trackBySuiteId"
|
|
1402
|
-
(click)="selectSuite(suite.suiteId)">
|
|
1403
|
-
<div class="suite-header">
|
|
1404
|
-
<div class="suite-icon">
|
|
1405
|
-
<i class="fa-solid fa-layer-group"></i>
|
|
1406
|
-
</div>
|
|
1407
|
-
<div class="suite-info">
|
|
1408
|
-
<h4>{{ suite.suiteName }}</h4>
|
|
1409
|
-
<div class="suite-meta">
|
|
1410
|
-
<span>{{ suite.totalRuns }} test runs</span>
|
|
1411
|
-
</div>
|
|
1412
|
-
</div>
|
|
1413
|
-
</div>
|
|
1414
|
-
<div class="suite-stats">
|
|
1415
|
-
<div class="suite-stat">
|
|
1416
|
-
<div class="stat-value pending">{{ suite.pendingCount }}</div>
|
|
1417
|
-
<div class="stat-label">Pending</div>
|
|
1418
|
-
</div>
|
|
1419
|
-
<div class="suite-stat">
|
|
1420
|
-
<div class="stat-value reviewed">{{ suite.reviewedCount }}</div>
|
|
1421
|
-
<div class="stat-label">Reviewed</div>
|
|
1422
|
-
</div>
|
|
1423
|
-
<div class="suite-stat">
|
|
1424
|
-
<div class="stat-value">{{ suite.avgRating | number:'1.1-1' }}</div>
|
|
1425
|
-
<div class="stat-label">Avg Rating</div>
|
|
1426
|
-
</div>
|
|
1427
|
-
<div class="suite-stat">
|
|
1428
|
-
<div class="stat-value" [class.good]="suite.agreementRate >= 70" [class.bad]="suite.agreementRate < 50">
|
|
1429
|
-
{{ suite.agreementRate | number:'1.0-0' }}%
|
|
1430
|
-
</div>
|
|
1431
|
-
<div class="stat-label">Agreement</div>
|
|
1432
|
-
</div>
|
|
1433
|
-
<div class="suite-stat">
|
|
1434
|
-
<div class="stat-value" [class.good]="suite.passRate >= 80" [class.bad]="suite.passRate < 50">
|
|
1435
|
-
{{ suite.passRate | number:'1.0-0' }}%
|
|
1436
|
-
</div>
|
|
1437
|
-
<div class="stat-label">Pass Rate</div>
|
|
1438
|
-
</div>
|
|
1439
|
-
</div>
|
|
1440
|
-
<i class="fa-solid fa-chevron-right suite-arrow"></i>
|
|
1441
|
-
</div>
|
|
1442
|
-
</ng-container>
|
|
1443
|
-
<ng-template #emptySuites>
|
|
1444
|
-
<div class="empty-state">
|
|
1445
|
-
<i class="fa-solid fa-layer-group"></i>
|
|
1446
|
-
<h3>No Test Suites</h3>
|
|
1447
|
-
<p>No test suites have been created yet.</p>
|
|
1448
|
-
</div>
|
|
1449
|
-
</ng-template>
|
|
1450
|
-
</div>
|
|
1451
|
-
</div>
|
|
1452
|
-
|
|
1453
|
-
<!-- Summary Statistics -->
|
|
1454
|
-
<div class="feedback-stats">
|
|
1455
|
-
<h3>
|
|
1456
|
-
<i class="fa-solid fa-chart-pie"></i>
|
|
1457
|
-
Feedback Statistics
|
|
1458
|
-
</h3>
|
|
1459
|
-
<div class="stats-grid">
|
|
1460
|
-
<div class="stat-card">
|
|
1461
|
-
<div class="stat-label">Total Feedback</div>
|
|
1462
|
-
<div class="stat-value">{{ (totalFeedback$ | async) ?? 0 }}</div>
|
|
1463
|
-
</div>
|
|
1464
|
-
<div class="stat-card">
|
|
1465
|
-
<div class="stat-label">Avg Rating</div>
|
|
1466
|
-
<div class="stat-value">{{ (avgRating$ | async) ?? 0 | number:'1.1-1' }}/10</div>
|
|
1467
|
-
</div>
|
|
1468
|
-
<div class="stat-card">
|
|
1469
|
-
<div class="stat-label">Agreement Rate</div>
|
|
1470
|
-
<div class="stat-value">{{ (agreementRate$ | async) ?? 0 | number:'1.1-1' }}%</div>
|
|
1471
|
-
</div>
|
|
1472
|
-
<div class="stat-card">
|
|
1473
|
-
<div class="stat-label">Discrepancy Count</div>
|
|
1474
|
-
<div class="stat-value">{{ (discrepancyCount$ | async) ?? 0 }}</div>
|
|
1475
|
-
</div>
|
|
1476
|
-
</div>
|
|
1477
|
-
</div>
|
|
1478
|
-
</div>
|
|
1479
|
-
`, animations: [], styles: ["\n :host {\n display: block;\n height: 100%;\n }\n\n .testing-feedback {\n padding: 20px;\n height: 100%;\n overflow-y: auto;\n background: #f8f9fa;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n }\n\n /* Header */\n .feedback-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 20px;\n background: white;\n padding: 20px;\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n }\n\n .header-left {\n display: flex;\n align-items: center;\n gap: 16px;\n }\n\n .header-left h2 {\n margin: 0;\n font-size: 22px;\n font-weight: 700;\n color: #1e293b;\n display: flex;\n align-items: center;\n gap: 12px;\n }\n\n .header-left h2 i {\n color: #3b82f6;\n }\n\n .pending-badge {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 14px;\n background: linear-gradient(135deg, #fff7ed 0%, #ffedd5 100%);\n border: 1px solid #fb923c;\n border-radius: 20px;\n }\n\n .badge-count {\n background: linear-gradient(135deg, #f97316 0%, #ea580c 100%);\n color: white;\n min-width: 24px;\n height: 24px;\n padding: 0 6px;\n border-radius: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n font-weight: 700;\n }\n\n .badge-text {\n font-size: 12px;\n font-weight: 600;\n color: #ea580c;\n }\n\n .action-btn {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 18px;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n background: white;\n color: #64748b;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s ease;\n }\n\n .action-btn:hover:not(:disabled) {\n background: #f8fafc;\n border-color: #cbd5e1;\n }\n\n .action-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n /* Summary Cards */\n .feedback-summary {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 16px;\n margin-bottom: 20px;\n }\n\n .summary-card {\n background: white;\n padding: 20px;\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n display: flex;\n align-items: center;\n gap: 16px;\n transition: all 0.2s ease;\n position: relative;\n }\n\n .summary-card.clickable {\n cursor: pointer;\n }\n\n .summary-card.clickable:hover {\n transform: translateY(-2px);\n box-shadow: 0 6px 20px rgba(0, 0, 0, 0.12);\n }\n\n .summary-card.active {\n border: 2px solid #3b82f6;\n background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);\n }\n\n .summary-icon {\n width: 52px;\n height: 52px;\n border-radius: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 22px;\n color: white;\n flex-shrink: 0;\n }\n\n .summary-icon.pending {\n background: linear-gradient(135deg, #f97316 0%, #ea580c 100%);\n }\n\n .summary-icon.reviewed {\n background: linear-gradient(135deg, #22c55e 0%, #16a34a 100%);\n }\n\n .summary-icon.suites {\n background: linear-gradient(135deg, #8b5cf6 0%, #7c3aed 100%);\n }\n\n .summary-icon.accuracy {\n background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);\n }\n\n .summary-content {\n flex: 1;\n }\n\n .summary-value {\n font-size: 28px;\n font-weight: 700;\n color: #1e293b;\n line-height: 1;\n margin-bottom: 4px;\n }\n\n .summary-label {\n font-size: 11px;\n color: #64748b;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n }\n\n .summary-arrow {\n color: #94a3b8;\n font-size: 14px;\n }\n\n /* Filters */\n .feedback-filters {\n display: flex;\n gap: 16px;\n margin-bottom: 20px;\n background: white;\n padding: 16px 20px;\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n flex-wrap: wrap;\n }\n\n .filter-group {\n display: flex;\n flex-direction: column;\n gap: 6px;\n min-width: 140px;\n }\n\n .filter-group.search {\n flex: 1;\n min-width: 200px;\n }\n\n .filter-group label {\n font-size: 10px;\n font-weight: 700;\n color: #64748b;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n }\n\n .filter-group select {\n padding: 10px 12px;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n font-size: 13px;\n background: white;\n color: #1e293b;\n cursor: pointer;\n }\n\n .filter-group select:focus {\n outline: none;\n border-color: #3b82f6;\n box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);\n }\n\n .search-input-wrapper {\n position: relative;\n display: flex;\n align-items: center;\n }\n\n .search-input-wrapper > i {\n position: absolute;\n left: 12px;\n color: #94a3b8;\n font-size: 13px;\n }\n\n .search-input-wrapper input {\n flex: 1;\n padding: 10px 40px 10px 36px;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n font-size: 13px;\n }\n\n .search-input-wrapper input:focus {\n outline: none;\n border-color: #3b82f6;\n box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);\n }\n\n .clear-btn {\n position: absolute;\n right: 8px;\n background: none;\n border: none;\n color: #94a3b8;\n cursor: pointer;\n padding: 6px;\n border-radius: 4px;\n }\n\n .clear-btn:hover {\n color: #64748b;\n background: #f1f5f9;\n }\n\n /* Content Area */\n .feedback-content {\n background: white;\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n overflow: hidden;\n margin-bottom: 20px;\n }\n\n .content-header {\n padding: 20px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border-bottom: 1px solid #e2e8f0;\n display: flex;\n justify-content: space-between;\n align-items: center;\n }\n\n .content-header h3 {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: #1e293b;\n display: flex;\n align-items: center;\n gap: 10px;\n }\n\n .content-header h3 i {\n color: #3b82f6;\n }\n\n .sort-controls {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n color: #64748b;\n }\n\n .sort-controls select {\n padding: 6px 10px;\n border: 1px solid #e2e8f0;\n border-radius: 6px;\n font-size: 12px;\n background: white;\n }\n\n /* Feedback List */\n .feedback-list {\n max-height: 600px;\n overflow-y: auto;\n }\n\n .feedback-item {\n border-bottom: 1px solid #f1f5f9;\n transition: all 0.2s ease;\n }\n\n .feedback-item.expanded {\n background: #f8fafc;\n }\n\n .item-header {\n padding: 16px 20px;\n display: flex;\n align-items: center;\n gap: 16px;\n cursor: pointer;\n transition: background 0.2s ease;\n }\n\n .item-header:hover {\n background: rgba(59, 130, 246, 0.04);\n }\n\n .item-main {\n flex: 1;\n min-width: 0;\n }\n\n .item-title {\n font-size: 14px;\n font-weight: 600;\n color: #1e293b;\n margin-bottom: 6px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .item-meta {\n display: flex;\n gap: 16px;\n font-size: 12px;\n color: #64748b;\n flex-wrap: wrap;\n }\n\n .item-meta span {\n display: flex;\n align-items: center;\n gap: 5px;\n }\n\n .meta-status {\n padding: 2px 8px;\n border-radius: 4px;\n font-weight: 600;\n font-size: 11px;\n }\n\n .meta-status.status-passed { background: #dcfce7; color: #16a34a; }\n .meta-status.status-failed { background: #fee2e2; color: #dc2626; }\n .meta-status.status-error { background: #fef3c7; color: #d97706; }\n .meta-status.status-running { background: #dbeafe; color: #2563eb; }\n\n .item-reason {\n flex-shrink: 0;\n }\n\n .reason-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n border-radius: 16px;\n font-size: 11px;\n font-weight: 600;\n }\n\n .reason-badge.no-feedback {\n background: #dbeafe;\n color: #2563eb;\n }\n\n .reason-badge.high-score-failed {\n background: #fee2e2;\n color: #dc2626;\n }\n\n .reason-badge.low-score-passed {\n background: #fef3c7;\n color: #d97706;\n }\n\n .expand-btn {\n background: none;\n border: none;\n color: #94a3b8;\n cursor: pointer;\n padding: 8px;\n border-radius: 6px;\n transition: all 0.2s ease;\n font-size: 14px;\n }\n\n .expand-btn:hover {\n background: #e2e8f0;\n color: #64748b;\n }\n\n /* Expanded Content */\n .item-content {\n padding: 20px;\n border-top: 1px solid #e2e8f0;\n background: white;\n }\n\n .feedback-form {\n max-width: 600px;\n }\n\n .form-section h4 {\n margin: 0 0 20px 0;\n font-size: 15px;\n font-weight: 600;\n color: #1e293b;\n }\n\n .rating-section,\n .correctness-section {\n margin-bottom: 20px;\n }\n\n .rating-section label,\n .correctness-section label {\n display: block;\n font-size: 12px;\n font-weight: 600;\n color: #64748b;\n margin-bottom: 10px;\n }\n\n .rating-stars-input {\n display: flex;\n align-items: center;\n gap: 4px;\n }\n\n .star-btn {\n background: none;\n border: none;\n font-size: 22px;\n color: #e2e8f0;\n cursor: pointer;\n padding: 2px;\n transition: all 0.15s ease;\n }\n\n .star-btn:hover {\n transform: scale(1.2);\n }\n\n .star-btn.filled {\n color: #f59e0b;\n }\n\n .rating-display {\n margin-left: 12px;\n font-size: 16px;\n font-weight: 700;\n color: #1e293b;\n }\n\n .correctness-buttons {\n display: flex;\n gap: 12px;\n }\n\n .correctness-btn {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 12px 20px;\n border: 2px solid #e2e8f0;\n border-radius: 10px;\n background: white;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s ease;\n }\n\n .correctness-btn.correct:hover,\n .correctness-btn.correct.active {\n border-color: #22c55e;\n background: #f0fdf4;\n color: #16a34a;\n }\n\n .correctness-btn.incorrect:hover,\n .correctness-btn.incorrect.active {\n border-color: #ef4444;\n background: #fef2f2;\n color: #dc2626;\n }\n\n .form-group {\n margin-bottom: 16px;\n }\n\n .form-group label {\n display: block;\n font-size: 12px;\n font-weight: 600;\n color: #64748b;\n margin-bottom: 8px;\n }\n\n .comments-textarea {\n width: 100%;\n padding: 12px;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n font-size: 14px;\n font-family: inherit;\n resize: vertical;\n min-height: 80px;\n }\n\n .comments-textarea:focus {\n outline: none;\n border-color: #3b82f6;\n box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);\n }\n\n .form-actions {\n display: flex;\n gap: 12px;\n margin-top: 20px;\n }\n\n .submit-btn {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 24px;\n border: none;\n border-radius: 8px;\n background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);\n color: white;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s ease;\n }\n\n .submit-btn:hover:not(:disabled) {\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(37, 99, 235, 0.3);\n }\n\n .submit-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n .view-btn {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 20px;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n background: white;\n color: #64748b;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s ease;\n }\n\n .view-btn:hover {\n border-color: #cbd5e1;\n background: #f8fafc;\n }\n\n /* Reviewed Items */\n .reviewed-item {\n padding: 16px 20px;\n border-bottom: 1px solid #f1f5f9;\n }\n\n .reviewed-header {\n display: flex;\n align-items: center;\n gap: 16px;\n }\n\n .reviewed-main {\n flex: 1;\n min-width: 0;\n }\n\n .reviewed-title {\n font-size: 14px;\n font-weight: 600;\n color: #1e293b;\n margin-bottom: 4px;\n }\n\n .reviewed-meta {\n display: flex;\n gap: 16px;\n font-size: 12px;\n color: #64748b;\n }\n\n .reviewed-meta span {\n display: flex;\n align-items: center;\n gap: 5px;\n }\n\n .reviewed-rating {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n }\n\n .rating-stars {\n display: flex;\n gap: 2px;\n }\n\n .rating-stars i {\n font-size: 12px;\n color: #e2e8f0;\n }\n\n .rating-stars i.filled {\n color: #f59e0b;\n }\n\n .rating-text {\n font-size: 12px;\n font-weight: 600;\n color: #64748b;\n }\n\n .reviewed-verdict {\n flex-shrink: 0;\n }\n\n .verdict-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n border-radius: 16px;\n font-size: 11px;\n font-weight: 600;\n }\n\n .verdict-badge.correct {\n background: #dcfce7;\n color: #16a34a;\n }\n\n .verdict-badge.incorrect {\n background: #fee2e2;\n color: #dc2626;\n }\n\n .view-btn-small {\n background: none;\n border: 1px solid #e2e8f0;\n border-radius: 6px;\n padding: 8px;\n color: #64748b;\n cursor: pointer;\n transition: all 0.2s ease;\n }\n\n .view-btn-small:hover {\n background: #f8fafc;\n border-color: #cbd5e1;\n }\n\n .reviewed-comments {\n margin-top: 12px;\n padding: 12px;\n background: #f8fafc;\n border-radius: 8px;\n border-left: 3px solid #3b82f6;\n }\n\n .reviewed-comments p {\n margin: 0;\n font-size: 13px;\n color: #475569;\n line-height: 1.5;\n }\n\n /* Suite Cards */\n .suites-list {\n padding: 16px;\n }\n\n .suite-card {\n display: flex;\n align-items: center;\n gap: 16px;\n padding: 20px;\n background: #f8fafc;\n border: 1px solid #e2e8f0;\n border-radius: 12px;\n cursor: pointer;\n transition: all 0.2s ease;\n margin-bottom: 12px;\n }\n\n .suite-card:hover {\n border-color: #3b82f6;\n background: white;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);\n }\n\n .suite-card:last-child {\n margin-bottom: 0;\n }\n\n .suite-header {\n display: flex;\n align-items: center;\n gap: 14px;\n flex: 1;\n min-width: 0;\n }\n\n .suite-icon {\n width: 44px;\n height: 44px;\n border-radius: 10px;\n background: linear-gradient(135deg, #8b5cf6 0%, #7c3aed 100%);\n display: flex;\n align-items: center;\n justify-content: center;\n color: white;\n font-size: 18px;\n flex-shrink: 0;\n }\n\n .suite-info h4 {\n margin: 0 0 4px 0;\n font-size: 15px;\n font-weight: 600;\n color: #1e293b;\n }\n\n .suite-meta {\n font-size: 12px;\n color: #64748b;\n }\n\n .suite-stats {\n display: flex;\n gap: 20px;\n }\n\n .suite-stat {\n text-align: center;\n min-width: 60px;\n }\n\n .suite-stat .stat-value {\n font-size: 18px;\n font-weight: 700;\n color: #1e293b;\n }\n\n .suite-stat .stat-value.pending {\n color: #f97316;\n }\n\n .suite-stat .stat-value.reviewed {\n color: #22c55e;\n }\n\n .suite-stat .stat-value.good {\n color: #22c55e;\n }\n\n .suite-stat .stat-value.bad {\n color: #ef4444;\n }\n\n .suite-stat .stat-label {\n font-size: 10px;\n color: #94a3b8;\n font-weight: 600;\n text-transform: uppercase;\n }\n\n .suite-arrow {\n color: #94a3b8;\n font-size: 14px;\n }\n\n /* Empty States */\n .empty-state {\n padding: 60px 20px;\n text-align: center;\n }\n\n .empty-state i {\n font-size: 56px;\n margin-bottom: 16px;\n color: #cbd5e1;\n }\n\n .empty-state.success i {\n color: #22c55e;\n }\n\n .empty-state h3 {\n font-size: 18px;\n color: #475569;\n margin: 0 0 8px 0;\n font-weight: 600;\n }\n\n .empty-state p {\n font-size: 14px;\n color: #94a3b8;\n margin: 0;\n }\n\n /* Statistics */\n .feedback-stats {\n background: white;\n padding: 20px;\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n }\n\n .feedback-stats h3 {\n margin: 0 0 20px 0;\n font-size: 16px;\n font-weight: 600;\n color: #1e293b;\n display: flex;\n align-items: center;\n gap: 10px;\n }\n\n .feedback-stats h3 i {\n color: #3b82f6;\n }\n\n .stats-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));\n gap: 16px;\n }\n\n .stat-card {\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n padding: 16px;\n border-radius: 10px;\n text-align: center;\n }\n\n .stat-card .stat-label {\n font-size: 10px;\n font-weight: 700;\n color: #64748b;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 8px;\n }\n\n .stat-card .stat-value {\n font-size: 24px;\n font-weight: 700;\n color: #1e293b;\n }\n\n /* Responsive */\n @media (max-width: 1024px) {\n .feedback-summary {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .suite-stats {\n flex-wrap: wrap;\n gap: 12px;\n }\n }\n\n @media (max-width: 768px) {\n .testing-feedback {\n padding: 16px;\n }\n\n .feedback-header {\n flex-direction: column;\n gap: 16px;\n align-items: flex-start;\n }\n\n .feedback-summary {\n grid-template-columns: 1fr 1fr;\n }\n\n .summary-card {\n padding: 16px;\n }\n\n .summary-value {\n font-size: 22px;\n }\n\n .feedback-filters {\n flex-direction: column;\n }\n\n .filter-group {\n min-width: 100%;\n }\n\n .item-header {\n flex-wrap: wrap;\n }\n\n .item-reason {\n width: 100%;\n margin-top: 8px;\n }\n\n .correctness-buttons {\n flex-direction: column;\n }\n\n .form-actions {\n flex-direction: column;\n }\n\n .reviewed-header {\n flex-wrap: wrap;\n }\n\n .suite-card {\n flex-direction: column;\n align-items: flex-start;\n }\n\n .suite-stats {\n width: 100%;\n justify-content: space-between;\n }\n }\n "] }]
|
|
1480
|
-
}], () => [{ type: i1.TestingInstrumentationService }, { type: i0.ChangeDetectorRef }], { initialState: [{
|
|
1481
|
-
type: Input
|
|
1482
|
-
}], stateChange: [{
|
|
1483
|
-
type: Output
|
|
1484
|
-
}] }); })();
|
|
1485
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TestingFeedbackComponent, { className: "TestingFeedbackComponent" }); })();
|
|
1486
|
-
//# sourceMappingURL=testing-feedback.component.js.map
|