1
0
mirror of https://github.com/BoostIo/Boostnote synced 2025-12-24 23:23:09 +00:00

Redesign SideNav & implement add repo func

This commit is contained in:
Rokt33r
2016-04-18 15:36:02 +09:00
parent 9c5cbd348b
commit ac7e08ae2c
11 changed files with 1062 additions and 211 deletions

View File

@@ -1,202 +0,0 @@
import React, { PropTypes } from 'react'
import { findWhere } from 'lodash'
import { setSearchFilter, switchFolder, uncacheArticle, saveAllArticles, switchArticle, clearSearch } from '../actions'
import { openModal, isModalOpen } from 'browser/lib/modal'
import FolderMark from 'browser/components/FolderMark'
import Preferences from '../modal/Preferences'
import CreateNewFolder from '../modal/CreateNewFolder'
import _ from 'lodash'
import ModeIcon from 'browser/components/ModeIcon'
const ipc = require('electron').ipcRenderer
const BRAND_COLOR = '#18AF90'
const OSX = global.process.platform === 'darwin'
const preferenceTutorialElement = (
<svg width='300' height='300' className='tutorial'>
<text x='15' y='30' fill={BRAND_COLOR} fontSize='24'>Preference</text>
<svg x='-30' y='-270' width='400' height='400'>
<path fill='white' d='M165.9,297c5.3,0,10.6,0.1,15.8,0.1c3.3,0,7.7,0.8,10.7-1c2.3-1.4,3.1-4,4.5-6.2c3.5-5.5,9.6-5.2,14.6-1.9
c4.6,3.1,8.7,8,8.4,13.8c-0.3,5.2-3.3,10.1-6.1,14.3c-3.1,4.7-6.6,7-12.2,7.9c-5.2,0.8-11.7,1.6-15.4-3
c-6.6-8.2,2.1-20.5,7.4-27.1c6.5-8.1,20.1-14,26.4-2.1c5.4,10.3-3.1,21.7-13,24.8c-5.7,1.8-11,0.9-16.2-1.9c-2-1.1-5-2.6-6.6-4.4
c-3.9-4.3-0.3-8.2,2.5-11.2c1.3-1.4-0.8-3.6-2.1-2.1c-2.7,2.9-5.8,6.6-5.1,10.9c0.7,4.4,5.6,6.9,9,8.9c8.6,5.1,18.7,4.8,26.8-1.2
c7.3-5.4,11.6-15,8-23.7c-3.3-8.1-11.7-11.8-20-9c-12.5,4.1-33.7,33.5-15.9,43.1c6.8,3.7,19.8,1.8,25.3-3.6
c6.1-5.8,12.1-17.2,9.5-25.7c-2.6-8.4-13.7-17-22.6-13.3c-1.6,0.7-3,1.7-4.1,3c-1.6,1.9-2.2,5.1-4.1,6.6c-3.1,2.4-10.1,1-13.7,1
c-4,0-7.9,0-11.9-0.1C164,294,164,297,165.9,297L165.9,297z'/>
</svg>
</svg>
)
const newFolderTutorialElement = (
<svg width='800' height='500' className='tutorial'>
<text x='30' y='110' fill={BRAND_COLOR} fontSize='24'>Create a new folder!!</text>
<text x='50' y='135' fill={BRAND_COLOR} fontSize='16'>{'press ' + (OSX ? '`⌘ + Shift + n`' : '`^ + Shift + n`')}</text>
<svg x='50' y='10' width='300' height='400'>
<path fill='white' d='M94.1,10.9C77.7,15.6,62,22.7,47.8,32.1c-13.6,9-27.7,20.4-37.1,33.9c-1.1,1.6,1.5,3.1,2.6,1.5
C22.6,54.1,37,42.7,50.6,33.8c13.7-8.8,28.6-15.5,44.2-20C96.7,13.3,95.9,10.4,94.1,10.9L94.1,10.9z'/>
<path fill='white' d='M71.1,8.6c7.9,1.6,15.8,3.2,23.6,4.7c-0.1-0.9-0.2-1.8-0.4-2.7c-4.6,3.4-5.4,7.7-4.4,13.2
c0.8,4.4,0.8,10.9,5.6,12.8c1.8,0.7,2.6-2.2,0.8-2.9c-2.3-1-2.6-6.2-3-8.3c-0.9-4.5-1.7-9,2.5-12.1c0.9-0.7,1-2.5-0.4-2.7
C87.5,9,79.6,7.4,71.8,5.9C70,5.4,69.2,8.3,71.1,8.6L71.1,8.6z'/>
</svg>
</svg>
)
export default class ArticleNavigator extends React.Component {
constructor (props) {
super(props)
this.newFolderHandler = e => {
if (isModalOpen()) return true
this.handleNewFolderButton(e)
}
}
componentDidMount () {
ipc.on('nav-new-folder', this.newFolderHandler)
}
componentWillUnmount () {
ipc.removeListener('nav-new-folder', this.newFolderHandler)
}
handlePreferencesButtonClick (e) {
openModal(Preferences)
}
handleNewFolderButton (e) {
let { user } = this.props
openModal(CreateNewFolder, {user: user})
}
handleFolderButtonClick (name) {
return e => {
let { dispatch } = this.props
dispatch(switchFolder(name))
}
}
handleAllFoldersButtonClick (e) {
let { dispatch } = this.props
dispatch(setSearchFilter(''))
}
handleUnsavedItemClick (article) {
let { dispatch } = this.props
return e => {
let { articles } = this.props
let isInArticleList = articles.some(_article => _article.key === article.key)
if (!isInArticleList) dispatch(clearSearch())
dispatch(switchArticle(article.key))
}
}
handleUncacheButtonClick (article) {
let { dispatch } = this.props
return e => {
dispatch(uncacheArticle(article.key))
}
}
handleSaveAllClick (e) {
let { dispatch } = this.props
dispatch(saveAllArticles())
}
render () {
let { status, user, folders, allArticles, modified, activeArticle } = this.props
let { targetFolders } = status
if (targetFolders == null) targetFolders = []
let modifiedElements = modified.map(modifiedArticle => {
let originalArticle = _.findWhere(allArticles, {key: modifiedArticle.key})
if (originalArticle == null) return false
let combinedArticle = Object.assign({}, originalArticle, modifiedArticle)
let className = 'ArticleNavigator-unsaved-list-item'
if (activeArticle && activeArticle.key === combinedArticle.key) className += ' active'
return (
<div key={modifiedArticle.key} onClick={e => this.handleUnsavedItemClick(combinedArticle)(e)} className={className}>
<div className='ArticleNavigator-unsaved-list-item-label'>
<ModeIcon mode={combinedArticle.mode}/>&nbsp;
{combinedArticle.title.trim().length > 0
? combinedArticle.title
: <span className='ArticleNavigator-unsaved-list-item-label-untitled'>(Untitled)</span>}
</div>
<button onClick={e => this.handleUncacheButtonClick(combinedArticle)(e)} className='ArticleNavigator-unsaved-list-item-discard-button'><i className='fa fa-times'/></button>
</div>
)
}).filter(modifiedArticle => modifiedArticle).sort((a, b) => a.updatedAt - b.updatedAt)
let hasModified = modifiedElements.length > 0
let folderElememts = folders.map((folder, index) => {
let isActive = findWhere(targetFolders, {key: folder.key})
let articleCount = allArticles.filter(article => article.FolderKey === folder.key && article.status !== 'NEW').length
return (
<button onClick={e => this.handleFolderButtonClick(folder.name)(e)} key={'folder-' + folder.key} className={isActive ? 'active' : ''}>
<FolderMark color={folder.color}/> {folder.name} <span className='articleCount'>{articleCount}</span>
</button>
)
})
return (
<div tabIndex='1' className='ArticleNavigator'>
<div className='userInfo'>
<div className='userProfileName'>{user.name}</div>
<div className='userName'>localStorage</div>
<button onClick={e => this.handlePreferencesButtonClick(e)} className='settingBtn'>
<i className='fa fa-fw fa-chevron-down'/>
<span className='tooltip'>Preferences</span>
</button>
{status.isTutorialOpen ? preferenceTutorialElement : null}
</div>
{/*<div className={'ArticleNavigator-unsaved' + (hasModified ? '' : ' hide')}>
<div className='ArticleNavigator-unsaved-header'>Work in progress</div>
<div className='ArticleNavigator-unsaved-list'>
{modifiedElements}
</div>
<div className='ArticleNavigator-unsaved-control'>
<button onClick={e => this.handleSaveAllClick()} className='ArticleNavigator-unsaved-control-save-all-button' disabled={modifiedElements.length === 0}>Save all</button>
</div>
</div>*/}
<div className={'ArticleNavigator-folders expand'}>
{status.isTutorialOpen ? newFolderTutorialElement : null}
<div className='ArticleNavigator-folders-header'>
<div className='title'>Folders</div>
<button onClick={e => this.handleNewFolderButton(e)} className='addBtn'>
<i className='fa fa-fw fa-plus'/>
<span className='tooltip'>Create a new folder ({OSX ? '⌘' : '^'} + Shift + n)</span>
</button>
</div>
<div className='folderList'>
<button onClick={e => this.handleAllFoldersButtonClick(e)} className={targetFolders.length === 0 ? 'active' : ''}>All folders</button>
{folderElememts}
</div>
</div>
</div>
)
}
}
ArticleNavigator.propTypes = {
dispatch: PropTypes.func,
status: PropTypes.shape({
folderId: PropTypes.number
}),
user: PropTypes.object,
folders: PropTypes.array,
allArticles: PropTypes.array,
articles: PropTypes.array,
modified: PropTypes.array,
activeArticle: PropTypes.shape({
key: PropTypes.string
})
}

