mirror of
https://github.com/BoostIo/Boostnote
synced 2025-12-13 17:56:25 +00:00
add Member setting, Team setting, FolderSetting(80%)
bump react-select
This commit is contained in:
@@ -8,9 +8,9 @@ import Preferences from 'boost/components/modal/Preferences'
|
|||||||
import CreateNewFolder from 'boost/components/modal/CreateNewFolder'
|
import CreateNewFolder from 'boost/components/modal/CreateNewFolder'
|
||||||
|
|
||||||
export default class ArticleNavigator extends React.Component {
|
export default class ArticleNavigator extends React.Component {
|
||||||
// componentDidMount () {
|
componentDidMount () {
|
||||||
// this.handlePreferencesButtonClick()
|
this.handlePreferencesButtonClick()
|
||||||
// }
|
}
|
||||||
|
|
||||||
handlePreferencesButtonClick (e) {
|
handlePreferencesButtonClick (e) {
|
||||||
openModal(Preferences)
|
openModal(Preferences)
|
||||||
@@ -51,7 +51,7 @@ export default class ArticleNavigator extends React.Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<button onClick={e => this.handleFolderButtonClick(folder.name)(e)} key={'folder-' + folder.id} className={isActive ? 'active' : ''}>
|
<button onClick={e => this.handleFolderButtonClick(folder.name)(e)} key={'folder-' + folder.id} className={isActive ? 'active' : ''}>
|
||||||
<FolderMark id={folder.id}/> {folder.name} {folder.public ? <i className='fa fa-fw fa-lock'/> : null}</button>
|
<FolderMark id={folder.id}/> {folder.name} {folder.public ? null : <i className='fa fa-fw fa-lock'/>}</button>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
: []
|
: []
|
||||||
|
|||||||
@@ -15,6 +15,9 @@ articleNavBgColor = #353535
|
|||||||
color brandColor
|
color brandColor
|
||||||
font-size 28px
|
font-size 28px
|
||||||
padding 6px 0 0 10px
|
padding 6px 0 0 10px
|
||||||
|
white-space nowrap
|
||||||
|
text-overflow ellipsis
|
||||||
|
overflow-x hidden
|
||||||
.userName
|
.userName
|
||||||
color white
|
color white
|
||||||
padding-left 20px
|
padding-left 20px
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ iptFocusBorderColor = #369DCD
|
|||||||
absolute right bottom
|
absolute right bottom
|
||||||
top 50px
|
top 50px
|
||||||
left 180px
|
left 180px
|
||||||
|
overflow-y auto
|
||||||
&>.section
|
&>.section
|
||||||
padding 10px
|
padding 10px
|
||||||
border-bottom 1px solid borderColor
|
border-bottom 1px solid borderColor
|
||||||
@@ -119,8 +120,304 @@ iptFocusBorderColor = #369DCD
|
|||||||
&.success
|
&.success
|
||||||
background-color successBackgroundColor
|
background-color successBackgroundColor
|
||||||
color successTextColor
|
color successTextColor
|
||||||
|
&.AppSettingTab
|
||||||
.description
|
.description
|
||||||
marked()
|
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
|
||||||
|
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
|
||||||
|
.userName
|
||||||
|
font-size 16px
|
||||||
|
margin-bottom 2px
|
||||||
|
.userEmail
|
||||||
|
font-size 12px
|
||||||
|
.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
|
||||||
|
.folderName
|
||||||
|
float left
|
||||||
|
width 175px
|
||||||
|
padding-left 15px
|
||||||
|
.folderPublic
|
||||||
|
float left
|
||||||
|
text-align center
|
||||||
|
width 100px
|
||||||
|
.folderControl
|
||||||
|
float right
|
||||||
|
width 145px
|
||||||
|
text-align center
|
||||||
|
&.FolderRow
|
||||||
|
.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
|
||||||
|
.folderPublic select
|
||||||
|
height 33px
|
||||||
|
border 1px solid borderColor
|
||||||
|
background-color white
|
||||||
|
outline none
|
||||||
|
display block
|
||||||
|
margin 0 auto
|
||||||
|
&:focus
|
||||||
|
border-color iptFocusBorderColor
|
||||||
|
.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
|
||||||
|
strong
|
||||||
|
font-size 16px
|
||||||
|
color brandColor
|
||||||
|
.folderControl
|
||||||
|
button
|
||||||
|
width 60px
|
||||||
|
&.primary
|
||||||
|
color brandColor
|
||||||
|
&:hover
|
||||||
|
color lighten(brandColor, 10%)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
29
lib/api.js
29
lib/api.js
@@ -86,6 +86,15 @@ export function createTeam (input) {
|
|||||||
.send(input)
|
.send(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function updateTeamInfo (teamId, input) {
|
||||||
|
return request
|
||||||
|
.put(API_URL + 'teams/' + teamId)
|
||||||
|
.set({
|
||||||
|
Authorization: 'Bearer ' + auth.token()
|
||||||
|
})
|
||||||
|
.send(input)
|
||||||
|
}
|
||||||
|
|
||||||
export function searchUser (key) {
|
export function searchUser (key) {
|
||||||
return request
|
return request
|
||||||
.get(API_URL + 'search/users')
|
.get(API_URL + 'search/users')
|
||||||
@@ -119,6 +128,23 @@ export function createFolder (input) {
|
|||||||
.send(input)
|
.send(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function updateFolder (id, input) {
|
||||||
|
return request
|
||||||
|
.put(API_URL + 'folders/' + id)
|
||||||
|
.set({
|
||||||
|
Authorization: 'Bearer ' + auth.token()
|
||||||
|
})
|
||||||
|
.send(input)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function destroyFolder (id) {
|
||||||
|
return request
|
||||||
|
.del(API_URL + 'folders/' + id)
|
||||||
|
.set({
|
||||||
|
Authorization: 'Bearer ' + auth.token()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export function sendEmail (input) {
|
export function sendEmail (input) {
|
||||||
return request
|
return request
|
||||||
.post(API_URL + 'mail')
|
.post(API_URL + 'mail')
|
||||||
@@ -139,9 +165,12 @@ export default {
|
|||||||
saveArticle,
|
saveArticle,
|
||||||
destroyArticle,
|
destroyArticle,
|
||||||
createTeam,
|
createTeam,
|
||||||
|
updateTeamInfo,
|
||||||
searchUser,
|
searchUser,
|
||||||
setMember,
|
setMember,
|
||||||
deleteMember,
|
deleteMember,
|
||||||
createFolder,
|
createFolder,
|
||||||
|
updateFolder,
|
||||||
|
destroyFolder,
|
||||||
sendEmail
|
sendEmail
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,9 @@ export default class CreateNewFolder extends React.Component {
|
|||||||
public: false
|
public: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
handleCloseButton (e) {
|
||||||
|
this.props.close()
|
||||||
|
}
|
||||||
|
|
||||||
handlePublicButtonClick (value) {
|
handlePublicButtonClick (value) {
|
||||||
console.log(value)
|
console.log(value)
|
||||||
@@ -61,7 +64,7 @@ export default class CreateNewFolder extends React.Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='CreateNewFolder modal'>
|
<div className='CreateNewFolder modal'>
|
||||||
<button className='closeBtn'><i className='fa fa-fw fa-times'/></button>
|
<button onClick={e => this.handleCloseButton(e)} className='closeBtn'><i className='fa fa-fw fa-times'/></button>
|
||||||
|
|
||||||
<div className='title'>Create new folder</div>
|
<div className='title'>Create new folder</div>
|
||||||
|
|
||||||
|
|||||||
@@ -140,8 +140,7 @@ export default class CreateNewTeam extends React.Component {
|
|||||||
handleMemberDeleteButtonClick (name) {
|
handleMemberDeleteButtonClick (name) {
|
||||||
let selectState = this.state.select
|
let selectState = this.state.select
|
||||||
let input = {
|
let input = {
|
||||||
name: name,
|
name: name
|
||||||
role: 'member'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return e => {
|
return e => {
|
||||||
@@ -175,15 +174,7 @@ export default class CreateNewTeam extends React.Component {
|
|||||||
|
|
||||||
setMember(selectState.team.id, input)
|
setMember(selectState.team.id, input)
|
||||||
.then(res => {
|
.then(res => {
|
||||||
let selectState = this.state.select
|
console.log(res.body)
|
||||||
let team = res.body
|
|
||||||
team.Members = team.Members.sort((a, b) => {
|
|
||||||
return new Date(a._pivot_createdAt) - new Date(b._pivot_createdAt)
|
|
||||||
})
|
|
||||||
selectState.team = team
|
|
||||||
selectState.newMember = ''
|
|
||||||
|
|
||||||
this.setState({select: selectState})
|
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
if (err.status != null) throw err
|
if (err.status != null) throw err
|
||||||
|
|||||||
40
lib/components/modal/Preference/AppSettingTab.js
Normal file
40
lib/components/modal/Preference/AppSettingTab.js
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import React, { PropTypes } from 'react'
|
||||||
|
|
||||||
|
export default class AppSettingTab extends React.Component {
|
||||||
|
render () {
|
||||||
|
return (
|
||||||
|
<div className='AppSettingTab content'>
|
||||||
|
<div className='section'>
|
||||||
|
<div className='sectionTitle'>Hotkey</div>
|
||||||
|
<div className='sectionInput'>
|
||||||
|
<label>Toggle Finder(popup)</label>
|
||||||
|
<input type='text'/>
|
||||||
|
</div>
|
||||||
|
<div className='sectionConfirm'>
|
||||||
|
<button>Save</button>
|
||||||
|
</div>
|
||||||
|
<div className='description'>
|
||||||
|
<ul>
|
||||||
|
<li><code>0</code> to <code>9</code></li>
|
||||||
|
<li><code>A</code> to <code>Z</code></li>
|
||||||
|
<li><code>F1</code> to <code>F24</code></li>
|
||||||
|
<li>Punctuations like <code>~</code>, <code>!</code>, <code>@</code>, <code>#</code>, <code>$</code>, etc.</li>
|
||||||
|
<li><code>Plus</code></li>
|
||||||
|
<li><code>Space</code></li>
|
||||||
|
<li><code>Backspace</code></li>
|
||||||
|
<li><code>Delete</code></li>
|
||||||
|
<li><code>Insert</code></li>
|
||||||
|
<li><code>Return</code> (or <code>Enter</code> as alias)</li>
|
||||||
|
<li><code>Up</code>, <code>Down</code>, <code>Left</code> and <code>Right</code></li>
|
||||||
|
<li><code>Home</code> and <code>End</code></li>
|
||||||
|
<li><code>PageUp</code> and <code>PageDown</code></li>
|
||||||
|
<li><code>Escape</code> (or <code>Esc</code> for short)</li>
|
||||||
|
<li><code>VolumeUp</code>, <code>VolumeDown</code> and <code>VolumeMute</code></li>
|
||||||
|
<li><code>MediaNextTrack</code>, <code>MediaPreviousTrack</code>, <code>MediaStop</code> and <code>MediaPlayPause</code></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
121
lib/components/modal/Preference/FolderRow.js
Normal file
121
lib/components/modal/Preference/FolderRow.js
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
import React, { PropTypes } from 'react'
|
||||||
|
import api from 'boost/api'
|
||||||
|
import linkState from 'boost/linkState'
|
||||||
|
import FolderMark from 'boost/components/FolderMark'
|
||||||
|
|
||||||
|
const IDLE = 'IDLE'
|
||||||
|
const EDIT = 'EDIT'
|
||||||
|
const DELETE = 'DELETE'
|
||||||
|
|
||||||
|
export default class FolderRow extends React.Component {
|
||||||
|
constructor (props) {
|
||||||
|
super(props)
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
mode: IDLE,
|
||||||
|
name: props.folder.name,
|
||||||
|
public: props.folder.public
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleCancelButtonClick (e) {
|
||||||
|
this.setState({
|
||||||
|
mode: IDLE,
|
||||||
|
name: this.props.folder.name,
|
||||||
|
public: this.props.folder.public
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
handleEditButtonClick (e) {
|
||||||
|
this.setState({mode: EDIT})
|
||||||
|
}
|
||||||
|
|
||||||
|
handleDeleteButtonClick (e) {
|
||||||
|
this.setState({mode: DELETE})
|
||||||
|
}
|
||||||
|
|
||||||
|
handleFolderPublicChange (e) {
|
||||||
|
this.setState({public: e.target.value})
|
||||||
|
}
|
||||||
|
|
||||||
|
handleSaveButtonClick (e) {
|
||||||
|
let input = {
|
||||||
|
name: this.state.name,
|
||||||
|
public: !!parseInt(this.state.public, 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
api.updateFolder(this.props.folder.id, input)
|
||||||
|
.then(res => {
|
||||||
|
console.log(res.body)
|
||||||
|
this.setState({mode: IDLE})
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
if (err.status != null) throw err
|
||||||
|
else console.error(err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
handleDeleteConfirmButtonClick (e) {
|
||||||
|
api.destroyFolder(this.props.folder.id)
|
||||||
|
.then(res => {
|
||||||
|
console.log(res.body)
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
if (err.status != null) throw err
|
||||||
|
else console.error(err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
let folder = this.props.folder
|
||||||
|
|
||||||
|
switch (this.state.mode) {
|
||||||
|
case EDIT:
|
||||||
|
return (
|
||||||
|
<div className='FolderRow edit'>
|
||||||
|
<div className='folderName'>
|
||||||
|
<input valueLink={this.linkState('name')} type='text'/>
|
||||||
|
</div>
|
||||||
|
<div className='folderPublic'>
|
||||||
|
<select value={this.state.public} onChange={e => this.handleFolderPublicChange(e)}>
|
||||||
|
<option value='0'>Private</option>
|
||||||
|
<option value='1'>Public</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div className='folderControl'>
|
||||||
|
<button onClick={e => this.handleSaveButtonClick(e)} className='primary'>Save</button>
|
||||||
|
<button onClick={e => this.handleCancelButtonClick(e)}>Cancel</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
case DELETE:
|
||||||
|
return (
|
||||||
|
<div className='FolderRow delete'>
|
||||||
|
<div className='folderDeleteLabel'>Are you sure to delete <strong>{folder.name}</strong> folder?</div>
|
||||||
|
<div className='folderControl'>
|
||||||
|
<button onClick={e => this.handleDeleteConfirmButtonClick(e)} className='primary'>Sure</button>
|
||||||
|
<button onClick={e => this.handleCancelButtonClick(e)}>Cancel</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
case IDLE:
|
||||||
|
default:
|
||||||
|
return (
|
||||||
|
<div className='FolderRow'>
|
||||||
|
<div className='folderName'><FolderMark id={folder.id}/> {folder.name}</div>
|
||||||
|
<div className='folderPublic'>{folder.public ? 'Public' : 'Private'}</div>
|
||||||
|
<div className='folderControl'>
|
||||||
|
<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-close'/></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FolderRow.propTypes = {
|
||||||
|
folder: PropTypes.shape()
|
||||||
|
}
|
||||||
|
|
||||||
|
FolderRow.prototype.linkState = linkState
|
||||||
63
lib/components/modal/Preference/FolderSettingTab.js
Normal file
63
lib/components/modal/Preference/FolderSettingTab.js
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
import React, { PropTypes } from 'react'
|
||||||
|
import _ from 'lodash'
|
||||||
|
import FolderRow from './FolderRow'
|
||||||
|
|
||||||
|
export default class FolderSettingTab extends React.Component {
|
||||||
|
|
||||||
|
getCurrentTeam (props) {
|
||||||
|
if (props == null) props = this.props
|
||||||
|
return _.findWhere(props.teams, {id: props.currentTeamId})
|
||||||
|
}
|
||||||
|
|
||||||
|
handleTeamSelectChange (e) {
|
||||||
|
this.props.switchTeam(e.target.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
renderTeamOptions () {
|
||||||
|
return this.props.teams.map(team => {
|
||||||
|
return (
|
||||||
|
<option key={'team-' + team.id} value={team.id}>{team.name}</option>)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
let team = this.getCurrentTeam()
|
||||||
|
console.log(team.Folders)
|
||||||
|
let folderElements = team.Folders.map(folder => {
|
||||||
|
return (
|
||||||
|
<FolderRow key={'folder-' + folder.id} folder={folder}/>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='FolderSettingTab content'>
|
||||||
|
<div className='header'>
|
||||||
|
<span>Setting of</span>
|
||||||
|
<select
|
||||||
|
value={this.props.currentTeamId}
|
||||||
|
onChange={e => this.handleTeamSelectChange(e)}
|
||||||
|
className='teamSelect'>
|
||||||
|
{this.renderTeamOptions()}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div className='section'>
|
||||||
|
<div className='sectionTitle'>Folders</div>
|
||||||
|
<div className='folderTable'>
|
||||||
|
<div className='folderHeader'>
|
||||||
|
<div className='folderName'>Folder name</div>
|
||||||
|
<div className='folderPublic'>Public/Private</div>
|
||||||
|
<div className='folderControl'>Edit/Delete</div>
|
||||||
|
</div>
|
||||||
|
{folderElements}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FolderSettingTab.propTypes = {
|
||||||
|
currentTeamId: PropTypes.number,
|
||||||
|
teams: PropTypes.array,
|
||||||
|
switchTeam: PropTypes.func
|
||||||
|
}
|
||||||
11
lib/components/modal/Preference/HelpTab.js
Normal file
11
lib/components/modal/Preference/HelpTab.js
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import React, { PropTypes } from 'react'
|
||||||
|
|
||||||
|
export default class HelpTab extends React.Component {
|
||||||
|
render () {
|
||||||
|
return (
|
||||||
|
<div className='content help'>
|
||||||
|
Comming soon
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
206
lib/components/modal/Preference/MemberSettingTab.js
Normal file
206
lib/components/modal/Preference/MemberSettingTab.js
Normal file
@@ -0,0 +1,206 @@
|
|||||||
|
import React, { PropTypes } from 'react'
|
||||||
|
import ProfileImage from 'boost/components/ProfileImage'
|
||||||
|
import Select from 'react-select'
|
||||||
|
import api from 'boost/api'
|
||||||
|
import _ from 'lodash'
|
||||||
|
|
||||||
|
function getUsers (input, cb) {
|
||||||
|
api.searchUser(input)
|
||||||
|
.then(function (res) {
|
||||||
|
let users = res.body
|
||||||
|
|
||||||
|
cb(null, {
|
||||||
|
options: users.map(user => {
|
||||||
|
return { value: user.name, label: user.name }
|
||||||
|
}),
|
||||||
|
complete: false
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.catch(function (err) {
|
||||||
|
console.error(err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class MemberSettingTab extends React.Component {
|
||||||
|
constructor (props) {
|
||||||
|
super(props)
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
newMember: ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getCurrentTeam (props) {
|
||||||
|
if (props == null) props = this.props
|
||||||
|
return _.findWhere(props.teams, {id: props.currentTeamId})
|
||||||
|
}
|
||||||
|
|
||||||
|
handleTeamSelectChange (e) {
|
||||||
|
this.props.switchTeam(e.target.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
handleNewMemberChange (value) {
|
||||||
|
this.setState({newMember: value})
|
||||||
|
}
|
||||||
|
|
||||||
|
handleClickAddMemberButton (e) {
|
||||||
|
let team = this.getCurrentTeam()
|
||||||
|
if (team == null || team.userType !== 'team') return null
|
||||||
|
|
||||||
|
let input = {
|
||||||
|
name: this.state.newMember,
|
||||||
|
role: 'member'
|
||||||
|
}
|
||||||
|
api.setMember(team.id, input)
|
||||||
|
.then(res => {
|
||||||
|
console.log(res.body)
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
if (err.status != null) throw err
|
||||||
|
else console.error(err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
handleMemberRoleChange (name) {
|
||||||
|
return e => {
|
||||||
|
let team = this.getCurrentTeam()
|
||||||
|
let input = {
|
||||||
|
name: name,
|
||||||
|
role: e.target.value
|
||||||
|
}
|
||||||
|
|
||||||
|
api.setMember(team.id, input)
|
||||||
|
.then(res => {
|
||||||
|
console.log(res.body)
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
if (err.status != null) throw err
|
||||||
|
else console.error(err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleMemberDeleteButtonClick (name) {
|
||||||
|
return e => {
|
||||||
|
let team = this.getCurrentTeam()
|
||||||
|
let input = {
|
||||||
|
name: name
|
||||||
|
}
|
||||||
|
|
||||||
|
api.deleteMember(team.id, input)
|
||||||
|
.then(res => {
|
||||||
|
console.log(res.body)
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
if (err.status != null) throw err
|
||||||
|
else console.error(err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
renderTeamOptions () {
|
||||||
|
return this.props.teams.map(team => {
|
||||||
|
return (
|
||||||
|
<option key={'team-' + team.id} value={team.id}>{team.name}</option>)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
console.log(this.props.teams)
|
||||||
|
|
||||||
|
let team = this.getCurrentTeam()
|
||||||
|
|
||||||
|
if (team == null || team.userType === 'person') {
|
||||||
|
return this.renderNoTeam()
|
||||||
|
}
|
||||||
|
|
||||||
|
let membersEl = team.Members.map(member => {
|
||||||
|
let isCurrentUser = this.props.currentUser.id === member.id
|
||||||
|
|
||||||
|
return (
|
||||||
|
<li key={'user-' + member.id}>
|
||||||
|
<div className='colUserName'>
|
||||||
|
<ProfileImage className='userPhoto' email={member.email} size='30'/>
|
||||||
|
<div className='userInfo'>
|
||||||
|
<div className='userName'>{`${member.profileName} (${member.name})`}</div>
|
||||||
|
<div className='userEmail'>{member.email}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='colRole'>
|
||||||
|
<select onChange={e => this.handleMemberRoleChange(member.name)(e)} disabled={isCurrentUser} value={member._pivot_role} className='userRole'>
|
||||||
|
<option value='owner'>Owner</option>
|
||||||
|
<option value='member'>Member</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div className='colDelete'>
|
||||||
|
<button className='deleteButton' onClick={e => this.handleMemberDeleteButtonClick(member.name)(e)} disabled={isCurrentUser}><i className='fa fa-times fa-fw'/></button>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='MemberSettingTab content'>
|
||||||
|
<div className='header'>
|
||||||
|
<span>Setting of</span>
|
||||||
|
<select
|
||||||
|
value={this.props.currentTeamId}
|
||||||
|
onChange={e => this.handleTeamSelectChange(e)}
|
||||||
|
className='teamSelect'>
|
||||||
|
{this.renderTeamOptions()}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='membersTableSection section'>
|
||||||
|
<div className='sectionTitle'>Members</div>
|
||||||
|
<div className='addMember'>
|
||||||
|
<div className='addMemberLabel'>Add member</div>
|
||||||
|
<div className='addMemberControl'>
|
||||||
|
<Select
|
||||||
|
className='memberName'
|
||||||
|
placeholder='Input username to add'
|
||||||
|
autoload={false}
|
||||||
|
asyncOptions={getUsers}
|
||||||
|
onChange={val => this.handleNewMemberChange(val)}
|
||||||
|
value={this.state.newMember}
|
||||||
|
/>
|
||||||
|
<button onClick={e => this.handleClickAddMemberButton(e)} className='addMemberBtn'>add</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ul className='memberList'>
|
||||||
|
<li className='header'>
|
||||||
|
<div className='colUserName'>Username</div>
|
||||||
|
<div className='colRole'>Role</div>
|
||||||
|
<div className='colDelete'>Delete</div>
|
||||||
|
</li>
|
||||||
|
{membersEl}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
renderNoTeam () {
|
||||||
|
return (
|
||||||
|
<div className='TeamSettingTab content'>
|
||||||
|
<div className='header'>
|
||||||
|
<span>Setting of</span>
|
||||||
|
<select
|
||||||
|
value={this.props.currentTeamId}
|
||||||
|
onChange={e => this.handleTeamSelectChange(e)}
|
||||||
|
className='teamSelect'>
|
||||||
|
{this.renderTeamOptions()}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div className='section'>Please select a team</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MemberSettingTab.propTypes = {
|
||||||
|
currentUser: PropTypes.shape(),
|
||||||
|
teams: PropTypes.array,
|
||||||
|
currentTeamId: PropTypes.number,
|
||||||
|
switchTeam: PropTypes.func
|
||||||
|
}
|
||||||
155
lib/components/modal/Preference/TeamSettingTab.js
Normal file
155
lib/components/modal/Preference/TeamSettingTab.js
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
import React, { PropTypes } from 'react'
|
||||||
|
import _ from 'lodash'
|
||||||
|
import linkState from 'boost/linkState'
|
||||||
|
import api from 'boost/api'
|
||||||
|
|
||||||
|
export default class TeamSettingTab extends React.Component {
|
||||||
|
constructor (props) {
|
||||||
|
super(props)
|
||||||
|
let team = this.getCurrentTeam(props)
|
||||||
|
this.state = {
|
||||||
|
teamName: team != null ? team.profileName : '',
|
||||||
|
deleteConfirm: false,
|
||||||
|
alert: null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillReceiveProps (nextProps) {
|
||||||
|
let team = this.getCurrentTeam(nextProps)
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
teamName: team != null ? team.profileName : '',
|
||||||
|
deleteConfirm: false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
getCurrentTeam (props) {
|
||||||
|
if (props == null) props = this.props
|
||||||
|
return _.findWhere(props.teams, {id: props.currentTeamId})
|
||||||
|
}
|
||||||
|
|
||||||
|
handleTeamSelectChange (e) {
|
||||||
|
this.props.switchTeam(e.target.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
handleSaveButtonClick (e) {
|
||||||
|
let input = {
|
||||||
|
profileName: this.state.teamName
|
||||||
|
}
|
||||||
|
let alert = {
|
||||||
|
type: 'info',
|
||||||
|
message: 'Sending...'
|
||||||
|
}
|
||||||
|
this.setState({alert}, () => {
|
||||||
|
api.updateTeamInfo(this.props.currentTeamId, input)
|
||||||
|
.then(res => {
|
||||||
|
console.log(res.body)
|
||||||
|
let alert = {
|
||||||
|
type: 'success',
|
||||||
|
message: 'Successfully done!'
|
||||||
|
}
|
||||||
|
this.setState({alert})
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
var message
|
||||||
|
if (err.status != null) {
|
||||||
|
message = err.response.body.message
|
||||||
|
} else if (err.code === 'ECONNREFUSED') {
|
||||||
|
message = 'Can\'t connect to API server.'
|
||||||
|
} else throw err
|
||||||
|
|
||||||
|
let alert = {
|
||||||
|
type: 'error',
|
||||||
|
message: message
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({alert})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
renderTeamOptions () {
|
||||||
|
return this.props.teams.map(team => {
|
||||||
|
return (
|
||||||
|
<option key={'team-' + team.id} value={team.id}>{team.name}</option>)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
let team = this.getCurrentTeam()
|
||||||
|
|
||||||
|
if (team == null || team.userType === 'person') {
|
||||||
|
return this.renderNoTeam()
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='TeamSettingTab content'>
|
||||||
|
<div className='header'>
|
||||||
|
<span>Setting of</span>
|
||||||
|
<select
|
||||||
|
value={this.props.currentTeamId}
|
||||||
|
onChange={e => this.handleTeamSelectChange(e)}
|
||||||
|
className='teamSelect'>
|
||||||
|
{this.renderTeamOptions()}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div className='section'>
|
||||||
|
<div className='sectionTitle'>Team profile</div>
|
||||||
|
<div className='sectionInput'>
|
||||||
|
<label className='label'>Team Name</label>
|
||||||
|
<input valueLink={this.linkState('teamName')} type='text'/>
|
||||||
|
</div>
|
||||||
|
<div className='sectionConfirm'>
|
||||||
|
<button onClick={e => this.handleSaveButtonClick(e)}>Save</button>
|
||||||
|
|
||||||
|
{this.state.alert != null
|
||||||
|
? (
|
||||||
|
<div className={'alert ' + this.state.alert.type}>{this.state.alert.message}</div>
|
||||||
|
)
|
||||||
|
: null}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{!this.state.deleteConfirm
|
||||||
|
? (
|
||||||
|
<div className='section teamDelete'>
|
||||||
|
<label>Delete this team</label>
|
||||||
|
<button onClick={e => this.setState({deleteConfirm: true})} className='deleteBtn'><i className='fa fa-fw fa-trash'/> Delete</button>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
: (
|
||||||
|
<div className='section teamDeleteConfirm'>
|
||||||
|
<label>Are you sure to delete this team?</label>
|
||||||
|
<button onClick={e => this.setState({deleteConfirm: false})}>Cancel</button>
|
||||||
|
<button className='deleteBtn'><i className='fa fa-fw fa-check'/> Sure</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
renderNoTeam () {
|
||||||
|
return (
|
||||||
|
<div className='TeamSettingTab content'>
|
||||||
|
<div className='header'>
|
||||||
|
<span>Setting of</span>
|
||||||
|
<select
|
||||||
|
value={this.props.currentTeamId}
|
||||||
|
onChange={e => this.handleTeamSelectChange(e)}
|
||||||
|
className='teamSelect'>
|
||||||
|
{this.renderTeamOptions()}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div className='section'>Please select a team</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TeamSettingTab.propTypes = {
|
||||||
|
currentTeamId: PropTypes.number,
|
||||||
|
teams: PropTypes.array,
|
||||||
|
switchTeam: PropTypes.func
|
||||||
|
}
|
||||||
|
|
||||||
|
TeamSettingTab.prototype.linkState = linkState
|
||||||
@@ -1,43 +1,31 @@
|
|||||||
import React, { PropTypes } from 'react'
|
import React, { PropTypes } from 'react'
|
||||||
import { connect, Provider } from 'react-redux'
|
import { connect, Provider } from 'react-redux'
|
||||||
import auth from 'boost/auth'
|
|
||||||
import linkState from 'boost/linkState'
|
import linkState from 'boost/linkState'
|
||||||
import Select from 'react-select'
|
|
||||||
import api from 'boost/api'
|
import api from 'boost/api'
|
||||||
import ProfileImage from 'boost/components/ProfileImage'
|
|
||||||
import store from 'boost/store'
|
import store from 'boost/store'
|
||||||
|
import AppSettingTab from './Preference/AppSettingTab'
|
||||||
|
import HelpTab from './Preference/HelpTab'
|
||||||
|
import TeamSettingTab from './Preference/TeamSettingTab'
|
||||||
|
import MemberSettingTab from './Preference/MemberSettingTab'
|
||||||
|
import FolderSettingTab from './Preference/FolderSettingTab'
|
||||||
|
import { closeModal } from 'boost/modal'
|
||||||
|
|
||||||
var { findDOMNode } = require('react-dom')
|
var { findDOMNode } = require('react-dom')
|
||||||
|
|
||||||
const PROFILE = 'PROFILE'
|
const PROFILE = 'PROFILE'
|
||||||
const PREFERENCES = 'PREFERENCES'
|
const APP = 'APP'
|
||||||
const HELP = 'HELP'
|
const HELP = 'HELP'
|
||||||
const TEAM = 'TEAM'
|
const TEAM = 'TEAM'
|
||||||
const MEMBER = 'MEMBER'
|
const MEMBER = 'MEMBER'
|
||||||
const FOLDER = 'FOLDER'
|
const FOLDER = 'FOLDER'
|
||||||
|
|
||||||
function getUsers (input, cb) {
|
|
||||||
api.searchUser(input)
|
|
||||||
.then(function (res) {
|
|
||||||
let users = res.body
|
|
||||||
|
|
||||||
cb(null, {
|
|
||||||
options: users.map(user => {
|
|
||||||
return { value: user.name, label: user.name }
|
|
||||||
}),
|
|
||||||
complete: false
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.catch(function (err) {
|
|
||||||
console.error(err)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
class Preferences extends React.Component {
|
class Preferences extends React.Component {
|
||||||
constructor (props) {
|
constructor (props) {
|
||||||
super(props)
|
super(props)
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
currentTab: PROFILE,
|
currentTab: PROFILE,
|
||||||
|
currentTeamId: props.status.userId,
|
||||||
profile: {
|
profile: {
|
||||||
userInfo: {
|
userInfo: {
|
||||||
profileName: props.currentUser.profileName,
|
profileName: props.currentUser.profileName,
|
||||||
@@ -54,6 +42,10 @@ class Preferences extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switchTeam (teamId) {
|
||||||
|
this.setState({currentTeamId: teamId})
|
||||||
|
}
|
||||||
|
|
||||||
handleNavButtonClick (tab) {
|
handleNavButtonClick (tab) {
|
||||||
return e => {
|
return e => {
|
||||||
this.setState({currentTab: tab})
|
this.setState({currentTab: tab})
|
||||||
@@ -65,7 +57,7 @@ class Preferences extends React.Component {
|
|||||||
|
|
||||||
let tabs = [
|
let tabs = [
|
||||||
{target: PROFILE, label: 'Profile'},
|
{target: PROFILE, label: 'Profile'},
|
||||||
{target: PREFERENCES, label: 'Preferences'},
|
{target: APP, label: 'Preferences'},
|
||||||
{target: HELP, label: 'Help & Feedback'},
|
{target: HELP, label: 'Help & Feedback'},
|
||||||
{target: TEAM, label: 'Team setting'},
|
{target: TEAM, label: 'Team setting'},
|
||||||
{target: MEMBER, label: 'Manage member'},
|
{target: MEMBER, label: 'Manage member'},
|
||||||
@@ -80,7 +72,7 @@ class Preferences extends React.Component {
|
|||||||
<div className='Preferences modal'>
|
<div className='Preferences modal'>
|
||||||
<div className='header'>
|
<div className='header'>
|
||||||
<div className='title'>Setting</div>
|
<div className='title'>Setting</div>
|
||||||
<button onClick={e => this.props.close()} className='closeBtn'>Done</button>
|
<button onClick={e => closeModal()} className='closeBtn'>Done</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='nav'>
|
<div className='nav'>
|
||||||
@@ -93,17 +85,39 @@ class Preferences extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderContent () {
|
renderContent () {
|
||||||
|
let currentTeamId = parseInt(this.state.currentTeamId, 10)
|
||||||
|
let teams = [this.props.currentUser].concat(this.props.currentUser.Teams)
|
||||||
|
|
||||||
switch (this.state.currentTab) {
|
switch (this.state.currentTab) {
|
||||||
case PREFERENCES:
|
case APP:
|
||||||
return this.renderPreferences()
|
return (<AppSettingTab/>)
|
||||||
case HELP:
|
case HELP:
|
||||||
return this.renderHelp()
|
return (<HelpTab/>)
|
||||||
case TEAM:
|
case TEAM:
|
||||||
return this.renderTeamSetting()
|
return (
|
||||||
|
<TeamSettingTab
|
||||||
|
currentTeamId={currentTeamId}
|
||||||
|
teams={teams}
|
||||||
|
switchTeam={teamId => this.switchTeam(teamId)}
|
||||||
|
/>
|
||||||
|
)
|
||||||
case MEMBER:
|
case MEMBER:
|
||||||
return this.renderMemberSetting()
|
return (
|
||||||
|
<MemberSettingTab
|
||||||
|
currentUser={this.props.currentUser}
|
||||||
|
currentTeamId={currentTeamId}
|
||||||
|
teams={teams}
|
||||||
|
switchTeam={teamId => this.switchTeam(teamId)}
|
||||||
|
/>
|
||||||
|
)
|
||||||
case FOLDER:
|
case FOLDER:
|
||||||
return this.renderFolderSetting()
|
return (
|
||||||
|
<FolderSettingTab
|
||||||
|
currentTeamId={currentTeamId}
|
||||||
|
teams={teams}
|
||||||
|
switchTeam={teamId => this.switchTeam(teamId)}
|
||||||
|
/>
|
||||||
|
)
|
||||||
case PROFILE:
|
case PROFILE:
|
||||||
default:
|
default:
|
||||||
return this.renderProfile()
|
return this.renderProfile()
|
||||||
@@ -250,7 +264,7 @@ class Preferences extends React.Component {
|
|||||||
<div className='sectionConfirm'>
|
<div className='sectionConfirm'>
|
||||||
<button onClick={e => this.handlePasswordSaveButton(e)}>Save</button>
|
<button onClick={e => this.handlePasswordSaveButton(e)}>Save</button>
|
||||||
|
|
||||||
{this.state.profile.password.alert != null
|
{profileState.password.alert != null
|
||||||
? (
|
? (
|
||||||
<div className={'alert ' + profileState.password.alert.type}>{profileState.password.alert.message}</div>
|
<div className={'alert ' + profileState.password.alert.type}>{profileState.password.alert.message}</div>
|
||||||
)
|
)
|
||||||
@@ -261,144 +275,6 @@ class Preferences extends React.Component {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
renderPreferences () {
|
|
||||||
return (
|
|
||||||
<div className='content preferences'>
|
|
||||||
<div className='section passwordSection'>
|
|
||||||
<div className='sectionTitle'>Hotkey</div>
|
|
||||||
<div className='sectionInput'>
|
|
||||||
<label>Toggle Finder(popup)</label>
|
|
||||||
<input type='text'/>
|
|
||||||
</div>
|
|
||||||
<div className='sectionConfirm'>
|
|
||||||
<button>Save</button>
|
|
||||||
</div>
|
|
||||||
<div className='description'>
|
|
||||||
<ul>
|
|
||||||
<li><code>0</code> to <code>9</code></li>
|
|
||||||
<li><code>A</code> to <code>Z</code></li>
|
|
||||||
<li><code>F1</code> to <code>F24</code></li>
|
|
||||||
<li>Punctuations like <code>~</code>, <code>!</code>, <code>@</code>, <code>#</code>, <code>$</code>, etc.</li>
|
|
||||||
<li><code>Plus</code></li>
|
|
||||||
<li><code>Space</code></li>
|
|
||||||
<li><code>Backspace</code></li>
|
|
||||||
<li><code>Delete</code></li>
|
|
||||||
<li><code>Insert</code></li>
|
|
||||||
<li><code>Return</code> (or <code>Enter</code> as alias)</li>
|
|
||||||
<li><code>Up</code>, <code>Down</code>, <code>Left</code> and <code>Right</code></li>
|
|
||||||
<li><code>Home</code> and <code>End</code></li>
|
|
||||||
<li><code>PageUp</code> and <code>PageDown</code></li>
|
|
||||||
<li><code>Escape</code> (or <code>Esc</code> for short)</li>
|
|
||||||
<li><code>VolumeUp</code>, <code>VolumeDown</code> and <code>VolumeMute</code></li>
|
|
||||||
<li><code>MediaNextTrack</code>, <code>MediaPreviousTrack</code>, <code>MediaStop</code> and <code>MediaPlayPause</code></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
renderHelp () {
|
|
||||||
return (
|
|
||||||
<div className='content help'>
|
|
||||||
Comming soon
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
renderTeamSetting () {
|
|
||||||
return (
|
|
||||||
<div className='content teamSetting'>
|
|
||||||
<div className='header'>
|
|
||||||
<select>
|
|
||||||
<option></option>
|
|
||||||
</select>
|
|
||||||
<div>'s Team Setting</div>
|
|
||||||
</div>
|
|
||||||
<div className='section'>
|
|
||||||
<div className='sectionTitle'>Team profile</div>
|
|
||||||
<div className='sectionInput'>
|
|
||||||
<div className='label'>Team Name</div>
|
|
||||||
<input type='text'/>
|
|
||||||
</div>
|
|
||||||
<div className='sectionConfirm'>
|
|
||||||
<button>Save</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{false
|
|
||||||
? (
|
|
||||||
<div className='section teamDelete'>
|
|
||||||
<div className='label'>Delete this team</div>
|
|
||||||
<button>Delete</button>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
: (
|
|
||||||
<div className='section teamDeleteConfirm'>
|
|
||||||
<div>Are you sure to delete this team?</div>
|
|
||||||
<button>Sure</button>
|
|
||||||
<button>Cancel</button>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
renderMemberSetting () {
|
|
||||||
let membersEl = [].map(member => {
|
|
||||||
let isCurrentUser = this.state.currentUser.id === member.id
|
|
||||||
|
|
||||||
return (
|
|
||||||
<li key={'user-' + member.id}>
|
|
||||||
<ProfileImage className='userPhoto' email={member.email} size='30'/>
|
|
||||||
<div className='userInfo'>
|
|
||||||
<div className='userName'>{`${member.profileName} (${member.name})`}</div>
|
|
||||||
<div className='userEmail'>{member.email}</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className='userControl'>
|
|
||||||
<select onChange={e => this.handleMemberRoleChange(member.name)(e)} disabled={isCurrentUser} value={member._pivot_role} className='userRole'>
|
|
||||||
<option value='owner'>Owner</option>
|
|
||||||
<option value='member'>Member</option>
|
|
||||||
</select>
|
|
||||||
<button onClick={e => this.handleMemberDeleteButtonClick(member.name)(e)} disabled={isCurrentUser}><i className='fa fa-times fa-fw'/></button>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className='content memberSetting'>
|
|
||||||
<div className='header'>
|
|
||||||
<select>
|
|
||||||
<option></option>
|
|
||||||
</select>
|
|
||||||
<div>'s Team Setting</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<Select
|
|
||||||
className='memberName'
|
|
||||||
autoload={false}
|
|
||||||
asyncOptions={getUsers}
|
|
||||||
onChange={val => this.handleNewMemberChange(val)}
|
|
||||||
value={null}
|
|
||||||
/>
|
|
||||||
<button onClick={e => this.handleClickAddMemberButton(e)} className='addMemberBtn'>add</button>
|
|
||||||
</div>
|
|
||||||
<ul className='memberList'>
|
|
||||||
{membersEl}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
renderFolderSetting () {
|
|
||||||
return (
|
|
||||||
<div className='content folderSetting'></div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Preferences.propTypes = {
|
Preferences.propTypes = {
|
||||||
@@ -410,9 +286,11 @@ Preferences.prototype.linkState = linkState
|
|||||||
|
|
||||||
function remap (state) {
|
function remap (state) {
|
||||||
let currentUser = state.currentUser
|
let currentUser = state.currentUser
|
||||||
|
let status = state.status
|
||||||
|
|
||||||
return {
|
return {
|
||||||
currentUser
|
currentUser,
|
||||||
|
status
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,5 +38,5 @@ export function openModal (component, props) {
|
|||||||
|
|
||||||
export function closeModal () {
|
export function closeModal () {
|
||||||
if (modalBase == null) { return }
|
if (modalBase == null) { return }
|
||||||
modalBase.setState({isHidden: true})
|
modalBase.setState({component: null, componentProps: null, isHidden: true})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,7 +60,7 @@
|
|||||||
"react-dom": "^0.14.0",
|
"react-dom": "^0.14.0",
|
||||||
"react-redux": "^3.1.0",
|
"react-redux": "^3.1.0",
|
||||||
"react-router": "^1.0.0-rc1",
|
"react-router": "^1.0.0-rc1",
|
||||||
"react-select": "^0.6.10",
|
"react-select": "^0.8.1",
|
||||||
"react-transform-catch-errors": "^1.0.0",
|
"react-transform-catch-errors": "^1.0.0",
|
||||||
"react-transform-hmr": "^1.0.1",
|
"react-transform-hmr": "^1.0.1",
|
||||||
"redbox-react": "^1.1.1",
|
"redbox-react": "^1.1.1",
|
||||||
|
|||||||
Reference in New Issue
Block a user