@acorex-platform/module-integration-management-client 0.0.30 → 0.0.32

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.
Files changed (17) hide show
  1. package/fesm2022/{acorex-platform-module-integration-management-client-integration-oauth-callback-page.component-XhloXUsZ.mjs → acorex-platform-module-integration-management-client-integration-oauth-callback-page.component-CZu5mKUA.mjs} +4 -4
  2. package/fesm2022/{acorex-platform-module-integration-management-client-integration-oauth-callback-page.component-XhloXUsZ.mjs.map → acorex-platform-module-integration-management-client-integration-oauth-callback-page.component-CZu5mKUA.mjs.map} +1 -1
  3. package/fesm2022/acorex-platform-module-integration-management-client-integration-ref-display.service-CP818xou.mjs +126 -0
  4. package/fesm2022/acorex-platform-module-integration-management-client-integration-ref-display.service-CP818xou.mjs.map +1 -0
  5. package/fesm2022/acorex-platform-module-integration-management-client-integration-ref-filter-widget-edit.component-DeED5cU5.mjs +164 -0
  6. package/fesm2022/acorex-platform-module-integration-management-client-integration-ref-filter-widget-edit.component-DeED5cU5.mjs.map +1 -0
  7. package/fesm2022/acorex-platform-module-integration-management-client-integration-ref-page.component-D9hdpnQq.mjs +148 -0
  8. package/fesm2022/acorex-platform-module-integration-management-client-integration-ref-page.component-D9hdpnQq.mjs.map +1 -0
  9. package/fesm2022/acorex-platform-module-integration-management-client-integration-ref-widget-column.component-CPLhmHOe.mjs +137 -0
  10. package/fesm2022/acorex-platform-module-integration-management-client-integration-ref-widget-column.component-CPLhmHOe.mjs.map +1 -0
  11. package/fesm2022/acorex-platform-module-integration-management-client-integration-ref-widget-view.component-BRpGpWHZ.mjs +46 -0
  12. package/fesm2022/acorex-platform-module-integration-management-client-integration-ref-widget-view.component-BRpGpWHZ.mjs.map +1 -0
  13. package/fesm2022/{acorex-platform-module-integration-management-client-integrations-page.component-Q-SHidYA.mjs → acorex-platform-module-integration-management-client-integrations-page.component-iH0DqEak.mjs} +3 -3
  14. package/fesm2022/{acorex-platform-module-integration-management-client-integrations-page.component-Q-SHidYA.mjs.map → acorex-platform-module-integration-management-client-integrations-page.component-iH0DqEak.mjs.map} +1 -1
  15. package/fesm2022/acorex-platform-module-integration-management-client.mjs +235 -4
  16. package/fesm2022/acorex-platform-module-integration-management-client.mjs.map +1 -1
  17. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"acorex-platform-module-integration-management-client-integrations-page.component-Q-SHidYA.mjs","sources":["../../../../libs/modules/integration-management/client/src/lib/features/integrations-page/integrations-page.component.ts","../../../../libs/modules/integration-management/client/src/lib/features/integrations-page/integrations-page.component.html"],"sourcesContent":["//#region ----- Imports -----\n\nimport { AXBadgeModule } from '@acorex/components/badge';\nimport { AXButtonModule } from '@acorex/components/button';\nimport { AXCheckBoxModule } from '@acorex/components/check-box';\nimport { AXDropdownButtonModule } from '@acorex/components/dropdown-button';\nimport { AXDecoratorModule } from '@acorex/components/decorators';\nimport { AXLabelModule } from '@acorex/components/label';\nimport { AXSkeletonModule } from '@acorex/components/skeleton';\nimport { AXSwitchModule } from '@acorex/components/switch';\nimport { AXTooltipModule } from '@acorex/components/tooltip';\nimport { AXTranslationModule } from '@acorex/core/translation';\nimport { AXValueChangedEvent } from '@acorex/cdk/common';\nimport { AXPLogoComponent, AXPDeviceService } from '@acorex-platform/framework-client/core';\nimport {\n AXPStateMessageComponent,\n AXPThemeLayoutBlockComponent,\n AXPThemeLayoutStartSideComponent,\n} from '@acorex-platform/framework-client/layout/components';\nimport {\n AXPIntegrationConnectionActionsService,\n type IntegrationConnectionPanelData,\n type ResolvedIntegrationSettingsBadge,\n} from '@acorex-platform/framework-client/layout/widgets';\nimport {\n AXPPageLayoutBase,\n AXPPageLayoutBaseComponent,\n AXPPageLayoutComponent,\n} from '@acorex-platform/framework-client/layout/views';\nimport { AXPQueryService } from '@acorex-platform/framework-client/runtime';\nimport {\n AXP_INTEGRATION_CONNECTION_SCOPE,\n AXP_INTEGRATION_CONNECTION_STATUS,\n runtimeQueryCollectionData,\n type AXPIntegrationDomainListItemDto,\n type AXPIntegrationProviderListItemDto,\n type AXPSafeIntegrationConnectionDto,\n} from '@acorex-platform/framework-shared/core';\nimport { AsyncPipe } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n inject,\n OnInit,\n signal,\n ViewEncapsulation,\n} from '@angular/core';\nimport { FormsModule } from '@angular/forms';\n\n//#endregion\n\n//#region ----- Types -----\n\ntype IntegrationDomainSection = {\n domain: AXPIntegrationDomainListItemDto;\n providers: AXPIntegrationProviderListItemDto[];\n};\n\ntype IntegrationOverviewStats = {\n connected: number;\n error: number;\n disabled: number;\n notConnected: number;\n};\n\nconst ERROR_CONNECTION_STATUSES: ReadonlySet<string> = new Set([\n AXP_INTEGRATION_CONNECTION_STATUS.Error,\n AXP_INTEGRATION_CONNECTION_STATUS.Invalid,\n AXP_INTEGRATION_CONNECTION_STATUS.Expired,\n AXP_INTEGRATION_CONNECTION_STATUS.RefreshRequired,\n AXP_INTEGRATION_CONNECTION_STATUS.PendingAuthorization,\n AXP_INTEGRATION_CONNECTION_STATUS.Revoked,\n]);\n\n//#endregion\n\n//#region ----- Constants -----\n\nconst PAGE_I18N = '@integration-management:pages.integrations';\nconst PANEL_I18N = '@platform-layout-widgets:widgets.integration-connections-panel';\nconst TENANT_SCOPE = AXP_INTEGRATION_CONNECTION_SCOPE.Tenant;\nconst SKELETON_SECTION_COUNT = 2;\nconst SKELETON_CARDS_PER_SECTION = 4;\n\n//#endregion\n\n//#region ----- Component -----\n\n@Component({\n selector: 'axm-integrations-page',\n templateUrl: './integrations-page.component.html',\n styleUrls: ['./integrations-page.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n providers: [{ provide: AXPPageLayoutBase, useExisting: AXMIntegrationsPageComponent }],\n imports: [\n AsyncPipe,\n FormsModule,\n AXBadgeModule,\n AXButtonModule,\n AXCheckBoxModule,\n AXDropdownButtonModule,\n AXDecoratorModule,\n AXLabelModule,\n AXSkeletonModule,\n AXSwitchModule,\n AXTooltipModule,\n AXTranslationModule,\n AXPLogoComponent,\n AXPPageLayoutComponent,\n AXPStateMessageComponent,\n AXPThemeLayoutBlockComponent,\n AXPThemeLayoutStartSideComponent,\n ],\n})\nexport class AXMIntegrationsPageComponent extends AXPPageLayoutBaseComponent implements OnInit {\n //#region ----- Services & Dependencies -----\n\n private readonly queryService = inject(AXPQueryService);\n private readonly actionsService = inject(AXPIntegrationConnectionActionsService);\n protected readonly deviceService = inject(AXPDeviceService);\n\n //#endregion\n\n //#region ----- Constants -----\n\n protected readonly PAGE_I18N = PAGE_I18N;\n protected readonly PANEL_I18N = PANEL_I18N;\n\n //#endregion\n\n //#region ----- State Signals -----\n\n protected readonly loading = signal(true);\n protected readonly pendingAction = signal(false);\n protected readonly domainSections = signal<IntegrationDomainSection[]>([]);\n protected readonly selectedDomainIds = signal<ReadonlySet<string>>(new Set());\n protected readonly panelData = signal<IntegrationConnectionPanelData>({\n providers: [],\n connections: [],\n providerBadges: {},\n connectAvailabilityByProvider: {},\n });\n protected readonly skeletonSectionPlaceholders = Array.from(\n { length: SKELETON_SECTION_COUNT },\n (_, index) => index,\n );\n protected readonly skeletonCardPlaceholders = Array.from(\n { length: SKELETON_CARDS_PER_SECTION },\n (_, index) => index,\n );\n\n //#endregion\n\n //#region ----- Sidebar Computed -----\n\n protected readonly overviewStats = computed((): IntegrationOverviewStats => {\n const providers = this.domainSections().flatMap((section) => section.providers);\n const connections = this.panelData().connections;\n\n let connected = 0;\n let error = 0;\n let disabled = 0;\n let notConnected = 0;\n\n for (const provider of providers) {\n if (this.actionsService.isConnectionEnabled(connections, provider.id, TENANT_SCOPE)) {\n connected += 1;\n continue;\n }\n\n if (this.actionsService.hasEstablishedConnection(connections, provider.id, TENANT_SCOPE)) {\n if (this.isProviderInError(connections, provider.id)) {\n error += 1;\n } else {\n disabled += 1;\n }\n continue;\n }\n\n notConnected += 1;\n }\n\n return { connected, error, disabled, notConnected };\n });\n\n protected readonly isAllDomainsSelected = computed(() => {\n const sections = this.domainSections();\n const selected = this.selectedDomainIds();\n if (!sections.length) {\n return true;\n }\n return sections.every((section) => selected.has(section.domain.id));\n });\n\n protected readonly filteredDomainSections = computed(() => {\n const selected = this.selectedDomainIds();\n if (!selected.size) {\n return [];\n }\n return this.domainSections().filter((section) => selected.has(section.domain.id));\n });\n\n protected readonly visibleDomainSections = computed(() => {\n if (!this.deviceService.isLarge()) {\n return this.domainSections();\n }\n return this.filteredDomainSections();\n });\n\n //#endregion\n\n //#region ----- Lifecycle -----\n\n override async ngOnInit(): Promise<void> {\n super.ngOnInit();\n await this.loadPage();\n }\n\n override async getPageTitle(): Promise<string> {\n return this.translateService.translateAsync(`${PAGE_I18N}.title`);\n }\n\n override async getPageDescription(): Promise<string> {\n return this.translateService.translateAsync(`${PAGE_I18N}.description`);\n }\n\n //#endregion\n\n //#region ----- Connection Helpers -----\n\n protected getConnections(providerId: string): AXPSafeIntegrationConnectionDto[] {\n return this.actionsService.getConnections(\n this.panelData().connections,\n providerId,\n TENANT_SCOPE,\n );\n }\n\n protected getConnection(providerId: string): AXPSafeIntegrationConnectionDto | undefined {\n return this.actionsService.getConnection(\n this.panelData().connections,\n providerId,\n TENANT_SCOPE,\n );\n }\n\n protected hasEstablishedConnection(providerId: string): boolean {\n return this.actionsService.hasEstablishedConnection(\n this.panelData().connections,\n providerId,\n TENANT_SCOPE,\n );\n }\n\n protected isConnectionEnabled(providerId: string): boolean {\n return this.actionsService.isConnectionEnabled(\n this.panelData().connections,\n providerId,\n TENANT_SCOPE,\n );\n }\n\n protected isEstablishedConnection(connection: AXPSafeIntegrationConnectionDto): boolean {\n return this.actionsService.isEstablishedConnection(connection);\n }\n\n protected isEnabledConnection(connection: AXPSafeIntegrationConnectionDto): boolean {\n return this.actionsService.isEnabledConnection(connection);\n }\n\n protected getProviderConnectionSummary(providerId: string): {\n connected: number;\n total: number;\n } {\n const connections = this.getConnections(providerId);\n return {\n connected: connections.filter((connection) => this.isEstablishedConnection(connection)).length,\n total: connections.length,\n };\n }\n\n protected getMultiConnectionStatusBadgeColor(\n providerId: string,\n ): 'success' | 'warning' | 'secondary' {\n const { connected, total } = this.getProviderConnectionSummary(providerId);\n if (total === 0 || connected === 0) {\n return 'secondary';\n }\n if (connected === total) {\n return 'success';\n }\n return 'warning';\n }\n\n protected supportsConnect(provider: AXPIntegrationProviderListItemDto): boolean {\n return this.actionsService.supportsConnect(provider);\n }\n\n protected supportsConfigure(\n provider: AXPIntegrationProviderListItemDto,\n connection?: AXPSafeIntegrationConnectionDto,\n ): boolean {\n return this.actionsService.supportsConfigure(\n provider,\n this.panelData().connections,\n TENANT_SCOPE,\n connection,\n );\n }\n\n protected isConnectDisabled(providerId: string): boolean {\n return this.actionsService.isConnectDisabled(\n this.panelData().connectAvailabilityByProvider,\n providerId,\n );\n }\n\n protected connectDisabledBadgeKey(providerId: string): string | undefined {\n return (\n this.panelData().connectAvailabilityByProvider[providerId]?.disabledBadgeKey\n ?? this.panelData().providers.find((provider) => provider.id === providerId)?.connectDisabledBadgeKey\n );\n }\n\n protected connectDisabledMessageKey(providerId: string): string | undefined {\n return (\n this.panelData().connectAvailabilityByProvider[providerId]?.disabledMessageKey\n ?? this.panelData().providers.find((provider) => provider.id === providerId)?.connectDisabledMessageKey\n );\n }\n\n protected getProviderBadges(providerId: string): ResolvedIntegrationSettingsBadge[] {\n return this.panelData().providerBadges[providerId] ?? [];\n }\n\n protected getManageActions(\n provider: AXPIntegrationProviderListItemDto,\n ): NonNullable<AXPIntegrationProviderListItemDto['manageActions']> {\n return this.actionsService.getManageActions(provider, TENANT_SCOPE);\n }\n\n //#endregion\n\n //#region ----- Sidebar Filters -----\n\n protected showSidebarPanel(): boolean {\n return this.deviceService.isLarge();\n }\n\n protected isDomainFilterSelected(domainId: string): boolean {\n return this.selectedDomainIds().has(domainId);\n }\n\n protected handleAllDomainsFilterChange(event: AXValueChangedEvent<boolean>): void {\n if (event.value) {\n this.selectAllDomainFilters();\n return;\n }\n this.selectedDomainIds.set(new Set());\n }\n\n protected handleSelectAllDomainFilters(): void {\n this.selectAllDomainFilters();\n }\n\n protected handleDomainFilterChange(domainId: string, event: AXValueChangedEvent<boolean>): void {\n const next = new Set(this.selectedDomainIds());\n if (event.value) {\n next.add(domainId);\n } else {\n next.delete(domainId);\n }\n this.selectedDomainIds.set(next);\n }\n\n private selectAllDomainFilters(): void {\n this.selectedDomainIds.set(new Set(this.domainSections().map((section) => section.domain.id)));\n }\n\n //#endregion\n\n //#region ----- Event Handlers -----\n\n protected async handleConnect(\n provider: AXPIntegrationProviderListItemDto,\n connection?: AXPSafeIntegrationConnectionDto,\n ): Promise<void> {\n if (this.pendingAction()) {\n return;\n }\n\n this.pendingAction.set(true);\n try {\n const outcome = await this.actionsService.connect(provider, {\n connectionScope: TENANT_SCOPE,\n connectAvailabilityByProvider: this.panelData().connectAvailabilityByProvider,\n ...(connection?.id ? { connectionId: connection.id } : {}),\n });\n if (outcome === 'reload') {\n await this.loadPage(false);\n }\n } finally {\n this.actionsService.releasePendingAction(() => this.pendingAction.set(false));\n }\n }\n\n protected async handleAddConnection(provider: AXPIntegrationProviderListItemDto): Promise<void> {\n await this.handleConnect(provider);\n }\n\n protected async handleConfigure(\n provider: AXPIntegrationProviderListItemDto,\n connection?: AXPSafeIntegrationConnectionDto,\n ): Promise<void> {\n await this.handleConnect(provider, connection ?? this.getConnection(provider.id));\n }\n\n protected async handleManageAction(\n provider: AXPIntegrationProviderListItemDto,\n action: NonNullable<AXPIntegrationProviderListItemDto['manageActions']>[number],\n connection?: AXPSafeIntegrationConnectionDto,\n ): Promise<void> {\n if (this.pendingAction()) {\n return;\n }\n\n this.pendingAction.set(true);\n try {\n const success = await this.actionsService.runManageAction(\n provider,\n action,\n TENANT_SCOPE,\n connection?.id,\n );\n if (success) {\n await this.loadPage(false);\n }\n } finally {\n this.actionsService.releasePendingAction(() => this.pendingAction.set(false));\n }\n }\n\n protected async handleDisconnect(\n provider: AXPIntegrationProviderListItemDto,\n connection?: AXPSafeIntegrationConnectionDto,\n ): Promise<void> {\n if (this.pendingAction()) {\n return;\n }\n\n const target = connection ?? this.getConnection(provider.id);\n if (!target) {\n return;\n }\n\n this.pendingAction.set(true);\n try {\n const success = await this.actionsService.disconnect(provider, target);\n if (success) {\n await this.loadPage(false);\n }\n } finally {\n this.actionsService.releasePendingAction(() => this.pendingAction.set(false));\n }\n }\n\n protected async handleRemove(\n provider: AXPIntegrationProviderListItemDto,\n connection: AXPSafeIntegrationConnectionDto,\n ): Promise<void> {\n if (this.pendingAction()) {\n return;\n }\n\n this.pendingAction.set(true);\n try {\n const success = await this.actionsService.remove(provider, connection);\n if (success) {\n await this.loadPage(false);\n }\n } finally {\n this.actionsService.releasePendingAction(() => this.pendingAction.set(false));\n }\n }\n\n protected async handleToggleEnabled(\n provider: AXPIntegrationProviderListItemDto,\n enabled: boolean,\n connection?: AXPSafeIntegrationConnectionDto,\n ): Promise<void> {\n if (this.pendingAction()) {\n return;\n }\n\n const target = connection ?? this.getConnection(provider.id);\n if (!target || !this.isEstablishedConnection(target)) {\n return;\n }\n\n if (this.isEnabledConnection(target) === enabled) {\n return;\n }\n\n this.pendingAction.set(true);\n try {\n const success = await this.actionsService.setConnectionEnabled(target.id, enabled);\n if (success) {\n await this.loadPage(false);\n }\n } finally {\n this.actionsService.releasePendingAction(() => this.pendingAction.set(false));\n }\n }\n\n //#endregion\n\n //#region ----- Data Loading -----\n\n private async loadPage(showBlockingLoader = true): Promise<void> {\n if (showBlockingLoader) {\n this.loading.set(true);\n }\n\n try {\n await this.actionsService.waitForSettingsLoaded();\n\n const [domainsResult, panelData] = await Promise.all([\n this.queryService.fetch<{ includeProviderCount?: boolean }, AXPIntegrationDomainListItemDto>(\n 'IntegrationManagement.Domain:List',\n { includeProviderCount: false },\n ),\n this.actionsService.loadPanelData({ connectionScope: TENANT_SCOPE }),\n ]);\n const domains = runtimeQueryCollectionData(domainsResult)?.items ?? [];\n\n const sections: IntegrationDomainSection[] = [];\n\n for (const domain of [...domains].sort(\n (left, right) => (left.sortOrder ?? 100) - (right.sortOrder ?? 100),\n )) {\n const providers = panelData.providers.filter(\n (provider) =>\n provider.domainId === domain.id && provider.connectionScopes.includes(TENANT_SCOPE),\n );\n\n if (!providers.length) {\n continue;\n }\n\n sections.push({ domain, providers });\n }\n\n this.domainSections.set(sections);\n this.selectAllDomainFilters();\n this.panelData.set(panelData);\n this.recompute();\n } finally {\n if (showBlockingLoader) {\n this.loading.set(false);\n }\n }\n }\n\n //#endregion\n\n //#region ----- Overview Helpers -----\n\n private isProviderInError(\n connections: AXPSafeIntegrationConnectionDto[],\n providerId: string,\n ): boolean {\n const providerConnections = this.actionsService.getConnections(\n connections,\n providerId,\n TENANT_SCOPE,\n );\n\n return providerConnections.some((connection) => {\n if (connection.isRevoked || ERROR_CONNECTION_STATUSES.has(connection.status)) {\n return true;\n }\n\n return Boolean(\n String(connection.lastErrorCode ?? '').trim()\n || String(connection.lastErrorMessage ?? '').trim(),\n );\n });\n }\n\n //#endregion\n}\n\n//#endregion\n","<axp-page-layout>\n <!-- ----- Page start side: overview stats and category filters (large screens) ----- -->\n @if (showSidebarPanel()) {\n <axp-layout-start-side class=\"h-full\">\n <axp-layout-content class=\"axm-integrations-page__sidebar\">\n @if (loading()) {\n <!-- ----- Sidebar skeleton while domains and providers load ----- -->\n <section class=\"axm-integrations-page__sidebar-section\">\n <ax-skeleton [animated]=\"true\" class=\"axm-integrations-page__skeleton-sidebar-title\"></ax-skeleton>\n <div class=\"axm-integrations-page__sidebar-section-body\">\n @for (row of [0, 1, 2, 3]; track row) {\n <ax-skeleton [animated]=\"true\" class=\"axm-integrations-page__skeleton-sidebar-row\"></ax-skeleton>\n }\n </div>\n </section>\n <section class=\"axm-integrations-page__sidebar-section\">\n <ax-skeleton [animated]=\"true\" class=\"axm-integrations-page__skeleton-sidebar-title\"></ax-skeleton>\n <div class=\"axm-integrations-page__sidebar-section-body\">\n @for (row of [0, 1, 2, 3, 4]; track row) {\n <ax-skeleton [animated]=\"true\" class=\"axm-integrations-page__skeleton-sidebar-row\"></ax-skeleton>\n }\n </div>\n </section>\n } @else {\n <section class=\"axm-integrations-page__sidebar-section\">\n <h3 class=\"axm-integrations-page__sidebar-section-title\">\n {{ (PAGE_I18N + '.sidebar.overview.title' | translate | async) ?? '' }}\n </h3>\n <ul class=\"axm-integrations-page__overview-list\">\n <li class=\"axm-integrations-page__overview-item\">\n <span class=\"axm-integrations-page__overview-label\">\n <ax-icon icon=\"fa-light fa-circle-check\"></ax-icon>\n <span>{{ (PAGE_I18N + '.sidebar.overview.connected' | translate | async) ?? '' }}</span>\n </span>\n <span class=\"axm-integrations-page__overview-count\">{{ overviewStats().connected }}</span>\n </li>\n <li class=\"axm-integrations-page__overview-item\">\n <span class=\"axm-integrations-page__overview-label\">\n <ax-icon icon=\"fa-light fa-shield-exclamation\"></ax-icon>\n <span>{{ (PAGE_I18N + '.sidebar.overview.error' | translate | async) ?? '' }}</span>\n </span>\n <span class=\"axm-integrations-page__overview-count\" [class.--danger]=\"overviewStats().error > 0\">{{ overviewStats().error }}</span>\n </li>\n <li class=\"axm-integrations-page__overview-item\">\n <span class=\"axm-integrations-page__overview-label\">\n <ax-icon icon=\"fa-light fa-toggle-off\"></ax-icon>\n <span>{{ (PAGE_I18N + '.sidebar.overview.disabled' | translate | async) ?? '' }}</span>\n </span>\n <span class=\"axm-integrations-page__overview-count\">{{ overviewStats().disabled }}</span>\n </li>\n <li class=\"axm-integrations-page__overview-item\">\n <span class=\"axm-integrations-page__overview-label\">\n <ax-icon icon=\"fa-light fa-plug\"></ax-icon>\n <span>{{ (PAGE_I18N + '.sidebar.overview.not-connected' | translate | async) ?? '' }}</span>\n </span>\n <span class=\"axm-integrations-page__overview-count\">{{ overviewStats().notConnected }}</span>\n </li>\n </ul>\n </section>\n\n <section class=\"axm-integrations-page__sidebar-section\">\n <h3 class=\"axm-integrations-page__sidebar-section-title\">\n {{ (PAGE_I18N + '.sidebar.categories.title' | translate | async) ?? '' }}\n </h3>\n <ul class=\"axm-integrations-page__category-list\">\n <li class=\"axm-integrations-page__category-item\">\n <ax-check-box\n class=\"axm-integrations-page__category-checkbox\"\n [ngModel]=\"isAllDomainsSelected()\"\n (onValueChanged)=\"handleAllDomainsFilterChange($event)\"\n >\n <ax-label>{{ (PAGE_I18N + '.sidebar.categories.all' | translate | async) ?? '' }}</ax-label>\n </ax-check-box>\n </li>\n @for (section of domainSections(); track section.domain.id) {\n <li class=\"axm-integrations-page__category-item\">\n <ax-check-box\n class=\"axm-integrations-page__category-checkbox\"\n [ngModel]=\"isDomainFilterSelected(section.domain.id)\"\n (onValueChanged)=\"handleDomainFilterChange(section.domain.id, $event)\"\n >\n <ax-label>{{ section.domain.displayName | translate | async }}</ax-label>\n </ax-check-box>\n </li>\n }\n </ul>\n </section>\n }\n </axp-layout-content>\n </axp-layout-start-side>\n }\n\n <axp-page-content>\n @if (loading()) {\n <!-- ----- Skeleton placeholders while domains and providers are fetched ----- -->\n <div class=\"flex w-full flex-col gap-8\">\n @for (sectionIndex of skeletonSectionPlaceholders; track sectionIndex) {\n <section class=\"flex flex-col gap-4\">\n <div class=\"flex flex-col gap-2\">\n <ax-skeleton [animated]=\"true\" class=\"axm-integrations-page__skeleton-section-title\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"axm-integrations-page__skeleton-section-description\"></ax-skeleton>\n </div>\n\n <div class=\"grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-[repeat(auto-fill,minmax(16rem,18rem))] lg:justify-start\">\n @for (cardIndex of skeletonCardPlaceholders; track cardIndex) {\n <div class=\"axm-integrations-page__skeleton-card\">\n <div class=\"flex items-start justify-between gap-3\">\n <ax-skeleton [animated]=\"true\" class=\"axm-integrations-page__skeleton-icon\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"axm-integrations-page__skeleton-status-badge\"></ax-skeleton>\n </div>\n\n <div class=\"flex flex-col gap-2\">\n <ax-skeleton [animated]=\"true\" class=\"axm-integrations-page__skeleton-title\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"axm-integrations-page__skeleton-description\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"axm-integrations-page__skeleton-description --short\"></ax-skeleton>\n </div>\n\n <div class=\"axm-integrations-page__skeleton-footer\">\n <ax-skeleton [animated]=\"true\" class=\"axm-integrations-page__skeleton-action\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"axm-integrations-page__skeleton-switch\"></ax-skeleton>\n </div>\n </div>\n }\n </div>\n </section>\n }\n </div>\n } @else if (!visibleDomainSections().length) {\n <!-- ----- Empty state when all category filters are cleared on large screens ----- -->\n <axp-state-message mode=\"empty\" icon=\"fa-light fa-filter\" [title]=\"PAGE_I18N + '.sidebar.empty-filter.title'\" [description]=\"PAGE_I18N + '.sidebar.empty-filter.description'\">\n <ax-button slot=\"actions\" look=\"solid\" color=\"primary\" [text]=\"(PAGE_I18N + '.sidebar.empty-filter.action' | translate | async) ?? ''\" (onClick)=\"handleSelectAllDomainFilters()\"></ax-button>\n </axp-state-message>\n } @else {\n <!-- ----- Domain sections with tenant provider cards ----- -->\n <div class=\"flex w-full flex-col gap-8\">\n @for (section of visibleDomainSections(); track section.domain.id) {\n <section class=\"flex flex-col gap-4\">\n <div class=\"flex flex-col gap-1\">\n <h2 class=\"text-lg font-semibold\">\n {{ section.domain.displayName | translate | async }}\n </h2>\n @if (section.domain.description) {\n <p class=\"text-sm text-muted\">\n {{ section.domain.description | translate | async }}\n </p>\n }\n </div>\n\n <div class=\"grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-[repeat(auto-fill,minmax(18rem,24rem))] lg:justify-start\">\n @for (provider of section.providers; track provider.id) {\n <article class=\"flex h-full w-full flex-col gap-3 rounded-xl border border-surface bg-lighter-surface p-4 shadow-sm transition-shadow hover:shadow-md\">\n <div class=\"flex items-start justify-between gap-3\">\n <div class=\"flex size-14 shrink-0 items-center justify-center rounded-xl border border-surface bg-transparent\">\n @if (provider.logoKey) {\n <axp-logo [logoKey]=\"provider.logoKey\" appearance=\"colored\" [size]=\"32\" />\n } @else if (provider.icon) {\n <ax-icon class=\"text-2xl\">\n <i [class]=\"provider.icon\"></i>\n </ax-icon>\n }\n </div>\n\n <div class=\"ax-sm\">\n @if (provider.allowMultipleConnections) {\n @if (getProviderConnectionSummary(provider.id); as summary) {\n @if (summary.total > 0) {\n <ax-badge\n look=\"twotone\"\n [color]=\"getMultiConnectionStatusBadgeColor(provider.id)\"\n [text]=\"(PANEL_I18N + '.status.connected-count' | translate: { params: { connected: summary.connected, total: summary.total } } | async) ?? ''\"\n ></ax-badge>\n } @else {\n <ax-badge look=\"twotone\" color=\"secondary\" [text]=\"(PANEL_I18N + '.status.not-connected' | translate | async) ?? ''\"></ax-badge>\n }\n }\n } @else if (hasEstablishedConnection(provider.id)) {\n @if (isConnectionEnabled(provider.id)) {\n <ax-badge look=\"twotone\" color=\"success\" [text]=\"(PANEL_I18N + '.status.connected' | translate | async) ?? ''\"></ax-badge>\n } @else {\n <ax-badge look=\"twotone\" color=\"warning\" [text]=\"(PANEL_I18N + '.status.disabled' | translate | async) ?? ''\"></ax-badge>\n }\n } @else {\n <ax-badge look=\"twotone\" color=\"secondary\" [text]=\"(PANEL_I18N + '.status.not-connected' | translate | async) ?? ''\"></ax-badge>\n }\n </div>\n </div>\n\n <div class=\"flex min-w-0 flex-1 flex-col gap-2\">\n <div class=\"flex flex-wrap items-center gap-2 font-medium\">\n <span>{{ provider.displayName | translate | async }}</span>\n @if (isConnectDisabled(provider.id) && connectDisabledBadgeKey(provider.id); as badgeKey) {\n <span\n class=\"inline-flex cursor-help\"\n [axTooltip]=\"(connectDisabledMessageKey(provider.id) | translate | async) ?? ''\"\n axTooltipPlacement=\"top\"\n [attr.aria-label]=\"(connectDisabledMessageKey(provider.id) | translate | async) ?? ''\"\n >\n <ax-badge size=\"sm\" look=\"twotone\" color=\"warning\" [text]=\"(badgeKey | translate | async) ?? ''\"></ax-badge>\n </span>\n }\n </div>\n\n @if (provider.description) {\n <p class=\"text-sm text-muted\">\n {{ provider.description | translate | async }}\n </p>\n }\n\n @if (getProviderBadges(provider.id); as badges) {\n @if (badges.length > 0) {\n <div class=\"flex flex-wrap items-center gap-1\">\n @for (badge of badges; track badge.text) {\n <ax-badge size=\"sm\" look=\"twotone\" [color]=\"badge.color\" [text]=\"badge.text\"></ax-badge>\n }\n </div>\n }\n }\n\n <!-- ----- Multi-connection provider: list each connection with status and actions ----- -->\n @if (provider.allowMultipleConnections) {\n <div class=\"mt-1 flex flex-col gap-2\">\n @for (connection of getConnections(provider.id); track connection.id) {\n <div class=\"flex flex-col gap-2 rounded-lg border border-surface bg-lighter-surface p-3\">\n <!-- ----- Row 1: connection identity + status badge ----- -->\n <div class=\"flex items-start justify-between gap-2\">\n <div class=\"min-w-0 flex-1\">\n <div class=\"truncate text-sm font-medium\">{{ connection.displayName }}</div>\n @if (connection.instanceUrl) {\n <div class=\"truncate text-xs text-muted\">{{ connection.instanceUrl }}</div>\n }\n </div>\n <div class=\"ax-sm shrink-0\">\n @if (isEstablishedConnection(connection)) {\n @if (isEnabledConnection(connection)) {\n <ax-badge look=\"twotone\" color=\"success\" [text]=\"(PANEL_I18N + '.status.connected' | translate | async) ?? ''\"></ax-badge>\n } @else {\n <ax-badge look=\"twotone\" color=\"warning\" [text]=\"(PANEL_I18N + '.status.disabled' | translate | async) ?? ''\"></ax-badge>\n }\n } @else {\n <ax-badge look=\"twotone\" color=\"secondary\" [text]=\"(PANEL_I18N + '.status.not-connected' | translate | async) ?? ''\"></ax-badge>\n }\n </div>\n </div>\n\n <!-- ----- Row 2: actions + enable toggle ----- -->\n <div class=\"flex flex-nowrap items-center justify-between gap-2\">\n <div class=\"flex shrink-0 flex-nowrap items-center gap-2\">\n @if (isEstablishedConnection(connection)) {\n <ax-dropdown-button\n size=\"sm\"\n look=\"outline\"\n [mode]=\"'dropdown'\"\n type=\"button\"\n [disabled]=\"pendingAction()\"\n [text]=\"(PANEL_I18N + '.actions.manage' | translate | async) ?? ''\"\n >\n <ax-button-item-list>\n @if (supportsConfigure(provider, connection)) {\n <ax-button-item\n [text]=\"(PANEL_I18N + '.actions.reconfigure' | translate | async) ?? ''\"\n [disabled]=\"pendingAction() || isConnectDisabled(provider.id)\"\n (onClick)=\"handleConfigure(provider, connection)\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-gear\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n }\n <ax-button-item\n [text]=\"(PANEL_I18N + '.actions.disconnect' | translate | async) ?? ''\"\n color=\"danger\"\n [disabled]=\"pendingAction()\"\n (onClick)=\"handleDisconnect(provider, connection)\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-link-slash\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n <ax-button-item\n [text]=\"(PANEL_I18N + '.actions.remove' | translate | async) ?? ''\"\n color=\"danger\"\n [disabled]=\"pendingAction()\"\n (onClick)=\"handleRemove(provider, connection)\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-trash\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n </ax-button-item-list>\n </ax-dropdown-button>\n } @else if (supportsConnect(provider)) {\n <ax-button\n size=\"sm\"\n look=\"solid\"\n type=\"button\"\n [disabled]=\"pendingAction() || isConnectDisabled(provider.id)\"\n [text]=\"(PANEL_I18N + '.actions.connect' | translate | async) ?? ''\"\n (onClick)=\"handleConnect(provider, connection)\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-plug\"></ax-icon>\n </ax-prefix>\n </ax-button>\n <ax-button\n size=\"sm\"\n look=\"outline\"\n color=\"danger\"\n type=\"button\"\n [disabled]=\"pendingAction()\"\n [text]=\"(PANEL_I18N + '.actions.remove' | translate | async) ?? ''\"\n (onClick)=\"handleRemove(provider, connection)\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-trash\"></ax-icon>\n </ax-prefix>\n </ax-button>\n } @else {\n <ax-button\n size=\"sm\"\n look=\"outline\"\n color=\"danger\"\n type=\"button\"\n [disabled]=\"pendingAction()\"\n [text]=\"(PANEL_I18N + '.actions.remove' | translate | async) ?? ''\"\n (onClick)=\"handleRemove(provider, connection)\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-trash\"></ax-icon>\n </ax-prefix>\n </ax-button>\n }\n </div>\n\n <ax-switch\n class=\"shrink-0\"\n [ngModel]=\"isEnabledConnection(connection)\"\n [disabled]=\"pendingAction() || !isEstablishedConnection(connection)\"\n (ngModelChange)=\"handleToggleEnabled(provider, $event, connection)\"\n ></ax-switch>\n </div>\n </div>\n }\n </div>\n }\n </div>\n\n <!-- ----- Card footer: single-connection manage/connect, or add connection for multi ----- -->\n <div class=\"mt-auto flex items-center justify-between gap-3 border-t border-surface pt-4\">\n @if (provider.allowMultipleConnections) {\n @if (supportsConnect(provider)) {\n <ax-button\n size=\"sm\"\n look=\"outline\"\n type=\"button\"\n [disabled]=\"pendingAction() || isConnectDisabled(provider.id)\"\n [text]=\"(PANEL_I18N + '.actions.add-connection' | translate | async) ?? ''\"\n (onClick)=\"handleAddConnection(provider)\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-plus\"></ax-icon>\n </ax-prefix>\n </ax-button>\n } @else {\n <span></span>\n }\n <span></span>\n } @else if (hasEstablishedConnection(provider.id)) {\n <ax-dropdown-button size=\"sm\" [mode]=\"'dropdown'\" type=\"button\" [disabled]=\"pendingAction()\" [text]=\"(PANEL_I18N + '.actions.manage' | translate | async) ?? ''\">\n <ax-button-item-list>\n @if (supportsConfigure(provider)) {\n <ax-button-item [text]=\"(PANEL_I18N + '.actions.reconfigure' | translate | async) ?? ''\" [disabled]=\"pendingAction() || isConnectDisabled(provider.id)\" (onClick)=\"handleConfigure(provider)\">\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-gear\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n }\n @for (action of getManageActions(provider); track action.commandKey) {\n <ax-button-item [text]=\"(action.titleKey | translate | async) ?? ''\" [color]=\"action.color\" [disabled]=\"pendingAction()\" (onClick)=\"handleManageAction(provider, action)\">\n @if (action.icon) {\n <ax-prefix>\n <ax-icon [icon]=\"action.icon\"></ax-icon>\n </ax-prefix>\n }\n </ax-button-item>\n }\n <ax-button-item [text]=\"(PANEL_I18N + '.actions.disconnect' | translate | async) ?? ''\" color=\"danger\" [disabled]=\"pendingAction()\" (onClick)=\"handleDisconnect(provider)\">\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-link-slash\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n </ax-button-item-list>\n </ax-dropdown-button>\n <ax-switch [ngModel]=\"isConnectionEnabled(provider.id)\" [disabled]=\"pendingAction() || !hasEstablishedConnection(provider.id)\" (ngModelChange)=\"handleToggleEnabled(provider, $event)\"></ax-switch>\n } @else if (supportsConnect(provider)) {\n <ax-button size=\"sm\" look=\"solid\" type=\"button\" [disabled]=\"pendingAction() || isConnectDisabled(provider.id)\" [text]=\"(PANEL_I18N + '.actions.connect' | translate | async) ?? ''\" (onClick)=\"handleConnect(provider)\">\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-plug\"></ax-icon>\n </ax-prefix>\n </ax-button>\n <ax-switch [ngModel]=\"isConnectionEnabled(provider.id)\" [disabled]=\"pendingAction() || !hasEstablishedConnection(provider.id)\" (ngModelChange)=\"handleToggleEnabled(provider, $event)\"></ax-switch>\n } @else {\n <span></span>\n <ax-switch [ngModel]=\"isConnectionEnabled(provider.id)\" [disabled]=\"pendingAction() || !hasEstablishedConnection(provider.id)\" (ngModelChange)=\"handleToggleEnabled(provider, $event)\"></ax-switch>\n }\n </div>\n </article>\n }\n </div>\n </section>\n }\n </div>\n }\n </axp-page-content>\n</axp-page-layout>\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"acorex-platform-module-integration-management-client-integrations-page.component-iH0DqEak.mjs","sources":["../../../../libs/modules/integration-management/client/src/lib/features/integrations-page/integrations-page.component.ts","../../../../libs/modules/integration-management/client/src/lib/features/integrations-page/integrations-page.component.html"],"sourcesContent":["//#region ----- Imports -----\n\nimport { AXBadgeModule } from '@acorex/components/badge';\nimport { AXButtonModule } from '@acorex/components/button';\nimport { AXCheckBoxModule } from '@acorex/components/check-box';\nimport { AXDropdownButtonModule } from '@acorex/components/dropdown-button';\nimport { AXDecoratorModule } from '@acorex/components/decorators';\nimport { AXLabelModule } from '@acorex/components/label';\nimport { AXSkeletonModule } from '@acorex/components/skeleton';\nimport { AXSwitchModule } from '@acorex/components/switch';\nimport { AXTooltipModule } from '@acorex/components/tooltip';\nimport { AXTranslationModule } from '@acorex/core/translation';\nimport { AXValueChangedEvent } from '@acorex/cdk/common';\nimport { AXPLogoComponent, AXPDeviceService } from '@acorex-platform/framework-client/core';\nimport {\n AXPStateMessageComponent,\n AXPThemeLayoutBlockComponent,\n AXPThemeLayoutStartSideComponent,\n} from '@acorex-platform/framework-client/layout/components';\nimport {\n AXPIntegrationConnectionActionsService,\n type IntegrationConnectionPanelData,\n type ResolvedIntegrationSettingsBadge,\n} from '@acorex-platform/framework-client/layout/widgets';\nimport {\n AXPPageLayoutBase,\n AXPPageLayoutBaseComponent,\n AXPPageLayoutComponent,\n} from '@acorex-platform/framework-client/layout/views';\nimport { AXPQueryService } from '@acorex-platform/framework-client/runtime';\nimport {\n AXP_INTEGRATION_CONNECTION_SCOPE,\n AXP_INTEGRATION_CONNECTION_STATUS,\n runtimeQueryCollectionData,\n type AXPIntegrationDomainListItemDto,\n type AXPIntegrationProviderListItemDto,\n type AXPSafeIntegrationConnectionDto,\n} from '@acorex-platform/framework-shared/core';\nimport { AsyncPipe } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n inject,\n OnInit,\n signal,\n ViewEncapsulation,\n} from '@angular/core';\nimport { FormsModule } from '@angular/forms';\n\n//#endregion\n\n//#region ----- Types -----\n\ntype IntegrationDomainSection = {\n domain: AXPIntegrationDomainListItemDto;\n providers: AXPIntegrationProviderListItemDto[];\n};\n\ntype IntegrationOverviewStats = {\n connected: number;\n error: number;\n disabled: number;\n notConnected: number;\n};\n\nconst ERROR_CONNECTION_STATUSES: ReadonlySet<string> = new Set([\n AXP_INTEGRATION_CONNECTION_STATUS.Error,\n AXP_INTEGRATION_CONNECTION_STATUS.Invalid,\n AXP_INTEGRATION_CONNECTION_STATUS.Expired,\n AXP_INTEGRATION_CONNECTION_STATUS.RefreshRequired,\n AXP_INTEGRATION_CONNECTION_STATUS.PendingAuthorization,\n AXP_INTEGRATION_CONNECTION_STATUS.Revoked,\n]);\n\n//#endregion\n\n//#region ----- Constants -----\n\nconst PAGE_I18N = '@integration-management:pages.integrations';\nconst PANEL_I18N = '@platform-layout-widgets:widgets.integration-connections-panel';\nconst TENANT_SCOPE = AXP_INTEGRATION_CONNECTION_SCOPE.Tenant;\nconst SKELETON_SECTION_COUNT = 2;\nconst SKELETON_CARDS_PER_SECTION = 4;\n\n//#endregion\n\n//#region ----- Component -----\n\n@Component({\n selector: 'axm-integrations-page',\n templateUrl: './integrations-page.component.html',\n styleUrls: ['./integrations-page.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n providers: [{ provide: AXPPageLayoutBase, useExisting: AXMIntegrationsPageComponent }],\n imports: [\n AsyncPipe,\n FormsModule,\n AXBadgeModule,\n AXButtonModule,\n AXCheckBoxModule,\n AXDropdownButtonModule,\n AXDecoratorModule,\n AXLabelModule,\n AXSkeletonModule,\n AXSwitchModule,\n AXTooltipModule,\n AXTranslationModule,\n AXPLogoComponent,\n AXPPageLayoutComponent,\n AXPStateMessageComponent,\n AXPThemeLayoutBlockComponent,\n AXPThemeLayoutStartSideComponent,\n ],\n})\nexport class AXMIntegrationsPageComponent extends AXPPageLayoutBaseComponent implements OnInit {\n //#region ----- Services & Dependencies -----\n\n private readonly queryService = inject(AXPQueryService);\n private readonly actionsService = inject(AXPIntegrationConnectionActionsService);\n protected readonly deviceService = inject(AXPDeviceService);\n\n //#endregion\n\n //#region ----- Constants -----\n\n protected readonly PAGE_I18N = PAGE_I18N;\n protected readonly PANEL_I18N = PANEL_I18N;\n\n //#endregion\n\n //#region ----- State Signals -----\n\n protected readonly loading = signal(true);\n protected readonly pendingAction = signal(false);\n protected readonly domainSections = signal<IntegrationDomainSection[]>([]);\n protected readonly selectedDomainIds = signal<ReadonlySet<string>>(new Set());\n protected readonly panelData = signal<IntegrationConnectionPanelData>({\n providers: [],\n connections: [],\n providerBadges: {},\n connectAvailabilityByProvider: {},\n });\n protected readonly skeletonSectionPlaceholders = Array.from(\n { length: SKELETON_SECTION_COUNT },\n (_, index) => index,\n );\n protected readonly skeletonCardPlaceholders = Array.from(\n { length: SKELETON_CARDS_PER_SECTION },\n (_, index) => index,\n );\n\n //#endregion\n\n //#region ----- Sidebar Computed -----\n\n protected readonly overviewStats = computed((): IntegrationOverviewStats => {\n const providers = this.domainSections().flatMap((section) => section.providers);\n const connections = this.panelData().connections;\n\n let connected = 0;\n let error = 0;\n let disabled = 0;\n let notConnected = 0;\n\n for (const provider of providers) {\n if (this.actionsService.isConnectionEnabled(connections, provider.id, TENANT_SCOPE)) {\n connected += 1;\n continue;\n }\n\n if (this.actionsService.hasEstablishedConnection(connections, provider.id, TENANT_SCOPE)) {\n if (this.isProviderInError(connections, provider.id)) {\n error += 1;\n } else {\n disabled += 1;\n }\n continue;\n }\n\n notConnected += 1;\n }\n\n return { connected, error, disabled, notConnected };\n });\n\n protected readonly isAllDomainsSelected = computed(() => {\n const sections = this.domainSections();\n const selected = this.selectedDomainIds();\n if (!sections.length) {\n return true;\n }\n return sections.every((section) => selected.has(section.domain.id));\n });\n\n protected readonly filteredDomainSections = computed(() => {\n const selected = this.selectedDomainIds();\n if (!selected.size) {\n return [];\n }\n return this.domainSections().filter((section) => selected.has(section.domain.id));\n });\n\n protected readonly visibleDomainSections = computed(() => {\n if (!this.deviceService.isLarge()) {\n return this.domainSections();\n }\n return this.filteredDomainSections();\n });\n\n //#endregion\n\n //#region ----- Lifecycle -----\n\n override async ngOnInit(): Promise<void> {\n super.ngOnInit();\n await this.loadPage();\n }\n\n override async getPageTitle(): Promise<string> {\n return this.translateService.translateAsync(`${PAGE_I18N}.title`);\n }\n\n override async getPageDescription(): Promise<string> {\n return this.translateService.translateAsync(`${PAGE_I18N}.description`);\n }\n\n //#endregion\n\n //#region ----- Connection Helpers -----\n\n protected getConnections(providerId: string): AXPSafeIntegrationConnectionDto[] {\n return this.actionsService.getConnections(\n this.panelData().connections,\n providerId,\n TENANT_SCOPE,\n );\n }\n\n protected getConnection(providerId: string): AXPSafeIntegrationConnectionDto | undefined {\n return this.actionsService.getConnection(\n this.panelData().connections,\n providerId,\n TENANT_SCOPE,\n );\n }\n\n protected hasEstablishedConnection(providerId: string): boolean {\n return this.actionsService.hasEstablishedConnection(\n this.panelData().connections,\n providerId,\n TENANT_SCOPE,\n );\n }\n\n protected isConnectionEnabled(providerId: string): boolean {\n return this.actionsService.isConnectionEnabled(\n this.panelData().connections,\n providerId,\n TENANT_SCOPE,\n );\n }\n\n protected isEstablishedConnection(connection: AXPSafeIntegrationConnectionDto): boolean {\n return this.actionsService.isEstablishedConnection(connection);\n }\n\n protected isEnabledConnection(connection: AXPSafeIntegrationConnectionDto): boolean {\n return this.actionsService.isEnabledConnection(connection);\n }\n\n protected getProviderConnectionSummary(providerId: string): {\n connected: number;\n total: number;\n } {\n const connections = this.getConnections(providerId);\n return {\n connected: connections.filter((connection) => this.isEstablishedConnection(connection)).length,\n total: connections.length,\n };\n }\n\n protected getMultiConnectionStatusBadgeColor(\n providerId: string,\n ): 'success' | 'warning' | 'secondary' {\n const { connected, total } = this.getProviderConnectionSummary(providerId);\n if (total === 0 || connected === 0) {\n return 'secondary';\n }\n if (connected === total) {\n return 'success';\n }\n return 'warning';\n }\n\n protected supportsConnect(provider: AXPIntegrationProviderListItemDto): boolean {\n return this.actionsService.supportsConnect(provider);\n }\n\n protected supportsConfigure(\n provider: AXPIntegrationProviderListItemDto,\n connection?: AXPSafeIntegrationConnectionDto,\n ): boolean {\n return this.actionsService.supportsConfigure(\n provider,\n this.panelData().connections,\n TENANT_SCOPE,\n connection,\n );\n }\n\n protected isConnectDisabled(providerId: string): boolean {\n return this.actionsService.isConnectDisabled(\n this.panelData().connectAvailabilityByProvider,\n providerId,\n );\n }\n\n protected connectDisabledBadgeKey(providerId: string): string | undefined {\n return (\n this.panelData().connectAvailabilityByProvider[providerId]?.disabledBadgeKey\n ?? this.panelData().providers.find((provider) => provider.id === providerId)?.connectDisabledBadgeKey\n );\n }\n\n protected connectDisabledMessageKey(providerId: string): string | undefined {\n return (\n this.panelData().connectAvailabilityByProvider[providerId]?.disabledMessageKey\n ?? this.panelData().providers.find((provider) => provider.id === providerId)?.connectDisabledMessageKey\n );\n }\n\n protected getProviderBadges(providerId: string): ResolvedIntegrationSettingsBadge[] {\n return this.panelData().providerBadges[providerId] ?? [];\n }\n\n protected getManageActions(\n provider: AXPIntegrationProviderListItemDto,\n ): NonNullable<AXPIntegrationProviderListItemDto['manageActions']> {\n return this.actionsService.getManageActions(provider, TENANT_SCOPE);\n }\n\n //#endregion\n\n //#region ----- Sidebar Filters -----\n\n protected showSidebarPanel(): boolean {\n return this.deviceService.isLarge();\n }\n\n protected isDomainFilterSelected(domainId: string): boolean {\n return this.selectedDomainIds().has(domainId);\n }\n\n protected handleAllDomainsFilterChange(event: AXValueChangedEvent<boolean>): void {\n if (event.value) {\n this.selectAllDomainFilters();\n return;\n }\n this.selectedDomainIds.set(new Set());\n }\n\n protected handleSelectAllDomainFilters(): void {\n this.selectAllDomainFilters();\n }\n\n protected handleDomainFilterChange(domainId: string, event: AXValueChangedEvent<boolean>): void {\n const next = new Set(this.selectedDomainIds());\n if (event.value) {\n next.add(domainId);\n } else {\n next.delete(domainId);\n }\n this.selectedDomainIds.set(next);\n }\n\n private selectAllDomainFilters(): void {\n this.selectedDomainIds.set(new Set(this.domainSections().map((section) => section.domain.id)));\n }\n\n //#endregion\n\n //#region ----- Event Handlers -----\n\n protected async handleConnect(\n provider: AXPIntegrationProviderListItemDto,\n connection?: AXPSafeIntegrationConnectionDto,\n ): Promise<void> {\n if (this.pendingAction()) {\n return;\n }\n\n this.pendingAction.set(true);\n try {\n const outcome = await this.actionsService.connect(provider, {\n connectionScope: TENANT_SCOPE,\n connectAvailabilityByProvider: this.panelData().connectAvailabilityByProvider,\n ...(connection?.id ? { connectionId: connection.id } : {}),\n });\n if (outcome === 'reload') {\n await this.loadPage(false);\n }\n } finally {\n this.actionsService.releasePendingAction(() => this.pendingAction.set(false));\n }\n }\n\n protected async handleAddConnection(provider: AXPIntegrationProviderListItemDto): Promise<void> {\n await this.handleConnect(provider);\n }\n\n protected async handleConfigure(\n provider: AXPIntegrationProviderListItemDto,\n connection?: AXPSafeIntegrationConnectionDto,\n ): Promise<void> {\n await this.handleConnect(provider, connection ?? this.getConnection(provider.id));\n }\n\n protected async handleManageAction(\n provider: AXPIntegrationProviderListItemDto,\n action: NonNullable<AXPIntegrationProviderListItemDto['manageActions']>[number],\n connection?: AXPSafeIntegrationConnectionDto,\n ): Promise<void> {\n if (this.pendingAction()) {\n return;\n }\n\n this.pendingAction.set(true);\n try {\n const success = await this.actionsService.runManageAction(\n provider,\n action,\n TENANT_SCOPE,\n connection?.id,\n );\n if (success) {\n await this.loadPage(false);\n }\n } finally {\n this.actionsService.releasePendingAction(() => this.pendingAction.set(false));\n }\n }\n\n protected async handleDisconnect(\n provider: AXPIntegrationProviderListItemDto,\n connection?: AXPSafeIntegrationConnectionDto,\n ): Promise<void> {\n if (this.pendingAction()) {\n return;\n }\n\n const target = connection ?? this.getConnection(provider.id);\n if (!target) {\n return;\n }\n\n this.pendingAction.set(true);\n try {\n const success = await this.actionsService.disconnect(provider, target);\n if (success) {\n await this.loadPage(false);\n }\n } finally {\n this.actionsService.releasePendingAction(() => this.pendingAction.set(false));\n }\n }\n\n protected async handleRemove(\n provider: AXPIntegrationProviderListItemDto,\n connection: AXPSafeIntegrationConnectionDto,\n ): Promise<void> {\n if (this.pendingAction()) {\n return;\n }\n\n this.pendingAction.set(true);\n try {\n const success = await this.actionsService.remove(provider, connection);\n if (success) {\n await this.loadPage(false);\n }\n } finally {\n this.actionsService.releasePendingAction(() => this.pendingAction.set(false));\n }\n }\n\n protected async handleToggleEnabled(\n provider: AXPIntegrationProviderListItemDto,\n enabled: boolean,\n connection?: AXPSafeIntegrationConnectionDto,\n ): Promise<void> {\n if (this.pendingAction()) {\n return;\n }\n\n const target = connection ?? this.getConnection(provider.id);\n if (!target || !this.isEstablishedConnection(target)) {\n return;\n }\n\n if (this.isEnabledConnection(target) === enabled) {\n return;\n }\n\n this.pendingAction.set(true);\n try {\n const success = await this.actionsService.setConnectionEnabled(target.id, enabled);\n if (success) {\n await this.loadPage(false);\n }\n } finally {\n this.actionsService.releasePendingAction(() => this.pendingAction.set(false));\n }\n }\n\n //#endregion\n\n //#region ----- Data Loading -----\n\n private async loadPage(showBlockingLoader = true): Promise<void> {\n if (showBlockingLoader) {\n this.loading.set(true);\n }\n\n try {\n await this.actionsService.waitForSettingsLoaded();\n\n const [domainsResult, panelData] = await Promise.all([\n this.queryService.fetch<{ includeProviderCount?: boolean }, AXPIntegrationDomainListItemDto>(\n 'IntegrationManagement.Domain:List',\n { includeProviderCount: false },\n ),\n this.actionsService.loadPanelData({ connectionScope: TENANT_SCOPE }),\n ]);\n const domains = runtimeQueryCollectionData(domainsResult)?.items ?? [];\n\n const sections: IntegrationDomainSection[] = [];\n\n for (const domain of [...domains].sort(\n (left, right) => (left.sortOrder ?? 100) - (right.sortOrder ?? 100),\n )) {\n const providers = panelData.providers.filter(\n (provider) =>\n provider.domainId === domain.id && provider.connectionScopes.includes(TENANT_SCOPE),\n );\n\n if (!providers.length) {\n continue;\n }\n\n sections.push({ domain, providers });\n }\n\n this.domainSections.set(sections);\n this.selectAllDomainFilters();\n this.panelData.set(panelData);\n this.recompute();\n } finally {\n if (showBlockingLoader) {\n this.loading.set(false);\n }\n }\n }\n\n //#endregion\n\n //#region ----- Overview Helpers -----\n\n private isProviderInError(\n connections: AXPSafeIntegrationConnectionDto[],\n providerId: string,\n ): boolean {\n const providerConnections = this.actionsService.getConnections(\n connections,\n providerId,\n TENANT_SCOPE,\n );\n\n return providerConnections.some((connection) => {\n if (connection.isRevoked || ERROR_CONNECTION_STATUSES.has(connection.status)) {\n return true;\n }\n\n return Boolean(\n String(connection.lastErrorCode ?? '').trim()\n || String(connection.lastErrorMessage ?? '').trim(),\n );\n });\n }\n\n //#endregion\n}\n\n//#endregion\n","<axp-page-layout>\n <!-- ----- Page start side: overview stats and category filters (large screens) ----- -->\n @if (showSidebarPanel()) {\n <axp-layout-start-side class=\"h-full\">\n <axp-layout-content class=\"axm-integrations-page__sidebar\">\n @if (loading()) {\n <!-- ----- Sidebar skeleton while domains and providers load ----- -->\n <section class=\"axm-integrations-page__sidebar-section\">\n <ax-skeleton [animated]=\"true\" class=\"axm-integrations-page__skeleton-sidebar-title\"></ax-skeleton>\n <div class=\"axm-integrations-page__sidebar-section-body\">\n @for (row of [0, 1, 2, 3]; track row) {\n <ax-skeleton [animated]=\"true\" class=\"axm-integrations-page__skeleton-sidebar-row\"></ax-skeleton>\n }\n </div>\n </section>\n <section class=\"axm-integrations-page__sidebar-section\">\n <ax-skeleton [animated]=\"true\" class=\"axm-integrations-page__skeleton-sidebar-title\"></ax-skeleton>\n <div class=\"axm-integrations-page__sidebar-section-body\">\n @for (row of [0, 1, 2, 3, 4]; track row) {\n <ax-skeleton [animated]=\"true\" class=\"axm-integrations-page__skeleton-sidebar-row\"></ax-skeleton>\n }\n </div>\n </section>\n } @else {\n <section class=\"axm-integrations-page__sidebar-section\">\n <h3 class=\"axm-integrations-page__sidebar-section-title\">\n {{ (PAGE_I18N + '.sidebar.overview.title' | translate | async) ?? '' }}\n </h3>\n <ul class=\"axm-integrations-page__overview-list\">\n <li class=\"axm-integrations-page__overview-item\">\n <span class=\"axm-integrations-page__overview-label\">\n <ax-icon icon=\"fa-light fa-circle-check\"></ax-icon>\n <span>{{ (PAGE_I18N + '.sidebar.overview.connected' | translate | async) ?? '' }}</span>\n </span>\n <span class=\"axm-integrations-page__overview-count\">{{ overviewStats().connected }}</span>\n </li>\n <li class=\"axm-integrations-page__overview-item\">\n <span class=\"axm-integrations-page__overview-label\">\n <ax-icon icon=\"fa-light fa-shield-exclamation\"></ax-icon>\n <span>{{ (PAGE_I18N + '.sidebar.overview.error' | translate | async) ?? '' }}</span>\n </span>\n <span class=\"axm-integrations-page__overview-count\" [class.--danger]=\"overviewStats().error > 0\">{{ overviewStats().error }}</span>\n </li>\n <li class=\"axm-integrations-page__overview-item\">\n <span class=\"axm-integrations-page__overview-label\">\n <ax-icon icon=\"fa-light fa-toggle-off\"></ax-icon>\n <span>{{ (PAGE_I18N + '.sidebar.overview.disabled' | translate | async) ?? '' }}</span>\n </span>\n <span class=\"axm-integrations-page__overview-count\">{{ overviewStats().disabled }}</span>\n </li>\n <li class=\"axm-integrations-page__overview-item\">\n <span class=\"axm-integrations-page__overview-label\">\n <ax-icon icon=\"fa-light fa-plug\"></ax-icon>\n <span>{{ (PAGE_I18N + '.sidebar.overview.not-connected' | translate | async) ?? '' }}</span>\n </span>\n <span class=\"axm-integrations-page__overview-count\">{{ overviewStats().notConnected }}</span>\n </li>\n </ul>\n </section>\n\n <section class=\"axm-integrations-page__sidebar-section\">\n <h3 class=\"axm-integrations-page__sidebar-section-title\">\n {{ (PAGE_I18N + '.sidebar.categories.title' | translate | async) ?? '' }}\n </h3>\n <ul class=\"axm-integrations-page__category-list\">\n <li class=\"axm-integrations-page__category-item\">\n <ax-check-box\n class=\"axm-integrations-page__category-checkbox\"\n [ngModel]=\"isAllDomainsSelected()\"\n (onValueChanged)=\"handleAllDomainsFilterChange($event)\"\n >\n <ax-label>{{ (PAGE_I18N + '.sidebar.categories.all' | translate | async) ?? '' }}</ax-label>\n </ax-check-box>\n </li>\n @for (section of domainSections(); track section.domain.id) {\n <li class=\"axm-integrations-page__category-item\">\n <ax-check-box\n class=\"axm-integrations-page__category-checkbox\"\n [ngModel]=\"isDomainFilterSelected(section.domain.id)\"\n (onValueChanged)=\"handleDomainFilterChange(section.domain.id, $event)\"\n >\n <ax-label>{{ section.domain.displayName | translate | async }}</ax-label>\n </ax-check-box>\n </li>\n }\n </ul>\n </section>\n }\n </axp-layout-content>\n </axp-layout-start-side>\n }\n\n <axp-page-content>\n @if (loading()) {\n <!-- ----- Skeleton placeholders while domains and providers are fetched ----- -->\n <div class=\"flex w-full flex-col gap-8\">\n @for (sectionIndex of skeletonSectionPlaceholders; track sectionIndex) {\n <section class=\"flex flex-col gap-4\">\n <div class=\"flex flex-col gap-2\">\n <ax-skeleton [animated]=\"true\" class=\"axm-integrations-page__skeleton-section-title\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"axm-integrations-page__skeleton-section-description\"></ax-skeleton>\n </div>\n\n <div class=\"grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-[repeat(auto-fill,minmax(16rem,18rem))] lg:justify-start\">\n @for (cardIndex of skeletonCardPlaceholders; track cardIndex) {\n <div class=\"axm-integrations-page__skeleton-card\">\n <div class=\"flex items-start justify-between gap-3\">\n <ax-skeleton [animated]=\"true\" class=\"axm-integrations-page__skeleton-icon\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"axm-integrations-page__skeleton-status-badge\"></ax-skeleton>\n </div>\n\n <div class=\"flex flex-col gap-2\">\n <ax-skeleton [animated]=\"true\" class=\"axm-integrations-page__skeleton-title\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"axm-integrations-page__skeleton-description\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"axm-integrations-page__skeleton-description --short\"></ax-skeleton>\n </div>\n\n <div class=\"axm-integrations-page__skeleton-footer\">\n <ax-skeleton [animated]=\"true\" class=\"axm-integrations-page__skeleton-action\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"axm-integrations-page__skeleton-switch\"></ax-skeleton>\n </div>\n </div>\n }\n </div>\n </section>\n }\n </div>\n } @else if (!visibleDomainSections().length) {\n <!-- ----- Empty state when all category filters are cleared on large screens ----- -->\n <axp-state-message mode=\"empty\" icon=\"fa-light fa-filter\" [title]=\"PAGE_I18N + '.sidebar.empty-filter.title'\" [description]=\"PAGE_I18N + '.sidebar.empty-filter.description'\">\n <ax-button slot=\"actions\" look=\"solid\" color=\"primary\" [text]=\"(PAGE_I18N + '.sidebar.empty-filter.action' | translate | async) ?? ''\" (onClick)=\"handleSelectAllDomainFilters()\"></ax-button>\n </axp-state-message>\n } @else {\n <!-- ----- Domain sections with tenant provider cards ----- -->\n <div class=\"flex w-full flex-col gap-8\">\n @for (section of visibleDomainSections(); track section.domain.id) {\n <section class=\"flex flex-col gap-4\">\n <div class=\"flex flex-col gap-1\">\n <h2 class=\"text-lg font-semibold\">\n {{ section.domain.displayName | translate | async }}\n </h2>\n @if (section.domain.description) {\n <p class=\"text-sm text-muted\">\n {{ section.domain.description | translate | async }}\n </p>\n }\n </div>\n\n <div class=\"grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-[repeat(auto-fill,minmax(18rem,24rem))] lg:justify-start\">\n @for (provider of section.providers; track provider.id) {\n <article class=\"flex h-full w-full flex-col gap-3 rounded-xl border border-surface bg-lighter-surface p-4 shadow-sm transition-shadow hover:shadow-md\">\n <div class=\"flex items-start justify-between gap-3\">\n <div class=\"flex size-14 shrink-0 items-center justify-center rounded-xl border border-surface bg-transparent\">\n @if (provider.logoKey) {\n <axp-logo [logoKey]=\"provider.logoKey\" appearance=\"colored\" [size]=\"32\" />\n } @else if (provider.icon) {\n <ax-icon class=\"text-2xl\">\n <i [class]=\"provider.icon\"></i>\n </ax-icon>\n }\n </div>\n\n <div class=\"ax-sm\">\n @if (provider.allowMultipleConnections) {\n @if (getProviderConnectionSummary(provider.id); as summary) {\n @if (summary.total > 0) {\n <ax-badge\n look=\"twotone\"\n [color]=\"getMultiConnectionStatusBadgeColor(provider.id)\"\n [text]=\"(PANEL_I18N + '.status.connected-count' | translate: { params: { connected: summary.connected, total: summary.total } } | async) ?? ''\"\n ></ax-badge>\n } @else {\n <ax-badge look=\"twotone\" color=\"secondary\" [text]=\"(PANEL_I18N + '.status.not-connected' | translate | async) ?? ''\"></ax-badge>\n }\n }\n } @else if (hasEstablishedConnection(provider.id)) {\n @if (isConnectionEnabled(provider.id)) {\n <ax-badge look=\"twotone\" color=\"success\" [text]=\"(PANEL_I18N + '.status.connected' | translate | async) ?? ''\"></ax-badge>\n } @else {\n <ax-badge look=\"twotone\" color=\"warning\" [text]=\"(PANEL_I18N + '.status.disabled' | translate | async) ?? ''\"></ax-badge>\n }\n } @else {\n <ax-badge look=\"twotone\" color=\"secondary\" [text]=\"(PANEL_I18N + '.status.not-connected' | translate | async) ?? ''\"></ax-badge>\n }\n </div>\n </div>\n\n <div class=\"flex min-w-0 flex-1 flex-col gap-2\">\n <div class=\"flex flex-wrap items-center gap-2 font-medium\">\n <span>{{ provider.displayName | translate | async }}</span>\n @if (isConnectDisabled(provider.id) && connectDisabledBadgeKey(provider.id); as badgeKey) {\n <span\n class=\"inline-flex cursor-help\"\n [axTooltip]=\"(connectDisabledMessageKey(provider.id) | translate | async) ?? ''\"\n axTooltipPlacement=\"top\"\n [attr.aria-label]=\"(connectDisabledMessageKey(provider.id) | translate | async) ?? ''\"\n >\n <ax-badge size=\"sm\" look=\"twotone\" color=\"warning\" [text]=\"(badgeKey | translate | async) ?? ''\"></ax-badge>\n </span>\n }\n </div>\n\n @if (provider.description) {\n <p class=\"text-sm text-muted\">\n {{ provider.description | translate | async }}\n </p>\n }\n\n @if (getProviderBadges(provider.id); as badges) {\n @if (badges.length > 0) {\n <div class=\"flex flex-wrap items-center gap-1\">\n @for (badge of badges; track badge.text) {\n <ax-badge size=\"sm\" look=\"twotone\" [color]=\"badge.color\" [text]=\"badge.text\"></ax-badge>\n }\n </div>\n }\n }\n\n <!-- ----- Multi-connection provider: list each connection with status and actions ----- -->\n @if (provider.allowMultipleConnections) {\n <div class=\"mt-1 flex flex-col gap-2\">\n @for (connection of getConnections(provider.id); track connection.id) {\n <div class=\"flex flex-col gap-2 rounded-lg border border-surface bg-lighter-surface p-3\">\n <!-- ----- Row 1: connection identity + status badge ----- -->\n <div class=\"flex items-start justify-between gap-2\">\n <div class=\"min-w-0 flex-1\">\n <div class=\"truncate text-sm font-medium\">{{ connection.displayName }}</div>\n @if (connection.instanceUrl) {\n <div class=\"truncate text-xs text-muted\">{{ connection.instanceUrl }}</div>\n }\n </div>\n <div class=\"ax-sm shrink-0\">\n @if (isEstablishedConnection(connection)) {\n @if (isEnabledConnection(connection)) {\n <ax-badge look=\"twotone\" color=\"success\" [text]=\"(PANEL_I18N + '.status.connected' | translate | async) ?? ''\"></ax-badge>\n } @else {\n <ax-badge look=\"twotone\" color=\"warning\" [text]=\"(PANEL_I18N + '.status.disabled' | translate | async) ?? ''\"></ax-badge>\n }\n } @else {\n <ax-badge look=\"twotone\" color=\"secondary\" [text]=\"(PANEL_I18N + '.status.not-connected' | translate | async) ?? ''\"></ax-badge>\n }\n </div>\n </div>\n\n <!-- ----- Row 2: actions + enable toggle ----- -->\n <div class=\"flex flex-nowrap items-center justify-between gap-2\">\n <div class=\"flex shrink-0 flex-nowrap items-center gap-2\">\n @if (isEstablishedConnection(connection)) {\n <ax-dropdown-button\n size=\"sm\"\n look=\"outline\"\n [mode]=\"'dropdown'\"\n type=\"button\"\n [disabled]=\"pendingAction()\"\n [text]=\"(PANEL_I18N + '.actions.manage' | translate | async) ?? ''\"\n >\n <ax-button-item-list>\n @if (supportsConfigure(provider, connection)) {\n <ax-button-item\n [text]=\"(PANEL_I18N + '.actions.reconfigure' | translate | async) ?? ''\"\n [disabled]=\"pendingAction() || isConnectDisabled(provider.id)\"\n (onClick)=\"handleConfigure(provider, connection)\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-gear\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n }\n <ax-button-item\n [text]=\"(PANEL_I18N + '.actions.disconnect' | translate | async) ?? ''\"\n color=\"danger\"\n [disabled]=\"pendingAction()\"\n (onClick)=\"handleDisconnect(provider, connection)\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-link-slash\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n <ax-button-item\n [text]=\"(PANEL_I18N + '.actions.remove' | translate | async) ?? ''\"\n color=\"danger\"\n [disabled]=\"pendingAction()\"\n (onClick)=\"handleRemove(provider, connection)\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-trash\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n </ax-button-item-list>\n </ax-dropdown-button>\n } @else if (supportsConnect(provider)) {\n <ax-button\n size=\"sm\"\n look=\"solid\"\n type=\"button\"\n [disabled]=\"pendingAction() || isConnectDisabled(provider.id)\"\n [text]=\"(PANEL_I18N + '.actions.connect' | translate | async) ?? ''\"\n (onClick)=\"handleConnect(provider, connection)\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-plug\"></ax-icon>\n </ax-prefix>\n </ax-button>\n <ax-button\n size=\"sm\"\n look=\"outline\"\n color=\"danger\"\n type=\"button\"\n [disabled]=\"pendingAction()\"\n [text]=\"(PANEL_I18N + '.actions.remove' | translate | async) ?? ''\"\n (onClick)=\"handleRemove(provider, connection)\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-trash\"></ax-icon>\n </ax-prefix>\n </ax-button>\n } @else {\n <ax-button\n size=\"sm\"\n look=\"outline\"\n color=\"danger\"\n type=\"button\"\n [disabled]=\"pendingAction()\"\n [text]=\"(PANEL_I18N + '.actions.remove' | translate | async) ?? ''\"\n (onClick)=\"handleRemove(provider, connection)\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-trash\"></ax-icon>\n </ax-prefix>\n </ax-button>\n }\n </div>\n\n <ax-switch\n class=\"shrink-0\"\n [ngModel]=\"isEnabledConnection(connection)\"\n [disabled]=\"pendingAction() || !isEstablishedConnection(connection)\"\n (ngModelChange)=\"handleToggleEnabled(provider, $event, connection)\"\n ></ax-switch>\n </div>\n </div>\n }\n </div>\n }\n </div>\n\n <!-- ----- Card footer: single-connection manage/connect, or add connection for multi ----- -->\n <div class=\"mt-auto flex items-center justify-between gap-3 border-t border-surface pt-4\">\n @if (provider.allowMultipleConnections) {\n @if (supportsConnect(provider)) {\n <ax-button\n size=\"sm\"\n look=\"outline\"\n type=\"button\"\n [disabled]=\"pendingAction() || isConnectDisabled(provider.id)\"\n [text]=\"(PANEL_I18N + '.actions.add-connection' | translate | async) ?? ''\"\n (onClick)=\"handleAddConnection(provider)\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-plus\"></ax-icon>\n </ax-prefix>\n </ax-button>\n } @else {\n <span></span>\n }\n <span></span>\n } @else if (hasEstablishedConnection(provider.id)) {\n <ax-dropdown-button size=\"sm\" [mode]=\"'dropdown'\" type=\"button\" [disabled]=\"pendingAction()\" [text]=\"(PANEL_I18N + '.actions.manage' | translate | async) ?? ''\">\n <ax-button-item-list>\n @if (supportsConfigure(provider)) {\n <ax-button-item [text]=\"(PANEL_I18N + '.actions.reconfigure' | translate | async) ?? ''\" [disabled]=\"pendingAction() || isConnectDisabled(provider.id)\" (onClick)=\"handleConfigure(provider)\">\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-gear\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n }\n @for (action of getManageActions(provider); track action.commandKey) {\n <ax-button-item [text]=\"(action.titleKey | translate | async) ?? ''\" [color]=\"action.color\" [disabled]=\"pendingAction()\" (onClick)=\"handleManageAction(provider, action)\">\n @if (action.icon) {\n <ax-prefix>\n <ax-icon [icon]=\"action.icon\"></ax-icon>\n </ax-prefix>\n }\n </ax-button-item>\n }\n <ax-button-item [text]=\"(PANEL_I18N + '.actions.disconnect' | translate | async) ?? ''\" color=\"danger\" [disabled]=\"pendingAction()\" (onClick)=\"handleDisconnect(provider)\">\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-link-slash\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n </ax-button-item-list>\n </ax-dropdown-button>\n <ax-switch [ngModel]=\"isConnectionEnabled(provider.id)\" [disabled]=\"pendingAction() || !hasEstablishedConnection(provider.id)\" (ngModelChange)=\"handleToggleEnabled(provider, $event)\"></ax-switch>\n } @else if (supportsConnect(provider)) {\n <ax-button size=\"sm\" look=\"solid\" type=\"button\" [disabled]=\"pendingAction() || isConnectDisabled(provider.id)\" [text]=\"(PANEL_I18N + '.actions.connect' | translate | async) ?? ''\" (onClick)=\"handleConnect(provider)\">\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-plug\"></ax-icon>\n </ax-prefix>\n </ax-button>\n <ax-switch [ngModel]=\"isConnectionEnabled(provider.id)\" [disabled]=\"pendingAction() || !hasEstablishedConnection(provider.id)\" (ngModelChange)=\"handleToggleEnabled(provider, $event)\"></ax-switch>\n } @else {\n <span></span>\n <ax-switch [ngModel]=\"isConnectionEnabled(provider.id)\" [disabled]=\"pendingAction() || !hasEstablishedConnection(provider.id)\" (ngModelChange)=\"handleToggleEnabled(provider, $event)\"></ax-switch>\n }\n </div>\n </article>\n }\n </div>\n </section>\n }\n </div>\n }\n </axp-page-content>\n</axp-page-layout>\n"],"names":["i11"],"mappings":"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"}
@@ -1,18 +1,22 @@
1
1
  import { AXP_INTEGRATION_CONNECTION_STATUS, AXP_INTEGRATION_CONNECTION_SCOPE, AXP_INTEGRATION_CATEGORY, AXPIntegrationNotConnectedError, AXPIntegrationExpiredError, AXPIntegrationMissingScopeError } from '@acorex-platform/framework-shared/core';
2
2
  import { AXPSessionService, AXP_PERMISSION_DEFINITION_PROVIDER } from '@acorex-platform/framework-client/auth';
3
- import { AXPEntityService } from '@acorex-platform/framework-client/layout/entity';
3
+ import { AXPEntityService, AXP_ENTITY_MODIFIER } from '@acorex-platform/framework-client/layout/entity';
4
4
  import * as i0 from '@angular/core';
5
5
  import { inject, Injectable, NgModule } from '@angular/core';
6
6
  import { isEmpty, trim, defaultTo } from 'lodash';
7
7
  import { RootConfig, AXPAdministrationPermissionKeys, AXMIntegrationManagementMenuKeys, AXMIntegrationManagementCommandKeys, AXMIntegrationManagementQueryKeys } from '@acorex-platform/module-integration-management-client/contracts';
8
8
  import { AXPIntegrationRuntimeService, AXPIntegrationProviderRegistryService, AXP_INTEGRATION_SECRET_STORE, AXP_INTEGRATION_RUNTIME_PROVIDER, AXP_PROTECTED_ROUTE_GUARDS, AXP_MENU_PROVIDER, AXP_SETTING_DEFINITION_PROVIDER, AXP_INTEGRATION_DOMAIN_PROVIDER } from '@acorex-platform/framework-client/common';
9
9
  import { AXP_MODULE_MANIFEST_PROVIDER, AXP_EXPRESSION_EVALUATOR_SCOPE_PROVIDER } from '@acorex-platform/framework-client/core';
10
+ import { AXP_PAGE_COMPONENT_PROVIDER } from '@acorex-platform/framework-client/layout/components';
11
+ import { AXP_WIDGET_DEFINITION_PROVIDER } from '@acorex-platform/framework-client/layout/widget-core';
10
12
  import { AXPRuntimeModule, provideCommandSetups, provideQuerySetups } from '@acorex-platform/framework-client/runtime';
11
13
  import { CommonModule } from '@angular/common';
12
14
  import { ROUTES } from '@angular/router';
13
15
  import { AXPCommonMenuKeys, AXPCommonPermissionGroupKeys } from '@acorex-platform/module-common-client/contracts';
14
16
  import { firstValueFrom } from 'rxjs';
15
17
  import { AXPRootLayoutComponent } from '@acorex-platform/framework-client/themes/default';
18
+ import { AXP_NAME_PROPERTY, AXP_DATA_PATH_PROPERTY, AXP_DISABLED_PROPERTY } from '@acorex-platform/framework-client/layout/widgets';
19
+ import { AXPWidgetGroupEnum } from '@acorex-platform/framework-shared/widget-core';
16
20
 
17
21
  //#endregion
18
22
 
@@ -570,7 +574,7 @@ function integrationManagementRoutesFactory() {
570
574
  children: [
571
575
  {
572
576
  path: '',
573
- loadComponent: () => import('./acorex-platform-module-integration-management-client-integrations-page.component-Q-SHidYA.mjs').then((c) => c.AXMIntegrationsPageComponent),
577
+ loadComponent: () => import('./acorex-platform-module-integration-management-client-integrations-page.component-iH0DqEak.mjs').then((c) => c.AXMIntegrationsPageComponent),
574
578
  data: { reuse: true },
575
579
  },
576
580
  ],
@@ -583,15 +587,212 @@ const integrationOAuthCallbackRoutes = [
583
587
  // App-agnostic callback first — must win over `:appName/...` (else appName="integrations").
584
588
  {
585
589
  path: 'integrations/oauth/callback/:providerId',
586
- loadComponent: () => import('./acorex-platform-module-integration-management-client-integration-oauth-callback-page.component-XhloXUsZ.mjs').then((c) => c.AXMIntegrationOAuthCallbackPageComponent),
590
+ loadComponent: () => import('./acorex-platform-module-integration-management-client-integration-oauth-callback-page.component-CZu5mKUA.mjs').then((c) => c.AXMIntegrationOAuthCallbackPageComponent),
587
591
  },
588
592
  // Legacy app-prefixed callback (older provider redirect URI configs).
589
593
  {
590
594
  path: ':appName/integrations/oauth/callback/:providerId',
591
- loadComponent: () => import('./acorex-platform-module-integration-management-client-integration-oauth-callback-page.component-XhloXUsZ.mjs').then((c) => c.AXMIntegrationOAuthCallbackPageComponent),
595
+ loadComponent: () => import('./acorex-platform-module-integration-management-client-integration-oauth-callback-page.component-CZu5mKUA.mjs').then((c) => c.AXMIntegrationOAuthCallbackPageComponent),
592
596
  },
593
597
  ];
594
598
 
599
+ const AXM_INTEGRATION_REF_PAGE_COMPONENT_KEY = 'integration-management.integration-ref-page';
600
+
601
+ //#region ----- Imports -----
602
+ //#endregion
603
+ //#region ----- Constants -----
604
+ const AXM_INTEGRATION_REF_FILTER_WIDGET_NAME = 'integration-ref-filter';
605
+ //#endregion
606
+ //#region ----- Widget config -----
607
+ const AXMIntegrationRefFilterWidget = {
608
+ name: AXM_INTEGRATION_REF_FILTER_WIDGET_NAME,
609
+ title: 'Integration Source Filter',
610
+ description: 'Select-box filter for integrationRef.source provider ids.',
611
+ type: 'filter',
612
+ icon: 'fa-light fa-plug',
613
+ /**
614
+ * `path` is required so AXPValueWidgetComponent treats this as a value widget
615
+ * and setValue/getValue bind into the filter context (otherwise Apply writes empty).
616
+ */
617
+ properties: [AXP_NAME_PROPERTY, AXP_DATA_PATH_PROPERTY, AXP_DISABLED_PROPERTY],
618
+ components: {
619
+ edit: {
620
+ component: () => import('./acorex-platform-module-integration-management-client-integration-ref-filter-widget-edit.component-DeED5cU5.mjs').then((c) => c.AXMIntegrationRefFilterWidgetEditComponent),
621
+ },
622
+ },
623
+ };
624
+ //#endregion
625
+
626
+ //#region ----- Imports -----
627
+ //#endregion
628
+ //#region ----- Constants -----
629
+ /** Widget name used on entity `integrationRef` fields (`schema.interface.type`). */
630
+ const AXM_INTEGRATION_REF_WIDGET_NAME = 'integration-ref';
631
+ //#endregion
632
+ //#region ----- Widget config -----
633
+ const AXMIntegrationRefWidget = {
634
+ name: AXM_INTEGRATION_REF_WIDGET_NAME,
635
+ title: 'Integration Provider',
636
+ description: 'Shows the integration provider logo for records linked via integrationRef.',
637
+ type: 'view',
638
+ categories: [],
639
+ groups: [AXPWidgetGroupEnum.EntityWidget],
640
+ icon: 'fa-light fa-plug',
641
+ defaultFilterWidgetName: AXM_INTEGRATION_REF_FILTER_WIDGET_NAME,
642
+ properties: [],
643
+ components: {
644
+ column: {
645
+ component: () => import('./acorex-platform-module-integration-management-client-integration-ref-widget-column.component-CPLhmHOe.mjs').then((c) => c.AXMIntegrationRefWidgetColumnComponent),
646
+ },
647
+ view: {
648
+ component: () => import('./acorex-platform-module-integration-management-client-integration-ref-widget-view.component-BRpGpWHZ.mjs').then((c) => c.AXMIntegrationRefWidgetViewComponent),
649
+ },
650
+ },
651
+ };
652
+ //#endregion
653
+
654
+ //#region ----- Imports -----
655
+ //#endregion
656
+ //#region ----- Constants -----
657
+ const COLUMN_TITLE = '@integration-management:widgets.integration-ref.column-title';
658
+ const PAGE_TITLE = '@integration-management:widgets.integration-ref.page.title';
659
+ /** Place near other related tabs (Members/Tasks/Documents), after Overview. */
660
+ const PAGE_ORDER = 20;
661
+ //#endregion
662
+ //#region ----- Modifier -----
663
+ /**
664
+ * For any entity that already declares `integrationRef`:
665
+ * - wire the `integration-ref` list widget / column
666
+ * - add a readonly Integration Info detail/edit tab (same tab strip as Overview/Profile)
667
+ */
668
+ const AXMIntegrationRefEntityModifier = {
669
+ entityName: '*',
670
+ /** After default column ordering so we can pin the icon column first. */
671
+ order: 120,
672
+ modifier: (ctx) => {
673
+ const property = ctx.properties.find('integrationRef').get();
674
+ if (!property) {
675
+ return;
676
+ }
677
+ ctx.properties.find('integrationRef').update((prop) => ({
678
+ ...prop,
679
+ title: COLUMN_TITLE,
680
+ options: {
681
+ ...prop.options,
682
+ filter: {
683
+ ...(prop.options?.filter ?? {}),
684
+ advance: {
685
+ ...(prop.options?.filter?.advance ?? {}),
686
+ enabled: true,
687
+ widgetType: AXM_INTEGRATION_REF_FILTER_WIDGET_NAME,
688
+ },
689
+ inline: {
690
+ ...(prop.options?.filter?.inline ?? {}),
691
+ enabled: true,
692
+ },
693
+ },
694
+ },
695
+ schema: {
696
+ ...prop.schema,
697
+ interface: {
698
+ ...(prop.schema.interface ?? {}),
699
+ type: AXM_INTEGRATION_REF_WIDGET_NAME,
700
+ options: {
701
+ ...(prop.schema.interface?.options ?? {}),
702
+ /**
703
+ * Drives list `inlineQueryField` → `integrationRef.source`
704
+ * so Source filters query the nested provider id.
705
+ */
706
+ textField: 'source',
707
+ expose: [
708
+ {
709
+ source: 'source',
710
+ target: 'integrationRef.source',
711
+ },
712
+ ],
713
+ },
714
+ },
715
+ },
716
+ }));
717
+ if (!ctx.columns.find('integrationRef').get()) {
718
+ ctx.columns.add({
719
+ name: 'integrationRef',
720
+ title: COLUMN_TITLE,
721
+ options: { width: '140px' },
722
+ });
723
+ }
724
+ else {
725
+ ctx.columns.find('integrationRef').update((col) => ({
726
+ ...col,
727
+ title: col.title ?? COLUMN_TITLE,
728
+ options: {
729
+ ...(col.options ?? {}),
730
+ width: '140px',
731
+ },
732
+ }));
733
+ }
734
+ const columns = ctx.columns.list();
735
+ if (columns?.length) {
736
+ const index = columns.findIndex((col) => col.name === 'integrationRef');
737
+ if (index > 0) {
738
+ const [column] = columns.splice(index, 1);
739
+ columns.unshift(column);
740
+ }
741
+ }
742
+ ctx.entity.pages ??= [];
743
+ const page = {
744
+ componentKey: AXM_INTEGRATION_REF_PAGE_COMPONENT_KEY,
745
+ title: PAGE_TITLE,
746
+ icon: 'fa-light fa-plug',
747
+ layout: { order: PAGE_ORDER, position: 'after' },
748
+ /**
749
+ * Required for update/edit form wizard steps.
750
+ * Details view always includes entity.pages; empty state handles unlinked records.
751
+ */
752
+ appearOn: { update: true },
753
+ };
754
+ const existingIndex = ctx.entity.pages.findIndex((entry) => entry.componentKey === AXM_INTEGRATION_REF_PAGE_COMPONENT_KEY);
755
+ if (existingIndex >= 0) {
756
+ ctx.entity.pages[existingIndex] = page;
757
+ }
758
+ else {
759
+ ctx.entity.pages.push(page);
760
+ }
761
+ },
762
+ };
763
+ //#endregion
764
+
765
+ //#endregion
766
+ //#region ----- Provider -----
767
+ class AXMIntegrationRefPageComponentProvider {
768
+ async components() {
769
+ return [
770
+ {
771
+ key: AXM_INTEGRATION_REF_PAGE_COMPONENT_KEY,
772
+ loader: () => import('./acorex-platform-module-integration-management-client-integration-ref-page.component-D9hdpnQq.mjs').then((m) => m.AXMIntegrationRefPageComponent),
773
+ },
774
+ ];
775
+ }
776
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMIntegrationRefPageComponentProvider, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
777
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMIntegrationRefPageComponentProvider }); }
778
+ }
779
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMIntegrationRefPageComponentProvider, decorators: [{
780
+ type: Injectable
781
+ }] });
782
+
783
+ //#endregion
784
+ //#region ----- Provider -----
785
+ class AXMIntegrationRefWidgetProvider {
786
+ getWidgets() {
787
+ return [AXMIntegrationRefWidget, AXMIntegrationRefFilterWidget];
788
+ }
789
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMIntegrationRefWidgetProvider, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
790
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMIntegrationRefWidgetProvider }); }
791
+ }
792
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMIntegrationRefWidgetProvider, decorators: [{
793
+ type: Injectable
794
+ }] });
795
+
595
796
  //#region ---- Imports ----
