MVP: finish give/remove roles practical example

This commit is contained in:
Katalina / stardust 2017-12-23 04:31:52 -06:00
parent 3c545bdeaa
commit d1f556b0f0
6 changed files with 82 additions and 29 deletions

View file

@ -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 }
})
}

View file

@ -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 <div key={name} className="role-picker__category">
<h4>{ name }</h4>
{
category.get('roles_map').map((r, k) => {
const id = r.get('id')
return <Role key={k} role={r} selected={isSelected(id)} onToggle={this.onRoleToggle(id)}/>
}).toArray()
}
</div>
}
}
export default Category

View file

@ -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

View file

@ -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
})

View file

@ -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 {
<button disabled={!this.rolesHaveChanged} onClick={() => dispatch(Actions.resetSelected)} className="uk-button action__button secondary">
Reset
</button>
<button disabled={!this.rolesHaveChanged} onClick={() => dispatch(Actions.submitSelected(server.id))} className="uk-button action__button primary">
<button disabled={!this.rolesHaveChanged} onClick={() => dispatch(Actions.submitSelected(this.props.match.params.server))} className="uk-button action__button primary">
Save Changes
</button>
</div>
</div>
<div className="role-picker__categories">
{
vm.map((c, name) => {
if (c.get('hidden')) {
return null
}
return <div key={name} className="role-picker__category">
<h4>{ name }</h4>
{
c.get('roles_map').map((r, k) => {
return <Role key={k} role={r} selected={this.isSelected(r.get('id'))} onToggle={() => this.props.dispatch(Actions.roleUpdate(r.get('id'), this.isSelected(r.get('id'))))} />
}).toArray()
}
</div>
}).toArray()
vm.map((c, name) => <Category name={name} category={c} isSelected={this.isSelected} onChange={(roles) => dispatch(Actions.updateRoles(roles))} />).toArray()
}
</div>
</section>

View file

@ -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'))