1
0
mirror of https://github.com/BoostIo/Boostnote synced 2025-12-13 17:56:25 +00:00
- add error alert(folder editing)
- debug clear button of search input
This commit is contained in:
Rokt33r
2015-11-05 09:50:07 +09:00
parent cc0f2c7c7f
commit 8abdedc11d
10 changed files with 126 additions and 77 deletions

View File

@@ -27,8 +27,8 @@ class HomePage extends React.Component {
} }
handleKeyDown (e) { handleKeyDown (e) {
if (isModalOpen() && e.keyCode === 27) { if (isModalOpen()) {
closeModal() if (e.keyCode === 27) closeModal()
return return
} }

View File

@@ -61,9 +61,7 @@ export default class ArticleTopBar extends React.Component {
} }
handleSearchClearButton (e) { handleSearchClearButton (e) {
let { dispatch } = this.props this.searchInput.value = ''
dispatch(setSearchFilter(''))
this.focusInput() this.focusInput()
} }

View File

@@ -7,9 +7,9 @@ import HomePage from './HomePage'
// import auth from 'boost/auth' // import auth from 'boost/auth'
import store from 'boost/store' import store from 'boost/store'
import ReactDOM from 'react-dom' import ReactDOM from 'react-dom'
import { isModalOpen, closeModal } from 'boost/modal'
import { IDLE_MODE, CREATE_MODE, EDIT_MODE } from 'boost/actions'
require('../styles/main/index.styl') require('../styles/main/index.styl')
import { openModal } from 'boost/modal'
import Tutorial from 'boost/components/modal/Tutorial'
let routes = ( let routes = (
<Route path='/' component={MainPage}> <Route path='/' component={MainPage}>
@@ -27,4 +27,11 @@ ReactDOM.render((
), el, function () { ), el, function () {
let loadingCover = document.getElementById('loadingCover') let loadingCover = document.getElementById('loadingCover')
loadingCover.parentNode.removeChild(loadingCover) loadingCover.parentNode.removeChild(loadingCover)
let status = JSON.parse(localStorage.getItem('status'))
if (status == null) status = {}
if (!status.introWatched) {
openModal(Tutorial)
status.introWatched = true
localStorage.setItem('status', JSON.stringify(status))
}
}) })

View File

@@ -37,22 +37,17 @@ iptFocusBorderColor = #369DCD
margin 100px auto 25px margin 100px auto 25px
&:focus &:focus
border-color iptFocusBorderColor border-color iptFocusBorderColor
.public .alert
color infoTextColor
background-color infoBackgroundColor
font-size 14px
padding 15px 15px
width 330px
border-radius 5px
margin 0 auto margin 0 auto
text-align center &.error
button color errorTextColor
border none background-color errorBackgroundColor
background-color transparent
font-size 18px
color inactiveTextColor
transition 0.1s
button:hover
font-size 22px
button.active
color brandColor
font-size 22px
.divider
margin 0 5px
.confirmBtn .confirmBtn
display block display block
position absolute position absolute

View File

@@ -103,23 +103,17 @@ iptFocusBorderColor = #369DCD
font-size 14px font-size 14px
&:hover &:hover
background-color lighten(brandColor, 10%) background-color lighten(brandColor, 10%)
.alert .alert
float right color infoTextColor
height 33px background-color infoBackgroundColor
padding 0 15px font-size 14px
border-radius 5px padding 15px 15px
margin-right 5px width 330px
line-height 33px border-radius 5px
font-size 14px margin 10px auto
&.info &.error
background-color infoBackgroundColor color errorTextColor
color infoTextColor background-color errorBackgroundColor
&.error
background-color errorBackgroundColor
color errorTextColor
&.success
background-color successBackgroundColor
color successTextColor
&.AppSettingTab &.AppSettingTab
.description .description
marked() marked()
@@ -390,6 +384,18 @@ iptFocusBorderColor = #369DCD
width 145px width 145px
text-align center text-align center
&.newFolder &.newFolder
.alert
display block
color infoTextColor
background-color infoBackgroundColor
font-size 14px
padding 15px 15px
width 330px
border-radius 5px
margin 0 auto
&.error
color errorTextColor
background-color errorBackgroundColor
.folderName input .folderName input
height 33px height 33px
border 1px solid transparent border 1px solid transparent

View File

@@ -18,22 +18,24 @@ export default class CreateNewFolder extends React.Component {
} }
handleConfirmButton (e) { handleConfirmButton (e) {
let { close } = this.props this.setState({alert: null}, () => {
let name = this.state.name let { close } = this.props
let input = { let name = this.state.name
name let input = {
} name
}
store.dispatch(createFolder(input)) try {
try { store.dispatch(createFolder(input))
} catch (e) { } catch (e) {
this.setState({alert: { this.setState({alert: {
type: 'error', type: 'error',
message: e.message message: e.message
}}) }})
return return
} }
close() close()
})
} }
render () { render () {

View File

@@ -34,20 +34,27 @@ export default class FolderRow extends React.Component {
this.setState({mode: DELETE}) this.setState({mode: DELETE})
} }
handleFolderPublicChange (e) {
this.setState({public: e.target.value})
}
handleSaveButtonClick (e) { handleSaveButtonClick (e) {
let { folder } = this.props let { folder, setAlert } = this.props
let input = {
name: this.state.name
}
Object.assign(folder, input)
store.dispatch(updateFolder(folder)) setAlert(null, () => {
this.setState({ let input = {
mode: IDLE name: this.state.name
}
folder = Object.assign({}, folder, input)
try {
store.dispatch(updateFolder(folder))
this.setState({
mode: IDLE
})
} catch (e) {
console.error(e)
setAlert({
type: 'error',
message: e.message
})
}
}) })
} }
@@ -98,7 +105,8 @@ export default class FolderRow extends React.Component {
} }
FolderRow.propTypes = { FolderRow.propTypes = {
folder: PropTypes.shape() folder: PropTypes.shape(),
setAlert: PropTypes.func
} }
FolderRow.prototype.linkState = linkState FolderRow.prototype.linkState = linkState

