// Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/ import type { FormKitValidationMessages } from '@formkit/validation' import { createMessageName } from '@formkit/validation' import type { FormKitLocale } from '@formkit/i18n' import { i18n } from '#shared/i18n.ts' import { commaSeparatedList, order } from '#shared/utils/formatter.ts' import type { ComputedRef } from 'vue' interface FormKitLocaleExtended extends FormKitLocale { validation: FormKitValidationMessages } // TODO: Use translateLabel for all validation messages if we stay with the labels inside of the messages. It's a open // question if we want use them inside of the messages. const loadLocales = (): FormKitLocaleExtended => { return { ui: { /** * Shown on a button for adding additional items. */ add: () => i18n.t('Add'), /** * Shown when a button to remove items is visible. */ remove: () => i18n.t('Remove'), /** * Shown when there are multiple items to remove at the same time. */ removeAll: () => i18n.t('Remove all'), /** * Shown when all fields are not filled out correctly. */ incomplete: () => i18n.t('Sorry, not all fields are filled out correctly.'), /** * Shown in a button inside a form to submit the form. */ submit: () => i18n.t('Submit'), /** * Shown when no files are selected. */ noFiles: () => i18n.t('No file chosen.'), /** * Shown on buttons that move fields up in a list. */ moveUp: () => i18n.t('Move up'), /** * Shown on buttons that move fields down in a list. */ moveDown: () => i18n.t('Move down'), /** * Shown when something is actively loading. */ isLoading: () => i18n.t('Loading…'), /** * Shown when there is more to load. */ loadMore: () => i18n.t('Load more'), /** * Show on buttons that navigate state forward */ next: () => i18n.t('Next'), /** * Show on buttons that navigate state backward */ prev: () => i18n.t('Previous'), /** * Shown when adding all values. */ addAllValues: () => i18n.t('Add all values'), /** * Shown when adding selected values. */ addSelectedValues: () => i18n.t('Add selected values'), /** * Shown when removing all values. */ removeAllValues: () => i18n.t('Remove all values'), /** * Shown when removing selected values. */ removeSelectedValues: () => i18n.t('Remove selected values'), /** * Shown when there is a date to choose. */ chooseDate: () => i18n.t('Choose date'), /** * Shown when there is a date to change. */ changeDate: () => i18n.t('Change date'), /** * Shown above error summaries when someone attempts to submit a form with * errors and the developer has implemented ``. */ summaryHeader: () => i18n.t('There were errors in your form.'), /* * Shown when there is something to close */ close: () => i18n.t('Close'), /** * Shown when there is something to open. */ open: () => i18n.t('Open'), }, validation: { /** * The value is not an accepted value. * @see {@link https://docs.formkit.com/essentials/validation#accepted} */ accepted({ name }) { /* */ return i18n.t('Please accept the %s.', name) /* */ }, /** * The value is not letter and/or spaces * @see {@link https://docs.formkit.com/essentials/validation#alpha-spaces} */ alpha_spaces() { /* */ return i18n.t('This field can only contain letters and spaces.') /* */ }, /** * The date is not after * @see {@link https://docs.formkit.com/essentials/validation#date-after} */ date_after({ args }) { if (Array.isArray(args) && args.length) { /* */ return i18n.t( 'This field must have a value that is after %s.', i18n.date(args[0]), ) /* */ } /* */ return i18n.t('This field must have a value that is in the future.') /* */ }, /** * The value is not a letter. * @see {@link https://docs.formkit.com/essentials/validation#alpha} */ alpha() { /* */ return i18n.t('This field can only contain alphabetical characters.') /* */ }, /** * The value is not alphanumeric * @see {@link https://docs.formkit.com/essentials/validation#alphanumeric} */ alphanumeric() { /* */ return i18n.t('This field can only contain letters and numbers.') /* */ }, /** * The value have no letter. * @see {@link https://formkit.com/essentials/validation#contains_alpha} */ contains_alpha() { /* */ return i18n.t('This field must contain alphabetical characters.') /* */ }, /** * The value have no alphanumeric * @see {@link https://formkit.com/essentials/validation#contains_alphanumeric} */ contains_alphanumeric() { /* */ return i18n.t('This field must contain letters or numbers.') /* */ }, /** * The value have no letter and/or spaces * @see {@link https://formkit.com/essentials/validation#contains_alpha-spaces} */ contains_alpha_spaces() { /* */ return i18n.t('This field must contain letters or spaces.') /* */ }, /** * The value have no symbol * @see {@link https://formkit.com/essentials/validation#contains_symbol} */ contains_symbol() { /* */ return i18n.t('This field must contain a symbol.') /* */ }, /** * The value have no uppercase * @see {@link https://formkit.com/essentials/validation#contains_uppercase} */ contains_uppercase() { /* */ return i18n.t('This field must contain an uppercase letter.') /* */ }, /** * The value have no lowercase * @see {@link https://formkit.com/essentials/validation#contains_lowercase} */ contains_lowercase() { /* */ return i18n.t('This field must contain a lowercase letter.') /* */ }, /** * The value have no numeric * @see {@link https://formkit.com/essentials/validation#contains_numeric} */ contains_numeric() { /* */ return i18n.t('This field must contain numbers.') /* */ }, /** * The value is not symbol * @see {@link https://formkit.com/essentials/validation#symbol} */ symbol() { /* */ return i18n.t('This field must be a symbol.') /* */ }, /** * The value is not uppercase * @see {@link https://formkit.com/essentials/validation#uppercase} */ uppercase() { /* */ return i18n.t('This field can only contain uppercase letters.') /* */ }, /** * The value is not lowercase * @see {@link https://formkit.com/essentials/validation#lowercase} */ lowercase() { /* */ return i18n.t('This field can only contain lowercase letters.') /* */ }, /** * The date is not before * @see {@link https://docs.formkit.com/essentials/validation#date-before} */ date_before({ args }) { if (Array.isArray(args) && args.length) { /* */ return i18n.t( 'This field must have a value that is before %s.', i18n.date(args[0]), ) /* */ } /* */ return i18n.t('This field must have a value that is in the past.') /* */ }, /** * The value is not between two numbers * @see {@link https://docs.formkit.com/essentials/validation#between} */ between({ args }) { if (Number.isNaN(args[0]) || Number.isNaN(args[1])) { /* */ return i18n.t( "This field was configured incorrectly and can't be submitted.", ) /* */ } const [first, second] = order(args[0], args[1]) /* */ return i18n.t( 'This field must have a value that is between %s and %s.', first, second, ) /* */ }, /** * The confirmation field does not match * @see {@link https://docs.formkit.com/essentials/validation#confirm} */ confirm() { // TODO: Check if message is in a good shape (e.g. for the usage for password + confirm password). /* */ return i18n.t("This field doesn't correspond to the expected value.") /* */ }, /** * The value is not a valid date * @see {@link https://docs.formkit.com/essentials/validation#date-format} */ date_format({ args }) { if (Array.isArray(args) && args.length) { /* */ return i18n.t( 'This field isn\'t a valid date, please use the format "%s".', args[0], ) /* */ } /* */ return i18n.t( "This field was configured incorrectly and can't be submitted.", ) /* */ }, /** * Is not within expected date range * @see {@link https://docs.formkit.com/essentials/validation#date-between} */ date_between({ args }) { /* */ return i18n.t( 'This field must have a value that is between %s and %s.', i18n.date(args[0]), i18n.date(args[1]), ) /* */ }, /** * Shown when the user-provided value is not a valid email address. * @see {@link https://docs.formkit.com/essentials/validation#email} */ email: i18n.t('Please enter a valid email address.'), /** * Does not end with the specified value * @see {@link https://docs.formkit.com/essentials/validation#ends-with} */ ends_with({ args }) { /* */ return i18n.t( 'This field doesn\'t end with "%s".', commaSeparatedList(args), ) /* */ }, /** * Is not an allowed value * @see {@link https://docs.formkit.com/essentials/validation#is} */ is() { /* */ return i18n.t("This field doesn't contain an allowed value.") /* */ }, /** * Does not match specified length * @see {@link https://docs.formkit.com/essentials/validation#length} */ length({ args: [first = 0, second = Infinity] }) { const min = Number(first) <= Number(second) ? first : second const max = Number(second) >= Number(first) ? second : first if (min === 1 && max === Infinity) { /* */ return i18n.t('This field must contain at least one character.') /* */ } if (min === 0 && max) { /* */ return i18n.t( 'This field must not contain more than %s characters.', max, ) /* */ } if (min && max === Infinity) { /* */ return i18n.t('This field must contain at least %s characters.', min) /* */ } /* */ return i18n.t( 'This field must contain between %s and %s characters.', min, max, ) /* */ }, /** * Value is not a match * @see {@link https://docs.formkit.com/essentials/validation#matches} */ matches() { /* */ return i18n.t("This field doesn't contain an allowed value.") /* */ }, /** * Exceeds maximum allowed value * @see {@link https://docs.formkit.com/essentials/validation#max} */ max({ node: { value }, args }) { if (Array.isArray(value)) { /* */ return i18n.t("This field can't have more than %s entries.", args[0]) /* */ } /* */ return i18n.t( 'This field must have a value that is at most %s.', args[0], ) /* */ }, /** * The (field-level) value does not match specified mime type * @see {@link https://docs.formkit.com/essentials/validation#mime} */ mime({ args }) { if (!args[0]) { /* */ return i18n.t('No file formats allowed.') /* */ } /* */ return i18n.t('This field must be of the type "%s".', args[0]) /* */ }, /** * Does not fulfill minimum allowed value * @see {@link https://docs.formkit.com/essentials/validation#min} */ min({ node: { value }, args }) { if (Array.isArray(value)) { /* */ return i18n.t("This field can't have less than %s entries.", args[0]) /* */ } /* */ return i18n.t( 'This field must have a value that is at least %s.', args[0], ) /* */ }, /** * Is not an allowed value * @see {@link https://docs.formkit.com/essentials/validation#not} */ not({ node: { value } }) { /* */ return i18n.t( 'This field can\'t contain the value "%s".', value as string, ) /* */ }, /** * Is not a number * @see {@link https://docs.formkit.com/essentials/validation#number} */ number() { /* */ return i18n.t('This field must contain a number.') /* */ }, /** * Required field. * @see {@link https://docs.formkit.com/essentials/validation#required} */ required() { /* */ return i18n.t('This field is required.') /* */ }, /** * Require one field. * @see {@link https://formkit.com/essentials/validation#require-one} */ require_one: ({ name, node, args: inputNames }) => { const labels = inputNames .map((name) => { const dependentNode = node.at(name) if (dependentNode) { return createMessageName(dependentNode) } return false }) .filter((name) => !!name) as unknown as ComputedRef[] labels.unshift(name as unknown as ComputedRef) /* */ // return `${labels.join(' or ')} is required.` const translatedSeparator = i18n.t('or') return i18n.t( '%s is required.', labels .map((label: ComputedRef) => label.value) .join(` ${translatedSeparator} `), ) /* */ }, /** * Does not start with specified value * @see {@link https://docs.formkit.com/essentials/validation#starts-with} */ starts_with({ args }) { /* */ return i18n.t( 'This field doesn\'t start with "%s".', commaSeparatedList(args), ) /* */ }, /** * Is not a url * @see {@link https://docs.formkit.com/essentials/validation#url} */ url() { /* */ return i18n.t('Please include a valid url.') /* */ }, /** * Shown when the date is invalid. */ invalidDate: () => i18n.t('The selected date is invalid.'), }, } } export default loadLocales