UNPKG

@react-form-builder/core

Version:

React JSON Schema Form Builder to create complex, validated, reusable forms with no deep React knowledge required

314 lines (313 loc) 10.7 kB
import { makeAutoObservable as h } from "mobx"; import { nameObservable as g } from "../utils/observableNaming.js"; import { isUndefined as u } from "../utils/tools.js"; const f = "LocalizationStore"; class m { constructor(t, e) { this.getValue = t, this.getCompatibleId = e; } getValue; getCompatibleId; initializeLanguageState(t) { const e = this.getValue(); for (const i of Object.keys(e)) t.add(i), this.#t(i) && delete e[i]; } getLocalization(t, e, i, o) { const n = this.getCompatibleId(e), a = this.getCompatibleId(i); return this.getValue()[t]?.[n]?.[o]?.[a]; } setLocalization(t, e, i, o, n) { const a = this.getCompatibleId(e), s = this.getCompatibleId(i); if (n === "") { this.#e(t, a, o, s); return; } const r = this.getValue(); r[t] ??= {}, r[t][a] ??= {}, r[t][a][o] ??= {}, r[t][a][o][s] = n; } removeLocalization(t, e) { const i = this.getCompatibleId(t); for (const o of e) { const n = this.getValue()[o]; n && (delete n[i], Object.keys(n).length === 0 && delete this.getValue()[o]); } } removeLocalizationForType(t, e, i) { const o = this.getCompatibleId(t); for (const n of i) { const a = this.getValue()[n]; a?.[o] && (delete a[o][e], Object.keys(a[o]).length === 0 && delete a[o], Object.keys(a).length === 0 && delete this.getValue()[n]); } } hasLocalization(t, e, i) { const o = this.getCompatibleId(t), n = this.getCompatibleId(e); return Object.values(this.getValue()).some((a) => !u(a?.[o]?.[i]?.[n])); } getLocalizationForComponent(t, e) { const i = this.getCompatibleId(t), o = {}; for (const n of e) { const a = this.getValue()[n]; if (!a) continue; const s = a[i]; s && (o[n] = {}, o[n][t] = s); } return o; } addLocalizationWithNewKey(t, e, i) { const o = this.getCompatibleId(i), n = Object.keys(t); for (const a of n) { const s = t[a][e]; if (!s) continue; const r = this.getValue(); r[a] ??= {}, r[a][o] = s; } } changeComponentKey(t, e, i) { const o = this.getCompatibleId(t), n = this.getCompatibleId(e); for (const a of i) { const s = this.getValue()[a]; if (!s) continue; const r = s[o]; r && (s[n] = r, delete s[o]); } } #e(t, e, i, o) { const n = this.getValue(), a = n[t], s = a?.[e], r = s?.[i]; !r || !Object.prototype.hasOwnProperty.call(r, o) || (delete r[o], Object.keys(r).length === 0 && delete s[i], s && Object.keys(s).length === 0 && delete a[e], a && Object.keys(a).length === 0 && delete n[t]); } #t(t) { const e = this.getValue()[t]; return !!e && Object.keys(e).length === 0; } } class L { constructor(t, e, i) { this.configuredLanguageCodes = t, this.hasTranslations = e, this.withTranslationsLanguageKeys = i; } configuredLanguageCodes; hasTranslations; withTranslationsLanguageKeys; findLocalizationKey(t) { const { exactConfigured: e, exactWithTranslations: i, sameCodeConfigured: o, sameCodeWithTranslations: n } = this.#n(t); return i || n || e || o || null; } hasLanguage(t) { return this.#e(t) !== null; } #e(t) { const { exactConfigured: e, sameCodeConfigured: i } = this.#n(t); return e ?? i ?? null; } #t(t) { return this.hasTranslations(t) ? t : null; } #i(t) { return this.hasTranslations(t) || this.configuredLanguageCodes.has(t) ? t : null; } #o(t, e) { const [i] = t.split("-"); for (const o of this.withTranslationsLanguageKeys()) if (o.startsWith(`${i}-`) && (!e || this.hasTranslations(o))) return o; return null; } #n(t) { const e = this.#i(t), i = this.#o(t, !1) ?? this.#a(t), o = this.#t(t), n = this.#o(t, !0); return { exactConfigured: e, sameCodeConfigured: i, exactWithTranslations: o, sameCodeWithTranslations: n }; } #a(t) { const [e] = t.split("-"); for (const i of this.configuredLanguageCodes) if (i.startsWith(`${e}-`)) return i; return null; } } class p { constructor(t, e) { this.languageFullCode = t, this.localizationStore = e, h(this, void 0, { name: g("LocalizationObservable") }); } languageFullCode; localizationStore; get items() { const t = this.localizationStore.findLocalizationKey(this.languageFullCode), e = t ? this.localizationStore.value[t] : null, { engine: i } = this.localizationStore; if (e) { const o = this.#e(e), n = i.addMessages(this.languageFullCode, o); return n.length !== 0 ? (console.error(`Unable to add localization resource: ${n}`), null) : o; } return null; } #e(t) { const e = {}, { engine: i } = this.localizationStore; return Object.entries(t).forEach(([o, n]) => { Object.entries(n ?? {}).forEach(([a, s]) => { Object.entries(s ?? {}).forEach(([r, l]) => { if (!u(l) && l !== null) { const d = `${i.getCompatibleId(o)}_${a}_${i.getCompatibleId(r)}`; e[d] = l; } }); }); }), e; } } class C { /** * Creates a new LocalizationStore instance. * @param value the initial localization value. * @param engine the localization engine to use. */ constructor(t = {}, e) { this.value = t, this.engine = e, this.repository = new m(() => this.value, this.engine.getCompatibleId.bind(this.engine)), this.resolver = new L( this.configuredLanguageCodes, this.#i.bind(this), () => Object.keys(this.value) ), this.#e(), h(this, void 0, { name: g(f) }); } value; engine; localizationCache = /* @__PURE__ */ new Map(); configuredLanguageCodes = /* @__PURE__ */ new Set(); repository; resolver; #e() { this.repository.initializeLanguageState(this.configuredLanguageCodes); } #t() { this.localizationCache.clear(); } /** * Returns value of localization constant. * @param languageFullCode the full code (en-US, en-GB etc.) of the language we are looking to localize. * @param componentKey the component we are looking to localize. * @param propertyName the property name we are looking to localize. * @param type the type of localization. * @returns the value of localization constant. */ getLocalization(t, e, i, o) { const n = this.findLocalizationKey(t) ?? t; return this.repository.getLocalization(n, e, i, o); } /** * Returns normalized localization item id for the component property. * @param componentKey the component key. * @param propertyName the component property name. * @returns normalized localization item id. */ getLocalizationItemId(t, e) { return this.engine.getCompatibleId(`${t}_${e}`); } /** * Sets localization for component property. * @param languageFullCode the full code (en-US, en-GB etc.) of the language in which localization will be set. * @param componentKey the component key that requires localization. * @param propertyName the component's property name to be localized. * @param type the type of localization. * @param value the localization value to persist. */ setLocalization(t, e, i, o, n) { this.repository.setLocalization(t, e, i, o, n), this.#t(); } /** * Removes localization for component. * @param componentKey the component key that requires localization removal. */ removeLocalization(t) { this.repository.removeLocalization(t, this.langCodes), this.#t(); } /** * Removes localization for component with specified type. * @param componentKey the component key that requires localization removal. * @param type the localization type. */ removeLocalizationForType(t, e) { this.repository.removeLocalizationForType(t, e, this.langCodes), this.#t(); } /** * Checks that the specified language exists in the localization. * Looks for exact match first, then match by language code only. * @param languageFullCode The full code (en-US, en-GB etc.) of the language to be checked. * @returns true if the specified language exists in the localization. */ hasLanguage(t) { return this.resolver.hasLanguage(t); } /** * Checks that the specified property has localization. * @param componentKey the component we are looking to localize. * @param propertyName the component's property name to be localized. * @param type the type of localization. * @returns true if the specified property has localization in at least one language. */ hasLocalization(t, e, i) { return this.repository.hasLocalization(t, e, i); } /** * Finds the best matching localization key for the given language code. * Looks for exact match first, then match by language code only. * @param languageFullCode the requested language full code. * @returns the best matching language full code or null if no match found. */ findLocalizationKey(t) { return this.resolver.findLocalizationKey(t); } #i(t) { const e = this.value[t]; return !!e && Object.keys(e).length > 0; } /** * @inheritDoc */ getItems(t) { const e = this.localizationCache.get(t) ?? new p(t, this); return this.localizationCache.has(t) || this.localizationCache.set(t, e), e.items; } /** * Changes the component key for all languages in the value object. * @param oldComponentKey the old component key to be replaced. * @param newComponentKey the new component key to replace the old component key. */ changeComponentKey(t, e) { this.repository.changeComponentKey(t, e, this.langCodes), this.#t(); } /** * Retrieves the localization values for a given component key. * @param componentKey the key of the component to retrieve localization for. * @returns the object containing the localization values for the component in each supported language. */ getLocalizationForComponent(t) { return this.repository.getLocalizationForComponent(t, this.langCodes); } /** * Inserts the localization values for a given component key. Replaces the old component key with the new component key. * @param localization the localization object for insertion. * @param oldComponentKey the old component key that needs to be replaced. * @param newComponentKey the new component key to be added. */ addLocalizationWithNewKey(t, e, i) { this.repository.addLocalizationWithNewKey(t, e, i), this.#t(); } /** * @returns the available language codes. */ get langCodes() { return [.../* @__PURE__ */ new Set([ ...Object.keys(this.value), ...this.configuredLanguageCodes ])]; } } export { C as LocalizationStore }; //# sourceMappingURL=LocalizationStore.js.map