mirror of
https://github.com/BoostIo/Boostnote
synced 2025-12-13 17:56:25 +00:00
beta
- add error alert(folder editing) - debug clear button of search input
This commit is contained in:
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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))
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -104,22 +104,16 @@ iptFocusBorderColor = #369DCD
|
|||||||
&:hover
|
&:hover
|
||||||
background-color lighten(brandColor, 10%)
|
background-color lighten(brandColor, 10%)
|
||||||
.alert
|
.alert
|
||||||
float right
|
|
||||||
height 33px
|
|
||||||
padding 0 15px
|
|
||||||
border-radius 5px
|
|
||||||
margin-right 5px
|
|
||||||
line-height 33px
|
|
||||||
font-size 14px
|
|
||||||
&.info
|
|
||||||
background-color infoBackgroundColor
|
|
||||||
color infoTextColor
|
color infoTextColor
|
||||||
|
background-color infoBackgroundColor
|
||||||
|
font-size 14px
|
||||||
|
padding 15px 15px
|
||||||
|
width 330px
|
||||||
|
border-radius 5px
|
||||||
|
margin 10px auto
|
||||||
&.error
|
&.error
|
||||||
background-color errorBackgroundColor
|
|
||||||
color errorTextColor
|
color errorTextColor
|
||||||
&.success
|
background-color errorBackgroundColor
|
||||||
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
|
||||||
|
|||||||
@@ -18,14 +18,15 @@ export default class CreateNewFolder extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleConfirmButton (e) {
|
handleConfirmButton (e) {
|
||||||
|
this.setState({alert: null}, () => {
|
||||||
let { close } = this.props
|
let { close } = this.props
|
||||||
let name = this.state.name
|
let name = this.state.name
|
||||||
let input = {
|
let input = {
|
||||||
name
|
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',
|
||||||
@@ -34,6 +35,7 @@ export default class CreateNewFolder extends React.Component {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
close()
|
close()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
|
|||||||
@@ -34,21 +34,28 @@ 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
|
||||||
|
|
||||||
|
setAlert(null, () => {
|
||||||
let input = {
|
let input = {
|
||||||
name: this.state.name
|
name: this.state.name
|
||||||
}
|
}
|
||||||
Object.assign(folder, input)
|
folder = Object.assign({}, folder, input)
|
||||||
|
|
||||||
|
try {
|
||||||
store.dispatch(updateFolder(folder))
|
store.dispatch(updateFolder(folder))
|
||||||
this.setState({
|
this.setState({
|
||||||
mode: IDLE
|
mode: IDLE
|
||||||
})
|
})
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e)
|
||||||
|
setAlert({
|
||||||
|
type: 'error',
|
||||||
|
message: e.message
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
handleDeleteConfirmButtonClick (e) {
|
handleDeleteConfirmButtonClick (e) {
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -13,25 +13,46 @@ export default class FolderSettingTab extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleSaveButtonClick (e) {
|
handleSaveButtonClick (e) {
|
||||||
|
this.setState({alert: null}, () => {
|
||||||
if (this.state.name.trim().length === 0) return false
|
if (this.state.name.trim().length === 0) return false
|
||||||
|
|
||||||
let { dispatch } = this.props
|
let { dispatch } = this.props
|
||||||
|
|
||||||
|
try {
|
||||||
dispatch(createFolder({
|
dispatch(createFolder({
|
||||||
name: this.state.name
|
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>
|
||||||
|
|||||||
@@ -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, {
|
||||||
|
|||||||
@@ -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": {
|
||||||
|
|||||||
Reference in New Issue
Block a user