View File

@@ -0,0 +1,75 @@
import React, { PropTypes } from 'react'
import CSSModules from 'browser/lib/CSSModules'
import styles from './Repository.styl'
class Repository extends React.Component {
render () {
let { repository } = this.props
let folderElements = repository.folders.map((folder) => {
return (
<div
key={folder.name}
styleName='folder'
>
<div styleName='folder-label'>
<i className='fa fa-cube'/> {folder.name}
</div>
<div styleName='folder-control'>
<button styleName='folder-control-button'>
<i className='fa fa-pencil'/>
</button>
<button styleName='folder-control-button'>
<i className='fa fa-trash'/>
</button>
</div>
</div>
)
})
return (
<div
className='Repository'
styleName='root'
>
<div styleName='header'>
<div styleName='header-name'>
<i className='fa fa-archive'/> {repository.name}
</div>
<div styleName='header-control'>
<button styleName='header-control-button'
>
<i className='fa fa-unlink'/>
</button>
<button styleName='header-control-button'
>
<i className='fa fa-pencil'/>
</button>
<button styleName='header-control-button'
>
<i className='fa fa-angle-down'/>
</button>
</div>
</div>
{folderElements}
<button styleName='newFolderButton'
>
<i className='fa fa-plus'/> New Folder
</button>
</div>
)
}
}
Repository.propTypes = {
repository: PropTypes.shape({
name: PropTypes.string,
folders: PropTypes.arrayOf(PropTypes.shape({
name: PropTypes.string
}))
})
}
export default CSSModules(Repository, styles)