View File

@@ -13,25 +13,46 @@ export default class FolderSettingTab extends React.Component {
} }
handleSaveButtonClick (e) { handleSaveButtonClick (e) {
if (this.state.name.trim().length === 0) return false this.setState({alert: null}, () => {
if (this.state.name.trim().length === 0) return false
let { dispatch } = this.props let { dispatch } = this.props
dispatch(createFolder({ try {
name: this.state.name dispatch(createFolder({
})) name: this.state.name
}))
} catch (e) {
this.setState({alert: {
type: 'error',
message: e.message
}})
return
}
this.setState({name: ''}) this.setState({name: ''})
})
}
setAlert (alert, cb) {
this.setState({alert: alert}, cb)
} }
render () { render () {
let { folders } = this.props let { folders } = this.props
let folderElements = folders.map(folder => { let folderElements = folders.map(folder => {
return ( return (
<FolderRow key={'folder-' + folder.key} folder={folder}/> <FolderRow key={'folder-' + folder.key} folder={folder} setAlert={(alert, cb) => this.setAlert(alert, cb)}/>
) )
}) })
let alert = this.state.alert
let alertElement = alert != null ? (
<p className={`alert ${alert.type}`}>
{alert.message}
</p>
) : null
return ( return (
<div className='FolderSettingTab content'> <div className='FolderSettingTab content'>
<div className='section'> <div className='section'>
@@ -50,6 +71,7 @@ export default class FolderSettingTab extends React.Component {
<button onClick={e => this.handleSaveButtonClick(e)} className='primary'>Add</button> <button onClick={e => this.handleSaveButtonClick(e)} className='primary'>Add</button>
</div> </div>
</div> </div>
{alertElement}
</div> </div>
</div> </div>
</div> </div>

View File

@@ -19,6 +19,8 @@ function folders (state = initialFolders, action) {
case FOLDER_CREATE: case FOLDER_CREATE:
{ {
let newFolder = action.data.folder let newFolder = action.data.folder
if (!_.isString(newFolder.name)) throw new Error('Folder name must be a string')
newFolder.name = newFolder.name.trim().replace(/\s/, '_')
Object.assign(newFolder, { Object.assign(newFolder, {
key: keygen(), key: keygen(),
createAt: new Date(), createAt: new Date(),
@@ -27,8 +29,10 @@ function folders (state = initialFolders, action) {
color: Math.round(Math.random() * 7) color: Math.round(Math.random() * 7)
}) })
if (newFolder.length === 0) throw new Error('Folder name is required')
let conflictFolder = _.findWhere(state, {name: newFolder.name}) let conflictFolder = _.findWhere(state, {name: newFolder.name})
if (conflictFolder != null) throw new Error('name conflicted!') if (conflictFolder != null) throw new Error(`${newFolder.name} already exists!`)
state.push(newFolder) state.push(newFolder)
dataStore.setFolders(null, state) dataStore.setFolders(null, state)
@@ -39,11 +43,18 @@ function folders (state = initialFolders, action) {
let folder = action.data.folder let folder = action.data.folder
let targetFolder = _.findWhere(state, {key: folder.key}) let targetFolder = _.findWhere(state, {key: folder.key})
if (!_.isString(folder.name)) throw new Error('Folder name must be a string')
folder.name = folder.name.trim().replace(/\s/, '_')
if (folder.length === 0) throw new Error('Folder name is required')
// Folder existence check // Folder existence check
if (targetFolder == null) throw new Error('Folder doesnt exist') if (targetFolder == null) throw new Error('Folder doesnt exist')
// Name conflict check // Name conflict check
if (targetFolder.name !== folder.name) { if (targetFolder.name !== folder.name) {
let conflictFolder = _.findWhere(state, {name: folder.name}) let conflictFolder = _.find(state, _folder => {
return folder.name === _folder.name && folder.key !== _folder.key
})
console.log(conflictFolder)
if (conflictFolder != null) throw new Error('Name conflicted') if (conflictFolder != null) throw new Error('Name conflicted')
} }
Object.assign(targetFolder, folder, { Object.assign(targetFolder, folder, {

View File

@@ -1,6 +1,6 @@
{ {
"name": "boost", "name": "boost",
"version": "0.4.0-alpha.7", "version": "0.4.0-beta",
"description": "Boost App", "description": "Boost App",
"main": "main.js", "main": "main.js",
"scripts": { "scripts": {