@umbraco-cms/backoffice 14.0.0--preview005-bbf54b9a → 14.0.0--preview005-c6c57135

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (20) hide show
  1. package/dist-cms/libs/element-api/element.mixin.d.ts +3 -3
  2. package/dist-cms/libs/element-api/element.mixin.js +2 -2
  3. package/dist-cms/libs/extension-api/registry/extension.registry.d.ts +19 -0
  4. package/dist-cms/libs/extension-api/registry/extension.registry.js +42 -1
  5. package/dist-cms/libs/localization-api/index.d.ts +2 -2
  6. package/dist-cms/libs/localization-api/index.js +2 -2
  7. package/dist-cms/libs/localization-api/{localize.controller.d.ts → localization.controller.d.ts} +6 -4
  8. package/dist-cms/libs/localization-api/{localize.controller.js → localization.controller.js} +34 -24
  9. package/dist-cms/libs/localization-api/localization.manager.d.ts +29 -0
  10. package/dist-cms/libs/localization-api/localization.manager.js +94 -0
  11. package/dist-cms/packages/core/localization/registry/localization.registry.d.ts +3 -3
  12. package/dist-cms/packages/core/localization/registry/localization.registry.js +59 -60
  13. package/dist-cms/packages/core/tree/tree-menu-item-default/tree-menu-item-default.element.js +1 -1
  14. package/dist-cms/packages/core/workspace/components/workspace-split-view/workspace-split-view.element.js +1 -1
  15. package/dist-cms/packages/documents/documents/workspace/document-workspace-split-view.element.js +1 -2
  16. package/dist-cms/packages/user/current-user/current-user.context.js +2 -7
  17. package/dist-cms/tsconfig.build.tsbuildinfo +1 -1
  18. package/package.json +1 -1
  19. package/dist-cms/libs/localization-api/manager.d.ts +0 -18
  20. package/dist-cms/libs/localization-api/manager.js +0 -40
@@ -1,4 +1,4 @@
1
- import { UmbLocalizeController } from '../localization-api/index.js';
1
+ import { UmbLocalizationController } from '../localization-api/index.js';
2
2
  import type { Observable } from '../../external/rxjs/index.js';
3
3
  import type { HTMLElementConstructor } from '../extension-api/index.js';
4
4
  import { type UmbControllerHostElement } from '../controller-api/index.js';
@@ -21,8 +21,8 @@ export declare class UmbElement extends UmbControllerHostElement {
21
21
  consumeContext<BaseType = unknown, ResultType extends BaseType = BaseType>(alias: string | UmbContextToken<BaseType, ResultType>, callback: UmbContextCallback<ResultType>): UmbContextConsumerController<BaseType, ResultType>;
22
22
  /**
23
23
  * Use the UmbLocalizeController to localize your element.
24
- * @see UmbLocalizeController
24
+ * @see UmbLocalizationController
25
25
  */
26
- localize: UmbLocalizeController;
26
+ localize: UmbLocalizationController;
27
27
  }
28
28
  export declare const UmbElementMixin: <T extends HTMLElementConstructor>(superClass: T) => HTMLElementConstructor<UmbElement> & T;
@@ -1,4 +1,4 @@
1
- import { UmbLocalizeController } from '../localization-api/index.js';
1
+ import { UmbLocalizationController } from '../localization-api/index.js';
2
2
  import { UmbControllerHostElementMixin } from '../controller-api/index.js';
3
3
  import { UmbContextConsumerController, UmbContextProviderController } from '../context-api/index.js';
4
4
  import { UmbObserverController } from '../observable-api/index.js';
