Skip to content

Commit

Permalink
#3081:Add template with readonly blocks to reportText
Browse files Browse the repository at this point in the history
This makes sure that when creating a report, the reportText field
contains a template text. Some of the heading blocks in the template
are readonly and can't be removed.
Note: it only works now on add, after save, on edit, the headings
are no longer readonly (still to be implemented).
  • Loading branch information
maradragan committed Jun 23, 2020
1 parent 73f5e0b commit 06a38fc
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 5 deletions.
12 changes: 8 additions & 4 deletions client/src/components/RichTextEditor.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import LinkAnet from "components/editor/LinkAnet"
import LinkSourceAnet from "components/editor/LinkSourceAnet"
import createNewlinePlugin from "components/editor/plugins/newlinePlugin"
import createReadonlyBlockPlugin from "components/editor/plugins/readonlyBlockPlugin"
import { convertFromHTML, convertToHTML } from "draft-convert"
import { convertFromRaw, convertToRaw } from "draft-js"
import {
Expand All @@ -25,6 +26,7 @@ import "draft-js-side-toolbar-plugin/lib/plugin.css"
import "components/RichTextEditor.css"

const newlinePlugin = createNewlinePlugin()
const readonlyBlockPlugin = createReadonlyBlockPlugin()

const BLOCK_TYPES = [
{ type: BLOCK_TYPE.HEADER_ONE },
Expand Down Expand Up @@ -172,7 +174,7 @@ class RichTextEditor extends Component {
}

render() {
const { className, value, onChange, onHandleBlur } = this.props
const { className, value, onChange, onHandleBlur, template } = this.props
const { sideToolbarPlugin } = this.state
const { SideToolbar } = sideToolbarPlugin
return (
Expand All @@ -192,8 +194,9 @@ class RichTextEditor extends Component {
}}
onBlur={onHandleBlur}
stateSaveInterval={100}
plugins={[sideToolbarPlugin, newlinePlugin]}
rawContentState={value ? fromHTML(value) : null}
plugins={[sideToolbarPlugin, newlinePlugin, readonlyBlockPlugin]}
handlePastedText={() => true}
rawContentState={value ? fromHTML(value) : template || null}
showUndoControl
showRedoControl
spellCheck
Expand Down Expand Up @@ -226,7 +229,8 @@ RichTextEditor.propTypes = {
className: PropTypes.string,
value: PropTypes.string,
onChange: PropTypes.func,
onHandleBlur: PropTypes.func
onHandleBlur: PropTypes.func,
template: PropTypes.object
}

export default RichTextEditor
6 changes: 5 additions & 1 deletion client/src/components/editor/plugins/newlinePlugin.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { preventHandleOnReadonly } from "components/editor/plugins/readonlyBlockPlugin"
import { ContentState, EditorState, Modifier, convertFromHTML } from "draft-js"

const HTML_REGEX = new RegExp(/<[a-z][\s\S]*>/i)
Expand All @@ -8,7 +9,6 @@ const createNewLines = (newLines, nextState) => {
const htmlMarkup = newLines.map(text => {
return text.length <= 1 ? "" : `<p>${text}</p>`
})

// Create content blocks based on the html for the new content statue
const blocksFromHTML = convertFromHTML(htmlMarkup.join(""))
const newContentState = ContentState.createFromBlockArray(
Expand All @@ -27,6 +27,10 @@ const createNewLines = (newLines, nextState) => {

const newlinePlugin = () => ({
handlePastedText(text, html, editorState, { setEditorState }) {
const isHandled = preventHandleOnReadonly(editorState) === "handled"
if (isHandled) {
return "handled"
}
const nextState = editorState
if (!HTML_REGEX.test(html)) {
const newLines = text.match(NEW_LINE_REGEX)
Expand Down
26 changes: 26 additions & 0 deletions client/src/components/editor/plugins/readonlyBlockPlugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
export const preventHandleOnReadonly = editorState => {
const selectionState = editorState.getSelection()
const anchorKey = selectionState.getAnchorKey()
const contentState = editorState.getCurrentContent()
const currentContentBlock = contentState.getBlockForKey(anchorKey)
const currentContentBlockData = currentContentBlock.getData().toObject()
if (currentContentBlockData.mandatory) {
return "handled"
}
return "not-handled"
}

const createReadonlyBlockPlugin = config => {
const handleKeyCommand = (command, editorState) => {
return preventHandleOnReadonly(editorState)
}
const handleBeforeInput = (chars, editorState) => {
return preventHandleOnReadonly(editorState)
}
return {
handleKeyCommand: handleKeyCommand,
handleBeforeInput: handleBeforeInput
}
}

export default createReadonlyBlockPlugin
22 changes: 22 additions & 0 deletions client/src/pages/reports/Form.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import ReportTags from "components/ReportTags"
import RichTextEditor from "components/RichTextEditor"
import { RECURSE_STRATEGY } from "components/SearchFilters"
import TaskTable from "components/TaskTable"
import { BLOCK_TYPE } from "draftail"
import { FastField, Field, Form, Formik } from "formik"
import _cloneDeep from "lodash/cloneDeep"
import _debounce from "lodash/debounce"
Expand Down Expand Up @@ -502,6 +503,26 @@ const BaseReportForm = ({
</div>
)
const isFutureEngagement = Report.isFuture(values.engagementDate)
const reportTextTemplate = {
blocks: [
{
data: { mandatory: true },
text: "Step 1",
type: BLOCK_TYPE.HEADER_ONE
},
{
data: { mandatory: true },
text: "Step 2",
type: BLOCK_TYPE.HEADER_ONE
},
{
data: {},
text: "Step 3",
type: BLOCK_TYPE.HEADER_ONE
}
],
entityMap: {}
}
return (
<div className="report-form">
<NavigationWarning isBlocking={dirty} />
Expand Down Expand Up @@ -960,6 +981,7 @@ const BaseReportForm = ({
// validation will be done by setFieldValue
setFieldTouched("reportText", true, false)
}}
template={reportTextTemplate}
/>
}
/>
Expand Down

0 comments on commit 06a38fc

Please sign in to comment.