From 0393eb2570796dcbbb212d168680e768759cf324 Mon Sep 17 00:00:00 2001 From: James Date: Thu, 4 Jun 2020 17:28:26 -0400 Subject: [PATCH] ensures nested field server validation works as intended --- src/client/components/elements/Nav/index.scss | 4 ++-- src/client/components/forms/Form/index.js | 4 +++- .../views/collections/Edit/index.scss | 2 +- src/fields/validateCreate.js | 22 +++++++++++++++++-- src/fields/validations.js | 6 +++-- 5 files changed, 30 insertions(+), 8 deletions(-) diff --git a/src/client/components/elements/Nav/index.scss b/src/client/components/elements/Nav/index.scss index c6826ae2d1..fa59456396 100644 --- a/src/client/components/elements/Nav/index.scss +++ b/src/client/components/elements/Nav/index.scss @@ -1,6 +1,7 @@ @import '../../../scss/styles.scss'; .nav { + flex-shrink: 0; position: sticky; top: 0; left: 0; @@ -92,9 +93,8 @@ svg { opacity: 0; position: absolute; - top: 50%; left: - base(.5); - transform: translateY(-50%) rotate(-90deg); + transform: rotate(-90deg); } &:hover { diff --git a/src/client/components/forms/Form/index.js b/src/client/components/forms/Form/index.js index 40fb4709a1..e8dbc5460f 100644 --- a/src/client/components/forms/Form/index.js +++ b/src/client/components/forms/Form/index.js @@ -34,7 +34,7 @@ const Form = (props) => { const [processing, setProcessing] = useState(false); const history = useHistory(); const locale = useLocale(); - const { addStatus } = useStatusList(); + const { addStatus, clearStatus } = useStatusList(); const { refreshToken } = useUser(); const getFields = useCallback(() => { @@ -111,6 +111,8 @@ const Form = (props) => { 'Content-Type': 'application/json', }, }).then((res) => { + clearStatus(); + window.scrollTo({ top: 0, behavior: 'smooth', diff --git a/src/client/components/views/collections/Edit/index.scss b/src/client/components/views/collections/Edit/index.scss index c2aea9a51f..f0ef04574f 100644 --- a/src/client/components/views/collections/Edit/index.scss +++ b/src/client/components/views/collections/Edit/index.scss @@ -130,7 +130,7 @@ @include large-break { &__edit { - padding: base(4); + padding: base(3.5); } } diff --git a/src/fields/validateCreate.js b/src/fields/validateCreate.js index 995733ff15..7fb19ccf9b 100644 --- a/src/fields/validateCreate.js +++ b/src/fields/validateCreate.js @@ -1,11 +1,26 @@ const { ValidationError } = require('../errors'); +const findRequiredSubfields = (fields) => { + if (fields) { + return fields.some((subField) => { + if (!subField.name && subField.fields) { + return findRequiredSubfields(subField.fields); + } + + return subField.required && !subField.localized; + }); + } + + return false; +}; + exports.iterateFields = async (data, fields, path = '') => { const validationPromises = []; const validatedFields = []; fields.forEach((field) => { - const requiresAtLeastOneSubfield = field.fields && field.fields.some(subField => (subField.required && !subField.localized)); + const requiresAtLeastOneSubfield = findRequiredSubfields(field.fields); + const dataToValidate = data || {}; if (field.required || requiresAtLeastOneSubfield) { @@ -14,7 +29,10 @@ exports.iterateFields = async (data, fields, path = '') => { // validated against directly if (field.name === undefined && field.fields) { field.fields.forEach((subField) => { - validationPromises.push(subField.validate(dataToValidate[subField.name], subField)); + validationPromises.push(subField.validate(dataToValidate[subField.name], { + ...subField, + path: `${path}${subField.name}`, + })); validatedFields.push(subField); }); } else { diff --git a/src/fields/validations.js b/src/fields/validations.js index 7ef5de18a5..736c8cdbb2 100644 --- a/src/fields/validations.js +++ b/src/fields/validations.js @@ -96,7 +96,9 @@ const optionsToValidatorMap = { group: async (value, options) => { return iterateFields(value, options.fields, `${options.name}.`); }, - repeater: async (value, options) => { + repeater: async (value, options = {}) => { + const path = options.path || options.name; + if (!value || value.length === 0) { return 'This field requires at least one row.'; } @@ -105,7 +107,7 @@ const optionsToValidatorMap = { const rowPromises = []; value.forEach((row, i) => { - rowPromises.push(iterateFields(row, options.fields, `${options.name}.${i}.`)); + rowPromises.push(iterateFields(row, options.fields, `${path}.${i}.`)); }); const rowResults = await Promise.all(rowPromises);