@portaidentity/cli 1.7.3 → 1.8.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/CHANGELOG.md +5 -0
- package/README.md +125 -105
- package/dist/admin/admin-date-time.d.ts +6 -0
- package/dist/admin/admin-date-time.d.ts.map +1 -0
- package/dist/admin/admin-date-time.js +33 -0
- package/dist/admin/admin-date-time.js.map +1 -0
- package/dist/admin/application-client-features.d.ts +38 -0
- package/dist/admin/application-client-features.d.ts.map +1 -0
- package/dist/admin/application-client-features.js +545 -0
- package/dist/admin/application-client-features.js.map +1 -0
- package/dist/admin/application-controller.d.ts +58 -0
- package/dist/admin/application-controller.d.ts.map +1 -0
- package/dist/admin/application-controller.js +286 -0
- package/dist/admin/application-controller.js.map +1 -0
- package/dist/admin/application-dialogs.d.ts +91 -0
- package/dist/admin/application-dialogs.d.ts.map +1 -0
- package/dist/admin/application-dialogs.js +250 -0
- package/dist/admin/application-dialogs.js.map +1 -0
- package/dist/admin/application-rbac-controller.d.ts +56 -0
- package/dist/admin/application-rbac-controller.d.ts.map +1 -0
- package/dist/admin/application-rbac-controller.js +280 -0
- package/dist/admin/application-rbac-controller.js.map +1 -0
- package/dist/admin/application-rbac-features.d.ts +51 -0
- package/dist/admin/application-rbac-features.d.ts.map +1 -0
- package/dist/admin/application-rbac-features.js +175 -0
- package/dist/admin/application-rbac-features.js.map +1 -0
- package/dist/admin/application-rbac-workspace.d.ts +62 -0
- package/dist/admin/application-rbac-workspace.d.ts.map +1 -0
- package/dist/admin/application-rbac-workspace.js +344 -0
- package/dist/admin/application-rbac-workspace.js.map +1 -0
- package/dist/admin/application-runtime.d.ts +44 -0
- package/dist/admin/application-runtime.d.ts.map +1 -0
- package/dist/admin/application-runtime.js +183 -0
- package/dist/admin/application-runtime.js.map +1 -0
- package/dist/admin/application-service.d.ts +39 -0
- package/dist/admin/application-service.d.ts.map +1 -0
- package/dist/admin/application-service.js +248 -0
- package/dist/admin/application-service.js.map +1 -0
- package/dist/admin/application-state.d.ts +109 -0
- package/dist/admin/application-state.d.ts.map +1 -0
- package/dist/admin/application-state.js +3 -0
- package/dist/admin/application-state.js.map +1 -0
- package/dist/admin/application-workspace.d.ts +77 -0
- package/dist/admin/application-workspace.d.ts.map +1 -0
- package/dist/admin/application-workspace.js +302 -0
- package/dist/admin/application-workspace.js.map +1 -0
- package/dist/admin/application.d.ts +88 -0
- package/dist/admin/application.d.ts.map +1 -0
- package/dist/admin/application.js +932 -0
- package/dist/admin/application.js.map +1 -0
- package/dist/admin/client-authentication-dialog.d.ts +77 -0
- package/dist/admin/client-authentication-dialog.d.ts.map +1 -0
- package/dist/admin/client-authentication-dialog.js +217 -0
- package/dist/admin/client-authentication-dialog.js.map +1 -0
- package/dist/admin/client-controller.d.ts +58 -0
- package/dist/admin/client-controller.d.ts.map +1 -0
- package/dist/admin/client-controller.js +462 -0
- package/dist/admin/client-controller.js.map +1 -0
- package/dist/admin/client-credential-dialogs.d.ts +36 -0
- package/dist/admin/client-credential-dialogs.d.ts.map +1 -0
- package/dist/admin/client-credential-dialogs.js +145 -0
- package/dist/admin/client-credential-dialogs.js.map +1 -0
- package/dist/admin/client-dialogs.d.ts +64 -0
- package/dist/admin/client-dialogs.d.ts.map +1 -0
- package/dist/admin/client-dialogs.js +110 -0
- package/dist/admin/client-dialogs.js.map +1 -0
- package/dist/admin/client-form-scroller.d.ts +17 -0
- package/dist/admin/client-form-scroller.d.ts.map +1 -0
- package/dist/admin/client-form-scroller.js +67 -0
- package/dist/admin/client-form-scroller.js.map +1 -0
- package/dist/admin/client-registration-dialog.d.ts +27 -0
- package/dist/admin/client-registration-dialog.d.ts.map +1 -0
- package/dist/admin/client-registration-dialog.js +195 -0
- package/dist/admin/client-registration-dialog.js.map +1 -0
- package/dist/admin/client-service.d.ts +41 -0
- package/dist/admin/client-service.d.ts.map +1 -0
- package/dist/admin/client-service.js +484 -0
- package/dist/admin/client-service.js.map +1 -0
- package/dist/admin/client-state.d.ts +157 -0
- package/dist/admin/client-state.d.ts.map +1 -0
- package/dist/admin/client-state.js +3 -0
- package/dist/admin/client-state.js.map +1 -0
- package/dist/admin/client-workspace.d.ts +88 -0
- package/dist/admin/client-workspace.d.ts.map +1 -0
- package/dist/admin/client-workspace.js +484 -0
- package/dist/admin/client-workspace.js.map +1 -0
- package/dist/admin/delete-confirmation-layout.d.ts +38 -0
- package/dist/admin/delete-confirmation-layout.d.ts.map +1 -0
- package/dist/admin/delete-confirmation-layout.js +52 -0
- package/dist/admin/delete-confirmation-layout.js.map +1 -0
- package/dist/admin/index.d.ts +64 -0
- package/dist/admin/index.d.ts.map +1 -0
- package/dist/admin/index.js +31 -0
- package/dist/admin/index.js.map +1 -0
- package/dist/admin/organization-controller.d.ts +77 -0
- package/dist/admin/organization-controller.d.ts.map +1 -0
- package/dist/admin/organization-controller.js +472 -0
- package/dist/admin/organization-controller.js.map +1 -0
- package/dist/admin/organization-dialogs.d.ts +63 -0
- package/dist/admin/organization-dialogs.d.ts.map +1 -0
- package/dist/admin/organization-dialogs.js +303 -0
- package/dist/admin/organization-dialogs.js.map +1 -0
- package/dist/admin/organization-service.d.ts +110 -0
- package/dist/admin/organization-service.d.ts.map +1 -0
- package/dist/admin/organization-service.js +548 -0
- package/dist/admin/organization-service.js.map +1 -0
- package/dist/admin/organization-workspace.d.ts +29 -0
- package/dist/admin/organization-workspace.d.ts.map +1 -0
- package/dist/admin/organization-workspace.js +421 -0
- package/dist/admin/organization-workspace.js.map +1 -0
- package/dist/admin/portability-controller.d.ts +83 -0
- package/dist/admin/portability-controller.d.ts.map +1 -0
- package/dist/admin/portability-controller.js +466 -0
- package/dist/admin/portability-controller.js.map +1 -0
- package/dist/admin/portability-service.d.ts +31 -0
- package/dist/admin/portability-service.d.ts.map +1 -0
- package/dist/admin/portability-service.js +51 -0
- package/dist/admin/portability-service.js.map +1 -0
- package/dist/admin/portability-state.d.ts +88 -0
- package/dist/admin/portability-state.d.ts.map +1 -0
- package/dist/admin/portability-state.js +3 -0
- package/dist/admin/portability-state.js.map +1 -0
- package/dist/admin/portability-workspace.d.ts +78 -0
- package/dist/admin/portability-workspace.d.ts.map +1 -0
- package/dist/admin/portability-workspace.js +337 -0
- package/dist/admin/portability-workspace.js.map +1 -0
- package/dist/admin/presentation.d.ts +46 -0
- package/dist/admin/presentation.d.ts.map +1 -0
- package/dist/admin/presentation.js +271 -0
- package/dist/admin/presentation.js.map +1 -0
- package/dist/admin/rbac-dialogs.d.ts +73 -0
- package/dist/admin/rbac-dialogs.d.ts.map +1 -0
- package/dist/admin/rbac-dialogs.js +345 -0
- package/dist/admin/rbac-dialogs.js.map +1 -0
- package/dist/admin/rbac-service.d.ts +47 -0
- package/dist/admin/rbac-service.d.ts.map +1 -0
- package/dist/admin/rbac-service.js +258 -0
- package/dist/admin/rbac-service.js.map +1 -0
- package/dist/admin/rbac-state.d.ts +129 -0
- package/dist/admin/rbac-state.d.ts.map +1 -0
- package/dist/admin/rbac-state.js +136 -0
- package/dist/admin/rbac-state.js.map +1 -0
- package/dist/admin/selectable-read-only-input.d.ts +18 -0
- package/dist/admin/selectable-read-only-input.d.ts.map +1 -0
- package/dist/admin/selectable-read-only-input.js +24 -0
- package/dist/admin/selectable-read-only-input.js.map +1 -0
- package/dist/admin/session-service.d.ts +169 -0
- package/dist/admin/session-service.d.ts.map +1 -0
- package/dist/admin/session-service.js +353 -0
- package/dist/admin/session-service.js.map +1 -0
- package/dist/admin/state.d.ts +301 -0
- package/dist/admin/state.d.ts.map +1 -0
- package/dist/admin/state.js +10 -0
- package/dist/admin/state.js.map +1 -0
- package/dist/admin/system-config-controller.d.ts +58 -0
- package/dist/admin/system-config-controller.d.ts.map +1 -0
- package/dist/admin/system-config-controller.js +218 -0
- package/dist/admin/system-config-controller.js.map +1 -0
- package/dist/admin/system-config-service.d.ts +54 -0
- package/dist/admin/system-config-service.d.ts.map +1 -0
- package/dist/admin/system-config-service.js +180 -0
- package/dist/admin/system-config-service.js.map +1 -0
- package/dist/admin/system-config-state.d.ts +77 -0
- package/dist/admin/system-config-state.d.ts.map +1 -0
- package/dist/admin/system-config-state.js +78 -0
- package/dist/admin/system-config-state.js.map +1 -0
- package/dist/admin/system-config-workspace.d.ts +47 -0
- package/dist/admin/system-config-workspace.d.ts.map +1 -0
- package/dist/admin/system-config-workspace.js +217 -0
- package/dist/admin/system-config-workspace.js.map +1 -0
- package/dist/admin/user-controller-types.d.ts +67 -0
- package/dist/admin/user-controller-types.d.ts.map +1 -0
- package/dist/admin/user-controller-types.js +3 -0
- package/dist/admin/user-controller-types.js.map +1 -0
- package/dist/admin/user-controller.d.ts +6 -0
- package/dist/admin/user-controller.d.ts.map +1 -0
- package/dist/admin/user-controller.js +674 -0
- package/dist/admin/user-controller.js.map +1 -0
- package/dist/admin/user-dialog-fields.d.ts +44 -0
- package/dist/admin/user-dialog-fields.d.ts.map +1 -0
- package/dist/admin/user-dialog-fields.js +130 -0
- package/dist/admin/user-dialog-fields.js.map +1 -0
- package/dist/admin/user-dialogs.d.ts +66 -0
- package/dist/admin/user-dialogs.d.ts.map +1 -0
- package/dist/admin/user-dialogs.js +374 -0
- package/dist/admin/user-dialogs.js.map +1 -0
- package/dist/admin/user-role-controller.d.ts +82 -0
- package/dist/admin/user-role-controller.d.ts.map +1 -0
- package/dist/admin/user-role-controller.js +337 -0
- package/dist/admin/user-role-controller.js.map +1 -0
- package/dist/admin/user-role-dialog.d.ts +94 -0
- package/dist/admin/user-role-dialog.d.ts.map +1 -0
- package/dist/admin/user-role-dialog.js +265 -0
- package/dist/admin/user-role-dialog.js.map +1 -0
- package/dist/admin/user-service-types.d.ts +100 -0
- package/dist/admin/user-service-types.d.ts.map +1 -0
- package/dist/admin/user-service-types.js +3 -0
- package/dist/admin/user-service-types.js.map +1 -0
- package/dist/admin/user-service.d.ts +14 -0
- package/dist/admin/user-service.d.ts.map +1 -0
- package/dist/admin/user-service.js +612 -0
- package/dist/admin/user-service.js.map +1 -0
- package/dist/admin/user-state.d.ts +158 -0
- package/dist/admin/user-state.d.ts.map +1 -0
- package/dist/admin/user-state.js +3 -0
- package/dist/admin/user-state.js.map +1 -0
- package/dist/admin/user-workspace.d.ts +65 -0
- package/dist/admin/user-workspace.d.ts.map +1 -0
- package/dist/admin/user-workspace.js +366 -0
- package/dist/admin/user-workspace.js.map +1 -0
- package/dist/auth/browser-flow.d.ts +27 -1
- package/dist/auth/browser-flow.d.ts.map +1 -1
- package/dist/auth/browser-flow.js +55 -33
- package/dist/auth/browser-flow.js.map +1 -1
- package/dist/auth/callback-server.d.ts.map +1 -1
- package/dist/auth/callback-server.js +5 -9
- package/dist/auth/callback-server.js.map +1 -1
- package/dist/auth/id-token-verifier.d.ts +39 -0
- package/dist/auth/id-token-verifier.d.ts.map +1 -0
- package/dist/auth/id-token-verifier.js +104 -0
- package/dist/auth/id-token-verifier.js.map +1 -0
- package/dist/auth/login-coordinator.d.ts +72 -0
- package/dist/auth/login-coordinator.d.ts.map +1 -0
- package/dist/auth/login-coordinator.js +190 -0
- package/dist/auth/login-coordinator.js.map +1 -0
- package/dist/auth/metadata.d.ts +2 -1
- package/dist/auth/metadata.d.ts.map +1 -1
- package/dist/auth/metadata.js +67 -6
- package/dist/auth/metadata.js.map +1 -1
- package/dist/auth/types.d.ts +14 -0
- package/dist/auth/types.d.ts.map +1 -1
- package/dist/client-factory.d.ts.map +1 -1
- package/dist/client-factory.js +15 -2
- package/dist/client-factory.js.map +1 -1
- package/dist/commands/admin.d.ts +22 -0
- package/dist/commands/admin.d.ts.map +1 -0
- package/dist/commands/admin.js +112 -0
- package/dist/commands/admin.js.map +1 -0
- package/dist/commands/app-claim.d.ts.map +1 -1
- package/dist/commands/app-claim.js +11 -4
- package/dist/commands/app-claim.js.map +1 -1
- package/dist/commands/app-module.d.ts.map +1 -1
- package/dist/commands/app-module.js +61 -12
- package/dist/commands/app-module.js.map +1 -1
- package/dist/commands/app-permission.d.ts.map +1 -1
- package/dist/commands/app-permission.js +66 -24
- package/dist/commands/app-permission.js.map +1 -1
- package/dist/commands/app-role.d.ts.map +1 -1
- package/dist/commands/app-role.js +48 -27
- package/dist/commands/app-role.js.map +1 -1
- package/dist/commands/app.d.ts.map +1 -1
- package/dist/commands/app.js +37 -25
- package/dist/commands/app.js.map +1 -1
- package/dist/commands/bulk.d.ts.map +1 -1
- package/dist/commands/bulk.js +9 -2
- package/dist/commands/bulk.js.map +1 -1
- package/dist/commands/client-secret.d.ts.map +1 -1
- package/dist/commands/client-secret.js +12 -6
- package/dist/commands/client-secret.js.map +1 -1
- package/dist/commands/client.d.ts +3 -2
- package/dist/commands/client.d.ts.map +1 -1
- package/dist/commands/client.js +87 -43
- package/dist/commands/client.js.map +1 -1
- package/dist/commands/config.d.ts +4 -0
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +68 -7
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/export.d.ts +6 -0
- package/dist/commands/export.d.ts.map +1 -0
- package/dist/commands/export.js +182 -0
- package/dist/commands/export.js.map +1 -0
- package/dist/commands/import.d.ts +6 -0
- package/dist/commands/import.d.ts.map +1 -0
- package/dist/commands/import.js +142 -0
- package/dist/commands/import.js.map +1 -0
- package/dist/commands/keys.d.ts.map +1 -1
- package/dist/commands/keys.js +11 -4
- package/dist/commands/keys.js.map +1 -1
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.js +24 -10
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/org.d.ts +2 -4
- package/dist/commands/org.d.ts.map +1 -1
- package/dist/commands/org.js +16 -76
- package/dist/commands/org.js.map +1 -1
- package/dist/commands/user-role.d.ts.map +1 -1
- package/dist/commands/user-role.js +19 -14
- package/dist/commands/user-role.js.map +1 -1
- package/dist/commands/user.d.ts +3 -2
- package/dist/commands/user.d.ts.map +1 -1
- package/dist/commands/user.js +47 -71
- package/dist/commands/user.js.map +1 -1
- package/dist/commands/version.d.ts +1 -1
- package/dist/commands/version.js +1 -1
- package/dist/credential-lock.d.ts +20 -0
- package/dist/credential-lock.d.ts.map +1 -0
- package/dist/credential-lock.js +130 -0
- package/dist/credential-lock.js.map +1 -0
- package/dist/credential-store.d.ts +14 -0
- package/dist/credential-store.d.ts.map +1 -1
- package/dist/credential-store.js +114 -3
- package/dist/credential-store.js.map +1 -1
- package/dist/error-handler.d.ts.map +1 -1
- package/dist/error-handler.js +2 -0
- package/dist/error-handler.js.map +1 -1
- package/dist/global-options.d.ts +8 -0
- package/dist/global-options.d.ts.map +1 -1
- package/dist/global-options.js +19 -8
- package/dist/global-options.js.map +1 -1
- package/dist/index.js +7 -5
- package/dist/index.js.map +1 -1
- package/dist/output.d.ts +11 -0
- package/dist/output.d.ts.map +1 -1
- package/dist/output.js +25 -6
- package/dist/output.js.map +1 -1
- package/dist/prompt.d.ts +2 -2
- package/dist/prompt.d.ts.map +1 -1
- package/dist/prompt.js +27 -7
- package/dist/prompt.js.map +1 -1
- package/package.json +7 -3
- package/dist/commands/gui.d.ts +0 -21
- package/dist/commands/gui.d.ts.map +0 -1
- package/dist/commands/gui.js +0 -67
- package/dist/commands/gui.js.map +0 -1
- package/dist/commands/provision.d.ts +0 -47
- package/dist/commands/provision.d.ts.map +0 -1
- package/dist/commands/provision.js +0 -444
- package/dist/commands/provision.js.map +0 -1
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
/** Operation ownership for the deployment-global application workflow. */
|
|
2
|
+
/** Creates the small global application workflow controller. */
|
|
3
|
+
export function createAdminApplicationController(options) {
|
|
4
|
+
let sessionEpoch = -1;
|
|
5
|
+
let generation = 0;
|
|
6
|
+
let operation;
|
|
7
|
+
let mutationDispatched = false;
|
|
8
|
+
let projection;
|
|
9
|
+
let recoveryRequired = false;
|
|
10
|
+
let disposed = false;
|
|
11
|
+
/** Publishes only while the controller still belongs to the application. */
|
|
12
|
+
const publish = (state) => {
|
|
13
|
+
if (!disposed)
|
|
14
|
+
options.publishState(state);
|
|
15
|
+
};
|
|
16
|
+
/** Clears asynchronous ownership and records uncertainty only after a mutation was dispatched. */
|
|
17
|
+
const cancel = (reconcileDispatchedMutation = false) => {
|
|
18
|
+
const uncertain = reconcileDispatchedMutation && mutationDispatched;
|
|
19
|
+
generation += 1;
|
|
20
|
+
operation?.abort();
|
|
21
|
+
operation = undefined;
|
|
22
|
+
mutationDispatched = false;
|
|
23
|
+
if (uncertain) {
|
|
24
|
+
recoveryRequired = true;
|
|
25
|
+
options.setRecoveryRequired?.(true);
|
|
26
|
+
publish({ kind: 'indeterminate', ...(projection ? { previous: projection } : {}) });
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
/** Returns true only for the current continuation. */
|
|
30
|
+
const owns = (capturedGeneration, controller) => !disposed &&
|
|
31
|
+
generation === capturedGeneration &&
|
|
32
|
+
operation === controller &&
|
|
33
|
+
!controller.signal.aborted;
|
|
34
|
+
/** Clears state and enters authentication after a definite session failure. */
|
|
35
|
+
const sessionInvalid = () => {
|
|
36
|
+
cancel();
|
|
37
|
+
projection = undefined;
|
|
38
|
+
recoveryRequired = false;
|
|
39
|
+
options.setRecoveryRequired?.(false);
|
|
40
|
+
publish({ kind: 'closed' });
|
|
41
|
+
options.requestAuthentication();
|
|
42
|
+
};
|
|
43
|
+
/** Publishes a safe fixed mutation failure while preserving validated content. */
|
|
44
|
+
const publishFailure = (result) => {
|
|
45
|
+
publish({
|
|
46
|
+
kind: 'failure',
|
|
47
|
+
failure: result.failure,
|
|
48
|
+
...(projection ? { previous: projection } : {}),
|
|
49
|
+
});
|
|
50
|
+
};
|
|
51
|
+
/** Handles one completed mutation and returns whether authoritative reload may continue. */
|
|
52
|
+
const finishMutation = (result) => {
|
|
53
|
+
mutationDispatched = false;
|
|
54
|
+
if (result.kind === 'session-invalid') {
|
|
55
|
+
sessionInvalid();
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
if (result.kind === 'outcome-unknown') {
|
|
59
|
+
recoveryRequired = true;
|
|
60
|
+
options.setRecoveryRequired?.(true);
|
|
61
|
+
publish({ kind: 'indeterminate', ...(projection ? { previous: projection } : {}) });
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
return result.kind === 'success';
|
|
65
|
+
};
|
|
66
|
+
/** Loads one selected application's metadata and complete same-parent module catalog. */
|
|
67
|
+
const select = async (applicationId) => {
|
|
68
|
+
if (disposed || operation)
|
|
69
|
+
return;
|
|
70
|
+
const current = options.readState();
|
|
71
|
+
const operations = options.readOperations();
|
|
72
|
+
if (current.kind !== 'authenticated' ||
|
|
73
|
+
!current.capabilities.canReadApplications ||
|
|
74
|
+
!operations?.get ||
|
|
75
|
+
!operations.listModules) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
const controller = new AbortController();
|
|
79
|
+
operation = controller;
|
|
80
|
+
const capturedGeneration = ++generation;
|
|
81
|
+
publish({ kind: 'loading', ...(projection ? { previous: projection } : {}) });
|
|
82
|
+
try {
|
|
83
|
+
const applicationResult = await operations.get(applicationId);
|
|
84
|
+
if (!owns(capturedGeneration, controller) || !applicationResult)
|
|
85
|
+
return;
|
|
86
|
+
if (applicationResult.kind === 'session-invalid') {
|
|
87
|
+
sessionInvalid();
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
if (applicationResult.kind === 'failure') {
|
|
91
|
+
publish({
|
|
92
|
+
kind: 'failure',
|
|
93
|
+
failure: applicationResult.failure,
|
|
94
|
+
...(projection ? { previous: projection } : {}),
|
|
95
|
+
});
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
const moduleResult = await operations.listModules(applicationResult.value.application.id);
|
|
99
|
+
if (!owns(capturedGeneration, controller) || !moduleResult)
|
|
100
|
+
return;
|
|
101
|
+
if (moduleResult.kind === 'session-invalid') {
|
|
102
|
+
sessionInvalid();
|
|
103
|
+
}
|
|
104
|
+
else if (moduleResult.kind === 'failure') {
|
|
105
|
+
publish({
|
|
106
|
+
kind: 'failure',
|
|
107
|
+
failure: moduleResult.failure,
|
|
108
|
+
...(projection ? { previous: projection } : {}),
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
projection = {
|
|
113
|
+
kind: 'detail',
|
|
114
|
+
scope: 'global',
|
|
115
|
+
applications: projection?.applications ?? [applicationResult.value.application],
|
|
116
|
+
application: applicationResult.value.application,
|
|
117
|
+
etag: applicationResult.value.etag,
|
|
118
|
+
modules: moduleResult.value,
|
|
119
|
+
};
|
|
120
|
+
recoveryRequired = false;
|
|
121
|
+
options.setRecoveryRequired?.(false);
|
|
122
|
+
publish(projection);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
finally {
|
|
126
|
+
if (operation === controller)
|
|
127
|
+
operation = undefined;
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
/** Loads the current complete catalog. */
|
|
131
|
+
const load = async () => {
|
|
132
|
+
if (disposed || operation)
|
|
133
|
+
return;
|
|
134
|
+
const current = options.readState();
|
|
135
|
+
const operations = options.readOperations();
|
|
136
|
+
if (current.kind !== 'authenticated' ||
|
|
137
|
+
!current.capabilities.canReadApplications ||
|
|
138
|
+
!operations?.listAll) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
const controller = new AbortController();
|
|
142
|
+
operation = controller;
|
|
143
|
+
const capturedGeneration = ++generation;
|
|
144
|
+
publish({ kind: 'loading', ...(projection ? { previous: projection } : {}) });
|
|
145
|
+
try {
|
|
146
|
+
const result = await operations.listAll();
|
|
147
|
+
if (!owns(capturedGeneration, controller) || !result)
|
|
148
|
+
return;
|
|
149
|
+
if (result.kind === 'session-invalid') {
|
|
150
|
+
sessionInvalid();
|
|
151
|
+
}
|
|
152
|
+
else if (result.kind === 'success') {
|
|
153
|
+
projection = { kind: 'list', scope: 'global', applications: result.value };
|
|
154
|
+
recoveryRequired = false;
|
|
155
|
+
options.setRecoveryRequired?.(false);
|
|
156
|
+
publish(projection);
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
publish({
|
|
160
|
+
kind: 'failure',
|
|
161
|
+
failure: result.failure,
|
|
162
|
+
...(projection ? { previous: projection } : {}),
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
finally {
|
|
167
|
+
if (operation === controller)
|
|
168
|
+
operation = undefined;
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
/** Reloads whichever safe projection the operator currently owns. */
|
|
172
|
+
const reload = () => projection?.kind === 'detail' ? select(projection.application.id) : load();
|
|
173
|
+
/** Checks that a module mutation still targets the selected parent. */
|
|
174
|
+
const ownsMutableModuleParent = (applicationId, moduleId) => projection?.kind === 'detail' &&
|
|
175
|
+
projection.application.id === applicationId &&
|
|
176
|
+
(moduleId === undefined ||
|
|
177
|
+
projection.modules.some((module) => module.id === moduleId && module.applicationId === applicationId));
|
|
178
|
+
/** Runs one application mutation with fresh capability and single-operation ownership. */
|
|
179
|
+
const mutate = async (capability, invoke, reload, confirm, precondition, reloadOnFailure = false) => {
|
|
180
|
+
if (disposed || operation || recoveryRequired)
|
|
181
|
+
return;
|
|
182
|
+
const initial = options.readState();
|
|
183
|
+
if (initial.kind !== 'authenticated' ||
|
|
184
|
+
!initial.capabilities[capability] ||
|
|
185
|
+
(precondition && !precondition())) {
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
const controller = new AbortController();
|
|
189
|
+
operation = controller;
|
|
190
|
+
const capturedGeneration = ++generation;
|
|
191
|
+
try {
|
|
192
|
+
if (confirm &&
|
|
193
|
+
(!(await confirm(controller.signal)) || !owns(capturedGeneration, controller))) {
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
const current = options.readState();
|
|
197
|
+
const operations = options.readOperations();
|
|
198
|
+
if (current.kind !== 'authenticated' ||
|
|
199
|
+
!current.capabilities[capability] ||
|
|
200
|
+
!operations ||
|
|
201
|
+
(precondition && !precondition())) {
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
mutationDispatched = true;
|
|
205
|
+
const result = await invoke(operations);
|
|
206
|
+
if (!owns(capturedGeneration, controller))
|
|
207
|
+
return;
|
|
208
|
+
if (result.kind === 'failure') {
|
|
209
|
+
mutationDispatched = false;
|
|
210
|
+
if (reloadOnFailure) {
|
|
211
|
+
const selectedApplicationId = projection?.kind === 'detail' ? projection.application.id : undefined;
|
|
212
|
+
operation = undefined;
|
|
213
|
+
if (selectedApplicationId)
|
|
214
|
+
await select(selectedApplicationId);
|
|
215
|
+
else
|
|
216
|
+
await load();
|
|
217
|
+
if (!projection)
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
publishFailure(result);
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
if (!finishMutation(result))
|
|
224
|
+
return;
|
|
225
|
+
operation = undefined;
|
|
226
|
+
if (reload === 'list')
|
|
227
|
+
await load();
|
|
228
|
+
else
|
|
229
|
+
await select(reload.applicationId);
|
|
230
|
+
}
|
|
231
|
+
finally {
|
|
232
|
+
if (operation === controller) {
|
|
233
|
+
operation = undefined;
|
|
234
|
+
mutationDispatched = false;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
return {
|
|
239
|
+
syncContext(state, nextSessionEpoch) {
|
|
240
|
+
if (disposed)
|
|
241
|
+
return;
|
|
242
|
+
const authenticated = state.kind === 'authenticated';
|
|
243
|
+
if (!authenticated || (sessionEpoch >= 0 && sessionEpoch !== nextSessionEpoch)) {
|
|
244
|
+
cancel();
|
|
245
|
+
projection = undefined;
|
|
246
|
+
recoveryRequired = false;
|
|
247
|
+
options.setRecoveryRequired?.(false);
|
|
248
|
+
publish({ kind: 'closed' });
|
|
249
|
+
}
|
|
250
|
+
sessionEpoch = authenticated ? nextSessionEpoch : -1;
|
|
251
|
+
},
|
|
252
|
+
load,
|
|
253
|
+
select,
|
|
254
|
+
reload,
|
|
255
|
+
create: (input) => mutate('canCreateApplications', (operations) => operations.create?.(input) ?? Promise.resolve({ kind: 'cancelled' }), 'list'),
|
|
256
|
+
update: (applicationId, input, etag) => mutate('canUpdateApplications', (operations) => operations.update?.(applicationId, input, etag) ?? Promise.resolve({ kind: 'cancelled' }), { applicationId }),
|
|
257
|
+
activate: (applicationId, confirm) => mutate('canUpdateApplications', (operations) => operations.activate?.(applicationId) ?? Promise.resolve({ kind: 'cancelled' }), { applicationId }, confirm),
|
|
258
|
+
deactivate: (applicationId, confirm) => mutate('canUpdateApplications', (operations) => operations.deactivate?.(applicationId) ?? Promise.resolve({ kind: 'cancelled' }), { applicationId }, confirm),
|
|
259
|
+
delete: (applicationId, confirm) => mutate('canDeleteApplications', (operations) => operations.delete?.(applicationId) ?? Promise.resolve({ kind: 'cancelled' }), 'list', confirm, undefined, true),
|
|
260
|
+
addModule: (applicationId, input) => mutate('canUpdateApplications', (operations) => operations.addModule?.(applicationId, input) ?? Promise.resolve({ kind: 'cancelled' }), { applicationId }, undefined, () => ownsMutableModuleParent(applicationId)),
|
|
261
|
+
updateModule: (applicationId, moduleId, input) => mutate('canUpdateApplications', (operations) => operations.updateModule?.(applicationId, moduleId, input) ??
|
|
262
|
+
Promise.resolve({ kind: 'cancelled' }), { applicationId }, undefined, () => ownsMutableModuleParent(applicationId, moduleId)),
|
|
263
|
+
activateModule: (applicationId, moduleId) => mutate('canUpdateApplications', (operations) => operations.activateModule?.(applicationId, moduleId) ??
|
|
264
|
+
Promise.resolve({ kind: 'cancelled' }), { applicationId }, undefined, () => ownsMutableModuleParent(applicationId, moduleId)),
|
|
265
|
+
deactivateModule: (applicationId, moduleId, confirm) => mutate('canUpdateApplications', (operations) => operations.deactivateModule?.(applicationId, moduleId) ??
|
|
266
|
+
Promise.resolve({ kind: 'cancelled' }), { applicationId }, confirm, () => ownsMutableModuleParent(applicationId, moduleId)),
|
|
267
|
+
deleteModule: (applicationId, moduleId, confirm) => mutate('canDeleteModules', (operations) => operations.deleteModule?.(applicationId, moduleId) ??
|
|
268
|
+
Promise.resolve({ kind: 'cancelled' }), { applicationId }, confirm, () => ownsMutableModuleParent(applicationId, moduleId), true),
|
|
269
|
+
cancelActiveOperation: () => cancel(true),
|
|
270
|
+
handleRecoverableGeometry(recoverable) {
|
|
271
|
+
if (!recoverable)
|
|
272
|
+
cancel(true);
|
|
273
|
+
},
|
|
274
|
+
dispose() {
|
|
275
|
+
if (disposed)
|
|
276
|
+
return;
|
|
277
|
+
cancel();
|
|
278
|
+
disposed = true;
|
|
279
|
+
projection = undefined;
|
|
280
|
+
recoveryRequired = false;
|
|
281
|
+
options.setRecoveryRequired?.(false);
|
|
282
|
+
options.publishState({ kind: 'closed' });
|
|
283
|
+
},
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
//# sourceMappingURL=application-controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"application-controller.js","sourceRoot":"","sources":["../../src/admin/application-controller.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/** Movable Layout DSL dialogs for deployment-global application administration. */
|
|
2
|
+
import type { CreateApplicationInput, CreateModuleInput, UpdateApplicationInput, UpdateModuleInput } from '@portaidentity/sdk';
|
|
3
|
+
import type { EventLoop, ModalDialogHost } from '@jsvision/ui';
|
|
4
|
+
import type { AdminApplication, AdminApplicationModule } from './application-state.js';
|
|
5
|
+
/** Modal host needed for abort-driven application dialog closure. */
|
|
6
|
+
export interface AdminApplicationDialogHost extends ModalDialogHost {
|
|
7
|
+
/** Event loop that can synchronously close the currently owned modal. */
|
|
8
|
+
readonly loop: ModalDialogHost['loop'] & Pick<EventLoop, 'endModal' | 'focusView'>;
|
|
9
|
+
}
|
|
10
|
+
/** Result of the global application create dialog. */
|
|
11
|
+
export type CreateApplicationDialogResult = {
|
|
12
|
+
readonly kind: 'create';
|
|
13
|
+
readonly input: CreateApplicationInput;
|
|
14
|
+
} | {
|
|
15
|
+
readonly kind: 'cancel';
|
|
16
|
+
};
|
|
17
|
+
/** Result of the global application edit dialog. */
|
|
18
|
+
export type EditApplicationDialogResult = {
|
|
19
|
+
readonly kind: 'update';
|
|
20
|
+
readonly applicationId: string;
|
|
21
|
+
readonly etag?: string;
|
|
22
|
+
readonly input: UpdateApplicationInput;
|
|
23
|
+
} | {
|
|
24
|
+
readonly kind: 'cancel';
|
|
25
|
+
};
|
|
26
|
+
/** Application lifecycle choices that require an explicit warning. */
|
|
27
|
+
export type ApplicationLifecycleAction = 'deactivate';
|
|
28
|
+
/** Result of an application lifecycle confirmation. */
|
|
29
|
+
export type ApplicationLifecycleDialogResult = {
|
|
30
|
+
readonly kind: ApplicationLifecycleAction;
|
|
31
|
+
readonly applicationId: string;
|
|
32
|
+
} | {
|
|
33
|
+
readonly kind: 'cancel';
|
|
34
|
+
};
|
|
35
|
+
/** Result of the module create dialog. */
|
|
36
|
+
export type CreateModuleDialogResult = {
|
|
37
|
+
readonly kind: 'create-module';
|
|
38
|
+
readonly applicationId: string;
|
|
39
|
+
readonly input: CreateModuleInput;
|
|
40
|
+
} | {
|
|
41
|
+
readonly kind: 'cancel';
|
|
42
|
+
};
|
|
43
|
+
/** Result of the module edit dialog. */
|
|
44
|
+
export type EditModuleDialogResult = {
|
|
45
|
+
readonly kind: 'update-module';
|
|
46
|
+
readonly applicationId: string;
|
|
47
|
+
readonly moduleId: string;
|
|
48
|
+
readonly input: UpdateModuleInput;
|
|
49
|
+
} | {
|
|
50
|
+
readonly kind: 'cancel';
|
|
51
|
+
};
|
|
52
|
+
/** Result of the module deactivation confirmation. */
|
|
53
|
+
export type ModuleDeactivationDialogResult = {
|
|
54
|
+
readonly kind: 'deactivate-module';
|
|
55
|
+
readonly applicationId: string;
|
|
56
|
+
readonly moduleId: string;
|
|
57
|
+
} | {
|
|
58
|
+
readonly kind: 'cancel';
|
|
59
|
+
};
|
|
60
|
+
/** Result of an irreversible application or module deletion dialog. */
|
|
61
|
+
export type ApplicationDeleteDialogResult = {
|
|
62
|
+
readonly kind: 'delete';
|
|
63
|
+
readonly applicationId: string;
|
|
64
|
+
} | {
|
|
65
|
+
readonly kind: 'cancel';
|
|
66
|
+
};
|
|
67
|
+
/** Result of an irreversible module deletion dialog. */
|
|
68
|
+
export type ModuleDeleteDialogResult = {
|
|
69
|
+
readonly kind: 'delete';
|
|
70
|
+
readonly applicationId: string;
|
|
71
|
+
readonly moduleId: string;
|
|
72
|
+
} | {
|
|
73
|
+
readonly kind: 'cancel';
|
|
74
|
+
};
|
|
75
|
+
/** Shows the application create form with optional slug and description. */
|
|
76
|
+
export declare function showCreateApplicationDialog(host: AdminApplicationDialogHost, operationSignal: AbortSignal): Promise<CreateApplicationDialogResult>;
|
|
77
|
+
/** Shows the application editor while keeping its stable slug read-only. */
|
|
78
|
+
export declare function showEditApplicationDialog(host: AdminApplicationDialogHost, operationSignal: AbortSignal, application: AdminApplication, etag?: string): Promise<EditApplicationDialogResult>;
|
|
79
|
+
/** Shows the exact application lifecycle effect before dispatch. */
|
|
80
|
+
export declare function showApplicationLifecycleDialog(host: AdminApplicationDialogHost, operationSignal: AbortSignal, action: ApplicationLifecycleAction, application: AdminApplication): Promise<ApplicationLifecycleDialogResult>;
|
|
81
|
+
/** Shows the deployment-global cascade before permanently deleting an application. */
|
|
82
|
+
export declare function showDeleteApplicationDialog(host: AdminApplicationDialogHost, operationSignal: AbortSignal, application: AdminApplication): Promise<ApplicationDeleteDialogResult>;
|
|
83
|
+
/** Shows the module create form under its explicit internal parent UUID. */
|
|
84
|
+
export declare function showCreateModuleDialog(host: AdminApplicationDialogHost, operationSignal: AbortSignal, applicationId: string): Promise<CreateModuleDialogResult>;
|
|
85
|
+
/** Shows the module editor with its stable slug and parent kept read-only. */
|
|
86
|
+
export declare function showEditModuleDialog(host: AdminApplicationDialogHost, operationSignal: AbortSignal, module: AdminApplicationModule): Promise<EditModuleDialogResult>;
|
|
87
|
+
/** Shows the exact module deactivation target before dispatch. */
|
|
88
|
+
export declare function showModuleDeactivationDialog(host: AdminApplicationDialogHost, operationSignal: AbortSignal, application: AdminApplication, module: AdminApplicationModule): Promise<ModuleDeactivationDialogResult>;
|
|
89
|
+
/** Shows the owned-permission cascade before permanently deleting a module. */
|
|
90
|
+
export declare function showDeleteModuleDialog(host: AdminApplicationDialogHost, operationSignal: AbortSignal, application: AdminApplication, module: AdminApplicationModule): Promise<ModuleDeleteDialogResult>;
|
|
91
|
+
//# sourceMappingURL=application-dialogs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"application-dialogs.d.ts","sourceRoot":"","sources":["../../src/admin/application-dialogs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
/** Movable Layout DSL dialogs for deployment-global application administration. */
|
|
2
|
+
import { Button, col, Commands, cover, Dialog, fixed, grow, Input, Label, Memo, row, signal, spacer, Text, } from '@jsvision/ui';
|
|
3
|
+
import { runAbortableAdminDialog } from './application-runtime.js';
|
|
4
|
+
import { deleteActionLabel, deleteConfirmationLayout } from './delete-confirmation-layout.js';
|
|
5
|
+
import { SelectableReadOnlyInput } from './selectable-read-only-input.js';
|
|
6
|
+
import { textValidator } from './user-dialog-fields.js';
|
|
7
|
+
/** Plain-language scope note shown when an application is created. */
|
|
8
|
+
const APPLICATION_CREATE_SCOPE_NOTICE = 'This application will be available to every organization.';
|
|
9
|
+
/** Plain-language scope note shown when a shared application or module changes. */
|
|
10
|
+
const APPLICATION_CHANGE_SCOPE_NOTICE = 'Changes apply wherever this application is used.';
|
|
11
|
+
/** Preferred height that leaves the shared description memo several visible editing rows. */
|
|
12
|
+
const ENTITY_FORM_DIALOG_HEIGHT = 20;
|
|
13
|
+
/** Dialog that includes its multiline description in the modal validity gate. */
|
|
14
|
+
class EntityDialog extends Dialog {
|
|
15
|
+
description;
|
|
16
|
+
descriptionMemo;
|
|
17
|
+
/** Creates one ordinary movable dialog with a bounded description owner. */
|
|
18
|
+
constructor(title, width, height, description, descriptionMemo) {
|
|
19
|
+
super({ title, width, height, centered: true });
|
|
20
|
+
this.description = description;
|
|
21
|
+
this.descriptionMemo = descriptionMemo;
|
|
22
|
+
}
|
|
23
|
+
/** Rejects oversized or unsafe descriptions before the modal can close. */
|
|
24
|
+
valid(command) {
|
|
25
|
+
if (command !== Commands.cancel &&
|
|
26
|
+
!validMultilineText(this.description.peek(), 0, 2_000, true)) {
|
|
27
|
+
this.firstInvalid = this.descriptionMemo;
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
return super.valid(command);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/** Accepts bounded memo text with line endings while rejecting other terminal controls. */
|
|
34
|
+
function validMultilineText(value, minimum, maximum, optional = false) {
|
|
35
|
+
if (value.length === 0)
|
|
36
|
+
return optional || minimum === 0;
|
|
37
|
+
if (value.length < minimum || value.length > maximum)
|
|
38
|
+
return false;
|
|
39
|
+
for (const character of value) {
|
|
40
|
+
const codePoint = character.codePointAt(0) ?? 0;
|
|
41
|
+
if (codePoint === 0x0a || codePoint === 0x0d)
|
|
42
|
+
continue;
|
|
43
|
+
if (codePoint <= 0x1f || (codePoint >= 0x7f && codePoint <= 0x9f))
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
/** Creates the server-compatible create-only slug validator. */
|
|
49
|
+
function slugValidator() {
|
|
50
|
+
const syntax = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;
|
|
51
|
+
return {
|
|
52
|
+
isValidInput: (value) => value.length <= 100 && ![...value].some((character) => character.codePointAt(0) <= 0x1f),
|
|
53
|
+
isValid: (value) => value.length === 0 || (value.length >= 3 && value.length <= 100 && syntax.test(value)),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/** Returns a dialog size capped to the current terminal surface. */
|
|
57
|
+
function dialogSize(host, preferredWidth, preferredHeight) {
|
|
58
|
+
return {
|
|
59
|
+
width: Math.max(1, Math.min(preferredWidth, host.desktop.bounds.width)),
|
|
60
|
+
height: Math.max(1, Math.min(preferredHeight, host.desktop.bounds.height)),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/** Runs one abortable modal and always removes its window from the desktop. */
|
|
64
|
+
async function runDialog(host, dialog, operationSignal) {
|
|
65
|
+
host.desktop.addWindow(dialog);
|
|
66
|
+
try {
|
|
67
|
+
return await runAbortableAdminDialog(host.loop, operationSignal, async () => (await host.loop.execView(dialog)) ?? Commands.cancel);
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
if (error instanceof DOMException && error.name === 'AbortError')
|
|
71
|
+
return Commands.cancel;
|
|
72
|
+
throw error;
|
|
73
|
+
}
|
|
74
|
+
finally {
|
|
75
|
+
host.desktop.removeWindow(dialog);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/** Creates one labeled single-line row that cannot stretch vertically. */
|
|
79
|
+
function inputRow(label, input) {
|
|
80
|
+
return fixed(row({ gap: 1 }, fixed(new Label(label, input), 14), grow(input)), 1);
|
|
81
|
+
}
|
|
82
|
+
/** Creates form signals and controls for create or edit. */
|
|
83
|
+
function entityForm(current, includeSlug = false) {
|
|
84
|
+
const name = signal(current?.name ?? '');
|
|
85
|
+
const slug = includeSlug ? signal('') : undefined;
|
|
86
|
+
const description = signal(current?.description ?? '');
|
|
87
|
+
const nameInput = new Input({
|
|
88
|
+
value: name,
|
|
89
|
+
maxLength: 255,
|
|
90
|
+
validator: textValidator(1, 255, false),
|
|
91
|
+
});
|
|
92
|
+
const slugInput = slug
|
|
93
|
+
? new Input({ value: slug, maxLength: 100, validator: slugValidator() })
|
|
94
|
+
: undefined;
|
|
95
|
+
const descriptionMemo = new Memo({ value: description });
|
|
96
|
+
return {
|
|
97
|
+
name,
|
|
98
|
+
...(slug ? { slug } : {}),
|
|
99
|
+
description,
|
|
100
|
+
nameInput,
|
|
101
|
+
...(slugInput ? { slugInput } : {}),
|
|
102
|
+
descriptionMemo,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
/** Builds the complete Layout DSL content for one entity form. */
|
|
106
|
+
function formLayout(form, readOnlySlug, submitLabel, scopeNotice) {
|
|
107
|
+
return col({ gap: 1, padding: { top: 1, right: 2, bottom: 1, left: 2 } }, inputRow('Name', form.nameInput), form.slugInput && inputRow('Slug', form.slugInput), readOnlySlug ? inputRow('Slug', new SelectableReadOnlyInput(readOnlySlug)) : undefined, fixed(new Text('Description'), 1), grow(form.descriptionMemo, 1, { min: 4 }), fixed(new Text(scopeNotice), 1), fixed(row({ gap: 1 }, spacer(), new Button(submitLabel, { command: Commands.ok, default: true }), new Button('Cancel', { command: Commands.cancel })), 2));
|
|
108
|
+
}
|
|
109
|
+
/** Shows the application create form with optional slug and description. */
|
|
110
|
+
export async function showCreateApplicationDialog(host, operationSignal) {
|
|
111
|
+
const { width, height } = dialogSize(host, 68, ENTITY_FORM_DIALOG_HEIGHT);
|
|
112
|
+
const form = entityForm(undefined, true);
|
|
113
|
+
const dialog = new EntityDialog('Create application', width, height, form.description, form.descriptionMemo);
|
|
114
|
+
dialog.add(cover(formLayout(form, undefined, '~C~reate', APPLICATION_CREATE_SCOPE_NOTICE)));
|
|
115
|
+
if ((await runDialog(host, dialog, operationSignal)) !== Commands.ok)
|
|
116
|
+
return { kind: 'cancel' };
|
|
117
|
+
const input = { name: form.name.peek() };
|
|
118
|
+
if (form.slug?.peek())
|
|
119
|
+
input.slug = form.slug.peek();
|
|
120
|
+
if (form.description.peek())
|
|
121
|
+
input.description = form.description.peek();
|
|
122
|
+
return { kind: 'create', input };
|
|
123
|
+
}
|
|
124
|
+
/** Shows the application editor while keeping its stable slug read-only. */
|
|
125
|
+
export async function showEditApplicationDialog(host, operationSignal, application, etag) {
|
|
126
|
+
const { width, height } = dialogSize(host, 68, ENTITY_FORM_DIALOG_HEIGHT);
|
|
127
|
+
const form = entityForm(application);
|
|
128
|
+
const dialog = new EntityDialog('Edit application', width, height, form.description, form.descriptionMemo);
|
|
129
|
+
dialog.add(cover(formLayout(form, application.slug, '~S~ave', APPLICATION_CHANGE_SCOPE_NOTICE)));
|
|
130
|
+
if ((await runDialog(host, dialog, operationSignal)) !== Commands.ok)
|
|
131
|
+
return { kind: 'cancel' };
|
|
132
|
+
const input = {};
|
|
133
|
+
if (form.name.peek() !== application.name)
|
|
134
|
+
input.name = form.name.peek();
|
|
135
|
+
if (form.description.peek() !== (application.description ?? '')) {
|
|
136
|
+
input.description = form.description.peek() || null;
|
|
137
|
+
}
|
|
138
|
+
return {
|
|
139
|
+
kind: 'update',
|
|
140
|
+
applicationId: application.id,
|
|
141
|
+
...(etag ? { etag } : {}),
|
|
142
|
+
input,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
/** Shows the exact application lifecycle effect before dispatch. */
|
|
146
|
+
export async function showApplicationLifecycleDialog(host, operationSignal, action, application) {
|
|
147
|
+
const { width, height } = dialogSize(host, 68, 12);
|
|
148
|
+
const title = 'Deactivate application';
|
|
149
|
+
const dialog = new Dialog({ title, width, height, centered: true });
|
|
150
|
+
dialog.add(cover(col({ gap: 1, padding: { top: 1, right: 2, bottom: 1, left: 2 } }, grow(new Text(`${title}: ${application.name}?\nNew client creation stops.\nExisting clients remain enabled.`)), fixed(new Text(APPLICATION_CHANGE_SCOPE_NOTICE), 1), fixed(row({ gap: 1 }, spacer(), new Button(title, { command: Commands.ok, default: true }), new Button('Cancel', { command: Commands.cancel })), 2))));
|
|
151
|
+
return (await runDialog(host, dialog, operationSignal)) === Commands.ok
|
|
152
|
+
? { kind: action, applicationId: application.id }
|
|
153
|
+
: { kind: 'cancel' };
|
|
154
|
+
}
|
|
155
|
+
/** Shows the deployment-global cascade before permanently deleting an application. */
|
|
156
|
+
export async function showDeleteApplicationDialog(host, operationSignal, application) {
|
|
157
|
+
const { width, height } = dialogSize(host, 76, 14);
|
|
158
|
+
const keep = new Button('Keep', { command: Commands.cancel, default: true });
|
|
159
|
+
const remove = new Button(deleteActionLabel(application.name, width), {
|
|
160
|
+
command: Commands.yes,
|
|
161
|
+
});
|
|
162
|
+
const dialog = new Dialog({ title: 'Delete application', width, height, centered: true });
|
|
163
|
+
const confirmation = deleteConfirmationLayout({
|
|
164
|
+
dialogWidth: width,
|
|
165
|
+
details: `Application: ${application.name}`,
|
|
166
|
+
warning: 'This deployment-global deletion removes its modules, clients, roles, permissions, and claims.',
|
|
167
|
+
keep,
|
|
168
|
+
remove,
|
|
169
|
+
});
|
|
170
|
+
dialog.add(cover(confirmation.content));
|
|
171
|
+
const outcome = runDialog(host, dialog, operationSignal);
|
|
172
|
+
host.loop.focusView(keep);
|
|
173
|
+
return (await outcome) === Commands.yes
|
|
174
|
+
? { kind: 'delete', applicationId: application.id }
|
|
175
|
+
: { kind: 'cancel' };
|
|
176
|
+
}
|
|
177
|
+
/** Shows the module create form under its explicit internal parent UUID. */
|
|
178
|
+
export async function showCreateModuleDialog(host, operationSignal, applicationId) {
|
|
179
|
+
const { width, height } = dialogSize(host, 68, ENTITY_FORM_DIALOG_HEIGHT);
|
|
180
|
+
const form = entityForm(undefined, true);
|
|
181
|
+
const dialog = new EntityDialog('Add module', width, height, form.description, form.descriptionMemo);
|
|
182
|
+
dialog.add(cover(formLayout(form, undefined, '~A~dd', APPLICATION_CHANGE_SCOPE_NOTICE)));
|
|
183
|
+
if ((await runDialog(host, dialog, operationSignal)) !== Commands.ok)
|
|
184
|
+
return { kind: 'cancel' };
|
|
185
|
+
const input = { name: form.name.peek() };
|
|
186
|
+
if (form.slug?.peek())
|
|
187
|
+
input.slug = form.slug.peek();
|
|
188
|
+
if (form.description.peek())
|
|
189
|
+
input.description = form.description.peek();
|
|
190
|
+
return { kind: 'create-module', applicationId, input };
|
|
191
|
+
}
|
|
192
|
+
/** Shows the module editor with its stable slug and parent kept read-only. */
|
|
193
|
+
export async function showEditModuleDialog(host, operationSignal, module) {
|
|
194
|
+
const { width, height } = dialogSize(host, 68, ENTITY_FORM_DIALOG_HEIGHT);
|
|
195
|
+
const form = entityForm(module);
|
|
196
|
+
const dialog = new EntityDialog('Edit module', width, height, form.description, form.descriptionMemo);
|
|
197
|
+
dialog.add(cover(formLayout(form, module.slug, '~S~ave', APPLICATION_CHANGE_SCOPE_NOTICE)));
|
|
198
|
+
if ((await runDialog(host, dialog, operationSignal)) !== Commands.ok)
|
|
199
|
+
return { kind: 'cancel' };
|
|
200
|
+
const input = {};
|
|
201
|
+
if (form.name.peek() !== module.name)
|
|
202
|
+
input.name = form.name.peek();
|
|
203
|
+
if (form.description.peek() !== (module.description ?? '')) {
|
|
204
|
+
input.description = form.description.peek() || null;
|
|
205
|
+
}
|
|
206
|
+
return {
|
|
207
|
+
kind: 'update-module',
|
|
208
|
+
applicationId: module.applicationId,
|
|
209
|
+
moduleId: module.id,
|
|
210
|
+
input,
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
/** Shows the exact module deactivation target before dispatch. */
|
|
214
|
+
export async function showModuleDeactivationDialog(host, operationSignal, application, module) {
|
|
215
|
+
if (module.applicationId !== application.id)
|
|
216
|
+
return { kind: 'cancel' };
|
|
217
|
+
const { width, height } = dialogSize(host, 68, 11);
|
|
218
|
+
const dialog = new Dialog({ title: 'Deactivate module', width, height, centered: true });
|
|
219
|
+
dialog.add(cover(col({ gap: 1, padding: { top: 1, right: 2, bottom: 1, left: 2 } }, grow(new Text(`Application: ${application.name}\nModule: ${module.name}`)), fixed(new Text(APPLICATION_CHANGE_SCOPE_NOTICE), 1), fixed(row({ gap: 1 }, spacer(), new Button('Deactivate', { command: Commands.ok, default: true }), new Button('Cancel', { command: Commands.cancel })), 2))));
|
|
220
|
+
return (await runDialog(host, dialog, operationSignal)) === Commands.ok
|
|
221
|
+
? {
|
|
222
|
+
kind: 'deactivate-module',
|
|
223
|
+
applicationId: application.id,
|
|
224
|
+
moduleId: module.id,
|
|
225
|
+
}
|
|
226
|
+
: { kind: 'cancel' };
|
|
227
|
+
}
|
|
228
|
+
/** Shows the owned-permission cascade before permanently deleting a module. */
|
|
229
|
+
export async function showDeleteModuleDialog(host, operationSignal, application, module) {
|
|
230
|
+
if (module.applicationId !== application.id)
|
|
231
|
+
return { kind: 'cancel' };
|
|
232
|
+
const { width, height } = dialogSize(host, 70, 13);
|
|
233
|
+
const keep = new Button('Keep', { command: Commands.cancel, default: true });
|
|
234
|
+
const remove = new Button(deleteActionLabel(module.name, width), { command: Commands.yes });
|
|
235
|
+
const dialog = new Dialog({ title: 'Delete module', width, height, centered: true });
|
|
236
|
+
const confirmation = deleteConfirmationLayout({
|
|
237
|
+
dialogWidth: width,
|
|
238
|
+
details: `Application: ${application.name}\nModule: ${module.name}`,
|
|
239
|
+
warning: 'Deleting this module also deletes its\npermissions and dependent links.',
|
|
240
|
+
keep,
|
|
241
|
+
remove,
|
|
242
|
+
});
|
|
243
|
+
dialog.add(cover(confirmation.content));
|
|
244
|
+
const outcome = runDialog(host, dialog, operationSignal);
|
|
245
|
+
host.loop.focusView(keep);
|
|
246
|
+
return (await outcome) === Commands.yes
|
|
247
|
+
? { kind: 'delete', applicationId: application.id, moduleId: module.id }
|
|
248
|
+
: { kind: 'cancel' };
|
|
249
|
+
}
|
|
250
|
+
//# sourceMappingURL=application-dialogs.js.map
|