View File

@@ -0,0 +1,90 @@
.root
margin-top 15px
margin-bottom 15px
.header
position relative
height 33px
&:hover
background-color alpha(white, 0.1)
.header-name
position absolute
left 0
top 0
bottom 0
right 72px
padding-left 10px
line-height 33px
color white
.header-control
position absolute
top 0
bottom 0
right 5px
width 72px
.header-control-button
width 24px
padding 0
margin-top 4.5px
height 24px
border none
border-radius 5px
background-color transparent
color white
&:hover
background-color alpha(white, 0.1)
&:active
background-color $brand-color
.folder
height 33px
width 100%
position relative
&:hover
background-color alpha(white 0.1)
.folder-label
position absolute
left 0
top 0
bottom 0
right 48px
padding-left 20px
line-height 33px
color white
.folder-control
position absolute
top 0
bottom 0
right 0
width 48px
.folder-control-button
width 24px
height 24px
margin-top 4.5px
border none
border-radius 5px
background-color transparent
color white
&:hover
background-color alpha(white, 0.1)
&:active
background-color $brand-color
.newFolderButton
height 33px
width 100%
border none
padding-left 20px
text-align left
background-color transparent
color white
&:hover
background-color alpha(white, 0.1)
&:active
background-color $brand-color

View File

