Skip to content
This repository has been archived by the owner on Apr 25, 2024. It is now read-only.

Develop #50

Merged
merged 3 commits into from
Jan 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,16 @@ All notable changes to this project will be documented in this file. Dates are d

Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).

#### [0.1.36](https://github.com/eea/volto-forests-theme/compare/0.1.35...0.1.36)

- Copy paste edit [`332e668`](https://github.com/eea/volto-forests-theme/commit/332e6689a7182945a93289bc2a5fa7e5f8577fa2)
- Added Copy/Paste appextras [`3e752fb`](https://github.com/eea/volto-forests-theme/commit/3e752fb80be602f9d16a46494c2fd07a81add407)

#### [0.1.35](https://github.com/eea/volto-forests-theme/compare/0.1.34...0.1.35)

> 19 January 2022

- Develop [`#49`](https://github.com/eea/volto-forests-theme/pull/49)
- Stickyy [`#46`](https://github.com/eea/volto-forests-theme/pull/46)
- Merge pull request #48 from eea/fix3 [`52652b7`](https://github.com/eea/volto-forests-theme/commit/52652b7994f3ba444ea3856f36884339b2e3b81f)
- change z index so nav can be visible [`0bf5d5b`](https://github.com/eea/volto-forests-theme/commit/0bf5d5bc63485fa24a1315ecf135d2656ede4111)
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@eeacms/volto-forests-theme",
"version": "0.1.35",
"version": "0.1.36",
"description": "@eeacms/volto-forests-theme: Volto add-on",
"main": "src/index.js",
"author": "European Environment Agency: IDM2 A-Team",
Expand Down
175 changes: 175 additions & 0 deletions src/components/theme/AppExtras/CopyPaste/CopyPaste.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
import React from 'react';
import { connect } from 'react-redux';
import { compose } from 'redux';
import { Portal } from 'react-portal';
import { toast } from 'react-toastify';
import { Button } from 'semantic-ui-react';
import { getBaseUrl } from '@plone/volto/helpers';
import { updateContent } from '@plone/volto/actions';
import { Icon, Toast } from '@plone/volto/components';
import copySVG from '@plone/volto/icons/copy.svg';
import pasteSVG from '@plone/volto/icons/paste.svg';

import './style.less';

const TIMEOUT = 2000;

const CopyPaste = (props) => {
const [readyToRender, setReadyToRender] = React.useState(false);
const clock = React.useRef(null);
const time = React.useRef(0);
const toolbar = React.useRef(null);
const { content } = props;

const copyData = () => {
navigator.clipboard.writeText(
JSON.stringify({
blocks: content.blocks,
blocks_layout: content.blocks_layout,
}),
);
toast.success(
<Toast success title={'Success'} content={`Copied blocks`} />,
);
};

const pasteData = () => {
const message = [
'============= BRAKING CHANGE =============',
'\nAre you sure you want to paste from clipboard?',
'\nThis action will replace all the blocks with those from clipboard and will trigger SUBMIT !!!',
];
navigator.clipboard.readText().then((text) => {
if (
// eslint-disable-next-line no-alert
window.confirm(message.join(''))
) {
try {
const data = JSON.parse(text) || {};
const { blocks = {}, blocks_layout = {} } = data;
const blocksIds = Object.keys(blocks);
let valid = true;
if (
blocks_layout &&
blocks_layout.items &&
blocks_layout.items.length === blocksIds.length
) {
blocks_layout.items.forEach((block) => {
if (valid && !blocksIds.includes(block)) {
valid = false;
}
});
}
if (valid) {
props.updateContent(getBaseUrl(props.pathname), data);
toast.success(
<Toast
success
title={'Success'}
content={'Blocks replaced successfully'}
/>,
);
} else {
toast.error(
<Toast
error
title={'Error'}
content={'Your clipboard contains incompatible data'}
/>,
);
}
} catch {
toast.error(
<Toast
error
title={'Error'}
content={'Your clipboard contains incompatible data'}
/>,
);
}
}
});
};

React.useEffect(() => {
clock.current = setInterval(() => {
const element = document.querySelector('#toolbar .toolbar-actions');
if (element) {
setReadyToRender(true);
clearInterval(clock.current);
time.current = 0;
return;
}
if (time.current >= TIMEOUT) {
clearInterval(clock.current);
time.current = 0;
return;
}
time.current += 100;
}, 100);
return () => {
clearInterval(clock.current);
time.current = 0;
};
}, []);

if (!__CLIENT__ || !readyToRender) return '';

return (
<Portal node={document.querySelector('#toolbar .toolbar-actions')}>
<div
ref={toolbar}
id="__developer_tools"
onMouseEnter={(e) => {
if (
e.altKey &&
toolbar.current &&
!toolbar.current.classList.contains('__dev_on')
) {
toolbar.current.classList.add('__dev_on');
}
}}
onMouseLeave={(e) => {
if (
toolbar.current &&
toolbar.current.classList.contains('__dev_on')
) {
toolbar.current.classList.remove('__dev_on');
}
}}
onFocus={() => {}}
>
<Button
className="copy"
aria-label="Copy blocks data"
title="Copy blocks data"
onClick={copyData}
>
<Icon name={copySVG} className="circled" size="30px" />
</Button>
<Button
className="paste"
aria-label="Paste blocks data"
title="Paste blocks data"
onClick={pasteData}
disabled={props.updateRequest.loading}
>
<Icon name={pasteSVG} className="circled" size="30px" />
</Button>
</div>
</Portal>
);
};

export default compose(
connect(
(state, props) => ({
content: state.content.data,
updateRequest: state.content.update,
pathname: props.location.pathname,
}),
{
updateContent,
},
),
)(CopyPaste);
3 changes: 3 additions & 0 deletions src/components/theme/AppExtras/CopyPaste/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import CopyPaste from './CopyPaste';

export default CopyPaste;
18 changes: 18 additions & 0 deletions src/components/theme/AppExtras/CopyPaste/style.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#__developer_tools {
.ui.button {
color: #007eb1;
opacity: 0;
pointer-events: none;

&.disabled {
opacity: 0 !important;
}
}

&.__dev_on {
.ui.button {
opacity: 1;
pointer-events: all;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"folders": [
{
"path": "../../../../.."
}
],
"settings": {}
}
13 changes: 13 additions & 0 deletions src/components/theme/AppExtras/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import CopyPaste from './CopyPaste';

export default (config) => {
config.settings.appExtras = [
...(config.settings.appExtras || []),
{
match: '/**/edit',
component: CopyPaste,
},
];

return config;
};
3 changes: 2 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Forbidden from '@plone/volto/components/theme/Forbidden/Forbidden';
import Unauthorized from '@plone/volto/components/theme/Unauthorized/Unauthorized';

import installAppExtras from '@eeacms/volto-forests-theme/components/theme/AppExtras';
import { installBlocks } from '@eeacms/volto-plotlycharts';
import { applyConfig as installFiseFrontend } from './localconfig';

Expand All @@ -11,7 +12,7 @@ import './slate-styles.css';

export default function applyConfig(config) {
// Add here your project's configuration here by modifying `config` accordingly
config = [installBlocks, installFiseFrontend].reduce(
config = [installBlocks, installAppExtras, installFiseFrontend].reduce(
(acc, apply) => apply(acc),
config,
);
Expand Down