596
797
  //#endregion
597
798
  //#region ---- Module ----
@@ -638,6 +839,21 @@ class AXMIntegrationManagementModule {
638
839
  useClass: AXMIntegrationEvaluatorScopeProvider,
639
840
  multi: true,
640
841
  },
842
+ {
843
+ provide: AXP_WIDGET_DEFINITION_PROVIDER,
844
+ useClass: AXMIntegrationRefWidgetProvider,
845
+ multi: true,
846
+ },
847
+ {
848
+ provide: AXP_PAGE_COMPONENT_PROVIDER,
849
+ useClass: AXMIntegrationRefPageComponentProvider,
850
+ multi: true,
851
+ },
852
+ {
853
+ provide: AXP_ENTITY_MODIFIER,
854
+ useValue: AXMIntegrationRefEntityModifier,
855
+ multi: true,
856
+ },
641
857
  provideCommandSetups([
642
858
  {
643
859
  key: AXMIntegrationManagementCommandKeys.ConnectionConnectWithCredentials,
@@ -724,6 +940,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
724
940
  useClass: AXMIntegrationEvaluatorScopeProvider,
725
941
  multi: true,
726
942
  },
943
+ {
944
+ provide: AXP_WIDGET_DEFINITION_PROVIDER,
945
+ useClass: AXMIntegrationRefWidgetProvider,
946
+ multi: true,
947
+ },
948
+ {
949
+ provide: AXP_PAGE_COMPONENT_PROVIDER,
950
+ useClass: AXMIntegrationRefPageComponentProvider,
951
+ multi: true,
952
+ },
953
+ {
954
+ provide: AXP_ENTITY_MODIFIER,
955
+ useValue: AXMIntegrationRefEntityModifier,
956
+ multi: true,
957
+ },
727
958
  provideCommandSetups([
728
959
  {
729
960
  key: AXMIntegrationManagementCommandKeys.ConnectionConnectWithCredentials,