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

Commit

Permalink
Develop (#202)
Browse files Browse the repository at this point in the history
* Refs #142010 - Optimize Volto-addons gitflow pipelines

* Revert to older version of slate-react

without the breaking API change

* Upgrade slate and slate-react versions

which brings up the problem with the breaking API change in Slate-React:
ianstormtaylor/slate#4540

* Split text block editor components in separate modules

* [JENKINS] Fix eslint

* Make it work with new react-slate method of getting the value

* Multiple Description blocks on the same page update each other

In fact, does the changes to the SlateEditor component for the
Slate-based Title & Description blocks too.

* Remove useless commented line

* Backwards block merge 2 (#195)

* Solve bug when merging blocks with Backspace

* Remove some dead code

* Update Jest snapshots

* Update Jest snapshots

Co-authored-by: Silviu Bogan <silviubogan@gmail.com>

* Automated release 5.1.2

Co-authored-by: valentinab25 <valentinab25>
Co-authored-by: Silviu Bogan <silviubogan@gmail.com>
Co-authored-by: Alin Voinea <contact@avoinea.com>
Co-authored-by: EEA Jenkins <@users.noreply.github.com>
  • Loading branch information
3 people authored Nov 30, 2021
1 parent b94dd90 commit 1fc4ad3
Show file tree
Hide file tree
Showing 11 changed files with 488 additions and 381 deletions.
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,22 @@ 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).

#### [5.1.2](https://github.com/eea/volto-slate/compare/5.1.1...5.1.2)

- Backwards block merge 2 [`#195`](https://github.com/eea/volto-slate/pull/195)
- Upgrade slate and slate-react versions [`#196`](https://github.com/eea/volto-slate/pull/196)
- Remove useless commented line [`f02a9e3`](https://github.com/eea/volto-slate/commit/f02a9e3aca19b5f7f0d39ec6a2e3040fc65a3591)
- Multiple Description blocks on the same page update each other [`44ec992`](https://github.com/eea/volto-slate/commit/44ec9923717b99516c2899fd26f51e8a860e14e0)
- Make it work with new react-slate method of getting the value [`9256b59`](https://github.com/eea/volto-slate/commit/9256b5904617e700f78ccde2e92a1d042461f28c)
- Split text block editor components in separate modules [`0888e61`](https://github.com/eea/volto-slate/commit/0888e6177254562c501847c151e946b6c8f10537)
- Revert to older version of slate-react [`044fadf`](https://github.com/eea/volto-slate/commit/044fadf592dc71a5756e82a94a98df0ba0b8c7ac)
- Refs #142010 - Optimize Volto-addons gitflow pipelines [`33bc1ed`](https://github.com/eea/volto-slate/commit/33bc1edeb63ee0d0e6fb8fa6c170d11ed4922a3d)

#### [5.1.1](https://github.com/eea/volto-slate/compare/5.1.0...5.1.1)

> 18 November 2021
- Title description nested blocks [`#188`](https://github.com/eea/volto-slate/pull/188)
- Title description nested blocks [`#187`](https://github.com/eea/volto-slate/pull/187)

#### [5.1.0](https://github.com/eea/volto-slate/compare/5.0.0...5.1.0)
Expand Down
29 changes: 23 additions & 6 deletions Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ pipeline {
stages {

stage('Code') {
when {
allOf {
environment name: 'CHANGE_ID', value: ''
not { branch 'master' }
not { changelog '.*^Automated release [0-9\\.]+$' }
}
}
steps {
parallel(

Expand All @@ -38,6 +45,13 @@ pipeline {
}

stage('Tests') {
when {
allOf {
environment name: 'CHANGE_ID', value: ''
not { branch 'master' }
not { changelog '.*^Automated release [0-9\\.]+$' }
}
}
steps {
parallel(

Expand Down Expand Up @@ -77,10 +91,11 @@ pipeline {
}

stage('Integration tests') {
// Exclude Pull-Requests. Already running on branch
when {
allOf {
environment name: 'CHANGE_ID', value: ''
not { branch 'master' }
not { changelog '.*^Automated release [0-9\\.]+$' }
}
}
steps {
Expand Down Expand Up @@ -130,11 +145,13 @@ pipeline {
}

stage('Report to SonarQube') {
// Exclude Pull-Requests
when {
allOf {
environment name: 'CHANGE_ID', value: ''
}
anyOf {
branch 'master'
branch 'develop'
}
not { changelog '.*^Automated release [0-9\\.]+$' }
}
steps {
node(label: 'swarm') {
Expand Down Expand Up @@ -164,8 +181,8 @@ pipeline {
steps {
node(label: 'docker') {
script {
if ( env.CHANGE_BRANCH != "develop" && !( env.CHANGE_BRANCH.startsWith("hotfix")) ) {
error "Pipeline aborted due to PR not made from develop or hotfix branch"
if ( env.CHANGE_BRANCH != "develop" ) {
error "Pipeline aborted due to PR not made from develop branch"
}
withCredentials([string(credentialsId: 'eea-jenkins-token', variable: 'GITHUB_TOKEN')]) {
sh '''docker pull eeacms/gitflow'''
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "volto-slate",
"version": "5.1.1",
"version": "5.1.2",
"description": "Slate.js integration with Volto",
"main": "src/index.js",
"author": "European Environment Agency: IDM2 A-Team",
Expand All @@ -25,10 +25,10 @@
"jsdom": "^16.6.0",
"react-intersection-observer": "^8.32.0",
"react-visibility-sensor": "5.1.1",
"slate": "^0.70.0",
"slate": "^0.71.0",
"slate-history": "^0.66.0",
"slate-hyperscript": "^0.67.0",
"slate-react": "^0.70.0",
"slate-react": "^0.71.0",
"weak-key": "^1.0.2"
},
"peerDependencies": {
Expand Down
286 changes: 286 additions & 0 deletions src/blocks/Text/DefaultTextBlockEditor.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,286 @@
import ReactDOM from 'react-dom';
import React from 'react';
import { readAsDataURL } from 'promise-file-reader';
import Dropzone from 'react-dropzone';
import { defineMessages, useIntl } from 'react-intl';
import { useInView } from 'react-intersection-observer';
import { Dimmer, Loader, Message, Segment } from 'semantic-ui-react';

import { flattenToAppURL, getBaseUrl } from '@plone/volto/helpers';
import config from '@plone/volto/registry';
import {
InlineForm,
SidebarPortal,
BlockChooserButton,
} from '@plone/volto/components';

import { SlateEditor } from 'volto-slate/editor';
import { serializeNodesToText } from 'volto-slate/editor/render';
import {
createImageBlock,
parseDefaultSelection,
deconstructToVoltoBlocks,
} from 'volto-slate/utils';
import { Transforms } from 'slate';

import ShortcutListing from './ShortcutListing';
import MarkdownIntroduction from './MarkdownIntroduction';
import { handleKey } from './keyboard';
import TextBlockSchema from './schema';

import imageBlockSVG from '@plone/volto/components/manage/Blocks/Image/block-image.svg';

import './css/editor.css';

// TODO: refactor dropzone to separate component wrapper

const messages = defineMessages({
text: {
id: 'Type text…',
defaultMessage: 'Type text…',
},
});

const DEBUG = false;

export const DefaultTextBlockEditor = (props) => {
const {
block,
blocksConfig,
data,
detached = false,
index,
onChangeBlock,
onInsertBlock,
onMutateBlock,
onSelectBlock,
pathname,
properties,
selected,
uploadRequest,
uploadContent,
uploadedContent,
defaultSelection,
saveSlateBlockSelection,
allowedBlocks,
formTitle,
formDescription,
} = props;

const { slate } = config.settings;
const { textblockExtensions } = slate;
const { value } = data;

// const [addNewBlockOpened, setAddNewBlockOpened] = React.useState();
const [showDropzone, setShowDropzone] = React.useState(false);
const [uploading, setUploading] = React.useState(false);
const [newImageId, setNewImageId] = React.useState(null);

const prevReq = React.useRef(null);

const withBlockProperties = React.useCallback(
(editor) => {
editor.getBlockProps = () => props;
return editor;
},
[props],
);

const onDrop = React.useCallback(
(files) => {
// TODO: need to fix setUploading, treat uploading indicator
// inteligently, show progress report on uploading files
setUploading(true);
files.forEach((file) => {
const [mime] = file.type.split('/');
if (mime !== 'image') return;

readAsDataURL(file).then((data) => {
const fields = data.match(/^data:(.*);(.*),(.*)$/);
uploadContent(
getBaseUrl(pathname),
{
'@type': 'Image',
title: file.name,
image: {
data: fields[3],
encoding: fields[2],
'content-type': fields[1],
filename: file.name,
},
},
block,
);
});
});
setShowDropzone(false);
},
[pathname, uploadContent, block],
);

const { loaded, loading } = uploadRequest;
const imageId = uploadedContent['@id'];
const prevLoaded = prevReq.current;

React.useEffect(() => {
if (loaded && !loading && !prevLoaded && newImageId !== imageId) {
const url = flattenToAppURL(imageId);
setNewImageId(imageId);

createImageBlock(url, index, props);
}
prevReq.current = loaded;
}, [props, loaded, loading, prevLoaded, imageId, newImageId, index]);

const handleUpdate = React.useCallback(
(editor) => {
// defaultSelection is used for things such as "restoring" the selection
// when joining blocks or moving the selection to block start on block
// split
if (defaultSelection) {
const selection = parseDefaultSelection(editor, defaultSelection);
if (selection) {
setTimeout(() => {
Transforms.select(editor, selection);
saveSlateBlockSelection(block, null);
}, 120);
// TODO: use React sync render API
// without setTimeout, the join is not correct. Slate uses internally
// a 100ms throttle, so setting to a bigger value seems to help
}
}
},
[defaultSelection, block, saveSlateBlockSelection],
);

const onEditorChange = (value, editor) => {
ReactDOM.unstable_batchedUpdates(() => {
onChangeBlock(block, {
...data,
value,
plaintext: serializeNodesToText(value || []),
// TODO: also add html serialized value
});
deconstructToVoltoBlocks(editor);
});
};

// Get editing instructions from block settings or props
let instructions = data?.instructions?.data || data?.instructions;
if (!instructions || instructions === '<p><br/></p>') {
instructions = formDescription;
}

const intl = useIntl();
const placeholder =
data.placeholder || formTitle || intl.formatMessage(messages.text);
const schema = TextBlockSchema(data);

const disableNewBlocks = data?.disableNewBlocks || detached;
const { ref, inView } = useInView({
threshold: 0,
rootMargin: '0px 0px 200px 0px',
});

const handleFocus = React.useCallback(() => {
if (!selected) {
onSelectBlock(block);
}
}, [onSelectBlock, selected, block]);

return (
<div className="text-slate-editor-inner" ref={ref}>
<>
<Dropzone
disableClick
onDrop={onDrop}
className="dropzone"
onDragOver={() => setShowDropzone(true)}
onDragLeave={() => setShowDropzone(false)}
>
{({ getRootProps, getInputProps }) => {
return showDropzone ? (
<div className="drop-indicator">
{uploading ? (
<Dimmer active>
<Loader indeterminate>Uploading image</Loader>
</Dimmer>
) : (
<Message>
<center>
<img src={imageBlockSVG} alt="" />
</center>
</Message>
)}
</div>
) : (
<>
<SlateEditor
index={index}
readOnly={!inView}
properties={properties}
extensions={textblockExtensions}
renderExtensions={[withBlockProperties]}
value={value}
block={block /* is this needed? */}
defaultSelection={defaultSelection}
onUpdate={handleUpdate}
debug={DEBUG}
onFocus={handleFocus}
onChange={(value, editor) => onEditorChange(value, editor)}
onKeyDown={handleKey}
selected={selected}
placeholder={placeholder}
/>
{DEBUG ? <div>{block}</div> : ''}
</>
);
}}
</Dropzone>

{selected && !data.plaintext && !disableNewBlocks && (
<BlockChooserButton
data={data}
block={block}
onInsertBlock={(id, value) => {
onSelectBlock(onInsertBlock(id, value));
}}
onMutateBlock={onMutateBlock}
allowedBlocks={allowedBlocks}
blocksConfig={blocksConfig}
size="24px"
className="block-add-button"
properties={properties}
/>
)}

<SidebarPortal selected={selected}>
<div id="slate-plugin-sidebar"></div>
{instructions ? (
<Segment attached>
<div dangerouslySetInnerHTML={{ __html: instructions }} />
</Segment>
) : (
<>
<ShortcutListing />
<MarkdownIntroduction />
<InlineForm
schema={schema}
title={schema.title}
onChangeField={(id, value) => {
onChangeBlock(block, {
...data,
[id]: value,
});
}}
formData={data}
/>
</>
)}
</SidebarPortal>
</>
</div>
);
};

export default DefaultTextBlockEditor;
Loading

0 comments on commit 1fc4ad3

Please sign in to comment.