From 650408c20eca35e0b0d6cca1a62204e8995fb41b Mon Sep 17 00:00:00 2001 From: soupette Date: Tue, 26 Nov 2019 16:10:59 +0100 Subject: [PATCH] Move icons to app for faster loading --- .../BooleanBox/EnumerationWrapper.js | 2 +- .../src/components/BooleanBox/Wrapper.js | 5 +- .../components/ComponentIconPicker/index.js | 4 +- .../src/components/HeaderNavLink/index.js | 13 ++- .../admin/src/containers/App/index.js | 3 +- .../App}/utils/icons.js | 0 .../containers/DataManagerProvider/index.js | 5 +- .../containers/DataManagerProvider/reducer.js | 2 + .../admin/src/containers/FormModal/index.js | 13 ++- .../admin/src/containers/FormModal/reducer.js | 13 ++- .../FormModal/utils/componentForm.js | 50 ++++++++++ .../src/containers/FormModal/utils/forms.js | 96 ++++++++++--------- .../admin/src/translations/en.json | 4 + 13 files changed, 151 insertions(+), 59 deletions(-) rename packages/strapi-plugin-content-type-builder/admin/src/{components/ComponentIconPicker => containers/App}/utils/icons.js (100%) create mode 100644 packages/strapi-plugin-content-type-builder/admin/src/containers/FormModal/utils/componentForm.js diff --git a/packages/strapi-plugin-content-type-builder/admin/src/components/BooleanBox/EnumerationWrapper.js b/packages/strapi-plugin-content-type-builder/admin/src/components/BooleanBox/EnumerationWrapper.js index 5045fa8893..232782bf80 100644 --- a/packages/strapi-plugin-content-type-builder/admin/src/components/BooleanBox/EnumerationWrapper.js +++ b/packages/strapi-plugin-content-type-builder/admin/src/components/BooleanBox/EnumerationWrapper.js @@ -3,7 +3,7 @@ import { Label } from '@buffetjs/core'; const EnumerationWrapper = styled(Label)` width: 415px; - height: 90px; + min-height: 90px; position: relative; padding-left: 54px; padding-top: 17px; diff --git a/packages/strapi-plugin-content-type-builder/admin/src/components/BooleanBox/Wrapper.js b/packages/strapi-plugin-content-type-builder/admin/src/components/BooleanBox/Wrapper.js index 22f162715f..7672048f0c 100644 --- a/packages/strapi-plugin-content-type-builder/admin/src/components/BooleanBox/Wrapper.js +++ b/packages/strapi-plugin-content-type-builder/admin/src/components/BooleanBox/Wrapper.js @@ -13,8 +13,9 @@ const Wrapper = styled.div` will-change: transform, opacity; color: #9ea7b8; > p { - max-width: 300px; - line-height: 17px; + max-width: calc(100% - 20px); + margin-top: -1px; + line-height: 18px; } } diff --git a/packages/strapi-plugin-content-type-builder/admin/src/components/ComponentIconPicker/index.js b/packages/strapi-plugin-content-type-builder/admin/src/components/ComponentIconPicker/index.js index a5adb7a18a..e77e4e5735 100644 --- a/packages/strapi-plugin-content-type-builder/admin/src/components/ComponentIconPicker/index.js +++ b/packages/strapi-plugin-content-type-builder/admin/src/components/ComponentIconPicker/index.js @@ -6,8 +6,6 @@ import useDataManager from '../../hooks/useDataManager'; import CellRenderer from './CellRenderer'; import Wrapper from './Wrapper'; -import allIcons from './utils/icons'; - const ComponentIconPicker = ({ error, isCreating, @@ -16,7 +14,7 @@ const ComponentIconPicker = ({ onChange, value, }) => { - const { allComponentsIconAlreadyTaken } = useDataManager(); + const { allIcons, allComponentsIconAlreadyTaken } = useDataManager(); const icons = allIcons.filter(ico => { if (isCreating) { diff --git a/packages/strapi-plugin-content-type-builder/admin/src/components/HeaderNavLink/index.js b/packages/strapi-plugin-content-type-builder/admin/src/components/HeaderNavLink/index.js index 35e37c2197..50fcabe7b8 100644 --- a/packages/strapi-plugin-content-type-builder/admin/src/components/HeaderNavLink/index.js +++ b/packages/strapi-plugin-content-type-builder/admin/src/components/HeaderNavLink/index.js @@ -11,12 +11,19 @@ import pluginId from '../../pluginId'; import Wrapper from './Wrapper'; /* istanbul ignore next */ -function HeaderNavLink({ custom, id, isActive, onClick }) { +function HeaderNavLink({ custom, isDisabled, id, isActive, onClick }) { return ( onClick(id)} + onClick={e => { + if (isDisabled) { + e.preventDefault(); + + return; + } + onClick(id); + }} > import('../ListView')); @@ -18,7 +19,7 @@ import RecursivePath from '../RecursivePath'; const App = () => { return ( - + }> { +const DataManagerProvider = ({ allIcons, children }) => { const [reducerState, dispatch] = useReducer(reducer, initialState, init); const { components, @@ -126,7 +126,6 @@ const DataManagerProvider = ({ children }) => { }; const removeComponentFromDynamicZone = (dzName, componentToRemoveIndex) => { - console.log({ dzName, componentToRemoveIndex }); dispatch({ type: 'REMOVE_COMPONENT_FROM_DYNAMIC_ZONE', dzName, @@ -201,6 +200,7 @@ const DataManagerProvider = ({ children }) => { components, contentTypes, createSchema, + allIcons, initialData, isInContentTypeView, modifiedData, @@ -226,6 +226,7 @@ const DataManagerProvider = ({ children }) => { }; DataManagerProvider.propTypes = { + allIcons: PropTypes.array.isRequired, children: PropTypes.node.isRequired, }; diff --git a/packages/strapi-plugin-content-type-builder/admin/src/containers/DataManagerProvider/reducer.js b/packages/strapi-plugin-content-type-builder/admin/src/containers/DataManagerProvider/reducer.js index 60c1844aa0..4d77c5c778 100644 --- a/packages/strapi-plugin-content-type-builder/admin/src/containers/DataManagerProvider/reducer.js +++ b/packages/strapi-plugin-content-type-builder/admin/src/containers/DataManagerProvider/reducer.js @@ -28,6 +28,8 @@ const reducer = (state, action) => { forTarget, targetUid, } = action; + delete rest.createComponent; + const pathToDataToEdit = ['component', 'contentType'].includes(forTarget) ? [forTarget] : [forTarget, targetUid]; diff --git a/packages/strapi-plugin-content-type-builder/admin/src/containers/FormModal/index.js b/packages/strapi-plugin-content-type-builder/admin/src/containers/FormModal/index.js index 74d7dd40d3..c25efd8b38 100644 --- a/packages/strapi-plugin-content-type-builder/admin/src/containers/FormModal/index.js +++ b/packages/strapi-plugin-content-type-builder/admin/src/containers/FormModal/index.js @@ -233,7 +233,10 @@ const FormModal = () => { value === '' ) { val = null; - } else if (type === 'radio' && (name === 'multiple' || name === 'single')) { + } else if ( + type === 'radio' && + (name === 'multiple' || name === 'single' || name === 'createComponent') + ) { val = value === 'false' ? false : true; } else if (type === 'radio' && name === 'default') { if (value === 'false') { @@ -367,7 +370,6 @@ const FormModal = () => { ? { paddingTop: '0.5rem', paddingBottom: '3rem' } : {}; - console.log({ formModal: modifiedData }); return ( { {NAVLINKS.map((link, index) => { return ( { ); } + if (input.type === 'spacer') { + return ( +
+ ); + } + if (input.type === 'relation') { return ( { let dataToSet; - if (attributeType === 'dynamiczone') { - dataToSet = { type: 'dynamiczone', components: [] }; + if (attributeType === 'component') { + dataToSet = { + type: 'component', + createComponent: true, + componentToCreate: { type: 'component' }, + }; + } else if (attributeType === 'dynamiczone') { + dataToSet = { + type: 'dynamiczone', + components: [], + }; } else if (attributeType === 'text') { dataToSet = { type: 'string' }; } else if (attributeType === 'number' || attributeType === 'date') { diff --git a/packages/strapi-plugin-content-type-builder/admin/src/containers/FormModal/utils/componentForm.js b/packages/strapi-plugin-content-type-builder/admin/src/containers/FormModal/utils/componentForm.js new file mode 100644 index 0000000000..4c55b360fb --- /dev/null +++ b/packages/strapi-plugin-content-type-builder/admin/src/containers/FormModal/utils/componentForm.js @@ -0,0 +1,50 @@ +import getTrad from '../../../utils/getTrad'; + +const componentForm = { + base(prefix = '') { + const items = [ + [ + { + autoFocus: true, + name: `${prefix}name`, + type: 'text', + label: { + id: getTrad('modalForm.attribute.form.base.name'), + }, + description: { + id: getTrad('modalForm.attribute.form.base.name.description'), + }, + validations: { + required: true, + }, + }, + { + autoFocus: true, + name: 'category', + type: 'creatableSelect', + label: { + id: getTrad('modalForm.components.create-component.category.label'), + }, + validations: { + required: true, + }, + }, + ], + [ + { + name: `${prefix}icon`, + type: 'componentIconPicker', + size: 12, + label: { + id: getTrad('modalForm.components.icon.label'), + }, + }, + ], + ]; + + return items; + }, + advanced() {}, +}; + +export default componentForm; diff --git a/packages/strapi-plugin-content-type-builder/admin/src/containers/FormModal/utils/forms.js b/packages/strapi-plugin-content-type-builder/admin/src/containers/FormModal/utils/forms.js index 8eccac1757..16a11b98c1 100644 --- a/packages/strapi-plugin-content-type-builder/admin/src/containers/FormModal/utils/forms.js +++ b/packages/strapi-plugin-content-type-builder/admin/src/containers/FormModal/utils/forms.js @@ -6,6 +6,7 @@ import { FormattedMessage } from 'react-intl'; import pluginId from '../../../pluginId'; import getTrad from '../../../utils/getTrad'; import { createComponentUid, createUid, nameToSlug } from './createUid'; +import componentForm from './componentForm'; yup.addMethod(yup.mixed, 'defined', function() { return this.test( @@ -54,6 +55,7 @@ const forms = { isEditing, attributeToEditName, initialData + // componentCategory ) { const alreadyTakenAttributes = Object.keys( get(currentSchema, ['schema', 'attributes'], {}) @@ -153,6 +155,8 @@ const forms = { }; switch (attributeType) { + case 'component': + return yup.object(); case 'dynamiczone': return yup.object().shape({ ...commonShape, @@ -494,6 +498,52 @@ const forms = { ], ]; + if (type === 'component') { + const itemsToConcat = + data.createComponent === true + ? [[{ type: 'spacer' }]].concat( + componentForm.base('componentToCreate.') + ) + : []; + + return { + items: [ + [ + { + label: { + id: getTrad('modalForm.attribute.text.type-selection'), + }, + name: 'createComponent', + type: 'booleanBox', + size: 12, + options: [ + { + headerId: getTrad( + `form.attribute.component.option.create` + ), + descriptionId: getTrad( + `form.attribute.component.option.create.description` + ), + value: true, + }, + { + headerId: getTrad( + `form.attribute.component.option.reuse-existing` + ), + descriptionId: getTrad( + `form.attribute.${type}.option.reuse-existing.description` + ), + value: false, + }, + ], + validations: {}, + }, + ], + ...itemsToConcat, + ], + }; + } + if (type === 'text' || type === 'media') { items.push([ { @@ -724,7 +774,7 @@ const forms = { .required(errorsTrads.required), category: yup.string().required(errorsTrads.required), icon: yup.string().required(errorsTrads.required), - collectionName: yup.string(), + collectionName: yup.string().nullable(), }); }, form: { @@ -749,50 +799,8 @@ const forms = { }; }, base() { - const defaultItems = [ - [ - { - autoFocus: true, - name: 'name', - type: 'text', - label: { - id: getTrad('modalForm.attribute.form.base.name'), - }, - description: { - id: getTrad('modalForm.attribute.form.base.name.description'), - }, - validations: { - required: true, - }, - }, - { - autoFocus: true, - name: 'category', - type: 'creatableSelect', - label: { - id: getTrad( - 'modalForm.components.create-component.category.label' - ), - }, - validations: { - required: true, - }, - }, - ], - [ - { - name: 'icon', - type: 'componentIconPicker', - size: 12, - label: { - id: getTrad('modalForm.components.icon.label'), - }, - }, - ], - ]; - return { - items: defaultItems, + items: componentForm.base(), }; }, }, diff --git a/packages/strapi-plugin-content-type-builder/admin/src/translations/en.json b/packages/strapi-plugin-content-type-builder/admin/src/translations/en.json index d1c7aebe22..e747da5b2e 100644 --- a/packages/strapi-plugin-content-type-builder/admin/src/translations/en.json +++ b/packages/strapi-plugin-content-type-builder/admin/src/translations/en.json @@ -210,6 +210,10 @@ "modalForm.attribute.form.base.name.description": "No space is allowed for the name of the attribute", "modalForm.attribute.text.type-selection": "Type", + "form.attribute.component.option.create": "Create a new component", + "form.attribute.component.option.create.description": "A component is shared across types, it will be available and accessible in your other components and content types as well.", + "form.attribute.component.option.reuse-existing": "Use an existing component", + "form.attribute.component.option.reuse-existing.description": "Reuse a component already created to keep your data consistent across content types.", "form.attribute.item.defineRelation.fieldName": "Field name", "form.attribute.item.settings.name": "Settings", "form.attribute.item.date.type.date": "date",