@red-hat-developer-hub/backstage-plugin-translations 0.2.1 → 0.3.0

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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @red-hat-developer-hub/backstage-plugin-translations
2
2
 
3
+ ## 0.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 36f1834: Backstage version bump to v1.49.3
8
+
9
+ ## 0.2.2
10
+
11
+ ### Patch Changes
12
+
13
+ - f6d5102: Translation added for German and Spanish
14
+
3
15
  ## 0.2.1
4
16
 
5
17
  ### Patch Changes
package/dist/alpha.d.ts CHANGED
@@ -1,9 +1,9 @@
1
- import * as _backstage_core_plugin_api_alpha from '@backstage/core-plugin-api/alpha';
1
+ import * as _backstage_frontend_plugin_api from '@backstage/frontend-plugin-api';
2
2
 
3
3
  /**
4
4
  * @alpha
5
5
  */
6
- declare const translationsPluginTranslationRef: _backstage_core_plugin_api_alpha.TranslationRef<"plugin.translations", {
6
+ declare const translationsPluginTranslationRef: _backstage_frontend_plugin_api.TranslationRef<"plugin.translations", {
7
7
  readonly "table.title": string;
8
8
  readonly "table.headers.refId": string;
9
9
  readonly "table.headers.key": string;
@@ -25,6 +25,6 @@ declare const translationsPluginTranslationRef: _backstage_core_plugin_api_alpha
25
25
  * @alpha
26
26
  *
27
27
  */
28
- declare const translationsPluginTranslations: _backstage_core_plugin_api_alpha.TranslationResource<"plugin.translations">;
28
+ declare const translationsPluginTranslations: _backstage_frontend_plugin_api.TranslationResource<"plugin.translations">;
29
29
 
30
30
  export { translationsPluginTranslationRef, translationsPluginTranslations };
@@ -16,6 +16,7 @@ class ResourceLoader {
16
16
  constructor(onLoad) {
17
17
  this.onLoad = onLoad;
18
18
  }
19
+ onLoad;
19
20
  /** Loaded resources by loader key */
20
21
  #loaded = /* @__PURE__ */ new Set();
21
22
  /** Resource loading promises by loader key */
@@ -1 +1 @@
1
- {"version":3,"file":"I18nextTranslationApi.esm.js","sources":["../../src/apis/I18nextTranslationApi.ts"],"sourcesContent":["/*\n * Copyright The Backstage Authors and Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n AppLanguageApi,\n TranslationApi,\n TranslationFunction,\n TranslationMessages,\n TranslationRef,\n TranslationResource,\n TranslationSnapshot,\n} from '@backstage/core-plugin-api/alpha';\nimport {\n createInstance as createI18n,\n FormatFunction,\n Interpolator,\n TFunction,\n type i18n as I18n,\n} from 'i18next';\nimport ObservableImpl from 'zen-observable';\n\nimport { Observable } from '@backstage/types';\nimport { createElement, Fragment, ReactNode, isValidElement } from 'react';\nimport {\n InternalTranslationRef,\n toInternalTranslationRef,\n} from './TranslationRef';\nimport {\n InternalTranslationResourceLoader,\n toInternalTranslationResource,\n} from './TranslationResource';\n\nconst DEFAULT_LANGUAGE = 'en';\n\n/** @public */\nexport interface I18nextTranslationApiOptions {\n languageApi: AppLanguageApi;\n resources?: Array<TranslationMessages | TranslationResource>;\n}\n\nfunction removeNulls(\n messages: Record<string, string | null>,\n): Record<string, string> {\n return Object.fromEntries(\n Object.entries(messages).filter(\n (e): e is [string, string] => e[1] !== null,\n ),\n );\n}\n\n/**\n * The built-in i18next backend loading logic doesn't handle on the fly switches\n * of language very well. It gets a bit confused about whether resources are actually\n * loaded or not, so instead we implement our own resource loader.\n */\nclass ResourceLoader {\n /** Loaded resources by loader key */\n #loaded = new Set<string>();\n /** Resource loading promises by loader key */\n #loading = new Map<string, Promise<void>>();\n /** Loaders for each resource language */\n #loaders = new Map<string, InternalTranslationResourceLoader>();\n\n constructor(\n private readonly onLoad: (loaded: {\n language: string;\n namespace: string;\n messages: Record<string, string | null>;\n }) => void,\n ) {}\n\n addTranslationResource(resource: TranslationResource) {\n const internalResource = toInternalTranslationResource(resource);\n for (const entry of internalResource.resources) {\n const key = this.#getLoaderKey(entry.language, internalResource.id);\n\n // First loader to register wins, this means that resources registered in the app\n // have priority over default resource from translation refs\n if (!this.#loaders.has(key)) {\n this.#loaders.set(key, entry.loader);\n }\n }\n }\n\n #getLoaderKey(language: string, namespace: string) {\n return `${language}/${namespace}`;\n }\n\n needsLoading(language: string, namespace: string) {\n const key = this.#getLoaderKey(language, namespace);\n const loader = this.#loaders.get(key);\n if (!loader) {\n return false;\n }\n\n return !this.#loaded.has(key);\n }\n\n async load(language: string, namespace: string): Promise<void> {\n const key = this.#getLoaderKey(language, namespace);\n\n const loader = this.#loaders.get(key);\n if (!loader) {\n return;\n }\n\n if (this.#loaded.has(key)) {\n return;\n }\n\n const loading = this.#loading.get(key);\n if (loading) {\n await loading;\n return;\n }\n\n const load = loader().then(\n result => {\n this.onLoad({ language, namespace, messages: result.messages });\n this.#loaded.add(key);\n },\n error => {\n this.#loaded.add(key); // Do not try to load failed resources again\n throw error;\n },\n );\n this.#loading.set(key, load);\n await load;\n }\n}\n\n/**\n * A helper for implementing JSX interpolation\n */\nexport class JsxInterpolator {\n readonly #setFormatHook: (hook: FormatFunction) => void;\n readonly #marker: string;\n readonly #pattern: RegExp;\n\n static fromI18n(i18n: I18n) {\n const interpolator = i18n.services.interpolator as Interpolator & {\n format: FormatFunction;\n };\n const originalFormat = interpolator.format;\n\n let formatHook: FormatFunction | undefined;\n\n // This is the only way to override the format function of the interpolator\n // without overriding the default formatters. See the behavior here:\n // https://github.com/i18next/i18next/blob/c633121e57e2b6024080142d78027842bf2a6e5e/src/i18next.js#L120-L125\n interpolator.format = (value, format, lng, formatOpts) => {\n if (format) {\n return originalFormat(value, format, lng, formatOpts);\n }\n return formatHook?.(value, format, lng, formatOpts) ?? value;\n };\n\n return new JsxInterpolator(\n // Using a random marker to ensure it can't be misused\n Math.random().toString(36).substring(2, 8),\n hook => {\n formatHook = hook;\n },\n );\n }\n\n private constructor(\n marker: string,\n setFormatHook: (hook: FormatFunction) => void,\n ) {\n this.#setFormatHook = setFormatHook;\n this.#marker = marker;\n this.#pattern = new RegExp(`\\\\$${marker}\\\\(([^)]+)\\\\)`);\n }\n\n wrapT<TMessages extends { [key in string]: string }>(\n originalT: TFunction,\n ): TranslationFunction<TMessages> {\n return ((key, options) => {\n let elementsMap: Map<string, ReactNode> | undefined = undefined;\n\n // There's no way to override the format hook via the translation function\n // options, event though types indicate that it might be possible.\n // Instead, override the format function hook before every invocation and\n // rely on synchronous execution.\n this.#setFormatHook(value => {\n if (isValidElement(value)) {\n if (!elementsMap) {\n elementsMap = new Map();\n }\n const elementKey = elementsMap.size.toString();\n elementsMap.set(elementKey, value);\n\n return `$${this.#marker}(${elementKey})`;\n }\n return value;\n });\n\n // Overriding the return options is not allowed via TranslationFunction,\n // so this will always be a string\n const result = originalT(key, options as any) as unknown as string;\n if (!elementsMap) {\n return result;\n }\n\n const split = result.split(this.#pattern);\n\n return createElement(\n Fragment,\n null,\n ...split\n .map((part, index) => {\n if (index % 2 === 0) {\n return part;\n }\n return elementsMap?.get(part);\n })\n .filter(Boolean),\n );\n }) as TranslationFunction<TMessages>;\n }\n}\n\n/** @public */\nexport class I18nextTranslationApi implements TranslationApi {\n static create(options: I18nextTranslationApiOptions) {\n const { languages } = options.languageApi.getAvailableLanguages();\n\n const i18n = createI18n({\n fallbackLng: DEFAULT_LANGUAGE,\n supportedLngs: languages,\n interpolation: {\n escapeValue: false,\n // Used for the JsxInterpolator format hook\n alwaysFormat: true,\n },\n ns: [],\n defaultNS: false,\n fallbackNS: false,\n\n // Disable resource loading on init, meaning i18n will be ready to use immediately\n initImmediate: false,\n });\n\n i18n.init();\n if (!i18n.isInitialized) {\n throw new Error('i18next was unexpectedly not initialized');\n }\n\n const interpolator = JsxInterpolator.fromI18n(i18n);\n\n const { language: initialLanguage } = options.languageApi.getLanguage();\n if (initialLanguage !== DEFAULT_LANGUAGE) {\n i18n.changeLanguage(initialLanguage);\n }\n\n const loader = new ResourceLoader(loaded => {\n i18n.addResourceBundle(\n loaded.language,\n loaded.namespace,\n removeNulls(loaded.messages),\n false, // do not merge with existing translations\n true, // overwrite translations\n );\n });\n\n const resources = options?.resources || [];\n // Iterate in reverse, giving higher priority to resources registered later\n for (let i = resources.length - 1; i >= 0; i--) {\n const resource = resources[i];\n if (resource.$$type === '@backstage/TranslationResource') {\n loader.addTranslationResource(resource);\n } else if (resource.$$type === '@backstage/TranslationMessages') {\n // Overrides for default messages, created with createTranslationMessages and installed via app\n i18n.addResourceBundle(\n DEFAULT_LANGUAGE,\n resource.id,\n removeNulls(resource.messages),\n true, // merge with existing translations\n false, // do not overwrite translations\n );\n }\n }\n\n const instance = new I18nextTranslationApi(\n i18n,\n loader,\n options.languageApi.getLanguage().language,\n interpolator,\n );\n\n options.languageApi.language$().subscribe(({ language }) => {\n instance.#changeLanguage(language);\n });\n\n return instance;\n }\n\n #i18n: I18n;\n #loader: ResourceLoader;\n #language: string;\n #jsxInterpolator: JsxInterpolator;\n\n /** Keep track of which refs we have registered default resources for */\n #registeredRefs = new Set<string>();\n /** Notify observers when language changes */\n #languageChangeListeners = new Set<() => void>();\n\n private constructor(\n i18n: I18n,\n loader: ResourceLoader,\n language: string,\n jsxInterpolator: JsxInterpolator,\n ) {\n this.#i18n = i18n;\n this.#loader = loader;\n this.#language = language;\n this.#jsxInterpolator = jsxInterpolator;\n }\n\n getI18nInstance(): I18n {\n return this.#i18n;\n }\n\n getTranslation<TMessages extends { [key in string]: string }>(\n translationRef: TranslationRef<string, TMessages>,\n ): TranslationSnapshot<TMessages> {\n const internalRef = toInternalTranslationRef(translationRef);\n\n this.#registerDefaults(internalRef);\n\n return this.#createSnapshot(internalRef);\n }\n\n translation$<TMessages extends { [key in string]: string }>(\n translationRef: TranslationRef<string, TMessages>,\n ): Observable<TranslationSnapshot<TMessages>> {\n const internalRef = toInternalTranslationRef(translationRef);\n\n this.#registerDefaults(internalRef);\n\n return new ObservableImpl<TranslationSnapshot<TMessages>>(subscriber => {\n let loadTicket = {}; // To check for stale loads\n\n const loadResource = () => {\n loadTicket = {};\n const ticket = loadTicket;\n this.#loader.load(this.#language, internalRef.id).then(\n () => {\n if (ticket === loadTicket) {\n const snapshot = this.#createSnapshot(internalRef);\n if (snapshot.ready) {\n subscriber.next(snapshot);\n }\n }\n },\n error => {\n if (ticket === loadTicket) {\n subscriber.error(Array.isArray(error) ? error[0] : error);\n }\n },\n );\n };\n\n const onChange = () => {\n const snapshot = this.#createSnapshot(internalRef);\n if (snapshot.ready) {\n subscriber.next(snapshot);\n } else {\n loadResource();\n }\n };\n\n if (this.#loader.needsLoading(this.#language, internalRef.id)) {\n loadResource();\n }\n\n this.#languageChangeListeners.add(onChange);\n return () => {\n this.#languageChangeListeners.delete(onChange);\n };\n });\n }\n\n #changeLanguage(language: string): void {\n if (this.#language !== language) {\n this.#language = language;\n this.#i18n.changeLanguage(language);\n this.#languageChangeListeners.forEach(listener => listener());\n }\n }\n\n #createSnapshot<TMessages extends { [key in string]: string }>(\n internalRef: InternalTranslationRef<string, TMessages>,\n ): TranslationSnapshot<TMessages> {\n if (this.#loader.needsLoading(this.#language, internalRef.id)) {\n return { ready: false };\n }\n\n const unwrappedT = this.#i18n.getFixedT(null, internalRef.id);\n const t = this.#jsxInterpolator.wrapT<TMessages>(unwrappedT);\n\n return {\n ready: true,\n t,\n };\n }\n\n #registerDefaults(internalRef: InternalTranslationRef): void {\n if (this.#registeredRefs.has(internalRef.id)) {\n return;\n }\n this.#registeredRefs.add(internalRef.id);\n\n const defaultMessages = internalRef.getDefaultMessages();\n this.#i18n.addResourceBundle(\n DEFAULT_LANGUAGE,\n internalRef.id,\n defaultMessages,\n true, // merge with existing translations\n false, // do not overwrite translations\n );\n\n const defaultResource = internalRef.getDefaultResource();\n if (defaultResource) {\n this.#loader.addTranslationResource(defaultResource);\n }\n }\n}\n"],"names":["createI18n"],"mappings":"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"}
1
+ {"version":3,"file":"I18nextTranslationApi.esm.js","sources":["../../src/apis/I18nextTranslationApi.ts"],"sourcesContent":["/*\n * Copyright The Backstage Authors and Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n AppLanguageApi,\n TranslationApi,\n TranslationFunction,\n TranslationMessages,\n TranslationRef,\n TranslationResource,\n TranslationSnapshot,\n} from '@backstage/core-plugin-api/alpha';\nimport {\n createInstance as createI18n,\n FormatFunction,\n Interpolator,\n TFunction,\n type i18n as I18n,\n} from 'i18next';\nimport ObservableImpl from 'zen-observable';\n\nimport { Observable } from '@backstage/types';\nimport { createElement, Fragment, ReactNode, isValidElement } from 'react';\nimport {\n InternalTranslationRef,\n toInternalTranslationRef,\n} from './TranslationRef';\nimport {\n InternalTranslationResourceLoader,\n toInternalTranslationResource,\n} from './TranslationResource';\n\nconst DEFAULT_LANGUAGE = 'en';\n\n/** @public */\nexport interface I18nextTranslationApiOptions {\n languageApi: AppLanguageApi;\n resources?: Array<TranslationMessages | TranslationResource>;\n}\n\nfunction removeNulls(\n messages: Record<string, string | null>,\n): Record<string, string> {\n return Object.fromEntries(\n Object.entries(messages).filter(\n (e): e is [string, string] => e[1] !== null,\n ),\n );\n}\n\n/**\n * The built-in i18next backend loading logic doesn't handle on the fly switches\n * of language very well. It gets a bit confused about whether resources are actually\n * loaded or not, so instead we implement our own resource loader.\n */\nclass ResourceLoader {\n /** Loaded resources by loader key */\n #loaded = new Set<string>();\n /** Resource loading promises by loader key */\n #loading = new Map<string, Promise<void>>();\n /** Loaders for each resource language */\n #loaders = new Map<string, InternalTranslationResourceLoader>();\n\n constructor(\n private readonly onLoad: (loaded: {\n language: string;\n namespace: string;\n messages: Record<string, string | null>;\n }) => void,\n ) {}\n\n addTranslationResource(resource: TranslationResource) {\n const internalResource = toInternalTranslationResource(resource);\n for (const entry of internalResource.resources) {\n const key = this.#getLoaderKey(entry.language, internalResource.id);\n\n // First loader to register wins, this means that resources registered in the app\n // have priority over default resource from translation refs\n if (!this.#loaders.has(key)) {\n this.#loaders.set(key, entry.loader);\n }\n }\n }\n\n #getLoaderKey(language: string, namespace: string) {\n return `${language}/${namespace}`;\n }\n\n needsLoading(language: string, namespace: string) {\n const key = this.#getLoaderKey(language, namespace);\n const loader = this.#loaders.get(key);\n if (!loader) {\n return false;\n }\n\n return !this.#loaded.has(key);\n }\n\n async load(language: string, namespace: string): Promise<void> {\n const key = this.#getLoaderKey(language, namespace);\n\n const loader = this.#loaders.get(key);\n if (!loader) {\n return;\n }\n\n if (this.#loaded.has(key)) {\n return;\n }\n\n const loading = this.#loading.get(key);\n if (loading) {\n await loading;\n return;\n }\n\n const load = loader().then(\n result => {\n this.onLoad({ language, namespace, messages: result.messages });\n this.#loaded.add(key);\n },\n error => {\n this.#loaded.add(key); // Do not try to load failed resources again\n throw error;\n },\n );\n this.#loading.set(key, load);\n await load;\n }\n}\n\n/**\n * A helper for implementing JSX interpolation\n */\nexport class JsxInterpolator {\n readonly #setFormatHook: (hook: FormatFunction) => void;\n readonly #marker: string;\n readonly #pattern: RegExp;\n\n static fromI18n(i18n: I18n) {\n const interpolator = i18n.services.interpolator as Interpolator & {\n format: FormatFunction;\n };\n const originalFormat = interpolator.format;\n\n let formatHook: FormatFunction | undefined;\n\n // This is the only way to override the format function of the interpolator\n // without overriding the default formatters. See the behavior here:\n // https://github.com/i18next/i18next/blob/c633121e57e2b6024080142d78027842bf2a6e5e/src/i18next.js#L120-L125\n interpolator.format = (value, format, lng, formatOpts) => {\n if (format) {\n return originalFormat(value, format, lng, formatOpts);\n }\n return formatHook?.(value, format, lng, formatOpts) ?? value;\n };\n\n return new JsxInterpolator(\n // Using a random marker to ensure it can't be misused\n Math.random().toString(36).substring(2, 8),\n hook => {\n formatHook = hook;\n },\n );\n }\n\n private constructor(\n marker: string,\n setFormatHook: (hook: FormatFunction) => void,\n ) {\n this.#setFormatHook = setFormatHook;\n this.#marker = marker;\n this.#pattern = new RegExp(`\\\\$${marker}\\\\(([^)]+)\\\\)`);\n }\n\n wrapT<TMessages extends { [key in string]: string }>(\n originalT: TFunction,\n ): TranslationFunction<TMessages> {\n return ((key, options) => {\n let elementsMap: Map<string, ReactNode> | undefined = undefined;\n\n // There's no way to override the format hook via the translation function\n // options, event though types indicate that it might be possible.\n // Instead, override the format function hook before every invocation and\n // rely on synchronous execution.\n this.#setFormatHook(value => {\n if (isValidElement(value)) {\n if (!elementsMap) {\n elementsMap = new Map();\n }\n const elementKey = elementsMap.size.toString();\n elementsMap.set(elementKey, value);\n\n return `$${this.#marker}(${elementKey})`;\n }\n return value;\n });\n\n // Overriding the return options is not allowed via TranslationFunction,\n // so this will always be a string\n const result = originalT(key, options as any) as unknown as string;\n if (!elementsMap) {\n return result;\n }\n\n const split = result.split(this.#pattern);\n\n return createElement(\n Fragment,\n null,\n ...split\n .map((part, index) => {\n if (index % 2 === 0) {\n return part;\n }\n return elementsMap?.get(part);\n })\n .filter(Boolean),\n );\n }) as TranslationFunction<TMessages>;\n }\n}\n\n/** @public */\nexport class I18nextTranslationApi implements TranslationApi {\n static create(options: I18nextTranslationApiOptions) {\n const { languages } = options.languageApi.getAvailableLanguages();\n\n const i18n = createI18n({\n fallbackLng: DEFAULT_LANGUAGE,\n supportedLngs: languages,\n interpolation: {\n escapeValue: false,\n // Used for the JsxInterpolator format hook\n alwaysFormat: true,\n },\n ns: [],\n defaultNS: false,\n fallbackNS: false,\n\n // Disable resource loading on init, meaning i18n will be ready to use immediately\n initImmediate: false,\n });\n\n i18n.init();\n if (!i18n.isInitialized) {\n throw new Error('i18next was unexpectedly not initialized');\n }\n\n const interpolator = JsxInterpolator.fromI18n(i18n);\n\n const { language: initialLanguage } = options.languageApi.getLanguage();\n if (initialLanguage !== DEFAULT_LANGUAGE) {\n i18n.changeLanguage(initialLanguage);\n }\n\n const loader = new ResourceLoader(loaded => {\n i18n.addResourceBundle(\n loaded.language,\n loaded.namespace,\n removeNulls(loaded.messages),\n false, // do not merge with existing translations\n true, // overwrite translations\n );\n });\n\n const resources = options?.resources || [];\n // Iterate in reverse, giving higher priority to resources registered later\n for (let i = resources.length - 1; i >= 0; i--) {\n const resource = resources[i];\n if (resource.$$type === '@backstage/TranslationResource') {\n loader.addTranslationResource(resource);\n } else if (resource.$$type === '@backstage/TranslationMessages') {\n // Overrides for default messages, created with createTranslationMessages and installed via app\n i18n.addResourceBundle(\n DEFAULT_LANGUAGE,\n resource.id,\n removeNulls(resource.messages),\n true, // merge with existing translations\n false, // do not overwrite translations\n );\n }\n }\n\n const instance = new I18nextTranslationApi(\n i18n,\n loader,\n options.languageApi.getLanguage().language,\n interpolator,\n );\n\n options.languageApi.language$().subscribe(({ language }) => {\n instance.#changeLanguage(language);\n });\n\n return instance;\n }\n\n #i18n: I18n;\n #loader: ResourceLoader;\n #language: string;\n #jsxInterpolator: JsxInterpolator;\n\n /** Keep track of which refs we have registered default resources for */\n #registeredRefs = new Set<string>();\n /** Notify observers when language changes */\n #languageChangeListeners = new Set<() => void>();\n\n private constructor(\n i18n: I18n,\n loader: ResourceLoader,\n language: string,\n jsxInterpolator: JsxInterpolator,\n ) {\n this.#i18n = i18n;\n this.#loader = loader;\n this.#language = language;\n this.#jsxInterpolator = jsxInterpolator;\n }\n\n getI18nInstance(): I18n {\n return this.#i18n;\n }\n\n getTranslation<TMessages extends { [key in string]: string }>(\n translationRef: TranslationRef<string, TMessages>,\n ): TranslationSnapshot<TMessages> {\n const internalRef = toInternalTranslationRef(translationRef);\n\n this.#registerDefaults(internalRef);\n\n return this.#createSnapshot(internalRef);\n }\n\n translation$<TMessages extends { [key in string]: string }>(\n translationRef: TranslationRef<string, TMessages>,\n ): Observable<TranslationSnapshot<TMessages>> {\n const internalRef = toInternalTranslationRef(translationRef);\n\n this.#registerDefaults(internalRef);\n\n return new ObservableImpl<TranslationSnapshot<TMessages>>(subscriber => {\n let loadTicket = {}; // To check for stale loads\n\n const loadResource = () => {\n loadTicket = {};\n const ticket = loadTicket;\n this.#loader.load(this.#language, internalRef.id).then(\n () => {\n if (ticket === loadTicket) {\n const snapshot = this.#createSnapshot(internalRef);\n if (snapshot.ready) {\n subscriber.next(snapshot);\n }\n }\n },\n error => {\n if (ticket === loadTicket) {\n subscriber.error(Array.isArray(error) ? error[0] : error);\n }\n },\n );\n };\n\n const onChange = () => {\n const snapshot = this.#createSnapshot(internalRef);\n if (snapshot.ready) {\n subscriber.next(snapshot);\n } else {\n loadResource();\n }\n };\n\n if (this.#loader.needsLoading(this.#language, internalRef.id)) {\n loadResource();\n }\n\n this.#languageChangeListeners.add(onChange);\n return () => {\n this.#languageChangeListeners.delete(onChange);\n };\n });\n }\n\n #changeLanguage(language: string): void {\n if (this.#language !== language) {\n this.#language = language;\n this.#i18n.changeLanguage(language);\n this.#languageChangeListeners.forEach(listener => listener());\n }\n }\n\n #createSnapshot<TMessages extends { [key in string]: string }>(\n internalRef: InternalTranslationRef<string, TMessages>,\n ): TranslationSnapshot<TMessages> {\n if (this.#loader.needsLoading(this.#language, internalRef.id)) {\n return { ready: false };\n }\n\n const unwrappedT = this.#i18n.getFixedT(null, internalRef.id);\n const t = this.#jsxInterpolator.wrapT<TMessages>(unwrappedT);\n\n return {\n ready: true,\n t,\n };\n }\n\n #registerDefaults(internalRef: InternalTranslationRef): void {\n if (this.#registeredRefs.has(internalRef.id)) {\n return;\n }\n this.#registeredRefs.add(internalRef.id);\n\n const defaultMessages = internalRef.getDefaultMessages();\n this.#i18n.addResourceBundle(\n DEFAULT_LANGUAGE,\n internalRef.id,\n defaultMessages,\n true, // merge with existing translations\n false, // do not overwrite translations\n );\n\n const defaultResource = internalRef.getDefaultResource();\n if (defaultResource) {\n this.#loader.addTranslationResource(defaultResource);\n }\n }\n}\n"],"names":["createI18n"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import * as _backstage_core_plugin_api_alpha from '@backstage/core-plugin-api/alpha';
2
1
  import { TranslationApi, AppLanguageApi, TranslationMessages, TranslationResource, TranslationRef, TranslationSnapshot } from '@backstage/core-plugin-api/alpha';
3
2
  import { i18n } from 'i18next';
4
3
  import { Observable } from '@backstage/types';
4
+ import * as _backstage_frontend_plugin_api from '@backstage/frontend-plugin-api';
5
5
  import * as react_jsx_runtime from 'react/jsx-runtime';
6
6
  import * as _backstage_core_plugin_api from '@backstage/core-plugin-api';
7
7
 
@@ -39,9 +39,7 @@ declare const TranslationsPage: () => react_jsx_runtime.JSX.Element;
39
39
  * @public
40
40
  */
41
41
  declare const ExportTranslationKeys: ({ resources, }: {
42
- resources: _backstage_core_plugin_api_alpha.TranslationRef<string, {
43
- [x: string]: string;
44
- }>[];
42
+ resources: _backstage_frontend_plugin_api.TranslationRef[];
45
43
  }) => react_jsx_runtime.JSX.Element;
46
44
 
47
45
  export { ExportTranslationKeys, I18nextTranslationApi, TranslationsPage, translationsPlugin };
@@ -4,19 +4,16 @@ import { translationsPluginTranslationRef } from './ref.esm.js';
4
4
  const translationsTranslationDe = createTranslationMessages({
5
5
  ref: translationsPluginTranslationRef,
6
6
  messages: {
7
- // CRITICAL: Use flat dot notation, not nested objects
8
7
  "page.title": "\xDCbersetzungen",
9
8
  "page.subtitle": "Geladene \xDCbersetzungen verwalten und anzeigen",
10
9
  "table.title": "Geladene \xDCbersetzungen ({{count}})",
11
- "table.headers.refId": "Ref-ID",
12
- "table.headers.key": "Schl\xFCssel",
13
10
  "table.options.pageSize": "Elemente pro Seite",
14
11
  "table.options.pageSizeOptions": "{{count}} Elemente anzeigen",
15
12
  "export.title": "\xDCbersetzungen",
16
- "export.downloadButton": "Standard-\xDCbersetzungen herunterladen (Englisch)",
17
- "export.filename": "\xFCbersetzungen-{{timestamp}}.json",
18
- "common.loading": "Wird geladen...",
19
- "common.error": "Ein Fehler ist aufgetreten",
13
+ "export.downloadButton": "Standard\xFCbersetzungen herunterladen (Englisch)",
14
+ "export.filename": "translations-{{timestamp}}.json",
15
+ "common.loading": "Ladevorgang l\xE4uft...",
16
+ "common.error": "Es ist ein Fehler aufgetreten",
20
17
  "common.noData": "Keine Daten verf\xFCgbar",
21
18
  "common.refresh": "Aktualisieren",
22
19
  "language.displayFormat": "{{displayName}} ({{code}})"
@@ -1 +1 @@
1
- {"version":3,"file":"de.esm.js","sources":["../../src/translations/de.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { createTranslationMessages } from '@backstage/core-plugin-api/alpha';\nimport { translationsPluginTranslationRef } from './ref';\n\nconst translationsTranslationDe = createTranslationMessages({\n ref: translationsPluginTranslationRef,\n messages: {\n // CRITICAL: Use flat dot notation, not nested objects\n 'page.title': 'Übersetzungen',\n 'page.subtitle': 'Geladene Übersetzungen verwalten und anzeigen',\n 'table.title': 'Geladene Übersetzungen ({{count}})',\n 'table.headers.refId': 'Ref-ID',\n 'table.headers.key': 'Schlüssel',\n 'table.options.pageSize': 'Elemente pro Seite',\n 'table.options.pageSizeOptions': '{{count}} Elemente anzeigen',\n 'export.title': 'Übersetzungen',\n 'export.downloadButton': 'Standard-Übersetzungen herunterladen (Englisch)',\n 'export.filename': 'übersetzungen-{{timestamp}}.json',\n 'common.loading': 'Wird geladen...',\n 'common.error': 'Ein Fehler ist aufgetreten',\n 'common.noData': 'Keine Daten verfügbar',\n 'common.refresh': 'Aktualisieren',\n 'language.displayFormat': '{{displayName}} ({{code}})',\n },\n});\n\nexport default translationsTranslationDe;\n"],"names":[],"mappings":";;;AAkBA,MAAM,4BAA4B,yBAAA,CAA0B;AAAA,EAC1D,GAAA,EAAK,gCAAA;AAAA,EACL,QAAA,EAAU;AAAA;AAAA,IAER,YAAA,EAAc,kBAAA;AAAA,IACd,eAAA,EAAiB,kDAAA;AAAA,IACjB,aAAA,EAAe,uCAAA;AAAA,IACf,qBAAA,EAAuB,QAAA;AAAA,IACvB,mBAAA,EAAqB,cAAA;AAAA,IACrB,wBAAA,EAA0B,oBAAA;AAAA,IAC1B,+BAAA,EAAiC,6BAAA;AAAA,IACjC,cAAA,EAAgB,kBAAA;AAAA,IAChB,uBAAA,EAAyB,oDAAA;AAAA,IACzB,iBAAA,EAAmB,qCAAA;AAAA,IACnB,gBAAA,EAAkB,iBAAA;AAAA,IAClB,cAAA,EAAgB,4BAAA;AAAA,IAChB,eAAA,EAAiB,0BAAA;AAAA,IACjB,gBAAA,EAAkB,eAAA;AAAA,IAClB,wBAAA,EAA0B;AAAA;AAE9B,CAAC;;;;"}
1
+ {"version":3,"file":"de.esm.js","sources":["../../src/translations/de.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { createTranslationMessages } from '@backstage/core-plugin-api/alpha';\nimport { translationsPluginTranslationRef } from './ref';\n\n/**\n * de translation for plugin.translations.\n * @public\n */\nconst translationsTranslationDe = createTranslationMessages({\n ref: translationsPluginTranslationRef,\n messages: {\n 'page.title': 'Übersetzungen',\n 'page.subtitle': 'Geladene Übersetzungen verwalten und anzeigen',\n 'table.title': 'Geladene Übersetzungen ({{count}})',\n 'table.options.pageSize': 'Elemente pro Seite',\n 'table.options.pageSizeOptions': '{{count}} Elemente anzeigen',\n 'export.title': 'Übersetzungen',\n 'export.downloadButton': 'Standardübersetzungen herunterladen (Englisch)',\n 'export.filename': 'translations-{{timestamp}}.json',\n 'common.loading': 'Ladevorgang läuft...',\n 'common.error': 'Es ist ein Fehler aufgetreten',\n 'common.noData': 'Keine Daten verfügbar',\n 'common.refresh': 'Aktualisieren',\n 'language.displayFormat': '{{displayName}} ({{code}})',\n },\n});\n\nexport default translationsTranslationDe;\n"],"names":[],"mappings":";;;AAuBA,MAAM,4BAA4B,yBAAA,CAA0B;AAAA,EAC1D,GAAA,EAAK,gCAAA;AAAA,EACL,QAAA,EAAU;AAAA,IACR,YAAA,EAAc,kBAAA;AAAA,IACd,eAAA,EAAiB,kDAAA;AAAA,IACjB,aAAA,EAAe,uCAAA;AAAA,IACf,wBAAA,EAA0B,oBAAA;AAAA,IAC1B,+BAAA,EAAiC,6BAAA;AAAA,IACjC,cAAA,EAAgB,kBAAA;AAAA,IAChB,uBAAA,EAAyB,mDAAA;AAAA,IACzB,iBAAA,EAAmB,iCAAA;AAAA,IACnB,gBAAA,EAAkB,yBAAA;AAAA,IAClB,cAAA,EAAgB,+BAAA;AAAA,IAChB,eAAA,EAAiB,0BAAA;AAAA,IACjB,gBAAA,EAAkB,eAAA;AAAA,IAClB,wBAAA,EAA0B;AAAA;AAE9B,CAAC;;;;"}
@@ -4,17 +4,14 @@ import { translationsPluginTranslationRef } from './ref.esm.js';
4
4
  const translationsTranslationEs = createTranslationMessages({
5
5
  ref: translationsPluginTranslationRef,
6
6
  messages: {
7
- // CRITICAL: Use flat dot notation, not nested objects
8
7
  "page.title": "Traducciones",
9
- "page.subtitle": "Gestionar y ver traducciones cargadas",
8
+ "page.subtitle": "Gestionar y visualizar las traducciones cargadas",
10
9
  "table.title": "Traducciones cargadas ({{count}})",
11
- "table.headers.refId": "ID de referencia",
12
- "table.headers.key": "Clave",
13
10
  "table.options.pageSize": "Elementos por p\xE1gina",
14
- "table.options.pageSizeOptions": "Mostrar {{count}} elementos",
11
+ "table.options.pageSizeOptions": "Mostrar {{count}}\xA0elementos",
15
12
  "export.title": "Traducciones",
16
- "export.downloadButton": "Descargar traducciones por defecto (Ingl\xE9s)",
17
- "export.filename": "traducciones-{{timestamp}}.json",
13
+ "export.downloadButton": "Descargar traducciones predeterminadas (ingl\xE9s)",
14
+ "export.filename": "translations-{{timestamp}}.json",
18
15
  "common.loading": "Cargando...",
19
16
  "common.error": "Ocurri\xF3 un error",
20
17
  "common.noData": "No hay datos disponibles",
@@ -1 +1 @@
1
- {"version":3,"file":"es.esm.js","sources":["../../src/translations/es.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { createTranslationMessages } from '@backstage/core-plugin-api/alpha';\nimport { translationsPluginTranslationRef } from './ref';\n\nconst translationsTranslationEs = createTranslationMessages({\n ref: translationsPluginTranslationRef,\n messages: {\n // CRITICAL: Use flat dot notation, not nested objects\n 'page.title': 'Traducciones',\n 'page.subtitle': 'Gestionar y ver traducciones cargadas',\n 'table.title': 'Traducciones cargadas ({{count}})',\n 'table.headers.refId': 'ID de referencia',\n 'table.headers.key': 'Clave',\n 'table.options.pageSize': 'Elementos por página',\n 'table.options.pageSizeOptions': 'Mostrar {{count}} elementos',\n 'export.title': 'Traducciones',\n 'export.downloadButton': 'Descargar traducciones por defecto (Inglés)',\n 'export.filename': 'traducciones-{{timestamp}}.json',\n 'common.loading': 'Cargando...',\n 'common.error': 'Ocurrió un error',\n 'common.noData': 'No hay datos disponibles',\n 'common.refresh': 'Actualizar',\n 'language.displayFormat': '{{displayName}} ({{code}})',\n },\n});\n\nexport default translationsTranslationEs;\n"],"names":[],"mappings":";;;AAkBA,MAAM,4BAA4B,yBAAA,CAA0B;AAAA,EAC1D,GAAA,EAAK,gCAAA;AAAA,EACL,QAAA,EAAU;AAAA;AAAA,IAER,YAAA,EAAc,cAAA;AAAA,IACd,eAAA,EAAiB,uCAAA;AAAA,IACjB,aAAA,EAAe,mCAAA;AAAA,IACf,qBAAA,EAAuB,kBAAA;AAAA,IACvB,mBAAA,EAAqB,OAAA;AAAA,IACrB,wBAAA,EAA0B,yBAAA;AAAA,IAC1B,+BAAA,EAAiC,6BAAA;AAAA,IACjC,cAAA,EAAgB,cAAA;AAAA,IAChB,uBAAA,EAAyB,gDAAA;AAAA,IACzB,iBAAA,EAAmB,iCAAA;AAAA,IACnB,gBAAA,EAAkB,aAAA;AAAA,IAClB,cAAA,EAAgB,qBAAA;AAAA,IAChB,eAAA,EAAiB,0BAAA;AAAA,IACjB,gBAAA,EAAkB,YAAA;AAAA,IAClB,wBAAA,EAA0B;AAAA;AAE9B,CAAC;;;;"}
1
+ {"version":3,"file":"es.esm.js","sources":["../../src/translations/es.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { createTranslationMessages } from '@backstage/core-plugin-api/alpha';\nimport { translationsPluginTranslationRef } from './ref';\n\n/**\n * es translation for plugin.translations.\n * @public\n */\nconst translationsTranslationEs = createTranslationMessages({\n ref: translationsPluginTranslationRef,\n messages: {\n 'page.title': 'Traducciones',\n 'page.subtitle': 'Gestionar y visualizar las traducciones cargadas',\n 'table.title': 'Traducciones cargadas ({{count}})',\n 'table.options.pageSize': 'Elementos por página',\n 'table.options.pageSizeOptions': 'Mostrar {{count}} elementos',\n 'export.title': 'Traducciones',\n 'export.downloadButton': 'Descargar traducciones predeterminadas (inglés)',\n 'export.filename': 'translations-{{timestamp}}.json',\n 'common.loading': 'Cargando...',\n 'common.error': 'Ocurrió un error',\n 'common.noData': 'No hay datos disponibles',\n 'common.refresh': 'Actualizar',\n 'language.displayFormat': '{{displayName}} ({{code}})',\n },\n});\n\nexport default translationsTranslationEs;\n"],"names":[],"mappings":";;;AAuBA,MAAM,4BAA4B,yBAAA,CAA0B;AAAA,EAC1D,GAAA,EAAK,gCAAA;AAAA,EACL,QAAA,EAAU;AAAA,IACR,YAAA,EAAc,cAAA;AAAA,IACd,eAAA,EAAiB,kDAAA;AAAA,IACjB,aAAA,EAAe,mCAAA;AAAA,IACf,wBAAA,EAA0B,yBAAA;AAAA,IAC1B,+BAAA,EAAiC,gCAAA;AAAA,IACjC,cAAA,EAAgB,cAAA;AAAA,IAChB,uBAAA,EAAyB,oDAAA;AAAA,IACzB,iBAAA,EAAmB,iCAAA;AAAA,IACnB,gBAAA,EAAkB,aAAA;AAAA,IAClB,cAAA,EAAgB,qBAAA;AAAA,IAChB,eAAA,EAAiB,0BAAA;AAAA,IACjB,gBAAA,EAAkB,YAAA;AAAA,IAClB,wBAAA,EAA0B;AAAA;AAE9B,CAAC;;;;"}
@@ -4,17 +4,16 @@ import { translationsPluginTranslationRef } from './ref.esm.js';
4
4
  const translationsTranslationIt = createTranslationMessages({
5
5
  ref: translationsPluginTranslationRef,
6
6
  messages: {
7
- // CRITICAL: Use flat dot notation, not nested objects
8
7
  "page.title": "Traduzioni",
9
- "page.subtitle": "Gestisci e visualizza le traduzioni caricate",
8
+ "page.subtitle": "Gestione e visualizzazione delle traduzioni caricate",
10
9
  "table.title": "Traduzioni caricate ({{count}})",
11
10
  "table.headers.refId": "ID di riferimento",
12
11
  "table.headers.key": "Chiave",
13
12
  "table.options.pageSize": "Elementi per pagina",
14
13
  "table.options.pageSizeOptions": "Mostra {{count}} elementi",
15
14
  "export.title": "Traduzioni",
16
- "export.downloadButton": "Scarica traduzioni predefinite (Inglese)",
17
- "export.filename": "traduzioni-{{timestamp}}.json",
15
+ "export.downloadButton": "Scarica le traduzioni predefinite (italiano)",
16
+ "export.filename": "translations-{{timestamp}}.json",
18
17
  "common.loading": "Caricamento...",
19
18
  "common.error": "Si \xE8 verificato un errore",
20
19
  "common.noData": "Nessun dato disponibile",
@@ -1 +1 @@
1
- {"version":3,"file":"it.esm.js","sources":["../../src/translations/it.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { createTranslationMessages } from '@backstage/core-plugin-api/alpha';\nimport { translationsPluginTranslationRef } from './ref';\n\n/**\n * Italian translation for plugin.translations.\n * @public\n */\nconst translationsTranslationIt = createTranslationMessages({\n ref: translationsPluginTranslationRef,\n messages: {\n // CRITICAL: Use flat dot notation, not nested objects\n 'page.title': 'Traduzioni',\n 'page.subtitle': 'Gestisci e visualizza le traduzioni caricate',\n 'table.title': 'Traduzioni caricate ({{count}})',\n 'table.headers.refId': 'ID di riferimento',\n 'table.headers.key': 'Chiave',\n 'table.options.pageSize': 'Elementi per pagina',\n 'table.options.pageSizeOptions': 'Mostra {{count}} elementi',\n 'export.title': 'Traduzioni',\n 'export.downloadButton': 'Scarica traduzioni predefinite (Inglese)',\n 'export.filename': 'traduzioni-{{timestamp}}.json',\n 'common.loading': 'Caricamento...',\n 'common.error': 'Si è verificato un errore',\n 'common.noData': 'Nessun dato disponibile',\n 'common.refresh': 'Aggiorna',\n 'language.displayFormat': '{{displayName}} ({{code}})',\n },\n});\n\nexport default translationsTranslationIt;\n"],"names":[],"mappings":";;;AAsBA,MAAM,4BAA4B,yBAAA,CAA0B;AAAA,EAC1D,GAAA,EAAK,gCAAA;AAAA,EACL,QAAA,EAAU;AAAA;AAAA,IAER,YAAA,EAAc,YAAA;AAAA,IACd,eAAA,EAAiB,8CAAA;AAAA,IACjB,aAAA,EAAe,iCAAA;AAAA,IACf,qBAAA,EAAuB,mBAAA;AAAA,IACvB,mBAAA,EAAqB,QAAA;AAAA,IACrB,wBAAA,EAA0B,qBAAA;AAAA,IAC1B,+BAAA,EAAiC,2BAAA;AAAA,IACjC,cAAA,EAAgB,YAAA;AAAA,IAChB,uBAAA,EAAyB,0CAAA;AAAA,IACzB,iBAAA,EAAmB,+BAAA;AAAA,IACnB,gBAAA,EAAkB,gBAAA;AAAA,IAClB,cAAA,EAAgB,8BAAA;AAAA,IAChB,eAAA,EAAiB,yBAAA;AAAA,IACjB,gBAAA,EAAkB,UAAA;AAAA,IAClB,wBAAA,EAA0B;AAAA;AAE9B,CAAC;;;;"}
1
+ {"version":3,"file":"it.esm.js","sources":["../../src/translations/it.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { createTranslationMessages } from '@backstage/core-plugin-api/alpha';\nimport { translationsPluginTranslationRef } from './ref';\n\n/**\n * Italian translation for translations.\n * @public\n */\nconst translationsTranslationIt = createTranslationMessages({\n ref: translationsPluginTranslationRef,\n messages: {\n 'page.title': 'Traduzioni',\n 'page.subtitle': 'Gestione e visualizzazione delle traduzioni caricate',\n 'table.title': 'Traduzioni caricate ({{count}})',\n 'table.headers.refId': 'ID di riferimento',\n 'table.headers.key': 'Chiave',\n 'table.options.pageSize': 'Elementi per pagina',\n 'table.options.pageSizeOptions': 'Mostra {{count}} elementi',\n 'export.title': 'Traduzioni',\n 'export.downloadButton': 'Scarica le traduzioni predefinite (italiano)',\n 'export.filename': 'translations-{{timestamp}}.json',\n 'common.loading': 'Caricamento...',\n 'common.error': 'Si è verificato un errore',\n 'common.noData': 'Nessun dato disponibile',\n 'common.refresh': 'Aggiorna',\n 'language.displayFormat': '{{displayName}} ({{code}})',\n },\n});\n\nexport default translationsTranslationIt;\n"],"names":[],"mappings":";;;AAuBA,MAAM,4BAA4B,yBAAA,CAA0B;AAAA,EAC1D,GAAA,EAAK,gCAAA;AAAA,EACL,QAAA,EAAU;AAAA,IACR,YAAA,EAAc,YAAA;AAAA,IACd,eAAA,EAAiB,sDAAA;AAAA,IACjB,aAAA,EAAe,iCAAA;AAAA,IACf,qBAAA,EAAuB,mBAAA;AAAA,IACvB,mBAAA,EAAqB,QAAA;AAAA,IACrB,wBAAA,EAA0B,qBAAA;AAAA,IAC1B,+BAAA,EAAiC,2BAAA;AAAA,IACjC,cAAA,EAAgB,YAAA;AAAA,IAChB,uBAAA,EAAyB,8CAAA;AAAA,IACzB,iBAAA,EAAmB,iCAAA;AAAA,IACnB,gBAAA,EAAkB,gBAAA;AAAA,IAClB,cAAA,EAAgB,8BAAA;AAAA,IAChB,eAAA,EAAiB,yBAAA;AAAA,IACjB,gBAAA,EAAkB,UAAA;AAAA,IAClB,wBAAA,EAA0B;AAAA;AAE9B,CAAC;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"ja.esm.js","sources":["../../src/translations/ja.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { createTranslationMessages } from '@backstage/core-plugin-api/alpha';\nimport { translationsPluginTranslationRef } from './ref';\n\n/**\n * Japanese translation for plugin.translations.\n * @public\n */\nconst translationsTranslationJa = createTranslationMessages({\n ref: translationsPluginTranslationRef,\n messages: {\n 'page.title': '翻訳',\n 'page.subtitle': '読み込まれた翻訳の管理および表示',\n 'table.title': '読み込まれた翻訳 ({{count}})',\n 'table.headers.refId': '参照 ID',\n 'table.headers.key': 'キー',\n 'table.options.pageSize': '1 ページの項目数',\n 'table.options.pageSizeOptions': '{{count}} 件の項目を表示',\n 'export.title': '翻訳',\n 'export.downloadButton': 'デフォルトの翻訳のダウンロード (英語)',\n 'export.filename': 'translations-{{timestamp}}.json',\n 'common.loading': '読み込み中...',\n 'common.error': 'エラーが発生しました',\n 'common.noData': '利用可能なデータはありません',\n 'common.refresh': '更新',\n 'language.displayFormat': '{{displayName}} ({{code}})',\n },\n});\n\nexport default translationsTranslationJa;\n"],"names":[],"mappings":";;;AAuBA,MAAM,4BAA4B,yBAAA,CAA0B;AAAA,EAC1D,GAAA,EAAK,gCAAA;AAAA,EACL,QAAA,EAAU;AAAA,IACR,YAAA,EAAc,cAAA;AAAA,IACd,eAAA,EAAiB,kGAAA;AAAA,IACjB,aAAA,EAAe,8DAAA;AAAA,IACf,qBAAA,EAAuB,iBAAA;AAAA,IACvB,mBAAA,EAAqB,cAAA;AAAA,IACrB,wBAAA,EAA0B,8CAAA;AAAA,IAC1B,+BAAA,EAAiC,sDAAA;AAAA,IACjC,cAAA,EAAgB,cAAA;AAAA,IAChB,uBAAA,EAAyB,2GAAA;AAAA,IACzB,iBAAA,EAAmB,iCAAA;AAAA,IACnB,gBAAA,EAAkB,mCAAA;AAAA,IAClB,cAAA,EAAgB,8DAAA;AAAA,IAChB,eAAA,EAAiB,sFAAA;AAAA,IACjB,gBAAA,EAAkB,cAAA;AAAA,IAClB,wBAAA,EAA0B;AAAA;AAE9B,CAAC;;;;"}
1
+ {"version":3,"file":"ja.esm.js","sources":["../../src/translations/ja.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { createTranslationMessages } from '@backstage/core-plugin-api/alpha';\nimport { translationsPluginTranslationRef } from './ref';\n\n/**\n * Japanese translation for translations.\n * @public\n */\nconst translationsTranslationJa = createTranslationMessages({\n ref: translationsPluginTranslationRef,\n messages: {\n 'page.title': '翻訳',\n 'page.subtitle': '読み込まれた翻訳の管理および表示',\n 'table.title': '読み込まれた翻訳 ({{count}})',\n 'table.headers.refId': '参照 ID',\n 'table.headers.key': 'キー',\n 'table.options.pageSize': '1 ページの項目数',\n 'table.options.pageSizeOptions': '{{count}} 件の項目を表示',\n 'export.title': '翻訳',\n 'export.downloadButton': 'デフォルトの翻訳のダウンロード (英語)',\n 'export.filename': 'translations-{{timestamp}}.json',\n 'common.loading': '読み込み中...',\n 'common.error': 'エラーが発生しました',\n 'common.noData': '利用可能なデータはありません',\n 'common.refresh': '更新',\n 'language.displayFormat': '{{displayName}} ({{code}})',\n },\n});\n\nexport default translationsTranslationJa;\n"],"names":[],"mappings":";;;AAuBA,MAAM,4BAA4B,yBAAA,CAA0B;AAAA,EAC1D,GAAA,EAAK,gCAAA;AAAA,EACL,QAAA,EAAU;AAAA,IACR,YAAA,EAAc,cAAA;AAAA,IACd,eAAA,EAAiB,kGAAA;AAAA,IACjB,aAAA,EAAe,8DAAA;AAAA,IACf,qBAAA,EAAuB,iBAAA;AAAA,IACvB,mBAAA,EAAqB,cAAA;AAAA,IACrB,wBAAA,EAA0B,8CAAA;AAAA,IAC1B,+BAAA,EAAiC,sDAAA;AAAA,IACjC,cAAA,EAAgB,cAAA;AAAA,IAChB,uBAAA,EAAyB,2GAAA;AAAA,IACzB,iBAAA,EAAmB,iCAAA;AAAA,IACnB,gBAAA,EAAkB,mCAAA;AAAA,IAClB,cAAA,EAAgB,8DAAA;AAAA,IAChB,eAAA,EAAiB,sFAAA;AAAA,IACjB,gBAAA,EAAkB,cAAA;AAAA,IAClB,wBAAA,EAA0B;AAAA;AAE9B,CAAC;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@red-hat-developer-hub/backstage-plugin-translations",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "license": "Apache-2.0",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -54,10 +54,10 @@
54
54
  "postpack": "backstage-cli package postpack"
55
55
  },
56
56
  "dependencies": {
57
- "@backstage/core-components": "^0.18.3",
58
- "@backstage/core-plugin-api": "^1.12.0",
59
- "@backstage/plugin-user-settings": "^0.8.29",
60
- "@backstage/theme": "^0.7.0",
57
+ "@backstage/core-components": "^0.18.8",
58
+ "@backstage/core-plugin-api": "^1.12.4",
59
+ "@backstage/plugin-user-settings": "^0.9.1",
60
+ "@backstage/theme": "^0.7.2",
61
61
  "@backstage/types": "^1.2.2",
62
62
  "@mui/icons-material": "5.18.0",
63
63
  "@mui/material": "5.18.0",
@@ -68,10 +68,10 @@
68
68
  "react": "^16.13.1 || ^17.0.0 || ^18.0.0"
69
69
  },
70
70
  "devDependencies": {
71
- "@backstage/cli": "^0.34.5",
72
- "@backstage/core-app-api": "^1.19.2",
73
- "@backstage/dev-utils": "^1.1.17",
74
- "@backstage/test-utils": "^1.7.13",
71
+ "@backstage/cli": "^0.36.0",
72
+ "@backstage/core-app-api": "^1.19.6",
73
+ "@backstage/dev-utils": "^1.1.21",
74
+ "@backstage/test-utils": "^1.7.16",
75
75
  "@testing-library/jest-dom": "^6.0.0",
76
76
  "@testing-library/react": "^14.0.0",
77
77
  "@testing-library/user-event": "^14.0.0",