From d318937f22b66d1bbdec050195bf94c440184501 Mon Sep 17 00:00:00 2001 From: ronronscelestes Date: Wed, 10 Nov 2021 14:11:05 +0100 Subject: [PATCH 01/13] added error state in accordion group custom --- .../AccordionGroupCustom/index.js | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/packages/core/admin/admin/src/content-manager/components/RepeatableComponent/AccordionGroupCustom/index.js b/packages/core/admin/admin/src/content-manager/components/RepeatableComponent/AccordionGroupCustom/index.js index 6f0cfadb6b..9f6c36c6ac 100644 --- a/packages/core/admin/admin/src/content-manager/components/RepeatableComponent/AccordionGroupCustom/index.js +++ b/packages/core/admin/admin/src/content-manager/components/RepeatableComponent/AccordionGroupCustom/index.js @@ -1,8 +1,9 @@ -import React from 'react'; +import React, { Children, cloneElement } from 'react'; import PropTypes from 'prop-types'; import styled from 'styled-components'; import { Box } from '@strapi/design-system/Box'; import { Text } from '@strapi/design-system/Text'; +import { Typography } from '@strapi/design-system/Typography'; import { Flex } from '@strapi/design-system/Flex'; import { KeyboardNavigable } from '@strapi/design-system/KeyboardNavigable'; @@ -61,7 +62,11 @@ const LabelAction = styled(Box)` } `; -const AccordionGroupCustom = ({ children, footer, label, labelAction }) => { +const AccordionGroupCustom = ({ children, footer, label, labelAction, error }) => { + const childrenArray = Children.toArray(children).map(child => { + return cloneElement(child, { hasErrorMessage: false }); + }); + return ( {label && ( @@ -72,13 +77,21 @@ const AccordionGroupCustom = ({ children, footer, label, labelAction }) => { {labelAction && {labelAction}} )} - {children} + {childrenArray} {footer && {footer}} + {error && ( + + + {error} + + + )} ); }; AccordionGroupCustom.defaultProps = { + error: undefined, footer: null, label: null, labelAction: undefined, @@ -86,6 +99,7 @@ AccordionGroupCustom.defaultProps = { AccordionGroupCustom.propTypes = { children: PropTypes.node.isRequired, + error: PropTypes.string, footer: PropTypes.node, label: PropTypes.string, labelAction: PropTypes.node, From b0bf6dcd505fa5a449a894ed1fbdf8a565403be7 Mon Sep 17 00:00:00 2001 From: ronronscelestes Date: Wed, 10 Nov 2021 15:15:49 +0100 Subject: [PATCH 02/13] added error state to repeatable component --- .../complex/content-types/complex/schema.json | 25 +++++++++++ .../src/api/complex/controllers/complex.js | 15 +++++++ .../src/api/complex/routes/complex.js | 44 +++++++++++++++++++ .../src/api/complex/services/complex.js | 7 +++ .../src/components/basic/component.json | 15 +++++++ .../RepeatableComponent/DraggedItem/index.js | 26 +++++------ .../components/RepeatableComponent/index.js | 22 ++++++---- 7 files changed, 132 insertions(+), 22 deletions(-) create mode 100644 examples/getstarted/src/api/complex/content-types/complex/schema.json create mode 100644 examples/getstarted/src/api/complex/controllers/complex.js create mode 100644 examples/getstarted/src/api/complex/routes/complex.js create mode 100644 examples/getstarted/src/api/complex/services/complex.js create mode 100644 examples/getstarted/src/components/basic/component.json diff --git a/examples/getstarted/src/api/complex/content-types/complex/schema.json b/examples/getstarted/src/api/complex/content-types/complex/schema.json new file mode 100644 index 0000000000..f083526039 --- /dev/null +++ b/examples/getstarted/src/api/complex/content-types/complex/schema.json @@ -0,0 +1,25 @@ +{ + "kind": "collectionType", + "collectionName": "complexes", + "info": { + "singularName": "complex", + "pluralName": "complexes", + "displayName": "Complex", + "description": "" + }, + "options": { + "draftAndPublish": false + }, + "pluginOptions": {}, + "attributes": { + "name": { + "type": "string" + }, + "Repeatable": { + "displayName": "Component", + "type": "component", + "repeatable": true, + "component": "basic.component" + } + } +} diff --git a/examples/getstarted/src/api/complex/controllers/complex.js b/examples/getstarted/src/api/complex/controllers/complex.js new file mode 100644 index 0000000000..ceffac6dfb --- /dev/null +++ b/examples/getstarted/src/api/complex/controllers/complex.js @@ -0,0 +1,15 @@ +'use strict'; + +/** + * A set of functions called "actions" for `complex` + */ + +module.exports = { + // exampleAction: async (ctx, next) => { + // try { + // ctx.body = 'ok'; + // } catch (err) { + // ctx.body = err; + // } + // } +}; diff --git a/examples/getstarted/src/api/complex/routes/complex.js b/examples/getstarted/src/api/complex/routes/complex.js new file mode 100644 index 0000000000..e975ed7ab6 --- /dev/null +++ b/examples/getstarted/src/api/complex/routes/complex.js @@ -0,0 +1,44 @@ +module.exports = { + routes: [ + { + method: 'GET', + path: '/complexes', + handler: 'complex.find', + config: { + policies: [], + }, + }, + { + method: 'GET', + path: '/complexes/:id', + handler: 'complex.findOne', + config: { + policies: [], + }, + }, + { + method: 'POST', + path: '/complexes', + handler: 'complex.create', + config: { + policies: [], + }, + }, + { + method: 'PUT', + path: '/complexes/:id', + handler: 'complex.update', + config: { + policies: [], + }, + }, + { + method: 'DELETE', + path: '/complexes/:id', + handler: 'complex.delete', + config: { + policies: [], + }, + }, + ], +}; diff --git a/examples/getstarted/src/api/complex/services/complex.js b/examples/getstarted/src/api/complex/services/complex.js new file mode 100644 index 0000000000..82bca995c7 --- /dev/null +++ b/examples/getstarted/src/api/complex/services/complex.js @@ -0,0 +1,7 @@ +'use strict'; + +/** + * complex service. + */ + +module.exports = () => ({}); diff --git a/examples/getstarted/src/components/basic/component.json b/examples/getstarted/src/components/basic/component.json new file mode 100644 index 0000000000..4a574bb8a1 --- /dev/null +++ b/examples/getstarted/src/components/basic/component.json @@ -0,0 +1,15 @@ +{ + "collectionName": "components_basic_components", + "info": { + "displayName": "Component", + "icon": "anchor", + "description": "" + }, + "options": {}, + "attributes": { + "name": { + "type": "string", + "required": true + } + } +} diff --git a/packages/core/admin/admin/src/content-manager/components/RepeatableComponent/DraggedItem/index.js b/packages/core/admin/admin/src/content-manager/components/RepeatableComponent/DraggedItem/index.js index bffc572bb6..2d0e266a77 100644 --- a/packages/core/admin/admin/src/content-manager/components/RepeatableComponent/DraggedItem/index.js +++ b/packages/core/admin/admin/src/content-manager/components/RepeatableComponent/DraggedItem/index.js @@ -38,10 +38,9 @@ const StyledBox = styled(Box)` const DraggedItem = ({ componentFieldName, // FIXME: errors - // doesPreviousFieldContainErrorsAndIsOpen, - // hasErrors, - // hasMinError, - // isFirst, + // Retrieved from the AccordionGroupCustom cloneElement + hasErrorMessage, + hasErrors, isDraggingSibling, isOpen, isReadOnly, @@ -180,7 +179,14 @@ const DraggedItem = ({ )} {!isDragging && !isDraggingSibling && ( - + {}, @@ -281,10 +283,8 @@ DraggedItem.defaultProps = { DraggedItem.propTypes = { componentFieldName: PropTypes.string.isRequired, - // doesPreviousFieldContainErrorsAndIsOpen: PropTypes.bool, - // hasErrors: PropTypes.bool, - // hasMinError: PropTypes.bool, - // isFirst: PropTypes.bool, + hasErrorMessage: PropTypes.bool.isRequired, + hasErrors: PropTypes.bool.isRequired, isDraggingSibling: PropTypes.bool, isOpen: PropTypes.bool, isReadOnly: PropTypes.bool.isRequired, diff --git a/packages/core/admin/admin/src/content-manager/components/RepeatableComponent/index.js b/packages/core/admin/admin/src/content-manager/components/RepeatableComponent/index.js index fd42a9936f..ba6babf615 100644 --- a/packages/core/admin/admin/src/content-manager/components/RepeatableComponent/index.js +++ b/packages/core/admin/admin/src/content-manager/components/RepeatableComponent/index.js @@ -72,6 +72,8 @@ const RepeatableComponent = ({ .join('.'); }); + console.log({ componentErrorKeys }); + const toggleCollapses = () => { setCollapseToOpen(''); }; @@ -112,9 +114,20 @@ const RepeatableComponent = ({ return ; } + const doesRepComponentHasChildError = componentErrorKeys.some( + error => error.split('.').length > 1 + ); + + let errorMessage = formErrors[name]; + + if (doesRepComponentHasChildError) { + errorMessage = 'The component(s) contain error(s)'; + } + return ( }> @@ -130,24 +143,15 @@ const RepeatableComponent = ({ const key = data.__temp_key__; const isOpen = collapseToOpen === key; const componentFieldName = `${name}.${index}`; - const previousComponentTempKey = get(componentValue, [index - 1, '__temp_key__']); - const doesPreviousFieldContainErrorsAndIsOpen = - componentErrorKeys.includes(`${name}.${index - 1}`) && - index !== 0 && - collapseToOpen === previousComponentTempKey; - const hasErrors = componentErrorKeys.includes(componentFieldName); return ( Date: Wed, 10 Nov 2021 16:18:53 +0100 Subject: [PATCH 03/13] add logic to display errors when rep component required min validation --- .../complex/content-types/complex/schema.json | 17 ++ .../getstarted/src/components/basic/rep2.json | 20 ++ .../components/ComponentInitializer/index.js | 75 +++++--- .../EditViewDataManagerProvider/index.js | 4 +- .../AccordionGroupCustom/index.js | 10 +- .../components/RepeatableComponent/index.js | 171 +++--------------- 6 files changed, 118 insertions(+), 179 deletions(-) create mode 100644 examples/getstarted/src/components/basic/rep2.json diff --git a/examples/getstarted/src/api/complex/content-types/complex/schema.json b/examples/getstarted/src/api/complex/content-types/complex/schema.json index f083526039..0684fd85e4 100644 --- a/examples/getstarted/src/api/complex/content-types/complex/schema.json +++ b/examples/getstarted/src/api/complex/content-types/complex/schema.json @@ -20,6 +20,23 @@ "type": "component", "repeatable": true, "component": "basic.component" + }, + "rep_required": { + "displayName": "rep2", + "type": "component", + "repeatable": true, + "component": "basic.rep2", + "required": true, + "min": 2 + }, + "dz": { + "type": "dynamiczone", + "components": [ + "basic.rep2", + "basic.component" + ], + "required": true, + "min": 2 } } } diff --git a/examples/getstarted/src/components/basic/rep2.json b/examples/getstarted/src/components/basic/rep2.json new file mode 100644 index 0000000000..90aeefecf2 --- /dev/null +++ b/examples/getstarted/src/components/basic/rep2.json @@ -0,0 +1,20 @@ +{ + "collectionName": "components_basic_rep2s", + "info": { + "displayName": "rep2", + "icon": "angle-double-right", + "description": "" + }, + "options": {}, + "attributes": { + "name_name": { + "type": "string", + "required": true + }, + "nested": { + "type": "component", + "repeatable": true, + "component": "basic.component" + } + } +} diff --git a/packages/core/admin/admin/src/content-manager/components/ComponentInitializer/index.js b/packages/core/admin/admin/src/content-manager/components/ComponentInitializer/index.js index ba4f5758f3..03d76c7b6c 100644 --- a/packages/core/admin/admin/src/content-manager/components/ComponentInitializer/index.js +++ b/packages/core/admin/admin/src/content-manager/components/ComponentInitializer/index.js @@ -23,45 +23,64 @@ const IconWrapper = styled.span` } `; -const ComponentInitializer = ({ isReadOnly, onClick }) => { +const ComponentInitializer = ({ error, isReadOnly, onClick }) => { const { formatMessage } = useIntl(); return ( - - - - - - - - - - {formatMessage({ - id: getTrad('components.empty-repeatable'), - defaultMessage: 'No entry yet. Click on the button below to add one.', - })} - - - - + <> + + + + + + + + + + {formatMessage({ + id: getTrad('components.empty-repeatable'), + defaultMessage: 'No entry yet. Click on the button below to add one.', + })} + + + + + {error?.id && ( + + {formatMessage( + { + id: error.id, + defaultMessage: error.defaultMessage, + }, + error.values + )} + + )} + ); }; ComponentInitializer.defaultProps = { + error: undefined, isReadOnly: false, }; ComponentInitializer.propTypes = { + error: PropTypes.shape({ + id: PropTypes.string.isRequired, + defaultMessage: PropTypes.string.isRequired, + values: PropTypes.object, + }), isReadOnly: PropTypes.bool, onClick: PropTypes.func.isRequired, }; diff --git a/packages/core/admin/admin/src/content-manager/components/EditViewDataManagerProvider/index.js b/packages/core/admin/admin/src/content-manager/components/EditViewDataManagerProvider/index.js index 6ad8069ea4..120afc23e6 100644 --- a/packages/core/admin/admin/src/content-manager/components/EditViewDataManagerProvider/index.js +++ b/packages/core/admin/admin/src/content-manager/components/EditViewDataManagerProvider/index.js @@ -300,8 +300,8 @@ const EditViewDataManagerProvider = ({ onPut(formData, trackerProperty); } } catch (err) { - console.error('ValidationError'); - console.error(err); + console.log('ValidationError'); + console.log(err); errors = getYupInnerErrors(err); diff --git a/packages/core/admin/admin/src/content-manager/components/RepeatableComponent/AccordionGroupCustom/index.js b/packages/core/admin/admin/src/content-manager/components/RepeatableComponent/AccordionGroupCustom/index.js index 9f6c36c6ac..b8ca15a198 100644 --- a/packages/core/admin/admin/src/content-manager/components/RepeatableComponent/AccordionGroupCustom/index.js +++ b/packages/core/admin/admin/src/content-manager/components/RepeatableComponent/AccordionGroupCustom/index.js @@ -1,5 +1,6 @@ import React, { Children, cloneElement } from 'react'; import PropTypes from 'prop-types'; +import { useIntl } from 'react-intl'; import styled from 'styled-components'; import { Box } from '@strapi/design-system/Box'; import { Text } from '@strapi/design-system/Text'; @@ -63,6 +64,7 @@ const LabelAction = styled(Box)` `; const AccordionGroupCustom = ({ children, footer, label, labelAction, error }) => { + const { formatMessage } = useIntl(); const childrenArray = Children.toArray(children).map(child => { return cloneElement(child, { hasErrorMessage: false }); }); @@ -82,7 +84,7 @@ const AccordionGroupCustom = ({ children, footer, label, labelAction, error }) = {error && ( - {error} + {formatMessage({ id: error.id, defaultMessage: error.defaultMessage }, error.values)} )} @@ -99,7 +101,11 @@ AccordionGroupCustom.defaultProps = { AccordionGroupCustom.propTypes = { children: PropTypes.node.isRequired, - error: PropTypes.string, + error: PropTypes.shape({ + id: PropTypes.string.isRequired, + defaultMessage: PropTypes.string.isRequired, + values: PropTypes.object, + }), footer: PropTypes.node, label: PropTypes.string, labelAction: PropTypes.node, diff --git a/packages/core/admin/admin/src/content-manager/components/RepeatableComponent/index.js b/packages/core/admin/admin/src/content-manager/components/RepeatableComponent/index.js index ba6babf615..d8fbac0989 100644 --- a/packages/core/admin/admin/src/content-manager/components/RepeatableComponent/index.js +++ b/packages/core/admin/admin/src/content-manager/components/RepeatableComponent/index.js @@ -43,7 +43,7 @@ const RepeatableComponent = ({ isNested, isReadOnly, max, - // min, + min, name, }) => { const toggleNotification = useNotification(); @@ -72,16 +72,13 @@ const RepeatableComponent = ({ .join('.'); }); - console.log({ componentErrorKeys }); - const toggleCollapses = () => { setCollapseToOpen(''); }; - // TODO - // const missingComponentsValue = min - componentValueLength; - const errorsArray = componentErrorKeys.map(key => get(formErrors, [key, 'id'], '')); - const hasMinError = get(errorsArray, [0], '').includes('min'); + const missingComponentsValue = min - componentValueLength; + + const hasMinError = get(formErrors, name, { id: '' }).id.includes('min'); const handleClick = useCallback(() => { if (!isReadOnly) { @@ -110,22 +107,34 @@ const RepeatableComponent = ({ toggleNotification, ]); + let errorMessage = formErrors[name]; + + if (hasMinError) { + errorMessage = { + id: 'content-manager.components.DynamicZone.missing-components', + defaultMessage: + 'There {number, plural, =0 {are # missing components} one {is # missing component} other {are # missing components}}', + values: { number: missingComponentsValue }, + }; + } + if (componentValueLength === 0) { - return ; + return ( + + ); } const doesRepComponentHasChildError = componentErrorKeys.some( error => error.split('.').length > 1 ); - let errorMessage = formErrors[name]; - - if (doesRepComponentHasChildError) { - errorMessage = 'The component(s) contain error(s)'; + // FIXME + if (doesRepComponentHasChildError && !hasMinError) { + errorMessage = { id: 'TODO', defaultMessage: 'The component(s) contain error(s)' }; } return ( - + - // - // - // {componentValue.map((data, index) => { - // const key = data.__temp_key__; - // const isOpen = collapseToOpen === key; - // const componentFieldName = `${name}.${index}`; - // const previousComponentTempKey = get(componentValue, [index - 1, '__temp_key__']); - // const doesPreviousFieldContainErrorsAndIsOpen = - // componentErrorKeys.includes(`${name}.${index - 1}`) && - // index !== 0 && - // collapseToOpen === previousComponentTempKey; - - // const hasErrors = componentErrorKeys.includes(componentFieldName); - - // return ( - // { - // if (isOpen) { - // setCollapseToOpen(''); - // } else { - // setCollapseToOpen(key); - // } - // }} - // parentName={name} - // schema={componentLayoutData} - // toggleCollapses={toggleCollapses} - // /> - // ); - // })} - // - // - // {hasMinError && ( - // - // 1 ? '.plural' : '.singular' - // }` - // )} - // values={{ count: missingComponentsValue }} - // /> - // - // )} - // - // ); }; RepeatableComponent.defaultProps = { @@ -312,7 +189,7 @@ RepeatableComponent.defaultProps = { formErrors: {}, isNested: false, max: Infinity, - // min: -Infinity, + min: 0, }; RepeatableComponent.propTypes = { @@ -324,7 +201,7 @@ RepeatableComponent.propTypes = { isNested: PropTypes.bool, isReadOnly: PropTypes.bool.isRequired, max: PropTypes.number, - // min: PropTypes.number, + min: PropTypes.number, name: PropTypes.string.isRequired, }; From 414d028a1366c0a4d6b8137ebe51bb8bcc82fa0c Mon Sep 17 00:00:00 2001 From: ronronscelestes Date: Wed, 10 Nov 2021 17:04:57 +0100 Subject: [PATCH 04/13] dz error state --- .../complex/content-types/complex/schema.json | 13 ++++++++++- .../getstarted/src/components/basic/pay.json | 16 ++++++++++++++ .../getstarted/src/components/basic/tata.json | 9 ++++++++ .../DynamicZone/components/Component/index.js | 22 ++++++++++++++++++- .../components/DynamicZone/index.js | 1 + 5 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 examples/getstarted/src/components/basic/pay.json create mode 100644 examples/getstarted/src/components/basic/tata.json diff --git a/examples/getstarted/src/api/complex/content-types/complex/schema.json b/examples/getstarted/src/api/complex/content-types/complex/schema.json index 0684fd85e4..73a735630e 100644 --- a/examples/getstarted/src/api/complex/content-types/complex/schema.json +++ b/examples/getstarted/src/api/complex/content-types/complex/schema.json @@ -32,8 +32,19 @@ "dz": { "type": "dynamiczone", "components": [ + "basic.pay", + "basic.component", "basic.rep2", - "basic.component" + "basic.simple", + "basic.tata", + "blog.test-como", + "default.apple", + "default.car", + "default.closingperiod", + "default.dish", + "default.openingtimes", + "default.restaurantservice", + "default.temp" ], "required": true, "min": 2 diff --git a/examples/getstarted/src/components/basic/pay.json b/examples/getstarted/src/components/basic/pay.json new file mode 100644 index 0000000000..6c451548d5 --- /dev/null +++ b/examples/getstarted/src/components/basic/pay.json @@ -0,0 +1,16 @@ +{ + "collectionName": "components_basic_pays", + "info": { + "displayName": "Pay", + "icon": "archway" + }, + "options": {}, + "attributes": { + "label": { + "displayName": "Tata", + "type": "component", + "repeatable": true, + "component": "basic.tata" + } + } +} diff --git a/examples/getstarted/src/components/basic/tata.json b/examples/getstarted/src/components/basic/tata.json new file mode 100644 index 0000000000..cb082bceba --- /dev/null +++ b/examples/getstarted/src/components/basic/tata.json @@ -0,0 +1,9 @@ +{ + "collectionName": "components_basic_tatas", + "info": { + "displayName": "Tata", + "icon": "arrows-alt" + }, + "options": {}, + "attributes": {} +} diff --git a/packages/core/admin/admin/src/content-manager/components/DynamicZone/components/Component/index.js b/packages/core/admin/admin/src/content-manager/components/DynamicZone/components/Component/index.js index c8e2d1662e..459ca649be 100644 --- a/packages/core/admin/admin/src/content-manager/components/DynamicZone/components/Component/index.js +++ b/packages/core/admin/admin/src/content-manager/components/DynamicZone/components/Component/index.js @@ -31,6 +31,7 @@ const StyledBox = styled(Box)` const Component = ({ componentUid, + formErrors, index, isOpen, isFieldAllowed, @@ -74,11 +75,30 @@ const Component = ({ { name: friendlyName } ); + const formErrorsKeys = Object.keys(formErrors); + + const fieldsErrors = formErrorsKeys.filter(errorKey => { + + const errorKeysArray = errorKey.split('.').filter((_, index) => index < 2) + + if (errorKeysArray.join('.') === `${name}.${index}`) { + return true; + } + + return false; + }); + + let errorMessage; + + if (fieldsErrors.length > 0) { + errorMessage = formatMessage({ id: 'TODO', defaultMessage: 'firstChildError.id'}) + }; + return ( - onToggle(index)} size="S"> + onToggle(index)} size="S" error={errorMessage}> } action={ diff --git a/packages/core/admin/admin/src/content-manager/components/DynamicZone/index.js b/packages/core/admin/admin/src/content-manager/components/DynamicZone/index.js index f283c63ff0..b1becbe911 100644 --- a/packages/core/admin/admin/src/content-manager/components/DynamicZone/index.js +++ b/packages/core/admin/admin/src/content-manager/components/DynamicZone/index.js @@ -188,6 +188,7 @@ const DynamicZone = ({ return ( Date: Mon, 15 Nov 2021 11:26:53 +0100 Subject: [PATCH 05/13] fixed dz shadow and dz accordion content background color --- .../complex/content-types/complex/schema.json | 3 +- .../src/components/basic/select.json | 19 +++++++++ .../DynamicZone/components/Component/index.js | 42 ++++++++++--------- .../NonRepeatableComponent/index.js | 2 +- 4 files changed, 45 insertions(+), 21 deletions(-) create mode 100644 examples/getstarted/src/components/basic/select.json diff --git a/examples/getstarted/src/api/complex/content-types/complex/schema.json b/examples/getstarted/src/api/complex/content-types/complex/schema.json index 73a735630e..d2cbec632f 100644 --- a/examples/getstarted/src/api/complex/content-types/complex/schema.json +++ b/examples/getstarted/src/api/complex/content-types/complex/schema.json @@ -44,7 +44,8 @@ "default.dish", "default.openingtimes", "default.restaurantservice", - "default.temp" + "default.temp", + "basic.select" ], "required": true, "min": 2 diff --git a/examples/getstarted/src/components/basic/select.json b/examples/getstarted/src/components/basic/select.json new file mode 100644 index 0000000000..64a2eeb1f0 --- /dev/null +++ b/examples/getstarted/src/components/basic/select.json @@ -0,0 +1,19 @@ +{ + "collectionName": "components_basic_selects", + "info": { + "displayName": "select", + "icon": "asterisk" + }, + "options": {}, + "attributes": { + "selectest": { + "type": "enumeration", + "enum": [ + "hola", + "hello", + "yo", + "toutca" + ] + } + } +} diff --git a/packages/core/admin/admin/src/content-manager/components/DynamicZone/components/Component/index.js b/packages/core/admin/admin/src/content-manager/components/DynamicZone/components/Component/index.js index 459ca649be..8b000214a9 100644 --- a/packages/core/admin/admin/src/content-manager/components/DynamicZone/components/Component/index.js +++ b/packages/core/admin/admin/src/content-manager/components/DynamicZone/components/Component/index.js @@ -22,13 +22,15 @@ const IconButtonCustom = styled(IconButton)` `; const StyledBox = styled(Box)` - > div { - > div:not(:first-of-type) { - overflow: visible; - } + > div:first-child { + box-shadow: ${({ theme }) => theme.shadows.tableShadow}; } `; +const AccordionContentRadius = styled(Box)` + border-radius: 0 0 ${({ theme }) => theme.spaces[1]} ${({ theme }) => theme.spaces[1]}; +`; + const Component = ({ componentUid, formErrors, @@ -75,12 +77,11 @@ const Component = ({ { name: friendlyName } ); - const formErrorsKeys = Object.keys(formErrors); + const formErrorsKeys = Object.keys(formErrors); const fieldsErrors = formErrorsKeys.filter(errorKey => { - - const errorKeysArray = errorKey.split('.').filter((_, index) => index < 2) - + const errorKeysArray = errorKey.split('.').filter((_, index) => index < 2); + if (errorKeysArray.join('.') === `${name}.${index}`) { return true; } @@ -91,13 +92,13 @@ const Component = ({ let errorMessage; if (fieldsErrors.length > 0) { - errorMessage = formatMessage({ id: 'TODO', defaultMessage: 'firstChildError.id'}) - }; + errorMessage = formatMessage({ id: 'TODO', defaultMessage: 'firstChildError.id' }); + } return ( - + onToggle(index)} size="S" error={errorMessage}> } @@ -133,14 +134,16 @@ const Component = ({ togglePosition="left" /> - onToggle(index)}> - - + + onToggle(index)}> + + + @@ -150,6 +153,7 @@ const Component = ({ Component.propTypes = { componentUid: PropTypes.string.isRequired, + formErrors: PropTypes.object.isRequired, index: PropTypes.number.isRequired, isFieldAllowed: PropTypes.bool.isRequired, isOpen: PropTypes.bool.isRequired, diff --git a/packages/core/admin/admin/src/content-manager/components/NonRepeatableComponent/index.js b/packages/core/admin/admin/src/content-manager/components/NonRepeatableComponent/index.js index b4f24246dc..993fa518d7 100644 --- a/packages/core/admin/admin/src/content-manager/components/NonRepeatableComponent/index.js +++ b/packages/core/admin/admin/src/content-manager/components/NonRepeatableComponent/index.js @@ -20,7 +20,7 @@ const NonRepeatableComponent = ({ componentUid, isFromDynamicZone, isNested, nam return ( Date: Mon, 15 Nov 2021 11:36:37 +0100 Subject: [PATCH 06/13] added error message trad for DZ component contains error(s) --- .../components/DynamicZone/components/Component/index.js | 5 ++++- packages/core/admin/admin/src/translations/en.json | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/core/admin/admin/src/content-manager/components/DynamicZone/components/Component/index.js b/packages/core/admin/admin/src/content-manager/components/DynamicZone/components/Component/index.js index 8b000214a9..f4e5021e4a 100644 --- a/packages/core/admin/admin/src/content-manager/components/DynamicZone/components/Component/index.js +++ b/packages/core/admin/admin/src/content-manager/components/DynamicZone/components/Component/index.js @@ -92,7 +92,10 @@ const Component = ({ let errorMessage; if (fieldsErrors.length > 0) { - errorMessage = formatMessage({ id: 'TODO', defaultMessage: 'firstChildError.id' }); + errorMessage = formatMessage({ + id: getTrad('components.DynamicZone.error-message'), + defaultMessage: 'The component contains error(s)', + }); } return ( diff --git a/packages/core/admin/admin/src/translations/en.json b/packages/core/admin/admin/src/translations/en.json index 359194d570..167211315a 100644 --- a/packages/core/admin/admin/src/translations/en.json +++ b/packages/core/admin/admin/src/translations/en.json @@ -454,6 +454,7 @@ "content-manager.components.DynamicZone.ComponentPicker-label": "Pick one component", "content-manager.components.DynamicZone.add-component": "Add a component to {componentName}", "content-manager.components.DynamicZone.delete-label": "Delete {name}", + "content-manager.components.DynamicZone.error-message": "The component contains error(s)", "content-manager.components.DynamicZone.missing-components": "There {number, plural, =0 {are # missing components} one {is # missing component} other {are # missing components}}", "content-manager.components.DynamicZone.move-down-label": "Move component down", "content-manager.components.DynamicZone.move-up-label": "Move component up", From 405fb6897a2314398480ad6990436eefa84a8985 Mon Sep 17 00:00:00 2001 From: ronronscelestes Date: Mon, 15 Nov 2021 11:49:14 +0100 Subject: [PATCH 07/13] feedback fix --- .../components/DynamicZone/components/Component/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core/admin/admin/src/content-manager/components/DynamicZone/components/Component/index.js b/packages/core/admin/admin/src/content-manager/components/DynamicZone/components/Component/index.js index f4e5021e4a..071f7f305f 100644 --- a/packages/core/admin/admin/src/content-manager/components/DynamicZone/components/Component/index.js +++ b/packages/core/admin/admin/src/content-manager/components/DynamicZone/components/Component/index.js @@ -80,9 +80,9 @@ const Component = ({ const formErrorsKeys = Object.keys(formErrors); const fieldsErrors = formErrorsKeys.filter(errorKey => { - const errorKeysArray = errorKey.split('.').filter((_, index) => index < 2); + const errorKeysArray = errorKey.split('.'); - if (errorKeysArray.join('.') === `${name}.${index}`) { + if (`${errorKeysArray[0]}.${errorKeysArray[1]}` === `${name}.${index}`) { return true; } From b2bfab277e9ed74de4c015e241c5e68216aa01ae Mon Sep 17 00:00:00 2001 From: ronronscelestes Date: Mon, 15 Nov 2021 11:56:22 +0100 Subject: [PATCH 08/13] removed unnecessary overflow visible on dragged item --- .../RepeatableComponent/DraggedItem/index.js | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/packages/core/admin/admin/src/content-manager/components/RepeatableComponent/DraggedItem/index.js b/packages/core/admin/admin/src/content-manager/components/RepeatableComponent/DraggedItem/index.js index 2d0e266a77..69b4af836f 100644 --- a/packages/core/admin/admin/src/content-manager/components/RepeatableComponent/DraggedItem/index.js +++ b/packages/core/admin/admin/src/content-manager/components/RepeatableComponent/DraggedItem/index.js @@ -5,7 +5,6 @@ import { useDrag, useDrop } from 'react-dnd'; import { getEmptyImage } from 'react-dnd-html5-backend'; import { useIntl } from 'react-intl'; import toString from 'lodash/toString'; -import styled from 'styled-components'; import { Accordion, AccordionToggle, AccordionContent } from '@strapi/design-system/Accordion'; import { Grid, GridItem } from '@strapi/design-system/Grid'; import { Stack } from '@strapi/design-system/Stack'; @@ -21,14 +20,6 @@ import DraggingSibling from './DraggingSibling'; import { CustomIconButton, DragHandleWrapper } from './IconButtonCustoms'; import { connect, select } from './utils'; -const StyledBox = styled(Box)` - > div { - > div:not(:first-of-type) { - overflow: visible; - } - } -`; - /* eslint-disable react/no-array-index-key */ // Issues: @@ -172,7 +163,7 @@ const DraggedItem = ({ const accordionTitle = toString(displayedValue); return ( - + {isDragging && } {!isDragging && isDraggingSibling && ( @@ -270,7 +261,7 @@ const DraggedItem = ({ )} - + ); }; From d6322b5ca0e81bb5164a438c3f11cd6ded76a501 Mon Sep 17 00:00:00 2001 From: ronronscelestes Date: Mon, 15 Nov 2021 12:01:15 +0100 Subject: [PATCH 09/13] removed unnecessary comment --- .../components/RepeatableComponent/DraggedItem/index.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/core/admin/admin/src/content-manager/components/RepeatableComponent/DraggedItem/index.js b/packages/core/admin/admin/src/content-manager/components/RepeatableComponent/DraggedItem/index.js index 69b4af836f..d67a6f797f 100644 --- a/packages/core/admin/admin/src/content-manager/components/RepeatableComponent/DraggedItem/index.js +++ b/packages/core/admin/admin/src/content-manager/components/RepeatableComponent/DraggedItem/index.js @@ -28,8 +28,7 @@ import { connect, select } from './utils'; const DraggedItem = ({ componentFieldName, - // FIXME: errors - // Retrieved from the AccordionGroupCustom cloneElement + // Errors are retrieved from the AccordionGroupCustom cloneElement hasErrorMessage, hasErrors, isDraggingSibling, From d991d5133328e63a2235463d7937e203f05465f7 Mon Sep 17 00:00:00 2001 From: ronronscelestes Date: Mon, 15 Nov 2021 12:10:22 +0100 Subject: [PATCH 10/13] fixed rep component child has error trad --- .../components/RepeatableComponent/DraggedItem/index.js | 4 +++- .../components/RepeatableComponent/index.js | 8 +++++--- packages/core/admin/admin/src/translations/en.json | 1 + 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/core/admin/admin/src/content-manager/components/RepeatableComponent/DraggedItem/index.js b/packages/core/admin/admin/src/content-manager/components/RepeatableComponent/DraggedItem/index.js index d67a6f797f..41c039d5b5 100644 --- a/packages/core/admin/admin/src/content-manager/components/RepeatableComponent/DraggedItem/index.js +++ b/packages/core/admin/admin/src/content-manager/components/RepeatableComponent/DraggedItem/index.js @@ -45,6 +45,7 @@ const DraggedItem = ({ // checkFormErrors, displayedValue, }) => { + console.log(hasErrorMessage, hasErrors); const dragRef = useRef(null); const dropRef = useRef(null); const [, forceRerenderAfterDnd] = useState(false); @@ -160,6 +161,7 @@ const DraggedItem = ({ }; const accordionTitle = toString(displayedValue); + const accordionHasError = hasErrors ? 'error' : undefined; return ( @@ -170,7 +172,7 @@ const DraggedItem = ({ {!isDragging && !isDraggingSibling && ( error.split('.').length > 1 ); - // FIXME if (doesRepComponentHasChildError && !hasMinError) { - errorMessage = { id: 'TODO', defaultMessage: 'The component(s) contain error(s)' }; + errorMessage = { + id: getTrad('components.RepComponent.error-message'), + defaultMessage: 'The component(s) contain error(s)', + }; } return ( diff --git a/packages/core/admin/admin/src/translations/en.json b/packages/core/admin/admin/src/translations/en.json index 167211315a..82b55061f5 100644 --- a/packages/core/admin/admin/src/translations/en.json +++ b/packages/core/admin/admin/src/translations/en.json @@ -475,6 +475,7 @@ "content-manager.components.LeftMenu.single-types": "{number, plural, =0 {Single Types} one {Single Type } other {Single Types}}", "content-manager.components.LimitSelect.itemsPerPage": "Items per page", "content-manager.components.NotAllowedInput.text": "No permissions to see this field", + "content-manager.components.RepComponent.error-message": "The component(s) contain error(s)", "content-manager.components.Search.placeholder": "Search for an entry...", "content-manager.components.Select.draft-info-title": "State: Draft", "content-manager.components.Select.publish-info-title": "State: Published", From dc6713be69d26feca362ac4b8b2ed2fd9b6893e1 Mon Sep 17 00:00:00 2001 From: ronronscelestes Date: Mon, 15 Nov 2021 12:17:03 +0100 Subject: [PATCH 11/13] remove log --- .../components/RepeatableComponent/DraggedItem/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/core/admin/admin/src/content-manager/components/RepeatableComponent/DraggedItem/index.js b/packages/core/admin/admin/src/content-manager/components/RepeatableComponent/DraggedItem/index.js index 41c039d5b5..e596c4195c 100644 --- a/packages/core/admin/admin/src/content-manager/components/RepeatableComponent/DraggedItem/index.js +++ b/packages/core/admin/admin/src/content-manager/components/RepeatableComponent/DraggedItem/index.js @@ -45,7 +45,6 @@ const DraggedItem = ({ // checkFormErrors, displayedValue, }) => { - console.log(hasErrorMessage, hasErrors); const dragRef = useRef(null); const dropRef = useRef(null); const [, forceRerenderAfterDnd] = useState(false); From ff12371f9c74012e665c640ade3546e11c65dc85 Mon Sep 17 00:00:00 2001 From: ronronscelestes Date: Mon, 15 Nov 2021 14:29:03 +0100 Subject: [PATCH 12/13] cleaned ctb data models --- .../complex/content-types/complex/schema.json | 54 ------------------- .../src/api/complex/controllers/complex.js | 15 ------ .../src/api/complex/routes/complex.js | 44 --------------- .../src/api/complex/services/complex.js | 7 --- .../src/components/basic/component.json | 15 ------ .../getstarted/src/components/basic/pay.json | 16 ------ .../getstarted/src/components/basic/rep2.json | 20 ------- .../src/components/basic/select.json | 19 ------- .../getstarted/src/components/basic/tata.json | 9 ---- 9 files changed, 199 deletions(-) delete mode 100644 examples/getstarted/src/api/complex/content-types/complex/schema.json delete mode 100644 examples/getstarted/src/api/complex/controllers/complex.js delete mode 100644 examples/getstarted/src/api/complex/routes/complex.js delete mode 100644 examples/getstarted/src/api/complex/services/complex.js delete mode 100644 examples/getstarted/src/components/basic/component.json delete mode 100644 examples/getstarted/src/components/basic/pay.json delete mode 100644 examples/getstarted/src/components/basic/rep2.json delete mode 100644 examples/getstarted/src/components/basic/select.json delete mode 100644 examples/getstarted/src/components/basic/tata.json diff --git a/examples/getstarted/src/api/complex/content-types/complex/schema.json b/examples/getstarted/src/api/complex/content-types/complex/schema.json deleted file mode 100644 index d2cbec632f..0000000000 --- a/examples/getstarted/src/api/complex/content-types/complex/schema.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "kind": "collectionType", - "collectionName": "complexes", - "info": { - "singularName": "complex", - "pluralName": "complexes", - "displayName": "Complex", - "description": "" - }, - "options": { - "draftAndPublish": false - }, - "pluginOptions": {}, - "attributes": { - "name": { - "type": "string" - }, - "Repeatable": { - "displayName": "Component", - "type": "component", - "repeatable": true, - "component": "basic.component" - }, - "rep_required": { - "displayName": "rep2", - "type": "component", - "repeatable": true, - "component": "basic.rep2", - "required": true, - "min": 2 - }, - "dz": { - "type": "dynamiczone", - "components": [ - "basic.pay", - "basic.component", - "basic.rep2", - "basic.simple", - "basic.tata", - "blog.test-como", - "default.apple", - "default.car", - "default.closingperiod", - "default.dish", - "default.openingtimes", - "default.restaurantservice", - "default.temp", - "basic.select" - ], - "required": true, - "min": 2 - } - } -} diff --git a/examples/getstarted/src/api/complex/controllers/complex.js b/examples/getstarted/src/api/complex/controllers/complex.js deleted file mode 100644 index ceffac6dfb..0000000000 --- a/examples/getstarted/src/api/complex/controllers/complex.js +++ /dev/null @@ -1,15 +0,0 @@ -'use strict'; - -/** - * A set of functions called "actions" for `complex` - */ - -module.exports = { - // exampleAction: async (ctx, next) => { - // try { - // ctx.body = 'ok'; - // } catch (err) { - // ctx.body = err; - // } - // } -}; diff --git a/examples/getstarted/src/api/complex/routes/complex.js b/examples/getstarted/src/api/complex/routes/complex.js deleted file mode 100644 index e975ed7ab6..0000000000 --- a/examples/getstarted/src/api/complex/routes/complex.js +++ /dev/null @@ -1,44 +0,0 @@ -module.exports = { - routes: [ - { - method: 'GET', - path: '/complexes', - handler: 'complex.find', - config: { - policies: [], - }, - }, - { - method: 'GET', - path: '/complexes/:id', - handler: 'complex.findOne', - config: { - policies: [], - }, - }, - { - method: 'POST', - path: '/complexes', - handler: 'complex.create', - config: { - policies: [], - }, - }, - { - method: 'PUT', - path: '/complexes/:id', - handler: 'complex.update', - config: { - policies: [], - }, - }, - { - method: 'DELETE', - path: '/complexes/:id', - handler: 'complex.delete', - config: { - policies: [], - }, - }, - ], -}; diff --git a/examples/getstarted/src/api/complex/services/complex.js b/examples/getstarted/src/api/complex/services/complex.js deleted file mode 100644 index 82bca995c7..0000000000 --- a/examples/getstarted/src/api/complex/services/complex.js +++ /dev/null @@ -1,7 +0,0 @@ -'use strict'; - -/** - * complex service. - */ - -module.exports = () => ({}); diff --git a/examples/getstarted/src/components/basic/component.json b/examples/getstarted/src/components/basic/component.json deleted file mode 100644 index 4a574bb8a1..0000000000 --- a/examples/getstarted/src/components/basic/component.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "collectionName": "components_basic_components", - "info": { - "displayName": "Component", - "icon": "anchor", - "description": "" - }, - "options": {}, - "attributes": { - "name": { - "type": "string", - "required": true - } - } -} diff --git a/examples/getstarted/src/components/basic/pay.json b/examples/getstarted/src/components/basic/pay.json deleted file mode 100644 index 6c451548d5..0000000000 --- a/examples/getstarted/src/components/basic/pay.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "collectionName": "components_basic_pays", - "info": { - "displayName": "Pay", - "icon": "archway" - }, - "options": {}, - "attributes": { - "label": { - "displayName": "Tata", - "type": "component", - "repeatable": true, - "component": "basic.tata" - } - } -} diff --git a/examples/getstarted/src/components/basic/rep2.json b/examples/getstarted/src/components/basic/rep2.json deleted file mode 100644 index 90aeefecf2..0000000000 --- a/examples/getstarted/src/components/basic/rep2.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "collectionName": "components_basic_rep2s", - "info": { - "displayName": "rep2", - "icon": "angle-double-right", - "description": "" - }, - "options": {}, - "attributes": { - "name_name": { - "type": "string", - "required": true - }, - "nested": { - "type": "component", - "repeatable": true, - "component": "basic.component" - } - } -} diff --git a/examples/getstarted/src/components/basic/select.json b/examples/getstarted/src/components/basic/select.json deleted file mode 100644 index 64a2eeb1f0..0000000000 --- a/examples/getstarted/src/components/basic/select.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "collectionName": "components_basic_selects", - "info": { - "displayName": "select", - "icon": "asterisk" - }, - "options": {}, - "attributes": { - "selectest": { - "type": "enumeration", - "enum": [ - "hola", - "hello", - "yo", - "toutca" - ] - } - } -} diff --git a/examples/getstarted/src/components/basic/tata.json b/examples/getstarted/src/components/basic/tata.json deleted file mode 100644 index cb082bceba..0000000000 --- a/examples/getstarted/src/components/basic/tata.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "collectionName": "components_basic_tatas", - "info": { - "displayName": "Tata", - "icon": "arrows-alt" - }, - "options": {}, - "attributes": {} -} From 8b30d4c87deeeb66376385ece4f7b08e5304c892 Mon Sep 17 00:00:00 2001 From: ronronscelestes Date: Mon, 15 Nov 2021 15:29:18 +0100 Subject: [PATCH 13/13] feedback fix --- .../src/content-manager/components/RepeatableComponent/index.js | 2 +- packages/core/admin/admin/src/translations/en.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core/admin/admin/src/content-manager/components/RepeatableComponent/index.js b/packages/core/admin/admin/src/content-manager/components/RepeatableComponent/index.js index daafa9591c..6ed82525a7 100644 --- a/packages/core/admin/admin/src/content-manager/components/RepeatableComponent/index.js +++ b/packages/core/admin/admin/src/content-manager/components/RepeatableComponent/index.js @@ -130,7 +130,7 @@ const RepeatableComponent = ({ if (doesRepComponentHasChildError && !hasMinError) { errorMessage = { - id: getTrad('components.RepComponent.error-message'), + id: getTrad('components.RepeatableComponent.error-message'), defaultMessage: 'The component(s) contain error(s)', }; } diff --git a/packages/core/admin/admin/src/translations/en.json b/packages/core/admin/admin/src/translations/en.json index 82b55061f5..950a0827f9 100644 --- a/packages/core/admin/admin/src/translations/en.json +++ b/packages/core/admin/admin/src/translations/en.json @@ -475,7 +475,7 @@ "content-manager.components.LeftMenu.single-types": "{number, plural, =0 {Single Types} one {Single Type } other {Single Types}}", "content-manager.components.LimitSelect.itemsPerPage": "Items per page", "content-manager.components.NotAllowedInput.text": "No permissions to see this field", - "content-manager.components.RepComponent.error-message": "The component(s) contain error(s)", + "content-manager.components.RepeatableComponent.error-message": "The component(s) contain error(s)", "content-manager.components.Search.placeholder": "Search for an entry...", "content-manager.components.Select.draft-info-title": "State: Draft", "content-manager.components.Select.publish-info-title": "State: Published",