Skip to content

Commit 3be31bc

Browse files
committed
fix: add easymde #4298
1 parent 6139dff commit 3be31bc

File tree

6 files changed

+118
-22
lines changed

6 files changed

+118
-22
lines changed

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
"html-webpack-plugin": "^2.30.1",
5656
"ignore-styles": "^1.2.0",
5757
"jsdom": "^7.2.2",
58+
"marked": "^2.0.0",
5859
"mocha": "^2.4.5",
5960
"mocha-jsdom": "~1.1.0",
6061
"nock": "^8.0.0",
@@ -96,6 +97,7 @@
9697
"draft-js-mention-plugin": "^2.0.0-rc2",
9798
"draft-js-plugins-editor": "^2.0.0-rc2",
9899
"draft-js-utils": "^0.1.7",
100+
"easymde": "^2.14.0",
99101
"expression-evaluator": "git+https://github.com/topcoder-platform/expression-evaluator.git#dev",
100102
"fbemitter": "^2.1.1",
101103
"fbjs": "^0.8.12",
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import React, { Component } from 'react'
2+
import styles from './MarkdownText.scss'
3+
import PropTypes from 'prop-types'
4+
import EasyMDE from 'easymde'
5+
import marked from 'marked'
6+
import cn from 'classnames'
7+
import _ from 'lodash'
8+
9+
class MarkdownText extends Component {
10+
constructor (props) {
11+
super(props)
12+
this.state = {
13+
isChanged: false
14+
}
15+
this.blurTheField = this.blurTheField.bind(this)
16+
this.updateDescriptionThrottled = _.throttle(this.updateDescription.bind(this), 10000) // 10s
17+
}
18+
19+
blurTheField () {
20+
const { onChange } = this.props
21+
onChange(this.easymde.value())
22+
}
23+
24+
updateDescription () {
25+
const { onChange } = this.props
26+
onChange(this.easymde.value())
27+
}
28+
29+
componentDidMount () {
30+
const { value, readOnly } = this.props
31+
if (!readOnly) {
32+
this.easymde = new EasyMDE({ element: this.refs.textarea, initialValue: value })
33+
this.easymde.codemirror.on('change', () => {
34+
this.setState({ isChanged: true })
35+
this.updateDescriptionThrottled(this.easymde.value())
36+
})
37+
this.easymde.codemirror.on('blur', () => {
38+
if (this.state.isChanged) {
39+
this.setState({ isChanged: false })
40+
this.blurTheField()
41+
}
42+
})
43+
} else {
44+
this.ref.current.innerHTML = value ? marked(value) : ''
45+
}
46+
}
47+
48+
render () {
49+
const { isPrivate, readOnly, placeholder, className } = this.props
50+
return (<div className={cn(className, styles.editor, { [styles.isPrivate]: isPrivate })}>
51+
{readOnly ? (
52+
<div ref="textarea" />
53+
) : (
54+
<textarea
55+
ref="textarea"
56+
placeholder={placeholder}
57+
/>
58+
)}
59+
</div>)
60+
}
61+
}
62+
63+
MarkdownText.defaultProps = {
64+
isPrivate: false,
65+
readOnly: false
66+
}
67+
68+
MarkdownText.propTypes = {
69+
onChange: PropTypes.func.isRequired,
70+
value: PropTypes.string,
71+
isPrivate: PropTypes.bool,
72+
placeholder: PropTypes.string,
73+
readOnly: PropTypes.bool
74+
}
75+
export default MarkdownText
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
@import '~tc-ui/src/styles/tc-includes';
2+
3+
.editor {
4+
@include roboto-light();
5+
6+
width: 100%;
7+
// margin: 0 30px;
8+
border-radius: 2px;
9+
font-size: 16px;
10+
max-height: 410px;
11+
display: flex;
12+
flex-direction: column;
13+
overflow: auto;
14+
15+
&.isPrivate {
16+
max-height: 205px;
17+
}
18+
19+
:global {
20+
.CodeMirror.CodeMirror-wrap {
21+
min-height: 0;
22+
flex: 1;
23+
}
24+
}
25+
26+
}

src/index.jsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import _ from 'lodash'
66
import { render } from 'react-dom'
77
import { SEGMENT_KEY } from './config/constants'
88
import App from './App'
9+
import 'easymde/dist/easymde.min.css'
910

1011
import 'styles/main.scss'
1112

src/projects/detail/components/JobPickerRow/JobPickerRow.jsx

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import IconX from '../../../../assets/icons/ui-16px-1_bold-remove.svg'
66
import IconAdd from '../../../../assets/icons/ui-16px-1_bold-add.svg'
77
import SkillsQuestion from '../SkillsQuestion/SkillsQuestionBase'
88
import PositiveNumberInput from '../../../../components/PositiveNumberInput/PositiveNumberInput'
9+
import MarkdownText from '../../../../components/MarkdownText/MarkdownText'
910
import SelectDropdown from 'appirio-tech-react-components/components/SelectDropdown/SelectDropdown'
1011

1112
import styles from './JobPickerRow.scss'
@@ -73,8 +74,8 @@ class JobPickerRow extends React.PureComponent {
7374
this.props.onChange(this.props.rowIndex, 'role', evt)
7475
}
7576

76-
handleDescriptionChange(evt) {
77-
this.props.onChange(this.props.rowIndex, 'description', evt.target.value)
77+
handleDescriptionChange(value) {
78+
this.props.onChange(this.props.rowIndex, 'description', value)
7879
}
7980

8081
resetDuration() {
@@ -234,13 +235,11 @@ class JobPickerRow extends React.PureComponent {
234235
<label className="tc-label" styleName="label">
235236
Job Description
236237
</label>
237-
<div styleName="job-description">
238-
<textarea
239-
className={`job-textarea ${isRowIncomplete && !value.description.trim() ? 'error' : 'empty'}`}
238+
<div styleName={`job-description ${isRowIncomplete && !value.description.trim() ? 'error' : ''}`} >
239+
<MarkdownText
240+
value={value.description || ''}
240241
onChange={this.handleDescriptionChange}
241242
placeholder="Job Description"
242-
type="text"
243-
value={value.description || ''}
244243
/>
245244
</div>
246245
</div>

src/projects/detail/components/JobPickerRow/JobPickerRow.scss

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -86,22 +86,15 @@
8686
display: block;
8787
}
8888

89-
.job-description textarea,
90-
.job-textarea[type="text"] {
91-
&.empty {
92-
color: $tc-gray-30;
89+
.job-description {
90+
&.error {
91+
:global {
92+
.CodeMirror {
93+
border:1px solid $tc-red-70;
94+
}
95+
}
9396
}
94-
min-height : 90px;
95-
96-
@include placeholder {
97-
@include roboto;
98-
color: $tc-gray-30;
99-
text-transform: none;
100-
font-style: italic;
101-
font-size: $base-unit*3;
102-
line-height: $base-unit*4;
103-
}
104-
}
97+
}
10598
}
10699

107100
.col-role-container {

0 commit comments

Comments
 (0)