@memberjunction/ng-dashboards 5.11.0 → 5.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AI/components/agents/agent-configuration.component.d.ts +34 -2
- package/dist/AI/components/agents/agent-configuration.component.d.ts.map +1 -1
- package/dist/AI/components/agents/agent-configuration.component.js +586 -223
- 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/agents/agent-filter-panel.component.d.ts +8 -0
- package/dist/AI/components/agents/agent-filter-panel.component.d.ts.map +1 -1
- package/dist/AI/components/agents/agent-filter-panel.component.js +85 -52
- package/dist/AI/components/agents/agent-filter-panel.component.js.map +1 -1
- package/dist/AI/components/charts/performance-heatmap.component.d.ts +1 -0
- package/dist/AI/components/charts/performance-heatmap.component.d.ts.map +1 -1
- package/dist/AI/components/charts/performance-heatmap.component.js +27 -5
- package/dist/AI/components/charts/performance-heatmap.component.js.map +1 -1
- package/dist/AI/components/charts/time-series-chart.component.d.ts +5 -0
- package/dist/AI/components/charts/time-series-chart.component.d.ts.map +1 -1
- package/dist/AI/components/charts/time-series-chart.component.js +23 -8
- package/dist/AI/components/charts/time-series-chart.component.js.map +1 -1
- package/dist/AI/components/execution-monitoring.component.js +2 -2
- package/dist/AI/components/execution-monitoring.component.js.map +1 -1
- package/dist/AI/components/models/model-management.component.js +2 -2
- package/dist/AI/components/prompts/model-prompt-priority-matrix.component.js +2 -2
- package/dist/AI/components/prompts/prompt-filter-panel.component.js +2 -2
- package/dist/AI/components/prompts/prompt-management.component.js +3 -3
- package/dist/AI/components/prompts/prompt-management.component.js.map +1 -1
- package/dist/AI/components/prompts/prompt-version-control.component.js +2 -2
- package/dist/AI/components/requests/agent-requests-resource.component.d.ts +83 -0
- package/dist/AI/components/requests/agent-requests-resource.component.d.ts.map +1 -0
- package/dist/AI/components/requests/agent-requests-resource.component.js +547 -0
- package/dist/AI/components/requests/agent-requests-resource.component.js.map +1 -0
- package/dist/AI/components/system/system-config-filter-panel.component.js +2 -2
- package/dist/AI/components/system/system-configuration.component.js +2 -2
- package/dist/AI/components/widgets/kpi-card.component.js +7 -7
- package/dist/AI/components/widgets/kpi-card.component.js.map +1 -1
- package/dist/AI/components/widgets/live-execution-widget.component.d.ts.map +1 -1
- package/dist/AI/components/widgets/live-execution-widget.component.js +6 -6
- package/dist/AI/components/widgets/live-execution-widget.component.js.map +1 -1
- package/dist/AI/index.d.ts +1 -0
- package/dist/AI/index.d.ts.map +1 -1
- package/dist/AI/index.js +2 -0
- package/dist/AI/index.js.map +1 -1
- package/dist/APIKeys/api-applications-panel.component.js +3 -3
- package/dist/APIKeys/api-applications-panel.component.js.map +1 -1
- package/dist/APIKeys/api-key-create-dialog.component.js +3 -3
- package/dist/APIKeys/api-key-create-dialog.component.js.map +1 -1
- package/dist/APIKeys/api-key-edit-panel.component.js +1 -1
- package/dist/APIKeys/api-key-edit-panel.component.js.map +1 -1
- package/dist/APIKeys/api-key-list.component.js +3 -3
- package/dist/APIKeys/api-key-list.component.js.map +1 -1
- package/dist/APIKeys/api-keys-resource.component.js +1 -1
- package/dist/APIKeys/api-keys-resource.component.js.map +1 -1
- package/dist/APIKeys/api-scopes-panel.component.js +2 -2
- package/dist/APIKeys/api-usage-panel.component.js +2 -2
- package/dist/Actions/components/actions-overview.component.js +2 -2
- package/dist/Actions/components/execution-monitoring.component.js +2 -2
- package/dist/Actions/components/explorer/action-breadcrumb.component.js +2 -2
- package/dist/Actions/components/explorer/action-card.component.js +2 -2
- package/dist/Actions/components/explorer/action-explorer.component.js +2 -2
- package/dist/Actions/components/explorer/action-list-item.component.js +2 -2
- package/dist/Actions/components/explorer/action-toolbar.component.js +2 -2
- package/dist/Actions/components/explorer/action-tree-panel.component.js +2 -2
- package/dist/Actions/components/explorer/new-action-panel.component.js +2 -2
- package/dist/Actions/components/explorer/new-action-panel.component.js.map +1 -1
- package/dist/Actions/components/explorer/new-category-panel.component.js +2 -2
- package/dist/Actions/components/explorer/new-category-panel.component.js.map +1 -1
- package/dist/Communication/communication-dashboard.component.js +2 -2
- package/dist/Communication/communication-logs-resource.component.d.ts.map +1 -1
- package/dist/Communication/communication-logs-resource.component.js +3 -3
- package/dist/Communication/communication-logs-resource.component.js.map +1 -1
- package/dist/Communication/communication-monitor-resource.component.d.ts.map +1 -1
- package/dist/Communication/communication-monitor-resource.component.js +5 -5
- package/dist/Communication/communication-monitor-resource.component.js.map +1 -1
- package/dist/Communication/communication-providers-resource.component.d.ts.map +1 -1
- package/dist/Communication/communication-providers-resource.component.js +3 -3
- package/dist/Communication/communication-providers-resource.component.js.map +1 -1
- package/dist/Communication/communication-runs-resource.component.d.ts.map +1 -1
- package/dist/Communication/communication-runs-resource.component.js +3 -3
- package/dist/Communication/communication-runs-resource.component.js.map +1 -1
- package/dist/Communication/communication-templates-resource.component.js +2 -2
- package/dist/Communication/communication-templates-resource.component.js.map +1 -1
- package/dist/ComponentStudio/component-studio-dashboard.component.js +2 -2
- package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.js +2 -2
- package/dist/ComponentStudio/components/artifact-load-dialog.component.js +2 -2
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.js +2 -2
- package/dist/ComponentStudio/components/browser/component-browser.component.js +2 -2
- package/dist/ComponentStudio/components/editors/code-editor-panel.component.js +2 -2
- package/dist/ComponentStudio/components/editors/code-editor-panel.component.js.map +1 -1
- package/dist/ComponentStudio/components/editors/data-requirements-editor.component.js +2 -2
- package/dist/ComponentStudio/components/editors/data-requirements-editor.component.js.map +1 -1
- package/dist/ComponentStudio/components/editors/requirements-editor.component.js +2 -2
- package/dist/ComponentStudio/components/editors/requirements-editor.component.js.map +1 -1
- package/dist/ComponentStudio/components/editors/spec-editor.component.js +2 -2
- package/dist/ComponentStudio/components/editors/spec-editor.component.js.map +1 -1
- package/dist/ComponentStudio/components/new-component-dialog/new-component-dialog.component.js +2 -2
- package/dist/ComponentStudio/components/save-version-dialog/save-version-dialog.component.js +2 -2
- package/dist/ComponentStudio/components/save-version-dialog/save-version-dialog.component.js.map +1 -1
- package/dist/ComponentStudio/components/text-import-dialog.component.js +2 -2
- package/dist/ComponentStudio/components/text-import-dialog.component.js.map +1 -1
- package/dist/ComponentStudio/components/workspace/component-preview.component.js +2 -2
- package/dist/ComponentStudio/components/workspace/editor-tabs.component.js +2 -2
- package/dist/ComponentStudio/components/workspace/editor-tabs.component.js.map +1 -1
- package/dist/Credentials/components/credentials-audit-resource.component.js +9 -9
- package/dist/Credentials/components/credentials-audit-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-categories-resource.component.d.ts.map +1 -1
- package/dist/Credentials/components/credentials-categories-resource.component.js +11 -3
- package/dist/Credentials/components/credentials-categories-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-list-resource.component.js +2 -2
- package/dist/Credentials/components/credentials-overview-resource.component.d.ts.map +1 -1
- package/dist/Credentials/components/credentials-overview-resource.component.js +12 -11
- package/dist/Credentials/components/credentials-overview-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-types-resource.component.js +9 -9
- package/dist/Credentials/components/credentials-types-resource.component.js.map +1 -1
- package/dist/Credentials/credentials-dashboard.component.js +2 -2
- package/dist/DashboardBrowser/dashboard-browser-resource.component.js +2 -2
- package/dist/DashboardBrowser/dashboard-share-dialog.component.js +2 -2
- package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.js +2 -2
- package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.js +2 -2
- package/dist/DataExplorer/components/view-selector/view-selector.component.js +2 -2
- package/dist/DataExplorer/data-explorer-dashboard.component.js +4 -4
- package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
- package/dist/Home/home-dashboard.component.js +2 -2
- package/dist/Integration/components/activity/activity.component.d.ts +1 -1
- package/dist/Integration/components/activity/activity.component.d.ts.map +1 -1
- package/dist/Integration/components/activity/activity.component.js +5 -5
- package/dist/Integration/components/activity/activity.component.js.map +1 -1
- package/dist/Integration/components/connections/connections.component.d.ts +31 -2
- package/dist/Integration/components/connections/connections.component.d.ts.map +1 -1
- package/dist/Integration/components/connections/connections.component.js +753 -412
- package/dist/Integration/components/connections/connections.component.js.map +1 -1
- package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js +3 -3
- package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js.map +1 -1
- package/dist/Integration/components/overview/overview.component.d.ts +0 -1
- package/dist/Integration/components/overview/overview.component.d.ts.map +1 -1
- package/dist/Integration/components/overview/overview.component.js +3 -6
- package/dist/Integration/components/overview/overview.component.js.map +1 -1
- package/dist/Integration/components/pipelines/pipelines.component.js +3 -3
- package/dist/Integration/components/pipelines/pipelines.component.js.map +1 -1
- package/dist/Integration/components/schedules/schedules.component.d.ts +20 -0
- package/dist/Integration/components/schedules/schedules.component.d.ts.map +1 -1
- package/dist/Integration/components/schedules/schedules.component.js +97 -5
- package/dist/Integration/components/schedules/schedules.component.js.map +1 -1
- package/dist/Integration/components/visual-editor/visual-editor.component.js +2 -2
- package/dist/Integration/components/widgets/integration-card.component.d.ts.map +1 -1
- package/dist/Integration/components/widgets/integration-card.component.js +5 -1
- package/dist/Integration/components/widgets/integration-card.component.js.map +1 -1
- package/dist/Integration/components/widgets/run-history-panel.component.js +2 -2
- package/dist/Integration/components/widgets/run-history-panel.component.js.map +1 -1
- package/dist/Integration/integration.module.d.ts +2 -1
- package/dist/Integration/integration.module.d.ts.map +1 -1
- package/dist/Integration/integration.module.js +7 -3
- package/dist/Integration/integration.module.js.map +1 -1
- package/dist/Integration/services/integration-data.service.d.ts +27 -2
- package/dist/Integration/services/integration-data.service.d.ts.map +1 -1
- package/dist/Integration/services/integration-data.service.js +107 -4
- package/dist/Integration/services/integration-data.service.js.map +1 -1
- package/dist/Lists/components/lists-browse-resource.component.js +2 -2
- package/dist/Lists/components/lists-browse-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-categories-resource.component.js +2 -2
- package/dist/Lists/components/lists-categories-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-my-lists-resource.component.js +2 -2
- package/dist/Lists/components/lists-my-lists-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-operations-resource.component.js +2 -2
- package/dist/Lists/components/lists-operations-resource.component.js.map +1 -1
- package/dist/Lists/components/venn-diagram/venn-diagram.component.js +3 -3
- package/dist/Lists/components/venn-diagram/venn-diagram.component.js.map +1 -1
- package/dist/MCP/components/mcp-connection-dialog.component.js +2 -2
- package/dist/MCP/components/mcp-log-detail-panel.component.js +2 -2
- package/dist/MCP/components/mcp-log-detail-panel.component.js.map +1 -1
- package/dist/MCP/components/mcp-server-dialog.component.js +2 -2
- package/dist/MCP/components/mcp-test-tool-dialog.component.js +2 -2
- 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-filter-panel.component.js +2 -2
- package/dist/QueryBrowser/query-browser-resource.component.js +7 -7
- package/dist/QueryBrowser/query-browser-resource.component.js.map +1 -1
- package/dist/Scheduling/components/index.d.ts +0 -1
- package/dist/Scheduling/components/index.d.ts.map +1 -1
- package/dist/Scheduling/components/index.js +0 -1
- package/dist/Scheduling/components/index.js.map +1 -1
- package/dist/Scheduling/components/scheduling-activity.component.js +2 -2
- package/dist/Scheduling/components/scheduling-jobs.component.d.ts +6 -9
- package/dist/Scheduling/components/scheduling-jobs.component.d.ts.map +1 -1
- package/dist/Scheduling/components/scheduling-jobs.component.js +118 -110
- package/dist/Scheduling/components/scheduling-jobs.component.js.map +1 -1
- package/dist/Scheduling/components/scheduling-overview.component.js +3 -3
- package/dist/Scheduling/components/scheduling-overview.component.js.map +1 -1
- package/dist/Scheduling/scheduling-dashboard.component.js +2 -2
- package/dist/SystemDiagnostics/system-diagnostics.component.js +4 -4
- package/dist/SystemDiagnostics/system-diagnostics.component.js.map +1 -1
- package/dist/Testing/components/testing-analytics.component.js +2 -2
- package/dist/Testing/components/testing-analytics.component.js.map +1 -1
- package/dist/Testing/components/testing-dashboard-tab.component.js +4 -4
- package/dist/Testing/components/testing-dashboard-tab.component.js.map +1 -1
- package/dist/Testing/components/testing-explorer.component.js +2 -2
- package/dist/Testing/components/testing-explorer.component.js.map +1 -1
- package/dist/Testing/components/testing-review.component.d.ts.map +1 -1
- package/dist/Testing/components/testing-review.component.js +5 -5
- package/dist/Testing/components/testing-review.component.js.map +1 -1
- package/dist/Testing/components/testing-runs.component.js +2 -2
- package/dist/Testing/components/testing-runs.component.js.map +1 -1
- package/dist/Testing/components/widgets/oracle-breakdown-table.component.js +2 -2
- package/dist/Testing/components/widgets/oracle-breakdown-table.component.js.map +1 -1
- package/dist/Testing/components/widgets/suite-tree.component.js +4 -4
- package/dist/Testing/components/widgets/suite-tree.component.js.map +1 -1
- package/dist/Testing/components/widgets/test-run-detail-panel.component.js +2 -2
- package/dist/Testing/components/widgets/test-run-detail-panel.component.js.map +1 -1
- package/dist/Testing/testing-dashboard.component.js +2 -2
- package/dist/VersionHistory/components/diff-resource.component.js +2 -2
- package/dist/VersionHistory/components/graph-resource.component.js +2 -2
- package/dist/VersionHistory/components/labels-resource.component.js +3 -3
- package/dist/VersionHistory/components/labels-resource.component.js.map +1 -1
- package/dist/VersionHistory/components/restore-resource.component.js +3 -3
- package/dist/VersionHistory/components/restore-resource.component.js.map +1 -1
- package/dist/__tests__/integration-data-service.test.js +1 -0
- package/dist/__tests__/integration-data-service.test.js.map +1 -1
- package/dist/module.d.ts +52 -49
- package/dist/module.d.ts.map +1 -1
- package/dist/module.js +25 -6
- package/dist/module.js.map +1 -1
- package/dist/public-api.d.ts +1 -1
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +1 -1
- package/dist/public-api.js.map +1 -1
- package/package.json +42 -40
- package/dist/Scheduling/components/job-slideout.component.d.ts +0 -45
- package/dist/Scheduling/components/job-slideout.component.d.ts.map +0 -1
- package/dist/Scheduling/components/job-slideout.component.js +0 -459
- package/dist/Scheduling/components/job-slideout.component.js.map +0 -1
|
@@ -1148,7 +1148,7 @@ let VersionHistoryDiffResourceComponent = class VersionHistoryDiffResourceCompon
|
|
|
1148
1148
|
i0.ɵɵconditional(ctx.IsLoading ? 1 : -1);
|
|
1149
1149
|
i0.ɵɵadvance();
|
|
1150
1150
|
i0.ɵɵconditional(!ctx.IsLoading ? 2 : -1);
|
|
1151
|
-
} }, dependencies: [i2.NgClass, i3.NgSelectOption, i3.ɵNgSelectMultipleOption, i3.DefaultValueAccessor, i3.SelectControlValueAccessor, i3.NgControlStatus, i3.NgModel, i4.LoadingComponent, i2.SlicePipe], styles: [".diff-container[_ngcontent-%COMP%] {\n padding: 24px;\n height: 100%;\n overflow-y: auto;\n}\n\n\n\n.page-header[_ngcontent-%COMP%] {\n margin-bottom: 24px;\n}\n\n.page-title[_ngcontent-%COMP%] {\n font-size: 24px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n margin: 0 0 4px 0;\n}\n\n.page-subtitle[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--text-secondary, #6b7280);\n margin: 0;\n}\n\n\n\n.config-panel[_ngcontent-%COMP%] {\n background: var(--card-background, #ffffff);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 12px;\n padding: 24px;\n margin-bottom: 24px;\n}\n\n.mode-selector[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n margin-bottom: 20px;\n}\n\n.mode-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 8px 18px;\n background: var(--hover-background, #f3f4f6);\n border: 2px solid transparent;\n border-radius: 8px;\n cursor: pointer;\n font-size: 14px;\n color: var(--text-secondary, #6b7280);\n transition: all 0.2s ease;\n}\n\n.mode-btn[_ngcontent-%COMP%]:hover {\n background: #e5e7eb;\n}\n\n.mode-btn.active[_ngcontent-%COMP%] {\n background: rgba(99, 102, 241, 0.08);\n border-color: #6366f1;\n color: #6366f1;\n font-weight: 600;\n}\n\n\n\n.label-selectors[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-end;\n gap: 16px;\n margin-bottom: 20px;\n}\n\n.selector-group[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.selector-label[_ngcontent-%COMP%] {\n display: block;\n font-size: 13px;\n font-weight: 600;\n color: var(--text-secondary, #6b7280);\n margin-bottom: 6px;\n}\n\n.selector-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 10px 12px;\n background: var(--card-background, #ffffff);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 8px;\n font-size: 14px;\n color: var(--text-primary, #1f2937);\n outline: none;\n box-sizing: border-box;\n}\n\n.selector-input[_ngcontent-%COMP%]:focus {\n border-color: #6366f1;\n box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);\n}\n\n.selector-arrow[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n padding-bottom: 8px;\n color: var(--text-secondary, #6b7280);\n font-size: 16px;\n}\n\n.current-state-badge[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n color: #6366f1;\n background: rgba(99, 102, 241, 0.1);\n padding: 2px 8px;\n border-radius: 8px;\n white-space: nowrap;\n}\n\n\n\n.btn-primary[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 10px 24px;\n background: #6366f1;\n border: none;\n border-radius: 8px;\n color: #ffffff;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.btn-primary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #4f46e5;\n}\n\n.btn-primary[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n\n\n.diff-summary[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: 12px;\n margin-bottom: 24px;\n}\n\n.diff-stat[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 16px 20px;\n border-radius: 10px;\n border: 1px solid var(--border-color, #e5e7eb);\n}\n\n.diff-stat[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n}\n\n.diff-stat-value[_ngcontent-%COMP%] {\n font-size: 22px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n}\n\n.diff-stat-label[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--text-secondary, #6b7280);\n}\n\n\n\n.change-added[_ngcontent-%COMP%] {\n background: rgba(16, 185, 129, 0.06);\n border-color: rgba(16, 185, 129, 0.2);\n color: #059669;\n}\n\n.change-removed[_ngcontent-%COMP%] {\n background: rgba(239, 68, 68, 0.06);\n border-color: rgba(239, 68, 68, 0.2);\n color: #dc2626;\n}\n\n.change-modified[_ngcontent-%COMP%] {\n background: rgba(245, 158, 11, 0.06);\n border-color: rgba(245, 158, 11, 0.2);\n color: #d97706;\n}\n\n.change-unchanged[_ngcontent-%COMP%] {\n background: rgba(107, 114, 128, 0.06);\n border-color: rgba(107, 114, 128, 0.2);\n color: #6b7280;\n}\n\n\n\n.entity-groups[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.entity-group[_ngcontent-%COMP%] {\n background: var(--card-background, #ffffff);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 10px;\n overflow: hidden;\n}\n\n.entity-group-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 14px 20px;\n cursor: pointer;\n transition: background 0.15s ease;\n}\n\n.entity-group-header[_ngcontent-%COMP%]:hover {\n background: var(--hover-background, #f9fafb);\n}\n\n.entity-group-left[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.entity-group-left[_ngcontent-%COMP%] i[_ngcontent-%COMP%]:first-child {\n font-size: 12px;\n color: var(--text-tertiary, #9ca3af);\n width: 16px;\n}\n\n.entity-icon[_ngcontent-%COMP%] {\n color: #6366f1;\n font-size: 14px;\n}\n\n.entity-group-name[_ngcontent-%COMP%] {\n font-size: 15px;\n font-weight: 600;\n color: var(--text-primary, #1f2937);\n}\n\n.entity-group-badges[_ngcontent-%COMP%] {\n display: flex;\n gap: 6px;\n}\n\n.badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 3px 10px;\n border-radius: 12px;\n font-size: 12px;\n font-weight: 600;\n border: none;\n}\n\n\n\n.entity-chevron[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--text-tertiary, #9ca3af);\n width: 14px;\n text-align: center;\n transition: transform 0.2s ease;\n}\n\n.entity-chevron.expanded[_ngcontent-%COMP%] {\n transform: rotate(90deg);\n}\n\n\n\n.entity-group-items[_ngcontent-%COMP%] {\n border-top: 1px solid var(--border-color, #e5e7eb);\n padding: 8px 16px;\n}\n\n.diff-item-wrapper[_ngcontent-%COMP%] {\n margin-bottom: 2px;\n}\n\n.diff-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 8px 12px;\n border-radius: 6px;\n}\n\n.diff-item.clickable[_ngcontent-%COMP%] {\n cursor: pointer;\n transition: background 0.15s ease;\n}\n\n.diff-item.clickable[_ngcontent-%COMP%]:hover {\n filter: brightness(0.97);\n}\n\n.diff-item-icon[_ngcontent-%COMP%] {\n font-size: 12px;\n width: 20px;\n text-align: center;\n}\n\n.diff-item-record[_ngcontent-%COMP%] {\n font-size: 13px;\n font-family: 'SF Mono', 'Fira Code', monospace;\n color: var(--text-primary, #1f2937);\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.diff-item-display-name[_ngcontent-%COMP%] {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n color: var(--text-secondary, #6b7280);\n font-weight: 500;\n}\n\n.diff-item-open-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 26px;\n height: 26px;\n border: 1px solid transparent;\n border-radius: 4px;\n background: transparent;\n color: var(--text-tertiary, #9ca3af);\n font-size: 11px;\n cursor: pointer;\n transition: all 0.15s ease;\n flex-shrink: 0;\n}\n\n.diff-item-open-btn[_ngcontent-%COMP%]:hover {\n border-color: #6366f1;\n color: #6366f1;\n background: rgba(99, 102, 241, 0.06);\n}\n\n.diff-item-type[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.diff-item-chevron[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--text-tertiary, #9ca3af);\n transition: transform 0.2s ease;\n}\n\n.diff-item-chevron.expanded[_ngcontent-%COMP%] {\n transform: rotate(90deg);\n}\n\n\n\n.diff-fields[_ngcontent-%COMP%] {\n margin-left: 42px;\n margin-bottom: 8px;\n padding: 8px 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.diff-field[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 6px 10px;\n border-radius: 6px;\n font-size: 13px;\n}\n\n.diff-field.change-added[_ngcontent-%COMP%] {\n background: rgba(16, 185, 129, 0.06);\n}\n\n.diff-field.change-modified[_ngcontent-%COMP%] {\n background: rgba(245, 158, 11, 0.06);\n}\n\n.diff-field.change-removed[_ngcontent-%COMP%] {\n background: rgba(239, 68, 68, 0.06);\n}\n\n.diff-field-name[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--text-primary, #1f2937);\n min-width: 120px;\n flex-shrink: 0;\n}\n\n.diff-field-values[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 0;\n flex: 1;\n}\n\n.diff-field-old[_ngcontent-%COMP%] {\n color: #ef4444;\n text-decoration: line-through;\n opacity: 0.8;\n font-family: 'SF Mono', 'Fira Code', monospace;\n font-size: 12px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.diff-field-arrow[_ngcontent-%COMP%] {\n color: var(--text-tertiary, #9ca3af);\n font-size: 10px;\n flex-shrink: 0;\n}\n\n.diff-field-new[_ngcontent-%COMP%] {\n color: #10b981;\n font-family: 'SF Mono', 'Fira Code', monospace;\n font-size: 12px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.diff-fields-empty[_ngcontent-%COMP%] {\n padding: 6px 10px;\n font-size: 12px;\n color: var(--text-tertiary, #9ca3af);\n font-style: italic;\n}\n\n\n\n.diff-toolbar-right[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.toolbar-action-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 6px;\n background: var(--card-background, #ffffff);\n color: var(--text-tertiary, #9ca3af);\n font-size: 13px;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.toolbar-action-btn[_ngcontent-%COMP%]:hover {\n border-color: #6366f1;\n color: #6366f1;\n background: rgba(99, 102, 241, 0.06);\n}\n\n\n\n.empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n text-align: center;\n}\n\n.empty-icon[_ngcontent-%COMP%] {\n font-size: 48px;\n color: var(--text-tertiary, #9ca3af);\n margin-bottom: 16px;\n}\n\n.empty-state[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n font-size: 18px;\n font-weight: 600;\n color: var(--text-primary, #1f2937);\n margin: 0 0 8px 0;\n}\n\n.empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--text-secondary, #6b7280);\n margin: 0;\n max-width: 400px;\n}\n\n\n\n.swap-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 50%;\n background: var(--card-background, #ffffff);\n color: #6366f1;\n font-size: 14px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.swap-btn[_ngcontent-%COMP%]:hover {\n background: rgba(99, 102, 241, 0.1);\n border-color: #6366f1;\n transform: rotate(180deg);\n}\n\n\n\n.diff-toolbar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 16px;\n flex-wrap: wrap;\n}\n\n.diff-search[_ngcontent-%COMP%] {\n position: relative;\n flex: 1;\n min-width: 200px;\n}\n\n.diff-search-icon[_ngcontent-%COMP%] {\n position: absolute;\n left: 12px;\n top: 50%;\n transform: translateY(-50%);\n color: var(--text-tertiary, #9ca3af);\n font-size: 13px;\n}\n\n.diff-search-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 8px 12px 8px 36px;\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 8px;\n font-size: 13px;\n background: var(--card-background, #ffffff);\n color: var(--text-primary, #1f2937);\n box-sizing: border-box;\n}\n\n.diff-search-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: #6366f1;\n box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);\n}\n\n.diff-filter-pills[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n}\n\n.filter-pill[_ngcontent-%COMP%] {\n padding: 6px 14px;\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 16px;\n background: var(--card-background, #ffffff);\n font-size: 12px;\n font-weight: 500;\n color: var(--text-secondary, #6b7280);\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.filter-pill[_ngcontent-%COMP%]:hover {\n border-color: #6366f1;\n color: #6366f1;\n}\n\n.filter-pill.active[_ngcontent-%COMP%] {\n background: #6366f1;\n border-color: #6366f1;\n color: #ffffff;\n}\n\n.filter-pill.change-added.active[_ngcontent-%COMP%] {\n background: #059669;\n border-color: #059669;\n}\n\n.filter-pill.change-removed.active[_ngcontent-%COMP%] {\n background: #dc2626;\n border-color: #dc2626;\n}\n\n.filter-pill.change-modified.active[_ngcontent-%COMP%] {\n background: #d97706;\n border-color: #d97706;\n}\n\n.diff-sort-toggle[_ngcontent-%COMP%] {\n display: flex;\n gap: 2px;\n}\n\n.toggle-btn-sm[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 6px;\n background: var(--card-background, #ffffff);\n color: var(--text-tertiary, #9ca3af);\n font-size: 13px;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.toggle-btn-sm[_ngcontent-%COMP%]:hover {\n border-color: #6366f1;\n color: #6366f1;\n}\n\n.toggle-btn-sm.active[_ngcontent-%COMP%] {\n background: rgba(99, 102, 241, 0.1);\n border-color: #6366f1;\n color: #6366f1;\n}\n\n@media (max-width: 768px) {\n .diff-summary[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .label-selectors[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n}"], changeDetection: 0 });
|
|
1151
|
+
} }, dependencies: [i2.NgClass, i3.NgSelectOption, i3.ɵNgSelectMultipleOption, i3.DefaultValueAccessor, i3.SelectControlValueAccessor, i3.NgControlStatus, i3.NgModel, i4.LoadingComponent, i2.SlicePipe], styles: [".diff-container[_ngcontent-%COMP%] {\n padding: 24px;\n height: 100%;\n overflow-y: auto;\n}\n\n\n\n.page-header[_ngcontent-%COMP%] {\n margin-bottom: 24px;\n}\n\n.page-title[_ngcontent-%COMP%] {\n font-size: 24px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0 0 4px 0;\n}\n\n.page-subtitle[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--mj-text-secondary);\n margin: 0;\n}\n\n\n\n.config-panel[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n padding: 24px;\n margin-bottom: 24px;\n}\n\n.mode-selector[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n margin-bottom: 20px;\n}\n\n.mode-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 8px 18px;\n background: var(--mj-bg-surface-sunken);\n border: 2px solid transparent;\n border-radius: 8px;\n cursor: pointer;\n font-size: 14px;\n color: var(--mj-text-secondary);\n transition: all 0.2s ease;\n}\n\n.mode-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-border-default);\n}\n\n.mode-btn.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n\n\n.label-selectors[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-end;\n gap: 16px;\n margin-bottom: 20px;\n}\n\n.selector-group[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.selector-label[_ngcontent-%COMP%] {\n display: block;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n margin-bottom: 6px;\n}\n\n.selector-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 10px 12px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-radius: 8px;\n font-size: 14px;\n color: var(--mj-text-primary);\n outline: none;\n box-sizing: border-box;\n}\n\n.selector-input[_ngcontent-%COMP%]:focus {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.selector-arrow[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n padding-bottom: 8px;\n color: var(--mj-text-secondary);\n font-size: 16px;\n}\n\n.current-state-badge[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n padding: 2px 8px;\n border-radius: 8px;\n white-space: nowrap;\n}\n\n\n\n.btn-primary[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 10px 24px;\n background: var(--mj-brand-primary);\n border: none;\n border-radius: 8px;\n color: var(--mj-text-inverse);\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.btn-primary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n.btn-primary[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n\n\n.diff-summary[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: 12px;\n margin-bottom: 24px;\n}\n\n.diff-stat[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 16px 20px;\n border-radius: 10px;\n border: 1px solid var(--mj-border-default);\n}\n\n.diff-stat[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n}\n\n.diff-stat-value[_ngcontent-%COMP%] {\n font-size: 22px;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.diff-stat-label[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n\n\n\n.change-added[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 6%, transparent);\n border-color: color-mix(in srgb, var(--mj-status-success) 20%, transparent);\n color: var(--mj-status-success);\n}\n\n.change-removed[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 6%, transparent);\n border-color: color-mix(in srgb, var(--mj-status-error) 20%, transparent);\n color: var(--mj-status-error);\n}\n\n.change-modified[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 6%, transparent);\n border-color: color-mix(in srgb, var(--mj-status-warning) 20%, transparent);\n color: var(--mj-status-warning);\n}\n\n.change-unchanged[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-text-muted) 6%, transparent);\n border-color: color-mix(in srgb, var(--mj-text-muted) 20%, transparent);\n color: var(--mj-text-muted);\n}\n\n\n\n.entity-groups[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.entity-group[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n overflow: hidden;\n}\n\n.entity-group-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 14px 20px;\n cursor: pointer;\n transition: background 0.15s ease;\n}\n\n.entity-group-header[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.entity-group-left[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.entity-group-left[_ngcontent-%COMP%] i[_ngcontent-%COMP%]:first-child {\n font-size: 12px;\n color: var(--mj-text-muted);\n width: 16px;\n}\n\n.entity-icon[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 14px;\n}\n\n.entity-group-name[_ngcontent-%COMP%] {\n font-size: 15px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.entity-group-badges[_ngcontent-%COMP%] {\n display: flex;\n gap: 6px;\n}\n\n.badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 3px 10px;\n border-radius: 12px;\n font-size: 12px;\n font-weight: 600;\n border: none;\n}\n\n\n\n.entity-chevron[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n width: 14px;\n text-align: center;\n transition: transform 0.2s ease;\n}\n\n.entity-chevron.expanded[_ngcontent-%COMP%] {\n transform: rotate(90deg);\n}\n\n\n\n.entity-group-items[_ngcontent-%COMP%] {\n border-top: 1px solid var(--mj-border-default);\n padding: 8px 16px;\n}\n\n.diff-item-wrapper[_ngcontent-%COMP%] {\n margin-bottom: 2px;\n}\n\n.diff-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 8px 12px;\n border-radius: 6px;\n}\n\n.diff-item.clickable[_ngcontent-%COMP%] {\n cursor: pointer;\n transition: background 0.15s ease;\n}\n\n.diff-item.clickable[_ngcontent-%COMP%]:hover {\n filter: brightness(0.97);\n}\n\n.diff-item-icon[_ngcontent-%COMP%] {\n font-size: 12px;\n width: 20px;\n text-align: center;\n}\n\n.diff-item-record[_ngcontent-%COMP%] {\n font-size: 13px;\n font-family: 'SF Mono', 'Fira Code', monospace;\n color: var(--mj-text-primary);\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.diff-item-display-name[_ngcontent-%COMP%] {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n color: var(--mj-text-secondary);\n font-weight: 500;\n}\n\n.diff-item-open-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 26px;\n height: 26px;\n border: 1px solid transparent;\n border-radius: 4px;\n background: transparent;\n color: var(--mj-text-muted);\n font-size: 11px;\n cursor: pointer;\n transition: all 0.15s ease;\n flex-shrink: 0;\n}\n\n.diff-item-open-btn[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 6%, transparent);\n}\n\n.diff-item-type[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.diff-item-chevron[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--mj-text-muted);\n transition: transform 0.2s ease;\n}\n\n.diff-item-chevron.expanded[_ngcontent-%COMP%] {\n transform: rotate(90deg);\n}\n\n\n\n.diff-fields[_ngcontent-%COMP%] {\n margin-left: 42px;\n margin-bottom: 8px;\n padding: 8px 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.diff-field[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 6px 10px;\n border-radius: 6px;\n font-size: 13px;\n}\n\n.diff-field.change-added[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 6%, transparent);\n}\n\n.diff-field.change-modified[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 6%, transparent);\n}\n\n.diff-field.change-removed[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 6%, transparent);\n}\n\n.diff-field-name[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--mj-text-primary);\n min-width: 120px;\n flex-shrink: 0;\n}\n\n.diff-field-values[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 0;\n flex: 1;\n}\n\n.diff-field-old[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n text-decoration: line-through;\n opacity: 0.8;\n font-family: 'SF Mono', 'Fira Code', monospace;\n font-size: 12px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.diff-field-arrow[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 10px;\n flex-shrink: 0;\n}\n\n.diff-field-new[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n font-family: 'SF Mono', 'Fira Code', monospace;\n font-size: 12px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.diff-fields-empty[_ngcontent-%COMP%] {\n padding: 6px 10px;\n font-size: 12px;\n color: var(--mj-text-muted);\n font-style: italic;\n}\n\n\n\n.diff-toolbar-right[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.toolbar-action-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-muted);\n font-size: 13px;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.toolbar-action-btn[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 6%, transparent);\n}\n\n\n\n.empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n text-align: center;\n}\n\n.empty-icon[_ngcontent-%COMP%] {\n font-size: 48px;\n color: var(--mj-text-muted);\n margin-bottom: 16px;\n}\n\n.empty-state[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n font-size: 18px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 8px 0;\n}\n\n.empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--mj-text-secondary);\n margin: 0;\n max-width: 400px;\n}\n\n\n\n.swap-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n border: 1px solid var(--mj-border-default);\n border-radius: 50%;\n background: var(--mj-bg-surface-card);\n color: var(--mj-brand-primary);\n font-size: 14px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.swap-btn[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n border-color: var(--mj-brand-primary);\n transform: rotate(180deg);\n}\n\n\n\n.diff-toolbar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 16px;\n flex-wrap: wrap;\n}\n\n.diff-search[_ngcontent-%COMP%] {\n position: relative;\n flex: 1;\n min-width: 200px;\n}\n\n.diff-search-icon[_ngcontent-%COMP%] {\n position: absolute;\n left: 12px;\n top: 50%;\n transform: translateY(-50%);\n color: var(--mj-text-muted);\n font-size: 13px;\n}\n\n.diff-search-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 8px 12px 8px 36px;\n border: 1px solid var(--mj-border-strong);\n border-radius: 8px;\n font-size: 13px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n box-sizing: border-box;\n}\n\n.diff-search-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.diff-filter-pills[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n}\n\n.filter-pill[_ngcontent-%COMP%] {\n padding: 6px 14px;\n border: 1px solid var(--mj-border-default);\n border-radius: 16px;\n background: var(--mj-bg-surface-card);\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.filter-pill[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n.filter-pill.active[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.filter-pill.change-added.active[_ngcontent-%COMP%] {\n background: var(--mj-status-success);\n border-color: var(--mj-status-success);\n}\n\n.filter-pill.change-removed.active[_ngcontent-%COMP%] {\n background: var(--mj-status-error);\n border-color: var(--mj-status-error);\n}\n\n.filter-pill.change-modified.active[_ngcontent-%COMP%] {\n background: var(--mj-status-warning);\n border-color: var(--mj-status-warning);\n}\n\n.diff-sort-toggle[_ngcontent-%COMP%] {\n display: flex;\n gap: 2px;\n}\n\n.toggle-btn-sm[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-muted);\n font-size: 13px;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.toggle-btn-sm[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n.toggle-btn-sm.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n@media (max-width: 768px) {\n .diff-summary[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .label-selectors[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n}"], changeDetection: 0 });
|
|
1152
1152
|
};
|
|
1153
1153
|
VersionHistoryDiffResourceComponent = VersionHistoryDiffResourceComponent_1 = __decorate([
|
|
1154
1154
|
RegisterClass(BaseResourceComponent, 'VersionHistoryDiffResource')
|
|
@@ -1156,7 +1156,7 @@ VersionHistoryDiffResourceComponent = VersionHistoryDiffResourceComponent_1 = __
|
|
|
1156
1156
|
export { VersionHistoryDiffResourceComponent };
|
|
1157
1157
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(VersionHistoryDiffResourceComponent, [{
|
|
1158
1158
|
type: Component,
|
|
1159
|
-
args: [{ standalone: false, selector: 'mj-version-history-diff-resource', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"diff-container\">\n @if (IsLoading) {\n <mj-loading text=\"Loading diff viewer...\"></mj-loading>\n }\n\n @if (!IsLoading) {\n <!-- Header -->\n <div class=\"page-header\">\n <div class=\"header-left\">\n <h2 class=\"page-title\">Diff Viewer</h2>\n <p class=\"page-subtitle\">Compare states between version labels or against current data</p>\n </div>\n </div>\n <!-- Diff Configuration Panel -->\n <div class=\"config-panel\">\n <!-- Mode Selector -->\n <div class=\"mode-selector\">\n <button class=\"mode-btn\"\n [class.active]=\"DiffMode === 'label-to-current'\"\n (click)=\"OnDiffModeChange('label-to-current')\">\n <i class=\"fa-solid fa-clock-rotate-left\"></i>\n Label vs Current\n </button>\n <button class=\"mode-btn\"\n [class.active]=\"DiffMode === 'label-to-label'\"\n (click)=\"OnDiffModeChange('label-to-label')\">\n <i class=\"fa-solid fa-code-compare\"></i>\n Label vs Label\n </button>\n </div>\n <!-- Label Selectors -->\n <div class=\"label-selectors\">\n <div class=\"selector-group\">\n <label class=\"selector-label\">\n {{DiffMode === 'label-to-current' ? 'Compare label' : 'From label'}}\n </label>\n <select class=\"selector-input\"\n [(ngModel)]=\"FromLabelId\">\n <option value=\"\">Select a label...</option>\n @for (label of FilteredFromLabels; track label) {\n <option\n [value]=\"label.ID\">\n {{FormatLabelOption(label)}}\n </option>\n }\n </select>\n </div>\n @if (DiffMode === 'label-to-label') {\n <div class=\"selector-arrow\">\n <button class=\"swap-btn\" (click)=\"SwapLabels()\" title=\"Swap direction\">\n <i class=\"fa-solid fa-arrows-rotate\"></i>\n </button>\n </div>\n }\n @if (DiffMode === 'label-to-current') {\n <div class=\"selector-arrow\">\n <i class=\"fa-solid fa-arrow-right\"></i>\n <span class=\"current-state-badge\">Current State</span>\n </div>\n }\n @if (DiffMode === 'label-to-label') {\n <div class=\"selector-group\">\n <label class=\"selector-label\">To label</label>\n <select class=\"selector-input\"\n [(ngModel)]=\"ToLabelId\">\n <option value=\"\">Select a label...</option>\n @for (label of FilteredToLabels; track label) {\n <option\n [value]=\"label.ID\">\n {{FormatLabelOption(label)}}\n </option>\n }\n </select>\n </div>\n }\n </div>\n <!-- Run Button -->\n <button class=\"btn-primary\"\n [disabled]=\"!CanRunDiff || IsDiffLoading\"\n (click)=\"RunDiff()\">\n @if (!IsDiffLoading) {\n <i class=\"fa-solid fa-play\"></i>\n }\n @if (IsDiffLoading) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n }\n <span>{{IsDiffLoading ? 'Comparing...' : 'Compare'}}</span>\n </button>\n </div>\n <!-- Diff Results -->\n @if (HasDiffResult) {\n <!-- Summary Stats -->\n <div class=\"diff-summary\">\n <div class=\"diff-stat change-added\">\n <i class=\"fa-solid fa-plus\"></i>\n <span class=\"diff-stat-value\">{{TotalAdded}}</span>\n <span class=\"diff-stat-label\">Added</span>\n </div>\n <div class=\"diff-stat change-removed\">\n <i class=\"fa-solid fa-minus\"></i>\n <span class=\"diff-stat-value\">{{TotalRemoved}}</span>\n <span class=\"diff-stat-label\">Removed</span>\n </div>\n <div class=\"diff-stat change-modified\">\n <i class=\"fa-solid fa-pen\"></i>\n <span class=\"diff-stat-value\">{{TotalModified}}</span>\n <span class=\"diff-stat-label\">Modified</span>\n </div>\n <div class=\"diff-stat change-unchanged\">\n <i class=\"fa-solid fa-equals\"></i>\n <span class=\"diff-stat-value\">{{TotalUnchanged}}</span>\n <span class=\"diff-stat-label\">Unchanged</span>\n </div>\n </div>\n <!-- Results toolbar -->\n @if (EntityGroups.length > 0) {\n <div class=\"diff-toolbar\">\n <div class=\"diff-search\">\n <i class=\"fa-solid fa-search diff-search-icon\"></i>\n <input type=\"text\" class=\"diff-search-input\"\n placeholder=\"Search by entity or record...\"\n [ngModel]=\"DiffSearch\"\n (ngModelChange)=\"OnDiffSearchChange($event)\" />\n </div>\n <div class=\"diff-filter-pills\">\n <button class=\"filter-pill\" [class.active]=\"DiffFilterType === 'all'\"\n (click)=\"OnDiffFilterChange('all')\">All</button>\n <button class=\"filter-pill change-added\" [class.active]=\"DiffFilterType === 'added'\"\n (click)=\"OnDiffFilterChange('added')\">Added</button>\n <button class=\"filter-pill change-removed\" [class.active]=\"DiffFilterType === 'removed'\"\n (click)=\"OnDiffFilterChange('removed')\">Removed</button>\n <button class=\"filter-pill change-modified\" [class.active]=\"DiffFilterType === 'modified'\"\n (click)=\"OnDiffFilterChange('modified')\">Modified</button>\n </div>\n <div class=\"diff-toolbar-right\">\n <button class=\"toolbar-action-btn\" (click)=\"ExpandAllGroups()\" title=\"Expand all\">\n <i class=\"fa-solid fa-angles-down\"></i>\n </button>\n <button class=\"toolbar-action-btn\" (click)=\"CollapseAllGroups()\" title=\"Collapse all\">\n <i class=\"fa-solid fa-angles-up\"></i>\n </button>\n <div class=\"diff-sort-toggle\">\n <button class=\"toggle-btn-sm\" [class.active]=\"DiffSortBy === 'name'\"\n (click)=\"OnDiffSortChange('name')\" title=\"Sort by name\">\n <i class=\"fa-solid\" [ngClass]=\"DiffSortBy === 'name' && DiffSortDir === 'desc' ? 'fa-arrow-up-z-a' : 'fa-arrow-down-a-z'\"></i>\n </button>\n <button class=\"toggle-btn-sm\" [class.active]=\"DiffSortBy === 'count'\"\n (click)=\"OnDiffSortChange('count')\" title=\"Sort by count\">\n <i class=\"fa-solid\" [ngClass]=\"DiffSortBy === 'count' && DiffSortDir === 'asc' ? 'fa-arrow-up-1-9' : 'fa-arrow-down-9-1'\"></i>\n </button>\n </div>\n </div>\n </div>\n }\n <!-- Entity Groups -->\n @if (FilteredEntityGroups.length > 0) {\n <div class=\"entity-groups\">\n @for (group of FilteredEntityGroups; track group) {\n <div class=\"entity-group\">\n <div class=\"entity-group-header\" (click)=\"ToggleEntityGroup(group)\">\n <div class=\"entity-group-left\">\n <i class=\"fa-solid fa-chevron-right entity-chevron\"\n [class.expanded]=\"group.IsExpanded\">\n </i>\n <i [class]=\"group.EntityIcon\" class=\"entity-icon\"></i>\n <span class=\"entity-group-name\">{{group.EntityName}}</span>\n </div>\n <div class=\"entity-group-badges\">\n @if (group.AddedCount > 0) {\n <span class=\"badge change-added\">\n +{{group.AddedCount}}\n </span>\n }\n @if (group.RemovedCount > 0) {\n <span class=\"badge change-removed\">\n -{{group.RemovedCount}}\n </span>\n }\n @if (group.ModifiedCount > 0) {\n <span class=\"badge change-modified\">\n ~{{group.ModifiedCount}}\n </span>\n }\n </div>\n </div>\n @if (group.IsExpanded) {\n <div class=\"entity-group-items\">\n @for (item of group.Items; track item) {\n <div class=\"diff-item-wrapper\">\n <div class=\"diff-item\" [ngClass]=\"GetChangeTypeClass(item.ChangeType)\"\n [class.clickable]=\"item.ChangeType === 'Modified'\"\n (click)=\"ToggleItem(item)\">\n <i [class]=\"GetChangeTypeIcon(item.ChangeType)\" class=\"diff-item-icon\"></i>\n <span class=\"diff-item-record\">\n {{FormatRecordID(item.RecordID)}}\n @if (item.DisplayName) {\n <span class=\"diff-item-display-name\"> ({{item.DisplayName}})</span>\n }\n </span>\n <span class=\"diff-item-type\">{{item.ChangeType}}</span>\n <button class=\"diff-item-open-btn\" (click)=\"OnOpenRecord(item); $event.stopPropagation()\"\n title=\"Open record\">\n <i class=\"fa-solid fa-arrow-up-right-from-square\"></i>\n </button>\n @if (item.ChangeType === 'Modified') {\n <i class=\"fa-solid fa-chevron-right diff-item-chevron\"\n [class.expanded]=\"item.IsExpanded\"\n ></i>\n }\n </div>\n <!-- Field-level changes -->\n @if (item.IsExpanded && item.ChangeType === 'Modified') {\n <div class=\"diff-fields\">\n @if (item.IsLoadingFields) {\n <mj-loading text=\"Loading changes...\" size=\"small\"></mj-loading>\n }\n @if (!item.IsLoadingFields && item.FieldChanges.length > 0) {\n @for (field of item.FieldChanges; track field) {\n <div class=\"diff-field\"\n [ngClass]=\"GetChangeTypeClass(field.ChangeType)\">\n <span class=\"diff-field-name\">{{field.FieldName}}</span>\n <span class=\"diff-field-values\">\n @if (field.OldValue) {\n <span class=\"diff-field-old\">{{field.OldValue | slice:0:60}}</span>\n }\n @if (field.OldValue && field.NewValue) {\n <i class=\"fa-solid fa-arrow-right diff-field-arrow\"></i>\n }\n @if (field.NewValue) {\n <span class=\"diff-field-new\">{{field.NewValue | slice:0:60}}</span>\n }\n </span>\n </div>\n }\n }\n @if (!item.IsLoadingFields && item.FieldsLoaded && item.FieldChanges.length === 0) {\n <div class=\"diff-fields-empty\">\n <span>No field-level changes available</span>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n <!-- No changes -->\n @if (FilteredEntityGroups.length === 0 && TotalChanges === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-check-circle empty-icon\" style=\"color: #10b981;\"></i>\n <h3>No differences found</h3>\n <p>The compared states are identical.</p>\n </div>\n }\n }\n <!-- No results yet -->\n @if (!HasDiffResult && !IsDiffLoading) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-code-compare empty-icon\"></i>\n <h3>Select labels to compare</h3>\n <p>Choose a diff mode and select labels above, then click Compare.</p>\n </div>\n }\n }\n</div>\n", styles: [".diff-container {\n padding: 24px;\n height: 100%;\n overflow-y: auto;\n}\n\n/* Header */\n.page-header {\n margin-bottom: 24px;\n}\n\n.page-title {\n font-size: 24px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n margin: 0 0 4px 0;\n}\n\n.page-subtitle {\n font-size: 14px;\n color: var(--text-secondary, #6b7280);\n margin: 0;\n}\n\n/* Config Panel */\n.config-panel {\n background: var(--card-background, #ffffff);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 12px;\n padding: 24px;\n margin-bottom: 24px;\n}\n\n.mode-selector {\n display: flex;\n gap: 8px;\n margin-bottom: 20px;\n}\n\n.mode-btn {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 8px 18px;\n background: var(--hover-background, #f3f4f6);\n border: 2px solid transparent;\n border-radius: 8px;\n cursor: pointer;\n font-size: 14px;\n color: var(--text-secondary, #6b7280);\n transition: all 0.2s ease;\n}\n\n.mode-btn:hover {\n background: #e5e7eb;\n}\n\n.mode-btn.active {\n background: rgba(99, 102, 241, 0.08);\n border-color: #6366f1;\n color: #6366f1;\n font-weight: 600;\n}\n\n/* Label Selectors */\n.label-selectors {\n display: flex;\n align-items: flex-end;\n gap: 16px;\n margin-bottom: 20px;\n}\n\n.selector-group {\n flex: 1;\n}\n\n.selector-label {\n display: block;\n font-size: 13px;\n font-weight: 600;\n color: var(--text-secondary, #6b7280);\n margin-bottom: 6px;\n}\n\n.selector-input {\n width: 100%;\n padding: 10px 12px;\n background: var(--card-background, #ffffff);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 8px;\n font-size: 14px;\n color: var(--text-primary, #1f2937);\n outline: none;\n box-sizing: border-box;\n}\n\n.selector-input:focus {\n border-color: #6366f1;\n box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);\n}\n\n.selector-arrow {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n padding-bottom: 8px;\n color: var(--text-secondary, #6b7280);\n font-size: 16px;\n}\n\n.current-state-badge {\n font-size: 11px;\n font-weight: 600;\n color: #6366f1;\n background: rgba(99, 102, 241, 0.1);\n padding: 2px 8px;\n border-radius: 8px;\n white-space: nowrap;\n}\n\n/* Run Button */\n.btn-primary {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 10px 24px;\n background: #6366f1;\n border: none;\n border-radius: 8px;\n color: #ffffff;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.btn-primary:hover:not(:disabled) {\n background: #4f46e5;\n}\n\n.btn-primary:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n/* Diff Summary */\n.diff-summary {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: 12px;\n margin-bottom: 24px;\n}\n\n.diff-stat {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 16px 20px;\n border-radius: 10px;\n border: 1px solid var(--border-color, #e5e7eb);\n}\n\n.diff-stat i {\n font-size: 16px;\n}\n\n.diff-stat-value {\n font-size: 22px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n}\n\n.diff-stat-label {\n font-size: 13px;\n color: var(--text-secondary, #6b7280);\n}\n\n/* Change type colors */\n.change-added {\n background: rgba(16, 185, 129, 0.06);\n border-color: rgba(16, 185, 129, 0.2);\n color: #059669;\n}\n\n.change-removed {\n background: rgba(239, 68, 68, 0.06);\n border-color: rgba(239, 68, 68, 0.2);\n color: #dc2626;\n}\n\n.change-modified {\n background: rgba(245, 158, 11, 0.06);\n border-color: rgba(245, 158, 11, 0.2);\n color: #d97706;\n}\n\n.change-unchanged {\n background: rgba(107, 114, 128, 0.06);\n border-color: rgba(107, 114, 128, 0.2);\n color: #6b7280;\n}\n\n/* Entity Groups */\n.entity-groups {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.entity-group {\n background: var(--card-background, #ffffff);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 10px;\n overflow: hidden;\n}\n\n.entity-group-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 14px 20px;\n cursor: pointer;\n transition: background 0.15s ease;\n}\n\n.entity-group-header:hover {\n background: var(--hover-background, #f9fafb);\n}\n\n.entity-group-left {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.entity-group-left i:first-child {\n font-size: 12px;\n color: var(--text-tertiary, #9ca3af);\n width: 16px;\n}\n\n.entity-icon {\n color: #6366f1;\n font-size: 14px;\n}\n\n.entity-group-name {\n font-size: 15px;\n font-weight: 600;\n color: var(--text-primary, #1f2937);\n}\n\n.entity-group-badges {\n display: flex;\n gap: 6px;\n}\n\n.badge {\n display: inline-flex;\n align-items: center;\n padding: 3px 10px;\n border-radius: 12px;\n font-size: 12px;\n font-weight: 600;\n border: none;\n}\n\n/* Entity chevron animation */\n.entity-chevron {\n font-size: 11px;\n color: var(--text-tertiary, #9ca3af);\n width: 14px;\n text-align: center;\n transition: transform 0.2s ease;\n}\n\n.entity-chevron.expanded {\n transform: rotate(90deg);\n}\n\n/* Entity group items */\n.entity-group-items {\n border-top: 1px solid var(--border-color, #e5e7eb);\n padding: 8px 16px;\n}\n\n.diff-item-wrapper {\n margin-bottom: 2px;\n}\n\n.diff-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 8px 12px;\n border-radius: 6px;\n}\n\n.diff-item.clickable {\n cursor: pointer;\n transition: background 0.15s ease;\n}\n\n.diff-item.clickable:hover {\n filter: brightness(0.97);\n}\n\n.diff-item-icon {\n font-size: 12px;\n width: 20px;\n text-align: center;\n}\n\n.diff-item-record {\n font-size: 13px;\n font-family: 'SF Mono', 'Fira Code', monospace;\n color: var(--text-primary, #1f2937);\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.diff-item-display-name {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n color: var(--text-secondary, #6b7280);\n font-weight: 500;\n}\n\n.diff-item-open-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 26px;\n height: 26px;\n border: 1px solid transparent;\n border-radius: 4px;\n background: transparent;\n color: var(--text-tertiary, #9ca3af);\n font-size: 11px;\n cursor: pointer;\n transition: all 0.15s ease;\n flex-shrink: 0;\n}\n\n.diff-item-open-btn:hover {\n border-color: #6366f1;\n color: #6366f1;\n background: rgba(99, 102, 241, 0.06);\n}\n\n.diff-item-type {\n font-size: 12px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.diff-item-chevron {\n font-size: 10px;\n color: var(--text-tertiary, #9ca3af);\n transition: transform 0.2s ease;\n}\n\n.diff-item-chevron.expanded {\n transform: rotate(90deg);\n}\n\n/* Field-level diff changes */\n.diff-fields {\n margin-left: 42px;\n margin-bottom: 8px;\n padding: 8px 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.diff-field {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 6px 10px;\n border-radius: 6px;\n font-size: 13px;\n}\n\n.diff-field.change-added {\n background: rgba(16, 185, 129, 0.06);\n}\n\n.diff-field.change-modified {\n background: rgba(245, 158, 11, 0.06);\n}\n\n.diff-field.change-removed {\n background: rgba(239, 68, 68, 0.06);\n}\n\n.diff-field-name {\n font-weight: 600;\n color: var(--text-primary, #1f2937);\n min-width: 120px;\n flex-shrink: 0;\n}\n\n.diff-field-values {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 0;\n flex: 1;\n}\n\n.diff-field-old {\n color: #ef4444;\n text-decoration: line-through;\n opacity: 0.8;\n font-family: 'SF Mono', 'Fira Code', monospace;\n font-size: 12px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.diff-field-arrow {\n color: var(--text-tertiary, #9ca3af);\n font-size: 10px;\n flex-shrink: 0;\n}\n\n.diff-field-new {\n color: #10b981;\n font-family: 'SF Mono', 'Fira Code', monospace;\n font-size: 12px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.diff-fields-empty {\n padding: 6px 10px;\n font-size: 12px;\n color: var(--text-tertiary, #9ca3af);\n font-style: italic;\n}\n\n/* Toolbar actions */\n.diff-toolbar-right {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.toolbar-action-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 6px;\n background: var(--card-background, #ffffff);\n color: var(--text-tertiary, #9ca3af);\n font-size: 13px;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.toolbar-action-btn:hover {\n border-color: #6366f1;\n color: #6366f1;\n background: rgba(99, 102, 241, 0.06);\n}\n\n/* Empty State */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n text-align: center;\n}\n\n.empty-icon {\n font-size: 48px;\n color: var(--text-tertiary, #9ca3af);\n margin-bottom: 16px;\n}\n\n.empty-state h3 {\n font-size: 18px;\n font-weight: 600;\n color: var(--text-primary, #1f2937);\n margin: 0 0 8px 0;\n}\n\n.empty-state p {\n font-size: 14px;\n color: var(--text-secondary, #6b7280);\n margin: 0;\n max-width: 400px;\n}\n\n/* Swap Button */\n.swap-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 50%;\n background: var(--card-background, #ffffff);\n color: #6366f1;\n font-size: 14px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.swap-btn:hover {\n background: rgba(99, 102, 241, 0.1);\n border-color: #6366f1;\n transform: rotate(180deg);\n}\n\n/* Diff Results Toolbar */\n.diff-toolbar {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 16px;\n flex-wrap: wrap;\n}\n\n.diff-search {\n position: relative;\n flex: 1;\n min-width: 200px;\n}\n\n.diff-search-icon {\n position: absolute;\n left: 12px;\n top: 50%;\n transform: translateY(-50%);\n color: var(--text-tertiary, #9ca3af);\n font-size: 13px;\n}\n\n.diff-search-input {\n width: 100%;\n padding: 8px 12px 8px 36px;\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 8px;\n font-size: 13px;\n background: var(--card-background, #ffffff);\n color: var(--text-primary, #1f2937);\n box-sizing: border-box;\n}\n\n.diff-search-input:focus {\n outline: none;\n border-color: #6366f1;\n box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);\n}\n\n.diff-filter-pills {\n display: flex;\n gap: 4px;\n}\n\n.filter-pill {\n padding: 6px 14px;\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 16px;\n background: var(--card-background, #ffffff);\n font-size: 12px;\n font-weight: 500;\n color: var(--text-secondary, #6b7280);\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.filter-pill:hover {\n border-color: #6366f1;\n color: #6366f1;\n}\n\n.filter-pill.active {\n background: #6366f1;\n border-color: #6366f1;\n color: #ffffff;\n}\n\n.filter-pill.change-added.active {\n background: #059669;\n border-color: #059669;\n}\n\n.filter-pill.change-removed.active {\n background: #dc2626;\n border-color: #dc2626;\n}\n\n.filter-pill.change-modified.active {\n background: #d97706;\n border-color: #d97706;\n}\n\n.diff-sort-toggle {\n display: flex;\n gap: 2px;\n}\n\n.toggle-btn-sm {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 6px;\n background: var(--card-background, #ffffff);\n color: var(--text-tertiary, #9ca3af);\n font-size: 13px;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.toggle-btn-sm:hover {\n border-color: #6366f1;\n color: #6366f1;\n}\n\n.toggle-btn-sm.active {\n background: rgba(99, 102, 241, 0.1);\n border-color: #6366f1;\n color: #6366f1;\n}\n\n@media (max-width: 768px) {\n .diff-summary {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .label-selectors {\n flex-direction: column;\n }\n}\n"] }]
|
|
1159
|
+
args: [{ standalone: false, selector: 'mj-version-history-diff-resource', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"diff-container\">\n @if (IsLoading) {\n <mj-loading text=\"Loading diff viewer...\"></mj-loading>\n }\n\n @if (!IsLoading) {\n <!-- Header -->\n <div class=\"page-header\">\n <div class=\"header-left\">\n <h2 class=\"page-title\">Diff Viewer</h2>\n <p class=\"page-subtitle\">Compare states between version labels or against current data</p>\n </div>\n </div>\n <!-- Diff Configuration Panel -->\n <div class=\"config-panel\">\n <!-- Mode Selector -->\n <div class=\"mode-selector\">\n <button class=\"mode-btn\"\n [class.active]=\"DiffMode === 'label-to-current'\"\n (click)=\"OnDiffModeChange('label-to-current')\">\n <i class=\"fa-solid fa-clock-rotate-left\"></i>\n Label vs Current\n </button>\n <button class=\"mode-btn\"\n [class.active]=\"DiffMode === 'label-to-label'\"\n (click)=\"OnDiffModeChange('label-to-label')\">\n <i class=\"fa-solid fa-code-compare\"></i>\n Label vs Label\n </button>\n </div>\n <!-- Label Selectors -->\n <div class=\"label-selectors\">\n <div class=\"selector-group\">\n <label class=\"selector-label\">\n {{DiffMode === 'label-to-current' ? 'Compare label' : 'From label'}}\n </label>\n <select class=\"selector-input\"\n [(ngModel)]=\"FromLabelId\">\n <option value=\"\">Select a label...</option>\n @for (label of FilteredFromLabels; track label) {\n <option\n [value]=\"label.ID\">\n {{FormatLabelOption(label)}}\n </option>\n }\n </select>\n </div>\n @if (DiffMode === 'label-to-label') {\n <div class=\"selector-arrow\">\n <button class=\"swap-btn\" (click)=\"SwapLabels()\" title=\"Swap direction\">\n <i class=\"fa-solid fa-arrows-rotate\"></i>\n </button>\n </div>\n }\n @if (DiffMode === 'label-to-current') {\n <div class=\"selector-arrow\">\n <i class=\"fa-solid fa-arrow-right\"></i>\n <span class=\"current-state-badge\">Current State</span>\n </div>\n }\n @if (DiffMode === 'label-to-label') {\n <div class=\"selector-group\">\n <label class=\"selector-label\">To label</label>\n <select class=\"selector-input\"\n [(ngModel)]=\"ToLabelId\">\n <option value=\"\">Select a label...</option>\n @for (label of FilteredToLabels; track label) {\n <option\n [value]=\"label.ID\">\n {{FormatLabelOption(label)}}\n </option>\n }\n </select>\n </div>\n }\n </div>\n <!-- Run Button -->\n <button class=\"btn-primary\"\n [disabled]=\"!CanRunDiff || IsDiffLoading\"\n (click)=\"RunDiff()\">\n @if (!IsDiffLoading) {\n <i class=\"fa-solid fa-play\"></i>\n }\n @if (IsDiffLoading) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n }\n <span>{{IsDiffLoading ? 'Comparing...' : 'Compare'}}</span>\n </button>\n </div>\n <!-- Diff Results -->\n @if (HasDiffResult) {\n <!-- Summary Stats -->\n <div class=\"diff-summary\">\n <div class=\"diff-stat change-added\">\n <i class=\"fa-solid fa-plus\"></i>\n <span class=\"diff-stat-value\">{{TotalAdded}}</span>\n <span class=\"diff-stat-label\">Added</span>\n </div>\n <div class=\"diff-stat change-removed\">\n <i class=\"fa-solid fa-minus\"></i>\n <span class=\"diff-stat-value\">{{TotalRemoved}}</span>\n <span class=\"diff-stat-label\">Removed</span>\n </div>\n <div class=\"diff-stat change-modified\">\n <i class=\"fa-solid fa-pen\"></i>\n <span class=\"diff-stat-value\">{{TotalModified}}</span>\n <span class=\"diff-stat-label\">Modified</span>\n </div>\n <div class=\"diff-stat change-unchanged\">\n <i class=\"fa-solid fa-equals\"></i>\n <span class=\"diff-stat-value\">{{TotalUnchanged}}</span>\n <span class=\"diff-stat-label\">Unchanged</span>\n </div>\n </div>\n <!-- Results toolbar -->\n @if (EntityGroups.length > 0) {\n <div class=\"diff-toolbar\">\n <div class=\"diff-search\">\n <i class=\"fa-solid fa-search diff-search-icon\"></i>\n <input type=\"text\" class=\"diff-search-input\"\n placeholder=\"Search by entity or record...\"\n [ngModel]=\"DiffSearch\"\n (ngModelChange)=\"OnDiffSearchChange($event)\" />\n </div>\n <div class=\"diff-filter-pills\">\n <button class=\"filter-pill\" [class.active]=\"DiffFilterType === 'all'\"\n (click)=\"OnDiffFilterChange('all')\">All</button>\n <button class=\"filter-pill change-added\" [class.active]=\"DiffFilterType === 'added'\"\n (click)=\"OnDiffFilterChange('added')\">Added</button>\n <button class=\"filter-pill change-removed\" [class.active]=\"DiffFilterType === 'removed'\"\n (click)=\"OnDiffFilterChange('removed')\">Removed</button>\n <button class=\"filter-pill change-modified\" [class.active]=\"DiffFilterType === 'modified'\"\n (click)=\"OnDiffFilterChange('modified')\">Modified</button>\n </div>\n <div class=\"diff-toolbar-right\">\n <button class=\"toolbar-action-btn\" (click)=\"ExpandAllGroups()\" title=\"Expand all\">\n <i class=\"fa-solid fa-angles-down\"></i>\n </button>\n <button class=\"toolbar-action-btn\" (click)=\"CollapseAllGroups()\" title=\"Collapse all\">\n <i class=\"fa-solid fa-angles-up\"></i>\n </button>\n <div class=\"diff-sort-toggle\">\n <button class=\"toggle-btn-sm\" [class.active]=\"DiffSortBy === 'name'\"\n (click)=\"OnDiffSortChange('name')\" title=\"Sort by name\">\n <i class=\"fa-solid\" [ngClass]=\"DiffSortBy === 'name' && DiffSortDir === 'desc' ? 'fa-arrow-up-z-a' : 'fa-arrow-down-a-z'\"></i>\n </button>\n <button class=\"toggle-btn-sm\" [class.active]=\"DiffSortBy === 'count'\"\n (click)=\"OnDiffSortChange('count')\" title=\"Sort by count\">\n <i class=\"fa-solid\" [ngClass]=\"DiffSortBy === 'count' && DiffSortDir === 'asc' ? 'fa-arrow-up-1-9' : 'fa-arrow-down-9-1'\"></i>\n </button>\n </div>\n </div>\n </div>\n }\n <!-- Entity Groups -->\n @if (FilteredEntityGroups.length > 0) {\n <div class=\"entity-groups\">\n @for (group of FilteredEntityGroups; track group) {\n <div class=\"entity-group\">\n <div class=\"entity-group-header\" (click)=\"ToggleEntityGroup(group)\">\n <div class=\"entity-group-left\">\n <i class=\"fa-solid fa-chevron-right entity-chevron\"\n [class.expanded]=\"group.IsExpanded\">\n </i>\n <i [class]=\"group.EntityIcon\" class=\"entity-icon\"></i>\n <span class=\"entity-group-name\">{{group.EntityName}}</span>\n </div>\n <div class=\"entity-group-badges\">\n @if (group.AddedCount > 0) {\n <span class=\"badge change-added\">\n +{{group.AddedCount}}\n </span>\n }\n @if (group.RemovedCount > 0) {\n <span class=\"badge change-removed\">\n -{{group.RemovedCount}}\n </span>\n }\n @if (group.ModifiedCount > 0) {\n <span class=\"badge change-modified\">\n ~{{group.ModifiedCount}}\n </span>\n }\n </div>\n </div>\n @if (group.IsExpanded) {\n <div class=\"entity-group-items\">\n @for (item of group.Items; track item) {\n <div class=\"diff-item-wrapper\">\n <div class=\"diff-item\" [ngClass]=\"GetChangeTypeClass(item.ChangeType)\"\n [class.clickable]=\"item.ChangeType === 'Modified'\"\n (click)=\"ToggleItem(item)\">\n <i [class]=\"GetChangeTypeIcon(item.ChangeType)\" class=\"diff-item-icon\"></i>\n <span class=\"diff-item-record\">\n {{FormatRecordID(item.RecordID)}}\n @if (item.DisplayName) {\n <span class=\"diff-item-display-name\"> ({{item.DisplayName}})</span>\n }\n </span>\n <span class=\"diff-item-type\">{{item.ChangeType}}</span>\n <button class=\"diff-item-open-btn\" (click)=\"OnOpenRecord(item); $event.stopPropagation()\"\n title=\"Open record\">\n <i class=\"fa-solid fa-arrow-up-right-from-square\"></i>\n </button>\n @if (item.ChangeType === 'Modified') {\n <i class=\"fa-solid fa-chevron-right diff-item-chevron\"\n [class.expanded]=\"item.IsExpanded\"\n ></i>\n }\n </div>\n <!-- Field-level changes -->\n @if (item.IsExpanded && item.ChangeType === 'Modified') {\n <div class=\"diff-fields\">\n @if (item.IsLoadingFields) {\n <mj-loading text=\"Loading changes...\" size=\"small\"></mj-loading>\n }\n @if (!item.IsLoadingFields && item.FieldChanges.length > 0) {\n @for (field of item.FieldChanges; track field) {\n <div class=\"diff-field\"\n [ngClass]=\"GetChangeTypeClass(field.ChangeType)\">\n <span class=\"diff-field-name\">{{field.FieldName}}</span>\n <span class=\"diff-field-values\">\n @if (field.OldValue) {\n <span class=\"diff-field-old\">{{field.OldValue | slice:0:60}}</span>\n }\n @if (field.OldValue && field.NewValue) {\n <i class=\"fa-solid fa-arrow-right diff-field-arrow\"></i>\n }\n @if (field.NewValue) {\n <span class=\"diff-field-new\">{{field.NewValue | slice:0:60}}</span>\n }\n </span>\n </div>\n }\n }\n @if (!item.IsLoadingFields && item.FieldsLoaded && item.FieldChanges.length === 0) {\n <div class=\"diff-fields-empty\">\n <span>No field-level changes available</span>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n <!-- No changes -->\n @if (FilteredEntityGroups.length === 0 && TotalChanges === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-check-circle empty-icon\" style=\"color: #10b981;\"></i>\n <h3>No differences found</h3>\n <p>The compared states are identical.</p>\n </div>\n }\n }\n <!-- No results yet -->\n @if (!HasDiffResult && !IsDiffLoading) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-code-compare empty-icon\"></i>\n <h3>Select labels to compare</h3>\n <p>Choose a diff mode and select labels above, then click Compare.</p>\n </div>\n }\n }\n</div>\n", styles: [".diff-container {\n padding: 24px;\n height: 100%;\n overflow-y: auto;\n}\n\n/* Header */\n.page-header {\n margin-bottom: 24px;\n}\n\n.page-title {\n font-size: 24px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0 0 4px 0;\n}\n\n.page-subtitle {\n font-size: 14px;\n color: var(--mj-text-secondary);\n margin: 0;\n}\n\n/* Config Panel */\n.config-panel {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n padding: 24px;\n margin-bottom: 24px;\n}\n\n.mode-selector {\n display: flex;\n gap: 8px;\n margin-bottom: 20px;\n}\n\n.mode-btn {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 8px 18px;\n background: var(--mj-bg-surface-sunken);\n border: 2px solid transparent;\n border-radius: 8px;\n cursor: pointer;\n font-size: 14px;\n color: var(--mj-text-secondary);\n transition: all 0.2s ease;\n}\n\n.mode-btn:hover {\n background: var(--mj-border-default);\n}\n\n.mode-btn.active {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n/* Label Selectors */\n.label-selectors {\n display: flex;\n align-items: flex-end;\n gap: 16px;\n margin-bottom: 20px;\n}\n\n.selector-group {\n flex: 1;\n}\n\n.selector-label {\n display: block;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n margin-bottom: 6px;\n}\n\n.selector-input {\n width: 100%;\n padding: 10px 12px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-radius: 8px;\n font-size: 14px;\n color: var(--mj-text-primary);\n outline: none;\n box-sizing: border-box;\n}\n\n.selector-input:focus {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.selector-arrow {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n padding-bottom: 8px;\n color: var(--mj-text-secondary);\n font-size: 16px;\n}\n\n.current-state-badge {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n padding: 2px 8px;\n border-radius: 8px;\n white-space: nowrap;\n}\n\n/* Run Button */\n.btn-primary {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 10px 24px;\n background: var(--mj-brand-primary);\n border: none;\n border-radius: 8px;\n color: var(--mj-text-inverse);\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.btn-primary:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n.btn-primary:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n/* Diff Summary */\n.diff-summary {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: 12px;\n margin-bottom: 24px;\n}\n\n.diff-stat {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 16px 20px;\n border-radius: 10px;\n border: 1px solid var(--mj-border-default);\n}\n\n.diff-stat i {\n font-size: 16px;\n}\n\n.diff-stat-value {\n font-size: 22px;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.diff-stat-label {\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n\n/* Change type colors */\n.change-added {\n background: color-mix(in srgb, var(--mj-status-success) 6%, transparent);\n border-color: color-mix(in srgb, var(--mj-status-success) 20%, transparent);\n color: var(--mj-status-success);\n}\n\n.change-removed {\n background: color-mix(in srgb, var(--mj-status-error) 6%, transparent);\n border-color: color-mix(in srgb, var(--mj-status-error) 20%, transparent);\n color: var(--mj-status-error);\n}\n\n.change-modified {\n background: color-mix(in srgb, var(--mj-status-warning) 6%, transparent);\n border-color: color-mix(in srgb, var(--mj-status-warning) 20%, transparent);\n color: var(--mj-status-warning);\n}\n\n.change-unchanged {\n background: color-mix(in srgb, var(--mj-text-muted) 6%, transparent);\n border-color: color-mix(in srgb, var(--mj-text-muted) 20%, transparent);\n color: var(--mj-text-muted);\n}\n\n/* Entity Groups */\n.entity-groups {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.entity-group {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n overflow: hidden;\n}\n\n.entity-group-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 14px 20px;\n cursor: pointer;\n transition: background 0.15s ease;\n}\n\n.entity-group-header:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.entity-group-left {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.entity-group-left i:first-child {\n font-size: 12px;\n color: var(--mj-text-muted);\n width: 16px;\n}\n\n.entity-icon {\n color: var(--mj-brand-primary);\n font-size: 14px;\n}\n\n.entity-group-name {\n font-size: 15px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.entity-group-badges {\n display: flex;\n gap: 6px;\n}\n\n.badge {\n display: inline-flex;\n align-items: center;\n padding: 3px 10px;\n border-radius: 12px;\n font-size: 12px;\n font-weight: 600;\n border: none;\n}\n\n/* Entity chevron animation */\n.entity-chevron {\n font-size: 11px;\n color: var(--mj-text-muted);\n width: 14px;\n text-align: center;\n transition: transform 0.2s ease;\n}\n\n.entity-chevron.expanded {\n transform: rotate(90deg);\n}\n\n/* Entity group items */\n.entity-group-items {\n border-top: 1px solid var(--mj-border-default);\n padding: 8px 16px;\n}\n\n.diff-item-wrapper {\n margin-bottom: 2px;\n}\n\n.diff-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 8px 12px;\n border-radius: 6px;\n}\n\n.diff-item.clickable {\n cursor: pointer;\n transition: background 0.15s ease;\n}\n\n.diff-item.clickable:hover {\n filter: brightness(0.97);\n}\n\n.diff-item-icon {\n font-size: 12px;\n width: 20px;\n text-align: center;\n}\n\n.diff-item-record {\n font-size: 13px;\n font-family: 'SF Mono', 'Fira Code', monospace;\n color: var(--mj-text-primary);\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.diff-item-display-name {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n color: var(--mj-text-secondary);\n font-weight: 500;\n}\n\n.diff-item-open-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 26px;\n height: 26px;\n border: 1px solid transparent;\n border-radius: 4px;\n background: transparent;\n color: var(--mj-text-muted);\n font-size: 11px;\n cursor: pointer;\n transition: all 0.15s ease;\n flex-shrink: 0;\n}\n\n.diff-item-open-btn:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 6%, transparent);\n}\n\n.diff-item-type {\n font-size: 12px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.diff-item-chevron {\n font-size: 10px;\n color: var(--mj-text-muted);\n transition: transform 0.2s ease;\n}\n\n.diff-item-chevron.expanded {\n transform: rotate(90deg);\n}\n\n/* Field-level diff changes */\n.diff-fields {\n margin-left: 42px;\n margin-bottom: 8px;\n padding: 8px 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.diff-field {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 6px 10px;\n border-radius: 6px;\n font-size: 13px;\n}\n\n.diff-field.change-added {\n background: color-mix(in srgb, var(--mj-status-success) 6%, transparent);\n}\n\n.diff-field.change-modified {\n background: color-mix(in srgb, var(--mj-status-warning) 6%, transparent);\n}\n\n.diff-field.change-removed {\n background: color-mix(in srgb, var(--mj-status-error) 6%, transparent);\n}\n\n.diff-field-name {\n font-weight: 600;\n color: var(--mj-text-primary);\n min-width: 120px;\n flex-shrink: 0;\n}\n\n.diff-field-values {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 0;\n flex: 1;\n}\n\n.diff-field-old {\n color: var(--mj-status-error);\n text-decoration: line-through;\n opacity: 0.8;\n font-family: 'SF Mono', 'Fira Code', monospace;\n font-size: 12px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.diff-field-arrow {\n color: var(--mj-text-muted);\n font-size: 10px;\n flex-shrink: 0;\n}\n\n.diff-field-new {\n color: var(--mj-status-success);\n font-family: 'SF Mono', 'Fira Code', monospace;\n font-size: 12px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.diff-fields-empty {\n padding: 6px 10px;\n font-size: 12px;\n color: var(--mj-text-muted);\n font-style: italic;\n}\n\n/* Toolbar actions */\n.diff-toolbar-right {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.toolbar-action-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-muted);\n font-size: 13px;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.toolbar-action-btn:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 6%, transparent);\n}\n\n/* Empty State */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n text-align: center;\n}\n\n.empty-icon {\n font-size: 48px;\n color: var(--mj-text-muted);\n margin-bottom: 16px;\n}\n\n.empty-state h3 {\n font-size: 18px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 8px 0;\n}\n\n.empty-state p {\n font-size: 14px;\n color: var(--mj-text-secondary);\n margin: 0;\n max-width: 400px;\n}\n\n/* Swap Button */\n.swap-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n border: 1px solid var(--mj-border-default);\n border-radius: 50%;\n background: var(--mj-bg-surface-card);\n color: var(--mj-brand-primary);\n font-size: 14px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.swap-btn:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n border-color: var(--mj-brand-primary);\n transform: rotate(180deg);\n}\n\n/* Diff Results Toolbar */\n.diff-toolbar {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 16px;\n flex-wrap: wrap;\n}\n\n.diff-search {\n position: relative;\n flex: 1;\n min-width: 200px;\n}\n\n.diff-search-icon {\n position: absolute;\n left: 12px;\n top: 50%;\n transform: translateY(-50%);\n color: var(--mj-text-muted);\n font-size: 13px;\n}\n\n.diff-search-input {\n width: 100%;\n padding: 8px 12px 8px 36px;\n border: 1px solid var(--mj-border-strong);\n border-radius: 8px;\n font-size: 13px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n box-sizing: border-box;\n}\n\n.diff-search-input:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.diff-filter-pills {\n display: flex;\n gap: 4px;\n}\n\n.filter-pill {\n padding: 6px 14px;\n border: 1px solid var(--mj-border-default);\n border-radius: 16px;\n background: var(--mj-bg-surface-card);\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.filter-pill:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n.filter-pill.active {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.filter-pill.change-added.active {\n background: var(--mj-status-success);\n border-color: var(--mj-status-success);\n}\n\n.filter-pill.change-removed.active {\n background: var(--mj-status-error);\n border-color: var(--mj-status-error);\n}\n\n.filter-pill.change-modified.active {\n background: var(--mj-status-warning);\n border-color: var(--mj-status-warning);\n}\n\n.diff-sort-toggle {\n display: flex;\n gap: 2px;\n}\n\n.toggle-btn-sm {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-muted);\n font-size: 13px;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.toggle-btn-sm:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n.toggle-btn-sm.active {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n@media (max-width: 768px) {\n .diff-summary {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .label-selectors {\n flex-direction: column;\n }\n}\n"] }]
|
|
1160
1160
|
}], () => [{ type: i0.ChangeDetectorRef }, { type: i1.NavigationService }], null); })();
|
|
1161
1161
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(VersionHistoryDiffResourceComponent, { className: "VersionHistoryDiffResourceComponent", filePath: "src/VersionHistory/components/diff-resource.component.ts", lineNumber: 59 }); })();
|
|
1162
1162
|
//# sourceMappingURL=diff-resource.component.js.map
|
|
@@ -507,7 +507,7 @@ let VersionHistoryGraphResourceComponent = class VersionHistoryGraphResourceComp
|
|
|
507
507
|
i0.ɵɵconditional(ctx.IsLoading ? 1 : -1);
|
|
508
508
|
i0.ɵɵadvance();
|
|
509
509
|
i0.ɵɵconditional(!ctx.IsLoading ? 2 : -1);
|
|
510
|
-
} }, dependencies: [i1.NgClass, i2.DefaultValueAccessor, i2.NgControlStatus, i2.NgModel, i3.LoadingComponent], styles: [".graph-container[_ngcontent-%COMP%] {\n padding: 24px;\n height: 100%;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n}\n\n\n\n.page-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 20px;\n}\n\n.header-left[_ngcontent-%COMP%] { flex: 1; }\n\n.page-title[_ngcontent-%COMP%] {\n font-size: 24px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n margin: 0 0 4px 0;\n}\n\n.page-subtitle[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--text-secondary, #6b7280);\n margin: 0;\n}\n\n.header-actions[_ngcontent-%COMP%] { display: flex; gap: 12px; }\n\n.btn-icon[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n background: var(--card-background, #ffffff);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n color: var(--text-secondary, #6b7280);\n}\n\n.btn-icon[_ngcontent-%COMP%]:hover {\n background: var(--hover-background, #f3f4f6);\n color: var(--text-primary, #1f2937);\n}\n\n\n\n.stats-row[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n margin-bottom: 20px;\n}\n\n.stat-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n background: var(--card-background, #ffffff);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 20px;\n font-size: 13px;\n color: var(--text-secondary, #6b7280);\n}\n\n.stat-badge[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #6366f1;\n}\n\n\n\n.graph-layout[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 340px 1fr;\n gap: 20px;\n flex: 1;\n min-height: 0;\n}\n\n\n\n.entity-list-panel[_ngcontent-%COMP%] {\n background: var(--card-background, #ffffff);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 12px;\n display: flex;\n flex-direction: column;\n max-height: calc(100vh - 280px);\n}\n\n.panel-header[_ngcontent-%COMP%] {\n padding: 16px 20px 0;\n}\n\n.panel-title[_ngcontent-%COMP%] {\n font-size: 16px;\n font-weight: 600;\n color: var(--text-primary, #1f2937);\n margin: 0;\n}\n\n.search-bar[_ngcontent-%COMP%] {\n position: relative;\n padding: 12px 16px 8px;\n}\n\n.search-icon[_ngcontent-%COMP%] {\n position: absolute;\n left: 28px;\n top: 50%;\n transform: translateY(-50%);\n color: var(--text-secondary, #6b7280);\n font-size: 13px;\n}\n\n.search-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 8px 12px 8px 34px;\n background: var(--hover-background, #f3f4f6);\n border: 1px solid transparent;\n border-radius: 8px;\n font-size: 13px;\n color: var(--text-primary, #1f2937);\n outline: none;\n box-sizing: border-box;\n}\n\n.search-input[_ngcontent-%COMP%]:focus {\n background: var(--card-background, #ffffff);\n border-color: #6366f1;\n}\n\n\n\n.schema-chips[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n padding: 0 16px 10px;\n}\n\n.schema-chip[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 4px 10px;\n background: var(--hover-background, #f3f4f6);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 14px;\n font-size: 11px;\n font-weight: 500;\n color: var(--text-secondary, #6b7280);\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.schema-chip[_ngcontent-%COMP%]:hover {\n background: rgba(99, 102, 241, 0.06);\n border-color: rgba(99, 102, 241, 0.3);\n}\n\n.schema-chip.active[_ngcontent-%COMP%] {\n background: rgba(99, 102, 241, 0.1);\n border-color: #6366f1;\n color: #6366f1;\n}\n\n.schema-chip-count[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 18px;\n height: 18px;\n padding: 0 4px;\n background: rgba(0, 0, 0, 0.06);\n border-radius: 9px;\n font-size: 10px;\n font-weight: 600;\n}\n\n.schema-chip.active[_ngcontent-%COMP%] .schema-chip-count[_ngcontent-%COMP%] {\n background: rgba(99, 102, 241, 0.15);\n}\n\n.entity-scroll-list[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 0 8px 8px;\n}\n\n.entity-list-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 12px;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.entity-list-item[_ngcontent-%COMP%]:hover {\n background: var(--hover-background, #f3f4f6);\n}\n\n.entity-list-item.selected[_ngcontent-%COMP%] {\n background: rgba(99, 102, 241, 0.08);\n border-left: 3px solid #6366f1;\n}\n\n.entity-list-name[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--text-primary, #1f2937);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n flex: 1;\n}\n\n.entity-list-badges[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n flex-shrink: 0;\n}\n\n.dep-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 3px;\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.dep-badge[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { font-size: 9px; }\n\n.level-none[_ngcontent-%COMP%] { display: none; }\n\n.level-low[_ngcontent-%COMP%] {\n background: rgba(16, 185, 129, 0.1);\n color: #059669;\n}\n\n.level-medium[_ngcontent-%COMP%] {\n background: rgba(245, 158, 11, 0.1);\n color: #d97706;\n}\n\n.level-high[_ngcontent-%COMP%] {\n background: rgba(239, 68, 68, 0.1);\n color: #dc2626;\n}\n\n.level-depends-on[_ngcontent-%COMP%] {\n background: rgba(99, 102, 241, 0.1);\n color: #6366f1;\n}\n\n.empty-list[_ngcontent-%COMP%] {\n padding: 20px;\n text-align: center;\n font-size: 13px;\n color: var(--text-secondary, #6b7280);\n}\n\n\n\n.entity-detail-panel[_ngcontent-%COMP%] {\n background: var(--card-background, #ffffff);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 12px;\n padding: 24px;\n overflow-y: auto;\n max-height: calc(100vh - 280px);\n}\n\n.detail-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 28px;\n padding-bottom: 16px;\n border-bottom: 1px solid var(--border-color, #e5e7eb);\n}\n\n.detail-header-text[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.detail-icon[_ngcontent-%COMP%] {\n font-size: 20px;\n color: #6366f1;\n}\n\n.detail-title[_ngcontent-%COMP%] {\n font-size: 20px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n margin: 0;\n}\n\n.detail-schema[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--text-secondary, #6b7280);\n}\n\n\n\n.relationship-section[_ngcontent-%COMP%] {\n margin-bottom: 28px;\n}\n\n.section-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n margin-bottom: 4px;\n}\n\n.section-header[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--text-primary, #1f2937);\n margin: 0;\n flex: 1;\n}\n\n.section-hint[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--text-tertiary, #9ca3af);\n margin: 0 0 12px 0;\n}\n\n.section-hint[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] {\n color: var(--text-secondary, #6b7280);\n}\n\n.section-icon[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.referenced-by-icon[_ngcontent-%COMP%] { color: #10b981; }\n.depends-on-icon[_ngcontent-%COMP%] { color: #6366f1; }\n\n.section-count[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 24px;\n height: 24px;\n padding: 0 8px;\n background: var(--hover-background, #f3f4f6);\n border-radius: 12px;\n font-size: 12px;\n font-weight: 600;\n color: var(--text-secondary, #6b7280);\n}\n\n.relationship-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.relationship-item[_ngcontent-%COMP%] {\n border-radius: 8px;\n transition: background 0.15s ease;\n}\n\n.relationship-item[_ngcontent-%COMP%]:hover {\n background: var(--hover-background, #f3f4f6);\n}\n\n.rel-main[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n cursor: pointer;\n}\n\n.rel-icon[_ngcontent-%COMP%] {\n font-size: 12px;\n color: #6366f1;\n opacity: 0.7;\n flex-shrink: 0;\n}\n\n.rel-entity-name[_ngcontent-%COMP%] {\n font-size: 14px;\n color: #6366f1;\n font-weight: 500;\n}\n\n.rel-entity-name[_ngcontent-%COMP%]:hover {\n text-decoration: underline;\n}\n\n.rel-join-field[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 11px;\n color: var(--text-tertiary, #9ca3af);\n font-family: 'SF Mono', 'Fira Code', monospace;\n margin-left: 4px;\n padding: 2px 8px;\n background: var(--hover-background, #f3f4f6);\n border-radius: 4px;\n}\n\n.rel-join-field[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 9px;\n opacity: 0.5;\n}\n\n.empty-relationships[_ngcontent-%COMP%] {\n padding: 12px;\n text-align: center;\n font-size: 13px;\n color: var(--text-tertiary, #9ca3af);\n}\n\n\n\n.no-selection[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n text-align: center;\n height: 100%;\n}\n\n.no-selection-icon[_ngcontent-%COMP%] {\n font-size: 48px;\n color: var(--text-tertiary, #9ca3af);\n margin-bottom: 16px;\n}\n\n.no-selection[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n font-size: 18px;\n font-weight: 600;\n color: var(--text-primary, #1f2937);\n margin: 0 0 8px 0;\n}\n\n.no-selection[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--text-secondary, #6b7280);\n margin: 0;\n max-width: 300px;\n}"], changeDetection: 0 });
|
|
510
|
+
} }, dependencies: [i1.NgClass, i2.DefaultValueAccessor, i2.NgControlStatus, i2.NgModel, i3.LoadingComponent], styles: [".graph-container[_ngcontent-%COMP%] {\n padding: 24px;\n height: 100%;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n}\n\n\n\n.page-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 20px;\n}\n\n.header-left[_ngcontent-%COMP%] { flex: 1; }\n\n.page-title[_ngcontent-%COMP%] {\n font-size: 24px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0 0 4px 0;\n}\n\n.page-subtitle[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--mj-text-secondary);\n margin: 0;\n}\n\n.header-actions[_ngcontent-%COMP%] { display: flex; gap: 12px; }\n\n.btn-icon[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n color: var(--mj-text-secondary);\n}\n\n.btn-icon[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n\n\n.stats-row[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n margin-bottom: 20px;\n}\n\n.stat-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 20px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n\n.stat-badge[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n\n\n.graph-layout[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 340px 1fr;\n gap: 20px;\n flex: 1;\n min-height: 0;\n}\n\n\n\n.entity-list-panel[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n display: flex;\n flex-direction: column;\n max-height: calc(100vh - 280px);\n}\n\n.panel-header[_ngcontent-%COMP%] {\n padding: 16px 20px 0;\n}\n\n.panel-title[_ngcontent-%COMP%] {\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0;\n}\n\n.search-bar[_ngcontent-%COMP%] {\n position: relative;\n padding: 12px 16px 8px;\n}\n\n.search-icon[_ngcontent-%COMP%] {\n position: absolute;\n left: 28px;\n top: 50%;\n transform: translateY(-50%);\n color: var(--mj-text-secondary);\n font-size: 13px;\n}\n\n.search-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 8px 12px 8px 34px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-radius: 8px;\n font-size: 13px;\n color: var(--mj-text-primary);\n outline: none;\n box-sizing: border-box;\n}\n\n.search-input[_ngcontent-%COMP%]:focus {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-brand-primary);\n}\n\n\n\n.schema-chips[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n padding: 0 16px 10px;\n}\n\n.schema-chip[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 4px 10px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 14px;\n font-size: 11px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.schema-chip[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 6%, transparent);\n border-color: color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n.schema-chip.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n.schema-chip-count[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 18px;\n height: 18px;\n padding: 0 4px;\n background: color-mix(in srgb, var(--mj-text-primary) 6%, transparent);\n border-radius: 9px;\n font-size: 10px;\n font-weight: 600;\n}\n\n.schema-chip.active[_ngcontent-%COMP%] .schema-chip-count[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.entity-scroll-list[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 0 8px 8px;\n}\n\n.entity-list-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 12px;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.entity-list-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.entity-list-item.selected[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n border-left: 3px solid var(--mj-brand-primary);\n}\n\n.entity-list-name[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n flex: 1;\n}\n\n.entity-list-badges[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n flex-shrink: 0;\n}\n\n.dep-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 3px;\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.dep-badge[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { font-size: 9px; }\n\n.level-none[_ngcontent-%COMP%] { display: none; }\n\n.level-low[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 10%, transparent);\n color: var(--mj-status-success);\n}\n\n.level-medium[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 10%, transparent);\n color: var(--mj-status-warning);\n}\n\n.level-high[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 10%, transparent);\n color: var(--mj-status-error);\n}\n\n.level-depends-on[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n color: var(--mj-brand-primary);\n}\n\n.empty-list[_ngcontent-%COMP%] {\n padding: 20px;\n text-align: center;\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n\n\n\n.entity-detail-panel[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n padding: 24px;\n overflow-y: auto;\n max-height: calc(100vh - 280px);\n}\n\n.detail-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 28px;\n padding-bottom: 16px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.detail-header-text[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.detail-icon[_ngcontent-%COMP%] {\n font-size: 20px;\n color: var(--mj-brand-primary);\n}\n\n.detail-title[_ngcontent-%COMP%] {\n font-size: 20px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0;\n}\n\n.detail-schema[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n\n\n.relationship-section[_ngcontent-%COMP%] {\n margin-bottom: 28px;\n}\n\n.section-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n margin-bottom: 4px;\n}\n\n.section-header[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0;\n flex: 1;\n}\n\n.section-hint[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n margin: 0 0 12px 0;\n}\n\n.section-hint[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n}\n\n.section-icon[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.referenced-by-icon[_ngcontent-%COMP%] { color: var(--mj-status-success); }\n.depends-on-icon[_ngcontent-%COMP%] { color: var(--mj-brand-primary); }\n\n.section-count[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 24px;\n height: 24px;\n padding: 0 8px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 12px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.relationship-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.relationship-item[_ngcontent-%COMP%] {\n border-radius: 8px;\n transition: background 0.15s ease;\n}\n\n.relationship-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.rel-main[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n cursor: pointer;\n}\n\n.rel-icon[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-brand-primary);\n opacity: 0.7;\n flex-shrink: 0;\n}\n\n.rel-entity-name[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--mj-brand-primary);\n font-weight: 500;\n}\n\n.rel-entity-name[_ngcontent-%COMP%]:hover {\n text-decoration: underline;\n}\n\n.rel-join-field[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 11px;\n color: var(--mj-text-muted);\n font-family: 'SF Mono', 'Fira Code', monospace;\n margin-left: 4px;\n padding: 2px 8px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 4px;\n}\n\n.rel-join-field[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 9px;\n opacity: 0.5;\n}\n\n.empty-relationships[_ngcontent-%COMP%] {\n padding: 12px;\n text-align: center;\n font-size: 13px;\n color: var(--mj-text-muted);\n}\n\n\n\n.no-selection[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n text-align: center;\n height: 100%;\n}\n\n.no-selection-icon[_ngcontent-%COMP%] {\n font-size: 48px;\n color: var(--mj-text-muted);\n margin-bottom: 16px;\n}\n\n.no-selection[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n font-size: 18px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 8px 0;\n}\n\n.no-selection[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--mj-text-secondary);\n margin: 0;\n max-width: 300px;\n}"], changeDetection: 0 });
|
|
511
511
|
};
|
|
512
512
|
VersionHistoryGraphResourceComponent = VersionHistoryGraphResourceComponent_1 = __decorate([
|
|
513
513
|
RegisterClass(BaseResourceComponent, 'VersionHistoryGraphResource')
|
|
@@ -515,7 +515,7 @@ VersionHistoryGraphResourceComponent = VersionHistoryGraphResourceComponent_1 =
|
|
|
515
515
|
export { VersionHistoryGraphResourceComponent };
|
|
516
516
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(VersionHistoryGraphResourceComponent, [{
|
|
517
517
|
type: Component,
|
|
518
|
-
args: [{ standalone: false, selector: 'mj-version-history-graph-resource', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"graph-container\">\n @if (IsLoading) {\n <mj-loading text=\"Loading dependency graph...\"></mj-loading>\n }\n\n @if (!IsLoading) {\n <!-- Header -->\n <div class=\"page-header\">\n <div class=\"header-left\">\n <h2 class=\"page-title\">Entity Dependency Graph</h2>\n <p class=\"page-subtitle\">Explore entity relationships used by the version history system</p>\n </div>\n <div class=\"header-actions\">\n <button class=\"btn-icon\" (click)=\"Refresh()\" title=\"Refresh\">\n <i class=\"fa-solid fa-refresh\"></i>\n </button>\n </div>\n </div>\n <!-- Stats Row -->\n <div class=\"stats-row\">\n <div class=\"stat-badge\">\n <i class=\"fa-solid fa-table\"></i>\n <span>{{TotalEntities}} Entities</span>\n </div>\n <div class=\"stat-badge\">\n <i class=\"fa-solid fa-diagram-project\"></i>\n <span>{{EntitiesWithDependents}} with Dependents</span>\n </div>\n <div class=\"stat-badge\">\n <i class=\"fa-solid fa-arrow-right-arrow-left\"></i>\n <span>{{TotalRelationships}} Relationships</span>\n </div>\n </div>\n <!-- Main Layout: Entity List + Detail -->\n <div class=\"graph-layout\">\n <!-- Entity List -->\n <div class=\"entity-list-panel\">\n <div class=\"panel-header\">\n <h3 class=\"panel-title\">Entities</h3>\n </div>\n <div class=\"search-bar\">\n <i class=\"fa-solid fa-search search-icon\"></i>\n <input type=\"text\"\n class=\"search-input\"\n placeholder=\"Filter entities...\"\n [ngModel]=\"SearchText\"\n (ngModelChange)=\"OnSearchChange($event)\" />\n </div>\n <!-- Schema Filter Chips -->\n @if (AvailableSchemas.length > 1) {\n <div class=\"schema-chips\">\n @for (schema of AvailableSchemas; track schema) {\n <button class=\"schema-chip\"\n [class.active]=\"SchemaFilter === schema\"\n (click)=\"OnSchemaFilterChange(schema)\">\n {{schema}}\n <span class=\"schema-chip-count\">{{GetSchemaEntityCount(schema)}}</span>\n </button>\n }\n </div>\n }\n <div class=\"entity-scroll-list\">\n @for (entity of FilteredEntities; track entity) {\n <div class=\"entity-list-item\"\n [class.selected]=\"entity.IsSelected\"\n (click)=\"SelectEntity(entity)\">\n <div class=\"entity-list-name\">{{entity.Name}}</div>\n <div class=\"entity-list-badges\">\n @if (entity.ReferencedByCount > 0) {\n <span class=\"dep-badge\"\n [ngClass]=\"GetDependencyLevel(entity.ReferencedByCount)\"\n title=\"Referenced by (entities with FKs to this)\">\n {{entity.ReferencedByCount}} <i class=\"fa-solid fa-arrow-down\"></i>\n </span>\n }\n @if (entity.DependsOnCount > 0) {\n <span class=\"dep-badge level-depends-on\"\n title=\"Depends on (entities this has FKs to)\">\n {{entity.DependsOnCount}} <i class=\"fa-solid fa-arrow-up\"></i>\n </span>\n }\n </div>\n </div>\n }\n @if (FilteredEntities.length === 0) {\n <div class=\"empty-list\">\n <p>No entities match your search.</p>\n </div>\n }\n </div>\n </div>\n <!-- Detail Panel -->\n <div class=\"entity-detail-panel\">\n @if (SelectedEntity) {\n <div class=\"detail-header\">\n <i class=\"fa-solid fa-table detail-icon\"></i>\n <div class=\"detail-header-text\">\n <h3 class=\"detail-title\">{{SelectedEntity.Name}}</h3>\n <span class=\"detail-schema\">{{SelectedEntity.SchemaName}}</span>\n </div>\n </div>\n <!-- Referenced By (entities that have FKs pointing to this entity) -->\n <div class=\"relationship-section\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-arrow-down section-icon referenced-by-icon\"></i>\n <h4>Referenced By</h4>\n <span class=\"section-count\">{{ReferencedByEntities.length}}</span>\n </div>\n <p class=\"section-hint\">Entities that have foreign keys pointing to <strong>{{SelectedEntity.Name}}</strong></p>\n @if (ReferencedByEntities.length > 0) {\n <div class=\"relationship-list\">\n @for (rel of ReferencedByEntities; track rel) {\n <div class=\"relationship-item\">\n <div class=\"rel-main\"\n (click)=\"NavigateToEntity(rel.ToEntity)\">\n <i class=\"fa-solid fa-table rel-icon\"></i>\n <span class=\"rel-entity-name\">{{rel.ToEntity}}</span>\n <span class=\"rel-join-field\">\n <i class=\"fa-solid fa-link\"></i>\n {{rel.RelatedEntityJoinField}}\n </span>\n </div>\n </div>\n }\n </div>\n }\n @if (ReferencedByEntities.length === 0) {\n <div class=\"empty-relationships\">\n <p>No entities reference this entity.</p>\n </div>\n }\n </div>\n <!-- Depends On (entities this entity has FKs to) -->\n <div class=\"relationship-section\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-arrow-up section-icon depends-on-icon\"></i>\n <h4>Depends On</h4>\n <span class=\"section-count\">{{DependsOnEntities.length}}</span>\n </div>\n <p class=\"section-hint\"><strong>{{SelectedEntity.Name}}</strong> has foreign keys pointing to these entities</p>\n @if (DependsOnEntities.length > 0) {\n <div class=\"relationship-list\">\n @for (rel of DependsOnEntities; track rel) {\n <div class=\"relationship-item\">\n <div class=\"rel-main\"\n (click)=\"NavigateToEntity(rel.FromEntity)\">\n <i class=\"fa-solid fa-table rel-icon\"></i>\n <span class=\"rel-entity-name\">{{rel.FromEntity}}</span>\n <span class=\"rel-join-field\">\n <i class=\"fa-solid fa-link\"></i>\n {{rel.RelatedEntityJoinField}}\n </span>\n </div>\n </div>\n }\n </div>\n }\n @if (DependsOnEntities.length === 0) {\n <div class=\"empty-relationships\">\n <p>This entity has no foreign key dependencies.</p>\n </div>\n }\n </div>\n } @else {\n <div class=\"no-selection\">\n <i class=\"fa-solid fa-diagram-project no-selection-icon\"></i>\n <h3>Select an Entity</h3>\n <p>Choose an entity from the list to explore its dependency relationships.</p>\n </div>\n }\n </div>\n </div>\n }\n</div>\n", styles: [".graph-container {\n padding: 24px;\n height: 100%;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n}\n\n/* Header */\n.page-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 20px;\n}\n\n.header-left { flex: 1; }\n\n.page-title {\n font-size: 24px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n margin: 0 0 4px 0;\n}\n\n.page-subtitle {\n font-size: 14px;\n color: var(--text-secondary, #6b7280);\n margin: 0;\n}\n\n.header-actions { display: flex; gap: 12px; }\n\n.btn-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n background: var(--card-background, #ffffff);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n color: var(--text-secondary, #6b7280);\n}\n\n.btn-icon:hover {\n background: var(--hover-background, #f3f4f6);\n color: var(--text-primary, #1f2937);\n}\n\n/* Stats Row */\n.stats-row {\n display: flex;\n gap: 12px;\n margin-bottom: 20px;\n}\n\n.stat-badge {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n background: var(--card-background, #ffffff);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 20px;\n font-size: 13px;\n color: var(--text-secondary, #6b7280);\n}\n\n.stat-badge i {\n color: #6366f1;\n}\n\n/* Main Layout */\n.graph-layout {\n display: grid;\n grid-template-columns: 340px 1fr;\n gap: 20px;\n flex: 1;\n min-height: 0;\n}\n\n/* Entity List Panel */\n.entity-list-panel {\n background: var(--card-background, #ffffff);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 12px;\n display: flex;\n flex-direction: column;\n max-height: calc(100vh - 280px);\n}\n\n.panel-header {\n padding: 16px 20px 0;\n}\n\n.panel-title {\n font-size: 16px;\n font-weight: 600;\n color: var(--text-primary, #1f2937);\n margin: 0;\n}\n\n.search-bar {\n position: relative;\n padding: 12px 16px 8px;\n}\n\n.search-icon {\n position: absolute;\n left: 28px;\n top: 50%;\n transform: translateY(-50%);\n color: var(--text-secondary, #6b7280);\n font-size: 13px;\n}\n\n.search-input {\n width: 100%;\n padding: 8px 12px 8px 34px;\n background: var(--hover-background, #f3f4f6);\n border: 1px solid transparent;\n border-radius: 8px;\n font-size: 13px;\n color: var(--text-primary, #1f2937);\n outline: none;\n box-sizing: border-box;\n}\n\n.search-input:focus {\n background: var(--card-background, #ffffff);\n border-color: #6366f1;\n}\n\n/* Schema Filter Chips */\n.schema-chips {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n padding: 0 16px 10px;\n}\n\n.schema-chip {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 4px 10px;\n background: var(--hover-background, #f3f4f6);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 14px;\n font-size: 11px;\n font-weight: 500;\n color: var(--text-secondary, #6b7280);\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.schema-chip:hover {\n background: rgba(99, 102, 241, 0.06);\n border-color: rgba(99, 102, 241, 0.3);\n}\n\n.schema-chip.active {\n background: rgba(99, 102, 241, 0.1);\n border-color: #6366f1;\n color: #6366f1;\n}\n\n.schema-chip-count {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 18px;\n height: 18px;\n padding: 0 4px;\n background: rgba(0, 0, 0, 0.06);\n border-radius: 9px;\n font-size: 10px;\n font-weight: 600;\n}\n\n.schema-chip.active .schema-chip-count {\n background: rgba(99, 102, 241, 0.15);\n}\n\n.entity-scroll-list {\n flex: 1;\n overflow-y: auto;\n padding: 0 8px 8px;\n}\n\n.entity-list-item {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 12px;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.entity-list-item:hover {\n background: var(--hover-background, #f3f4f6);\n}\n\n.entity-list-item.selected {\n background: rgba(99, 102, 241, 0.08);\n border-left: 3px solid #6366f1;\n}\n\n.entity-list-name {\n font-size: 13px;\n color: var(--text-primary, #1f2937);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n flex: 1;\n}\n\n.entity-list-badges {\n display: flex;\n gap: 4px;\n flex-shrink: 0;\n}\n\n.dep-badge {\n display: inline-flex;\n align-items: center;\n gap: 3px;\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.dep-badge i { font-size: 9px; }\n\n.level-none { display: none; }\n\n.level-low {\n background: rgba(16, 185, 129, 0.1);\n color: #059669;\n}\n\n.level-medium {\n background: rgba(245, 158, 11, 0.1);\n color: #d97706;\n}\n\n.level-high {\n background: rgba(239, 68, 68, 0.1);\n color: #dc2626;\n}\n\n.level-depends-on {\n background: rgba(99, 102, 241, 0.1);\n color: #6366f1;\n}\n\n.empty-list {\n padding: 20px;\n text-align: center;\n font-size: 13px;\n color: var(--text-secondary, #6b7280);\n}\n\n/* Detail Panel */\n.entity-detail-panel {\n background: var(--card-background, #ffffff);\n border: 1px solid var(--border-color, #e5e7eb);\n border-radius: 12px;\n padding: 24px;\n overflow-y: auto;\n max-height: calc(100vh - 280px);\n}\n\n.detail-header {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 28px;\n padding-bottom: 16px;\n border-bottom: 1px solid var(--border-color, #e5e7eb);\n}\n\n.detail-header-text {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.detail-icon {\n font-size: 20px;\n color: #6366f1;\n}\n\n.detail-title {\n font-size: 20px;\n font-weight: 700;\n color: var(--text-primary, #1f2937);\n margin: 0;\n}\n\n.detail-schema {\n font-size: 12px;\n color: var(--text-secondary, #6b7280);\n}\n\n/* Relationship Sections */\n.relationship-section {\n margin-bottom: 28px;\n}\n\n.section-header {\n display: flex;\n align-items: center;\n gap: 10px;\n margin-bottom: 4px;\n}\n\n.section-header h4 {\n font-size: 14px;\n font-weight: 600;\n color: var(--text-primary, #1f2937);\n margin: 0;\n flex: 1;\n}\n\n.section-hint {\n font-size: 12px;\n color: var(--text-tertiary, #9ca3af);\n margin: 0 0 12px 0;\n}\n\n.section-hint strong {\n color: var(--text-secondary, #6b7280);\n}\n\n.section-icon {\n font-size: 14px;\n}\n\n.referenced-by-icon { color: #10b981; }\n.depends-on-icon { color: #6366f1; }\n\n.section-count {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 24px;\n height: 24px;\n padding: 0 8px;\n background: var(--hover-background, #f3f4f6);\n border-radius: 12px;\n font-size: 12px;\n font-weight: 600;\n color: var(--text-secondary, #6b7280);\n}\n\n.relationship-list {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.relationship-item {\n border-radius: 8px;\n transition: background 0.15s ease;\n}\n\n.relationship-item:hover {\n background: var(--hover-background, #f3f4f6);\n}\n\n.rel-main {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n cursor: pointer;\n}\n\n.rel-icon {\n font-size: 12px;\n color: #6366f1;\n opacity: 0.7;\n flex-shrink: 0;\n}\n\n.rel-entity-name {\n font-size: 14px;\n color: #6366f1;\n font-weight: 500;\n}\n\n.rel-entity-name:hover {\n text-decoration: underline;\n}\n\n.rel-join-field {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 11px;\n color: var(--text-tertiary, #9ca3af);\n font-family: 'SF Mono', 'Fira Code', monospace;\n margin-left: 4px;\n padding: 2px 8px;\n background: var(--hover-background, #f3f4f6);\n border-radius: 4px;\n}\n\n.rel-join-field i {\n font-size: 9px;\n opacity: 0.5;\n}\n\n.empty-relationships {\n padding: 12px;\n text-align: center;\n font-size: 13px;\n color: var(--text-tertiary, #9ca3af);\n}\n\n/* No Selection */\n.no-selection {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n text-align: center;\n height: 100%;\n}\n\n.no-selection-icon {\n font-size: 48px;\n color: var(--text-tertiary, #9ca3af);\n margin-bottom: 16px;\n}\n\n.no-selection h3 {\n font-size: 18px;\n font-weight: 600;\n color: var(--text-primary, #1f2937);\n margin: 0 0 8px 0;\n}\n\n.no-selection p {\n font-size: 14px;\n color: var(--text-secondary, #6b7280);\n margin: 0;\n max-width: 300px;\n}\n"] }]
|
|
518
|
+
args: [{ standalone: false, selector: 'mj-version-history-graph-resource', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"graph-container\">\n @if (IsLoading) {\n <mj-loading text=\"Loading dependency graph...\"></mj-loading>\n }\n\n @if (!IsLoading) {\n <!-- Header -->\n <div class=\"page-header\">\n <div class=\"header-left\">\n <h2 class=\"page-title\">Entity Dependency Graph</h2>\n <p class=\"page-subtitle\">Explore entity relationships used by the version history system</p>\n </div>\n <div class=\"header-actions\">\n <button class=\"btn-icon\" (click)=\"Refresh()\" title=\"Refresh\">\n <i class=\"fa-solid fa-refresh\"></i>\n </button>\n </div>\n </div>\n <!-- Stats Row -->\n <div class=\"stats-row\">\n <div class=\"stat-badge\">\n <i class=\"fa-solid fa-table\"></i>\n <span>{{TotalEntities}} Entities</span>\n </div>\n <div class=\"stat-badge\">\n <i class=\"fa-solid fa-diagram-project\"></i>\n <span>{{EntitiesWithDependents}} with Dependents</span>\n </div>\n <div class=\"stat-badge\">\n <i class=\"fa-solid fa-arrow-right-arrow-left\"></i>\n <span>{{TotalRelationships}} Relationships</span>\n </div>\n </div>\n <!-- Main Layout: Entity List + Detail -->\n <div class=\"graph-layout\">\n <!-- Entity List -->\n <div class=\"entity-list-panel\">\n <div class=\"panel-header\">\n <h3 class=\"panel-title\">Entities</h3>\n </div>\n <div class=\"search-bar\">\n <i class=\"fa-solid fa-search search-icon\"></i>\n <input type=\"text\"\n class=\"search-input\"\n placeholder=\"Filter entities...\"\n [ngModel]=\"SearchText\"\n (ngModelChange)=\"OnSearchChange($event)\" />\n </div>\n <!-- Schema Filter Chips -->\n @if (AvailableSchemas.length > 1) {\n <div class=\"schema-chips\">\n @for (schema of AvailableSchemas; track schema) {\n <button class=\"schema-chip\"\n [class.active]=\"SchemaFilter === schema\"\n (click)=\"OnSchemaFilterChange(schema)\">\n {{schema}}\n <span class=\"schema-chip-count\">{{GetSchemaEntityCount(schema)}}</span>\n </button>\n }\n </div>\n }\n <div class=\"entity-scroll-list\">\n @for (entity of FilteredEntities; track entity) {\n <div class=\"entity-list-item\"\n [class.selected]=\"entity.IsSelected\"\n (click)=\"SelectEntity(entity)\">\n <div class=\"entity-list-name\">{{entity.Name}}</div>\n <div class=\"entity-list-badges\">\n @if (entity.ReferencedByCount > 0) {\n <span class=\"dep-badge\"\n [ngClass]=\"GetDependencyLevel(entity.ReferencedByCount)\"\n title=\"Referenced by (entities with FKs to this)\">\n {{entity.ReferencedByCount}} <i class=\"fa-solid fa-arrow-down\"></i>\n </span>\n }\n @if (entity.DependsOnCount > 0) {\n <span class=\"dep-badge level-depends-on\"\n title=\"Depends on (entities this has FKs to)\">\n {{entity.DependsOnCount}} <i class=\"fa-solid fa-arrow-up\"></i>\n </span>\n }\n </div>\n </div>\n }\n @if (FilteredEntities.length === 0) {\n <div class=\"empty-list\">\n <p>No entities match your search.</p>\n </div>\n }\n </div>\n </div>\n <!-- Detail Panel -->\n <div class=\"entity-detail-panel\">\n @if (SelectedEntity) {\n <div class=\"detail-header\">\n <i class=\"fa-solid fa-table detail-icon\"></i>\n <div class=\"detail-header-text\">\n <h3 class=\"detail-title\">{{SelectedEntity.Name}}</h3>\n <span class=\"detail-schema\">{{SelectedEntity.SchemaName}}</span>\n </div>\n </div>\n <!-- Referenced By (entities that have FKs pointing to this entity) -->\n <div class=\"relationship-section\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-arrow-down section-icon referenced-by-icon\"></i>\n <h4>Referenced By</h4>\n <span class=\"section-count\">{{ReferencedByEntities.length}}</span>\n </div>\n <p class=\"section-hint\">Entities that have foreign keys pointing to <strong>{{SelectedEntity.Name}}</strong></p>\n @if (ReferencedByEntities.length > 0) {\n <div class=\"relationship-list\">\n @for (rel of ReferencedByEntities; track rel) {\n <div class=\"relationship-item\">\n <div class=\"rel-main\"\n (click)=\"NavigateToEntity(rel.ToEntity)\">\n <i class=\"fa-solid fa-table rel-icon\"></i>\n <span class=\"rel-entity-name\">{{rel.ToEntity}}</span>\n <span class=\"rel-join-field\">\n <i class=\"fa-solid fa-link\"></i>\n {{rel.RelatedEntityJoinField}}\n </span>\n </div>\n </div>\n }\n </div>\n }\n @if (ReferencedByEntities.length === 0) {\n <div class=\"empty-relationships\">\n <p>No entities reference this entity.</p>\n </div>\n }\n </div>\n <!-- Depends On (entities this entity has FKs to) -->\n <div class=\"relationship-section\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-arrow-up section-icon depends-on-icon\"></i>\n <h4>Depends On</h4>\n <span class=\"section-count\">{{DependsOnEntities.length}}</span>\n </div>\n <p class=\"section-hint\"><strong>{{SelectedEntity.Name}}</strong> has foreign keys pointing to these entities</p>\n @if (DependsOnEntities.length > 0) {\n <div class=\"relationship-list\">\n @for (rel of DependsOnEntities; track rel) {\n <div class=\"relationship-item\">\n <div class=\"rel-main\"\n (click)=\"NavigateToEntity(rel.FromEntity)\">\n <i class=\"fa-solid fa-table rel-icon\"></i>\n <span class=\"rel-entity-name\">{{rel.FromEntity}}</span>\n <span class=\"rel-join-field\">\n <i class=\"fa-solid fa-link\"></i>\n {{rel.RelatedEntityJoinField}}\n </span>\n </div>\n </div>\n }\n </div>\n }\n @if (DependsOnEntities.length === 0) {\n <div class=\"empty-relationships\">\n <p>This entity has no foreign key dependencies.</p>\n </div>\n }\n </div>\n } @else {\n <div class=\"no-selection\">\n <i class=\"fa-solid fa-diagram-project no-selection-icon\"></i>\n <h3>Select an Entity</h3>\n <p>Choose an entity from the list to explore its dependency relationships.</p>\n </div>\n }\n </div>\n </div>\n }\n</div>\n", styles: [".graph-container {\n padding: 24px;\n height: 100%;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n}\n\n/* Header */\n.page-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 20px;\n}\n\n.header-left { flex: 1; }\n\n.page-title {\n font-size: 24px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0 0 4px 0;\n}\n\n.page-subtitle {\n font-size: 14px;\n color: var(--mj-text-secondary);\n margin: 0;\n}\n\n.header-actions { display: flex; gap: 12px; }\n\n.btn-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n color: var(--mj-text-secondary);\n}\n\n.btn-icon:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n/* Stats Row */\n.stats-row {\n display: flex;\n gap: 12px;\n margin-bottom: 20px;\n}\n\n.stat-badge {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 20px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n\n.stat-badge i {\n color: var(--mj-brand-primary);\n}\n\n/* Main Layout */\n.graph-layout {\n display: grid;\n grid-template-columns: 340px 1fr;\n gap: 20px;\n flex: 1;\n min-height: 0;\n}\n\n/* Entity List Panel */\n.entity-list-panel {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n display: flex;\n flex-direction: column;\n max-height: calc(100vh - 280px);\n}\n\n.panel-header {\n padding: 16px 20px 0;\n}\n\n.panel-title {\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0;\n}\n\n.search-bar {\n position: relative;\n padding: 12px 16px 8px;\n}\n\n.search-icon {\n position: absolute;\n left: 28px;\n top: 50%;\n transform: translateY(-50%);\n color: var(--mj-text-secondary);\n font-size: 13px;\n}\n\n.search-input {\n width: 100%;\n padding: 8px 12px 8px 34px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-radius: 8px;\n font-size: 13px;\n color: var(--mj-text-primary);\n outline: none;\n box-sizing: border-box;\n}\n\n.search-input:focus {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-brand-primary);\n}\n\n/* Schema Filter Chips */\n.schema-chips {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n padding: 0 16px 10px;\n}\n\n.schema-chip {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 4px 10px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 14px;\n font-size: 11px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.schema-chip:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 6%, transparent);\n border-color: color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n.schema-chip.active {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n.schema-chip-count {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 18px;\n height: 18px;\n padding: 0 4px;\n background: color-mix(in srgb, var(--mj-text-primary) 6%, transparent);\n border-radius: 9px;\n font-size: 10px;\n font-weight: 600;\n}\n\n.schema-chip.active .schema-chip-count {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.entity-scroll-list {\n flex: 1;\n overflow-y: auto;\n padding: 0 8px 8px;\n}\n\n.entity-list-item {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 12px;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.entity-list-item:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.entity-list-item.selected {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n border-left: 3px solid var(--mj-brand-primary);\n}\n\n.entity-list-name {\n font-size: 13px;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n flex: 1;\n}\n\n.entity-list-badges {\n display: flex;\n gap: 4px;\n flex-shrink: 0;\n}\n\n.dep-badge {\n display: inline-flex;\n align-items: center;\n gap: 3px;\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.dep-badge i { font-size: 9px; }\n\n.level-none { display: none; }\n\n.level-low {\n background: color-mix(in srgb, var(--mj-status-success) 10%, transparent);\n color: var(--mj-status-success);\n}\n\n.level-medium {\n background: color-mix(in srgb, var(--mj-status-warning) 10%, transparent);\n color: var(--mj-status-warning);\n}\n\n.level-high {\n background: color-mix(in srgb, var(--mj-status-error) 10%, transparent);\n color: var(--mj-status-error);\n}\n\n.level-depends-on {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n color: var(--mj-brand-primary);\n}\n\n.empty-list {\n padding: 20px;\n text-align: center;\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n\n/* Detail Panel */\n.entity-detail-panel {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n padding: 24px;\n overflow-y: auto;\n max-height: calc(100vh - 280px);\n}\n\n.detail-header {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 28px;\n padding-bottom: 16px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.detail-header-text {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.detail-icon {\n font-size: 20px;\n color: var(--mj-brand-primary);\n}\n\n.detail-title {\n font-size: 20px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0;\n}\n\n.detail-schema {\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n/* Relationship Sections */\n.relationship-section {\n margin-bottom: 28px;\n}\n\n.section-header {\n display: flex;\n align-items: center;\n gap: 10px;\n margin-bottom: 4px;\n}\n\n.section-header h4 {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0;\n flex: 1;\n}\n\n.section-hint {\n font-size: 12px;\n color: var(--mj-text-muted);\n margin: 0 0 12px 0;\n}\n\n.section-hint strong {\n color: var(--mj-text-secondary);\n}\n\n.section-icon {\n font-size: 14px;\n}\n\n.referenced-by-icon { color: var(--mj-status-success); }\n.depends-on-icon { color: var(--mj-brand-primary); }\n\n.section-count {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 24px;\n height: 24px;\n padding: 0 8px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 12px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.relationship-list {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.relationship-item {\n border-radius: 8px;\n transition: background 0.15s ease;\n}\n\n.relationship-item:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.rel-main {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n cursor: pointer;\n}\n\n.rel-icon {\n font-size: 12px;\n color: var(--mj-brand-primary);\n opacity: 0.7;\n flex-shrink: 0;\n}\n\n.rel-entity-name {\n font-size: 14px;\n color: var(--mj-brand-primary);\n font-weight: 500;\n}\n\n.rel-entity-name:hover {\n text-decoration: underline;\n}\n\n.rel-join-field {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 11px;\n color: var(--mj-text-muted);\n font-family: 'SF Mono', 'Fira Code', monospace;\n margin-left: 4px;\n padding: 2px 8px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 4px;\n}\n\n.rel-join-field i {\n font-size: 9px;\n opacity: 0.5;\n}\n\n.empty-relationships {\n padding: 12px;\n text-align: center;\n font-size: 13px;\n color: var(--mj-text-muted);\n}\n\n/* No Selection */\n.no-selection {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n text-align: center;\n height: 100%;\n}\n\n.no-selection-icon {\n font-size: 48px;\n color: var(--mj-text-muted);\n margin-bottom: 16px;\n}\n\n.no-selection h3 {\n font-size: 18px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 8px 0;\n}\n\n.no-selection p {\n font-size: 14px;\n color: var(--mj-text-secondary);\n margin: 0;\n max-width: 300px;\n}\n"] }]
|
|
519
519
|
}], () => [{ type: i0.ChangeDetectorRef }], null); })();
|
|
520
520
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(VersionHistoryGraphResourceComponent, { className: "VersionHistoryGraphResourceComponent", filePath: "src/VersionHistory/components/graph-resource.component.ts", lineNumber: 35 }); })();
|
|
521
521
|
//# sourceMappingURL=graph-resource.component.js.map
|