|
1 |
| -import type { ManifestLocalization } from '../../extensions/localization.extension.js'; |
| 1 | +import { customElement, html, property, state } from '@umbraco-cms/backoffice/external/lit'; |
2 | 2 | import { UmbChangeEvent } from '@umbraco-cms/backoffice/event';
|
3 |
| -import { css, html, customElement, query, state, property } from '@umbraco-cms/backoffice/external/lit'; |
4 |
| -import type { UUISelectEvent } from '@umbraco-cms/backoffice/external/uui'; |
5 |
| -import { UUIFormControlMixin } from '@umbraco-cms/backoffice/external/uui'; |
6 | 3 | import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
|
7 | 4 | import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';
|
| 5 | +import { UmbFormControlMixin } from '@umbraco-cms/backoffice/validation'; |
| 6 | +import { UMB_DEFAULT_LOCALIZATION_CULTURE } from '@umbraco-cms/backoffice/localization-api'; |
| 7 | +import type { PropertyValues } from '@umbraco-cms/backoffice/external/lit'; |
| 8 | +import type { UUISelectEvent } from '@umbraco-cms/backoffice/external/uui'; |
8 | 9 |
|
9 | 10 | interface UmbCultureInputOption {
|
10 | 11 | name: string;
|
11 | 12 | value: string;
|
12 | 13 | }
|
13 | 14 |
|
14 | 15 | @customElement('umb-ui-culture-input')
|
15 |
| -export class UmbUiCultureInputElement extends UUIFormControlMixin(UmbLitElement, '') { |
| 16 | +export class UmbUiCultureInputElement extends UmbFormControlMixin<string, typeof UmbLitElement, undefined>( |
| 17 | + UmbLitElement, |
| 18 | +) { |
| 19 | + #invalidCulture?: string; |
| 20 | + #invalidBaseCulture?: string; |
| 21 | + |
16 | 22 | @state()
|
17 | 23 | private _options: Array<UmbCultureInputOption> = [];
|
18 | 24 |
|
19 |
| - @query('uui-combobox') |
20 |
| - private _selectElement!: HTMLInputElement; |
21 |
| - |
22 | 25 | @property({ type: String })
|
23 |
| - override get value() { |
24 |
| - return super.value; |
25 |
| - } |
26 |
| - override set value(value: FormDataEntryValue | FormData) { |
27 |
| - if (typeof value === 'string') { |
| 26 | + override set value(value: string | undefined) { |
| 27 | + if (value && typeof value === 'string') { |
28 | 28 | const oldValue = super.value;
|
29 | 29 | super.value = value.toLowerCase();
|
30 | 30 | this.requestUpdate('value', oldValue);
|
31 | 31 | }
|
32 | 32 | }
|
| 33 | + override get value(): string | undefined { |
| 34 | + return super.value; |
| 35 | + } |
33 | 36 |
|
34 | 37 | constructor() {
|
35 | 38 | super();
|
36 |
| - this.#observeTranslations(); |
37 |
| - } |
38 | 39 |
|
39 |
| - #observeTranslations() { |
40 | 40 | this.observe(
|
41 | 41 | umbExtensionsRegistry.byType('localization'),
|
42 |
| - (localizationManifests) => { |
43 |
| - this.#mapToOptions(localizationManifests); |
| 42 | + (manifests) => { |
| 43 | + const options = manifests |
| 44 | + .filter((manifest) => !!manifest.meta.culture) |
| 45 | + .map((manifest) => { |
| 46 | + const culture = manifest.meta.culture.toLowerCase(); |
| 47 | + return { |
| 48 | + name: this.localize.term(`uiCulture_${culture}`), |
| 49 | + value: culture, |
| 50 | + }; |
| 51 | + }); |
| 52 | + |
| 53 | + const distinct = [...new Map(options.map((item) => [item.value, item])).values()]; |
| 54 | + |
| 55 | + this._options = distinct.sort((a, b) => a.name.localeCompare(b.name)); |
44 | 56 | },
|
45 | 57 | 'umbObserveLocalizationManifests',
|
46 | 58 | );
|
47 |
| - } |
48 | 59 |
|
49 |
| - #mapToOptions(manifests: Array<ManifestLocalization>) { |
50 |
| - this._options = manifests |
51 |
| - .filter((isoCode) => isoCode !== undefined) |
52 |
| - .map((manifest) => ({ |
53 |
| - name: manifest.name, |
54 |
| - value: manifest.meta.culture.toLowerCase(), |
55 |
| - })); |
| 60 | + this.addValidator( |
| 61 | + 'customError', |
| 62 | + () => this.localize.term('user_languageNotFound', this.#invalidCulture, this.value), |
| 63 | + () => !!this.#invalidCulture && !this.#invalidBaseCulture, |
| 64 | + ); |
| 65 | + |
| 66 | + this.addValidator( |
| 67 | + 'customError', |
| 68 | + () => this.localize.term('user_languageNotFoundFallback', this.#invalidCulture, this.#invalidBaseCulture), |
| 69 | + () => !!this.#invalidCulture && !!this.#invalidBaseCulture, |
| 70 | + ); |
56 | 71 | }
|
57 | 72 |
|
58 |
| - protected override getFormElement() { |
59 |
| - return this._selectElement; |
| 73 | + protected override firstUpdated(_changedProperties: PropertyValues): void { |
| 74 | + super.firstUpdated(_changedProperties); |
| 75 | + |
| 76 | + if (this.value) { |
| 77 | + // Check if the culture can be found. |
| 78 | + const found = this._options.find((option) => option.value === this.value); |
| 79 | + if (!found) { |
| 80 | + this.#invalidCulture = this.value; |
| 81 | + |
| 82 | + // if not found, check for the base culture |
| 83 | + const locale = new Intl.Locale(this.value); |
| 84 | + if (locale.language) { |
| 85 | + const foundBase = this._options.find((option) => option.value === locale.language); |
| 86 | + if (foundBase) { |
| 87 | + this.value = locale.language; |
| 88 | + } else { |
| 89 | + // if the base culture is not found, set the value to "en" |
| 90 | + this.#invalidBaseCulture = locale.language; |
| 91 | + this.value = UMB_DEFAULT_LOCALIZATION_CULTURE; |
| 92 | + } |
| 93 | + } else { |
| 94 | + // if the base culture is not found, set the value to "en" |
| 95 | + this.value = UMB_DEFAULT_LOCALIZATION_CULTURE; |
| 96 | + } |
| 97 | + } |
| 98 | + } |
| 99 | + |
| 100 | + this.addFormControlElement(this.shadowRoot!.querySelector('uui-select')!); |
| 101 | + this.checkValidity(); |
60 | 102 | }
|
61 | 103 |
|
62 | 104 | #onCustomValidationChange(event: UUISelectEvent) {
|
| 105 | + this.#invalidCulture = undefined; |
| 106 | + this.#invalidBaseCulture = undefined; |
63 | 107 | this.value = event.target.value.toString();
|
64 | 108 | this.dispatchEvent(new UmbChangeEvent());
|
65 | 109 | }
|
66 | 110 |
|
67 | 111 | override render() {
|
68 | 112 | return html`
|
69 | 113 | <uui-select
|
70 |
| - style="margin-top: var(--uui-size-space-1)" |
71 |
| - @change=${this.#onCustomValidationChange} |
72 |
| - .options=${this._options.map((e) => ({ |
73 |
| - name: e.name, |
74 |
| - value: e.value, |
75 |
| - selected: e.value == this.value, |
76 |
| - }))}></uui-select> |
| 114 | + .options=${this._options.map((e) => ({ ...e, selected: e.value == this.value }))} |
| 115 | + @change=${this.#onCustomValidationChange}> |
| 116 | + </uui-select> |
77 | 117 | `;
|
78 | 118 | }
|
79 |
| - |
80 |
| - static override styles = [ |
81 |
| - css` |
82 |
| - :host { |
83 |
| - display: block; |
84 |
| - } |
85 |
| - `, |
86 |
| - ]; |
87 | 119 | }
|
88 | 120 |
|
89 | 121 | export default UmbUiCultureInputElement;
|
|
0 commit comments