11import React , { PropTypes } from 'react'
22import moment from 'moment'
3- import { findWhere } from 'lodash'
3+ import { findWhere , uniq } from 'lodash'
44import ModeIcon from 'boost/components/ModeIcon'
55import MarkdownPreview from 'boost/components/MarkdownPreview'
66import CodeEditor from 'boost/components/CodeEditor'
7+ import { NEW , IDLE_MODE , CREATE_MODE , EDIT_MODE , switchMode } from '../actions'
8+ import aceModes from 'boost/ace-modes'
9+ import Select from 'react-select'
10+ import linkState from 'boost/linkState'
11+
12+ var modeOptions = aceModes . map ( function ( mode ) {
13+ return {
14+ label : mode ,
15+ value : mode
16+ }
17+ } )
718
819export default class ArticleDetail extends React . Component {
9- render ( ) {
10- let { article, status, user } = this . props
20+ constructor ( props ) {
21+ super ( props )
22+ this . state = {
23+ article : Object . assign ( { } , props . activeArticle )
24+ }
25+ }
1126
12- let tags = article . Tags . length > 0 ? article . Tags . map ( tag => {
27+ componentWillReceiveProps ( nextProps ) {
28+ this . setState ( { article : nextProps . activeArticle } )
29+ }
30+
31+ renderEmpty ( ) {
32+ return (
33+ < div className = 'ArticleDetail' >
34+ Empty article
35+ </ div >
36+ )
37+ }
38+
39+ renderIdle ( ) {
40+ let { status, activeArticle, activeUser } = this . props
41+
42+ let tags = activeArticle . Tags . length > 0 ? activeArticle . Tags . map ( tag => {
1343 return (
1444 < a key = { tag . id } > { tag . name } </ a >
1545 )
1646 } ) : (
1747 < span className = 'noTags' > Not tagged yet</ span >
1848 )
19- let folder = findWhere ( user . Folders , { id : article . FolderId } )
49+ let folder = findWhere ( activeUser . Folders , { id : activeArticle . FolderId } )
2050 let folderName = folder != null ? folder . name : '(unknown)'
2151
2252 return (
@@ -25,9 +55,9 @@ export default class ArticleDetail extends React.Component {
2555 < div className = 'left' >
2656 < div className = 'info' >
2757 < i className = 'fa fa-fw fa-square' /> { folderName }
28- by { article . User . profileName }
29- Created { moment ( article . createdAt ) . format ( 'YYYY/MM/DD' ) }
30- Updated { moment ( article . updatedAt ) . format ( 'YYYY/MM/DD' ) }
58+ by { activeArticle . User . profileName }
59+ Created { moment ( activeArticle . createdAt ) . format ( 'YYYY/MM/DD' ) }
60+ Updated { moment ( activeArticle . updatedAt ) . format ( 'YYYY/MM/DD' ) }
3161 </ div >
3262 < div className = 'tags' > < i className = 'fa fa-fw fa-tags' /> { tags } </ div >
3363 </ div >
@@ -41,19 +71,112 @@ export default class ArticleDetail extends React.Component {
4171 < div className = 'detailBody' >
4272 < div className = 'detailPanel' >
4373 < div className = 'header' >
44- < ModeIcon className = 'mode' mode = { article . mode } />
45- < div className = 'title' > { article . title } </ div >
74+ < ModeIcon className = 'mode' mode = { activeArticle . mode } />
75+ < div className = 'title' > { activeArticle . title } </ div >
4676 </ div >
47- { article . mode === 'markdown' ? < MarkdownPreview content = { article . content } /> : < CodeEditor readOnly = { true } onChange = { this . handleContentChange } mode = { article . mode } code = { article . content } /> }
77+ { activeArticle . mode === 'markdown' ? < MarkdownPreview content = { activeArticle . content } /> : < CodeEditor readOnly = { true } onChange = { this . handleContentChange } mode = { activeArticle . mode } code = { activeArticle . content } /> }
4878 </ div >
4979 </ div >
5080 </ div >
5181 )
5282 }
83+
84+ handleCancelButtonClick ( e ) {
85+ this . props . dispatch ( switchMode ( IDLE_MODE ) )
86+ }
87+
88+ handleSaveButtonClick ( e ) {
89+ console . log ( this . state . article )
90+ }
91+
92+ handleFolderIdChange ( value ) {
93+ let article = this . state . article
94+ article . FolderId = value
95+ this . setState ( { article : article } )
96+ }
97+
98+ handleTagsChange ( tag , tags ) {
99+ tags = uniq ( tags , function ( tag ) {
100+ return tag . value
101+ } )
102+
103+ var article = this . state . article
104+ article . Tags = tags . map ( function ( tag ) {
105+ return tag . value
106+ } )
107+
108+ this . setState ( { article : article } )
109+ }
110+
111+ handleModeChange ( value ) {
112+ let article = this . state . article
113+ article . mode = value
114+ this . setState ( { article : article } )
115+ }
116+
117+ handleContentChange ( e , value ) {
118+ let article = this . state . article
119+ article . content = value
120+ this . setState ( { article : article } )
121+ }
122+
123+ renderEdit ( ) {
124+ let { status, activeUser } = this . props
125+
126+ let folderOptions = activeUser . Folders . map ( folder => {
127+ return {
128+ label : folder . name ,
129+ value : folder . id
130+ }
131+ } )
132+
133+ return (
134+ < div className = 'ArticleDetail edit' >
135+ < div className = 'detailInfo' >
136+ < div className = 'left' >
137+ < Select ref = 'folder' onChange = { value => this . handleFolderIdChange ( value ) } clearable = { false } placeholder = 'select folder...' options = { folderOptions } value = { this . state . article . FolderId } className = 'folder' />
138+ < Select onChange = { ( tag , tags ) => this . handleTagsChange ( tag , tags ) } clearable = { false } multi = { true } placeholder = 'add some tags...' allowCreate = { true } value = { this . state . article . Tags } className = 'tags' />
139+ </ div >
140+ < div className = 'right' >
141+ < button onClick = { e => this . handleCancelButtonClick ( e ) } > Cancel</ button >
142+ < button onClick = { e => this . handleSaveButtonClick ( e ) } className = 'primary' > Save</ button >
143+ </ div >
144+ </ div >
145+ < div className = 'detailBody' >
146+ < div className = 'detailPanel' >
147+ < div className = 'header' >
148+ < div className = 'title' >
149+ < input ref = 'title' valueLink = { this . linkState ( 'article.title' ) } />
150+ </ div >
151+ < Select ref = 'mode' onChange = { value => this . handleModeChange ( value ) } clearable = { false } options = { modeOptions } placeholder = 'select mode...' value = { this . state . article . mode } className = 'mode' />
152+ </ div >
153+ < CodeEditor onChange = { ( e , value ) => this . handleContentChange ( e , value ) } mode = { this . state . article . mode } code = { this . state . article . content } />
154+ </ div >
155+ </ div >
156+ </ div >
157+ )
158+ }
159+
160+ render ( ) {
161+ let { status, activeArticle } = this . props
162+
163+ if ( activeArticle == null ) return this . renderEmpty ( )
164+
165+ switch ( status . mode ) {
166+ case CREATE_MODE :
167+ case EDIT_MODE :
168+ return this . renderEdit ( )
169+ case IDLE_MODE :
170+ default :
171+ return this . renderIdle ( )
172+
173+ }
174+ }
53175}
54176
55177ArticleDetail . propTypes = {
56- article : PropTypes . shape ( ) ,
57178 status : PropTypes . shape ( ) ,
58- user : PropTypes . shape ( )
179+ activeArticle : PropTypes . shape ( ) ,
180+ activeUser : PropTypes . shape ( )
59181}
182+ ArticleDetail . prototype . linkState = linkState
0 commit comments