Implemented drag and drop on spells page

This commit is contained in:
Stefan Zermatten
2020-07-26 19:39:50 +02:00
parent 1ac01941c7
commit 0f20cd4bd9
5 changed files with 113 additions and 26 deletions

View File

@@ -3,7 +3,10 @@
<column-layout wide-columns>
<div v-if="spellsWithoutList.length">
<v-card>
<spell-list :spells="spellsWithoutList" />
<spell-list
:spells="spellsWithoutList"
:parent-ref="{id: creatureId, collection: 'creatures'}"
/>
</v-card>
</div>
<div

View File

@@ -135,7 +135,7 @@
{title: 'Home', icon: 'home', to: '/'},
{title: 'Characters', icon: 'portrait', to: '/characterList', requireLogin: true},
{title: 'Library', icon: 'book', to: '/library', requireLogin: true},
{title: 'Tabletops', icon: 'api', to: '/tabletops', requireLogin: true},
//{title: 'Tabletops', icon: 'api', to: '/tabletops', requireLogin: true},
//{title: 'Friends', icon: 'people', to: '/friends', requireLogin: true},
{title: 'Feedback', icon: 'bug_report', to: '/feedback'},
{title: 'About', icon: 'subject', to: '/about'},

View File

@@ -4,26 +4,62 @@
dense
class="spell-list"
>
<template v-for="level in levels">
<v-subheader :key="`${level}-header`">
{{ level === 0 ? 'Cantrips' : `Level ${level}` }}
</v-subheader>
<spell-list-tile
v-for="spell in spellsByLevel[level]"
:key="spell._id"
:data-id="`spell-list-tile-${spell._id}`"
:model="spell"
@click="clickProperty(spell._id)"
/>
</template>
<draggable
v-model="computedSpells"
:group="`spell-list`"
ghost-class="ghost"
draggable=".item"
handle=".handle"
:animation="200"
@change="change"
>
<template v-for="spell in computedSpells">
<v-subheader
v-if="spell.isSubheader"
:key="`${spell.level}-header`"
class="item"
>
{{ spell.level === 0 ? 'Cantrips' : `Level ${spell.level}` }}
</v-subheader>
<spell-list-tile
v-else
:key="spell._id"
class="item"
:data-id="`spell-list-tile-${spell._id}`"
:model="spell"
@click="clickProperty(spell._id)"
/>
</template>
</draggable>
</v-list>
</template>
<script>
import draggable from 'vuedraggable';
import SpellListTile from '/imports/ui/properties/components/spells/SpellListTile.vue';
import { organizeDoc } from '/imports/api/parenting/organizeMethods.js';
function spellsWithSubheaders(spells = []){
let result = [];
let lastSpell = undefined;
let sortedSpells = [...spells].sort((a, b) => a.level - b.level)
sortedSpells.forEach(spell => {
if (spell.isSubheader) return;
if (!lastSpell || spell.level > lastSpell.level){
result.push({
isSubheader: true,
level: spell.level,
});
}
result.push(spell);
lastSpell = spell;
});
return result;
}
export default {
components: {
draggable,
SpellListTile,
},
props: {
@@ -31,24 +67,36 @@ export default {
type: Array,
default: () => [],
},
parentRef: {
type: Object,
required: true,
},
},
data(){ return {
dataSpells: [],
}},
computed: {
levels(){
let levels = new Set();
this.spells.forEach(spell => levels.add(spell.level));
return levels;
},
spellsByLevel(){
let spellsByLevel = {};
this.spells.forEach(spell => {
if (!spellsByLevel[spell.level]){
spellsByLevel[spell.level] = [spell];
} else {
spellsByLevel[spell.level].push(spell);
}
});
return spellsByLevel;
},
computedSpells: {
get(){
return spellsWithSubheaders(this.dataSpells);
},
set(value){
this.dataSpells = value;
},
}
},
watch: {
spells(value){
this.dataSpells = spellsWithSubheaders(value);
}
},
mounted(){
this.dataSpells = spellsWithSubheaders(this.spells);
},
methods: {
clickProperty(_id){
@@ -58,6 +106,31 @@ export default {
data: {_id},
});
},
change({added, moved}){
let event = added || moved;
if (event){
// If this spell is now adjacent to another, set the order accordingly
let order;
let before = this.dataSpells[event.newIndex - 1];
let after = this.dataSpells[event.newIndex + 1];
if (before && before._id){
order = before.order + 0.5;
} else if (after && after._id) {
order = after.order - 0.5;
} else {
order = -0.5;
}
let doc = event.element;
organizeDoc.call({
docRef: {
id: doc._id,
collection: 'creatureProperties',
},
parentRef: this.parentRef,
order,
});
}
},
}
}
</script>

View File

@@ -10,7 +10,10 @@
</v-toolbar-title>
<v-spacer />
</template>
<spell-list :spells="spells" />
<spell-list
:spells="spells"
:parent-ref="{id: model._id, collection: 'creatureProperties'}"
/>
</toolbar-card>
</template>

View File

@@ -17,6 +17,14 @@
{{ components }}
</v-list-tile-sub-title>
</v-list-tile-content>
<v-list-tile-action>
<v-icon
style="height: 100%; width: 40px; cursor: move;"
class="handle"
>
drag_indicator
</v-icon>
</v-list-tile-action>
</v-list-tile>
</template>