@memberjunction/ng-dashboards 5.38.0 → 5.40.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 +14 -7
- package/dist/AI/components/agents/agent-configuration.component.js +199 -198
- package/dist/AI/components/agents/agent-configuration.component.js.map +1 -1
- package/dist/AI/components/analytics/ai-analytics-resource.component.d.ts.map +1 -1
- package/dist/AI/components/analytics/ai-analytics-resource.component.js +20 -17
- package/dist/AI/components/analytics/ai-analytics-resource.component.js.map +1 -1
- package/dist/AI/components/analytics/cost-budget/cost-budget.component.d.ts +15 -0
- package/dist/AI/components/analytics/cost-budget/cost-budget.component.d.ts.map +1 -1
- package/dist/AI/components/analytics/cost-budget/cost-budget.component.js +166 -58
- package/dist/AI/components/analytics/cost-budget/cost-budget.component.js.map +1 -1
- package/dist/AI/components/analytics/executive-summary/executive-summary.component.d.ts.map +1 -1
- package/dist/AI/components/analytics/executive-summary/executive-summary.component.js +2 -1
- package/dist/AI/components/analytics/executive-summary/executive-summary.component.js.map +1 -1
- package/dist/AI/components/analytics/model-performance/model-performance.component.d.ts +1 -0
- package/dist/AI/components/analytics/model-performance/model-performance.component.d.ts.map +1 -1
- package/dist/AI/components/analytics/model-performance/model-performance.component.js +55 -36
- package/dist/AI/components/analytics/model-performance/model-performance.component.js.map +1 -1
- package/dist/AI/components/analytics/prompt-runs/prompt-run-analysis.component.d.ts +9 -1
- package/dist/AI/components/analytics/prompt-runs/prompt-run-analysis.component.d.ts.map +1 -1
- package/dist/AI/components/analytics/prompt-runs/prompt-run-analysis.component.js +158 -117
- package/dist/AI/components/analytics/prompt-runs/prompt-run-analysis.component.js.map +1 -1
- package/dist/AI/components/analytics/usage-patterns/usage-patterns.component.d.ts +1 -0
- package/dist/AI/components/analytics/usage-patterns/usage-patterns.component.d.ts.map +1 -1
- package/dist/AI/components/analytics/usage-patterns/usage-patterns.component.js +22 -8
- package/dist/AI/components/analytics/usage-patterns/usage-patterns.component.js.map +1 -1
- package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts +217 -860
- package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts.map +1 -1
- package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js +1717 -7802
- package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js.map +1 -1
- package/dist/AI/components/autotagging/components/classify-item-drilldown.component.d.ts +56 -0
- package/dist/AI/components/autotagging/components/classify-item-drilldown.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/components/classify-item-drilldown.component.js +423 -0
- package/dist/AI/components/autotagging/components/classify-item-drilldown.component.js.map +1 -0
- package/dist/AI/components/autotagging/components/classify-item-grid.component.d.ts +70 -0
- package/dist/AI/components/autotagging/components/classify-item-grid.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/components/classify-item-grid.component.js +308 -0
- package/dist/AI/components/autotagging/components/classify-item-grid.component.js.map +1 -0
- package/dist/AI/components/autotagging/components/classify-org-context-editor.component.d.ts +29 -0
- package/dist/AI/components/autotagging/components/classify-org-context-editor.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/components/classify-org-context-editor.component.js +186 -0
- package/dist/AI/components/autotagging/components/classify-org-context-editor.component.js.map +1 -0
- package/dist/AI/components/autotagging/components/classify-overview-analytics.component.d.ts +69 -0
- package/dist/AI/components/autotagging/components/classify-overview-analytics.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/components/classify-overview-analytics.component.js +278 -0
- package/dist/AI/components/autotagging/components/classify-overview-analytics.component.js.map +1 -0
- package/dist/AI/components/autotagging/components/classify-seed-taxonomy.component.d.ts +73 -0
- package/dist/AI/components/autotagging/components/classify-seed-taxonomy.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/components/classify-seed-taxonomy.component.js +393 -0
- package/dist/AI/components/autotagging/components/classify-seed-taxonomy.component.js.map +1 -0
- package/dist/AI/components/autotagging/dialogs/classify-setup-wizard.component.d.ts +122 -0
- package/dist/AI/components/autotagging/dialogs/classify-setup-wizard.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/dialogs/classify-setup-wizard.component.js +908 -0
- package/dist/AI/components/autotagging/dialogs/classify-setup-wizard.component.js.map +1 -0
- package/dist/AI/components/autotagging/dialogs/dry-run-preview.dialog.component.d.ts +87 -0
- package/dist/AI/components/autotagging/dialogs/dry-run-preview.dialog.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/dialogs/dry-run-preview.dialog.component.js +475 -0
- package/dist/AI/components/autotagging/dialogs/dry-run-preview.dialog.component.js.map +1 -0
- package/dist/AI/components/autotagging/dialogs/item-detail.dialog.component.d.ts +29 -0
- package/dist/AI/components/autotagging/dialogs/item-detail.dialog.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/dialogs/item-detail.dialog.component.js +208 -0
- package/dist/AI/components/autotagging/dialogs/item-detail.dialog.component.js.map +1 -0
- package/dist/AI/components/autotagging/dialogs/no-content-type-warning.dialog.component.d.ts +21 -0
- package/dist/AI/components/autotagging/dialogs/no-content-type-warning.dialog.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/dialogs/no-content-type-warning.dialog.component.js +70 -0
- package/dist/AI/components/autotagging/dialogs/no-content-type-warning.dialog.component.js.map +1 -0
- package/dist/AI/components/autotagging/dialogs/source-type-form.dialog.component.d.ts +333 -0
- package/dist/AI/components/autotagging/dialogs/source-type-form.dialog.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/dialogs/source-type-form.dialog.component.js +2125 -0
- package/dist/AI/components/autotagging/dialogs/source-type-form.dialog.component.js.map +1 -0
- package/dist/AI/components/autotagging/shared/classify.dryrun.d.ts +61 -0
- package/dist/AI/components/autotagging/shared/classify.dryrun.d.ts.map +1 -0
- package/dist/AI/components/autotagging/shared/classify.dryrun.js +78 -0
- package/dist/AI/components/autotagging/shared/classify.dryrun.js.map +1 -0
- package/dist/AI/components/autotagging/shared/classify.format.d.ts +58 -0
- package/dist/AI/components/autotagging/shared/classify.format.d.ts.map +1 -0
- package/dist/AI/components/autotagging/shared/classify.format.js +260 -0
- package/dist/AI/components/autotagging/shared/classify.format.js.map +1 -0
- package/dist/AI/components/autotagging/shared/classify.types.d.ts +319 -0
- package/dist/AI/components/autotagging/shared/classify.types.d.ts.map +1 -0
- package/dist/AI/components/autotagging/shared/classify.types.js +6 -0
- package/dist/AI/components/autotagging/shared/classify.types.js.map +1 -0
- package/dist/AI/components/autotagging/tabs/health-tab.component.d.ts +103 -0
- package/dist/AI/components/autotagging/tabs/health-tab.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/tabs/health-tab.component.js +571 -0
- package/dist/AI/components/autotagging/tabs/health-tab.component.js.map +1 -0
- package/dist/AI/components/autotagging/tabs/history-tab.component.d.ts +77 -0
- package/dist/AI/components/autotagging/tabs/history-tab.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/tabs/history-tab.component.js +519 -0
- package/dist/AI/components/autotagging/tabs/history-tab.component.js.map +1 -0
- package/dist/AI/components/autotagging/tabs/inbox-tab.component.d.ts +107 -0
- package/dist/AI/components/autotagging/tabs/inbox-tab.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/tabs/inbox-tab.component.js +719 -0
- package/dist/AI/components/autotagging/tabs/inbox-tab.component.js.map +1 -0
- package/dist/AI/components/autotagging/tabs/pipeline-tab.component.d.ts +131 -0
- package/dist/AI/components/autotagging/tabs/pipeline-tab.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/tabs/pipeline-tab.component.js +813 -0
- package/dist/AI/components/autotagging/tabs/pipeline-tab.component.js.map +1 -0
- package/dist/AI/components/autotagging/tabs/sources-tab.component.d.ts +177 -0
- package/dist/AI/components/autotagging/tabs/sources-tab.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/tabs/sources-tab.component.js +1465 -0
- package/dist/AI/components/autotagging/tabs/sources-tab.component.js.map +1 -0
- package/dist/AI/components/autotagging/tabs/tags-tab.component.d.ts +78 -0
- package/dist/AI/components/autotagging/tabs/tags-tab.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/tabs/tags-tab.component.js +492 -0
- package/dist/AI/components/autotagging/tabs/tags-tab.component.js.map +1 -0
- package/dist/AI/components/autotagging/tabs/taxonomy-tab.component.d.ts +397 -0
- package/dist/AI/components/autotagging/tabs/taxonomy-tab.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/tabs/taxonomy-tab.component.js +3490 -0
- package/dist/AI/components/autotagging/tabs/taxonomy-tab.component.js.map +1 -0
- package/dist/AI/components/autotagging/tabs/types-tab.component.d.ts +56 -0
- package/dist/AI/components/autotagging/tabs/types-tab.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/tabs/types-tab.component.js +271 -0
- package/dist/AI/components/autotagging/tabs/types-tab.component.js.map +1 -0
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts +3 -0
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts.map +1 -1
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.js +306 -290
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.js.map +1 -1
- package/dist/AI/components/execution-monitoring.component.js +1 -1
- package/dist/AI/components/execution-monitoring.component.js.map +1 -1
- package/dist/AI/components/models/model-management.component.js +209 -208
- package/dist/AI/components/models/model-management.component.js.map +1 -1
- package/dist/AI/components/prompts/prompt-management.component.js +130 -128
- package/dist/AI/components/prompts/prompt-management.component.js.map +1 -1
- package/dist/AI/components/requests/agent-requests-resource.component.js +61 -61
- package/dist/AI/components/requests/agent-requests-resource.component.js.map +1 -1
- package/dist/AI/components/system/system-configuration.component.js +17 -17
- package/dist/AI/components/system/system-configuration.component.js.map +1 -1
- package/dist/AI/components/tags/tags-resource.component.d.ts +1 -0
- package/dist/AI/components/tags/tags-resource.component.d.ts.map +1 -1
- package/dist/AI/components/tags/tags-resource.component.js +578 -538
- package/dist/AI/components/tags/tags-resource.component.js.map +1 -1
- package/dist/AI/components/vectors/vector-management-resource.component.d.ts +3 -0
- package/dist/AI/components/vectors/vector-management-resource.component.d.ts.map +1 -1
- package/dist/AI/components/vectors/vector-management-resource.component.js +331 -303
- package/dist/AI/components/vectors/vector-management-resource.component.js.map +1 -1
- package/dist/AI/services/ai-instrumentation.service.d.ts +5 -0
- package/dist/AI/services/ai-instrumentation.service.d.ts.map +1 -1
- package/dist/AI/services/ai-instrumentation.service.js +14 -2
- package/dist/AI/services/ai-instrumentation.service.js.map +1 -1
- package/dist/AI/services/cache-metrics.d.ts +50 -0
- package/dist/AI/services/cache-metrics.d.ts.map +1 -0
- package/dist/AI/services/cache-metrics.js +43 -0
- package/dist/AI/services/cache-metrics.js.map +1 -0
- package/dist/APIKeys/api-applications-panel.component.js +2 -2
- package/dist/APIKeys/api-key-create-dialog.component.js +2 -2
- package/dist/APIKeys/api-key-edit-panel.component.js +2 -2
- package/dist/APIKeys/api-keys-resource.component.js +132 -131
- package/dist/APIKeys/api-keys-resource.component.js.map +1 -1
- package/dist/Actions/components/actions-overview.component.js +141 -141
- package/dist/Actions/components/actions-overview.component.js.map +1 -1
- package/dist/Actions/components/execution-monitoring.component.js +15 -15
- package/dist/Actions/components/execution-monitoring.component.js.map +1 -1
- package/dist/Actions/components/explorer/action-explorer.component.d.ts +0 -5
- package/dist/Actions/components/explorer/action-explorer.component.d.ts.map +1 -1
- package/dist/Actions/components/explorer/action-explorer.component.js +139 -212
- package/dist/Actions/components/explorer/action-explorer.component.js.map +1 -1
- package/dist/Admin/admin-data-schema.component.js +2 -2
- package/dist/Admin/admin-data-schema.component.js.map +1 -1
- package/dist/Admin/admin-dev-tools-resource.component.js +2 -2
- package/dist/Admin/admin-dev-tools-resource.component.js.map +1 -1
- package/dist/Admin/admin-identity-access.component.js +2 -2
- package/dist/Admin/admin-identity-access.component.js.map +1 -1
- package/dist/Admin/admin-monitoring.component.js +2 -2
- package/dist/Admin/admin-monitoring.component.js.map +1 -1
- package/dist/ApplicationRoles/application-roles-resource.component.js +54 -49
- package/dist/ApplicationRoles/application-roles-resource.component.js.map +1 -1
- package/dist/Communication/communication-logs-resource.component.d.ts +6 -0
- package/dist/Communication/communication-logs-resource.component.d.ts.map +1 -1
- package/dist/Communication/communication-logs-resource.component.js +72 -50
- package/dist/Communication/communication-logs-resource.component.js.map +1 -1
- package/dist/Communication/communication-monitor-resource.component.js +103 -102
- package/dist/Communication/communication-monitor-resource.component.js.map +1 -1
- package/dist/Communication/communication-providers-resource.component.js +52 -51
- package/dist/Communication/communication-providers-resource.component.js.map +1 -1
- package/dist/Communication/communication-runs-resource.component.js +39 -38
- package/dist/Communication/communication-runs-resource.component.js.map +1 -1
- package/dist/Communication/communication-templates-resource.component.d.ts +6 -0
- package/dist/Communication/communication-templates-resource.component.d.ts.map +1 -1
- package/dist/Communication/communication-templates-resource.component.js +92 -89
- package/dist/Communication/communication-templates-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-audit-resource.component.js +136 -135
- package/dist/Credentials/components/credentials-audit-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-categories-resource.component.js +155 -152
- package/dist/Credentials/components/credentials-categories-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-list-resource.component.js +119 -118
- package/dist/Credentials/components/credentials-list-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-overview-resource.component.js +129 -128
- package/dist/Credentials/components/credentials-overview-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-types-resource.component.js +107 -106
- package/dist/Credentials/components/credentials-types-resource.component.js.map +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts +31 -340
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.js +468 -1958
- package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
- package/dist/DataExplorer/data-explorer-resource.component.d.ts.map +1 -1
- package/dist/DataExplorer/data-explorer-resource.component.js +10 -0
- package/dist/DataExplorer/data-explorer-resource.component.js.map +1 -1
- package/dist/DatabaseDesigner/components/database-designer-dashboard.component.js +1 -1
- package/dist/DatabaseDesigner/components/entity-list.component.js +115 -114
- package/dist/DatabaseDesigner/components/entity-list.component.js.map +1 -1
- package/dist/DatabaseDesigner/database-designer-dashboards.module.d.ts +5 -6
- package/dist/DatabaseDesigner/database-designer-dashboards.module.d.ts.map +1 -1
- package/dist/DatabaseDesigner/database-designer-dashboards.module.js +4 -5
- package/dist/DatabaseDesigner/database-designer-dashboards.module.js.map +1 -1
- package/dist/DevTools/app-state-inspector.component.js +18 -17
- package/dist/DevTools/app-state-inspector.component.js.map +1 -1
- package/dist/DevTools/class-registry.component.js +88 -85
- package/dist/DevTools/class-registry.component.js.map +1 -1
- package/dist/DevTools/event-monitor.component.js +155 -150
- package/dist/DevTools/event-monitor.component.js.map +1 -1
- package/dist/DevTools/graphql-console.component.js +245 -243
- package/dist/DevTools/graphql-console.component.js.map +1 -1
- package/dist/DevTools/layout-inspector.component.js +18 -17
- package/dist/DevTools/layout-inspector.component.js.map +1 -1
- package/dist/EntityAdmin/entity-admin-dashboard.component.js +20 -19
- package/dist/EntityAdmin/entity-admin-dashboard.component.js.map +1 -1
- package/dist/Home/home-dashboard.component.js +2 -2
- package/dist/Integration/components/activity/activity.component.d.ts.map +1 -1
- package/dist/Integration/components/activity/activity.component.js +236 -229
- package/dist/Integration/components/activity/activity.component.js.map +1 -1
- package/dist/Integration/components/connections/connections.component.js +390 -389
- package/dist/Integration/components/connections/connections.component.js.map +1 -1
- package/dist/Integration/components/overview/overview.component.js +2 -2
- package/dist/KnowledgeHub/components/analytics/analytics-resource.component.d.ts.map +1 -1
- package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js +14 -11
- package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js.map +1 -1
- package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.d.ts +27 -2
- package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.d.ts.map +1 -1
- package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js +244 -119
- package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js.map +1 -1
- package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js +293 -291
- package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js.map +1 -1
- package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.js +62 -61
- package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.js.map +1 -1
- package/dist/KnowledgeHub/components/visualize/record-drilldown/record-drilldown.component.d.ts +65 -0
- package/dist/KnowledgeHub/components/visualize/record-drilldown/record-drilldown.component.d.ts.map +1 -0
- package/dist/KnowledgeHub/components/visualize/record-drilldown/record-drilldown.component.js +176 -0
- package/dist/KnowledgeHub/components/visualize/record-drilldown/record-drilldown.component.js.map +1 -0
- package/dist/KnowledgeHub/components/visualize/tag-cloud/tag-cloud.component.d.ts +81 -0
- package/dist/KnowledgeHub/components/visualize/tag-cloud/tag-cloud.component.d.ts.map +1 -0
- package/dist/KnowledgeHub/components/visualize/tag-cloud/tag-cloud.component.js +308 -0
- package/dist/KnowledgeHub/components/visualize/tag-cloud/tag-cloud.component.js.map +1 -0
- package/dist/KnowledgeHub/components/visualize/visualize-resource.component.d.ts +85 -0
- package/dist/KnowledgeHub/components/visualize/visualize-resource.component.d.ts.map +1 -0
- package/dist/KnowledgeHub/components/visualize/visualize-resource.component.js +362 -0
- package/dist/KnowledgeHub/components/visualize/visualize-resource.component.js.map +1 -0
- package/dist/KnowledgeHub/index.d.ts +3 -0
- package/dist/KnowledgeHub/index.d.ts.map +1 -1
- package/dist/KnowledgeHub/index.js +3 -0
- package/dist/KnowledgeHub/index.js.map +1 -1
- package/dist/Lists/components/lists-browse-resource.component.d.ts +6 -2
- package/dist/Lists/components/lists-browse-resource.component.d.ts.map +1 -1
- package/dist/Lists/components/lists-browse-resource.component.js +525 -566
- package/dist/Lists/components/lists-browse-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-categories-resource.component.js +135 -134
- package/dist/Lists/components/lists-categories-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-my-lists-resource.component.js +199 -198
- package/dist/Lists/components/lists-my-lists-resource.component.js.map +1 -1
- package/dist/MCP/components/mcp-server-dialog.component.js +2 -2
- package/dist/MCP/mcp-dashboard.component.js +443 -438
- package/dist/MCP/mcp-dashboard.component.js.map +1 -1
- package/dist/QueryBrowser/query-browser-resource.component.js +1 -1
- package/dist/QueryBrowser/query-browser-resource.component.js.map +1 -1
- package/dist/Scheduling/components/scheduling-activity.component.d.ts.map +1 -1
- package/dist/Scheduling/components/scheduling-activity.component.js +146 -147
- package/dist/Scheduling/components/scheduling-activity.component.js.map +1 -1
- package/dist/Scheduling/components/scheduling-jobs.component.js +76 -75
- package/dist/Scheduling/components/scheduling-jobs.component.js.map +1 -1
- package/dist/Scheduling/components/scheduling-overview.component.js +97 -96
- package/dist/Scheduling/components/scheduling-overview.component.js.map +1 -1
- package/dist/Scheduling/scheduling-dashboard.component.js +24 -22
- package/dist/Scheduling/scheduling-dashboard.component.js.map +1 -1
- package/dist/Scheduling/services/scheduling-instrumentation.service.d.ts +2 -0
- package/dist/Scheduling/services/scheduling-instrumentation.service.d.ts.map +1 -1
- package/dist/Scheduling/services/scheduling-instrumentation.service.js +1 -0
- package/dist/Scheduling/services/scheduling-instrumentation.service.js.map +1 -1
- package/dist/Testing/components/testing-dashboard-tab-resource.component.js +1 -1
- package/dist/Testing/components/testing-explorer.component.d.ts +14 -4
- package/dist/Testing/components/testing-explorer.component.d.ts.map +1 -1
- package/dist/Testing/components/testing-explorer.component.js +436 -427
- package/dist/Testing/components/testing-explorer.component.js.map +1 -1
- package/dist/Testing/components/testing-runs-resource.component.js +1 -1
- package/dist/Testing/components/testing-runs.component.js +116 -115
- package/dist/Testing/components/testing-runs.component.js.map +1 -1
- package/dist/Testing/testing-dashboard.component.js +6 -7
- package/dist/Testing/testing-dashboard.component.js.map +1 -1
- package/dist/VersionHistory/components/labels-resource.component.js +173 -172
- package/dist/VersionHistory/components/labels-resource.component.js.map +1 -1
- package/dist/VersionHistory/components/restore-resource.component.d.ts +6 -0
- package/dist/VersionHistory/components/restore-resource.component.d.ts.map +1 -1
- package/dist/VersionHistory/components/restore-resource.component.js +116 -92
- package/dist/VersionHistory/components/restore-resource.component.js.map +1 -1
- package/dist/ai-dashboards.module.d.ts +57 -35
- package/dist/ai-dashboards.module.d.ts.map +1 -1
- package/dist/ai-dashboards.module.js +80 -1
- package/dist/ai-dashboards.module.js.map +1 -1
- package/dist/communication-dashboards.module.d.ts +1 -1
- package/dist/communication-dashboards.module.d.ts.map +1 -1
- package/dist/communication-dashboards.module.js +7 -1
- package/dist/communication-dashboards.module.js.map +1 -1
- package/dist/data-explorer-dashboards.module.d.ts +12 -14
- package/dist/data-explorer-dashboards.module.d.ts.map +1 -1
- package/dist/data-explorer-dashboards.module.js +5 -14
- package/dist/data-explorer-dashboards.module.js.map +1 -1
- package/dist/public-api.d.ts +3 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +3 -0
- package/dist/public-api.js.map +1 -1
- package/dist/testing-dashboards.module.d.ts +4 -5
- package/dist/testing-dashboards.module.d.ts.map +1 -1
- package/dist/testing-dashboards.module.js +7 -5
- package/dist/testing-dashboards.module.js.map +1 -1
- package/package.json +57 -54
- package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.d.ts +0 -79
- package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.d.ts.map +0 -1
- package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.js +0 -195
- package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.js.map +0 -1
- package/dist/DataExplorer/components/view-selector/view-selector.component.d.ts +0 -226
- package/dist/DataExplorer/components/view-selector/view-selector.component.d.ts.map +0 -1
- package/dist/DataExplorer/components/view-selector/view-selector.component.js +0 -861
- package/dist/DataExplorer/components/view-selector/view-selector.component.js.map +0 -1
|
@@ -0,0 +1,475 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Classify · Dry-run / disposition PREVIEW dialog.
|
|
3
|
+
*
|
|
4
|
+
* Honest, client-side, in-memory preview of how a source's EXISTING extracted
|
|
5
|
+
* ContentItemTags would be dispositioned under its current taxonomy mode +
|
|
6
|
+
* thresholds. This is NOT a fresh LLM run and NOTHING is persisted — it samples
|
|
7
|
+
* up to N existing tags, resolves each against the cached taxonomy
|
|
8
|
+
* (Tags / TagSynonyms) client-side, and replays the deterministic routing via the
|
|
9
|
+
* pure `previewDispositions` helper.
|
|
10
|
+
*
|
|
11
|
+
* It is hosted by the Sources tab (which already hosts its own dialogs): data
|
|
12
|
+
* DOWN via `[SourceCard]` / `[Show]`, intent UP via `(Closed)`. On open it loads
|
|
13
|
+
* the sample itself (read-only RunView, `ResultType: 'simple'`).
|
|
14
|
+
*
|
|
15
|
+
* NOTE: the server also has a semantic/embedding match tier not reproducible
|
|
16
|
+
* client-side, so borderline rows may resolve differently in a real run. The
|
|
17
|
+
* template states this explicitly.
|
|
18
|
+
*/
|
|
19
|
+
import { Component, ChangeDetectorRef, EventEmitter, Input, Output, inject } from '@angular/core';
|
|
20
|
+
import { RunView } from '@memberjunction/core';
|
|
21
|
+
import { UUIDsEqual } from '@memberjunction/global';
|
|
22
|
+
import { BaseAngularComponent } from '@memberjunction/ng-base-types';
|
|
23
|
+
import { TagEngineBase } from '@memberjunction/tag-engine-base';
|
|
24
|
+
import { KnowledgeHubMetadataEngine } from '@memberjunction/core-entities';
|
|
25
|
+
import { previewDispositions, } from '../shared/classify.dryrun';
|
|
26
|
+
import * as i0 from "@angular/core";
|
|
27
|
+
import * as i1 from "@memberjunction/ng-shared-generic";
|
|
28
|
+
import * as i2 from "@memberjunction/ng-ui-components";
|
|
29
|
+
function ClassifyDryRunPreviewDialogComponent_Conditional_0_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
30
|
+
i0.ɵɵelementStart(0, "div", 7);
|
|
31
|
+
i0.ɵɵelement(1, "i");
|
|
32
|
+
i0.ɵɵelementStart(2, "span", 17);
|
|
33
|
+
i0.ɵɵtext(3);
|
|
34
|
+
i0.ɵɵelementEnd()();
|
|
35
|
+
} if (rf & 2) {
|
|
36
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
37
|
+
i0.ɵɵadvance();
|
|
38
|
+
i0.ɵɵclassMap(ctx_r1.SourceCard.Icon);
|
|
39
|
+
i0.ɵɵadvance(2);
|
|
40
|
+
i0.ɵɵtextInterpolate(ctx_r1.SourceCard.Name);
|
|
41
|
+
} }
|
|
42
|
+
function ClassifyDryRunPreviewDialogComponent_Conditional_0_Conditional_36_Template(rf, ctx) { if (rf & 1) {
|
|
43
|
+
i0.ɵɵelement(0, "mj-loading", 13);
|
|
44
|
+
} }
|
|
45
|
+
function ClassifyDryRunPreviewDialogComponent_Conditional_0_Conditional_37_Template(rf, ctx) { if (rf & 1) {
|
|
46
|
+
i0.ɵɵelementStart(0, "div", 14);
|
|
47
|
+
i0.ɵɵelement(1, "i", 18);
|
|
48
|
+
i0.ɵɵelementStart(2, "p");
|
|
49
|
+
i0.ɵɵtext(3, "No extracted tags found for this source yet. Run the pipeline first, then preview how its tags would be dispositioned.");
|
|
50
|
+
i0.ɵɵelementEnd()();
|
|
51
|
+
} }
|
|
52
|
+
function ClassifyDryRunPreviewDialogComponent_Conditional_0_Conditional_38_Conditional_13_Template(rf, ctx) { if (rf & 1) {
|
|
53
|
+
i0.ɵɵelementStart(0, "span", 26);
|
|
54
|
+
i0.ɵɵtext(1);
|
|
55
|
+
i0.ɵɵelementEnd();
|
|
56
|
+
} if (rf & 2) {
|
|
57
|
+
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
58
|
+
i0.ɵɵadvance();
|
|
59
|
+
i0.ɵɵtextInterpolate1("", ctx_r1.Counts.Reject, " reject");
|
|
60
|
+
} }
|
|
61
|
+
function ClassifyDryRunPreviewDialogComponent_Conditional_0_Conditional_38_For_27_Template(rf, ctx) { if (rf & 1) {
|
|
62
|
+
i0.ɵɵelementStart(0, "tr")(1, "td", 31);
|
|
63
|
+
i0.ɵɵtext(2);
|
|
64
|
+
i0.ɵɵelementEnd();
|
|
65
|
+
i0.ɵɵelementStart(3, "td", 32);
|
|
66
|
+
i0.ɵɵtext(4);
|
|
67
|
+
i0.ɵɵelementEnd();
|
|
68
|
+
i0.ɵɵelementStart(5, "td", 33);
|
|
69
|
+
i0.ɵɵtext(6);
|
|
70
|
+
i0.ɵɵelementEnd();
|
|
71
|
+
i0.ɵɵelementStart(7, "td")(8, "span", 34);
|
|
72
|
+
i0.ɵɵtext(9);
|
|
73
|
+
i0.ɵɵelementEnd()()();
|
|
74
|
+
} if (rf & 2) {
|
|
75
|
+
const row_r3 = ctx.$implicit;
|
|
76
|
+
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
77
|
+
i0.ɵɵadvance(2);
|
|
78
|
+
i0.ɵɵtextInterpolate(row_r3.tag);
|
|
79
|
+
i0.ɵɵadvance(2);
|
|
80
|
+
i0.ɵɵtextInterpolate(row_r3.matchedTag ?? "\u2014");
|
|
81
|
+
i0.ɵɵadvance(2);
|
|
82
|
+
i0.ɵɵtextInterpolate(ctx_r1.FormatScore(row_r3.score));
|
|
83
|
+
i0.ɵɵadvance(2);
|
|
84
|
+
i0.ɵɵclassMap(ctx_r1.DispositionClass(row_r3.disposition));
|
|
85
|
+
i0.ɵɵproperty("title", row_r3.reason);
|
|
86
|
+
i0.ɵɵadvance();
|
|
87
|
+
i0.ɵɵtextInterpolate1(" ", ctx_r1.DispositionLabel(row_r3.disposition), " ");
|
|
88
|
+
} }
|
|
89
|
+
function ClassifyDryRunPreviewDialogComponent_Conditional_0_Conditional_38_Template(rf, ctx) { if (rf & 1) {
|
|
90
|
+
i0.ɵɵelementStart(0, "div", 19);
|
|
91
|
+
i0.ɵɵelement(1, "i", 20);
|
|
92
|
+
i0.ɵɵelementStart(2, "span");
|
|
93
|
+
i0.ɵɵtext(3);
|
|
94
|
+
i0.ɵɵelementStart(4, "span", 21);
|
|
95
|
+
i0.ɵɵtext(5, "(rough estimate)");
|
|
96
|
+
i0.ɵɵelementEnd()()();
|
|
97
|
+
i0.ɵɵelementStart(6, "div", 22)(7, "span", 23);
|
|
98
|
+
i0.ɵɵtext(8);
|
|
99
|
+
i0.ɵɵelementEnd();
|
|
100
|
+
i0.ɵɵelementStart(9, "span", 24);
|
|
101
|
+
i0.ɵɵtext(10);
|
|
102
|
+
i0.ɵɵelementEnd();
|
|
103
|
+
i0.ɵɵelementStart(11, "span", 25);
|
|
104
|
+
i0.ɵɵtext(12);
|
|
105
|
+
i0.ɵɵelementEnd();
|
|
106
|
+
i0.ɵɵconditionalCreate(13, ClassifyDryRunPreviewDialogComponent_Conditional_0_Conditional_38_Conditional_13_Template, 2, 1, "span", 26);
|
|
107
|
+
i0.ɵɵelementEnd();
|
|
108
|
+
i0.ɵɵelementStart(14, "table", 27)(15, "thead")(16, "tr")(17, "th");
|
|
109
|
+
i0.ɵɵtext(18, "Tag");
|
|
110
|
+
i0.ɵɵelementEnd();
|
|
111
|
+
i0.ɵɵelementStart(19, "th");
|
|
112
|
+
i0.ɵɵtext(20, "Matched");
|
|
113
|
+
i0.ɵɵelementEnd();
|
|
114
|
+
i0.ɵɵelementStart(21, "th", 28);
|
|
115
|
+
i0.ɵɵtext(22, "Score");
|
|
116
|
+
i0.ɵɵelementEnd();
|
|
117
|
+
i0.ɵɵelementStart(23, "th");
|
|
118
|
+
i0.ɵɵtext(24, "What would happen");
|
|
119
|
+
i0.ɵɵelementEnd()()();
|
|
120
|
+
i0.ɵɵelementStart(25, "tbody");
|
|
121
|
+
i0.ɵɵrepeaterCreate(26, ClassifyDryRunPreviewDialogComponent_Conditional_0_Conditional_38_For_27_Template, 10, 7, "tr", null, i0.ɵɵrepeaterTrackByIndex);
|
|
122
|
+
i0.ɵɵelementEnd()();
|
|
123
|
+
i0.ɵɵelementStart(28, "div", 29);
|
|
124
|
+
i0.ɵɵelement(29, "i", 30);
|
|
125
|
+
i0.ɵɵtext(30, " A real run also uses a semantic / embedding match tier not reproducible here, so borderline rows may resolve differently. ");
|
|
126
|
+
i0.ɵɵelementEnd();
|
|
127
|
+
} if (rf & 2) {
|
|
128
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
129
|
+
i0.ɵɵadvance(3);
|
|
130
|
+
i0.ɵɵtextInterpolate4(" ", ctx_r1.Estimate.ItemsSampled, " sampled tag", ctx_r1.Estimate.ItemsSampled === 1 ? "" : "s", " \u00B7 est. ", ctx_r1.FormatTokens(ctx_r1.Estimate.EstimatedTokens), " tokens \u00B7 ~", ctx_r1.FormatCost(ctx_r1.Estimate.EstimatedCost), " ");
|
|
131
|
+
i0.ɵɵadvance(5);
|
|
132
|
+
i0.ɵɵtextInterpolate1("", ctx_r1.Counts.AutoApply, " auto-apply");
|
|
133
|
+
i0.ɵɵadvance(2);
|
|
134
|
+
i0.ɵɵtextInterpolate1("", ctx_r1.Counts.RouteToInbox, " \u2192 inbox");
|
|
135
|
+
i0.ɵɵadvance(2);
|
|
136
|
+
i0.ɵɵtextInterpolate1("", ctx_r1.Counts.CreateNew, " create");
|
|
137
|
+
i0.ɵɵadvance();
|
|
138
|
+
i0.ɵɵconditional(ctx_r1.Counts.Reject > 0 ? 13 : -1);
|
|
139
|
+
i0.ɵɵadvance(13);
|
|
140
|
+
i0.ɵɵrepeater(ctx_r1.Rows);
|
|
141
|
+
} }
|
|
142
|
+
function ClassifyDryRunPreviewDialogComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
143
|
+
const _r1 = i0.ɵɵgetCurrentView();
|
|
144
|
+
i0.ɵɵelementStart(0, "div", 0);
|
|
145
|
+
i0.ɵɵlistener("click", function ClassifyDryRunPreviewDialogComponent_Conditional_0_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.close()); });
|
|
146
|
+
i0.ɵɵelementEnd();
|
|
147
|
+
i0.ɵɵelementStart(1, "div", 1)(2, "div", 2)(3, "h3");
|
|
148
|
+
i0.ɵɵelement(4, "i", 3);
|
|
149
|
+
i0.ɵɵtext(5, " Dry-run preview");
|
|
150
|
+
i0.ɵɵelementEnd();
|
|
151
|
+
i0.ɵɵelementStart(6, "button", 4);
|
|
152
|
+
i0.ɵɵlistener("click", function ClassifyDryRunPreviewDialogComponent_Conditional_0_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.close()); });
|
|
153
|
+
i0.ɵɵelement(7, "i", 5);
|
|
154
|
+
i0.ɵɵelementEnd()();
|
|
155
|
+
i0.ɵɵelementStart(8, "div", 6);
|
|
156
|
+
i0.ɵɵconditionalCreate(9, ClassifyDryRunPreviewDialogComponent_Conditional_0_Conditional_9_Template, 4, 3, "div", 7);
|
|
157
|
+
i0.ɵɵelementStart(10, "div", 8);
|
|
158
|
+
i0.ɵɵelement(11, "i", 9);
|
|
159
|
+
i0.ɵɵelementStart(12, "span");
|
|
160
|
+
i0.ɵɵtext(13, " Preview of how this source's sampled tags resolve under the current ");
|
|
161
|
+
i0.ɵɵelementStart(14, "b");
|
|
162
|
+
i0.ɵɵtext(15, "mode & thresholds");
|
|
163
|
+
i0.ɵɵelementEnd();
|
|
164
|
+
i0.ɵɵtext(16, " \u2014 ");
|
|
165
|
+
i0.ɵɵelementStart(17, "b");
|
|
166
|
+
i0.ɵɵtext(18, "no LLM call, nothing persisted");
|
|
167
|
+
i0.ɵɵelementEnd();
|
|
168
|
+
i0.ɵɵtext(19, ". ");
|
|
169
|
+
i0.ɵɵelementEnd()();
|
|
170
|
+
i0.ɵɵelementStart(20, "div", 10)(21, "span", 11);
|
|
171
|
+
i0.ɵɵelement(22, "i", 3);
|
|
172
|
+
i0.ɵɵtext(23, " PREVIEW");
|
|
173
|
+
i0.ɵɵelementEnd();
|
|
174
|
+
i0.ɵɵelementStart(24, "span", 12);
|
|
175
|
+
i0.ɵɵtext(25, "Mode ");
|
|
176
|
+
i0.ɵɵelementStart(26, "b");
|
|
177
|
+
i0.ɵɵtext(27);
|
|
178
|
+
i0.ɵɵelementEnd()();
|
|
179
|
+
i0.ɵɵelementStart(28, "span", 12);
|
|
180
|
+
i0.ɵɵtext(29, "Match ");
|
|
181
|
+
i0.ɵɵelementStart(30, "b");
|
|
182
|
+
i0.ɵɵtext(31);
|
|
183
|
+
i0.ɵɵelementEnd()();
|
|
184
|
+
i0.ɵɵelementStart(32, "span", 12);
|
|
185
|
+
i0.ɵɵtext(33, "Suggest ");
|
|
186
|
+
i0.ɵɵelementStart(34, "b");
|
|
187
|
+
i0.ɵɵtext(35);
|
|
188
|
+
i0.ɵɵelementEnd()()();
|
|
189
|
+
i0.ɵɵconditionalCreate(36, ClassifyDryRunPreviewDialogComponent_Conditional_0_Conditional_36_Template, 1, 0, "mj-loading", 13)(37, ClassifyDryRunPreviewDialogComponent_Conditional_0_Conditional_37_Template, 4, 0, "div", 14)(38, ClassifyDryRunPreviewDialogComponent_Conditional_0_Conditional_38_Template, 31, 8);
|
|
190
|
+
i0.ɵɵelementStart(39, "div", 15)(40, "button", 16);
|
|
191
|
+
i0.ɵɵlistener("click", function ClassifyDryRunPreviewDialogComponent_Conditional_0_Template_button_click_40_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.close()); });
|
|
192
|
+
i0.ɵɵtext(41, "Close");
|
|
193
|
+
i0.ɵɵelementEnd()()()();
|
|
194
|
+
} if (rf & 2) {
|
|
195
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
196
|
+
i0.ɵɵadvance(9);
|
|
197
|
+
i0.ɵɵconditional(ctx_r1.SourceCard ? 9 : -1);
|
|
198
|
+
i0.ɵɵadvance(18);
|
|
199
|
+
i0.ɵɵtextInterpolate(ctx_r1.ModeLabel(ctx_r1.EffectiveMode));
|
|
200
|
+
i0.ɵɵadvance(4);
|
|
201
|
+
i0.ɵɵtextInterpolate(ctx_r1.FormatScore(ctx_r1.EffectiveMatchThreshold));
|
|
202
|
+
i0.ɵɵadvance(4);
|
|
203
|
+
i0.ɵɵtextInterpolate(ctx_r1.FormatScore(ctx_r1.EffectiveSuggestThreshold));
|
|
204
|
+
i0.ɵɵadvance();
|
|
205
|
+
i0.ɵɵconditional(ctx_r1.Loading ? 36 : ctx_r1.NoTagsSampled ? 37 : 38);
|
|
206
|
+
} }
|
|
207
|
+
/** Default routing config when a source has no explicit Configuration blob. */
|
|
208
|
+
const DEFAULT_MODE = 'auto-grow';
|
|
209
|
+
const DEFAULT_MATCH_THRESHOLD = 0.85;
|
|
210
|
+
/** Illustrative per-item token estimate for the (non-binding) cost line. */
|
|
211
|
+
const EST_TOKENS_PER_ITEM = 840;
|
|
212
|
+
/** Illustrative blended $/1K-token rate for the cost estimate. */
|
|
213
|
+
const EST_COST_PER_1K_TOKENS = 0.01;
|
|
214
|
+
/** Max existing tags to sample for the preview. */
|
|
215
|
+
const SAMPLE_SIZE = 15;
|
|
216
|
+
export class ClassifyDryRunPreviewDialogComponent extends BaseAngularComponent {
|
|
217
|
+
cdr = inject(ChangeDetectorRef);
|
|
218
|
+
/** Whether the dialog is visible. */
|
|
219
|
+
_show = false;
|
|
220
|
+
set Show(value) {
|
|
221
|
+
const opening = value && !this._show;
|
|
222
|
+
this._show = value;
|
|
223
|
+
if (opening && this._sourceCard) {
|
|
224
|
+
void this.runPreview(this._sourceCard);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
get Show() {
|
|
228
|
+
return this._show;
|
|
229
|
+
}
|
|
230
|
+
/** The source being previewed; supplied by the Sources tab when opening. */
|
|
231
|
+
_sourceCard = null;
|
|
232
|
+
set SourceCard(value) {
|
|
233
|
+
this._sourceCard = value;
|
|
234
|
+
if (value && this._show) {
|
|
235
|
+
void this.runPreview(value);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
get SourceCard() {
|
|
239
|
+
return this._sourceCard;
|
|
240
|
+
}
|
|
241
|
+
/** Emitted when the user dismisses the dialog. */
|
|
242
|
+
Closed = new EventEmitter();
|
|
243
|
+
// ── View state ──
|
|
244
|
+
Loading = false;
|
|
245
|
+
Rows = [];
|
|
246
|
+
Counts = { AutoApply: 0, RouteToInbox: 0, CreateNew: 0, Reject: 0 };
|
|
247
|
+
Estimate = { ItemsSampled: 0, EstimatedTokens: 0, EstimatedCost: 0 };
|
|
248
|
+
/** Effective config used for this preview (mirrored for the "effective values" line). */
|
|
249
|
+
EffectiveMode = DEFAULT_MODE;
|
|
250
|
+
EffectiveMatchThreshold = DEFAULT_MATCH_THRESHOLD;
|
|
251
|
+
EffectiveSuggestThreshold = DEFAULT_MATCH_THRESHOLD - 0.05;
|
|
252
|
+
/** True when the sampled source has no extracted tags yet. */
|
|
253
|
+
NoTagsSampled = false;
|
|
254
|
+
close() {
|
|
255
|
+
this.Closed.emit();
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Load a sample of the source's existing extracted tags, resolve each against
|
|
259
|
+
* the cached taxonomy, and produce the preview rows + summary. Read-only —
|
|
260
|
+
* nothing is written.
|
|
261
|
+
*/
|
|
262
|
+
async runPreview(card) {
|
|
263
|
+
this.Loading = true;
|
|
264
|
+
this.Rows = [];
|
|
265
|
+
this.NoTagsSampled = false;
|
|
266
|
+
this.cdr.detectChanges();
|
|
267
|
+
try {
|
|
268
|
+
const p = this.ProviderToUse;
|
|
269
|
+
await TagEngineBase.Instance.Config(false, p.CurrentUser, p);
|
|
270
|
+
await KnowledgeHubMetadataEngine.Instance.Config(false, p.CurrentUser, p);
|
|
271
|
+
const cfg = this.resolveSourceConfig(card.ID);
|
|
272
|
+
this.EffectiveMode = cfg.mode;
|
|
273
|
+
this.EffectiveMatchThreshold = cfg.matchThreshold;
|
|
274
|
+
this.EffectiveSuggestThreshold = cfg.suggestThreshold;
|
|
275
|
+
const inputs = await this.loadSampleTags(card.ID);
|
|
276
|
+
if (inputs.length === 0) {
|
|
277
|
+
this.NoTagsSampled = true;
|
|
278
|
+
this.Estimate = { ItemsSampled: 0, EstimatedTokens: 0, EstimatedCost: 0 };
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
const resolve = this.buildResolver();
|
|
282
|
+
this.Rows = previewDispositions(inputs, cfg, resolve);
|
|
283
|
+
this.Counts = this.tally(this.Rows);
|
|
284
|
+
this.Estimate = this.estimate(inputs.length);
|
|
285
|
+
}
|
|
286
|
+
catch (error) {
|
|
287
|
+
console.error('[Classify] Dry-run preview error:', error);
|
|
288
|
+
}
|
|
289
|
+
finally {
|
|
290
|
+
this.Loading = false;
|
|
291
|
+
this.cdr.detectChanges();
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Sample up to SAMPLE_SIZE existing ContentItemTags for the source. We first
|
|
296
|
+
* pull a handful of the source's items, then their tags — the simplest path
|
|
297
|
+
* that avoids depending on a direct source-level filter on ContentItemTags.
|
|
298
|
+
*/
|
|
299
|
+
async loadSampleTags(sourceID) {
|
|
300
|
+
const rv = RunView.FromMetadataProvider(this.ProviderToUse);
|
|
301
|
+
const itemResult = await rv.RunView({
|
|
302
|
+
EntityName: 'MJ: Content Items',
|
|
303
|
+
ExtraFilter: `ContentSourceID='${sourceID}'`,
|
|
304
|
+
OrderBy: '__mj_UpdatedAt DESC',
|
|
305
|
+
Fields: ['ID'],
|
|
306
|
+
MaxRows: SAMPLE_SIZE,
|
|
307
|
+
ResultType: 'simple',
|
|
308
|
+
});
|
|
309
|
+
if (!itemResult.Success || itemResult.Results.length === 0)
|
|
310
|
+
return [];
|
|
311
|
+
const itemIds = itemResult.Results.map(i => i.ID);
|
|
312
|
+
const inClause = itemIds.map(id => `'${id}'`).join(',');
|
|
313
|
+
const tagResult = await rv.RunView({
|
|
314
|
+
EntityName: 'MJ: Content Item Tags',
|
|
315
|
+
ExtraFilter: `ItemID IN (${inClause})`,
|
|
316
|
+
Fields: ['Tag', 'TagID', 'Weight'],
|
|
317
|
+
MaxRows: SAMPLE_SIZE,
|
|
318
|
+
ResultType: 'simple',
|
|
319
|
+
});
|
|
320
|
+
if (!tagResult.Success)
|
|
321
|
+
return [];
|
|
322
|
+
return tagResult.Results
|
|
323
|
+
.filter(t => !!t.Tag)
|
|
324
|
+
.map(t => ({
|
|
325
|
+
tag: t.Tag,
|
|
326
|
+
resolvedTagId: t.TagID ?? null,
|
|
327
|
+
weight: Number(t.Weight ?? 1),
|
|
328
|
+
}));
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Read the source's effective taxonomy config from its ConfigurationObject,
|
|
332
|
+
* falling back to documented runtime defaults. SuggestThreshold defaults to
|
|
333
|
+
* matchThreshold − 0.05 (matches the server's runtime default).
|
|
334
|
+
*/
|
|
335
|
+
resolveSourceConfig(sourceID) {
|
|
336
|
+
const source = KnowledgeHubMetadataEngine.Instance.ContentSources.find(cs => UUIDsEqual(cs.ID, sourceID));
|
|
337
|
+
const config = source?.ConfigurationObject ?? null;
|
|
338
|
+
const mode = config?.TagTaxonomyMode ?? DEFAULT_MODE;
|
|
339
|
+
const matchThreshold = config?.TagMatchThreshold ?? DEFAULT_MATCH_THRESHOLD;
|
|
340
|
+
const suggestThreshold = config?.SuggestThreshold ?? matchThreshold - 0.05;
|
|
341
|
+
return { mode, matchThreshold, suggestThreshold };
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Build the client-side resolver closure over the cached taxonomy.
|
|
345
|
+
* tier 'synonym' if the tag matches a TagSynonym (case-insensitive),
|
|
346
|
+
* 'exact' if it matches a Tag Name (case-insensitive), 'fuzzy' if a
|
|
347
|
+
* normalized match (lowercase, strip plurals/hyphens) hits, else 'none'.
|
|
348
|
+
*/
|
|
349
|
+
buildResolver() {
|
|
350
|
+
const engine = TagEngineBase.Instance;
|
|
351
|
+
const activeTags = engine.Tags.filter(t => t.Status === 'Active');
|
|
352
|
+
// synonym text (lower) → owning Tag
|
|
353
|
+
const synonymMap = new Map();
|
|
354
|
+
const tagById = new Map();
|
|
355
|
+
for (const t of activeTags) {
|
|
356
|
+
tagById.set(t.ID.toLowerCase(), { id: t.ID, name: t.Name });
|
|
357
|
+
}
|
|
358
|
+
for (const syn of engine.TagSynonyms) {
|
|
359
|
+
// Only Active synonyms resolve — Pending (proposed, unapproved) and
|
|
360
|
+
// Rejected ones are not live, matching the server-side resolver.
|
|
361
|
+
if (syn.Status !== 'Active')
|
|
362
|
+
continue;
|
|
363
|
+
const owner = tagById.get((syn.TagID ?? '').toLowerCase());
|
|
364
|
+
if (owner && syn.Synonym) {
|
|
365
|
+
synonymMap.set(syn.Synonym.trim().toLowerCase(), owner);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
// exact name (lower) → Tag; normalized name (lower) → Tag (for fuzzy tier)
|
|
369
|
+
const exactMap = new Map();
|
|
370
|
+
const normalizedMap = new Map();
|
|
371
|
+
for (const t of activeTags) {
|
|
372
|
+
const entry = { id: t.ID, name: t.Name };
|
|
373
|
+
exactMap.set(t.Name.trim().toLowerCase(), entry);
|
|
374
|
+
normalizedMap.set(this.normalize(t.Name), entry);
|
|
375
|
+
}
|
|
376
|
+
return (tag) => {
|
|
377
|
+
const lower = tag.trim().toLowerCase();
|
|
378
|
+
const syn = synonymMap.get(lower);
|
|
379
|
+
if (syn)
|
|
380
|
+
return { tagId: syn.id, tagName: syn.name, score: 1.0, tier: 'synonym' };
|
|
381
|
+
const exact = exactMap.get(lower);
|
|
382
|
+
if (exact)
|
|
383
|
+
return { tagId: exact.id, tagName: exact.name, score: 1.0, tier: 'exact' };
|
|
384
|
+
const fuzzy = normalizedMap.get(this.normalize(tag));
|
|
385
|
+
if (fuzzy)
|
|
386
|
+
return { tagId: fuzzy.id, tagName: fuzzy.name, score: 0.8, tier: 'fuzzy' };
|
|
387
|
+
return { tagId: null, tagName: null, score: null, tier: 'none' };
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
/** Lowercase, strip hyphens/underscores/whitespace and a trailing plural 's'. */
|
|
391
|
+
normalize(value) {
|
|
392
|
+
let v = value.trim().toLowerCase().replace(/[-_\s]+/g, '');
|
|
393
|
+
if (v.endsWith('s') && v.length > 3)
|
|
394
|
+
v = v.slice(0, -1);
|
|
395
|
+
return v;
|
|
396
|
+
}
|
|
397
|
+
tally(rows) {
|
|
398
|
+
const counts = { AutoApply: 0, RouteToInbox: 0, CreateNew: 0, Reject: 0 };
|
|
399
|
+
for (const r of rows) {
|
|
400
|
+
switch (r.disposition) {
|
|
401
|
+
case 'auto-apply':
|
|
402
|
+
counts.AutoApply++;
|
|
403
|
+
break;
|
|
404
|
+
case 'route-to-inbox':
|
|
405
|
+
counts.RouteToInbox++;
|
|
406
|
+
break;
|
|
407
|
+
case 'create-new':
|
|
408
|
+
counts.CreateNew++;
|
|
409
|
+
break;
|
|
410
|
+
case 'reject':
|
|
411
|
+
counts.Reject++;
|
|
412
|
+
break;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
return counts;
|
|
416
|
+
}
|
|
417
|
+
estimate(itemsSampled) {
|
|
418
|
+
const tokens = itemsSampled * EST_TOKENS_PER_ITEM;
|
|
419
|
+
const cost = (tokens / 1000) * EST_COST_PER_1K_TOKENS;
|
|
420
|
+
return { ItemsSampled: itemsSampled, EstimatedTokens: tokens, EstimatedCost: cost };
|
|
421
|
+
}
|
|
422
|
+
// ── Template helpers ──
|
|
423
|
+
/** Status-token-backed CSS class for a disposition pill. */
|
|
424
|
+
DispositionClass(d) {
|
|
425
|
+
switch (d) {
|
|
426
|
+
case 'auto-apply': return 'disp disp-apply';
|
|
427
|
+
case 'route-to-inbox': return 'disp disp-inbox';
|
|
428
|
+
case 'create-new': return 'disp disp-create';
|
|
429
|
+
case 'reject': return 'disp disp-reject';
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
/** Human label for a disposition pill. */
|
|
433
|
+
DispositionLabel(d) {
|
|
434
|
+
switch (d) {
|
|
435
|
+
case 'auto-apply': return 'AUTO-APPLY';
|
|
436
|
+
case 'route-to-inbox': return '→ INBOX';
|
|
437
|
+
case 'create-new': return this.EffectiveMode === 'free-flow' ? 'CREATE (free-flow)' : 'CREATE (auto-grow)';
|
|
438
|
+
case 'reject': return 'REJECT';
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
FormatScore(score) {
|
|
442
|
+
return score == null ? '—' : score.toFixed(2);
|
|
443
|
+
}
|
|
444
|
+
FormatTokens(tokens) {
|
|
445
|
+
return tokens.toLocaleString();
|
|
446
|
+
}
|
|
447
|
+
FormatCost(cost) {
|
|
448
|
+
return `$${cost.toFixed(2)}`;
|
|
449
|
+
}
|
|
450
|
+
ModeLabel(mode) {
|
|
451
|
+
switch (mode) {
|
|
452
|
+
case 'constrained': return 'Constrained';
|
|
453
|
+
case 'auto-grow': return 'Auto-grow';
|
|
454
|
+
case 'free-flow': return 'Free-flow';
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
static ɵfac = /*@__PURE__*/ (() => { let ɵClassifyDryRunPreviewDialogComponent_BaseFactory; return function ClassifyDryRunPreviewDialogComponent_Factory(__ngFactoryType__) { return (ɵClassifyDryRunPreviewDialogComponent_BaseFactory || (ɵClassifyDryRunPreviewDialogComponent_BaseFactory = i0.ɵɵgetInheritedFactory(ClassifyDryRunPreviewDialogComponent)))(__ngFactoryType__ || ClassifyDryRunPreviewDialogComponent); }; })();
|
|
458
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ClassifyDryRunPreviewDialogComponent, selectors: [["classify-dry-run-preview"]], inputs: { Show: "Show", SourceCard: "SourceCard" }, outputs: { Closed: "Closed" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 1, vars: 1, consts: [[1, "at-slide-overlay", 3, "click"], [1, "at-slide-panel", "dry-run-panel"], [1, "at-slide-header"], [1, "fa-solid", "fa-flask"], ["aria-label", "Close dry-run preview", 1, "at-slide-close", 3, "click"], [1, "fa-solid", "fa-times"], [1, "at-slide-body"], [1, "dry-source-line"], [1, "dry-banner"], [1, "fa-solid", "fa-circle-info"], [1, "dry-effective"], [1, "pill", "purple"], [1, "dry-eff-item"], ["text", "Sampling existing tags\u2026"], [1, "dry-empty"], [1, "dry-footer"], ["mjButton", "", "variant", "primary", "size", "sm", 3, "click"], [1, "dry-source-name"], [1, "fa-solid", "fa-tags"], [1, "dry-estimate"], [1, "fa-solid", "fa-calculator"], [1, "dry-est-note"], [1, "dry-summary"], [1, "disp", "disp-apply"], [1, "disp", "disp-inbox"], [1, "disp", "disp-create"], [1, "disp", "disp-reject"], [1, "dry-table"], [1, "dry-col-score"], [1, "dry-disclaimer"], [1, "fa-solid", "fa-triangle-exclamation"], [1, "dry-cell-tag"], [1, "dry-cell-matched"], [1, "dry-col-score", "dry-mono"], [3, "title"]], template: function ClassifyDryRunPreviewDialogComponent_Template(rf, ctx) { if (rf & 1) {
|
|
459
|
+
i0.ɵɵconditionalCreate(0, ClassifyDryRunPreviewDialogComponent_Conditional_0_Template, 42, 5);
|
|
460
|
+
} if (rf & 2) {
|
|
461
|
+
i0.ɵɵconditional(ctx.Show ? 0 : -1);
|
|
462
|
+
} }, dependencies: [i1.LoadingComponent, i2.MJButtonDirective], styles: ["\n\n\n\n\n\n\n.dry-run-panel[_ngcontent-%COMP%] {\n width: 640px;\n max-width: 92vw;\n}\n\n.dry-source-line[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 0.95rem;\n color: var(--mj-text-primary);\n margin-bottom: 12px;\n}\n.dry-source-line[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n}\n.dry-source-name[_ngcontent-%COMP%] {\n font-weight: 600;\n}\n\n\n\n.dry-banner[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 10px 12px;\n border-radius: 8px;\n background: color-mix(in srgb, var(--mj-status-info) 8%, var(--mj-bg-surface));\n border: 1px solid var(--mj-status-info-border);\n color: var(--mj-status-info-text);\n font-size: 0.85rem;\n line-height: 1.4;\n margin-bottom: 14px;\n}\n.dry-banner[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n margin-top: 2px;\n}\n\n\n\n.dry-effective[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 10px;\n margin-bottom: 14px;\n}\n.dry-eff-item[_ngcontent-%COMP%] {\n font-size: 0.8rem;\n color: var(--mj-text-secondary);\n}\n.dry-eff-item[_ngcontent-%COMP%] b[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n}\n\n.pill[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 3px 9px;\n border-radius: 999px;\n font-size: 0.72rem;\n font-weight: 700;\n letter-spacing: 0.03em;\n}\n.pill.purple[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n\n\n.dry-estimate[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 0.82rem;\n color: var(--mj-text-secondary);\n margin-bottom: 12px;\n}\n.dry-est-note[_ngcontent-%COMP%] {\n font-style: italic;\n color: var(--mj-text-muted);\n}\n\n\n\n.dry-summary[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n margin-bottom: 14px;\n}\n\n\n\n.disp[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 3px 9px;\n border-radius: 6px;\n font-size: 0.72rem;\n font-weight: 700;\n letter-spacing: 0.02em;\n white-space: nowrap;\n}\n.disp-apply[_ngcontent-%COMP%] {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success-text);\n border: 1px solid var(--mj-status-success-border);\n}\n.disp-inbox[_ngcontent-%COMP%] {\n background: var(--mj-status-warning-bg);\n color: var(--mj-status-warning-text);\n border: 1px solid var(--mj-status-warning-border);\n}\n.disp-create[_ngcontent-%COMP%] {\n background: var(--mj-status-info-bg);\n color: var(--mj-status-info-text);\n border: 1px solid var(--mj-status-info-border);\n}\n.disp-reject[_ngcontent-%COMP%] {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error-text);\n border: 1px solid var(--mj-status-error-border);\n}\n\n\n\n.dry-table[_ngcontent-%COMP%] {\n width: 100%;\n border-collapse: collapse;\n font-size: 0.84rem;\n margin-bottom: 14px;\n}\n.dry-table[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n text-align: left;\n font-weight: 600;\n color: var(--mj-text-secondary);\n padding: 6px 8px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n.dry-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 7px 8px;\n border-bottom: 1px solid var(--mj-border-subtle);\n color: var(--mj-text-primary);\n vertical-align: middle;\n}\n.dry-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n.dry-cell-tag[_ngcontent-%COMP%] {\n font-weight: 500;\n}\n.dry-cell-matched[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n}\n.dry-col-score[_ngcontent-%COMP%] {\n text-align: right;\n width: 64px;\n}\n.dry-mono[_ngcontent-%COMP%] {\n font-family: var(--mj-font-mono, monospace);\n color: var(--mj-text-secondary);\n}\n\n.dry-disclaimer[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n font-size: 0.78rem;\n color: var(--mj-text-muted);\n line-height: 1.4;\n margin-bottom: 16px;\n}\n.dry-disclaimer[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n margin-top: 2px;\n color: var(--mj-status-warning);\n}\n\n.dry-empty[_ngcontent-%COMP%] {\n text-align: center;\n padding: 32px 16px;\n color: var(--mj-text-muted);\n}\n.dry-empty[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1.8rem;\n margin-bottom: 10px;\n color: var(--mj-text-disabled);\n}\n.dry-empty[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n font-size: 0.88rem;\n line-height: 1.5;\n max-width: 420px;\n margin: 0 auto;\n}\n\n.dry-footer[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n margin-top: 4px;\n}"] });
|
|
463
|
+
}
|
|
464
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ClassifyDryRunPreviewDialogComponent, [{
|
|
465
|
+
type: Component,
|
|
466
|
+
args: [{ standalone: false, selector: 'classify-dry-run-preview', template: "<!-- \u2550\u2550\u2550\u2550\u2550\u2550 DRY-RUN / DISPOSITION PREVIEW SLIDE-IN \u2550\u2550\u2550\u2550\u2550\u2550 -->\n@if (Show) {\n <div class=\"at-slide-overlay\" (click)=\"close()\"></div>\n <div class=\"at-slide-panel dry-run-panel\">\n <div class=\"at-slide-header\">\n <h3><i class=\"fa-solid fa-flask\"></i> Dry-run preview</h3>\n <button class=\"at-slide-close\" aria-label=\"Close dry-run preview\" (click)=\"close()\"><i class=\"fa-solid fa-times\"></i></button>\n </div>\n\n <div class=\"at-slide-body\">\n <!-- Source + intent line -->\n @if (SourceCard) {\n <div class=\"dry-source-line\">\n <i [class]=\"SourceCard.Icon\"></i>\n <span class=\"dry-source-name\">{{ SourceCard.Name }}</span>\n </div>\n }\n\n <!-- \"nothing persisted\" banner -->\n <div class=\"dry-banner\">\n <i class=\"fa-solid fa-circle-info\"></i>\n <span>\n Preview of how this source's sampled tags resolve under the current\n <b>mode & thresholds</b> \u2014 <b>no LLM call, nothing persisted</b>.\n </span>\n </div>\n\n <!-- Effective config -->\n <div class=\"dry-effective\">\n <span class=\"pill purple\"><i class=\"fa-solid fa-flask\"></i> PREVIEW</span>\n <span class=\"dry-eff-item\">Mode <b>{{ ModeLabel(EffectiveMode) }}</b></span>\n <span class=\"dry-eff-item\">Match <b>{{ FormatScore(EffectiveMatchThreshold) }}</b></span>\n <span class=\"dry-eff-item\">Suggest <b>{{ FormatScore(EffectiveSuggestThreshold) }}</b></span>\n </div>\n\n @if (Loading) {\n <mj-loading text=\"Sampling existing tags\u2026\"></mj-loading>\n } @else if (NoTagsSampled) {\n <div class=\"dry-empty\">\n <i class=\"fa-solid fa-tags\"></i>\n <p>No extracted tags found for this source yet. Run the pipeline first, then preview how its tags would be dispositioned.</p>\n </div>\n } @else {\n <!-- Estimate line (illustrative) -->\n <div class=\"dry-estimate\">\n <i class=\"fa-solid fa-calculator\"></i>\n <span>\n {{ Estimate.ItemsSampled }} sampled tag{{ Estimate.ItemsSampled === 1 ? '' : 's' }} \u00B7\n est. {{ FormatTokens(Estimate.EstimatedTokens) }} tokens \u00B7\n ~{{ FormatCost(Estimate.EstimatedCost) }}\n <span class=\"dry-est-note\">(rough estimate)</span>\n </span>\n </div>\n\n <!-- Summary counts -->\n <div class=\"dry-summary\">\n <span class=\"disp disp-apply\">{{ Counts.AutoApply }} auto-apply</span>\n <span class=\"disp disp-inbox\">{{ Counts.RouteToInbox }} \u2192 inbox</span>\n <span class=\"disp disp-create\">{{ Counts.CreateNew }} create</span>\n @if (Counts.Reject > 0) {\n <span class=\"disp disp-reject\">{{ Counts.Reject }} reject</span>\n }\n </div>\n\n <!-- Disposition table -->\n <table class=\"dry-table\">\n <thead>\n <tr>\n <th>Tag</th>\n <th>Matched</th>\n <th class=\"dry-col-score\">Score</th>\n <th>What would happen</th>\n </tr>\n </thead>\n <tbody>\n @for (row of Rows; track $index) {\n <tr>\n <td class=\"dry-cell-tag\">{{ row.tag }}</td>\n <td class=\"dry-cell-matched\">{{ row.matchedTag ?? '\u2014' }}</td>\n <td class=\"dry-col-score dry-mono\">{{ FormatScore(row.score) }}</td>\n <td>\n <span [class]=\"DispositionClass(row.disposition)\" [title]=\"row.reason\">\n {{ DispositionLabel(row.disposition) }}\n </span>\n </td>\n </tr>\n }\n </tbody>\n </table>\n\n <div class=\"dry-disclaimer\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n A real run also uses a semantic / embedding match tier not reproducible here,\n so borderline rows may resolve differently.\n </div>\n }\n\n <!-- Footer -->\n <div class=\"dry-footer\">\n <button mjButton variant=\"primary\" size=\"sm\" (click)=\"close()\">Close</button>\n </div>\n </div>\n </div>\n}\n", styles: ["/**\n * Dry-run preview dialog \u2014 net-new rules only. The slide-in shell (.at-slide-*)\n * is owned by the host (ViewEncapsulation.None) and already styles the panel.\n * Disposition pills use semantic status tokens so they adapt to dark mode.\n */\n\n.dry-run-panel {\n width: 640px;\n max-width: 92vw;\n}\n\n.dry-source-line {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 0.95rem;\n color: var(--mj-text-primary);\n margin-bottom: 12px;\n}\n.dry-source-line i {\n color: var(--mj-text-secondary);\n}\n.dry-source-name {\n font-weight: 600;\n}\n\n/* \"nothing persisted\" banner */\n.dry-banner {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 10px 12px;\n border-radius: 8px;\n background: color-mix(in srgb, var(--mj-status-info) 8%, var(--mj-bg-surface));\n border: 1px solid var(--mj-status-info-border);\n color: var(--mj-status-info-text);\n font-size: 0.85rem;\n line-height: 1.4;\n margin-bottom: 14px;\n}\n.dry-banner i {\n margin-top: 2px;\n}\n\n/* effective config row */\n.dry-effective {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 10px;\n margin-bottom: 14px;\n}\n.dry-eff-item {\n font-size: 0.8rem;\n color: var(--mj-text-secondary);\n}\n.dry-eff-item b {\n color: var(--mj-text-primary);\n}\n\n.pill {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 3px 9px;\n border-radius: 999px;\n font-size: 0.72rem;\n font-weight: 700;\n letter-spacing: 0.03em;\n}\n.pill.purple {\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n/* estimate line */\n.dry-estimate {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 0.82rem;\n color: var(--mj-text-secondary);\n margin-bottom: 12px;\n}\n.dry-est-note {\n font-style: italic;\n color: var(--mj-text-muted);\n}\n\n/* summary counts */\n.dry-summary {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n margin-bottom: 14px;\n}\n\n/* disposition pills (status-token backed) */\n.disp {\n display: inline-flex;\n align-items: center;\n padding: 3px 9px;\n border-radius: 6px;\n font-size: 0.72rem;\n font-weight: 700;\n letter-spacing: 0.02em;\n white-space: nowrap;\n}\n.disp-apply {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success-text);\n border: 1px solid var(--mj-status-success-border);\n}\n.disp-inbox {\n background: var(--mj-status-warning-bg);\n color: var(--mj-status-warning-text);\n border: 1px solid var(--mj-status-warning-border);\n}\n.disp-create {\n background: var(--mj-status-info-bg);\n color: var(--mj-status-info-text);\n border: 1px solid var(--mj-status-info-border);\n}\n.disp-reject {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error-text);\n border: 1px solid var(--mj-status-error-border);\n}\n\n/* table */\n.dry-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 0.84rem;\n margin-bottom: 14px;\n}\n.dry-table thead th {\n text-align: left;\n font-weight: 600;\n color: var(--mj-text-secondary);\n padding: 6px 8px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n.dry-table tbody td {\n padding: 7px 8px;\n border-bottom: 1px solid var(--mj-border-subtle);\n color: var(--mj-text-primary);\n vertical-align: middle;\n}\n.dry-table tbody tr:hover {\n background: var(--mj-bg-surface-hover);\n}\n.dry-cell-tag {\n font-weight: 500;\n}\n.dry-cell-matched {\n color: var(--mj-text-secondary);\n}\n.dry-col-score {\n text-align: right;\n width: 64px;\n}\n.dry-mono {\n font-family: var(--mj-font-mono, monospace);\n color: var(--mj-text-secondary);\n}\n\n.dry-disclaimer {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n font-size: 0.78rem;\n color: var(--mj-text-muted);\n line-height: 1.4;\n margin-bottom: 16px;\n}\n.dry-disclaimer i {\n margin-top: 2px;\n color: var(--mj-status-warning);\n}\n\n.dry-empty {\n text-align: center;\n padding: 32px 16px;\n color: var(--mj-text-muted);\n}\n.dry-empty i {\n font-size: 1.8rem;\n margin-bottom: 10px;\n color: var(--mj-text-disabled);\n}\n.dry-empty p {\n font-size: 0.88rem;\n line-height: 1.5;\n max-width: 420px;\n margin: 0 auto;\n}\n\n.dry-footer {\n display: flex;\n gap: 8px;\n margin-top: 4px;\n}\n"] }]
|
|
467
|
+
}], null, { Show: [{
|
|
468
|
+
type: Input
|
|
469
|
+
}], SourceCard: [{
|
|
470
|
+
type: Input
|
|
471
|
+
}], Closed: [{
|
|
472
|
+
type: Output
|
|
473
|
+
}] }); })();
|
|
474
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ClassifyDryRunPreviewDialogComponent, { className: "ClassifyDryRunPreviewDialogComponent", filePath: "src/AI/components/autotagging/dialogs/dry-run-preview.dialog.component.ts", lineNumber: 46 }); })();
|
|
475
|
+
//# sourceMappingURL=dry-run-preview.dialog.component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dry-run-preview.dialog.component.js","sourceRoot":"","sources":["../../../../../src/AI/components/autotagging/dialogs/dry-run-preview.dialog.component.ts","../../../../../src/AI/components/autotagging/dialogs/dry-run-preview.dialog.component.html"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Classify · Dry-run / disposition PREVIEW dialog.\n *\n * Honest, client-side, in-memory preview of how a source's EXISTING extracted\n * ContentItemTags would be dispositioned under its current taxonomy mode +\n * thresholds. This is NOT a fresh LLM run and NOTHING is persisted — it samples\n * up to N existing tags, resolves each against the cached taxonomy\n * (Tags / TagSynonyms) client-side, and replays the deterministic routing via the\n * pure `previewDispositions` helper.\n *\n * It is hosted by the Sources tab (which already hosts its own dialogs): data\n * DOWN via `[SourceCard]` / `[Show]`, intent UP via `(Closed)`. On open it loads\n * the sample itself (read-only RunView, `ResultType: 'simple'`).\n *\n * NOTE: the server also has a semantic/embedding match tier not reproducible\n * client-side, so borderline rows may resolve differently in a real run. The\n * template states this explicitly.\n */\nimport { Component, ChangeDetectorRef, EventEmitter, Input, Output, inject } from '@angular/core';\nimport { RunView } from '@memberjunction/core';\nimport { UUIDsEqual } from '@memberjunction/global';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { TagEngineBase } from '@memberjunction/tag-engine-base';\nimport { KnowledgeHubMetadataEngine } from '@memberjunction/core-entities';\nimport { SourceCard, DryRunDispositionCount, DryRunEstimate } from '../shared/classify.types';\nimport {\n previewDispositions, DryRunInput, DryRunConfig, DryRunRow, ResolveResult, Disposition,\n} from '../shared/classify.dryrun';\n\n/** Default routing config when a source has no explicit Configuration blob. */\nconst DEFAULT_MODE: DryRunConfig['mode'] = 'auto-grow';\nconst DEFAULT_MATCH_THRESHOLD = 0.85;\n/** Illustrative per-item token estimate for the (non-binding) cost line. */\nconst EST_TOKENS_PER_ITEM = 840;\n/** Illustrative blended $/1K-token rate for the cost estimate. */\nconst EST_COST_PER_1K_TOKENS = 0.01;\n/** Max existing tags to sample for the preview. */\nconst SAMPLE_SIZE = 15;\n\n@Component({\n standalone: false,\n selector: 'classify-dry-run-preview',\n templateUrl: './dry-run-preview.dialog.component.html',\n styleUrls: ['./dry-run-preview.dialog.component.css'],\n})\nexport class ClassifyDryRunPreviewDialogComponent extends BaseAngularComponent {\n private cdr = inject(ChangeDetectorRef);\n\n /** Whether the dialog is visible. */\n private _show = false;\n @Input()\n set Show(value: boolean) {\n const opening = value && !this._show;\n this._show = value;\n if (opening && this._sourceCard) {\n void this.runPreview(this._sourceCard);\n }\n }\n get Show(): boolean {\n return this._show;\n }\n\n /** The source being previewed; supplied by the Sources tab when opening. */\n private _sourceCard: SourceCard | null = null;\n @Input()\n set SourceCard(value: SourceCard | null) {\n this._sourceCard = value;\n if (value && this._show) {\n void this.runPreview(value);\n }\n }\n get SourceCard(): SourceCard | null {\n return this._sourceCard;\n }\n\n /** Emitted when the user dismisses the dialog. */\n @Output() Closed = new EventEmitter<void>();\n\n // ── View state ──\n\n public Loading = false;\n public Rows: DryRunRow[] = [];\n public Counts: DryRunDispositionCount = { AutoApply: 0, RouteToInbox: 0, CreateNew: 0, Reject: 0 };\n public Estimate: DryRunEstimate = { ItemsSampled: 0, EstimatedTokens: 0, EstimatedCost: 0 };\n /** Effective config used for this preview (mirrored for the \"effective values\" line). */\n public EffectiveMode: DryRunConfig['mode'] = DEFAULT_MODE;\n public EffectiveMatchThreshold = DEFAULT_MATCH_THRESHOLD;\n public EffectiveSuggestThreshold = DEFAULT_MATCH_THRESHOLD - 0.05;\n /** True when the sampled source has no extracted tags yet. */\n public NoTagsSampled = false;\n\n public close(): void {\n this.Closed.emit();\n }\n\n /**\n * Load a sample of the source's existing extracted tags, resolve each against\n * the cached taxonomy, and produce the preview rows + summary. Read-only —\n * nothing is written.\n */\n private async runPreview(card: SourceCard): Promise<void> {\n this.Loading = true;\n this.Rows = [];\n this.NoTagsSampled = false;\n this.cdr.detectChanges();\n\n try {\n const p = this.ProviderToUse;\n await TagEngineBase.Instance.Config(false, p.CurrentUser, p);\n await KnowledgeHubMetadataEngine.Instance.Config(false, p.CurrentUser, p);\n\n const cfg = this.resolveSourceConfig(card.ID);\n this.EffectiveMode = cfg.mode;\n this.EffectiveMatchThreshold = cfg.matchThreshold;\n this.EffectiveSuggestThreshold = cfg.suggestThreshold;\n\n const inputs = await this.loadSampleTags(card.ID);\n if (inputs.length === 0) {\n this.NoTagsSampled = true;\n this.Estimate = { ItemsSampled: 0, EstimatedTokens: 0, EstimatedCost: 0 };\n return;\n }\n\n const resolve = this.buildResolver();\n this.Rows = previewDispositions(inputs, cfg, resolve);\n this.Counts = this.tally(this.Rows);\n this.Estimate = this.estimate(inputs.length);\n } catch (error) {\n console.error('[Classify] Dry-run preview error:', error);\n } finally {\n this.Loading = false;\n this.cdr.detectChanges();\n }\n }\n\n /**\n * Sample up to SAMPLE_SIZE existing ContentItemTags for the source. We first\n * pull a handful of the source's items, then their tags — the simplest path\n * that avoids depending on a direct source-level filter on ContentItemTags.\n */\n private async loadSampleTags(sourceID: string): Promise<DryRunInput[]> {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n\n const itemResult = await rv.RunView<{ ID: string }>({\n EntityName: 'MJ: Content Items',\n ExtraFilter: `ContentSourceID='${sourceID}'`,\n OrderBy: '__mj_UpdatedAt DESC',\n Fields: ['ID'],\n MaxRows: SAMPLE_SIZE,\n ResultType: 'simple',\n });\n if (!itemResult.Success || itemResult.Results.length === 0) return [];\n\n const itemIds = itemResult.Results.map(i => i.ID);\n const inClause = itemIds.map(id => `'${id}'`).join(',');\n\n const tagResult = await rv.RunView<{ Tag: string; TagID: string | null; Weight: number | null }>({\n EntityName: 'MJ: Content Item Tags',\n ExtraFilter: `ItemID IN (${inClause})`,\n Fields: ['Tag', 'TagID', 'Weight'],\n MaxRows: SAMPLE_SIZE,\n ResultType: 'simple',\n });\n if (!tagResult.Success) return [];\n\n return tagResult.Results\n .filter(t => !!t.Tag)\n .map(t => ({\n tag: t.Tag,\n resolvedTagId: t.TagID ?? null,\n weight: Number(t.Weight ?? 1),\n }));\n }\n\n /**\n * Read the source's effective taxonomy config from its ConfigurationObject,\n * falling back to documented runtime defaults. SuggestThreshold defaults to\n * matchThreshold − 0.05 (matches the server's runtime default).\n */\n private resolveSourceConfig(sourceID: string): DryRunConfig {\n const source = KnowledgeHubMetadataEngine.Instance.ContentSources.find(cs => UUIDsEqual(cs.ID, sourceID));\n const config = source?.ConfigurationObject ?? null;\n\n const mode = config?.TagTaxonomyMode ?? DEFAULT_MODE;\n const matchThreshold = config?.TagMatchThreshold ?? DEFAULT_MATCH_THRESHOLD;\n const suggestThreshold = config?.SuggestThreshold ?? matchThreshold - 0.05;\n\n return { mode, matchThreshold, suggestThreshold };\n }\n\n /**\n * Build the client-side resolver closure over the cached taxonomy.\n * tier 'synonym' if the tag matches a TagSynonym (case-insensitive),\n * 'exact' if it matches a Tag Name (case-insensitive), 'fuzzy' if a\n * normalized match (lowercase, strip plurals/hyphens) hits, else 'none'.\n */\n private buildResolver(): (tag: string) => ResolveResult {\n const engine = TagEngineBase.Instance;\n const activeTags = engine.Tags.filter(t => t.Status === 'Active');\n\n // synonym text (lower) → owning Tag\n const synonymMap = new Map<string, { id: string; name: string }>();\n const tagById = new Map<string, { id: string; name: string }>();\n for (const t of activeTags) {\n tagById.set(t.ID.toLowerCase(), { id: t.ID, name: t.Name });\n }\n for (const syn of engine.TagSynonyms) {\n // Only Active synonyms resolve — Pending (proposed, unapproved) and\n // Rejected ones are not live, matching the server-side resolver.\n if (syn.Status !== 'Active') continue;\n const owner = tagById.get((syn.TagID ?? '').toLowerCase());\n if (owner && syn.Synonym) {\n synonymMap.set(syn.Synonym.trim().toLowerCase(), owner);\n }\n }\n\n // exact name (lower) → Tag; normalized name (lower) → Tag (for fuzzy tier)\n const exactMap = new Map<string, { id: string; name: string }>();\n const normalizedMap = new Map<string, { id: string; name: string }>();\n for (const t of activeTags) {\n const entry = { id: t.ID, name: t.Name };\n exactMap.set(t.Name.trim().toLowerCase(), entry);\n normalizedMap.set(this.normalize(t.Name), entry);\n }\n\n return (tag: string): ResolveResult => {\n const lower = tag.trim().toLowerCase();\n\n const syn = synonymMap.get(lower);\n if (syn) return { tagId: syn.id, tagName: syn.name, score: 1.0, tier: 'synonym' };\n\n const exact = exactMap.get(lower);\n if (exact) return { tagId: exact.id, tagName: exact.name, score: 1.0, tier: 'exact' };\n\n const fuzzy = normalizedMap.get(this.normalize(tag));\n if (fuzzy) return { tagId: fuzzy.id, tagName: fuzzy.name, score: 0.8, tier: 'fuzzy' };\n\n return { tagId: null, tagName: null, score: null, tier: 'none' };\n };\n }\n\n /** Lowercase, strip hyphens/underscores/whitespace and a trailing plural 's'. */\n private normalize(value: string): string {\n let v = value.trim().toLowerCase().replace(/[-_\\s]+/g, '');\n if (v.endsWith('s') && v.length > 3) v = v.slice(0, -1);\n return v;\n }\n\n private tally(rows: DryRunRow[]): DryRunDispositionCount {\n const counts: DryRunDispositionCount = { AutoApply: 0, RouteToInbox: 0, CreateNew: 0, Reject: 0 };\n for (const r of rows) {\n switch (r.disposition) {\n case 'auto-apply': counts.AutoApply++; break;\n case 'route-to-inbox': counts.RouteToInbox++; break;\n case 'create-new': counts.CreateNew++; break;\n case 'reject': counts.Reject++; break;\n }\n }\n return counts;\n }\n\n private estimate(itemsSampled: number): DryRunEstimate {\n const tokens = itemsSampled * EST_TOKENS_PER_ITEM;\n const cost = (tokens / 1000) * EST_COST_PER_1K_TOKENS;\n return { ItemsSampled: itemsSampled, EstimatedTokens: tokens, EstimatedCost: cost };\n }\n\n // ── Template helpers ──\n\n /** Status-token-backed CSS class for a disposition pill. */\n public DispositionClass(d: Disposition): string {\n switch (d) {\n case 'auto-apply': return 'disp disp-apply';\n case 'route-to-inbox': return 'disp disp-inbox';\n case 'create-new': return 'disp disp-create';\n case 'reject': return 'disp disp-reject';\n }\n }\n\n /** Human label for a disposition pill. */\n public DispositionLabel(d: Disposition): string {\n switch (d) {\n case 'auto-apply': return 'AUTO-APPLY';\n case 'route-to-inbox': return '→ INBOX';\n case 'create-new': return this.EffectiveMode === 'free-flow' ? 'CREATE (free-flow)' : 'CREATE (auto-grow)';\n case 'reject': return 'REJECT';\n }\n }\n\n public FormatScore(score: number | null): string {\n return score == null ? '—' : score.toFixed(2);\n }\n\n public FormatTokens(tokens: number): string {\n return tokens.toLocaleString();\n }\n\n public FormatCost(cost: number): string {\n return `$${cost.toFixed(2)}`;\n }\n\n public ModeLabel(mode: DryRunConfig['mode']): string {\n switch (mode) {\n case 'constrained': return 'Constrained';\n case 'auto-grow': return 'Auto-grow';\n case 'free-flow': return 'Free-flow';\n }\n }\n}\n","<!-- ══════ DRY-RUN / DISPOSITION PREVIEW SLIDE-IN ══════ -->\n@if (Show) {\n <div class=\"at-slide-overlay\" (click)=\"close()\"></div>\n <div class=\"at-slide-panel dry-run-panel\">\n <div class=\"at-slide-header\">\n <h3><i class=\"fa-solid fa-flask\"></i> Dry-run preview</h3>\n <button class=\"at-slide-close\" aria-label=\"Close dry-run preview\" (click)=\"close()\"><i class=\"fa-solid fa-times\"></i></button>\n </div>\n\n <div class=\"at-slide-body\">\n <!-- Source + intent line -->\n @if (SourceCard) {\n <div class=\"dry-source-line\">\n <i [class]=\"SourceCard.Icon\"></i>\n <span class=\"dry-source-name\">{{ SourceCard.Name }}</span>\n </div>\n }\n\n <!-- \"nothing persisted\" banner -->\n <div class=\"dry-banner\">\n <i class=\"fa-solid fa-circle-info\"></i>\n <span>\n Preview of how this source's sampled tags resolve under the current\n <b>mode & thresholds</b> — <b>no LLM call, nothing persisted</b>.\n </span>\n </div>\n\n <!-- Effective config -->\n <div class=\"dry-effective\">\n <span class=\"pill purple\"><i class=\"fa-solid fa-flask\"></i> PREVIEW</span>\n <span class=\"dry-eff-item\">Mode <b>{{ ModeLabel(EffectiveMode) }}</b></span>\n <span class=\"dry-eff-item\">Match <b>{{ FormatScore(EffectiveMatchThreshold) }}</b></span>\n <span class=\"dry-eff-item\">Suggest <b>{{ FormatScore(EffectiveSuggestThreshold) }}</b></span>\n </div>\n\n @if (Loading) {\n <mj-loading text=\"Sampling existing tags…\"></mj-loading>\n } @else if (NoTagsSampled) {\n <div class=\"dry-empty\">\n <i class=\"fa-solid fa-tags\"></i>\n <p>No extracted tags found for this source yet. Run the pipeline first, then preview how its tags would be dispositioned.</p>\n </div>\n } @else {\n <!-- Estimate line (illustrative) -->\n <div class=\"dry-estimate\">\n <i class=\"fa-solid fa-calculator\"></i>\n <span>\n {{ Estimate.ItemsSampled }} sampled tag{{ Estimate.ItemsSampled === 1 ? '' : 's' }} ·\n est. {{ FormatTokens(Estimate.EstimatedTokens) }} tokens ·\n ~{{ FormatCost(Estimate.EstimatedCost) }}\n <span class=\"dry-est-note\">(rough estimate)</span>\n </span>\n </div>\n\n <!-- Summary counts -->\n <div class=\"dry-summary\">\n <span class=\"disp disp-apply\">{{ Counts.AutoApply }} auto-apply</span>\n <span class=\"disp disp-inbox\">{{ Counts.RouteToInbox }} → inbox</span>\n <span class=\"disp disp-create\">{{ Counts.CreateNew }} create</span>\n @if (Counts.Reject > 0) {\n <span class=\"disp disp-reject\">{{ Counts.Reject }} reject</span>\n }\n </div>\n\n <!-- Disposition table -->\n <table class=\"dry-table\">\n <thead>\n <tr>\n <th>Tag</th>\n <th>Matched</th>\n <th class=\"dry-col-score\">Score</th>\n <th>What would happen</th>\n </tr>\n </thead>\n <tbody>\n @for (row of Rows; track $index) {\n <tr>\n <td class=\"dry-cell-tag\">{{ row.tag }}</td>\n <td class=\"dry-cell-matched\">{{ row.matchedTag ?? '—' }}</td>\n <td class=\"dry-col-score dry-mono\">{{ FormatScore(row.score) }}</td>\n <td>\n <span [class]=\"DispositionClass(row.disposition)\" [title]=\"row.reason\">\n {{ DispositionLabel(row.disposition) }}\n </span>\n </td>\n </tr>\n }\n </tbody>\n </table>\n\n <div class=\"dry-disclaimer\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n A real run also uses a semantic / embedding match tier not reproducible here,\n so borderline rows may resolve differently.\n </div>\n }\n\n <!-- Footer -->\n <div class=\"dry-footer\">\n <button mjButton variant=\"primary\" size=\"sm\" (click)=\"close()\">Close</button>\n </div>\n </div>\n </div>\n}\n"]}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Classify · Content Item Detail slide-in dialog.
|
|
3
|
+
*
|
|
4
|
+
* Presentational slide-in panel showing a content item's details, tags, text,
|
|
5
|
+
* metadata, and actions. Opened from multiple tabs, so it is rendered by the
|
|
6
|
+
* HOST (the data orchestrator), which builds the `ContentItemDetail` and toggles
|
|
7
|
+
* visibility. This component is purely presentational: data DOWN via `[Item]` /
|
|
8
|
+
* `[Show]`, intents UP via `(Closed)` / `(OpenRecordRequested)`.
|
|
9
|
+
*/
|
|
10
|
+
import { EventEmitter } from '@angular/core';
|
|
11
|
+
import { BaseAngularComponent } from '@memberjunction/ng-base-types';
|
|
12
|
+
import { ContentItemDetail } from '../shared/classify.types';
|
|
13
|
+
import { formatWeight, tagFontSize } from '../shared/classify.format';
|
|
14
|
+
import * as i0 from "@angular/core";
|
|
15
|
+
export declare class ClassifyItemDetailDialogComponent extends BaseAngularComponent {
|
|
16
|
+
/** The content item to display, built and supplied by the host orchestrator. */
|
|
17
|
+
Item: ContentItemDetail | null;
|
|
18
|
+
/** Whether the slide-in is visible. */
|
|
19
|
+
Show: boolean;
|
|
20
|
+
/** Emitted when the user dismisses the panel (overlay/close button). */
|
|
21
|
+
Closed: EventEmitter<void>;
|
|
22
|
+
/** Emitted when the user requests to open the underlying record. */
|
|
23
|
+
OpenRecordRequested: EventEmitter<ContentItemDetail>;
|
|
24
|
+
readonly FormatWeight: typeof formatWeight;
|
|
25
|
+
readonly TagFontSize: typeof tagFontSize;
|
|
26
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ClassifyItemDetailDialogComponent, never>;
|
|
27
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<ClassifyItemDetailDialogComponent, "classify-item-detail-dialog", never, { "Item": { "alias": "Item"; "required": false; }; "Show": { "alias": "Show"; "required": false; }; }, { "Closed": "Closed"; "OpenRecordRequested": "OpenRecordRequested"; }, never, never, false, never>;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=item-detail.dialog.component.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"item-detail.dialog.component.d.ts","sourceRoot":"","sources":["../../../../../src/AI/components/autotagging/dialogs/item-detail.dialog.component.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAA4B,YAAY,EAAE,MAAM,eAAe,CAAC;AACvE,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;;AAEtE,qBAMa,iCAAkC,SAAQ,oBAAoB;IACvE,gFAAgF;IACvE,IAAI,EAAE,iBAAiB,GAAG,IAAI,CAAQ;IAC/C,uCAAuC;IAC9B,IAAI,UAAS;IAEtB,wEAAwE;IAC9D,MAAM,qBAA4B;IAC5C,oEAAoE;IAC1D,mBAAmB,kCAAyC;IAGtE,SAAgB,YAAY,sBAAgB;IAC5C,SAAgB,WAAW,qBAAe;yCAbjC,iCAAiC;2CAAjC,iCAAiC;CAc7C"}
|