@umbraco-cms/backoffice 17.4.0-rc → 17.4.0-rc2
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/custom-elements.json +1 -1
- package/dist-cms/apps/app/app.element.js +120 -7
- package/dist-cms/apps/backoffice/backoffice.context.js +1 -9
- package/dist-cms/apps/backoffice/backoffice.element.d.ts +0 -2
- package/dist-cms/apps/backoffice/backoffice.element.js +0 -58
- package/dist-cms/apps/backoffice/components/backoffice-main.element.d.ts +2 -2
- package/dist-cms/apps/backoffice/components/backoffice-main.element.js +16 -3
- package/dist-cms/libs/extension-api/controller/base-extension-initializer.controller.d.ts +1 -1
- package/dist-cms/libs/extension-api/controller/base-extension-initializer.controller.js +61 -19
- package/dist-cms/libs/extension-api/controller/extension-api-initializer.controller.d.ts +1 -1
- package/dist-cms/libs/extension-api/controller/extension-api-initializer.controller.js +10 -3
- package/dist-cms/libs/extension-api/controller/extension-element-and-api-initializer.controller.d.ts +1 -1
- package/dist-cms/libs/extension-api/controller/extension-element-and-api-initializer.controller.js +12 -3
- package/dist-cms/libs/extension-api/controller/extension-element-initializer.controller.d.ts +1 -1
- package/dist-cms/libs/extension-api/controller/extension-element-initializer.controller.js +11 -3
- package/dist-cms/libs/extension-api/controller/extension-manifest-initializer.controller.d.ts +1 -1
- package/dist-cms/libs/extension-api/controller/extension-manifest-initializer.controller.js +1 -1
- package/dist-cms/libs/extension-api/initializers/extension-initializer-base.d.ts +2 -2
- package/dist-cms/libs/extension-api/initializers/extension-initializer-base.js +7 -3
- package/dist-cms/libs/extension-api/registry/extension.registry.js +22 -2
- package/dist-cms/packages/block/block/conditions/block-workspace-is-readonly.condition.js +4 -2
- package/dist-cms/packages/block/block/context/block-entry.context.js +1 -4
- package/dist-cms/packages/block/block/workspace/block-element-manager.js +2 -2
- package/dist-cms/packages/block/block/workspace/block-workspace-editor.element.d.ts +1 -0
- package/dist-cms/packages/block/block/workspace/block-workspace-editor.element.js +31 -9
- package/dist-cms/packages/block/block/workspace/block-workspace-language-access.controller.d.ts +16 -0
- package/dist-cms/packages/block/block/workspace/block-workspace-language-access.controller.js +126 -0
- package/dist-cms/packages/block/block/workspace/block-workspace.context.js +23 -19
- package/dist-cms/packages/block/block/workspace/manifests.js +3 -0
- package/dist-cms/packages/block/block-custom-view/types.d.ts +1 -0
- package/dist-cms/packages/block/block-grid/components/block-grid-entry/block-grid-entry.element.js +4 -5
- package/dist-cms/packages/block/block-grid/property-editors/block-grid-editor/property-editor-ui-block-grid.element.js +2 -5
- package/dist-cms/packages/block/block-list/components/block-list-entry/block-list-entry.element.js +11 -6
- package/dist-cms/packages/block/block-rte/components/block-rte-entry/block-rte-entry.element.js +4 -5
- package/dist-cms/packages/block/block-single/components/block-single-entry/block-single-entry.element.js +4 -5
- package/dist-cms/packages/code-editor/umbraco-package.d.ts +1 -0
- package/dist-cms/packages/code-editor/umbraco-package.js +1 -0
- package/dist-cms/packages/content/content/global-components/content-workspace-property.element.js +1 -1
- package/dist-cms/packages/core/components/body-layout/body-layout.element.js +3 -1
- package/dist-cms/packages/core/extension-registry/conditions/condition-base.controller.js +3 -2
- package/dist-cms/packages/core/extension-registry/conditions/delay.condition.js +5 -1
- package/dist-cms/packages/core/extension-registry/conditions/switch.condition.d.ts +0 -2
- package/dist-cms/packages/core/extension-registry/conditions/switch.condition.js +13 -7
- package/dist-cms/packages/core/property/property-guard-manager/property-guard.manager.d.ts +1 -1
- package/dist-cms/packages/core/property/property-guard-manager/property-guard.manager.js +6 -3
- package/dist-cms/packages/core/property/property-guard-manager/variant-property-guard.manager.d.ts +1 -1
- package/dist-cms/packages/core/property/property-guard-manager/variant-property-guard.manager.js +7 -3
- package/dist-cms/packages/core/recycle-bin/conditions/is-trashed/entity-is-trashed.condition.js +2 -1
- package/dist-cms/packages/core/repository/data-mapper/mapping/data-mapping-resolver.js +1 -0
- package/dist-cms/packages/core/utils/guard-manager/guard.manager.base.d.ts +4 -2
- package/dist-cms/packages/core/utils/guard-manager/guard.manager.base.js +10 -5
- package/dist-cms/packages/core/utils/guard-manager/readonly-guard.manager.js +9 -5
- package/dist-cms/packages/core/utils/guard-manager/readonly-variant-guard.manager.d.ts +12 -2
- package/dist-cms/packages/core/utils/guard-manager/readonly-variant-guard.manager.js +26 -11
- package/dist-cms/packages/core/variant/variant-id.class.d.ts +4 -0
- package/dist-cms/packages/core/variant/variant-id.class.js +5 -1
- package/dist-cms/packages/core/workspace/components/workspace-action/common/submit/submit.action.d.ts +2 -2
- package/dist-cms/packages/core/workspace/components/workspace-action/common/submit/submit.action.js +8 -2
- package/dist-cms/packages/core/workspace/components/workspace-split-view/workspace-split-view-variant-selector.element.js +7 -10
- package/dist-cms/packages/core/workspace/namable/name-write-guard.manager.js +5 -2
- package/dist-cms/packages/core/workspace/workspace.element.d.ts +0 -2
- package/dist-cms/packages/core/workspace/workspace.element.js +1 -4
- package/dist-cms/packages/documents/document-types/property-type/manifests.js +2 -1
- package/dist-cms/packages/documents/documents/reference/repository/manifests.js +2 -1
- package/dist-cms/packages/documents/documents/user-permissions/document-property-value/conditions/document-property-value-user-permission.condition.js +2 -0
- package/dist-cms/packages/documents/documents/user-permissions/document-property-value/data/manifests.js +4 -2
- package/dist-cms/packages/documents/documents/user-permissions/document-property-value/workspace-context/document-block-property-value-user-permission.workspace-context.js +3 -5
- package/dist-cms/packages/documents/documents/workspace/actions/save.action.js +2 -0
- package/dist-cms/packages/documents/documents/workspace/document-workspace.context.js +6 -1
- package/dist-cms/packages/documents/umbraco-package.d.ts +1 -6
- package/dist-cms/packages/documents/umbraco-package.js +2 -8
- package/dist-cms/packages/media/media/reference/repository/manifests.js +2 -1
- package/dist-cms/packages/media/media-types/property-type/manifests.js +2 -1
- package/dist-cms/packages/members/member/reference/repository/manifests.js +2 -1
- package/dist-cms/packages/members/member-type/property-type/manifests.js +2 -1
- package/dist-cms/packages/rte/components/rte-base.element.d.ts +2 -1
- package/dist-cms/packages/rte/components/rte-base.element.js +19 -6
- package/dist-cms/packages/ufm/umbraco-package.d.ts +1 -0
- package/dist-cms/packages/ufm/umbraco-package.js +1 -0
- package/dist-cms/packages/user/current-user/current-user.context.d.ts +3 -1
- package/dist-cms/packages/user/current-user/current-user.context.js +11 -17
- package/dist-cms/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/vscode-html-custom-data.json +3 -3
package/custom-elements.json
CHANGED
|
@@ -382,7 +382,7 @@
|
|
|
382
382
|
},
|
|
383
383
|
{
|
|
384
384
|
"name": "styles",
|
|
385
|
-
"default": "\"css`\\n\\t\\t:host {\\n\\t\\t\\toverflow: hidden;\\n\\t\\t\\tmin-width: 920px;\\n\\t\\t}\\n\\n\\t\\t:host,\\n\\t\\t#router-slot {\\n\\t\\t\\tdisplay: block;\\n\\t\\t\\twidth: 100%;\\n\\t\\t\\theight: 100vh;\\n\\t\\t}\\n\\t`\""
|
|
385
|
+
"default": "\"css`\\n\\t\\t:host {\\n\\t\\t\\toverflow: hidden;\\n\\t\\t\\tmin-width: 920px;\\n\\t\\t}\\n\\n\\t\\t:host,\\n\\t\\t#router-slot {\\n\\t\\t\\tdisplay: block;\\n\\t\\t\\twidth: 100%;\\n\\t\\t\\theight: 100vh;\\n\\t\\t}\\n\\n\\t\\t#loader {\\n\\t\\t\\tdisplay: flex;\\n\\t\\t\\theight: 100%;\\n\\t\\t\\tjustify-content: center;\\n\\t\\t\\talign-items: center;\\n\\t\\t\\topacity: 0;\\n\\t\\t\\tanimation: fadeIn 240ms forwards;\\n\\t\\t}\\n\\t\\t@keyframes fadeIn {\\n\\t\\t\\tto {\\n\\t\\t\\t\\topacity: 1;\\n\\t\\t\\t}\\n\\t\\t}\\n\\t`\""
|
|
386
386
|
}
|
|
387
387
|
]
|
|
388
388
|
},
|
|
@@ -18,17 +18,59 @@ import { UmbLitElement } from '../../packages/core/lit-element/index.js';
|
|
|
18
18
|
import { pathWithoutBasePath } from '../../packages/core/router/index.js';
|
|
19
19
|
import { RuntimeLevelModel } from '../../packages/core/backend-api/index.js';
|
|
20
20
|
import { UmbContextDebugController } from '../../packages/core/debug/index.js';
|
|
21
|
-
import { UmbBundleExtensionInitializer, UmbServerExtensionRegistrator } from '../../libs/extension-api/index.js';
|
|
21
|
+
import { UmbBundleExtensionInitializer, UmbServerExtensionRegistrator, } from '../../libs/extension-api/index.js';
|
|
22
22
|
import { UmbAppEntryPointExtensionInitializer, umbExtensionsRegistry, } from '../../packages/core/extension-registry/index.js';
|
|
23
|
-
import { firstValueFrom } from '../../external/rxjs/index.js';
|
|
24
23
|
import { redirectToStoredPath } from '../../packages/core/utils/index.js';
|
|
25
24
|
import { umbHttpClient } from '../../packages/core/http-client/index.js';
|
|
26
25
|
import { UmbViewContext } from '../../packages/core/view/index.js';
|
|
27
26
|
import './app-logo.element.js';
|
|
27
|
+
import { UMB_CURRENT_USER_CONTEXT } from '../../packages/user/current-user/index.js';
|
|
28
|
+
const CORE_PACKAGES = [
|
|
29
|
+
import('../../packages/block/umbraco-package.js'),
|
|
30
|
+
import('../../packages/clipboard/umbraco-package.js'),
|
|
31
|
+
import('../../packages/code-editor/umbraco-package.js'),
|
|
32
|
+
import('../../packages/content/umbraco-package.js'),
|
|
33
|
+
import('../../packages/data-type/umbraco-package.js'),
|
|
34
|
+
import('../../packages/dictionary/umbraco-package.js'),
|
|
35
|
+
import('../../packages/documents/umbraco-package.js'),
|
|
36
|
+
import('../../packages/embedded-media/umbraco-package.js'),
|
|
37
|
+
import('../../packages/extension-insights/umbraco-package.js'),
|
|
38
|
+
import('../../packages/health-check/umbraco-package.js'),
|
|
39
|
+
import('../../packages/help/umbraco-package.js'),
|
|
40
|
+
import('../../packages/language/umbraco-package.js'),
|
|
41
|
+
import('../../packages/log-viewer/umbraco-package.js'),
|
|
42
|
+
import('../../packages/management-api/umbraco-package.js'),
|
|
43
|
+
import('../../packages/markdown-editor/umbraco-package.js'),
|
|
44
|
+
import('../../packages/media/umbraco-package.js'),
|
|
45
|
+
import('../../packages/members/umbraco-package.js'),
|
|
46
|
+
import('../../packages/models-builder/umbraco-package.js'),
|
|
47
|
+
import('../../packages/multi-url-picker/umbraco-package.js'),
|
|
48
|
+
import('../../packages/packages/umbraco-package.js'),
|
|
49
|
+
import('../../packages/performance-profiling/umbraco-package.js'),
|
|
50
|
+
import('../../packages/property-editors/umbraco-package.js'),
|
|
51
|
+
import('../../packages/publish-cache/umbraco-package.js'),
|
|
52
|
+
import('../../packages/relations/umbraco-package.js'),
|
|
53
|
+
import('../../packages/rte/umbraco-package.js'),
|
|
54
|
+
import('../../packages/settings/umbraco-package.js'),
|
|
55
|
+
import('../../packages/static-file/umbraco-package.js'),
|
|
56
|
+
import('../../packages/sysinfo/umbraco-package.js'),
|
|
57
|
+
import('../../packages/tags/umbraco-package.js'),
|
|
58
|
+
import('../../packages/telemetry/umbraco-package.js'),
|
|
59
|
+
import('../../packages/templating/umbraco-package.js'),
|
|
60
|
+
import('../../packages/tiptap/umbraco-package.js'),
|
|
61
|
+
import('../../packages/translation/umbraco-package.js'),
|
|
62
|
+
import('../../packages/ufm/umbraco-package.js'),
|
|
63
|
+
import('../../packages/umbraco-news/umbraco-package.js'),
|
|
64
|
+
import('../../packages/user/umbraco-package.js'),
|
|
65
|
+
import('../../packages/webhook/umbraco-package.js'),
|
|
66
|
+
];
|
|
28
67
|
let UmbAppElement = class UmbAppElement extends UmbLitElement {
|
|
29
68
|
#authContext;
|
|
30
69
|
#serverConnection;
|
|
31
70
|
#authController;
|
|
71
|
+
#bundleInitializer;
|
|
72
|
+
#currentUser;
|
|
73
|
+
#packageModules;
|
|
32
74
|
constructor() {
|
|
33
75
|
super();
|
|
34
76
|
/**
|
|
@@ -120,15 +162,21 @@ let UmbAppElement = class UmbAppElement extends UmbLitElement {
|
|
|
120
162
|
{
|
|
121
163
|
path: '**',
|
|
122
164
|
component: () => import('../backoffice/backoffice.element.js'),
|
|
123
|
-
guards: [this.#isAuthorizedGuard()],
|
|
165
|
+
guards: [this.#isAuthorizedGuard(), this.#loadedGuard()],
|
|
124
166
|
},
|
|
125
167
|
];
|
|
126
168
|
this.#authController = new UmbAppAuthController(this);
|
|
127
|
-
new UmbBundleExtensionInitializer(this, umbExtensionsRegistry);
|
|
169
|
+
this.#bundleInitializer = new UmbBundleExtensionInitializer(this, umbExtensionsRegistry);
|
|
128
170
|
new UUIIconRegistryEssential().attach(this);
|
|
129
171
|
new UmbContextDebugController(this);
|
|
130
172
|
new UmbNetworkConnectionStatusManager(this);
|
|
131
173
|
new UmbViewContext(this, null);
|
|
174
|
+
this.consumeContext(UMB_CURRENT_USER_CONTEXT, (userContext) => {
|
|
175
|
+
this.#currentUser = userContext;
|
|
176
|
+
if (userContext) {
|
|
177
|
+
this.#loadCurrentUser();
|
|
178
|
+
}
|
|
179
|
+
});
|
|
132
180
|
}
|
|
133
181
|
connectedCallback() {
|
|
134
182
|
super.connectedCallback();
|
|
@@ -137,6 +185,18 @@ let UmbAppElement = class UmbAppElement extends UmbLitElement {
|
|
|
137
185
|
async #setup() {
|
|
138
186
|
this.#authContext = new UmbAuthContext(this, this.serverUrl, this.backofficePath, this.bypassAuth, this.keepUserLoggedIn);
|
|
139
187
|
this.#authContext.configureClient(umbHttpClient);
|
|
188
|
+
this.observe(this.#authContext.isAuthorized, async (isAuthorized) => {
|
|
189
|
+
if (isAuthorized === undefined)
|
|
190
|
+
return;
|
|
191
|
+
if (isAuthorized) {
|
|
192
|
+
// TODO: Remove dependency on current user context from the app element in future [MR]
|
|
193
|
+
this.#loadCurrentUser();
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
// TODO: Unregistering all extensions from v.18 [NL]
|
|
197
|
+
//void this.#unregisterExtensions();
|
|
198
|
+
}
|
|
199
|
+
}, null);
|
|
140
200
|
this.#serverConnection = await new UmbServerConnection(this, this.serverUrl).connect();
|
|
141
201
|
new UmbServerContext(this, {
|
|
142
202
|
backofficePath: this.backofficePath,
|
|
@@ -147,8 +207,7 @@ let UmbAppElement = class UmbAppElement extends UmbLitElement {
|
|
|
147
207
|
onInit(this, umbExtensionsRegistry);
|
|
148
208
|
// Register public extensions (login extensions)
|
|
149
209
|
await new UmbServerExtensionRegistrator(this, umbExtensionsRegistry).registerPublicExtensions();
|
|
150
|
-
|
|
151
|
-
await firstValueFrom(initializer.loaded);
|
|
210
|
+
new UmbAppEntryPointExtensionInitializer(this, umbExtensionsRegistry);
|
|
152
211
|
// Try to initialise the auth flow and get the runtime status
|
|
153
212
|
try {
|
|
154
213
|
// If the runtime level is "install" or ?status=false is set, we should clear any cached tokens
|
|
@@ -198,6 +257,30 @@ let UmbAppElement = class UmbAppElement extends UmbLitElement {
|
|
|
198
257
|
// Auth context configures umbHttpClient in its constructor, so we only need to set initial state
|
|
199
258
|
await this.#authContext.setInitialState();
|
|
200
259
|
}
|
|
260
|
+
async #registerExtensions() {
|
|
261
|
+
if (this.#packageModules === undefined) {
|
|
262
|
+
this.#packageModules = Promise.all(CORE_PACKAGES);
|
|
263
|
+
this.#packageModules.then(() => {
|
|
264
|
+
this.#loadCurrentUser();
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
umbExtensionsRegistry.registerMany((await this.#packageModules).flatMap((modules) => modules.extensions));
|
|
268
|
+
}
|
|
269
|
+
// TODO (V18): Unregister extensions on sign-out. [NL]
|
|
270
|
+
/*
|
|
271
|
+
async #unregisterExtensions() {
|
|
272
|
+
if (!this.#packageModules) return;
|
|
273
|
+
(await this.#packageModules).forEach((packageModule) => {
|
|
274
|
+
const aliases = packageModule.extensions.map((extension) => extension.alias);
|
|
275
|
+
umbExtensionsRegistry.unregisterMany(aliases);
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
*/
|
|
279
|
+
#loadCurrentUser() {
|
|
280
|
+
if (!this.#currentUser || !this.#packageModules)
|
|
281
|
+
return;
|
|
282
|
+
this.#currentUser.load();
|
|
283
|
+
}
|
|
201
284
|
#redirect() {
|
|
202
285
|
const pathname = pathWithoutBasePath({ start: true, end: false });
|
|
203
286
|
// If we are on the oauth_complete or error page, we should not redirect
|
|
@@ -238,6 +321,20 @@ let UmbAppElement = class UmbAppElement extends UmbLitElement {
|
|
|
238
321
|
#isAuthorizedGuard() {
|
|
239
322
|
return () => this.#authController.isAuthorized() ?? false;
|
|
240
323
|
}
|
|
324
|
+
#loadedGuard() {
|
|
325
|
+
return async () => {
|
|
326
|
+
const results = await Promise.allSettled([
|
|
327
|
+
this.observe(this.#bundleInitializer?.loaded).asPromise(),
|
|
328
|
+
this.#registerExtensions(),
|
|
329
|
+
new UmbServerExtensionRegistrator(this, umbExtensionsRegistry).registerPrivateExtensions(),
|
|
330
|
+
]);
|
|
331
|
+
const result = results.reduce((acc, curr) => acc && curr.status === 'fulfilled', true);
|
|
332
|
+
if (result === false) {
|
|
333
|
+
this.#errorPage('Extensions failed loading, this might be due to a network issue or a server error. Check that extensions registered on the server are valid.', undefined, { headline: 'Failed to load extensions' });
|
|
334
|
+
}
|
|
335
|
+
return result;
|
|
336
|
+
};
|
|
337
|
+
}
|
|
241
338
|
#errorPage(errorMsg, error, options) {
|
|
242
339
|
// Redirect to the error page
|
|
243
340
|
this._routes = [
|
|
@@ -258,7 +355,9 @@ let UmbAppElement = class UmbAppElement extends UmbLitElement {
|
|
|
258
355
|
this.requestUpdate();
|
|
259
356
|
}
|
|
260
357
|
render() {
|
|
261
|
-
return html `<umb-router-slot id="router-slot" .routes=${this._routes}
|
|
358
|
+
return html `<umb-router-slot id="router-slot" .routes=${this._routes}
|
|
359
|
+
><div id="loader"><uui-loader data-mark="app-router-loader"></uui-loader></div
|
|
360
|
+
></umb-router-slot>`;
|
|
262
361
|
}
|
|
263
362
|
static { this.styles = css `
|
|
264
363
|
:host {
|
|
@@ -272,6 +371,20 @@ let UmbAppElement = class UmbAppElement extends UmbLitElement {
|
|
|
272
371
|
width: 100%;
|
|
273
372
|
height: 100vh;
|
|
274
373
|
}
|
|
374
|
+
|
|
375
|
+
#loader {
|
|
376
|
+
display: flex;
|
|
377
|
+
height: 100%;
|
|
378
|
+
justify-content: center;
|
|
379
|
+
align-items: center;
|
|
380
|
+
opacity: 0;
|
|
381
|
+
animation: fadeIn 240ms forwards;
|
|
382
|
+
}
|
|
383
|
+
@keyframes fadeIn {
|
|
384
|
+
to {
|
|
385
|
+
opacity: 1;
|
|
386
|
+
}
|
|
387
|
+
}
|
|
275
388
|
`; }
|
|
276
389
|
};
|
|
277
390
|
__decorate([
|
|
@@ -6,7 +6,6 @@ import { UmbContextBase } from '../../libs/class-api/index.js';
|
|
|
6
6
|
import { UmbContextToken } from '../../libs/context-api/index.js';
|
|
7
7
|
import { UmbExtensionsManifestInitializer } from '../../libs/extension-api/index.js';
|
|
8
8
|
import { UmbSysinfoRepository } from '../../packages/sysinfo/index.js';
|
|
9
|
-
import { UMB_AUTH_CONTEXT } from '../../packages/core/auth/index.js';
|
|
10
9
|
import { UMB_CURRENT_USER_CONTEXT } from '../../packages/user/current-user/index.js';
|
|
11
10
|
export class UmbBackofficeContext extends UmbContextBase {
|
|
12
11
|
#activeSectionAlias;
|
|
@@ -22,14 +21,7 @@ export class UmbBackofficeContext extends UmbContextBase {
|
|
|
22
21
|
this.allowedSections = this.#allowedSections.asObservable();
|
|
23
22
|
this.#version = new UmbStringState(undefined);
|
|
24
23
|
this.version = this.#version.asObservable();
|
|
25
|
-
|
|
26
|
-
this.consumeContext(UMB_AUTH_CONTEXT, (authContext) => {
|
|
27
|
-
this.observe(authContext?.isAuthorized, (isAuthorized) => {
|
|
28
|
-
if (!isAuthorized)
|
|
29
|
-
return;
|
|
30
|
-
this.#getVersion();
|
|
31
|
-
});
|
|
32
|
-
});
|
|
24
|
+
this.#getVersion();
|
|
33
25
|
this.consumeContext(UMB_CURRENT_USER_CONTEXT, (userContext) => {
|
|
34
26
|
this.observe(userContext?.allowedSections, (allowedSections) => {
|
|
35
27
|
if (!allowedSections)
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import { UmbLitElement } from '../../packages/core/lit-element/index.js';
|
|
2
2
|
import './components/index.js';
|
|
3
3
|
export declare class UmbBackofficeElement extends UmbLitElement {
|
|
4
|
-
#private;
|
|
5
4
|
/**
|
|
6
5
|
* Backoffice extension registry.
|
|
7
6
|
* This enables to register and unregister extensions via DevTools, or just via querying this element via the DOM.
|
|
8
7
|
*/
|
|
9
8
|
extensionRegistry: import("../../packages/core/extension-registry/index.js").UmbBackofficeExtensionRegistry;
|
|
10
9
|
constructor();
|
|
11
|
-
firstUpdated(): Promise<void>;
|
|
12
10
|
render(): import("lit-html").TemplateResult<1>;
|
|
13
11
|
static readonly styles: import("lit").CSSResult[];
|
|
14
12
|
}
|
|
@@ -7,49 +7,8 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
import { UmbBackofficeContext } from './backoffice.context.js';
|
|
8
8
|
import { css, html, customElement } from '../../external/lit/index.js';
|
|
9
9
|
import { UmbBackofficeEntryPointExtensionInitializer, UmbEntryPointExtensionInitializer, umbExtensionsRegistry, } from '../../packages/core/extension-registry/index.js';
|
|
10
|
-
import { UmbServerExtensionRegistrator } from '../../libs/extension-api/index.js';
|
|
11
10
|
import { UmbLitElement } from '../../packages/core/lit-element/index.js';
|
|
12
|
-
import { UMB_AUTH_CONTEXT } from '../../packages/core/auth/index.js';
|
|
13
11
|
import './components/index.js';
|
|
14
|
-
const CORE_PACKAGES = [
|
|
15
|
-
import('../../packages/block/umbraco-package.js'),
|
|
16
|
-
import('../../packages/clipboard/umbraco-package.js'),
|
|
17
|
-
import('../../packages/code-editor/umbraco-package.js'),
|
|
18
|
-
import('../../packages/content/umbraco-package.js'),
|
|
19
|
-
import('../../packages/data-type/umbraco-package.js'),
|
|
20
|
-
import('../../packages/dictionary/umbraco-package.js'),
|
|
21
|
-
import('../../packages/documents/umbraco-package.js'),
|
|
22
|
-
import('../../packages/embedded-media/umbraco-package.js'),
|
|
23
|
-
import('../../packages/extension-insights/umbraco-package.js'),
|
|
24
|
-
import('../../packages/health-check/umbraco-package.js'),
|
|
25
|
-
import('../../packages/help/umbraco-package.js'),
|
|
26
|
-
import('../../packages/language/umbraco-package.js'),
|
|
27
|
-
import('../../packages/log-viewer/umbraco-package.js'),
|
|
28
|
-
import('../../packages/management-api/umbraco-package.js'),
|
|
29
|
-
import('../../packages/markdown-editor/umbraco-package.js'),
|
|
30
|
-
import('../../packages/media/umbraco-package.js'),
|
|
31
|
-
import('../../packages/members/umbraco-package.js'),
|
|
32
|
-
import('../../packages/models-builder/umbraco-package.js'),
|
|
33
|
-
import('../../packages/multi-url-picker/umbraco-package.js'),
|
|
34
|
-
import('../../packages/packages/umbraco-package.js'),
|
|
35
|
-
import('../../packages/performance-profiling/umbraco-package.js'),
|
|
36
|
-
import('../../packages/property-editors/umbraco-package.js'),
|
|
37
|
-
import('../../packages/publish-cache/umbraco-package.js'),
|
|
38
|
-
import('../../packages/relations/umbraco-package.js'),
|
|
39
|
-
import('../../packages/rte/umbraco-package.js'),
|
|
40
|
-
import('../../packages/settings/umbraco-package.js'),
|
|
41
|
-
import('../../packages/static-file/umbraco-package.js'),
|
|
42
|
-
import('../../packages/sysinfo/umbraco-package.js'),
|
|
43
|
-
import('../../packages/tags/umbraco-package.js'),
|
|
44
|
-
import('../../packages/telemetry/umbraco-package.js'),
|
|
45
|
-
import('../../packages/templating/umbraco-package.js'),
|
|
46
|
-
import('../../packages/tiptap/umbraco-package.js'),
|
|
47
|
-
import('../../packages/translation/umbraco-package.js'),
|
|
48
|
-
import('../../packages/ufm/umbraco-package.js'),
|
|
49
|
-
import('../../packages/umbraco-news/umbraco-package.js'),
|
|
50
|
-
import('../../packages/user/umbraco-package.js'),
|
|
51
|
-
import('../../packages/webhook/umbraco-package.js'),
|
|
52
|
-
];
|
|
53
12
|
let UmbBackofficeElement = class UmbBackofficeElement extends UmbLitElement {
|
|
54
13
|
constructor() {
|
|
55
14
|
super();
|
|
@@ -62,23 +21,6 @@ let UmbBackofficeElement = class UmbBackofficeElement extends UmbLitElement {
|
|
|
62
21
|
new UmbBackofficeEntryPointExtensionInitializer(this, umbExtensionsRegistry);
|
|
63
22
|
new UmbEntryPointExtensionInitializer(this, umbExtensionsRegistry);
|
|
64
23
|
}
|
|
65
|
-
async firstUpdated() {
|
|
66
|
-
// TODO: Move this logic into the Context? [NL]
|
|
67
|
-
await this.#extensionsAfterAuth();
|
|
68
|
-
// So far local packages are this simple to register, so no need for a manager to do that:
|
|
69
|
-
CORE_PACKAGES.forEach(async (packageImport) => {
|
|
70
|
-
const packageModule = await packageImport;
|
|
71
|
-
umbExtensionsRegistry.registerMany(packageModule.extensions);
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
async #extensionsAfterAuth() {
|
|
75
|
-
const authContext = await this.getContext(UMB_AUTH_CONTEXT, { preventTimeout: true });
|
|
76
|
-
if (!authContext) {
|
|
77
|
-
throw new Error('UmbBackofficeElement requires the UMB_AUTH_CONTEXT to be set.');
|
|
78
|
-
}
|
|
79
|
-
await this.observe(authContext.isAuthorized).asPromise();
|
|
80
|
-
await new UmbServerExtensionRegistrator(this, umbExtensionsRegistry).registerPrivateExtensions();
|
|
81
|
-
}
|
|
82
24
|
render() {
|
|
83
25
|
return html `
|
|
84
26
|
<umb-backoffice-header></umb-backoffice-header>
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { UmbLitElement } from '../../../packages/core/lit-element/index.js';
|
|
2
2
|
export declare class UmbBackofficeMainElement extends UmbLitElement {
|
|
3
3
|
#private;
|
|
4
|
-
private _routes
|
|
4
|
+
private _routes?;
|
|
5
5
|
private _sections;
|
|
6
6
|
constructor();
|
|
7
7
|
private _observeBackoffice;
|
|
8
|
-
render(): import("lit-html").TemplateResult<1
|
|
8
|
+
render(): import("lit-html").TemplateResult<1>;
|
|
9
9
|
static styles: import("lit").CSSResult[];
|
|
10
10
|
}
|
|
11
11
|
declare global {
|
|
@@ -13,7 +13,6 @@ let UmbBackofficeMainElement = class UmbBackofficeMainElement extends UmbLitElem
|
|
|
13
13
|
#backofficeContext;
|
|
14
14
|
constructor() {
|
|
15
15
|
super();
|
|
16
|
-
this._routes = [];
|
|
17
16
|
this._sections = [];
|
|
18
17
|
this.consumeContext(UMB_BACKOFFICE_CONTEXT, (_instance) => {
|
|
19
18
|
this.#backofficeContext = _instance;
|
|
@@ -64,8 +63,9 @@ let UmbBackofficeMainElement = class UmbBackofficeMainElement extends UmbLitElem
|
|
|
64
63
|
this._routes = newRoutes;
|
|
65
64
|
}
|
|
66
65
|
render() {
|
|
67
|
-
if (!this._routes.length)
|
|
68
|
-
return
|
|
66
|
+
if (!this._routes || !this._routes.length) {
|
|
67
|
+
return html `<div id="loader"><uui-loader></uui-loader></div>`;
|
|
68
|
+
}
|
|
69
69
|
return html `<umb-router-slot .routes=${this._routes}></umb-router-slot>`;
|
|
70
70
|
}
|
|
71
71
|
static { this.styles = [
|
|
@@ -78,6 +78,19 @@ let UmbBackofficeMainElement = class UmbBackofficeMainElement extends UmbLitElem
|
|
|
78
78
|
100% - 60px
|
|
79
79
|
); /* 60 => top header height, TODO: Make sure this comes from somewhere so it is maintainable and eventually responsive. */
|
|
80
80
|
}
|
|
81
|
+
|
|
82
|
+
#loader {
|
|
83
|
+
display: flex;
|
|
84
|
+
justify-content: center;
|
|
85
|
+
align-items: center;
|
|
86
|
+
opacity: 0;
|
|
87
|
+
animation: fadeIn 240ms forwards;
|
|
88
|
+
}
|
|
89
|
+
@keyframes fadeIn {
|
|
90
|
+
to {
|
|
91
|
+
opacity: 1;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
81
94
|
`,
|
|
82
95
|
]; }
|
|
83
96
|
};
|
|
@@ -20,7 +20,7 @@ export declare abstract class UmbBaseExtensionInitializer<ManifestType extends M
|
|
|
20
20
|
constructor(host: UmbControllerHost, extensionRegistry: UmbExtensionRegistry<ManifestCondition>, controllerTypeName: string, alias: string, onPermissionChanged?: (isPermitted: boolean, controller: SubClassType) => void);
|
|
21
21
|
protected _init(): void;
|
|
22
22
|
asPromise(): Promise<void>;
|
|
23
|
-
protected abstract _conditionsAreGood(): Promise<boolean>;
|
|
23
|
+
protected abstract _conditionsAreGood(signal: AbortSignal): Promise<boolean>;
|
|
24
24
|
protected abstract _conditionsAreBad(): Promise<void>;
|
|
25
25
|
equal(otherClass: UmbBaseExtensionInitializer | undefined): boolean;
|
|
26
26
|
destroy(): void;
|
|
@@ -46,7 +46,7 @@ export class UmbBaseExtensionInitializer extends UmbControllerBase {
|
|
|
46
46
|
return (this.#manifest?.conditions ?? []).length > 0;
|
|
47
47
|
};
|
|
48
48
|
this.#gotConditions = (manifests) => {
|
|
49
|
-
manifests
|
|
49
|
+
manifests?.forEach(this.#gotCondition);
|
|
50
50
|
};
|
|
51
51
|
this.#gotCondition = async (conditionManifest) => {
|
|
52
52
|
if (!this.#manifest)
|
|
@@ -88,34 +88,54 @@ export class UmbBaseExtensionInitializer extends UmbControllerBase {
|
|
|
88
88
|
// When writing this the only plausible case is a call from the conditionController to the onChange callback.
|
|
89
89
|
return;
|
|
90
90
|
}
|
|
91
|
+
// Find a condition that is not permitted (Notice how no conditions, means that this extension is permitted)
|
|
92
|
+
const isPositive = this.#checkConditionsAreGood();
|
|
93
|
+
if (this._isConditionsPositive === isPositive) {
|
|
94
|
+
// No change in the conditions, so we don't need to do anything, this is an optimization to prevent multiple calls to the callback when there is no change. [NL]
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
91
97
|
// We will collect old value here, but we need to re-collect it after a async method have been called, as it could have changed in the mean time. [NL]
|
|
92
98
|
let oldValue = this.#isPermitted ?? false;
|
|
93
|
-
// Find a condition that is not permitted (Notice how no conditions, means that this extension is permitted)
|
|
94
|
-
const isPositive = this.#conditionsAreInitialized() &&
|
|
95
|
-
this.#conditionControllers.some((condition) => condition.permitted === false) === false;
|
|
96
99
|
this._isConditionsPositive = isPositive;
|
|
97
100
|
if (isPositive === true) {
|
|
98
101
|
if (this.#isPermitted !== true) {
|
|
99
|
-
|
|
100
|
-
//
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
102
|
+
let newPermission;
|
|
103
|
+
// check current pending _conditionsAreGood call: [NL]
|
|
104
|
+
let entry = this.#pendingGoodCall;
|
|
105
|
+
if (entry && entry.manifest === this.#manifest) {
|
|
106
|
+
newPermission = await entry.promise;
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
// Since this is a new call, then lets abort the pending call. [NL]
|
|
110
|
+
this.#abortPendingGoodCall();
|
|
111
|
+
await this._conditionsAreBad();
|
|
112
|
+
const abortController = new AbortController();
|
|
113
|
+
const promise = this._conditionsAreGood(abortController.signal);
|
|
114
|
+
entry = { manifest: this.#manifest, promise, abortController };
|
|
115
|
+
this.#pendingGoodCall = entry;
|
|
116
|
+
newPermission = await promise;
|
|
117
|
+
}
|
|
118
|
+
if (this.#pendingGoodCall !== entry) {
|
|
104
119
|
return;
|
|
105
120
|
}
|
|
121
|
+
else {
|
|
122
|
+
this.#pendingGoodCall = undefined;
|
|
123
|
+
}
|
|
124
|
+
// Only set new permission if we are still positive, otherwise it means that we have been destroyed in the mean time, or we got destroyed. [NL]
|
|
125
|
+
if (newPermission === false || this._isConditionsPositive !== true) {
|
|
126
|
+
// Then we need to revert the above work. Sync call — see the note in
|
|
127
|
+
// the else-if branch on why we don't await. [NL]
|
|
128
|
+
this._conditionsAreBad();
|
|
129
|
+
newPermission = false;
|
|
130
|
+
}
|
|
106
131
|
// We update the oldValue as this point, cause in this way we are sure its the value at this point, when doing async code someone else might have changed the state in the mean time. [NL]
|
|
107
132
|
oldValue = this.#isPermitted ?? false;
|
|
108
133
|
this.#isPermitted = newPermission;
|
|
109
134
|
}
|
|
110
135
|
}
|
|
111
136
|
else if (this.#isPermitted !== false) {
|
|
112
|
-
//
|
|
113
|
-
|
|
114
|
-
// Only continue if we are still negative, otherwise it means that something changed in the mean time. [NL]
|
|
115
|
-
if (this._isConditionsPositive === true) {
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
|
-
// We update the oldValue as this point, cause in this way we are sure its the value at this point, when doing async code someone else might have changed the state in the mean time. [NL]
|
|
137
|
+
// clean-up any current [NL]
|
|
138
|
+
this._conditionsAreBad();
|
|
119
139
|
oldValue = this.#isPermitted ?? false;
|
|
120
140
|
this.#isPermitted = false;
|
|
121
141
|
}
|
|
@@ -146,6 +166,7 @@ export class UmbBaseExtensionInitializer extends UmbControllerBase {
|
|
|
146
166
|
}
|
|
147
167
|
else {
|
|
148
168
|
this.#manifest = undefined;
|
|
169
|
+
this._isConditionsPositive = undefined;
|
|
149
170
|
this.#clearPermittedState();
|
|
150
171
|
this.#overwrites = [];
|
|
151
172
|
this.#cleanConditions();
|
|
@@ -240,10 +261,28 @@ export class UmbBaseExtensionInitializer extends UmbControllerBase {
|
|
|
240
261
|
}
|
|
241
262
|
return undefined;
|
|
242
263
|
}
|
|
243
|
-
#
|
|
264
|
+
#checkConditionsAreGood() {
|
|
244
265
|
// Not good if we don't have a manifest.
|
|
266
|
+
if (this.#manifest === undefined)
|
|
267
|
+
return false;
|
|
245
268
|
// Only good if conditions of manifest is equal to the amount of condition controllers (one for each condition). [NL]
|
|
246
|
-
|
|
269
|
+
const hasAllConditions = (this.#manifest.conditions ?? []).length === this.#conditionControllers.length;
|
|
270
|
+
if (hasAllConditions === false)
|
|
271
|
+
return false;
|
|
272
|
+
// Compare all manifest conditions with the condition controllers configs to be sure we have the right ones, as we might end up in a state where we have the same amount of controllers as conditions, but they are not the right ones. [NL]
|
|
273
|
+
const allConditionsHaveControllers = (this.#manifest.conditions ?? []).every((condition) => this.#conditionControllers.some((controller) => controller.config === condition));
|
|
274
|
+
if (allConditionsHaveControllers === false)
|
|
275
|
+
return false;
|
|
276
|
+
// Only good if all the conditions are permitted:
|
|
277
|
+
return this.#conditionControllers.some((condition) => condition.permitted === false) === false;
|
|
278
|
+
}
|
|
279
|
+
// The currently-pending `_conditionsAreGood()` promise and manifest, to detect if we can reuse it.
|
|
280
|
+
#pendingGoodCall;
|
|
281
|
+
#abortPendingGoodCall() {
|
|
282
|
+
if (this.#pendingGoodCall) {
|
|
283
|
+
this.#pendingGoodCall.abortController.abort();
|
|
284
|
+
this.#pendingGoodCall = undefined;
|
|
285
|
+
}
|
|
247
286
|
}
|
|
248
287
|
#onConditionsChangedCallback;
|
|
249
288
|
equal(otherClass) {
|
|
@@ -279,9 +318,12 @@ export class UmbBaseExtensionInitializer extends UmbControllerBase {
|
|
|
279
318
|
return;
|
|
280
319
|
this.#manifest = undefined;
|
|
281
320
|
this.#promiseResolvers = [];
|
|
321
|
+
// Abort any pending good-call so its subclass run refuses to commit (sees
|
|
322
|
+
// `signal.aborted`) instead of trying to assign into a destroyed initializer. [NL]
|
|
323
|
+
this.#abortPendingGoodCall();
|
|
282
324
|
this.#clearPermittedState(); // This fires the callback as not permitted, if it was permitted before. [NL]
|
|
283
325
|
this.#isPermitted = undefined;
|
|
284
|
-
this._isConditionsPositive =
|
|
326
|
+
this._isConditionsPositive = undefined;
|
|
285
327
|
this.#overwrites = [];
|
|
286
328
|
this.#cleanConditions();
|
|
287
329
|
this.#onPermissionChanged = undefined;
|
|
@@ -36,7 +36,7 @@ export declare class UmbExtensionApiInitializer<ManifestType extends ManifestApi
|
|
|
36
36
|
* ```
|
|
37
37
|
*/
|
|
38
38
|
constructor(host: UmbControllerHost, extensionRegistry: UmbExtensionRegistry<ManifestCondition>, alias: string, constructorArguments: Array<unknown> | UmbApiConstructorArgumentsMethodType<ManifestType> | undefined, onPermissionChanged?: (isPermitted: boolean, controller: ControllerType) => void);
|
|
39
|
-
protected _conditionsAreGood(): Promise<boolean>;
|
|
39
|
+
protected _conditionsAreGood(signal: AbortSignal): Promise<boolean>;
|
|
40
40
|
protected _conditionsAreBad(): Promise<void>;
|
|
41
41
|
destroy(): void;
|
|
42
42
|
}
|
|
@@ -60,13 +60,20 @@ export class UmbExtensionApiInitializer extends UmbBaseExtensionInitializer {
|
|
|
60
60
|
});
|
|
61
61
|
};
|
|
62
62
|
*/
|
|
63
|
-
async _conditionsAreGood() {
|
|
63
|
+
async _conditionsAreGood(signal) {
|
|
64
64
|
const manifest = this.manifest; // In this case we are sure its not undefined.
|
|
65
65
|
const newApi = await createExtensionApi(this._host, manifest, this.#constructorArguments);
|
|
66
|
-
if (!this._isConditionsPositive) {
|
|
67
|
-
|
|
66
|
+
if (signal.aborted || !this._isConditionsPositive) {
|
|
67
|
+
newApi?.destroy?.();
|
|
68
68
|
return false;
|
|
69
69
|
}
|
|
70
|
+
// A previous _conditionsAreGood() on this same initializer may have already
|
|
71
|
+
// assigned this.#api and resolved before us. Without cleanup that instance would
|
|
72
|
+
// keep running until this._host is destroyed — not a hard leak, but any
|
|
73
|
+
// subscriptions / context consumers / async setup it started stay alive.
|
|
74
|
+
if (this.#api && this.#api !== newApi) {
|
|
75
|
+
this.#api.destroy?.();
|
|
76
|
+
}
|
|
70
77
|
this.#api = newApi;
|
|
71
78
|
if (this.#api) {
|
|
72
79
|
this.#api.manifest = manifest;
|
package/dist-cms/libs/extension-api/controller/extension-element-and-api-initializer.controller.d.ts
CHANGED
|
@@ -32,7 +32,7 @@ export declare class UmbExtensionElementAndApiInitializer<ManifestType extends M
|
|
|
32
32
|
get apiProps(): Record<string, unknown> | undefined;
|
|
33
33
|
set apiProps(newVal: Record<string, unknown> | undefined);
|
|
34
34
|
constructor(host: UmbControllerHost, extensionRegistry: UmbExtensionRegistry<ManifestCondition>, alias: string, constructorArguments: Array<unknown> | UmbApiConstructorArgumentsMethodType<ManifestType> | undefined, onPermissionChanged: (isPermitted: boolean, controller: ControllerType) => void, defaultElement?: string, defaultApi?: ApiLoaderProperty<ExtensionApiInterface>);
|
|
35
|
-
protected _conditionsAreGood(): Promise<boolean>;
|
|
35
|
+
protected _conditionsAreGood(signal: AbortSignal): Promise<boolean>;
|
|
36
36
|
protected _conditionsAreBad(): Promise<void>;
|
|
37
37
|
destroy(): void;
|
|
38
38
|
}
|
package/dist-cms/libs/extension-api/controller/extension-element-and-api-initializer.controller.js
CHANGED
|
@@ -100,17 +100,26 @@ export class UmbExtensionElementAndApiInitializer extends UmbBaseExtensionInitia
|
|
|
100
100
|
this.#api[key] = this.#apiProps[key];
|
|
101
101
|
});
|
|
102
102
|
};
|
|
103
|
-
async _conditionsAreGood() {
|
|
103
|
+
async _conditionsAreGood(signal) {
|
|
104
104
|
const manifest = this.manifest; // In this case we are sure its not undefined.
|
|
105
105
|
const { element: newComponent, api: newApi } = await createExtensionElementWithApi(manifest, this.#constructorArguments, this.#defaultElement, this.#defaultApi);
|
|
106
|
-
if (!this._isConditionsPositive) {
|
|
106
|
+
if (signal.aborted || !this._isConditionsPositive) {
|
|
107
107
|
newApi?.destroy?.();
|
|
108
108
|
if (newComponent && 'destroy' in newComponent) {
|
|
109
109
|
newComponent.destroy();
|
|
110
110
|
}
|
|
111
|
-
// We are not positive anymore, so we will back out of this creation.
|
|
112
111
|
return false;
|
|
113
112
|
}
|
|
113
|
+
// A previous _conditionsAreGood() on this same initializer may have already
|
|
114
|
+
// assigned this.#api / this.#component and resolved before us. The API's host is
|
|
115
|
+
// the transient element (see createExtensionElementWithApi), not this initializer,
|
|
116
|
+
// so nothing else in the controller-host chain will clean an orphaned pair up.
|
|
117
|
+
if (this.#api && this.#api !== newApi) {
|
|
118
|
+
this.#api.destroy?.();
|
|
119
|
+
}
|
|
120
|
+
if (this.#component && this.#component !== newComponent && 'destroy' in this.#component) {
|
|
121
|
+
this.#component.destroy();
|
|
122
|
+
}
|
|
114
123
|
this.#api = newApi;
|
|
115
124
|
if (this.#api) {
|
|
116
125
|
this.#assignApiProps();
|
package/dist-cms/libs/extension-api/controller/extension-element-initializer.controller.d.ts
CHANGED
|
@@ -22,7 +22,7 @@ export declare class UmbExtensionElementInitializer<ManifestType extends Manifes
|
|
|
22
22
|
get properties(): Record<string, unknown> | undefined;
|
|
23
23
|
set properties(newVal: Record<string, unknown> | undefined);
|
|
24
24
|
constructor(host: UmbControllerHost, extensionRegistry: UmbExtensionRegistry<ManifestCondition>, alias: string, onPermissionChanged: (isPermitted: boolean, controller: ControllerType) => void, defaultElement?: string);
|
|
25
|
-
protected _conditionsAreGood(): Promise<boolean>;
|
|
25
|
+
protected _conditionsAreGood(signal: AbortSignal): Promise<boolean>;
|
|
26
26
|
protected _conditionsAreBad(): Promise<void>;
|
|
27
27
|
destroy(): void;
|
|
28
28
|
}
|
|
@@ -56,13 +56,21 @@ export class UmbExtensionElementInitializer extends UmbBaseExtensionInitializer
|
|
|
56
56
|
this.#component[key] = this.#properties[key];
|
|
57
57
|
});
|
|
58
58
|
};
|
|
59
|
-
async _conditionsAreGood() {
|
|
59
|
+
async _conditionsAreGood(signal) {
|
|
60
60
|
const manifest = this.manifest; // In this case we are sure its not undefined.
|
|
61
61
|
const newComponent = await createExtensionElement(manifest, this.#defaultElement);
|
|
62
|
-
if (!this._isConditionsPositive) {
|
|
63
|
-
|
|
62
|
+
if (signal.aborted || !this._isConditionsPositive) {
|
|
63
|
+
if (newComponent && 'destroy' in newComponent) {
|
|
64
|
+
newComponent.destroy();
|
|
65
|
+
}
|
|
64
66
|
return false;
|
|
65
67
|
}
|
|
68
|
+
if (this.#component && this.#component !== newComponent) {
|
|
69
|
+
if ('destroy' in this.#component) {
|
|
70
|
+
this.#component.destroy();
|
|
71
|
+
}
|
|
72
|
+
this.#component = undefined;
|
|
73
|
+
}
|
|
66
74
|
this.#component = newComponent;
|
|
67
75
|
if (this.#component) {
|
|
68
76
|
this.#assignProperties();
|
package/dist-cms/libs/extension-api/controller/extension-manifest-initializer.controller.d.ts
CHANGED
|
@@ -13,6 +13,6 @@ import type { UmbControllerHost } from '../../controller-api/index.js';
|
|
|
13
13
|
*/
|
|
14
14
|
export declare class UmbExtensionManifestInitializer<ManifestType extends ManifestWithDynamicConditions = ManifestWithDynamicConditions, ControllerType extends UmbBaseExtensionInitializer<ManifestType, any> = any> extends UmbBaseExtensionInitializer<ManifestType, ControllerType> {
|
|
15
15
|
constructor(host: UmbControllerHost, extensionRegistry: UmbExtensionRegistry<ManifestCondition>, alias: string, onPermissionChanged: (isPermitted: boolean, controller: ControllerType) => void);
|
|
16
|
-
protected _conditionsAreGood(): Promise<boolean>;
|
|
16
|
+
protected _conditionsAreGood(_signal: AbortSignal): Promise<boolean>;
|
|
17
17
|
protected _conditionsAreBad(): Promise<void>;
|
|
18
18
|
}
|