1
0
mirror of https://github.com/BoostIo/Boostnote synced 2025-12-20 13:11:44 +00:00

CRUD done

This commit is contained in:
Rokt33r
2015-10-15 10:46:22 +09:00
parent 9d2b64e82b
commit 832ca3347c
8 changed files with 317 additions and 46 deletions

View File

@@ -4,10 +4,11 @@ import { findWhere, uniq } from 'lodash'
import ModeIcon from 'boost/components/ModeIcon'
import MarkdownPreview from 'boost/components/MarkdownPreview'
import CodeEditor from 'boost/components/CodeEditor'
import { NEW, IDLE_MODE, CREATE_MODE, EDIT_MODE, switchMode } from '../actions'
import { UNSYNCED, IDLE_MODE, CREATE_MODE, EDIT_MODE, switchMode, switchArticle, updateArticle, destroyArticle } from '../actions'
import aceModes from 'boost/ace-modes'
import Select from 'react-select'
import linkState from 'boost/linkState'
import api from 'boost/api'
var modeOptions = aceModes.map(function (mode) {
return {
@@ -16,16 +17,27 @@ var modeOptions = aceModes.map(function (mode) {
}
})
function makeInstantArticle (article) {
let instantArticle = Object.assign({}, article)
instantArticle.Tags = instantArticle.Tags.map(tag => tag.name)
return instantArticle
}
export default class ArticleDetail extends React.Component {
constructor (props) {
super(props)
this.state = {
article: Object.assign({}, props.activeArticle)
article: makeInstantArticle(props.activeArticle)
}
}
componentWillReceiveProps (nextProps) {
this.setState({article: nextProps.activeArticle})
if (nextProps.activeArticle != null && nextProps.activeArticle.id !== this.state.article.id) {
this.setState({article: makeInstantArticle(nextProps.activeArticle)}, function () {
console.log('receive props')
})
}
}
renderEmpty () {
@@ -36,12 +48,46 @@ export default class ArticleDetail extends React.Component {
)
}
handleEditButtonClick (e) {
let { dispatch } = this.props
dispatch(switchMode(EDIT_MODE))
}
handleDeleteButtonClick (e) {
this.setState({openDeleteConfirmMenu: true})
}
handleDeleteConfirmButtonClick (e) {
let { dispatch, activeUser, activeArticle } = this.props
api.destroyArticle(activeArticle.id)
.then(res => {
console.log(res.body)
})
.catch(err => {
// connect failed need to queue data
if (err.code === 'ECONNREFUSED') {
return
}
if (err.status != null) throw err
else console.log(err)
})
dispatch(destroyArticle(activeUser.id, activeArticle.id))
this.setState({openDeleteConfirmMenu: false})
}
handleDeleteCancleButtonClick (e) {
this.setState({openDeleteConfirmMenu: false})
}
renderIdle () {
let { status, activeArticle, activeUser } = this.props
let { activeArticle, activeUser } = this.props
let tags = activeArticle.Tags.length > 0 ? activeArticle.Tags.map(tag => {
return (
<a key={tag.id}>{tag.name}</a>
<a key={tag.name}>{tag.name}</a>
)
}) : (
<span className='noTags'>Not tagged yet</span>
@@ -50,24 +96,37 @@ export default class ArticleDetail extends React.Component {
let folderName = folder != null ? folder.name : '(unknown)'
return (
<div className='ArticleDetail show'>
<div className='detailInfo'>
<div className='left'>
<div className='info'>
<i className='fa fa-fw fa-square'/> {folderName}&nbsp;
by {activeArticle.User.profileName}&nbsp;
Created {moment(activeArticle.createdAt).format('YYYY/MM/DD')}&nbsp;
Updated {moment(activeArticle.updatedAt).format('YYYY/MM/DD')}
<div className='ArticleDetail idle'>
{this.state.openDeleteConfirmMenu
? (
<div className='deleteConfirm'>
<div className='right'>
Are you sure to delete this article?
<button onClick={e => this.handleDeleteConfirmButtonClick(e)} className='primary'><i className='fa fa-fw fa-check'/> Sure</button>
<button onClick={e => this.handleDeleteCancleButtonClick(e)}><i className='fa fa-fw fa-times'/> Cancle</button>
</div>
</div>
<div className='tags'><i className='fa fa-fw fa-tags'/>{tags}</div>
</div>
)
: (
<div className='detailInfo'>
<div className='left'>
<div className='info'>
<i className='fa fa-fw fa-square'/> {folderName}&nbsp;
by {activeArticle.User.profileName}&nbsp;
Created {moment(activeArticle.createdAt).format('YYYY/MM/DD')}&nbsp;
Updated {moment(activeArticle.updatedAt).format('YYYY/MM/DD')}
</div>
<div className='tags'><i className='fa fa-fw fa-tags'/>{tags}</div>
</div>
<div className='right'>
<button onClick={e => this.handleEditButtonClick(e)}><i className='fa fa-fw fa-edit'/></button>
<button onClick={e => this.handleDeleteButtonClick(e)}><i className='fa fa-fw fa-trash'/></button>
<button><i className='fa fa-fw fa-share-alt'/></button>
</div>
</div>
)
}
<div className='right'>
<button><i className='fa fa-fw fa-edit'/></button>
<button><i className='fa fa-fw fa-trash'/></button>
<button><i className='fa fa-fw fa-share-alt'/></button>
</div>
</div>
<div className='detailBody'>
<div className='detailPanel'>
<div className='header'>
@@ -86,7 +145,67 @@ export default class ArticleDetail extends React.Component {
}
handleSaveButtonClick (e) {
console.log(this.state.article)
let { activeArticle } = this.props
if (typeof activeArticle.id === 'string') this.saveAsNew()
else this.save()
}
saveAsNew () {
let { dispatch, activeUser } = this.props
let article = this.state.article
let newArticle = Object.assign({}, article)
article.tags = article.Tags
api.createArticle(article)
.then(res => {
console.log(res.body)
})
.catch(err => {
// connect failed need to queue data
if (err.code === 'ECONNREFUSED') {
return
}
if (err.status != null) throw err
else console.log(err)
})
newArticle.status = UNSYNCED
newArticle.Tags = newArticle.Tags.map(tag => { return {name: tag} })
dispatch(updateArticle(activeUser.id, newArticle))
dispatch(switchMode(IDLE_MODE))
dispatch(switchArticle(article.id))
}
save () {
let { dispatch, activeUser } = this.props
let article = this.state.article
let newArticle = Object.assign({}, article)
article.tags = article.Tags
api.saveArticle(article)
.then(res => {
console.log(res.body)
})
.catch(err => {
// connect failed need to queue data
if (err.code === 'ECONNREFUSED') {
return
}
if (err.status != null) throw err
else console.log(err)
})
newArticle.status = UNSYNCED
newArticle.Tags = newArticle.Tags.map(tag => { return {name: tag} })
dispatch(updateArticle(activeUser.id, newArticle))
dispatch(switchMode(IDLE_MODE))
dispatch(switchArticle(article.id))
}
handleFolderIdChange (value) {
@@ -121,7 +240,7 @@ export default class ArticleDetail extends React.Component {
}
renderEdit () {
let { status, activeUser } = this.props
let { activeUser } = this.props
let folderOptions = activeUser.Folders.map(folder => {
return {
@@ -146,7 +265,7 @@ export default class ArticleDetail extends React.Component {
<div className='detailPanel'>
<div className='header'>
<div className='title'>
<input ref='title' valueLink={this.linkState('article.title')}/>
<input placeholder='Title' ref='title' valueLink={this.linkState('article.title')}/>
</div>
<Select ref='mode' onChange={value => this.handleModeChange(value)} clearable={false} options={modeOptions}placeholder='select mode...' value={this.state.article.mode} className='mode'/>
</div>