moved to category relation instead of category

This commit is contained in:
vabene1111
2024-10-13 17:48:55 +02:00
parent be886b108c
commit e0f8d1ea9e

View File

@@ -33,13 +33,13 @@
:move="trackMovedItem"
>
<template #item="{element}">
<v-list-item border :key="element.id">
<v-list-item border :key="element.category.id">
<template #prepend>
<v-icon class="drag-handle cursor-grab" icon="$dragHandle"></v-icon>
</template>
{{ element.name }}
{{ element.category.name }}
<template #append>
<v-btn color="create" size="small" @click="addCategory(element)">
<v-btn color="create" size="small" @click="addCategoryRelation(element)">
<i class="fa-solid fa-plus"></i>
</v-btn>
</template>
@@ -48,7 +48,8 @@
<template #footer>
<v-list-item class="cursor-pointer" border prepend-icon="$create" variant="tonal" base-color="create">
{{ $t('New_Supermarket_Category') }}
<model-edit-dialog model="SupermarketCategory" @create="args => supermarketCategories.push(args)"></model-edit-dialog>
<model-edit-dialog model="SupermarketCategory"
@create="(args: SupermarketCategory) => supermarketCategories.push(args)"></model-edit-dialog>
</v-list-item>
</template>
</draggable>
@@ -58,23 +59,24 @@
<h3> {{ $t('SelectedCategories') }} </h3>
<draggable
tag="VList"
v-model="editingObjSupermarketCategories"
v-model="editingObjectSupermarketCategoriesRelations"
handle=".drag-handle" item-key="id" group="categories"
:empty-insert-threshold="20"
@sort="updateEditingObjectSupermarketCategoryRelation"
@sort="sortCategoryRelations()"
:move="trackMovedItem"
@add="addCategory(lastMovedCategory)"
@remove="removeCategory(lastMovedCategory)"
@add="addCategoryRelation(lastMovedCategoryRelation)"
@remove="removeCategoryRelation(lastMovedCategoryRelation)"
>
<template #item="{element}">
<v-list-item border :key="element.id">
<v-list-item border :key="element.category.id">
<template #prepend>
<v-icon class="drag-handle" icon="$dragHandle"></v-icon>
</template>
{{ element.name }}
{{ element.category.name }}
<v-chip>{{ element.order }}</v-chip>
<template #append>
<v-btn color="warning" size="small" @click="removeCategory(element)">
<v-btn color="warning" size="small" @click="removeCategoryRelation(element)">
<i class="fa-solid fa-minus"></i>
</v-btn>
</template>
@@ -124,15 +126,21 @@ const supermarketCategories = ref([] as SupermarketCategory[])
// all relations existing on the editing obj (internal datastructure, UI works with computed/manual list of categories)
const editingObjectSupermarketCategoriesRelations = ref([] as SupermarketCategoryRelation[])
// categories used by the selected supermarket
const editingObjSupermarketCategories = ref([] as SupermarketCategory[])
// track the last moved item in the draggable list to use in add/remove functions
const lastMovedCategory = ref({} as SupermarketCategory)
const lastMovedCategoryRelation = ref({} as SupermarketCategoryRelation)
// variable to prevent sorting while some other operation is currently running that would conflict / would make sorting unnecessary (e.g. adding item)
const preventSort = ref(false)
// computed: categories not yet used in editing supermarket
const unusedSupermarketCategories = computed(() => {
return supermarketCategories.value.filter(e => editingObjSupermarketCategories.value.findIndex(sc => sc.id == e.id) == -1)
let sCR = [] as SupermarketCategoryRelation[]
supermarketCategories.value.forEach((sc) => {
if (editingObjectSupermarketCategoriesRelations.value.findIndex(e => e.category.id == sc.id) == -1) {
sCR.push({supermarket: editingObj.value.id, category: sc, order: 0,} as SupermarketCategoryRelation)
}
})
return sCR
})
onMounted(() => {
@@ -145,78 +153,101 @@ onMounted(() => {
existingItemFunction: () => {
// initialize list of supermarket category relations
editingObjectSupermarketCategoriesRelations.value = editingObj.value.categoryToSupermarket
// load categories from relation list
editingObjectSupermarketCategoriesRelations.value.forEach(cTS => {
editingObjSupermarketCategories.value.push(cTS.category)
})
}
})
})
})
function updateEditingObjectSupermarketCategoryRelation(operation: any) {
if (operation.to == operation.from) {
console.log('sort', operation)
}
}
/**
* called whenever something in the list is moved to track the last moved element (to be used in add/remove functions)
* @param operation
*/
function trackMovedItem(operation: any) {
lastMovedCategory.value = operation.draggedContext.element
console.log('LAST MOVED', lastMovedCategory.value)
lastMovedCategoryRelation.value = operation.draggedContext.element
}
function sortCategoryRelations(startIndex: number = 0) {
const api = new ApiApi()
console.log('sort called start index: ', startIndex)
if (!preventSort.value) {
editingObjectSupermarketCategoriesRelations.value.forEach((sc, index) => {
console.log('sorting ', index, startIndex)
if (index >= startIndex) {
if (index == 0) {
sc.order = 0
} else {
sc.order = editingObjectSupermarketCategoriesRelations.value[index - 1].order! + 1
}
api.apiSupermarketCategoryRelationUpdate({id: sc.id!, supermarketCategoryRelation: sc}).catch((err: any) => {
useMessageStore().addError(ErrorMessageType.UPDATE_ERROR, err)
})
}
})
}
}
/**
* create supermarket category relation from given category and save it
* @param sc SupermarketCategory to create relation from
* add category relation to client list (if not already done by draggable) and to the server
* if required re-order existing client items so newly inserted items stays at correct order
* @param sCR SupermarketCategoryRelation to add
*/
function addCategory(sc: SupermarketCategory) {
function addCategoryRelation(sCR: SupermarketCategoryRelation) {
let api = new ApiApi()
let sC = {
category: sc,
order: editingObjSupermarketCategories.value.length + 1,
supermarket: editingObj.value.id,
} as SupermarketCategoryRelation
preventSort.value = true
api.apiSupermarketCategoryRelationCreate({supermarketCategoryRelation: sC}).then(r => {
editingObjectSupermarketCategoriesRelations.value.push(r)
// if the category has not been added already (by draggable) add it to the end of the list
if(editingObjSupermarketCategories.value.findIndex(e => e.id == sc.id) == -1){
editingObjSupermarketCategories.value.push(sc)
let relationIndex = editingObjectSupermarketCategoriesRelations.value.findIndex(e => e.category.id == sCR.category.id)
if (relationIndex != -1) {
if (relationIndex != 0 && editingObjectSupermarketCategoriesRelations.value[relationIndex - 1]) {
sCR.order = editingObjectSupermarketCategoriesRelations.value[relationIndex - 1].order! + 1
} else {
sCR.order = 0
}
} else {
// item will be added last to list so give it the highest order
sCR.order = editingObjectSupermarketCategoriesRelations.value[editingObjectSupermarketCategoriesRelations.value.length - 1].order! + 1
}
api.apiSupermarketCategoryRelationCreate({supermarketCategoryRelation: sCR}).then(r => {
// add to / update in client list
if (relationIndex != -1) {
// replace with sCR from API response
editingObjectSupermarketCategoriesRelations.value.splice(relationIndex, 1, r)
} else {
// add new to end of the list
editingObjectSupermarketCategoriesRelations.value.push(r)
}
preventSort.value = false
// TODO reorder existing items after index
}).catch((err: any) => {
useMessageStore().addError(ErrorMessageType.CREATE_ERROR, err)
preventSort.value = false
})
}
/**
* remove category from supermarket category relation
* finds relation by looking through relation list for given category
* @param sc SupermarketCategory to remove from relation
* remove SupermarketCategoryRelation from client list (if not already done by draggable) and from server
* @param sCR SupermarketCategoryRelation to remove
*/
function removeCategory(sc: SupermarketCategory) {
function removeCategoryRelation(sCR: SupermarketCategoryRelation) {
let api = new ApiApi()
// find relation and delete it / remove it from frontend list
let relationIndex = editingObjectSupermarketCategoriesRelations.value.findIndex(e => e.category.id == sc.id)
if (relationIndex > -1) {
api.apiSupermarketCategoryRelationDestroy({id: editingObjectSupermarketCategoriesRelations.value[relationIndex].id!}).then(r => {
editingObjectSupermarketCategoriesRelations.value.splice(relationIndex, 1)
// remove from client list
let relationIndex = editingObjectSupermarketCategoriesRelations.value.findIndex(e => e.category.id == sCR.category.id)
if (relationIndex != -1) {
editingObjectSupermarketCategoriesRelations.value.splice(relationIndex, 1)
}
// remove category from list (might have already been done by draggable)
editingObjSupermarketCategories.value = editingObjSupermarketCategories.value.filter(e => e.id != sc.id)
}).catch((err: any) => {
// delete on server if ID is present (should always be)
if (sCR.id) {
api.apiSupermarketCategoryRelationDestroy({id: sCR.id}).catch((err: any) => {
useMessageStore().addError(ErrorMessageType.DELETE_ERROR, err)
})
}
}
</script>