@valtimo/plugin-management 13.46.0 → 13.47.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/fesm2022/valtimo-plugin-management.mjs +4829 -320
  2. package/fesm2022/valtimo-plugin-management.mjs.map +1 -1
  3. package/lib/components/plugin-add-modal/plugin-add-modal.component.d.ts +90 -14
  4. package/lib/components/plugin-add-select/plugin-add-select.component.d.ts +17 -11
  5. package/lib/components/plugin-app-add-modal/plugin-app-add-modal.component.d.ts +127 -0
  6. package/lib/components/plugin-apps-page/plugin-apps-page.component.d.ts +120 -0
  7. package/lib/components/plugin-edit-modal/plugin-edit-modal.component.d.ts +10 -1
  8. package/lib/components/plugin-external-configure/plugin-external-configure.component.d.ts +78 -0
  9. package/lib/components/plugin-external-edit-modal/plugin-external-edit-modal.component.d.ts +79 -0
  10. package/lib/components/plugin-external-permissions/plugin-external-permissions.component.d.ts +83 -0
  11. package/lib/components/plugin-external-review-modal/plugin-external-review-modal.component.d.ts +41 -0
  12. package/lib/components/plugin-host-connection-form/plugin-host-connection-form.component.d.ts +85 -0
  13. package/lib/components/plugin-host-edit-modal/plugin-host-edit-modal.component.d.ts +58 -0
  14. package/lib/components/plugin-host-event-queue-modal/plugin-host-event-queue-modal.component.d.ts +34 -0
  15. package/lib/components/plugin-host-frontend-origins-modal/plugin-host-frontend-origins-modal.component.d.ts +30 -0
  16. package/lib/components/plugin-host-modal/plugin-host-modal.component.d.ts +46 -0
  17. package/lib/components/plugin-hosts-page/plugin-hosts-page.component.d.ts +84 -0
  18. package/lib/components/plugin-log-modal/plugin-log-modal.component.d.ts +55 -0
  19. package/lib/components/plugin-management/plugin-management.component.d.ts +102 -13
  20. package/lib/components/plugin-upload-modal/plugin-upload-modal.component.d.ts +76 -0
  21. package/lib/components/plugin-usage-modal/plugin-usage-modal.component.d.ts +26 -0
  22. package/lib/constants/index.d.ts +2 -0
  23. package/lib/constants/plugin-app-add-modal.test-ids.d.ts +8 -0
  24. package/lib/constants/plugin-external-review-modal.test-ids.d.ts +4 -0
  25. package/lib/models/external-plugin-permissions.model.d.ts +6 -0
  26. package/lib/models/index.d.ts +2 -0
  27. package/lib/models/unified-plugin-definition.model.d.ts +41 -0
  28. package/lib/plugin-management.module.d.ts +12 -5
  29. package/lib/utils/csp-allows-origin.util.d.ts +13 -0
  30. package/lib/utils/external-plugin-compatibility.util.d.ts +11 -0
  31. package/lib/utils/external-plugin-egress.util.d.ts +15 -0
  32. package/lib/utils/index.d.ts +3 -0
  33. package/package.json +1 -1
  34. package/public-api.d.ts +5 -0
@@ -1,25 +1,101 @@
1
- import { EventEmitter } from '@angular/core';
1
+ import { EventEmitter, OnDestroy } from '@angular/core';
2
2
  import { PluginManagementStateService } from '../../services';
3
- import { BehaviorSubject, Subject } from 'rxjs';
4
- import { PluginConfigurationData, PluginManagementService } from '@valtimo/plugin';
3
+ import { BehaviorSubject, Observable } from 'rxjs';
4
+ import { ExternalPluginDefinition, ExternalPluginGrantedEndpointEntry, ExternalPluginGrantedEventEntry, ExternalPluginEndpoint, ExternalPluginService, PluginConfigurationData, PluginManagementService } from '@valtimo/plugin';
5
5
  import { NGXLogger } from 'ngx-logger';
6
+ import { TranslateService } from '@ngx-translate/core';
6
7
  import * as i0 from "@angular/core";
