UNPKG

admin-bro

Version:
176 lines (165 loc) 5.76 kB
import { i18n as I18n, TFunction, TOptions } from 'i18next' import startCase from 'lodash/startCase' /** * @memberof TranslateFunctions * @alias TranslateFunction */ export type TranslateFunction = ( /** * kwy which should be translated in a given namespace */ key: string, /** * Optional resourceId or [Translate options]{@link https://www.i18next.com/overview/configuration-options} */ resourceId?: string | TOptions, /** * [Translate options]{@link https://www.i18next.com/overview/configuration-options} */ options?: TOptions ) => string /** * Translate Functions are the helper functions which you can use to translate * your application. * * On the fronted they can be used with {@link useTranslation} hook. On the backend * they are injected to any {@link AdminBro} instance and {@link ActionContext}. */ export interface TranslateFunctions { /** * shortcut for I18n.translate function. * @see https://www.i18next.com/overview/api#t */ t: TFunction; /** * I18n.translate function. * @see https://www.i18next.com/overview/api#t */ translate: TFunction; /** * Shortcut for {@link TranslateFunctions#translateAction} */ ta: TranslateFunction; /** * Translates all [actions]{@link Action}, to be more specific - their labels. * By default, it looks for a [translation key]{@link LocaleTranslations} in * `resource.{resourceId}.actions.{actionName}`, when it doesn't find * that, the lookup is moved to `actions.{actionName}`. * Finally, when that also fails, it returns startCase of the action name. */ translateAction: TranslateFunction; /** * Shortcut for {@link TranslateFunctions#translateButton} */ tb: TranslateFunction; /** * Translates all buttons. * By default, it looks for a [translation key]{@link LocaleTranslations} in * `resource.{resourceId}.buttons.{actionName}`, when it doesn't find * that, the lookup is moved to `buttons.{actionName}`. * Finally, when that also fails, it returns startCase of the given button name. */ translateButton: TranslateFunction; /** * Shortcut for {@link TranslateFunctions#translateLabel} */ tl: TranslateFunction; /** * Translates all labels. Most of all all resource names are treated as labels. * Also, labels are texts in the user interface which cannot be recognized * as any other type. * By default, it looks for a [translation key]{@link LocaleTranslations} in * `resource.{resourceId}.labels.{actionName}`, when it doesn't find * that, the lookup is moved to `labels.{actionName}`. * Finally, when that also fails, it returns startCase of the given label. */ translateLabel: TranslateFunction; /** * Shortcut for {@link TranslateFunctions#translateProperty} */ tp: TranslateFunction; /** * Translates all the property names. * By default, it looks for a [translation key]{@link LocaleTranslations} in * `resource.{resourceId}.properties.{propertyPath}`, when it doesn't find * that, the lookup is moved to `properties.{propertyPath}`. When that fails, * it returns startCase of the given property name. * * What is important here is that you can put nested property as well, In that * case you have to pass dotted path: * * ```javascript * { * properties: { * parent: 'parent property', * 'parent.nested': 'nested property' * } * } * ``` */ translateProperty: TranslateFunction; /** * Shortcut for {@link TranslateFunctions#translateMessage} */ tm: TranslateFunction; /** * Translates all the messages in the application. * By default, it looks for a [translation key]{@link LocaleTranslations} in * `resource.{resourceId}.messages.{messageName}`, when it doesn't find * that, the lookup is moved to `messages.{messageName}`. * Finally, when that also fails, it returns startCase of the given message name. */ translateMessage: TranslateFunction; } export const formatName = (name: string): string => name.split('.').join('.') const translate = ( i18n: I18n, key: string, name: string, resourceId?: string | TOptions, options?: TOptions, ): string => { const realOptions: TOptions = (typeof resourceId === 'string' ? options : resourceId) || {} const formattedName = formatName(name) let keys = [`${key}.${formattedName}`] if (resourceId) { keys = [`resources.${resourceId}.${key}.${formattedName}`, ...keys] } if (i18n.exists(keys)) { return i18n.t(keys, realOptions) } return realOptions.defaultValue ?? startCase(name) } export const createFunctions = (i18n: I18n): TranslateFunctions => { const translateAction: TranslateFunction = (actionName, resourceId, options) => ( translate(i18n, 'actions', actionName as string, resourceId, options) ) const translateButton: TranslateFunction = ( buttonLabel, resourceId, options, ) => ( translate(i18n, 'buttons', buttonLabel, resourceId, options) ) const translateLabel: TranslateFunction = (label, resourceId, options) => ( translate(i18n, 'labels', label as string, resourceId, options) ) const translateProperty: TranslateFunction = (propertyName, resourceId, options) => ( translate(i18n, 'properties', propertyName, resourceId, options) ) const translateMessage: TranslateFunction = (messageName, resourceId, options) => ( translate(i18n, 'messages', messageName, resourceId, options) ) return { translateAction, ta: translateAction, translateButton, tb: translateButton, translateLabel, tl: translateLabel, translateProperty, tp: translateProperty, translateMessage, tm: translateMessage, t: i18n.t, translate: i18n.t, } }