diff --git a/Server/api/servers.js b/Server/api/servers.js index ad651c1..357123c 100644 --- a/Server/api/servers.js +++ b/Server/api/servers.js @@ -24,4 +24,24 @@ module.exports = (R, $) => { ctx.body = server }) + + R.patch('/api/servers/:server/roles', async ctx => { + const { userId } = ctx.session + const { server } = ctx.params + let gm = $.discord.gm(server, userId) + + const { added, removed } = ctx.request.body + + if (added.length > 0) { + gm = await gm.addRoles(added) + } + + if (removed.length > 0) { + gm = await gm.removeRoles(removed) + } + + console.log(gm.roles) + + ctx.body = { ok: true } + }) } diff --git a/UI/src/components/role-picker/Category.js b/UI/src/components/role-picker/Category.js new file mode 100644 index 0000000..fd9c77b --- /dev/null +++ b/UI/src/components/role-picker/Category.js @@ -0,0 +1,43 @@ +import React, { Component } from 'react' +import { Map } from 'immutable' + +import Role from '../role' + +class Category extends Component { + + toggleRoleMulti (id, next) { + this.props.onChange(Map({ [id]: next })) + } + + toggleRoleSingle (id, next) { + this.props.onChange(this.props.category.get('roles').reduce((acc, i) => acc.set(i, false), Map()).set(id, next)) + } + + onRoleToggle = id => (next, old) => { + const type = this.props.category.get('type') + + switch (type) { + case 'multi': return this.toggleRoleMulti(id, next) + case 'single': return this.toggleRoleSingle(id, next) + default: console.warn('NOT SURE') + } + } + + render () { + const { category, name, isSelected } = this.props + if (category.get('hidden')) { + return null + } + + return
+

{ name }

+ { + category.get('roles_map').map((r, k) => { + const id = r.get('id') + return + }).toArray() + } +
+ } +} +export default Category diff --git a/UI/src/components/role-picker/RolePicker.sass b/UI/src/components/role-picker/RolePicker.sass index 602fa59..0ccd55f 100644 --- a/UI/src/components/role-picker/RolePicker.sass +++ b/UI/src/components/role-picker/RolePicker.sass @@ -38,7 +38,7 @@ .action__button border: 0 - border-radius: 5px + border-radius: 2px transition: transform 0.2s ease-out, box-shadow 0.2s ease-out position: relative @@ -50,7 +50,7 @@ right: 0 left: 0 background-color: rgba(0,0,0,0.1) - border-radius: 5px + border-radius: 2px opacity: 0 transition: opacity 0.15s ease-in-out diff --git a/UI/src/components/role-picker/actions.js b/UI/src/components/role-picker/actions.js index 110f544..408d5c5 100644 --- a/UI/src/components/role-picker/actions.js +++ b/UI/src/components/role-picker/actions.js @@ -1,15 +1,6 @@ import { Map, Set, fromJS } from 'immutable' import superagent from 'superagent' -export const roleUpdate = (id, oldState) => (dispatch, getState) => { - dispatch({ - type: Symbol.for('update selected roles'), - data: { - id, - state: !oldState - } - }) -} export const setup = id => async dispatch => { // const rsp = await superagent.get(`/api/server/${id}`) @@ -89,4 +80,13 @@ export const submitSelected = serverId => async (dispatch, getState) => { }, Map({ added: Set(), removed: Set() })) await superagent.patch(`/api/servers/${serverId}/roles`).send(diff.toJS()) + + dispatch({ + type: Symbol.for('sync selected roles') + }) } + +export const updateRoles = roles => ({ + type: Symbol.for('update selected roles'), + data: roles +}) diff --git a/UI/src/components/role-picker/index.js b/UI/src/components/role-picker/index.js index e2775a7..4f8a261 100644 --- a/UI/src/components/role-picker/index.js +++ b/UI/src/components/role-picker/index.js @@ -4,7 +4,7 @@ import superagent from 'superagent' import * as Actions from './actions' import './RolePicker.sass' -import Role from '../role' +import Category from './Category' import { Scrollbars } from 'react-custom-scrollbars'; const mapState = ({ rolePicker, servers }, ownProps) => { @@ -28,7 +28,7 @@ class RolePicker extends Component { } } - isSelected (id) { + isSelected = id => { return this.props.data.getIn([ 'rolesSelected', id ]) } @@ -62,27 +62,14 @@ class RolePicker extends Component { -
{ - vm.map((c, name) => { - if (c.get('hidden')) { - return null - } - - return
-

{ name }

- { - c.get('roles_map').map((r, k) => { - return this.props.dispatch(Actions.roleUpdate(r.get('id'), this.isSelected(r.get('id'))))} /> - }).toArray() - } -
- }).toArray() + vm.map((c, name) => dispatch(Actions.updateRoles(roles))} />).toArray() }
diff --git a/UI/src/reducers/role-picker.js b/UI/src/reducers/role-picker.js index 71a2ab8..bdba646 100644 --- a/UI/src/reducers/role-picker.js +++ b/UI/src/reducers/role-picker.js @@ -20,7 +20,10 @@ export default (state = initialState, { type, data }) => { return state.set('emptyRoles', data) case Symbol.for('update selected roles'): - return state.setIn(['rolesSelected', data.id], data.state) + return state.mergeIn(['rolesSelected'], data) + + case Symbol.for('sync selected roles'): + return state.set('originalRolesSelected', state.get('rolesSelected')) case Symbol.for('reset selected'): return state.set('rolesSelected', state.get('originalRolesSelected'))