7
- export declare class PluginAddModalComponent {
8
- private readonly stateService;
9
- private readonly pluginManagementService;
10
- private readonly logger;
11
- open: boolean;
8
+ export declare class PluginAddModalComponent implements OnDestroy {
9
+ private readonly _stateService;
10
+ private readonly _pluginManagementService;
11
+ private readonly _externalPluginService;
12
+ private readonly _logger;
13
+ private readonly _translateService;
14
+ /**
15
+ * Opening with a plugin already selected — the "Configure plugin" action on the upload
16
+ * notification does exactly that — skips the choose-a-plugin step and lands on the configuration
17
+ * form, which is the whole point of that shortcut.
18
+ */
19
+ set open(value: boolean);
20
+ get open(): boolean;
21
+ set externalDefinitions(value: ExternalPluginDefinition[] | null);
22
+ get externalDefinitions(): ExternalPluginDefinition[] | null;
12
23
  closeModal: EventEmitter<boolean>;
13
- readonly inputDisabled$: import("rxjs").Observable<boolean>;
14
- readonly selectedPluginDefinition$: import("rxjs").Observable<import("@valtimo/plugin").PluginDefinition>;
24
+ readonly inputDisabled$: Observable<boolean>;
25
+ readonly selectedPluginDefinition$: Observable<import("@valtimo/plugin").PluginDefinition>;
15
26
  readonly configurationValid$: BehaviorSubject<boolean>;
16
- readonly returnToFirstStepSubject$: Subject<boolean>;
17
- constructor(stateService: PluginManagementStateService, pluginManagementService: PluginManagementService, logger: NGXLogger);
27
+ private _open;
28
+ private _externalDefinitions;
29
+ private readonly _externalDefinitions$;
30
+ readonly isExternalPlugin$: Observable<boolean>;
31
+ /**
32
+ * The localized compatibility warning to show on the configure step, or null when the selected
33
+ * plugin is embedded, compatible, or not yet chosen. Recomputed on language change so the message
34
+ * stays localized.
35
+ */
36
+ readonly incompatibleWarning$: Observable<string | null>;
37
+ readonly endpoints$: BehaviorSubject<ExternalPluginEndpoint[]>;
38
+ readonly eventSubscriptions$: BehaviorSubject<string[]>;
39
+ readonly capabilities$: BehaviorSubject<string[]>;
40
+ readonly egress$: BehaviorSubject<string[]>;
41
+ readonly derivedEgress$: BehaviorSubject<string[]>;
42
+ readonly permissionsValid$: BehaviorSubject<boolean>;
43
+ currentStepIndex: number;
44
+ isExternal: boolean;
45
+ progressSteps: Array<{
46
+ label: string;
47
+ complete: boolean;
48
+ }>;
49
+ private _externalConfigureComponent;
50
+ private readonly _subscriptions;
51
+ constructor(_stateService: PluginManagementStateService, _pluginManagementService: PluginManagementService, _externalPluginService: ExternalPluginService, _logger: NGXLogger, _translateService: TranslateService);
52
+ ngOnDestroy(): void;
53
+ /**
54
+ * Lands on the configuration step when the modal is opened while a plugin is already selected.
55
+ * The step count itself is already right by now: `isExternal` is kept in sync from the
56
+ * constructor's `isExternalPlugin$` subscription, which fires synchronously off the selection.
57
+ */
58
+ private _skipSelectStepWhenPreselected;
59
+ goToNextStep(): void;
18
60
  complete(): void;
19
61
  hide(): void;
20
62
  onValid(valid: boolean): void;
21
63
  onConfiguration(configuration: PluginConfigurationData): void;
22
- private returnToFirstStep;
64
+ onEndpointsResolved(endpoints: Array<ExternalPluginEndpoint>): void;
65
+ onEventSubscriptionsResolved(eventTypes: Array<string>): void;
66
+ onPermissionsValid(valid: boolean): void;
67
+ onGrantedEndpointsChange(endpoints: Array<ExternalPluginGrantedEndpointEntry>): void;
68
+ onGrantedEventsChange(events: Array<ExternalPluginGrantedEventEntry>): void;
69
+ onCapabilitiesResolved(caps: Array<string>): void;
70
+ onGrantedCapabilitiesChange(caps: Array<string>): void;
71
+ onEgressResolved(targets: Array<string>): void;
72
+ /**
73
+ * Derived destinations don't gate the step — the admin already supplied them by typing the value —
74
+ * so this only refreshes the display.
75
+ */
76
+ onDerivedEgressResolved(targets: Array<string>): void;
77
+ onGrantedEgressChange(targets: Array<string>): void;
78
+ onExternalSave(event: {
79
+ definitionId: string;
80
+ title: string;
81
+ properties: Record<string, unknown>;
82
+ grantedEndpoints: Array<ExternalPluginGrantedEndpointEntry>;
83
+ grantedEvents: Array<ExternalPluginGrantedEventEntry>;
84
+ grantedCapabilities: Array<string>;
85
+ grantedEgress: Array<string>;
86
+ }): void;
87
+ /**
88
+ * Permissions step starts valid (no acknowledgement required) only when the plugin declared nothing
89
+ * to acknowledge — no endpoints, events, capabilities or manifest egress targets. The
90
+ * acknowledgement otherwise gates the step.
91
+ */
92
+ private _recomputePermissionsValid;
93
+ /**
94
+ * Carbon's progress indicator recomputes step completion only inside its `current` setter, so a
95
+ * rebuilt steps array (language change, plugin-kind change) must carry the `complete` flags
96
+ * itself — with an unchanged current step the rebuild would otherwise wipe the checkmarks.
97
+ */
98
+ private _buildProgressSteps;
23
99
  static ɵfac: i0.ɵɵFactoryDeclaration<PluginAddModalComponent, never>;
24
- static ɵcmp: i0.ɵɵComponentDeclaration<PluginAddModalComponent, "valtimo-plugin-add-modal", never, { "open": { "alias": "open"; "required": false; }; }, { "closeModal": "closeModal"; }, never, never, false, never>;
100
+ static ɵcmp: i0.ɵɵComponentDeclaration<PluginAddModalComponent, "valtimo-plugin-add-modal", never, { "open": { "alias": "open"; "required": false; }; "externalDefinitions": { "alias": "externalDefinitions"; "required": false; }; }, { "closeModal": "closeModal"; }, never, never, false, never>;
25
101
  }
@@ -1,29 +1,35 @@
1
1
  import { OnDestroy, OnInit } from '@angular/core';
2
+ import { TranslateService } from '@ngx-translate/core';
3
+ import { Observable } from 'rxjs';
2
4
  import { PluginManagementStateService } from '../../services';
3
- import { PluginDefinition, PluginManagementService } from '@valtimo/plugin';
5
+ import { UnifiedPluginDefinition } from '../../models';
6
+ import { ExternalPluginDefinition, PluginDefinition, PluginManagementService } from '@valtimo/plugin';
4
7
  import * as i0 from "@angular/core";
5
8
  export declare class PluginAddSelectComponent implements OnInit, OnDestroy {
6
- private readonly pluginManagementService;
7
- private readonly stateService;
8
- readonly selectedPluginDefinition$: import("rxjs").Observable<PluginDefinition>;
9
- readonly disabled$: import("rxjs").Observable<boolean>;
10
- readonly pluginDefinitionsWithLogos$: import("rxjs").Observable<import("@valtimo/plugin").PluginDefinitionWithLogo[]>;
9
+ private readonly _pluginManagementService;
10
+ private readonly _stateService;
11
+ private readonly _translateService;
12
+ set externalDefinitions(value: ExternalPluginDefinition[] | null);
13
+ readonly selectedPluginDefinition$: Observable<PluginDefinition>;
14
+ readonly disabled$: Observable<boolean>;
11
15
  readonly testIds: {
12
16
  readonly tileGrid: "pluginCatalogTileGrid";
13
17
  readonly tileLogo: "pluginCatalogTileLogo";
14
18
  readonly tileTitle: "pluginCatalogTileTitle";
15
19
  readonly tileDescription: "pluginCatalogTileDescription";
16
20
  };
17
- private refreshSubscription;
18
- constructor(pluginManagementService: PluginManagementService, stateService: PluginManagementStateService);
21
+ private readonly _externalDefs$;
22
+ readonly allDefinitions$: Observable<UnifiedPluginDefinition[] | undefined>;
23
+ private readonly _subscriptions;
24
+ constructor(_pluginManagementService: PluginManagementService, _stateService: PluginManagementStateService, _translateService: TranslateService);
19
25
  ngOnInit(): void;
20
26
  ngOnDestroy(): void;
21
27
  selectPluginDefinition(event: {
22
28
  value: PluginDefinition;
23
29
  }): void;
24
30
  deselectPluginDefinition(): void;
25
- private getPluginDefinitions;
26
- private openRefreshSubscription;
31
+ private _getPluginDefinitions;
32
+ private _openRefreshSubscription;
27
33
  static ɵfac: i0.ɵɵFactoryDeclaration<PluginAddSelectComponent, never>;
28
- static ɵcmp: i0.ɵɵComponentDeclaration<PluginAddSelectComponent, "valtimo-plugin-add-select", never, {}, {}, never, never, false, never>;
34
+ static ɵcmp: i0.ɵɵComponentDeclaration<PluginAddSelectComponent, "valtimo-plugin-add-select", never, { "externalDefinitions": { "alias": "externalDefinitions"; "required": false; }; }, {}, never, never, false, never>;
29
35
  }
@@ -0,0 +1,127 @@
1
+ import { EventEmitter, OnChanges, OnDestroy, SimpleChanges } from '@angular/core';
2
+ import { TranslateService } from '@ngx-translate/core';
3
+ import { ExternalPluginDefinition, ExternalPluginGrantedEndpointEntry, ExternalPluginGrantedEventEntry, ExternalPluginEndpoint, ExternalPluginService } from '@valtimo/plugin';
4
+ import { NGXLogger } from 'ngx-logger';
5
+ import { BehaviorSubject } from 'rxjs';
6
+ import * as i0 from "@angular/core";
7
+ type ConnectState = 'idle' | 'connecting' | 'connected' | 'failed' | 'conflict' | 'timeout';
8
+ /**
9
+ * Connects an app and configures it in a single stepper: Connect → Enter data → Permissions.
10
+ *
11
+ * Connecting registers the app as an external plugin host (kind APP) and waits for the app's
12
+ * plugin definition to be discovered. Because the CSP meta tag is fixed at bootstrap, an app that
13
+ * ships its own config bundle cannot be framed until the page is reloaded — in that case a
14
+ * confirmation dialog announces the refresh and the flow resumes at the configuration step via
15
+ * the `configureApp` query parameter on the apps page (see {@link PluginAppsPageComponent}).
16
+ * When the current CSP already allows the app's origin (or no CSP is configured), the stepper
17
+ * continues without a refresh.
18
+ */
19
+ export declare class PluginAppAddModalComponent implements OnChanges, OnDestroy {
20
+ private readonly _externalPluginService;
21
+ private readonly _translateService;
22
+ private readonly _logger;
23
+ private _connectionForm;
24
+ private _configureComponent;
25
+ open: boolean;
26
+ /** When set, the stepper opens at the configuration step for this already-connected app. */
27
+ resumeHostId: string | null;
28
+ closeEvent: EventEmitter<void>;
29
+ completedEvent: EventEmitter<void>;
30
+ readonly $currentStep: import("@angular/core").WritableSignal<number>;
31
+ readonly $connectState: import("@angular/core").WritableSignal<ConnectState>;
32
+ readonly $connectionFormValid: import("@angular/core").WritableSignal<boolean>;
33
+ readonly $definition: import("@angular/core").WritableSignal<ExternalPluginDefinition>;
34
+ readonly $resolvingDefinition: import("@angular/core").WritableSignal<boolean>;
35
+ readonly $resumeLoadFailed: import("@angular/core").WritableSignal<boolean>;
36
+ readonly $configValid: import("@angular/core").WritableSignal<boolean>;
37
+ readonly $permissionsValid: import("@angular/core").WritableSignal<boolean>;
38
+ readonly $saving: import("@angular/core").WritableSignal<boolean>;
39
+ readonly $endpoints: import("@angular/core").WritableSignal<ExternalPluginEndpoint[]>;
40
+ readonly $eventSubscriptions: import("@angular/core").WritableSignal<string[]>;
41
+ readonly $capabilities: import("@angular/core").WritableSignal<string[]>;
42
+ readonly $egress: import("@angular/core").WritableSignal<string[]>;
43
+ readonly $derivedEgress: import("@angular/core").WritableSignal<string[]>;
44
+ /** Details of the conflicting registration, shown when connecting is rejected with a 409. */
45
+ readonly $conflict: import("@angular/core").WritableSignal<{
46
+ pluginId: string;
47
+ hostName: string;
48
+ }>;
49
+ /**
50
+ * Why connecting failed, rendered in the failed notification. The backend answers a fixable
51
+ * mistake (a bind address as base URL, a broker over plaintext HTTP) with a 400 whose `detail`
52
+ * explains it — `createHost` keeps that off the global error toast so it can be shown here.
53
+ */
54
+ readonly $connectError: import("@angular/core").WritableSignal<string>;
55
+ readonly refreshModalOpen$: BehaviorSubject<boolean>;
56
+ progressSteps: Array<{
57
+ label: string;
58
+ complete: boolean;
59
+ }>;
60
+ protected readonly testIds: {
61
+ readonly cancelButton: "pluginAppAddModalCancelButton";
62
+ readonly connectButton: "pluginAppAddModalConnectButton";
63
+ readonly continueButton: "pluginAppAddModalContinueButton";
64
+ readonly retryButton: "pluginAppAddModalRetryButton";
65
+ readonly nextButton: "pluginAppAddModalNextButton";
66
+ readonly completeButton: "pluginAppAddModalCompleteButton";
67
+ };
68
+ private _host;
69
+ private _definitionPollSubscription;
70
+ private readonly _subscriptions;
71
+ /** The connection form stays locked from the moment the host is created. */
72
+ get connectionLocked(): boolean;
73
+ constructor(_externalPluginService: ExternalPluginService, _translateService: TranslateService, _logger: NGXLogger);
74
+ ngOnChanges(changes: SimpleChanges): void;
75
+ ngOnDestroy(): void;
76
+ onConnectionFormValidChange(valid: boolean): void;
77
+ onConnect(): void;
78
+ onRetryDiscovery(): void;
79
+ onContinue(): void;
80
+ onRefreshConfirm(): void;
81
+ onRefreshCancel(): void;
82
+ onConfigValid(valid: boolean): void;
83
+ onEndpointsResolved(endpoints: Array<ExternalPluginEndpoint>): void;
84
+ onEventSubscriptionsResolved(eventTypes: Array<string>): void;
85
+ onCapabilitiesResolved(capabilities: Array<string>): void;
86
+ onEgressResolved(targets: Array<string>): void;
87
+ onDerivedEgressResolved(targets: Array<string>): void;
88
+ onPermissionsValid(valid: boolean): void;
89
+ onGrantedEndpointsChange(endpoints: Array<ExternalPluginGrantedEndpointEntry>): void;
90
+ onGrantedEventsChange(events: Array<ExternalPluginGrantedEventEntry>): void;
91
+ onGrantedCapabilitiesChange(capabilities: Array<string>): void;
92
+ onGrantedEgressChange(targets: Array<string>): void;
93
+ goToPermissionsStep(): void;
94
+ onComplete(): void;
95
+ onExternalSave(event: {
96
+ definitionId: string;
97
+ title: string;
98
+ properties: Record<string, unknown>;
99
+ grantedEndpoints: Array<ExternalPluginGrantedEndpointEntry>;
100
+ grantedEvents: Array<ExternalPluginGrantedEventEntry>;
101
+ grantedCapabilities: Array<string>;
102
+ grantedEgress: Array<string>;
103
+ }): void;
104
+ onClose(): void;
105
+ private _startResume;
106
+ /**
107
+ * Discovery runs synchronously (best-effort) when the host is created, so the definition is
108
+ * usually there on the first try; the poll covers an app that is slow to come up, bounded to
109
+ * roughly the backend's own periodic discovery interval.
110
+ */
111
+ private _pollForDefinition;
112
+ private _stopDefinitionPoll;
113
+ private _buildResumeUrl;
114
+ /** See `PluginHostsPageComponent._extractHostError` — the message precedence is identical. */
115
+ private _extractConnectError;
116
+ private _resetAfterClose;
117
+ /**
118
+ * Carbon's progress indicator recomputes step completion only inside its `current` setter, so a
119
+ * rebuilt steps array must carry the `complete` flags itself: a rebuild with an unchanged current
120
+ * step — the translation file finishing to load after the modal already resumed at the
121
+ * configuration step — would otherwise wipe the checkmarks of the completed steps.
122
+ */
123
+ private _buildProgressSteps;
124
+ static ɵfac: i0.ɵɵFactoryDeclaration<PluginAppAddModalComponent, never>;
125
+ static ɵcmp: i0.ɵɵComponentDeclaration<PluginAppAddModalComponent, "valtimo-plugin-app-add-modal", never, { "open": { "alias": "open"; "required": false; }; "resumeHostId": { "alias": "resumeHostId"; "required": false; }; }, { "closeEvent": "closeEvent"; "completedEvent": "completedEvent"; }, never, never, true, never>;
126
+ }
127
+ export {};
@@ -0,0 +1,120 @@
1
+ import { OnDestroy, OnInit } from '@angular/core';
2
+ import { ActivatedRoute, Router } from '@angular/router';
3
+ import { TranslateService } from '@ngx-translate/core';
4
+ import { ActionItem, CarbonTag, ColumnConfig } from '@valtimo/components';
5
+ import { ExternalPluginConfiguration, ExternalPluginDefinition, ExternalPluginHost, ExternalPluginHostConnectionUpdateRequest, ExternalPluginHostEventQueueUpdateRequest, ExternalPluginHostUsage, ExternalPluginService } from '@valtimo/plugin';
6
+ import { BehaviorSubject, Observable } from 'rxjs';
7
+ import { NGXLogger } from 'ngx-logger';
8
+ import { UnifiedPluginConfigurationRow } from '../../models';
9
+ import * as i0 from "@angular/core";
10
+ /** One row on the apps page: the APP-kind host enriched with its discovered plugin and configuration. */
11
+ interface PluginAppRow extends ExternalPluginHost {
12
+ statusTags: CarbonTag[];
13
+ lastHealthCheckFormatted: string;
14
+ configurationTitle: string;
15
+ definition: ExternalPluginDefinition | null;
16
+ configuration: ExternalPluginConfiguration | null;
17
+ /** Whether the app's plugin declares the `log` capability — apps without it serve no logs endpoint. */
18
+ supportsLogs: boolean;
19
+ /** The app changed its manifest/version after acceptance; an admin must review before it runs again. */
20
+ reviewRequired: boolean;
21
+ }
22
+ export declare class PluginAppsPageComponent implements OnInit, OnDestroy {
23
+ private readonly _logger;
24
+ private readonly _route;
25
+ private readonly _router;
26
+ private readonly _translateService;
27
+ private readonly _externalPluginService;
28
+ private readonly _destroy$;
29
+ private readonly _refreshApps$;
30
+ private _appsInitialLoad;
31
+ private readonly _tabVisible$;
32
+ readonly appsLoading$: BehaviorSubject<boolean>;
33
+ readonly appsRefreshing$: BehaviorSubject<boolean>;
34
+ readonly $addModalOpen: import("@angular/core").WritableSignal<boolean>;
35
+ readonly $resumeHostId: import("@angular/core").WritableSignal<string>;
36
+ readonly refreshModalOpen$: BehaviorSubject<boolean>;
37
+ private _pendingRefreshHostId;
38
+ readonly $editModalOpen: import("@angular/core").WritableSignal<boolean>;
39
+ readonly $selectedConfiguration: import("@angular/core").WritableSignal<UnifiedPluginConfigurationRow>;
40
+ readonly $reviewModalOpen: import("@angular/core").WritableSignal<boolean>;
41
+ readonly $reviewDefinition: import("@angular/core").WritableSignal<ExternalPluginDefinition>;
42
+ readonly deleteConfigurationModalOpen$: BehaviorSubject<boolean>;
43
+ configurationToDelete: {
44
+ id: string;
45
+ title: string;
46
+ } | null;
47
+ readonly $logModalOpen: import("@angular/core").WritableSignal<boolean>;
48
+ readonly $logConfigurationId: import("@angular/core").WritableSignal<string>;
49
+ readonly $logConfigurationTitle: import("@angular/core").WritableSignal<string>;
50
+ readonly deleteHostModalOpen$: BehaviorSubject<boolean>;
51
+ hostToDelete: ExternalPluginHost | null;
52
+ readonly eventQueueModalOpen$: BehaviorSubject<boolean>;
53
+ readonly hostToEditEventQueue$: BehaviorSubject<ExternalPluginHost>;
54
+ readonly editConnectionModalOpen$: BehaviorSubject<boolean>;
55
+ readonly hostToEditConnection$: BehaviorSubject<ExternalPluginHost>;
56
+ readonly editConnectionSubmitting$: BehaviorSubject<boolean>;
57
+ readonly editConnectionErrorMessage$: BehaviorSubject<string>;
58
+ readonly reloadModalOpen$: BehaviorSubject<boolean>;
59
+ readonly frontendOriginsModalOpen$: BehaviorSubject<boolean>;
60
+ readonly hostToEditFrontendOrigins$: BehaviorSubject<ExternalPluginHost>;
61
+ readonly usageModalOpen$: BehaviorSubject<boolean>;
62
+ readonly usageModalUsages$: BehaviorSubject<ExternalPluginHostUsage[]>;
63
+ usageModalEntityName: string | null;
64
+ usageModalTitleKey: string;
65
+ usageModalDescriptionKey: string;
66
+ readonly appFields: ColumnConfig[];
67
+ readonly appActionItems: ActionItem[];
68
+ readonly apps$: Observable<Array<PluginAppRow>>;
69
+ constructor(_logger: NGXLogger, _route: ActivatedRoute, _router: Router, _translateService: TranslateService, _externalPluginService: ExternalPluginService);
70
+ ngOnInit(): void;
71
+ ngOnDestroy(): void;
72
+ openAddModal(): void;
73
+ onAddModalClose(): void;
74
+ onAddModalCompleted(): void;
75
+ onRowClicked(row: PluginAppRow): void;
76
+ reviewChanges(row: PluginAppRow): void;
77
+ closeReviewModal(): void;
78
+ onReviewAccepted(): void;
79
+ configureApp(row: PluginAppRow): void;
80
+ onRefreshConfirm(): void;
81
+ onRefreshCancel(): void;
82
+ private _openResume;
83
+ private _closeAddModal;
84
+ /** Keeps the resume parameter in the URL while configuring, so a manual reload restores the step. */
85
+ private _setConfigureAppQueryParam;
86
+ editConfiguration(row: PluginAppRow): void;
87
+ closeEditModal(): void;
88
+ onConfigurationSaved(): void;
89
+ onConfigurationDeleteRequested(configurationId: string): void;
90
+ confirmDeleteConfiguration(): void;
91
+ cancelDeleteConfiguration(): void;
92
+ viewLogs(row: PluginAppRow): void;
93
+ closeLogModal(): void;
94
+ deleteHost(host: ExternalPluginHost): void;
95
+ confirmDeleteHost(): void;
96
+ cancelDeleteHost(): void;
97
+ editHostEventQueue(host: ExternalPluginHost): void;
98
+ closeEventQueueModal(): void;
99
+ submitEventQueueUpdate(request: ExternalPluginHostEventQueueUpdateRequest): void;
100
+ editHostConnection(host: ExternalPluginHost): void;
101
+ closeEditConnectionModal(): void;
102
+ /** Same reload rule as the hosts page: a new base URL means a new CSP frame origin. */
103
+ submitConnectionUpdate(patch: ExternalPluginHostConnectionUpdateRequest): void;
104
+ confirmReload(): void;
105
+ cancelReload(): void;
106
+ editHostFrontendOrigins(host: ExternalPluginHost): void;
107
+ closeFrontendOriginsModal(): void;
108
+ submitFrontendOriginsUpdate(origins: Array<string>): void;
109
+ /** Mirrors the hosts page: `detail` is the operator-facing reason the validation mapper fills. */
110
+ private _extractHostError;
111
+ closeUsageModal(): void;
112
+ private _toAppRow;
113
+ private _showHostInUseModal;
114
+ private _showConfigurationInUseModal;
115
+ private _getStatusTag;
116
+ private _formatLastHealthCheck;
117
+ static ɵfac: i0.ɵɵFactoryDeclaration<PluginAppsPageComponent, never>;
118
+ static ɵcmp: i0.ɵɵComponentDeclaration<PluginAppsPageComponent, "ng-component", never, {}, {}, never, never, true, never>;
119
+ }
120
+ export {};
@@ -11,6 +11,10 @@ export declare class PluginEditModalComponent {
11
11
  readonly open = false;
12
12
  readonly saveNewConfiguration = false;
13
13
  closeModal: EventEmitter<boolean>;
14
+ deleteEvent: EventEmitter<{
15
+ configurationId: string;
16
+ configurationTitle: string;
17
+ }>;
14
18
  readonly inputDisabled$: Observable<boolean>;
15
19
  readonly selectedPluginConfiguration$: Observable<PluginConfiguration>;
16
20
  readonly configurationValid$: BehaviorSubject<boolean>;
@@ -20,11 +24,16 @@ export declare class PluginEditModalComponent {
20
24
  };
21
25
  constructor(stateService: PluginManagementStateService, pluginManagementService: PluginManagementService, logger: NGXLogger);
22
26
  save(): void;
27
+ /**
28
+ * Bubble the delete request up to the parent so the shared usage pre-check +
29
+ * destructive-confirmation flow runs in one place (mirrors how the external edit modal works).
30
+ * The parent closes this modal as part of that flow.
31
+ */
23
32
  delete(): void;
24
33
  hide(): void;
25
34
  onPluginValid(valid: boolean): void;
26
35
  onPluginConfiguration(configuration: PluginConfigurationData): void;
27
36
  private saveNewPluginConfiguration;
28
37
  static ɵfac: i0.ɵɵFactoryDeclaration<PluginEditModalComponent, never>;
29
- static ɵcmp: i0.ɵɵComponentDeclaration<PluginEditModalComponent, "valtimo-plugin-edit-modal", never, { "open": { "alias": "open"; "required": false; }; "saveNewConfiguration": { "alias": "saveNewConfiguration"; "required": false; }; }, { "closeModal": "closeModal"; }, never, never, false, never>;
38
+ static ɵcmp: i0.ɵɵComponentDeclaration<PluginEditModalComponent, "valtimo-plugin-edit-modal", never, { "open": { "alias": "open"; "required": false; }; "saveNewConfiguration": { "alias": "saveNewConfiguration"; "required": false; }; }, { "closeModal": "closeModal"; "deleteEvent": "deleteEvent"; }, never, never, false, never>;
30
39
  }
@@ -0,0 +1,78 @@
1
+ import { EventEmitter, OnDestroy, OnInit } from '@angular/core';
2
+ import { FormControl, FormGroup } from '@angular/forms';
3
+ import { ExternalPluginGrantedEndpointEntry, ExternalPluginGrantedEventEntry, ExternalPluginEndpoint, ExternalPluginService } from '@valtimo/plugin';
4
+ import { PluginManagementStateService } from '../../services';
5
+ import * as i0 from "@angular/core";
6
+ interface ExternalPluginSaveEvent {
7
+ definitionId: string;
8
+ title: string;
9
+ properties: Record<string, unknown>;
10
+ grantedEndpoints: Array<ExternalPluginGrantedEndpointEntry>;
11
+ grantedEvents: Array<ExternalPluginGrantedEventEntry>;
12
+ grantedCapabilities: Array<string>;
13
+ grantedEgress: Array<string>;
14
+ }
15
+ /**
16
+ * The "enter data" step for an external plugin configuration: the plugin's own config bundle in an
17
+ * iframe when it ships one, a title + JSON properties fallback otherwise.
18
+ *
19
+ * Works in two modes:
20
+ * - Bound to {@link PluginManagementStateService} (the plugins page add modal): the definition
21
+ * follows the selected plugin and saving is triggered through the state service's `save$`.
22
+ * - Standalone via the `definitionId` input (the app add stepper): the definition is loaded
23
+ * directly and saving is triggered imperatively through {@link triggerSave}.
24
+ */
25
+ export declare class PluginExternalConfigureComponent implements OnInit, OnDestroy {
26
+ private readonly _stateService;
27
+ private readonly _externalPluginService;
28
+ /** When set, configures this definition directly instead of the state service's selection. */
29
+ definitionId: string | null;
30
+ validEvent: EventEmitter<boolean>;
31
+ saveEvent: EventEmitter<ExternalPluginSaveEvent>;
32
+ endpointsResolved: EventEmitter<ExternalPluginEndpoint[]>;
33
+ eventSubscriptionsResolved: EventEmitter<string[]>;
34
+ capabilitiesResolved: EventEmitter<string[]>;
35
+ egressResolved: EventEmitter<string[]>;
36
+ /**
37
+ * The origins GZAC will derive from the configuration values entered on this step, recomputed as
38
+ * they change. Not a grant — the admin supplying the URL is the grant — but the permissions step
39
+ * shows them so the full destination set is visible before activation.
40
+ */
41
+ derivedEgressResolved: EventEmitter<string[]>;
42
+ readonly $configBundleUrl: import("@angular/core").WritableSignal<string>;
43
+ readonly $loading: import("@angular/core").WritableSignal<boolean>;
44
+ readonly _form: FormGroup<{
45
+ title: FormControl<string>;
46
+ properties: FormControl<string>;
47
+ }>;
48
+ private _definitionId;
49
+ private _iframeConfigTitle;
50
+ private _iframeConfigData;
51
+ private _grantedEndpoints;
52
+ private _grantedEvents;
53
+ private _grantedCapabilities;
54
+ private _grantedEgress;
55
+ private _configurationSchema;
56
+ private readonly _subscriptions;
57
+ constructor(_stateService: PluginManagementStateService, _externalPluginService: ExternalPluginService);
58
+ ngOnInit(): void;
59
+ ngOnDestroy(): void;
60
+ /** Imperative save trigger for the `definitionId` mode (mirrors the state service's `save$`). */
61
+ triggerSave(): void;
62
+ onIframeConfigurationChanged(event: {
63
+ valid: boolean;
64
+ title: string;
65
+ data: Record<string, unknown>;
66
+ }): void;
67
+ setGrantedEndpoints(endpoints: Array<ExternalPluginGrantedEndpointEntry>): void;
68
+ setGrantedEvents(events: Array<ExternalPluginGrantedEventEntry>): void;
69
+ setGrantedCapabilities(caps: Array<string>): void;
70
+ setGrantedEgress(targets: Array<string>): void;
71
+ private _applyDefinition;
72
+ private _emitDerivedEgress;
73
+ private _validateForm;
74
+ private _onSaveTriggered;
75
+ static ɵfac: i0.ɵɵFactoryDeclaration<PluginExternalConfigureComponent, never>;
76
+ static ɵcmp: i0.ɵɵComponentDeclaration<PluginExternalConfigureComponent, "valtimo-plugin-external-configure", never, { "definitionId": { "alias": "definitionId"; "required": false; }; }, { "validEvent": "validEvent"; "saveEvent": "saveEvent"; "endpointsResolved": "endpointsResolved"; "eventSubscriptionsResolved": "eventSubscriptionsResolved"; "capabilitiesResolved": "capabilitiesResolved"; "egressResolved": "egressResolved"; "derivedEgressResolved": "derivedEgressResolved"; }, never, never, true, never>;
77
+ }
78
+ export {};
@@ -0,0 +1,79 @@
1
+ import { EventEmitter, OnChanges, OnDestroy, SimpleChanges } from '@angular/core';
2
+ import { TranslateService } from '@ngx-translate/core';
3
+ import { FormControl, FormGroup } from '@angular/forms';
4
+ import { ExternalPluginEndpoint, ExternalPluginService } from '@valtimo/plugin';
5
+ import { UnifiedPluginConfigurationRow } from '../../models';
6
+ import * as i0 from "@angular/core";
7
+ export declare class PluginExternalEditModalComponent implements OnChanges, OnDestroy {
8
+ private readonly _externalPluginService;
9
+ private readonly _translateService;
10
+ open: boolean;
11
+ configuration: UnifiedPluginConfigurationRow | null;
12
+ closeEvent: EventEmitter<void>;
13
+ savedEvent: EventEmitter<void>;
14
+ deleteEvent: EventEmitter<string>;
15
+ readonly _form: FormGroup<{
16
+ title: FormControl<string>;
17
+ properties: FormControl<string>;
18
+ }>;
19
+ readonly $loading: import("@angular/core").WritableSignal<boolean>;
20
+ readonly $propertiesInvalid: import("@angular/core").WritableSignal<boolean>;
21
+ readonly $configBundleUrl: import("@angular/core").WritableSignal<string>;
22
+ readonly $prefillConfiguration: import("@angular/core").WritableSignal<{
23
+ title: string;
24
+ configuration: Record<string, unknown>;
25
+ }>;
26
+ readonly $endpoints: import("@angular/core").WritableSignal<ExternalPluginEndpoint[]>;
27
+ readonly $eventSubscriptions: import("@angular/core").WritableSignal<string[]>;
28
+ readonly $capabilities: import("@angular/core").WritableSignal<string[]>;
29
+ readonly $egress: import("@angular/core").WritableSignal<string[]>;
30
+ /**
31
+ * Destinations derived from this configuration's own `x-egress-target` values. Taken from the saved
32
+ * configuration rather than recomputed locally, so the list matches what GZAC pushed to the host.
33
+ */
34
+ readonly $derivedEgress: import("@angular/core").WritableSignal<string[]>;
35
+ readonly $permissionsValid: import("@angular/core").WritableSignal<boolean>;
36
+ readonly $hasPermissionsStep: import("@angular/core").WritableSignal<boolean>;
37
+ readonly $definitionName: import("@angular/core").WritableSignal<string>;
38
+ readonly $awaitingHost: import("@angular/core").WritableSignal<boolean>;
39
+ currentStepIndex: number;
40
+ progressSteps: Array<{
41
+ label: string;
42
+ complete: boolean;
43
+ }>;
44
+ private _iframeConfigTitle;
45
+ private _iframeConfigData;
46
+ private readonly _$configurationSchema;
47
+ private readonly _$iframeValid;
48
+ private readonly _$definition;
49
+ private readonly _subscriptions;
50
+ private _propertiesValueSubscription;
51
+ constructor(_externalPluginService: ExternalPluginService, _translateService: TranslateService);
52
+ ngOnDestroy(): void;
53
+ ngOnChanges(changes: SimpleChanges): void;
54
+ goToNextStep(): void;
55
+ onSave(): void;
56
+ onDelete(): void;
57
+ onClose(): void;
58
+ onIframeConfigurationChanged(event: {
59
+ valid: boolean;
60
+ title: string;
61
+ data: Record<string, unknown>;
62
+ }): void;
63
+ onPermissionsValid(valid: boolean): void;
64
+ get configValid(): boolean;
65
+ private _saveFromIframe;
66
+ private _initForm;
67
+ private _setDefinition;
68
+ private _updateDefinitionName;
69
+ private _resolveConfigBundleUrl;
70
+ /**
71
+ * Carbon's progress indicator recomputes step completion only inside its `current` setter, so a
72
+ * rebuilt steps array (language change, permissions step appearing) must carry the `complete`
73
+ * flags itself — with an unchanged current step the rebuild would otherwise wipe the checkmarks.
74
+ */
75
+ private _buildProgressSteps;
76
+ private _resetForm;
77
+ static ɵfac: i0.ɵɵFactoryDeclaration<PluginExternalEditModalComponent, never>;
78
+ static ɵcmp: i0.ɵɵComponentDeclaration<PluginExternalEditModalComponent, "valtimo-plugin-external-edit-modal", never, { "open": { "alias": "open"; "required": false; }; "configuration": { "alias": "configuration"; "required": false; }; }, { "closeEvent": "closeEvent"; "savedEvent": "savedEvent"; "deleteEvent": "deleteEvent"; }, never, never, true, never>;
79
+ }