@@ -6,7 +6,7 @@ export const UmbElementMixin = (superClass) => {
6
6
  class UmbElementMixinClass extends UmbControllerHostElementMixin(superClass) {
7
7
  constructor() {
8
8
  super(...arguments);
9
- this.localize = new UmbLocalizeController(this);
9
+ this.localize = new UmbLocalizationController(this);
10
10
  }
11
11
  /**
12
12
  * @description Observe a RxJS source of choice.
@@ -21,6 +21,25 @@ export declare class UmbExtensionRegistry<IncomingManifestTypes extends Manifest
21
21
  getByAlias<T extends ManifestBase = ManifestBase>(alias: string): Observable<T | undefined>;
22
22
  getByTypeAndAlias<Key extends keyof ManifestTypeMap<ManifestTypes> | string, T extends ManifestBase = SpecificManifestTypeOrManifestBase<ManifestTypes, Key>>(type: Key, alias: string): Observable<T | undefined>;
23
23
  getByTypeAndAliases<Key extends keyof ManifestTypeMap<ManifestTypes> | string, T extends ManifestBase = SpecificManifestTypeOrManifestBase<ManifestTypes, Key>>(type: Key, aliases: Array<string>): Observable<T[]>;
24
+ /**
25
+ * Get an observable of an extension by type and a given filter method.
26
+ * This will return the all extensions that matches the type and which filter method returns true.
27
+ * The filter method will be called for each extension manifest of the given type, and the first argument to it is the extension manifest.
28
+ * @param type {string} - The type of the extension to get
29
+ * @param filter {(ext: T): void} - The filter method to use to filter the extensions
30
+ * @returns {Observable<T | undefined>} - An observable of the extensions that matches the type and filter method
31
+ */
32
+ byTypeAndFilter<Key extends keyof ManifestTypeMap<ManifestTypes> | string, T extends ManifestBase = SpecificManifestTypeOrManifestBase<ManifestTypes, Key>>(type: Key, filter: (ext: T) => boolean): Observable<T | undefined>;
33
+ /**
34
+ * Get an observable that provides extensions matching the given type.
35
+ * @param type {string} - The type of the extensions to get.
36
+ * @returns {Observable<T | undefined>} - An observable of the extensions that matches the type.
37
+ */
24
38
  extensionsOfType<Key extends keyof ManifestTypeMap<ManifestTypes> | string, T extends ManifestBase = SpecificManifestTypeOrManifestBase<ManifestTypes, Key>>(type: Key): Observable<T[]>;
39
+ /**
40
+ * Get an observable that provides extensions matching given types.
41
+ * @param type {Array<string>} - The types of the extensions to get.
42
+ * @returns {Observable<T | undefined>} - An observable of the extensions that matches the types.
43
+ */
25
44
  extensionsOfTypes<ExtensionTypes extends ManifestBase = ManifestBase>(types: string[]): Observable<Array<ExtensionTypes>>;
26
45
  }
@@ -1,5 +1,5 @@
1
1
  import { UmbBasicState } from '../../observable-api/index.js';
2
- import { map, distinctUntilChanged, combineLatest, of, switchMap, } from '../../../external/rxjs/index.js';
2
+ import { map, distinctUntilChanged, combineLatest, of, switchMap } from '../../../external/rxjs/index.js';
3
3
  function extensionArrayMemoization(previousValue, currentValue) {
4
4
  // If length is different, data is different:
5
5
  if (previousValue.length !== currentValue.length) {
@@ -137,6 +137,7 @@ export class UmbExtensionRegistry {
137
137
  _extensionsOfTypes(types) {
138
138
  return this.extensions.pipe(map((exts) => exts.filter((ext) => types.indexOf(ext.type) !== -1)), distinctUntilChanged(extensionArrayMemoization));
139
139
  }
140
+ // TODO: get rid of the name get
140
141
  getByAlias(alias) {
141
142
  return this.extensions.pipe(map((exts) => exts.find((ext) => ext.alias === alias)), distinctUntilChanged(extensionSingleMemoization), switchMap((ext) => {
142
143
  if (ext?.kind) {
@@ -160,6 +161,7 @@ export class UmbExtensionRegistry {
160
161
  return of(ext);
161
162
  }), distinctUntilChanged(extensionAndKindMatchSingleMemoization));
162
163
  }
164
+ // TODO: get rid of the name get
163
165
  getByTypeAndAlias(type, alias) {
164
166
  return combineLatest([
165
167
  this.extensions.pipe(map((exts) => exts.find((ext) => ext.type === type && ext.alias === alias)), distinctUntilChanged(extensionSingleMemoization)),
@@ -180,6 +182,7 @@ export class UmbExtensionRegistry {
180
182
  return ext;
181
183
  }), distinctUntilChanged(extensionAndKindMatchSingleMemoization));
182
184
  }
185
+ // TODO: get rid of the name get
183
186
  getByTypeAndAliases(type, aliases) {
184
187
  return combineLatest([
185
188
  this.extensions.pipe(map((exts) => exts.filter((ext) => ext.type === type && aliases.indexOf(ext.alias) !== -1)), distinctUntilChanged(extensionArrayMemoization)),
@@ -199,6 +202,39 @@ export class UmbExtensionRegistry {
199
202
  })
200
203
  .sort(sortExtensions)), distinctUntilChanged(extensionAndKindMatchArrayMemoization));
201
204
  }
205
+ /**
206
+ * Get an observable of an extension by type and a given filter method.
207
+ * This will return the all extensions that matches the type and which filter method returns true.
208
+ * The filter method will be called for each extension manifest of the given type, and the first argument to it is the extension manifest.
209
+ * @param type {string} - The type of the extension to get
210
+ * @param filter {(ext: T): void} - The filter method to use to filter the extensions
211
+ * @returns {Observable<T | undefined>} - An observable of the extensions that matches the type and filter method
212
+ */
213
+ byTypeAndFilter(type, filter) {
214
+ return combineLatest([
215
+ this.extensions.pipe(map((exts) => exts.find((ext) => ext.type === type && filter(ext))), distinctUntilChanged(extensionSingleMemoization)),
216
+ this._kindsOfType(type),
217
+ ]).pipe(map(([ext, kinds]) => {
218
+ // TODO: share one merge function between the different methods of this class:
219
+ // Specific Extension Meta merge (does not merge conditions)
220
+ if (ext) {
221
+ const baseManifest = kinds.find((kind) => kind.matchKind === ext.kind)?.manifest;
222
+ if (baseManifest) {
223
+ const merged = { __isMatchedWithKind: true, ...baseManifest, ...ext };
224
+ if (baseManifest.meta) {
225
+ merged.meta = { ...baseManifest.meta, ...ext.meta };
226
+ }
227
+ return merged;
228
+ }
229
+ }
230
+ return ext;
231
+ }), distinctUntilChanged(extensionAndKindMatchSingleMemoization));
232
+ }
233
+ /**
234
+ * Get an observable that provides extensions matching the given type.
235
+ * @param type {string} - The type of the extensions to get.
236
+ * @returns {Observable<T | undefined>} - An observable of the extensions that matches the type.
237
+ */
202
238
  extensionsOfType(type) {
203
239
  return combineLatest([this._extensionsOfType(type), this._kindsOfType(type)]).pipe(map(([exts, kinds]) => exts
204
240
  .map((ext) => {
@@ -215,6 +251,11 @@ export class UmbExtensionRegistry {
215
251
  })
216
252
  .sort(sortExtensions)), distinctUntilChanged(extensionAndKindMatchArrayMemoization));
217
253
  }
254
+ /**
255
+ * Get an observable that provides extensions matching given types.
256
+ * @param type {Array<string>} - The types of the extensions to get.
257
+ * @returns {Observable<T | undefined>} - An observable of the extensions that matches the types.
258
+ */
218
259
  extensionsOfTypes(types) {
219
260
  return combineLatest([this._extensionsOfTypes(types), this._kindsOfTypes(types)]).pipe(map(([exts, kinds]) => exts
220
261
  .map((ext) => {
@@ -1,3 +1,3 @@
1
- export * from './localize.controller.js';
1
+ export * from './localization.controller.js';
2
2
  export * from './types/localization.js';
3
- export * from './manager.js';
3
+ export * from './localization.manager.js';
@@ -1,3 +1,3 @@
1
- export * from './localize.controller.js';
1
+ export * from './localization.controller.js';
2
2
  export * from './types/localization.js';
3
- export * from './manager.js';
3
+ export * from './localization.manager.js';
@@ -1,4 +1,4 @@
1
- import type { DefaultLocalizationSet, FunctionParams, LocalizationSet } from './manager.js';
1
+ import type { UmbLocalizationSet, FunctionParams, UmbLocalizationSetBase, UmbLocalizationSetKey } from './localization.manager.js';
2
2
  import type { UmbController, UmbControllerHost } from '../controller-api/index.js';
3
3
  /**
4
4
  * The UmbLocalizeController enables localization for your element.
@@ -18,13 +18,15 @@ import type { UmbController, UmbControllerHost } from '../controller-api/index.j
18
18
  * }
19
19
  * ```
20
20
  */
21
- export declare class UmbLocalizeController<LocalizationType extends LocalizationSet = DefaultLocalizationSet> implements UmbController {
21
+ export declare class UmbLocalizationController<LocalizationSetType extends UmbLocalizationSetBase = UmbLocalizationSet> implements UmbController {
22
22
  #private;
23
- controllerAlias: symbol;
23
+ readonly controllerAlias: symbol;
24
24
  constructor(host: UmbControllerHost);
25
25
  hostConnected(): void;
26
26
  hostDisconnected(): void;
27
27
  destroy(): void;
28
+ documentUpdate(): void;
29
+ keysChanged(changedKeys: Set<UmbLocalizationSetKey>): void;
28
30
  /**
29
31
  * Gets the host element's directionality as determined by the `dir` attribute. The return value is transformed to
30
32
  * lowercase.
@@ -37,7 +39,7 @@ export declare class UmbLocalizeController<LocalizationType extends Localization
37
39
  lang(): string;
38
40
  private getLocalizationData;
39
41
  /** Outputs a translated term. */
40
- term<K extends keyof LocalizationType>(key: K, ...args: FunctionParams<LocalizationType[K]>): string;
42
+ term<K extends keyof LocalizationSetType>(key: K, ...args: FunctionParams<LocalizationSetType[K]>): string;
41
43
  /** Outputs a localized date in the specified format. */
42
44
  date(dateToFormat: Date | string, options?: Intl.DateTimeFormatOptions): string;
43
45
  /** Outputs a localized number in the specified format. */
@@ -9,9 +9,9 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
9
9
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
10
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
11
  };
12
- var _UmbLocalizeController_host, _UmbLocalizeController_hostEl;
13
- import { connectedElements, documentDirection, documentLanguage, fallback, localizations, } from './manager.js';
14
- const LocalizeControllerAlias = Symbol();
12
+ var _UmbLocalizationController_host, _UmbLocalizationController_hostEl, _UmbLocalizationController_usedKeys;
13
+ import { umbLocalizationManager } from './localization.manager.js';
14
+ const LocalizationControllerAlias = Symbol();
15
15
  /**
16
16
  * The UmbLocalizeController enables localization for your element.
17
17
  *
@@ -30,52 +30,62 @@ const LocalizeControllerAlias = Symbol();
30
30
  * }
31
31
  * ```
32
32
  */
33
- export class UmbLocalizeController {
33
+ export class UmbLocalizationController {
34
34
  constructor(host) {
35
- _UmbLocalizeController_host.set(this, void 0);
36
- _UmbLocalizeController_hostEl.set(this, void 0);
37
- this.controllerAlias = LocalizeControllerAlias;
38
- __classPrivateFieldSet(this, _UmbLocalizeController_host, host, "f");
39
- __classPrivateFieldSet(this, _UmbLocalizeController_hostEl, host.getHostElement(), "f");
40
- __classPrivateFieldGet(this, _UmbLocalizeController_host, "f").addController(this);
35
+ _UmbLocalizationController_host.set(this, void 0);
36
+ _UmbLocalizationController_hostEl.set(this, void 0);
37
+ this.controllerAlias = LocalizationControllerAlias;
38
+ _UmbLocalizationController_usedKeys.set(this, new Array());
39
+ __classPrivateFieldSet(this, _UmbLocalizationController_host, host, "f");
40
+ __classPrivateFieldSet(this, _UmbLocalizationController_hostEl, host.getHostElement(), "f");
41
+ __classPrivateFieldGet(this, _UmbLocalizationController_host, "f").addController(this);
41
42
  }
42
43
  hostConnected() {
43
- if (connectedElements.has(__classPrivateFieldGet(this, _UmbLocalizeController_hostEl, "f"))) {
44
- return;
45
- }
46
- connectedElements.add(__classPrivateFieldGet(this, _UmbLocalizeController_hostEl, "f"));
44
+ umbLocalizationManager.appendConsumer(this);
47
45
  }
48
46
  hostDisconnected() {
49
- connectedElements.delete(__classPrivateFieldGet(this, _UmbLocalizeController_hostEl, "f"));
47
+ umbLocalizationManager.removeConsumer(this);
50
48
  }
51
49
  destroy() {
52
- __classPrivateFieldGet(this, _UmbLocalizeController_host, "f").removeController(this);
53
- __classPrivateFieldSet(this, _UmbLocalizeController_hostEl, undefined, "f");
50
+ __classPrivateFieldGet(this, _UmbLocalizationController_host, "f").removeController(this);
51
+ __classPrivateFieldSet(this, _UmbLocalizationController_hostEl, undefined, "f");
52
+ }
53
+ documentUpdate() {
54
+ __classPrivateFieldGet(this, _UmbLocalizationController_hostEl, "f")?.requestUpdate?.();
55
+ }
56
+ keysChanged(changedKeys) {
57
+ const hasOneOfTheseKeys = __classPrivateFieldGet(this, _UmbLocalizationController_usedKeys, "f").find((key) => changedKeys.has(key));
58
+ if (hasOneOfTheseKeys) {
59
+ __classPrivateFieldGet(this, _UmbLocalizationController_hostEl, "f")?.requestUpdate?.();
60
+ }
54
61
  }
55
62
  /**
56
63
  * Gets the host element's directionality as determined by the `dir` attribute. The return value is transformed to
57
64
  * lowercase.
58
65
  */
59
66
  dir() {
60
- return `${__classPrivateFieldGet(this, _UmbLocalizeController_hostEl, "f").dir || documentDirection}`.toLowerCase();
67
+ return `${__classPrivateFieldGet(this, _UmbLocalizationController_hostEl, "f")?.dir || umbLocalizationManager.documentDirection}`.toLowerCase();
61
68
  }
62
69
  /**
63
70
  * Gets the host element's language as determined by the `lang` attribute. The return value is transformed to
64
71
  * lowercase.
65
72
  */
66
73
  lang() {
67
- return `${__classPrivateFieldGet(this, _UmbLocalizeController_hostEl, "f").lang || documentLanguage}`.toLowerCase();
74
+ return `${__classPrivateFieldGet(this, _UmbLocalizationController_hostEl, "f")?.lang || umbLocalizationManager.documentLanguage}`.toLowerCase();
68
75
  }
69
76
  getLocalizationData(lang) {
70
77
  const locale = new Intl.Locale(lang);
71
78
  const language = locale?.language.toLowerCase();
72
79
  const region = locale?.region?.toLowerCase() ?? '';
73
- const primary = localizations.get(`${language}-${region}`);
74
- const secondary = localizations.get(language);
80
+ const primary = umbLocalizationManager.localizations.get(`${language}-${region}`);
81
+ const secondary = umbLocalizationManager.localizations.get(language);
75
82
  return { locale, language, region, primary, secondary };
76
83
  }
77
84
  /** Outputs a translated term. */
78
85
  term(key, ...args) {
86
+ if (!__classPrivateFieldGet(this, _UmbLocalizationController_usedKeys, "f").includes(key)) {
87
+ __classPrivateFieldGet(this, _UmbLocalizationController_usedKeys, "f").push(key);
88
+ }
79
89
  const { primary, secondary } = this.getLocalizationData(this.lang());
80
90
  let term;
81
91
  // Look for a matching term using regionCode, code, then the fallback
@@ -85,8 +95,8 @@ export class UmbLocalizeController {
85
95
  else if (secondary && secondary[key]) {
86
96
  term = secondary[key];
87
97
  }
88
- else if (fallback && fallback[key]) {
89
- term = fallback[key];
98
+ else if (umbLocalizationManager.fallback && umbLocalizationManager.fallback[key]) {
99
+ term = umbLocalizationManager.fallback[key];
90
100
  }
91
101
  else {
92
102
  return String(key);
@@ -120,4 +130,4 @@ export class UmbLocalizeController {
120
130
  return new Intl.RelativeTimeFormat(this.lang(), options).format(value, unit);
121
131
  }
122
132
  }
123
- _UmbLocalizeController_host = new WeakMap(), _UmbLocalizeController_hostEl = new WeakMap();
133
+ _UmbLocalizationController_host = new WeakMap(), _UmbLocalizationController_hostEl = new WeakMap(), _UmbLocalizationController_usedKeys = new WeakMap();
@@ -0,0 +1,29 @@
1
+ import type { UmbLocalizationController } from './localization.controller.js';
2
+ import type { UmbLocalizationEntry } from './types/localization.js';
3
+ export type FunctionParams<T> = T extends (...args: infer U) => string ? U : [];
4
+ export interface UmbLocalizationSetBase {
5
+ $code: string;
6
+ $dir: 'ltr' | 'rtl';
7
+ }
8
+ export type UmbLocalizationSetKey = string | number | symbol;
9
+ export interface UmbLocalizationSet extends UmbLocalizationSetBase {
10
+ [key: UmbLocalizationSetKey]: UmbLocalizationEntry;
11
+ }
12
+ export declare const UMB_DEFAULT_LOCALIZATION_CULTURE = "en-us";
13
+ export declare class UmbLocalizationManager {
14
+ #private;
15
+ connectedControllers: Set<UmbLocalizationController<UmbLocalizationSetBase>>;
16
+ localizations: Map<string, UmbLocalizationSetBase>;
17
+ documentDirection: string;
18
+ documentLanguage: string;
19
+ get fallback(): UmbLocalizationSet | undefined;
20
+ constructor();
21
+ appendConsumer(consumer: UmbLocalizationController<UmbLocalizationSetBase>): void;
22
+ removeConsumer(consumer: UmbLocalizationController<UmbLocalizationSetBase>): void;
23
+ /** Registers one or more translations */
24
+ registerLocalization(t: UmbLocalizationSetBase): void;
25
+ registerManyLocalizations(translations: Array<UmbLocalizationSetBase>): void;
26
+ /** Updates all localized elements that are currently connected */
27
+ updateAll: () => void;
28
+ }
29
+ export declare const umbLocalizationManager: UmbLocalizationManager;
@@ -0,0 +1,94 @@
1
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
2
+ if (kind === "m") throw new TypeError("Private method is not writable");
3
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
4
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
5
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
6
+ };
7
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
8
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
9
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
+ };
12
+ var _UmbLocalizationManager_instances, _UmbLocalizationManager_documentElementObserver, _UmbLocalizationManager_changedKeys, _UmbLocalizationManager_requestUpdateChangedKeysId, _UmbLocalizationManager_registerLocalizationBind, _UmbLocalizationManager_updateChangedKeys, _UmbLocalizationManager_requestChangedKeysUpdate;
13
+ export const UMB_DEFAULT_LOCALIZATION_CULTURE = 'en-us';
14
+ export class UmbLocalizationManager {
15
+ get fallback() {
16
+ return this.localizations.get(UMB_DEFAULT_LOCALIZATION_CULTURE);
17
+ }
18
+ constructor() {
19
+ _UmbLocalizationManager_instances.add(this);
20
+ this.connectedControllers = new Set();
21
+ _UmbLocalizationManager_documentElementObserver.set(this, void 0);
22
+ _UmbLocalizationManager_changedKeys.set(this, new Set());
23
+ _UmbLocalizationManager_requestUpdateChangedKeysId.set(this, undefined);
24
+ this.localizations = new Map();
25
+ this.documentDirection = document.documentElement.dir || 'ltr';
26
+ this.documentLanguage = document.documentElement.lang || navigator.language;
27
+ _UmbLocalizationManager_registerLocalizationBind.set(this, this.registerLocalization.bind(this));
28
+ /** Updates all localized elements that are currently connected */
29
+ this.updateAll = () => {
30
+ const newDir = document.documentElement.dir || 'ltr';
31
+ const newLang = document.documentElement.lang || navigator.language;
32
+ if (this.documentDirection === newDir && this.documentLanguage === newLang)
33
+ return;
34
+ // The document direction or language did changed, so lets move on:
35
+ this.documentDirection = newDir;
36
+ this.documentLanguage = newLang;
37
+ // Check if there was any changed.
38
+ this.connectedControllers.forEach((ctrl) => {
39
+ ctrl.documentUpdate();
40
+ });
41
+ if (__classPrivateFieldGet(this, _UmbLocalizationManager_requestUpdateChangedKeysId, "f")) {
42
+ cancelAnimationFrame(__classPrivateFieldGet(this, _UmbLocalizationManager_requestUpdateChangedKeysId, "f"));
43
+ __classPrivateFieldSet(this, _UmbLocalizationManager_requestUpdateChangedKeysId, undefined, "f");
44
+ }
45
+ __classPrivateFieldGet(this, _UmbLocalizationManager_changedKeys, "f").clear();
46
+ };
47
+ _UmbLocalizationManager_updateChangedKeys.set(this, () => {
48
+ __classPrivateFieldSet(this, _UmbLocalizationManager_requestUpdateChangedKeysId, undefined, "f");
49
+ this.connectedControllers.forEach((ctrl) => {
50
+ ctrl.keysChanged(__classPrivateFieldGet(this, _UmbLocalizationManager_changedKeys, "f"));
51
+ });
52
+ __classPrivateFieldGet(this, _UmbLocalizationManager_changedKeys, "f").clear();
53
+ });
54
+ __classPrivateFieldSet(this, _UmbLocalizationManager_documentElementObserver, new MutationObserver(this.updateAll), "f");
55
+ __classPrivateFieldGet(this, _UmbLocalizationManager_documentElementObserver, "f").observe(document.documentElement, {
56
+ attributes: true,
57
+ attributeFilter: ['dir', 'lang'],
58
+ });
59
+ }
60
+ appendConsumer(consumer) {
61
+ if (this.connectedControllers.has(consumer))
62
+ return;
63
+ this.connectedControllers.add(consumer);
64
+ }
65
+ removeConsumer(consumer) {
66
+ this.connectedControllers.delete(consumer);
67
+ }
68
+ /** Registers one or more translations */
69
+ registerLocalization(t) {
70
+ const code = t.$code.toLowerCase();
71
+ if (this.localizations.has(code)) {
72
+ // Merge translations that share the same language code
73
+ this.localizations.set(code, { ...this.localizations.get(code), ...t });
74
+ }
75
+ else {
76
+ this.localizations.set(code, t);
77
+ }
78
+ // Declare what keys have been changed:
79
+ const keys = Object.keys(t);
80
+ for (const key of keys) {
81
+ __classPrivateFieldGet(this, _UmbLocalizationManager_changedKeys, "f").add(key);
82
+ }
83
+ __classPrivateFieldGet(this, _UmbLocalizationManager_instances, "m", _UmbLocalizationManager_requestChangedKeysUpdate).call(this);
84
+ }
85
+ registerManyLocalizations(translations) {
86
+ translations.map(__classPrivateFieldGet(this, _UmbLocalizationManager_registerLocalizationBind, "f"));
87
+ }
88
+ }
89
+ _UmbLocalizationManager_documentElementObserver = new WeakMap(), _UmbLocalizationManager_changedKeys = new WeakMap(), _UmbLocalizationManager_requestUpdateChangedKeysId = new WeakMap(), _UmbLocalizationManager_registerLocalizationBind = new WeakMap(), _UmbLocalizationManager_updateChangedKeys = new WeakMap(), _UmbLocalizationManager_instances = new WeakSet(), _UmbLocalizationManager_requestChangedKeysUpdate = function _UmbLocalizationManager_requestChangedKeysUpdate() {
90
+ if (__classPrivateFieldGet(this, _UmbLocalizationManager_requestUpdateChangedKeysId, "f"))
91
+ return;
92
+ __classPrivateFieldSet(this, _UmbLocalizationManager_requestUpdateChangedKeysId, requestAnimationFrame(__classPrivateFieldGet(this, _UmbLocalizationManager_updateChangedKeys, "f")), "f");
93
+ };
94
+ export const umbLocalizationManager = new UmbLocalizationManager();
@@ -1,12 +1,12 @@
1
- import type { LocalizationSet } from '../../../../libs/localization-api/index.js';
1
+ import type { UmbLocalizationSetBase } from '../../../../libs/localization-api/index.js';
2
2
  import type { UmbBackofficeExtensionRegistry } from '../../extension-registry/index.js';
3
3
  export declare class UmbLocalizationRegistry {
4
4
  #private;
5
+ readonly currentLanguage: import("rxjs/internal/Observable").Observable<string>;
5
6
  /**
6
7
  * Get the current registered translations.
7
8
  */
8
- get localizations(): Map<string, LocalizationSet>;
9
- get isDefaultLoaded(): import("rxjs/internal/Observable").Observable<boolean>;
9
+ get localizations(): Map<string, UmbLocalizationSetBase>;
10
10
  constructor(extensionRegistry: UmbBackofficeExtensionRegistry);
11
11
  /**
12
12
  * Load a language from the extension registry.
@@ -3,72 +3,75 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
3
3
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
4
4
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
5
5
  };
6
- var _UmbLocalizationRegistry_instances, _UmbLocalizationRegistry_currentLanguage, _UmbLocalizationRegistry_isDefaultLoaded, _UmbLocalizationRegistry_addOrUpdateDictionary;
7
- import { registerLocalization, localizations, } from '../../../../libs/localization-api/index.js';
8
- import { hasDefaultExport, loadManifestPlainJs } from '../../../../libs/extension-api/index.js';
6
+ var _UmbLocalizationRegistry_currentLanguage, _UmbLocalizationRegistry_loadedExtAliases, _UmbLocalizationRegistry_loadExtension;
7
+ import { umbLocalizationManager } from '../../../../libs/localization-api/index.js';
9
8
  import { umbExtensionsRegistry } from '../../extension-registry/index.js';
10
- import { BehaviorSubject, Subject, combineLatest, map, distinctUntilChanged, filter, startWith, } from '../../../../external/rxjs/index.js';
9
+ import { UmbStringState } from '../../../../libs/observable-api/index.js';
10
+ import { combineLatest } from '../../../../external/rxjs/index.js';
11
+ import { hasDefaultExport, loadManifestPlainJs } from '../../../../libs/extension-api/index.js';
12
+ function addOrUpdateDictionary(innerDictionary, dictionaryName, dictionary) {
13
+ for (const [key, value] of Object.entries(dictionary)) {
14
+ innerDictionary[`${dictionaryName}_${key}`] = value;
15
+ }
16
+ }
11
17
  export class UmbLocalizationRegistry {
12
18
  /**
13
19
  * Get the current registered translations.
14
20
  */
15
21
  get localizations() {
16
- return localizations;
17
- }
18
- get isDefaultLoaded() {
19
- return __classPrivateFieldGet(this, _UmbLocalizationRegistry_isDefaultLoaded, "f").asObservable();
22
+ return umbLocalizationManager.localizations;
20
23
  }
21
24
  constructor(extensionRegistry) {
22
- _UmbLocalizationRegistry_instances.add(this);
23
- _UmbLocalizationRegistry_currentLanguage.set(this, new Subject());
24
- _UmbLocalizationRegistry_isDefaultLoaded.set(this, new BehaviorSubject(false));
25
- const currentLanguage$ = __classPrivateFieldGet(this, _UmbLocalizationRegistry_currentLanguage, "f").pipe(startWith(document.documentElement.lang || 'en-us'), map((x) => x.toLowerCase()), distinctUntilChanged());
26
- const currentExtensions$ = extensionRegistry.extensionsOfType('localization').pipe(filter((x) => x.length > 0), distinctUntilChanged((prev, curr) => prev.length === curr.length && prev.every((x) => curr.includes(x))));
27
- combineLatest([currentLanguage$, currentExtensions$]).subscribe(async ([userCulture, extensions]) => {
28
- const locale = new Intl.Locale(userCulture);
29
- const translations = await Promise.all(extensions
30
- .filter((x) => x.meta.culture.toLowerCase() === locale.baseName.toLowerCase() ||
31
- x.meta.culture.toLowerCase() === locale.language.toLowerCase())
32
- .map(async (extension) => {
33
- const innerDictionary = {};
34
- // If extension contains a dictionary, add it to the inner dictionary.
35
- if (extension.meta.localizations) {
36
- for (const [dictionaryName, dictionary] of Object.entries(extension.meta.localizations)) {
37
- __classPrivateFieldGet(this, _UmbLocalizationRegistry_instances, "m", _UmbLocalizationRegistry_addOrUpdateDictionary).call(this, innerDictionary, dictionaryName, dictionary);
38
- }
25
+ _UmbLocalizationRegistry_currentLanguage.set(this, new UmbStringState(document.documentElement.lang ?? 'en-us'));
26
+ this.currentLanguage = __classPrivateFieldGet(this, _UmbLocalizationRegistry_currentLanguage, "f").asObservable();
27
+ _UmbLocalizationRegistry_loadedExtAliases.set(this, []);
28
+ _UmbLocalizationRegistry_loadExtension.set(this, async (extension) => {
29
+ __classPrivateFieldGet(this, _UmbLocalizationRegistry_loadedExtAliases, "f").push(extension.alias);
30
+ const innerDictionary = {};
31
+ // If extension contains a dictionary, add it to the inner dictionary.
32
+ if (extension.meta.localizations) {
33
+ for (const [dictionaryName, dictionary] of Object.entries(extension.meta.localizations)) {
34
+ addOrUpdateDictionary(innerDictionary, dictionaryName, dictionary);
39
35
  }
40
- // If extension contains a js file, load it and add the default dictionary to the inner dictionary.
41
- if (extension.js) {
42
- const loadedExtension = await loadManifestPlainJs(extension.js);
43
- if (loadedExtension && hasDefaultExport(loadedExtension)) {
44
- for (const [dictionaryName, dictionary] of Object.entries(loadedExtension.default)) {
45
- __classPrivateFieldGet(this, _UmbLocalizationRegistry_instances, "m", _UmbLocalizationRegistry_addOrUpdateDictionary).call(this, innerDictionary, dictionaryName, dictionary);
46
- }
36
+ }
37
+ // If extension contains a js file, load it and add the default dictionary to the inner dictionary.
38
+ if (extension.js) {
39
+ const loadedExtension = await loadManifestPlainJs(extension.js);
40
+ if (loadedExtension && hasDefaultExport(loadedExtension)) {
41
+ for (const [dictionaryName, dictionary] of Object.entries(loadedExtension.default)) {
42
+ addOrUpdateDictionary(innerDictionary, dictionaryName, dictionary);
47
43
  }
48
44
  }
49
- // Notify subscribers that the inner dictionary has changed.
50
- return {
51
- $code: extension.meta.culture.toLowerCase(),
52
- $dir: extension.meta.direction ?? 'ltr',
53
- ...innerDictionary,
54
- };
55
- }));
56
- if (translations.length) {
57
- registerLocalization(...translations);
58
- // Set the document language
59
- const newLang = locale.baseName.toLowerCase();
60
- if (document.documentElement.lang.toLowerCase() !== newLang) {
61
- document.documentElement.lang = newLang;
62
- }
63
- // Set the document direction to the direction of the primary language
64
- const newDir = translations[0].$dir ?? 'ltr';
65
- if (document.documentElement.dir !== newDir) {
66
- document.documentElement.dir = newDir;
67
- }
68
45
  }
69
- if (!__classPrivateFieldGet(this, _UmbLocalizationRegistry_isDefaultLoaded, "f").value) {
70
- __classPrivateFieldGet(this, _UmbLocalizationRegistry_isDefaultLoaded, "f").next(true);
71
- __classPrivateFieldGet(this, _UmbLocalizationRegistry_isDefaultLoaded, "f").complete();
46
+ // Notify subscribers that the inner dictionary has changed.
47
+ return {
48
+ $code: extension.meta.culture.toLowerCase(),
49
+ $dir: extension.meta.direction ?? 'ltr',
50
+ ...innerDictionary,
51
+ };
52
+ });
53
+ combineLatest([this.currentLanguage, extensionRegistry.extensionsOfType('localization')]).subscribe(async ([currentLanguage, extensions]) => {
54
+ const locale = new Intl.Locale(currentLanguage);
55
+ const filteredExt = extensions.filter((ext) => ext.meta.culture.toLowerCase() === locale.baseName.toLowerCase() ||
56
+ ext.meta.culture.toLowerCase() === locale.language.toLowerCase());
57
+ // Only get the extensions that are not already loading/loaded:
58
+ const diff = filteredExt.filter((ext) => !__classPrivateFieldGet(this, _UmbLocalizationRegistry_loadedExtAliases, "f").includes(ext.alias));
59
+ if (diff.length !== 0) {
60
+ // got new localizations to load:
61
+ const translations = await Promise.all(diff.map(__classPrivateFieldGet(this, _UmbLocalizationRegistry_loadExtension, "f")));
62
+ if (translations.length) {
63
+ umbLocalizationManager.registerManyLocalizations(translations);
64
+ // Set the document language
65
+ const newLang = locale.baseName.toLowerCase();
66
+ if (document.documentElement.lang.toLowerCase() !== newLang) {
67
+ document.documentElement.lang = newLang;
68
+ }
69
+ // Set the document direction to the direction of the primary language
70
+ const newDir = translations[0].$dir ?? 'ltr';
71
+ if (document.documentElement.dir !== newDir) {
72
+ document.documentElement.dir = newDir;
73
+ }
74
+ }
72
75
  }
73
76
  });
74
77
  }
@@ -77,12 +80,8 @@ export class UmbLocalizationRegistry {
77
80
  * @param locale The locale to load.
78
81
  */
79
82
  loadLanguage(locale) {
80
- __classPrivateFieldGet(this, _UmbLocalizationRegistry_currentLanguage, "f").next(locale);
83
+ __classPrivateFieldGet(this, _UmbLocalizationRegistry_currentLanguage, "f").setValue(locale.toLowerCase());
81
84
  }
82
85
  }
83
- _UmbLocalizationRegistry_currentLanguage = new WeakMap(), _UmbLocalizationRegistry_isDefaultLoaded = new WeakMap(), _UmbLocalizationRegistry_instances = new WeakSet(), _UmbLocalizationRegistry_addOrUpdateDictionary = function _UmbLocalizationRegistry_addOrUpdateDictionary(innerDictionary, dictionaryName, dictionary) {
84
- for (const [key, value] of Object.entries(dictionary)) {
85
- innerDictionary[`${dictionaryName}_${key}`] = value;
86
- }
87
- };
86
+ _UmbLocalizationRegistry_currentLanguage = new WeakMap(), _UmbLocalizationRegistry_loadedExtAliases = new WeakMap(), _UmbLocalizationRegistry_loadExtension = new WeakMap();
88
87
  export const umbLocalizationRegistry = new UmbLocalizationRegistry(umbExtensionsRegistry);
@@ -6,7 +6,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
6
6
  };
7
7
  import { html, nothing, customElement, property } from '../../../../external/lit/index.js';
8
8
  import { UmbLitElement } from '../../../../shared/lit-element/index.js';
9
- import { umbExtensionsRegistry, } from '../../extension-registry/index.js';
9
+ import { umbExtensionsRegistry } from '../../extension-registry/index.js';
10
10
  // TODO: Move to separate file:
11
11
  const manifest = {
12
12
  type: 'kind',
@@ -45,7 +45,7 @@ UmbWorkspaceSplitViewElement.styles = [
45
45
  display: block;
46
46
  width: 100%;
47
47
  height: 100%;
48
- min-height: 0;
48
+ min-width: 0;
49
49
  }
50
50
 
51
51
  :host(:not(:last-child)) {
@@ -54,8 +54,7 @@ UmbDocumentWorkspaceSplitViewElement.styles = [
54
54
  }
55
55
 
56
56
  #splitViews {
57
- display: grid;
58
- grid-template-columns: 50% 50%;
57
+ display: flex;
59
58
  width: 100%;
60
59
  height: calc(100% - var(--umb-footer-layout-height));
61
60
  }