@@ -0,0 +1,63 @@
$nav-border-color = #838383
$nav-background-color = #353535
.root
absolute top bottom left
width 200px
border-right solid 1px $nav-border-color
background-color $nav-background-color
.menu
margin-top 30px
margin-bottom 15px
.menu-button
height 33px
padding 0 10px
font-size 14px
width 100%
text-align left
border none
color white
background-color transparent
&:hover
background-color alph(white, 0.1)
&:active
background-color $brand-color
.repositoryList
absolute left right
top 145px
border-top solid 1px $nav-border-color
.control
absolute bottom left right
height 33px
border-top solid 1px $nav-border-color
.control-newRepositoryButton
absolute top bottom left
width 167px
padding 0 10px
text-align left
border-width 0 1px 0 0
border-color $nav-border-color
border-style solid
color white
background-color transparent
&:hover
background-color alph(white, 0.1)
&:active
background-color $brand-color
.control-toggleButton
absolute top bottom right
width 33px
color white
background-color transparent
border none
&:hover
background-color alph(white, 0.1)
&:active
background-color $brand-color

View File

@@ -0,0 +1,156 @@
import React, { PropTypes } from 'react'
import CSSModules from 'browser/lib/CSSModules'
import styles from './SideNav.styl'
import actions from 'browser/main/actions'
import { openModal, isModalOpen } from 'browser/lib/modal'
import Preferences from '../../modal/Preferences'
import CreateNewFolder from '../../modal/CreateNewFolder'
import Repository from './Repository'
import NewRepositoryModal from '../../modal/NewRepositoryModal'
const ipc = require('electron').ipcRenderer
const BRAND_COLOR = '#18AF90'
const OSX = global.process.platform === 'darwin'
const preferenceTutorialElement = (
<svg width='300' height='300' className='tutorial'>
<text x='15' y='30' fill={BRAND_COLOR} fontSize='24'>Preference</text>
<svg x='-30' y='-270' width='400' height='400'>
<path fill='white' d='M165.9,297c5.3,0,10.6,0.1,15.8,0.1c3.3,0,7.7,0.8,10.7-1c2.3-1.4,3.1-4,4.5-6.2c3.5-5.5,9.6-5.2,14.6-1.9
c4.6,3.1,8.7,8,8.4,13.8c-0.3,5.2-3.3,10.1-6.1,14.3c-3.1,4.7-6.6,7-12.2,7.9c-5.2,0.8-11.7,1.6-15.4-3
c-6.6-8.2,2.1-20.5,7.4-27.1c6.5-8.1,20.1-14,26.4-2.1c5.4,10.3-3.1,21.7-13,24.8c-5.7,1.8-11,0.9-16.2-1.9c-2-1.1-5-2.6-6.6-4.4
c-3.9-4.3-0.3-8.2,2.5-11.2c1.3-1.4-0.8-3.6-2.1-2.1c-2.7,2.9-5.8,6.6-5.1,10.9c0.7,4.4,5.6,6.9,9,8.9c8.6,5.1,18.7,4.8,26.8-1.2
c7.3-5.4,11.6-15,8-23.7c-3.3-8.1-11.7-11.8-20-9c-12.5,4.1-33.7,33.5-15.9,43.1c6.8,3.7,19.8,1.8,25.3-3.6
c6.1-5.8,12.1-17.2,9.5-25.7c-2.6-8.4-13.7-17-22.6-13.3c-1.6,0.7-3,1.7-4.1,3c-1.6,1.9-2.2,5.1-4.1,6.6c-3.1,2.4-10.1,1-13.7,1
c-4,0-7.9,0-11.9-0.1C164,294,164,297,165.9,297L165.9,297z'/>
</svg>
</svg>
)
const newFolderTutorialElement = (
<svg width='800' height='500' className='tutorial'>
<text x='30' y='110' fill={BRAND_COLOR} fontSize='24'>Create a new folder!!</text>
<text x='50' y='135' fill={BRAND_COLOR} fontSize='16'>{'press ' + (OSX ? '`⌘ + Shift + n`' : '`^ + Shift + n`')}</text>
<svg x='50' y='10' width='300' height='400'>
<path fill='white' d='M94.1,10.9C77.7,15.6,62,22.7,47.8,32.1c-13.6,9-27.7,20.4-37.1,33.9c-1.1,1.6,1.5,3.1,2.6,1.5
C22.6,54.1,37,42.7,50.6,33.8c13.7-8.8,28.6-15.5,44.2-20C96.7,13.3,95.9,10.4,94.1,10.9L94.1,10.9z'/>
<path fill='white' d='M71.1,8.6c7.9,1.6,15.8,3.2,23.6,4.7c-0.1-0.9-0.2-1.8-0.4-2.7c-4.6,3.4-5.4,7.7-4.4,13.2
c0.8,4.4,0.8,10.9,5.6,12.8c1.8,0.7,2.6-2.2,0.8-2.9c-2.3-1-2.6-6.2-3-8.3c-0.9-4.5-1.7-9,2.5-12.1c0.9-0.7,1-2.5-0.4-2.7
C87.5,9,79.6,7.4,71.8,5.9C70,5.4,69.2,8.3,71.1,8.6L71.1,8.6z'/>
</svg>
</svg>
)
class SideNav extends React.Component {
constructor (props) {
super(props)
this.newFolderHandler = e => {
if (isModalOpen()) return true
this.handleNewFolderButton(e)
}
}
componentDidMount () {
ipc.on('nav-new-folder', this.newFolderHandler)
}
componentWillUnmount () {
ipc.removeListener('nav-new-folder', this.newFolderHandler)
}
handlePreferencesButtonClick (e) {
openModal(Preferences)
}
handleNewFolderButton (e) {
let { user } = this.props
openModal(CreateNewFolder, {user: user})
}
handleFolderButtonClick (name) {
return e => {
let { dispatch } = this.props
dispatch(actions.switchFolder(name))
}
}
handleAllFoldersButtonClick (e) {
let { dispatch } = this.props
dispatch(actions.setSearchFilter(''))
}
handleNewRepositoryButtonClick (e) {
openModal(NewRepositoryModal)
}
render () {
let { repositories } = this.props
let repositorieElements = repositories.map((repo) => {
return <Repository
key={repo.name}
repository={repo}
/>
})
return (
<div
className='SideNav'
styleName='root'
tabIndex='1'
>
<div styleName='menu'>
<button styleName='menu-button'
>
<i className='fa fa-history'/> Recents
</button>
<button styleName='menu-button'
>
<i className='fa fa-star'/> Favorited
</button>
<button styleName='menu-button'
>
<i className='fa fa-list'/> All posts
</button>
</div>
<div styleName='repositoryList'>
{repositories.length > 0 ? repositorieElements : (
<div styleName='repositoryList-empty'>Empty</div>
)}
</div>
<div styleName='control'>
<button
styleName='control-newRepositoryButton'
onClick={(e) => this.handleNewRepositoryButtonClick(e)}
>
<i className='fa fa-plus'/> New Repository
</button>
<button styleName='control-toggleButton'
>
<i className='fa fa-angle-double-right'/>
</button>
</div>
</div>
)
}
}
SideNav.propTypes = {
dispatch: PropTypes.func,
status: PropTypes.shape({
folderId: PropTypes.number
}),
user: PropTypes.object,
folders: PropTypes.array,
allArticles: PropTypes.array,
articles: PropTypes.array,
modified: PropTypes.array,
activeArticle: PropTypes.shape({
key: PropTypes.string
}),
repositories: PropTypes.array
}
export default CSSModules(SideNav, styles)

