Skip to content

Commit

Permalink
Added BlockToolbar for copy/paste inside a column
Browse files Browse the repository at this point in the history
  • Loading branch information
razvanMiu committed Mar 22, 2021
1 parent 17d4fa8 commit fb8f600
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 12 deletions.
120 changes: 109 additions & 11 deletions src/ColumnsBlock/ColumnsBlockEdit.jsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import React from 'react';
import { Grid, Segment } from 'semantic-ui-react';
import { isEmpty } from 'lodash';
import { SidebarPortal, Icon } from '@plone/volto/components'; // BlocksForm, Icon,
import { isEmpty, without } from 'lodash';
import { SidebarPortal, BlocksToolbar, Icon } from '@plone/volto/components'; // BlocksForm, Icon,
import InlineForm from '@plone/volto/components/manage/Form/InlineForm';
import { emptyBlocksForm } from '@plone/volto/helpers';
import {
emptyBlocksForm,
getBlocksLayoutFieldname,
} from '@plone/volto/helpers';
import { setSidebarTab } from '@plone/volto/actions';
import { connect } from 'react-redux';
import { BlocksForm } from '@plone/volto/components';
Expand Down Expand Up @@ -44,6 +47,7 @@ class ColumnsBlockEdit extends React.Component {
constructor(props) {
super(props);
this.state = {
multiSelected: [],
colSelections: {}, // selected block for each column
showSidebar: false,
activeColumn: null,
Expand Down Expand Up @@ -154,6 +158,58 @@ class ColumnsBlockEdit extends React.Component {
}
};

onSelectBlock = (
id,
colId,
colData,
activeBlock,
isMultipleSelection,
event,
) => {
let newMultiSelected = [];
let selected = id;

if (isMultipleSelection) {
selected = null;
const blocksLayoutFieldname = getBlocksLayoutFieldname(colData);

const blocks_layout = colData[blocksLayoutFieldname].items;

if (event.shiftKey) {
const anchor =
this.state.multiSelected.length > 0
? blocks_layout.indexOf(this.state.multiSelected[0])
: blocks_layout.indexOf(activeBlock);
const focus = blocks_layout.indexOf(id);

if (anchor === focus) {
newMultiSelected = [id];
} else if (focus > anchor) {
newMultiSelected = [...blocks_layout.slice(anchor, focus + 1)];
} else {
newMultiSelected = [...blocks_layout.slice(focus, anchor + 1)];
}
}

if ((event.ctrlKey || event.metaKey) && !event.shiftKey) {
if (this.state.multiSelected.includes(id)) {
selected = null;
newMultiSelected = without(this.state.multiSelected, id);
} else {
newMultiSelected = [...(this.state.multiSelected || []), id];
}
}
}

this.setState({
multiSelected: newMultiSelected,
colSelections: {
// this invalidates selection in all other columns
[colId]: selected,
},
});
};

getColumnsBlockSchema = () => {
const schema = ColumnsBlockSchema();
const { data } = this.props;
Expand Down Expand Up @@ -226,6 +282,12 @@ class ColumnsBlockEdit extends React.Component {
const { gridCols, gridSize } = data;
const coldata = data.data;
const columnList = getColumns(coldata);
const selectedCol =
Object.keys(this.state.colSelections).length > 0
? Object.keys(this.state.colSelections)[0]
: null;
const selectedColData = coldata.blocks[selectedCol] || null;
const selectedBlock = this.state.colSelections[selectedCol];

const {
gridSizes,
Expand Down Expand Up @@ -284,14 +346,21 @@ class ColumnsBlockEdit extends React.Component {
selectedBlock={
selected ? this.state.colSelections[colId] : null
}
onSelectBlock={(id) =>
this.setState({
colSelections: {
// this invalidates selection in all other columns
[colId]: id,
},
})
}
onSelectBlock={(id, selected, e) => {
const isMultipleSelection = e
? e.shiftKey || e.ctrlKey || e.metaKey
: false;
this.onSelectBlock(
id,
colId,
selectedColData,
selectedBlock,
selectedCol !== colId || selectedBlock === id
? false
: isMultipleSelection,
e,
);
}}
onChangeFormData={(newFormData) => {
onChangeBlock(block, {
...data,
Expand Down Expand Up @@ -334,6 +403,9 @@ class ColumnsBlockEdit extends React.Component {
)}
</>
}
multiSelected={this.state.multiSelected.includes(
blockProps.block,
)}
>
{editBlock}
</EditBlockWrapper>
Expand All @@ -344,6 +416,32 @@ class ColumnsBlockEdit extends React.Component {
</Grid>
)}

{selected && selectedColData ? (
<BlocksToolbar
formData={selectedColData}
selectedBlock={selectedBlock}
selectedBlocks={this.state.multiSelected}
onChangeBlocks={(newBlockData) => {
onChangeBlock(block, {
...data,
data: {
...coldata,
blocks: {
...coldata.blocks,
[selectedCol]: { ...selectedColData, ...newBlockData },
},
},
});
}}
onSetSelectedBlocks={(blockIds) => {
this.setState({ multiSelected: blockIds });
}}
onSelectBlock={this.onSelectBlock}
/>
) : (
''
)}

{Object.keys(this.state.colSelections).length === 0 &&
!data?.readOnlySettings ? (
<SidebarPortal selected={selected}>
Expand Down
9 changes: 8 additions & 1 deletion src/ColumnsBlock/EditBlockWrapper.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import includes from 'lodash/includes';
import isBoolean from 'lodash/isBoolean';
import { defineMessages, injectIntl } from 'react-intl';
import { doesNodeContainClick } from 'semantic-ui-react/dist/commonjs/lib';
import cx from 'classnames';

import dragSVG from '@plone/volto/icons/drag.svg';
import addSVG from '@plone/volto/icons/circle-plus.svg';
Expand Down Expand Up @@ -148,7 +149,13 @@ class EditBlockWrapper extends React.Component {
</div>
)}

<div className={`ui drag block inner ${type}`}>{children}</div>
<div
className={cx('ui drag block wrapper inner', type, {
multiSelected: this.props.multiSelected,
})}
>
{children}
</div>
</div>
</div>
);
Expand Down
7 changes: 7 additions & 0 deletions src/ColumnsBlock/styles.less
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,13 @@
[data-rbd-draggable-context-id] {
margin-bottom: 0.3em;
}

.block.wrapper.multiSelected {
.block .block::before {
z-index: 1;
background-color: rgba(120, 192, 215, 0.375);
}
}
}

.columns-view {
Expand Down

0 comments on commit fb8f600

Please sign in to comment.