@acorex-platform/module-integration-management-client 0.0.21

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 (31) hide show
  1. package/fesm2022/acorex-platform-module-integration-management-client-connect-with-credentials.command-DO_zqjHV.mjs +102 -0
  2. package/fesm2022/acorex-platform-module-integration-management-client-connect-with-credentials.command-DO_zqjHV.mjs.map +1 -0
  3. package/fesm2022/acorex-platform-module-integration-management-client-contracts.mjs +163 -0
  4. package/fesm2022/acorex-platform-module-integration-management-client-contracts.mjs.map +1 -0
  5. package/fesm2022/acorex-platform-module-integration-management-client-delete-connection.command-DQ_kn8dH.mjs +53 -0
  6. package/fesm2022/acorex-platform-module-integration-management-client-delete-connection.command-DQ_kn8dH.mjs.map +1 -0
  7. package/fesm2022/acorex-platform-module-integration-management-client-disconnect-connection.command-B4HeDA1n.mjs +60 -0
  8. package/fesm2022/acorex-platform-module-integration-management-client-disconnect-connection.command-B4HeDA1n.mjs.map +1 -0
  9. package/fesm2022/acorex-platform-module-integration-management-client-get-provider.query-Ds10RwnU.mjs +30 -0
  10. package/fesm2022/acorex-platform-module-integration-management-client-get-provider.query-Ds10RwnU.mjs.map +1 -0
  11. package/fesm2022/acorex-platform-module-integration-management-client-integration-connection-lifecycle.dispatcher-DRWR9ysx.mjs +45 -0
  12. package/fesm2022/acorex-platform-module-integration-management-client-integration-connection-lifecycle.dispatcher-DRWR9ysx.mjs.map +1 -0
  13. package/fesm2022/acorex-platform-module-integration-management-client-integration-oauth-callback-page.component-XhloXUsZ.mjs +176 -0
  14. package/fesm2022/acorex-platform-module-integration-management-client-integration-oauth-callback-page.component-XhloXUsZ.mjs.map +1 -0
  15. package/fesm2022/acorex-platform-module-integration-management-client-integrations-page.component-Q-SHidYA.mjs +406 -0
  16. package/fesm2022/acorex-platform-module-integration-management-client-integrations-page.component-Q-SHidYA.mjs.map +1 -0
  17. package/fesm2022/acorex-platform-module-integration-management-client-list-domains.query--GGD6J46.mjs +52 -0
  18. package/fesm2022/acorex-platform-module-integration-management-client-list-domains.query--GGD6J46.mjs.map +1 -0
  19. package/fesm2022/acorex-platform-module-integration-management-client-list-my-connections.query-CmHu1qFm.mjs +27 -0
  20. package/fesm2022/acorex-platform-module-integration-management-client-list-my-connections.query-CmHu1qFm.mjs.map +1 -0
  21. package/fesm2022/acorex-platform-module-integration-management-client-list-providers.query-ODKJ_UhI.mjs +65 -0
  22. package/fesm2022/acorex-platform-module-integration-management-client-list-providers.query-ODKJ_UhI.mjs.map +1 -0
  23. package/fesm2022/acorex-platform-module-integration-management-client-update-connection.command-BNMR-t12.mjs +42 -0
  24. package/fesm2022/acorex-platform-module-integration-management-client-update-connection.command-BNMR-t12.mjs.map +1 -0
  25. package/fesm2022/acorex-platform-module-integration-management-client-validate-connection.command-CGtb_GPX.mjs +83 -0
  26. package/fesm2022/acorex-platform-module-integration-management-client-validate-connection.command-CGtb_GPX.mjs.map +1 -0
  27. package/fesm2022/acorex-platform-module-integration-management-client.mjs +776 -0
  28. package/fesm2022/acorex-platform-module-integration-management-client.mjs.map +1 -0
  29. package/package.json +28 -0
  30. package/types/acorex-platform-module-integration-management-client-contracts.d.ts +191 -0
  31. package/types/acorex-platform-module-integration-management-client.d.ts +74 -0
