diff --git a/package.json b/package.json index 08eff17..1e98c0e 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,13 @@ "version": "0.1.0", "private": true, "dependencies": { + "draft-js": "^0.10.5", + "draft-js-autolist-plugin": "^2.0.0", + "draft-js-markdown-plugin": "^3.0.0", + "draft-js-plugins-editor": "^2.0.8", "glamor": "^2.20.40", + "markdown-draft-js": "^1.0.1", + "prismjs": "^1.15.0", "react": "^15.6.1", "react-animated-number": "^0.4.3", "react-big-calendar": "^0.19.0", diff --git a/src/components/Content/RightPanel/TaskDetails/TaskDetails.css b/src/components/Content/RightPanel/TaskDetails/TaskDetails.css index 4112f4b..970ecf1 100644 --- a/src/components/Content/RightPanel/TaskDetails/TaskDetails.css +++ b/src/components/Content/RightPanel/TaskDetails/TaskDetails.css @@ -115,7 +115,7 @@ .subtasks-list { list-style: none; - padding-left: 0 + padding-left: 0; } .subtask-item { diff --git a/src/components/Content/RightPanel/TaskDetails/TaskDetails.js b/src/components/Content/RightPanel/TaskDetails/TaskDetails.js index 5d5fac6..4fe96e6 100644 --- a/src/components/Content/RightPanel/TaskDetails/TaskDetails.js +++ b/src/components/Content/RightPanel/TaskDetails/TaskDetails.js @@ -3,12 +3,12 @@ import { connect } from 'react-redux'; import { withRouter } from 'react-router-dom'; import { showTaskInPursuance } from '../../../../utils/tasks'; import { getPursuances, getTasks, getUsers, rpShowTaskDetails, patchTask } from '../../../../actions'; -import ReactMarkdown from 'react-markdown'; import FaCircleO from 'react-icons/lib/fa/circle-o'; import TaskDetailsTopbar from './TaskDetailsTopbar'; import TaskTitle from './TaskTitle/TaskTitle'; import TaskIcons from './TaskIcons/TaskIcons'; import TaskForm from '../../TaskManager/TaskForm/TaskForm'; +import Wysiwyg from './Wysiwyg/Wysiwyg'; import './TaskDetails.css'; @@ -93,17 +93,7 @@ class TaskDetails extends Component {

Description / Deliverables

- - { - if (props.href.startsWith('/')) { - return {props.children}; - } - // If link to external site, open in new tab - return {props.children}; - }}} /> - +

Subtasks

diff --git a/src/components/Content/RightPanel/TaskDetails/Wysiwyg/Wysiwyg.css b/src/components/Content/RightPanel/TaskDetails/Wysiwyg/Wysiwyg.css new file mode 100644 index 0000000..f060e28 --- /dev/null +++ b/src/components/Content/RightPanel/TaskDetails/Wysiwyg/Wysiwyg.css @@ -0,0 +1,21 @@ +.wysiwyg { + box-sizing: border-box; + border: 1px solid #ccc; + cursor: text; + padding: 16px; + border-radius: 5px; + margin: 20px 0; + box-shadow: inset 0px 1px 8px 3px #ABABAB; + background: #fefefe; + color: black; +} + +.wysiwyg :global(.public-DraftEditor-content) { + min-height: 140px; +} + +.wysiwyg-save, +.wysiwyg-edit { + border-radius: 5px; + background-color: #000; +} \ No newline at end of file diff --git a/src/components/Content/RightPanel/TaskDetails/Wysiwyg/Wysiwyg.js b/src/components/Content/RightPanel/TaskDetails/Wysiwyg/Wysiwyg.js new file mode 100644 index 0000000..9b95366 --- /dev/null +++ b/src/components/Content/RightPanel/TaskDetails/Wysiwyg/Wysiwyg.js @@ -0,0 +1,113 @@ +import React, {Component} from 'react'; +import {connect} from 'react-redux'; +import {EditorState, convertToRaw, convertFromRaw} from 'draft-js'; +import { Editor } from 'draft-js'; +import createAutoListPlugin from 'draft-js-autolist-plugin' +import createMarkdownPlugin from 'draft-js-markdown-plugin'; +import {markdownToDraft, draftToMarkdown} from 'markdown-draft-js'; +import ReactMarkdown from 'react-markdown'; +import './Wysiwyg.css'; + +const autoListPlugin = createAutoListPlugin(); + +const plugins = [ + autoListPlugin, + createMarkdownPlugin() +]; + +class Wysiwyg extends Component { + constructor(props) { + super(props); + const content = this.calculateContent(); + + this.state = { + editMode: false, + editorState: EditorState.createWithContent(convertFromRaw(content)) + }; + } + + calculateContent = () => { + const {tasks: { taskMap }, taskGid, attributeName} = this.props, + attributeValue = taskMap[taskGid][attributeName], + content = attributeValue ? markdownToDraft(attributeValue, { + remarkableOptions: { + html: false, + preserveNewlines: true + } + }) : markdownToDraft(''); + + return content; + } + + editModeEnable = () => { + const content = this.calculateContent(); + + this.setState({ + editMode: true, + editorState: EditorState.createWithContent(convertFromRaw(content)) + }); + }; + + onChange = (editorState) => { + this.setState({ + editorState + }); + }; + + save = () => { + const {patchTask} = this.props, + markdown = draftToMarkdown(convertToRaw(this.state.editorState.getCurrentContent())), + payload = {gid: this.props.taskGid}; + + payload[this.props.attributeName] = markdown; + + patchTask(payload); + + this.setState({ + editMode: false + }); + } + + render() { + const {tasks: {taskMap}} = this.props, + attributeValue = taskMap[this.props.taskGid][this.props.attributeName]; + + return ( +
+ { + this.state.editMode && ( +
+
+ +
+ +
+ ) + } + { + !this.state.editMode && ( +
+ { + if (props.href.startsWith('/')) { + return {props.children}; + } + // If link to external site, open in new tab + return {props.children}; + }}} /> + +
+ ) + } +
+ ); + } +} + +export default connect(({tasks}) => ({tasks}), null)(Wysiwyg); \ No newline at end of file