-
Notifications
You must be signed in to change notification settings - Fork 381
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rework i18n support in JSON Forms core
UI strings can now be translated via special translation functions handed over to JSON Forms. Translations are automatically handed within the default mapping functions and are therefore available in all renderer sets. This includes a key-determination algorithm, allowing to either rely on using labels as keys or specifying 'i18n' keys in UI Schema options or directly within the JSON Schema. Errors are handled separately to allow for maximum flexibility. Includes test cases for the most common mapping functions. Also AJV is set to non-strict by default to not throw errors when handing over JSON Schemas containing 'i18n' keys.
- Loading branch information
Showing
22 changed files
with
947 additions
and
261 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { ErrorObject } from 'ajv'; | ||
import { JsonSchema, UISchemaElement } from '../models'; | ||
|
||
export type Translator = { | ||
(id: string, defaultMessage: string, values?: any): string; | ||
(id: string, defaultMessage: undefined, values?: any): string | undefined; | ||
} | ||
|
||
export type ErrorTranslator = (error: ErrorObject, translate: Translator, uischema?: UISchemaElement) => string; | ||
|
||
export interface JsonFormsI18nState { | ||
locale?: string; | ||
translate?: Translator; | ||
translateError?: ErrorTranslator; | ||
} | ||
|
||
export type i18nJsonSchema = JsonSchema & {i18n?: string}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
import { ErrorObject } from 'ajv'; | ||
import { UISchemaElement } from '../models'; | ||
import { formatErrorMessage } from '../util'; | ||
import { i18nJsonSchema, ErrorTranslator, Translator } from './i18nTypes'; | ||
|
||
export const getI18nKey = ( | ||
schema: i18nJsonSchema | undefined, | ||
uischema: UISchemaElement | undefined, | ||
key: string | ||
): string | undefined => { | ||
if (uischema?.options?.i18n) { | ||
return `${uischema.options.i18n}.${key}`; | ||
} | ||
if (schema?.i18n) { | ||
return `${schema.i18n}.${key}`; | ||
} | ||
return undefined; | ||
}; | ||
|
||
export const defaultTranslator: Translator = (_id: string, defaultMessage: string | undefined) => defaultMessage; | ||
|
||
export const defaultErrorTranslator: ErrorTranslator = (error, t, uischema) => { | ||
// check whether there is a special keyword message | ||
const keyInSchemas = getI18nKey( | ||
error.parentSchema, | ||
uischema, | ||
`error.${error.keyword}` | ||
); | ||
const specializedKeywordMessage = keyInSchemas && t(keyInSchemas, undefined); | ||
if (specializedKeywordMessage !== undefined) { | ||
return specializedKeywordMessage; | ||
} | ||
|
||
// check whether there is a generic keyword message | ||
const genericKeywordMessage = t(`error.${error.keyword}`, undefined); | ||
if (genericKeywordMessage !== undefined) { | ||
return genericKeywordMessage; | ||
} | ||
|
||
// check whether there is a customization for the default message | ||
const messageCustomization = t(error.message, undefined); | ||
if (messageCustomization !== undefined) { | ||
return messageCustomization; | ||
} | ||
|
||
// rewrite required property messages (if they were not customized) as we place them next to the respective input | ||
if (error.keyword === 'required') { | ||
return t('is a required property', 'is a required property'); | ||
} | ||
|
||
return error.message; | ||
}; | ||
|
||
/** | ||
* Returns the determined error message for the given errors. | ||
* All errors must correspond to the given schema and uischema. | ||
*/ | ||
export const getCombinedErrorMessage = ( | ||
errors: ErrorObject[], | ||
et: ErrorTranslator, | ||
t: Translator, | ||
schema?: i18nJsonSchema, | ||
uischema?: UISchemaElement | ||
) => { | ||
if (errors.length > 0 && t) { | ||
// check whether there is a special message which overwrites all others | ||
const keyInSchemas = getI18nKey(schema, uischema, 'error.custom'); | ||
const specializedErrorMessage = keyInSchemas && t(keyInSchemas, undefined); | ||
if (specializedErrorMessage !== undefined) { | ||
return specializedErrorMessage; | ||
} | ||
} | ||
return formatErrorMessage( | ||
errors.map(error => et(error, t, uischema)) | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from './i18nTypes'; | ||
export * from './i18nUtil'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,3 +34,4 @@ export * from './util'; | |
|
||
export * from './Helpers'; | ||
export * from './store'; | ||
export * from './i18n'; |
Oops, something went wrong.