Fix form error labels to work with intl fields

This commit is contained in:
SachaG 2018-06-30 11:48:37 +02:00
parent bb80001056
commit 35c811e791
4 changed files with 33 additions and 32 deletions

View file

@ -352,10 +352,9 @@ class SmartForm extends Component {
*/
getLabel = fieldName => {
return this.context.intl.formatMessage({
id: this.getCollection()._name + '.' + fieldName,
defaultMessage: this.state.flatSchema[fieldName].label,
});
const id = `${this.getCollection().options.collectionName.toLowerCase()}.${fieldName}`;
const defaultMessage = this.state.flatSchema[fieldName] && this.state.flatSchema[fieldName].label;
return this.context.intl.formatMessage({ id, defaultMessage });
};
// --------------------------------------------------------------------- //

View file

@ -11,6 +11,7 @@ const FormError = ({ error, errorContext, getLabel }) => error.message || (
errorContext,
label: error.properties.name && getLabel(error.properties.name),
...error.data, // backwards compatibility
// note: for intl fields, the error's label property will overwrite the getLabel label
...error.properties,
}}
defaultMessage={JSON.stringify(error)}

View file

@ -6,7 +6,7 @@ import { runCallbacks } from './callbacks.js';
import { getSetting, registerSetting } from './settings.js';
import { registerFragment, getDefaultFragmentText } from './fragments.js';
import escapeStringRegexp from 'escape-string-regexp';
import { Locales, getIntlString } from './intl';
import { validateIntlField, getIntlString } from './intl';
const wrapAsync = (Meteor.wrapAsync)? Meteor.wrapAsync : Meteor._wrapAsync;
// import { debug } from './debug.js';
@ -119,33 +119,6 @@ Mongo.Collection.prototype.helpers = function(helpers) {
});
};
/*
Custom validation function to check for required locales
See https://github.com/aldeed/simple-schema-js#custom-field-validation
*/
const validateIntlField = function () {
let errors = [];
// if field is required, go through locales to check which one are required
if (!this.definition.optional) {
const requiredLocales = Locales.filter(locale => locale.required);
requiredLocales.forEach((locale, index) => {
const strings = this.value;
const hasString = strings.some(s => s.locale === locale.id && s.value);
if (!hasString) {
errors.push({ id: 'errors.required', path: `${this.key}.${index}`, properties: { name: `${this.key.replace('_intl', '')} (${locale.id})` }});
}
});
}
// hack to work around the fact that custom validation function can only return a single string
return `intlError|${JSON.stringify(errors)}`;
}
export const createCollection = options => {
const { typeName, collectionName = getCollectionName(typeName), schema, generateGraphQLSchema = true, dbCollectionName } = options;

View file

@ -44,4 +44,32 @@ export const getIntlString = () => {
const IntlString = new SimpleSchema(schema);
IntlString.name = 'IntlString';
return IntlString;
}
/*
Custom validation function to check for required locales
See https://github.com/aldeed/simple-schema-js#custom-field-validation
*/
export const validateIntlField = function () {
let errors = [];
// if field is required, go through locales to check which one are required
if (!this.definition.optional) {
const requiredLocales = Locales.filter(locale => locale.required);
requiredLocales.forEach((locale, index) => {
const strings = this.value;
const hasString = strings.some(s => s.locale === locale.id && s.value);
const originalFieldName = this.key.replace('_intl', '');
if (!hasString) {
errors.push({ id: 'errors.required', path: `${this.key}.${index}`, properties: { name: `${originalFieldName}_${locale.id}`, label: `${originalFieldName} (${locale.id})` }});
}
});
}
// hack to work around the fact that custom validation function can only return a single string
return `intlError|${JSON.stringify(errors)}`;
}