@memberjunction/ng-dashboards 5.21.0 → 5.23.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/README.md +51 -0
- package/dist/AI/components/agents/agent-configuration.component.d.ts.map +1 -1
- package/dist/AI/components/agents/agent-configuration.component.js +364 -362
- package/dist/AI/components/agents/agent-configuration.component.js.map +1 -1
- package/dist/AI/components/agents/agent-editor.component.js +2 -2
- package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts +313 -0
- package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js +2792 -0
- package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js.map +1 -0
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts +382 -0
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts.map +1 -0
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.js +2683 -0
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.js.map +1 -0
- package/dist/AI/components/execution-monitoring.component.d.ts.map +1 -1
- package/dist/AI/components/execution-monitoring.component.js +191 -197
- package/dist/AI/components/execution-monitoring.component.js.map +1 -1
- package/dist/AI/components/models/model-management.component.js +9 -8
- package/dist/AI/components/models/model-management.component.js.map +1 -1
- package/dist/AI/components/prompts/prompt-management.component.js +305 -299
- package/dist/AI/components/prompts/prompt-management.component.js.map +1 -1
- package/dist/AI/components/system/system-configuration.component.js +319 -313
- package/dist/AI/components/system/system-configuration.component.js.map +1 -1
- package/dist/AI/components/vectors/vector-management-resource.component.d.ts +240 -0
- package/dist/AI/components/vectors/vector-management-resource.component.d.ts.map +1 -0
- package/dist/AI/components/vectors/vector-management-resource.component.js +1767 -0
- package/dist/AI/components/vectors/vector-management-resource.component.js.map +1 -0
- package/dist/AI/index.d.ts +3 -0
- package/dist/AI/index.d.ts.map +1 -1
- package/dist/AI/index.js +6 -0
- package/dist/AI/index.js.map +1 -1
- package/dist/AI/services/ai-instrumentation.service.d.ts +50 -7
- package/dist/AI/services/ai-instrumentation.service.d.ts.map +1 -1
- package/dist/AI/services/ai-instrumentation.service.js +161 -193
- package/dist/AI/services/ai-instrumentation.service.js.map +1 -1
- package/dist/APIKeys/api-applications-panel.component.js +10 -12
- package/dist/APIKeys/api-applications-panel.component.js.map +1 -1
- package/dist/APIKeys/api-key-create-dialog.component.js +13 -19
- package/dist/APIKeys/api-key-create-dialog.component.js.map +1 -1
- package/dist/APIKeys/api-key-edit-panel.component.js +12 -14
- package/dist/APIKeys/api-key-edit-panel.component.js.map +1 -1
- package/dist/APIKeys/api-scopes-panel.component.js +61 -68
- package/dist/APIKeys/api-scopes-panel.component.js.map +1 -1
- package/dist/APIKeys/api-usage-panel.component.js +10 -11
- package/dist/APIKeys/api-usage-panel.component.js.map +1 -1
- package/dist/Actions/components/actions-list-view.component.js +82 -96
- package/dist/Actions/components/actions-list-view.component.js.map +1 -1
- package/dist/Actions/components/actions-overview.component.js +130 -134
- package/dist/Actions/components/actions-overview.component.js.map +1 -1
- package/dist/Actions/components/categories-list-view.component.d.ts.map +1 -1
- package/dist/Actions/components/categories-list-view.component.js +40 -46
- package/dist/Actions/components/categories-list-view.component.js.map +1 -1
- package/dist/Actions/components/code-management.component.js +2 -2
- package/dist/Actions/components/code-management.component.js.map +1 -1
- package/dist/Actions/components/entity-integration.component.js +2 -2
- package/dist/Actions/components/entity-integration.component.js.map +1 -1
- package/dist/Actions/components/execution-monitoring.component.js +127 -132
- package/dist/Actions/components/execution-monitoring.component.js.map +1 -1
- package/dist/Actions/components/executions-list-view.component.js +2 -2
- package/dist/Actions/components/executions-list-view.component.js.map +1 -1
- package/dist/Actions/components/explorer/action-card.component.js +11 -17
- package/dist/Actions/components/explorer/action-card.component.js.map +1 -1
- package/dist/Actions/components/explorer/action-explorer.component.js +5 -11
- package/dist/Actions/components/explorer/action-explorer.component.js.map +1 -1
- package/dist/Actions/components/explorer/action-list-item.component.js +8 -10
- package/dist/Actions/components/explorer/action-list-item.component.js.map +1 -1
- package/dist/Actions/components/explorer/action-toolbar.component.js +112 -133
- package/dist/Actions/components/explorer/action-toolbar.component.js.map +1 -1
- package/dist/Actions/components/explorer/action-tree-panel.component.js +63 -83
- package/dist/Actions/components/explorer/action-tree-panel.component.js.map +1 -1
- package/dist/Actions/components/explorer/new-action-panel.component.js +17 -21
- package/dist/Actions/components/explorer/new-action-panel.component.js.map +1 -1
- package/dist/Actions/components/explorer/new-category-panel.component.js +17 -21
- package/dist/Actions/components/explorer/new-category-panel.component.js.map +1 -1
- package/dist/Actions/components/scheduled-actions.component.js +2 -2
- package/dist/Actions/components/scheduled-actions.component.js.map +1 -1
- package/dist/Actions/components/security-permissions.component.js +2 -2
- package/dist/Actions/components/security-permissions.component.js.map +1 -1
- package/dist/ComponentStudio/component-studio-dashboard.component.d.ts +13 -5
- package/dist/ComponentStudio/component-studio-dashboard.component.d.ts.map +1 -1
- package/dist/ComponentStudio/component-studio-dashboard.component.js +168 -145
- package/dist/ComponentStudio/component-studio-dashboard.component.js.map +1 -1
- package/dist/ComponentStudio/components/artifact-load-dialog.component.d.ts +4 -5
- package/dist/ComponentStudio/components/artifact-load-dialog.component.d.ts.map +1 -1
- package/dist/ComponentStudio/components/artifact-load-dialog.component.js +197 -200
- package/dist/ComponentStudio/components/artifact-load-dialog.component.js.map +1 -1
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.d.ts +5 -7
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.d.ts.map +1 -1
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.js +142 -148
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.js.map +1 -1
- package/dist/ComponentStudio/components/browser/component-browser.component.js +153 -166
- package/dist/ComponentStudio/components/browser/component-browser.component.js.map +1 -1
- package/dist/ComponentStudio/components/editors/code-editor-panel.component.js +15 -20
- package/dist/ComponentStudio/components/editors/code-editor-panel.component.js.map +1 -1
- package/dist/ComponentStudio/components/editors/data-requirements-editor.component.js +16 -21
- package/dist/ComponentStudio/components/editors/data-requirements-editor.component.js.map +1 -1
- package/dist/ComponentStudio/components/editors/requirements-editor.component.js +18 -23
- package/dist/ComponentStudio/components/editors/requirements-editor.component.js.map +1 -1
- package/dist/ComponentStudio/components/editors/spec-editor.component.js +25 -30
- package/dist/ComponentStudio/components/editors/spec-editor.component.js.map +1 -1
- package/dist/ComponentStudio/components/new-component-dialog/new-component-dialog.component.js +10 -11
- package/dist/ComponentStudio/components/new-component-dialog/new-component-dialog.component.js.map +1 -1
- package/dist/ComponentStudio/components/save-version-dialog/save-version-dialog.component.d.ts.map +1 -1
- package/dist/ComponentStudio/components/save-version-dialog/save-version-dialog.component.js +24 -35
- package/dist/ComponentStudio/components/save-version-dialog/save-version-dialog.component.js.map +1 -1
- package/dist/ComponentStudio/components/text-import-dialog.component.js +15 -17
- package/dist/ComponentStudio/components/text-import-dialog.component.js.map +1 -1
- package/dist/Credentials/components/credentials-categories-resource.component.js +7 -6
- package/dist/Credentials/components/credentials-categories-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-list-resource.component.js +6 -5
- package/dist/Credentials/components/credentials-list-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-types-resource.component.js +7 -6
- package/dist/Credentials/components/credentials-types-resource.component.js.map +1 -1
- package/dist/DashboardBrowser/dashboard-browser-resource.component.d.ts +11 -0
- package/dist/DashboardBrowser/dashboard-browser-resource.component.d.ts.map +1 -1
- package/dist/DashboardBrowser/dashboard-browser-resource.component.js +57 -0
- package/dist/DashboardBrowser/dashboard-browser-resource.component.js.map +1 -1
- package/dist/DashboardBrowser/dashboard-share-dialog.component.js +9 -9
- package/dist/DashboardBrowser/dashboard-share-dialog.component.js.map +1 -1
- package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.d.ts +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts +10 -2
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.js +35 -11
- package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
- package/dist/DataExplorer/data-explorer-resource.component.d.ts +1 -0
- package/dist/DataExplorer/data-explorer-resource.component.d.ts.map +1 -1
- package/dist/DataExplorer/data-explorer-resource.component.js +8 -4
- package/dist/DataExplorer/data-explorer-resource.component.js.map +1 -1
- package/dist/Home/home-dashboard.component.d.ts +181 -1
- package/dist/Home/home-dashboard.component.d.ts.map +1 -1
- package/dist/Home/home-dashboard.component.js +1704 -182
- package/dist/Home/home-dashboard.component.js.map +1 -1
- package/dist/Integration/components/connections/connections.component.js +4 -4
- package/dist/Integration/components/connections/connections.component.js.map +1 -1
- package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js +246 -259
- package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js.map +1 -1
- package/dist/Integration/components/widgets/integration-card.component.js +7 -9
- package/dist/Integration/components/widgets/integration-card.component.js.map +1 -1
- package/dist/Integration/integration.module.d.ts +6 -10
- package/dist/Integration/integration.module.d.ts.map +1 -1
- package/dist/Integration/integration.module.js +12 -20
- package/dist/Integration/integration.module.js.map +1 -1
- package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.d.ts +106 -0
- package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.d.ts.map +1 -0
- package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js +607 -0
- package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js.map +1 -0
- package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.d.ts +126 -0
- package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.d.ts.map +1 -0
- package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js +1086 -0
- package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js.map +1 -0
- package/dist/KnowledgeHub/components/results-detail/search-result-detail.component.d.ts +56 -0
- package/dist/KnowledgeHub/components/results-detail/search-result-detail.component.d.ts.map +1 -0
- package/dist/KnowledgeHub/components/results-detail/search-result-detail.component.js +291 -0
- package/dist/KnowledgeHub/components/results-detail/search-result-detail.component.js.map +1 -0
- package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.d.ts +85 -0
- package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.d.ts.map +1 -0
- package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.js +461 -0
- package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.js.map +1 -0
- package/dist/KnowledgeHub/index.d.ts +5 -0
- package/dist/KnowledgeHub/index.d.ts.map +1 -0
- package/dist/KnowledgeHub/index.js +6 -0
- package/dist/KnowledgeHub/index.js.map +1 -0
- package/dist/Lists/components/lists-browse-resource.component.d.ts.map +1 -1
- package/dist/Lists/components/lists-browse-resource.component.js +9 -7
- package/dist/Lists/components/lists-browse-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-my-lists-resource.component.js +5 -4
- package/dist/Lists/components/lists-my-lists-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-operations-resource.component.js +10 -9
- package/dist/Lists/components/lists-operations-resource.component.js.map +1 -1
- package/dist/MCP/components/mcp-connection-dialog.component.js +141 -132
- package/dist/MCP/components/mcp-connection-dialog.component.js.map +1 -1
- package/dist/MCP/components/mcp-log-detail-panel.component.js +4 -4
- package/dist/MCP/components/mcp-log-detail-panel.component.js.map +1 -1
- package/dist/MCP/components/mcp-server-dialog.component.js +141 -128
- package/dist/MCP/components/mcp-server-dialog.component.js.map +1 -1
- package/dist/MCP/components/mcp-test-tool-dialog.component.js +210 -218
- package/dist/MCP/components/mcp-test-tool-dialog.component.js.map +1 -1
- package/dist/MCP/mcp-dashboard.component.js +2 -2
- package/dist/MCP/mcp-dashboard.component.js.map +1 -1
- package/dist/MCP/mcp.module.d.ts +6 -9
- package/dist/MCP/mcp.module.d.ts.map +1 -1
- package/dist/MCP/mcp.module.js +20 -22
- package/dist/MCP/mcp.module.js.map +1 -1
- package/dist/QueryBrowser/query-browser-resource.component.d.ts.map +1 -1
- package/dist/QueryBrowser/query-browser-resource.component.js +5 -1
- package/dist/QueryBrowser/query-browser-resource.component.js.map +1 -1
- package/dist/Scheduling/components/scheduling-activity.component.js +5 -4
- package/dist/Scheduling/components/scheduling-activity.component.js.map +1 -1
- package/dist/Scheduling/components/scheduling-jobs.component.js +6 -5
- package/dist/Scheduling/components/scheduling-jobs.component.js.map +1 -1
- package/dist/Scheduling/components/scheduling-overview.component.js +93 -92
- package/dist/Scheduling/components/scheduling-overview.component.js.map +1 -1
- package/dist/SystemDiagnostics/system-diagnostics.component.d.ts.map +1 -1
- package/dist/SystemDiagnostics/system-diagnostics.component.js +1 -0
- package/dist/SystemDiagnostics/system-diagnostics.component.js.map +1 -1
- package/dist/Testing/components/testing-dashboard-tab-resource.component.d.ts +7 -1
- package/dist/Testing/components/testing-dashboard-tab-resource.component.d.ts.map +1 -1
- package/dist/Testing/components/testing-dashboard-tab-resource.component.js +63 -8
- package/dist/Testing/components/testing-dashboard-tab-resource.component.js.map +1 -1
- package/dist/Testing/components/testing-dashboard-tab.component.d.ts +9 -1
- package/dist/Testing/components/testing-dashboard-tab.component.d.ts.map +1 -1
- package/dist/Testing/components/testing-dashboard-tab.component.js +109 -62
- package/dist/Testing/components/testing-dashboard-tab.component.js.map +1 -1
- package/dist/Testing/components/testing-explorer.component.d.ts +2 -1
- package/dist/Testing/components/testing-explorer.component.d.ts.map +1 -1
- package/dist/Testing/components/testing-explorer.component.js +241 -200
- package/dist/Testing/components/testing-explorer.component.js.map +1 -1
- package/dist/Testing/components/testing-runs-resource.component.d.ts +7 -1
- package/dist/Testing/components/testing-runs-resource.component.d.ts.map +1 -1
- package/dist/Testing/components/testing-runs-resource.component.js +63 -8
- package/dist/Testing/components/testing-runs-resource.component.js.map +1 -1
- package/dist/Testing/components/testing-runs.component.d.ts.map +1 -1
- package/dist/Testing/components/testing-runs.component.js +7 -5
- package/dist/Testing/components/testing-runs.component.js.map +1 -1
- package/dist/Testing/testing-dashboard.component.d.ts +9 -1
- package/dist/Testing/testing-dashboard.component.d.ts.map +1 -1
- package/dist/Testing/testing-dashboard.component.js +122 -54
- package/dist/Testing/testing-dashboard.component.js.map +1 -1
- package/dist/actions-dashboards.module.d.ts +8 -13
- package/dist/actions-dashboards.module.d.ts.map +1 -1
- package/dist/actions-dashboards.module.js +6 -27
- package/dist/actions-dashboards.module.js.map +1 -1
- package/dist/ai-dashboards.module.d.ts +14 -11
- package/dist/ai-dashboards.module.d.ts.map +1 -1
- package/dist/ai-dashboards.module.js +58 -44
- package/dist/ai-dashboards.module.js.map +1 -1
- package/dist/communication-dashboards.module.d.ts +4 -8
- package/dist/communication-dashboards.module.d.ts.map +1 -1
- package/dist/communication-dashboards.module.js +0 -19
- package/dist/communication-dashboards.module.js.map +1 -1
- package/dist/component-studio-dashboards.module.d.ts +7 -11
- package/dist/component-studio-dashboards.module.d.ts.map +1 -1
- package/dist/component-studio-dashboards.module.js +22 -34
- package/dist/component-studio-dashboards.module.js.map +1 -1
- package/dist/core-dashboards.module.d.ts +13 -18
- package/dist/core-dashboards.module.d.ts.map +1 -1
- package/dist/core-dashboards.module.js +18 -31
- package/dist/core-dashboards.module.js.map +1 -1
- package/dist/credentials-dashboards.module.d.ts +5 -8
- package/dist/credentials-dashboards.module.d.ts.map +1 -1
- package/dist/credentials-dashboards.module.js +3 -19
- package/dist/credentials-dashboards.module.js.map +1 -1
- package/dist/data-explorer-dashboards.module.d.ts +7 -13
- package/dist/data-explorer-dashboards.module.d.ts.map +1 -1
- package/dist/data-explorer-dashboards.module.js +0 -27
- package/dist/data-explorer-dashboards.module.js.map +1 -1
- package/dist/lists-dashboards.module.d.ts +5 -8
- package/dist/lists-dashboards.module.d.ts.map +1 -1
- package/dist/lists-dashboards.module.js +3 -19
- package/dist/lists-dashboards.module.js.map +1 -1
- package/dist/public-api.d.ts +5 -1
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +6 -1
- package/dist/public-api.js.map +1 -1
- package/dist/scheduling-dashboards.module.d.ts +6 -10
- package/dist/scheduling-dashboards.module.d.ts.map +1 -1
- package/dist/scheduling-dashboards.module.js +3 -23
- package/dist/scheduling-dashboards.module.js.map +1 -1
- package/dist/testing-dashboards.module.d.ts +7 -12
- package/dist/testing-dashboards.module.d.ts.map +1 -1
- package/dist/testing-dashboards.module.js +4 -27
- package/dist/testing-dashboards.module.js.map +1 -1
- package/package.json +47 -53
|
@@ -0,0 +1,2792 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* @fileoverview Content Autotagging Dashboard
|
|
9
|
+
*
|
|
10
|
+
* Full dashboard for the content autotagging pipeline with left-nav and 5 tabs:
|
|
11
|
+
* Pipeline Monitor, Sources Management, Content Types, Tag Library, Run History.
|
|
12
|
+
* Supports CRUD on sources and content types via slide-in forms,
|
|
13
|
+
* pipeline triggering with real-time GraphQL subscription progress.
|
|
14
|
+
*/
|
|
15
|
+
import { Component, ChangeDetectorRef, inject, ViewEncapsulation } from '@angular/core';
|
|
16
|
+
import { Subject } from 'rxjs';
|
|
17
|
+
import { takeUntil } from 'rxjs/operators';
|
|
18
|
+
import { CompositeKey, Metadata, RunView } from '@memberjunction/core';
|
|
19
|
+
import { KnowledgeHubMetadataEngine } from '@memberjunction/core-entities';
|
|
20
|
+
import { RegisterClass, UUIDsEqual } from '@memberjunction/global';
|
|
21
|
+
import { BaseResourceComponent, NavigationService } from '@memberjunction/ng-shared';
|
|
22
|
+
import { GraphQLAIClient } from '@memberjunction/graphql-dataprovider';
|
|
23
|
+
import { MJNotificationService } from '@memberjunction/ng-notifications';
|
|
24
|
+
import { AIEngineBase } from '@memberjunction/ai-engine-base';
|
|
25
|
+
import * as i0 from "@angular/core";
|
|
26
|
+
import * as i1 from "@angular/forms";
|
|
27
|
+
import * as i2 from "@memberjunction/ng-shared-generic";
|
|
28
|
+
import * as i3 from "@memberjunction/ng-trees";
|
|
29
|
+
import * as i4 from "@angular/common";
|
|
30
|
+
const _forTrack0 = ($index, $item) => $item.Tab;
|
|
31
|
+
const _forTrack1 = ($index, $item) => $item.Label;
|
|
32
|
+
const _forTrack2 = ($index, $item) => $item.ID;
|
|
33
|
+
const _forTrack3 = ($index, $item) => $item.Tag;
|
|
34
|
+
const _forTrack4 = ($index, $item) => $item.SourceName;
|
|
35
|
+
function AutotaggingPipelineResourceComponent_For_8_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
36
|
+
i0.ɵɵelementStart(0, "span", 14);
|
|
37
|
+
i0.ɵɵtext(1);
|
|
38
|
+
i0.ɵɵelementEnd();
|
|
39
|
+
} if (rf & 2) {
|
|
40
|
+
const item_r2 = i0.ɵɵnextContext().$implicit;
|
|
41
|
+
i0.ɵɵclassProp("at-nav-badge-live", item_r2.BadgeClass === "nav-badge-live");
|
|
42
|
+
i0.ɵɵadvance();
|
|
43
|
+
i0.ɵɵtextInterpolate(item_r2.BadgeText);
|
|
44
|
+
} }
|
|
45
|
+
function AutotaggingPipelineResourceComponent_For_8_Template(rf, ctx) { if (rf & 1) {
|
|
46
|
+
const _r1 = i0.ɵɵgetCurrentView();
|
|
47
|
+
i0.ɵɵelementStart(0, "div", 7);
|
|
48
|
+
i0.ɵɵlistener("click", function AutotaggingPipelineResourceComponent_For_8_Template_div_click_0_listener() { const item_r2 = i0.ɵɵrestoreView(_r1).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.SwitchTab(item_r2.Tab)); });
|
|
49
|
+
i0.ɵɵelement(1, "i");
|
|
50
|
+
i0.ɵɵtext(2);
|
|
51
|
+
i0.ɵɵconditionalCreate(3, AutotaggingPipelineResourceComponent_For_8_Conditional_3_Template, 2, 3, "span", 13);
|
|
52
|
+
i0.ɵɵelementEnd();
|
|
53
|
+
} if (rf & 2) {
|
|
54
|
+
const item_r2 = ctx.$implicit;
|
|
55
|
+
const ctx_r2 = i0.ɵɵnextContext();
|
|
56
|
+
i0.ɵɵclassProp("active", ctx_r2.ActiveTab === item_r2.Tab);
|
|
57
|
+
i0.ɵɵadvance();
|
|
58
|
+
i0.ɵɵclassMap(item_r2.Icon);
|
|
59
|
+
i0.ɵɵadvance();
|
|
60
|
+
i0.ɵɵtextInterpolate1(" ", item_r2.Label, " ");
|
|
61
|
+
i0.ɵɵadvance();
|
|
62
|
+
i0.ɵɵconditional(item_r2.BadgeText ? 3 : -1);
|
|
63
|
+
} }
|
|
64
|
+
function AutotaggingPipelineResourceComponent_Conditional_15_Template(rf, ctx) { if (rf & 1) {
|
|
65
|
+
i0.ɵɵelement(0, "i", 15);
|
|
66
|
+
i0.ɵɵtext(1, " Running... ");
|
|
67
|
+
} }
|
|
68
|
+
function AutotaggingPipelineResourceComponent_Conditional_16_Template(rf, ctx) { if (rf & 1) {
|
|
69
|
+
i0.ɵɵelement(0, "i", 16);
|
|
70
|
+
i0.ɵɵtext(1, " Run Pipeline ");
|
|
71
|
+
} }
|
|
72
|
+
function AutotaggingPipelineResourceComponent_Conditional_18_Template(rf, ctx) { if (rf & 1) {
|
|
73
|
+
i0.ɵɵelementStart(0, "div", 12);
|
|
74
|
+
i0.ɵɵelement(1, "mj-loading", 17);
|
|
75
|
+
i0.ɵɵelementEnd();
|
|
76
|
+
} }
|
|
77
|
+
function AutotaggingPipelineResourceComponent_Conditional_19_Conditional_0_For_13_Conditional_6_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
78
|
+
i0.ɵɵelement(0, "i", 50);
|
|
79
|
+
} }
|
|
80
|
+
function AutotaggingPipelineResourceComponent_Conditional_19_Conditional_0_For_13_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
81
|
+
i0.ɵɵelementStart(0, "div", 49);
|
|
82
|
+
i0.ɵɵconditionalCreate(1, AutotaggingPipelineResourceComponent_Conditional_19_Conditional_0_For_13_Conditional_6_Conditional_1_Template, 1, 0, "i", 50);
|
|
83
|
+
i0.ɵɵtext(2);
|
|
84
|
+
i0.ɵɵelementEnd();
|
|
85
|
+
} if (rf & 2) {
|
|
86
|
+
const kpi_r5 = i0.ɵɵnextContext().$implicit;
|
|
87
|
+
i0.ɵɵclassProp("up", kpi_r5.TrendUp);
|
|
88
|
+
i0.ɵɵadvance();
|
|
89
|
+
i0.ɵɵconditional(kpi_r5.TrendUp ? 1 : -1);
|
|
90
|
+
i0.ɵɵadvance();
|
|
91
|
+
i0.ɵɵtextInterpolate1(" ", kpi_r5.Trend, " ");
|
|
92
|
+
} }
|
|
93
|
+
function AutotaggingPipelineResourceComponent_Conditional_19_Conditional_0_For_13_Template(rf, ctx) { if (rf & 1) {
|
|
94
|
+
i0.ɵɵelementStart(0, "div", 26)(1, "div", 46);
|
|
95
|
+
i0.ɵɵtext(2);
|
|
96
|
+
i0.ɵɵpipe(3, "number");
|
|
97
|
+
i0.ɵɵelementEnd();
|
|
98
|
+
i0.ɵɵelementStart(4, "div", 47);
|
|
99
|
+
i0.ɵɵtext(5);
|
|
100
|
+
i0.ɵɵelementEnd();
|
|
101
|
+
i0.ɵɵconditionalCreate(6, AutotaggingPipelineResourceComponent_Conditional_19_Conditional_0_For_13_Conditional_6_Template, 3, 4, "div", 48);
|
|
102
|
+
i0.ɵɵelementEnd();
|
|
103
|
+
} if (rf & 2) {
|
|
104
|
+
const kpi_r5 = ctx.$implicit;
|
|
105
|
+
i0.ɵɵadvance();
|
|
106
|
+
i0.ɵɵclassProp("at-kpi-error-value", kpi_r5.Label === "Errors" && kpi_r5.Value > 0);
|
|
107
|
+
i0.ɵɵadvance();
|
|
108
|
+
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind1(3, 5, kpi_r5.Value));
|
|
109
|
+
i0.ɵɵadvance(3);
|
|
110
|
+
i0.ɵɵtextInterpolate(kpi_r5.Label);
|
|
111
|
+
i0.ɵɵadvance();
|
|
112
|
+
i0.ɵɵconditional(kpi_r5.Trend ? 6 : -1);
|
|
113
|
+
} }
|
|
114
|
+
function AutotaggingPipelineResourceComponent_Conditional_19_Conditional_0_Conditional_16_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
115
|
+
i0.ɵɵelementStart(0, "div", 56);
|
|
116
|
+
i0.ɵɵtext(1);
|
|
117
|
+
i0.ɵɵelementEnd();
|
|
118
|
+
} if (rf & 2) {
|
|
119
|
+
const ctx_r2 = i0.ɵɵnextContext(4);
|
|
120
|
+
i0.ɵɵadvance();
|
|
121
|
+
i0.ɵɵtextInterpolate(ctx_r2.RunCurrentItem);
|
|
122
|
+
} }
|
|
123
|
+
function AutotaggingPipelineResourceComponent_Conditional_19_Conditional_0_Conditional_16_Template(rf, ctx) { if (rf & 1) {
|
|
124
|
+
i0.ɵɵelementStart(0, "div", 29)(1, "div", 51)(2, "span", 52);
|
|
125
|
+
i0.ɵɵtext(3);
|
|
126
|
+
i0.ɵɵelementEnd();
|
|
127
|
+
i0.ɵɵelementStart(4, "span", 53);
|
|
128
|
+
i0.ɵɵtext(5);
|
|
129
|
+
i0.ɵɵelementEnd()();
|
|
130
|
+
i0.ɵɵelementStart(6, "div", 54);
|
|
131
|
+
i0.ɵɵelement(7, "div", 55);
|
|
132
|
+
i0.ɵɵelementEnd();
|
|
133
|
+
i0.ɵɵconditionalCreate(8, AutotaggingPipelineResourceComponent_Conditional_19_Conditional_0_Conditional_16_Conditional_8_Template, 2, 1, "div", 56);
|
|
134
|
+
i0.ɵɵelementEnd();
|
|
135
|
+
} if (rf & 2) {
|
|
136
|
+
const ctx_r2 = i0.ɵɵnextContext(3);
|
|
137
|
+
i0.ɵɵadvance(3);
|
|
138
|
+
i0.ɵɵtextInterpolate(ctx_r2.RunStage);
|
|
139
|
+
i0.ɵɵadvance(2);
|
|
140
|
+
i0.ɵɵtextInterpolate1("", ctx_r2.RunProgress, "%");
|
|
141
|
+
i0.ɵɵadvance(2);
|
|
142
|
+
i0.ɵɵstyleProp("width", ctx_r2.RunProgress, "%");
|
|
143
|
+
i0.ɵɵadvance();
|
|
144
|
+
i0.ɵɵconditional(ctx_r2.RunCurrentItem ? 8 : -1);
|
|
145
|
+
} }
|
|
146
|
+
function AutotaggingPipelineResourceComponent_Conditional_19_Conditional_0_Conditional_23_Template(rf, ctx) { if (rf & 1) {
|
|
147
|
+
i0.ɵɵelementStart(0, "div", 35);
|
|
148
|
+
i0.ɵɵelement(1, "i", 57);
|
|
149
|
+
i0.ɵɵelementStart(2, "p");
|
|
150
|
+
i0.ɵɵtext(3, "No processed items yet.");
|
|
151
|
+
i0.ɵɵelementEnd()();
|
|
152
|
+
} }
|
|
153
|
+
function AutotaggingPipelineResourceComponent_Conditional_19_Conditional_0_For_25_For_8_Template(rf, ctx) { if (rf & 1) {
|
|
154
|
+
i0.ɵɵelementStart(0, "span", 63);
|
|
155
|
+
i0.ɵɵtext(1);
|
|
156
|
+
i0.ɵɵelementEnd();
|
|
157
|
+
} if (rf & 2) {
|
|
158
|
+
const tag_r8 = ctx.$implicit;
|
|
159
|
+
i0.ɵɵadvance();
|
|
160
|
+
i0.ɵɵtextInterpolate(tag_r8);
|
|
161
|
+
} }
|
|
162
|
+
function AutotaggingPipelineResourceComponent_Conditional_19_Conditional_0_For_25_Template(rf, ctx) { if (rf & 1) {
|
|
163
|
+
const _r6 = i0.ɵɵgetCurrentView();
|
|
164
|
+
i0.ɵɵelementStart(0, "div", 58);
|
|
165
|
+
i0.ɵɵlistener("click", function AutotaggingPipelineResourceComponent_Conditional_19_Conditional_0_For_25_Template_div_click_0_listener() { const $index_r7 = i0.ɵɵrestoreView(_r6).$index; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.OpenFeedItemDetail($index_r7)); });
|
|
166
|
+
i0.ɵɵelement(1, "div", 59);
|
|
167
|
+
i0.ɵɵelementStart(2, "span", 60);
|
|
168
|
+
i0.ɵɵtext(3);
|
|
169
|
+
i0.ɵɵelementEnd();
|
|
170
|
+
i0.ɵɵelementStart(4, "span", 61);
|
|
171
|
+
i0.ɵɵtext(5);
|
|
172
|
+
i0.ɵɵelementEnd();
|
|
173
|
+
i0.ɵɵelementStart(6, "div", 62);
|
|
174
|
+
i0.ɵɵrepeaterCreate(7, AutotaggingPipelineResourceComponent_Conditional_19_Conditional_0_For_25_For_8_Template, 2, 1, "span", 63, i0.ɵɵrepeaterTrackByIdentity);
|
|
175
|
+
i0.ɵɵelementEnd();
|
|
176
|
+
i0.ɵɵelementStart(9, "span", 64);
|
|
177
|
+
i0.ɵɵtext(10);
|
|
178
|
+
i0.ɵɵelementEnd()();
|
|
179
|
+
} if (rf & 2) {
|
|
180
|
+
const item_r9 = ctx.$implicit;
|
|
181
|
+
i0.ɵɵadvance();
|
|
182
|
+
i0.ɵɵclassMap(item_r9.Status);
|
|
183
|
+
i0.ɵɵadvance(2);
|
|
184
|
+
i0.ɵɵtextInterpolate(item_r9.Name);
|
|
185
|
+
i0.ɵɵadvance(2);
|
|
186
|
+
i0.ɵɵtextInterpolate(item_r9.SourceName);
|
|
187
|
+
i0.ɵɵadvance(2);
|
|
188
|
+
i0.ɵɵrepeater(item_r9.Tags);
|
|
189
|
+
i0.ɵɵadvance(3);
|
|
190
|
+
i0.ɵɵtextInterpolate(item_r9.TimeAgo);
|
|
191
|
+
} }
|
|
192
|
+
function AutotaggingPipelineResourceComponent_Conditional_19_Conditional_0_For_34_Template(rf, ctx) { if (rf & 1) {
|
|
193
|
+
i0.ɵɵelementStart(0, "div", 40)(1, "div", 65);
|
|
194
|
+
i0.ɵɵelement(2, "i");
|
|
195
|
+
i0.ɵɵelementEnd();
|
|
196
|
+
i0.ɵɵelementStart(3, "div", 66)(4, "div", 67);
|
|
197
|
+
i0.ɵɵtext(5);
|
|
198
|
+
i0.ɵɵelementEnd();
|
|
199
|
+
i0.ɵɵelementStart(6, "div", 68);
|
|
200
|
+
i0.ɵɵtext(7);
|
|
201
|
+
i0.ɵɵelementEnd()();
|
|
202
|
+
i0.ɵɵelement(8, "div", 69);
|
|
203
|
+
i0.ɵɵelementEnd();
|
|
204
|
+
} if (rf & 2) {
|
|
205
|
+
const source_r10 = ctx.$implicit;
|
|
206
|
+
i0.ɵɵadvance(2);
|
|
207
|
+
i0.ɵɵclassMap(source_r10.Icon);
|
|
208
|
+
i0.ɵɵadvance(3);
|
|
209
|
+
i0.ɵɵtextInterpolate(source_r10.Name);
|
|
210
|
+
i0.ɵɵadvance(2);
|
|
211
|
+
i0.ɵɵtextInterpolate(source_r10.Meta);
|
|
212
|
+
i0.ɵɵadvance();
|
|
213
|
+
i0.ɵɵclassMap(source_r10.StatusClass);
|
|
214
|
+
} }
|
|
215
|
+
function AutotaggingPipelineResourceComponent_Conditional_19_Conditional_0_For_41_Template(rf, ctx) { if (rf & 1) {
|
|
216
|
+
i0.ɵɵelementStart(0, "span", 70);
|
|
217
|
+
i0.ɵɵtext(1);
|
|
218
|
+
i0.ɵɵelementEnd();
|
|
219
|
+
} if (rf & 2) {
|
|
220
|
+
const tag_r11 = ctx.$implicit;
|
|
221
|
+
i0.ɵɵclassMap(tag_r11.SizeClass);
|
|
222
|
+
i0.ɵɵstyleProp("opacity", 0.4 + tag_r11.AvgWeight * 0.6);
|
|
223
|
+
i0.ɵɵproperty("title", "Weight: " + tag_r11.AvgWeight.toFixed(2));
|
|
224
|
+
i0.ɵɵadvance();
|
|
225
|
+
i0.ɵɵtextInterpolate(tag_r11.Tag);
|
|
226
|
+
} }
|
|
227
|
+
function AutotaggingPipelineResourceComponent_Conditional_19_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
228
|
+
const _r4 = i0.ɵɵgetCurrentView();
|
|
229
|
+
i0.ɵɵelementStart(0, "div", 18)(1, "div")(2, "div", 19);
|
|
230
|
+
i0.ɵɵtext(3, "Pipeline Monitor");
|
|
231
|
+
i0.ɵɵelementEnd();
|
|
232
|
+
i0.ɵɵelementStart(4, "div", 20);
|
|
233
|
+
i0.ɵɵtext(5, "Real-time processing status and recent activity");
|
|
234
|
+
i0.ɵɵelementEnd()();
|
|
235
|
+
i0.ɵɵelementStart(6, "div", 21)(7, "button", 22);
|
|
236
|
+
i0.ɵɵlistener("click", function AutotaggingPipelineResourceComponent_Conditional_19_Conditional_0_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.LoadPipelineData()); });
|
|
237
|
+
i0.ɵɵelement(8, "i", 23);
|
|
238
|
+
i0.ɵɵtext(9, " Refresh ");
|
|
239
|
+
i0.ɵɵelementEnd()()();
|
|
240
|
+
i0.ɵɵelementStart(10, "div", 24)(11, "div", 25);
|
|
241
|
+
i0.ɵɵrepeaterCreate(12, AutotaggingPipelineResourceComponent_Conditional_19_Conditional_0_For_13_Template, 7, 7, "div", 26, _forTrack1);
|
|
242
|
+
i0.ɵɵelementEnd();
|
|
243
|
+
i0.ɵɵelementStart(14, "div", 27)(15, "div", 28);
|
|
244
|
+
i0.ɵɵconditionalCreate(16, AutotaggingPipelineResourceComponent_Conditional_19_Conditional_0_Conditional_16_Template, 9, 5, "div", 29);
|
|
245
|
+
i0.ɵɵelementStart(17, "div", 30)(18, "div", 31)(19, "span", 32);
|
|
246
|
+
i0.ɵɵelement(20, "i", 33);
|
|
247
|
+
i0.ɵɵtext(21, " Recent Processing");
|
|
248
|
+
i0.ɵɵelementEnd()();
|
|
249
|
+
i0.ɵɵelementStart(22, "div", 34);
|
|
250
|
+
i0.ɵɵconditionalCreate(23, AutotaggingPipelineResourceComponent_Conditional_19_Conditional_0_Conditional_23_Template, 4, 0, "div", 35);
|
|
251
|
+
i0.ɵɵrepeaterCreate(24, AutotaggingPipelineResourceComponent_Conditional_19_Conditional_0_For_25_Template, 11, 5, "div", 36, i0.ɵɵrepeaterTrackByIndex);
|
|
252
|
+
i0.ɵɵelementEnd()()();
|
|
253
|
+
i0.ɵɵelementStart(26, "div", 37)(27, "div", 38)(28, "div", 31)(29, "span", 32);
|
|
254
|
+
i0.ɵɵelement(30, "i", 39);
|
|
255
|
+
i0.ɵɵtext(31, " Sources");
|
|
256
|
+
i0.ɵɵelementEnd()();
|
|
257
|
+
i0.ɵɵelementStart(32, "div", 34);
|
|
258
|
+
i0.ɵɵrepeaterCreate(33, AutotaggingPipelineResourceComponent_Conditional_19_Conditional_0_For_34_Template, 9, 6, "div", 40, _forTrack2);
|
|
259
|
+
i0.ɵɵelementEnd()();
|
|
260
|
+
i0.ɵɵelementStart(35, "div", 41)(36, "div", 42);
|
|
261
|
+
i0.ɵɵelement(37, "i", 43);
|
|
262
|
+
i0.ɵɵtext(38, " Trending Tags");
|
|
263
|
+
i0.ɵɵelementEnd();
|
|
264
|
+
i0.ɵɵelementStart(39, "div", 44);
|
|
265
|
+
i0.ɵɵrepeaterCreate(40, AutotaggingPipelineResourceComponent_Conditional_19_Conditional_0_For_41_Template, 2, 6, "span", 45, _forTrack3);
|
|
266
|
+
i0.ɵɵelementEnd()()()()();
|
|
267
|
+
} if (rf & 2) {
|
|
268
|
+
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
269
|
+
i0.ɵɵadvance(12);
|
|
270
|
+
i0.ɵɵrepeater(ctx_r2.KPIMetrics);
|
|
271
|
+
i0.ɵɵadvance(4);
|
|
272
|
+
i0.ɵɵconditional(ctx_r2.IsRunning ? 16 : -1);
|
|
273
|
+
i0.ɵɵadvance(7);
|
|
274
|
+
i0.ɵɵconditional(ctx_r2.FeedItems.length === 0 ? 23 : -1);
|
|
275
|
+
i0.ɵɵadvance();
|
|
276
|
+
i0.ɵɵrepeater(ctx_r2.FeedItems);
|
|
277
|
+
i0.ɵɵadvance(9);
|
|
278
|
+
i0.ɵɵrepeater(ctx_r2.SourceMinis);
|
|
279
|
+
i0.ɵɵadvance(7);
|
|
280
|
+
i0.ɵɵrepeater(ctx_r2.TrendingTags);
|
|
281
|
+
} }
|
|
282
|
+
function AutotaggingPipelineResourceComponent_Conditional_19_Conditional_1_For_13_Conditional_12_Template(rf, ctx) { if (rf & 1) {
|
|
283
|
+
i0.ɵɵelementStart(0, "div", 85);
|
|
284
|
+
i0.ɵɵtext(1);
|
|
285
|
+
i0.ɵɵelementEnd();
|
|
286
|
+
} if (rf & 2) {
|
|
287
|
+
const card_r14 = i0.ɵɵnextContext().$implicit;
|
|
288
|
+
i0.ɵɵadvance();
|
|
289
|
+
i0.ɵɵtextInterpolate(card_r14.URL);
|
|
290
|
+
} }
|
|
291
|
+
function AutotaggingPipelineResourceComponent_Conditional_19_Conditional_1_For_13_Template(rf, ctx) { if (rf & 1) {
|
|
292
|
+
const _r13 = i0.ɵɵgetCurrentView();
|
|
293
|
+
i0.ɵɵelementStart(0, "div", 79);
|
|
294
|
+
i0.ɵɵlistener("click", function AutotaggingPipelineResourceComponent_Conditional_19_Conditional_1_For_13_Template_div_click_0_listener() { const card_r14 = i0.ɵɵrestoreView(_r13).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.OpenSourceDetail(card_r14)); });
|
|
295
|
+
i0.ɵɵelementStart(1, "div", 80)(2, "div", 81);
|
|
296
|
+
i0.ɵɵelement(3, "i");
|
|
297
|
+
i0.ɵɵelementEnd();
|
|
298
|
+
i0.ɵɵelementStart(4, "div")(5, "div", 82);
|
|
299
|
+
i0.ɵɵtext(6);
|
|
300
|
+
i0.ɵɵelementEnd();
|
|
301
|
+
i0.ɵɵelementStart(7, "div", 83);
|
|
302
|
+
i0.ɵɵtext(8);
|
|
303
|
+
i0.ɵɵelementEnd()();
|
|
304
|
+
i0.ɵɵelementStart(9, "div", 84);
|
|
305
|
+
i0.ɵɵelement(10, "div", 69);
|
|
306
|
+
i0.ɵɵtext(11);
|
|
307
|
+
i0.ɵɵelementEnd()();
|
|
308
|
+
i0.ɵɵconditionalCreate(12, AutotaggingPipelineResourceComponent_Conditional_19_Conditional_1_For_13_Conditional_12_Template, 2, 1, "div", 85);
|
|
309
|
+
i0.ɵɵelementStart(13, "div", 86)(14, "div", 87)(15, "div", 88);
|
|
310
|
+
i0.ɵɵtext(16);
|
|
311
|
+
i0.ɵɵelementEnd();
|
|
312
|
+
i0.ɵɵelementStart(17, "div", 89);
|
|
313
|
+
i0.ɵɵtext(18, "Items");
|
|
314
|
+
i0.ɵɵelementEnd()();
|
|
315
|
+
i0.ɵɵelementStart(19, "div", 87)(20, "div", 88);
|
|
316
|
+
i0.ɵɵtext(21);
|
|
317
|
+
i0.ɵɵelementEnd();
|
|
318
|
+
i0.ɵɵelementStart(22, "div", 89);
|
|
319
|
+
i0.ɵɵtext(23, "Tags");
|
|
320
|
+
i0.ɵɵelementEnd()();
|
|
321
|
+
i0.ɵɵelementStart(24, "div", 87)(25, "div", 88);
|
|
322
|
+
i0.ɵɵtext(26);
|
|
323
|
+
i0.ɵɵelementEnd();
|
|
324
|
+
i0.ɵɵelementStart(27, "div", 89);
|
|
325
|
+
i0.ɵɵtext(28, "Avg Tags");
|
|
326
|
+
i0.ɵɵelementEnd()();
|
|
327
|
+
i0.ɵɵelementStart(29, "div", 87)(30, "div", 88);
|
|
328
|
+
i0.ɵɵtext(31);
|
|
329
|
+
i0.ɵɵelementEnd();
|
|
330
|
+
i0.ɵɵelementStart(32, "div", 89);
|
|
331
|
+
i0.ɵɵtext(33, "Last Run");
|
|
332
|
+
i0.ɵɵelementEnd()()();
|
|
333
|
+
i0.ɵɵelementStart(34, "div", 90)(35, "button", 91);
|
|
334
|
+
i0.ɵɵlistener("click", function AutotaggingPipelineResourceComponent_Conditional_19_Conditional_1_For_13_Template_button_click_35_listener($event) { const card_r14 = i0.ɵɵrestoreView(_r13).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); ctx_r2.OpenEditSourceForm(card_r14); return i0.ɵɵresetView($event.stopPropagation()); });
|
|
335
|
+
i0.ɵɵelement(36, "i", 92);
|
|
336
|
+
i0.ɵɵtext(37, " Edit");
|
|
337
|
+
i0.ɵɵelementEnd();
|
|
338
|
+
i0.ɵɵelementStart(38, "button", 91);
|
|
339
|
+
i0.ɵɵlistener("click", function AutotaggingPipelineResourceComponent_Conditional_19_Conditional_1_For_13_Template_button_click_38_listener($event) { i0.ɵɵrestoreView(_r13); const ctx_r2 = i0.ɵɵnextContext(3); ctx_r2.RunPipeline(); return i0.ɵɵresetView($event.stopPropagation()); });
|
|
340
|
+
i0.ɵɵelement(39, "i", 16);
|
|
341
|
+
i0.ɵɵtext(40, " Run");
|
|
342
|
+
i0.ɵɵelementEnd();
|
|
343
|
+
i0.ɵɵelementStart(41, "button", 93);
|
|
344
|
+
i0.ɵɵlistener("click", function AutotaggingPipelineResourceComponent_Conditional_19_Conditional_1_For_13_Template_button_click_41_listener($event) { const card_r14 = i0.ɵɵrestoreView(_r13).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); ctx_r2.DeleteSource(card_r14); return i0.ɵɵresetView($event.stopPropagation()); });
|
|
345
|
+
i0.ɵɵelement(42, "i", 94);
|
|
346
|
+
i0.ɵɵtext(43, " Delete");
|
|
347
|
+
i0.ɵɵelementEnd()()();
|
|
348
|
+
} if (rf & 2) {
|
|
349
|
+
const card_r14 = ctx.$implicit;
|
|
350
|
+
const ctx_r2 = i0.ɵɵnextContext(3);
|
|
351
|
+
i0.ɵɵadvance(3);
|
|
352
|
+
i0.ɵɵclassMap(card_r14.Icon);
|
|
353
|
+
i0.ɵɵadvance(3);
|
|
354
|
+
i0.ɵɵtextInterpolate(card_r14.Name);
|
|
355
|
+
i0.ɵɵadvance(2);
|
|
356
|
+
i0.ɵɵtextInterpolate2("", card_r14.SourceTypeName, " \u00B7 ", card_r14.FileTypeName);
|
|
357
|
+
i0.ɵɵadvance();
|
|
358
|
+
i0.ɵɵclassMap(card_r14.StatusClass);
|
|
359
|
+
i0.ɵɵadvance();
|
|
360
|
+
i0.ɵɵclassMap(card_r14.StatusClass);
|
|
361
|
+
i0.ɵɵadvance();
|
|
362
|
+
i0.ɵɵtextInterpolate1(" ", card_r14.StatusLabel, " ");
|
|
363
|
+
i0.ɵɵadvance();
|
|
364
|
+
i0.ɵɵconditional(card_r14.URL ? 12 : -1);
|
|
365
|
+
i0.ɵɵadvance(4);
|
|
366
|
+
i0.ɵɵtextInterpolate(ctx_r2.formatNumber(card_r14.ItemCount));
|
|
367
|
+
i0.ɵɵadvance(5);
|
|
368
|
+
i0.ɵɵtextInterpolate(ctx_r2.formatNumber(card_r14.TagCount));
|
|
369
|
+
i0.ɵɵadvance(5);
|
|
370
|
+
i0.ɵɵtextInterpolate(card_r14.AvgTags);
|
|
371
|
+
i0.ɵɵadvance(5);
|
|
372
|
+
i0.ɵɵtextInterpolate(card_r14.LastRunAgo);
|
|
373
|
+
} }
|
|
374
|
+
function AutotaggingPipelineResourceComponent_Conditional_19_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
375
|
+
const _r12 = i0.ɵɵgetCurrentView();
|
|
376
|
+
i0.ɵɵelementStart(0, "div", 18)(1, "div")(2, "div", 19);
|
|
377
|
+
i0.ɵɵtext(3, "Content Sources");
|
|
378
|
+
i0.ɵɵelementEnd();
|
|
379
|
+
i0.ɵɵelementStart(4, "div", 20);
|
|
380
|
+
i0.ɵɵtext(5, "Configure where content is ingested from");
|
|
381
|
+
i0.ɵɵelementEnd()();
|
|
382
|
+
i0.ɵɵelementStart(6, "div", 21)(7, "button", 71);
|
|
383
|
+
i0.ɵɵlistener("click", function AutotaggingPipelineResourceComponent_Conditional_19_Conditional_1_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r12); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.OpenAddSourceForm()); });
|
|
384
|
+
i0.ɵɵelement(8, "i", 72);
|
|
385
|
+
i0.ɵɵtext(9, " Add Source ");
|
|
386
|
+
i0.ɵɵelementEnd()()();
|
|
387
|
+
i0.ɵɵelementStart(10, "div", 24)(11, "div", 73);
|
|
388
|
+
i0.ɵɵrepeaterCreate(12, AutotaggingPipelineResourceComponent_Conditional_19_Conditional_1_For_13_Template, 44, 15, "div", 74, _forTrack2);
|
|
389
|
+
i0.ɵɵelementStart(14, "div", 75);
|
|
390
|
+
i0.ɵɵlistener("click", function AutotaggingPipelineResourceComponent_Conditional_19_Conditional_1_Template_div_click_14_listener() { i0.ɵɵrestoreView(_r12); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.OpenAddSourceForm()); });
|
|
391
|
+
i0.ɵɵelement(15, "i", 76);
|
|
392
|
+
i0.ɵɵelementStart(16, "span", 77);
|
|
393
|
+
i0.ɵɵtext(17, "Add Content Source");
|
|
394
|
+
i0.ɵɵelementEnd();
|
|
395
|
+
i0.ɵɵelementStart(18, "span", 78);
|
|
396
|
+
i0.ɵɵtext(19, "Web, RSS, Email, Files, API");
|
|
397
|
+
i0.ɵɵelementEnd()()()();
|
|
398
|
+
} if (rf & 2) {
|
|
399
|
+
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
400
|
+
i0.ɵɵadvance(12);
|
|
401
|
+
i0.ɵɵrepeater(ctx_r2.SourceCards);
|
|
402
|
+
} }
|
|
403
|
+
function AutotaggingPipelineResourceComponent_Conditional_19_Conditional_2_For_13_Template(rf, ctx) { if (rf & 1) {
|
|
404
|
+
const _r16 = i0.ɵɵgetCurrentView();
|
|
405
|
+
i0.ɵɵelementStart(0, "div", 96)(1, "div", 98)(2, "span", 99);
|
|
406
|
+
i0.ɵɵtext(3);
|
|
407
|
+
i0.ɵɵelementEnd();
|
|
408
|
+
i0.ɵɵelementStart(4, "span", 100);
|
|
409
|
+
i0.ɵɵtext(5);
|
|
410
|
+
i0.ɵɵelementEnd()();
|
|
411
|
+
i0.ɵɵelementStart(6, "div", 101)(7, "span", 102);
|
|
412
|
+
i0.ɵɵtext(8, "Description");
|
|
413
|
+
i0.ɵɵelementEnd();
|
|
414
|
+
i0.ɵɵelementStart(9, "span", 103);
|
|
415
|
+
i0.ɵɵtext(10);
|
|
416
|
+
i0.ɵɵelementEnd()();
|
|
417
|
+
i0.ɵɵelementStart(11, "div", 101)(12, "span", 102);
|
|
418
|
+
i0.ɵɵtext(13, "Sources Using");
|
|
419
|
+
i0.ɵɵelementEnd();
|
|
420
|
+
i0.ɵɵelementStart(14, "span", 103);
|
|
421
|
+
i0.ɵɵtext(15);
|
|
422
|
+
i0.ɵɵelementEnd()();
|
|
423
|
+
i0.ɵɵelementStart(16, "div", 101)(17, "span", 102);
|
|
424
|
+
i0.ɵɵtext(18, "Items Tagged");
|
|
425
|
+
i0.ɵɵelementEnd();
|
|
426
|
+
i0.ɵɵelementStart(19, "span", 103);
|
|
427
|
+
i0.ɵɵtext(20);
|
|
428
|
+
i0.ɵɵelementEnd()();
|
|
429
|
+
i0.ɵɵelementStart(21, "div", 104);
|
|
430
|
+
i0.ɵɵelement(22, "i", 3);
|
|
431
|
+
i0.ɵɵelementStart(23, "span");
|
|
432
|
+
i0.ɵɵtext(24);
|
|
433
|
+
i0.ɵɵelementEnd();
|
|
434
|
+
i0.ɵɵelementStart(25, "div", 105);
|
|
435
|
+
i0.ɵɵelement(26, "div", 106);
|
|
436
|
+
i0.ɵɵelementEnd();
|
|
437
|
+
i0.ɵɵelementStart(27, "span");
|
|
438
|
+
i0.ɵɵtext(28);
|
|
439
|
+
i0.ɵɵelementEnd();
|
|
440
|
+
i0.ɵɵelementStart(29, "span", 107);
|
|
441
|
+
i0.ɵɵtext(30, "tags/item");
|
|
442
|
+
i0.ɵɵelementEnd()();
|
|
443
|
+
i0.ɵɵelementStart(31, "div", 108)(32, "button", 91);
|
|
444
|
+
i0.ɵɵlistener("click", function AutotaggingPipelineResourceComponent_Conditional_19_Conditional_2_For_13_Template_button_click_32_listener() { const card_r17 = i0.ɵɵrestoreView(_r16).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.OpenEditTypeForm(card_r17)); });
|
|
445
|
+
i0.ɵɵelement(33, "i", 92);
|
|
446
|
+
i0.ɵɵtext(34, " Edit");
|
|
447
|
+
i0.ɵɵelementEnd()()();
|
|
448
|
+
} if (rf & 2) {
|
|
449
|
+
const card_r17 = ctx.$implicit;
|
|
450
|
+
const ctx_r2 = i0.ɵɵnextContext(3);
|
|
451
|
+
i0.ɵɵadvance(3);
|
|
452
|
+
i0.ɵɵtextInterpolate(card_r17.Name);
|
|
453
|
+
i0.ɵɵadvance(2);
|
|
454
|
+
i0.ɵɵtextInterpolate(card_r17.AIModelName);
|
|
455
|
+
i0.ɵɵadvance(5);
|
|
456
|
+
i0.ɵɵtextInterpolate(card_r17.Description || "\u2014");
|
|
457
|
+
i0.ɵɵadvance(5);
|
|
458
|
+
i0.ɵɵtextInterpolate(card_r17.SourcesUsing);
|
|
459
|
+
i0.ɵɵadvance(5);
|
|
460
|
+
i0.ɵɵtextInterpolate(ctx_r2.formatNumber(card_r17.ItemsTagged));
|
|
461
|
+
i0.ɵɵadvance(4);
|
|
462
|
+
i0.ɵɵtextInterpolate(card_r17.MinTags);
|
|
463
|
+
i0.ɵɵadvance(2);
|
|
464
|
+
i0.ɵɵstyleProp("left", card_r17.RangeLeftPct, "%")("right", card_r17.RangeRightPct, "%");
|
|
465
|
+
i0.ɵɵadvance(2);
|
|
466
|
+
i0.ɵɵtextInterpolate(card_r17.MaxTags);
|
|
467
|
+
} }
|
|
468
|
+
function AutotaggingPipelineResourceComponent_Conditional_19_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
469
|
+
const _r15 = i0.ɵɵgetCurrentView();
|
|
470
|
+
i0.ɵɵelementStart(0, "div", 18)(1, "div")(2, "div", 19);
|
|
471
|
+
i0.ɵɵtext(3, "Content Types");
|
|
472
|
+
i0.ɵɵelementEnd();
|
|
473
|
+
i0.ɵɵelementStart(4, "div", 20);
|
|
474
|
+
i0.ɵɵtext(5, "Configure AI tagging rules per content category");
|
|
475
|
+
i0.ɵɵelementEnd()();
|
|
476
|
+
i0.ɵɵelementStart(6, "div", 21)(7, "button", 71);
|
|
477
|
+
i0.ɵɵlistener("click", function AutotaggingPipelineResourceComponent_Conditional_19_Conditional_2_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r15); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.OpenAddTypeForm()); });
|
|
478
|
+
i0.ɵɵelement(8, "i", 72);
|
|
479
|
+
i0.ɵɵtext(9, " Add Type ");
|
|
480
|
+
i0.ɵɵelementEnd()()();
|
|
481
|
+
i0.ɵɵelementStart(10, "div", 24)(11, "div", 95);
|
|
482
|
+
i0.ɵɵrepeaterCreate(12, AutotaggingPipelineResourceComponent_Conditional_19_Conditional_2_For_13_Template, 35, 11, "div", 96, _forTrack2);
|
|
483
|
+
i0.ɵɵelementStart(14, "div", 97);
|
|
484
|
+
i0.ɵɵlistener("click", function AutotaggingPipelineResourceComponent_Conditional_19_Conditional_2_Template_div_click_14_listener() { i0.ɵɵrestoreView(_r15); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.OpenAddTypeForm()); });
|
|
485
|
+
i0.ɵɵelement(15, "i", 76);
|
|
486
|
+
i0.ɵɵelementStart(16, "span", 77);
|
|
487
|
+
i0.ɵɵtext(17, "Add Content Type");
|
|
488
|
+
i0.ɵɵelementEnd();
|
|
489
|
+
i0.ɵɵelementStart(18, "span", 78);
|
|
490
|
+
i0.ɵɵtext(19, "Configure tagging rules");
|
|
491
|
+
i0.ɵɵelementEnd()()()();
|
|
492
|
+
} if (rf & 2) {
|
|
493
|
+
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
494
|
+
i0.ɵɵadvance(12);
|
|
495
|
+
i0.ɵɵrepeater(ctx_r2.ContentTypeCards);
|
|
496
|
+
} }
|
|
497
|
+
function AutotaggingPipelineResourceComponent_Conditional_19_Conditional_3_For_30_Template(rf, ctx) { if (rf & 1) {
|
|
498
|
+
i0.ɵɵelementStart(0, "tr")(1, "td", 121);
|
|
499
|
+
i0.ɵɵtext(2);
|
|
500
|
+
i0.ɵɵelementEnd();
|
|
501
|
+
i0.ɵɵelementStart(3, "td");
|
|
502
|
+
i0.ɵɵtext(4);
|
|
503
|
+
i0.ɵɵelementEnd();
|
|
504
|
+
i0.ɵɵelementStart(5, "td")(6, "div", 122)(7, "div", 123);
|
|
505
|
+
i0.ɵɵelement(8, "div", 124);
|
|
506
|
+
i0.ɵɵelementEnd();
|
|
507
|
+
i0.ɵɵelementStart(9, "span", 125);
|
|
508
|
+
i0.ɵɵtext(10);
|
|
509
|
+
i0.ɵɵelementEnd()()();
|
|
510
|
+
i0.ɵɵelementStart(11, "td")(12, "div", 126);
|
|
511
|
+
i0.ɵɵelement(13, "div", 127);
|
|
512
|
+
i0.ɵɵelementEnd()();
|
|
513
|
+
i0.ɵɵelementStart(14, "td");
|
|
514
|
+
i0.ɵɵtext(15);
|
|
515
|
+
i0.ɵɵelementEnd();
|
|
516
|
+
i0.ɵɵelementStart(16, "td");
|
|
517
|
+
i0.ɵɵtext(17);
|
|
518
|
+
i0.ɵɵelementEnd()();
|
|
519
|
+
} if (rf & 2) {
|
|
520
|
+
const row_r19 = ctx.$implicit;
|
|
521
|
+
i0.ɵɵadvance(2);
|
|
522
|
+
i0.ɵɵtextInterpolate(row_r19.Tag);
|
|
523
|
+
i0.ɵɵadvance(2);
|
|
524
|
+
i0.ɵɵtextInterpolate(row_r19.UsageCount);
|
|
525
|
+
i0.ɵɵadvance(4);
|
|
526
|
+
i0.ɵɵstyleProp("width", row_r19.AvgWeight * 100, "%");
|
|
527
|
+
i0.ɵɵclassProp("at-weight-high", row_r19.AvgWeight >= 0.7)("at-weight-medium", row_r19.AvgWeight >= 0.4 && row_r19.AvgWeight < 0.7)("at-weight-low", row_r19.AvgWeight < 0.4);
|
|
528
|
+
i0.ɵɵadvance(2);
|
|
529
|
+
i0.ɵɵtextInterpolate(row_r19.AvgWeight.toFixed(2));
|
|
530
|
+
i0.ɵɵadvance(3);
|
|
531
|
+
i0.ɵɵstyleProp("width", row_r19.BarWidthPct, "%");
|
|
532
|
+
i0.ɵɵadvance(2);
|
|
533
|
+
i0.ɵɵtextInterpolate(row_r19.TopSource);
|
|
534
|
+
i0.ɵɵadvance(2);
|
|
535
|
+
i0.ɵɵtextInterpolate(row_r19.FirstSeen);
|
|
536
|
+
} }
|
|
537
|
+
function AutotaggingPipelineResourceComponent_Conditional_19_Conditional_3_For_38_Template(rf, ctx) { if (rf & 1) {
|
|
538
|
+
i0.ɵɵelementStart(0, "span", 70);
|
|
539
|
+
i0.ɵɵtext(1);
|
|
540
|
+
i0.ɵɵelementEnd();
|
|
541
|
+
} if (rf & 2) {
|
|
542
|
+
const tag_r20 = ctx.$implicit;
|
|
543
|
+
i0.ɵɵclassMap(tag_r20.SizeClass);
|
|
544
|
+
i0.ɵɵstyleProp("opacity", 0.4 + tag_r20.AvgWeight * 0.6);
|
|
545
|
+
i0.ɵɵproperty("title", "Weight: " + tag_r20.AvgWeight.toFixed(2));
|
|
546
|
+
i0.ɵɵadvance();
|
|
547
|
+
i0.ɵɵtextInterpolate(tag_r20.Tag);
|
|
548
|
+
} }
|
|
549
|
+
function AutotaggingPipelineResourceComponent_Conditional_19_Conditional_3_For_45_Template(rf, ctx) { if (rf & 1) {
|
|
550
|
+
i0.ɵɵelementStart(0, "div", 120)(1, "span");
|
|
551
|
+
i0.ɵɵtext(2);
|
|
552
|
+
i0.ɵɵelementEnd();
|
|
553
|
+
i0.ɵɵelementStart(3, "strong");
|
|
554
|
+
i0.ɵɵtext(4);
|
|
555
|
+
i0.ɵɵelementEnd()();
|
|
556
|
+
} if (rf & 2) {
|
|
557
|
+
const s_r21 = ctx.$implicit;
|
|
558
|
+
i0.ɵɵadvance(2);
|
|
559
|
+
i0.ɵɵtextInterpolate(s_r21.SourceName);
|
|
560
|
+
i0.ɵɵadvance(2);
|
|
561
|
+
i0.ɵɵtextInterpolate(s_r21.Count);
|
|
562
|
+
} }
|
|
563
|
+
function AutotaggingPipelineResourceComponent_Conditional_19_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
564
|
+
const _r18 = i0.ɵɵgetCurrentView();
|
|
565
|
+
i0.ɵɵelementStart(0, "div", 18)(1, "div")(2, "div", 19);
|
|
566
|
+
i0.ɵɵtext(3, "Tag Library");
|
|
567
|
+
i0.ɵɵelementEnd();
|
|
568
|
+
i0.ɵɵelementStart(4, "div", 20);
|
|
569
|
+
i0.ɵɵtext(5);
|
|
570
|
+
i0.ɵɵelementEnd()();
|
|
571
|
+
i0.ɵɵelementStart(6, "div", 21)(7, "input", 109);
|
|
572
|
+
i0.ɵɵtwoWayListener("ngModelChange", function AutotaggingPipelineResourceComponent_Conditional_19_Conditional_3_Template_input_ngModelChange_7_listener($event) { i0.ɵɵrestoreView(_r18); const ctx_r2 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r2.TagSearchQuery, $event) || (ctx_r2.TagSearchQuery = $event); return i0.ɵɵresetView($event); });
|
|
573
|
+
i0.ɵɵlistener("input", function AutotaggingPipelineResourceComponent_Conditional_19_Conditional_3_Template_input_input_7_listener() { i0.ɵɵrestoreView(_r18); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.FilterTags()); });
|
|
574
|
+
i0.ɵɵelementEnd()()();
|
|
575
|
+
i0.ɵɵelementStart(8, "div", 24)(9, "div", 110)(10, "div", 111)(11, "div", 38)(12, "div", 112)(13, "table", 113)(14, "thead")(15, "tr")(16, "th");
|
|
576
|
+
i0.ɵɵtext(17, "Tag");
|
|
577
|
+
i0.ɵɵelementEnd();
|
|
578
|
+
i0.ɵɵelementStart(18, "th");
|
|
579
|
+
i0.ɵɵtext(19, "Count");
|
|
580
|
+
i0.ɵɵelementEnd();
|
|
581
|
+
i0.ɵɵelementStart(20, "th");
|
|
582
|
+
i0.ɵɵtext(21, "Avg Weight");
|
|
583
|
+
i0.ɵɵelementEnd();
|
|
584
|
+
i0.ɵɵelementStart(22, "th");
|
|
585
|
+
i0.ɵɵtext(23, "Distribution");
|
|
586
|
+
i0.ɵɵelementEnd();
|
|
587
|
+
i0.ɵɵelementStart(24, "th");
|
|
588
|
+
i0.ɵɵtext(25, "Top Source");
|
|
589
|
+
i0.ɵɵelementEnd();
|
|
590
|
+
i0.ɵɵelementStart(26, "th");
|
|
591
|
+
i0.ɵɵtext(27, "First Seen");
|
|
592
|
+
i0.ɵɵelementEnd()()();
|
|
593
|
+
i0.ɵɵelementStart(28, "tbody");
|
|
594
|
+
i0.ɵɵrepeaterCreate(29, AutotaggingPipelineResourceComponent_Conditional_19_Conditional_3_For_30_Template, 18, 15, "tr", null, _forTrack3);
|
|
595
|
+
i0.ɵɵelementEnd()()()()();
|
|
596
|
+
i0.ɵɵelementStart(31, "div", 114)(32, "div", 41)(33, "div", 115);
|
|
597
|
+
i0.ɵɵelement(34, "i", 116);
|
|
598
|
+
i0.ɵɵtext(35, " Tag Cloud");
|
|
599
|
+
i0.ɵɵelementEnd();
|
|
600
|
+
i0.ɵɵelementStart(36, "div", 44);
|
|
601
|
+
i0.ɵɵrepeaterCreate(37, AutotaggingPipelineResourceComponent_Conditional_19_Conditional_3_For_38_Template, 2, 6, "span", 45, _forTrack3);
|
|
602
|
+
i0.ɵɵelementEnd()();
|
|
603
|
+
i0.ɵɵelementStart(39, "div", 117)(40, "div", 42);
|
|
604
|
+
i0.ɵɵelement(41, "i", 118);
|
|
605
|
+
i0.ɵɵtext(42, " By Source");
|
|
606
|
+
i0.ɵɵelementEnd();
|
|
607
|
+
i0.ɵɵelementStart(43, "div", 119);
|
|
608
|
+
i0.ɵɵrepeaterCreate(44, AutotaggingPipelineResourceComponent_Conditional_19_Conditional_3_For_45_Template, 5, 2, "div", 120, _forTrack4);
|
|
609
|
+
i0.ɵɵelementEnd()()()()();
|
|
610
|
+
} if (rf & 2) {
|
|
611
|
+
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
612
|
+
i0.ɵɵadvance(5);
|
|
613
|
+
i0.ɵɵtextInterpolate1("", ctx_r2.TagRows.length, " unique tags across all content sources");
|
|
614
|
+
i0.ɵɵadvance(2);
|
|
615
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r2.TagSearchQuery);
|
|
616
|
+
i0.ɵɵadvance(22);
|
|
617
|
+
i0.ɵɵrepeater(ctx_r2.FilteredTagRows);
|
|
618
|
+
i0.ɵɵadvance(8);
|
|
619
|
+
i0.ɵɵrepeater(ctx_r2.TagCloud);
|
|
620
|
+
i0.ɵɵadvance(7);
|
|
621
|
+
i0.ɵɵrepeater(ctx_r2.TagsBySource);
|
|
622
|
+
} }
|
|
623
|
+
function AutotaggingPipelineResourceComponent_Conditional_19_Conditional_4_For_11_Template(rf, ctx) { if (rf & 1) {
|
|
624
|
+
i0.ɵɵelementStart(0, "option", 130);
|
|
625
|
+
i0.ɵɵtext(1);
|
|
626
|
+
i0.ɵɵelementEnd();
|
|
627
|
+
} if (rf & 2) {
|
|
628
|
+
const s_r23 = ctx.$implicit;
|
|
629
|
+
i0.ɵɵproperty("value", s_r23);
|
|
630
|
+
i0.ɵɵadvance();
|
|
631
|
+
i0.ɵɵtextInterpolate(s_r23);
|
|
632
|
+
} }
|
|
633
|
+
function AutotaggingPipelineResourceComponent_Conditional_19_Conditional_4_For_43_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
634
|
+
i0.ɵɵelement(0, "i", 137);
|
|
635
|
+
} }
|
|
636
|
+
function AutotaggingPipelineResourceComponent_Conditional_19_Conditional_4_For_43_Template(rf, ctx) { if (rf & 1) {
|
|
637
|
+
i0.ɵɵelementStart(0, "tr")(1, "td")(2, "span", 136);
|
|
638
|
+
i0.ɵɵconditionalCreate(3, AutotaggingPipelineResourceComponent_Conditional_19_Conditional_4_For_43_Conditional_3_Template, 1, 0, "i", 137);
|
|
639
|
+
i0.ɵɵtext(4);
|
|
640
|
+
i0.ɵɵelementEnd()();
|
|
641
|
+
i0.ɵɵelementStart(5, "td", 138);
|
|
642
|
+
i0.ɵɵtext(6);
|
|
643
|
+
i0.ɵɵelementEnd();
|
|
644
|
+
i0.ɵɵelementStart(7, "td");
|
|
645
|
+
i0.ɵɵtext(8);
|
|
646
|
+
i0.ɵɵelementEnd();
|
|
647
|
+
i0.ɵɵelementStart(9, "td", 139);
|
|
648
|
+
i0.ɵɵtext(10);
|
|
649
|
+
i0.ɵɵelementEnd();
|
|
650
|
+
i0.ɵɵelementStart(11, "td");
|
|
651
|
+
i0.ɵɵtext(12);
|
|
652
|
+
i0.ɵɵelementEnd();
|
|
653
|
+
i0.ɵɵelementStart(13, "td");
|
|
654
|
+
i0.ɵɵtext(14);
|
|
655
|
+
i0.ɵɵelementEnd();
|
|
656
|
+
i0.ɵɵelementStart(15, "td");
|
|
657
|
+
i0.ɵɵtext(16);
|
|
658
|
+
i0.ɵɵelementEnd()();
|
|
659
|
+
} if (rf & 2) {
|
|
660
|
+
const row_r24 = ctx.$implicit;
|
|
661
|
+
i0.ɵɵadvance(2);
|
|
662
|
+
i0.ɵɵclassMap(row_r24.StatusClass);
|
|
663
|
+
i0.ɵɵadvance();
|
|
664
|
+
i0.ɵɵconditional(row_r24.StatusClass === "running" ? 3 : -1);
|
|
665
|
+
i0.ɵɵadvance();
|
|
666
|
+
i0.ɵɵtextInterpolate1(" ", row_r24.Status, " ");
|
|
667
|
+
i0.ɵɵadvance(2);
|
|
668
|
+
i0.ɵɵtextInterpolate(row_r24.SourceName);
|
|
669
|
+
i0.ɵɵadvance(2);
|
|
670
|
+
i0.ɵɵtextInterpolate(row_r24.StartedDisplay);
|
|
671
|
+
i0.ɵɵadvance(2);
|
|
672
|
+
i0.ɵɵtextInterpolate(row_r24.Duration);
|
|
673
|
+
i0.ɵɵadvance(2);
|
|
674
|
+
i0.ɵɵtextInterpolate(row_r24.Items);
|
|
675
|
+
i0.ɵɵadvance(2);
|
|
676
|
+
i0.ɵɵtextInterpolate(row_r24.Tags);
|
|
677
|
+
i0.ɵɵadvance();
|
|
678
|
+
i0.ɵɵclassMap(row_r24.ErrorClass);
|
|
679
|
+
i0.ɵɵadvance();
|
|
680
|
+
i0.ɵɵtextInterpolate(row_r24.Errors);
|
|
681
|
+
} }
|
|
682
|
+
function AutotaggingPipelineResourceComponent_Conditional_19_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
683
|
+
const _r22 = i0.ɵɵgetCurrentView();
|
|
684
|
+
i0.ɵɵelementStart(0, "div", 18)(1, "div")(2, "div", 19);
|
|
685
|
+
i0.ɵɵtext(3, "Run History");
|
|
686
|
+
i0.ɵɵelementEnd();
|
|
687
|
+
i0.ɵɵelementStart(4, "div", 20);
|
|
688
|
+
i0.ɵɵtext(5, "Processing run log across all content sources");
|
|
689
|
+
i0.ɵɵelementEnd()();
|
|
690
|
+
i0.ɵɵelementStart(6, "div", 21)(7, "select", 128);
|
|
691
|
+
i0.ɵɵtwoWayListener("ngModelChange", function AutotaggingPipelineResourceComponent_Conditional_19_Conditional_4_Template_select_ngModelChange_7_listener($event) { i0.ɵɵrestoreView(_r22); const ctx_r2 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r2.HistorySourceFilter, $event) || (ctx_r2.HistorySourceFilter = $event); return i0.ɵɵresetView($event); });
|
|
692
|
+
i0.ɵɵlistener("change", function AutotaggingPipelineResourceComponent_Conditional_19_Conditional_4_Template_select_change_7_listener() { i0.ɵɵrestoreView(_r22); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.FilterRunHistory()); });
|
|
693
|
+
i0.ɵɵelementStart(8, "option", 129);
|
|
694
|
+
i0.ɵɵtext(9, "All Sources");
|
|
695
|
+
i0.ɵɵelementEnd();
|
|
696
|
+
i0.ɵɵrepeaterCreate(10, AutotaggingPipelineResourceComponent_Conditional_19_Conditional_4_For_11_Template, 2, 2, "option", 130, i0.ɵɵrepeaterTrackByIdentity);
|
|
697
|
+
i0.ɵɵelementEnd();
|
|
698
|
+
i0.ɵɵelementStart(12, "select", 128);
|
|
699
|
+
i0.ɵɵtwoWayListener("ngModelChange", function AutotaggingPipelineResourceComponent_Conditional_19_Conditional_4_Template_select_ngModelChange_12_listener($event) { i0.ɵɵrestoreView(_r22); const ctx_r2 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r2.HistoryStatusFilter, $event) || (ctx_r2.HistoryStatusFilter = $event); return i0.ɵɵresetView($event); });
|
|
700
|
+
i0.ɵɵlistener("change", function AutotaggingPipelineResourceComponent_Conditional_19_Conditional_4_Template_select_change_12_listener() { i0.ɵɵrestoreView(_r22); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.FilterRunHistory()); });
|
|
701
|
+
i0.ɵɵelementStart(13, "option", 129);
|
|
702
|
+
i0.ɵɵtext(14, "All Status");
|
|
703
|
+
i0.ɵɵelementEnd();
|
|
704
|
+
i0.ɵɵelementStart(15, "option", 131);
|
|
705
|
+
i0.ɵɵtext(16, "Complete");
|
|
706
|
+
i0.ɵɵelementEnd();
|
|
707
|
+
i0.ɵɵelementStart(17, "option", 132);
|
|
708
|
+
i0.ɵɵtext(18, "Failed");
|
|
709
|
+
i0.ɵɵelementEnd();
|
|
710
|
+
i0.ɵɵelementStart(19, "option", 133);
|
|
711
|
+
i0.ɵɵtext(20, "Running");
|
|
712
|
+
i0.ɵɵelementEnd()()()();
|
|
713
|
+
i0.ɵɵelementStart(21, "div", 24)(22, "div", 38)(23, "div", 134)(24, "table", 135)(25, "thead")(26, "tr")(27, "th");
|
|
714
|
+
i0.ɵɵtext(28, "Status");
|
|
715
|
+
i0.ɵɵelementEnd();
|
|
716
|
+
i0.ɵɵelementStart(29, "th");
|
|
717
|
+
i0.ɵɵtext(30, "Source");
|
|
718
|
+
i0.ɵɵelementEnd();
|
|
719
|
+
i0.ɵɵelementStart(31, "th");
|
|
720
|
+
i0.ɵɵtext(32, "Started");
|
|
721
|
+
i0.ɵɵelementEnd();
|
|
722
|
+
i0.ɵɵelementStart(33, "th");
|
|
723
|
+
i0.ɵɵtext(34, "Duration");
|
|
724
|
+
i0.ɵɵelementEnd();
|
|
725
|
+
i0.ɵɵelementStart(35, "th");
|
|
726
|
+
i0.ɵɵtext(36, "Items");
|
|
727
|
+
i0.ɵɵelementEnd();
|
|
728
|
+
i0.ɵɵelementStart(37, "th");
|
|
729
|
+
i0.ɵɵtext(38, "Tags");
|
|
730
|
+
i0.ɵɵelementEnd();
|
|
731
|
+
i0.ɵɵelementStart(39, "th");
|
|
732
|
+
i0.ɵɵtext(40, "Errors");
|
|
733
|
+
i0.ɵɵelementEnd()()();
|
|
734
|
+
i0.ɵɵelementStart(41, "tbody");
|
|
735
|
+
i0.ɵɵrepeaterCreate(42, AutotaggingPipelineResourceComponent_Conditional_19_Conditional_4_For_43_Template, 17, 12, "tr", null, _forTrack2);
|
|
736
|
+
i0.ɵɵelementEnd()()()()();
|
|
737
|
+
} if (rf & 2) {
|
|
738
|
+
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
739
|
+
i0.ɵɵadvance(7);
|
|
740
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r2.HistorySourceFilter);
|
|
741
|
+
i0.ɵɵadvance(3);
|
|
742
|
+
i0.ɵɵrepeater(ctx_r2.HistorySourceOptions);
|
|
743
|
+
i0.ɵɵadvance(2);
|
|
744
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r2.HistoryStatusFilter);
|
|
745
|
+
i0.ɵɵadvance(30);
|
|
746
|
+
i0.ɵɵrepeater(ctx_r2.FilteredRunRows);
|
|
747
|
+
} }
|
|
748
|
+
function AutotaggingPipelineResourceComponent_Conditional_19_Template(rf, ctx) { if (rf & 1) {
|
|
749
|
+
i0.ɵɵconditionalCreate(0, AutotaggingPipelineResourceComponent_Conditional_19_Conditional_0_Template, 42, 2);
|
|
750
|
+
i0.ɵɵconditionalCreate(1, AutotaggingPipelineResourceComponent_Conditional_19_Conditional_1_Template, 20, 0);
|
|
751
|
+
i0.ɵɵconditionalCreate(2, AutotaggingPipelineResourceComponent_Conditional_19_Conditional_2_Template, 20, 0);
|
|
752
|
+
i0.ɵɵconditionalCreate(3, AutotaggingPipelineResourceComponent_Conditional_19_Conditional_3_Template, 46, 2);
|
|
753
|
+
i0.ɵɵconditionalCreate(4, AutotaggingPipelineResourceComponent_Conditional_19_Conditional_4_Template, 44, 2);
|
|
754
|
+
} if (rf & 2) {
|
|
755
|
+
const ctx_r2 = i0.ɵɵnextContext();
|
|
756
|
+
i0.ɵɵconditional(ctx_r2.ActiveTab === "pipeline" ? 0 : -1);
|
|
757
|
+
i0.ɵɵadvance();
|
|
758
|
+
i0.ɵɵconditional(ctx_r2.ActiveTab === "sources" ? 1 : -1);
|
|
759
|
+
i0.ɵɵadvance();
|
|
760
|
+
i0.ɵɵconditional(ctx_r2.ActiveTab === "types" ? 2 : -1);
|
|
761
|
+
i0.ɵɵadvance();
|
|
762
|
+
i0.ɵɵconditional(ctx_r2.ActiveTab === "tags" ? 3 : -1);
|
|
763
|
+
i0.ɵɵadvance();
|
|
764
|
+
i0.ɵɵconditional(ctx_r2.ActiveTab === "history" ? 4 : -1);
|
|
765
|
+
} }
|
|
766
|
+
function AutotaggingPipelineResourceComponent_Conditional_20_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
767
|
+
i0.ɵɵtext(0, " Add Content Source ");
|
|
768
|
+
} }
|
|
769
|
+
function AutotaggingPipelineResourceComponent_Conditional_20_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
770
|
+
i0.ɵɵtext(0, " Edit Content Source ");
|
|
771
|
+
} }
|
|
772
|
+
function AutotaggingPipelineResourceComponent_Conditional_20_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
773
|
+
i0.ɵɵtext(0, " Add Content Type ");
|
|
774
|
+
} }
|
|
775
|
+
function AutotaggingPipelineResourceComponent_Conditional_20_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
776
|
+
i0.ɵɵtext(0, " Edit Content Type ");
|
|
777
|
+
} }
|
|
778
|
+
function AutotaggingPipelineResourceComponent_Conditional_20_Conditional_11_For_11_Template(rf, ctx) { if (rf & 1) {
|
|
779
|
+
i0.ɵɵelementStart(0, "option", 130);
|
|
780
|
+
i0.ɵɵtext(1);
|
|
781
|
+
i0.ɵɵelementEnd();
|
|
782
|
+
} if (rf & 2) {
|
|
783
|
+
const opt_r27 = ctx.$implicit;
|
|
784
|
+
i0.ɵɵproperty("value", opt_r27.ID);
|
|
785
|
+
i0.ɵɵadvance();
|
|
786
|
+
i0.ɵɵtextInterpolate(opt_r27.Name);
|
|
787
|
+
} }
|
|
788
|
+
function AutotaggingPipelineResourceComponent_Conditional_20_Conditional_11_For_19_Template(rf, ctx) { if (rf & 1) {
|
|
789
|
+
i0.ɵɵelementStart(0, "option", 130);
|
|
790
|
+
i0.ɵɵtext(1);
|
|
791
|
+
i0.ɵɵelementEnd();
|
|
792
|
+
} if (rf & 2) {
|
|
793
|
+
const opt_r28 = ctx.$implicit;
|
|
794
|
+
i0.ɵɵproperty("value", opt_r28.ID);
|
|
795
|
+
i0.ɵɵadvance();
|
|
796
|
+
i0.ɵɵtextInterpolate(opt_r28.Name);
|
|
797
|
+
} }
|
|
798
|
+
function AutotaggingPipelineResourceComponent_Conditional_20_Conditional_11_For_27_Template(rf, ctx) { if (rf & 1) {
|
|
799
|
+
i0.ɵɵelementStart(0, "option", 130);
|
|
800
|
+
i0.ɵɵtext(1);
|
|
801
|
+
i0.ɵɵelementEnd();
|
|
802
|
+
} if (rf & 2) {
|
|
803
|
+
const opt_r29 = ctx.$implicit;
|
|
804
|
+
i0.ɵɵproperty("value", opt_r29.ID);
|
|
805
|
+
i0.ɵɵadvance();
|
|
806
|
+
i0.ɵɵtextInterpolate(opt_r29.Name);
|
|
807
|
+
} }
|
|
808
|
+
function AutotaggingPipelineResourceComponent_Conditional_20_Conditional_11_For_45_Template(rf, ctx) { if (rf & 1) {
|
|
809
|
+
i0.ɵɵelementStart(0, "option", 130);
|
|
810
|
+
i0.ɵɵtext(1);
|
|
811
|
+
i0.ɵɵelementEnd();
|
|
812
|
+
} if (rf & 2) {
|
|
813
|
+
const opt_r30 = ctx.$implicit;
|
|
814
|
+
i0.ɵɵproperty("value", opt_r30.ID);
|
|
815
|
+
i0.ɵɵadvance();
|
|
816
|
+
i0.ɵɵtextInterpolate(opt_r30.Name);
|
|
817
|
+
} }
|
|
818
|
+
function AutotaggingPipelineResourceComponent_Conditional_20_Conditional_11_Conditional_50_Template(rf, ctx) { if (rf & 1) {
|
|
819
|
+
i0.ɵɵelement(0, "i", 15);
|
|
820
|
+
i0.ɵɵtext(1, " Saving... ");
|
|
821
|
+
} }
|
|
822
|
+
function AutotaggingPipelineResourceComponent_Conditional_20_Conditional_11_Conditional_51_Template(rf, ctx) { if (rf & 1) {
|
|
823
|
+
i0.ɵɵelement(0, "i", 155);
|
|
824
|
+
i0.ɵɵtext(1, " Save ");
|
|
825
|
+
} }
|
|
826
|
+
function AutotaggingPipelineResourceComponent_Conditional_20_Conditional_11_Template(rf, ctx) { if (rf & 1) {
|
|
827
|
+
const _r26 = i0.ɵɵgetCurrentView();
|
|
828
|
+
i0.ɵɵelementStart(0, "div", 146)(1, "label", 147);
|
|
829
|
+
i0.ɵɵtext(2, "Name");
|
|
830
|
+
i0.ɵɵelementEnd();
|
|
831
|
+
i0.ɵɵelementStart(3, "input", 148);
|
|
832
|
+
i0.ɵɵtwoWayListener("ngModelChange", function AutotaggingPipelineResourceComponent_Conditional_20_Conditional_11_Template_input_ngModelChange_3_listener($event) { i0.ɵɵrestoreView(_r26); const ctx_r2 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r2.FormSourceName, $event) || (ctx_r2.FormSourceName = $event); return i0.ɵɵresetView($event); });
|
|
833
|
+
i0.ɵɵelementEnd()();
|
|
834
|
+
i0.ɵɵelementStart(4, "div", 146)(5, "label", 147);
|
|
835
|
+
i0.ɵɵtext(6, "Source Type");
|
|
836
|
+
i0.ɵɵelementEnd();
|
|
837
|
+
i0.ɵɵelementStart(7, "select", 149);
|
|
838
|
+
i0.ɵɵtwoWayListener("ngModelChange", function AutotaggingPipelineResourceComponent_Conditional_20_Conditional_11_Template_select_ngModelChange_7_listener($event) { i0.ɵɵrestoreView(_r26); const ctx_r2 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r2.FormSourceTypeID, $event) || (ctx_r2.FormSourceTypeID = $event); return i0.ɵɵresetView($event); });
|
|
839
|
+
i0.ɵɵelementStart(8, "option", 129);
|
|
840
|
+
i0.ɵɵtext(9, "Select source type...");
|
|
841
|
+
i0.ɵɵelementEnd();
|
|
842
|
+
i0.ɵɵrepeaterCreate(10, AutotaggingPipelineResourceComponent_Conditional_20_Conditional_11_For_11_Template, 2, 2, "option", 130, _forTrack2);
|
|
843
|
+
i0.ɵɵelementEnd()();
|
|
844
|
+
i0.ɵɵelementStart(12, "div", 146)(13, "label", 147);
|
|
845
|
+
i0.ɵɵtext(14, "Content Type");
|
|
846
|
+
i0.ɵɵelementEnd();
|
|
847
|
+
i0.ɵɵelementStart(15, "select", 149);
|
|
848
|
+
i0.ɵɵtwoWayListener("ngModelChange", function AutotaggingPipelineResourceComponent_Conditional_20_Conditional_11_Template_select_ngModelChange_15_listener($event) { i0.ɵɵrestoreView(_r26); const ctx_r2 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r2.FormContentTypeID, $event) || (ctx_r2.FormContentTypeID = $event); return i0.ɵɵresetView($event); });
|
|
849
|
+
i0.ɵɵelementStart(16, "option", 129);
|
|
850
|
+
i0.ɵɵtext(17, "Select content type...");
|
|
851
|
+
i0.ɵɵelementEnd();
|
|
852
|
+
i0.ɵɵrepeaterCreate(18, AutotaggingPipelineResourceComponent_Conditional_20_Conditional_11_For_19_Template, 2, 2, "option", 130, _forTrack2);
|
|
853
|
+
i0.ɵɵelementEnd()();
|
|
854
|
+
i0.ɵɵelementStart(20, "div", 146)(21, "label", 147);
|
|
855
|
+
i0.ɵɵtext(22, "File Type");
|
|
856
|
+
i0.ɵɵelementEnd();
|
|
857
|
+
i0.ɵɵelementStart(23, "select", 149);
|
|
858
|
+
i0.ɵɵtwoWayListener("ngModelChange", function AutotaggingPipelineResourceComponent_Conditional_20_Conditional_11_Template_select_ngModelChange_23_listener($event) { i0.ɵɵrestoreView(_r26); const ctx_r2 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r2.FormFileTypeID, $event) || (ctx_r2.FormFileTypeID = $event); return i0.ɵɵresetView($event); });
|
|
859
|
+
i0.ɵɵelementStart(24, "option", 129);
|
|
860
|
+
i0.ɵɵtext(25, "Select file type...");
|
|
861
|
+
i0.ɵɵelementEnd();
|
|
862
|
+
i0.ɵɵrepeaterCreate(26, AutotaggingPipelineResourceComponent_Conditional_20_Conditional_11_For_27_Template, 2, 2, "option", 130, _forTrack2);
|
|
863
|
+
i0.ɵɵelementEnd()();
|
|
864
|
+
i0.ɵɵelementStart(28, "div", 146)(29, "label", 147);
|
|
865
|
+
i0.ɵɵtext(30, "URL");
|
|
866
|
+
i0.ɵɵelementEnd();
|
|
867
|
+
i0.ɵɵelementStart(31, "input", 150);
|
|
868
|
+
i0.ɵɵtwoWayListener("ngModelChange", function AutotaggingPipelineResourceComponent_Conditional_20_Conditional_11_Template_input_ngModelChange_31_listener($event) { i0.ɵɵrestoreView(_r26); const ctx_r2 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r2.FormSourceURL, $event) || (ctx_r2.FormSourceURL = $event); return i0.ɵɵresetView($event); });
|
|
869
|
+
i0.ɵɵelementEnd()();
|
|
870
|
+
i0.ɵɵelementStart(32, "div", 146)(33, "label", 147);
|
|
871
|
+
i0.ɵɵtext(34, "Embedding Model Override");
|
|
872
|
+
i0.ɵɵelementEnd();
|
|
873
|
+
i0.ɵɵelementStart(35, "mj-tree-dropdown", 151);
|
|
874
|
+
i0.ɵɵlistener("ValueChange", function AutotaggingPipelineResourceComponent_Conditional_20_Conditional_11_Template_mj_tree_dropdown_ValueChange_35_listener($event) { i0.ɵɵrestoreView(_r26); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.FormSourceEmbeddingModelID = ctx_r2.FromCompositeKey($event)); });
|
|
875
|
+
i0.ɵɵelementEnd();
|
|
876
|
+
i0.ɵɵelementStart(36, "span", 152);
|
|
877
|
+
i0.ɵɵtext(37, "Overrides Content Type default");
|
|
878
|
+
i0.ɵɵelementEnd()();
|
|
879
|
+
i0.ɵɵelementStart(38, "div", 146)(39, "label", 147);
|
|
880
|
+
i0.ɵɵtext(40, "Vector Index Override");
|
|
881
|
+
i0.ɵɵelementEnd();
|
|
882
|
+
i0.ɵɵelementStart(41, "select", 149);
|
|
883
|
+
i0.ɵɵtwoWayListener("ngModelChange", function AutotaggingPipelineResourceComponent_Conditional_20_Conditional_11_Template_select_ngModelChange_41_listener($event) { i0.ɵɵrestoreView(_r26); const ctx_r2 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r2.FormSourceVectorIndexID, $event) || (ctx_r2.FormSourceVectorIndexID = $event); return i0.ɵɵresetView($event); });
|
|
884
|
+
i0.ɵɵelementStart(42, "option", 129);
|
|
885
|
+
i0.ɵɵtext(43, "Use system default");
|
|
886
|
+
i0.ɵɵelementEnd();
|
|
887
|
+
i0.ɵɵrepeaterCreate(44, AutotaggingPipelineResourceComponent_Conditional_20_Conditional_11_For_45_Template, 2, 2, "option", 130, _forTrack2);
|
|
888
|
+
i0.ɵɵelementEnd();
|
|
889
|
+
i0.ɵɵelementStart(46, "span", 152);
|
|
890
|
+
i0.ɵɵtext(47, "Overrides Content Type default");
|
|
891
|
+
i0.ɵɵelementEnd()();
|
|
892
|
+
i0.ɵɵelementStart(48, "div", 153)(49, "button", 154);
|
|
893
|
+
i0.ɵɵlistener("click", function AutotaggingPipelineResourceComponent_Conditional_20_Conditional_11_Template_button_click_49_listener() { i0.ɵɵrestoreView(_r26); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.SaveSource()); });
|
|
894
|
+
i0.ɵɵconditionalCreate(50, AutotaggingPipelineResourceComponent_Conditional_20_Conditional_11_Conditional_50_Template, 2, 0)(51, AutotaggingPipelineResourceComponent_Conditional_20_Conditional_11_Conditional_51_Template, 2, 0);
|
|
895
|
+
i0.ɵɵelementEnd();
|
|
896
|
+
i0.ɵɵelementStart(52, "button", 22);
|
|
897
|
+
i0.ɵɵlistener("click", function AutotaggingPipelineResourceComponent_Conditional_20_Conditional_11_Template_button_click_52_listener() { i0.ɵɵrestoreView(_r26); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.CloseForm()); });
|
|
898
|
+
i0.ɵɵtext(53, "Cancel");
|
|
899
|
+
i0.ɵɵelementEnd()();
|
|
900
|
+
} if (rf & 2) {
|
|
901
|
+
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
902
|
+
i0.ɵɵadvance(3);
|
|
903
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r2.FormSourceName);
|
|
904
|
+
i0.ɵɵadvance(4);
|
|
905
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r2.FormSourceTypeID);
|
|
906
|
+
i0.ɵɵadvance(3);
|
|
907
|
+
i0.ɵɵrepeater(ctx_r2.SourceTypeOptions);
|
|
908
|
+
i0.ɵɵadvance(5);
|
|
909
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r2.FormContentTypeID);
|
|
910
|
+
i0.ɵɵadvance(3);
|
|
911
|
+
i0.ɵɵrepeater(ctx_r2.ContentTypeOptions);
|
|
912
|
+
i0.ɵɵadvance(5);
|
|
913
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r2.FormFileTypeID);
|
|
914
|
+
i0.ɵɵadvance(3);
|
|
915
|
+
i0.ɵɵrepeater(ctx_r2.FileTypeOptions);
|
|
916
|
+
i0.ɵɵadvance(5);
|
|
917
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r2.FormSourceURL);
|
|
918
|
+
i0.ɵɵadvance(4);
|
|
919
|
+
i0.ɵɵproperty("BranchConfig", ctx_r2.AIModelVendorBranch)("LeafConfig", ctx_r2.EmbeddingModelsLeaf)("Clearable", true)("Value", ctx_r2.ToCompositeKey(ctx_r2.FormSourceEmbeddingModelID));
|
|
920
|
+
i0.ɵɵadvance(6);
|
|
921
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r2.FormSourceVectorIndexID);
|
|
922
|
+
i0.ɵɵadvance(3);
|
|
923
|
+
i0.ɵɵrepeater(ctx_r2.VectorIndexOptions);
|
|
924
|
+
i0.ɵɵadvance(5);
|
|
925
|
+
i0.ɵɵproperty("disabled", ctx_r2.FormSaving);
|
|
926
|
+
i0.ɵɵadvance();
|
|
927
|
+
i0.ɵɵconditional(ctx_r2.FormSaving ? 50 : 51);
|
|
928
|
+
} }
|
|
929
|
+
function AutotaggingPipelineResourceComponent_Conditional_20_Conditional_12_For_32_Template(rf, ctx) { if (rf & 1) {
|
|
930
|
+
i0.ɵɵelementStart(0, "option", 130);
|
|
931
|
+
i0.ɵɵtext(1);
|
|
932
|
+
i0.ɵɵelementEnd();
|
|
933
|
+
} if (rf & 2) {
|
|
934
|
+
const opt_r32 = ctx.$implicit;
|
|
935
|
+
i0.ɵɵproperty("value", opt_r32.ID);
|
|
936
|
+
i0.ɵɵadvance();
|
|
937
|
+
i0.ɵɵtextInterpolate(opt_r32.Name);
|
|
938
|
+
} }
|
|
939
|
+
function AutotaggingPipelineResourceComponent_Conditional_20_Conditional_12_Conditional_35_Template(rf, ctx) { if (rf & 1) {
|
|
940
|
+
i0.ɵɵelement(0, "i", 15);
|
|
941
|
+
i0.ɵɵtext(1, " Saving... ");
|
|
942
|
+
} }
|
|
943
|
+
function AutotaggingPipelineResourceComponent_Conditional_20_Conditional_12_Conditional_36_Template(rf, ctx) { if (rf & 1) {
|
|
944
|
+
i0.ɵɵelement(0, "i", 155);
|
|
945
|
+
i0.ɵɵtext(1, " Save ");
|
|
946
|
+
} }
|
|
947
|
+
function AutotaggingPipelineResourceComponent_Conditional_20_Conditional_12_Template(rf, ctx) { if (rf & 1) {
|
|
948
|
+
const _r31 = i0.ɵɵgetCurrentView();
|
|
949
|
+
i0.ɵɵelementStart(0, "div", 146)(1, "label", 147);
|
|
950
|
+
i0.ɵɵtext(2, "Name");
|
|
951
|
+
i0.ɵɵelementEnd();
|
|
952
|
+
i0.ɵɵelementStart(3, "input", 156);
|
|
953
|
+
i0.ɵɵtwoWayListener("ngModelChange", function AutotaggingPipelineResourceComponent_Conditional_20_Conditional_12_Template_input_ngModelChange_3_listener($event) { i0.ɵɵrestoreView(_r31); const ctx_r2 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r2.FormTypeName, $event) || (ctx_r2.FormTypeName = $event); return i0.ɵɵresetView($event); });
|
|
954
|
+
i0.ɵɵelementEnd()();
|
|
955
|
+
i0.ɵɵelementStart(4, "div", 146)(5, "label", 147);
|
|
956
|
+
i0.ɵɵtext(6, "Description");
|
|
957
|
+
i0.ɵɵelementEnd();
|
|
958
|
+
i0.ɵɵelementStart(7, "textarea", 157);
|
|
959
|
+
i0.ɵɵtwoWayListener("ngModelChange", function AutotaggingPipelineResourceComponent_Conditional_20_Conditional_12_Template_textarea_ngModelChange_7_listener($event) { i0.ɵɵrestoreView(_r31); const ctx_r2 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r2.FormTypeDescription, $event) || (ctx_r2.FormTypeDescription = $event); return i0.ɵɵresetView($event); });
|
|
960
|
+
i0.ɵɵelementEnd()();
|
|
961
|
+
i0.ɵɵelementStart(8, "div", 146)(9, "label", 147);
|
|
962
|
+
i0.ɵɵtext(10, "AI Model (for tagging)");
|
|
963
|
+
i0.ɵɵelementEnd();
|
|
964
|
+
i0.ɵɵelementStart(11, "mj-tree-dropdown", 158);
|
|
965
|
+
i0.ɵɵlistener("ValueChange", function AutotaggingPipelineResourceComponent_Conditional_20_Conditional_12_Template_mj_tree_dropdown_ValueChange_11_listener($event) { i0.ɵɵrestoreView(_r31); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.FormTypeAIModelID = ctx_r2.FromCompositeKey($event)); });
|
|
966
|
+
i0.ɵɵelementEnd()();
|
|
967
|
+
i0.ɵɵelementStart(12, "div", 159)(13, "div", 160)(14, "label", 147);
|
|
968
|
+
i0.ɵɵtext(15, "Min Tags");
|
|
969
|
+
i0.ɵɵelementEnd();
|
|
970
|
+
i0.ɵɵelementStart(16, "input", 161);
|
|
971
|
+
i0.ɵɵtwoWayListener("ngModelChange", function AutotaggingPipelineResourceComponent_Conditional_20_Conditional_12_Template_input_ngModelChange_16_listener($event) { i0.ɵɵrestoreView(_r31); const ctx_r2 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r2.FormTypeMinTags, $event) || (ctx_r2.FormTypeMinTags = $event); return i0.ɵɵresetView($event); });
|
|
972
|
+
i0.ɵɵelementEnd()();
|
|
973
|
+
i0.ɵɵelementStart(17, "div", 160)(18, "label", 147);
|
|
974
|
+
i0.ɵɵtext(19, "Max Tags");
|
|
975
|
+
i0.ɵɵelementEnd();
|
|
976
|
+
i0.ɵɵelementStart(20, "input", 162);
|
|
977
|
+
i0.ɵɵtwoWayListener("ngModelChange", function AutotaggingPipelineResourceComponent_Conditional_20_Conditional_12_Template_input_ngModelChange_20_listener($event) { i0.ɵɵrestoreView(_r31); const ctx_r2 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r2.FormTypeMaxTags, $event) || (ctx_r2.FormTypeMaxTags = $event); return i0.ɵɵresetView($event); });
|
|
978
|
+
i0.ɵɵelementEnd()()();
|
|
979
|
+
i0.ɵɵelementStart(21, "div", 146)(22, "label", 147);
|
|
980
|
+
i0.ɵɵtext(23, "Embedding Model");
|
|
981
|
+
i0.ɵɵelementEnd();
|
|
982
|
+
i0.ɵɵelementStart(24, "mj-tree-dropdown", 151);
|
|
983
|
+
i0.ɵɵlistener("ValueChange", function AutotaggingPipelineResourceComponent_Conditional_20_Conditional_12_Template_mj_tree_dropdown_ValueChange_24_listener($event) { i0.ɵɵrestoreView(_r31); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.FormTypeEmbeddingModelID = ctx_r2.FromCompositeKey($event)); });
|
|
984
|
+
i0.ɵɵelementEnd()();
|
|
985
|
+
i0.ɵɵelementStart(25, "div", 146)(26, "label", 147);
|
|
986
|
+
i0.ɵɵtext(27, "Vector Index");
|
|
987
|
+
i0.ɵɵelementEnd();
|
|
988
|
+
i0.ɵɵelementStart(28, "select", 149);
|
|
989
|
+
i0.ɵɵtwoWayListener("ngModelChange", function AutotaggingPipelineResourceComponent_Conditional_20_Conditional_12_Template_select_ngModelChange_28_listener($event) { i0.ɵɵrestoreView(_r31); const ctx_r2 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r2.FormTypeVectorIndexID, $event) || (ctx_r2.FormTypeVectorIndexID = $event); return i0.ɵɵresetView($event); });
|
|
990
|
+
i0.ɵɵelementStart(29, "option", 129);
|
|
991
|
+
i0.ɵɵtext(30, "Use system default");
|
|
992
|
+
i0.ɵɵelementEnd();
|
|
993
|
+
i0.ɵɵrepeaterCreate(31, AutotaggingPipelineResourceComponent_Conditional_20_Conditional_12_For_32_Template, 2, 2, "option", 130, _forTrack2);
|
|
994
|
+
i0.ɵɵelementEnd()();
|
|
995
|
+
i0.ɵɵelementStart(33, "div", 153)(34, "button", 154);
|
|
996
|
+
i0.ɵɵlistener("click", function AutotaggingPipelineResourceComponent_Conditional_20_Conditional_12_Template_button_click_34_listener() { i0.ɵɵrestoreView(_r31); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.SaveContentType()); });
|
|
997
|
+
i0.ɵɵconditionalCreate(35, AutotaggingPipelineResourceComponent_Conditional_20_Conditional_12_Conditional_35_Template, 2, 0)(36, AutotaggingPipelineResourceComponent_Conditional_20_Conditional_12_Conditional_36_Template, 2, 0);
|
|
998
|
+
i0.ɵɵelementEnd();
|
|
999
|
+
i0.ɵɵelementStart(37, "button", 22);
|
|
1000
|
+
i0.ɵɵlistener("click", function AutotaggingPipelineResourceComponent_Conditional_20_Conditional_12_Template_button_click_37_listener() { i0.ɵɵrestoreView(_r31); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.CloseForm()); });
|
|
1001
|
+
i0.ɵɵtext(38, "Cancel");
|
|
1002
|
+
i0.ɵɵelementEnd()();
|
|
1003
|
+
} if (rf & 2) {
|
|
1004
|
+
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
1005
|
+
i0.ɵɵadvance(3);
|
|
1006
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r2.FormTypeName);
|
|
1007
|
+
i0.ɵɵadvance(4);
|
|
1008
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r2.FormTypeDescription);
|
|
1009
|
+
i0.ɵɵadvance(4);
|
|
1010
|
+
i0.ɵɵproperty("BranchConfig", ctx_r2.AIModelVendorBranch)("LeafConfig", ctx_r2.AllModelsLeaf)("Clearable", true)("Value", ctx_r2.ToCompositeKey(ctx_r2.FormTypeAIModelID));
|
|
1011
|
+
i0.ɵɵadvance(5);
|
|
1012
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r2.FormTypeMinTags);
|
|
1013
|
+
i0.ɵɵadvance(4);
|
|
1014
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r2.FormTypeMaxTags);
|
|
1015
|
+
i0.ɵɵadvance(4);
|
|
1016
|
+
i0.ɵɵproperty("BranchConfig", ctx_r2.AIModelVendorBranch)("LeafConfig", ctx_r2.EmbeddingModelsLeaf)("Clearable", true)("Value", ctx_r2.ToCompositeKey(ctx_r2.FormTypeEmbeddingModelID));
|
|
1017
|
+
i0.ɵɵadvance(4);
|
|
1018
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r2.FormTypeVectorIndexID);
|
|
1019
|
+
i0.ɵɵadvance(3);
|
|
1020
|
+
i0.ɵɵrepeater(ctx_r2.VectorIndexOptions);
|
|
1021
|
+
i0.ɵɵadvance(3);
|
|
1022
|
+
i0.ɵɵproperty("disabled", ctx_r2.FormSaving);
|
|
1023
|
+
i0.ɵɵadvance();
|
|
1024
|
+
i0.ɵɵconditional(ctx_r2.FormSaving ? 35 : 36);
|
|
1025
|
+
} }
|
|
1026
|
+
function AutotaggingPipelineResourceComponent_Conditional_20_Template(rf, ctx) { if (rf & 1) {
|
|
1027
|
+
const _r25 = i0.ɵɵgetCurrentView();
|
|
1028
|
+
i0.ɵɵelementStart(0, "div", 140);
|
|
1029
|
+
i0.ɵɵlistener("click", function AutotaggingPipelineResourceComponent_Conditional_20_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r25); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.CloseForm()); });
|
|
1030
|
+
i0.ɵɵelementEnd();
|
|
1031
|
+
i0.ɵɵelementStart(1, "div", 141)(2, "div", 142)(3, "h3");
|
|
1032
|
+
i0.ɵɵconditionalCreate(4, AutotaggingPipelineResourceComponent_Conditional_20_Conditional_4_Template, 1, 0)(5, AutotaggingPipelineResourceComponent_Conditional_20_Conditional_5_Template, 1, 0)(6, AutotaggingPipelineResourceComponent_Conditional_20_Conditional_6_Template, 1, 0)(7, AutotaggingPipelineResourceComponent_Conditional_20_Conditional_7_Template, 1, 0);
|
|
1033
|
+
i0.ɵɵelementEnd();
|
|
1034
|
+
i0.ɵɵelementStart(8, "button", 143);
|
|
1035
|
+
i0.ɵɵlistener("click", function AutotaggingPipelineResourceComponent_Conditional_20_Template_button_click_8_listener() { i0.ɵɵrestoreView(_r25); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.CloseForm()); });
|
|
1036
|
+
i0.ɵɵelement(9, "i", 144);
|
|
1037
|
+
i0.ɵɵelementEnd()();
|
|
1038
|
+
i0.ɵɵelementStart(10, "div", 145);
|
|
1039
|
+
i0.ɵɵconditionalCreate(11, AutotaggingPipelineResourceComponent_Conditional_20_Conditional_11_Template, 54, 12);
|
|
1040
|
+
i0.ɵɵconditionalCreate(12, AutotaggingPipelineResourceComponent_Conditional_20_Conditional_12_Template, 39, 15);
|
|
1041
|
+
i0.ɵɵelementEnd()();
|
|
1042
|
+
} if (rf & 2) {
|
|
1043
|
+
const ctx_r2 = i0.ɵɵnextContext();
|
|
1044
|
+
i0.ɵɵadvance(4);
|
|
1045
|
+
i0.ɵɵconditional(ctx_r2.FormMode === "add-source" ? 4 : ctx_r2.FormMode === "edit-source" ? 5 : ctx_r2.FormMode === "add-type" ? 6 : ctx_r2.FormMode === "edit-type" ? 7 : -1);
|
|
1046
|
+
i0.ɵɵadvance(7);
|
|
1047
|
+
i0.ɵɵconditional(ctx_r2.FormMode === "add-source" || ctx_r2.FormMode === "edit-source" ? 11 : -1);
|
|
1048
|
+
i0.ɵɵadvance();
|
|
1049
|
+
i0.ɵɵconditional(ctx_r2.FormMode === "add-type" || ctx_r2.FormMode === "edit-type" ? 12 : -1);
|
|
1050
|
+
} }
|
|
1051
|
+
function AutotaggingPipelineResourceComponent_Conditional_21_Conditional_17_Template(rf, ctx) { if (rf & 1) {
|
|
1052
|
+
i0.ɵɵelementStart(0, "span", 170);
|
|
1053
|
+
i0.ɵɵelement(1, "i", 181);
|
|
1054
|
+
i0.ɵɵtext(2);
|
|
1055
|
+
i0.ɵɵelementEnd();
|
|
1056
|
+
} if (rf & 2) {
|
|
1057
|
+
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
1058
|
+
i0.ɵɵadvance(2);
|
|
1059
|
+
i0.ɵɵtextInterpolate1(" ", ctx_r2.SelectedFeedItem.FileTypeName);
|
|
1060
|
+
} }
|
|
1061
|
+
function AutotaggingPipelineResourceComponent_Conditional_21_Conditional_18_Template(rf, ctx) { if (rf & 1) {
|
|
1062
|
+
i0.ɵɵelementStart(0, "div", 171)(1, "div", 172);
|
|
1063
|
+
i0.ɵɵtext(2, "URL");
|
|
1064
|
+
i0.ɵɵelementEnd();
|
|
1065
|
+
i0.ɵɵelementStart(3, "a", 182);
|
|
1066
|
+
i0.ɵɵtext(4);
|
|
1067
|
+
i0.ɵɵelement(5, "i", 183);
|
|
1068
|
+
i0.ɵɵelementEnd()();
|
|
1069
|
+
} if (rf & 2) {
|
|
1070
|
+
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
1071
|
+
i0.ɵɵadvance(3);
|
|
1072
|
+
i0.ɵɵproperty("href", ctx_r2.SelectedFeedItem.URL, i0.ɵɵsanitizeUrl);
|
|
1073
|
+
i0.ɵɵadvance();
|
|
1074
|
+
i0.ɵɵtextInterpolate1(" ", ctx_r2.SelectedFeedItem.URL, " ");
|
|
1075
|
+
} }
|
|
1076
|
+
function AutotaggingPipelineResourceComponent_Conditional_21_Conditional_19_Template(rf, ctx) { if (rf & 1) {
|
|
1077
|
+
i0.ɵɵelementStart(0, "div", 171)(1, "div", 172);
|
|
1078
|
+
i0.ɵɵtext(2, "Content Preview");
|
|
1079
|
+
i0.ɵɵelementEnd();
|
|
1080
|
+
i0.ɵɵelementStart(3, "div", 184);
|
|
1081
|
+
i0.ɵɵtext(4);
|
|
1082
|
+
i0.ɵɵelementEnd()();
|
|
1083
|
+
} if (rf & 2) {
|
|
1084
|
+
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
1085
|
+
i0.ɵɵadvance(4);
|
|
1086
|
+
i0.ɵɵtextInterpolate(ctx_r2.SelectedFeedItem.TextContent);
|
|
1087
|
+
} }
|
|
1088
|
+
function AutotaggingPipelineResourceComponent_Conditional_21_Conditional_20_For_5_Template(rf, ctx) { if (rf & 1) {
|
|
1089
|
+
i0.ɵɵelementStart(0, "span", 186);
|
|
1090
|
+
i0.ɵɵtext(1);
|
|
1091
|
+
i0.ɵɵelementEnd();
|
|
1092
|
+
} if (rf & 2) {
|
|
1093
|
+
const tag_r34 = ctx.$implicit;
|
|
1094
|
+
i0.ɵɵadvance();
|
|
1095
|
+
i0.ɵɵtextInterpolate(tag_r34);
|
|
1096
|
+
} }
|
|
1097
|
+
function AutotaggingPipelineResourceComponent_Conditional_21_Conditional_20_Template(rf, ctx) { if (rf & 1) {
|
|
1098
|
+
i0.ɵɵelementStart(0, "div", 171)(1, "div", 172);
|
|
1099
|
+
i0.ɵɵtext(2);
|
|
1100
|
+
i0.ɵɵelementEnd();
|
|
1101
|
+
i0.ɵɵelementStart(3, "div", 185);
|
|
1102
|
+
i0.ɵɵrepeaterCreate(4, AutotaggingPipelineResourceComponent_Conditional_21_Conditional_20_For_5_Template, 2, 1, "span", 186, i0.ɵɵrepeaterTrackByIdentity);
|
|
1103
|
+
i0.ɵɵelementEnd()();
|
|
1104
|
+
} if (rf & 2) {
|
|
1105
|
+
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
1106
|
+
i0.ɵɵadvance(2);
|
|
1107
|
+
i0.ɵɵtextInterpolate1("Tags (", ctx_r2.SelectedFeedItem.Tags.length, ")");
|
|
1108
|
+
i0.ɵɵadvance(2);
|
|
1109
|
+
i0.ɵɵrepeater(ctx_r2.SelectedFeedItem.Tags);
|
|
1110
|
+
} }
|
|
1111
|
+
function AutotaggingPipelineResourceComponent_Conditional_21_Conditional_25_Template(rf, ctx) { if (rf & 1) {
|
|
1112
|
+
i0.ɵɵelementStart(0, "div", 174)(1, "span", 175);
|
|
1113
|
+
i0.ɵɵtext(2, "Checksum");
|
|
1114
|
+
i0.ɵɵelementEnd();
|
|
1115
|
+
i0.ɵɵelementStart(3, "span", 187);
|
|
1116
|
+
i0.ɵɵtext(4);
|
|
1117
|
+
i0.ɵɵelementEnd()();
|
|
1118
|
+
} if (rf & 2) {
|
|
1119
|
+
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
1120
|
+
i0.ɵɵadvance(4);
|
|
1121
|
+
i0.ɵɵtextInterpolate(ctx_r2.SelectedFeedItem.Checksum);
|
|
1122
|
+
} }
|
|
1123
|
+
function AutotaggingPipelineResourceComponent_Conditional_21_Template(rf, ctx) { if (rf & 1) {
|
|
1124
|
+
const _r33 = i0.ɵɵgetCurrentView();
|
|
1125
|
+
i0.ɵɵelementStart(0, "div", 140);
|
|
1126
|
+
i0.ɵɵlistener("click", function AutotaggingPipelineResourceComponent_Conditional_21_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r33); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.CloseItemDetail()); });
|
|
1127
|
+
i0.ɵɵelementEnd();
|
|
1128
|
+
i0.ɵɵelementStart(1, "div", 163)(2, "div", 142)(3, "h3");
|
|
1129
|
+
i0.ɵɵelement(4, "i", 164);
|
|
1130
|
+
i0.ɵɵtext(5, " Content Item");
|
|
1131
|
+
i0.ɵɵelementEnd();
|
|
1132
|
+
i0.ɵɵelementStart(6, "button", 143);
|
|
1133
|
+
i0.ɵɵlistener("click", function AutotaggingPipelineResourceComponent_Conditional_21_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r33); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.CloseItemDetail()); });
|
|
1134
|
+
i0.ɵɵelement(7, "i", 144);
|
|
1135
|
+
i0.ɵɵelementEnd()();
|
|
1136
|
+
i0.ɵɵelementStart(8, "div", 145)(9, "div", 165)(10, "h4", 166);
|
|
1137
|
+
i0.ɵɵtext(11);
|
|
1138
|
+
i0.ɵɵelementEnd();
|
|
1139
|
+
i0.ɵɵelementStart(12, "div", 167)(13, "span", 168);
|
|
1140
|
+
i0.ɵɵtext(14);
|
|
1141
|
+
i0.ɵɵelementEnd();
|
|
1142
|
+
i0.ɵɵelementStart(15, "span", 169);
|
|
1143
|
+
i0.ɵɵtext(16);
|
|
1144
|
+
i0.ɵɵelementEnd();
|
|
1145
|
+
i0.ɵɵconditionalCreate(17, AutotaggingPipelineResourceComponent_Conditional_21_Conditional_17_Template, 3, 1, "span", 170);
|
|
1146
|
+
i0.ɵɵelementEnd()();
|
|
1147
|
+
i0.ɵɵconditionalCreate(18, AutotaggingPipelineResourceComponent_Conditional_21_Conditional_18_Template, 6, 2, "div", 171);
|
|
1148
|
+
i0.ɵɵconditionalCreate(19, AutotaggingPipelineResourceComponent_Conditional_21_Conditional_19_Template, 5, 1, "div", 171);
|
|
1149
|
+
i0.ɵɵconditionalCreate(20, AutotaggingPipelineResourceComponent_Conditional_21_Conditional_20_Template, 6, 1, "div", 171);
|
|
1150
|
+
i0.ɵɵelementStart(21, "div", 171)(22, "div", 172);
|
|
1151
|
+
i0.ɵɵtext(23, "Metadata");
|
|
1152
|
+
i0.ɵɵelementEnd();
|
|
1153
|
+
i0.ɵɵelementStart(24, "div", 173);
|
|
1154
|
+
i0.ɵɵconditionalCreate(25, AutotaggingPipelineResourceComponent_Conditional_21_Conditional_25_Template, 5, 1, "div", 174);
|
|
1155
|
+
i0.ɵɵelementStart(26, "div", 174)(27, "span", 175);
|
|
1156
|
+
i0.ɵɵtext(28, "Created");
|
|
1157
|
+
i0.ɵɵelementEnd();
|
|
1158
|
+
i0.ɵɵelementStart(29, "span", 176);
|
|
1159
|
+
i0.ɵɵtext(30);
|
|
1160
|
+
i0.ɵɵelementEnd()();
|
|
1161
|
+
i0.ɵɵelementStart(31, "div", 174)(32, "span", 175);
|
|
1162
|
+
i0.ɵɵtext(33, "Updated");
|
|
1163
|
+
i0.ɵɵelementEnd();
|
|
1164
|
+
i0.ɵɵelementStart(34, "span", 176);
|
|
1165
|
+
i0.ɵɵtext(35);
|
|
1166
|
+
i0.ɵɵelementEnd()()()();
|
|
1167
|
+
i0.ɵɵelementStart(36, "div", 177)(37, "button", 71);
|
|
1168
|
+
i0.ɵɵlistener("click", function AutotaggingPipelineResourceComponent_Conditional_21_Template_button_click_37_listener() { i0.ɵɵrestoreView(_r33); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OpenRecordFromItem(ctx_r2.SelectedFeedItem)); });
|
|
1169
|
+
i0.ɵɵelement(38, "i", 178);
|
|
1170
|
+
i0.ɵɵtext(39, " Open Record ");
|
|
1171
|
+
i0.ɵɵelementEnd();
|
|
1172
|
+
i0.ɵɵelementStart(40, "button", 179);
|
|
1173
|
+
i0.ɵɵelement(41, "i", 180);
|
|
1174
|
+
i0.ɵɵtext(42, " See Similar Items ");
|
|
1175
|
+
i0.ɵɵelementEnd()()()();
|
|
1176
|
+
} if (rf & 2) {
|
|
1177
|
+
const ctx_r2 = i0.ɵɵnextContext();
|
|
1178
|
+
i0.ɵɵadvance(11);
|
|
1179
|
+
i0.ɵɵtextInterpolate(ctx_r2.SelectedFeedItem.Name);
|
|
1180
|
+
i0.ɵɵadvance(3);
|
|
1181
|
+
i0.ɵɵtextInterpolate(ctx_r2.SelectedFeedItem.SourceName);
|
|
1182
|
+
i0.ɵɵadvance(2);
|
|
1183
|
+
i0.ɵɵtextInterpolate(ctx_r2.SelectedFeedItem.ContentTypeName);
|
|
1184
|
+
i0.ɵɵadvance();
|
|
1185
|
+
i0.ɵɵconditional(ctx_r2.SelectedFeedItem.FileTypeName ? 17 : -1);
|
|
1186
|
+
i0.ɵɵadvance();
|
|
1187
|
+
i0.ɵɵconditional(ctx_r2.SelectedFeedItem.URL ? 18 : -1);
|
|
1188
|
+
i0.ɵɵadvance();
|
|
1189
|
+
i0.ɵɵconditional(ctx_r2.SelectedFeedItem.TextContent ? 19 : -1);
|
|
1190
|
+
i0.ɵɵadvance();
|
|
1191
|
+
i0.ɵɵconditional(ctx_r2.SelectedFeedItem.Tags.length > 0 ? 20 : -1);
|
|
1192
|
+
i0.ɵɵadvance(5);
|
|
1193
|
+
i0.ɵɵconditional(ctx_r2.SelectedFeedItem.Checksum ? 25 : -1);
|
|
1194
|
+
i0.ɵɵadvance(5);
|
|
1195
|
+
i0.ɵɵtextInterpolate(ctx_r2.SelectedFeedItem.CreatedAt);
|
|
1196
|
+
i0.ɵɵadvance(5);
|
|
1197
|
+
i0.ɵɵtextInterpolate(ctx_r2.SelectedFeedItem.UpdatedAt);
|
|
1198
|
+
} }
|
|
1199
|
+
function AutotaggingPipelineResourceComponent_Conditional_22_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
1200
|
+
i0.ɵɵelementStart(0, "div", 12);
|
|
1201
|
+
i0.ɵɵelement(1, "mj-loading", 188);
|
|
1202
|
+
i0.ɵɵelementEnd();
|
|
1203
|
+
} }
|
|
1204
|
+
function AutotaggingPipelineResourceComponent_Conditional_22_Conditional_10_Conditional_15_Template(rf, ctx) { if (rf & 1) {
|
|
1205
|
+
i0.ɵɵelementStart(0, "div", 174)(1, "span", 175);
|
|
1206
|
+
i0.ɵɵtext(2, "URL");
|
|
1207
|
+
i0.ɵɵelementEnd();
|
|
1208
|
+
i0.ɵɵelementStart(3, "a", 199);
|
|
1209
|
+
i0.ɵɵtext(4);
|
|
1210
|
+
i0.ɵɵelementEnd()();
|
|
1211
|
+
} if (rf & 2) {
|
|
1212
|
+
const ctx_r2 = i0.ɵɵnextContext(3);
|
|
1213
|
+
i0.ɵɵadvance(3);
|
|
1214
|
+
i0.ɵɵproperty("href", ctx_r2.SelectedSource.URL, i0.ɵɵsanitizeUrl);
|
|
1215
|
+
i0.ɵɵadvance();
|
|
1216
|
+
i0.ɵɵtextInterpolate(ctx_r2.SelectedSource.URL);
|
|
1217
|
+
} }
|
|
1218
|
+
function AutotaggingPipelineResourceComponent_Conditional_22_Conditional_10_Conditional_69_Template(rf, ctx) { if (rf & 1) {
|
|
1219
|
+
i0.ɵɵelementStart(0, "div", 196)(1, "p");
|
|
1220
|
+
i0.ɵɵtext(2, "No content items yet.");
|
|
1221
|
+
i0.ɵɵelementEnd()();
|
|
1222
|
+
} }
|
|
1223
|
+
function AutotaggingPipelineResourceComponent_Conditional_22_Conditional_10_For_71_Template(rf, ctx) { if (rf & 1) {
|
|
1224
|
+
const _r37 = i0.ɵɵgetCurrentView();
|
|
1225
|
+
i0.ɵɵelementStart(0, "div", 200);
|
|
1226
|
+
i0.ɵɵlistener("click", function AutotaggingPipelineResourceComponent_Conditional_22_Conditional_10_For_71_Template_div_click_0_listener() { const ci_r38 = i0.ɵɵrestoreView(_r37).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.OpenContentItemDetail(ci_r38)); });
|
|
1227
|
+
i0.ɵɵelement(1, "div", 59);
|
|
1228
|
+
i0.ɵɵelementStart(2, "span", 201);
|
|
1229
|
+
i0.ɵɵtext(3);
|
|
1230
|
+
i0.ɵɵelementEnd();
|
|
1231
|
+
i0.ɵɵelementStart(4, "span", 202);
|
|
1232
|
+
i0.ɵɵtext(5);
|
|
1233
|
+
i0.ɵɵelementEnd();
|
|
1234
|
+
i0.ɵɵelementStart(6, "span", 203);
|
|
1235
|
+
i0.ɵɵtext(7);
|
|
1236
|
+
i0.ɵɵelementEnd()();
|
|
1237
|
+
} if (rf & 2) {
|
|
1238
|
+
const ci_r38 = ctx.$implicit;
|
|
1239
|
+
i0.ɵɵadvance();
|
|
1240
|
+
i0.ɵɵclassMap(ci_r38.StatusDot);
|
|
1241
|
+
i0.ɵɵadvance(2);
|
|
1242
|
+
i0.ɵɵtextInterpolate(ci_r38.Name);
|
|
1243
|
+
i0.ɵɵadvance(2);
|
|
1244
|
+
i0.ɵɵtextInterpolate1("", ci_r38.TagCount, " tags");
|
|
1245
|
+
i0.ɵɵadvance(2);
|
|
1246
|
+
i0.ɵɵtextInterpolate(ci_r38.UpdatedAt);
|
|
1247
|
+
} }
|
|
1248
|
+
function AutotaggingPipelineResourceComponent_Conditional_22_Conditional_10_Conditional_72_For_5_Template(rf, ctx) { if (rf & 1) {
|
|
1249
|
+
i0.ɵɵelementStart(0, "div", 205)(1, "span", 136);
|
|
1250
|
+
i0.ɵɵtext(2);
|
|
1251
|
+
i0.ɵɵelementEnd();
|
|
1252
|
+
i0.ɵɵelementStart(3, "span", 206);
|
|
1253
|
+
i0.ɵɵtext(4);
|
|
1254
|
+
i0.ɵɵelementEnd();
|
|
1255
|
+
i0.ɵɵelementStart(5, "span", 207);
|
|
1256
|
+
i0.ɵɵtext(6);
|
|
1257
|
+
i0.ɵɵelementEnd();
|
|
1258
|
+
i0.ɵɵelementStart(7, "span", 208);
|
|
1259
|
+
i0.ɵɵtext(8);
|
|
1260
|
+
i0.ɵɵelementEnd()();
|
|
1261
|
+
} if (rf & 2) {
|
|
1262
|
+
const run_r39 = ctx.$implicit;
|
|
1263
|
+
i0.ɵɵadvance();
|
|
1264
|
+
i0.ɵɵclassMap(run_r39.StatusClass);
|
|
1265
|
+
i0.ɵɵadvance();
|
|
1266
|
+
i0.ɵɵtextInterpolate(run_r39.Status);
|
|
1267
|
+
i0.ɵɵadvance(2);
|
|
1268
|
+
i0.ɵɵtextInterpolate(run_r39.StartedDisplay);
|
|
1269
|
+
i0.ɵɵadvance(2);
|
|
1270
|
+
i0.ɵɵtextInterpolate(run_r39.Duration);
|
|
1271
|
+
i0.ɵɵadvance(2);
|
|
1272
|
+
i0.ɵɵtextInterpolate1("", run_r39.Items, " items");
|
|
1273
|
+
} }
|
|
1274
|
+
function AutotaggingPipelineResourceComponent_Conditional_22_Conditional_10_Conditional_72_Template(rf, ctx) { if (rf & 1) {
|
|
1275
|
+
i0.ɵɵelementStart(0, "div", 171)(1, "div", 172);
|
|
1276
|
+
i0.ɵɵtext(2, "Recent Runs");
|
|
1277
|
+
i0.ɵɵelementEnd();
|
|
1278
|
+
i0.ɵɵelementStart(3, "div", 204);
|
|
1279
|
+
i0.ɵɵrepeaterCreate(4, AutotaggingPipelineResourceComponent_Conditional_22_Conditional_10_Conditional_72_For_5_Template, 9, 6, "div", 205, _forTrack2);
|
|
1280
|
+
i0.ɵɵelementEnd()();
|
|
1281
|
+
} if (rf & 2) {
|
|
1282
|
+
const ctx_r2 = i0.ɵɵnextContext(3);
|
|
1283
|
+
i0.ɵɵadvance(4);
|
|
1284
|
+
i0.ɵɵrepeater(ctx_r2.SelectedSource.RunHistory);
|
|
1285
|
+
} }
|
|
1286
|
+
function AutotaggingPipelineResourceComponent_Conditional_22_Conditional_10_Template(rf, ctx) { if (rf & 1) {
|
|
1287
|
+
const _r36 = i0.ɵɵgetCurrentView();
|
|
1288
|
+
i0.ɵɵelementStart(0, "div", 189)(1, "div", 81);
|
|
1289
|
+
i0.ɵɵelement(2, "i");
|
|
1290
|
+
i0.ɵɵelementEnd();
|
|
1291
|
+
i0.ɵɵelementStart(3, "div")(4, "h4", 166);
|
|
1292
|
+
i0.ɵɵtext(5);
|
|
1293
|
+
i0.ɵɵelementEnd();
|
|
1294
|
+
i0.ɵɵelementStart(6, "div", 167)(7, "span", 169);
|
|
1295
|
+
i0.ɵɵtext(8);
|
|
1296
|
+
i0.ɵɵelementEnd();
|
|
1297
|
+
i0.ɵɵelementStart(9, "span", 190);
|
|
1298
|
+
i0.ɵɵtext(10);
|
|
1299
|
+
i0.ɵɵelementEnd()()()();
|
|
1300
|
+
i0.ɵɵelementStart(11, "div", 171)(12, "div", 172);
|
|
1301
|
+
i0.ɵɵtext(13, "Configuration");
|
|
1302
|
+
i0.ɵɵelementEnd();
|
|
1303
|
+
i0.ɵɵelementStart(14, "div", 173);
|
|
1304
|
+
i0.ɵɵconditionalCreate(15, AutotaggingPipelineResourceComponent_Conditional_22_Conditional_10_Conditional_15_Template, 5, 2, "div", 174);
|
|
1305
|
+
i0.ɵɵelementStart(16, "div", 174)(17, "span", 175);
|
|
1306
|
+
i0.ɵɵtext(18, "Content Type");
|
|
1307
|
+
i0.ɵɵelementEnd();
|
|
1308
|
+
i0.ɵɵelementStart(19, "span", 176);
|
|
1309
|
+
i0.ɵɵtext(20);
|
|
1310
|
+
i0.ɵɵelementEnd()();
|
|
1311
|
+
i0.ɵɵelementStart(21, "div", 174)(22, "span", 175);
|
|
1312
|
+
i0.ɵɵtext(23, "File Type");
|
|
1313
|
+
i0.ɵɵelementEnd();
|
|
1314
|
+
i0.ɵɵelementStart(24, "span", 176);
|
|
1315
|
+
i0.ɵɵtext(25);
|
|
1316
|
+
i0.ɵɵelementEnd()();
|
|
1317
|
+
i0.ɵɵelementStart(26, "div", 174)(27, "span", 175);
|
|
1318
|
+
i0.ɵɵtext(28, "Embedding Model");
|
|
1319
|
+
i0.ɵɵelementEnd();
|
|
1320
|
+
i0.ɵɵelementStart(29, "span", 176);
|
|
1321
|
+
i0.ɵɵtext(30);
|
|
1322
|
+
i0.ɵɵelementEnd()();
|
|
1323
|
+
i0.ɵɵelementStart(31, "div", 174)(32, "span", 175);
|
|
1324
|
+
i0.ɵɵtext(33, "Vector Index");
|
|
1325
|
+
i0.ɵɵelementEnd();
|
|
1326
|
+
i0.ɵɵelementStart(34, "span", 176);
|
|
1327
|
+
i0.ɵɵtext(35);
|
|
1328
|
+
i0.ɵɵelementEnd()()()();
|
|
1329
|
+
i0.ɵɵelementStart(36, "div", 171)(37, "div", 172);
|
|
1330
|
+
i0.ɵɵtext(38, "Statistics");
|
|
1331
|
+
i0.ɵɵelementEnd();
|
|
1332
|
+
i0.ɵɵelementStart(39, "div", 191)(40, "div", 192)(41, "div", 193);
|
|
1333
|
+
i0.ɵɵtext(42);
|
|
1334
|
+
i0.ɵɵelementEnd();
|
|
1335
|
+
i0.ɵɵelementStart(43, "div", 194);
|
|
1336
|
+
i0.ɵɵtext(44, "Items");
|
|
1337
|
+
i0.ɵɵelementEnd()();
|
|
1338
|
+
i0.ɵɵelementStart(45, "div", 192)(46, "div", 193);
|
|
1339
|
+
i0.ɵɵtext(47);
|
|
1340
|
+
i0.ɵɵelementEnd();
|
|
1341
|
+
i0.ɵɵelementStart(48, "div", 194);
|
|
1342
|
+
i0.ɵɵtext(49, "Tags");
|
|
1343
|
+
i0.ɵɵelementEnd()();
|
|
1344
|
+
i0.ɵɵelementStart(50, "div", 192)(51, "div", 193);
|
|
1345
|
+
i0.ɵɵtext(52);
|
|
1346
|
+
i0.ɵɵelementEnd();
|
|
1347
|
+
i0.ɵɵelementStart(53, "div", 194);
|
|
1348
|
+
i0.ɵɵtext(54, "Avg Tags");
|
|
1349
|
+
i0.ɵɵelementEnd()();
|
|
1350
|
+
i0.ɵɵelementStart(55, "div", 192)(56, "div", 193);
|
|
1351
|
+
i0.ɵɵtext(57);
|
|
1352
|
+
i0.ɵɵelementEnd();
|
|
1353
|
+
i0.ɵɵelementStart(58, "div", 194);
|
|
1354
|
+
i0.ɵɵtext(59, "Last Run");
|
|
1355
|
+
i0.ɵɵelementEnd()();
|
|
1356
|
+
i0.ɵɵelementStart(60, "div", 192)(61, "div", 193);
|
|
1357
|
+
i0.ɵɵtext(62);
|
|
1358
|
+
i0.ɵɵelementEnd();
|
|
1359
|
+
i0.ɵɵelementStart(63, "div", 194);
|
|
1360
|
+
i0.ɵɵtext(64, "Errors");
|
|
1361
|
+
i0.ɵɵelementEnd()()()();
|
|
1362
|
+
i0.ɵɵelementStart(65, "div", 171)(66, "div", 172);
|
|
1363
|
+
i0.ɵɵtext(67);
|
|
1364
|
+
i0.ɵɵelementEnd();
|
|
1365
|
+
i0.ɵɵelementStart(68, "div", 195);
|
|
1366
|
+
i0.ɵɵconditionalCreate(69, AutotaggingPipelineResourceComponent_Conditional_22_Conditional_10_Conditional_69_Template, 3, 0, "div", 196);
|
|
1367
|
+
i0.ɵɵrepeaterCreate(70, AutotaggingPipelineResourceComponent_Conditional_22_Conditional_10_For_71_Template, 8, 5, "div", 197, _forTrack2);
|
|
1368
|
+
i0.ɵɵelementEnd()();
|
|
1369
|
+
i0.ɵɵconditionalCreate(72, AutotaggingPipelineResourceComponent_Conditional_22_Conditional_10_Conditional_72_Template, 6, 0, "div", 171);
|
|
1370
|
+
i0.ɵɵelementStart(73, "div", 177)(74, "button", 71);
|
|
1371
|
+
i0.ɵɵlistener("click", function AutotaggingPipelineResourceComponent_Conditional_22_Conditional_10_Template_button_click_74_listener() { i0.ɵɵrestoreView(_r36); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.OpenEditSourceFromDetail()); });
|
|
1372
|
+
i0.ɵɵelement(75, "i", 92);
|
|
1373
|
+
i0.ɵɵtext(76, " Edit ");
|
|
1374
|
+
i0.ɵɵelementEnd();
|
|
1375
|
+
i0.ɵɵelementStart(77, "button", 22);
|
|
1376
|
+
i0.ɵɵlistener("click", function AutotaggingPipelineResourceComponent_Conditional_22_Conditional_10_Template_button_click_77_listener() { i0.ɵɵrestoreView(_r36); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.RunSourceFromDetail()); });
|
|
1377
|
+
i0.ɵɵelement(78, "i", 16);
|
|
1378
|
+
i0.ɵɵtext(79, " Run Now ");
|
|
1379
|
+
i0.ɵɵelementEnd();
|
|
1380
|
+
i0.ɵɵelementStart(80, "button", 198);
|
|
1381
|
+
i0.ɵɵlistener("click", function AutotaggingPipelineResourceComponent_Conditional_22_Conditional_10_Template_button_click_80_listener() { i0.ɵɵrestoreView(_r36); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.DeleteSourceFromDetail()); });
|
|
1382
|
+
i0.ɵɵelement(81, "i", 94);
|
|
1383
|
+
i0.ɵɵtext(82, " Delete ");
|
|
1384
|
+
i0.ɵɵelementEnd()();
|
|
1385
|
+
} if (rf & 2) {
|
|
1386
|
+
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
1387
|
+
i0.ɵɵadvance(2);
|
|
1388
|
+
i0.ɵɵclassMap(ctx_r2.SelectedSource.Icon);
|
|
1389
|
+
i0.ɵɵadvance(3);
|
|
1390
|
+
i0.ɵɵtextInterpolate(ctx_r2.SelectedSource.Name);
|
|
1391
|
+
i0.ɵɵadvance(3);
|
|
1392
|
+
i0.ɵɵtextInterpolate(ctx_r2.SelectedSource.SourceTypeName);
|
|
1393
|
+
i0.ɵɵadvance();
|
|
1394
|
+
i0.ɵɵclassMap("at-detail-badge-status-" + ctx_r2.SelectedSource.StatusClass);
|
|
1395
|
+
i0.ɵɵadvance();
|
|
1396
|
+
i0.ɵɵtextInterpolate1(" ", ctx_r2.SelectedSource.StatusLabel, " ");
|
|
1397
|
+
i0.ɵɵadvance(5);
|
|
1398
|
+
i0.ɵɵconditional(ctx_r2.SelectedSource.URL ? 15 : -1);
|
|
1399
|
+
i0.ɵɵadvance(5);
|
|
1400
|
+
i0.ɵɵtextInterpolate(ctx_r2.SelectedSource.ContentTypeName);
|
|
1401
|
+
i0.ɵɵadvance(5);
|
|
1402
|
+
i0.ɵɵtextInterpolate(ctx_r2.SelectedSource.FileTypeName);
|
|
1403
|
+
i0.ɵɵadvance(5);
|
|
1404
|
+
i0.ɵɵtextInterpolate(ctx_r2.SelectedSource.EmbeddingModelName);
|
|
1405
|
+
i0.ɵɵadvance(5);
|
|
1406
|
+
i0.ɵɵtextInterpolate(ctx_r2.SelectedSource.VectorIndexName);
|
|
1407
|
+
i0.ɵɵadvance(7);
|
|
1408
|
+
i0.ɵɵtextInterpolate(ctx_r2.formatNumber(ctx_r2.SelectedSource.ItemCount));
|
|
1409
|
+
i0.ɵɵadvance(5);
|
|
1410
|
+
i0.ɵɵtextInterpolate(ctx_r2.formatNumber(ctx_r2.SelectedSource.TagCount));
|
|
1411
|
+
i0.ɵɵadvance(5);
|
|
1412
|
+
i0.ɵɵtextInterpolate(ctx_r2.SelectedSource.AvgTags);
|
|
1413
|
+
i0.ɵɵadvance(5);
|
|
1414
|
+
i0.ɵɵtextInterpolate(ctx_r2.SelectedSource.LastRunAgo);
|
|
1415
|
+
i0.ɵɵadvance(4);
|
|
1416
|
+
i0.ɵɵclassProp("at-kpi-error-value", ctx_r2.SelectedSource.ErrorCount > 0);
|
|
1417
|
+
i0.ɵɵadvance();
|
|
1418
|
+
i0.ɵɵtextInterpolate(ctx_r2.SelectedSource.ErrorCount);
|
|
1419
|
+
i0.ɵɵadvance(5);
|
|
1420
|
+
i0.ɵɵtextInterpolate1("Content Library (", ctx_r2.SelectedSource.ContentItems.length, ")");
|
|
1421
|
+
i0.ɵɵadvance(2);
|
|
1422
|
+
i0.ɵɵconditional(ctx_r2.SelectedSource.ContentItems.length === 0 ? 69 : -1);
|
|
1423
|
+
i0.ɵɵadvance();
|
|
1424
|
+
i0.ɵɵrepeater(ctx_r2.SelectedSource.ContentItems);
|
|
1425
|
+
i0.ɵɵadvance(2);
|
|
1426
|
+
i0.ɵɵconditional(ctx_r2.SelectedSource.RunHistory.length > 0 ? 72 : -1);
|
|
1427
|
+
} }
|
|
1428
|
+
function AutotaggingPipelineResourceComponent_Conditional_22_Template(rf, ctx) { if (rf & 1) {
|
|
1429
|
+
const _r35 = i0.ɵɵgetCurrentView();
|
|
1430
|
+
i0.ɵɵelementStart(0, "div", 140);
|
|
1431
|
+
i0.ɵɵlistener("click", function AutotaggingPipelineResourceComponent_Conditional_22_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r35); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.CloseSourceDetail()); });
|
|
1432
|
+
i0.ɵɵelementEnd();
|
|
1433
|
+
i0.ɵɵelementStart(1, "div", 163)(2, "div", 142)(3, "h3");
|
|
1434
|
+
i0.ɵɵelement(4, "i", 39);
|
|
1435
|
+
i0.ɵɵtext(5, " Source Detail");
|
|
1436
|
+
i0.ɵɵelementEnd();
|
|
1437
|
+
i0.ɵɵelementStart(6, "button", 143);
|
|
1438
|
+
i0.ɵɵlistener("click", function AutotaggingPipelineResourceComponent_Conditional_22_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r35); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.CloseSourceDetail()); });
|
|
1439
|
+
i0.ɵɵelement(7, "i", 144);
|
|
1440
|
+
i0.ɵɵelementEnd()();
|
|
1441
|
+
i0.ɵɵelementStart(8, "div", 145);
|
|
1442
|
+
i0.ɵɵconditionalCreate(9, AutotaggingPipelineResourceComponent_Conditional_22_Conditional_9_Template, 2, 0, "div", 12);
|
|
1443
|
+
i0.ɵɵconditionalCreate(10, AutotaggingPipelineResourceComponent_Conditional_22_Conditional_10_Template, 83, 22);
|
|
1444
|
+
i0.ɵɵelementEnd()();
|
|
1445
|
+
} if (rf & 2) {
|
|
1446
|
+
const ctx_r2 = i0.ɵɵnextContext();
|
|
1447
|
+
i0.ɵɵadvance(9);
|
|
1448
|
+
i0.ɵɵconditional(ctx_r2.SourceDetailLoading ? 9 : -1);
|
|
1449
|
+
i0.ɵɵadvance();
|
|
1450
|
+
i0.ɵɵconditional(!ctx_r2.SourceDetailLoading && ctx_r2.SelectedSource ? 10 : -1);
|
|
1451
|
+
} }
|
|
1452
|
+
let AutotaggingPipelineResourceComponent = class AutotaggingPipelineResourceComponent extends BaseResourceComponent {
|
|
1453
|
+
destroy$ = new Subject();
|
|
1454
|
+
cdr = inject(ChangeDetectorRef);
|
|
1455
|
+
navigationService = inject(NavigationService);
|
|
1456
|
+
// ── Global state ──
|
|
1457
|
+
IsLoading = true;
|
|
1458
|
+
// ── Tab state ──
|
|
1459
|
+
ActiveTab = 'pipeline';
|
|
1460
|
+
tabDataLoaded = new Set();
|
|
1461
|
+
// ── Left nav ──
|
|
1462
|
+
NavItems = [];
|
|
1463
|
+
// ── Pipeline tab ──
|
|
1464
|
+
KPIMetrics = [];
|
|
1465
|
+
PipelineStages = [];
|
|
1466
|
+
FeedItems = [];
|
|
1467
|
+
SourceMinis = [];
|
|
1468
|
+
TrendingTags = [];
|
|
1469
|
+
// Pipeline run state
|
|
1470
|
+
IsRunning = false;
|
|
1471
|
+
RunProgress = 0;
|
|
1472
|
+
RunStage = '';
|
|
1473
|
+
RunCurrentItem = '';
|
|
1474
|
+
// ── Sources tab ──
|
|
1475
|
+
SourceCards = [];
|
|
1476
|
+
// ── Content Types tab ──
|
|
1477
|
+
ContentTypeCards = [];
|
|
1478
|
+
// ── Tag Library tab ──
|
|
1479
|
+
TagRows = [];
|
|
1480
|
+
TagCloud = [];
|
|
1481
|
+
TagsBySource = [];
|
|
1482
|
+
TagSearchQuery = '';
|
|
1483
|
+
FilteredTagRows = [];
|
|
1484
|
+
// ── Run History tab ──
|
|
1485
|
+
RunHistoryRows = [];
|
|
1486
|
+
HistorySourceFilter = '';
|
|
1487
|
+
HistoryStatusFilter = '';
|
|
1488
|
+
FilteredRunRows = [];
|
|
1489
|
+
HistorySourceOptions = [];
|
|
1490
|
+
// ── Slide-in form ──
|
|
1491
|
+
FormMode = 'none';
|
|
1492
|
+
FormSaving = false;
|
|
1493
|
+
// Source form fields
|
|
1494
|
+
FormSourceName = '';
|
|
1495
|
+
FormSourceTypeID = '';
|
|
1496
|
+
FormContentTypeID = '';
|
|
1497
|
+
FormFileTypeID = '';
|
|
1498
|
+
FormSourceURL = '';
|
|
1499
|
+
EditingSourceID = '';
|
|
1500
|
+
// Content Type form fields
|
|
1501
|
+
FormTypeName = '';
|
|
1502
|
+
FormTypeDescription = '';
|
|
1503
|
+
FormTypeAIModelID = '';
|
|
1504
|
+
FormTypeMinTags = 1;
|
|
1505
|
+
FormTypeMaxTags = 10;
|
|
1506
|
+
EditingTypeID = '';
|
|
1507
|
+
// Embedding model + vector index form fields (Content Type)
|
|
1508
|
+
FormTypeEmbeddingModelID = '';
|
|
1509
|
+
FormTypeVectorIndexID = '';
|
|
1510
|
+
// Embedding model + vector index form fields (Content Source overrides)
|
|
1511
|
+
FormSourceEmbeddingModelID = '';
|
|
1512
|
+
FormSourceVectorIndexID = '';
|
|
1513
|
+
// ── Detail panels ──
|
|
1514
|
+
SelectedFeedItem = null;
|
|
1515
|
+
ShowItemDetail = false;
|
|
1516
|
+
SelectedSource = null;
|
|
1517
|
+
ShowSourceDetail = false;
|
|
1518
|
+
SourceDetailLoading = false;
|
|
1519
|
+
// Dropdown options for forms
|
|
1520
|
+
SourceTypeOptions = [];
|
|
1521
|
+
ContentTypeOptions = [];
|
|
1522
|
+
FileTypeOptions = [];
|
|
1523
|
+
AIModelOptions = [];
|
|
1524
|
+
EmbeddingModelOptions = [];
|
|
1525
|
+
VectorIndexOptions = [];
|
|
1526
|
+
// Tree-dropdown configs for AI model selection (vendor → model grouping)
|
|
1527
|
+
AIModelVendorBranch = {
|
|
1528
|
+
EntityName: 'MJ: AI Vendors',
|
|
1529
|
+
DisplayField: 'Name',
|
|
1530
|
+
IDField: 'ID',
|
|
1531
|
+
DefaultIcon: 'fa-solid fa-building',
|
|
1532
|
+
OrderBy: 'Name ASC',
|
|
1533
|
+
};
|
|
1534
|
+
AllModelsLeaf = {
|
|
1535
|
+
EntityName: 'MJ: AI Models',
|
|
1536
|
+
ParentField: '',
|
|
1537
|
+
DisplayField: 'Name',
|
|
1538
|
+
IDField: 'ID',
|
|
1539
|
+
DefaultIcon: 'fa-solid fa-brain',
|
|
1540
|
+
OrderBy: '__mj_CreatedAt DESC',
|
|
1541
|
+
JunctionConfig: {
|
|
1542
|
+
EntityName: 'MJ: AI Model Vendors',
|
|
1543
|
+
LeafForeignKey: 'ModelID',
|
|
1544
|
+
BranchForeignKey: 'VendorID',
|
|
1545
|
+
},
|
|
1546
|
+
};
|
|
1547
|
+
EmbeddingModelsLeaf = {
|
|
1548
|
+
EntityName: 'MJ: AI Models',
|
|
1549
|
+
ParentField: '',
|
|
1550
|
+
DisplayField: 'Name',
|
|
1551
|
+
IDField: 'ID',
|
|
1552
|
+
DefaultIcon: 'fa-solid fa-vector-square',
|
|
1553
|
+
ExtraFilter: "AIModelType = 'Embeddings'",
|
|
1554
|
+
OrderBy: '__mj_CreatedAt DESC',
|
|
1555
|
+
JunctionConfig: {
|
|
1556
|
+
EntityName: 'MJ: AI Model Vendors',
|
|
1557
|
+
LeafForeignKey: 'ModelID',
|
|
1558
|
+
BranchForeignKey: 'VendorID',
|
|
1559
|
+
},
|
|
1560
|
+
};
|
|
1561
|
+
// ── Raw data cache ──
|
|
1562
|
+
contentSourcesRaw = [];
|
|
1563
|
+
contentItemsRaw = [];
|
|
1564
|
+
contentTagsRaw = [];
|
|
1565
|
+
contentRunsRaw = [];
|
|
1566
|
+
contentSourceTypesRaw = [];
|
|
1567
|
+
contentTypesRaw = [];
|
|
1568
|
+
contentFileTypesRaw = [];
|
|
1569
|
+
aiModelsRaw = [];
|
|
1570
|
+
// ── Lifecycle ──
|
|
1571
|
+
async ngAfterViewInit() {
|
|
1572
|
+
await this.LoadPipelineData();
|
|
1573
|
+
this.tabDataLoaded.add('pipeline');
|
|
1574
|
+
this.IsLoading = false;
|
|
1575
|
+
this.cdr.detectChanges();
|
|
1576
|
+
this.NotifyLoadComplete();
|
|
1577
|
+
}
|
|
1578
|
+
ngOnDestroy() {
|
|
1579
|
+
this.destroy$.next();
|
|
1580
|
+
this.destroy$.complete();
|
|
1581
|
+
}
|
|
1582
|
+
async GetResourceDisplayName(_data) {
|
|
1583
|
+
return 'Content Autotagging';
|
|
1584
|
+
}
|
|
1585
|
+
async GetResourceIconClass(_data) {
|
|
1586
|
+
return 'fa-solid fa-tags';
|
|
1587
|
+
}
|
|
1588
|
+
// ── Tab switching ──
|
|
1589
|
+
async SwitchTab(tab) {
|
|
1590
|
+
if (tab === this.ActiveTab)
|
|
1591
|
+
return;
|
|
1592
|
+
this.ActiveTab = tab;
|
|
1593
|
+
this.cdr.detectChanges();
|
|
1594
|
+
if (!this.tabDataLoaded.has(tab)) {
|
|
1595
|
+
await this.loadTabData(tab);
|
|
1596
|
+
this.tabDataLoaded.add(tab);
|
|
1597
|
+
this.cdr.detectChanges();
|
|
1598
|
+
}
|
|
1599
|
+
}
|
|
1600
|
+
async loadTabData(tab) {
|
|
1601
|
+
switch (tab) {
|
|
1602
|
+
case 'pipeline':
|
|
1603
|
+
await this.LoadPipelineData();
|
|
1604
|
+
break;
|
|
1605
|
+
case 'sources':
|
|
1606
|
+
await this.loadSourcesData();
|
|
1607
|
+
break;
|
|
1608
|
+
case 'types':
|
|
1609
|
+
await this.loadContentTypesData();
|
|
1610
|
+
break;
|
|
1611
|
+
case 'tags':
|
|
1612
|
+
await this.loadTagLibraryData();
|
|
1613
|
+
break;
|
|
1614
|
+
case 'history':
|
|
1615
|
+
await this.loadRunHistoryData();
|
|
1616
|
+
break;
|
|
1617
|
+
}
|
|
1618
|
+
}
|
|
1619
|
+
// ════════════════════════════════════════════
|
|
1620
|
+
// PIPELINE TAB — Data Loading & Building
|
|
1621
|
+
// ════════════════════════════════════════════
|
|
1622
|
+
async LoadPipelineData() {
|
|
1623
|
+
try {
|
|
1624
|
+
const rv = new RunView();
|
|
1625
|
+
const [sourcesResult, itemsResult, runsResult, tagsResult, sourceTypesResult, contentTypesResult] = await rv.RunViews([
|
|
1626
|
+
{ EntityName: 'MJ: Content Sources', OrderBy: 'Name', ResultType: 'simple' },
|
|
1627
|
+
{ EntityName: 'MJ: Content Items', OrderBy: '__mj_UpdatedAt DESC', MaxRows: 200, ResultType: 'simple', Fields: ['ID', 'Name', 'ContentSourceID', 'ContentSource', 'ContentSourceType', 'ContentType', 'ContentFileType', 'URL', 'TextContent', 'Checksum', '__mj_CreatedAt', '__mj_UpdatedAt'] },
|
|
1628
|
+
{ EntityName: 'MJ: Content Process Runs', OrderBy: 'StartTime DESC', MaxRows: 100, ResultType: 'simple' },
|
|
1629
|
+
{ EntityName: 'MJ: Content Item Tags', ResultType: 'simple', Fields: ['ID', 'ItemID', 'Tag', 'Weight', '__mj_CreatedAt'] },
|
|
1630
|
+
{ EntityName: 'MJ: Content Source Types', ResultType: 'simple' },
|
|
1631
|
+
{ EntityName: 'MJ: Content Types', ResultType: 'simple' }
|
|
1632
|
+
]);
|
|
1633
|
+
this.contentSourcesRaw = sourcesResult.Success ? sourcesResult.Results : [];
|
|
1634
|
+
this.contentItemsRaw = itemsResult.Success ? itemsResult.Results : [];
|
|
1635
|
+
this.contentRunsRaw = runsResult.Success ? runsResult.Results : [];
|
|
1636
|
+
this.contentTagsRaw = tagsResult.Success ? tagsResult.Results : [];
|
|
1637
|
+
this.contentSourceTypesRaw = sourceTypesResult.Success ? sourceTypesResult.Results : [];
|
|
1638
|
+
this.contentTypesRaw = contentTypesResult.Success ? contentTypesResult.Results : [];
|
|
1639
|
+
this.buildNavItems();
|
|
1640
|
+
this.buildKPIMetrics();
|
|
1641
|
+
this.buildPipelineStages();
|
|
1642
|
+
this.buildFeedItems();
|
|
1643
|
+
this.buildSourceMinis();
|
|
1644
|
+
this.buildTrendingTags();
|
|
1645
|
+
}
|
|
1646
|
+
catch (error) {
|
|
1647
|
+
console.error('[Autotagging] Error loading pipeline data:', error);
|
|
1648
|
+
}
|
|
1649
|
+
}
|
|
1650
|
+
buildNavItems() {
|
|
1651
|
+
this.NavItems = [
|
|
1652
|
+
{ Tab: 'pipeline', Icon: 'fa-solid fa-gauge-high', Label: 'Pipeline', BadgeText: this.IsRunning ? 'Live' : '', BadgeClass: 'nav-badge-live' },
|
|
1653
|
+
{ Tab: 'sources', Icon: 'fa-solid fa-database', Label: 'Sources', BadgeText: String(this.contentSourcesRaw.length), BadgeClass: '' },
|
|
1654
|
+
{ Tab: 'types', Icon: 'fa-solid fa-sliders', Label: 'Content Types', BadgeText: String(this.contentTypesRaw.length), BadgeClass: '' },
|
|
1655
|
+
{ Tab: 'tags', Icon: 'fa-solid fa-tag', Label: 'Tag Library', BadgeText: String(this.contentTagsRaw.length), BadgeClass: '' },
|
|
1656
|
+
];
|
|
1657
|
+
}
|
|
1658
|
+
buildKPIMetrics() {
|
|
1659
|
+
const sourceCount = this.contentSourcesRaw.length;
|
|
1660
|
+
const itemCount = this.contentItemsRaw.length;
|
|
1661
|
+
const tagCount = this.contentTagsRaw.length;
|
|
1662
|
+
const errorCount = this.contentRunsRaw.filter(r => r['Status']?.toLowerCase() === 'error' || r['Status']?.toLowerCase() === 'failed').length;
|
|
1663
|
+
this.KPIMetrics = [
|
|
1664
|
+
{ Label: 'Active Sources', Value: sourceCount, Icon: 'fa-solid fa-satellite-dish', Trend: '', TrendUp: true },
|
|
1665
|
+
{ Label: 'Content Items', Value: itemCount, Icon: 'fa-solid fa-file-lines', Trend: '', TrendUp: true },
|
|
1666
|
+
{ Label: 'Tags Generated', Value: tagCount, Icon: 'fa-solid fa-tags', Trend: tagCount > 0 && itemCount > 0 ? `${(tagCount / itemCount).toFixed(1)} avg/item` : '', TrendUp: true },
|
|
1667
|
+
{ Label: 'Errors', Value: errorCount, Icon: 'fa-solid fa-circle-exclamation', Trend: '', TrendUp: false }
|
|
1668
|
+
];
|
|
1669
|
+
}
|
|
1670
|
+
buildPipelineStages() {
|
|
1671
|
+
this.PipelineStages = [
|
|
1672
|
+
{ Name: 'Ingest', Icon: 'fa-solid fa-download', Status: 'idle', Count: '\u2014' },
|
|
1673
|
+
{ Name: 'Extract', Icon: 'fa-solid fa-file-lines', Status: 'idle', Count: '\u2014' },
|
|
1674
|
+
{ Name: 'Chunk', Icon: 'fa-solid fa-scissors', Status: 'idle', Count: '\u2014' },
|
|
1675
|
+
{ Name: 'Tag', Icon: 'fa-solid fa-tags', Status: 'idle', Count: '\u2014' },
|
|
1676
|
+
{ Name: 'Vectorize', Icon: 'fa-solid fa-vector-square', Status: 'idle', Count: '\u2014' }
|
|
1677
|
+
];
|
|
1678
|
+
}
|
|
1679
|
+
buildFeedItems() {
|
|
1680
|
+
const tagsByItem = this.countTagsByItem();
|
|
1681
|
+
this.FeedItems = this.contentItemsRaw.slice(0, 50).map(item => {
|
|
1682
|
+
const itemId = item['ID'];
|
|
1683
|
+
const itemTags = this.getTopTagsForItem(itemId, 3);
|
|
1684
|
+
return {
|
|
1685
|
+
Name: item['Name'] ?? 'Unnamed Item',
|
|
1686
|
+
SourceName: item['ContentSource'] ?? 'Unknown',
|
|
1687
|
+
Tags: itemTags,
|
|
1688
|
+
TimeAgo: this.formatRelativeTime(item['__mj_UpdatedAt']),
|
|
1689
|
+
Status: this.inferItemStatus(tagsByItem.get(itemId) ?? 0)
|
|
1690
|
+
};
|
|
1691
|
+
});
|
|
1692
|
+
}
|
|
1693
|
+
buildSourceMinis() {
|
|
1694
|
+
const itemCountBySource = this.countItemsBySource();
|
|
1695
|
+
this.SourceMinis = this.contentSourcesRaw.map(source => {
|
|
1696
|
+
const id = source['ID'];
|
|
1697
|
+
const itemCount = itemCountBySource.get(id) ?? 0;
|
|
1698
|
+
const typeName = source['ContentSourceType'] ?? 'Unknown';
|
|
1699
|
+
return {
|
|
1700
|
+
ID: id,
|
|
1701
|
+
Name: source['Name'] ?? 'Unnamed',
|
|
1702
|
+
Icon: this.GetSourceTypeIcon(typeName),
|
|
1703
|
+
Meta: `${this.formatNumber(itemCount)} items`,
|
|
1704
|
+
StatusClass: 'active'
|
|
1705
|
+
};
|
|
1706
|
+
});
|
|
1707
|
+
}
|
|
1708
|
+
buildTrendingTags() {
|
|
1709
|
+
const tagCounts = this.countAllTags();
|
|
1710
|
+
const avgWeights = this.computeAvgWeights();
|
|
1711
|
+
const scored = Array.from(tagCounts.entries()).map(([tag, count]) => {
|
|
1712
|
+
const weight = avgWeights.get(tag) ?? 1.0;
|
|
1713
|
+
return { tag, count, weight, score: count * weight };
|
|
1714
|
+
}).sort((a, b) => b.score - a.score).slice(0, 12);
|
|
1715
|
+
const maxScore = scored.length > 0 ? scored[0].score : 1;
|
|
1716
|
+
this.TrendingTags = scored.map(s => ({
|
|
1717
|
+
Tag: s.tag,
|
|
1718
|
+
AvgWeight: s.weight,
|
|
1719
|
+
SizeClass: s.score >= maxScore * 0.7 ? 'large' : s.score >= maxScore * 0.3 ? '' : 'small'
|
|
1720
|
+
}));
|
|
1721
|
+
}
|
|
1722
|
+
// ════════════════════════════════════════════
|
|
1723
|
+
// SOURCES TAB
|
|
1724
|
+
// ════════════════════════════════════════════
|
|
1725
|
+
async loadSourcesData() {
|
|
1726
|
+
await this.ensureBaseDataLoaded();
|
|
1727
|
+
this.buildSourceCards();
|
|
1728
|
+
}
|
|
1729
|
+
buildSourceCards() {
|
|
1730
|
+
const itemCountBySource = this.countItemsBySource();
|
|
1731
|
+
const tagCountBySource = this.countTagsBySource();
|
|
1732
|
+
const lastRunBySource = this.getLastRunBySource();
|
|
1733
|
+
this.SourceCards = this.contentSourcesRaw.map(source => {
|
|
1734
|
+
const id = source['ID'];
|
|
1735
|
+
const itemCount = itemCountBySource.get(id) ?? 0;
|
|
1736
|
+
const tagCount = tagCountBySource.get(id) ?? 0;
|
|
1737
|
+
const avgTags = itemCount > 0 ? (tagCount / itemCount).toFixed(1) : '0';
|
|
1738
|
+
const lastRun = lastRunBySource.get(id);
|
|
1739
|
+
const typeName = source['ContentSourceType'] ?? 'Unknown';
|
|
1740
|
+
const lastRunStatus = lastRun ? lastRun['Status']?.toLowerCase() : null;
|
|
1741
|
+
const hasError = lastRunStatus === 'error' || lastRunStatus === 'failed';
|
|
1742
|
+
return {
|
|
1743
|
+
ID: id,
|
|
1744
|
+
Name: source['Name'] ?? 'Unnamed Source',
|
|
1745
|
+
SourceTypeName: typeName,
|
|
1746
|
+
ContentTypeName: source['ContentType'] ?? 'Unknown',
|
|
1747
|
+
FileTypeName: source['ContentFileType'] ?? 'Unknown',
|
|
1748
|
+
Icon: this.GetSourceTypeIcon(typeName),
|
|
1749
|
+
StatusClass: hasError ? 'error' : 'active',
|
|
1750
|
+
StatusLabel: hasError ? 'Error' : 'Active',
|
|
1751
|
+
URL: source['URL'] ?? '',
|
|
1752
|
+
ItemCount: itemCount,
|
|
1753
|
+
TagCount: tagCount,
|
|
1754
|
+
AvgTags: avgTags,
|
|
1755
|
+
LastRunAgo: lastRun ? this.formatRelativeTime(lastRun['StartTime']) : 'Never',
|
|
1756
|
+
ContentSourceTypeID: source['ContentSourceTypeID'],
|
|
1757
|
+
ContentTypeID: source['ContentTypeID'],
|
|
1758
|
+
ContentFileTypeID: source['ContentFileTypeID'],
|
|
1759
|
+
EmbeddingModelID: source['EmbeddingModelID'] ?? '',
|
|
1760
|
+
VectorIndexID: source['VectorIndexID'] ?? ''
|
|
1761
|
+
};
|
|
1762
|
+
});
|
|
1763
|
+
}
|
|
1764
|
+
// ════════════════════════════════════════════
|
|
1765
|
+
// CONTENT TYPES TAB
|
|
1766
|
+
// ════════════════════════════════════════════
|
|
1767
|
+
async loadContentTypesData() {
|
|
1768
|
+
if (this.contentTypesRaw.length === 0) {
|
|
1769
|
+
const rv = new RunView();
|
|
1770
|
+
const result = await rv.RunView({ EntityName: 'MJ: Content Types', ResultType: 'simple' });
|
|
1771
|
+
if (result.Success)
|
|
1772
|
+
this.contentTypesRaw = result.Results;
|
|
1773
|
+
}
|
|
1774
|
+
await this.ensureBaseDataLoaded();
|
|
1775
|
+
this.buildContentTypeCards();
|
|
1776
|
+
}
|
|
1777
|
+
buildContentTypeCards() {
|
|
1778
|
+
const sourcesUsingByType = this.countSourcesByContentType();
|
|
1779
|
+
const itemsByType = this.countItemsByContentType();
|
|
1780
|
+
this.ContentTypeCards = this.contentTypesRaw.map(ct => {
|
|
1781
|
+
const id = ct['ID'];
|
|
1782
|
+
const minTags = ct['MinTags'] ?? 1;
|
|
1783
|
+
const maxTags = ct['MaxTags'] ?? 10;
|
|
1784
|
+
const range = 15; // max possible
|
|
1785
|
+
return {
|
|
1786
|
+
ID: id,
|
|
1787
|
+
Name: ct['Name'] ?? 'Unnamed',
|
|
1788
|
+
Description: ct['Description'] ?? '',
|
|
1789
|
+
AIModelName: ct['AIModel'] ?? 'Default Model',
|
|
1790
|
+
AIModelID: ct['AIModelID'] ?? '',
|
|
1791
|
+
MinTags: minTags,
|
|
1792
|
+
MaxTags: maxTags,
|
|
1793
|
+
SourcesUsing: sourcesUsingByType.get(id) ?? 0,
|
|
1794
|
+
ItemsTagged: itemsByType.get(id) ?? 0,
|
|
1795
|
+
RangeLeftPct: Math.round((minTags / range) * 100),
|
|
1796
|
+
RangeRightPct: Math.round(100 - (maxTags / range) * 100),
|
|
1797
|
+
EmbeddingModelID: ct['EmbeddingModelID'] ?? '',
|
|
1798
|
+
VectorIndexID: ct['VectorIndexID'] ?? ''
|
|
1799
|
+
};
|
|
1800
|
+
});
|
|
1801
|
+
}
|
|
1802
|
+
// ════════════════════════════════════════════
|
|
1803
|
+
// TAG LIBRARY TAB
|
|
1804
|
+
// ════════════════════════════════════════════
|
|
1805
|
+
async loadTagLibraryData() {
|
|
1806
|
+
await this.ensureBaseDataLoaded();
|
|
1807
|
+
this.buildTagRows();
|
|
1808
|
+
this.buildTagCloud();
|
|
1809
|
+
this.buildTagsBySource();
|
|
1810
|
+
this.FilteredTagRows = this.TagRows;
|
|
1811
|
+
}
|
|
1812
|
+
buildTagRows() {
|
|
1813
|
+
const tagCounts = this.countAllTags();
|
|
1814
|
+
const avgWeights = this.computeAvgWeights();
|
|
1815
|
+
const tagSourceMap = this.getTopSourcePerTag();
|
|
1816
|
+
const tagFirstSeen = this.getFirstSeenPerTag();
|
|
1817
|
+
const sorted = Array.from(tagCounts.entries()).sort((a, b) => b[1] - a[1]);
|
|
1818
|
+
const maxCount = sorted.length > 0 ? sorted[0][1] : 1;
|
|
1819
|
+
this.TagRows = sorted.map(([tag, count]) => ({
|
|
1820
|
+
Tag: tag,
|
|
1821
|
+
UsageCount: count,
|
|
1822
|
+
AvgWeight: avgWeights.get(tag) ?? 1.0,
|
|
1823
|
+
BarWidthPct: Math.round((count / maxCount) * 100),
|
|
1824
|
+
TopSource: tagSourceMap.get(tag) ?? 'Unknown',
|
|
1825
|
+
FirstSeen: tagFirstSeen.get(tag) ?? ''
|
|
1826
|
+
}));
|
|
1827
|
+
}
|
|
1828
|
+
buildTagCloud() {
|
|
1829
|
+
const tagCounts = this.countAllTags();
|
|
1830
|
+
const avgWeights = this.computeAvgWeights();
|
|
1831
|
+
// Sort by a combined score: usage count * avg weight (so high-weight, high-count tags bubble up)
|
|
1832
|
+
const scored = Array.from(tagCounts.entries()).map(([tag, count]) => {
|
|
1833
|
+
const weight = avgWeights.get(tag) ?? 1.0;
|
|
1834
|
+
return { tag, count, weight, score: count * weight };
|
|
1835
|
+
}).sort((a, b) => b.score - a.score).slice(0, 20);
|
|
1836
|
+
const maxScore = scored.length > 0 ? scored[0].score : 1;
|
|
1837
|
+
this.TagCloud = scored.map(s => ({
|
|
1838
|
+
Tag: s.tag,
|
|
1839
|
+
AvgWeight: s.weight,
|
|
1840
|
+
SizeClass: s.score >= maxScore * 0.7 ? 'large' : s.score >= maxScore * 0.3 ? '' : 'small'
|
|
1841
|
+
}));
|
|
1842
|
+
}
|
|
1843
|
+
buildTagsBySource() {
|
|
1844
|
+
const sourceTagCounts = new Map();
|
|
1845
|
+
const itemSourceMap = new Map();
|
|
1846
|
+
for (const item of this.contentItemsRaw) {
|
|
1847
|
+
itemSourceMap.set(item['ID'], item['ContentSource'] ?? 'Unknown');
|
|
1848
|
+
}
|
|
1849
|
+
for (const tag of this.contentTagsRaw) {
|
|
1850
|
+
const source = itemSourceMap.get(tag['ItemID']) ?? 'Unknown';
|
|
1851
|
+
sourceTagCounts.set(source, (sourceTagCounts.get(source) ?? 0) + 1);
|
|
1852
|
+
}
|
|
1853
|
+
this.TagsBySource = Array.from(sourceTagCounts.entries())
|
|
1854
|
+
.sort((a, b) => b[1] - a[1])
|
|
1855
|
+
.map(([name, count]) => ({ SourceName: name, Count: count }));
|
|
1856
|
+
}
|
|
1857
|
+
/** Convert a string ID to a CompositeKey for tree-dropdown binding */
|
|
1858
|
+
ToCompositeKey(id) {
|
|
1859
|
+
if (!id)
|
|
1860
|
+
return null;
|
|
1861
|
+
return new CompositeKey([{ FieldName: 'ID', Value: id }]);
|
|
1862
|
+
}
|
|
1863
|
+
/** Extract the ID string from a CompositeKey (from tree-dropdown ValueChange) */
|
|
1864
|
+
FromCompositeKey(key) {
|
|
1865
|
+
if (!key)
|
|
1866
|
+
return '';
|
|
1867
|
+
const ck = Array.isArray(key) ? key[0] : key;
|
|
1868
|
+
if (!ck?.KeyValuePairs?.length)
|
|
1869
|
+
return '';
|
|
1870
|
+
return String(ck.KeyValuePairs[0].Value || '');
|
|
1871
|
+
}
|
|
1872
|
+
FilterTags() {
|
|
1873
|
+
const q = this.TagSearchQuery.toLowerCase().trim();
|
|
1874
|
+
this.FilteredTagRows = q
|
|
1875
|
+
? this.TagRows.filter(r => r.Tag.toLowerCase().includes(q))
|
|
1876
|
+
: this.TagRows;
|
|
1877
|
+
this.cdr.detectChanges();
|
|
1878
|
+
}
|
|
1879
|
+
// ════════════════════════════════════════════
|
|
1880
|
+
// RUN HISTORY TAB
|
|
1881
|
+
// ════════════════════════════════════════════
|
|
1882
|
+
async loadRunHistoryData() {
|
|
1883
|
+
if (this.contentRunsRaw.length === 0) {
|
|
1884
|
+
const rv = new RunView();
|
|
1885
|
+
const result = await rv.RunView({
|
|
1886
|
+
EntityName: 'MJ: Content Process Runs',
|
|
1887
|
+
OrderBy: 'StartTime DESC',
|
|
1888
|
+
MaxRows: 200,
|
|
1889
|
+
ResultType: 'simple'
|
|
1890
|
+
});
|
|
1891
|
+
if (result.Success)
|
|
1892
|
+
this.contentRunsRaw = result.Results;
|
|
1893
|
+
}
|
|
1894
|
+
this.buildRunHistoryRows();
|
|
1895
|
+
this.buildHistorySourceOptions();
|
|
1896
|
+
this.FilteredRunRows = this.RunHistoryRows;
|
|
1897
|
+
}
|
|
1898
|
+
buildRunHistoryRows() {
|
|
1899
|
+
this.RunHistoryRows = this.contentRunsRaw.map(run => {
|
|
1900
|
+
const status = run['Status'] ?? 'Unknown';
|
|
1901
|
+
const startTime = run['StartTime'];
|
|
1902
|
+
const endTime = run['EndTime'];
|
|
1903
|
+
const duration = this.computeDuration(startTime, endTime);
|
|
1904
|
+
const processedItems = run['ProcessedItems'];
|
|
1905
|
+
const statusLower = status.toLowerCase();
|
|
1906
|
+
const isFailed = statusLower === 'error' || statusLower === 'failed';
|
|
1907
|
+
const isRunning = statusLower === 'running' || statusLower === 'processing';
|
|
1908
|
+
return {
|
|
1909
|
+
ID: run['ID'],
|
|
1910
|
+
Status: this.displayStatus(status),
|
|
1911
|
+
StatusClass: isFailed ? 'failed' : isRunning ? 'running' : 'complete',
|
|
1912
|
+
SourceName: run['Source'] ?? 'Unknown',
|
|
1913
|
+
StartedDisplay: startTime ? this.formatDate(startTime) : '\u2014',
|
|
1914
|
+
Duration: duration,
|
|
1915
|
+
Items: processedItems != null ? this.formatNumber(processedItems) : '\u2014',
|
|
1916
|
+
Tags: '\u2014',
|
|
1917
|
+
Errors: isFailed ? status : '0',
|
|
1918
|
+
ErrorClass: isFailed ? 'run-error-text' : ''
|
|
1919
|
+
};
|
|
1920
|
+
});
|
|
1921
|
+
}
|
|
1922
|
+
buildHistorySourceOptions() {
|
|
1923
|
+
const sources = new Set();
|
|
1924
|
+
for (const run of this.contentRunsRaw) {
|
|
1925
|
+
const s = run['Source'];
|
|
1926
|
+
if (s)
|
|
1927
|
+
sources.add(s);
|
|
1928
|
+
}
|
|
1929
|
+
this.HistorySourceOptions = Array.from(sources).sort();
|
|
1930
|
+
}
|
|
1931
|
+
FilterRunHistory() {
|
|
1932
|
+
this.FilteredRunRows = this.RunHistoryRows.filter(row => {
|
|
1933
|
+
if (this.HistorySourceFilter && row.SourceName !== this.HistorySourceFilter)
|
|
1934
|
+
return false;
|
|
1935
|
+
if (this.HistoryStatusFilter && row.StatusClass !== this.HistoryStatusFilter)
|
|
1936
|
+
return false;
|
|
1937
|
+
return true;
|
|
1938
|
+
});
|
|
1939
|
+
this.cdr.detectChanges();
|
|
1940
|
+
}
|
|
1941
|
+
// ════════════════════════════════════════════
|
|
1942
|
+
// SLIDE-IN FORM — Sources
|
|
1943
|
+
// ════════════════════════════════════════════
|
|
1944
|
+
async OpenAddSourceForm() {
|
|
1945
|
+
await this.ensureFormDropdownsLoaded();
|
|
1946
|
+
this.resetSourceForm();
|
|
1947
|
+
this.FormMode = 'add-source';
|
|
1948
|
+
this.cdr.detectChanges();
|
|
1949
|
+
}
|
|
1950
|
+
async OpenEditSourceForm(card) {
|
|
1951
|
+
await this.ensureFormDropdownsLoaded();
|
|
1952
|
+
this.FormSourceName = card.Name;
|
|
1953
|
+
this.FormSourceTypeID = card.ContentSourceTypeID;
|
|
1954
|
+
this.FormContentTypeID = card.ContentTypeID;
|
|
1955
|
+
this.FormFileTypeID = card.ContentFileTypeID;
|
|
1956
|
+
this.FormSourceURL = card.URL;
|
|
1957
|
+
this.FormSourceEmbeddingModelID = card.EmbeddingModelID ?? '';
|
|
1958
|
+
this.FormSourceVectorIndexID = card.VectorIndexID ?? '';
|
|
1959
|
+
this.EditingSourceID = card.ID;
|
|
1960
|
+
this.FormMode = 'edit-source';
|
|
1961
|
+
this.cdr.detectChanges();
|
|
1962
|
+
}
|
|
1963
|
+
async SaveSource() {
|
|
1964
|
+
if (this.FormSaving)
|
|
1965
|
+
return;
|
|
1966
|
+
this.FormSaving = true;
|
|
1967
|
+
this.cdr.detectChanges();
|
|
1968
|
+
try {
|
|
1969
|
+
const md = new Metadata();
|
|
1970
|
+
const entity = await md.GetEntityObject('MJ: Content Sources');
|
|
1971
|
+
if (this.FormMode === 'edit-source' && this.EditingSourceID) {
|
|
1972
|
+
await entity.InnerLoad(new CompositeKey([{ FieldName: 'ID', Value: this.EditingSourceID }]));
|
|
1973
|
+
}
|
|
1974
|
+
else {
|
|
1975
|
+
entity.NewRecord();
|
|
1976
|
+
}
|
|
1977
|
+
entity.Set('Name', this.FormSourceName);
|
|
1978
|
+
entity.Set('ContentSourceTypeID', this.FormSourceTypeID);
|
|
1979
|
+
entity.Set('ContentTypeID', this.FormContentTypeID);
|
|
1980
|
+
entity.Set('ContentFileTypeID', this.FormFileTypeID);
|
|
1981
|
+
entity.Set('URL', this.FormSourceURL);
|
|
1982
|
+
entity.Set('EmbeddingModelID', this.FormSourceEmbeddingModelID || null);
|
|
1983
|
+
entity.Set('VectorIndexID', this.FormSourceVectorIndexID || null);
|
|
1984
|
+
const saved = await entity.Save();
|
|
1985
|
+
if (saved) {
|
|
1986
|
+
MJNotificationService.Instance.CreateSimpleNotification(this.FormMode === 'edit-source' ? 'Source updated' : 'Source created', 'success', 2500);
|
|
1987
|
+
this.CloseForm();
|
|
1988
|
+
await this.refreshSourcesTab();
|
|
1989
|
+
}
|
|
1990
|
+
else {
|
|
1991
|
+
MJNotificationService.Instance.CreateSimpleNotification('Failed to save source', 'error', 3000);
|
|
1992
|
+
}
|
|
1993
|
+
}
|
|
1994
|
+
catch (error) {
|
|
1995
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
1996
|
+
MJNotificationService.Instance.CreateSimpleNotification(`Error: ${msg}`, 'error', 4000);
|
|
1997
|
+
}
|
|
1998
|
+
finally {
|
|
1999
|
+
this.FormSaving = false;
|
|
2000
|
+
this.cdr.detectChanges();
|
|
2001
|
+
}
|
|
2002
|
+
}
|
|
2003
|
+
async DeleteSource(card) {
|
|
2004
|
+
if (!confirm(`Delete source "${card.Name}"? This cannot be undone.`))
|
|
2005
|
+
return;
|
|
2006
|
+
try {
|
|
2007
|
+
const md = new Metadata();
|
|
2008
|
+
const entity = await md.GetEntityObject('MJ: Content Sources');
|
|
2009
|
+
await entity.InnerLoad(new CompositeKey([{ FieldName: 'ID', Value: card.ID }]));
|
|
2010
|
+
const deleted = await entity.Delete();
|
|
2011
|
+
if (deleted) {
|
|
2012
|
+
MJNotificationService.Instance.CreateSimpleNotification('Source deleted', 'success', 2500);
|
|
2013
|
+
await this.refreshSourcesTab();
|
|
2014
|
+
}
|
|
2015
|
+
else {
|
|
2016
|
+
MJNotificationService.Instance.CreateSimpleNotification('Failed to delete source', 'error', 3000);
|
|
2017
|
+
}
|
|
2018
|
+
}
|
|
2019
|
+
catch (error) {
|
|
2020
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
2021
|
+
MJNotificationService.Instance.CreateSimpleNotification(`Error: ${msg}`, 'error', 4000);
|
|
2022
|
+
}
|
|
2023
|
+
}
|
|
2024
|
+
// ════════════════════════════════════════════
|
|
2025
|
+
// SLIDE-IN FORM — Content Types
|
|
2026
|
+
// ════════════════════════════════════════════
|
|
2027
|
+
async OpenAddTypeForm() {
|
|
2028
|
+
await this.ensureFormDropdownsLoaded();
|
|
2029
|
+
this.resetTypeForm();
|
|
2030
|
+
this.FormMode = 'add-type';
|
|
2031
|
+
this.cdr.detectChanges();
|
|
2032
|
+
}
|
|
2033
|
+
async OpenEditTypeForm(card) {
|
|
2034
|
+
await this.ensureFormDropdownsLoaded();
|
|
2035
|
+
this.FormTypeName = card.Name;
|
|
2036
|
+
this.FormTypeDescription = card.Description;
|
|
2037
|
+
this.FormTypeAIModelID = card.AIModelID;
|
|
2038
|
+
this.FormTypeMinTags = card.MinTags;
|
|
2039
|
+
this.FormTypeMaxTags = card.MaxTags;
|
|
2040
|
+
this.FormTypeEmbeddingModelID = card.EmbeddingModelID ?? '';
|
|
2041
|
+
this.FormTypeVectorIndexID = card.VectorIndexID ?? '';
|
|
2042
|
+
this.EditingTypeID = card.ID;
|
|
2043
|
+
this.FormMode = 'edit-type';
|
|
2044
|
+
this.cdr.detectChanges();
|
|
2045
|
+
}
|
|
2046
|
+
async SaveContentType() {
|
|
2047
|
+
if (this.FormSaving)
|
|
2048
|
+
return;
|
|
2049
|
+
this.FormSaving = true;
|
|
2050
|
+
this.cdr.detectChanges();
|
|
2051
|
+
try {
|
|
2052
|
+
const md = new Metadata();
|
|
2053
|
+
const entity = await md.GetEntityObject('MJ: Content Types');
|
|
2054
|
+
if (this.FormMode === 'edit-type' && this.EditingTypeID) {
|
|
2055
|
+
await entity.InnerLoad(new CompositeKey([{ FieldName: 'ID', Value: this.EditingTypeID }]));
|
|
2056
|
+
}
|
|
2057
|
+
else {
|
|
2058
|
+
entity.NewRecord();
|
|
2059
|
+
}
|
|
2060
|
+
entity.Set('Name', this.FormTypeName);
|
|
2061
|
+
entity.Set('Description', this.FormTypeDescription);
|
|
2062
|
+
entity.Set('AIModelID', this.FormTypeAIModelID);
|
|
2063
|
+
entity.Set('MinTags', this.FormTypeMinTags);
|
|
2064
|
+
entity.Set('MaxTags', this.FormTypeMaxTags);
|
|
2065
|
+
entity.Set('EmbeddingModelID', this.FormTypeEmbeddingModelID || null);
|
|
2066
|
+
entity.Set('VectorIndexID', this.FormTypeVectorIndexID || null);
|
|
2067
|
+
const saved = await entity.Save();
|
|
2068
|
+
if (saved) {
|
|
2069
|
+
MJNotificationService.Instance.CreateSimpleNotification(this.FormMode === 'edit-type' ? 'Content type updated' : 'Content type created', 'success', 2500);
|
|
2070
|
+
this.CloseForm();
|
|
2071
|
+
await this.refreshContentTypesTab();
|
|
2072
|
+
}
|
|
2073
|
+
else {
|
|
2074
|
+
MJNotificationService.Instance.CreateSimpleNotification('Failed to save content type', 'error', 3000);
|
|
2075
|
+
}
|
|
2076
|
+
}
|
|
2077
|
+
catch (error) {
|
|
2078
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
2079
|
+
MJNotificationService.Instance.CreateSimpleNotification(`Error: ${msg}`, 'error', 4000);
|
|
2080
|
+
}
|
|
2081
|
+
finally {
|
|
2082
|
+
this.FormSaving = false;
|
|
2083
|
+
this.cdr.detectChanges();
|
|
2084
|
+
}
|
|
2085
|
+
}
|
|
2086
|
+
CloseForm() {
|
|
2087
|
+
this.FormMode = 'none';
|
|
2088
|
+
this.cdr.detectChanges();
|
|
2089
|
+
}
|
|
2090
|
+
// ════════════════════════════════════════════
|
|
2091
|
+
// PIPELINE RUN
|
|
2092
|
+
// ════════════════════════════════════════════
|
|
2093
|
+
async RunPipeline() {
|
|
2094
|
+
if (this.IsRunning)
|
|
2095
|
+
return;
|
|
2096
|
+
const provider = Metadata.Provider;
|
|
2097
|
+
if (!provider)
|
|
2098
|
+
return;
|
|
2099
|
+
this.IsRunning = true;
|
|
2100
|
+
this.RunProgress = 0;
|
|
2101
|
+
this.RunStage = 'Starting...';
|
|
2102
|
+
this.RunCurrentItem = '';
|
|
2103
|
+
this.cdr.detectChanges();
|
|
2104
|
+
try {
|
|
2105
|
+
const aiClient = new GraphQLAIClient(provider);
|
|
2106
|
+
const result = await aiClient.RunAutotagPipeline();
|
|
2107
|
+
if (!result.Success || !result.PipelineRunID) {
|
|
2108
|
+
this.IsRunning = false;
|
|
2109
|
+
this.RunStage = '';
|
|
2110
|
+
MJNotificationService.Instance.CreateSimpleNotification(`Pipeline failed: ${result.ErrorMessage ?? 'Unknown error'}`, 'error', 5000);
|
|
2111
|
+
this.cdr.detectChanges();
|
|
2112
|
+
return;
|
|
2113
|
+
}
|
|
2114
|
+
this.subscribeToPipelineProgress(result.PipelineRunID);
|
|
2115
|
+
}
|
|
2116
|
+
catch (error) {
|
|
2117
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
2118
|
+
console.error('[Autotagging] Error starting pipeline:', msg);
|
|
2119
|
+
this.IsRunning = false;
|
|
2120
|
+
this.RunStage = '';
|
|
2121
|
+
MJNotificationService.Instance.CreateSimpleNotification(`Pipeline error: ${msg}`, 'error', 5000);
|
|
2122
|
+
this.cdr.detectChanges();
|
|
2123
|
+
}
|
|
2124
|
+
}
|
|
2125
|
+
subscribeToPipelineProgress(pipelineRunID) {
|
|
2126
|
+
const provider = Metadata.Provider;
|
|
2127
|
+
const subscriptionQuery = `
|
|
2128
|
+
subscription PipelineProgress($pipelineRunID: String!) {
|
|
2129
|
+
PipelineProgress(pipelineRunID: $pipelineRunID) {
|
|
2130
|
+
PipelineRunID
|
|
2131
|
+
Stage
|
|
2132
|
+
TotalItems
|
|
2133
|
+
ProcessedItems
|
|
2134
|
+
CurrentItem
|
|
2135
|
+
PercentComplete
|
|
2136
|
+
ElapsedMs
|
|
2137
|
+
}
|
|
2138
|
+
}
|
|
2139
|
+
`;
|
|
2140
|
+
let idleTimer = null;
|
|
2141
|
+
const finishPipeline = (success) => {
|
|
2142
|
+
if (idleTimer)
|
|
2143
|
+
clearTimeout(idleTimer);
|
|
2144
|
+
rxSub?.unsubscribe();
|
|
2145
|
+
Promise.resolve().then(async () => {
|
|
2146
|
+
this.IsRunning = false;
|
|
2147
|
+
this.RunStage = success ? 'Complete' : 'Error';
|
|
2148
|
+
this.RunProgress = success ? 100 : 0;
|
|
2149
|
+
for (const stage of this.PipelineStages) {
|
|
2150
|
+
stage.Status = 'idle';
|
|
2151
|
+
stage.Count = '\u2014';
|
|
2152
|
+
}
|
|
2153
|
+
if (success) {
|
|
2154
|
+
this.tabDataLoaded.clear();
|
|
2155
|
+
await this.LoadPipelineData();
|
|
2156
|
+
this.tabDataLoaded.add('pipeline');
|
|
2157
|
+
MJNotificationService.Instance.CreateSimpleNotification('Pipeline complete', 'success', 3000);
|
|
2158
|
+
}
|
|
2159
|
+
this.cdr.detectChanges();
|
|
2160
|
+
});
|
|
2161
|
+
};
|
|
2162
|
+
const resetIdleTimer = () => {
|
|
2163
|
+
if (idleTimer)
|
|
2164
|
+
clearTimeout(idleTimer);
|
|
2165
|
+
idleTimer = setTimeout(() => {
|
|
2166
|
+
if (this.IsRunning)
|
|
2167
|
+
finishPipeline(true);
|
|
2168
|
+
}, 30000);
|
|
2169
|
+
};
|
|
2170
|
+
resetIdleTimer();
|
|
2171
|
+
const sub = provider.subscribe(subscriptionQuery, { pipelineRunID });
|
|
2172
|
+
const rxSub = sub.pipe(takeUntil(this.destroy$)).subscribe({
|
|
2173
|
+
next: (data) => {
|
|
2174
|
+
const progress = data['PipelineProgress'];
|
|
2175
|
+
if (!progress)
|
|
2176
|
+
return;
|
|
2177
|
+
const stage = progress['Stage'];
|
|
2178
|
+
const pct = progress['PercentComplete'];
|
|
2179
|
+
const currentItem = progress['CurrentItem'];
|
|
2180
|
+
this.RunProgress = pct;
|
|
2181
|
+
this.RunStage = this.formatStageName(stage);
|
|
2182
|
+
this.RunCurrentItem = currentItem ?? '';
|
|
2183
|
+
this.updateStagesForActiveRun(stage);
|
|
2184
|
+
this.cdr.detectChanges();
|
|
2185
|
+
if (stage === 'complete') {
|
|
2186
|
+
finishPipeline(true);
|
|
2187
|
+
}
|
|
2188
|
+
else if (stage === 'error') {
|
|
2189
|
+
finishPipeline(false);
|
|
2190
|
+
}
|
|
2191
|
+
else {
|
|
2192
|
+
resetIdleTimer();
|
|
2193
|
+
}
|
|
2194
|
+
},
|
|
2195
|
+
error: (err) => {
|
|
2196
|
+
console.error('[Autotagging] Pipeline subscription error:', err);
|
|
2197
|
+
finishPipeline(false);
|
|
2198
|
+
}
|
|
2199
|
+
});
|
|
2200
|
+
}
|
|
2201
|
+
updateStagesForActiveRun(activeStageCode) {
|
|
2202
|
+
const stageCodeToName = {
|
|
2203
|
+
'ingest': 'Ingest', 'extract': 'Extract', 'chunk': 'Chunk',
|
|
2204
|
+
'tag': 'Tag', 'autotag': 'Tag', 'vectorize': 'Vectorize'
|
|
2205
|
+
};
|
|
2206
|
+
const activeName = stageCodeToName[activeStageCode] ?? '';
|
|
2207
|
+
let passedActive = false;
|
|
2208
|
+
for (const stage of this.PipelineStages) {
|
|
2209
|
+
if (stage.Name === activeName) {
|
|
2210
|
+
stage.Status = 'active';
|
|
2211
|
+
passedActive = true;
|
|
2212
|
+
}
|
|
2213
|
+
else if (!passedActive) {
|
|
2214
|
+
stage.Status = 'complete';
|
|
2215
|
+
}
|
|
2216
|
+
else {
|
|
2217
|
+
stage.Status = 'idle';
|
|
2218
|
+
}
|
|
2219
|
+
}
|
|
2220
|
+
}
|
|
2221
|
+
formatStageName(stage) {
|
|
2222
|
+
const map = {
|
|
2223
|
+
'extract': 'Extracting content', 'autotag': 'Running autotaggers',
|
|
2224
|
+
'vectorize': 'Vectorizing content', 'complete': 'Complete',
|
|
2225
|
+
'error': 'Error', 'ingest': 'Ingesting', 'chunk': 'Chunking',
|
|
2226
|
+
'tag': 'Tagging'
|
|
2227
|
+
};
|
|
2228
|
+
return map[stage] ?? stage;
|
|
2229
|
+
}
|
|
2230
|
+
// ════════════════════════════════════════════
|
|
2231
|
+
// HELPER — Aggregation utilities
|
|
2232
|
+
// ════════════════════════════════════════════
|
|
2233
|
+
countTagsByItem() {
|
|
2234
|
+
const counts = new Map();
|
|
2235
|
+
for (const tag of this.contentTagsRaw) {
|
|
2236
|
+
const itemId = tag['ItemID'];
|
|
2237
|
+
if (itemId)
|
|
2238
|
+
counts.set(itemId, (counts.get(itemId) ?? 0) + 1);
|
|
2239
|
+
}
|
|
2240
|
+
return counts;
|
|
2241
|
+
}
|
|
2242
|
+
getTopTagsForItem(itemId, max) {
|
|
2243
|
+
const tags = [];
|
|
2244
|
+
for (const tag of this.contentTagsRaw) {
|
|
2245
|
+
if (tag['ItemID'] === itemId) {
|
|
2246
|
+
tags.push(tag['Tag']);
|
|
2247
|
+
if (tags.length >= max)
|
|
2248
|
+
break;
|
|
2249
|
+
}
|
|
2250
|
+
}
|
|
2251
|
+
return tags;
|
|
2252
|
+
}
|
|
2253
|
+
countItemsBySource() {
|
|
2254
|
+
const counts = new Map();
|
|
2255
|
+
for (const item of this.contentItemsRaw) {
|
|
2256
|
+
const sourceId = item['ContentSourceID'];
|
|
2257
|
+
if (sourceId)
|
|
2258
|
+
counts.set(sourceId, (counts.get(sourceId) ?? 0) + 1);
|
|
2259
|
+
}
|
|
2260
|
+
return counts;
|
|
2261
|
+
}
|
|
2262
|
+
countTagsBySource() {
|
|
2263
|
+
const itemSourceMap = new Map();
|
|
2264
|
+
for (const item of this.contentItemsRaw) {
|
|
2265
|
+
itemSourceMap.set(item['ID'], item['ContentSourceID']);
|
|
2266
|
+
}
|
|
2267
|
+
const counts = new Map();
|
|
2268
|
+
for (const tag of this.contentTagsRaw) {
|
|
2269
|
+
const sourceId = itemSourceMap.get(tag['ItemID']);
|
|
2270
|
+
if (sourceId)
|
|
2271
|
+
counts.set(sourceId, (counts.get(sourceId) ?? 0) + 1);
|
|
2272
|
+
}
|
|
2273
|
+
return counts;
|
|
2274
|
+
}
|
|
2275
|
+
getLastRunBySource() {
|
|
2276
|
+
const map = new Map();
|
|
2277
|
+
for (const run of this.contentRunsRaw) {
|
|
2278
|
+
const sourceId = run['SourceID'];
|
|
2279
|
+
if (sourceId && !map.has(sourceId)) {
|
|
2280
|
+
map.set(sourceId, run);
|
|
2281
|
+
}
|
|
2282
|
+
}
|
|
2283
|
+
return map;
|
|
2284
|
+
}
|
|
2285
|
+
countAllTags() {
|
|
2286
|
+
const counts = new Map();
|
|
2287
|
+
for (const tag of this.contentTagsRaw) {
|
|
2288
|
+
const t = tag['Tag'];
|
|
2289
|
+
if (t)
|
|
2290
|
+
counts.set(t, (counts.get(t) ?? 0) + 1);
|
|
2291
|
+
}
|
|
2292
|
+
return counts;
|
|
2293
|
+
}
|
|
2294
|
+
/** Compute average weight per tag across all occurrences */
|
|
2295
|
+
computeAvgWeights() {
|
|
2296
|
+
const sums = new Map();
|
|
2297
|
+
const counts = new Map();
|
|
2298
|
+
for (const tag of this.contentTagsRaw) {
|
|
2299
|
+
const t = tag['Tag'];
|
|
2300
|
+
const w = Number(tag['Weight'] ?? 0.5);
|
|
2301
|
+
if (t) {
|
|
2302
|
+
sums.set(t, (sums.get(t) ?? 0) + w);
|
|
2303
|
+
counts.set(t, (counts.get(t) ?? 0) + 1);
|
|
2304
|
+
}
|
|
2305
|
+
}
|
|
2306
|
+
const avgs = new Map();
|
|
2307
|
+
for (const [t, sum] of sums) {
|
|
2308
|
+
avgs.set(t, Math.round((sum / (counts.get(t) ?? 1)) * 100) / 100);
|
|
2309
|
+
}
|
|
2310
|
+
return avgs;
|
|
2311
|
+
}
|
|
2312
|
+
getTopSourcePerTag() {
|
|
2313
|
+
const tagSourceCounts = new Map();
|
|
2314
|
+
const itemSourceMap = new Map();
|
|
2315
|
+
for (const item of this.contentItemsRaw) {
|
|
2316
|
+
itemSourceMap.set(item['ID'], item['ContentSource'] ?? 'Unknown');
|
|
2317
|
+
}
|
|
2318
|
+
for (const tag of this.contentTagsRaw) {
|
|
2319
|
+
const t = tag['Tag'];
|
|
2320
|
+
const source = itemSourceMap.get(tag['ItemID']) ?? 'Unknown';
|
|
2321
|
+
if (!tagSourceCounts.has(t))
|
|
2322
|
+
tagSourceCounts.set(t, new Map());
|
|
2323
|
+
const inner = tagSourceCounts.get(t);
|
|
2324
|
+
inner.set(source, (inner.get(source) ?? 0) + 1);
|
|
2325
|
+
}
|
|
2326
|
+
const result = new Map();
|
|
2327
|
+
for (const [tag, sourceCounts] of tagSourceCounts) {
|
|
2328
|
+
let maxSource = '';
|
|
2329
|
+
let maxCount = 0;
|
|
2330
|
+
for (const [source, count] of sourceCounts) {
|
|
2331
|
+
if (count > maxCount) {
|
|
2332
|
+
maxSource = source;
|
|
2333
|
+
maxCount = count;
|
|
2334
|
+
}
|
|
2335
|
+
}
|
|
2336
|
+
result.set(tag, maxSource);
|
|
2337
|
+
}
|
|
2338
|
+
return result;
|
|
2339
|
+
}
|
|
2340
|
+
getFirstSeenPerTag() {
|
|
2341
|
+
const result = new Map();
|
|
2342
|
+
for (const tag of this.contentTagsRaw) {
|
|
2343
|
+
const t = tag['Tag'];
|
|
2344
|
+
if (t && !result.has(t)) {
|
|
2345
|
+
const date = tag['__mj_CreatedAt'];
|
|
2346
|
+
result.set(t, date ? this.formatShortDate(date) : '');
|
|
2347
|
+
}
|
|
2348
|
+
}
|
|
2349
|
+
return result;
|
|
2350
|
+
}
|
|
2351
|
+
countSourcesByContentType() {
|
|
2352
|
+
const counts = new Map();
|
|
2353
|
+
for (const source of this.contentSourcesRaw) {
|
|
2354
|
+
const typeId = source['ContentTypeID'];
|
|
2355
|
+
if (typeId)
|
|
2356
|
+
counts.set(typeId, (counts.get(typeId) ?? 0) + 1);
|
|
2357
|
+
}
|
|
2358
|
+
return counts;
|
|
2359
|
+
}
|
|
2360
|
+
countItemsByContentType() {
|
|
2361
|
+
const counts = new Map();
|
|
2362
|
+
for (const item of this.contentItemsRaw) {
|
|
2363
|
+
const typeId = item['ContentTypeID'];
|
|
2364
|
+
if (typeId)
|
|
2365
|
+
counts.set(typeId, (counts.get(typeId) ?? 0) + 1);
|
|
2366
|
+
}
|
|
2367
|
+
return counts;
|
|
2368
|
+
}
|
|
2369
|
+
inferItemStatus(tagCount) {
|
|
2370
|
+
return tagCount > 0 ? 'complete' : 'processing';
|
|
2371
|
+
}
|
|
2372
|
+
// ════════════════════════════════════════════
|
|
2373
|
+
// HELPER — Formatting
|
|
2374
|
+
// ════════════════════════════════════════════
|
|
2375
|
+
formatRelativeTime(dateStr) {
|
|
2376
|
+
if (!dateStr)
|
|
2377
|
+
return 'Never';
|
|
2378
|
+
const now = new Date();
|
|
2379
|
+
const then = new Date(dateStr);
|
|
2380
|
+
const diffMs = now.getTime() - then.getTime();
|
|
2381
|
+
const diffMins = Math.floor(diffMs / 60000);
|
|
2382
|
+
if (diffMins < 1)
|
|
2383
|
+
return 'Just now';
|
|
2384
|
+
if (diffMins < 60)
|
|
2385
|
+
return `${diffMins}m ago`;
|
|
2386
|
+
const diffHours = Math.floor(diffMins / 60);
|
|
2387
|
+
if (diffHours < 24)
|
|
2388
|
+
return `${diffHours}h ago`;
|
|
2389
|
+
const diffDays = Math.floor(diffHours / 24);
|
|
2390
|
+
return `${diffDays}d ago`;
|
|
2391
|
+
}
|
|
2392
|
+
formatNumber(n) {
|
|
2393
|
+
return n.toLocaleString();
|
|
2394
|
+
}
|
|
2395
|
+
formatShortDate(dateStr) {
|
|
2396
|
+
try {
|
|
2397
|
+
const d = new Date(dateStr);
|
|
2398
|
+
return d.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
|
|
2399
|
+
}
|
|
2400
|
+
catch {
|
|
2401
|
+
return '';
|
|
2402
|
+
}
|
|
2403
|
+
}
|
|
2404
|
+
formatDate(dateStr) {
|
|
2405
|
+
try {
|
|
2406
|
+
const d = new Date(dateStr);
|
|
2407
|
+
return d.toLocaleDateString('en-US', { month: 'short', day: 'numeric', hour: 'numeric', minute: '2-digit' });
|
|
2408
|
+
}
|
|
2409
|
+
catch {
|
|
2410
|
+
return dateStr;
|
|
2411
|
+
}
|
|
2412
|
+
}
|
|
2413
|
+
computeDuration(start, end) {
|
|
2414
|
+
if (!start)
|
|
2415
|
+
return '\u2014';
|
|
2416
|
+
const s = new Date(start);
|
|
2417
|
+
const e = end ? new Date(end) : new Date();
|
|
2418
|
+
const ms = e.getTime() - s.getTime();
|
|
2419
|
+
if (ms < 1000)
|
|
2420
|
+
return `${ms}ms`;
|
|
2421
|
+
if (ms < 60000)
|
|
2422
|
+
return `${Math.round(ms / 1000)}s`;
|
|
2423
|
+
const mins = Math.floor(ms / 60000);
|
|
2424
|
+
const secs = Math.round((ms % 60000) / 1000);
|
|
2425
|
+
return `${mins}m ${secs}s`;
|
|
2426
|
+
}
|
|
2427
|
+
displayStatus(status) {
|
|
2428
|
+
const lower = status.toLowerCase();
|
|
2429
|
+
if (lower === 'complete' || lower === 'completed' || lower === 'done')
|
|
2430
|
+
return 'Complete';
|
|
2431
|
+
if (lower === 'error' || lower === 'failed')
|
|
2432
|
+
return 'Failed';
|
|
2433
|
+
if (lower === 'running' || lower === 'processing')
|
|
2434
|
+
return 'Running';
|
|
2435
|
+
return status;
|
|
2436
|
+
}
|
|
2437
|
+
GetSourceTypeIcon(typeName) {
|
|
2438
|
+
const iconMap = {
|
|
2439
|
+
'Web': 'fa-solid fa-globe', 'Web Crawler': 'fa-solid fa-globe',
|
|
2440
|
+
'API': 'fa-solid fa-plug', 'Database': 'fa-solid fa-database',
|
|
2441
|
+
'File': 'fa-solid fa-file-alt', 'Email': 'fa-solid fa-envelope',
|
|
2442
|
+
'RSS': 'fa-solid fa-rss', 'RSS Feed': 'fa-solid fa-rss',
|
|
2443
|
+
'CMS': 'fa-solid fa-newspaper', 'PDF': 'fa-solid fa-file-pdf'
|
|
2444
|
+
};
|
|
2445
|
+
return iconMap[typeName] ?? 'fa-solid fa-folder';
|
|
2446
|
+
}
|
|
2447
|
+
// ════════════════════════════════════════════
|
|
2448
|
+
// HELPER — Data loading
|
|
2449
|
+
// ════════════════════════════════════════════
|
|
2450
|
+
async ensureBaseDataLoaded() {
|
|
2451
|
+
if (this.contentSourcesRaw.length > 0 && this.contentItemsRaw.length > 0)
|
|
2452
|
+
return;
|
|
2453
|
+
await this.LoadPipelineData();
|
|
2454
|
+
}
|
|
2455
|
+
async ensureFormDropdownsLoaded() {
|
|
2456
|
+
try {
|
|
2457
|
+
// Use KnowledgeHubMetadataEngine for cached reference data — instant, no RunView needed
|
|
2458
|
+
const engine = KnowledgeHubMetadataEngine.Instance;
|
|
2459
|
+
await engine.Config(false); // no-op if already loaded
|
|
2460
|
+
this.SourceTypeOptions = engine.ContentSourceTypes.map(t => ({ ID: t.ID, Name: t.Name }));
|
|
2461
|
+
this.ContentTypeOptions = engine.ContentTypes.map(t => ({ ID: t.ID, Name: t.Name }));
|
|
2462
|
+
this.FileTypeOptions = engine.ContentFileTypes.map(t => ({ ID: t.ID, Name: t.Name }));
|
|
2463
|
+
this.VectorIndexOptions = engine.VectorIndexes.map(vi => ({ ID: vi.ID, Name: vi.Name }));
|
|
2464
|
+
// AI Models from AIEngineBase (already cached)
|
|
2465
|
+
if (this.AIModelOptions.length === 0) {
|
|
2466
|
+
const aiEngine = AIEngineBase.Instance;
|
|
2467
|
+
await aiEngine.Config(false);
|
|
2468
|
+
this.AIModelOptions = aiEngine.Models.map(m => ({ ID: m.ID, Name: m.Name }));
|
|
2469
|
+
this.EmbeddingModelOptions = aiEngine.Models
|
|
2470
|
+
.filter(m => m.AIModelType?.trim().toLowerCase() === 'embeddings')
|
|
2471
|
+
.map(m => ({ ID: m.ID, Name: m.Name }));
|
|
2472
|
+
}
|
|
2473
|
+
}
|
|
2474
|
+
catch (error) {
|
|
2475
|
+
console.error('[Autotagging] Error loading form dropdowns:', error);
|
|
2476
|
+
}
|
|
2477
|
+
}
|
|
2478
|
+
resetSourceForm() {
|
|
2479
|
+
this.FormSourceName = '';
|
|
2480
|
+
this.FormSourceTypeID = '';
|
|
2481
|
+
this.FormContentTypeID = '';
|
|
2482
|
+
this.FormFileTypeID = '';
|
|
2483
|
+
this.FormSourceURL = '';
|
|
2484
|
+
this.FormSourceEmbeddingModelID = '';
|
|
2485
|
+
this.FormSourceVectorIndexID = '';
|
|
2486
|
+
this.EditingSourceID = '';
|
|
2487
|
+
}
|
|
2488
|
+
resetTypeForm() {
|
|
2489
|
+
this.FormTypeName = '';
|
|
2490
|
+
this.FormTypeDescription = '';
|
|
2491
|
+
this.FormTypeAIModelID = '';
|
|
2492
|
+
this.FormTypeMinTags = 1;
|
|
2493
|
+
this.FormTypeMaxTags = 10;
|
|
2494
|
+
this.FormTypeEmbeddingModelID = '';
|
|
2495
|
+
this.FormTypeVectorIndexID = '';
|
|
2496
|
+
this.EditingTypeID = '';
|
|
2497
|
+
}
|
|
2498
|
+
async refreshSourcesTab() {
|
|
2499
|
+
this.tabDataLoaded.delete('sources');
|
|
2500
|
+
this.tabDataLoaded.delete('pipeline');
|
|
2501
|
+
const rv = new RunView();
|
|
2502
|
+
const result = await rv.RunView({ EntityName: 'MJ: Content Sources', OrderBy: 'Name', ResultType: 'simple' });
|
|
2503
|
+
if (result.Success)
|
|
2504
|
+
this.contentSourcesRaw = result.Results;
|
|
2505
|
+
this.buildSourceCards();
|
|
2506
|
+
this.buildNavItems();
|
|
2507
|
+
this.cdr.detectChanges();
|
|
2508
|
+
}
|
|
2509
|
+
async refreshContentTypesTab() {
|
|
2510
|
+
this.tabDataLoaded.delete('types');
|
|
2511
|
+
const rv = new RunView();
|
|
2512
|
+
const result = await rv.RunView({ EntityName: 'MJ: Content Types', ResultType: 'simple' });
|
|
2513
|
+
if (result.Success)
|
|
2514
|
+
this.contentTypesRaw = result.Results;
|
|
2515
|
+
this.buildContentTypeCards();
|
|
2516
|
+
this.cdr.detectChanges();
|
|
2517
|
+
}
|
|
2518
|
+
// ════════════════════════════════════════════
|
|
2519
|
+
// DETAIL PANELS — Feed Item / Content Item
|
|
2520
|
+
// ════════════════════════════════════════════
|
|
2521
|
+
OpenFeedItemDetail(index) {
|
|
2522
|
+
const feed = this.FeedItems[index];
|
|
2523
|
+
if (!feed)
|
|
2524
|
+
return;
|
|
2525
|
+
const rawItem = this.contentItemsRaw[index];
|
|
2526
|
+
if (!rawItem)
|
|
2527
|
+
return;
|
|
2528
|
+
const itemId = rawItem['ID'];
|
|
2529
|
+
const allTags = this.getAllTagsForItem(itemId);
|
|
2530
|
+
const tagCount = allTags.length;
|
|
2531
|
+
this.SelectedFeedItem = {
|
|
2532
|
+
ID: itemId,
|
|
2533
|
+
Name: feed.Name,
|
|
2534
|
+
SourceName: feed.SourceName,
|
|
2535
|
+
SourceTypeName: rawItem['ContentSourceType'] ?? 'Unknown',
|
|
2536
|
+
ContentTypeName: rawItem['ContentType'] ?? 'Unknown',
|
|
2537
|
+
FileTypeName: rawItem['ContentFileType'] ?? '',
|
|
2538
|
+
URL: rawItem['URL'] ?? '',
|
|
2539
|
+
TextContent: rawItem['TextContent'] ?? '',
|
|
2540
|
+
Checksum: rawItem['Checksum'] ?? '',
|
|
2541
|
+
Tags: allTags,
|
|
2542
|
+
CreatedAt: this.formatDate(rawItem['__mj_CreatedAt'] ?? ''),
|
|
2543
|
+
UpdatedAt: this.formatDate(rawItem['__mj_UpdatedAt'] ?? ''),
|
|
2544
|
+
ContentSourceID: rawItem['ContentSourceID'] ?? '',
|
|
2545
|
+
StatusDot: feed.Status,
|
|
2546
|
+
TagCount: tagCount
|
|
2547
|
+
};
|
|
2548
|
+
this.ShowItemDetail = true;
|
|
2549
|
+
this.cdr.detectChanges();
|
|
2550
|
+
}
|
|
2551
|
+
OpenContentItemDetail(item) {
|
|
2552
|
+
this.SelectedFeedItem = item;
|
|
2553
|
+
this.ShowItemDetail = true;
|
|
2554
|
+
this.cdr.detectChanges();
|
|
2555
|
+
}
|
|
2556
|
+
CloseItemDetail() {
|
|
2557
|
+
this.ShowItemDetail = false;
|
|
2558
|
+
this.SelectedFeedItem = null;
|
|
2559
|
+
this.cdr.detectChanges();
|
|
2560
|
+
}
|
|
2561
|
+
OpenRecordFromItem(item) {
|
|
2562
|
+
const md = new Metadata();
|
|
2563
|
+
const pkey = new CompositeKey();
|
|
2564
|
+
pkey.KeyValuePairs = [{ FieldName: 'ID', Value: item.ID }];
|
|
2565
|
+
this.navigationService.OpenEntityRecord('MJ: Content Items', pkey);
|
|
2566
|
+
}
|
|
2567
|
+
getAllTagsForItem(itemId) {
|
|
2568
|
+
const tags = [];
|
|
2569
|
+
for (const tag of this.contentTagsRaw) {
|
|
2570
|
+
if (tag['ItemID'] === itemId) {
|
|
2571
|
+
tags.push(tag['Tag']);
|
|
2572
|
+
}
|
|
2573
|
+
}
|
|
2574
|
+
return tags;
|
|
2575
|
+
}
|
|
2576
|
+
// ════════════════════════════════════════════
|
|
2577
|
+
// DETAIL PANELS — Source Detail
|
|
2578
|
+
// ════════════════════════════════════════════
|
|
2579
|
+
async OpenSourceDetail(card) {
|
|
2580
|
+
this.SourceDetailLoading = true;
|
|
2581
|
+
this.ShowSourceDetail = true;
|
|
2582
|
+
this.cdr.detectChanges();
|
|
2583
|
+
try {
|
|
2584
|
+
const sourceItems = await this.loadContentItemsForSource(card.ID);
|
|
2585
|
+
const sourceRuns = await this.loadRunHistoryForSource(card.ID);
|
|
2586
|
+
const embeddingModelName = this.resolveEmbeddingModelName(card.EmbeddingModelID);
|
|
2587
|
+
const vectorIndexName = this.resolveVectorIndexName(card.VectorIndexID);
|
|
2588
|
+
const errorCount = sourceRuns.filter(r => r.StatusClass === 'failed').length;
|
|
2589
|
+
this.SelectedSource = {
|
|
2590
|
+
ID: card.ID,
|
|
2591
|
+
Name: card.Name,
|
|
2592
|
+
SourceTypeName: card.SourceTypeName,
|
|
2593
|
+
FileTypeName: card.FileTypeName,
|
|
2594
|
+
ContentTypeName: card.ContentTypeName,
|
|
2595
|
+
StatusClass: card.StatusClass,
|
|
2596
|
+
StatusLabel: card.StatusLabel,
|
|
2597
|
+
Icon: card.Icon,
|
|
2598
|
+
URL: card.URL,
|
|
2599
|
+
EmbeddingModelName: embeddingModelName,
|
|
2600
|
+
VectorIndexName: vectorIndexName,
|
|
2601
|
+
ItemCount: card.ItemCount,
|
|
2602
|
+
TagCount: card.TagCount,
|
|
2603
|
+
AvgTags: card.AvgTags,
|
|
2604
|
+
LastRunAgo: card.LastRunAgo,
|
|
2605
|
+
ErrorCount: errorCount,
|
|
2606
|
+
ContentItems: sourceItems,
|
|
2607
|
+
RunHistory: sourceRuns
|
|
2608
|
+
};
|
|
2609
|
+
}
|
|
2610
|
+
catch (error) {
|
|
2611
|
+
console.error('[Autotagging] Error loading source detail:', error);
|
|
2612
|
+
}
|
|
2613
|
+
finally {
|
|
2614
|
+
this.SourceDetailLoading = false;
|
|
2615
|
+
this.cdr.detectChanges();
|
|
2616
|
+
}
|
|
2617
|
+
}
|
|
2618
|
+
CloseSourceDetail() {
|
|
2619
|
+
this.ShowSourceDetail = false;
|
|
2620
|
+
this.SelectedSource = null;
|
|
2621
|
+
this.cdr.detectChanges();
|
|
2622
|
+
}
|
|
2623
|
+
OpenRecordFromSource(source) {
|
|
2624
|
+
const pkey = new CompositeKey();
|
|
2625
|
+
pkey.KeyValuePairs = [{ FieldName: 'ID', Value: source.ID }];
|
|
2626
|
+
this.navigationService.OpenEntityRecord('MJ: Content Sources', pkey);
|
|
2627
|
+
}
|
|
2628
|
+
OpenEditSourceFromDetail() {
|
|
2629
|
+
if (!this.SelectedSource)
|
|
2630
|
+
return;
|
|
2631
|
+
const card = this.SourceCards.find(c => UUIDsEqual(c.ID, this.SelectedSource.ID));
|
|
2632
|
+
if (card) {
|
|
2633
|
+
this.CloseSourceDetail();
|
|
2634
|
+
this.OpenEditSourceForm(card);
|
|
2635
|
+
}
|
|
2636
|
+
}
|
|
2637
|
+
async RunSourceFromDetail() {
|
|
2638
|
+
this.CloseSourceDetail();
|
|
2639
|
+
await this.RunPipeline();
|
|
2640
|
+
}
|
|
2641
|
+
async DeleteSourceFromDetail() {
|
|
2642
|
+
if (!this.SelectedSource)
|
|
2643
|
+
return;
|
|
2644
|
+
const card = this.SourceCards.find(c => UUIDsEqual(c.ID, this.SelectedSource.ID));
|
|
2645
|
+
if (card) {
|
|
2646
|
+
this.CloseSourceDetail();
|
|
2647
|
+
await this.DeleteSource(card);
|
|
2648
|
+
}
|
|
2649
|
+
}
|
|
2650
|
+
async loadContentItemsForSource(sourceId) {
|
|
2651
|
+
const rv = new RunView();
|
|
2652
|
+
const result = await rv.RunView({
|
|
2653
|
+
EntityName: 'MJ: Content Items',
|
|
2654
|
+
ExtraFilter: `ContentSourceID='${sourceId}'`,
|
|
2655
|
+
OrderBy: '__mj_UpdatedAt DESC',
|
|
2656
|
+
MaxRows: 100,
|
|
2657
|
+
ResultType: 'simple'
|
|
2658
|
+
});
|
|
2659
|
+
if (!result.Success)
|
|
2660
|
+
return [];
|
|
2661
|
+
const tagsByItem = this.countTagsByItem();
|
|
2662
|
+
return result.Results.map(item => {
|
|
2663
|
+
const itemId = item['ID'];
|
|
2664
|
+
const allTags = this.getAllTagsForItem(itemId);
|
|
2665
|
+
const tagCount = tagsByItem.get(itemId) ?? allTags.length;
|
|
2666
|
+
return {
|
|
2667
|
+
ID: itemId,
|
|
2668
|
+
Name: item['Name'] ?? 'Unnamed',
|
|
2669
|
+
SourceName: item['ContentSource'] ?? '',
|
|
2670
|
+
SourceTypeName: item['ContentSourceType'] ?? '',
|
|
2671
|
+
ContentTypeName: item['ContentType'] ?? '',
|
|
2672
|
+
FileTypeName: item['ContentFileType'] ?? '',
|
|
2673
|
+
URL: item['URL'] ?? '',
|
|
2674
|
+
TextContent: item['TextContent'] ?? '',
|
|
2675
|
+
Checksum: item['Checksum'] ?? '',
|
|
2676
|
+
Tags: allTags,
|
|
2677
|
+
CreatedAt: this.formatDate(item['__mj_CreatedAt'] ?? ''),
|
|
2678
|
+
UpdatedAt: this.formatDate(item['__mj_UpdatedAt'] ?? ''),
|
|
2679
|
+
ContentSourceID: sourceId,
|
|
2680
|
+
StatusDot: tagCount > 0 ? 'complete' : 'processing',
|
|
2681
|
+
TagCount: tagCount
|
|
2682
|
+
};
|
|
2683
|
+
});
|
|
2684
|
+
}
|
|
2685
|
+
async loadRunHistoryForSource(sourceId) {
|
|
2686
|
+
const rv = new RunView();
|
|
2687
|
+
const result = await rv.RunView({
|
|
2688
|
+
EntityName: 'MJ: Content Process Runs',
|
|
2689
|
+
ExtraFilter: `SourceID='${sourceId}'`,
|
|
2690
|
+
OrderBy: 'StartTime DESC',
|
|
2691
|
+
MaxRows: 10,
|
|
2692
|
+
ResultType: 'simple'
|
|
2693
|
+
});
|
|
2694
|
+
if (!result.Success)
|
|
2695
|
+
return [];
|
|
2696
|
+
return result.Results.map(run => {
|
|
2697
|
+
const status = run['Status'] ?? 'Unknown';
|
|
2698
|
+
const startTime = run['StartTime'];
|
|
2699
|
+
const endTime = run['EndTime'];
|
|
2700
|
+
const duration = this.computeDuration(startTime, endTime);
|
|
2701
|
+
const processedItems = run['ProcessedItems'];
|
|
2702
|
+
const statusLower = status.toLowerCase();
|
|
2703
|
+
const isFailed = statusLower === 'error' || statusLower === 'failed';
|
|
2704
|
+
const isRunning = statusLower === 'running' || statusLower === 'processing';
|
|
2705
|
+
return {
|
|
2706
|
+
ID: run['ID'],
|
|
2707
|
+
Status: this.displayStatus(status),
|
|
2708
|
+
StatusClass: isFailed ? 'failed' : isRunning ? 'running' : 'complete',
|
|
2709
|
+
SourceName: run['Source'] ?? 'Unknown',
|
|
2710
|
+
StartedDisplay: startTime ? this.formatDate(startTime) : '\u2014',
|
|
2711
|
+
Duration: duration,
|
|
2712
|
+
Items: processedItems != null ? this.formatNumber(processedItems) : '\u2014',
|
|
2713
|
+
Tags: '\u2014',
|
|
2714
|
+
Errors: isFailed ? status : '0',
|
|
2715
|
+
ErrorClass: isFailed ? 'run-error-text' : ''
|
|
2716
|
+
};
|
|
2717
|
+
});
|
|
2718
|
+
}
|
|
2719
|
+
resolveEmbeddingModelName(modelId) {
|
|
2720
|
+
if (!modelId)
|
|
2721
|
+
return 'System default';
|
|
2722
|
+
const aiEngine = AIEngineBase.Instance;
|
|
2723
|
+
const model = aiEngine.Models.find(m => UUIDsEqual(m.ID, modelId));
|
|
2724
|
+
return model ? model.Name : 'Unknown';
|
|
2725
|
+
}
|
|
2726
|
+
resolveVectorIndexName(indexId) {
|
|
2727
|
+
if (!indexId)
|
|
2728
|
+
return 'System default';
|
|
2729
|
+
const engine = KnowledgeHubMetadataEngine.Instance;
|
|
2730
|
+
const idx = engine.GetVectorIndexById(indexId);
|
|
2731
|
+
return idx ? idx.Name : 'Unknown';
|
|
2732
|
+
}
|
|
2733
|
+
static ɵfac = /*@__PURE__*/ (() => { let ɵAutotaggingPipelineResourceComponent_BaseFactory; return function AutotaggingPipelineResourceComponent_Factory(__ngFactoryType__) { return (ɵAutotaggingPipelineResourceComponent_BaseFactory || (ɵAutotaggingPipelineResourceComponent_BaseFactory = i0.ɵɵgetInheritedFactory(AutotaggingPipelineResourceComponent)))(__ngFactoryType__ || AutotaggingPipelineResourceComponent); }; })();
|
|
2734
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: AutotaggingPipelineResourceComponent, selectors: [["app-autotagging-pipeline-resource"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 23, vars: 9, consts: [[1, "at-dashboard"], [1, "at-left-nav"], [1, "at-left-nav-header"], [1, "fa-solid", "fa-tags"], [1, "at-left-nav-items"], [1, "at-nav-item", 3, "active"], [1, "at-nav-divider"], [1, "at-nav-item", 3, "click"], [1, "fa-solid", "fa-clock-rotate-left"], [1, "at-left-nav-footer"], [1, "at-run-pipeline-btn", 3, "click", "disabled"], [1, "at-main-area"], [1, "at-loading-overlay"], [1, "at-nav-badge", 3, "at-nav-badge-live"], [1, "at-nav-badge"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "fa-solid", "fa-play"], ["text", "Loading autotagging data..."], [1, "at-page-header"], [1, "at-page-title"], [1, "at-page-subtitle"], [1, "at-page-actions"], [1, "at-action-btn", "at-secondary-btn", 3, "click"], [1, "fa-solid", "fa-arrows-rotate"], [1, "at-page-body"], [1, "at-kpi-strip"], [1, "at-kpi-card"], [1, "at-pipeline-layout"], [1, "at-pipeline-center"], [1, "at-progress-section"], [1, "at-card", 2, "flex", "1"], [1, "at-card-header"], [1, "at-card-title"], [1, "fa-solid", "fa-bolt"], [1, "at-card-body"], [1, "at-empty-state"], [1, "at-feed-item", "at-feed-item-clickable"], [1, "at-pipeline-right"], [1, "at-card"], [1, "fa-solid", "fa-database"], [1, "at-source-mini"], [1, "at-card", "at-tag-cloud-card"], [1, "at-card-title", 2, "margin-bottom", "10px"], [1, "fa-solid", "fa-chart-bar"], [1, "at-tag-cloud"], [1, "at-tag-pill", 3, "class", "opacity", "title"], [1, "at-kpi-value"], [1, "at-kpi-label"], [1, "at-kpi-trend", 3, "up"], [1, "at-kpi-trend"], [1, "fa-solid", "fa-arrow-up"], [1, "at-progress-header"], [1, "at-progress-stage-label"], [1, "at-progress-pct"], [1, "at-progress-bar"], [1, "at-progress-fill"], [1, "at-progress-current"], [1, "fa-solid", "fa-inbox"], [1, "at-feed-item", "at-feed-item-clickable", 3, "click"], [1, "at-feed-status-dot"], [1, "at-feed-item-name"], [1, "at-feed-item-source"], [1, "at-feed-item-tags"], [1, "at-feed-tag"], [1, "at-feed-item-time"], [1, "at-source-mini-icon"], [1, "at-source-mini-info"], [1, "at-source-mini-name"], [1, "at-source-mini-meta"], [1, "at-source-mini-status"], [1, "at-tag-pill", 3, "title"], [1, "at-action-btn", "at-primary-btn", 3, "click"], [1, "fa-solid", "fa-plus"], [1, "at-sources-grid"], [1, "at-source-card-full", "at-source-card-clickable"], [1, "at-add-source-card", 3, "click"], [1, "fa-solid", "fa-plus-circle"], [2, "font-size", "0.85rem", "font-weight", "600"], [2, "font-size", "0.72rem"], [1, "at-source-card-full", "at-source-card-clickable", 3, "click"], [1, "at-source-card-header"], [1, "at-source-card-icon"], [1, "at-source-card-title"], [1, "at-source-card-type"], [1, "at-source-card-status"], [1, "at-source-card-url"], [1, "at-source-card-stats"], [1, "at-source-stat"], [1, "at-source-stat-value"], [1, "at-source-stat-label"], [1, "at-source-card-actions"], [1, "at-source-action-btn", 3, "click"], [1, "fa-solid", "fa-pen"], [1, "at-source-action-btn", "at-source-delete-btn", 3, "click"], [1, "fa-solid", "fa-trash"], [1, "at-ct-grid"], [1, "at-ct-card"], [1, "at-add-type-card", 3, "click"], [1, "at-ct-card-header"], [1, "at-ct-card-name"], [1, "at-ct-card-model"], [1, "at-ct-field"], [1, "at-ct-field-label"], [1, "at-ct-field-value"], [1, "at-ct-tag-range"], [1, "at-ct-tag-range-bar"], [1, "at-ct-tag-range-fill"], [1, "at-ct-range-suffix"], [1, "at-source-card-actions", 2, "margin-top", "10px"], ["type", "text", "placeholder", "Search tags...", 1, "at-search-input", 3, "ngModelChange", "input", "ngModel"], [1, "at-tag-lib-layout"], [1, "at-tag-lib-main"], [1, "at-card-body", 2, "max-height", "500px", "overflow-y", "auto"], [1, "at-tag-table"], [1, "at-tag-lib-sidebar"], [1, "at-card-title", 2, "margin-bottom", "12px"], [1, "fa-solid", "fa-cloud"], [1, "at-card", 2, "padding", "16px", "margin-top", "12px"], [1, "fa-solid", "fa-chart-pie"], [1, "at-tags-by-source"], [1, "at-tag-source-row"], [1, "at-tag-name-cell"], [1, "at-weight-indicator"], [1, "at-weight-bar"], [1, "at-weight-bar-fill"], [1, "at-weight-value"], [1, "at-tag-bar"], [1, "at-tag-bar-fill"], [1, "at-filter-select", 3, "ngModelChange", "change", "ngModel"], ["value", ""], [3, "value"], ["value", "complete"], ["value", "failed"], ["value", "running"], [1, "at-card-body", 2, "max-height", "600px", "overflow-y", "auto"], [1, "at-run-table"], [1, "at-run-status-badge"], [1, "fa-solid", "fa-spinner", "fa-spin", 2, "font-size", "0.55rem"], [1, "at-run-source-name"], [1, "at-run-duration"], [1, "at-slide-overlay", 3, "click"], [1, "at-slide-panel"], [1, "at-slide-header"], [1, "at-slide-close", 3, "click"], [1, "fa-solid", "fa-times"], [1, "at-slide-body"], [1, "at-form-group"], [1, "at-form-label"], ["type", "text", "placeholder", "Source name", 1, "at-form-input", 3, "ngModelChange", "ngModel"], [1, "at-form-select", 3, "ngModelChange", "ngModel"], ["type", "text", "placeholder", "https://...", 1, "at-form-input", 3, "ngModelChange", "ngModel"], ["SelectionMode", "single", "SelectableTypes", "leaf", "Placeholder", "Use system default", 3, "ValueChange", "BranchConfig", "LeafConfig", "Clearable", "Value"], [1, "at-form-hint"], [1, "at-form-actions"], [1, "at-action-btn", "at-primary-btn", 3, "click", "disabled"], [1, "fa-solid", "fa-check"], ["type", "text", "placeholder", "Content type name", 1, "at-form-input", 3, "ngModelChange", "ngModel"], ["rows", "3", "placeholder", "Description...", 1, "at-form-textarea", 3, "ngModelChange", "ngModel"], ["SelectionMode", "single", "SelectableTypes", "leaf", "Placeholder", "Select AI model...", 3, "ValueChange", "BranchConfig", "LeafConfig", "Clearable", "Value"], [1, "at-form-row"], [1, "at-form-group", 2, "flex", "1"], ["type", "number", "min", "0", 1, "at-form-input", 3, "ngModelChange", "ngModel"], ["type", "number", "min", "1", 1, "at-form-input", 3, "ngModelChange", "ngModel"], [1, "at-slide-panel", "at-detail-panel"], [1, "fa-solid", "fa-file-lines"], [1, "at-detail-item-header"], [1, "at-detail-item-name"], [1, "at-detail-badges"], [1, "at-detail-badge", "at-detail-badge-source"], [1, "at-detail-badge", "at-detail-badge-type"], [1, "at-detail-badge", "at-detail-badge-file"], [1, "at-detail-section"], [1, "at-detail-section-label"], [1, "at-detail-meta-grid"], [1, "at-detail-meta-row"], [1, "at-detail-meta-key"], [1, "at-detail-meta-value"], [1, "at-detail-actions"], [1, "fa-solid", "fa-external-link-alt"], ["disabled", "", 1, "at-action-btn", "at-secondary-btn"], [1, "fa-solid", "fa-magnifying-glass"], [1, "fa-solid", "fa-file"], ["target", "_blank", 1, "at-detail-link", 3, "href"], [1, "fa-solid", "fa-external-link-alt", 2, "font-size", "0.65rem", "margin-left", "4px"], [1, "at-detail-text-preview"], [1, "at-detail-tags"], [1, "at-tag-pill"], [1, "at-detail-meta-value", "at-detail-meta-mono"], ["text", "Loading source details..."], [1, "at-detail-source-header"], [1, "at-detail-badge"], [1, "at-detail-stats-strip"], [1, "at-detail-stat"], [1, "at-detail-stat-value"], [1, "at-detail-stat-label"], [1, "at-detail-content-list"], [1, "at-empty-state", 2, "padding", "16px"], [1, "at-detail-content-item"], [1, "at-action-btn", "at-secondary-btn", "at-source-delete-btn", 3, "click"], ["target", "_blank", 1, "at-detail-link", "at-detail-meta-value", 3, "href"], [1, "at-detail-content-item", 3, "click"], [1, "at-detail-content-item-name"], [1, "at-detail-content-item-tags"], [1, "at-detail-content-item-time"], [1, "at-detail-run-history"], [1, "at-detail-run-row"], [1, "at-detail-run-time"], [1, "at-detail-run-duration"], [1, "at-detail-run-items"]], template: function AutotaggingPipelineResourceComponent_Template(rf, ctx) { if (rf & 1) {
|
|
2735
|
+
i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "div", 2)(3, "h2");
|
|
2736
|
+
i0.ɵɵelement(4, "i", 3);
|
|
2737
|
+
i0.ɵɵtext(5, " Autotagging");
|
|
2738
|
+
i0.ɵɵelementEnd()();
|
|
2739
|
+
i0.ɵɵelementStart(6, "div", 4);
|
|
2740
|
+
i0.ɵɵrepeaterCreate(7, AutotaggingPipelineResourceComponent_For_8_Template, 4, 6, "div", 5, _forTrack0);
|
|
2741
|
+
i0.ɵɵelement(9, "div", 6);
|
|
2742
|
+
i0.ɵɵelementStart(10, "div", 7);
|
|
2743
|
+
i0.ɵɵlistener("click", function AutotaggingPipelineResourceComponent_Template_div_click_10_listener() { return ctx.SwitchTab("history"); });
|
|
2744
|
+
i0.ɵɵelement(11, "i", 8);
|
|
2745
|
+
i0.ɵɵtext(12, " Run History ");
|
|
2746
|
+
i0.ɵɵelementEnd()();
|
|
2747
|
+
i0.ɵɵelementStart(13, "div", 9)(14, "button", 10);
|
|
2748
|
+
i0.ɵɵlistener("click", function AutotaggingPipelineResourceComponent_Template_button_click_14_listener() { return ctx.RunPipeline(); });
|
|
2749
|
+
i0.ɵɵconditionalCreate(15, AutotaggingPipelineResourceComponent_Conditional_15_Template, 2, 0)(16, AutotaggingPipelineResourceComponent_Conditional_16_Template, 2, 0);
|
|
2750
|
+
i0.ɵɵelementEnd()()();
|
|
2751
|
+
i0.ɵɵelementStart(17, "div", 11);
|
|
2752
|
+
i0.ɵɵconditionalCreate(18, AutotaggingPipelineResourceComponent_Conditional_18_Template, 2, 0, "div", 12);
|
|
2753
|
+
i0.ɵɵconditionalCreate(19, AutotaggingPipelineResourceComponent_Conditional_19_Template, 5, 5);
|
|
2754
|
+
i0.ɵɵelementEnd();
|
|
2755
|
+
i0.ɵɵconditionalCreate(20, AutotaggingPipelineResourceComponent_Conditional_20_Template, 13, 3);
|
|
2756
|
+
i0.ɵɵconditionalCreate(21, AutotaggingPipelineResourceComponent_Conditional_21_Template, 43, 10);
|
|
2757
|
+
i0.ɵɵconditionalCreate(22, AutotaggingPipelineResourceComponent_Conditional_22_Template, 11, 2);
|
|
2758
|
+
i0.ɵɵelementEnd();
|
|
2759
|
+
} if (rf & 2) {
|
|
2760
|
+
i0.ɵɵadvance(7);
|
|
2761
|
+
i0.ɵɵrepeater(ctx.NavItems);
|
|
2762
|
+
i0.ɵɵadvance(3);
|
|
2763
|
+
i0.ɵɵclassProp("active", ctx.ActiveTab === "history");
|
|
2764
|
+
i0.ɵɵadvance(4);
|
|
2765
|
+
i0.ɵɵproperty("disabled", ctx.IsRunning);
|
|
2766
|
+
i0.ɵɵadvance();
|
|
2767
|
+
i0.ɵɵconditional(ctx.IsRunning ? 15 : 16);
|
|
2768
|
+
i0.ɵɵadvance(3);
|
|
2769
|
+
i0.ɵɵconditional(ctx.IsLoading ? 18 : -1);
|
|
2770
|
+
i0.ɵɵadvance();
|
|
2771
|
+
i0.ɵɵconditional(!ctx.IsLoading ? 19 : -1);
|
|
2772
|
+
i0.ɵɵadvance();
|
|
2773
|
+
i0.ɵɵconditional(ctx.FormMode !== "none" ? 20 : -1);
|
|
2774
|
+
i0.ɵɵadvance();
|
|
2775
|
+
i0.ɵɵconditional(ctx.ShowItemDetail && ctx.SelectedFeedItem ? 21 : -1);
|
|
2776
|
+
i0.ɵɵadvance();
|
|
2777
|
+
i0.ɵɵconditional(ctx.ShowSourceDetail ? 22 : -1);
|
|
2778
|
+
} }, dependencies: [i1.NgSelectOption, i1.ɵNgSelectMultipleOption, i1.DefaultValueAccessor, i1.NumberValueAccessor, i1.SelectControlValueAccessor, i1.NgControlStatus, i1.MinValidator, i1.NgModel, i2.LoadingComponent, i3.TreeDropdownComponent, i4.DecimalPipe], styles: ["/* ============================================================\n Content Autotagging Dashboard\n All colors use MJ design tokens \u2014 no hardcoded hex values.\n All classes prefixed with at- to prevent leaking (ViewEncapsulation.None).\n ============================================================ */\n\n/* \u2500\u2500 Root layout \u2500\u2500 */\n\n.at-dashboard {\n display: flex;\n height: 100%;\n overflow: hidden;\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550 LEFT NAV \u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.at-left-nav {\n width: 220px;\n background: var(--mj-bg-surface);\n border-right: 1px solid var(--mj-border-default);\n display: flex;\n flex-direction: column;\n flex-shrink: 0;\n}\n\n.at-left-nav-header {\n padding: 16px 16px 12px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.at-left-nav-header h2 {\n font-size: 0.95rem;\n font-weight: 700;\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 0;\n color: var(--mj-text-primary);\n}\n\n.at-left-nav-header h2 i {\n color: var(--mj-brand-primary);\n}\n\n.at-left-nav-items {\n flex: 1;\n padding: 8px;\n overflow-y: auto;\n}\n\n.at-nav-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 12px;\n border-radius: 8px;\n font-size: 0.82rem;\n font-weight: 500;\n color: var(--mj-text-muted);\n cursor: pointer;\n transition: all 0.12s ease;\n margin-bottom: 2px;\n}\n\n.at-nav-item:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-secondary);\n}\n\n.at-nav-item.active {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n.at-nav-item i {\n width: 18px;\n text-align: center;\n font-size: 0.8rem;\n}\n\n.at-nav-badge {\n margin-left: auto;\n background: var(--mj-bg-surface-sunken);\n padding: 1px 7px;\n border-radius: 10px;\n font-size: 0.65rem;\n font-weight: 600;\n color: var(--mj-text-muted);\n}\n\n.at-nav-item.active .at-nav-badge {\n background: color-mix(in srgb, var(--mj-brand-primary) 18%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.at-nav-badge-live {\n background: var(--mj-status-success-bg) !important;\n color: var(--mj-status-success-text) !important;\n}\n\n.at-nav-divider {\n height: 1px;\n background: var(--mj-border-subtle);\n margin: 8px 12px;\n}\n\n.at-left-nav-footer {\n padding: 12px;\n border-top: 1px solid var(--mj-border-subtle);\n}\n\n.at-run-pipeline-btn {\n width: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 10px;\n border: none;\n border-radius: 8px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 0.82rem;\n font-weight: 600;\n cursor: pointer;\n transition: background 0.15s ease;\n}\n\n.at-run-pipeline-btn:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n.at-run-pipeline-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550 MAIN CONTENT AREA \u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.at-main-area {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n.at-loading-overlay {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n}\n\n.at-page-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 14px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.at-page-title {\n font-size: 1rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.at-page-subtitle {\n font-size: 0.72rem;\n color: var(--mj-text-muted);\n margin-top: 2px;\n}\n\n.at-page-actions {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.at-page-body {\n flex: 1;\n overflow-y: auto;\n padding: 16px 20px;\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550 SHARED COMPONENTS \u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.at-action-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 7px 14px;\n border: 1px solid;\n border-radius: 7px;\n cursor: pointer;\n font-size: 0.78rem;\n font-weight: 500;\n transition: all 0.15s ease;\n}\n\n.at-primary-btn {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-color: var(--mj-brand-primary);\n}\n\n.at-primary-btn:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n.at-primary-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.at-secondary-btn {\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n border-color: var(--mj-border-default);\n}\n\n.at-secondary-btn:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.at-card {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 10px;\n overflow: hidden;\n}\n\n.at-card-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.at-card-title {\n font-size: 0.82rem;\n font-weight: 600;\n display: flex;\n align-items: center;\n gap: 6px;\n color: var(--mj-text-primary);\n}\n\n.at-card-title i {\n color: var(--mj-brand-primary);\n font-size: 0.75rem;\n}\n\n.at-card-body {\n padding: 0;\n}\n\n.at-empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 32px 16px;\n color: var(--mj-text-disabled);\n}\n\n.at-empty-state i {\n font-size: 28px;\n}\n\n.at-empty-state p {\n margin: 0;\n font-size: 13px;\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550 KPI STRIP \u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.at-kpi-strip {\n display: flex;\n gap: 12px;\n margin-bottom: 16px;\n}\n\n.at-kpi-card {\n flex: 1;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 10px;\n padding: 14px 16px;\n}\n\n.at-kpi-value {\n font-size: 1.4rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.at-kpi-error-value {\n color: var(--mj-status-error-text);\n}\n\n.at-kpi-label {\n font-size: 0.72rem;\n color: var(--mj-text-muted);\n margin-top: 2px;\n}\n\n.at-kpi-trend {\n font-size: 0.68rem;\n margin-top: 4px;\n display: flex;\n align-items: center;\n gap: 4px;\n color: var(--mj-text-muted);\n}\n\n.at-kpi-trend.up {\n color: var(--mj-status-success-text);\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550 PIPELINE TAB \u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.at-pipeline-layout {\n display: flex;\n gap: 16px;\n}\n\n.at-pipeline-center {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 12px;\n min-width: 0;\n}\n\n.at-pipeline-right {\n width: 320px;\n flex-shrink: 0;\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n/* Pipeline Stages */\n\n.at-pipeline-stages {\n display: flex;\n gap: 0;\n align-items: center;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 10px;\n padding: 12px 16px;\n}\n\n.at-pipeline-stage {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n}\n\n.at-pipeline-stage-icon {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 50%;\n font-size: 0.85rem;\n}\n\n.stage-idle .at-pipeline-stage-icon {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n}\n\n.stage-active .at-pipeline-stage-icon {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n animation: at-pulse 1.5s infinite;\n}\n\n.stage-complete .at-pipeline-stage-icon {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success-text);\n}\n\n@keyframes at-pulse {\n 0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--mj-brand-primary) 30%, transparent); }\n 50% { box-shadow: 0 0 0 6px color-mix(in srgb, var(--mj-brand-primary) 0%, transparent); }\n}\n\n.at-pipeline-stage-name {\n font-size: 0.68rem;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.at-pipeline-stage-count {\n font-size: 0.6rem;\n color: var(--mj-text-muted);\n}\n\n.at-pipeline-arrow {\n width: 24px;\n text-align: center;\n color: var(--mj-text-disabled);\n font-size: 0.6rem;\n}\n\n/* Progress section */\n\n.at-progress-section {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 8px;\n padding: 10px 16px;\n}\n\n.at-progress-header {\n display: flex;\n justify-content: space-between;\n font-size: 0.75rem;\n margin-bottom: 4px;\n}\n\n.at-progress-stage-label {\n color: var(--mj-text-secondary);\n font-weight: 500;\n}\n\n.at-progress-pct {\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n.at-progress-bar {\n height: 4px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 2px;\n overflow: hidden;\n}\n\n.at-progress-fill {\n height: 100%;\n background: var(--mj-brand-primary);\n border-radius: 2px;\n transition: width 0.3s ease;\n}\n\n.at-progress-current {\n font-size: 0.68rem;\n color: var(--mj-text-muted);\n margin-top: 4px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* Feed items */\n\n.at-feed-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 14px;\n border-bottom: 1px solid var(--mj-border-subtle);\n font-size: 0.78rem;\n}\n\n.at-feed-item:last-child {\n border-bottom: none;\n}\n\n.at-feed-status-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n}\n\n.at-feed-status-dot.complete {\n background: var(--mj-status-success);\n}\n\n.at-feed-status-dot.processing {\n background: var(--mj-brand-primary);\n animation: at-pulse 1.5s infinite;\n}\n\n.at-feed-status-dot.error {\n background: var(--mj-status-error);\n}\n\n.at-feed-item-name {\n flex: 1;\n font-weight: 500;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: var(--mj-text-primary);\n}\n\n.at-feed-item-source {\n color: var(--mj-text-muted);\n font-size: 0.7rem;\n min-width: 100px;\n}\n\n.at-feed-item-tags {\n display: flex;\n gap: 4px;\n}\n\n.at-feed-tag {\n padding: 1px 6px;\n border-radius: 3px;\n font-size: 0.62rem;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.at-feed-item-time {\n color: var(--mj-text-muted);\n font-size: 0.68rem;\n white-space: nowrap;\n min-width: 60px;\n text-align: right;\n}\n\n/* Source mini cards (right panel) */\n\n.at-source-mini {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 14px;\n border-bottom: 1px solid var(--mj-border-subtle);\n cursor: pointer;\n transition: background 0.1s ease;\n}\n\n.at-source-mini:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.at-source-mini:last-child {\n border-bottom: none;\n}\n\n.at-source-mini-icon {\n width: 28px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 6px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 0.72rem;\n flex-shrink: 0;\n}\n\n.at-source-mini-info {\n flex: 1;\n min-width: 0;\n}\n\n.at-source-mini-name {\n font-size: 0.78rem;\n font-weight: 600;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: var(--mj-text-primary);\n}\n\n.at-source-mini-meta {\n font-size: 0.65rem;\n color: var(--mj-text-muted);\n}\n\n.at-source-mini-status {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n}\n\n.at-source-mini-status.active {\n background: var(--mj-status-success);\n}\n\n.at-source-mini-status.error {\n background: var(--mj-status-error);\n}\n\n.at-source-mini-status.inactive {\n background: var(--mj-text-disabled);\n}\n\n/* Tag cloud card */\n\n.at-tag-cloud-card {\n padding: 16px;\n}\n\n.at-tag-cloud {\n display: flex;\n flex-wrap: wrap;\n gap: 5px;\n}\n\n.at-tag-pill {\n padding: 4px 12px;\n border-radius: 14px;\n font-size: 0.72rem;\n font-weight: 500;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n color: var(--mj-text-secondary);\n border: 1px solid var(--mj-border-subtle);\n cursor: pointer;\n transition: all 0.12s ease;\n}\n\n.at-tag-pill:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n.at-tag-pill.large {\n font-size: 0.85rem;\n padding: 5px 14px;\n}\n\n.at-tag-pill.small {\n font-size: 0.65rem;\n padding: 3px 8px;\n color: var(--mj-text-muted);\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550 SOURCES TAB \u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.at-sources-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));\n gap: 12px;\n}\n\n.at-source-card-full {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 10px;\n padding: 16px;\n transition: border-color 0.15s ease;\n}\n\n.at-source-card-full:hover {\n border-color: var(--mj-border-default);\n}\n\n.at-source-card-header {\n display: flex;\n align-items: center;\n gap: 10px;\n margin-bottom: 12px;\n}\n\n.at-source-card-icon {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 10px;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 1rem;\n flex-shrink: 0;\n}\n\n.at-source-card-title {\n font-size: 0.9rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.at-source-card-type {\n font-size: 0.68rem;\n color: var(--mj-text-muted);\n}\n\n.at-source-card-status {\n margin-left: auto;\n display: flex;\n align-items: center;\n gap: 5px;\n font-size: 0.7rem;\n font-weight: 500;\n}\n\n.at-source-card-status.active {\n color: var(--mj-status-success-text);\n}\n\n.at-source-card-status.error {\n color: var(--mj-status-error-text);\n}\n\n.at-source-card-status.inactive {\n color: var(--mj-text-disabled);\n}\n\n.at-source-card-url {\n font-size: 0.7rem;\n color: var(--mj-brand-primary);\n margin-bottom: 10px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.at-source-card-stats {\n display: flex;\n gap: 16px;\n padding-top: 10px;\n border-top: 1px solid var(--mj-border-subtle);\n}\n\n.at-source-stat {\n display: flex;\n flex-direction: column;\n}\n\n.at-source-stat-value {\n font-size: 1rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.at-source-stat-label {\n font-size: 0.65rem;\n color: var(--mj-text-muted);\n}\n\n.at-source-card-actions {\n display: flex;\n gap: 6px;\n margin-top: 10px;\n}\n\n.at-source-action-btn {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n padding: 6px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 0.7rem;\n cursor: pointer;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n transition: all 0.12s ease;\n}\n\n.at-source-action-btn:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n.at-source-delete-btn:hover {\n border-color: var(--mj-status-error);\n color: var(--mj-status-error-text);\n}\n\n.at-add-source-card {\n background: none;\n border: 2px dashed var(--mj-border-default);\n border-radius: 10px;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 40px;\n cursor: pointer;\n transition: all 0.15s ease;\n color: var(--mj-text-muted);\n min-height: 200px;\n}\n\n.at-add-source-card:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n.at-add-source-card i {\n font-size: 1.5rem;\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550 CONTENT TYPES TAB \u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.at-ct-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));\n gap: 12px;\n}\n\n.at-ct-card {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 10px;\n padding: 16px;\n}\n\n.at-ct-card-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 10px;\n}\n\n.at-ct-card-name {\n font-size: 0.9rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.at-ct-card-model {\n font-size: 0.68rem;\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n padding: 2px 8px;\n border-radius: 10px;\n}\n\n.at-ct-field {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 6px 0;\n border-bottom: 1px solid var(--mj-border-subtle);\n font-size: 0.78rem;\n}\n\n.at-ct-field:last-child {\n border-bottom: none;\n}\n\n.at-ct-field-label {\n color: var(--mj-text-muted);\n}\n\n.at-ct-field-value {\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.at-ct-tag-range {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 8px;\n padding: 8px 10px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 6px;\n font-size: 0.75rem;\n color: var(--mj-text-primary);\n}\n\n.at-ct-tag-range i {\n color: var(--mj-brand-primary);\n}\n\n.at-ct-tag-range-bar {\n flex: 1;\n height: 6px;\n background: var(--mj-bg-surface);\n border-radius: 3px;\n position: relative;\n}\n\n.at-ct-tag-range-fill {\n position: absolute;\n height: 100%;\n background: var(--mj-brand-primary);\n border-radius: 3px;\n}\n\n.at-ct-range-suffix {\n color: var(--mj-text-muted);\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550 TAG LIBRARY TAB \u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.at-tag-lib-layout {\n display: flex;\n gap: 16px;\n}\n\n.at-tag-lib-main {\n flex: 1;\n}\n\n.at-tag-lib-sidebar {\n width: 280px;\n flex-shrink: 0;\n}\n\n.at-tag-table {\n width: 100%;\n border-collapse: collapse;\n}\n\n.at-tag-table th {\n text-align: left;\n padding: 8px 12px;\n font-size: 0.7rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--mj-text-muted);\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-elevated);\n position: sticky;\n top: 0;\n z-index: 1;\n}\n\n.at-tag-table td {\n padding: 10px 12px;\n font-size: 0.8rem;\n border-bottom: 1px solid var(--mj-border-subtle);\n color: var(--mj-text-primary);\n}\n\n.at-tag-table tr:hover td {\n background: var(--mj-bg-surface-hover);\n}\n\n.at-tag-name-cell {\n font-weight: 600;\n}\n\n.at-tag-bar {\n width: 80px;\n height: 6px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 3px;\n display: inline-block;\n vertical-align: middle;\n}\n\n.at-tag-bar-fill {\n height: 100%;\n background: var(--mj-brand-primary);\n border-radius: 3px;\n}\n\n/* Weight indicator in tag table */\n.at-weight-indicator {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.at-weight-bar {\n width: 50px;\n height: 6px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 3px;\n overflow: hidden;\n}\n\n.at-weight-bar-fill {\n height: 100%;\n border-radius: 3px;\n transition: width 0.2s ease;\n}\n\n.at-weight-bar-fill.at-weight-high {\n background: var(--mj-status-success);\n}\n\n.at-weight-bar-fill.at-weight-medium {\n background: var(--mj-status-warning);\n}\n\n.at-weight-bar-fill.at-weight-low {\n background: var(--mj-status-error);\n}\n\n.at-weight-value {\n font-size: 0.7rem;\n font-weight: 600;\n color: var(--mj-text-muted);\n min-width: 28px;\n}\n\n.at-tags-by-source {\n font-size: 0.78rem;\n}\n\n.at-tag-source-row {\n display: flex;\n justify-content: space-between;\n padding: 5px 0;\n border-bottom: 1px solid var(--mj-border-subtle);\n color: var(--mj-text-primary);\n}\n\n.at-tag-source-row:last-child {\n border-bottom: none;\n}\n\n.at-search-input {\n padding: 7px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 7px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 0.8rem;\n width: 200px;\n outline: none;\n}\n\n.at-search-input::placeholder {\n color: var(--mj-text-disabled);\n}\n\n.at-search-input:focus {\n border-color: var(--mj-brand-primary);\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550 RUN HISTORY TAB \u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.at-run-table {\n width: 100%;\n border-collapse: collapse;\n}\n\n.at-run-table th {\n text-align: left;\n padding: 10px 14px;\n font-size: 0.7rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--mj-text-muted);\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-elevated);\n position: sticky;\n top: 0;\n z-index: 1;\n}\n\n.at-run-table td {\n padding: 12px 14px;\n font-size: 0.8rem;\n border-bottom: 1px solid var(--mj-border-subtle);\n color: var(--mj-text-primary);\n}\n\n.at-run-table tr:hover td {\n background: var(--mj-bg-surface-hover);\n cursor: pointer;\n}\n\n.at-run-status-badge {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 2px 10px;\n border-radius: 10px;\n font-size: 0.7rem;\n font-weight: 600;\n}\n\n.at-run-status-badge.complete {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success-text);\n}\n\n.at-run-status-badge.failed {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error-text);\n}\n\n.at-run-status-badge.running {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.at-run-duration {\n color: var(--mj-text-muted);\n font-size: 0.75rem;\n}\n\n.at-run-source-name {\n font-weight: 500;\n}\n\n.at-run-error-text {\n color: var(--mj-status-error-text);\n}\n\n.at-filter-select {\n padding: 7px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 7px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 0.78rem;\n outline: none;\n}\n\n.at-filter-select:focus {\n border-color: var(--mj-brand-primary);\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550 SLIDE-IN FORM PANEL \u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.at-slide-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-overlay);\n z-index: 1000;\n}\n\n.at-slide-panel {\n position: fixed;\n right: 0;\n top: 0;\n bottom: 0;\n width: 420px;\n max-width: 100vw;\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n z-index: 1001;\n display: flex;\n flex-direction: column;\n box-shadow: -4px 0 24px color-mix(in srgb, var(--mj-text-primary) 15%, transparent);\n}\n\n.at-slide-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.at-slide-header h3 {\n margin: 0;\n font-size: 1rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.at-slide-close {\n background: none;\n border: none;\n font-size: 1.1rem;\n color: var(--mj-text-muted);\n cursor: pointer;\n padding: 4px;\n}\n\n.at-slide-close:hover {\n color: var(--mj-text-primary);\n}\n\n.at-slide-body {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n}\n\n.at-form-group {\n margin-bottom: 16px;\n}\n\n.at-form-label {\n display: block;\n font-size: 0.78rem;\n font-weight: 600;\n color: var(--mj-text-secondary);\n margin-bottom: 6px;\n}\n\n.at-form-input,\n.at-form-select,\n.at-form-textarea {\n width: 100%;\n padding: 9px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 7px;\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-primary);\n font-size: 0.82rem;\n outline: none;\n font-family: inherit;\n}\n\n.at-form-input:focus,\n.at-form-select:focus,\n.at-form-textarea:focus {\n border-color: var(--mj-brand-primary);\n}\n\n.at-form-input::placeholder,\n.at-form-textarea::placeholder {\n color: var(--mj-text-disabled);\n}\n\n.at-form-textarea {\n resize: vertical;\n}\n\n.at-form-row {\n display: flex;\n gap: 12px;\n}\n\n.at-form-actions {\n display: flex;\n gap: 8px;\n margin-top: 24px;\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550 RESPONSIVE \u2550\u2550\u2550\u2550\u2550\u2550 */\n\n@media (max-width: 1100px) {\n .at-pipeline-layout {\n flex-direction: column;\n }\n\n .at-pipeline-right {\n width: 100%;\n flex-direction: row;\n }\n\n .at-tag-lib-layout {\n flex-direction: column;\n }\n\n .at-tag-lib-sidebar {\n width: 100%;\n }\n}\n\n@media (max-width: 768px) {\n .at-left-nav {\n width: 180px;\n }\n\n .at-kpi-strip {\n flex-wrap: wrap;\n }\n\n .at-kpi-card {\n min-width: 140px;\n }\n\n .at-sources-grid {\n grid-template-columns: 1fr;\n }\n\n .at-ct-grid {\n grid-template-columns: 1fr;\n }\n\n .at-slide-panel {\n width: 100vw;\n }\n}\n\n@media (max-width: 480px) {\n .at-left-nav {\n width: 56px;\n }\n\n .at-left-nav-header h2 {\n font-size: 0;\n }\n\n .at-left-nav-header h2 i {\n font-size: 1rem;\n }\n\n .at-nav-item {\n justify-content: center;\n padding: 10px;\n font-size: 0;\n }\n\n .at-nav-item i {\n font-size: 1rem;\n }\n\n .at-nav-badge {\n display: none;\n }\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n Slide-in Form Panel\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.at-slide-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.35);\n z-index: 9999;\n animation: at-fade-in 0.2s ease;\n}\n\n@keyframes at-fade-in { from { opacity: 0; } to { opacity: 1; } }\n\n.at-slide-panel {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n width: 420px;\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n box-shadow: -8px 0 40px rgba(0, 0, 0, 0.4);\n z-index: 10000;\n display: flex;\n flex-direction: column;\n animation: at-slide-in 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n@keyframes at-slide-in { from { transform: translateX(100%); } to { transform: translateX(0); } }\n\n.at-slide-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.at-slide-header h3 {\n font-size: 1rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.at-slide-close {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n font-size: 0.85rem;\n transition: all 0.15s ease;\n}\n\n.at-slide-close:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.at-slide-body {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.at-form-group {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.at-form-label {\n font-size: 0.75rem;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n.at-form-input,\n.at-form-select,\n.at-form-textarea {\n padding: 9px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 7px;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n font-size: 0.85rem;\n outline: none;\n transition: border-color 0.15s ease;\n font-family: inherit;\n}\n\n.at-form-input:focus,\n.at-form-select:focus,\n.at-form-textarea:focus {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.at-form-select {\n appearance: none;\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%2364748b' d='M3 5l3 3 3-3'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: right 10px center;\n padding-right: 30px;\n}\n\n.at-form-textarea {\n resize: vertical;\n min-height: 70px;\n}\n\n.at-form-row {\n display: flex;\n gap: 12px;\n}\n\n.at-form-actions {\n display: flex;\n gap: 8px;\n padding-top: 8px;\n border-top: 1px solid var(--mj-border-subtle);\n margin-top: 8px;\n}\n\n.at-form-actions .at-action-btn {\n flex: 1;\n justify-content: center;\n}\n\n/* Also add empty state for Content Types (matching Sources) */\n.at-add-type-card {\n background: none;\n border: 2px dashed var(--mj-border-default);\n border-radius: 10px;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 40px;\n cursor: pointer;\n transition: all 0.15s ease;\n color: var(--mj-text-muted);\n min-height: 200px;\n}\n\n.at-add-type-card:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n.at-add-type-card i {\n font-size: 1.5rem;\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550 FORKED PIPELINE STAGES \u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.at-pipeline-stages-forked {\n display: flex;\n align-items: center;\n gap: 0;\n}\n\n.at-pipeline-fork {\n display: flex;\n align-items: center;\n gap: 0;\n flex: 2;\n}\n\n.at-pipeline-fork-lines {\n width: 28px;\n display: flex;\n flex-direction: column;\n gap: 12px;\n position: relative;\n flex-shrink: 0;\n}\n\n.at-pipeline-fork-line {\n height: 2px;\n background: var(--mj-border-default);\n width: 100%;\n position: relative;\n}\n\n.at-pipeline-fork-line::before {\n content: '';\n position: absolute;\n width: 2px;\n height: 12px;\n background: var(--mj-border-default);\n left: 0;\n}\n\n.at-fork-top::before {\n bottom: 0;\n left: 0;\n}\n\n.at-fork-bottom::before {\n top: 0;\n left: 0;\n}\n\n.at-pipeline-fork-branches {\n display: flex;\n flex-direction: column;\n gap: 8px;\n flex: 1;\n}\n\n.at-pipeline-fork-branches .at-pipeline-stage {\n flex: none;\n padding: 6px 0;\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550 CLICKABLE FEED ITEMS \u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.at-feed-item-clickable {\n cursor: pointer;\n}\n\n.at-feed-item-clickable:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550 CLICKABLE SOURCE CARDS \u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.at-source-card-clickable {\n cursor: pointer;\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550 FORM HINT \u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.at-form-hint {\n font-size: 0.68rem;\n color: var(--mj-text-muted);\n font-style: italic;\n margin-top: 2px;\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550 DETAIL PANEL (wider) \u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.at-detail-panel {\n width: 500px;\n}\n\n/* \u2500\u2500 Detail: Item header \u2500\u2500 */\n\n.at-detail-item-header {\n margin-bottom: 8px;\n}\n\n.at-detail-item-name {\n font-size: 1.05rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0 0 6px 0;\n word-break: break-word;\n}\n\n.at-detail-badges {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n}\n\n.at-detail-badge {\n padding: 2px 10px;\n border-radius: 10px;\n font-size: 0.7rem;\n font-weight: 600;\n}\n\n.at-detail-badge-source {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.at-detail-badge-type {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.at-detail-badge-file {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n}\n\n.at-detail-badge-status-active {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success-text);\n}\n\n.at-detail-badge-status-error {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error-text);\n}\n\n.at-detail-badge-status-inactive {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-disabled);\n}\n\n/* \u2500\u2500 Detail: Sections \u2500\u2500 */\n\n.at-detail-section {\n margin-bottom: 4px;\n}\n\n.at-detail-section-label {\n font-size: 0.72rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n color: var(--mj-text-muted);\n margin-bottom: 6px;\n}\n\n.at-detail-link {\n font-size: 0.8rem;\n color: var(--mj-brand-primary);\n text-decoration: none;\n word-break: break-all;\n}\n\n.at-detail-link:hover {\n text-decoration: underline;\n}\n\n/* \u2500\u2500 Detail: Text preview \u2500\u2500 */\n\n.at-detail-text-preview {\n max-height: 200px;\n overflow-y: auto;\n padding: 10px 12px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 6px;\n font-size: 0.78rem;\n font-family: 'SF Mono', 'Cascadia Code', 'Menlo', monospace;\n color: var(--mj-text-primary);\n white-space: pre-wrap;\n word-break: break-word;\n line-height: 1.5;\n}\n\n/* \u2500\u2500 Detail: Tags \u2500\u2500 */\n\n.at-detail-tags {\n display: flex;\n flex-wrap: wrap;\n gap: 5px;\n}\n\n/* \u2500\u2500 Detail: Meta grid \u2500\u2500 */\n\n.at-detail-meta-grid {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 8px;\n overflow: hidden;\n}\n\n.at-detail-meta-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 12px;\n border-bottom: 1px solid var(--mj-border-subtle);\n font-size: 0.78rem;\n}\n\n.at-detail-meta-row:last-child {\n border-bottom: none;\n}\n\n.at-detail-meta-key {\n color: var(--mj-text-muted);\n font-weight: 500;\n flex-shrink: 0;\n margin-right: 12px;\n}\n\n.at-detail-meta-value {\n color: var(--mj-text-primary);\n text-align: right;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.at-detail-meta-mono {\n font-family: 'SF Mono', 'Cascadia Code', 'Menlo', monospace;\n font-size: 0.72rem;\n}\n\n/* \u2500\u2500 Detail: Actions \u2500\u2500 */\n\n.at-detail-actions {\n display: flex;\n gap: 8px;\n padding-top: 8px;\n border-top: 1px solid var(--mj-border-subtle);\n margin-top: 8px;\n}\n\n.at-detail-actions .at-action-btn {\n flex: 1;\n justify-content: center;\n}\n\n/* \u2500\u2500 Detail: Source header \u2500\u2500 */\n\n.at-detail-source-header {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 8px;\n}\n\n/* \u2500\u2500 Detail: Stats strip \u2500\u2500 */\n\n.at-detail-stats-strip {\n display: flex;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n.at-detail-stat {\n flex: 1;\n min-width: 60px;\n text-align: center;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 8px;\n padding: 8px 6px;\n}\n\n.at-detail-stat-value {\n font-size: 1rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.at-detail-stat-label {\n font-size: 0.62rem;\n color: var(--mj-text-muted);\n margin-top: 2px;\n}\n\n/* \u2500\u2500 Detail: Content Library \u2500\u2500 */\n\n.at-detail-content-list {\n max-height: 250px;\n overflow-y: auto;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 8px;\n}\n\n.at-detail-content-item {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n border-bottom: 1px solid var(--mj-border-subtle);\n font-size: 0.78rem;\n cursor: pointer;\n transition: background 0.1s ease;\n}\n\n.at-detail-content-item:last-child {\n border-bottom: none;\n}\n\n.at-detail-content-item:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.at-detail-content-item-name {\n flex: 1;\n font-weight: 500;\n color: var(--mj-text-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.at-detail-content-item-tags {\n font-size: 0.68rem;\n color: var(--mj-text-muted);\n white-space: nowrap;\n}\n\n.at-detail-content-item-time {\n font-size: 0.68rem;\n color: var(--mj-text-muted);\n white-space: nowrap;\n}\n\n/* \u2500\u2500 Detail: Run history \u2500\u2500 */\n\n.at-detail-run-history {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 8px;\n max-height: 200px;\n overflow-y: auto;\n}\n\n.at-detail-run-row {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n border-bottom: 1px solid var(--mj-border-subtle);\n font-size: 0.75rem;\n}\n\n.at-detail-run-row:last-child {\n border-bottom: none;\n}\n\n.at-detail-run-time {\n color: var(--mj-text-secondary);\n flex: 1;\n}\n\n.at-detail-run-duration {\n color: var(--mj-text-muted);\n}\n\n.at-detail-run-items {\n color: var(--mj-text-muted);\n}\n\n@media (max-width: 600px) {\n .at-slide-panel {\n width: 100%;\n }\n\n .at-detail-panel {\n width: 100%;\n }\n}\n"], encapsulation: 2 });
|
|
2779
|
+
};
|
|
2780
|
+
AutotaggingPipelineResourceComponent = __decorate([
|
|
2781
|
+
RegisterClass(BaseResourceComponent, 'AutotaggingPipelineResource')
|
|
2782
|
+
], AutotaggingPipelineResourceComponent);
|
|
2783
|
+
export { AutotaggingPipelineResourceComponent };
|
|
2784
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(AutotaggingPipelineResourceComponent, [{
|
|
2785
|
+
type: Component,
|
|
2786
|
+
args: [{ standalone: false, selector: 'app-autotagging-pipeline-resource', encapsulation: ViewEncapsulation.None, template: "<!-- Content Autotagging Dashboard -->\n<div class=\"at-dashboard\">\n\n <!-- \u2550\u2550\u2550\u2550\u2550\u2550 LEFT NAV \u2550\u2550\u2550\u2550\u2550\u2550 -->\n <div class=\"at-left-nav\">\n <div class=\"at-left-nav-header\">\n <h2><i class=\"fa-solid fa-tags\"></i> Autotagging</h2>\n </div>\n <div class=\"at-left-nav-items\">\n @for (item of NavItems; track item.Tab) {\n <div class=\"at-nav-item\" [class.active]=\"ActiveTab === item.Tab\" (click)=\"SwitchTab(item.Tab)\">\n <i [class]=\"item.Icon\"></i> {{ item.Label }}\n @if (item.BadgeText) {\n <span class=\"at-nav-badge\" [class.at-nav-badge-live]=\"item.BadgeClass === 'nav-badge-live'\">{{ item.BadgeText }}</span>\n }\n </div>\n }\n <div class=\"at-nav-divider\"></div>\n <div class=\"at-nav-item\" [class.active]=\"ActiveTab === 'history'\" (click)=\"SwitchTab('history')\">\n <i class=\"fa-solid fa-clock-rotate-left\"></i> Run History\n </div>\n </div>\n <div class=\"at-left-nav-footer\">\n <button class=\"at-run-pipeline-btn\" (click)=\"RunPipeline()\" [disabled]=\"IsRunning\">\n @if (IsRunning) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Running...\n } @else {\n <i class=\"fa-solid fa-play\"></i> Run Pipeline\n }\n </button>\n </div>\n </div>\n\n <!-- \u2550\u2550\u2550\u2550\u2550\u2550 MAIN AREA \u2550\u2550\u2550\u2550\u2550\u2550 -->\n <div class=\"at-main-area\">\n\n @if (IsLoading) {\n <div class=\"at-loading-overlay\">\n <mj-loading text=\"Loading autotagging data...\"></mj-loading>\n </div>\n }\n\n @if (!IsLoading) {\n\n <!-- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 -->\n <!-- TAB 1: PIPELINE MONITOR -->\n <!-- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 -->\n @if (ActiveTab === 'pipeline') {\n <div class=\"at-page-header\">\n <div>\n <div class=\"at-page-title\">Pipeline Monitor</div>\n <div class=\"at-page-subtitle\">Real-time processing status and recent activity</div>\n </div>\n <div class=\"at-page-actions\">\n <button class=\"at-action-btn at-secondary-btn\" (click)=\"LoadPipelineData()\">\n <i class=\"fa-solid fa-arrows-rotate\"></i> Refresh\n </button>\n </div>\n </div>\n <div class=\"at-page-body\">\n <!-- KPIs -->\n <div class=\"at-kpi-strip\">\n @for (kpi of KPIMetrics; track kpi.Label) {\n <div class=\"at-kpi-card\">\n <div class=\"at-kpi-value\" [class.at-kpi-error-value]=\"kpi.Label === 'Errors' && kpi.Value > 0\">{{ kpi.Value | number }}</div>\n <div class=\"at-kpi-label\">{{ kpi.Label }}</div>\n @if (kpi.Trend) {\n <div class=\"at-kpi-trend\" [class.up]=\"kpi.TrendUp\">\n @if (kpi.TrendUp) { <i class=\"fa-solid fa-arrow-up\"></i> }\n {{ kpi.Trend }}\n </div>\n }\n </div>\n }\n </div>\n\n <div class=\"at-pipeline-layout\">\n <div class=\"at-pipeline-center\">\n <!-- Pipeline stages visualization hidden for now \u2014 can re-enable with animation later -->\n\n <!-- Progress bar (visible during run) -->\n @if (IsRunning) {\n <div class=\"at-progress-section\">\n <div class=\"at-progress-header\">\n <span class=\"at-progress-stage-label\">{{ RunStage }}</span>\n <span class=\"at-progress-pct\">{{ RunProgress }}%</span>\n </div>\n <div class=\"at-progress-bar\"><div class=\"at-progress-fill\" [style.width.%]=\"RunProgress\"></div></div>\n @if (RunCurrentItem) {\n <div class=\"at-progress-current\">{{ RunCurrentItem }}</div>\n }\n </div>\n }\n\n <!-- Recent Processing Feed -->\n <div class=\"at-card\" style=\"flex: 1;\">\n <div class=\"at-card-header\">\n <span class=\"at-card-title\"><i class=\"fa-solid fa-bolt\"></i> Recent Processing</span>\n </div>\n <div class=\"at-card-body\">\n @if (FeedItems.length === 0) {\n <div class=\"at-empty-state\">\n <i class=\"fa-solid fa-inbox\"></i>\n <p>No processed items yet.</p>\n </div>\n }\n @for (item of FeedItems; track $index) {\n <div class=\"at-feed-item at-feed-item-clickable\" (click)=\"OpenFeedItemDetail($index)\">\n <div class=\"at-feed-status-dot\" [class]=\"item.Status\"></div>\n <span class=\"at-feed-item-name\">{{ item.Name }}</span>\n <span class=\"at-feed-item-source\">{{ item.SourceName }}</span>\n <div class=\"at-feed-item-tags\">\n @for (tag of item.Tags; track tag) {\n <span class=\"at-feed-tag\">{{ tag }}</span>\n }\n </div>\n <span class=\"at-feed-item-time\">{{ item.TimeAgo }}</span>\n </div>\n }\n </div>\n </div>\n </div>\n\n <!-- Right sidebar -->\n <div class=\"at-pipeline-right\">\n <!-- Sources Quick List -->\n <div class=\"at-card\">\n <div class=\"at-card-header\">\n <span class=\"at-card-title\"><i class=\"fa-solid fa-database\"></i> Sources</span>\n </div>\n <div class=\"at-card-body\">\n @for (source of SourceMinis; track source.ID) {\n <div class=\"at-source-mini\">\n <div class=\"at-source-mini-icon\"><i [class]=\"source.Icon\"></i></div>\n <div class=\"at-source-mini-info\">\n <div class=\"at-source-mini-name\">{{ source.Name }}</div>\n <div class=\"at-source-mini-meta\">{{ source.Meta }}</div>\n </div>\n <div class=\"at-source-mini-status\" [class]=\"source.StatusClass\"></div>\n </div>\n }\n </div>\n </div>\n <!-- Trending Tags -->\n <div class=\"at-card at-tag-cloud-card\">\n <div class=\"at-card-title\" style=\"margin-bottom: 10px;\"><i class=\"fa-solid fa-chart-bar\"></i> Trending Tags</div>\n <div class=\"at-tag-cloud\">\n @for (tag of TrendingTags; track tag.Tag) {\n <span class=\"at-tag-pill\" [class]=\"tag.SizeClass\"\n [style.opacity]=\"0.4 + tag.AvgWeight * 0.6\"\n [title]=\"'Weight: ' + tag.AvgWeight.toFixed(2)\">{{ tag.Tag }}</span>\n }\n </div>\n </div>\n </div>\n </div>\n </div>\n }\n\n <!-- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 -->\n <!-- TAB 2: SOURCES -->\n <!-- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 -->\n @if (ActiveTab === 'sources') {\n <div class=\"at-page-header\">\n <div>\n <div class=\"at-page-title\">Content Sources</div>\n <div class=\"at-page-subtitle\">Configure where content is ingested from</div>\n </div>\n <div class=\"at-page-actions\">\n <button class=\"at-action-btn at-primary-btn\" (click)=\"OpenAddSourceForm()\">\n <i class=\"fa-solid fa-plus\"></i> Add Source\n </button>\n </div>\n </div>\n <div class=\"at-page-body\">\n <div class=\"at-sources-grid\">\n @for (card of SourceCards; track card.ID) {\n <div class=\"at-source-card-full at-source-card-clickable\" (click)=\"OpenSourceDetail(card)\">\n <div class=\"at-source-card-header\">\n <div class=\"at-source-card-icon\"><i [class]=\"card.Icon\"></i></div>\n <div>\n <div class=\"at-source-card-title\">{{ card.Name }}</div>\n <div class=\"at-source-card-type\">{{ card.SourceTypeName }} \u00B7 {{ card.FileTypeName }}</div>\n </div>\n <div class=\"at-source-card-status\" [class]=\"card.StatusClass\">\n <div class=\"at-source-mini-status\" [class]=\"card.StatusClass\"></div>\n {{ card.StatusLabel }}\n </div>\n </div>\n @if (card.URL) {\n <div class=\"at-source-card-url\">{{ card.URL }}</div>\n }\n <div class=\"at-source-card-stats\">\n <div class=\"at-source-stat\">\n <div class=\"at-source-stat-value\">{{ formatNumber(card.ItemCount) }}</div>\n <div class=\"at-source-stat-label\">Items</div>\n </div>\n <div class=\"at-source-stat\">\n <div class=\"at-source-stat-value\">{{ formatNumber(card.TagCount) }}</div>\n <div class=\"at-source-stat-label\">Tags</div>\n </div>\n <div class=\"at-source-stat\">\n <div class=\"at-source-stat-value\">{{ card.AvgTags }}</div>\n <div class=\"at-source-stat-label\">Avg Tags</div>\n </div>\n <div class=\"at-source-stat\">\n <div class=\"at-source-stat-value\">{{ card.LastRunAgo }}</div>\n <div class=\"at-source-stat-label\">Last Run</div>\n </div>\n </div>\n <div class=\"at-source-card-actions\">\n <button class=\"at-source-action-btn\" (click)=\"OpenEditSourceForm(card); $event.stopPropagation()\"><i class=\"fa-solid fa-pen\"></i> Edit</button>\n <button class=\"at-source-action-btn\" (click)=\"RunPipeline(); $event.stopPropagation()\"><i class=\"fa-solid fa-play\"></i> Run</button>\n <button class=\"at-source-action-btn at-source-delete-btn\" (click)=\"DeleteSource(card); $event.stopPropagation()\"><i class=\"fa-solid fa-trash\"></i> Delete</button>\n </div>\n </div>\n }\n\n <!-- Add Source Card -->\n <div class=\"at-add-source-card\" (click)=\"OpenAddSourceForm()\">\n <i class=\"fa-solid fa-plus-circle\"></i>\n <span style=\"font-size: 0.85rem; font-weight: 600;\">Add Content Source</span>\n <span style=\"font-size: 0.72rem;\">Web, RSS, Email, Files, API</span>\n </div>\n </div>\n </div>\n }\n\n <!-- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 -->\n <!-- TAB 3: CONTENT TYPES -->\n <!-- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 -->\n @if (ActiveTab === 'types') {\n <div class=\"at-page-header\">\n <div>\n <div class=\"at-page-title\">Content Types</div>\n <div class=\"at-page-subtitle\">Configure AI tagging rules per content category</div>\n </div>\n <div class=\"at-page-actions\">\n <button class=\"at-action-btn at-primary-btn\" (click)=\"OpenAddTypeForm()\">\n <i class=\"fa-solid fa-plus\"></i> Add Type\n </button>\n </div>\n </div>\n <div class=\"at-page-body\">\n <div class=\"at-ct-grid\">\n @for (card of ContentTypeCards; track card.ID) {\n <div class=\"at-ct-card\">\n <div class=\"at-ct-card-header\">\n <span class=\"at-ct-card-name\">{{ card.Name }}</span>\n <span class=\"at-ct-card-model\">{{ card.AIModelName }}</span>\n </div>\n <div class=\"at-ct-field\">\n <span class=\"at-ct-field-label\">Description</span>\n <span class=\"at-ct-field-value\">{{ card.Description || '\\u2014' }}</span>\n </div>\n <div class=\"at-ct-field\">\n <span class=\"at-ct-field-label\">Sources Using</span>\n <span class=\"at-ct-field-value\">{{ card.SourcesUsing }}</span>\n </div>\n <div class=\"at-ct-field\">\n <span class=\"at-ct-field-label\">Items Tagged</span>\n <span class=\"at-ct-field-value\">{{ formatNumber(card.ItemsTagged) }}</span>\n </div>\n <div class=\"at-ct-tag-range\">\n <i class=\"fa-solid fa-tags\"></i>\n <span>{{ card.MinTags }}</span>\n <div class=\"at-ct-tag-range-bar\">\n <div class=\"at-ct-tag-range-fill\" [style.left.%]=\"card.RangeLeftPct\" [style.right.%]=\"card.RangeRightPct\"></div>\n </div>\n <span>{{ card.MaxTags }}</span>\n <span class=\"at-ct-range-suffix\">tags/item</span>\n </div>\n <div class=\"at-source-card-actions\" style=\"margin-top: 10px;\">\n <button class=\"at-source-action-btn\" (click)=\"OpenEditTypeForm(card)\"><i class=\"fa-solid fa-pen\"></i> Edit</button>\n </div>\n </div>\n }\n <!-- Add Content Type Card -->\n <div class=\"at-add-type-card\" (click)=\"OpenAddTypeForm()\">\n <i class=\"fa-solid fa-plus-circle\"></i>\n <span style=\"font-size: 0.85rem; font-weight: 600;\">Add Content Type</span>\n <span style=\"font-size: 0.72rem;\">Configure tagging rules</span>\n </div>\n </div>\n </div>\n }\n\n <!-- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 -->\n <!-- TAB 4: TAG LIBRARY -->\n <!-- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 -->\n @if (ActiveTab === 'tags') {\n <div class=\"at-page-header\">\n <div>\n <div class=\"at-page-title\">Tag Library</div>\n <div class=\"at-page-subtitle\">{{ TagRows.length }} unique tags across all content sources</div>\n </div>\n <div class=\"at-page-actions\">\n <input type=\"text\" class=\"at-search-input\" placeholder=\"Search tags...\"\n [(ngModel)]=\"TagSearchQuery\" (input)=\"FilterTags()\">\n </div>\n </div>\n <div class=\"at-page-body\">\n <div class=\"at-tag-lib-layout\">\n <div class=\"at-tag-lib-main\">\n <div class=\"at-card\">\n <div class=\"at-card-body\" style=\"max-height: 500px; overflow-y: auto;\">\n <table class=\"at-tag-table\">\n <thead>\n <tr>\n <th>Tag</th>\n <th>Count</th>\n <th>Avg Weight</th>\n <th>Distribution</th>\n <th>Top Source</th>\n <th>First Seen</th>\n </tr>\n </thead>\n <tbody>\n @for (row of FilteredTagRows; track row.Tag) {\n <tr>\n <td class=\"at-tag-name-cell\">{{ row.Tag }}</td>\n <td>{{ row.UsageCount }}</td>\n <td>\n <div class=\"at-weight-indicator\">\n <div class=\"at-weight-bar\">\n <div class=\"at-weight-bar-fill\" [style.width.%]=\"row.AvgWeight * 100\"\n [class.at-weight-high]=\"row.AvgWeight >= 0.7\"\n [class.at-weight-medium]=\"row.AvgWeight >= 0.4 && row.AvgWeight < 0.7\"\n [class.at-weight-low]=\"row.AvgWeight < 0.4\"></div>\n </div>\n <span class=\"at-weight-value\">{{ row.AvgWeight.toFixed(2) }}</span>\n </div>\n </td>\n <td>\n <div class=\"at-tag-bar\">\n <div class=\"at-tag-bar-fill\" [style.width.%]=\"row.BarWidthPct\"></div>\n </div>\n </td>\n <td>{{ row.TopSource }}</td>\n <td>{{ row.FirstSeen }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </div>\n </div>\n <div class=\"at-tag-lib-sidebar\">\n <div class=\"at-card at-tag-cloud-card\">\n <div class=\"at-card-title\" style=\"margin-bottom: 12px;\"><i class=\"fa-solid fa-cloud\"></i> Tag Cloud</div>\n <div class=\"at-tag-cloud\">\n @for (tag of TagCloud; track tag.Tag) {\n <span class=\"at-tag-pill\" [class]=\"tag.SizeClass\"\n [style.opacity]=\"0.4 + tag.AvgWeight * 0.6\"\n [title]=\"'Weight: ' + tag.AvgWeight.toFixed(2)\">{{ tag.Tag }}</span>\n }\n </div>\n </div>\n <div class=\"at-card\" style=\"padding: 16px; margin-top: 12px;\">\n <div class=\"at-card-title\" style=\"margin-bottom: 10px;\"><i class=\"fa-solid fa-chart-pie\"></i> By Source</div>\n <div class=\"at-tags-by-source\">\n @for (s of TagsBySource; track s.SourceName) {\n <div class=\"at-tag-source-row\">\n <span>{{ s.SourceName }}</span>\n <strong>{{ s.Count }}</strong>\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n </div>\n }\n\n <!-- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 -->\n <!-- TAB 5: RUN HISTORY -->\n <!-- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 -->\n @if (ActiveTab === 'history') {\n <div class=\"at-page-header\">\n <div>\n <div class=\"at-page-title\">Run History</div>\n <div class=\"at-page-subtitle\">Processing run log across all content sources</div>\n </div>\n <div class=\"at-page-actions\">\n <select class=\"at-filter-select\" [(ngModel)]=\"HistorySourceFilter\" (change)=\"FilterRunHistory()\">\n <option value=\"\">All Sources</option>\n @for (s of HistorySourceOptions; track s) {\n <option [value]=\"s\">{{ s }}</option>\n }\n </select>\n <select class=\"at-filter-select\" [(ngModel)]=\"HistoryStatusFilter\" (change)=\"FilterRunHistory()\">\n <option value=\"\">All Status</option>\n <option value=\"complete\">Complete</option>\n <option value=\"failed\">Failed</option>\n <option value=\"running\">Running</option>\n </select>\n </div>\n </div>\n <div class=\"at-page-body\">\n <div class=\"at-card\">\n <div class=\"at-card-body\" style=\"max-height: 600px; overflow-y: auto;\">\n <table class=\"at-run-table\">\n <thead>\n <tr>\n <th>Status</th>\n <th>Source</th>\n <th>Started</th>\n <th>Duration</th>\n <th>Items</th>\n <th>Tags</th>\n <th>Errors</th>\n </tr>\n </thead>\n <tbody>\n @for (row of FilteredRunRows; track row.ID) {\n <tr>\n <td>\n <span class=\"at-run-status-badge\" [class]=\"row.StatusClass\">\n @if (row.StatusClass === 'running') {\n <i class=\"fa-solid fa-spinner fa-spin\" style=\"font-size: 0.55rem\"></i>\n }\n {{ row.Status }}\n </span>\n </td>\n <td class=\"at-run-source-name\">{{ row.SourceName }}</td>\n <td>{{ row.StartedDisplay }}</td>\n <td class=\"at-run-duration\">{{ row.Duration }}</td>\n <td>{{ row.Items }}</td>\n <td>{{ row.Tags }}</td>\n <td [class]=\"row.ErrorClass\">{{ row.Errors }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </div>\n </div>\n }\n }\n </div>\n\n <!-- \u2550\u2550\u2550\u2550\u2550\u2550 SLIDE-IN FORM OVERLAY \u2550\u2550\u2550\u2550\u2550\u2550 -->\n @if (FormMode !== 'none') {\n <div class=\"at-slide-overlay\" (click)=\"CloseForm()\"></div>\n <div class=\"at-slide-panel\">\n <div class=\"at-slide-header\">\n <h3>\n @if (FormMode === 'add-source') { Add Content Source }\n @else if (FormMode === 'edit-source') { Edit Content Source }\n @else if (FormMode === 'add-type') { Add Content Type }\n @else if (FormMode === 'edit-type') { Edit Content Type }\n </h3>\n <button class=\"at-slide-close\" (click)=\"CloseForm()\"><i class=\"fa-solid fa-times\"></i></button>\n </div>\n <div class=\"at-slide-body\">\n\n <!-- Source form -->\n @if (FormMode === 'add-source' || FormMode === 'edit-source') {\n <div class=\"at-form-group\">\n <label class=\"at-form-label\">Name</label>\n <input type=\"text\" class=\"at-form-input\" [(ngModel)]=\"FormSourceName\" placeholder=\"Source name\">\n </div>\n <div class=\"at-form-group\">\n <label class=\"at-form-label\">Source Type</label>\n <select class=\"at-form-select\" [(ngModel)]=\"FormSourceTypeID\">\n <option value=\"\">Select source type...</option>\n @for (opt of SourceTypeOptions; track opt.ID) {\n <option [value]=\"opt.ID\">{{ opt.Name }}</option>\n }\n </select>\n </div>\n <div class=\"at-form-group\">\n <label class=\"at-form-label\">Content Type</label>\n <select class=\"at-form-select\" [(ngModel)]=\"FormContentTypeID\">\n <option value=\"\">Select content type...</option>\n @for (opt of ContentTypeOptions; track opt.ID) {\n <option [value]=\"opt.ID\">{{ opt.Name }}</option>\n }\n </select>\n </div>\n <div class=\"at-form-group\">\n <label class=\"at-form-label\">File Type</label>\n <select class=\"at-form-select\" [(ngModel)]=\"FormFileTypeID\">\n <option value=\"\">Select file type...</option>\n @for (opt of FileTypeOptions; track opt.ID) {\n <option [value]=\"opt.ID\">{{ opt.Name }}</option>\n }\n </select>\n </div>\n <div class=\"at-form-group\">\n <label class=\"at-form-label\">URL</label>\n <input type=\"text\" class=\"at-form-input\" [(ngModel)]=\"FormSourceURL\" placeholder=\"https://...\">\n </div>\n <div class=\"at-form-group\">\n <label class=\"at-form-label\">Embedding Model Override</label>\n <mj-tree-dropdown\n [BranchConfig]=\"AIModelVendorBranch\"\n [LeafConfig]=\"EmbeddingModelsLeaf\"\n SelectionMode=\"single\"\n SelectableTypes=\"leaf\"\n Placeholder=\"Use system default\"\n [Clearable]=\"true\"\n [Value]=\"ToCompositeKey(FormSourceEmbeddingModelID)\"\n (ValueChange)=\"FormSourceEmbeddingModelID = FromCompositeKey($event)\">\n </mj-tree-dropdown>\n <span class=\"at-form-hint\">Overrides Content Type default</span>\n </div>\n <div class=\"at-form-group\">\n <label class=\"at-form-label\">Vector Index Override</label>\n <select class=\"at-form-select\" [(ngModel)]=\"FormSourceVectorIndexID\">\n <option value=\"\">Use system default</option>\n @for (opt of VectorIndexOptions; track opt.ID) {\n <option [value]=\"opt.ID\">{{ opt.Name }}</option>\n }\n </select>\n <span class=\"at-form-hint\">Overrides Content Type default</span>\n </div>\n <div class=\"at-form-actions\">\n <button class=\"at-action-btn at-primary-btn\" (click)=\"SaveSource()\" [disabled]=\"FormSaving\">\n @if (FormSaving) { <i class=\"fa-solid fa-spinner fa-spin\"></i> Saving... }\n @else { <i class=\"fa-solid fa-check\"></i> Save }\n </button>\n <button class=\"at-action-btn at-secondary-btn\" (click)=\"CloseForm()\">Cancel</button>\n </div>\n }\n\n <!-- Content Type form -->\n @if (FormMode === 'add-type' || FormMode === 'edit-type') {\n <div class=\"at-form-group\">\n <label class=\"at-form-label\">Name</label>\n <input type=\"text\" class=\"at-form-input\" [(ngModel)]=\"FormTypeName\" placeholder=\"Content type name\">\n </div>\n <div class=\"at-form-group\">\n <label class=\"at-form-label\">Description</label>\n <textarea class=\"at-form-textarea\" [(ngModel)]=\"FormTypeDescription\" rows=\"3\" placeholder=\"Description...\"></textarea>\n </div>\n <div class=\"at-form-group\">\n <label class=\"at-form-label\">AI Model (for tagging)</label>\n <mj-tree-dropdown\n [BranchConfig]=\"AIModelVendorBranch\"\n [LeafConfig]=\"AllModelsLeaf\"\n SelectionMode=\"single\"\n SelectableTypes=\"leaf\"\n Placeholder=\"Select AI model...\"\n [Clearable]=\"true\"\n [Value]=\"ToCompositeKey(FormTypeAIModelID)\"\n (ValueChange)=\"FormTypeAIModelID = FromCompositeKey($event)\">\n </mj-tree-dropdown>\n </div>\n <div class=\"at-form-row\">\n <div class=\"at-form-group\" style=\"flex: 1;\">\n <label class=\"at-form-label\">Min Tags</label>\n <input type=\"number\" class=\"at-form-input\" [(ngModel)]=\"FormTypeMinTags\" min=\"0\">\n </div>\n <div class=\"at-form-group\" style=\"flex: 1;\">\n <label class=\"at-form-label\">Max Tags</label>\n <input type=\"number\" class=\"at-form-input\" [(ngModel)]=\"FormTypeMaxTags\" min=\"1\">\n </div>\n </div>\n <div class=\"at-form-group\">\n <label class=\"at-form-label\">Embedding Model</label>\n <mj-tree-dropdown\n [BranchConfig]=\"AIModelVendorBranch\"\n [LeafConfig]=\"EmbeddingModelsLeaf\"\n SelectionMode=\"single\"\n SelectableTypes=\"leaf\"\n Placeholder=\"Use system default\"\n [Clearable]=\"true\"\n [Value]=\"ToCompositeKey(FormTypeEmbeddingModelID)\"\n (ValueChange)=\"FormTypeEmbeddingModelID = FromCompositeKey($event)\">\n </mj-tree-dropdown>\n </div>\n <div class=\"at-form-group\">\n <label class=\"at-form-label\">Vector Index</label>\n <select class=\"at-form-select\" [(ngModel)]=\"FormTypeVectorIndexID\">\n <option value=\"\">Use system default</option>\n @for (opt of VectorIndexOptions; track opt.ID) {\n <option [value]=\"opt.ID\">{{ opt.Name }}</option>\n }\n </select>\n </div>\n <div class=\"at-form-actions\">\n <button class=\"at-action-btn at-primary-btn\" (click)=\"SaveContentType()\" [disabled]=\"FormSaving\">\n @if (FormSaving) { <i class=\"fa-solid fa-spinner fa-spin\"></i> Saving... }\n @else { <i class=\"fa-solid fa-check\"></i> Save }\n </button>\n <button class=\"at-action-btn at-secondary-btn\" (click)=\"CloseForm()\">Cancel</button>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- \u2550\u2550\u2550\u2550\u2550\u2550 ITEM DETAIL SLIDE-IN \u2550\u2550\u2550\u2550\u2550\u2550 -->\n @if (ShowItemDetail && SelectedFeedItem) {\n <div class=\"at-slide-overlay\" (click)=\"CloseItemDetail()\"></div>\n <div class=\"at-slide-panel at-detail-panel\">\n <div class=\"at-slide-header\">\n <h3><i class=\"fa-solid fa-file-lines\"></i> Content Item</h3>\n <button class=\"at-slide-close\" (click)=\"CloseItemDetail()\"><i class=\"fa-solid fa-times\"></i></button>\n </div>\n <div class=\"at-slide-body\">\n <!-- Header -->\n <div class=\"at-detail-item-header\">\n <h4 class=\"at-detail-item-name\">{{ SelectedFeedItem.Name }}</h4>\n <div class=\"at-detail-badges\">\n <span class=\"at-detail-badge at-detail-badge-source\">{{ SelectedFeedItem.SourceName }}</span>\n <span class=\"at-detail-badge at-detail-badge-type\">{{ SelectedFeedItem.ContentTypeName }}</span>\n @if (SelectedFeedItem.FileTypeName) {\n <span class=\"at-detail-badge at-detail-badge-file\"><i class=\"fa-solid fa-file\"></i> {{ SelectedFeedItem.FileTypeName }}</span>\n }\n </div>\n </div>\n\n <!-- URL -->\n @if (SelectedFeedItem.URL) {\n <div class=\"at-detail-section\">\n <div class=\"at-detail-section-label\">URL</div>\n <a [href]=\"SelectedFeedItem.URL\" target=\"_blank\" class=\"at-detail-link\">\n {{ SelectedFeedItem.URL }}\n <i class=\"fa-solid fa-external-link-alt\" style=\"font-size: 0.65rem; margin-left: 4px;\"></i>\n </a>\n </div>\n }\n\n <!-- Text Preview -->\n @if (SelectedFeedItem.TextContent) {\n <div class=\"at-detail-section\">\n <div class=\"at-detail-section-label\">Content Preview</div>\n <div class=\"at-detail-text-preview\">{{ SelectedFeedItem.TextContent }}</div>\n </div>\n }\n\n <!-- Tags -->\n @if (SelectedFeedItem.Tags.length > 0) {\n <div class=\"at-detail-section\">\n <div class=\"at-detail-section-label\">Tags ({{ SelectedFeedItem.Tags.length }})</div>\n <div class=\"at-detail-tags\">\n @for (tag of SelectedFeedItem.Tags; track tag) {\n <span class=\"at-tag-pill\">{{ tag }}</span>\n }\n </div>\n </div>\n }\n\n <!-- Metadata -->\n <div class=\"at-detail-section\">\n <div class=\"at-detail-section-label\">Metadata</div>\n <div class=\"at-detail-meta-grid\">\n @if (SelectedFeedItem.Checksum) {\n <div class=\"at-detail-meta-row\">\n <span class=\"at-detail-meta-key\">Checksum</span>\n <span class=\"at-detail-meta-value at-detail-meta-mono\">{{ SelectedFeedItem.Checksum }}</span>\n </div>\n }\n <div class=\"at-detail-meta-row\">\n <span class=\"at-detail-meta-key\">Created</span>\n <span class=\"at-detail-meta-value\">{{ SelectedFeedItem.CreatedAt }}</span>\n </div>\n <div class=\"at-detail-meta-row\">\n <span class=\"at-detail-meta-key\">Updated</span>\n <span class=\"at-detail-meta-value\">{{ SelectedFeedItem.UpdatedAt }}</span>\n </div>\n </div>\n </div>\n\n <!-- Actions -->\n <div class=\"at-detail-actions\">\n <button class=\"at-action-btn at-primary-btn\" (click)=\"OpenRecordFromItem(SelectedFeedItem)\">\n <i class=\"fa-solid fa-external-link-alt\"></i> Open Record\n </button>\n <button class=\"at-action-btn at-secondary-btn\" disabled>\n <i class=\"fa-solid fa-magnifying-glass\"></i> See Similar Items\n </button>\n </div>\n </div>\n </div>\n }\n\n <!-- \u2550\u2550\u2550\u2550\u2550\u2550 SOURCE DETAIL SLIDE-IN \u2550\u2550\u2550\u2550\u2550\u2550 -->\n @if (ShowSourceDetail) {\n <div class=\"at-slide-overlay\" (click)=\"CloseSourceDetail()\"></div>\n <div class=\"at-slide-panel at-detail-panel\">\n <div class=\"at-slide-header\">\n <h3><i class=\"fa-solid fa-database\"></i> Source Detail</h3>\n <button class=\"at-slide-close\" (click)=\"CloseSourceDetail()\"><i class=\"fa-solid fa-times\"></i></button>\n </div>\n <div class=\"at-slide-body\">\n @if (SourceDetailLoading) {\n <div class=\"at-loading-overlay\">\n <mj-loading text=\"Loading source details...\"></mj-loading>\n </div>\n }\n @if (!SourceDetailLoading && SelectedSource) {\n <!-- Source Header -->\n <div class=\"at-detail-source-header\">\n <div class=\"at-source-card-icon\"><i [class]=\"SelectedSource.Icon\"></i></div>\n <div>\n <h4 class=\"at-detail-item-name\">{{ SelectedSource.Name }}</h4>\n <div class=\"at-detail-badges\">\n <span class=\"at-detail-badge at-detail-badge-type\">{{ SelectedSource.SourceTypeName }}</span>\n <span class=\"at-detail-badge\" [class]=\"'at-detail-badge-status-' + SelectedSource.StatusClass\">\n {{ SelectedSource.StatusLabel }}\n </span>\n </div>\n </div>\n </div>\n\n <!-- Configuration -->\n <div class=\"at-detail-section\">\n <div class=\"at-detail-section-label\">Configuration</div>\n <div class=\"at-detail-meta-grid\">\n @if (SelectedSource.URL) {\n <div class=\"at-detail-meta-row\">\n <span class=\"at-detail-meta-key\">URL</span>\n <a [href]=\"SelectedSource.URL\" target=\"_blank\" class=\"at-detail-link at-detail-meta-value\">{{ SelectedSource.URL }}</a>\n </div>\n }\n <div class=\"at-detail-meta-row\">\n <span class=\"at-detail-meta-key\">Content Type</span>\n <span class=\"at-detail-meta-value\">{{ SelectedSource.ContentTypeName }}</span>\n </div>\n <div class=\"at-detail-meta-row\">\n <span class=\"at-detail-meta-key\">File Type</span>\n <span class=\"at-detail-meta-value\">{{ SelectedSource.FileTypeName }}</span>\n </div>\n <div class=\"at-detail-meta-row\">\n <span class=\"at-detail-meta-key\">Embedding Model</span>\n <span class=\"at-detail-meta-value\">{{ SelectedSource.EmbeddingModelName }}</span>\n </div>\n <div class=\"at-detail-meta-row\">\n <span class=\"at-detail-meta-key\">Vector Index</span>\n <span class=\"at-detail-meta-value\">{{ SelectedSource.VectorIndexName }}</span>\n </div>\n </div>\n </div>\n\n <!-- Stats -->\n <div class=\"at-detail-section\">\n <div class=\"at-detail-section-label\">Statistics</div>\n <div class=\"at-detail-stats-strip\">\n <div class=\"at-detail-stat\">\n <div class=\"at-detail-stat-value\">{{ formatNumber(SelectedSource.ItemCount) }}</div>\n <div class=\"at-detail-stat-label\">Items</div>\n </div>\n <div class=\"at-detail-stat\">\n <div class=\"at-detail-stat-value\">{{ formatNumber(SelectedSource.TagCount) }}</div>\n <div class=\"at-detail-stat-label\">Tags</div>\n </div>\n <div class=\"at-detail-stat\">\n <div class=\"at-detail-stat-value\">{{ SelectedSource.AvgTags }}</div>\n <div class=\"at-detail-stat-label\">Avg Tags</div>\n </div>\n <div class=\"at-detail-stat\">\n <div class=\"at-detail-stat-value\">{{ SelectedSource.LastRunAgo }}</div>\n <div class=\"at-detail-stat-label\">Last Run</div>\n </div>\n <div class=\"at-detail-stat\">\n <div class=\"at-detail-stat-value\" [class.at-kpi-error-value]=\"SelectedSource.ErrorCount > 0\">{{ SelectedSource.ErrorCount }}</div>\n <div class=\"at-detail-stat-label\">Errors</div>\n </div>\n </div>\n </div>\n\n <!-- Content Library -->\n <div class=\"at-detail-section\">\n <div class=\"at-detail-section-label\">Content Library ({{ SelectedSource.ContentItems.length }})</div>\n <div class=\"at-detail-content-list\">\n @if (SelectedSource.ContentItems.length === 0) {\n <div class=\"at-empty-state\" style=\"padding: 16px;\">\n <p>No content items yet.</p>\n </div>\n }\n @for (ci of SelectedSource.ContentItems; track ci.ID) {\n <div class=\"at-detail-content-item\" (click)=\"OpenContentItemDetail(ci)\">\n <div class=\"at-feed-status-dot\" [class]=\"ci.StatusDot\"></div>\n <span class=\"at-detail-content-item-name\">{{ ci.Name }}</span>\n <span class=\"at-detail-content-item-tags\">{{ ci.TagCount }} tags</span>\n <span class=\"at-detail-content-item-time\">{{ ci.UpdatedAt }}</span>\n </div>\n }\n </div>\n </div>\n\n <!-- Run History -->\n @if (SelectedSource.RunHistory.length > 0) {\n <div class=\"at-detail-section\">\n <div class=\"at-detail-section-label\">Recent Runs</div>\n <div class=\"at-detail-run-history\">\n @for (run of SelectedSource.RunHistory; track run.ID) {\n <div class=\"at-detail-run-row\">\n <span class=\"at-run-status-badge\" [class]=\"run.StatusClass\">{{ run.Status }}</span>\n <span class=\"at-detail-run-time\">{{ run.StartedDisplay }}</span>\n <span class=\"at-detail-run-duration\">{{ run.Duration }}</span>\n <span class=\"at-detail-run-items\">{{ run.Items }} items</span>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Actions -->\n <div class=\"at-detail-actions\">\n <button class=\"at-action-btn at-primary-btn\" (click)=\"OpenEditSourceFromDetail()\">\n <i class=\"fa-solid fa-pen\"></i> Edit\n </button>\n <button class=\"at-action-btn at-secondary-btn\" (click)=\"RunSourceFromDetail()\">\n <i class=\"fa-solid fa-play\"></i> Run Now\n </button>\n <button class=\"at-action-btn at-secondary-btn at-source-delete-btn\" (click)=\"DeleteSourceFromDetail()\">\n <i class=\"fa-solid fa-trash\"></i> Delete\n </button>\n </div>\n }\n </div>\n </div>\n }\n</div>\n", styles: ["/* ============================================================\n Content Autotagging Dashboard\n All colors use MJ design tokens \u2014 no hardcoded hex values.\n All classes prefixed with at- to prevent leaking (ViewEncapsulation.None).\n ============================================================ */\n\n/* \u2500\u2500 Root layout \u2500\u2500 */\n\n.at-dashboard {\n display: flex;\n height: 100%;\n overflow: hidden;\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550 LEFT NAV \u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.at-left-nav {\n width: 220px;\n background: var(--mj-bg-surface);\n border-right: 1px solid var(--mj-border-default);\n display: flex;\n flex-direction: column;\n flex-shrink: 0;\n}\n\n.at-left-nav-header {\n padding: 16px 16px 12px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.at-left-nav-header h2 {\n font-size: 0.95rem;\n font-weight: 700;\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 0;\n color: var(--mj-text-primary);\n}\n\n.at-left-nav-header h2 i {\n color: var(--mj-brand-primary);\n}\n\n.at-left-nav-items {\n flex: 1;\n padding: 8px;\n overflow-y: auto;\n}\n\n.at-nav-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 12px;\n border-radius: 8px;\n font-size: 0.82rem;\n font-weight: 500;\n color: var(--mj-text-muted);\n cursor: pointer;\n transition: all 0.12s ease;\n margin-bottom: 2px;\n}\n\n.at-nav-item:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-secondary);\n}\n\n.at-nav-item.active {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n.at-nav-item i {\n width: 18px;\n text-align: center;\n font-size: 0.8rem;\n}\n\n.at-nav-badge {\n margin-left: auto;\n background: var(--mj-bg-surface-sunken);\n padding: 1px 7px;\n border-radius: 10px;\n font-size: 0.65rem;\n font-weight: 600;\n color: var(--mj-text-muted);\n}\n\n.at-nav-item.active .at-nav-badge {\n background: color-mix(in srgb, var(--mj-brand-primary) 18%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.at-nav-badge-live {\n background: var(--mj-status-success-bg) !important;\n color: var(--mj-status-success-text) !important;\n}\n\n.at-nav-divider {\n height: 1px;\n background: var(--mj-border-subtle);\n margin: 8px 12px;\n}\n\n.at-left-nav-footer {\n padding: 12px;\n border-top: 1px solid var(--mj-border-subtle);\n}\n\n.at-run-pipeline-btn {\n width: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 10px;\n border: none;\n border-radius: 8px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 0.82rem;\n font-weight: 600;\n cursor: pointer;\n transition: background 0.15s ease;\n}\n\n.at-run-pipeline-btn:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n.at-run-pipeline-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550 MAIN CONTENT AREA \u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.at-main-area {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n.at-loading-overlay {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n}\n\n.at-page-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 14px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.at-page-title {\n font-size: 1rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.at-page-subtitle {\n font-size: 0.72rem;\n color: var(--mj-text-muted);\n margin-top: 2px;\n}\n\n.at-page-actions {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.at-page-body {\n flex: 1;\n overflow-y: auto;\n padding: 16px 20px;\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550 SHARED COMPONENTS \u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.at-action-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 7px 14px;\n border: 1px solid;\n border-radius: 7px;\n cursor: pointer;\n font-size: 0.78rem;\n font-weight: 500;\n transition: all 0.15s ease;\n}\n\n.at-primary-btn {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-color: var(--mj-brand-primary);\n}\n\n.at-primary-btn:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n.at-primary-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.at-secondary-btn {\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n border-color: var(--mj-border-default);\n}\n\n.at-secondary-btn:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.at-card {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 10px;\n overflow: hidden;\n}\n\n.at-card-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.at-card-title {\n font-size: 0.82rem;\n font-weight: 600;\n display: flex;\n align-items: center;\n gap: 6px;\n color: var(--mj-text-primary);\n}\n\n.at-card-title i {\n color: var(--mj-brand-primary);\n font-size: 0.75rem;\n}\n\n.at-card-body {\n padding: 0;\n}\n\n.at-empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 32px 16px;\n color: var(--mj-text-disabled);\n}\n\n.at-empty-state i {\n font-size: 28px;\n}\n\n.at-empty-state p {\n margin: 0;\n font-size: 13px;\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550 KPI STRIP \u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.at-kpi-strip {\n display: flex;\n gap: 12px;\n margin-bottom: 16px;\n}\n\n.at-kpi-card {\n flex: 1;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 10px;\n padding: 14px 16px;\n}\n\n.at-kpi-value {\n font-size: 1.4rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.at-kpi-error-value {\n color: var(--mj-status-error-text);\n}\n\n.at-kpi-label {\n font-size: 0.72rem;\n color: var(--mj-text-muted);\n margin-top: 2px;\n}\n\n.at-kpi-trend {\n font-size: 0.68rem;\n margin-top: 4px;\n display: flex;\n align-items: center;\n gap: 4px;\n color: var(--mj-text-muted);\n}\n\n.at-kpi-trend.up {\n color: var(--mj-status-success-text);\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550 PIPELINE TAB \u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.at-pipeline-layout {\n display: flex;\n gap: 16px;\n}\n\n.at-pipeline-center {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 12px;\n min-width: 0;\n}\n\n.at-pipeline-right {\n width: 320px;\n flex-shrink: 0;\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n/* Pipeline Stages */\n\n.at-pipeline-stages {\n display: flex;\n gap: 0;\n align-items: center;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 10px;\n padding: 12px 16px;\n}\n\n.at-pipeline-stage {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n}\n\n.at-pipeline-stage-icon {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 50%;\n font-size: 0.85rem;\n}\n\n.stage-idle .at-pipeline-stage-icon {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n}\n\n.stage-active .at-pipeline-stage-icon {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n animation: at-pulse 1.5s infinite;\n}\n\n.stage-complete .at-pipeline-stage-icon {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success-text);\n}\n\n@keyframes at-pulse {\n 0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--mj-brand-primary) 30%, transparent); }\n 50% { box-shadow: 0 0 0 6px color-mix(in srgb, var(--mj-brand-primary) 0%, transparent); }\n}\n\n.at-pipeline-stage-name {\n font-size: 0.68rem;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.at-pipeline-stage-count {\n font-size: 0.6rem;\n color: var(--mj-text-muted);\n}\n\n.at-pipeline-arrow {\n width: 24px;\n text-align: center;\n color: var(--mj-text-disabled);\n font-size: 0.6rem;\n}\n\n/* Progress section */\n\n.at-progress-section {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 8px;\n padding: 10px 16px;\n}\n\n.at-progress-header {\n display: flex;\n justify-content: space-between;\n font-size: 0.75rem;\n margin-bottom: 4px;\n}\n\n.at-progress-stage-label {\n color: var(--mj-text-secondary);\n font-weight: 500;\n}\n\n.at-progress-pct {\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n.at-progress-bar {\n height: 4px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 2px;\n overflow: hidden;\n}\n\n.at-progress-fill {\n height: 100%;\n background: var(--mj-brand-primary);\n border-radius: 2px;\n transition: width 0.3s ease;\n}\n\n.at-progress-current {\n font-size: 0.68rem;\n color: var(--mj-text-muted);\n margin-top: 4px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* Feed items */\n\n.at-feed-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 14px;\n border-bottom: 1px solid var(--mj-border-subtle);\n font-size: 0.78rem;\n}\n\n.at-feed-item:last-child {\n border-bottom: none;\n}\n\n.at-feed-status-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n}\n\n.at-feed-status-dot.complete {\n background: var(--mj-status-success);\n}\n\n.at-feed-status-dot.processing {\n background: var(--mj-brand-primary);\n animation: at-pulse 1.5s infinite;\n}\n\n.at-feed-status-dot.error {\n background: var(--mj-status-error);\n}\n\n.at-feed-item-name {\n flex: 1;\n font-weight: 500;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: var(--mj-text-primary);\n}\n\n.at-feed-item-source {\n color: var(--mj-text-muted);\n font-size: 0.7rem;\n min-width: 100px;\n}\n\n.at-feed-item-tags {\n display: flex;\n gap: 4px;\n}\n\n.at-feed-tag {\n padding: 1px 6px;\n border-radius: 3px;\n font-size: 0.62rem;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.at-feed-item-time {\n color: var(--mj-text-muted);\n font-size: 0.68rem;\n white-space: nowrap;\n min-width: 60px;\n text-align: right;\n}\n\n/* Source mini cards (right panel) */\n\n.at-source-mini {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 14px;\n border-bottom: 1px solid var(--mj-border-subtle);\n cursor: pointer;\n transition: background 0.1s ease;\n}\n\n.at-source-mini:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.at-source-mini:last-child {\n border-bottom: none;\n}\n\n.at-source-mini-icon {\n width: 28px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 6px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 0.72rem;\n flex-shrink: 0;\n}\n\n.at-source-mini-info {\n flex: 1;\n min-width: 0;\n}\n\n.at-source-mini-name {\n font-size: 0.78rem;\n font-weight: 600;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: var(--mj-text-primary);\n}\n\n.at-source-mini-meta {\n font-size: 0.65rem;\n color: var(--mj-text-muted);\n}\n\n.at-source-mini-status {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n}\n\n.at-source-mini-status.active {\n background: var(--mj-status-success);\n}\n\n.at-source-mini-status.error {\n background: var(--mj-status-error);\n}\n\n.at-source-mini-status.inactive {\n background: var(--mj-text-disabled);\n}\n\n/* Tag cloud card */\n\n.at-tag-cloud-card {\n padding: 16px;\n}\n\n.at-tag-cloud {\n display: flex;\n flex-wrap: wrap;\n gap: 5px;\n}\n\n.at-tag-pill {\n padding: 4px 12px;\n border-radius: 14px;\n font-size: 0.72rem;\n font-weight: 500;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n color: var(--mj-text-secondary);\n border: 1px solid var(--mj-border-subtle);\n cursor: pointer;\n transition: all 0.12s ease;\n}\n\n.at-tag-pill:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n.at-tag-pill.large {\n font-size: 0.85rem;\n padding: 5px 14px;\n}\n\n.at-tag-pill.small {\n font-size: 0.65rem;\n padding: 3px 8px;\n color: var(--mj-text-muted);\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550 SOURCES TAB \u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.at-sources-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));\n gap: 12px;\n}\n\n.at-source-card-full {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 10px;\n padding: 16px;\n transition: border-color 0.15s ease;\n}\n\n.at-source-card-full:hover {\n border-color: var(--mj-border-default);\n}\n\n.at-source-card-header {\n display: flex;\n align-items: center;\n gap: 10px;\n margin-bottom: 12px;\n}\n\n.at-source-card-icon {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 10px;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 1rem;\n flex-shrink: 0;\n}\n\n.at-source-card-title {\n font-size: 0.9rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.at-source-card-type {\n font-size: 0.68rem;\n color: var(--mj-text-muted);\n}\n\n.at-source-card-status {\n margin-left: auto;\n display: flex;\n align-items: center;\n gap: 5px;\n font-size: 0.7rem;\n font-weight: 500;\n}\n\n.at-source-card-status.active {\n color: var(--mj-status-success-text);\n}\n\n.at-source-card-status.error {\n color: var(--mj-status-error-text);\n}\n\n.at-source-card-status.inactive {\n color: var(--mj-text-disabled);\n}\n\n.at-source-card-url {\n font-size: 0.7rem;\n color: var(--mj-brand-primary);\n margin-bottom: 10px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.at-source-card-stats {\n display: flex;\n gap: 16px;\n padding-top: 10px;\n border-top: 1px solid var(--mj-border-subtle);\n}\n\n.at-source-stat {\n display: flex;\n flex-direction: column;\n}\n\n.at-source-stat-value {\n font-size: 1rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.at-source-stat-label {\n font-size: 0.65rem;\n color: var(--mj-text-muted);\n}\n\n.at-source-card-actions {\n display: flex;\n gap: 6px;\n margin-top: 10px;\n}\n\n.at-source-action-btn {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n padding: 6px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 0.7rem;\n cursor: pointer;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n transition: all 0.12s ease;\n}\n\n.at-source-action-btn:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n.at-source-delete-btn:hover {\n border-color: var(--mj-status-error);\n color: var(--mj-status-error-text);\n}\n\n.at-add-source-card {\n background: none;\n border: 2px dashed var(--mj-border-default);\n border-radius: 10px;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 40px;\n cursor: pointer;\n transition: all 0.15s ease;\n color: var(--mj-text-muted);\n min-height: 200px;\n}\n\n.at-add-source-card:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n.at-add-source-card i {\n font-size: 1.5rem;\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550 CONTENT TYPES TAB \u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.at-ct-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));\n gap: 12px;\n}\n\n.at-ct-card {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 10px;\n padding: 16px;\n}\n\n.at-ct-card-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 10px;\n}\n\n.at-ct-card-name {\n font-size: 0.9rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.at-ct-card-model {\n font-size: 0.68rem;\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n padding: 2px 8px;\n border-radius: 10px;\n}\n\n.at-ct-field {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 6px 0;\n border-bottom: 1px solid var(--mj-border-subtle);\n font-size: 0.78rem;\n}\n\n.at-ct-field:last-child {\n border-bottom: none;\n}\n\n.at-ct-field-label {\n color: var(--mj-text-muted);\n}\n\n.at-ct-field-value {\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.at-ct-tag-range {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 8px;\n padding: 8px 10px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 6px;\n font-size: 0.75rem;\n color: var(--mj-text-primary);\n}\n\n.at-ct-tag-range i {\n color: var(--mj-brand-primary);\n}\n\n.at-ct-tag-range-bar {\n flex: 1;\n height: 6px;\n background: var(--mj-bg-surface);\n border-radius: 3px;\n position: relative;\n}\n\n.at-ct-tag-range-fill {\n position: absolute;\n height: 100%;\n background: var(--mj-brand-primary);\n border-radius: 3px;\n}\n\n.at-ct-range-suffix {\n color: var(--mj-text-muted);\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550 TAG LIBRARY TAB \u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.at-tag-lib-layout {\n display: flex;\n gap: 16px;\n}\n\n.at-tag-lib-main {\n flex: 1;\n}\n\n.at-tag-lib-sidebar {\n width: 280px;\n flex-shrink: 0;\n}\n\n.at-tag-table {\n width: 100%;\n border-collapse: collapse;\n}\n\n.at-tag-table th {\n text-align: left;\n padding: 8px 12px;\n font-size: 0.7rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--mj-text-muted);\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-elevated);\n position: sticky;\n top: 0;\n z-index: 1;\n}\n\n.at-tag-table td {\n padding: 10px 12px;\n font-size: 0.8rem;\n border-bottom: 1px solid var(--mj-border-subtle);\n color: var(--mj-text-primary);\n}\n\n.at-tag-table tr:hover td {\n background: var(--mj-bg-surface-hover);\n}\n\n.at-tag-name-cell {\n font-weight: 600;\n}\n\n.at-tag-bar {\n width: 80px;\n height: 6px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 3px;\n display: inline-block;\n vertical-align: middle;\n}\n\n.at-tag-bar-fill {\n height: 100%;\n background: var(--mj-brand-primary);\n border-radius: 3px;\n}\n\n/* Weight indicator in tag table */\n.at-weight-indicator {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.at-weight-bar {\n width: 50px;\n height: 6px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 3px;\n overflow: hidden;\n}\n\n.at-weight-bar-fill {\n height: 100%;\n border-radius: 3px;\n transition: width 0.2s ease;\n}\n\n.at-weight-bar-fill.at-weight-high {\n background: var(--mj-status-success);\n}\n\n.at-weight-bar-fill.at-weight-medium {\n background: var(--mj-status-warning);\n}\n\n.at-weight-bar-fill.at-weight-low {\n background: var(--mj-status-error);\n}\n\n.at-weight-value {\n font-size: 0.7rem;\n font-weight: 600;\n color: var(--mj-text-muted);\n min-width: 28px;\n}\n\n.at-tags-by-source {\n font-size: 0.78rem;\n}\n\n.at-tag-source-row {\n display: flex;\n justify-content: space-between;\n padding: 5px 0;\n border-bottom: 1px solid var(--mj-border-subtle);\n color: var(--mj-text-primary);\n}\n\n.at-tag-source-row:last-child {\n border-bottom: none;\n}\n\n.at-search-input {\n padding: 7px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 7px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 0.8rem;\n width: 200px;\n outline: none;\n}\n\n.at-search-input::placeholder {\n color: var(--mj-text-disabled);\n}\n\n.at-search-input:focus {\n border-color: var(--mj-brand-primary);\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550 RUN HISTORY TAB \u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.at-run-table {\n width: 100%;\n border-collapse: collapse;\n}\n\n.at-run-table th {\n text-align: left;\n padding: 10px 14px;\n font-size: 0.7rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--mj-text-muted);\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-elevated);\n position: sticky;\n top: 0;\n z-index: 1;\n}\n\n.at-run-table td {\n padding: 12px 14px;\n font-size: 0.8rem;\n border-bottom: 1px solid var(--mj-border-subtle);\n color: var(--mj-text-primary);\n}\n\n.at-run-table tr:hover td {\n background: var(--mj-bg-surface-hover);\n cursor: pointer;\n}\n\n.at-run-status-badge {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 2px 10px;\n border-radius: 10px;\n font-size: 0.7rem;\n font-weight: 600;\n}\n\n.at-run-status-badge.complete {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success-text);\n}\n\n.at-run-status-badge.failed {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error-text);\n}\n\n.at-run-status-badge.running {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.at-run-duration {\n color: var(--mj-text-muted);\n font-size: 0.75rem;\n}\n\n.at-run-source-name {\n font-weight: 500;\n}\n\n.at-run-error-text {\n color: var(--mj-status-error-text);\n}\n\n.at-filter-select {\n padding: 7px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 7px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 0.78rem;\n outline: none;\n}\n\n.at-filter-select:focus {\n border-color: var(--mj-brand-primary);\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550 SLIDE-IN FORM PANEL \u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.at-slide-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-overlay);\n z-index: 1000;\n}\n\n.at-slide-panel {\n position: fixed;\n right: 0;\n top: 0;\n bottom: 0;\n width: 420px;\n max-width: 100vw;\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n z-index: 1001;\n display: flex;\n flex-direction: column;\n box-shadow: -4px 0 24px color-mix(in srgb, var(--mj-text-primary) 15%, transparent);\n}\n\n.at-slide-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.at-slide-header h3 {\n margin: 0;\n font-size: 1rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.at-slide-close {\n background: none;\n border: none;\n font-size: 1.1rem;\n color: var(--mj-text-muted);\n cursor: pointer;\n padding: 4px;\n}\n\n.at-slide-close:hover {\n color: var(--mj-text-primary);\n}\n\n.at-slide-body {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n}\n\n.at-form-group {\n margin-bottom: 16px;\n}\n\n.at-form-label {\n display: block;\n font-size: 0.78rem;\n font-weight: 600;\n color: var(--mj-text-secondary);\n margin-bottom: 6px;\n}\n\n.at-form-input,\n.at-form-select,\n.at-form-textarea {\n width: 100%;\n padding: 9px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 7px;\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-primary);\n font-size: 0.82rem;\n outline: none;\n font-family: inherit;\n}\n\n.at-form-input:focus,\n.at-form-select:focus,\n.at-form-textarea:focus {\n border-color: var(--mj-brand-primary);\n}\n\n.at-form-input::placeholder,\n.at-form-textarea::placeholder {\n color: var(--mj-text-disabled);\n}\n\n.at-form-textarea {\n resize: vertical;\n}\n\n.at-form-row {\n display: flex;\n gap: 12px;\n}\n\n.at-form-actions {\n display: flex;\n gap: 8px;\n margin-top: 24px;\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550 RESPONSIVE \u2550\u2550\u2550\u2550\u2550\u2550 */\n\n@media (max-width: 1100px) {\n .at-pipeline-layout {\n flex-direction: column;\n }\n\n .at-pipeline-right {\n width: 100%;\n flex-direction: row;\n }\n\n .at-tag-lib-layout {\n flex-direction: column;\n }\n\n .at-tag-lib-sidebar {\n width: 100%;\n }\n}\n\n@media (max-width: 768px) {\n .at-left-nav {\n width: 180px;\n }\n\n .at-kpi-strip {\n flex-wrap: wrap;\n }\n\n .at-kpi-card {\n min-width: 140px;\n }\n\n .at-sources-grid {\n grid-template-columns: 1fr;\n }\n\n .at-ct-grid {\n grid-template-columns: 1fr;\n }\n\n .at-slide-panel {\n width: 100vw;\n }\n}\n\n@media (max-width: 480px) {\n .at-left-nav {\n width: 56px;\n }\n\n .at-left-nav-header h2 {\n font-size: 0;\n }\n\n .at-left-nav-header h2 i {\n font-size: 1rem;\n }\n\n .at-nav-item {\n justify-content: center;\n padding: 10px;\n font-size: 0;\n }\n\n .at-nav-item i {\n font-size: 1rem;\n }\n\n .at-nav-badge {\n display: none;\n }\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n Slide-in Form Panel\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.at-slide-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.35);\n z-index: 9999;\n animation: at-fade-in 0.2s ease;\n}\n\n@keyframes at-fade-in { from { opacity: 0; } to { opacity: 1; } }\n\n.at-slide-panel {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n width: 420px;\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n box-shadow: -8px 0 40px rgba(0, 0, 0, 0.4);\n z-index: 10000;\n display: flex;\n flex-direction: column;\n animation: at-slide-in 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n@keyframes at-slide-in { from { transform: translateX(100%); } to { transform: translateX(0); } }\n\n.at-slide-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.at-slide-header h3 {\n font-size: 1rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.at-slide-close {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n font-size: 0.85rem;\n transition: all 0.15s ease;\n}\n\n.at-slide-close:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.at-slide-body {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.at-form-group {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.at-form-label {\n font-size: 0.75rem;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n.at-form-input,\n.at-form-select,\n.at-form-textarea {\n padding: 9px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 7px;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n font-size: 0.85rem;\n outline: none;\n transition: border-color 0.15s ease;\n font-family: inherit;\n}\n\n.at-form-input:focus,\n.at-form-select:focus,\n.at-form-textarea:focus {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.at-form-select {\n appearance: none;\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%2364748b' d='M3 5l3 3 3-3'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: right 10px center;\n padding-right: 30px;\n}\n\n.at-form-textarea {\n resize: vertical;\n min-height: 70px;\n}\n\n.at-form-row {\n display: flex;\n gap: 12px;\n}\n\n.at-form-actions {\n display: flex;\n gap: 8px;\n padding-top: 8px;\n border-top: 1px solid var(--mj-border-subtle);\n margin-top: 8px;\n}\n\n.at-form-actions .at-action-btn {\n flex: 1;\n justify-content: center;\n}\n\n/* Also add empty state for Content Types (matching Sources) */\n.at-add-type-card {\n background: none;\n border: 2px dashed var(--mj-border-default);\n border-radius: 10px;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 40px;\n cursor: pointer;\n transition: all 0.15s ease;\n color: var(--mj-text-muted);\n min-height: 200px;\n}\n\n.at-add-type-card:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n.at-add-type-card i {\n font-size: 1.5rem;\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550 FORKED PIPELINE STAGES \u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.at-pipeline-stages-forked {\n display: flex;\n align-items: center;\n gap: 0;\n}\n\n.at-pipeline-fork {\n display: flex;\n align-items: center;\n gap: 0;\n flex: 2;\n}\n\n.at-pipeline-fork-lines {\n width: 28px;\n display: flex;\n flex-direction: column;\n gap: 12px;\n position: relative;\n flex-shrink: 0;\n}\n\n.at-pipeline-fork-line {\n height: 2px;\n background: var(--mj-border-default);\n width: 100%;\n position: relative;\n}\n\n.at-pipeline-fork-line::before {\n content: '';\n position: absolute;\n width: 2px;\n height: 12px;\n background: var(--mj-border-default);\n left: 0;\n}\n\n.at-fork-top::before {\n bottom: 0;\n left: 0;\n}\n\n.at-fork-bottom::before {\n top: 0;\n left: 0;\n}\n\n.at-pipeline-fork-branches {\n display: flex;\n flex-direction: column;\n gap: 8px;\n flex: 1;\n}\n\n.at-pipeline-fork-branches .at-pipeline-stage {\n flex: none;\n padding: 6px 0;\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550 CLICKABLE FEED ITEMS \u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.at-feed-item-clickable {\n cursor: pointer;\n}\n\n.at-feed-item-clickable:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550 CLICKABLE SOURCE CARDS \u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.at-source-card-clickable {\n cursor: pointer;\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550 FORM HINT \u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.at-form-hint {\n font-size: 0.68rem;\n color: var(--mj-text-muted);\n font-style: italic;\n margin-top: 2px;\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550 DETAIL PANEL (wider) \u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.at-detail-panel {\n width: 500px;\n}\n\n/* \u2500\u2500 Detail: Item header \u2500\u2500 */\n\n.at-detail-item-header {\n margin-bottom: 8px;\n}\n\n.at-detail-item-name {\n font-size: 1.05rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0 0 6px 0;\n word-break: break-word;\n}\n\n.at-detail-badges {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n}\n\n.at-detail-badge {\n padding: 2px 10px;\n border-radius: 10px;\n font-size: 0.7rem;\n font-weight: 600;\n}\n\n.at-detail-badge-source {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.at-detail-badge-type {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.at-detail-badge-file {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n}\n\n.at-detail-badge-status-active {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success-text);\n}\n\n.at-detail-badge-status-error {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error-text);\n}\n\n.at-detail-badge-status-inactive {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-disabled);\n}\n\n/* \u2500\u2500 Detail: Sections \u2500\u2500 */\n\n.at-detail-section {\n margin-bottom: 4px;\n}\n\n.at-detail-section-label {\n font-size: 0.72rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n color: var(--mj-text-muted);\n margin-bottom: 6px;\n}\n\n.at-detail-link {\n font-size: 0.8rem;\n color: var(--mj-brand-primary);\n text-decoration: none;\n word-break: break-all;\n}\n\n.at-detail-link:hover {\n text-decoration: underline;\n}\n\n/* \u2500\u2500 Detail: Text preview \u2500\u2500 */\n\n.at-detail-text-preview {\n max-height: 200px;\n overflow-y: auto;\n padding: 10px 12px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 6px;\n font-size: 0.78rem;\n font-family: 'SF Mono', 'Cascadia Code', 'Menlo', monospace;\n color: var(--mj-text-primary);\n white-space: pre-wrap;\n word-break: break-word;\n line-height: 1.5;\n}\n\n/* \u2500\u2500 Detail: Tags \u2500\u2500 */\n\n.at-detail-tags {\n display: flex;\n flex-wrap: wrap;\n gap: 5px;\n}\n\n/* \u2500\u2500 Detail: Meta grid \u2500\u2500 */\n\n.at-detail-meta-grid {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 8px;\n overflow: hidden;\n}\n\n.at-detail-meta-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 12px;\n border-bottom: 1px solid var(--mj-border-subtle);\n font-size: 0.78rem;\n}\n\n.at-detail-meta-row:last-child {\n border-bottom: none;\n}\n\n.at-detail-meta-key {\n color: var(--mj-text-muted);\n font-weight: 500;\n flex-shrink: 0;\n margin-right: 12px;\n}\n\n.at-detail-meta-value {\n color: var(--mj-text-primary);\n text-align: right;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.at-detail-meta-mono {\n font-family: 'SF Mono', 'Cascadia Code', 'Menlo', monospace;\n font-size: 0.72rem;\n}\n\n/* \u2500\u2500 Detail: Actions \u2500\u2500 */\n\n.at-detail-actions {\n display: flex;\n gap: 8px;\n padding-top: 8px;\n border-top: 1px solid var(--mj-border-subtle);\n margin-top: 8px;\n}\n\n.at-detail-actions .at-action-btn {\n flex: 1;\n justify-content: center;\n}\n\n/* \u2500\u2500 Detail: Source header \u2500\u2500 */\n\n.at-detail-source-header {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 8px;\n}\n\n/* \u2500\u2500 Detail: Stats strip \u2500\u2500 */\n\n.at-detail-stats-strip {\n display: flex;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n.at-detail-stat {\n flex: 1;\n min-width: 60px;\n text-align: center;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 8px;\n padding: 8px 6px;\n}\n\n.at-detail-stat-value {\n font-size: 1rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.at-detail-stat-label {\n font-size: 0.62rem;\n color: var(--mj-text-muted);\n margin-top: 2px;\n}\n\n/* \u2500\u2500 Detail: Content Library \u2500\u2500 */\n\n.at-detail-content-list {\n max-height: 250px;\n overflow-y: auto;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 8px;\n}\n\n.at-detail-content-item {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n border-bottom: 1px solid var(--mj-border-subtle);\n font-size: 0.78rem;\n cursor: pointer;\n transition: background 0.1s ease;\n}\n\n.at-detail-content-item:last-child {\n border-bottom: none;\n}\n\n.at-detail-content-item:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.at-detail-content-item-name {\n flex: 1;\n font-weight: 500;\n color: var(--mj-text-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.at-detail-content-item-tags {\n font-size: 0.68rem;\n color: var(--mj-text-muted);\n white-space: nowrap;\n}\n\n.at-detail-content-item-time {\n font-size: 0.68rem;\n color: var(--mj-text-muted);\n white-space: nowrap;\n}\n\n/* \u2500\u2500 Detail: Run history \u2500\u2500 */\n\n.at-detail-run-history {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 8px;\n max-height: 200px;\n overflow-y: auto;\n}\n\n.at-detail-run-row {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n border-bottom: 1px solid var(--mj-border-subtle);\n font-size: 0.75rem;\n}\n\n.at-detail-run-row:last-child {\n border-bottom: none;\n}\n\n.at-detail-run-time {\n color: var(--mj-text-secondary);\n flex: 1;\n}\n\n.at-detail-run-duration {\n color: var(--mj-text-muted);\n}\n\n.at-detail-run-items {\n color: var(--mj-text-muted);\n}\n\n@media (max-width: 600px) {\n .at-slide-panel {\n width: 100%;\n }\n\n .at-detail-panel {\n width: 100%;\n }\n}\n"] }]
|
|
2787
|
+
}], null, null); })();
|
|
2788
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(AutotaggingPipelineResourceComponent, { className: "AutotaggingPipelineResourceComponent", filePath: "src/AI/components/autotagging/autotagging-pipeline-resource.component.ts", lineNumber: 193 }); })();
|
|
2789
|
+
export function LoadAutotaggingPipelineResource() {
|
|
2790
|
+
// Prevents tree-shaking
|
|
2791
|
+
}
|
|
2792
|
+
//# sourceMappingURL=autotagging-pipeline-resource.component.js.map
|