From bea58fa7f4f0af4329c2f054e2a1b3a94aa2b061 Mon Sep 17 00:00:00 2001 From: Mara Dragan Date: Fri, 26 Jun 2020 00:39:32 +0200 Subject: [PATCH] NCI-Agency/anet#3081: WIP: Replace mandatory elems with placeholder In the RichTextEditor, replace mandatory elements with a placeholder when all their text is being deleted. --- client/src/components/RichTextEditor.js | 11 +++- .../editor/plugins/readonlyBlockPlugin.js | 50 +++++++++++++++++-- client/src/pages/reports/Form.js | 2 +- 3 files changed, 57 insertions(+), 6 deletions(-) diff --git a/client/src/components/RichTextEditor.js b/client/src/components/RichTextEditor.js index 8508a84478..6b160e5017 100644 --- a/client/src/components/RichTextEditor.js +++ b/client/src/components/RichTextEditor.js @@ -106,8 +106,8 @@ const importerConfig = { }, htmlToBlock: (nodeName, node) => { if ( - nodeName === "h1" || - node.attributes?.classname?.nodeValue === "mandatory" + nodeName === "h1" && + node.attributes?.class?.nodeValue === "mandatory" ) { return { type: BLOCK_TYPE.HEADER_ONE, @@ -115,6 +115,13 @@ const importerConfig = { } } + if (nodeName === "p" && node.attributes?.class?.nodeValue === "mandatory") { + return { + type: BLOCK_TYPE.UNSTYLED, + data: { mandatory: true } + } + } + if (nodeName === "hr" || nodeName === "img") { // "atomic" blocks is how Draft.js structures block-level entities. return "atomic" diff --git a/client/src/components/editor/plugins/readonlyBlockPlugin.js b/client/src/components/editor/plugins/readonlyBlockPlugin.js index 1f4bf2e165..aea43f5573 100644 --- a/client/src/components/editor/plugins/readonlyBlockPlugin.js +++ b/client/src/components/editor/plugins/readonlyBlockPlugin.js @@ -1,3 +1,15 @@ +import { EditorState, Modifier } from "draft-js" + +const createPlaceholder = (placeholder, nextState) => { + // Replace the text with a placeholder + const nextContentState = Modifier.replaceText( + nextState.getCurrentContent(), + nextState.getSelection(), + placeholder + ) + return EditorState.push(nextState, nextContentState, "insert-characters") +} + const createReadonlyBlockPlugin = config => { // TODO: rename plugin const blockStyleFn = contentBlock => { @@ -8,7 +20,7 @@ const createReadonlyBlockPlugin = config => { } } - const handleKeyCommand = (command, editorState) => { + const handleKeyCommand = (command, editorState, { setEditorState }) => { if (["backspace", "delete"].includes(command)) { const selectionState = editorState.getSelection() const anchorKey = selectionState.getAnchorKey() @@ -16,13 +28,45 @@ const createReadonlyBlockPlugin = config => { const currentContentBlock = contentState.getBlockForKey(anchorKey) const currentContentBlockData = currentContentBlock.getData().toObject() const currentContentBlockText = currentContentBlock.getText() + const mandatoryBlock = currentContentBlockData.mandatory + const blockAchorOffset = selectionState.anchorOffset + const blockLength = currentContentBlockText.length + if (command === "backspace" && mandatoryBlock && blockAchorOffset === 0) { + // Prevent deleting the block itself + // FIXME: handleKeyCommand is not being used in this case for the first + // content block + return "handled" + } if ( - currentContentBlockData.mandatory && - currentContentBlockText.length === 1 + command === "delete" && + mandatoryBlock && + blockAchorOffset === blockLength ) { // Prevent deleting the block itself return "handled" } + if ( + command === "delete" && + mandatoryBlock && + blockAchorOffset === 0 && + blockLength === 1 + ) { + // Replace by placeholder + const nextState = editorState + setEditorState(createPlaceholder("placeholder", nextState)) + return "handled" + } + if ( + command === "backspace" && + mandatoryBlock && + blockAchorOffset === 1 && + blockLength === 1 + ) { + // Replace by placeholder + const nextState = editorState + setEditorState(createPlaceholder("placeholder", nextState)) + return "handled" + } } return "not-handled" diff --git a/client/src/pages/reports/Form.js b/client/src/pages/reports/Form.js index f508e4898d..6899b71c92 100644 --- a/client/src/pages/reports/Form.js +++ b/client/src/pages/reports/Form.js @@ -504,7 +504,7 @@ const BaseReportForm = ({ ) const isFutureEngagement = Report.isFuture(values.engagementDate) const reportTextTemplateHTML = - '

Key details 1

' + '

Key details 1

Key details 2

' const reportTextTemplate = { blocks: [ {