diff --git a/browser/lib/Repository.js b/browser/lib/Repository.js
index 3a72ec0c..9c583b4b 100644
--- a/browser/lib/Repository.js
+++ b/browser/lib/Repository.js
@@ -362,7 +362,7 @@ class Repository {
if (_.isString(override.name) && override.name.trim().length > 0) targetFolder.name = override.name.trim()
if (_.isString(override.color)) targetFolder.color = override.color
- return this.updateJSON(this.json)
+ return this.saveJSON(this.json)
.then(() => targetFolder)
}
@@ -380,7 +380,7 @@ class Repository {
targetFolder = folders.splice(targetIndex, 1)[0]
}
- return this.updateJSON(null)
+ return this.saveJSON(null)
.then(() => targetFolder)
}
diff --git a/browser/lib/consts.js b/browser/lib/consts.js
index de75eaf1..400ffb78 100644
--- a/browser/lib/consts.js
+++ b/browser/lib/consts.js
@@ -8,6 +8,16 @@ const consts = {
'#1FAD85',
'#E10051',
'#B013A4'
+ ],
+ FOLDER_COLOR_NAMES: [
+ 'Cerulean Blue',
+ 'Dodger Blue',
+ 'Pizazz',
+ 'Confetti',
+ 'Emerald',
+ 'Mountain Meadow',
+ 'Razzmatazz',
+ 'Violet Eggplant'
]
}
diff --git a/browser/main/HomePage/SideNav/FolderItem.js b/browser/main/HomePage/SideNav/FolderItem.js
new file mode 100644
index 00000000..c9164225
--- /dev/null
+++ b/browser/main/HomePage/SideNav/FolderItem.js
@@ -0,0 +1,212 @@
+import React, { PropTypes } from 'react'
+import CSSModules from 'browser/lib/CSSModules'
+import styles from './FolderItem.styl'
+import store from 'browser/main/store'
+import Repository from 'browser/lib/Repository'
+import consts from 'browser/lib/consts'
+
+const electron = require('electron')
+const { remote } = electron
+const { Menu, MenuItem } = remote
+
+class FolderItem extends React.Component {
+ constructor (props) {
+ super(props)
+
+ this.state = {
+ isEditing: false,
+ isUpdating: false,
+ name: props.folder.name
+ }
+ }
+
+ handleColorButtonClick (color) {
+ return (e) => {
+ let { repository, folder } = this.props
+ this.setState({
+ isUpdating: true
+ }, () => {
+ Repository.find(repository.key)
+ .then((repository) => {
+ console.log(repository)
+ return repository.updateFolder(folder.key, {color: color})
+ })
+ .then((folder) => {
+ store.dispatch({
+ type: 'EDIT_FOLDER',
+ key: repository.key,
+ folder: folder
+ })
+ this.setState({
+ isEditing: false,
+ isUpdating: false
+ })
+ })
+ .catch((err) => {
+ console.error(err)
+ this.setState({
+ isEditing: false,
+ isUpdating: false
+ })
+ })
+ })
+ }
+ }
+
+ handleContextButtonClick (e) {
+ if (this.state.isUpdating) {
+ return
+ }
+
+ var menu = new Menu()
+ menu.append(new MenuItem({
+ label: 'Rename',
+ click: () => this.handleRenameButtonClick(e)
+ }))
+ var colorMenu = new Menu()
+ consts.FOLDER_COLORS.forEach((color, index) => {
+ colorMenu.append(new MenuItem({
+ label: consts.FOLDER_COLOR_NAMES[index],
+ click: (e) => this.handleColorButtonClick(color)(e)
+ }))
+ })
+ menu.append(new MenuItem({
+ label: 'Recolor',
+ submenu: colorMenu
+ }))
+ menu.append(new MenuItem({ type: 'separator' }))
+ menu.append(new MenuItem({
+ label: 'Delete',
+ click: () => this.handleDeleteButtonClick(e)
+ }))
+
+ menu.popup(remote.getCurrentWindow())
+ }
+
+ handleRenameButtonClick (e) {
+ this.setState({
+ isEditing: true,
+ name: this.props.folder.name
+ }, () => {
+ this.refs.nameInput.focus()
+ })
+ }
+
+ handleDeleteButtonClick (e) {
+ let { repository, folder } = this.props
+
+ this.setState({
+ isUpdating: true
+ }, () => {
+ Repository.find(repository.key)
+ .then((repository) => {
+ console.log(repository)
+ return repository.removeFolder(folder.key)
+ })
+ .then(() => {
+ store.dispatch({
+ type: 'REMOVE_FOLDER',
+ repository: repository.key,
+ folder: folder.key
+ })
+ })
+ .catch((err) => {
+ console.error(err)
+ this.setState({
+ isUpdating: false
+ })
+ })
+ })
+ }
+
+ renderIdle () {
+ let { folder } = this.props
+
+ return (
+
+
+ {folder.name}
+
+
+
+
+
+ )
+ }
+
+ handleNameInputChange (e) {
+ this.setState({
+ name: e.target.value
+ })
+ }
+
+ handleNameInputBlur (e) {
+ let { folder, repository } = this.props
+
+ this.setState({
+ isUpdating: true
+ }, () => {
+ Repository.find(repository.key)
+ .then((repository) => {
+ console.log(repository)
+ return repository.updateFolder(folder.key, {name: this.state.name})
+ })
+ .then((folder) => {
+ store.dispatch({
+ type: 'EDIT_FOLDER',
+ key: repository.key,
+ folder: folder
+ })
+ this.setState({
+ isEditing: false,
+ isUpdating: false
+ })
+ })
+ .catch((err) => {
+ console.error(err)
+ this.setState({
+ isEditing: false,
+ isUpdating: false
+ })
+ })
+ })
+ }
+
+ renderEdit () {
+ return (
+ this.handleContextButtonClick(e)}
+ >
+ this.handleNameInputChange(e)}
+ onBlur={(e) => this.handleNameInputBlur(e)}
+ disabled={this.state.isUpdating}
+ />
+
+ )
+ }
+
+ render () {
+ return this.state.isEditing ? this.renderEdit() : this.renderIdle()
+ }
+}
+
+FolderItem.propTypes = {
+ folder: PropTypes.shape({
+ name: PropTypes.string,
+ color: PropTypes.string
+ }),
+ repository: PropTypes.shape({
+ key: PropTypes.string
+ })
+}
+
+export default CSSModules(FolderItem, styles)
diff --git a/browser/main/HomePage/SideNav/FolderItem.styl b/browser/main/HomePage/SideNav/FolderItem.styl
new file mode 100644
index 00000000..817b975e
--- /dev/null
+++ b/browser/main/HomePage/SideNav/FolderItem.styl
@@ -0,0 +1,56 @@
+.root
+ height 33px
+ width 100%
+ position relative
+ cursor pointer
+ &:hover
+ background-color alpha(white, 0.1)
+ .control
+ opacity 1
+
+.label
+ position absolute
+ left 0
+ top 0
+ bottom 0
+ right 48px
+ padding-left 20px
+ line-height 33px
+ color white
+
+.control
+ opacity 0
+ position absolute
+ top 0
+ bottom 0
+ right 5px
+ width 24px
+
+.control-button
+ width 24px
+ height 24px
+ margin-top 4.5px
+ border none
+ border-radius 5px
+ background-color transparent
+ color $nav-inactive-color
+ &:hover
+ color white
+ background-color alpha(white, 0.1)
+ &:active
+ color white
+ background-color $brand-color
+
+.nameInput
+ absolute top bottom
+ left 10px
+ right 10px
+ height 33px
+ padding 0 10px
+ border-radius 5px
+ border solid 1px $nav-border-color
+ outline none
+ &:focus
+ border-color $focus-border-color
+ &:disabled
+ background-color $disabled-input-background
diff --git a/browser/main/HomePage/SideNav/RepositorySection.js b/browser/main/HomePage/SideNav/RepositorySection.js
index 6ace6531..294e2a99 100644
--- a/browser/main/HomePage/SideNav/RepositorySection.js
+++ b/browser/main/HomePage/SideNav/RepositorySection.js
@@ -2,11 +2,11 @@ import React, { PropTypes } from 'react'
import CSSModules from 'browser/lib/CSSModules'
import styles from './RepositorySection.styl'
import Repository from 'browser/lib/Repository'
+import FolderItem from './FolderItem'
const electron = require('electron')
const { remote } = electron
-const Menu = remote.Menu
-const MenuItem = remote.MenuItem
+const { Menu, MenuItem } = remote
class RepositorySection extends React.Component {
constructor (props) {
@@ -124,19 +124,11 @@ class RepositorySection extends React.Component {
let folderElements = repository.folders.map((folder) => {
return (
-
-
- {folder.name}
-
-
-
-
-
+ folder={folder}
+ repository={repository}
+ />
)
})
diff --git a/browser/main/HomePage/SideNav/RepositorySection.styl b/browser/main/HomePage/SideNav/RepositorySection.styl
index 9bc95ca4..8230fc3e 100644
--- a/browser/main/HomePage/SideNav/RepositorySection.styl
+++ b/browser/main/HomePage/SideNav/RepositorySection.styl
@@ -50,49 +50,6 @@
@extend .header-control-button
opacity 1
-.folder
- height 33px
- width 100%
- position relative
- cursor pointer
- &:hover
- background-color alpha(white, 0.1)
- .folder-control
- opacity 1
-
-.folder-label
- position absolute
- left 0
- top 0
- bottom 0
- right 48px
- padding-left 20px
- line-height 33px
- color white
-
-.folder-control
- opacity 0
- position absolute
- top 0
- bottom 0
- right 5px
- width 24px
-
-.folder-control-button
- width 24px
- height 24px
- margin-top 4.5px
- border none
- border-radius 5px
- background-color transparent
- color $nav-inactive-color
- &:hover
- color white
- background-color alpha(white, 0.1)
- &:active
- color white
- background-color $brand-color
-
.newFolderForm
width 100%
padding 0 15px
diff --git a/browser/main/HomePage/SideNav/SideNav.styl b/browser/main/HomePage/SideNav/SideNav.styl
index 1b67b6e8..65bb6b37 100644
--- a/browser/main/HomePage/SideNav/SideNav.styl
+++ b/browser/main/HomePage/SideNav/SideNav.styl
@@ -47,8 +47,8 @@
.repositoryList-empty
padding 0 10px
- height 44px
- line-height 44px
+ margin-top 15px
+ line-height 24px
color $nav-inactive-color
.navToggle
diff --git a/browser/main/HomePage/SideNav/index.js b/browser/main/HomePage/SideNav/index.js
index 171b1f0b..4d76847c 100644
--- a/browser/main/HomePage/SideNav/index.js
+++ b/browser/main/HomePage/SideNav/index.js
@@ -72,7 +72,7 @@ class SideNav extends React.Component {
{repositories.length > 0 ? repositorieElements : (
-
No repository mount
+
No repository mount.
)}
diff --git a/browser/main/store.js b/browser/main/store.js
index adabd37a..109d2dfd 100644
--- a/browser/main/store.js
+++ b/browser/main/store.js
@@ -65,6 +65,44 @@ function repositories (state = initialRepositories, action) {
targetRepo.folders.splice(targetFolderIndex, 1, action.folder)
}
+ return repos
+ }
+ case 'EDIT_FOLDER':
+ {
+ let repos = state.slice()
+ let targetRepo = _.find(repos, {key: action.key})
+
+ if (targetRepo == null) return state
+
+ let targetFolderIndex = _.findIndex(targetRepo.folders, {key: action.folder.key})
+ if (targetFolderIndex < 0) {
+ targetRepo.folders.push(action.folder)
+ } else {
+ targetRepo.folders.splice(targetFolderIndex, 1, action.folder)
+ }
+
+ return repos
+ }
+ /**
+ * Remove a folder from the repository
+ * {
+ * type: 'REMOVE_FOLDER',
+ * repository: repositoryKey,
+ * folder: folderKey
+ * }
+ */
+ case 'REMOVE_FOLDER':
+ {
+ let repos = state.slice()
+ let targetRepo = _.find(repos, {key: action.repository})
+
+ if (targetRepo == null) return state
+
+ let targetFolderIndex = _.findIndex(targetRepo.folders, {key: action.folder})
+ if (targetFolderIndex > -1) {
+ targetRepo.folders.splice(targetFolderIndex, 1)
+ }
+
return repos
}
}
diff --git a/browser/styles/main/modal/Preferences.styl b/browser/styles/main/modal/Preferences.styl
index 0bb32d97..9239f571 100644
--- a/browser/styles/main/modal/Preferences.styl
+++ b/browser/styles/main/modal/Preferences.styl
@@ -31,8 +31,6 @@ iptFocusBorderColor = #369DCD
margin-right 15px
border none
border-radius 5px
- &:hover
- background-color lighten(closeBtnBgColor, 10%)
&>.nav
absolute left bottom
top 50px
@@ -158,8 +156,6 @@ iptFocusBorderColor = #369DCD
height 33px
padding 0 15px
font-size 14px
- &:hover
- background-color lighten(brandColor, 10%)
.alert
float right
width 250px
@@ -188,441 +184,3 @@ iptFocusBorderColor = #369DCD
&.AppSettingTab
.description
marked()
- &.TeamSettingTab
- .header
- border-bottom 1px solid borderColor
- padding 10px
- font-size 18px
- color brandColor
- line-height 33px
- .teamSelect
- border 1px solid borderColor
- height 33px
- width 200px
- margin 0 10px
- outline none
- font-size 14px
- &:focus
- border-color iptFocusBorderColor
- .teamDeleteConfirm
-
- label
- line-height 33px
- font-size 14px
- .teamDelete
- label
- line-height 33px
- font-size 18px
- color brandColor
- .teamDelete, .teamDeleteConfirm
- padding 15px 20px 15px 15px
- button
- background-color white
- height 33px
- font-size 14px
- padding 0 15px
- border 1px solid borderColor
- float right
- margin 0 5px
- border-radius 5px
- &:hover
- background-color darken(white, 10%)
- button.deleteBtn
- background-color brandColor
- border none
- color white
- &:hover
- background-color lighten(brandColor, 10%)
- &.MemberSettingTab
- &>.header
- border-bottom 1px solid borderColor
- padding 10px
- font-size 18px
- color brandColor
- line-height 33px
- .teamSelect
- border 1px solid borderColor
- height 33px
- width 200px
- margin 0 10px
- outline none
- font-size 14px
- &:focus
- border-color iptFocusBorderColor
- .membersTableSection
- .addMember
- clearfix()
- padding 10px
- .addMemberLabel
- font-size 14px
- line-height 33px
- float left
- .addMemberControl
- width 330px
- float left
- margin-left 25px
- .Select
- display block
- margin 0
- float left
- width 280px
- height 33px
- font-size 14px
- border none
- line-height 33px
- background-color transparent
- outline none
- &.is-focus
- .Select-control
- border-color iptFocusBorderColor
- .Select-control
- height 33px
- line-height 33px
- padding 0 0 0 15px
- border-radius 5px 0 0 5px
- border 1px solid borderColor
- border-right none
- .Select-placeholder
- padding 0 0 0 15px
- .Seleect-arrow
- top 21px
- .Select-clear
- padding 0 10px
- .Select-noresults, .Select-option
- line-height 33px
- padding 0 0 0 15px
- button
- font-weight 400
- height 33px
- cursor pointer
- margin 0
- padding 0
- width 50px
- float right
- border none
- background-color brandColor
- border-top-right-radius 5px
- border-bottom-right-radius 5px
- color white
- font-size 14px
- .memberList
- &>.header
- clearfix()
- &>.userName
- float left
- &>.role
- float left
- &>.control
- float right
- &>li
- &.edit
- .colDescription
- font-size 14px
- line-height 33px
- padding-left 15px
- float left
- strong
- font-size 16px
- color brandColor
- .colDeleteConfirm
- float right
- margin-right 15px
- button
- border none
- height 30px
- width 60px
- margin-top 1.5px
- font-size 14px
- background-color transparent
- color stripBtnColor
- &:hover
- color stripHoverBtnColor
- &:disabled
- color lighten(stripBtnColor, 10%)
- cursor not-allowed
- &.primary
- color brandColor
- &:hover
- color lighten(brandColor, 10%)
-
- border-bottom 1px solid borderColor
- height 44px
- padding 0 25px
- width 420px
- margin 0 auto
- clearfix()
- &:nth-last-child(1)
- border-bottom-color transparent
- .colUserName
- float left
- width 250px
- clearfix()
- .userPhoto
- width 30px
- height 30px
- float left
- margin-top 7px
- margin-right 15px
- border-radius 15px
- .userInfo
- float left
- margin-top 7px
- width 205px
- .userName
- font-size 16px
- margin-bottom 2px
- overflow ellipsis
- .userEmail
- font-size 12px
- overflow ellipsis
- .colRole
- float left
- width 75px
- .userRole
- height 30px
- background-color transparent
- border 1px solid transparent
- margin-top 7px
- margin-right 35px
- outline none
- cursor pointer
- &:hover
- border-color borderColor
- &:focus
- border-color iptFocusBorderColor
- &:disabled
- border-color transparent
- cursor not-allowed
- .colDelete
- width 45px
- float right
- text-align center
- button.deleteButton
- border none
- height 30px
- width 30px
- margin-top 7px
- background-color transparent
- color stripBtnColor
- &:hover
- color stripHoverBtnColor
- &:disabled
- color lighten(stripBtnColor, 10%)
- cursor not-allowed
- &.header
- .colRole, .colDelete
- text-align center
- .colUserName, .colRole, .colDelete
- line-height 44px
- &.FolderSettingTab
- &>.header
- border-bottom 1px solid borderColor
- padding 10px
- font-size 18px
- color brandColor
- line-height 33px
- .teamSelect
- border 1px solid borderColor
- height 33px
- width 200px
- margin 0 10px
- outline none
- font-size 14px
- &:focus
- border-color iptFocusBorderColor
- .section
- .folderTable
- width 420px
- margin 15px auto
- &>div
- border-bottom 1px solid borderColor
- clearfix()
- height 43px
- line-height 33px
- padding 5px 0
- &:last-child
- border-color transparent
- .folderColor
- float left
- margin-left 10px
- text-align center
- width 44px
- .folderName
- float left
- width 175px
- overflow ellipsis
- .folderControl
- float right
- width 125px
- text-align center
- &.folderHeader
- .folderName
- padding-left 25px
- &.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
- height 33px
- border 1px solid transparent
- border-radius 5px
- padding 0 10px
- font-size 14px
- outline none
- width 150px
- overflow ellipsis
- &:hover
- border-color borderColor
- &:focus
- border-color iptFocusBorderColor
- .folderPublic select
- height 33px
- border 1px solid transparent
- background-color white
- outline none
- display block
- margin 0 auto
- font-size 14px
- &:hover
- border-color borderColor
- &:focus
- border-color iptFocusBorderColor
- .folderControl
- button
- border none
- height 30px
- margin-top 1.5px
- font-size 14px
- background-color transparent
- color brandColor
- &:hover
- color lighten(brandColor, 10%)
- &.FolderRow
- .sortBtns
- float left
- display block
- height 30px
- width 30px
- margin-top 1.5px
- position absolute
- button
- absolute left
- background-color transparent
- border none
- height 15px
- padding 0
- margin 0
- color stripBtnColor
- &:first-child
- top 0
- &:last-child
- top 15px
- &:hover
- color stripHoverBtnColor
- &:disabled
- color lighten(stripBtnColor, 10%)
- cursor not-allowed
- .folderName input
- height 33px
- border 1px solid borderColor
- border-radius 5px
- padding 0 10px
- font-size 14px
- outline none
- width 150px
- &:focus
- border-color iptFocusBorderColor
- .folderColor
- .select
- height 33px
- width 33px
- border 1px solid borderColor
- background-color white
- outline none
- display block
- margin 0 auto
- font-size 14px
- border-radius 5px
- &:focus
- border-color iptFocusBorderColor
- .options
- position absolute
- background-color white
- text-align left
- border 1px solid borderColor
- border-radius 5px
- padding 0 5px 5px
- margin-left 5px
- margin-top -34px
- clearfix()
- .label
- margin-left 5px
- line-height 22px
- font-size 12px
- button
- float left
- border none
- width 33px
- height 33px
- margin-right 5px
- border 1px solid transparent
- line-height 29px
- overflow hidden
- border-radius 5px
- background-color transparent
- outline none
- transition 0.1s
- &:hover
- border-color borderColor
- &.active
- border-color iptFocusBorderColor
- .FolderMark
- transform scale(1.4)
- .folderControl
- button
- border none
- height 30px
- width 30px
- margin-top 1.5px
- font-size 14px
- background-color transparent
- color stripBtnColor
- &:hover
- color stripHoverBtnColor
- &:disabled
- color lighten(stripBtnColor, 10%)
- cursor not-allowed
- &.edit
- .folderControl
- button
- width 60px
- &.primary
- color brandColor
- &:hover
- color lighten(brandColor, 10%)
- &.delete
- .folderDeleteLabel
- float left
- height 33px
- width 250px
- padding-left 15px
- overflow ellipsis
- strong
- font-size 16px
- color brandColor
- .folderControl
- button
- width 60px
- &.primary
- color brandColor
- &:hover
- color lighten(brandColor, 10%)