From 859b1e7eea822babd438dad44891738d07e4cf2f Mon Sep 17 00:00:00 2001 From: Jefferson Bledsoe Date: Tue, 22 Nov 2022 01:02:11 +0000 Subject: [PATCH] Spacing fixes for sections and views (#65) --- src/config/settings.js | 9 ++ .../volto-form-block/components/FormView.jsx | 7 +- .../components/theme/View/DefaultView.jsx | 107 ++++++++++++---- .../volto/components/theme/View/EventView.jsx | 121 ++++++++++++++++++ .../theme/View/EventView.original.jsx | 117 +++++++++++++++++ .../volto/components/theme/View/ImageView.jsx | 74 +++++++++++ .../theme/View/ImageView.original.jsx | 71 ++++++++++ .../components/theme/View/NewsItemView.jsx | 83 ++++++++++++ .../theme/View/NewsItemView.original.jsx | 76 +++++++++++ 9 files changed, 631 insertions(+), 34 deletions(-) create mode 100644 src/customizations/volto/components/theme/View/EventView.jsx create mode 100644 src/customizations/volto/components/theme/View/EventView.original.jsx create mode 100644 src/customizations/volto/components/theme/View/ImageView.jsx create mode 100644 src/customizations/volto/components/theme/View/ImageView.original.jsx create mode 100644 src/customizations/volto/components/theme/View/NewsItemView.jsx create mode 100644 src/customizations/volto/components/theme/View/NewsItemView.original.jsx diff --git a/src/config/settings.js b/src/config/settings.js index 6a778f3d..0da103a7 100644 --- a/src/config/settings.js +++ b/src/config/settings.js @@ -1,5 +1,14 @@ export const updateSettingsConfig = (config) => { config.settings.navDepth = 2; + + config.settings.fullWidthBlockTypes = [ + 'hero', + 'nsw_section', + 'nsw_inPageAlert', + 'nsw_announcementBar', + 'form', + ...(config.settings.fullWidthBlockTypes || []), + ]; }; export default updateSettingsConfig; diff --git a/src/customizations/volto-form-block/components/FormView.jsx b/src/customizations/volto-form-block/components/FormView.jsx index ce3057ca..d1af2049 100644 --- a/src/customizations/volto-form-block/components/FormView.jsx +++ b/src/customizations/volto-form-block/components/FormView.jsx @@ -80,12 +80,7 @@ const FormView = ({ ) : ( // TODO: The original component has a `loading` state. Is this needed here? -
+ {data.static_fields?.map((field) => { return ( { return []; } + const coreContentBlockTypes = Object.keys(config.blocks.blocksConfig).filter( + (blockId) => { + if (fullWidthContentBlocks.includes(blockId)) { + return true; + } else if (config.settings.fullWidthBlockTypes.includes(blockId)) { + return false; + } + return true; + }, + ); + return blocksInLayout?.reduce((result, currentBlockId) => { // Handles the messy case where a block is not in the layout // but is stored. This is a rare case, but it happens. @@ -81,11 +78,7 @@ const getCoreContentGroupedLayout = (blocksInLayout, blocksData) => { sectionFields.map((k) => [k, currentBlock?.[k]]), ); - if ( - currentBlockSectionData.sectionType === 'sameAsPrevious' || - JSON.stringify(previousBlockSectionData) === - JSON.stringify(currentBlockSectionData) - ) { + if (currentBlockSectionData.sectionType === 'sameAsPrevious') { previousBlockOrGroup.push(currentBlockId); result.splice(result.length - 1, 1, previousBlockOrGroup); } else { @@ -151,25 +144,83 @@ const BlocksLayout = ({ content, location }) => { blocksData, ); + const blocksNeedSections = Object.values(blocksData).some( + (blockData) => + _blockNeedsSection(blockData) || + config.settings.fullWidthBlockTypes.includes(blockData['@type']), + ); + + // Below block of code is all needed for `hideTopPadding?` + const breadcrumbStartDepth = useSelector( + (state) => state.nswSiteSettings?.data?.breadcrumb_start_depth, + ); + const siteDepth = useSelector( + (state) => state.nswSiteSettings?.data?.site_depth, + ); + const breadcrumbsHidden = + location.pathname === '/' || siteDepth < breadcrumbStartDepth; + const hideTopPadding = + config.settings.fullWidthBlockTypes.includes( + blocksData[blocksInLayout[0]]?.['@type'], + ) === breadcrumbsHidden; + return (
{groupedBlocksLayout.map((blockIdOrGroup, index) => { if (blockIdOrGroup instanceof Array) { const blockGroup = blockIdOrGroup; // Rename it just to make the code more readable - if (_blockNeedsSection(blocksData?.[blockGroup[0]])) { + if (blocksNeedSections) { const blockWithSectionData = blocksData?.[blockGroup[0]]; const sectionColour = getSectionColour(blockWithSectionData); + if (_blockNeedsSection(blockWithSectionData)) { + return ( +
+ {blockGroup.map((blockId) => { + // Copy pasted from below. Should really make this a function! + const blockData = blocksData?.[blockId]; + const blockType = blockData?.['@type']; + const Block = + config.blocks.blocksConfig[blockType]?.['view'] || + null; + return Block !== null ? ( + + ) : ( +
+ {intl.formatMessage(messages.unknownBlock, { + block: blockType, + })} +
+ ); + })} +
+ ); + } + return (
{
); } - return fullWidthBlockTypes.includes(blockType) ? ( + return config.settings.fullWidthBlockTypes.includes(blockType) ? ( ( + + {content.title &&

{content.title}

} + {content.description && ( +

{content.description}

+ )} + {content.image && ( + + )} + {content.text && ( +
+ )} + +); + +/** + * EventView view component class. + * @function EventView + * @params {object} content Content object. + * @returns {string} Markup of the component. + */ +const EventView = (props) => { + const { content } = props; + + return ( +
+
+
+ + + {hasBlocksData(content) ? ( + + ) : ( + + )} + + + + + + {hasBlocksData(content) ? ( + <> + + + + + ) : ( + + )} + + +
+
+
+ ); +}; + +/** + * Property types. + * @property {Object} propTypes Property types. + * @static + */ +EventView.propTypes = { + content: PropTypes.shape({ + title: PropTypes.string, + description: PropTypes.string, + text: PropTypes.shape({ + data: PropTypes.string, + }), + attendees: PropTypes.arrayOf(PropTypes.string).isRequired, + contact_email: PropTypes.string, + contact_name: PropTypes.string, + contact_phone: PropTypes.string, + end: PropTypes.string.isRequired, + event_url: PropTypes.string, + location: PropTypes.string, + open_end: PropTypes.bool, + recurrence: PropTypes.any, + start: PropTypes.string.isRequired, + subjects: PropTypes.arrayOf(PropTypes.string).isRequired, + whole_day: PropTypes.bool, + }).isRequired, +}; + +export default EventView; diff --git a/src/customizations/volto/components/theme/View/EventView.original.jsx b/src/customizations/volto/components/theme/View/EventView.original.jsx new file mode 100644 index 00000000..7d44d33c --- /dev/null +++ b/src/customizations/volto/components/theme/View/EventView.original.jsx @@ -0,0 +1,117 @@ +/** + * EventView view component. + * @module components/theme/View/EventView + */ + +import React from 'react'; +import PropTypes from 'prop-types'; +import { hasBlocksData, flattenHTMLToAppURL } from '@plone/volto/helpers'; +import { Image, Grid } from 'semantic-ui-react'; +import RenderBlocks from '@plone/volto/components/theme/View/RenderBlocks'; +import { EventDetails } from '@plone/volto/components'; + +const EventTextfieldView = ({ content }) => ( + + {content.title &&

{content.title}

} + {content.description && ( +

{content.description}

+ )} + {content.image && ( + + )} + {content.text && ( +
+ )} + +); + +/** + * EventView view component class. + * @function EventView + * @params {object} content Content object. + * @returns {string} Markup of the component. + */ +const EventView = (props) => { + const { content } = props; + + return ( +
+ + + {hasBlocksData(content) ? ( + + ) : ( + + )} + + + + + + {hasBlocksData(content) ? ( + <> + + + + + ) : ( + + )} + + +
+ ); +}; + +/** + * Property types. + * @property {Object} propTypes Property types. + * @static + */ +EventView.propTypes = { + content: PropTypes.shape({ + title: PropTypes.string, + description: PropTypes.string, + text: PropTypes.shape({ + data: PropTypes.string, + }), + attendees: PropTypes.arrayOf(PropTypes.string).isRequired, + contact_email: PropTypes.string, + contact_name: PropTypes.string, + contact_phone: PropTypes.string, + end: PropTypes.string.isRequired, + event_url: PropTypes.string, + location: PropTypes.string, + open_end: PropTypes.bool, + recurrence: PropTypes.any, + start: PropTypes.string.isRequired, + subjects: PropTypes.arrayOf(PropTypes.string).isRequired, + whole_day: PropTypes.bool, + }).isRequired, +}; + +export default EventView; diff --git a/src/customizations/volto/components/theme/View/ImageView.jsx b/src/customizations/volto/components/theme/View/ImageView.jsx new file mode 100644 index 00000000..25f19eba --- /dev/null +++ b/src/customizations/volto/components/theme/View/ImageView.jsx @@ -0,0 +1,74 @@ +/** + * Image view component. + * @module components/theme/View/ImageView + */ + +import React from 'react'; +import PropTypes from 'prop-types'; +import { FormattedMessage } from 'react-intl'; +import prettybytes from 'pretty-bytes'; + +import { flattenToAppURL } from '@plone/volto/helpers'; + +/** + * Image view component class. + * @function ImageView + * @params {object} content Content object. + * @returns {string} Markup of the component. + */ +const ImageView = ({ content }) => ( +
+
+
+

+ {content.title} + {content.subtitle && ` - ${content.subtitle}`} +

+ {content.description && ( +

{content.description}

+ )} + {content?.image?.download && ( + + {content.title} +
+ +   —   + +
+
+ )} +
+
+
+); + +/** + * Property types. + * @property {Object} propTypes Property types. + * @static + */ +ImageView.propTypes = { + content: PropTypes.shape({ + title: PropTypes.string, + description: PropTypes.string, + image: PropTypes.shape({ + scales: PropTypes.shape({ + preview: PropTypes.shape({ + download: PropTypes.string, + }), + }), + }), + }).isRequired, +}; + +export default ImageView; diff --git a/src/customizations/volto/components/theme/View/ImageView.original.jsx b/src/customizations/volto/components/theme/View/ImageView.original.jsx new file mode 100644 index 00000000..b3bc1d59 --- /dev/null +++ b/src/customizations/volto/components/theme/View/ImageView.original.jsx @@ -0,0 +1,71 @@ +/** + * Image view component. + * @module components/theme/View/ImageView + */ + +import React from 'react'; +import PropTypes from 'prop-types'; +import { Container } from 'semantic-ui-react'; +import { FormattedMessage } from 'react-intl'; +import prettybytes from 'pretty-bytes'; + +import { flattenToAppURL } from '@plone/volto/helpers'; + +/** + * Image view component class. + * @function ImageView + * @params {object} content Content object. + * @returns {string} Markup of the component. + */ +const ImageView = ({ content }) => ( + +

+ {content.title} + {content.subtitle && ` - ${content.subtitle}`} +

+ {content.description && ( +

{content.description}

+ )} + {content?.image?.download && ( + + {content.title} +
+ +   —   + +
+
+ )} +
+); + +/** + * Property types. + * @property {Object} propTypes Property types. + * @static + */ +ImageView.propTypes = { + content: PropTypes.shape({ + title: PropTypes.string, + description: PropTypes.string, + image: PropTypes.shape({ + scales: PropTypes.shape({ + preview: PropTypes.shape({ + download: PropTypes.string, + }), + }), + }), + }).isRequired, +}; + +export default ImageView; diff --git a/src/customizations/volto/components/theme/View/NewsItemView.jsx b/src/customizations/volto/components/theme/View/NewsItemView.jsx new file mode 100644 index 00000000..e58c5805 --- /dev/null +++ b/src/customizations/volto/components/theme/View/NewsItemView.jsx @@ -0,0 +1,83 @@ +/** + * NewsItemView view component. + * @module components/theme/View/NewsItemView + */ + +import React from 'react'; +import PropTypes from 'prop-types'; +import { Image } from 'semantic-ui-react'; +import { + hasBlocksData, + flattenToAppURL, + flattenHTMLToAppURL, +} from '@plone/volto/helpers'; +import RenderBlocks from '@plone/volto/components/theme/View/RenderBlocks'; + +/** + * NewsItemView view component class. + * @function NewsItemView + * @params {object} content Content object. + * @returns {string} Markup of the component. + */ +const NewsItemView = ({ content }) => { + return ( +
+
+
+ {hasBlocksData(content) ? ( + + ) : ( + <> + {content.title && ( +

+ {content.title} + {content.subtitle && ` - ${content.subtitle}`} +

+ )} + {content.description && ( +

{content.description}

+ )} + {content.image && ( + {content.title} + )} + {content.text && ( +
+ )} + + )} +
+
+
+ ); +}; + +/** + * Property types. + * @property {Object} propTypes Property types. + * @static + */ +NewsItemView.propTypes = { + content: PropTypes.shape({ + title: PropTypes.string, + description: PropTypes.string, + text: PropTypes.shape({ + data: PropTypes.string, + }), + }).isRequired, +}; + +export default NewsItemView; diff --git a/src/customizations/volto/components/theme/View/NewsItemView.original.jsx b/src/customizations/volto/components/theme/View/NewsItemView.original.jsx new file mode 100644 index 00000000..6415dda5 --- /dev/null +++ b/src/customizations/volto/components/theme/View/NewsItemView.original.jsx @@ -0,0 +1,76 @@ +/** + * NewsItemView view component. + * @module components/theme/View/NewsItemView + */ + +import React from 'react'; +import PropTypes from 'prop-types'; +import { Container, Image } from 'semantic-ui-react'; +import { + hasBlocksData, + flattenToAppURL, + flattenHTMLToAppURL, +} from '@plone/volto/helpers'; +import RenderBlocks from '@plone/volto/components/theme/View/RenderBlocks'; + +/** + * NewsItemView view component class. + * @function NewsItemView + * @params {object} content Content object. + * @returns {string} Markup of the component. + */ +const NewsItemView = ({ content }) => + hasBlocksData(content) ? ( +
+ +
+ ) : ( + + {content.title && ( +

+ {content.title} + {content.subtitle && ` - ${content.subtitle}`} +

+ )} + {content.description && ( +

{content.description}

+ )} + {content.image && ( + {content.title} + )} + {content.text && ( +
+ )} + + ); + +/** + * Property types. + * @property {Object} propTypes Property types. + * @static + */ +NewsItemView.propTypes = { + content: PropTypes.shape({ + title: PropTypes.string, + description: PropTypes.string, + text: PropTypes.shape({ + data: PropTypes.string, + }), + }).isRequired, +}; + +export default NewsItemView;