Skip to content

Commit

Permalink
feat(group): Variations support refs #157040 #26 from eea/variationsS…
Browse files Browse the repository at this point in the history
…upport
  • Loading branch information
ichim-david committed Aug 30, 2023
2 parents 763f764 + f9bc97d commit 8342ae8
Show file tree
Hide file tree
Showing 6 changed files with 168 additions and 102 deletions.
1 change: 1 addition & 0 deletions src/components/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { default as GroupBlockDefaultBody } from './manage/Blocks/Group/DefaultBody';
export { default as GroupBlockEdit } from './manage/Blocks/Group/Edit';
export { default as GroupBlockView } from './manage/Blocks/Group/View';
export { default as GroupBlockLayout } from './manage/Blocks/Group/LayoutSchema';
17 changes: 17 additions & 0 deletions src/components/manage/Blocks/Group/Body.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from 'react';
import PropTypes from 'prop-types';
import { GroupBlockDefaultBody } from '@eeacms/volto-group-block/components';

const Body = (props) => {
const { variation } = props;

const BodyComponent = variation?.template || GroupBlockDefaultBody;

return <BodyComponent {...props} />;
};

Body.propTypes = {
variation: PropTypes.objectOf(PropTypes.any).isRequired,
};

export default Body;
105 changes: 105 additions & 0 deletions src/components/manage/Blocks/Group/DefaultBody.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { Button } from 'semantic-ui-react';
import { BlocksForm, Icon, RenderBlocks } from '@plone/volto/components';
import EditBlockWrapper from './EditBlockWrapper';

import helpSVG from '@plone/volto/icons/help.svg';

const GroupBlockDefaultBody = (props) => {
const {
block,
data,
onChangeBlock,
onChangeField,
pathname,
selected,
selectedBlock,
onSelectBlock,
setSelectedBlock,
manage,
childBlocksForm,
multiSelected,
formDescription,
isEditMode,
} = props;
const metadata = props.metadata || props.properties;
const blockState = {};

// Get editing instructions from block settings or props
let instructions = data?.instructions?.data || data?.instructions;
if (!instructions || instructions === '<p><br/></p>') {
instructions = formDescription;
}
return isEditMode ? (
<BlocksForm
metadata={metadata}
properties={childBlocksForm}
manage={manage}
selectedBlock={selected ? selectedBlock : null}
allowedBlocks={data.allowedBlocks}
title={data.placeholder}
description={instructions}
onSelectBlock={(id, l, e) => {
const isMultipleSelection = e
? e.shiftKey || e.ctrlKey || e.metaKey
: false;
onSelectBlock(id, isMultipleSelection, e, selectedBlock);
}}
onChangeFormData={(newFormData) => {
onChangeBlock(block, {
...data,
data: newFormData,
});
}}
onChangeField={(id, value) => {
if (['blocks', 'blocks_layout'].indexOf(id) > -1) {
blockState[id] = value;
onChangeBlock(block, {
...data,
data: {
...data.data,
...blockState,
},
});
} else {
onChangeField(id, value);
}
}}
pathname={pathname}
>
{({ draginfo }, editBlock, blockProps) => (
<EditBlockWrapper
draginfo={draginfo}
blockProps={blockProps}
disabled={data.disableInnerButtons}
extraControls={
<>
{instructions && (
<>
<Button
icon
basic
title="Section help"
onClick={() => {
setSelectedBlock();
const tab = manage ? 0 : 1;
props.setSidebarTab(tab);
}}
>
<Icon name={helpSVG} className="" size="19px" />
</Button>
</>
)}
</>
}
multiSelected={multiSelected.includes(blockProps.block)}
>
{editBlock}
</EditBlockWrapper>
)}
</BlocksForm>
) : (
<RenderBlocks {...props} metadata={metadata} content={data?.data || {}} />
);
};

export default GroupBlockDefaultBody;
123 changes: 27 additions & 96 deletions src/components/manage/Blocks/Group/Edit.jsx
Original file line number Diff line number Diff line change
@@ -1,46 +1,35 @@
import React, { useState, useCallback } from 'react';
import { isEmpty, without } from 'lodash';
import {
emptyBlocksForm,
withBlockExtensions,
getBlocksLayoutFieldname,
} from '@plone/volto/helpers';
import BodyComponent from './Body';

import config from '@plone/volto/registry';
import {
BlocksForm,
SidebarPortal,
Icon,
BlockDataForm,
BlocksToolbar,
} from '@plone/volto/components';
import {
emptyBlocksForm,
getBlocksLayoutFieldname,
} from '@plone/volto/helpers';
import PropTypes from 'prop-types';
import { Button, Segment } from 'semantic-ui-react';
import EditBlockWrapper from './EditBlockWrapper';
import { Segment } from 'semantic-ui-react';
import EditSchema from './EditSchema';

import CounterComponent from './CounterComponent';
import helpSVG from '@plone/volto/icons/help.svg';
import './editor.less';

