diff --git a/CHANGELOG.md b/CHANGELOG.md index 8805af3..fc496c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,17 +1,18 @@ ## 1.0.14 (unreleased) ----------------------- -- Nothing changed yet. +--- +- Update to Volto 16.25.0 [davisagli] ## 1.0.13 (2023-10-09) ------------------------- + +--- - Add randomnmess to sponsors block variaion listing [pbauer] + 1.0.12.dev0 (2023-09-18) -1.0.12.dev0 (2023-09-18) ------------------------- +--- - Update GHA workflow actions to latest versions [fredvd] @@ -25,24 +26,28 @@ - Add github_username and portrait fields to user schema (Closed #125) + 1.0.3 (2023-03-23) + +--- -1.0.3 (2023-03-23) ------------------- - Update footer links (Closed #39) [fredvd] + 1.0.2 (2023-03-21) + +--- -1.0.2 (2023-03-21) ------------------- - Fix workflow for tag deploy [fredvd] + 1.0.1 (2023-03-21) + +--- -1.0.1 (2023-03-21) ------------------- - Test first tag live deployment. [fredvd] - Update to Plone 6.0.2 [fredvd] + 1.0 (2022-10-140 + +--- -1.0 (2022-10-140 ----------------- - Initial version [plone] diff --git a/backend/src/ploneorg/src/ploneorg/content/foundationsponsor.py b/backend/src/ploneorg/src/ploneorg/content/foundationsponsor.py index 4dfd207..0560d8c 100644 --- a/backend/src/ploneorg/src/ploneorg/content/foundationsponsor.py +++ b/backend/src/ploneorg/src/ploneorg/content/foundationsponsor.py @@ -178,7 +178,6 @@ class IFoundationSponsor(Schema): country = schema.Choice( title=_PMF("Country", default="Country"), vocabulary="ploneorg.vocabulary.countries", - default="USA", required=True, ) diff --git a/frontend/package.json b/frontend/package.json index 04b3e26..b7bed6a 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -159,7 +159,7 @@ "@kitconcept/volto-blocks-grid": "^5.2.0", "@kitconcept/volto-slider-block": "^4.0.0", "@plone-collective/volto-authomatic": "1.3.0", - "@plone/volto": "16.19.0", + "@plone/volto": "16.25.0", "react-slick": "0.28.1", "slick-carousel": "1.8.1", "volto-dropdownmenu": "2.4.3", diff --git a/frontend/src/customizations/volto/helpers/FormValidation/FormValidation.js b/frontend/src/customizations/volto/helpers/FormValidation/FormValidation.js index ef2057f..9254f71 100644 --- a/frontend/src/customizations/volto/helpers/FormValidation/FormValidation.js +++ b/frontend/src/customizations/volto/helpers/FormValidation/FormValidation.js @@ -4,31 +4,36 @@ */ import { map, uniq, keys, intersection, isEmpty } from 'lodash'; import { messages } from '@plone/volto/helpers/MessageLabels/MessageLabels'; +import config from '@plone/volto/registry'; +import { toast } from 'react-toastify'; +import Toast from '@plone/volto/components/manage/Toast/Toast'; /** * Will return the intl message if invalid * @param {boolean} isValid - * @param {string} maxCriterion + * @param {string} criterion * @param {string | number} valueToCompare can compare '47' < 50 * @param {Function} intlFunc */ -const validationMessage = (isValid, maxCriterion, valueToCompare, intlFunc) => +const validationMessage = (isValid, criterion, valueToCompare, intlFunc) => !isValid - ? intlFunc(messages[maxCriterion], { + ? intlFunc(messages[criterion], { len: valueToCompare, }) : null; + /** * Returns if based on the criterion the value is lower or equal * @param {string | number} value can compare '47' < 50 * @param {string | number} valueToCompare can compare '47' < 50 - * @param {string} minCriterion + * @param {string} maxCriterion * @param {Function} intlFunc */ -const isMaxPropertyValid = (value, valueToCompare, minCriterion, intlFunc) => { +const isMaxPropertyValid = (value, valueToCompare, maxCriterion, intlFunc) => { const isValid = valueToCompare !== undefined ? value <= valueToCompare : true; - return validationMessage(isValid, minCriterion, valueToCompare, intlFunc); + return validationMessage(isValid, maxCriterion, valueToCompare, intlFunc); }; + /** * Returns if based on the criterion the value is higher or equal * @param {string | number} value can compare '47' < 50 @@ -36,15 +41,17 @@ const isMaxPropertyValid = (value, valueToCompare, minCriterion, intlFunc) => { * @param {string} minCriterion * @param {Function} intlFunc */ -const isMinPropertyValid = (value, valueToCompare, maxCriterion, intlFunc) => { +const isMinPropertyValid = (value, valueToCompare, minCriterion, intlFunc) => { const isValid = valueToCompare !== undefined ? value >= valueToCompare : true; - return validationMessage(isValid, maxCriterion, valueToCompare, intlFunc); + return validationMessage(isValid, minCriterion, valueToCompare, intlFunc); }; const widgetValidation = { email: { isValidEmail: (emailValue, emailObj, intlFunc) => { - const emailRegex = /^\w+([.-]?\w+)*@\w+([.-]?\w+)*(\.\w{2,3})+$/; + // Email Regex taken from from WHATWG living standard: + // https://html.spec.whatwg.org/multipage/input.html#e-mail-state-(type=email) + const emailRegex = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/; const isValid = emailRegex.test(emailValue); return !isValid ? intlFunc(messages.isValidEmail) : null; }, @@ -65,7 +72,16 @@ const widgetValidation = { }, url: { isValidURL: (urlValue, urlObj, intlFunc) => { - const urlRegex = /^(http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/)?[a-z0-9]+([-.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?|^(http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/)?[a-z0-9]+([_.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?|^((http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/)?([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/gm; + var urlRegex = new RegExp( + '^(https?:\\/\\/)?' + // validate protocol + '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|' + // validate domain name + '((\\d{1,3}\\.){3}\\d{1,3}))|' + // validate OR ip (v4) address + '(localhost)' + // validate OR localhost address + '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*' + // validate port and path + '(\\?[;&a-z\\d%_.~+=-]*)?' + // validate query string + '(\\#[-a-z\\d_]*)?$', // validate fragment locator + 'i', + ); const isValid = urlRegex.test(urlValue); return !isValid ? intlFunc(messages.isValidURL) : null; }, @@ -111,7 +127,7 @@ const widgetValidation = { maxLength: (value, itemObj, intlFunc) => isMaxPropertyValid( value.length, - itemObj.maxLengthj, + itemObj.maxLength, 'maxLength', intlFunc, ), @@ -194,7 +210,7 @@ const validateRequiredFields = ( const type = schema.properties[requiredField]?.type; const widget = schema.properties[requiredField]?.widget; - let isEmpty = !formData[requiredField]; + let isEmpty = !formData[requiredField] && formData[requiredField] !== 0; if (!isEmpty) { if (type === 'array') { isEmpty = formData[requiredField] @@ -212,10 +228,8 @@ const validateRequiredFields = ( ((type !== 'boolean' && isEmpty) || (type === 'boolean' && formData[requiredField] !== true)) ) { - const requiredFieldName = - schema.properties[requiredField].title || requiredField; - errors[requiredFieldName] = []; - errors[requiredFieldName].push(formatMessage(messages.required)); + errors[requiredField] = []; + errors[requiredField].push(formatMessage(messages.required)); } }); @@ -362,3 +376,29 @@ class FormValidation { } export default FormValidation; + +/** + * Check if a file upload is within the maximum size limit. + * @param {File} file + * @param {Function} intlFunc + * @returns {Boolean} + */ +export const validateFileUploadSize = (file, intlFunc) => { + const isValid = + !config.settings.maxFileUploadSize || + file.size <= config.settings.maxFileUploadSize; + if (!isValid) { + toast.error( + , + ); + } + return isValid; +}; diff --git a/frontend/yarn.lock b/frontend/yarn.lock index d3e9094..45800ae 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -2759,9 +2759,9 @@ __metadata: languageName: node linkType: hard -"@plone/volto@npm:16.19.0": - version: 16.19.0 - resolution: "@plone/volto@npm:16.19.0" +"@plone/volto@npm:16.25.0": + version: 16.25.0 + resolution: "@plone/volto@npm:16.25.0" dependencies: "@babel/core": ^7.0.0 "@babel/plugin-proposal-export-default-from": 7.18.9 @@ -2851,7 +2851,7 @@ __metadata: lodash-move: 1.1.1 lodash-webpack-plugin: 0.11.5 mini-css-extract-plugin: 0.9.0 - moment: 2.24.0 + moment: 2.29.4 object-assign: 4.1.1 pofile: 1.0.10 postcss: 8.4.13 @@ -2943,7 +2943,7 @@ __metadata: webpack-node-externals: 3.0.0 xmlrpc: 1.3.2 yarnhook: 0.5.1 - checksum: 4be6a649349c4210126a6024dd6a9e0f1b7f518fdf24b2256d5e811a193219c5065363e320e524abb58cf91c41ffa61d5b038885277d45cfd0c87bfa11c247ec + checksum: 3046c1a2a8f225ff5e3ff2f7ef110d1df244f05e8984d1189b685572a6613ade20cb29a11b72e98077af82279281a60ab183b63f1e7eb6b18352c19c4bb66428 languageName: node linkType: hard @@ -11778,7 +11778,7 @@ __metadata: "@kitconcept/volto-slider-block": ^4.0.0 "@plone-collective/volto-authomatic": 1.3.0 "@plone/scripts": ^2.2.1 - "@plone/volto": 16.19.0 + "@plone/volto": 16.25.0 "@storybook/addon-actions": ^6.3.0 "@storybook/addon-controls": 6.3.0 "@storybook/addon-essentials": ^6.3.0 @@ -16541,14 +16541,7 @@ __metadata: languageName: node linkType: hard -"moment@npm:2.24.0": - version: 2.24.0 - resolution: "moment@npm:2.24.0" - checksum: 9cd93a251a2b33cb1b532eade0e496a2a7547faa6cfe37a283ee7bf69e202cd7c8ab0673d66883b5b29aed051353176dc0e6684f04073a75b0a155c500be1580 - languageName: node - linkType: hard - -"moment@npm:2.x, moment@npm:>=1.6.0": +"moment@npm:2.29.4, moment@npm:2.x, moment@npm:>=1.6.0": version: 2.29.4 resolution: "moment@npm:2.29.4" checksum: 0ec3f9c2bcba38dc2451b1daed5daded747f17610b92427bebe1d08d48d8b7bdd8d9197500b072d14e326dd0ccf3e326b9e3d07c5895d3d49e39b6803b76e80e