@memberjunction/ng-dashboards 5.30.1 → 5.32.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.map +1 -1
- package/dist/AI/components/agents/agent-configuration.component.js +4 -4
- package/dist/AI/components/agents/agent-configuration.component.js.map +1 -1
- package/dist/AI/components/agents/agent-editor.component.d.ts +2 -1
- package/dist/AI/components/agents/agent-editor.component.d.ts.map +1 -1
- package/dist/AI/components/agents/agent-editor.component.js +8 -6
- package/dist/AI/components/agents/agent-editor.component.js.map +1 -1
- package/dist/AI/components/analytics/agent-runs/agent-run-analysis.component.d.ts +2 -1
- package/dist/AI/components/analytics/agent-runs/agent-run-analysis.component.d.ts.map +1 -1
- package/dist/AI/components/analytics/agent-runs/agent-run-analysis.component.js +6 -5
- package/dist/AI/components/analytics/agent-runs/agent-run-analysis.component.js.map +1 -1
- package/dist/AI/components/analytics/cost-budget/cost-budget.component.d.ts +2 -1
- package/dist/AI/components/analytics/cost-budget/cost-budget.component.d.ts.map +1 -1
- package/dist/AI/components/analytics/cost-budget/cost-budget.component.js +6 -5
- package/dist/AI/components/analytics/cost-budget/cost-budget.component.js.map +1 -1
- package/dist/AI/components/analytics/error-analysis/error-analysis.component.d.ts +2 -1
- package/dist/AI/components/analytics/error-analysis/error-analysis.component.d.ts.map +1 -1
- package/dist/AI/components/analytics/error-analysis/error-analysis.component.js +6 -5
- package/dist/AI/components/analytics/error-analysis/error-analysis.component.js.map +1 -1
- package/dist/AI/components/analytics/executive-summary/executive-summary.component.d.ts +2 -1
- package/dist/AI/components/analytics/executive-summary/executive-summary.component.d.ts.map +1 -1
- package/dist/AI/components/analytics/executive-summary/executive-summary.component.js +7 -4
- package/dist/AI/components/analytics/executive-summary/executive-summary.component.js.map +1 -1
- package/dist/AI/components/analytics/model-performance/model-performance.component.d.ts +3 -2
- package/dist/AI/components/analytics/model-performance/model-performance.component.d.ts.map +1 -1
- package/dist/AI/components/analytics/model-performance/model-performance.component.js +10 -6
- package/dist/AI/components/analytics/model-performance/model-performance.component.js.map +1 -1
- package/dist/AI/components/analytics/prompt-runs/prompt-run-analysis.component.d.ts +2 -1
- package/dist/AI/components/analytics/prompt-runs/prompt-run-analysis.component.d.ts.map +1 -1
- package/dist/AI/components/analytics/prompt-runs/prompt-run-analysis.component.js +6 -5
- package/dist/AI/components/analytics/prompt-runs/prompt-run-analysis.component.js.map +1 -1
- package/dist/AI/components/analytics/usage-patterns/usage-patterns.component.d.ts +2 -1
- package/dist/AI/components/analytics/usage-patterns/usage-patterns.component.d.ts.map +1 -1
- package/dist/AI/components/analytics/usage-patterns/usage-patterns.component.js +6 -5
- package/dist/AI/components/analytics/usage-patterns/usage-patterns.component.js.map +1 -1
- package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts.map +1 -1
- package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js +55 -52
- package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js.map +1 -1
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.js +15 -15
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.js.map +1 -1
- package/dist/AI/components/execution-monitoring.component.d.ts.map +1 -1
- package/dist/AI/components/execution-monitoring.component.js +4 -3
- 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/models/model-management.component.js.map +1 -1
- package/dist/AI/components/prompts/model-prompt-priority-matrix.component.d.ts +2 -1
- package/dist/AI/components/prompts/model-prompt-priority-matrix.component.d.ts.map +1 -1
- package/dist/AI/components/prompts/model-prompt-priority-matrix.component.js +10 -8
- package/dist/AI/components/prompts/model-prompt-priority-matrix.component.js.map +1 -1
- package/dist/AI/components/prompts/prompt-management.component.d.ts.map +1 -1
- package/dist/AI/components/prompts/prompt-management.component.js +2 -2
- package/dist/AI/components/prompts/prompt-management.component.js.map +1 -1
- package/dist/AI/components/prompts/prompt-version-control.component.d.ts +2 -1
- package/dist/AI/components/prompts/prompt-version-control.component.d.ts.map +1 -1
- package/dist/AI/components/prompts/prompt-version-control.component.js +13 -10
- package/dist/AI/components/prompts/prompt-version-control.component.js.map +1 -1
- package/dist/AI/components/requests/agent-requests-resource.component.js +1 -1
- package/dist/AI/components/requests/agent-requests-resource.component.js.map +1 -1
- package/dist/AI/components/tags/tags-resource.component.d.ts +1181 -0
- package/dist/AI/components/tags/tags-resource.component.d.ts.map +1 -0
- package/dist/AI/components/tags/tags-resource.component.js +7487 -0
- package/dist/AI/components/tags/tags-resource.component.js.map +1 -0
- package/dist/AI/components/vectors/vector-management-resource.component.d.ts.map +1 -1
- package/dist/AI/components/vectors/vector-management-resource.component.js +25 -21
- package/dist/AI/components/vectors/vector-management-resource.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 +5 -0
- package/dist/AI/index.js.map +1 -1
- package/dist/AI/services/ai-instrumentation.service.d.ts +5 -0
- package/dist/AI/services/ai-instrumentation.service.d.ts.map +1 -1
- package/dist/AI/services/ai-instrumentation.service.js +12 -4
- package/dist/AI/services/ai-instrumentation.service.js.map +1 -1
- package/dist/APIKeys/api-applications-panel.component.d.ts +3 -2
- package/dist/APIKeys/api-applications-panel.component.d.ts.map +1 -1
- package/dist/APIKeys/api-applications-panel.component.js +5 -4
- package/dist/APIKeys/api-applications-panel.component.js.map +1 -1
- package/dist/APIKeys/api-key-create-dialog.component.d.ts +2 -1
- package/dist/APIKeys/api-key-create-dialog.component.d.ts.map +1 -1
- package/dist/APIKeys/api-key-create-dialog.component.js +5 -5
- package/dist/APIKeys/api-key-create-dialog.component.js.map +1 -1
- package/dist/APIKeys/api-key-edit-panel.component.d.ts +3 -2
- package/dist/APIKeys/api-key-edit-panel.component.d.ts.map +1 -1
- package/dist/APIKeys/api-key-edit-panel.component.js +11 -10
- package/dist/APIKeys/api-key-edit-panel.component.js.map +1 -1
- package/dist/APIKeys/api-key-list.component.d.ts +2 -1
- package/dist/APIKeys/api-key-list.component.d.ts.map +1 -1
- package/dist/APIKeys/api-key-list.component.js +6 -5
- package/dist/APIKeys/api-key-list.component.js.map +1 -1
- package/dist/APIKeys/api-keys-resource.component.d.ts.map +1 -1
- package/dist/APIKeys/api-keys-resource.component.js +4 -4
- package/dist/APIKeys/api-keys-resource.component.js.map +1 -1
- package/dist/APIKeys/api-scopes-panel.component.d.ts +3 -2
- package/dist/APIKeys/api-scopes-panel.component.d.ts.map +1 -1
- package/dist/APIKeys/api-scopes-panel.component.js +8 -6
- package/dist/APIKeys/api-scopes-panel.component.js.map +1 -1
- package/dist/APIKeys/api-usage-panel.component.d.ts +3 -2
- package/dist/APIKeys/api-usage-panel.component.d.ts.map +1 -1
- package/dist/APIKeys/api-usage-panel.component.js +10 -8
- package/dist/APIKeys/api-usage-panel.component.js.map +1 -1
- package/dist/Actions/components/actions-list-view.component.d.ts +2 -1
- package/dist/Actions/components/actions-list-view.component.d.ts.map +1 -1
- package/dist/Actions/components/actions-list-view.component.js +6 -5
- package/dist/Actions/components/actions-list-view.component.js.map +1 -1
- package/dist/Actions/components/actions-overview.component.js +2 -2
- package/dist/Actions/components/actions-overview.component.js.map +1 -1
- package/dist/Actions/components/categories-list-view.component.d.ts +2 -1
- package/dist/Actions/components/categories-list-view.component.d.ts.map +1 -1
- package/dist/Actions/components/categories-list-view.component.js +6 -5
- package/dist/Actions/components/categories-list-view.component.js.map +1 -1
- package/dist/Actions/components/execution-monitoring.component.js +1 -1
- package/dist/Actions/components/execution-monitoring.component.js.map +1 -1
- package/dist/Actions/components/explorer/action-card.component.d.ts +2 -1
- package/dist/Actions/components/explorer/action-card.component.d.ts.map +1 -1
- package/dist/Actions/components/explorer/action-card.component.js +6 -4
- package/dist/Actions/components/explorer/action-card.component.js.map +1 -1
- package/dist/Actions/components/explorer/action-explorer.component.js +1 -1
- package/dist/Actions/components/explorer/action-explorer.component.js.map +1 -1
- package/dist/Actions/components/explorer/new-action-panel.component.d.ts +2 -1
- package/dist/Actions/components/explorer/new-action-panel.component.d.ts.map +1 -1
- package/dist/Actions/components/explorer/new-action-panel.component.js +7 -5
- package/dist/Actions/components/explorer/new-action-panel.component.js.map +1 -1
- package/dist/Actions/components/explorer/new-category-panel.component.d.ts +2 -1
- package/dist/Actions/components/explorer/new-category-panel.component.d.ts.map +1 -1
- package/dist/Actions/components/explorer/new-category-panel.component.js +7 -5
- package/dist/Actions/components/explorer/new-category-panel.component.js.map +1 -1
- package/dist/ApplicationRoles/application-roles-resource.component.js +4 -4
- package/dist/ApplicationRoles/application-roles-resource.component.js.map +1 -1
- package/dist/Communication/communication-logs-resource.component.js +1 -1
- package/dist/Communication/communication-logs-resource.component.js.map +1 -1
- package/dist/Communication/communication-monitor-resource.component.js +1 -1
- package/dist/Communication/communication-monitor-resource.component.js.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.js +1 -1
- package/dist/Communication/communication-runs-resource.component.js.map +1 -1
- package/dist/Communication/communication-templates-resource.component.js +3 -3
- package/dist/Communication/communication-templates-resource.component.js.map +1 -1
- package/dist/ComponentStudio/component-studio-dashboard.component.d.ts +1 -1
- package/dist/ComponentStudio/component-studio-dashboard.component.d.ts.map +1 -1
- package/dist/ComponentStudio/component-studio-dashboard.component.js +5 -4
- package/dist/ComponentStudio/component-studio-dashboard.component.js.map +1 -1
- package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.d.ts +2 -1
- package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.d.ts.map +1 -1
- package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.js +6 -4
- package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.js.map +1 -1
- package/dist/ComponentStudio/components/artifact-load-dialog.component.d.ts +11 -2
- package/dist/ComponentStudio/components/artifact-load-dialog.component.d.ts.map +1 -1
- package/dist/ComponentStudio/components/artifact-load-dialog.component.js +61 -27
- package/dist/ComponentStudio/components/artifact-load-dialog.component.js.map +1 -1
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.d.ts +4 -2
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.d.ts.map +1 -1
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.js +19 -11
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.js.map +1 -1
- package/dist/ComponentStudio/components/editors/data-requirements-editor.component.d.ts +4 -2
- package/dist/ComponentStudio/components/editors/data-requirements-editor.component.d.ts.map +1 -1
- package/dist/ComponentStudio/components/editors/data-requirements-editor.component.js +11 -3
- package/dist/ComponentStudio/components/editors/data-requirements-editor.component.js.map +1 -1
- package/dist/ComponentStudio/components/workspace/component-preview.component.d.ts +10 -1
- package/dist/ComponentStudio/components/workspace/component-preview.component.d.ts.map +1 -1
- package/dist/ComponentStudio/components/workspace/component-preview.component.js +18 -9
- package/dist/ComponentStudio/components/workspace/component-preview.component.js.map +1 -1
- package/dist/ComponentStudio/services/component-studio-state.service.d.ts +11 -1
- package/dist/ComponentStudio/services/component-studio-state.service.d.ts.map +1 -1
- package/dist/ComponentStudio/services/component-studio-state.service.js +23 -3
- package/dist/ComponentStudio/services/component-studio-state.service.js.map +1 -1
- package/dist/ComponentStudio/services/component-version.service.d.ts +6 -1
- package/dist/ComponentStudio/services/component-version.service.d.ts.map +1 -1
- package/dist/ComponentStudio/services/component-version.service.js +16 -6
- package/dist/ComponentStudio/services/component-version.service.js.map +1 -1
- package/dist/Credentials/components/credentials-audit-resource.component.js +1 -1
- 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 +3 -3
- package/dist/Credentials/components/credentials-categories-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-list-resource.component.d.ts.map +1 -1
- package/dist/Credentials/components/credentials-list-resource.component.js +3 -3
- package/dist/Credentials/components/credentials-list-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-overview-resource.component.d.ts.map +1 -1
- package/dist/Credentials/components/credentials-overview-resource.component.js +3 -3
- package/dist/Credentials/components/credentials-overview-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-types-resource.component.d.ts.map +1 -1
- package/dist/Credentials/components/credentials-types-resource.component.js +3 -3
- package/dist/Credentials/components/credentials-types-resource.component.js.map +1 -1
- package/dist/Credentials/credentials-dashboard.component.js +1 -1
- package/dist/Credentials/credentials-dashboard.component.js.map +1 -1
- package/dist/DashboardBrowser/dashboard-browser-resource.component.js +13 -13
- package/dist/DashboardBrowser/dashboard-browser-resource.component.js.map +1 -1
- package/dist/DashboardBrowser/dashboard-share-adapter.d.ts +4 -0
- package/dist/DashboardBrowser/dashboard-share-adapter.d.ts.map +1 -1
- package/dist/DashboardBrowser/dashboard-share-adapter.js +5 -2
- package/dist/DashboardBrowser/dashboard-share-adapter.js.map +1 -1
- package/dist/DashboardBrowser/dashboard-share-dialog.component.d.ts +3 -1
- package/dist/DashboardBrowser/dashboard-share-dialog.component.d.ts.map +1 -1
- package/dist/DashboardBrowser/dashboard-share-dialog.component.js +9 -4
- package/dist/DashboardBrowser/dashboard-share-dialog.component.js.map +1 -1
- package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.d.ts +3 -2
- package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.d.ts.map +1 -1
- package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.js +7 -6
- package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.js.map +1 -1
- package/dist/DataExplorer/components/view-selector/view-selector.component.d.ts +3 -2
- package/dist/DataExplorer/components/view-selector/view-selector.component.d.ts.map +1 -1
- package/dist/DataExplorer/components/view-selector/view-selector.component.js +6 -5
- package/dist/DataExplorer/components/view-selector/view-selector.component.js.map +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.js +10 -9
- package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
- package/dist/DataExplorer/services/explorer-state.service.d.ts +6 -1
- package/dist/DataExplorer/services/explorer-state.service.d.ts.map +1 -1
- package/dist/DataExplorer/services/explorer-state.service.js +15 -5
- package/dist/DataExplorer/services/explorer-state.service.js.map +1 -1
- package/dist/DatabaseDesigner/components/create-wizard/database-create-wizard.component.d.ts +64 -0
- package/dist/DatabaseDesigner/components/create-wizard/database-create-wizard.component.d.ts.map +1 -0
- package/dist/DatabaseDesigner/components/create-wizard/database-create-wizard.component.js +400 -0
- package/dist/DatabaseDesigner/components/create-wizard/database-create-wizard.component.js.map +1 -0
- package/dist/DatabaseDesigner/components/create-wizard/steps/step-basics.component.d.ts +42 -0
- package/dist/DatabaseDesigner/components/create-wizard/steps/step-basics.component.d.ts.map +1 -0
- package/dist/DatabaseDesigner/components/create-wizard/steps/step-basics.component.js +232 -0
- package/dist/DatabaseDesigner/components/create-wizard/steps/step-basics.component.js.map +1 -0
- package/dist/DatabaseDesigner/components/create-wizard/steps/step-fields.component.d.ts +14 -0
- package/dist/DatabaseDesigner/components/create-wizard/steps/step-fields.component.d.ts.map +1 -0
- package/dist/DatabaseDesigner/components/create-wizard/steps/step-fields.component.js +38 -0
- package/dist/DatabaseDesigner/components/create-wizard/steps/step-fields.component.js.map +1 -0
- package/dist/DatabaseDesigner/components/create-wizard/steps/step-pipeline.component.d.ts +24 -0
- package/dist/DatabaseDesigner/components/create-wizard/steps/step-pipeline.component.d.ts.map +1 -0
- package/dist/DatabaseDesigner/components/create-wizard/steps/step-pipeline.component.js +77 -0
- package/dist/DatabaseDesigner/components/create-wizard/steps/step-pipeline.component.js.map +1 -0
- package/dist/DatabaseDesigner/components/create-wizard/steps/step-relationships.component.d.ts +88 -0
- package/dist/DatabaseDesigner/components/create-wizard/steps/step-relationships.component.d.ts.map +1 -0
- package/dist/DatabaseDesigner/components/create-wizard/steps/step-relationships.component.js +404 -0
- package/dist/DatabaseDesigner/components/create-wizard/steps/step-relationships.component.js.map +1 -0
- package/dist/DatabaseDesigner/components/create-wizard/steps/step-review.component.d.ts +12 -0
- package/dist/DatabaseDesigner/components/create-wizard/steps/step-review.component.d.ts.map +1 -0
- package/dist/DatabaseDesigner/components/create-wizard/steps/step-review.component.js +116 -0
- package/dist/DatabaseDesigner/components/create-wizard/steps/step-review.component.js.map +1 -0
- package/dist/DatabaseDesigner/components/database-designer-dashboard.component.d.ts +55 -0
- package/dist/DatabaseDesigner/components/database-designer-dashboard.component.d.ts.map +1 -0
- package/dist/DatabaseDesigner/components/database-designer-dashboard.component.js +204 -0
- package/dist/DatabaseDesigner/components/database-designer-dashboard.component.js.map +1 -0
- package/dist/DatabaseDesigner/components/entity-list.component.d.ts +61 -0
- package/dist/DatabaseDesigner/components/entity-list.component.d.ts.map +1 -0
- package/dist/DatabaseDesigner/components/entity-list.component.js +485 -0
- package/dist/DatabaseDesigner/components/entity-list.component.js.map +1 -0
- package/dist/DatabaseDesigner/components/modify/database-modify.component.d.ts +52 -0
- package/dist/DatabaseDesigner/components/modify/database-modify.component.d.ts.map +1 -0
- package/dist/DatabaseDesigner/components/modify/database-modify.component.js +320 -0
- package/dist/DatabaseDesigner/components/modify/database-modify.component.js.map +1 -0
- package/dist/DatabaseDesigner/components/shared/database-preview-pane.component.d.ts +79 -0
- package/dist/DatabaseDesigner/components/shared/database-preview-pane.component.d.ts.map +1 -0
- package/dist/DatabaseDesigner/components/shared/database-preview-pane.component.js +378 -0
- package/dist/DatabaseDesigner/components/shared/database-preview-pane.component.js.map +1 -0
- package/dist/DatabaseDesigner/components/shared/entity-fields-grid.component.d.ts +85 -0
- package/dist/DatabaseDesigner/components/shared/entity-fields-grid.component.d.ts.map +1 -0
- package/dist/DatabaseDesigner/components/shared/entity-fields-grid.component.js +429 -0
- package/dist/DatabaseDesigner/components/shared/entity-fields-grid.component.js.map +1 -0
- package/dist/DatabaseDesigner/components/shared/entity-pipeline-panel.component.d.ts +58 -0
- package/dist/DatabaseDesigner/components/shared/entity-pipeline-panel.component.d.ts.map +1 -0
- package/dist/DatabaseDesigner/components/shared/entity-pipeline-panel.component.js +333 -0
- package/dist/DatabaseDesigner/components/shared/entity-pipeline-panel.component.js.map +1 -0
- package/dist/DatabaseDesigner/components/shared/entity-review-panel.component.d.ts +36 -0
- package/dist/DatabaseDesigner/components/shared/entity-review-panel.component.d.ts.map +1 -0
- package/dist/DatabaseDesigner/components/shared/entity-review-panel.component.js +345 -0
- package/dist/DatabaseDesigner/components/shared/entity-review-panel.component.js.map +1 -0
- package/dist/DatabaseDesigner/components/shared/wizard-step-indicator.component.d.ts +13 -0
- package/dist/DatabaseDesigner/components/shared/wizard-step-indicator.component.d.ts.map +1 -0
- package/dist/DatabaseDesigner/components/shared/wizard-step-indicator.component.js +81 -0
- package/dist/DatabaseDesigner/components/shared/wizard-step-indicator.component.js.map +1 -0
- package/dist/DatabaseDesigner/database-designer-dashboards.module.d.ts +30 -0
- package/dist/DatabaseDesigner/database-designer-dashboards.module.d.ts.map +1 -0
- package/dist/DatabaseDesigner/database-designer-dashboards.module.js +131 -0
- package/dist/DatabaseDesigner/database-designer-dashboards.module.js.map +1 -0
- package/dist/DatabaseDesigner/database-designer-erd.d.ts +19 -0
- package/dist/DatabaseDesigner/database-designer-erd.d.ts.map +1 -0
- package/dist/DatabaseDesigner/database-designer-erd.js +84 -0
- package/dist/DatabaseDesigner/database-designer-erd.js.map +1 -0
- package/dist/DatabaseDesigner/database-designer.types.d.ts +167 -0
- package/dist/DatabaseDesigner/database-designer.types.d.ts.map +1 -0
- package/dist/DatabaseDesigner/database-designer.types.js +26 -0
- package/dist/DatabaseDesigner/database-designer.types.js.map +1 -0
- package/dist/DatabaseDesigner/services/database-designer.engine.d.ts +94 -0
- package/dist/DatabaseDesigner/services/database-designer.engine.d.ts.map +1 -0
- package/dist/DatabaseDesigner/services/database-designer.engine.js +392 -0
- package/dist/DatabaseDesigner/services/database-designer.engine.js.map +1 -0
- package/dist/DatabaseDesigner/services/database-designer.service.d.ts +78 -0
- package/dist/DatabaseDesigner/services/database-designer.service.d.ts.map +1 -0
- package/dist/DatabaseDesigner/services/database-designer.service.js +273 -0
- package/dist/DatabaseDesigner/services/database-designer.service.js.map +1 -0
- package/dist/DatabaseDesigner/services/entity-wizard-state.service.d.ts +79 -0
- package/dist/DatabaseDesigner/services/entity-wizard-state.service.d.ts.map +1 -0
- package/dist/DatabaseDesigner/services/entity-wizard-state.service.js +204 -0
- package/dist/DatabaseDesigner/services/entity-wizard-state.service.js.map +1 -0
- package/dist/EntityAdmin/entity-admin-dashboard.component.d.ts.map +1 -1
- package/dist/EntityAdmin/entity-admin-dashboard.component.js +2 -2
- package/dist/EntityAdmin/entity-admin-dashboard.component.js.map +1 -1
- package/dist/Home/action-pin-config-dialog.component.d.ts +2 -1
- package/dist/Home/action-pin-config-dialog.component.d.ts.map +1 -1
- package/dist/Home/action-pin-config-dialog.component.js +6 -4
- package/dist/Home/action-pin-config-dialog.component.js.map +1 -1
- package/dist/Home/action-pin-runner-dialog.component.d.ts +2 -1
- package/dist/Home/action-pin-runner-dialog.component.d.ts.map +1 -1
- package/dist/Home/action-pin-runner-dialog.component.js +5 -4
- package/dist/Home/action-pin-runner-dialog.component.js.map +1 -1
- package/dist/Home/home-application.d.ts.map +1 -1
- package/dist/Home/home-application.js +10 -12
- package/dist/Home/home-application.js.map +1 -1
- package/dist/Home/home-dashboard.component.d.ts.map +1 -1
- package/dist/Home/home-dashboard.component.js +3 -3
- package/dist/Home/home-dashboard.component.js.map +1 -1
- package/dist/Integration/components/activity/activity.component.d.ts.map +1 -1
- package/dist/Integration/components/activity/activity.component.js +1 -0
- package/dist/Integration/components/activity/activity.component.js.map +1 -1
- package/dist/Integration/components/connections/connections.component.d.ts.map +1 -1
- package/dist/Integration/components/connections/connections.component.js +11 -10
- package/dist/Integration/components/connections/connections.component.js.map +1 -1
- package/dist/Integration/components/mapping-workspace/mapping-workspace.component.d.ts.map +1 -1
- package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js +2 -2
- package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js.map +1 -1
- package/dist/Integration/components/overview/overview.component.d.ts.map +1 -1
- package/dist/Integration/components/overview/overview.component.js +1 -0
- package/dist/Integration/components/overview/overview.component.js.map +1 -1
- package/dist/Integration/components/pipelines/pipelines.component.d.ts.map +1 -1
- package/dist/Integration/components/pipelines/pipelines.component.js +1 -0
- package/dist/Integration/components/pipelines/pipelines.component.js.map +1 -1
- package/dist/Integration/components/schedules/schedules.component.d.ts.map +1 -1
- package/dist/Integration/components/schedules/schedules.component.js +5 -4
- package/dist/Integration/components/schedules/schedules.component.js.map +1 -1
- package/dist/Integration/services/integration-data.service.d.ts +5 -1
- package/dist/Integration/services/integration-data.service.d.ts.map +1 -1
- package/dist/Integration/services/integration-data.service.js +27 -19
- package/dist/Integration/services/integration-data.service.js.map +1 -1
- package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js +6 -6
- package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js.map +1 -1
- package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.d.ts.map +1 -1
- package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js +8 -6
- package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js.map +1 -1
- package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js +6 -6
- package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js.map +1 -1
- package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.js +3 -3
- package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-browse-resource.component.js +6 -6
- package/dist/Lists/components/lists-browse-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-categories-resource.component.js +4 -4
- package/dist/Lists/components/lists-categories-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-my-lists-resource.component.js +6 -6
- package/dist/Lists/components/lists-my-lists-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-operations-resource.component.d.ts.map +1 -1
- package/dist/Lists/components/lists-operations-resource.component.js +11 -10
- package/dist/Lists/components/lists-operations-resource.component.js.map +1 -1
- package/dist/Lists/services/list-set-operations.service.d.ts +5 -0
- package/dist/Lists/services/list-set-operations.service.d.ts.map +1 -1
- package/dist/Lists/services/list-set-operations.service.js +11 -3
- package/dist/Lists/services/list-set-operations.service.js.map +1 -1
- package/dist/MCP/components/mcp-connection-dialog.component.d.ts +2 -1
- package/dist/MCP/components/mcp-connection-dialog.component.d.ts.map +1 -1
- package/dist/MCP/components/mcp-connection-dialog.component.js +8 -6
- package/dist/MCP/components/mcp-connection-dialog.component.js.map +1 -1
- package/dist/MCP/components/mcp-server-dialog.component.d.ts +2 -1
- package/dist/MCP/components/mcp-server-dialog.component.d.ts.map +1 -1
- package/dist/MCP/components/mcp-server-dialog.component.js +7 -5
- package/dist/MCP/components/mcp-server-dialog.component.js.map +1 -1
- package/dist/MCP/mcp-dashboard.component.d.ts.map +1 -1
- package/dist/MCP/mcp-dashboard.component.js +12 -12
- package/dist/MCP/mcp-dashboard.component.js.map +1 -1
- package/dist/Permissions/permissions-shared.d.ts +3 -3
- package/dist/Permissions/permissions-shared.d.ts.map +1 -1
- package/dist/Permissions/permissions-shared.js +5 -5
- package/dist/Permissions/permissions-shared.js.map +1 -1
- package/dist/Permissions/resource-access-resource.component.js +1 -1
- package/dist/Permissions/resource-access-resource.component.js.map +1 -1
- package/dist/Permissions/user-access-resource.component.js +1 -2
- package/dist/Permissions/user-access-resource.component.js.map +1 -1
- package/dist/QueryBrowser/query-browser-resource.component.d.ts.map +1 -1
- package/dist/QueryBrowser/query-browser-resource.component.js +2 -2
- package/dist/QueryBrowser/query-browser-resource.component.js.map +1 -1
- package/dist/Scheduling/scheduling-dashboard.component.d.ts.map +1 -1
- package/dist/Scheduling/scheduling-dashboard.component.js +1 -0
- package/dist/Scheduling/scheduling-dashboard.component.js.map +1 -1
- package/dist/Scheduling/services/scheduling-instrumentation.service.d.ts +5 -0
- package/dist/Scheduling/services/scheduling-instrumentation.service.d.ts.map +1 -1
- package/dist/Scheduling/services/scheduling-instrumentation.service.js +21 -13
- package/dist/Scheduling/services/scheduling-instrumentation.service.js.map +1 -1
- package/dist/SystemDiagnostics/system-diagnostics.component.d.ts.map +1 -1
- package/dist/SystemDiagnostics/system-diagnostics.component.js +2 -2
- package/dist/SystemDiagnostics/system-diagnostics.component.js.map +1 -1
- package/dist/Testing/components/testing-explorer.component.d.ts +2 -1
- package/dist/Testing/components/testing-explorer.component.d.ts.map +1 -1
- package/dist/Testing/components/testing-explorer.component.js +9 -7
- package/dist/Testing/components/testing-explorer.component.js.map +1 -1
- package/dist/Testing/services/testing-instrumentation.service.d.ts +6 -1
- package/dist/Testing/services/testing-instrumentation.service.d.ts.map +1 -1
- package/dist/Testing/services/testing-instrumentation.service.js +21 -11
- package/dist/Testing/services/testing-instrumentation.service.js.map +1 -1
- package/dist/Testing/testing-dashboard.component.d.ts +3 -1
- package/dist/Testing/testing-dashboard.component.d.ts.map +1 -1
- package/dist/Testing/testing-dashboard.component.js +15 -11
- package/dist/Testing/testing-dashboard.component.js.map +1 -1
- package/dist/VersionHistory/components/diff-resource.component.d.ts.map +1 -1
- package/dist/VersionHistory/components/diff-resource.component.js +5 -5
- package/dist/VersionHistory/components/diff-resource.component.js.map +1 -1
- package/dist/VersionHistory/components/graph-resource.component.d.ts.map +1 -1
- package/dist/VersionHistory/components/graph-resource.component.js +1 -2
- package/dist/VersionHistory/components/graph-resource.component.js.map +1 -1
- package/dist/VersionHistory/components/labels-resource.component.d.ts.map +1 -1
- 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 +1 -1
- package/dist/VersionHistory/components/restore-resource.component.js.map +1 -1
- package/dist/ai-dashboards.module.d.ts +35 -34
- package/dist/ai-dashboards.module.d.ts.map +1 -1
- package/dist/ai-dashboards.module.js +6 -0
- package/dist/ai-dashboards.module.js.map +1 -1
- package/dist/module.d.ts +13 -12
- package/dist/module.d.ts.map +1 -1
- package/dist/module.js +7 -0
- package/dist/module.js.map +1 -1
- package/dist/public-api.d.ts +3 -1
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +3 -1
- package/dist/public-api.js.map +1 -1
- package/dist/shared/entity-field-display.d.ts +4 -3
- package/dist/shared/entity-field-display.d.ts.map +1 -1
- package/dist/shared/entity-field-display.js +9 -9
- package/dist/shared/entity-field-display.js.map +1 -1
- package/package.json +52 -51
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"new-category-panel.component.js","sourceRoot":"","sources":["../../../../src/Actions/components/explorer/new-category-panel.component.ts","../../../../src/Actions/components/explorer/new-category-panel.component.html"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,KAAK,EACL,MAAM,EACN,YAAY,EAGZ,uBAAuB,EAExB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC1E,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAG1D,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;;;;;;ICC1C,8BAA0B;IACxB,wBAA8C;IAC9C,YACF;IAAA,iBAAM;;;IADJ,eACF;IADE,yDACF;;;IAcE,gCAAyB;IAAA,YAAoB;IAAA,iBAAO;;;IAA3B,cAAoB;IAApB,2CAAoB;;;IAuC7C,wBAA2C;IAC3C,6BACF;;;IACE,wBAAiC;IACjC,iCACF;;;;IA7ER,8BAA8D;IAAlC,gMAAS,8BAAuB,KAAC;IAGvD,AADF,AADF,8BAAkC,aACN,SACpB;IACF,uBAAuC;IACvC,8BACF;IAAA,iBAAK;IACL,iCAEsB;IAApB,6LAAS,gBAAS,KAAC;IACnB,uBAAiC;IAErC,AADE,iBAAS,EACL;IAEN,8BAA2B;IACzB,yGAAyB;IAQvB,AADF,+BAAwB,iBACgC;IACpD,gCACF;IAAA,iBAAQ;IACR,kCAKqC;IAHnC,0SAAkB;IAFpB,iBAKqC;IACrC,6GAAsB;IAGxB,iBAAM;IAGJ,AADF,+BAAwB,iBAC8B;IAClD,8BACF;IAAA,iBAAQ;IACR,qCAKqB;IAHnB,2TAAyB;IAI7B,AADuB,iBAAW,EAC5B;IAGJ,AADF,+BAAwB,iBACyB;IAC7C,kCACF;IAAA,iBAAQ;IACR,wCAK0B;IAJxB,wTAAsB;IAKxB,iBAAc;IACd,iCAAwB;IACtB,8DACF;IAEJ,AADE,AADE,iBAAO,EACH,EACF;IAGJ,AADF,gCAA0B,kBAIH;IAAnB,8LAAS,eAAQ,KAAC;IAIhB,AAHF,iGAAgB,2EAGP;IAIX,iBAAS;IACT,mCAGsB;IAApB,8LAAS,gBAAS,KAAC;IACnB,yBACF;IAGN,AADE,AADE,AADE,iBAAS,EACL,EACF,EACF;;;IAtFqB,cAAQ;IAAR,oCAAQ;IAc7B,eAKC;IALD,mDAKC;IAWG,eAAgC;IAAhC,gDAAgC;IAHhC,2CAAkB;IAElB,+BAAiB;IAEnB,cAEC;IAFD,iDAEC;IASC,eAAyB;IAAzB,kDAAyB;IAGzB,AADA,wBAAU,mBACQ;IAQlB,eAAsB;IAAtB,+CAAsB;IAItB,AAHA,gDAA2B,wBAGJ;IAWzB,eAAqB;IAArB,0CAAqB;IAErB,cAMC;IAND,2CAMC;IAID,eAAqB;IAArB,0CAAqB;;AD9C/B,MAAM,OAAO,yBAAyB;IAoB3B;IACC;IApBD,UAAU,GAA6B,EAAE,CAAC;IAC1C,mBAAmB,GAAkB,IAAI,CAAC;IACzC,eAAe,GAAG,IAAI,YAAY,EAA0B,CAAC;IAC7D,KAAK,GAAG,IAAI,YAAY,EAAQ,CAAC;IAEpC,MAAM,GAAG,KAAK,CAAC;IACf,QAAQ,GAAG,KAAK,CAAC;IAExB,cAAc;IACP,IAAI,GAAG,EAAE,CAAC;IACV,WAAW,GAAG,EAAE,CAAC;IACjB,QAAQ,GAAkB,IAAI,CAAC;IAEtC,aAAa;IACN,MAAM,GAA8B,EAAE,CAAC;IAEtC,QAAQ,GAAG,IAAI,OAAO,EAAQ,CAAC;IAEvC,YACS,YAAwC,EACvC,GAAsB;QADvB,iBAAY,GAAZ,YAAY,CAA4B;QACvC,QAAG,GAAH,GAAG,CAAmB;IAC7B,CAAC;IAEJ,QAAQ;QACN,IAAI,CAAC,YAAY,CAAC,qBAAqB,CAAC,IAAI,CAC1C,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CACzB,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE;YACnB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;YACrB,IAAI,MAAM,EAAE,CAAC;gBACX,IAAI,CAAC,SAAS,EAAE,CAAC;gBACjB,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;oBAC7B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,mBAAmB,CAAC;gBAC3C,CAAC;YACH,CAAC;YACD,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QAC1B,CAAC,CAAC,CAAC;IACL,CAAC;IAED,WAAW;QACT,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QACrB,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;IAC3B,CAAC;IAEO,SAAS;QACf,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC;QACf,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC;QACtB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,mBAAmB,CAAC;QACzC,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;QACjB,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;IACxB,CAAC;IAEM,OAAO;QACZ,IAAI,CAAC,YAAY,CAAC,qBAAqB,EAAE,CAAC;QAC1C,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IACpB,CAAC;IAEM,eAAe,CAAC,KAAiB;QACtC,IAAK,KAAK,CAAC,MAAsB,CAAC,SAAS,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC;YACvE,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,CAAC;IACH,CAAC;IAEM,QAAQ;QACb,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;QAEjB,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChD,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,2BAA2B,CAAC;QACpD,CAAC;aAAM,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,6CAA6C,CAAC;QACtE,CAAC;aAAM,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;YACzC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,gDAAgD,CAAC;QACzE,CAAC;QAED,+CAA+C;QAC/C,MAAM,gBAAgB,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAChD,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE;YACvD,CAAC,CAAC,CAAC,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,CACjD,CAAC;QACF,IAAI,gBAAgB,EAAE,CAAC;YACrB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,wDAAwD,CAAC;QACjF,CAAC;QAED,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC;IAC/C,CAAC;IAEM,KAAK,CAAC,MAAM;QACjB,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC;YACrB,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;YACxB,OAAO;QACT,CAAC;QAED,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QAExB,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC1B,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC,eAAe,CAAyB,uBAAuB,CAAC,CAAC;YAE3F,QAAQ,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YACjC,QAAQ,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC;YACvD,QAAQ,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC;YAE1C,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YAEpC,IAAI,KAAK,EAAE,CAAC;gBACV,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACpC,IAAI,CAAC,YAAY,CAAC,qBAAqB,EAAE,CAAC;YAC5C,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,4CAA4C,CAAC;YACxE,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,QAAQ,CAAC,2BAA2B,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;YACxD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,gDAAgD,CAAC;QAC5E,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;YACtB,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QAC1B,CAAC;IACH,CAAC;IAEM,gBAAgB;QACrB,MAAM,OAAO,GAAkD;YAC7D,EAAE,IAAI,EAAE,6BAA6B,EAAE,KAAK,EAAE,IAAI,EAAE;SACrD,CAAC;QAEF,+CAA+C;QAC/C,MAAM,gBAAgB,GAAG,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAC1D,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAC7B,CAAC;QAEF,gBAAgB,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;YAClC,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI,EAAE,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC;gBACpC,KAAK,EAAE,QAAQ,CAAC,EAAE;aACnB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,OAAO,OAAO,CAAC;IACjB,CAAC;IAEO,eAAe,CAAC,QAAgC;QACtD,MAAM,IAAI,GAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACvC,IAAI,eAAe,GAAG,QAAQ,CAAC,QAAQ,CAAC;QAExC,OAAO,eAAe,EAAE,CAAC;YACvB,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,eAAe,CAAC,CAAC,CAAC;YAC5E,IAAI,MAAM,EAAE,CAAC;gBACX,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBAC1B,eAAe,GAAG,MAAM,CAAC,QAAQ,IAAI,IAAI,CAAC;YAC5C,CAAC;iBAAM,CAAC;gBACN,MAAM;YACR,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC;mHA3JU,yBAAyB;6DAAzB,yBAAyB;YCpCtC,6FAAc;;YAAd,qCAyFC;skFDjEa;gBACV,OAAO,CAAC,SAAS,EAAE;oBACjB,UAAU,CAAC,QAAQ,EAAE;wBACnB,KAAK,CAAC,EAAE,SAAS,EAAE,kBAAkB,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;wBACpD,OAAO,CAAC,gBAAgB,EAAE,KAAK,CAAC,EAAE,SAAS,EAAE,eAAe,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;qBAC7E,CAAC;oBACF,UAAU,CAAC,QAAQ,EAAE;wBACnB,OAAO,CAAC,eAAe,EAAE,KAAK,CAAC,EAAE,SAAS,EAAE,kBAAkB,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;qBAC/E,CAAC;iBACH,CAAC;aACH;;iFAEU,yBAAyB;cAlBrC,SAAS;6BACI,KAAK,YACP,uBAAuB,mBAGhB,uBAAuB,CAAC,MAAM,cACnC;oBACV,OAAO,CAAC,SAAS,EAAE;wBACjB,UAAU,CAAC,QAAQ,EAAE;4BACnB,KAAK,CAAC,EAAE,SAAS,EAAE,kBAAkB,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;4BACpD,OAAO,CAAC,gBAAgB,EAAE,KAAK,CAAC,EAAE,SAAS,EAAE,eAAe,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;yBAC7E,CAAC;wBACF,UAAU,CAAC,QAAQ,EAAE;4BACnB,OAAO,CAAC,eAAe,EAAE,KAAK,CAAC,EAAE,SAAS,EAAE,kBAAkB,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;yBAC/E,CAAC;qBACH,CAAC;iBACH;;kBAGA,KAAK;;kBACL,KAAK;;kBACL,MAAM;;kBACN,MAAM;;kFAJI,yBAAyB","sourcesContent":["import {\n Component,\n Input,\n Output,\n EventEmitter,\n OnInit,\n OnDestroy,\n ChangeDetectionStrategy,\n ChangeDetectorRef\n} from '@angular/core';\nimport { trigger, transition, style, animate } from '@angular/animations';\nimport { Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\nimport { Metadata, LogError } from '@memberjunction/core';\nimport { MJActionCategoryEntity } from '@memberjunction/core-entities';\nimport { ActionExplorerStateService } from '../../services/action-explorer-state.service';\nimport { UUIDsEqual } from '@memberjunction/global';\n\n@Component({\n standalone: false,\n selector: 'mj-new-category-panel',\n templateUrl: './new-category-panel.component.html',\n styleUrls: ['./new-category-panel.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n animations: [\n trigger('slideIn', [\n transition(':enter', [\n style({ transform: 'translateX(100%)', opacity: 0 }),\n animate('250ms ease-out', style({ transform: 'translateX(0)', opacity: 1 }))\n ]),\n transition(':leave', [\n animate('200ms ease-in', style({ transform: 'translateX(100%)', opacity: 0 }))\n ])\n ])\n ]\n})\nexport class NewCategoryPanelComponent implements OnInit, OnDestroy {\n @Input() Categories: MJActionCategoryEntity[] = [];\n @Input() PreselectedParentId: string | null = null;\n @Output() CategoryCreated = new EventEmitter<MJActionCategoryEntity>();\n @Output() Close = new EventEmitter<void>();\n\n public IsOpen = false;\n public IsSaving = false;\n\n // Form fields\n public Name = '';\n public Description = '';\n public ParentID: string | null = null;\n\n // Validation\n public Errors: { [key: string]: string } = {};\n\n private destroy$ = new Subject<void>();\n\n constructor(\n public StateService: ActionExplorerStateService,\n private cdr: ChangeDetectorRef\n ) {}\n\n ngOnInit(): void {\n this.StateService.NewCategoryPanelOpen$.pipe(\n takeUntil(this.destroy$)\n ).subscribe(isOpen => {\n this.IsOpen = isOpen;\n if (isOpen) {\n this.resetForm();\n if (this.PreselectedParentId) {\n this.ParentID = this.PreselectedParentId;\n }\n }\n this.cdr.markForCheck();\n });\n }\n\n ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n private resetForm(): void {\n this.Name = '';\n this.Description = '';\n this.ParentID = this.PreselectedParentId;\n this.Errors = {};\n this.IsSaving = false;\n }\n\n public onClose(): void {\n this.StateService.closeNewCategoryPanel();\n this.Close.emit();\n }\n\n public onBackdropClick(event: MouseEvent): void {\n if ((event.target as HTMLElement).classList.contains('panel-backdrop')) {\n this.onClose();\n }\n }\n\n public validate(): boolean {\n this.Errors = {};\n\n if (!this.Name || this.Name.trim().length === 0) {\n this.Errors['name'] = 'Category name is required';\n } else if (this.Name.trim().length < 2) {\n this.Errors['name'] = 'Category name must be at least 2 characters';\n } else if (this.Name.trim().length > 200) {\n this.Errors['name'] = 'Category name must be less than 200 characters';\n }\n\n // Check for duplicate names within same parent\n const existingCategory = this.Categories.find(c =>\n c.Name.toLowerCase() === this.Name.trim().toLowerCase() &&\n (c.ParentID || null) === (this.ParentID || null)\n );\n if (existingCategory) {\n this.Errors['name'] = 'A category with this name already exists at this level';\n }\n\n return Object.keys(this.Errors).length === 0;\n }\n\n public async onSave(): Promise<void> {\n if (!this.validate()) {\n this.cdr.markForCheck();\n return;\n }\n\n this.IsSaving = true;\n this.cdr.markForCheck();\n\n try {\n const md = new Metadata();\n const category = await md.GetEntityObject<MJActionCategoryEntity>('MJ: Action Categories');\n\n category.Name = this.Name.trim();\n category.Description = this.Description.trim() || null;\n category.ParentID = this.ParentID || null;\n\n const saved = await category.Save();\n\n if (saved) {\n this.CategoryCreated.emit(category);\n this.StateService.closeNewCategoryPanel();\n } else {\n this.Errors['general'] = 'Failed to save category. Please try again.';\n }\n } catch (error) {\n LogError('Failed to create category', undefined, error);\n this.Errors['general'] = 'An error occurred while creating the category.';\n } finally {\n this.IsSaving = false;\n this.cdr.markForCheck();\n }\n }\n\n public getParentOptions(): Array<{ text: string; value: string | null }> {\n const options: Array<{ text: string; value: string | null }> = [\n { text: '(No Parent - Root Category)', value: null }\n ];\n\n // Sort categories by name for easier selection\n const sortedCategories = [...this.Categories].sort((a, b) =>\n a.Name.localeCompare(b.Name)\n );\n\n sortedCategories.forEach(category => {\n options.push({\n text: this.getCategoryPath(category),\n value: category.ID\n });\n });\n\n return options;\n }\n\n private getCategoryPath(category: MJActionCategoryEntity): string {\n const path: string[] = [category.Name];\n let currentParentId = category.ParentID;\n\n while (currentParentId) {\n const parent = this.Categories.find(c => UUIDsEqual(c.ID, currentParentId));\n if (parent) {\n path.unshift(parent.Name);\n currentParentId = parent.ParentID || null;\n } else {\n break;\n }\n }\n\n return path.join(' / ');\n }\n}\n","@if (IsOpen) {\n <div class=\"panel-backdrop\" (click)=\"onBackdropClick($event)\">\n <div class=\"slide-panel\" @slideIn>\n <div class=\"panel-header\">\n <h2>\n <i class=\"fa-solid fa-folder-plus\"></i>\n New Category\n </h2>\n <button mjButton\n variant=\"flat\"\n (click)=\"onClose()\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n <div class=\"panel-content\">\n @if (Errors['general']) {\n <div class=\"error-banner\">\n <i class=\"fa-solid fa-exclamation-circle\"></i>\n {{ Errors['general'] }}\n </div>\n }\n\n <div class=\"form-group\">\n <label for=\"categoryName\" class=\"form-label required\">\n Category Name\n </label>\n <input type=\"text\" class=\"mj-input\"\n id=\"categoryName\"\n [(ngModel)]=\"Name\"\n placeholder=\"Enter category name\"\n [maxlength]=\"200\"\n [class.invalid]=\"Errors['name']\" />\n @if (Errors['name']) {\n <span class=\"error-text\">{{ Errors['name'] }}</span>\n }\n </div>\n\n <div class=\"form-group\">\n <label for=\"categoryDescription\" class=\"form-label\">\n Description\n </label>\n <textarea class=\"mj-textarea\"\n id=\"categoryDescription\"\n [(ngModel)]=\"Description\"\n placeholder=\"Optional description for this category\"\n [rows]=\"3\"\n [maxlength]=\"1000\"></textarea>\n </div>\n\n <div class=\"form-group\">\n <label for=\"categoryParent\" class=\"form-label\">\n Parent Category\n </label>\n <mj-dropdown\n [(ngModel)]=\"ParentID\"\n [Data]=\"getParentOptions()\"\n TextField=\"text\"\n ValueField=\"value\"\n [ValuePrimitive]=\"true\">\n </mj-dropdown>\n <span class=\"help-text\">\n Leave empty to create a root-level category\n </span>\n </div>\n </div>\n\n <div class=\"panel-footer\">\n <button mjButton\n variant=\"primary\"\n [disabled]=\"IsSaving\"\n (click)=\"onSave()\">\n @if (IsSaving) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n Creating...\n } @else {\n <i class=\"fa-solid fa-check\"></i>\n Create Category\n }\n </button>\n <button mjButton\n variant=\"outline\"\n [disabled]=\"IsSaving\"\n (click)=\"onClose()\">\n Cancel\n </button>\n </div>\n </div>\n </div>\n}\n"]}
|
|
1
|
+
{"version":3,"file":"new-category-panel.component.js","sourceRoot":"","sources":["../../../../src/Actions/components/explorer/new-category-panel.component.ts","../../../../src/Actions/components/explorer/new-category-panel.component.html"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n Input,\n Output,\n EventEmitter,\n OnInit,\n OnDestroy,\n ChangeDetectionStrategy,\n ChangeDetectorRef\n} from '@angular/core';\nimport { trigger, transition, style, animate } from '@angular/animations';\nimport { Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\nimport { LogError } from '@memberjunction/core';\nimport { MJActionCategoryEntity } from '@memberjunction/core-entities';\nimport { ActionExplorerStateService } from '../../services/action-explorer-state.service';\nimport { UUIDsEqual } from '@memberjunction/global';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\n\n@Component({\n standalone: false,\n selector: 'mj-new-category-panel',\n templateUrl: './new-category-panel.component.html',\n styleUrls: ['./new-category-panel.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n animations: [\n trigger('slideIn', [\n transition(':enter', [\n style({ transform: 'translateX(100%)', opacity: 0 }),\n animate('250ms ease-out', style({ transform: 'translateX(0)', opacity: 1 }))\n ]),\n transition(':leave', [\n animate('200ms ease-in', style({ transform: 'translateX(100%)', opacity: 0 }))\n ])\n ])\n ]\n})\nexport class NewCategoryPanelComponent extends BaseAngularComponent implements OnInit, OnDestroy {\n @Input() Categories: MJActionCategoryEntity[] = [];\n @Input() PreselectedParentId: string | null = null;\n @Output() CategoryCreated = new EventEmitter<MJActionCategoryEntity>();\n @Output() Close = new EventEmitter<void>();\n\n public IsOpen = false;\n public IsSaving = false;\n\n // Form fields\n public Name = '';\n public Description = '';\n public ParentID: string | null = null;\n\n // Validation\n public Errors: { [key: string]: string } = {};\n\n private destroy$ = new Subject<void>();\n\n constructor(\n public StateService: ActionExplorerStateService,\n private cdr: ChangeDetectorRef\n ) { super(); }\n\n ngOnInit(): void {\n this.StateService.NewCategoryPanelOpen$.pipe(\n takeUntil(this.destroy$)\n ).subscribe(isOpen => {\n this.IsOpen = isOpen;\n if (isOpen) {\n this.resetForm();\n if (this.PreselectedParentId) {\n this.ParentID = this.PreselectedParentId;\n }\n }\n this.cdr.markForCheck();\n });\n }\n\n ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n private resetForm(): void {\n this.Name = '';\n this.Description = '';\n this.ParentID = this.PreselectedParentId;\n this.Errors = {};\n this.IsSaving = false;\n }\n\n public onClose(): void {\n this.StateService.closeNewCategoryPanel();\n this.Close.emit();\n }\n\n public onBackdropClick(event: MouseEvent): void {\n if ((event.target as HTMLElement).classList.contains('panel-backdrop')) {\n this.onClose();\n }\n }\n\n public validate(): boolean {\n this.Errors = {};\n\n if (!this.Name || this.Name.trim().length === 0) {\n this.Errors['name'] = 'Category name is required';\n } else if (this.Name.trim().length < 2) {\n this.Errors['name'] = 'Category name must be at least 2 characters';\n } else if (this.Name.trim().length > 200) {\n this.Errors['name'] = 'Category name must be less than 200 characters';\n }\n\n // Check for duplicate names within same parent\n const existingCategory = this.Categories.find(c =>\n c.Name.toLowerCase() === this.Name.trim().toLowerCase() &&\n (c.ParentID || null) === (this.ParentID || null)\n );\n if (existingCategory) {\n this.Errors['name'] = 'A category with this name already exists at this level';\n }\n\n return Object.keys(this.Errors).length === 0;\n }\n\n public async onSave(): Promise<void> {\n if (!this.validate()) {\n this.cdr.markForCheck();\n return;\n }\n\n this.IsSaving = true;\n this.cdr.markForCheck();\n\n try {\n const md = this.ProviderToUse;\n const category = await md.GetEntityObject<MJActionCategoryEntity>('MJ: Action Categories');\n\n category.Name = this.Name.trim();\n category.Description = this.Description.trim() || null;\n category.ParentID = this.ParentID || null;\n\n const saved = await category.Save();\n\n if (saved) {\n this.CategoryCreated.emit(category);\n this.StateService.closeNewCategoryPanel();\n } else {\n this.Errors['general'] = 'Failed to save category. Please try again.';\n }\n } catch (error) {\n LogError('Failed to create category', undefined, error);\n this.Errors['general'] = 'An error occurred while creating the category.';\n } finally {\n this.IsSaving = false;\n this.cdr.markForCheck();\n }\n }\n\n public getParentOptions(): Array<{ text: string; value: string | null }> {\n const options: Array<{ text: string; value: string | null }> = [\n { text: '(No Parent - Root Category)', value: null }\n ];\n\n // Sort categories by name for easier selection\n const sortedCategories = [...this.Categories].sort((a, b) =>\n a.Name.localeCompare(b.Name)\n );\n\n sortedCategories.forEach(category => {\n options.push({\n text: this.getCategoryPath(category),\n value: category.ID\n });\n });\n\n return options;\n }\n\n private getCategoryPath(category: MJActionCategoryEntity): string {\n const path: string[] = [category.Name];\n let currentParentId = category.ParentID;\n\n while (currentParentId) {\n const parent = this.Categories.find(c => UUIDsEqual(c.ID, currentParentId));\n if (parent) {\n path.unshift(parent.Name);\n currentParentId = parent.ParentID || null;\n } else {\n break;\n }\n }\n\n return path.join(' / ');\n }\n}\n","@if (IsOpen) {\n <div class=\"panel-backdrop\" (click)=\"onBackdropClick($event)\">\n <div class=\"slide-panel\" @slideIn>\n <div class=\"panel-header\">\n <h2>\n <i class=\"fa-solid fa-folder-plus\"></i>\n New Category\n </h2>\n <button mjButton\n variant=\"flat\"\n (click)=\"onClose()\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n <div class=\"panel-content\">\n @if (Errors['general']) {\n <div class=\"error-banner\">\n <i class=\"fa-solid fa-exclamation-circle\"></i>\n {{ Errors['general'] }}\n </div>\n }\n\n <div class=\"form-group\">\n <label for=\"categoryName\" class=\"form-label required\">\n Category Name\n </label>\n <input type=\"text\" class=\"mj-input\"\n id=\"categoryName\"\n [(ngModel)]=\"Name\"\n placeholder=\"Enter category name\"\n [maxlength]=\"200\"\n [class.invalid]=\"Errors['name']\" />\n @if (Errors['name']) {\n <span class=\"error-text\">{{ Errors['name'] }}</span>\n }\n </div>\n\n <div class=\"form-group\">\n <label for=\"categoryDescription\" class=\"form-label\">\n Description\n </label>\n <textarea class=\"mj-textarea\"\n id=\"categoryDescription\"\n [(ngModel)]=\"Description\"\n placeholder=\"Optional description for this category\"\n [rows]=\"3\"\n [maxlength]=\"1000\"></textarea>\n </div>\n\n <div class=\"form-group\">\n <label for=\"categoryParent\" class=\"form-label\">\n Parent Category\n </label>\n <mj-dropdown\n [(ngModel)]=\"ParentID\"\n [Data]=\"getParentOptions()\"\n TextField=\"text\"\n ValueField=\"value\"\n [ValuePrimitive]=\"true\">\n </mj-dropdown>\n <span class=\"help-text\">\n Leave empty to create a root-level category\n </span>\n </div>\n </div>\n\n <div class=\"panel-footer\">\n <button mjButton\n variant=\"primary\"\n [disabled]=\"IsSaving\"\n (click)=\"onSave()\">\n @if (IsSaving) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n Creating...\n } @else {\n <i class=\"fa-solid fa-check\"></i>\n Create Category\n }\n </button>\n <button mjButton\n variant=\"outline\"\n [disabled]=\"IsSaving\"\n (click)=\"onClose()\">\n Cancel\n </button>\n </div>\n </div>\n </div>\n}\n"]}
|
|
@@ -7,7 +7,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
import { Component } from '@angular/core';
|
|
8
8
|
import { RegisterClass, UUIDsEqual } from '@memberjunction/global';
|
|
9
9
|
import { BaseResourceComponent } from '@memberjunction/ng-shared';
|
|
10
|
-
import { CompositeKey,
|
|
10
|
+
import { CompositeKey, RunView } from '@memberjunction/core';
|
|
11
11
|
import * as i0 from "@angular/core";
|
|
12
12
|
import * as i1 from "@angular/common";
|
|
13
13
|
import * as i2 from "@angular/forms";
|
|
@@ -245,8 +245,8 @@ let ApplicationRolesResourceComponent = class ApplicationRolesResourceComponent
|
|
|
245
245
|
this.ErrorMessage = null;
|
|
246
246
|
this.cdr.detectChanges();
|
|
247
247
|
try {
|
|
248
|
-
const md =
|
|
249
|
-
const rv =
|
|
248
|
+
const md = this.ProviderToUse;
|
|
249
|
+
const rv = RunView.FromMetadataProvider(this.ProviderToUse);
|
|
250
250
|
// Load available roles from metadata
|
|
251
251
|
this.AvailableRoles = md.Roles.map(r => ({ ID: r.ID, Name: r.Name }))
|
|
252
252
|
.sort((a, b) => a.Name.localeCompare(b.Name));
|
|
@@ -386,7 +386,7 @@ let ApplicationRolesResourceComponent = class ApplicationRolesResourceComponent
|
|
|
386
386
|
this.SuccessMessage = null;
|
|
387
387
|
this.cdr.detectChanges();
|
|
388
388
|
try {
|
|
389
|
-
const md =
|
|
389
|
+
const md = this.ProviderToUse;
|
|
390
390
|
// Process deletes
|
|
391
391
|
for (const deleteId of this._pendingDeletes) {
|
|
392
392
|
const entity = await md.GetEntityObject('MJ: Application Roles');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"application-roles-resource.component.js","sourceRoot":"","sources":["../../src/ApplicationRoles/application-roles-resource.component.ts","../../src/ApplicationRoles/application-roles-resource.component.html"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,SAAS,EAAwC,MAAM,eAAe,CAAC;AAChF,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;;;;;;;;ICW3D,wBAA2C;IAAC,2BAC9C;;;IACE,wBAAuC;IAAC,8BAC1C;;;;IARF,iCAAsF;IAAjD,qMAAS,uBAAgB,KAAC;IAC7D,wBAAuC;IAAC,yBAC1C;IAAA,iBAAS;IACT,kCAAiF;IAA9C,qMAAS,oBAAa,KAAC;IAGtD,AAFF,uGAAgB,iFAEP;IAGX,iBAAS;;;IATuD,0CAAqB;IAG1B,eAAqB;IAArB,0CAAqB;IAC9E,cAIC;IAJD,yCAIC;;;IAWP,8BAAmC;IACjC,wBAA8C;IAC9C,YACF;IAAA,iBAAM;;;IADJ,eACF;IADE,oDACF;;;IAGA,8BAAqC;IACnC,wBAAwC;IACxC,YACF;IAAA,iBAAM;;;IADJ,eACF;IADE,sDACF;;;IAKA,iCAA6D;;;IA4CrC,gCAAwB;IAAA,mBAAG;IAAA,iBAAO;;;;IAJtC,AADF,0BAA4D,aACrC;IACnB,wBAAmD;IACnD,YACA;IAAA,6JAAiB;IAGnB,iBAAK;IAEH,AADF,8BAAuB,gBAIkB;IAAhC,0QAAU,8BAAoB,KAAC;IACxC,AAJE,iBAGuC,EACpC;IAEH,AADF,8BAAsB,gBAIkB;IAA/B,0QAAU,6BAAmB,KAAC;IACvC,AAJE,iBAGsC,EACnC;IAEH,AADF,8BAAwB,kBACqE;IAAhE,0TAAS,mCAAsB,KAAC;IACzD,yBAAqC;IAG3C,AADE,AADE,iBAAS,EACN,EACF;;;IAzB2B,AAA5B,uCAA2B,yBAA4B;IAGvD,eACA;IADA,gDACA;IAAA,cAEC;IAFD,uCAEC;IAKM,eAAyB;IAAzB,0CAAyB;IAMzB,eAAwB;IAAxB,yCAAwB;;;IAzBnC,AADF,AADF,AADF,iCAA2B,YAClB,SACD,aACmB;IAAA,oBAAI;IAAA,iBAAK;IAC9B,8BAAuB;IAAA,0BAAU;IAAA,iBAAK;IACtC,8BAAsB;IAAA,yBAAS;IAAA,iBAAK;IACpC,8BAAwB;IAAA,wBAAO;IAEnC,AADE,AADiC,iBAAK,EACjC,EACC;IACR,8BAAO;IACL,2LA2BC;IAEL,AADE,iBAAQ,EACF;;;IA7BJ,gBA2BC;IA3BD,6BA2BC;;;IAIL,+BAA8B;IAC5B,wBAAkC;IAClC,kGACF;IAAA,iBAAM;;;IAUF,kCAA0B;IAAA,YAAe;IAAA,iBAAS;;;IAA1C,kCAAiB;IAAC,cAAe;IAAf,kCAAe;;;;IAzDjD,+BAA+B;IA2C3B,AAzCF,0IAA8B,iHAyCrB;IASP,AADF,+BAA0B,iBAG6C;IAA7D,kRAAU,qDAAiD,KAAC;IAClE,kCAA0B;IAAA,uCAAuB;IAAA,iBAAS;IAC1D,2IAEC;IACH,iBAAS;IACT,iCAGmE;IAD3D,0QAAS,wBAAc,KAAC;IAE9B,yBAAgC;IAAC,2BACnC;IAEJ,AADE,AADE,iBAAS,EACL,EACF;;;;IAjEJ,cA8CC;IA9CD,mDA8CC;IAKS,eAA4D;IAA5D,oFAA4D;IAGlE,eAEC;IAFD,cAAA,mCAAyB,CAExB;IAKK,eAA0D;IAA1D,kFAA0D;;;;IA3ExE,AAFF,+BAAoG,cAEvC;IAA7B,qOAAS,4BAAkB,KAAC;IACxD,+BAA6B;IAC3B,wBAA4F;IAC5F,gCAAuB;IAAA,YAA2B;IAAA,iBAAO;IACzD,gCAA8E;IAC5E,YACF;IAEJ,AADE,AADE,iBAAO,EACH,EACF;IAGN,0HAAsB;IAsExB,iBAAM;;;;IAnFmD,AAAlC,6CAAiC,wCAA2C;IAIzE,eAAmE;IAAnE,oFAAmE;IAChE,eAA2B;IAA3B,8CAA2B;IACnB,cAA8C;IAA9C,0DAA8C;IAC3E,cACF;IADE,mEACF;IAKJ,cAqEC;IArED,4CAqEC;;;IAxFP,6BAAuB;IACrB,wJACF;IAAA,iBAAI;IAEJ,+BAAwB;IACtB,sJAqFC;IACH,iBAAM;;;IAtFJ,eAqFC;IArFD,uCAqFC;;AD1GP;;;GAGG;AAQI,IAAM,iCAAiC,GAAvC,MAAM,iCAAkC,SAAQ,qBAAqB;IAYtD;IAXpB,iBAAiB,GAAuB,EAAE,CAAC;IAC3C,cAAc,GAAmC,EAAE,CAAC;IACpD,SAAS,GAAG,IAAI,CAAC;IACjB,QAAQ,GAAG,KAAK,CAAC;IACjB,iBAAiB,GAAG,KAAK,CAAC;IAC1B,YAAY,GAAkB,IAAI,CAAC;IACnC,cAAc,GAAkB,IAAI,CAAC;IAErC,8CAA8C;IAC9C,mBAAmB,GAAwB,IAAI,GAAG,EAAE,CAAC;IAErD,YAAoB,GAAsB;QACxC,KAAK,EAAE,CAAC;QADU,QAAG,GAAH,GAAG,CAAmB;IAE1C,CAAC;IAEQ,KAAK,CAAC,sBAAsB,CAAC,KAAmB;QACvD,OAAO,WAAW,CAAC;IACrB,CAAC;IAEQ,KAAK,CAAC,oBAAoB,CAAC,KAAmB;QACrD,OAAO,yBAAyB,CAAC;IACnC,CAAC;IAEQ,KAAK,CAAC,QAAQ;QACrB,KAAK,CAAC,QAAQ,EAAE,CAAC;QACjB,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;QACtB,IAAI,CAAC,kBAAkB,EAAE,CAAC;IAC5B,CAAC;IAEQ,WAAW;QAClB,KAAK,CAAC,WAAW,EAAE,CAAC;IACtB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,QAAQ;QACZ,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAEzB,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC1B,MAAM,EAAE,GAAG,IAAI,OAAO,EAAE,CAAC;YAEzB,qCAAqC;YACrC,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;iBAClE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;YAEhD,wCAAwC;YACxC,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAAkI;gBAC/J,UAAU,EAAE,uBAAuB;gBACnC,UAAU,EAAE,QAAQ;aACrB,CAAC,CAAC;YAEH,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpB,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,YAAY,IAAI,mCAAmC,CAAC;gBAC/E,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;gBACvB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;gBACzB,OAAO;YACT,CAAC;YAED,0BAA0B;YAC1B,MAAM,MAAM,GAAG,IAAI,GAAG,EAA4B,CAAC;YAEnD,qEAAqE;YACrE,KAAK,MAAM,GAAG,IAAI,EAAE,CAAC,YAAY,EAAE,CAAC;gBAClC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE;oBACjB,aAAa,EAAE,GAAG,CAAC,EAAE;oBACrB,eAAe,EAAE,GAAG,CAAC,IAAI;oBACzB,KAAK,EAAE,EAAE;oBACT,QAAQ,EAAE,KAAK;iBAChB,CAAC,CAAC;YACL,CAAC;YAED,4BAA4B;YAC5B,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpC,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;gBAC/C,IAAI,KAAK,EAAE,CAAC;oBACV,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC;wBACf,EAAE,EAAE,MAAM,CAAC,EAAE;wBACb,aAAa,EAAE,MAAM,CAAC,aAAa;wBACnC,eAAe,EAAE,KAAK,CAAC,eAAe;wBACtC,MAAM,EAAE,MAAM,CAAC,MAAM;wBACrB,QAAQ,EAAE,MAAM,CAAC,IAAI,IAAI,EAAE;wBAC3B,SAAS,EAAE,MAAM,CAAC,SAAS;wBAC3B,QAAQ,EAAE,MAAM,CAAC,QAAQ;wBACzB,OAAO,EAAE,KAAK;wBACd,KAAK,EAAE,KAAK;qBACb,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YAED,+BAA+B;YAC/B,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;gBACpC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;YACnE,CAAC;YAED,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;iBACjD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC;QACxE,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAI,CAAC,YAAY,GAAG,uBAAuB,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1F,CAAC;QAED,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACvB,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC;QAC/B,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,WAAW,CAAC,KAAuB;QACjC,KAAK,CAAC,QAAQ,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC;QACjC,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,eAAe,CAAC,GAAuB;QACrC,GAAG,CAAC,SAAS,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC;QAC/B,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC;QACnB,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;QAC9B,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,cAAc,CAAC,GAAuB;QACpC,GAAG,CAAC,QAAQ,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC;QAC7B,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC;QACnB,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;QAC9B,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,kBAAkB,CAAC,KAAuB;QACxC,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;QAC9E,OAAO,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IACnF,CAAC;IAED;;OAEG;IACH,OAAO,CAAC,KAAuB;QAC7B,MAAM,MAAM,GAAG,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QACjE,IAAI,CAAC,MAAM;YAAE,OAAO;QAEpB,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC;QACrE,IAAI,CAAC,IAAI;YAAE,OAAO;QAElB,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC;YACf,EAAE,EAAE,EAAE;YACN,aAAa,EAAE,KAAK,CAAC,aAAa;YAClC,eAAe,EAAE,KAAK,CAAC,eAAe;YACtC,MAAM,EAAE,IAAI,CAAC,EAAE;YACf,QAAQ,EAAE,IAAI,CAAC,IAAI;YACnB,SAAS,EAAE,IAAI;YACf,QAAQ,EAAE,KAAK;YACf,OAAO,EAAE,IAAI;YACb,KAAK,EAAE,IAAI;SACZ,CAAC,CAAC;QAEH,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;QACjE,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QACrD,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;QAC9B,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,UAAU,CAAC,KAAuB,EAAE,GAAuB;QACzD,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACrC,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC;YACb,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QAC7B,CAAC;QACD,mEAAmE;QACnE,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACpC,CAAC;QACD,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;QAC9B,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC3B,CAAC;IAEO,eAAe,GAAa,EAAE,CAAC;IAEvC;;OAEG;IACH,KAAK,CAAC,WAAW;QACf,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC3B,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAEzB,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,IAAI,QAAQ,EAAE,CAAC;YAE1B,kBAAkB;YAClB,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;gBAC5C,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,eAAe,CAAC,uBAAuB,CAAC,CAAC;gBACjE,MAAM,MAAM,CAAC,SAAS,CAAC,IAAI,YAAY,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC;gBACjF,MAAM,YAAY,GAAG,MAAM,MAAM,CAAC,MAAM,EAAE,CAAC;gBAC3C,IAAI,CAAC,YAAY,EAAE,CAAC;oBAClB,IAAI,CAAC,YAAY,GAAG,qCAAqC,MAAM,CAAC,YAAY,EAAE,OAAO,IAAI,eAAe,EAAE,CAAC;oBAC3G,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;oBACtB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;oBACzB,OAAO;gBACT,CAAC;YACH,CAAC;YAED,mCAAmC;YACnC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;gBAC3C,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;oBAC9B,IAAI,CAAC,GAAG,CAAC,OAAO;wBAAE,SAAS;oBAE3B,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;wBACd,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,eAAe,CAAC,uBAAuB,CAAC,CAAC;wBACjE,MAAM,CAAC,SAAS,EAAE,CAAC;wBACnB,MAAM,CAAC,GAAG,CAAC,eAAe,EAAE,GAAG,CAAC,aAAa,CAAC,CAAC;wBAC/C,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;wBACjC,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC;wBACvC,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;wBACrC,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;wBACvC,IAAI,CAAC,UAAU,EAAE,CAAC;4BAChB,IAAI,CAAC,YAAY,GAAG,0CAA0C,GAAG,CAAC,QAAQ,KAAK,MAAM,CAAC,YAAY,EAAE,OAAO,IAAI,eAAe,EAAE,CAAC;4BACjI,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;4BACtB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;4BACzB,OAAO;wBACT,CAAC;wBACD,GAAG,CAAC,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;oBAC5B,CAAC;yBAAM,CAAC;wBACN,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,eAAe,CAAC,uBAAuB,CAAC,CAAC;wBACjE,MAAM,MAAM,CAAC,SAAS,CAAC,IAAI,YAAY,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;wBAC/E,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC;wBACvC,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;wBACrC,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;wBACvC,IAAI,CAAC,UAAU,EAAE,CAAC;4BAChB,IAAI,CAAC,YAAY,GAAG,wCAAwC,GAAG,CAAC,QAAQ,KAAK,MAAM,CAAC,YAAY,EAAE,OAAO,IAAI,eAAe,EAAE,CAAC;4BAC/H,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;4BACtB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;4BACzB,OAAO;wBACT,CAAC;oBACH,CAAC;oBAED,GAAG,CAAC,OAAO,GAAG,KAAK,CAAC;oBACpB,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC;gBACpB,CAAC;YACH,CAAC;YAED,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;YAC1B,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC;YAC/B,IAAI,CAAC,cAAc,GAAG,iCAAiC,CAAC;QAC1D,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAI,CAAC,YAAY,GAAG,iBAAiB,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QACpF,CAAC;QAED,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;QACtB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,cAAc;QAClB,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;QAC1B,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;IACxB,CAAC;IAED;;OAEG;IACH,YAAY,CAAC,MAAc,EAAE,KAAuB;QAClD,OAAO,KAAK,CAAC,aAAa,CAAC;IAC7B,CAAC;IAED;;OAEG;IACH,cAAc,CAAC,MAAc,EAAE,GAAuB;QACpD,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;IAClD,CAAC;IAED;;OAEG;IACH,iBAAiB,CAAC,KAAuB;QACvC,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,oCAAoC,CAAC;QAC1E,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,QAAQ,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC;IACrF,CAAC;IAED;;OAEG;IACH,eAAe,CAAC,KAAuB,EAAE,MAAc;QACrD,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,KAAK,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;IAC5D,CAAC;2HA9SU,iCAAiC;6DAAjC,iCAAiC;YCvC1C,AADF,AAFF,8BAAiC,aAEX,aACO;YACvB,uBAAmD;YACnD,6BAAyB;YAAA,iCAAiB;YAC5C,AAD4C,iBAAK,EAC3C;YACN,8BAA4B;YAC1B,yFAAyB;YAYzB,iCAA6F;YAAxD,8GAAS,cAAU,IAAC;YACvD,uBAAqE;YAAC,0BACxE;YAEJ,AADE,AADE,iBAAS,EACL,EACF;YAGN,qGAAoB;YAMpB,qGAAsB;YAQtB,6GAAiB;YAKjB,2FAAkB;YA8FpB,iBAAM;;YApIA,eAWC;YAXD,gDAWC;YACyD,cAAkC;YAAlC,wDAAkC;YACrD,cAA2B;YAA3B,wCAA2B;YAMtE,eAKC;YALD,4CAKC;YACD,cAKC;YALD,8CAKC;YAGD,cAEC;YAFD,yCAEC;YAGD,cA6FC;YA7FD,0CA6FC;;;ADjGU,iCAAiC;IAP7C,aAAa,CAAC,qBAAqB,EAAE,0BAA0B,CAAC;GAOpD,iCAAiC,CA+S7C;;iFA/SY,iCAAiC;cAN7C,SAAS;6BACI,KAAK,YACP,+BAA+B;;kFAI9B,iCAAiC;AAiT9C,8BAA8B;AAC9B,MAAM,UAAU,4BAA4B;IAC1C,wBAAwB;AAC1B,CAAC","sourcesContent":["import { Component, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';\nimport { RegisterClass, UUIDsEqual } from '@memberjunction/global';\nimport { BaseResourceComponent } from '@memberjunction/ng-shared';\nimport { CompositeKey, Metadata, RunView } from '@memberjunction/core';\nimport { ResourceData } from '@memberjunction/core-entities';\n\n/**\n * Represents an application's role assignment for display in the grid.\n */\ninterface ApplicationRoleRow {\n ID: string;\n ApplicationID: string;\n ApplicationName: string;\n RoleID: string;\n RoleName: string;\n CanAccess: boolean;\n CanAdmin: boolean;\n IsDirty: boolean;\n IsNew: boolean;\n}\n\n/**\n * Represents an application with its role assignments grouped.\n */\ninterface ApplicationGroup {\n ApplicationID: string;\n ApplicationName: string;\n Roles: ApplicationRoleRow[];\n Expanded: boolean;\n}\n\n/**\n * Admin dashboard for managing Application Role assignments.\n * Shows which roles can access and administer each application.\n */\n@RegisterClass(BaseResourceComponent, 'ApplicationRolesResource')\n@Component({\n standalone: false,\n selector: 'mj-application-roles-resource',\n templateUrl: './application-roles-resource.component.html',\n styleUrls: ['./application-roles-resource.component.css']\n})\nexport class ApplicationRolesResourceComponent extends BaseResourceComponent implements OnInit, OnDestroy {\n ApplicationGroups: ApplicationGroup[] = [];\n AvailableRoles: { ID: string; Name: string }[] = [];\n IsLoading = true;\n IsSaving = false;\n HasUnsavedChanges = false;\n ErrorMessage: string | null = null;\n SuccessMessage: string | null = null;\n\n // For the \"Add Role\" dropdown per application\n SelectedRoleIdToAdd: Map<string, string> = new Map();\n\n constructor(private cdr: ChangeDetectorRef) {\n super();\n }\n\n override async GetResourceDisplayName(_data: ResourceData): Promise<string> {\n return 'App Roles';\n }\n\n override async GetResourceIconClass(_data: ResourceData): Promise<string> {\n return 'fa-solid fa-user-shield';\n }\n\n override async ngOnInit(): Promise<void> {\n super.ngOnInit();\n await this.loadData();\n this.NotifyLoadComplete();\n }\n\n override ngOnDestroy(): void {\n super.ngOnDestroy();\n }\n\n /**\n * Load all application role data and available roles.\n */\n async loadData(): Promise<void> {\n this.IsLoading = true;\n this.ErrorMessage = null;\n this.cdr.detectChanges();\n\n try {\n const md = new Metadata();\n const rv = new RunView();\n\n // Load available roles from metadata\n this.AvailableRoles = md.Roles.map(r => ({ ID: r.ID, Name: r.Name }))\n .sort((a, b) => a.Name.localeCompare(b.Name));\n\n // Load existing ApplicationRole records\n const result = await rv.RunView<{ ID: string; ApplicationID: string; Application: string; RoleID: string; Role: string; CanAccess: boolean; CanAdmin: boolean }>({\n EntityName: 'MJ: Application Roles',\n ResultType: 'simple',\n });\n\n if (!result.Success) {\n this.ErrorMessage = result.ErrorMessage || 'Failed to load application roles.';\n this.IsLoading = false;\n this.cdr.detectChanges();\n return;\n }\n\n // Build grouped structure\n const appMap = new Map<string, ApplicationGroup>();\n\n // Seed all applications so we can show apps without any role records\n for (const app of md.Applications) {\n appMap.set(app.ID, {\n ApplicationID: app.ID,\n ApplicationName: app.Name,\n Roles: [],\n Expanded: false,\n });\n }\n\n // Populate role assignments\n for (const record of result.Results) {\n const group = appMap.get(record.ApplicationID);\n if (group) {\n group.Roles.push({\n ID: record.ID,\n ApplicationID: record.ApplicationID,\n ApplicationName: group.ApplicationName,\n RoleID: record.RoleID,\n RoleName: record.Role || '',\n CanAccess: record.CanAccess,\n CanAdmin: record.CanAdmin,\n IsDirty: false,\n IsNew: false,\n });\n }\n }\n\n // Sort roles within each group\n for (const group of appMap.values()) {\n group.Roles.sort((a, b) => a.RoleName.localeCompare(b.RoleName));\n }\n\n this.ApplicationGroups = Array.from(appMap.values())\n .sort((a, b) => a.ApplicationName.localeCompare(b.ApplicationName));\n } catch (e) {\n this.ErrorMessage = `Error loading data: ${e instanceof Error ? e.message : String(e)}`;\n }\n\n this.IsLoading = false;\n this.HasUnsavedChanges = false;\n this.cdr.detectChanges();\n }\n\n /**\n * Toggle the expanded/collapsed state of an application group.\n */\n ToggleGroup(group: ApplicationGroup): void {\n group.Expanded = !group.Expanded;\n this.cdr.detectChanges();\n }\n\n /**\n * Toggle CanAccess for a specific role assignment.\n */\n ToggleCanAccess(row: ApplicationRoleRow): void {\n row.CanAccess = !row.CanAccess;\n row.IsDirty = true;\n this.HasUnsavedChanges = true;\n this.cdr.detectChanges();\n }\n\n /**\n * Toggle CanAdmin for a specific role assignment.\n */\n ToggleCanAdmin(row: ApplicationRoleRow): void {\n row.CanAdmin = !row.CanAdmin;\n row.IsDirty = true;\n this.HasUnsavedChanges = true;\n this.cdr.detectChanges();\n }\n\n /**\n * Get roles not yet assigned to a specific application (for the \"Add Role\" dropdown).\n */\n GetUnassignedRoles(group: ApplicationGroup): { ID: string; Name: string }[] {\n const assignedRoleIds = new Set(group.Roles.map(r => r.RoleID.toLowerCase()));\n return this.AvailableRoles.filter(r => !assignedRoleIds.has(r.ID.toLowerCase()));\n }\n\n /**\n * Add a new role assignment to an application group.\n */\n AddRole(group: ApplicationGroup): void {\n const roleId = this.SelectedRoleIdToAdd.get(group.ApplicationID);\n if (!roleId) return;\n\n const role = this.AvailableRoles.find(r => UUIDsEqual(r.ID, roleId));\n if (!role) return;\n\n group.Roles.push({\n ID: '',\n ApplicationID: group.ApplicationID,\n ApplicationName: group.ApplicationName,\n RoleID: role.ID,\n RoleName: role.Name,\n CanAccess: true,\n CanAdmin: false,\n IsDirty: true,\n IsNew: true,\n });\n\n group.Roles.sort((a, b) => a.RoleName.localeCompare(b.RoleName));\n this.SelectedRoleIdToAdd.delete(group.ApplicationID);\n this.HasUnsavedChanges = true;\n this.cdr.detectChanges();\n }\n\n /**\n * Remove a role assignment (marks for deletion on save; removes immediately if new).\n */\n RemoveRole(group: ApplicationGroup, row: ApplicationRoleRow): void {\n const idx = group.Roles.indexOf(row);\n if (idx >= 0) {\n group.Roles.splice(idx, 1);\n }\n // If not new, we need to delete it on save — track via dirty state\n if (!row.IsNew) {\n this._pendingDeletes.push(row.ID);\n }\n this.HasUnsavedChanges = true;\n this.cdr.detectChanges();\n }\n\n private _pendingDeletes: string[] = [];\n\n /**\n * Save all unsaved changes (new records, modified records, deleted records).\n */\n async SaveChanges(): Promise<void> {\n this.IsSaving = true;\n this.ErrorMessage = null;\n this.SuccessMessage = null;\n this.cdr.detectChanges();\n\n try {\n const md = new Metadata();\n\n // Process deletes\n for (const deleteId of this._pendingDeletes) {\n const entity = await md.GetEntityObject('MJ: Application Roles');\n await entity.InnerLoad(new CompositeKey([{ FieldName: 'ID', Value: deleteId }]));\n const deleteResult = await entity.Delete();\n if (!deleteResult) {\n this.ErrorMessage = `Failed to delete role assignment: ${entity.LatestResult?.Message || 'Unknown error'}`;\n this.IsSaving = false;\n this.cdr.detectChanges();\n return;\n }\n }\n\n // Process new and modified records\n for (const group of this.ApplicationGroups) {\n for (const row of group.Roles) {\n if (!row.IsDirty) continue;\n\n if (row.IsNew) {\n const entity = await md.GetEntityObject('MJ: Application Roles');\n entity.NewRecord();\n entity.Set('ApplicationID', row.ApplicationID);\n entity.Set('RoleID', row.RoleID);\n entity.Set('CanAccess', row.CanAccess);\n entity.Set('CanAdmin', row.CanAdmin);\n const saveResult = await entity.Save();\n if (!saveResult) {\n this.ErrorMessage = `Failed to save new role assignment for ${row.RoleName}: ${entity.LatestResult?.Message || 'Unknown error'}`;\n this.IsSaving = false;\n this.cdr.detectChanges();\n return;\n }\n row.ID = entity.Get('ID');\n } else {\n const entity = await md.GetEntityObject('MJ: Application Roles');\n await entity.InnerLoad(new CompositeKey([{ FieldName: 'ID', Value: row.ID }]));\n entity.Set('CanAccess', row.CanAccess);\n entity.Set('CanAdmin', row.CanAdmin);\n const saveResult = await entity.Save();\n if (!saveResult) {\n this.ErrorMessage = `Failed to update role assignment for ${row.RoleName}: ${entity.LatestResult?.Message || 'Unknown error'}`;\n this.IsSaving = false;\n this.cdr.detectChanges();\n return;\n }\n }\n\n row.IsDirty = false;\n row.IsNew = false;\n }\n }\n\n this._pendingDeletes = [];\n this.HasUnsavedChanges = false;\n this.SuccessMessage = 'All changes saved successfully.';\n } catch (e) {\n this.ErrorMessage = `Error saving: ${e instanceof Error ? e.message : String(e)}`;\n }\n\n this.IsSaving = false;\n this.cdr.detectChanges();\n }\n\n /**\n * Discard all unsaved changes and reload data.\n */\n async DiscardChanges(): Promise<void> {\n this._pendingDeletes = [];\n await this.loadData();\n }\n\n /**\n * Track by function for application groups.\n */\n TrackByAppId(_index: number, group: ApplicationGroup): string {\n return group.ApplicationID;\n }\n\n /**\n * Track by function for role rows.\n */\n TrackByRoleRow(_index: number, row: ApplicationRoleRow): string {\n return row.IsNew ? `new-${row.RoleID}` : row.ID;\n }\n\n /**\n * Get the role count label for an application.\n */\n GetRoleCountLabel(group: ApplicationGroup): string {\n if (group.Roles.length === 0) return 'Open Access (no role restrictions)';\n return `${group.Roles.length} role${group.Roles.length === 1 ? '' : 's'} assigned`;\n }\n\n /**\n * Handle dropdown selection for adding roles.\n */\n OnAddRoleSelect(group: ApplicationGroup, roleId: string): void {\n this.SelectedRoleIdToAdd.set(group.ApplicationID, roleId);\n }\n}\n\n/** Tree-shaking prevention */\nexport function LoadApplicationRolesResource(): void {\n // Prevents tree-shaking\n}\n","<div class=\"app-roles-container\">\n <!-- Header -->\n <div class=\"header\">\n <div class=\"header-left\">\n <i class=\"fa-solid fa-user-shield header-icon\"></i>\n <h2 class=\"header-title\">Application Roles</h2>\n </div>\n <div class=\"header-actions\">\n @if (HasUnsavedChanges) {\n <button mjButton variant=\"secondary\" (click)=\"DiscardChanges()\" [disabled]=\"IsSaving\">\n <i class=\"fa-solid fa-rotate-left\"></i> Discard\n </button>\n <button mjButton variant=\"primary\" (click)=\"SaveChanges()\" [disabled]=\"IsSaving\">\n @if (IsSaving) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Saving...\n } @else {\n <i class=\"fa-solid fa-floppy-disk\"></i> Save Changes\n }\n </button>\n }\n <button mjButton variant=\"secondary\" (click)=\"loadData()\" [disabled]=\"IsLoading || IsSaving\">\n <i class=\"fa-solid fa-arrows-rotate\" [class.fa-spin]=\"IsLoading\"></i> Refresh\n </button>\n </div>\n </div>\n\n <!-- Status Messages -->\n @if (ErrorMessage) {\n <div class=\"message error-message\">\n <i class=\"fa-solid fa-circle-exclamation\"></i>\n {{ ErrorMessage }}\n </div>\n }\n @if (SuccessMessage) {\n <div class=\"message success-message\">\n <i class=\"fa-solid fa-circle-check\"></i>\n {{ SuccessMessage }}\n </div>\n }\n\n <!-- Loading State -->\n @if (IsLoading) {\n <mj-loading text=\"Loading application roles...\"></mj-loading>\n }\n\n <!-- Main Content -->\n @if (!IsLoading) {\n <p class=\"description\">\n Configure which roles can access each application. Applications with no role assignments are open to all users (backwards compatible).\n </p>\n\n <div class=\"app-groups\">\n @for (group of ApplicationGroups; track TrackByAppId($index, group)) {\n <div class=\"app-group\" [class.expanded]=\"group.Expanded\" [class.has-roles]=\"group.Roles.length > 0\">\n <!-- Application Header Row -->\n <div class=\"app-group-header\" (click)=\"ToggleGroup(group)\">\n <div class=\"app-header-left\">\n <i class=\"fa-solid\" [ngClass]=\"group.Expanded ? 'fa-chevron-down' : 'fa-chevron-right'\"></i>\n <span class=\"app-name\">{{ group.ApplicationName }}</span>\n <span class=\"role-count-badge\" [class.open-access]=\"group.Roles.length === 0\">\n {{ GetRoleCountLabel(group) }}\n </span>\n </div>\n </div>\n\n <!-- Expanded Content -->\n @if (group.Expanded) {\n <div class=\"app-group-content\">\n <!-- Existing Role Assignments -->\n @if (group.Roles.length > 0) {\n <table class=\"roles-table\">\n <thead>\n <tr>\n <th class=\"col-role\">Role</th>\n <th class=\"col-access\">Can Access</th>\n <th class=\"col-admin\">Can Admin</th>\n <th class=\"col-actions\">Actions</th>\n </tr>\n </thead>\n <tbody>\n @for (row of group.Roles; track TrackByRoleRow($index, row)) {\n <tr [class.dirty]=\"row.IsDirty\" [class.new-row]=\"row.IsNew\">\n <td class=\"col-role\">\n <i class=\"fa-solid fa-shield-halved role-icon\"></i>\n {{ row.RoleName }}\n @if (row.IsNew) {\n <span class=\"new-badge\">new</span>\n }\n </td>\n <td class=\"col-access\">\n <input type=\"checkbox\"\n class=\"mj-checkbox\"\n [checked]=\"row.CanAccess\"\n (change)=\"ToggleCanAccess(row)\">\n </td>\n <td class=\"col-admin\">\n <input type=\"checkbox\"\n class=\"mj-checkbox\"\n [checked]=\"row.CanAdmin\"\n (change)=\"ToggleCanAdmin(row)\">\n </td>\n <td class=\"col-actions\">\n <button class=\"remove-btn\" (click)=\"RemoveRole(group, row)\" title=\"Remove role assignment\">\n <i class=\"fa-solid fa-trash-can\"></i>\n </button>\n </td>\n </tr>\n }\n </tbody>\n </table>\n } @else {\n <div class=\"no-roles-message\">\n <i class=\"fa-solid fa-unlock\"></i>\n No role restrictions — all authenticated users can access this application.\n </div>\n }\n\n <!-- Add Role -->\n <div class=\"add-role-row\">\n <select class=\"mj-input add-role-select\"\n [value]=\"SelectedRoleIdToAdd.get(group.ApplicationID) || ''\"\n (change)=\"OnAddRoleSelect(group, $any($event.target).value)\">\n <option value=\"\" disabled>Select a role to add...</option>\n @for (role of GetUnassignedRoles(group); track role.ID) {\n <option [value]=\"role.ID\">{{ role.Name }}</option>\n }\n </select>\n <button mjButton\n variant=\"secondary\"\n (click)=\"AddRole(group)\"\n [disabled]=\"!SelectedRoleIdToAdd.get(group.ApplicationID)\">\n <i class=\"fa-solid fa-plus\"></i> Add Role\n </button>\n </div>\n </div>\n }\n </div>\n }\n </div>\n }\n</div>\n"]}
|
|
1
|
+
{"version":3,"file":"application-roles-resource.component.js","sourceRoot":"","sources":["../../src/ApplicationRoles/application-roles-resource.component.ts","../../src/ApplicationRoles/application-roles-resource.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';\nimport { RegisterClass, UUIDsEqual } from '@memberjunction/global';\nimport { BaseResourceComponent } from '@memberjunction/ng-shared';\nimport { CompositeKey, Metadata, RunView } from '@memberjunction/core';\nimport { ResourceData } from '@memberjunction/core-entities';\n\n/**\n * Represents an application's role assignment for display in the grid.\n */\ninterface ApplicationRoleRow {\n ID: string;\n ApplicationID: string;\n ApplicationName: string;\n RoleID: string;\n RoleName: string;\n CanAccess: boolean;\n CanAdmin: boolean;\n IsDirty: boolean;\n IsNew: boolean;\n}\n\n/**\n * Represents an application with its role assignments grouped.\n */\ninterface ApplicationGroup {\n ApplicationID: string;\n ApplicationName: string;\n Roles: ApplicationRoleRow[];\n Expanded: boolean;\n}\n\n/**\n * Admin dashboard for managing Application Role assignments.\n * Shows which roles can access and administer each application.\n */\n@RegisterClass(BaseResourceComponent, 'ApplicationRolesResource')\n@Component({\n standalone: false,\n selector: 'mj-application-roles-resource',\n templateUrl: './application-roles-resource.component.html',\n styleUrls: ['./application-roles-resource.component.css']\n})\nexport class ApplicationRolesResourceComponent extends BaseResourceComponent implements OnInit, OnDestroy {\n ApplicationGroups: ApplicationGroup[] = [];\n AvailableRoles: { ID: string; Name: string }[] = [];\n IsLoading = true;\n IsSaving = false;\n HasUnsavedChanges = false;\n ErrorMessage: string | null = null;\n SuccessMessage: string | null = null;\n\n // For the \"Add Role\" dropdown per application\n SelectedRoleIdToAdd: Map<string, string> = new Map();\n\n constructor(private cdr: ChangeDetectorRef) {\n super();\n }\n\n override async GetResourceDisplayName(_data: ResourceData): Promise<string> {\n return 'App Roles';\n }\n\n override async GetResourceIconClass(_data: ResourceData): Promise<string> {\n return 'fa-solid fa-user-shield';\n }\n\n override async ngOnInit(): Promise<void> {\n super.ngOnInit();\n await this.loadData();\n this.NotifyLoadComplete();\n }\n\n override ngOnDestroy(): void {\n super.ngOnDestroy();\n }\n\n /**\n * Load all application role data and available roles.\n */\n async loadData(): Promise<void> {\n this.IsLoading = true;\n this.ErrorMessage = null;\n this.cdr.detectChanges();\n\n try {\n const md = this.ProviderToUse;\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n\n // Load available roles from metadata\n this.AvailableRoles = md.Roles.map(r => ({ ID: r.ID, Name: r.Name }))\n .sort((a, b) => a.Name.localeCompare(b.Name));\n\n // Load existing ApplicationRole records\n const result = await rv.RunView<{ ID: string; ApplicationID: string; Application: string; RoleID: string; Role: string; CanAccess: boolean; CanAdmin: boolean }>({\n EntityName: 'MJ: Application Roles',\n ResultType: 'simple',\n });\n\n if (!result.Success) {\n this.ErrorMessage = result.ErrorMessage || 'Failed to load application roles.';\n this.IsLoading = false;\n this.cdr.detectChanges();\n return;\n }\n\n // Build grouped structure\n const appMap = new Map<string, ApplicationGroup>();\n\n // Seed all applications so we can show apps without any role records\n for (const app of md.Applications) {\n appMap.set(app.ID, {\n ApplicationID: app.ID,\n ApplicationName: app.Name,\n Roles: [],\n Expanded: false,\n });\n }\n\n // Populate role assignments\n for (const record of result.Results) {\n const group = appMap.get(record.ApplicationID);\n if (group) {\n group.Roles.push({\n ID: record.ID,\n ApplicationID: record.ApplicationID,\n ApplicationName: group.ApplicationName,\n RoleID: record.RoleID,\n RoleName: record.Role || '',\n CanAccess: record.CanAccess,\n CanAdmin: record.CanAdmin,\n IsDirty: false,\n IsNew: false,\n });\n }\n }\n\n // Sort roles within each group\n for (const group of appMap.values()) {\n group.Roles.sort((a, b) => a.RoleName.localeCompare(b.RoleName));\n }\n\n this.ApplicationGroups = Array.from(appMap.values())\n .sort((a, b) => a.ApplicationName.localeCompare(b.ApplicationName));\n } catch (e) {\n this.ErrorMessage = `Error loading data: ${e instanceof Error ? e.message : String(e)}`;\n }\n\n this.IsLoading = false;\n this.HasUnsavedChanges = false;\n this.cdr.detectChanges();\n }\n\n /**\n * Toggle the expanded/collapsed state of an application group.\n */\n ToggleGroup(group: ApplicationGroup): void {\n group.Expanded = !group.Expanded;\n this.cdr.detectChanges();\n }\n\n /**\n * Toggle CanAccess for a specific role assignment.\n */\n ToggleCanAccess(row: ApplicationRoleRow): void {\n row.CanAccess = !row.CanAccess;\n row.IsDirty = true;\n this.HasUnsavedChanges = true;\n this.cdr.detectChanges();\n }\n\n /**\n * Toggle CanAdmin for a specific role assignment.\n */\n ToggleCanAdmin(row: ApplicationRoleRow): void {\n row.CanAdmin = !row.CanAdmin;\n row.IsDirty = true;\n this.HasUnsavedChanges = true;\n this.cdr.detectChanges();\n }\n\n /**\n * Get roles not yet assigned to a specific application (for the \"Add Role\" dropdown).\n */\n GetUnassignedRoles(group: ApplicationGroup): { ID: string; Name: string }[] {\n const assignedRoleIds = new Set(group.Roles.map(r => r.RoleID.toLowerCase()));\n return this.AvailableRoles.filter(r => !assignedRoleIds.has(r.ID.toLowerCase()));\n }\n\n /**\n * Add a new role assignment to an application group.\n */\n AddRole(group: ApplicationGroup): void {\n const roleId = this.SelectedRoleIdToAdd.get(group.ApplicationID);\n if (!roleId) return;\n\n const role = this.AvailableRoles.find(r => UUIDsEqual(r.ID, roleId));\n if (!role) return;\n\n group.Roles.push({\n ID: '',\n ApplicationID: group.ApplicationID,\n ApplicationName: group.ApplicationName,\n RoleID: role.ID,\n RoleName: role.Name,\n CanAccess: true,\n CanAdmin: false,\n IsDirty: true,\n IsNew: true,\n });\n\n group.Roles.sort((a, b) => a.RoleName.localeCompare(b.RoleName));\n this.SelectedRoleIdToAdd.delete(group.ApplicationID);\n this.HasUnsavedChanges = true;\n this.cdr.detectChanges();\n }\n\n /**\n * Remove a role assignment (marks for deletion on save; removes immediately if new).\n */\n RemoveRole(group: ApplicationGroup, row: ApplicationRoleRow): void {\n const idx = group.Roles.indexOf(row);\n if (idx >= 0) {\n group.Roles.splice(idx, 1);\n }\n // If not new, we need to delete it on save — track via dirty state\n if (!row.IsNew) {\n this._pendingDeletes.push(row.ID);\n }\n this.HasUnsavedChanges = true;\n this.cdr.detectChanges();\n }\n\n private _pendingDeletes: string[] = [];\n\n /**\n * Save all unsaved changes (new records, modified records, deleted records).\n */\n async SaveChanges(): Promise<void> {\n this.IsSaving = true;\n this.ErrorMessage = null;\n this.SuccessMessage = null;\n this.cdr.detectChanges();\n\n try {\n const md = this.ProviderToUse;\n\n // Process deletes\n for (const deleteId of this._pendingDeletes) {\n const entity = await md.GetEntityObject('MJ: Application Roles');\n await entity.InnerLoad(new CompositeKey([{ FieldName: 'ID', Value: deleteId }]));\n const deleteResult = await entity.Delete();\n if (!deleteResult) {\n this.ErrorMessage = `Failed to delete role assignment: ${entity.LatestResult?.Message || 'Unknown error'}`;\n this.IsSaving = false;\n this.cdr.detectChanges();\n return;\n }\n }\n\n // Process new and modified records\n for (const group of this.ApplicationGroups) {\n for (const row of group.Roles) {\n if (!row.IsDirty) continue;\n\n if (row.IsNew) {\n const entity = await md.GetEntityObject('MJ: Application Roles');\n entity.NewRecord();\n entity.Set('ApplicationID', row.ApplicationID);\n entity.Set('RoleID', row.RoleID);\n entity.Set('CanAccess', row.CanAccess);\n entity.Set('CanAdmin', row.CanAdmin);\n const saveResult = await entity.Save();\n if (!saveResult) {\n this.ErrorMessage = `Failed to save new role assignment for ${row.RoleName}: ${entity.LatestResult?.Message || 'Unknown error'}`;\n this.IsSaving = false;\n this.cdr.detectChanges();\n return;\n }\n row.ID = entity.Get('ID');\n } else {\n const entity = await md.GetEntityObject('MJ: Application Roles');\n await entity.InnerLoad(new CompositeKey([{ FieldName: 'ID', Value: row.ID }]));\n entity.Set('CanAccess', row.CanAccess);\n entity.Set('CanAdmin', row.CanAdmin);\n const saveResult = await entity.Save();\n if (!saveResult) {\n this.ErrorMessage = `Failed to update role assignment for ${row.RoleName}: ${entity.LatestResult?.Message || 'Unknown error'}`;\n this.IsSaving = false;\n this.cdr.detectChanges();\n return;\n }\n }\n\n row.IsDirty = false;\n row.IsNew = false;\n }\n }\n\n this._pendingDeletes = [];\n this.HasUnsavedChanges = false;\n this.SuccessMessage = 'All changes saved successfully.';\n } catch (e) {\n this.ErrorMessage = `Error saving: ${e instanceof Error ? e.message : String(e)}`;\n }\n\n this.IsSaving = false;\n this.cdr.detectChanges();\n }\n\n /**\n * Discard all unsaved changes and reload data.\n */\n async DiscardChanges(): Promise<void> {\n this._pendingDeletes = [];\n await this.loadData();\n }\n\n /**\n * Track by function for application groups.\n */\n TrackByAppId(_index: number, group: ApplicationGroup): string {\n return group.ApplicationID;\n }\n\n /**\n * Track by function for role rows.\n */\n TrackByRoleRow(_index: number, row: ApplicationRoleRow): string {\n return row.IsNew ? `new-${row.RoleID}` : row.ID;\n }\n\n /**\n * Get the role count label for an application.\n */\n GetRoleCountLabel(group: ApplicationGroup): string {\n if (group.Roles.length === 0) return 'Open Access (no role restrictions)';\n return `${group.Roles.length} role${group.Roles.length === 1 ? '' : 's'} assigned`;\n }\n\n /**\n * Handle dropdown selection for adding roles.\n */\n OnAddRoleSelect(group: ApplicationGroup, roleId: string): void {\n this.SelectedRoleIdToAdd.set(group.ApplicationID, roleId);\n }\n}\n\n/** Tree-shaking prevention */\nexport function LoadApplicationRolesResource(): void {\n // Prevents tree-shaking\n}\n","<div class=\"app-roles-container\">\n <!-- Header -->\n <div class=\"header\">\n <div class=\"header-left\">\n <i class=\"fa-solid fa-user-shield header-icon\"></i>\n <h2 class=\"header-title\">Application Roles</h2>\n </div>\n <div class=\"header-actions\">\n @if (HasUnsavedChanges) {\n <button mjButton variant=\"secondary\" (click)=\"DiscardChanges()\" [disabled]=\"IsSaving\">\n <i class=\"fa-solid fa-rotate-left\"></i> Discard\n </button>\n <button mjButton variant=\"primary\" (click)=\"SaveChanges()\" [disabled]=\"IsSaving\">\n @if (IsSaving) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Saving...\n } @else {\n <i class=\"fa-solid fa-floppy-disk\"></i> Save Changes\n }\n </button>\n }\n <button mjButton variant=\"secondary\" (click)=\"loadData()\" [disabled]=\"IsLoading || IsSaving\">\n <i class=\"fa-solid fa-arrows-rotate\" [class.fa-spin]=\"IsLoading\"></i> Refresh\n </button>\n </div>\n </div>\n\n <!-- Status Messages -->\n @if (ErrorMessage) {\n <div class=\"message error-message\">\n <i class=\"fa-solid fa-circle-exclamation\"></i>\n {{ ErrorMessage }}\n </div>\n }\n @if (SuccessMessage) {\n <div class=\"message success-message\">\n <i class=\"fa-solid fa-circle-check\"></i>\n {{ SuccessMessage }}\n </div>\n }\n\n <!-- Loading State -->\n @if (IsLoading) {\n <mj-loading text=\"Loading application roles...\"></mj-loading>\n }\n\n <!-- Main Content -->\n @if (!IsLoading) {\n <p class=\"description\">\n Configure which roles can access each application. Applications with no role assignments are open to all users (backwards compatible).\n </p>\n\n <div class=\"app-groups\">\n @for (group of ApplicationGroups; track TrackByAppId($index, group)) {\n <div class=\"app-group\" [class.expanded]=\"group.Expanded\" [class.has-roles]=\"group.Roles.length > 0\">\n <!-- Application Header Row -->\n <div class=\"app-group-header\" (click)=\"ToggleGroup(group)\">\n <div class=\"app-header-left\">\n <i class=\"fa-solid\" [ngClass]=\"group.Expanded ? 'fa-chevron-down' : 'fa-chevron-right'\"></i>\n <span class=\"app-name\">{{ group.ApplicationName }}</span>\n <span class=\"role-count-badge\" [class.open-access]=\"group.Roles.length === 0\">\n {{ GetRoleCountLabel(group) }}\n </span>\n </div>\n </div>\n\n <!-- Expanded Content -->\n @if (group.Expanded) {\n <div class=\"app-group-content\">\n <!-- Existing Role Assignments -->\n @if (group.Roles.length > 0) {\n <table class=\"roles-table\">\n <thead>\n <tr>\n <th class=\"col-role\">Role</th>\n <th class=\"col-access\">Can Access</th>\n <th class=\"col-admin\">Can Admin</th>\n <th class=\"col-actions\">Actions</th>\n </tr>\n </thead>\n <tbody>\n @for (row of group.Roles; track TrackByRoleRow($index, row)) {\n <tr [class.dirty]=\"row.IsDirty\" [class.new-row]=\"row.IsNew\">\n <td class=\"col-role\">\n <i class=\"fa-solid fa-shield-halved role-icon\"></i>\n {{ row.RoleName }}\n @if (row.IsNew) {\n <span class=\"new-badge\">new</span>\n }\n </td>\n <td class=\"col-access\">\n <input type=\"checkbox\"\n class=\"mj-checkbox\"\n [checked]=\"row.CanAccess\"\n (change)=\"ToggleCanAccess(row)\">\n </td>\n <td class=\"col-admin\">\n <input type=\"checkbox\"\n class=\"mj-checkbox\"\n [checked]=\"row.CanAdmin\"\n (change)=\"ToggleCanAdmin(row)\">\n </td>\n <td class=\"col-actions\">\n <button class=\"remove-btn\" (click)=\"RemoveRole(group, row)\" title=\"Remove role assignment\">\n <i class=\"fa-solid fa-trash-can\"></i>\n </button>\n </td>\n </tr>\n }\n </tbody>\n </table>\n } @else {\n <div class=\"no-roles-message\">\n <i class=\"fa-solid fa-unlock\"></i>\n No role restrictions — all authenticated users can access this application.\n </div>\n }\n\n <!-- Add Role -->\n <div class=\"add-role-row\">\n <select class=\"mj-input add-role-select\"\n [value]=\"SelectedRoleIdToAdd.get(group.ApplicationID) || ''\"\n (change)=\"OnAddRoleSelect(group, $any($event.target).value)\">\n <option value=\"\" disabled>Select a role to add...</option>\n @for (role of GetUnassignedRoles(group); track role.ID) {\n <option [value]=\"role.ID\">{{ role.Name }}</option>\n }\n </select>\n <button mjButton\n variant=\"secondary\"\n (click)=\"AddRole(group)\"\n [disabled]=\"!SelectedRoleIdToAdd.get(group.ApplicationID)\">\n <i class=\"fa-solid fa-plus\"></i> Add Role\n </button>\n </div>\n </div>\n }\n </div>\n }\n </div>\n }\n</div>\n"]}
|
|
@@ -108,7 +108,7 @@ let CommunicationLogsResourceComponent = class CommunicationLogsResourceComponen
|
|
|
108
108
|
try {
|
|
109
109
|
this.isLoading = true;
|
|
110
110
|
this.cdr.detectChanges();
|
|
111
|
-
const rv =
|
|
111
|
+
const rv = RunView.FromMetadataProvider(this.ProviderToUse);
|
|
112
112
|
const result = await rv.RunView({
|
|
113
113
|
EntityName: 'MJ: Communication Logs',
|
|
114
114
|
OrderBy: 'MessageDate DESC',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"communication-logs-resource.component.js","sourceRoot":"","sources":["../../src/Communication/communication-logs-resource.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';\nimport { ResourceData, MJCommunicationLogEntity } from '@memberjunction/core-entities';\nimport { RegisterClass } from '@memberjunction/global';\nimport { BaseResourceComponent } from '@memberjunction/ng-shared';\nimport { RunView } from '@memberjunction/core';\n@RegisterClass(BaseResourceComponent, 'CommunicationLogsResource')\n@Component({\n standalone: false,\n selector: 'mj-communication-logs-resource',\n template: `\n <div class=\"logs-wrapper\">\n <div class=\"card\">\n <div class=\"logs-toolbar\">\n <div class=\"search-input-wrapper\">\n <i class=\"fa-solid fa-search\"></i>\n <input type=\"text\" placeholder=\"Search messages, providers, recipients...\" (input)=\"onSearch($event)\">\n </div>\n <div class=\"filter-chip\" [class.active]=\"statusFilter === ''\"\n (click)=\"onStatusFilter('')\">\n <i class=\"fa-solid fa-filter\"></i> All\n </div>\n <div class=\"filter-chip\" [class.active]=\"statusFilter === 'Complete'\"\n (click)=\"onStatusFilter('Complete')\">\n <i class=\"fa-solid fa-check-circle\"></i> Sent\n </div>\n <div class=\"filter-chip\" [class.active]=\"statusFilter === 'Failed'\"\n (click)=\"onStatusFilter('Failed')\">\n <i class=\"fa-solid fa-times-circle\"></i> Failed\n </div>\n <div class=\"filter-chip\" [class.active]=\"statusFilter === 'Pending'\"\n (click)=\"onStatusFilter('Pending')\">\n <i class=\"fa-solid fa-clock\"></i> Pending\n </div>\n <div class=\"toolbar-spacer\"></div>\n <button class=\"tb-btn\" (click)=\"loadData()\">\n <i class=\"fa-solid fa-rotate\" [class.spinning]=\"isLoading\"></i> Refresh\n </button>\n </div>\n <div class=\"table-wrapper\">\n <table class=\"log-table\">\n <thead>\n <tr>\n <th>Status</th>\n <th>Direction</th>\n <th>Provider</th>\n <th>Type</th>\n <th>Date</th>\n <th>Error</th>\n </tr>\n </thead>\n <tbody>\n @for (log of filteredLogs; track log) {\n <tr>\n <td>\n <span class=\"log-status-badge\" [ngClass]=\"getStatusClass(log.Status)\">\n <i [class]=\"getStatusIcon(log.Status)\"></i>\n {{log.Status}}\n </span>\n </td>\n <td>\n <span class=\"log-direction\" [ngClass]=\"log.Direction.toLowerCase()\">\n <i [class]=\"log.Direction === 'Sending' ? 'fa-solid fa-arrow-up-right' : 'fa-solid fa-arrow-down-left'\"></i>\n {{log.Direction}}\n </span>\n </td>\n <td>\n <span class=\"log-provider-badge\">\n <i [class]=\"getProviderIcon(log.CommunicationProvider)\" [style.color]=\"getProviderColor(log.CommunicationProvider)\"></i>\n {{log.CommunicationProvider}}\n </span>\n </td>\n <td>{{log.CommunicationProviderMessageType}}</td>\n <td>{{log.MessageDate | date:'medium'}}</td>\n <td>\n @if (log.ErrorMessage) {\n <span class=\"log-error-text\" [title]=\"log.ErrorMessage\">\n {{log.ErrorMessage}}\n </span>\n }\n @if (!log.ErrorMessage) {\n <span class=\"no-error\">—</span>\n }\n </td>\n </tr>\n }\n @if (filteredLogs.length === 0 && !isLoading) {\n <tr>\n <td colspan=\"6\" class=\"no-data\">\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-inbox\"></i>\n <p>No logs found matching your criteria</p>\n </div>\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </div>\n </div>\n `,\n styles: [`\n .logs-wrapper {\n height: 100%;\n padding: 24px;\n background: var(--mj-bg-surface);\n }\n .card {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n height: 100%;\n }\n\n /* TOOLBAR */\n .logs-toolbar {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n flex-shrink: 0;\n }\n .search-input-wrapper {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1;\n max-width: 400px;\n padding: 6px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n transition: border-color 0.15s, box-shadow 0.15s;\n }\n .search-input-wrapper:focus-within {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n }\n .search-input-wrapper i { color: var(--mj-text-muted); font-size: 12px; }\n .search-input-wrapper input {\n flex: 1; border: none; outline: none;\n background: transparent; font-size: 12px;\n font-family: inherit; color: var(--mj-text-primary);\n }\n .search-input-wrapper input::placeholder { color: var(--mj-text-muted); }\n\n .filter-chip {\n display: inline-flex; align-items: center;\n gap: 4px; padding: 4px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 16px;\n background: var(--mj-bg-surface-card);\n font-size: 11px; font-weight: 500;\n color: var(--mj-text-secondary);\n cursor: pointer; transition: all 0.15s;\n }\n .filter-chip:hover {\n border-color: var(--mj-border-strong);\n background: var(--mj-bg-surface-sunken);\n }\n .filter-chip.active {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n }\n .filter-chip i { font-size: 10px; }\n\n .toolbar-spacer { flex: 1; }\n\n .tb-btn {\n display: inline-flex; align-items: center;\n gap: 6px; padding: 6px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-secondary);\n font-size: 12px; font-weight: 500;\n cursor: pointer; transition: all 0.15s ease;\n font-family: inherit;\n }\n .tb-btn:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-border-strong);\n color: var(--mj-text-primary);\n }\n .tb-btn i { font-size: 12px; }\n\n @keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }\n .spinning { animation: spin 1s linear infinite; }\n\n /* TABLE */\n .table-wrapper { flex: 1; overflow-y: auto; }\n\n .log-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 12px;\n }\n .log-table thead {\n background: var(--mj-bg-surface-sunken);\n position: sticky; top: 0; z-index: 1;\n }\n .log-table th {\n padding: 10px 16px;\n text-align: left;\n font-weight: 700; font-size: 10px;\n text-transform: uppercase; letter-spacing: 0.5px;\n color: var(--mj-text-muted);\n border-bottom: 1px solid var(--mj-border-default);\n white-space: nowrap;\n }\n .log-table td {\n padding: 12px 16px;\n border-bottom: 1px solid var(--mj-border-default);\n color: var(--mj-text-primary);\n vertical-align: middle;\n }\n .log-table tbody tr { transition: background 0.15s; }\n .log-table tbody tr:hover { background: var(--mj-bg-surface-sunken); }\n\n .log-status-badge {\n display: inline-flex; align-items: center;\n gap: 4px; font-size: 11px; font-weight: 600;\n padding: 3px 10px;\n border-radius: 4px;\n }\n .log-status-badge.complete {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n }\n .log-status-badge.failed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n }\n .log-status-badge.pending {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n }\n .log-status-badge.in-progress {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n }\n\n .log-direction {\n display: flex; align-items: center;\n gap: 4px; font-size: 11px;\n color: var(--mj-text-muted);\n }\n .log-direction i { font-size: 10px; }\n .log-direction.sending i { color: var(--mj-brand-primary); }\n .log-direction.receiving i { color: var(--mj-status-success); }\n\n .log-provider-badge {\n display: inline-flex; align-items: center;\n gap: 6px; padding: 3px 10px;\n border-radius: 4px;\n background: var(--mj-bg-surface-sunken);\n font-weight: 500;\n }\n\n .log-error-text {\n color: var(--mj-status-error);\n max-width: 200px;\n overflow: hidden; text-overflow: ellipsis;\n white-space: nowrap; font-size: 11px;\n display: block;\n }\n .no-error { color: var(--mj-text-muted); }\n\n .no-data { padding: 0 !important; }\n .empty-state {\n display: flex; flex-direction: column;\n align-items: center; justify-content: center;\n padding: 48px 0; color: var(--mj-text-muted);\n }\n .empty-state i { font-size: 2rem; margin-bottom: 12px; opacity: 0.5; }\n .empty-state p { margin: 0; font-size: 13px; }\n `]\n})\nexport class CommunicationLogsResourceComponent extends BaseResourceComponent implements OnInit, OnDestroy {\n public logs: MJCommunicationLogEntity[] = [];\n public filteredLogs: MJCommunicationLogEntity[] = [];\n public isLoading = false;\n public statusFilter = '';\n private searchTerm = '';\n\n constructor(private cdr: ChangeDetectorRef) {\n super();\n }\n\n async ngOnInit(): Promise<void> {\n super.ngOnInit();\n await this.loadData();\n this.NotifyLoadComplete();\n }\n\n ngOnDestroy(): void {\n super.ngOnDestroy();\n }\n\n public async loadData(): Promise<void> {\n try {\n this.isLoading = true;\n this.cdr.detectChanges();\n\n const rv = new RunView();\n const result = await rv.RunView<MJCommunicationLogEntity>({\n EntityName: 'MJ: Communication Logs',\n OrderBy: 'MessageDate DESC',\n MaxRows: 200,\n ResultType: 'entity_object'\n });\n\n if (result.Success) {\n this.logs = result.Results;\n this.applyFilter();\n }\n } catch (error) {\n console.error('Error loading logs:', error);\n } finally {\n this.isLoading = false;\n this.cdr.detectChanges();\n }\n }\n\n public onSearch(event: Event): void {\n this.searchTerm = (event.target as HTMLInputElement).value.toLowerCase();\n this.applyFilter();\n }\n\n public onStatusFilter(status: string): void {\n this.statusFilter = status;\n this.applyFilter();\n }\n\n public getStatusClass(status: string): string {\n const s = (status || '').toLowerCase();\n if (s === 'complete') return 'complete';\n if (s === 'failed') return 'failed';\n if (s === 'pending') return 'pending';\n if (s === 'in-progress') return 'in-progress';\n return '';\n }\n\n public getStatusIcon(status: string): string {\n const s = (status || '').toLowerCase();\n if (s === 'complete') return 'fa-solid fa-check';\n if (s === 'failed') return 'fa-solid fa-xmark';\n if (s === 'pending') return 'fa-solid fa-clock';\n if (s === 'in-progress') return 'fa-solid fa-spinner';\n return 'fa-solid fa-circle';\n }\n\n public getProviderIcon(name: string): string {\n if (!name) return 'fa-solid fa-server';\n const n = name.toLowerCase();\n if (n.includes('sendgrid')) return 'fa-solid fa-envelope';\n if (n.includes('twilio')) return 'fa-solid fa-comment-sms';\n if (n.includes('gmail') || n.includes('google')) return 'fa-brands fa-google';\n if (n.includes('microsoft') || n.includes('graph')) return 'fa-brands fa-microsoft';\n return 'fa-solid fa-server';\n }\n\n public getProviderColor(name: string): string {\n if (!name) return 'inherit';\n const n = name.toLowerCase();\n if (n.includes('sendgrid')) return '#1A82E2';\n if (n.includes('twilio')) return '#F22F46';\n if (n.includes('gmail') || n.includes('google')) return '#EA4335';\n if (n.includes('microsoft') || n.includes('graph')) return '#0078D4';\n return 'inherit';\n }\n\n private applyFilter(): void {\n let filtered = this.logs;\n\n if (this.statusFilter) {\n filtered = filtered.filter(l => l.Status === this.statusFilter);\n }\n\n if (this.searchTerm) {\n filtered = filtered.filter(l =>\n l.CommunicationProvider?.toLowerCase().includes(this.searchTerm) ||\n l.CommunicationProviderMessageType?.toLowerCase().includes(this.searchTerm) ||\n l.Status?.toLowerCase().includes(this.searchTerm) ||\n l.ErrorMessage?.toLowerCase().includes(this.searchTerm)\n );\n }\n\n this.filteredLogs = filtered;\n this.cdr.detectChanges();\n }\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n return 'Message Logs';\n }\n\n async GetResourceIconClass(data: ResourceData): Promise<string> {\n return 'fa-solid fa-list-ul';\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"communication-logs-resource.component.js","sourceRoot":"","sources":["../../src/Communication/communication-logs-resource.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';\nimport { ResourceData, MJCommunicationLogEntity } from '@memberjunction/core-entities';\nimport { RegisterClass } from '@memberjunction/global';\nimport { BaseResourceComponent } from '@memberjunction/ng-shared';\nimport { RunView } from '@memberjunction/core';\n@RegisterClass(BaseResourceComponent, 'CommunicationLogsResource')\n@Component({\n standalone: false,\n selector: 'mj-communication-logs-resource',\n template: `\n <div class=\"logs-wrapper\">\n <div class=\"card\">\n <div class=\"logs-toolbar\">\n <div class=\"search-input-wrapper\">\n <i class=\"fa-solid fa-search\"></i>\n <input type=\"text\" placeholder=\"Search messages, providers, recipients...\" (input)=\"onSearch($event)\">\n </div>\n <div class=\"filter-chip\" [class.active]=\"statusFilter === ''\"\n (click)=\"onStatusFilter('')\">\n <i class=\"fa-solid fa-filter\"></i> All\n </div>\n <div class=\"filter-chip\" [class.active]=\"statusFilter === 'Complete'\"\n (click)=\"onStatusFilter('Complete')\">\n <i class=\"fa-solid fa-check-circle\"></i> Sent\n </div>\n <div class=\"filter-chip\" [class.active]=\"statusFilter === 'Failed'\"\n (click)=\"onStatusFilter('Failed')\">\n <i class=\"fa-solid fa-times-circle\"></i> Failed\n </div>\n <div class=\"filter-chip\" [class.active]=\"statusFilter === 'Pending'\"\n (click)=\"onStatusFilter('Pending')\">\n <i class=\"fa-solid fa-clock\"></i> Pending\n </div>\n <div class=\"toolbar-spacer\"></div>\n <button class=\"tb-btn\" (click)=\"loadData()\">\n <i class=\"fa-solid fa-rotate\" [class.spinning]=\"isLoading\"></i> Refresh\n </button>\n </div>\n <div class=\"table-wrapper\">\n <table class=\"log-table\">\n <thead>\n <tr>\n <th>Status</th>\n <th>Direction</th>\n <th>Provider</th>\n <th>Type</th>\n <th>Date</th>\n <th>Error</th>\n </tr>\n </thead>\n <tbody>\n @for (log of filteredLogs; track log) {\n <tr>\n <td>\n <span class=\"log-status-badge\" [ngClass]=\"getStatusClass(log.Status)\">\n <i [class]=\"getStatusIcon(log.Status)\"></i>\n {{log.Status}}\n </span>\n </td>\n <td>\n <span class=\"log-direction\" [ngClass]=\"log.Direction.toLowerCase()\">\n <i [class]=\"log.Direction === 'Sending' ? 'fa-solid fa-arrow-up-right' : 'fa-solid fa-arrow-down-left'\"></i>\n {{log.Direction}}\n </span>\n </td>\n <td>\n <span class=\"log-provider-badge\">\n <i [class]=\"getProviderIcon(log.CommunicationProvider)\" [style.color]=\"getProviderColor(log.CommunicationProvider)\"></i>\n {{log.CommunicationProvider}}\n </span>\n </td>\n <td>{{log.CommunicationProviderMessageType}}</td>\n <td>{{log.MessageDate | date:'medium'}}</td>\n <td>\n @if (log.ErrorMessage) {\n <span class=\"log-error-text\" [title]=\"log.ErrorMessage\">\n {{log.ErrorMessage}}\n </span>\n }\n @if (!log.ErrorMessage) {\n <span class=\"no-error\">—</span>\n }\n </td>\n </tr>\n }\n @if (filteredLogs.length === 0 && !isLoading) {\n <tr>\n <td colspan=\"6\" class=\"no-data\">\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-inbox\"></i>\n <p>No logs found matching your criteria</p>\n </div>\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </div>\n </div>\n `,\n styles: [`\n .logs-wrapper {\n height: 100%;\n padding: 24px;\n background: var(--mj-bg-surface);\n }\n .card {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n height: 100%;\n }\n\n /* TOOLBAR */\n .logs-toolbar {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n flex-shrink: 0;\n }\n .search-input-wrapper {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1;\n max-width: 400px;\n padding: 6px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n transition: border-color 0.15s, box-shadow 0.15s;\n }\n .search-input-wrapper:focus-within {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n }\n .search-input-wrapper i { color: var(--mj-text-muted); font-size: 12px; }\n .search-input-wrapper input {\n flex: 1; border: none; outline: none;\n background: transparent; font-size: 12px;\n font-family: inherit; color: var(--mj-text-primary);\n }\n .search-input-wrapper input::placeholder { color: var(--mj-text-muted); }\n\n .filter-chip {\n display: inline-flex; align-items: center;\n gap: 4px; padding: 4px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 16px;\n background: var(--mj-bg-surface-card);\n font-size: 11px; font-weight: 500;\n color: var(--mj-text-secondary);\n cursor: pointer; transition: all 0.15s;\n }\n .filter-chip:hover {\n border-color: var(--mj-border-strong);\n background: var(--mj-bg-surface-sunken);\n }\n .filter-chip.active {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n }\n .filter-chip i { font-size: 10px; }\n\n .toolbar-spacer { flex: 1; }\n\n .tb-btn {\n display: inline-flex; align-items: center;\n gap: 6px; padding: 6px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-secondary);\n font-size: 12px; font-weight: 500;\n cursor: pointer; transition: all 0.15s ease;\n font-family: inherit;\n }\n .tb-btn:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-border-strong);\n color: var(--mj-text-primary);\n }\n .tb-btn i { font-size: 12px; }\n\n @keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }\n .spinning { animation: spin 1s linear infinite; }\n\n /* TABLE */\n .table-wrapper { flex: 1; overflow-y: auto; }\n\n .log-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 12px;\n }\n .log-table thead {\n background: var(--mj-bg-surface-sunken);\n position: sticky; top: 0; z-index: 1;\n }\n .log-table th {\n padding: 10px 16px;\n text-align: left;\n font-weight: 700; font-size: 10px;\n text-transform: uppercase; letter-spacing: 0.5px;\n color: var(--mj-text-muted);\n border-bottom: 1px solid var(--mj-border-default);\n white-space: nowrap;\n }\n .log-table td {\n padding: 12px 16px;\n border-bottom: 1px solid var(--mj-border-default);\n color: var(--mj-text-primary);\n vertical-align: middle;\n }\n .log-table tbody tr { transition: background 0.15s; }\n .log-table tbody tr:hover { background: var(--mj-bg-surface-sunken); }\n\n .log-status-badge {\n display: inline-flex; align-items: center;\n gap: 4px; font-size: 11px; font-weight: 600;\n padding: 3px 10px;\n border-radius: 4px;\n }\n .log-status-badge.complete {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n }\n .log-status-badge.failed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n }\n .log-status-badge.pending {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n }\n .log-status-badge.in-progress {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n }\n\n .log-direction {\n display: flex; align-items: center;\n gap: 4px; font-size: 11px;\n color: var(--mj-text-muted);\n }\n .log-direction i { font-size: 10px; }\n .log-direction.sending i { color: var(--mj-brand-primary); }\n .log-direction.receiving i { color: var(--mj-status-success); }\n\n .log-provider-badge {\n display: inline-flex; align-items: center;\n gap: 6px; padding: 3px 10px;\n border-radius: 4px;\n background: var(--mj-bg-surface-sunken);\n font-weight: 500;\n }\n\n .log-error-text {\n color: var(--mj-status-error);\n max-width: 200px;\n overflow: hidden; text-overflow: ellipsis;\n white-space: nowrap; font-size: 11px;\n display: block;\n }\n .no-error { color: var(--mj-text-muted); }\n\n .no-data { padding: 0 !important; }\n .empty-state {\n display: flex; flex-direction: column;\n align-items: center; justify-content: center;\n padding: 48px 0; color: var(--mj-text-muted);\n }\n .empty-state i { font-size: 2rem; margin-bottom: 12px; opacity: 0.5; }\n .empty-state p { margin: 0; font-size: 13px; }\n `]\n})\nexport class CommunicationLogsResourceComponent extends BaseResourceComponent implements OnInit, OnDestroy {\n public logs: MJCommunicationLogEntity[] = [];\n public filteredLogs: MJCommunicationLogEntity[] = [];\n public isLoading = false;\n public statusFilter = '';\n private searchTerm = '';\n\n constructor(private cdr: ChangeDetectorRef) {\n super();\n }\n\n async ngOnInit(): Promise<void> {\n super.ngOnInit();\n await this.loadData();\n this.NotifyLoadComplete();\n }\n\n ngOnDestroy(): void {\n super.ngOnDestroy();\n }\n\n public async loadData(): Promise<void> {\n try {\n this.isLoading = true;\n this.cdr.detectChanges();\n\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const result = await rv.RunView<MJCommunicationLogEntity>({\n EntityName: 'MJ: Communication Logs',\n OrderBy: 'MessageDate DESC',\n MaxRows: 200,\n ResultType: 'entity_object'\n });\n\n if (result.Success) {\n this.logs = result.Results;\n this.applyFilter();\n }\n } catch (error) {\n console.error('Error loading logs:', error);\n } finally {\n this.isLoading = false;\n this.cdr.detectChanges();\n }\n }\n\n public onSearch(event: Event): void {\n this.searchTerm = (event.target as HTMLInputElement).value.toLowerCase();\n this.applyFilter();\n }\n\n public onStatusFilter(status: string): void {\n this.statusFilter = status;\n this.applyFilter();\n }\n\n public getStatusClass(status: string): string {\n const s = (status || '').toLowerCase();\n if (s === 'complete') return 'complete';\n if (s === 'failed') return 'failed';\n if (s === 'pending') return 'pending';\n if (s === 'in-progress') return 'in-progress';\n return '';\n }\n\n public getStatusIcon(status: string): string {\n const s = (status || '').toLowerCase();\n if (s === 'complete') return 'fa-solid fa-check';\n if (s === 'failed') return 'fa-solid fa-xmark';\n if (s === 'pending') return 'fa-solid fa-clock';\n if (s === 'in-progress') return 'fa-solid fa-spinner';\n return 'fa-solid fa-circle';\n }\n\n public getProviderIcon(name: string): string {\n if (!name) return 'fa-solid fa-server';\n const n = name.toLowerCase();\n if (n.includes('sendgrid')) return 'fa-solid fa-envelope';\n if (n.includes('twilio')) return 'fa-solid fa-comment-sms';\n if (n.includes('gmail') || n.includes('google')) return 'fa-brands fa-google';\n if (n.includes('microsoft') || n.includes('graph')) return 'fa-brands fa-microsoft';\n return 'fa-solid fa-server';\n }\n\n public getProviderColor(name: string): string {\n if (!name) return 'inherit';\n const n = name.toLowerCase();\n if (n.includes('sendgrid')) return '#1A82E2';\n if (n.includes('twilio')) return '#F22F46';\n if (n.includes('gmail') || n.includes('google')) return '#EA4335';\n if (n.includes('microsoft') || n.includes('graph')) return '#0078D4';\n return 'inherit';\n }\n\n private applyFilter(): void {\n let filtered = this.logs;\n\n if (this.statusFilter) {\n filtered = filtered.filter(l => l.Status === this.statusFilter);\n }\n\n if (this.searchTerm) {\n filtered = filtered.filter(l =>\n l.CommunicationProvider?.toLowerCase().includes(this.searchTerm) ||\n l.CommunicationProviderMessageType?.toLowerCase().includes(this.searchTerm) ||\n l.Status?.toLowerCase().includes(this.searchTerm) ||\n l.ErrorMessage?.toLowerCase().includes(this.searchTerm)\n );\n }\n\n this.filteredLogs = filtered;\n this.cdr.detectChanges();\n }\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n return 'Message Logs';\n }\n\n async GetResourceIconClass(data: ResourceData): Promise<string> {\n return 'fa-solid fa-list-ul';\n }\n}\n"]}
|
|
@@ -168,7 +168,7 @@ let CommunicationMonitorResourceComponent = class CommunicationMonitorResourceCo
|
|
|
168
168
|
try {
|
|
169
169
|
this.isLoading = true;
|
|
170
170
|
this.cdr.detectChanges();
|
|
171
|
-
const rv =
|
|
171
|
+
const rv = RunView.FromMetadataProvider(this.ProviderToUse);
|
|
172
172
|
const yesterday = new Date();
|
|
173
173
|
yesterday.setDate(yesterday.getDate() - 1);
|
|
174
174
|
const yesterdayIso = yesterday.toISOString();
|