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 op_mini all"
|
||||
],
|
||||
"proxy": "http://localhost:6768",
|
||||
"proxy": "http://localhost:6769",
|
||||
"devDependencies": {
|
||||
"@babel/plugin-proposal-decorators": "^7.4.0",
|
||||
"customize-cra": "^0.2.12",
|
||||
|
|
|
@ -33,7 +33,6 @@ class Category extends Component {
|
|||
</div>
|
||||
{
|
||||
category.get('roles_map')
|
||||
.sortBy(r => r.get('position'))
|
||||
.reverse()
|
||||
.map((r, k) => <Role key={k} role={r} categoryId={name} />)
|
||||
.toArray()
|
||||
|
|
|
@ -24,6 +24,28 @@ export default class CategoryEditor extends Component {
|
|||
<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'))} />
|
||||
</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 style={{ marginTop: 10 }}>
|
||||
<div className="uk-form-controls">
|
||||
|
|
|
@ -36,7 +36,16 @@
|
|||
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
|
||||
box-sizing: border-box
|
||||
|
|
|
@ -9,7 +9,7 @@ export const constructView = id => async (dispatch, getState) => {
|
|||
const server = getState().servers.get(id)
|
||||
|
||||
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({
|
||||
type: Symbol.for('re: setup'),
|
||||
|
@ -115,7 +115,8 @@ export const createCategory = (dispatch, getState) => {
|
|||
|
||||
let name = 'New Category'
|
||||
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++
|
||||
name = `New Category ${idx}`
|
||||
}
|
||||
|
@ -131,16 +132,57 @@ export const createCategory = (dispatch, getState) => {
|
|||
roles_map: Set([]),
|
||||
hidden: true,
|
||||
type: 'multi',
|
||||
position: idx,
|
||||
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) => {
|
||||
const viewMap = getState().roleEditor.get('viewMap')
|
||||
.filterNot((_, k) => k === 'Uncategorized')
|
||||
.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() })
|
||||
dispatch({ type: Symbol.for('re: swap original state') })
|
||||
}
|
||||
|
|
|
@ -107,6 +107,8 @@ class RoleEditor extends Component {
|
|||
dispatch(Actions.saveServer(server))
|
||||
}
|
||||
|
||||
onBump = (category, name) => (move) => () => this.props.dispatch(Actions.bumpCategory(category, name)(move))
|
||||
|
||||
get hasChanged () {
|
||||
return this.props.editor.get('originalSnapshot').hashCode() !== this.props.editor.get('viewMap').hashCode()
|
||||
}
|
||||
|
@ -143,16 +145,19 @@ class RoleEditor extends Component {
|
|||
{
|
||||
vm
|
||||
.filter((_, k) => k !== 'Uncategorized')
|
||||
.map((c, name) => <Category
|
||||
.sortBy(c => c.get('position'))
|
||||
.map((c, name, arr) => <Category
|
||||
key={name}
|
||||
name={name}
|
||||
category={c}
|
||||
arrMax={arr.count()}
|
||||
mode={c.get('mode')}
|
||||
onDrop={this.dropRole(c, name)}
|
||||
onEdit={this.editCategory(c, name)}
|
||||
onEditOpen={this.openEditor(c, name)}
|
||||
onSave={this.saveCategory(c, name)}
|
||||
onDelete={this.deleteCategory(c, name)}
|
||||
onBump={this.onBump(c, name)}
|
||||
/>)
|
||||
.toArray()
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ export const setup = id => async dispatch => {
|
|||
export const getViewMap = server => {
|
||||
const roles = server.get('roles')
|
||||
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 accountedRoles = categories.map(c => c.get('roles')).toSet().flatten()
|
||||
|
@ -31,7 +32,17 @@ export const getViewMap = server => {
|
|||
hidden: true,
|
||||
type: 'multi',
|
||||
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')
|
||||
// fill in roles_map
|
||||
.map(r =>
|
||||
|
|
|
@ -134,7 +134,7 @@ class RolePicker extends Component {
|
|||
</div>
|
||||
<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>
|
||||
</section>
|
||||
|
|
|
@ -63,3 +63,7 @@ h1,h2,h3,h4,h5,h6 {
|
|||
.fade {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.yeet {
|
||||
display: none;
|
||||
}
|
Loading…
Add table
Reference in a new issue