@@ -0,0 +1,406 @@
1
+ import * as i2 from '@acorex/components/badge';
2
+ import { AXBadgeModule } from '@acorex/components/badge';
3
+ import * as i3 from '@acorex/components/button';
4
+ import { AXButtonModule } from '@acorex/components/button';
5
+ import * as i4 from '@acorex/components/check-box';
6
+ import { AXCheckBoxModule } from '@acorex/components/check-box';
7
+ import * as i5 from '@acorex/components/dropdown-button';
8
+ import { AXDropdownButtonModule } from '@acorex/components/dropdown-button';
9
+ import * as i6 from '@acorex/components/decorators';
10
+ import { AXDecoratorModule } from '@acorex/components/decorators';
11
+ import * as i7 from '@acorex/components/label';
12
+ import { AXLabelModule } from '@acorex/components/label';
13
+ import * as i8 from '@acorex/components/skeleton';
14
+ import { AXSkeletonModule } from '@acorex/components/skeleton';
15
+ import * as i9 from '@acorex/components/switch';
16
+ import { AXSwitchModule } from '@acorex/components/switch';
17
+ import * as i10 from '@acorex/components/tooltip';
18
+ import { AXTooltipModule } from '@acorex/components/tooltip';
19
+ import * as i11 from '@acorex/core/translation';
20
+ import { AXTranslationModule } from '@acorex/core/translation';
21
+ import { AXPDeviceService, AXPLogoComponent } from '@acorex-platform/framework-client/core';
22
+ import { AXPStateMessageComponent, AXPThemeLayoutBlockComponent, AXPThemeLayoutStartSideComponent } from '@acorex-platform/framework-client/layout/components';
23
+ import { AXPIntegrationConnectionActionsService } from '@acorex-platform/framework-client/layout/widgets';
24
+ import { AXPPageLayoutBaseComponent, AXPPageLayoutComponent, AXPPageLayoutBase } from '@acorex-platform/framework-client/layout/views';
25
+ import { AXPQueryService } from '@acorex-platform/framework-client/runtime';
26
+ import { AXP_INTEGRATION_CONNECTION_STATUS, AXP_INTEGRATION_CONNECTION_SCOPE, runtimeQueryCollectionData } from '@acorex-platform/framework-shared/core';
27
+ import { AsyncPipe } from '@angular/common';
28
+ import * as i0 from '@angular/core';
29
+ import { inject, signal, computed, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
30
+ import * as i1 from '@angular/forms';
31
+ import { FormsModule } from '@angular/forms';
32
+
33
+ //#region ----- Imports -----
34
+ const ERROR_CONNECTION_STATUSES = new Set([
35
+ AXP_INTEGRATION_CONNECTION_STATUS.Error,
36
+ AXP_INTEGRATION_CONNECTION_STATUS.Invalid,
37
+ AXP_INTEGRATION_CONNECTION_STATUS.Expired,
38
+ AXP_INTEGRATION_CONNECTION_STATUS.RefreshRequired,
39
+ AXP_INTEGRATION_CONNECTION_STATUS.PendingAuthorization,
40
+ AXP_INTEGRATION_CONNECTION_STATUS.Revoked,
41
+ ]);
42
+ //#endregion
43
+ //#region ----- Constants -----
44
+ const PAGE_I18N = '@integration-management:pages.integrations';
45
+ const PANEL_I18N = '@platform-layout-widgets:widgets.integration-connections-panel';
46
+ const TENANT_SCOPE = AXP_INTEGRATION_CONNECTION_SCOPE.Tenant;
47
+ const SKELETON_SECTION_COUNT = 2;
48
+ const SKELETON_CARDS_PER_SECTION = 4;
49
+ //#endregion
50
+ //#region ----- Component -----
51
+ class AXMIntegrationsPageComponent extends AXPPageLayoutBaseComponent {
52
+ constructor() {
53
+ super(...arguments);
54
+ //#region ----- Services & Dependencies -----
55
+ this.queryService = inject(AXPQueryService);
56
+ this.actionsService = inject(AXPIntegrationConnectionActionsService);
57
+ this.deviceService = inject(AXPDeviceService);
58
+ //#endregion
59
+ //#region ----- Constants -----
60
+ this.PAGE_I18N = PAGE_I18N;
61
+ this.PANEL_I18N = PANEL_I18N;
62
+ //#endregion
63
+ //#region ----- State Signals -----
64
+ this.loading = signal(true, /* @ts-ignore */
65
+ ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
66
+ this.pendingAction = signal(false, /* @ts-ignore */
67
+ ...(ngDevMode ? [{ debugName: "pendingAction" }] : /* istanbul ignore next */ []));
68
+ this.domainSections = signal([], /* @ts-ignore */
69
+ ...(ngDevMode ? [{ debugName: "domainSections" }] : /* istanbul ignore next */ []));
70
+ this.selectedDomainIds = signal(new Set(), /* @ts-ignore */
71
+ ...(ngDevMode ? [{ debugName: "selectedDomainIds" }] : /* istanbul ignore next */ []));
72
+ this.panelData = signal({
73
+ providers: [],
74
+ connections: [],
75
+ providerBadges: {},
76
+ connectAvailabilityByProvider: {},
77
+ }, /* @ts-ignore */
78
+ ...(ngDevMode ? [{ debugName: "panelData" }] : /* istanbul ignore next */ []));
79
+ this.skeletonSectionPlaceholders = Array.from({ length: SKELETON_SECTION_COUNT }, (_, index) => index);
80
+ this.skeletonCardPlaceholders = Array.from({ length: SKELETON_CARDS_PER_SECTION }, (_, index) => index);
81
+ //#endregion
82
+ //#region ----- Sidebar Computed -----
83
+ this.overviewStats = computed(() => {
84
+ const providers = this.domainSections().flatMap((section) => section.providers);
85
+ const connections = this.panelData().connections;
86
+ let connected = 0;
87
+ let error = 0;
88
+ let disabled = 0;
89
+ let notConnected = 0;
90
+ for (const provider of providers) {
91
+ if (this.actionsService.isConnectionEnabled(connections, provider.id, TENANT_SCOPE)) {
92
+ connected += 1;
93
+ continue;
94
+ }
95
+ if (this.actionsService.hasEstablishedConnection(connections, provider.id, TENANT_SCOPE)) {
96
+ if (this.isProviderInError(connections, provider.id)) {
97
+ error += 1;
98
+ }
99
+ else {
100
+ disabled += 1;
101
+ }
102
+ continue;
103
+ }
104
+ notConnected += 1;
105
+ }
106
+ return { connected, error, disabled, notConnected };
107
+ }, /* @ts-ignore */
108
+ ...(ngDevMode ? [{ debugName: "overviewStats" }] : /* istanbul ignore next */ []));
109
+ this.isAllDomainsSelected = computed(() => {
110
+ const sections = this.domainSections();
111
+ const selected = this.selectedDomainIds();
112
+ if (!sections.length) {
113
+ return true;
114
+ }
115
+ return sections.every((section) => selected.has(section.domain.id));
116
+ }, /* @ts-ignore */
117
+ ...(ngDevMode ? [{ debugName: "isAllDomainsSelected" }] : /* istanbul ignore next */ []));
118
+ this.filteredDomainSections = computed(() => {
119
+ const selected = this.selectedDomainIds();
120
+ if (!selected.size) {
121
+ return [];
122
+ }
123
+ return this.domainSections().filter((section) => selected.has(section.domain.id));
124
+ }, /* @ts-ignore */
125
+ ...(ngDevMode ? [{ debugName: "filteredDomainSections" }] : /* istanbul ignore next */ []));
126
+ this.visibleDomainSections = computed(() => {
127
+ if (!this.deviceService.isLarge()) {
128
+ return this.domainSections();
129
+ }
130
+ return this.filteredDomainSections();
131
+ }, /* @ts-ignore */
132
+ ...(ngDevMode ? [{ debugName: "visibleDomainSections" }] : /* istanbul ignore next */ []));
133
+ }
134
+ //#endregion
135
+ //#region ----- Lifecycle -----
136
+ async ngOnInit() {
137
+ super.ngOnInit();
138
+ await this.loadPage();
139
+ }
140
+ async getPageTitle() {
141
+ return this.translateService.translateAsync(`${PAGE_I18N}.title`);
142
+ }
143
+ async getPageDescription() {
144
+ return this.translateService.translateAsync(`${PAGE_I18N}.description`);
145
+ }
146
+ //#endregion
147
+ //#region ----- Connection Helpers -----
148
+ getConnections(providerId) {
149
+ return this.actionsService.getConnections(this.panelData().connections, providerId, TENANT_SCOPE);
150
+ }
151
+ getConnection(providerId) {
152
+ return this.actionsService.getConnection(this.panelData().connections, providerId, TENANT_SCOPE);
153
+ }
154
+ hasEstablishedConnection(providerId) {
155
+ return this.actionsService.hasEstablishedConnection(this.panelData().connections, providerId, TENANT_SCOPE);
156
+ }
157
+ isConnectionEnabled(providerId) {
158
+ return this.actionsService.isConnectionEnabled(this.panelData().connections, providerId, TENANT_SCOPE);
159
+ }
160
+ isEstablishedConnection(connection) {
161
+ return this.actionsService.isEstablishedConnection(connection);
162
+ }
163
+ isEnabledConnection(connection) {
164
+ return this.actionsService.isEnabledConnection(connection);
165
+ }
166
+ getProviderConnectionSummary(providerId) {
167
+ const connections = this.getConnections(providerId);
168
+ return {
169
+ connected: connections.filter((connection) => this.isEstablishedConnection(connection)).length,
170
+ total: connections.length,
171
+ };
172
+ }
173
+ getMultiConnectionStatusBadgeColor(providerId) {
174
+ const { connected, total } = this.getProviderConnectionSummary(providerId);
175
+ if (total === 0 || connected === 0) {
176
+ return 'secondary';
177
+ }
178
+ if (connected === total) {
179
+ return 'success';
180
+ }
181
+ return 'warning';
182
+ }
183
+ supportsConnect(provider) {
184
+ return this.actionsService.supportsConnect(provider);
185
+ }
186
+ supportsConfigure(provider, connection) {
187
+ return this.actionsService.supportsConfigure(provider, this.panelData().connections, TENANT_SCOPE, connection);
188
+ }
189
+ isConnectDisabled(providerId) {
190
+ return this.actionsService.isConnectDisabled(this.panelData().connectAvailabilityByProvider, providerId);
191
+ }
192
+ connectDisabledBadgeKey(providerId) {
193
+ return (this.panelData().connectAvailabilityByProvider[providerId]?.disabledBadgeKey
194
+ ?? this.panelData().providers.find((provider) => provider.id === providerId)?.connectDisabledBadgeKey);
195
+ }
196
+ connectDisabledMessageKey(providerId) {
197
+ return (this.panelData().connectAvailabilityByProvider[providerId]?.disabledMessageKey
198
+ ?? this.panelData().providers.find((provider) => provider.id === providerId)?.connectDisabledMessageKey);
199
+ }
200
+ getProviderBadges(providerId) {
201
+ return this.panelData().providerBadges[providerId] ?? [];
202
+ }
203
+ getManageActions(provider) {
204
+ return this.actionsService.getManageActions(provider, TENANT_SCOPE);
205
+ }
206
+ //#endregion
207
+ //#region ----- Sidebar Filters -----
208
+ showSidebarPanel() {
209
+ return this.deviceService.isLarge();
210
+ }
211
+ isDomainFilterSelected(domainId) {
212
+ return this.selectedDomainIds().has(domainId);
213
+ }
214
+ handleAllDomainsFilterChange(event) {
215
+ if (event.value) {
216
+ this.selectAllDomainFilters();
217
+ return;
218
+ }
219
+ this.selectedDomainIds.set(new Set());
220
+ }
221
+ handleSelectAllDomainFilters() {
222
+ this.selectAllDomainFilters();
223
+ }
224
+ handleDomainFilterChange(domainId, event) {
225
+ const next = new Set(this.selectedDomainIds());
226
+ if (event.value) {
227
+ next.add(domainId);
228
+ }
229
+ else {
230
+ next.delete(domainId);
231
+ }
232
+ this.selectedDomainIds.set(next);
233
+ }
234
+ selectAllDomainFilters() {
235
+ this.selectedDomainIds.set(new Set(this.domainSections().map((section) => section.domain.id)));
236
+ }
237
+ //#endregion
238
+ //#region ----- Event Handlers -----
239
+ async handleConnect(provider, connection) {
240
+ if (this.pendingAction()) {
241
+ return;
242
+ }
243
+ this.pendingAction.set(true);
244
+ try {
245
+ const outcome = await this.actionsService.connect(provider, {
246
+ connectionScope: TENANT_SCOPE,
247
+ connectAvailabilityByProvider: this.panelData().connectAvailabilityByProvider,
248
+ ...(connection?.id ? { connectionId: connection.id } : {}),
249
+ });
250
+ if (outcome === 'reload') {
251
+ await this.loadPage(false);
252
+ }
253
+ }
254
+ finally {
255
+ this.actionsService.releasePendingAction(() => this.pendingAction.set(false));
256
+ }
257
+ }
258
+ async handleAddConnection(provider) {
259
+ await this.handleConnect(provider);
260
+ }
261
+ async handleConfigure(provider, connection) {
262
+ await this.handleConnect(provider, connection ?? this.getConnection(provider.id));
263
+ }
264
+ async handleManageAction(provider, action, connection) {
265
+ if (this.pendingAction()) {
266
+ return;
267
+ }
268
+ this.pendingAction.set(true);
269
+ try {
270
+ const success = await this.actionsService.runManageAction(provider, action, TENANT_SCOPE, connection?.id);
271
+ if (success) {
272
+ await this.loadPage(false);
273
+ }
274
+ }
275
+ finally {
276
+ this.actionsService.releasePendingAction(() => this.pendingAction.set(false));
277
+ }
278
+ }
279
+ async handleDisconnect(provider, connection) {
280
+ if (this.pendingAction()) {
281
+ return;
282
+ }
283
+ const target = connection ?? this.getConnection(provider.id);
284
+ if (!target) {
285
+ return;
286
+ }
287
+ this.pendingAction.set(true);
288
+ try {
289
+ const success = await this.actionsService.disconnect(provider, target);
290
+ if (success) {
291
+ await this.loadPage(false);
292
+ }
293
+ }
294
+ finally {
295
+ this.actionsService.releasePendingAction(() => this.pendingAction.set(false));
296
+ }
297
+ }
298
+ async handleRemove(provider, connection) {
299
+ if (this.pendingAction()) {
300
+ return;
301
+ }
302
+ this.pendingAction.set(true);
303
+ try {
304
+ const success = await this.actionsService.remove(provider, connection);
305
+ if (success) {
306
+ await this.loadPage(false);
307
+ }
308
+ }
309
+ finally {
310
+ this.actionsService.releasePendingAction(() => this.pendingAction.set(false));
311
+ }
312
+ }
313
+ async handleToggleEnabled(provider, enabled, connection) {
314
+ if (this.pendingAction()) {
315
+ return;
316
+ }
317
+ const target = connection ?? this.getConnection(provider.id);
318
+ if (!target || !this.isEstablishedConnection(target)) {
319
+ return;
320
+ }
321
+ if (this.isEnabledConnection(target) === enabled) {
322
+ return;
323
+ }
324
+ this.pendingAction.set(true);
325
+ try {
326
+ const success = await this.actionsService.setConnectionEnabled(target.id, enabled);
327
+ if (success) {
328
+ await this.loadPage(false);
329
+ }
330
+ }
331
+ finally {
332
+ this.actionsService.releasePendingAction(() => this.pendingAction.set(false));
333
+ }
334
+ }
335
+ //#endregion
336
+ //#region ----- Data Loading -----
337
+ async loadPage(showBlockingLoader = true) {
338
+ if (showBlockingLoader) {
339
+ this.loading.set(true);
340
+ }
341
+ try {
342
+ await this.actionsService.waitForSettingsLoaded();
343
+ const [domainsResult, panelData] = await Promise.all([
344
+ this.queryService.fetch('IntegrationManagement.Domain:List', { includeProviderCount: false }),
345
+ this.actionsService.loadPanelData({ connectionScope: TENANT_SCOPE }),
346
+ ]);
347
+ const domains = runtimeQueryCollectionData(domainsResult)?.items ?? [];
348
+ const sections = [];
349
+ for (const domain of [...domains].sort((left, right) => (left.sortOrder ?? 100) - (right.sortOrder ?? 100))) {
350
+ const providers = panelData.providers.filter((provider) => provider.domainId === domain.id && provider.connectionScopes.includes(TENANT_SCOPE));
351
+ if (!providers.length) {
352
+ continue;
353
+ }
354
+ sections.push({ domain, providers });
355
+ }
356
+ this.domainSections.set(sections);
357
+ this.selectAllDomainFilters();
358
+ this.panelData.set(panelData);
359
+ this.recompute();
360
+ }
361
+ finally {
362
+ if (showBlockingLoader) {
363
+ this.loading.set(false);
364
+ }
365
+ }
366
+ }
367
+ //#endregion
368
+ //#region ----- Overview Helpers -----
369
+ isProviderInError(connections, providerId) {
370
+ const providerConnections = this.actionsService.getConnections(connections, providerId, TENANT_SCOPE);
371
+ return providerConnections.some((connection) => {
372
+ if (connection.isRevoked || ERROR_CONNECTION_STATUSES.has(connection.status)) {
373
+ return true;
374
+ }
375
+ return Boolean(String(connection.lastErrorCode ?? '').trim()
376
+ || String(connection.lastErrorMessage ?? '').trim());
377
+ });
378
+ }
379
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMIntegrationsPageComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
380
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXMIntegrationsPageComponent, isStandalone: true, selector: "axm-integrations-page", providers: [{ provide: AXPPageLayoutBase, useExisting: AXMIntegrationsPageComponent }], usesInheritance: true, ngImport: i0, template: "<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", styles: ["@layer properties;axm-integrations-page axp-layout-start-side{min-width:calc(var(--spacing, .25rem) * 80)!important;border-inline-end-style:var(--tw-border-style);border-inline-end-width:1px}axm-integrations-page axp-layout-start-side axp-layout-content.axm-integrations-page__sidebar{flex:none;padding-inline:calc(var(--spacing, .25rem) * 4);padding-bottom:calc(var(--spacing, .25rem) * 4)}axm-integrations-page .axm-integrations-page__sidebar-section{margin-top:calc(var(--spacing, .25rem) * 4)}axm-integrations-page .axm-integrations-page__sidebar-section-title{margin:0;padding-bottom:calc(var(--spacing, .25rem) * 2);--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);opacity:85%}axm-integrations-page .axm-integrations-page__sidebar-section:first-child .axm-integrations-page__sidebar-section-title{padding-top:calc(var(--spacing, .25rem) * 4)}axm-integrations-page .axm-integrations-page__sidebar-section-body{display:flex;flex-direction:column;gap:calc(var(--spacing, .25rem) * 3)}axm-integrations-page .axm-integrations-page__overview-list,axm-integrations-page .axm-integrations-page__category-list{margin:0;display:flex;list-style-type:none;flex-direction:column;gap:var(--spacing, .25rem);padding:0}axm-integrations-page .axm-integrations-page__overview-item{display:flex;align-items:center;justify-content:space-between;gap:calc(var(--spacing, .25rem) * 3);padding-block:calc(var(--spacing, .25rem) * 1.5);font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)))}axm-integrations-page .axm-integrations-page__overview-label{display:inline-flex;min-width:0px;align-items:center;gap:calc(var(--spacing, .25rem) * 2.5)}axm-integrations-page .axm-integrations-page__overview-label ax-icon{font-size:var(--text-base, 1rem);line-height:var(--tw-leading, var(--text-base--line-height, 1.5 ));color:rgba(var(--ax-sys-color-text-default))}@supports (color: color-mix(in lab,red,red)){axm-integrations-page .axm-integrations-page__overview-label ax-icon{color:color-mix(in oklab,rgba(var(--ax-sys-color-text-default)) 80%,transparent)}}axm-integrations-page .axm-integrations-page__overview-count{display:inline-flex;min-width:calc(var(--spacing, .25rem) * 7);flex-shrink:0;align-items:center;justify-content:center;border-radius:var(--radius-md, .375rem);padding-inline:calc(var(--spacing, .25rem) * 2);padding-block:calc(var(--spacing, .25rem) * .5);font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);background-color:rgb(var(--ax-sys-color-surface));color:rgb(var(--ax-sys-color-on-surface))}axm-integrations-page .axm-integrations-page__overview-count.--danger{background-color:var(--color-danger);color:var(--color-on-danger);border-color:var(--color-border-danger)}axm-integrations-page .axm-integrations-page__category-item{padding-block:calc(var(--spacing, .25rem) * 1.5);font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)))}axm-integrations-page .axm-integrations-page__category-checkbox{width:100%}axm-integrations-page .axm-integrations-page__skeleton-sidebar-title{height:calc(var(--spacing, .25rem) * 6);width:calc(var(--spacing, .25rem) * 28);border-radius:var(--radius-md, .375rem)}axm-integrations-page .axm-integrations-page__skeleton-sidebar-row{height:calc(var(--spacing, .25rem) * 8);width:100%;border-radius:var(--radius-md, .375rem)}axm-integrations-page .axm-integrations-page__skeleton-section-title{height:calc(var(--spacing, .25rem) * 6);width:calc(var(--spacing, .25rem) * 40);border-radius:var(--radius-md, .375rem)}axm-integrations-page .axm-integrations-page__skeleton-section-description{height:calc(var(--spacing, .25rem) * 4);width:100%;max-width:var(--container-md, 28rem);border-radius:var(--radius-md, .375rem)}axm-integrations-page .axm-integrations-page__skeleton-card{display:flex;height:100%;width:100%;flex-direction:column;gap:calc(var(--spacing, .25rem) * 3);border-radius:var(--radius-xl, .75rem);border-style:var(--tw-border-style);border-width:1px;background-color:var(--color-lighter);color:var(--color-on-lighter);border-color:var(--color-border-lighter);border-color:rgba(var(--ax-sys-color-surface));padding:calc(var(--spacing, .25rem) * 4)}axm-integrations-page .axm-integrations-page__skeleton-icon{width:calc(var(--spacing, .25rem) * 14);height:calc(var(--spacing, .25rem) * 14);flex-shrink:0;border-radius:var(--radius-xl, .75rem)}axm-integrations-page .axm-integrations-page__skeleton-status-badge{height:calc(var(--spacing, .25rem) * 6);width:calc(var(--spacing, .25rem) * 20);flex-shrink:0;border-radius:calc(infinity * 1px)}axm-integrations-page .axm-integrations-page__skeleton-title{height:calc(var(--spacing, .25rem) * 5);width:calc(3 / 5 * 100%);border-radius:var(--radius-md, .375rem)}axm-integrations-page .axm-integrations-page__skeleton-description{height:calc(var(--spacing, .25rem) * 4);width:100%;border-radius:var(--radius-md, .375rem)}axm-integrations-page .axm-integrations-page__skeleton-description.--short{width:80%}axm-integrations-page .axm-integrations-page__skeleton-footer{margin-top:auto;display:flex;align-items:center;justify-content:space-between;gap:calc(var(--spacing, .25rem) * 3);border-top-style:var(--tw-border-style);border-top-width:1px;border-color:rgba(var(--ax-sys-color-surface));padding-top:calc(var(--spacing, .25rem) * 4)}axm-integrations-page .axm-integrations-page__skeleton-action{height:calc(var(--spacing, .25rem) * 8);width:calc(var(--spacing, .25rem) * 24);border-radius:var(--radius-md, .375rem)}axm-integrations-page .axm-integrations-page__skeleton-switch{height:calc(var(--spacing, .25rem) * 6);width:calc(var(--spacing, .25rem) * 11);border-radius:calc(infinity * 1px)}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-font-weight: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: i2.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i3.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "component", type: i3.AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: i3.AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items", "closeParentOnClick", "lockOnLoading"], outputs: ["onItemClick"] }, { kind: "ngmodule", type: AXCheckBoxModule }, { kind: "component", type: i4.AXCheckBoxComponent, selector: "ax-check-box", inputs: ["disabled", "tabIndex", "readonly", "color", "value", "name", "id", "isLoading", "indeterminate"], outputs: ["onBlur", "onFocus", "valueChange", "onValueChanged"] }, { kind: "ngmodule", type: AXDropdownButtonModule }, { kind: "component", type: i5.AXDropdownButtonComponent, selector: "ax-dropdown-button", inputs: ["disabled", "size", "text", "color", "look", "type", "mode"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "lookChange", "colorChange", "disabledChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i6.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i6.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXLabelModule }, { kind: "component", type: i7.AXLabelComponent, selector: "ax-label", inputs: ["required", "for"], outputs: ["requiredChange"] }, { kind: "ngmodule", type: AXSkeletonModule }, { kind: "component", type: i8.AXSkeletonComponent, selector: "ax-skeleton", inputs: ["animated"] }, { kind: "ngmodule", type: AXSwitchModule }, { kind: "component", type: i9.AXSwitchComponent, selector: "ax-switch", inputs: ["disabled", "readonly", "color", "tabIndex", "value", "name", "isLoading"], outputs: ["onBlur", "onFocus", "valueChange", "onValueChanged", "readonlyChange", "disabledChange"] }, { kind: "ngmodule", type: AXTooltipModule }, { kind: "directive", type: i10.AXTooltipDirective, selector: "[axTooltip]", inputs: ["axTooltipDisabled", "axTooltip", "axTooltipContext", "axTooltipPlacement", "axTooltipOffsetX", "axTooltipOffsetY", "axTooltipOpenAfter", "axTooltipCloseAfter"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXPLogoComponent, selector: "axp-logo", inputs: ["logoKey", "appearance", "size", "format"] }, { kind: "component", type: AXPPageLayoutComponent, selector: "axp-page-layout" }, { kind: "component", type: AXPStateMessageComponent, selector: "axp-state-message", inputs: ["mode", "icon", "title", "description", "titleParams", "descriptionParams", "look"] }, { kind: "component", type: AXPThemeLayoutBlockComponent, selector: " axp-page-content, axp-page-footer-container, axp-page-footer, axp-page-header, axp-page-header-container, axp-page-toolbar, axp-layout-content, axp-layout-page-content, axp-layout-sections, axp-layout-body, axp-layout-page-body, axp-layout-prefix, axp-layout-suffix, axp-layout-title-bar, axp-layout-title, axp-layout-title-actions, axp-layout-nav-button, axp-layout-description, axp-layout-breadcrumbs, axp-layout-list-action, " }, { kind: "component", type: AXPThemeLayoutStartSideComponent, selector: "axp-layout-page-start-side, axp-layout-start-side" }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: i11.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
381
+ }
382
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMIntegrationsPageComponent, decorators: [{
383
+ type: Component,
384
+ args: [{ selector: 'axm-integrations-page', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, providers: [{ provide: AXPPageLayoutBase, useExisting: AXMIntegrationsPageComponent }], imports: [
385
+ AsyncPipe,
386
+ FormsModule,
387
+ AXBadgeModule,
388
+ AXButtonModule,
389
+ AXCheckBoxModule,
390
+ AXDropdownButtonModule,
391
+ AXDecoratorModule,
392
+ AXLabelModule,
393
+ AXSkeletonModule,
394
+ AXSwitchModule,
395
+ AXTooltipModule,
396
+ AXTranslationModule,
397
+ AXPLogoComponent,
398
+ AXPPageLayoutComponent,
399
+ AXPStateMessageComponent,
400
+ AXPThemeLayoutBlockComponent,
401
+ AXPThemeLayoutStartSideComponent,
402
+ ], template: "<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", styles: ["@layer properties;axm-integrations-page axp-layout-start-side{min-width:calc(var(--spacing, .25rem) * 80)!important;border-inline-end-style:var(--tw-border-style);border-inline-end-width:1px}axm-integrations-page axp-layout-start-side axp-layout-content.axm-integrations-page__sidebar{flex:none;padding-inline:calc(var(--spacing, .25rem) * 4);padding-bottom:calc(var(--spacing, .25rem) * 4)}axm-integrations-page .axm-integrations-page__sidebar-section{margin-top:calc(var(--spacing, .25rem) * 4)}axm-integrations-page .axm-integrations-page__sidebar-section-title{margin:0;padding-bottom:calc(var(--spacing, .25rem) * 2);--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);opacity:85%}axm-integrations-page .axm-integrations-page__sidebar-section:first-child .axm-integrations-page__sidebar-section-title{padding-top:calc(var(--spacing, .25rem) * 4)}axm-integrations-page .axm-integrations-page__sidebar-section-body{display:flex;flex-direction:column;gap:calc(var(--spacing, .25rem) * 3)}axm-integrations-page .axm-integrations-page__overview-list,axm-integrations-page .axm-integrations-page__category-list{margin:0;display:flex;list-style-type:none;flex-direction:column;gap:var(--spacing, .25rem);padding:0}axm-integrations-page .axm-integrations-page__overview-item{display:flex;align-items:center;justify-content:space-between;gap:calc(var(--spacing, .25rem) * 3);padding-block:calc(var(--spacing, .25rem) * 1.5);font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)))}axm-integrations-page .axm-integrations-page__overview-label{display:inline-flex;min-width:0px;align-items:center;gap:calc(var(--spacing, .25rem) * 2.5)}axm-integrations-page .axm-integrations-page__overview-label ax-icon{font-size:var(--text-base, 1rem);line-height:var(--tw-leading, var(--text-base--line-height, 1.5 ));color:rgba(var(--ax-sys-color-text-default))}@supports (color: color-mix(in lab,red,red)){axm-integrations-page .axm-integrations-page__overview-label ax-icon{color:color-mix(in oklab,rgba(var(--ax-sys-color-text-default)) 80%,transparent)}}axm-integrations-page .axm-integrations-page__overview-count{display:inline-flex;min-width:calc(var(--spacing, .25rem) * 7);flex-shrink:0;align-items:center;justify-content:center;border-radius:var(--radius-md, .375rem);padding-inline:calc(var(--spacing, .25rem) * 2);padding-block:calc(var(--spacing, .25rem) * .5);font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);background-color:rgb(var(--ax-sys-color-surface));color:rgb(var(--ax-sys-color-on-surface))}axm-integrations-page .axm-integrations-page__overview-count.--danger{background-color:var(--color-danger);color:var(--color-on-danger);border-color:var(--color-border-danger)}axm-integrations-page .axm-integrations-page__category-item{padding-block:calc(var(--spacing, .25rem) * 1.5);font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)))}axm-integrations-page .axm-integrations-page__category-checkbox{width:100%}axm-integrations-page .axm-integrations-page__skeleton-sidebar-title{height:calc(var(--spacing, .25rem) * 6);width:calc(var(--spacing, .25rem) * 28);border-radius:var(--radius-md, .375rem)}axm-integrations-page .axm-integrations-page__skeleton-sidebar-row{height:calc(var(--spacing, .25rem) * 8);width:100%;border-radius:var(--radius-md, .375rem)}axm-integrations-page .axm-integrations-page__skeleton-section-title{height:calc(var(--spacing, .25rem) * 6);width:calc(var(--spacing, .25rem) * 40);border-radius:var(--radius-md, .375rem)}axm-integrations-page .axm-integrations-page__skeleton-section-description{height:calc(var(--spacing, .25rem) * 4);width:100%;max-width:var(--container-md, 28rem);border-radius:var(--radius-md, .375rem)}axm-integrations-page .axm-integrations-page__skeleton-card{display:flex;height:100%;width:100%;flex-direction:column;gap:calc(var(--spacing, .25rem) * 3);border-radius:var(--radius-xl, .75rem);border-style:var(--tw-border-style);border-width:1px;background-color:var(--color-lighter);color:var(--color-on-lighter);border-color:var(--color-border-lighter);border-color:rgba(var(--ax-sys-color-surface));padding:calc(var(--spacing, .25rem) * 4)}axm-integrations-page .axm-integrations-page__skeleton-icon{width:calc(var(--spacing, .25rem) * 14);height:calc(var(--spacing, .25rem) * 14);flex-shrink:0;border-radius:var(--radius-xl, .75rem)}axm-integrations-page .axm-integrations-page__skeleton-status-badge{height:calc(var(--spacing, .25rem) * 6);width:calc(var(--spacing, .25rem) * 20);flex-shrink:0;border-radius:calc(infinity * 1px)}axm-integrations-page .axm-integrations-page__skeleton-title{height:calc(var(--spacing, .25rem) * 5);width:calc(3 / 5 * 100%);border-radius:var(--radius-md, .375rem)}axm-integrations-page .axm-integrations-page__skeleton-description{height:calc(var(--spacing, .25rem) * 4);width:100%;border-radius:var(--radius-md, .375rem)}axm-integrations-page .axm-integrations-page__skeleton-description.--short{width:80%}axm-integrations-page .axm-integrations-page__skeleton-footer{margin-top:auto;display:flex;align-items:center;justify-content:space-between;gap:calc(var(--spacing, .25rem) * 3);border-top-style:var(--tw-border-style);border-top-width:1px;border-color:rgba(var(--ax-sys-color-surface));padding-top:calc(var(--spacing, .25rem) * 4)}axm-integrations-page .axm-integrations-page__skeleton-action{height:calc(var(--spacing, .25rem) * 8);width:calc(var(--spacing, .25rem) * 24);border-radius:var(--radius-md, .375rem)}axm-integrations-page .axm-integrations-page__skeleton-switch{height:calc(var(--spacing, .25rem) * 6);width:calc(var(--spacing, .25rem) * 11);border-radius:calc(infinity * 1px)}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-font-weight: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
403
+ }] });
404
+
405
+ export { AXMIntegrationsPageComponent };
406
+ //# sourceMappingURL=acorex-platform-module-integration-management-client-integrations-page.component-Q-SHidYA.mjs.map