feat: categories selection and delete

This commit is contained in:
Florian Sylvain
2024-10-13 23:18:37 +02:00
parent 6758e0e9ea
commit 01881cc446
4 changed files with 92 additions and 2 deletions
+18 -1
View File
@@ -1,7 +1,7 @@
<script setup lang="ts">
import type { Category } from '@/composables/category'
import { useCategoriesStore } from '@/stores/categories'
import { ref, type Ref } from 'vue'
import { ref, watch, type Ref } from 'vue'
interface CategoryItem {
id: number
@@ -16,6 +16,7 @@ const props = defineProps<{
const emit = defineEmits<{
categoriesUpdated: []
categoriesIdsToDeleteUpdated: [ids: number[]]
}>()
const categoriesStore = useCategoriesStore()
@@ -26,6 +27,8 @@ const deleteDialogCategory: Ref<CategoryItem | undefined> = ref()
const itemsPerPageGlob: Ref<number> = ref(10)
const itemsPage: Ref<number> = ref(0)
const itemsSelected: Ref<number[]> = ref([])
function onDeleteClick(category: CategoryItem) {
deleteDialogCategory.value = category
deleteDialog.value = true
@@ -57,11 +60,23 @@ async function loadItems({
else categoriesStore.updateSort(undefined, undefined)
emit('categoriesUpdated')
}
watch(itemsSelected, (newItemsSelected) => {
emit('categoriesIdsToDeleteUpdated', newItemsSelected)
})
watch(
() => props.fetchedCategories,
() => {
itemsSelected.value = []
}
)
</script>
<template>
<VDataTableServer
:headers="[
{ title: 'ID', key: 'id', sortable: true },
{ title: 'Name', key: 'name', sortable: true },
{ title: 'Actions', key: 'actions', align: 'end', sortable: false }
]"
@@ -69,7 +84,9 @@ async function loadItems({
:loading="props.loading"
:items-length="props.itemsTotal"
v-model:items-per-page="itemsPerPageGlob"
v-model="itemsSelected"
@update:options="loadItems"
show-select
>
<template v-slot:[`item.actions`]="{ item }">
<VBtn icon="mdi-pencil" variant="flat" size="small"></VBtn>
+51
View File
@@ -0,0 +1,51 @@
<script setup lang="ts">
import { useCategoriesStore } from '@/stores/categories'
import { ref, type Ref } from 'vue'
const emit = defineEmits<{
categoriesDeleted: []
}>()
const props = defineProps<{
ids: number[]
}>()
const dialog: Ref<boolean> = ref(false)
const categoriesStore = useCategoriesStore()
async function onSubmit(): Promise<void> {
await categoriesStore.deleteCategories(props.ids)
emit('categoriesDeleted')
dialog.value = false
}
</script>
<template>
<VDialog v-model="dialog" max-width="500">
<template v-slot:activator="{ props: activatorProps }">
<VBtn
v-if="props.ids.length > 0"
prepend-icon="mdi-delete"
text="Delete selected"
color="error"
variant="outlined"
v-bind="activatorProps"
></VBtn>
</template>
<VCard prepend-icon="mdi-delete" title="Create Category">
<VForm @submit.prevent="onSubmit">
<VCardText class="text-body-1">
Are you absolutely sure you want to delete the {{ ids.length }} selected categories? This
is unrecoverable.
</VCardText>
<VDivider />
<VCardActions>
<VSpacer />
<VBtn color="primary" text="Close" variant="outlined" @click="dialog = false"></VBtn>
<VBtn color="error" text="Delete" variant="flat" type="submit"></VBtn>
</VCardActions>
</VForm>
</VCard>
</VDialog>
</template>
+9
View File
@@ -46,10 +46,19 @@ export const useCategoriesStore = defineStore('categories', () => {
})
}
const deleteCategories = async (ids: number[]): Promise<Response> => {
return await fetch(`${api.url}/category`, {
...api.options,
method: 'DELETE',
body: JSON.stringify({ ids })
})
}
return {
getCategories,
postCategory,
deleteCategory,
deleteCategories,
updateSkipTake,
updateSort
}
+14 -1
View File
@@ -1,6 +1,7 @@
<script setup lang="ts">
import CategoriesTable from '@/components/CategoriesTable.vue'
import CategoryCreate from '@/components/CategoryCreate.vue'
import DeleteCategories from '@/components/DeleteCategories.vue'
import type { Category } from '@/composables/category'
import { useCategoriesStore } from '@/stores/categories'
import { onMounted, ref, type Ref } from 'vue'
@@ -9,12 +10,20 @@ const categoriesStore = useCategoriesStore()
const fetchedCategories: Ref<Category | undefined> = ref()
const loading: Ref<boolean> = ref(true)
const categoriesIdsToDelete: Ref<number[]> = ref([])
async function fetchCategories() {
const categoriesPromise = await categoriesStore.getCategories()
fetchedCategories.value = await categoriesPromise.json()
loading.value = false
}
async function deleteCategories() {
await categoriesStore.deleteCategories(categoriesIdsToDelete.value)
await fetchCategories()
categoriesIdsToDelete.value = []
}
onMounted(async () => {
await fetchCategories()
})
@@ -23,10 +32,14 @@ onMounted(async () => {
<template>
<header class="d-flex align-center justify-space-between">
<h1 class="text-h3">Categories</h1>
<CategoryCreate @categoryCreated="fetchCategories" />
<div class="d-flex align-center ga-2">
<DeleteCategories @categoriesDeleted="deleteCategories" :ids="categoriesIdsToDelete" />
<CategoryCreate @categoryCreated="fetchCategories" />
</div>
</header>
<CategoriesTable
@categoriesUpdated="fetchCategories"
@categoriesIdsToDeleteUpdated="categoriesIdsToDelete = $event"
:fetchedCategories="fetchedCategories"
:loading="loading"
:itemsTotal="fetchedCategories?.total ?? 0"