@umbraco-cms/backoffice 17.5.0-rc → 17.5.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/dist-cms/apps/app/app.element.js +6 -1
- package/dist-cms/assets/lang/de.js +1 -1
- package/dist-cms/assets/lang/fr.js +1 -1
- package/dist-cms/assets/lang/nb.js +1 -1
- package/dist-cms/assets/lang/nl.js +1 -1
- package/dist-cms/assets/lang/sv.js +1 -1
- package/dist-cms/libs/extension-api/initializers/extension-initializer-base.js +26 -2
- package/dist-cms/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -217,7 +217,7 @@ let UmbAppElement = class UmbAppElement extends UmbLitElement {
|
|
|
217
217
|
onInit(this, umbExtensionsRegistry);
|
|
218
218
|
// Register public extensions (login extensions)
|
|
219
219
|
await new UmbServerExtensionRegistrator(this, umbExtensionsRegistry).registerPublicExtensions();
|
|
220
|
-
new UmbAppEntryPointExtensionInitializer(this, umbExtensionsRegistry);
|
|
220
|
+
const entryPointInitializer = new UmbAppEntryPointExtensionInitializer(this, umbExtensionsRegistry);
|
|
221
221
|
// Try to initialise the auth flow and get the runtime status
|
|
222
222
|
try {
|
|
223
223
|
// If the runtime level is "install" or ?status=false is set, we should clear any cached tokens
|
|
@@ -230,6 +230,11 @@ let UmbAppElement = class UmbAppElement extends UmbLitElement {
|
|
|
230
230
|
else {
|
|
231
231
|
await this.#setAuthStatus();
|
|
232
232
|
}
|
|
233
|
+
// The login screen decides which auth provider to use from the registered
|
|
234
|
+
// `authProvider` extensions. App-entry-points may register or unregister those during
|
|
235
|
+
// their async onInit, so wait for them to settle before routing — otherwise on a slow
|
|
236
|
+
// connection the decision races and falls back to the local login.
|
|
237
|
+
await this.observe(entryPointInitializer.loaded).asPromise();
|
|
233
238
|
// Initialise the router
|
|
234
239
|
this.#redirect();
|
|
235
240
|
}
|
|
@@ -967,7 +967,7 @@ export default {
|
|
|
967
967
|
greeting5: 'Willkommen',
|
|
968
968
|
greeting6: 'Willkommen',
|
|
969
969
|
instruction: 'Hier anmelden:',
|
|
970
|
-
signInWith: 'Anmelden mit',
|
|
970
|
+
signInWith: 'Anmelden mit {0}',
|
|
971
971
|
timeout: 'Sitzung abgelaufen',
|
|
972
972
|
bottomText: '<p style="text-align:right;">© 2001 - %0% <br /><a href="https://umbraco.com" style="text-decoration: none" target="_blank" rel="noopener">umbraco.org</a></p> ',
|
|
973
973
|
forgottenPassword: 'Kennwort vergessen?',
|
|
@@ -848,7 +848,7 @@ export default {
|
|
|
848
848
|
greeting5: 'Bienvenue',
|
|
849
849
|
greeting6: 'Bienvenue',
|
|
850
850
|
instruction: 'Connectez-vous ci-dessous',
|
|
851
|
-
signInWith: 'Identifiez-vous avec',
|
|
851
|
+
signInWith: 'Identifiez-vous avec {0}',
|
|
852
852
|
timeout: 'La session a expiré',
|
|
853
853
|
bottomText: '<p style="text-align:right;">© 2001 - %0% <br /><a href="https://umbraco.com" style="text-decoration: none" target="_blank" rel="noopener">Umbraco.com</a></p> ',
|
|
854
854
|
forgottenPassword: 'Mot de passe oublié?',
|
|
@@ -660,7 +660,7 @@ export default {
|
|
|
660
660
|
greeting5: 'Velkommen',
|
|
661
661
|
greeting6: 'Velkommen',
|
|
662
662
|
instruction: 'Logg på nedenfor',
|
|
663
|
-
signInWith: 'Logg på med',
|
|
663
|
+
signInWith: 'Logg på med {0}',
|
|
664
664
|
timeout: 'Din sesjon er utløpt',
|
|
665
665
|
bottomText: '<p style="text-align:right;">© 2001 - %0% <br /><a href="https://umbraco.com" style="text-decoration: none" target="_blank" rel="noopener">umbraco.com</a></p> ',
|
|
666
666
|
},
|
|
@@ -866,7 +866,7 @@ export default {
|
|
|
866
866
|
greeting5: 'Welkom',
|
|
867
867
|
greeting6: 'Welkom',
|
|
868
868
|
instruction: 'log hieronder in',
|
|
869
|
-
signInWith: 'Inloggen met',
|
|
869
|
+
signInWith: 'Inloggen met {0}',
|
|
870
870
|
timeout: 'Sessie is verlopen',
|
|
871
871
|
bottomText: '<p style="text-align:right;">© 2001 - %0% <br /><a href="https://umbraco.com" style="text-decoration: none" target="_blank" rel="noopener">umbraco.com</a></p>',
|
|
872
872
|
forgottenPassword: 'Wachtwoord vergeten?',
|
|
@@ -7,28 +7,52 @@ export class UmbExtensionInitializerBase extends UmbControllerBase {
|
|
|
7
7
|
#extensionMap;
|
|
8
8
|
// Use the value `undefined`, as that would not resolve a observation promise. [NL]
|
|
9
9
|
#loaded;
|
|
10
|
+
// Identifies the current processing pass. The observer callback is async, so passes can
|
|
11
|
+
// overlap; only the latest pass is allowed to settle `loaded`, so a slower earlier pass
|
|
12
|
+
// cannot unblock waiters before the newest set of extensions has finished instantiating.
|
|
13
|
+
#loadPass;
|
|
10
14
|
constructor(host, extensionRegistry, manifestType) {
|
|
11
15
|
super(host);
|
|
12
16
|
this.#extensionMap = new Map();
|
|
13
17
|
// Use the value `undefined`, as that would not resolve a observation promise. [NL]
|
|
14
18
|
this.#loaded = new UmbBooleanState(undefined);
|
|
15
19
|
this.loaded = this.#loaded.asObservable();
|
|
20
|
+
// Identifies the current processing pass. The observer callback is async, so passes can
|
|
21
|
+
// overlap; only the latest pass is allowed to settle `loaded`, so a slower earlier pass
|
|
22
|
+
// cannot unblock waiters before the newest set of extensions has finished instantiating.
|
|
23
|
+
this.#loadPass = 0;
|
|
16
24
|
this.host = host;
|
|
17
25
|
this.extensionRegistry = extensionRegistry;
|
|
18
26
|
this.observe(extensionRegistry.byType(manifestType), async (extensions) => {
|
|
27
|
+
const pass = ++this.#loadPass;
|
|
28
|
+
// Re-arm while this pass is in flight so a consumer awaiting `loaded` waits for it to
|
|
29
|
+
// finish instead of resolving on a stale `true` from a previous pass. `undefined`
|
|
30
|
+
// rather than `false` because `asPromise()` resolves on the first non-undefined value.
|
|
31
|
+
this.#loaded.setValue(undefined);
|
|
19
32
|
this.#extensionMap.forEach((existingExt) => {
|
|
20
33
|
if (!extensions.find((b) => b.alias === existingExt.alias)) {
|
|
21
34
|
this.unloadExtension(existingExt);
|
|
22
35
|
this.#extensionMap.delete(existingExt.alias);
|
|
23
36
|
}
|
|
24
37
|
});
|
|
25
|
-
|
|
38
|
+
// `allSettled` so a throwing/rejecting `instantiateExtension` cannot leave `loaded`
|
|
39
|
+
// stuck at `undefined` and hang a waiter (e.g. the app boot gate). Failures are
|
|
40
|
+
// surfaced rather than swallowed.
|
|
41
|
+
const results = await Promise.allSettled(extensions.map((extension) => {
|
|
26
42
|
if (this.#extensionMap.has(extension.alias))
|
|
27
43
|
return;
|
|
28
44
|
this.#extensionMap.set(extension.alias, extension);
|
|
29
45
|
return this.instantiateExtension(extension);
|
|
30
46
|
}));
|
|
31
|
-
|
|
47
|
+
for (const result of results) {
|
|
48
|
+
if (result.status === 'rejected') {
|
|
49
|
+
console.error('[UmbExtensionInitializer] Failed to instantiate extension', result.reason);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// Only the latest pass settles `loaded`. Resolving unconditionally — including for
|
|
53
|
+
// zero extensions — so a consumer awaiting `loaded` (the app-entry-point boot gate,
|
|
54
|
+
// the bundle guard) never hangs on a default install that registers none of this type.
|
|
55
|
+
if (pass === this.#loadPass) {
|
|
32
56
|
this.#loaded.setValue(true);
|
|
33
57
|
}
|
|
34
58
|
});
|