const Edit = (props) => {
const {
block,
data,
onChangeBlock,
onChangeField,
pathname,
selected,
manage,
formDescription,
} = props;
const metadata = props.metadata || props.properties;
const { block, data, onChangeBlock, selected, formDescription } = props;
const [multiSelected, setMultiSelected] = useState([]);
const data_blocks = data?.data?.blocks;
const properties = isEmpty(data_blocks) ? emptyBlocksForm() : data.data;
const childBlocksForm = isEmpty(data_blocks) ? emptyBlocksForm() : data.data;

const [selectedBlock, setSelectedBlock] = useState(
properties.blocks_layout.items[0],
childBlocksForm.blocks_layout.items[0],
);

const blockState = {};
const handleKeyDown = (
e,
index,
Expand Down Expand Up @@ -131,15 +120,15 @@ const Edit = (props) => {
React.useEffect(() => {
if (
isEmpty(data_blocks) &&
properties.blocks_layout.items[0] !== selectedBlock
childBlocksForm.blocks_layout.items[0] !== selectedBlock
) {
setSelectedBlock(properties.blocks_layout.items[0]);
setSelectedBlock(childBlocksForm.blocks_layout.items[0]);
onChangeBlock(block, {
...data,
data: properties,
data: childBlocksForm,
});
}
}, [onChangeBlock, properties, selectedBlock, block, data, data_blocks]);
}, [onChangeBlock, childBlocksForm, selectedBlock, block, data, data_blocks]);

// Get editing instructions from block settings or props
let instructions = data?.instructions?.data || data?.instructions;
Expand Down Expand Up @@ -167,6 +156,16 @@ const Edit = (props) => {
>
{data.title || 'Section'}
</legend>
<BodyComponent
{...props}
isEditMode={true}
selectedBlock={selectedBlock}
setSelectedBlock={setSelectedBlock}
multiSelected={multiSelected}
setMultiSelected={setMultiSelected}
onSelectBlock={onSelectBlock}
childBlocksForm={childBlocksForm}
/>
{selected ? (
<BlocksToolbar
selectedBlock={Object.keys(selectedBlock || {})[0]}
Expand All @@ -189,74 +188,6 @@ const Edit = (props) => {
) : (
''
)}
<BlocksForm
metadata={metadata}
properties={properties}
manage={manage}
selectedBlock={selected ? selectedBlock : null}
allowedBlocks={data.allowedBlocks}
title={data.placeholder}
description={instructions}
onSelectBlock={(id, l, e) => {
const isMultipleSelection = e
? e.shiftKey || e.ctrlKey || e.metaKey
: false;
onSelectBlock(id, isMultipleSelection, e, selectedBlock);
}}
onChangeFormData={(newFormData) => {
onChangeBlock(block, {
...data,
data: newFormData,
});
}}
onChangeField={(id, value) => {
if (['blocks', 'blocks_layout'].indexOf(id) > -1) {
blockState[id] = value;
onChangeBlock(block, {
...data,
data: {
...data.data,
...blockState,
},
});
} else {
onChangeField(id, value);
}
}}
pathname={pathname}
>
{({ draginfo }, editBlock, blockProps) => (
<EditBlockWrapper
draginfo={draginfo}
blockProps={blockProps}
disabled={data.disableInnerButtons}
extraControls={
<>
{instructions && (
<>
<Button
icon
basic
title="Section help"
onClick={() => {
setSelectedBlock();
const tab = manage ? 0 : 1;
props.setSidebarTab(tab);
}}
>
<Icon name={helpSVG} className="" size="19px" />
</Button>
</>
)}
</>
}
multiSelected={multiSelected.includes(blockProps.block)}
>
{editBlock}
</EditBlockWrapper>
)}
</BlocksForm>

{props.data.maxChars && (
<CounterComponent {...props} setSelectedBlock={setSelectedBlock} />
)}
Expand Down Expand Up @@ -293,4 +224,4 @@ Edit.propTypes = {
manage: PropTypes.bool.isRequired,
};

export default Edit;
export default withBlockExtensions(Edit);
8 changes: 4 additions & 4 deletions src/components/manage/Blocks/Group/View.jsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React from 'react';
import { RenderBlocks } from '@plone/volto/components';
import { withBlockExtensions } from '@plone/volto/helpers';
import BodyComponent from './Body';

const View = (props) => {
const { data } = props;
const metadata = props.metadata || props.properties;
const CustomTag = `${data.as || 'div'}`;
const customId = data?.title
?.toLowerCase()
Expand All @@ -12,9 +12,9 @@ const View = (props) => {
?.replace(/\s+/gi, '-');
return (
<CustomTag id={customId}>
<RenderBlocks {...props} metadata={metadata} content={data?.data || {}} />
<BodyComponent {...props} />
</CustomTag>
);
};

export default View;
export default withBlockExtensions(View);
16 changes: 14 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { getBlocks } from '@plone/volto/helpers';
import { GroupBlockEdit, GroupBlockView, GroupBlockLayout } from './components';

import {
GroupBlockEdit,
GroupBlockView,
GroupBlockLayout,
GroupBlockDefaultBody,
} from './components';
import codeSVG from '@plone/volto/icons/row.svg';

const applyConfig = (config) => {
Expand Down Expand Up @@ -45,6 +49,14 @@ const applyConfig = (config) => {
addPermission: [],
view: [],
},
variations: [
{
id: 'default',
isDefault: true,
title: 'Default',
template: GroupBlockDefaultBody,
},
],
tocEntries: (block = {}, tocData) => {
// integration with volto-block-toc
const headlines = tocData.levels || ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
Expand Down

0 comments on commit 8342ae8

Please sign in to comment.