diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..211dab2 --- /dev/null +++ b/.npmignore @@ -0,0 +1,16 @@ +.vscode/ +.history +logs +*.log +npm-debug.log* +.DS_Store +*.swp +yarn-error.log + +node_modules +build +dist +.env.local +.env.development.local +.env.test.local +.env.production.local diff --git a/package.json b/package.json new file mode 100644 index 0000000..32da33e --- /dev/null +++ b/package.json @@ -0,0 +1,15 @@ +{ + "name": "@codesyntax/volto-listingadvanced-variation", + "version": "0.0.1", + "description": "volto-listingadvanced-variation: Volto add-on", + "main": "src/index.js", + "license": "MIT", + "keywords": [ + "volto-addon", + "volto-variation", + "volto-listing-block", + "volto", + "plone", + "react" + ] +} \ No newline at end of file diff --git a/src/AdvancedListingBlockTemplate.jsx b/src/AdvancedListingBlockTemplate.jsx new file mode 100644 index 0000000..3cb450c --- /dev/null +++ b/src/AdvancedListingBlockTemplate.jsx @@ -0,0 +1,109 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { ConditionalLink } from '@plone/volto/components'; +import { flattenToAppURL } from '@plone/volto/helpers'; +import config from '@plone/volto/registry'; + +import DefaultImageSVG from '@plone/volto/components/manage/Blocks/Listing/default-image.svg'; +import { isInternalURL } from '@plone/volto/helpers/Url/Url'; +import { Grid, Image } from 'semantic-ui-react'; + +const AdvancedListingBlockTemplate = ({ + items, + linkTitle, + linkHref, + isEditMode, + imageSide, + imageWidth, + howManyColumns, + titleTag, +}) => { + let link = null; + let href = linkHref?.[0]?.['@id'] || ''; + if (isInternalURL(href)) { + link = ( + + {linkTitle || href} + + ); + } else if (href) { + link = {linkTitle || href}; + } + + const { settings } = config; + const hasImage = imageSide !== null; + imageWidth = imageWidth ? imageWidth : 2; + return ( + <> + + {items.map((item) => ( + + + + {imageSide === 'left' && ( + + {!item[settings.listingPreviewImageField] && ( + This content has no image, this is a default placeholder. + )} + {item[settings.listingPreviewImageField] && ( + {item.title} + )} + + )} + + {titleTag ? ( + titleTag(item.title ? item.title : item.id) + ) : ( +

{item.title ? item.title : item.id}

+ )} +

{item.description}

+
+ {imageSide === 'right' && ( + + {!item[settings.listingPreviewImageField] && ( + This content has no image, this is a default placeholder. + )} + {item[settings.listingPreviewImageField] && ( + {item.title} + )} + + )} +
+
+
+ ))} +
+ {link &&
{link}
} + + ); +}; + +AdvancedListingBlockTemplate.propTypes = { + items: PropTypes.arrayOf(PropTypes.any).isRequired, + linkMore: PropTypes.any, + isEditMode: PropTypes.bool, +}; + +export default AdvancedListingBlockTemplate; diff --git a/src/advancedSchema.js b/src/advancedSchema.js new file mode 100644 index 0000000..e739b26 --- /dev/null +++ b/src/advancedSchema.js @@ -0,0 +1,84 @@ +import React from 'react'; +import messages from './messages'; + +export const advancedSchema = (props) => { + const { intl, schema } = props; + + return { + ...schema, + fieldsets: [ + { + id: 'default', + title: 'Default', + fields: ['variation'], + }, + { + id: 'querystring', + title: intl.formatMessage(messages.querystring), + fields: ['querystring'], + }, + { + id: 'columns', + title: intl.formatMessage(messages.columnsConfiguration), + fields: ['howManyColumns'], + }, + { + id: 'image', + title: intl.formatMessage(messages.imageConfiguration), + fields: ['imageSide', 'imageWidth'], + }, + { + id: 'title', + title: intl.formatMessage(messages.titleConfiguration), + fields: ['titleTag'], + }, + ], + properties: { + ...schema.properties, + howManyColumns: { + title: intl.formatMessage(messages.columnsCountConfiguration), + choices: [ + [1, '1'], + [2, '2'], + [3, '3'], + [4, '4'], + ], + }, + imageWidth: { + title: intl.formatMessage(messages.imageWidthConfiguration), + description: intl.formatMessage( + messages.imageWidthConfigurationDescription, + ), + choices: [ + [2, '2/12'], + [3, '3/12'], + [4, '4/12'], + [5, '5/12'], + [6, '6/12'], + ], + }, + imageSide: { + title: intl.formatMessage(messages.imagePositionConfiguration), + description: intl.formatMessage( + messages.imagePositionConfigurationDescription, + ), + choices: [ + [null, 'No image'], + ['right', 'right'], + ['left', 'left'], + ], + }, + titleTag: { + title: intl.formatMessage(messages.titleTagConfiguration), + description: intl.formatMessage( + messages.titleTagConfigurationDescription, + ), + choices: [ + [(children) =>

{children}

, 'H2'], + [(children) =>

{children}

, 'H3'], + [(children) =>

{children}

, 'H4'], + ], + }, + }, + }; +}; diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..2b7763a --- /dev/null +++ b/src/index.js @@ -0,0 +1,17 @@ +import AdvancedListingBlockTemplate from './AdvancedListingBlockTemplate'; +import { advancedSchema } from './advancedSchema'; + +const applyConfig = (config) => { + config.blocks.blocksConfig.listing.variations = [ + ...config.blocks.blocksConfig.listing.variations, + { + id: 'advanced', + title: 'Advanced', + template: AdvancedListingBlockTemplate, + schemaEnhancer: advancedSchema, + }, + ]; + return config; +}; + +export default applyConfig; diff --git a/src/messages.js b/src/messages.js new file mode 100644 index 0000000..c33754f --- /dev/null +++ b/src/messages.js @@ -0,0 +1,49 @@ +import { defineMessages } from 'react-intl'; +const messages = defineMessages({ + querystring: { + id: 'Query', + defaultMessage: 'Query', + }, + columnsConfiguration: { + id: 'Columns configuration', + defaultMessage: 'Columns configuration', + }, + columnsCountConfiguration: { + id: 'How many columns:', + defaultMessage: 'How many columns:', + }, + imageConfiguration: { + id: 'Image position/size', + defaultMessage: 'Image position/size', + }, + imageWidthConfiguration: { + id: 'Image width (x/12):', + defaultMessage: 'Image width (x/12):', + }, + imageWidthConfigurationDescription: { + id: 'Default image width will be 2/12', + defaultMessage: 'Default image width will be 2/12', + }, + imagePositionConfiguration: { + id: 'Image position:', + defaultMessage: 'Image position:', + }, + imagePositionConfigurationDescription: { + id: 'Default with no image', + defaultMessage: 'Default with no image', + }, + titleConfiguration: { + id: 'Title configuration', + defaultMessage: 'Title configuration', + }, + titleTagConfiguration: { + id: 'Title text HTML tag', + defaultMessage: 'Title text HTML tag', + }, + titleTagConfigurationDescription: { + id: 'Default HTML tag will be H3', + defaultMessage: 'Default HTML tag will be H3', + }, +}); + +export default messages;