@valtimo/plugin-management 13.45.1 → 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.
- package/fesm2022/valtimo-plugin-management.mjs +4829 -320
- package/fesm2022/valtimo-plugin-management.mjs.map +1 -1
- package/lib/components/plugin-add-modal/plugin-add-modal.component.d.ts +90 -14
- package/lib/components/plugin-add-select/plugin-add-select.component.d.ts +17 -11
- package/lib/components/plugin-app-add-modal/plugin-app-add-modal.component.d.ts +127 -0
- package/lib/components/plugin-apps-page/plugin-apps-page.component.d.ts +120 -0
- package/lib/components/plugin-edit-modal/plugin-edit-modal.component.d.ts +10 -1
- package/lib/components/plugin-external-configure/plugin-external-configure.component.d.ts +78 -0
- package/lib/components/plugin-external-edit-modal/plugin-external-edit-modal.component.d.ts +79 -0
- package/lib/components/plugin-external-permissions/plugin-external-permissions.component.d.ts +83 -0
- package/lib/components/plugin-external-review-modal/plugin-external-review-modal.component.d.ts +41 -0
- package/lib/components/plugin-host-connection-form/plugin-host-connection-form.component.d.ts +85 -0
- package/lib/components/plugin-host-edit-modal/plugin-host-edit-modal.component.d.ts +58 -0
- package/lib/components/plugin-host-event-queue-modal/plugin-host-event-queue-modal.component.d.ts +34 -0
- package/lib/components/plugin-host-frontend-origins-modal/plugin-host-frontend-origins-modal.component.d.ts +30 -0
- package/lib/components/plugin-host-modal/plugin-host-modal.component.d.ts +46 -0
- package/lib/components/plugin-hosts-page/plugin-hosts-page.component.d.ts +84 -0
- package/lib/components/plugin-log-modal/plugin-log-modal.component.d.ts +55 -0
- package/lib/components/plugin-management/plugin-management.component.d.ts +102 -13
- package/lib/components/plugin-upload-modal/plugin-upload-modal.component.d.ts +76 -0
- package/lib/components/plugin-usage-modal/plugin-usage-modal.component.d.ts +26 -0
- package/lib/constants/index.d.ts +2 -0
- package/lib/constants/plugin-app-add-modal.test-ids.d.ts +8 -0
- package/lib/constants/plugin-external-review-modal.test-ids.d.ts +4 -0
- package/lib/models/external-plugin-permissions.model.d.ts +6 -0
- package/lib/models/index.d.ts +2 -0
- package/lib/models/unified-plugin-definition.model.d.ts +41 -0
- package/lib/plugin-management.module.d.ts +12 -5
- package/lib/utils/csp-allows-origin.util.d.ts +13 -0
- package/lib/utils/external-plugin-compatibility.util.d.ts +11 -0
- package/lib/utils/external-plugin-egress.util.d.ts +15 -0
- package/lib/utils/index.d.ts +3 -0
- package/package.json +1 -1
- package/public-api.d.ts +5 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { EventEmitter, OnChanges, SimpleChanges } from '@angular/core';
|
|
2
|
+
import { ExternalPluginGrantedEndpointEntry, ExternalPluginGrantedEventEntry, ExternalPluginEndpoint } from '@valtimo/plugin';
|
|
3
|
+
import { EnrichedEndpoint } from '../../models';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
/**
|
|
6
|
+
* Lists the GZAC API endpoints, platform events, host capabilities and outbound destinations an
|
|
7
|
+
* external plugin requires. Permissions are all-or-nothing: the backend rejects a configuration
|
|
8
|
+
* unless every endpoint, `eventSubscriptions` type, capability and `permissions.egress` origin the
|
|
9
|
+
* manifest declares is granted. The admin reviews the full list and accepts all of it with a single
|
|
10
|
+
* acknowledgement before saving.
|
|
11
|
+
*
|
|
12
|
+
* The outbound-destination section has two halves, which differ in who decided them:
|
|
13
|
+
*
|
|
14
|
+
* - {@link egress} — declared in the manifest, so part of the grant the admin accepts here.
|
|
15
|
+
* - {@link derivedEgress} — origins computed from the configuration values the admin just entered in
|
|
16
|
+
* properties marked `x-egress-target`. Not a separate grant: typing the URL *is* the grant, and it
|
|
17
|
+
* is shown so the admin sees the complete set of destinations the plugin will be able to reach.
|
|
18
|
+
*
|
|
19
|
+
* In `readonlyMode` (editing an existing configuration) the list is informational only — the
|
|
20
|
+
* permissions were already accepted at activation — so no acknowledgement is required.
|
|
21
|
+
*/
|
|
22
|
+
export declare class PluginExternalPermissionsComponent implements OnChanges {
|
|
23
|
+
endpoints: Array<ExternalPluginEndpoint>;
|
|
24
|
+
eventSubscriptions: Array<string>;
|
|
25
|
+
capabilities: Array<string>;
|
|
26
|
+
/** Manifest-declared origins (`permissions.egress`), granted as a set with the rest. */
|
|
27
|
+
egress: Array<string>;
|
|
28
|
+
/** Origins derived from the admin's own `x-egress-target` configuration values. */
|
|
29
|
+
derivedEgress: Array<string>;
|
|
30
|
+
readonlyMode: boolean;
|
|
31
|
+
validEvent: EventEmitter<boolean>;
|
|
32
|
+
grantedEndpointsChange: EventEmitter<ExternalPluginGrantedEndpointEntry[]>;
|
|
33
|
+
grantedEventsChange: EventEmitter<ExternalPluginGrantedEventEntry[]>;
|
|
34
|
+
grantedCapabilitiesChange: EventEmitter<string[]>;
|
|
35
|
+
grantedEgressChange: EventEmitter<string[]>;
|
|
36
|
+
readonly $enrichedEndpoints: import("@angular/core").WritableSignal<EnrichedEndpoint[]>;
|
|
37
|
+
readonly $eventTypes: import("@angular/core").WritableSignal<string[]>;
|
|
38
|
+
readonly $capabilities: import("@angular/core").WritableSignal<string[]>;
|
|
39
|
+
readonly $egress: import("@angular/core").WritableSignal<string[]>;
|
|
40
|
+
readonly $derivedEgress: import("@angular/core").WritableSignal<string[]>;
|
|
41
|
+
readonly $accepted: import("@angular/core").WritableSignal<boolean>;
|
|
42
|
+
private readonly _externalPluginService;
|
|
43
|
+
private readonly _translateService;
|
|
44
|
+
/**
|
|
45
|
+
* True when the manifest requests nothing — no review or acknowledgement is needed then.
|
|
46
|
+
* Derived egress is deliberately not part of this: it is not a grant (the admin typing the URL
|
|
47
|
+
* is the grant), so it is only ever displayed, never accepted.
|
|
48
|
+
*/
|
|
49
|
+
get isEmpty(): boolean;
|
|
50
|
+
ngOnChanges(changes: SimpleChanges): void;
|
|
51
|
+
onAcceptanceChange(accepted: boolean): void;
|
|
52
|
+
_httpMethodTagType(method: string): string;
|
|
53
|
+
private _endpointKey;
|
|
54
|
+
private _fetchDescriptionsAndInit;
|
|
55
|
+
private _setEnriched;
|
|
56
|
+
/**
|
|
57
|
+
* Accepting the permissions grants the full declared set — partial grants are not allowed by the
|
|
58
|
+
* backend, so the component always emits every endpoint.
|
|
59
|
+
*/
|
|
60
|
+
private _emitGrantedEndpoints;
|
|
61
|
+
/**
|
|
62
|
+
* Mirror of {@link _emitGrantedEndpoints} for event subscriptions — same all-or-nothing model:
|
|
63
|
+
* the host treats the granted list as the dispatch allowlist, narrower-or-equal to the manifest's
|
|
64
|
+
* declared `eventSubscriptions`.
|
|
65
|
+
*/
|
|
66
|
+
private _emitGrantedEvents;
|
|
67
|
+
private _emitGrantedCapabilities;
|
|
68
|
+
/**
|
|
69
|
+
* Only the manifest-declared origins are emitted. Derived ones are not a grant the backend accepts
|
|
70
|
+
* — it recomputes them from the configuration values on every push — so sending them would trip the
|
|
71
|
+
* exact-match check against the manifest.
|
|
72
|
+
*/
|
|
73
|
+
private _emitGrantedEgress;
|
|
74
|
+
/**
|
|
75
|
+
* A `*.` entry authorises every subdomain under it, which is a materially wider grant than a fixed
|
|
76
|
+
* host — under author-controlled DNS it reopens both arbitrary-subdomain exfiltration and the DNS
|
|
77
|
+
* channel. The template renders these distinctly so the difference is visible, not buried in a list.
|
|
78
|
+
*/
|
|
79
|
+
_isWildcardEgress(target: string): boolean;
|
|
80
|
+
private _emitValidity;
|
|
81
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<PluginExternalPermissionsComponent, never>;
|
|
82
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<PluginExternalPermissionsComponent, "valtimo-plugin-external-permissions", never, { "endpoints": { "alias": "endpoints"; "required": false; }; "eventSubscriptions": { "alias": "eventSubscriptions"; "required": false; }; "capabilities": { "alias": "capabilities"; "required": false; }; "egress": { "alias": "egress"; "required": false; }; "derivedEgress": { "alias": "derivedEgress"; "required": false; }; "readonlyMode": { "alias": "readonlyMode"; "required": false; }; }, { "validEvent": "validEvent"; "grantedEndpointsChange": "grantedEndpointsChange"; "grantedEventsChange": "grantedEventsChange"; "grantedCapabilitiesChange": "grantedCapabilitiesChange"; "grantedEgressChange": "grantedEgressChange"; }, never, never, true, never>;
|
|
83
|
+
}
|
package/lib/components/plugin-external-review-modal/plugin-external-review-modal.component.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { EventEmitter, OnChanges, SimpleChanges } from '@angular/core';
|
|
2
|
+
import { ExternalPluginDefinition, ExternalPluginEndpoint, ExternalPluginService } from '@valtimo/plugin';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
/**
|
|
5
|
+
* Review-and-accept flow for a definition whose host serves different content than what was
|
|
6
|
+
* accepted (a changed plugin package, or — for URL apps without package hashing — a changed
|
|
7
|
+
* manifest). Deliberately identical to the activation flow: the full *pending* permission
|
|
8
|
+
* footprint with the standard acceptance text and all-or-nothing checkbox — no separate
|
|
9
|
+
* changed-permissions treatment. Accepting is a single call: the backend pins the reviewed
|
|
10
|
+
* content, promotes the pending manifest, and re-grants every configuration of the definition to
|
|
11
|
+
* the manifest's declared sets in one transaction.
|
|
12
|
+
*/
|
|
13
|
+
export declare class PluginExternalReviewModalComponent implements OnChanges {
|
|
14
|
+
private readonly _externalPluginService;
|
|
15
|
+
open: boolean;
|
|
16
|
+
definition: ExternalPluginDefinition | null;
|
|
17
|
+
closeEvent: EventEmitter<void>;
|
|
18
|
+
acceptedEvent: EventEmitter<void>;
|
|
19
|
+
readonly $loading: import("@angular/core").WritableSignal<boolean>;
|
|
20
|
+
readonly $errorMessage: import("@angular/core").WritableSignal<string>;
|
|
21
|
+
readonly $permissionsValid: import("@angular/core").WritableSignal<boolean>;
|
|
22
|
+
readonly $pendingEndpoints: import("@angular/core").WritableSignal<ExternalPluginEndpoint[]>;
|
|
23
|
+
readonly $pendingEvents: import("@angular/core").WritableSignal<string[]>;
|
|
24
|
+
readonly $pendingCapabilities: import("@angular/core").WritableSignal<string[]>;
|
|
25
|
+
readonly $pendingEgress: import("@angular/core").WritableSignal<string[]>;
|
|
26
|
+
protected readonly testIds: {
|
|
27
|
+
readonly cancelButton: "pluginExternalReviewModalCancelButton";
|
|
28
|
+
readonly acceptButton: "pluginExternalReviewModalAcceptButton";
|
|
29
|
+
};
|
|
30
|
+
constructor(_externalPluginService: ExternalPluginService);
|
|
31
|
+
ngOnChanges(changes: SimpleChanges): void;
|
|
32
|
+
onPermissionsValid(valid: boolean): void;
|
|
33
|
+
onClose(): void;
|
|
34
|
+
/**
|
|
35
|
+
* Echoes the reviewed pending hash — acceptance of a *specific* state, not of whatever the host
|
|
36
|
+
* serves by now. The backend re-grants the definition's configurations in the same act.
|
|
37
|
+
*/
|
|
38
|
+
onAccept(): void;
|
|
39
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<PluginExternalReviewModalComponent, never>;
|
|
40
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<PluginExternalReviewModalComponent, "valtimo-plugin-external-review-modal", never, { "open": { "alias": "open"; "required": false; }; "definition": { "alias": "definition"; "required": false; }; }, { "closeEvent": "closeEvent"; "acceptedEvent": "acceptedEvent"; }, never, never, true, never>;
|
|
41
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { EventEmitter, OnChanges, OnDestroy, OnInit, SimpleChanges } from '@angular/core';
|
|
2
|
+
import { FormArray, FormControl, FormGroup } from '@angular/forms';
|
|
3
|
+
import { SelectItem } from '@valtimo/components';
|
|
4
|
+
import { ExternalPluginEventQueueMode, ExternalPluginHost, ExternalPluginHostConnectionUpdateRequest, ExternalPluginHostCreateRequest, ExternalPluginHostKind, ExternalPluginService } from '@valtimo/plugin';
|
|
5
|
+
import * as i0 from "@angular/core";
|
|
6
|
+
/**
|
|
7
|
+
* The connection details form shared by host registration (plugin-host modal) and app
|
|
8
|
+
* registration (the app add stepper). Owns the form controls, the backend-provided defaults and
|
|
9
|
+
* the queue-mode/TTL validation rules; the embedding component decides when to submit and builds
|
|
10
|
+
* the create request via {@link buildRequest}.
|
|
11
|
+
*/
|
|
12
|
+
export declare class PluginHostConnectionFormComponent implements OnInit, OnChanges, OnDestroy {
|
|
13
|
+
private readonly _externalPluginService;
|
|
14
|
+
/** Fetches fresh defaults every time this turns true (i.e. every time the embedding modal opens). */
|
|
15
|
+
active: boolean;
|
|
16
|
+
/** Freezes the form, e.g. while connecting or after the host has been created. */
|
|
17
|
+
disabled: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Edit mode (#618): prefill from this host instead of the environment defaults, make the secret
|
|
20
|
+
* optional (blank = unchanged), and hide the event-queue and frontend-origins sections — those
|
|
21
|
+
* keep their dedicated modals. The embedder builds the update via {@link buildConnectionPatch},
|
|
22
|
+
* which sends dirty fields only, so the write-only secret and the credential-redacted broker URL
|
|
23
|
+
* never round-trip unless the admin actually retyped them.
|
|
24
|
+
*/
|
|
25
|
+
editHost: ExternalPluginHost | null;
|
|
26
|
+
/** Chooses the placeholder examples: 'host' in the plugin-host modal, 'app' in the app add stepper. */
|
|
27
|
+
variant: 'host' | 'app';
|
|
28
|
+
validChange: EventEmitter<boolean>;
|
|
29
|
+
/**
|
|
30
|
+
* Matches `ExternalPluginHostService.MIN_SECRET_LENGTH` and the host's `MIN_ADMIN_TOKEN_LENGTH`.
|
|
31
|
+
* Checked here so the form names the problem instead of saving an unusable secret.
|
|
32
|
+
*/
|
|
33
|
+
readonly MIN_SECRET_LENGTH = 16;
|
|
34
|
+
readonly form: FormGroup<{
|
|
35
|
+
name: FormControl<string>;
|
|
36
|
+
baseUrl: FormControl<string>;
|
|
37
|
+
secret: FormControl<string>;
|
|
38
|
+
gzacCallbackBaseUrl: FormControl<string>;
|
|
39
|
+
eventBrokerAmqpUrl: FormControl<string>;
|
|
40
|
+
eventBrokerExchange: FormControl<string>;
|
|
41
|
+
eventQueueMode: FormControl<ExternalPluginEventQueueMode>;
|
|
42
|
+
eventQueueTtlMs: FormControl<number>;
|
|
43
|
+
frontendOrigins: FormArray<FormControl<string>>;
|
|
44
|
+
}>;
|
|
45
|
+
minTtlMs: number;
|
|
46
|
+
maxTtlMs: number;
|
|
47
|
+
defaultTtlMs: number;
|
|
48
|
+
queueModeItems: SelectItem[];
|
|
49
|
+
private readonly _subscriptions;
|
|
50
|
+
/** Prefill snapshot in edit mode; [isEdited] and [buildConnectionPatch] compare against it. */
|
|
51
|
+
private _editBaseline;
|
|
52
|
+
get namePlaceholder(): string;
|
|
53
|
+
get baseUrlPlaceholder(): string;
|
|
54
|
+
get secretPlaceholder(): string;
|
|
55
|
+
get ttlHintKey(): string;
|
|
56
|
+
get frontendOriginControls(): Array<FormControl<string>>;
|
|
57
|
+
constructor(_externalPluginService: ExternalPluginService);
|
|
58
|
+
ngOnInit(): void;
|
|
59
|
+
ngOnChanges(changes: SimpleChanges): void;
|
|
60
|
+
ngOnDestroy(): void;
|
|
61
|
+
addFrontendOrigin(): void;
|
|
62
|
+
removeFrontendOrigin(index: number): void;
|
|
63
|
+
buildRequest(kind: ExternalPluginHostKind): ExternalPluginHostCreateRequest | null;
|
|
64
|
+
/**
|
|
65
|
+
* Whether a connection field currently differs from the value it was prefilled with. Deliberately
|
|
66
|
+
* a value comparison, not `dirty`: a field the admin edited and then reverted counts as unchanged
|
|
67
|
+
* again — the warning below it disappears and the field never travels. That also means a broker
|
|
68
|
+
* URL reverted to its redacted prefill (`amqp://***@…`) is simply not sent, instead of tripping
|
|
69
|
+
* the backend's redaction-marker guard.
|
|
70
|
+
*/
|
|
71
|
+
isEdited(field: 'name' | 'baseUrl' | 'gzacCallbackBaseUrl' | 'eventBrokerAmqpUrl' | 'eventBrokerExchange'): boolean;
|
|
72
|
+
/**
|
|
73
|
+
* The connection PATCH body: fields that differ from the prefill baseline only, so an untouched
|
|
74
|
+
* secret (empty) and an untouched or reverted redacted broker URL never travel. `null` while the
|
|
75
|
+
* form is invalid; an empty object when nothing was edited — the embedder can skip the call then.
|
|
76
|
+
*/
|
|
77
|
+
buildConnectionPatch(): ExternalPluginHostConnectionUpdateRequest | null;
|
|
78
|
+
reset(): void;
|
|
79
|
+
private _enterEditMode;
|
|
80
|
+
private _fetchDefaults;
|
|
81
|
+
private _setFrontendOrigins;
|
|
82
|
+
private _originControl;
|
|
83
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<PluginHostConnectionFormComponent, never>;
|
|
84
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<PluginHostConnectionFormComponent, "valtimo-plugin-host-connection-form", never, { "active": { "alias": "active"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "editHost": { "alias": "editHost"; "required": false; }; "variant": { "alias": "variant"; "required": false; }; }, { "validChange": "validChange"; }, never, never, true, never>;
|
|
85
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { EventEmitter, OnDestroy } from '@angular/core';
|
|
2
|
+
import { TranslateService } from '@ngx-translate/core';
|
|
3
|
+
import { NotificationContent } from 'carbon-components-angular';
|
|
4
|
+
import { ExternalPluginHost, ExternalPluginHostConnectionUpdateRequest } from '@valtimo/plugin';
|
|
5
|
+
import { Observable } from 'rxjs';
|
|
6
|
+
import { PluginHostConnectionFormComponent } from '../plugin-host-connection-form/plugin-host-connection-form.component';
|
|
7
|
+
import * as i0 from "@angular/core";
|
|
8
|
+
/**
|
|
9
|
+
* Edit-connection modal for a registered host or app (#618): repoint a moved host or broker, or
|
|
10
|
+
* rotate the admin secret, without recreating the row. Wraps the shared connection form in edit
|
|
11
|
+
* mode and emits the dirty-fields-only patch; the embedding page makes the call, renders its
|
|
12
|
+
* failure inline here, and handles the CSP reload when the base URL changed.
|
|
13
|
+
*/
|
|
14
|
+
export declare class PluginHostEditModalComponent implements OnDestroy {
|
|
15
|
+
private readonly _translateService;
|
|
16
|
+
/** Same resolve-via-setter pattern as the add modal: the body only exists while open. */
|
|
17
|
+
set connectionForm(form: PluginHostConnectionFormComponent | undefined);
|
|
18
|
+
/**
|
|
19
|
+
* A successful save closes via the parent, bypassing [onClose] — so the changed-flags are reset
|
|
20
|
+
* here too. Else the secret warning carries over to the next host opened.
|
|
21
|
+
*/
|
|
22
|
+
set open(value: boolean);
|
|
23
|
+
get open(): boolean;
|
|
24
|
+
host: ExternalPluginHost | null;
|
|
25
|
+
/** Wording only: 'host' on the hosts page, 'app' on the apps page. */
|
|
26
|
+
variant: 'host' | 'app';
|
|
27
|
+
/** Disables both footer buttons and shows the inline loader while the update call is in flight. */
|
|
28
|
+
submitting: boolean;
|
|
29
|
+
/** Why the last update failed; owned by the parent, cleared here on any edit (add-modal pattern). */
|
|
30
|
+
set errorMessage(value: string | null);
|
|
31
|
+
closeEvent: EventEmitter<void>;
|
|
32
|
+
submitEvent: EventEmitter<ExternalPluginHostConnectionUpdateRequest>;
|
|
33
|
+
formValid: boolean;
|
|
34
|
+
/** Drives the rotation warning: the host must be restarted with the matching ADMIN_TOKEN. */
|
|
35
|
+
readonly $secretChanged: import("@angular/core").WritableSignal<boolean>;
|
|
36
|
+
/** Drives the consumer-reconnect note for broker edits. */
|
|
37
|
+
readonly $brokerChanged: import("@angular/core").WritableSignal<boolean>;
|
|
38
|
+
private readonly _errorMessage$;
|
|
39
|
+
private _open;
|
|
40
|
+
private _connectionForm;
|
|
41
|
+
private _formEditSubscription;
|
|
42
|
+
readonly errorNotification$: Observable<NotificationContent | null>;
|
|
43
|
+
/**
|
|
44
|
+
* Built from `stream` rather than once in the constructor: at construction time the translation
|
|
45
|
+
* file may not be loaded yet and `instant` would bake the raw keys in. Re-emits on (re)load, and
|
|
46
|
+
* stays one stable object per emission so change detection is not fed a fresh literal every pass.
|
|
47
|
+
*/
|
|
48
|
+
readonly secretWarning$: Observable<NotificationContent>;
|
|
49
|
+
readonly brokerNote$: Observable<NotificationContent>;
|
|
50
|
+
constructor(_translateService: TranslateService);
|
|
51
|
+
ngOnDestroy(): void;
|
|
52
|
+
onFormValidChange(valid: boolean): void;
|
|
53
|
+
onSubmit(): void;
|
|
54
|
+
onClose(): void;
|
|
55
|
+
private _notification;
|
|
56
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<PluginHostEditModalComponent, never>;
|
|
57
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<PluginHostEditModalComponent, "valtimo-plugin-host-edit-modal", never, { "open": { "alias": "open"; "required": false; }; "host": { "alias": "host"; "required": false; }; "variant": { "alias": "variant"; "required": false; }; "submitting": { "alias": "submitting"; "required": false; }; "errorMessage": { "alias": "errorMessage"; "required": false; }; }, { "closeEvent": "closeEvent"; "submitEvent": "submitEvent"; }, never, never, true, never>;
|
|
58
|
+
}
|
package/lib/components/plugin-host-event-queue-modal/plugin-host-event-queue-modal.component.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { EventEmitter, OnChanges, OnDestroy, OnInit, SimpleChanges } from '@angular/core';
|
|
2
|
+
import { FormControl, FormGroup } from '@angular/forms';
|
|
3
|
+
import { SelectItem } from '@valtimo/components';
|
|
4
|
+
import { ExternalPluginEventQueueMode, ExternalPluginHost, ExternalPluginHostEventQueueUpdateRequest, ExternalPluginService } from '@valtimo/plugin';
|
|
5
|
+
import * as i0 from "@angular/core";
|
|
6
|
+
export declare class PluginHostEventQueueModalComponent implements OnChanges, OnInit, OnDestroy {
|
|
7
|
+
private readonly _externalPluginService;
|
|
8
|
+
open: boolean;
|
|
9
|
+
host: ExternalPluginHost | null;
|
|
10
|
+
/** Chooses the wording: 'host' on the plugin-hosts page, 'app' on the apps page. */
|
|
11
|
+
variant: 'host' | 'app';
|
|
12
|
+
closeEvent: EventEmitter<void>;
|
|
13
|
+
submitEvent: EventEmitter<ExternalPluginHostEventQueueUpdateRequest>;
|
|
14
|
+
readonly form: FormGroup<{
|
|
15
|
+
eventQueueMode: FormControl<ExternalPluginEventQueueMode>;
|
|
16
|
+
eventQueueTtlMs: FormControl<number>;
|
|
17
|
+
}>;
|
|
18
|
+
minTtlMs: number;
|
|
19
|
+
maxTtlMs: number;
|
|
20
|
+
defaultTtlMs: number;
|
|
21
|
+
queueModeItems: SelectItem[];
|
|
22
|
+
private readonly _subscriptions;
|
|
23
|
+
get ttlHintKey(): string;
|
|
24
|
+
constructor(_externalPluginService: ExternalPluginService);
|
|
25
|
+
ngOnInit(): void;
|
|
26
|
+
ngOnChanges(changes: SimpleChanges): void;
|
|
27
|
+
ngOnDestroy(): void;
|
|
28
|
+
onSubmit(): void;
|
|
29
|
+
onClose(): void;
|
|
30
|
+
private _fetchDefaults;
|
|
31
|
+
private _loadHost;
|
|
32
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<PluginHostEventQueueModalComponent, never>;
|
|
33
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<PluginHostEventQueueModalComponent, "valtimo-plugin-host-event-queue-modal", never, { "open": { "alias": "open"; "required": false; }; "host": { "alias": "host"; "required": false; }; "variant": { "alias": "variant"; "required": false; }; }, { "closeEvent": "closeEvent"; "submitEvent": "submitEvent"; }, never, never, true, never>;
|
|
34
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { EventEmitter, OnChanges, SimpleChanges } from '@angular/core';
|
|
2
|
+
import { FormArray, FormControl, FormGroup } from '@angular/forms';
|
|
3
|
+
import { ExternalPluginHost } from '@valtimo/plugin';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
/**
|
|
6
|
+
* Runtime edit path for the browser origins allowed to embed a host's plugin screens — the same
|
|
7
|
+
* narrowly-scoped shape as the event-queue modal. The connection fields (base URL, secret, broker)
|
|
8
|
+
* have their own edit modal (#618).
|
|
9
|
+
*
|
|
10
|
+
* Saving an empty list is meaningful, not a mistake: it means no page may frame this host's plugins.
|
|
11
|
+
*/
|
|
12
|
+
export declare class PluginHostFrontendOriginsModalComponent implements OnChanges {
|
|
13
|
+
open: boolean;
|
|
14
|
+
host: ExternalPluginHost | null;
|
|
15
|
+
closeEvent: EventEmitter<void>;
|
|
16
|
+
submitEvent: EventEmitter<string[]>;
|
|
17
|
+
readonly form: FormGroup<{
|
|
18
|
+
frontendOrigins: FormArray<FormControl<string>>;
|
|
19
|
+
}>;
|
|
20
|
+
get originControls(): Array<FormControl<string>>;
|
|
21
|
+
ngOnChanges(changes: SimpleChanges): void;
|
|
22
|
+
addOrigin(): void;
|
|
23
|
+
removeOrigin(index: number): void;
|
|
24
|
+
onSubmit(): void;
|
|
25
|
+
onClose(): void;
|
|
26
|
+
private _loadHost;
|
|
27
|
+
private _originControl;
|
|
28
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<PluginHostFrontendOriginsModalComponent, never>;
|
|
29
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<PluginHostFrontendOriginsModalComponent, "valtimo-plugin-host-frontend-origins-modal", never, { "open": { "alias": "open"; "required": false; }; "host": { "alias": "host"; "required": false; }; }, { "closeEvent": "closeEvent"; "submitEvent": "submitEvent"; }, never, never, true, never>;
|
|
30
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { EventEmitter, OnDestroy } from '@angular/core';
|
|
2
|
+
import { TranslateService } from '@ngx-translate/core';
|
|
3
|
+
import { NotificationContent } from 'carbon-components-angular';
|
|
4
|
+
import { ExternalPluginHostCreateRequest, ExternalPluginHostKind } from '@valtimo/plugin';
|
|
5
|
+
import { Observable } from 'rxjs';
|
|
6
|
+
import { PluginHostConnectionFormComponent } from '../plugin-host-connection-form/plugin-host-connection-form.component';
|
|
7
|
+
import * as i0 from "@angular/core";
|
|
8
|
+
export declare class PluginHostModalComponent implements OnDestroy {
|
|
9
|
+
private readonly _translateService;
|
|
10
|
+
/**
|
|
11
|
+
* The embedded connection form, resolved via a setter because the modal body only exists while
|
|
12
|
+
* the modal is open (`*ngIf`). Editing anything dismisses the previous failure: the admin is
|
|
13
|
+
* already acting on it, and a message that outlives the value it complained about is worse than
|
|
14
|
+
* none.
|
|
15
|
+
*/
|
|
16
|
+
set connectionForm(form: PluginHostConnectionFormComponent | undefined);
|
|
17
|
+
open: boolean;
|
|
18
|
+
kind: ExternalPluginHostKind;
|
|
19
|
+
/** Disables both footer buttons and shows the inline loader while the create call is in flight. */
|
|
20
|
+
submitting: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Why the last create attempt failed, rendered above the fields. Owned by the parent (it is the
|
|
23
|
+
* one that makes the call) but cleared here as soon as the admin edits anything, so a stale
|
|
24
|
+
* message never sits above a form they have already corrected.
|
|
25
|
+
*/
|
|
26
|
+
set errorMessage(value: string | null);
|
|
27
|
+
closeEvent: EventEmitter<void>;
|
|
28
|
+
submitEvent: EventEmitter<ExternalPluginHostCreateRequest>;
|
|
29
|
+
formValid: boolean;
|
|
30
|
+
get isApp(): boolean;
|
|
31
|
+
private readonly _errorMessage$;
|
|
32
|
+
private _connectionForm;
|
|
33
|
+
private _formEditSubscription;
|
|
34
|
+
/**
|
|
35
|
+
* The inline notification, built here rather than as a template object literal: a literal would
|
|
36
|
+
* be a new object on every change-detection pass, which keeps the notification component churning.
|
|
37
|
+
*/
|
|
38
|
+
readonly errorNotification$: Observable<NotificationContent | null>;
|
|
39
|
+
constructor(_translateService: TranslateService);
|
|
40
|
+
ngOnDestroy(): void;
|
|
41
|
+
onFormValidChange(valid: boolean): void;
|
|
42
|
+
onSubmit(): void;
|
|
43
|
+
onClose(): void;
|
|
44
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<PluginHostModalComponent, never>;
|
|
45
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<PluginHostModalComponent, "valtimo-plugin-host-modal", never, { "open": { "alias": "open"; "required": false; }; "kind": { "alias": "kind"; "required": false; }; "submitting": { "alias": "submitting"; "required": false; }; "errorMessage": { "alias": "errorMessage"; "required": false; }; }, { "closeEvent": "closeEvent"; "submitEvent": "submitEvent"; }, never, never, true, never>;
|
|
46
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { OnDestroy } from '@angular/core';
|
|
2
|
+
import { TranslateService } from '@ngx-translate/core';
|
|
3
|
+
import { ActionItem, CarbonTag, ColumnConfig } from '@valtimo/components';
|
|
4
|
+
import { ExternalPluginHost, ExternalPluginHostConnectionUpdateRequest, ExternalPluginHostCreateRequest, ExternalPluginHostEventQueueUpdateRequest, ExternalPluginHostUsage, ExternalPluginService } from '@valtimo/plugin';
|
|
5
|
+
import { BehaviorSubject, Observable } from 'rxjs';
|
|
6
|
+
import { NGXLogger } from 'ngx-logger';
|
|
7
|
+
import * as i0 from "@angular/core";
|
|
8
|
+
export declare class PluginHostsPageComponent implements OnDestroy {
|
|
9
|
+
private readonly _logger;
|
|
10
|
+
private readonly _translateService;
|
|
11
|
+
private readonly _externalPluginService;
|
|
12
|
+
private readonly _destroy$;
|
|
13
|
+
private readonly _refreshHosts$;
|
|
14
|
+
private _hostsInitialLoad;
|
|
15
|
+
private readonly _tabVisible$;
|
|
16
|
+
readonly hostsLoading$: BehaviorSubject<boolean>;
|
|
17
|
+
readonly hostsRefreshing$: BehaviorSubject<boolean>;
|
|
18
|
+
readonly hostModalOpen$: BehaviorSubject<boolean>;
|
|
19
|
+
readonly hostSubmitting$: BehaviorSubject<boolean>;
|
|
20
|
+
readonly hostErrorMessage$: BehaviorSubject<string>;
|
|
21
|
+
readonly reloadModalOpen$: BehaviorSubject<boolean>;
|
|
22
|
+
readonly deleteHostModalOpen$: BehaviorSubject<boolean>;
|
|
23
|
+
hostToDelete: ExternalPluginHost | null;
|
|
24
|
+
readonly editConnectionModalOpen$: BehaviorSubject<boolean>;
|
|
25
|
+
readonly hostToEditConnection$: BehaviorSubject<ExternalPluginHost>;
|
|
26
|
+
readonly editConnectionSubmitting$: BehaviorSubject<boolean>;
|
|
27
|
+
readonly editConnectionErrorMessage$: BehaviorSubject<string>;
|
|
28
|
+
readonly eventQueueModalOpen$: BehaviorSubject<boolean>;
|
|
29
|
+
readonly hostToEditEventQueue$: BehaviorSubject<ExternalPluginHost>;
|
|
30
|
+
readonly frontendOriginsModalOpen$: BehaviorSubject<boolean>;
|
|
31
|
+
readonly hostToEditFrontendOrigins$: BehaviorSubject<ExternalPluginHost>;
|
|
32
|
+
readonly usageModalOpen$: BehaviorSubject<boolean>;
|
|
33
|
+
readonly usageModalUsages$: BehaviorSubject<ExternalPluginHostUsage[]>;
|
|
34
|
+
usageModalEntityName: string | null;
|
|
35
|
+
usageModalTitleKey: string;
|
|
36
|
+
usageModalDescriptionKey: string;
|
|
37
|
+
readonly hostFields: ColumnConfig[];
|
|
38
|
+
readonly hostActionItems: ActionItem[];
|
|
39
|
+
readonly hosts$: Observable<Array<ExternalPluginHost & {
|
|
40
|
+
statusTag: CarbonTag;
|
|
41
|
+
lastHealthCheckFormatted: string;
|
|
42
|
+
}>>;
|
|
43
|
+
constructor(_logger: NGXLogger, _translateService: TranslateService, _externalPluginService: ExternalPluginService);
|
|
44
|
+
ngOnDestroy(): void;
|
|
45
|
+
openHostModal(): void;
|
|
46
|
+
closeHostModal(): void;
|
|
47
|
+
/**
|
|
48
|
+
* Keeps the modal open and populated when registration fails, showing the reason inline. The
|
|
49
|
+
* backend answers a fixable mistake with a 400 carrying `detail`; the service marks that status
|
|
50
|
+
* `InterceptorSkip`, so this is the only place the admin ever sees it.
|
|
51
|
+
*/
|
|
52
|
+
submitHost(request: ExternalPluginHostCreateRequest): void;
|
|
53
|
+
editHostFrontendOrigins(host: ExternalPluginHost): void;
|
|
54
|
+
closeFrontendOriginsModal(): void;
|
|
55
|
+
submitFrontendOriginsUpdate(origins: Array<string>): void;
|
|
56
|
+
/**
|
|
57
|
+
* The most specific message the response carries. `detail` is what the backend's validation
|
|
58
|
+
* mapper fills with the operator-facing reason; `message`/`title` cover the other problem shapes;
|
|
59
|
+
* the translated fallback covers a response with none of them (a gateway error, say).
|
|
60
|
+
*/
|
|
61
|
+
private _extractHostError;
|
|
62
|
+
deleteHost(host: ExternalPluginHost): void;
|
|
63
|
+
confirmDeleteHost(): void;
|
|
64
|
+
cancelDeleteHost(): void;
|
|
65
|
+
editHostConnection(host: ExternalPluginHost): void;
|
|
66
|
+
closeEditConnectionModal(): void;
|
|
67
|
+
/**
|
|
68
|
+
* Applies the dirty-fields-only connection patch (#618). A changed base URL also changes the
|
|
69
|
+
* origin the frontend CSP must allow, and that CSP is fixed at bootstrap — so a repoint gets the
|
|
70
|
+
* same reload-required modal as registering a new host.
|
|
71
|
+
*/
|
|
72
|
+
submitConnectionUpdate(patch: ExternalPluginHostConnectionUpdateRequest): void;
|
|
73
|
+
editHostEventQueue(host: ExternalPluginHost): void;
|
|
74
|
+
closeEventQueueModal(): void;
|
|
75
|
+
submitEventQueueUpdate(request: ExternalPluginHostEventQueueUpdateRequest): void;
|
|
76
|
+
closeUsageModal(): void;
|
|
77
|
+
confirmReload(): void;
|
|
78
|
+
cancelReload(): void;
|
|
79
|
+
private _showHostInUseModal;
|
|
80
|
+
private _getStatusTag;
|
|
81
|
+
private _formatLastHealthCheck;
|
|
82
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<PluginHostsPageComponent, never>;
|
|
83
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<PluginHostsPageComponent, "ng-component", never, {}, {}, never, never, true, never>;
|
|
84
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { EventEmitter, OnChanges, SimpleChanges, TemplateRef } from '@angular/core';
|
|
2
|
+
import { CarbonPaginatorConfig, ColumnConfig, Pagination } from '@valtimo/components';
|
|
3
|
+
import { PluginLogEntry } from '@valtimo/plugin';
|
|
4
|
+
import { ListItem } from 'carbon-components-angular';
|
|
5
|
+
import * as i0 from "@angular/core";
|
|
6
|
+
export declare class PluginLogModalComponent implements OnChanges {
|
|
7
|
+
open: boolean;
|
|
8
|
+
configurationId: string | null;
|
|
9
|
+
configurationTitle: string;
|
|
10
|
+
closeModal: EventEmitter<void>;
|
|
11
|
+
timestampTpl: TemplateRef<any>;
|
|
12
|
+
levelTpl: TemplateRef<any>;
|
|
13
|
+
sourceTpl: TemplateRef<any>;
|
|
14
|
+
readonly $loading: import("@angular/core").WritableSignal<boolean>;
|
|
15
|
+
readonly $rows: import("@angular/core").WritableSignal<PluginLogEntry[]>;
|
|
16
|
+
readonly $selectedRow: import("@angular/core").WritableSignal<PluginLogEntry>;
|
|
17
|
+
private readonly _$totalElements;
|
|
18
|
+
fields: ColumnConfig[];
|
|
19
|
+
page: number;
|
|
20
|
+
pageSize: number;
|
|
21
|
+
readonly paginatorConfig: CarbonPaginatorConfig;
|
|
22
|
+
levelItems: Partial<ListItem>[];
|
|
23
|
+
sourceItems: Partial<ListItem>[];
|
|
24
|
+
private _levelFilter;
|
|
25
|
+
private _sourceFilter;
|
|
26
|
+
private readonly _externalPluginService;
|
|
27
|
+
private readonly _iconService;
|
|
28
|
+
private readonly _cdr;
|
|
29
|
+
private readonly _translateService;
|
|
30
|
+
constructor();
|
|
31
|
+
get pagination(): Pagination;
|
|
32
|
+
ngOnChanges(changes: SimpleChanges): void;
|
|
33
|
+
onClose(): void;
|
|
34
|
+
onPaginationClicked(page: number): void;
|
|
35
|
+
onRowClicked(row: PluginLogEntry): void;
|
|
36
|
+
onLevelSelected(event: {
|
|
37
|
+
item: {
|
|
38
|
+
value: string;
|
|
39
|
+
};
|
|
40
|
+
}): void;
|
|
41
|
+
onSourceSelected(event: {
|
|
42
|
+
item: {
|
|
43
|
+
value: string;
|
|
44
|
+
};
|
|
45
|
+
}): void;
|
|
46
|
+
closeDetail(): void;
|
|
47
|
+
levelTagType(level: string): string;
|
|
48
|
+
sourceTagType(source: string): string;
|
|
49
|
+
formatData(data: unknown): string;
|
|
50
|
+
private _resetFilters;
|
|
51
|
+
private _initFields;
|
|
52
|
+
private _loadLogs;
|
|
53
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<PluginLogModalComponent, never>;
|
|
54
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<PluginLogModalComponent, "valtimo-plugin-log-modal", never, { "open": { "alias": "open"; "required": false; }; "configurationId": { "alias": "configurationId"; "required": false; }; "configurationTitle": { "alias": "configurationTitle"; "required": false; }; }, { "closeModal": "closeModal"; }, never, never, true, never>;
|
|
55
|
+
}
|