ra-core
Version:
Core components of react-admin, a frontend Framework for building admin applications on top of REST services, using ES6, React
114 lines • 5.34 kB
JavaScript
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
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;
var react_1 = require("react");
var set_1 = __importDefault(require("lodash/set"));
var get_1 = __importDefault(require("lodash/get"));
var cloneDeep_1 = __importDefault(require("lodash/cloneDeep"));
var useLocaleState_1 = require("./useLocaleState");
/**
* 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
*/
var useTranslatable = function (options) {
var localeFromUI = (0, useLocaleState_1.useLocaleState)()[0];
var _a = options.defaultLocale, defaultLocale = _a === void 0 ? localeFromUI : _a, locales = options.locales;
var _b = (0, react_1.useState)(defaultLocale), selectedLocale = _b[0], setSelectedLocale = _b[1];
var context = (0, react_1.useMemo)(function () { return ({
locales: locales,
selectedLocale: selectedLocale,
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' }
*/
var getRecordForLocale = function (record, locale) {
if (!record) {
return record;
}
// Get all paths of the record
var 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
var recordForLocale = paths.reduce(function (acc, path) {
if (path.includes(locale)) {
var pathWithoutLocale = path.slice(0, -1);
var value = (0, get_1.default)(record, path);
return (0, set_1.default)(acc, pathWithoutLocale, value);
}
return acc;
}, (0, cloneDeep_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']]
var getRecordPaths = function (record, path) {
if (record === void 0) { record = {}; }
if (path === void 0) { path = []; }
return Object.entries(record).reduce(function (acc, _a) {
var key = _a[0], value = _a[1];
if (value !== null && typeof value === 'object') {
return __spreadArray(__spreadArray(__spreadArray([], acc, true), [
__spreadArray(__spreadArray([], path, true), [key], false)
], false), getRecordPaths(value, __spreadArray(__spreadArray([], path, true), [key], false)), true);
}
if (Array.isArray(value)) {
return value.reduce(function (acc, item, index) { return __spreadArray(__spreadArray([], acc, true), getRecordPaths(item, __spreadArray(__spreadArray([], path, true), [key, "".concat(index)], false)), true); }, acc);
}
return __spreadArray(__spreadArray([], acc, true), [__spreadArray(__spreadArray([], path, true), [key], false)], false);
}, []);
};
//# sourceMappingURL=useTranslatable.js.map
;