ra-core
Version:
Core components of react-admin, a frontend Framework for building admin applications on top of REST services, using ES6, React
107 lines • 4.53 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getRecordForLocale = exports.useTranslatable = void 0;
const react_1 = require("react");
const set_js_1 = __importDefault(require("lodash/set.js"));
const get_js_1 = __importDefault(require("lodash/get.js"));
const cloneDeep_js_1 = __importDefault(require("lodash/cloneDeep.js"));
const useLocaleState_1 = require("./useLocaleState.cjs");
/**
* Hook supplying the logic to translate a field value in multiple languages.
*
* @param options The hook options
* @param {string} options.defaultLocale The locale of the default selected locale. Defaults to 'en'.
* @param {string[]} options.locales An array of the supported locales. Each is an object with a locale and a name property. For example { locale: 'en', name: 'English' }.
*
* @returns
* An object with following properties and methods:
* - selectedLocale: The locale of the currently selected locale
* - locales: An array of the supported locales
* - getLabel: A function which returns the translated label for the given field
* - getSource: A function which returns the source for the given field
* - selectLocale: A function which set the selected locale
*/
const useTranslatable = (options) => {
const [localeFromUI] = (0, useLocaleState_1.useLocaleState)();
const { defaultLocale = localeFromUI, locales } = options;
const [selectedLocale, setSelectedLocale] = (0, react_1.useState)(defaultLocale);
const context = (0, react_1.useMemo)(() => ({
locales,
selectedLocale: selectedLocale || 'en',
selectLocale: setSelectedLocale,
getRecordForLocale: exports.getRecordForLocale,
}), [locales, selectedLocale]);
return context;
};
exports.useTranslatable = useTranslatable;
/**
* Returns a record where translatable fields have their values set to the value of the given locale.
* This is necessary because the fields rely on the RecordContext to get their values and have no knowledge of the locale.
*
* Given the record { title: { en: 'title_en', fr: 'title_fr' } } and the locale 'fr',
* the record for the locale 'fr' will be { title: 'title_fr' }
*/
const getRecordForLocale = (record, locale) => {
if (!record) {
return record;
}
// Get all paths of the record
const paths = getRecordPaths(record);
// For each path, if a path ends with the locale, set the value of the path without the locale
// to the value of the path with the locale
const recordForLocale = paths.reduce((acc, path) => {
if (path.includes(locale)) {
const pathWithoutLocale = path.slice(0, -1);
const value = (0, get_js_1.default)(record, path);
return (0, set_js_1.default)(acc, pathWithoutLocale, value);
}
return acc;
}, (0, cloneDeep_js_1.default)(record));
return recordForLocale;
};
exports.getRecordForLocale = getRecordForLocale;
// Return all the possible paths of the record as an array of arrays
// For example, given the record
// {
// title: { en: 'title_en', fr: 'title_fr' },
// items: [
// { description: { en: 'item1_en', fr: 'item1_fr' } },
// { description: { en: 'item2_en', fr: 'item2_fr' } }
// ]
// },
// the paths will be
// [
// ['title'],
// ['title', 'en'],
// ['title', 'fr'],
// ['items'],
// ['items', '0'],
// ['items', '0', 'description'],
// ['items', '0', 'description', 'en'],
// ['items', '0', 'description', 'fr'],
// ['items', '1'],
// ['items', '1', 'description'],
// ['items', '1', 'description', 'en'],
// ['items', '1', 'description', 'fr']]
const getRecordPaths = (record = {}, path = []) => {
return Object.entries(record).reduce((acc, [key, value]) => {
if (value !== null && typeof value === 'object') {
return [
...acc,
[...path, key],
...getRecordPaths(value, [...path, key]),
];
}
if (Array.isArray(value)) {
return value.reduce((acc, item, index) => [
...acc,
...getRecordPaths(item, [...path, key, `${index}`]),
], acc);
}
return [...acc, [...path, key]];
}, []);
};
//# sourceMappingURL=useTranslatable.js.map