ADD: Draggable categories + fixes

This commit is contained in:
Robert Kossessa
2024-02-09 14:45:32 +01:00
parent 48bf22208e
commit 697e5fceb7
2 changed files with 68 additions and 42 deletions

View File

@@ -52,47 +52,60 @@
</div> </div>
</div> </div>
<div v-else> <div v-else>
<draggable
key="categoriesDraggable"
group="profileCategories"
item-key="name"
:list="store.profileCategories"
v-bind="dragOptions"
@start="drag = true"
@end="drag = false"
@change="onCategoryDrop">
<template #item="dragCategory">
<Collapsible <Collapsible
v-for="(category, categoryIndex) in store.profileCategories" :key="categoryIndex" v-model:open="collapse[dragCategory.index]"
v-model:open="collapse[categoryIndex]"
:default-open="true"> :default-open="true">
<!-- TODO: Make profile groups computed instead defining them of using v-for --> <!-- TODO: Make profile groups computed instead defining them of using v-for -->
<CollapsibleTrigger <CollapsibleTrigger
class="w-full h-12 py-2 text-left text-muted-foreground text-sm bg-zinc-900 border-0 border-b"> class="w-full h-12 py-2 text-left text-muted-foreground text-sm bg-zinc-900 border-0 border-b">
<ChevronRight class="chevrot h-4 w-4 mb-0.5 ml-4 inline-block transition-transform" /> <ChevronRight class="chevrot h-4 w-4 mb-0.5 ml-4 inline-block transition-transform" />
{{ category.name }}<span class="font-heading text-sm text-zinc-600"> ({{ category.profiles?.length || 0 {{ dragCategory.element.name }}<span
class="font-heading text-sm text-zinc-600"> ({{ dragCategory.element.profiles?.length || 0
}})</span> }})</span>
</CollapsibleTrigger> </CollapsibleTrigger>
<CollapsibleContent> <CollapsibleContent>
<TransitionGroup> <TransitionGroup>
<draggable <draggable
key="draggable" key="profilesDraggable"
group="profiles"
item-key="id" item-key="id"
:list="category.profiles" :list="dragCategory.element.profiles"
v-bind="dragOptions" v-bind="dragOptions"
@start="drag = true" @start="drag = true"
@end="drag = false" @end="drag = false"
@change="(event)=>onProfileDrop(event, categoryIndex)"> @change="(event)=>onProfileDrop(event, dragCategory.index)">
<template v-if="category.profiles.length === 0" #header> <template v-if="dragCategory.element.profiles.length === 0" #header>
<div class="flex h-12 justify-center items-center hideable-header"> <div class="flex h-12 justify-center items-center hideable-header">
<MoreHorizontal class="w-4 text-zinc-600" /> <MoreHorizontal class="w-4 text-zinc-600" />
</div> </div>
</template> </template>
<template #item="{ element }"> <template #item="dragProfile">
<div :key="element.name"> <div :key="dragProfile.element.name">
<ProfileButton <ProfileButton
:profile="element" :profile="dragProfile.element"
:show-hover-buttons="!drag" :show-hover-buttons="!drag"
:selected="store.selectedProfile?.id === element.id" :selected="store.selectedProfile?.id === dragProfile.element.id"
@select="store.selectProfile(element.id); showProfileConfig=true" @select="store.selectProfile(dragProfile.element.id); showProfileConfig=true"
@duplicate="store.duplicateProfile(element.id)" @duplicate="store.duplicateProfile(dragProfile.element.id)"
@delete="store.removeProfile(element.id)" /> @delete="store.removeProfile(dragProfile.element.id)" />
</div> </div>
</template> </template>
</draggable> </draggable>
</TransitionGroup> </TransitionGroup>
</CollapsibleContent> </CollapsibleContent>
</Collapsible> </Collapsible>
</template>
</draggable>
</div> </div>
</div> </div>
<Transition name="slide"> <Transition name="slide">
@@ -123,7 +136,6 @@ defineProps({
}) })
const dragOptions = ref({ const dragOptions = ref({
group: 'profiles',
ghostClass: 'ghost', ghostClass: 'ghost',
animation: 150, animation: 150,
direction: 'vertical', direction: 'vertical',
@@ -179,6 +191,15 @@ watch(showProfileConfig, value => {
// return map // return map
// }) // })
const onCategoryDrop = (event) => {
if (event.moved) {
const category = event.moved.element
const oldIndex = event.moved.oldIndex
const newIndex = event.moved.newIndex
store.moveProfileCategory(category.name, oldIndex, newIndex)
}
}
const onProfileDrop = (event, categoryIndex) => { const onProfileDrop = (event, categoryIndex) => {
if (event.moved) { if (event.moved) {
const profile = event.moved.element const profile = event.moved.element

View File

@@ -82,6 +82,11 @@ export const useStore = defineStore('main', {
category.profiles[newIndex] = category.profiles[oldIndex] category.profiles[newIndex] = category.profiles[oldIndex]
category.profiles[newIndex] = tmpProfile category.profiles[newIndex] = tmpProfile
}, },
moveProfileCategory(categoryName, oldIndex, newIndex) {
const tmpCategory = this.profileCategories[newIndex]
this.profileCategories[newIndex] = this.profileCategories[oldIndex]
this.profileCategories[newIndex] = tmpCategory
},
changeProfileCategory(profileId, newCategoryIndex, newIndex) { changeProfileCategory(profileId, newCategoryIndex, newIndex) {
const profile = this.profiles.find(p => p.id === profileId) const profile = this.profiles.find(p => p.id === profileId)
const oldCategory = this.profileCategories.find(c => c.profiles.find(p => p.id === profileId)) const oldCategory = this.profileCategories.find(c => c.profiles.find(p => p.id === profileId))