From b092738fa50d0bbc32ba296b09c53ba763b22e0c Mon Sep 17 00:00:00 2001 From: Lone Iversen <108085781+loivsen@users.noreply.github.com> Date: Tue, 5 Sep 2023 12:14:37 +0200 Subject: [PATCH] meta object --- .../.github/CONTRIBUTING.md | 3 +-- .../.storybook/preview.js | 4 +-- .../localize.controller.test.ts | 26 +++++++++---------- .../localization-api/localize.controller.ts | 22 ++++++++-------- .../src/libs/localization-api/manager.ts | 16 ++++++------ .../models/localization.model.ts | 6 ++--- .../localization/localize.element.test.ts | 4 +-- .../registry/localization.registry.test.ts | 24 ++++++++--------- .../registry/localization.registry.ts | 18 ++++++------- ...hboard-localization-dictionary.element.ts} | 0 .../packages/dictionary/section.manifest.ts | 6 ++--- 11 files changed, 64 insertions(+), 65 deletions(-) rename src/Umbraco.Web.UI.Client/src/packages/dictionary/dashboards/dictionary/{dashboard-translation-dictionary.element.ts => dashboard-localization-dictionary.element.ts} (100%) diff --git a/src/Umbraco.Web.UI.Client/.github/CONTRIBUTING.md b/src/Umbraco.Web.UI.Client/.github/CONTRIBUTING.md index ebc40f9fef..6a340b6392 100644 --- a/src/Umbraco.Web.UI.Client/.github/CONTRIBUTING.md +++ b/src/Umbraco.Web.UI.Client/.github/CONTRIBUTING.md @@ -34,8 +34,7 @@ The frontend has an API formatter that takes the OpenAPI schema file and convert ### Caveats -1. There is currently no way to add translations. All texts in the UI are expected to be written in Umbraco’s default language of English. -2. The backoffice can be run and tested against a real Umbraco instance by cloning down the `v14/dev` branch, but there are no guarantees about how well it works yet. +1. The backoffice can be run and tested against a real Umbraco instance by cloning down the `v14/dev` branch, but there are no guarantees about how well it works yet. **Current schema for API:** diff --git a/src/Umbraco.Web.UI.Client/.storybook/preview.js b/src/Umbraco.Web.UI.Client/.storybook/preview.js index ec5ee43281..26c8b6228c 100644 --- a/src/Umbraco.Web.UI.Client/.storybook/preview.js +++ b/src/Umbraco.Web.UI.Client/.storybook/preview.js @@ -25,7 +25,7 @@ import '../src/libs/controller-api/controller-host-initializer.element.ts'; import '../src/packages/core/components'; import { manifests as documentManifests } from '../src/packages/documents'; -import { manifests as translationManifests } from '../src/packages/core/localization/manifests'; +import { manifests as localizationManifests } from '../src/packages/core/localization/manifests'; // MSW startMockServiceWorker({ serviceWorker: { url: (import.meta.env.VITE_BASE_PATH ?? '/') + 'mockServiceWorker.js' } }); @@ -39,7 +39,7 @@ class UmbStoryBookElement extends UmbLitElement { this._registerExtensions(documentManifests); this.provideContext(UMB_MODAL_CONTEXT_TOKEN, new UmbModalManagerContext(this)); - this._registerExtensions(translationManifests); + this._registerExtensions(localizationManifests); umbLocalizationRegistry.loadLanguage('en-us'); // register default language } diff --git a/src/Umbraco.Web.UI.Client/src/libs/localization-api/localize.controller.test.ts b/src/Umbraco.Web.UI.Client/src/libs/localization-api/localize.controller.test.ts index bb9b849b5f..fe57d093ef 100644 --- a/src/Umbraco.Web.UI.Client/src/libs/localization-api/localize.controller.test.ts +++ b/src/Umbraco.Web.UI.Client/src/libs/localization-api/localize.controller.test.ts @@ -1,5 +1,5 @@ import { aTimeout, elementUpdated, expect, fixture, html } from '@open-wc/testing'; -import { DefaultTranslationSet, TranslationSet, registerTranslation, translations } from './manager.js'; +import { DefaultLocalizationSet, LocalizationSet, registerLocalization, localizations } from './manager.js'; import { UmbLocalizeController } from './localize.controller.js'; import { LitElement, customElement, property } from '@umbraco-cms/backoffice/external/lit'; import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api'; @@ -10,7 +10,7 @@ class UmbLocalizeControllerHostElement extends UmbElementMixin(LitElement) { @property() lang = 'en-us'; } -interface TestTranslation extends TranslationSet { +interface TestLocalization extends LocalizationSet { close: string; logout: string; withInlineToken: any; @@ -19,8 +19,8 @@ interface TestTranslation extends TranslationSet { numUsersSelected: (count: number) => string; } -//#region Translations -const english: TestTranslation = { +//#region Localizations +const english: TestLocalization = { $code: 'en-us', $dir: 'ltr', close: 'Close', @@ -35,20 +35,20 @@ const english: TestTranslation = { }, }; -const englishOverride: DefaultTranslationSet = { +const englishOverride: DefaultLocalizationSet = { $code: 'en-us', $dir: 'ltr', close: 'Close 2', }; -const danish: DefaultTranslationSet = { +const danish: DefaultLocalizationSet = { $code: 'da', $dir: 'ltr', close: 'Luk', notOnRegional: 'Not on regional', }; -const danishRegional: DefaultTranslationSet = { +const danishRegional: DefaultLocalizationSet = { $code: 'da-dk', $dir: 'ltr', close: 'Luk', @@ -56,10 +56,10 @@ const danishRegional: DefaultTranslationSet = { //#endregion describe('UmbLocalizeController', () => { - let controller: UmbLocalizeController; + let controller: UmbLocalizeController; beforeEach(async () => { - registerTranslation(english, danish, danishRegional); + registerLocalization(english, danish, danishRegional); document.documentElement.lang = english.$code; document.documentElement.dir = english.$dir; await aTimeout(0); @@ -76,7 +76,7 @@ describe('UmbLocalizeController', () => { afterEach(() => { controller.destroy(); - translations.clear(); + localizations.clear(); }); it('should have a default language', () => { @@ -131,7 +131,7 @@ describe('UmbLocalizeController', () => { it('should override a term if new translation is registered', () => { // Let the registry load the new extension - registerTranslation(englishOverride); + registerLocalization(englishOverride); expect(controller.term('close')).to.equal('Close 2'); }); @@ -174,7 +174,7 @@ describe('UmbLocalizeController', () => { it('should return a date with a custom format', () => { expect(controller.date(new Date(2020, 11, 31), { month: 'long', day: '2-digit', year: 'numeric' })).to.equal( - 'December 31, 2020' + 'December 31, 2020', ); }); }); @@ -198,7 +198,7 @@ describe('UmbLocalizeController', () => { it('should return a number with a custom format', () => { expect(controller.number(123456.789, { minimumFractionDigits: 2, maximumFractionDigits: 2 })).to.equal( - '123,456.79' + '123,456.79', ); }); }); diff --git a/src/Umbraco.Web.UI.Client/src/libs/localization-api/localize.controller.ts b/src/Umbraco.Web.UI.Client/src/libs/localization-api/localize.controller.ts index ff20f3d29a..ee09d487b5 100644 --- a/src/Umbraco.Web.UI.Client/src/libs/localization-api/localize.controller.ts +++ b/src/Umbraco.Web.UI.Client/src/libs/localization-api/localize.controller.ts @@ -12,14 +12,14 @@ The above copyright notice and this permission notice shall be included in all c THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ import { - DefaultTranslationSet, + DefaultLocalizationSet, FunctionParams, - TranslationSet, + LocalizationSet, connectedElements, documentDirection, documentLanguage, fallback, - translations, + localizations, } from './manager.js'; import { UmbController, UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; @@ -42,7 +42,7 @@ const LocalizeControllerAlias = Symbol(); * } * ``` */ -export class UmbLocalizeController +export class UmbLocalizeController implements UmbController { #host; @@ -88,19 +88,19 @@ export class UmbLocalizeControllertranslations.get(`${language}-${region}`); - const secondary = translations.get(language); + const primary = localizations.get(`${language}-${region}`); + const secondary = localizations.get(language); return { locale, language, region, primary, secondary }; } /** Outputs a translated term. */ - term(key: K, ...args: FunctionParams): string { - const { primary, secondary } = this.getTranslationData(this.lang()); + term(key: K, ...args: FunctionParams): string { + const { primary, secondary } = this.getLocalizationData(this.lang()); let term: any; // Look for a matching term using regionCode, code, then the fallback @@ -108,8 +108,8 @@ export class UmbLocalizeController = T extends (...args: infer U) => string ? U : []; -export interface TranslationSet { +export interface LocalizationSet { $code: string; // e.g. en, en-GB $dir: 'ltr' | 'rtl'; } -export interface DefaultTranslationSet extends TranslationSet { +export interface DefaultLocalizationSet extends LocalizationSet { [key: string]: UmbLocalizationEntry; } export const connectedElements = new Set(); const documentElementObserver = new MutationObserver(update); -export const translations: Map = new Map(); +export const localizations: Map = new Map(); export let documentDirection = document.documentElement.dir || 'ltr'; export let documentLanguage = document.documentElement.lang || navigator.language; -export let fallback: TranslationSet; +export let fallback: LocalizationSet; // Watch for changes on documentElementObserver.observe(document.documentElement, { @@ -39,15 +39,15 @@ documentElementObserver.observe(document.documentElement, { }); /** Registers one or more translations */ -export function registerTranslation(...translation: TranslationSet[]) { +export function registerLocalization(...translation: LocalizationSet[]) { translation.map((t) => { const code = t.$code.toLowerCase(); - if (translations.has(code)) { + if (localizations.has(code)) { // Merge translations that share the same language code - translations.set(code, { ...translations.get(code), ...t }); + localizations.set(code, { ...localizations.get(code), ...t }); } else { - translations.set(code, t); + localizations.set(code, t); } // The first translation that's registered is the fallback diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/models/localization.model.ts b/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/models/localization.model.ts index 17265ab1d7..f1ca9eec56 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/models/localization.model.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/models/localization.model.ts @@ -20,7 +20,7 @@ export interface MetaLocalization { culture: string; /** - * @summary The direction of the translations (left-to-right or right-to-left). + * @summary The direction of the localizations (left-to-right or right-to-left). * @description * The value is used to describe the direction of the translations according to the extension system * and it will be set as the `dir` attribute on the `` element. It defaults to `ltr`. @@ -31,7 +31,7 @@ export interface MetaLocalization { direction?: 'ltr' | 'rtl'; /** - * The translations. + * The localizations. * @example * { * "general": { @@ -40,5 +40,5 @@ export interface MetaLocalization { * } * } */ - translations?: UmbLocalizationDictionary; + localizations?: UmbLocalizationDictionary; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/localization/localize.element.test.ts b/src/Umbraco.Web.UI.Client/src/packages/core/localization/localize.element.test.ts index 1f4ffd4006..3db7df5f70 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/localization/localize.element.test.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/localization/localize.element.test.ts @@ -10,7 +10,7 @@ const english = { name: 'Test English', meta: { culture: 'en', - translations: { + localizations: { general: { close: 'Close', logout: 'Log out', @@ -33,7 +33,7 @@ const danish = { name: 'Test Danish', meta: { culture: 'da', - translations: { + localizations: { general: { close: 'Luk', }, diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/localization/registry/localization.registry.test.ts b/src/Umbraco.Web.UI.Client/src/packages/core/localization/registry/localization.registry.test.ts index fab1ceb005..d198253e15 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/localization/registry/localization.registry.test.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/localization/registry/localization.registry.test.ts @@ -10,7 +10,7 @@ const english: ManifestLocalization = { meta: { culture: 'en-us', direction: 'ltr', - translations: { + localizations: { general: { close: 'Close', logout: 'Log out', @@ -32,7 +32,7 @@ const englishOverride: ManifestLocalization = { name: 'Test English', meta: { culture: 'en-us', - translations: { + localizations: { general: { close: 'Close 2', }, @@ -46,7 +46,7 @@ const danish: ManifestLocalization = { name: 'Test Danish', meta: { culture: 'da', - translations: { + localizations: { general: { close: 'Luk', notOnRegional: 'Not on regional', @@ -61,7 +61,7 @@ const danishRegional: ManifestLocalization = { name: 'Test Danish (Denmark)', meta: { culture: 'da-dk', - translations: { + localizations: { general: { close: 'Luk', }, @@ -84,7 +84,7 @@ describe('UmbLocalizeController', () => { }); afterEach(() => { - registry.translations.clear(); + registry.localizations.clear(); }); it('should set the document language and direction', async () => { @@ -93,9 +93,9 @@ describe('UmbLocalizeController', () => { }); it('should load translations for the current language', async () => { - expect(registry.translations.has(english.meta.culture)).to.be.true; + expect(registry.localizations.has(english.meta.culture)).to.be.true; - const current = registry.translations.get(english.meta.culture); + const current = registry.localizations.get(english.meta.culture); expect(current).to.have.property('general_close', 'Close'); // Also tests that the translation is flattened. expect(current).to.have.property('general_logout', 'Log out'); }); @@ -105,7 +105,7 @@ describe('UmbLocalizeController', () => { await aTimeout(0); - const current = registry.translations.get(english.meta.culture); + const current = registry.localizations.get(english.meta.culture); expect(current).to.have.property('general_close', 'Close 2'); expect(current).to.have.property('general_logout', 'Log out'); }); @@ -116,10 +116,10 @@ describe('UmbLocalizeController', () => { await aTimeout(0); // Check that the new language is loaded. - expect(registry.translations.has(danish.meta.culture)).to.be.true; + expect(registry.localizations.has(danish.meta.culture)).to.be.true; // Check that the new language has the correct translations. - const current = registry.translations.get(danish.meta.culture); + const current = registry.localizations.get(danish.meta.culture); expect(current).to.have.property('general_close', 'Luk'); }); @@ -129,7 +129,7 @@ describe('UmbLocalizeController', () => { await aTimeout(0); // Check that both the regional and the base language is loaded. - expect(registry.translations.has(danishRegional.meta.culture), 'expected "da-dk" to be present').to.be.true; - expect(registry.translations.has(danish.meta.culture), 'expected "da" to be present').to.be.true; + expect(registry.localizations.has(danishRegional.meta.culture), 'expected "da-dk" to be present').to.be.true; + expect(registry.localizations.has(danish.meta.culture), 'expected "da" to be present').to.be.true; }); }); diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/localization/registry/localization.registry.ts b/src/Umbraco.Web.UI.Client/src/packages/core/localization/registry/localization.registry.ts index 024f70c7a0..7b8b83bd24 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/localization/registry/localization.registry.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/localization/registry/localization.registry.ts @@ -1,9 +1,9 @@ import { UmbLocalizationDictionary, UmbLocalizationFlatDictionary, - TranslationSet, - registerTranslation, - translations, + LocalizationSet, + registerLocalization, + localizations, } from '@umbraco-cms/backoffice/localization-api'; import { hasDefaultExport, loadExtension } from '@umbraco-cms/backoffice/extension-api'; import { UmbBackofficeExtensionRegistry, umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; @@ -21,8 +21,8 @@ export class UmbLocalizationRegistry { /** * Get the current registered translations. */ - get translations() { - return translations; + get localizations() { + return localizations; } get isDefaultLoaded() { @@ -57,8 +57,8 @@ export class UmbLocalizationRegistry { const innerDictionary: UmbLocalizationFlatDictionary = {}; // If extension contains a dictionary, add it to the inner dictionary. - if (extension.meta.translations) { - for (const [dictionaryName, dictionary] of Object.entries(extension.meta.translations)) { + if (extension.meta.localizations) { + for (const [dictionaryName, dictionary] of Object.entries(extension.meta.localizations)) { this.#addOrUpdateDictionary(innerDictionary, dictionaryName, dictionary); } } @@ -77,12 +77,12 @@ export class UmbLocalizationRegistry { $code: extension.meta.culture.toLowerCase(), $dir: extension.meta.direction ?? 'ltr', ...innerDictionary, - } satisfies TranslationSet; + } satisfies LocalizationSet; }), ); if (translations.length) { - registerTranslation(...translations); + registerLocalization(...translations); // Set the document language const newLang = locale.baseName.toLowerCase(); diff --git a/src/Umbraco.Web.UI.Client/src/packages/dictionary/dashboards/dictionary/dashboard-translation-dictionary.element.ts b/src/Umbraco.Web.UI.Client/src/packages/dictionary/dashboards/dictionary/dashboard-localization-dictionary.element.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/dictionary/dashboards/dictionary/dashboard-translation-dictionary.element.ts rename to src/Umbraco.Web.UI.Client/src/packages/dictionary/dashboards/dictionary/dashboard-localization-dictionary.element.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/dictionary/section.manifest.ts b/src/Umbraco.Web.UI.Client/src/packages/dictionary/section.manifest.ts index 81b4ea2a8c..53f963ca62 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/dictionary/section.manifest.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/dictionary/section.manifest.ts @@ -34,10 +34,10 @@ const menuSectionSidebarApp: ManifestTypes = { const dashboards: Array = [ { type: 'dashboard', - alias: 'Umb.Dashboard.TranslationDictionary', - name: 'Dictionary Translation Dashboard', + alias: 'Umb.Dashboard.LocalizationDictionary', + name: 'Dictionary localization Dashboard', elementName: 'umb-dashboard-translation-dictionary', - loader: () => import('./dashboards/dictionary/dashboard-translation-dictionary.element.js'), + loader: () => import('./dashboards/dictionary/dashboard-localization-dictionary.element.js'), meta: { label: 'Dictionary overview', pathname: '',