View File

@@ -2,7 +2,7 @@ import React, { PropTypes} from 'react'
import { connect } from 'react-redux'
import ReactDOM from 'react-dom'
import { toggleTutorial } from '../actions'
import ArticleNavigator from './ArticleNavigator'
import SideNav from './SideNav'
import ArticleTopBar from './ArticleTopBar'
import ArticleList from './ArticleList'
import ArticleDetail from './ArticleDetail'
@@ -73,12 +73,14 @@ class HomePage extends React.Component {
render () {
let { dispatch, status, user, articles, allArticles, modified, activeArticle, folders, tags } = this.props
let { repositories } = this.props
return (
<div className='HomePage'>
<ArticleNavigator
<SideNav
ref='nav'
dispatch={dispatch}
repositories={repositories}
status={status}
user={user}
folders={folders}
@@ -212,6 +214,8 @@ function remap (state) {
let activeArticle = _.findWhere(articles, {key: status.articleKey})
if (activeArticle == null) activeArticle = articles[0]
let { repositories } = state
return {
user,
folders,
@@ -220,7 +224,8 @@ function remap (state) {
allArticles,
modified,
activeArticle,
tags
tags,
repositories
}
}
@@ -235,7 +240,8 @@ HomePage.propTypes = {
activeArticle: PropTypes.shape(),
dispatch: PropTypes.func,
folders: PropTypes.array,
tags: PropTypes.array
tags: PropTypes.array,
repositories: PropTypes.array
}
export default connect(remap)(HomePage)

View File

@@ -153,6 +153,17 @@ export function toggleTutorial () {
}
}
/**
* v0.6.* Actions
*/
export function addRepo (data) {
return {
type: 'ADD_REPOSITORY',
data
}
}
export default {
updateUser,
@@ -174,5 +185,8 @@ export default {
setSearchFilter,
setTagFilter,
clearSearch,
toggleTutorial
toggleTutorial,
// v0.6.*
addRepo
}

View File

@@ -0,0 +1,175 @@
import React, { PropTypes } from 'react'
import CSSModules from 'browser/lib/CSSModules'
import styles from './NewRepositoryModal.styl'
import linkState from 'browser/lib/linkState'
import RepositoryManager from 'browser/lib/RepositoryManager'
import store from 'browser/main/store'
import actions from 'browser/main/actions'
const electron = require('electron')
const remote = electron.remote
function browseFolder () {
let dialog = remote.dialog
let defaultPath = remote.app.getHomeDir()
return new Promise((resolve, reject) => {
dialog.showOpenDialog({
title: 'Select Directory',
defaultPath,
properties: ['openDirectory', 'createDirectory']
}, function (targetPaths) {
if (targetPaths == null) return resolve('')
resolve(targetPaths[0])
})
})
}
class NewRepositoryModal extends React.Component {
constructor (props) {
super(props)
this.state = {
name: '',
path: '',
isPathSectionFocused: false,
error: null,
isBrowsingPath: false
}
}
handleCloseButtonClick (e) {
this.props.close()
}
handlePathFocus (e) {
this.setState({
isPathSectionFocused: true
})
}
handlePathBlur (e) {
if (e.relatedTarget !== this.refs.pathInput && e.relatedTarget !== this.refs.browseButton) {
this.setState({
isPathSectionFocused: false
})
}
}
handleBrowseButtonClick (e) {
this.setState({
isBrowsingPath: true
}, () => {
browseFolder()
.then((targetPath) => {
this.setState({
path: targetPath,
isBrowsingPath: false
})
})
.catch((err) => {
console.error('BrowseFAILED')
console.error(err)
this.setState({
isBrowsingPath: false
})
})
})
}
handleConfirmButtonClick (e) {
let targetPath = this.state.path
let name = this.state.name
RepositoryManager
.addRepo({
targetPath,
name
})
.then((newRepo) => {
store.dispatch(actions.addRepo(newRepo))
this.props.close()
})
.catch((err) => {
console.error(err)
this.setState({
error: err.message
})
})
}
render () {
return (
<div className='NewRepositoryModal'
styleName='root'
>
<div styleName='header'>
<div styleName='header-title'>New Repository</div>
<button styleName='header-closeButton'
onClick={(e) => this.handleCloseButtonClick(e)}
>
<i className='fa fa-times'/>
</button>
</div>
<div styleName='body'>
<div styleName='body-section'>
<div styleName='body-section-label'>Repository Name</div>
<input styleName='body-section-input'
ref='nameInput'
valueLink={this.linkState('name')}
/>
</div>
<div styleName='body-section'>
<div styleName='body-section-label'>Repository Path</div>
<div styleName={!this.state.isPathSectionFocused ? 'body-section-path' : 'body-section-path--focus'}>
<input styleName='body-section-path-input'
valueLink={this.linkState('path')}
style={styles.body_section_path_input}
onFocus={(e) => this.handlePathFocus(e)}
onBlur={(e) => this.handlePathBlur(e)}
disabled={this.state.isBrowsingPath}
/>
<button styleName='body-section-path-button'
onClick={(e) => this.handleBrowseButtonClick(e)}
onFocus={(e) => this.handlePathFocus(e)}
onBlur={(e) => this.handlePathBlur(e)}
disabled={this.state.isBrowsingPath}
>
...
</button>
</div>
</div>
{
this.state.error != null && (
<div styleName='body-error'>
{this.state.error}
</div>
)
}
</div>
<div styleName='footer'>
<button styleName='footer-cancelButton'
onClick={(e) => this.handleCloseButtonClick(e)}
>
<i className='fa fa-times'/> Cancel
</button>
<button styleName='footer-confirmButton'
onClick={(e) => this.handleConfirmButtonClick(e)}
>
<i className='fa fa-check'/> Confirm
</button>
</div>
</div>
)
}
}
NewRepositoryModal.propTypes = {
close: PropTypes.func
}
NewRepositoryModal.prototype.linkState = linkState
export default CSSModules(NewRepositoryModal, styles)

View File

@@ -0,0 +1,133 @@
$modal-width = 550px
$modal-header-color = #F2F2F2
$body-button-background-color = #2BAC8F
.root
modal()
width $modal-width
height 310px
.header
height 50px
background-color $modal-header-color
.header-title
font-size 24px
line-height 50px
padding-left 15px
.header-closeButton
position absolute
top 8.5px
right 8.5px
width 33px
height 33px
font-size 20px
background-color transparent
border none
color #AAA
&:hover
color #4D4D4D
.body
absolute left right
top 50px
bottom 50px
padding 35px 0
.body-section
height 33px
margin-bottom 15px
position relative
.body-section-label
absolute top bottom left
width 175px
text-align right
line-height 33px
padding-right 15px
.body-section-input
absolute top bottom
left 175px
width 315px
padding 0 10px
border $default-border
border-radius 5px
outline none
&:focus
border $active-border
.body-section-path
absolute top bottom
left 175px
width 315px
padding 0 10px
border $default-border
border-radius 5px
outline none
overflow hidden
.body-section-path--focus
@extend .body-section-path
border $active-border
.body-section-path-input
absolute top left bottom
width 265px
border none
outline none
padding 0 10px
.body-section-path-button
absolute top right bottom
width 50px
border none
border-left $default-border
outline none
color white
background-color $body-button-background-color
transition 0.15s
&:hover
background-color lighten($body-button-background-color, 7%)
&:disabled
background-color lighten(gray, 15%)
.body-error
height 33px
margin 35px auto 0
width 320px
border-radius 5px
text-align center
line-height 33px
color $danger-color
background-color $danger-lighten-color
.footer
absolute left right bottom
height 50px
.footer-cancelButton
position absolute
height 33px
right 85.5px
width 72px
top 8.5px
border-radius 5px
border $default-border
background-color darken(white, 0.03)
&:hover
background-color white
.footer-confirmButton
position absolute
height 33px
right 8.5px
width 72px
top 8.5px
color white
border-radius 5px
border none
background-color #2BAC8F
&:hover
background-color lighten($body-button-background-color, 7%)

View File

@@ -36,14 +36,16 @@ const initialStatus = {
isTutorialOpen: false
}
dataStore.init()
let data = dataStore.getData()
let data = {
articles: [],
folders: []
}
let initialArticles = {
data: data && data.articles ? data.articles : [],
modified: []
}
let initialFolders = data && data.folders ? data.folders : []
let initialUser = dataStore.getUser().user
let initialUser = {}
function user (state = initialUser, action) {
switch (action.type) {
@@ -298,9 +300,53 @@ function status (state = initialStatus, action) {
}
}
/**
* v0.6.* Reducers
*/
/**
* Repositories
* ```
* repositories = [{
* key: String,
* name: String,
* path: String, // path of repository
* status: String, // status of repository [LOADING, IDLE, ERROR]
* folders: {
* name: String,
* color: String
* },
* notes: [{
* key: String,
* title: String,
* content: String,
* folder: String,
* tags: [String],
* createdAt: Date,
* updatedAt: Date
* }]
* }]
* ```
*/
import RepositoryManager from 'browser/lib/RepositoryManager'
const initialRepositories = RepositoryManager.getRepos()
function repositories (state = initialRepositories, action) {
console.log(state)
switch (action.type) {
case 'ADD_REPOSITORY':
let repos = state.slice()
repos.push(action.data)
return repos
}
return state
}
// v0.6 end
export default combineReducers({
user,
folders,
articles,
status
status,
repositories
})