mirror of
https://github.com/roleypoly/roleypoly-v1.git
synced 2025-04-25 04:09:12 +00:00
feat(UI/Roles): add category sorting
This commit is contained in:
parent
b4ce19eb41
commit
2a91fa74f9
9 changed files with 100 additions and 8 deletions
|
@ -42,7 +42,7 @@
|
||||||
"not ie <= 11",
|
"not ie <= 11",
|
||||||
"not op_mini all"
|
"not op_mini all"
|
||||||
],
|
],
|
||||||
"proxy": "http://localhost:6768",
|
"proxy": "http://localhost:6769",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/plugin-proposal-decorators": "^7.4.0",
|
"@babel/plugin-proposal-decorators": "^7.4.0",
|
||||||
"customize-cra": "^0.2.12",
|
"customize-cra": "^0.2.12",
|
||||||
|
|
|
@ -33,7 +33,6 @@ class Category extends Component {
|
||||||
</div>
|
</div>
|
||||||
{
|
{
|
||||||
category.get('roles_map')
|
category.get('roles_map')
|
||||||
.sortBy(r => r.get('position'))
|
|
||||||
.reverse()
|
.reverse()
|
||||||
.map((r, k) => <Role key={k} role={r} categoryId={name} />)
|
.map((r, k) => <Role key={k} role={r} categoryId={name} />)
|
||||||
.toArray()
|
.toArray()
|
||||||
|
|
|
@ -24,6 +24,28 @@ export default class CategoryEditor extends Component {
|
||||||
<div className="uk-form-controls">
|
<div className="uk-form-controls">
|
||||||
<input type="text" className="uk-input" placeholder='' value={category.get('name')} onChange={this.props.onEdit('name', Symbol.for('edit: text'))} />
|
<input type="text" className="uk-input" placeholder='' value={category.get('name')} onChange={this.props.onEdit('name', Symbol.for('edit: text'))} />
|
||||||
</div>
|
</div>
|
||||||
|
<div className="role-editor__bumpers">
|
||||||
|
<div
|
||||||
|
onClick={this.props.onBump(-1)}
|
||||||
|
className={
|
||||||
|
`role-editor__bumpers-bump
|
||||||
|
${category.get('position') === 0 ? 'yeet' : ''}
|
||||||
|
`}
|
||||||
|
uk-tooltip="delay: 1s"
|
||||||
|
title="Move category up">
|
||||||
|
<i uk-icon="icon: chevron-up"></i>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
onClick={this.props.onBump(1)}
|
||||||
|
className={
|
||||||
|
`role-editor__bumpers-bump
|
||||||
|
${category.get('position') === this.props.arrMax - 1 ? 'yeet' : ''}
|
||||||
|
`}
|
||||||
|
uk-tooltip="delay: 1s"
|
||||||
|
title="Move category down">
|
||||||
|
<i uk-icon="icon: chevron-down"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style={{ marginTop: 10 }}>
|
<div style={{ marginTop: 10 }}>
|
||||||
<div className="uk-form-controls">
|
<div className="uk-form-controls">
|
||||||
|
|
|
@ -36,7 +36,16 @@
|
||||||
color: var(--c-white)
|
color: var(--c-white)
|
||||||
|
|
||||||
|
|
||||||
|
.role-editor__bumpers
|
||||||
|
position: absolute
|
||||||
|
top: 10px
|
||||||
|
right: 10px
|
||||||
|
display: flex
|
||||||
|
|
||||||
|
&-bump
|
||||||
|
transition: color 0.15s ease-in-out
|
||||||
|
&:hover
|
||||||
|
color: var(--c-white)
|
||||||
|
|
||||||
.role-editor__category
|
.role-editor__category
|
||||||
box-sizing: border-box
|
box-sizing: border-box
|
||||||
|
|
|
@ -9,7 +9,7 @@ export const constructView = id => async (dispatch, getState) => {
|
||||||
const server = getState().servers.get(id)
|
const server = getState().servers.get(id)
|
||||||
|
|
||||||
let { viewMap, hasSafeRoles } = getViewMap(server)
|
let { viewMap, hasSafeRoles } = getViewMap(server)
|
||||||
viewMap = viewMap.map(c => c.set('mode', Symbol.for('drop')))
|
viewMap = viewMap.map((c, idx) => c.set('mode', Symbol.for('drop')))
|
||||||
|
|
||||||
dispatch({
|
dispatch({
|
||||||
type: Symbol.for('re: setup'),
|
type: Symbol.for('re: setup'),
|
||||||
|
@ -115,7 +115,8 @@ export const createCategory = (dispatch, getState) => {
|
||||||
|
|
||||||
let name = 'New Category'
|
let name = 'New Category'
|
||||||
let idx = 1
|
let idx = 1
|
||||||
while (vm.find(c => c.get('name') === name) !== undefined) {
|
const pred = c => c.get('name') === name
|
||||||
|
while (vm.find(pred) !== undefined) {
|
||||||
idx++
|
idx++
|
||||||
name = `New Category ${idx}`
|
name = `New Category ${idx}`
|
||||||
}
|
}
|
||||||
|
@ -131,16 +132,57 @@ export const createCategory = (dispatch, getState) => {
|
||||||
roles_map: Set([]),
|
roles_map: Set([]),
|
||||||
hidden: true,
|
hidden: true,
|
||||||
type: 'multi',
|
type: 'multi',
|
||||||
|
position: idx,
|
||||||
mode: Symbol.for('edit')
|
mode: Symbol.for('edit')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const bumpCategory = (category, name) => move => async (dispatch, getState) => {
|
||||||
|
const { roleEditor } = getState()
|
||||||
|
const vm = roleEditor.get('viewMap')
|
||||||
|
|
||||||
|
const position = category.get('position')
|
||||||
|
const nextPos = position + move
|
||||||
|
|
||||||
|
const replaceThisOne = vm.findKey(category => category.get('position') === nextPos)
|
||||||
|
|
||||||
|
dispatch({
|
||||||
|
type: Symbol.for('re: edit category'),
|
||||||
|
data: {
|
||||||
|
id: name,
|
||||||
|
key: 'position',
|
||||||
|
value: nextPos
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!!replaceThisOne) {
|
||||||
|
dispatch({
|
||||||
|
type: Symbol.for('re: edit category'),
|
||||||
|
data: {
|
||||||
|
id: replaceThisOne,
|
||||||
|
key: 'position',
|
||||||
|
value: position
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
export const saveServer = id => async (dispatch, getState) => {
|
export const saveServer = id => async (dispatch, getState) => {
|
||||||
const viewMap = getState().roleEditor.get('viewMap')
|
const viewMap = getState().roleEditor.get('viewMap')
|
||||||
.filterNot((_, k) => k === 'Uncategorized')
|
.filterNot((_, k) => k === 'Uncategorized')
|
||||||
.map(v => v.delete('roles_map').delete('mode').delete('id'))
|
.map(v => v.delete('roles_map').delete('mode').delete('id'))
|
||||||
|
|
||||||
|
viewMap.map((v, idx) => {
|
||||||
|
if (v.has('position')) {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
console.warn('category position wasnt set, so fake ones are being made', {cat: v.toJS(), idx, position: viewMap.count()+idx})
|
||||||
|
return v.set('position', viewMap.count()+idx)
|
||||||
|
})
|
||||||
|
|
||||||
await superagent.patch(`/api/server/${id}`).send({ categories: viewMap.toJS() })
|
await superagent.patch(`/api/server/${id}`).send({ categories: viewMap.toJS() })
|
||||||
dispatch({ type: Symbol.for('re: swap original state') })
|
dispatch({ type: Symbol.for('re: swap original state') })
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,6 +107,8 @@ class RoleEditor extends Component {
|
||||||
dispatch(Actions.saveServer(server))
|
dispatch(Actions.saveServer(server))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onBump = (category, name) => (move) => () => this.props.dispatch(Actions.bumpCategory(category, name)(move))
|
||||||
|
|
||||||
get hasChanged () {
|
get hasChanged () {
|
||||||
return this.props.editor.get('originalSnapshot').hashCode() !== this.props.editor.get('viewMap').hashCode()
|
return this.props.editor.get('originalSnapshot').hashCode() !== this.props.editor.get('viewMap').hashCode()
|
||||||
}
|
}
|
||||||
|
@ -143,16 +145,19 @@ class RoleEditor extends Component {
|
||||||
{
|
{
|
||||||
vm
|
vm
|
||||||
.filter((_, k) => k !== 'Uncategorized')
|
.filter((_, k) => k !== 'Uncategorized')
|
||||||
.map((c, name) => <Category
|
.sortBy(c => c.get('position'))
|
||||||
|
.map((c, name, arr) => <Category
|
||||||
key={name}
|
key={name}
|
||||||
name={name}
|
name={name}
|
||||||
category={c}
|
category={c}
|
||||||
|
arrMax={arr.count()}
|
||||||
mode={c.get('mode')}
|
mode={c.get('mode')}
|
||||||
onDrop={this.dropRole(c, name)}
|
onDrop={this.dropRole(c, name)}
|
||||||
onEdit={this.editCategory(c, name)}
|
onEdit={this.editCategory(c, name)}
|
||||||
onEditOpen={this.openEditor(c, name)}
|
onEditOpen={this.openEditor(c, name)}
|
||||||
onSave={this.saveCategory(c, name)}
|
onSave={this.saveCategory(c, name)}
|
||||||
onDelete={this.deleteCategory(c, name)}
|
onDelete={this.deleteCategory(c, name)}
|
||||||
|
onBump={this.onBump(c, name)}
|
||||||
/>)
|
/>)
|
||||||
.toArray()
|
.toArray()
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ export const setup = id => async dispatch => {
|
||||||
export const getViewMap = server => {
|
export const getViewMap = server => {
|
||||||
const roles = server.get('roles')
|
const roles = server.get('roles')
|
||||||
const categories = server.get('categories')
|
const categories = server.get('categories')
|
||||||
|
const categoriesIds = server.get('categories').keySeq()
|
||||||
|
|
||||||
const allRoles = server.get('roles').filter(v => v.get('safe')).map(r => r.get('id')).toSet()
|
const allRoles = server.get('roles').filter(v => v.get('safe')).map(r => r.get('id')).toSet()
|
||||||
const accountedRoles = categories.map(c => c.get('roles')).toSet().flatten()
|
const accountedRoles = categories.map(c => c.get('roles')).toSet().flatten()
|
||||||
|
@ -31,7 +32,17 @@ export const getViewMap = server => {
|
||||||
hidden: true,
|
hidden: true,
|
||||||
type: 'multi',
|
type: 'multi',
|
||||||
name: 'Uncategorized'
|
name: 'Uncategorized'
|
||||||
})).map(c => {
|
}))
|
||||||
|
.map(
|
||||||
|
(cat, idx) =>
|
||||||
|
cat.set(
|
||||||
|
'position',
|
||||||
|
cat.get('position', categoriesIds.findIndex(v => v === idx)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
// .sortBy(cat => cat.get('position'))
|
||||||
|
.map(c => {
|
||||||
const roles = c.get('roles')
|
const roles = c.get('roles')
|
||||||
// fill in roles_map
|
// fill in roles_map
|
||||||
.map(r =>
|
.map(r =>
|
||||||
|
|
|
@ -134,7 +134,7 @@ class RolePicker extends Component {
|
||||||
</div>
|
</div>
|
||||||
<div className="role-picker__categories">
|
<div className="role-picker__categories">
|
||||||
{
|
{
|
||||||
vm.map((c, name) => <Category key={name} name={name} category={c} isSelected={this.isSelected} onChange={(roles) => dispatch(Actions.updateRoles(roles))} />).toArray()
|
vm.sortBy(v => v.get('position')).map((c, name) => <Category key={name} name={name} category={c} isSelected={this.isSelected} onChange={(roles) => dispatch(Actions.updateRoles(roles))} />).toArray()
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
@ -62,4 +62,8 @@ h1,h2,h3,h4,h5,h6 {
|
||||||
|
|
||||||
.fade {
|
.fade {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.yeet {
|
||||||
|
display: none;
|
||||||
}
|
}
|
Loading…
Add table
Reference in a new issue