added batch delete dialog

This commit is contained in:
vabene1111
2025-08-20 21:47:43 +02:00
parent 45a567856a
commit a30deb4bae
36 changed files with 191 additions and 9 deletions

View File

@@ -0,0 +1,98 @@
<template>
<v-dialog max-width="600px" :activator="props.activator" v-model="dialog">
<v-card :loading="loading">
<v-closable-card-title
:title="$t('delete_title', {type: $t(genericModel.model.localizationKey)})"
:sub-title="genericModel.getLabel(props.source)"
:icon="genericModel.model.icon"
v-model="dialog"
></v-closable-card-title>
<v-divider></v-divider>
<v-card-text>
{{ $t('BatchDeleteConfirm') }}
<v-list>
<v-list-item border v-for="i in itemsToDelete">
{{ genericModel.getLabel(i) }}
<template #append>
<v-chip prepend-icon="fa-solid fa-xmark" color="error" v-if="deletedErrored.includes(i)">{{$t('Error')}}</v-chip>
<v-chip prepend-icon="fa-solid fa-check" color="success" v-else-if="deletedItems.includes(i)">{{$t('Deleted')}}</v-chip>
<v-chip prepend-icon="fa-solid fa-circle-notch fa-spin" color="info" v-else-if="loading">{{$t('Waiting')}}</v-chip>
<v-btn icon="fa-solid fa-up-right-from-square" :to="{name: 'IngredientEditorPage', query: {food_id: i.id}}"
v-if="genericModel.model.name == 'Food' && deletedErrored.includes(i)" size="small"></v-btn>
<v-btn icon="fa-solid fa-up-right-from-square" :to="{name: 'IngredientEditorPage', query: {unit_id: i.id}}"
v-if="genericModel.model.name == 'Unit' && deletedErrored.includes(i)" size="small"></v-btn>
</template>
</v-list-item>
</v-list>
<p class="font-italic text-disabled">{{$t('BatchDeleteHelp')}}</p>
</v-card-text>
<v-card-actions>
<v-btn :disabled="loading" @click="dialog = false">{{ $t('Cancel') }}</v-btn>
<v-btn color="error" @click="deleteAll()" :loading="loading">{{ $t('Delete_All') }}</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<script setup lang="ts">
import {onMounted, PropType, ref, watch} from "vue";
import {EditorSupportedModels, EditorSupportedTypes, getGenericModelFromString} from "@/types/Models.ts";
import VClosableCardTitle from "@/components/dialogs/VClosableCardTitle.vue";
import {useI18n} from "vue-i18n";
const emit = defineEmits(['change'])
const props = defineProps({
model: {type: String as PropType<EditorSupportedModels>, required: true},
items: {type: [] as PropType<Array<EditorSupportedTypes>>, required: true},
activator: {type: String, default: 'parent'},
})
const {t} = useI18n()
const dialog = defineModel<boolean>({default: false})
const loading = ref(false)
const genericModel = getGenericModelFromString(props.model, t)
const itemsToDelete = ref<EditorSupportedTypes[]>([])
const deletedItems = ref<EditorSupportedTypes[]>([])
const deletedErrored = ref<EditorSupportedTypes[]>([])
watch(dialog, (newValue, oldValue) => {
if(!oldValue && newValue){
itemsToDelete.value = JSON.parse(JSON.stringify(props.items))
}
})
/**
* loop through the items and delete them
*/
function deleteAll() {
let promises: Promise<any>[] = []
loading.value = true
itemsToDelete.value.forEach(item => {
promises.push(genericModel.destroy(item.id!).then((r: any) => {
deletedItems.value.push(item)
}).catch((err: any) => {
deletedErrored.value.push(item)
}))
})
Promise.allSettled(promises).then(() => {
loading.value = false
emit('change')
})
}
</script>
<style scoped>
</style>

View File

@@ -30,7 +30,7 @@
</v-card-text>
<v-card-actions>
<v-btn :disabled="loading">{{ $t('Cancel') }}</v-btn>
<v-btn :disabled="loading" @click="dialog = false">{{ $t('Cancel') }}</v-btn>
<v-btn color="warning" @click="mergeModel()" :loading="loading" :disabled="!target">{{ $t('Merge') }}</v-btn>
</v-card-actions>
</v-card>

View File

@@ -19,6 +19,8 @@
"Auto_Planner": "",
"Automate": "",
"Automation": "",
"BatchDeleteConfirm": "",
"BatchDeleteHelp": "",
"Bookmarklet": "",
"Books": "",
"CREATE_ERROR": "",

View File

@@ -19,6 +19,8 @@
"Auto_Planner": "Автоматичен плановик",
"Automate": "Автоматизация",
"Automation": "Автоматизация",
"BatchDeleteConfirm": "",
"BatchDeleteHelp": "",
"Bookmarklet": "Книжен пазар",
"Books": "Книги",
"CREATE_ERROR": "",

View File

@@ -26,6 +26,8 @@
"Automate": "Automatitzar",
"Automation": "Automatizació",
"Back": "Enrere",
"BatchDeleteConfirm": "",
"BatchDeleteHelp": "",
"Bookmarklet": "Marcadors",
"Books": "Llibres",
"CREATE_ERROR": "",

View File

@@ -26,6 +26,8 @@
"Automate": "Automatizovat",
"Automation": "Automatizace",
"Back": "Zpět",
"BatchDeleteConfirm": "",
"BatchDeleteHelp": "",
"Bookmarklet": "Skript v záložce",
"Books": "Kuchařky",
"CREATE_ERROR": "",

View File

@@ -26,6 +26,8 @@
"Automate": "Automatiser",
"Automation": "Automatisering",
"Back": "Tilbage",
"BatchDeleteConfirm": "",
"BatchDeleteHelp": "",
"Bookmarklet": "Bogmærke",
"Books": "Bøger",
"CREATE_ERROR": "",

View File

@@ -46,6 +46,8 @@
"BaseUnit": "Basiseinheit",
"BaseUnitHelp": "Optionale Standardeinheit zur automatischen Umrechnung",
"Basics": "Grundlagen",
"BatchDeleteConfirm": "Möchtest du alle angezeigten Objekte löschen? Dies kann nicht rückgängig gemacht werden!",
"BatchDeleteHelp": "Wenn ein Objekt nicht gelöscht werden kann, wird es noch irgendwo verwendet. ",
"Book": "Buch",
"Bookmarklet": "Lesezeichen",
"BookmarkletHelp1": "Schiebe den Knopf in deine Lesezeichenleiste",

View File

@@ -26,6 +26,8 @@
"Automate": "Αυτοματοποίηση",
"Automation": "Αυτοματισμός",
"Back": "Πίσω",
"BatchDeleteConfirm": "",
"BatchDeleteHelp": "",
"Bookmarklet": "Bookmarklet",
"Books": "Βιβλία",
"CREATE_ERROR": "",

View File

@@ -44,6 +44,8 @@
"BaseUnit": "Base Unit",
"BaseUnitHelp": "Standard unit for automatic unit conversion",
"Basics": "Basics",
"BatchDeleteConfirm": "Do you want to delete all shown items? This cannot be undone!",
"BatchDeleteHelp": "If an item cannot be deleted it is used somewhere. ",
"Book": "Book",
"Bookmarklet": "Bookmarklet",
"BookmarkletHelp1": "Drag the following button to your bookmarks bar",

View File

@@ -43,6 +43,8 @@
"BaseUnit": "Unidad base",
"BaseUnitHelp": "Unidad estándar para la conversión automática de unidades",
"Basics": "Básicos",
"BatchDeleteConfirm": "",
"BatchDeleteHelp": "",
"Book": "Libro",
"Bookmarklet": "Marcador ejecutable",
"BookmarkletHelp1": "Arrastra el siguiente botón a tu barra de marcadores",

View File

@@ -27,6 +27,8 @@
"Automate": "Automatisoi",
"Automation": "Automaatio",
"Back": "Takaisin",
"BatchDeleteConfirm": "",
"BatchDeleteHelp": "",
"Bookmarklet": "Kirjamerkki",
"Books": "Kirjat",
"CREATE_ERROR": "",

View File

@@ -45,6 +45,8 @@
"BaseUnit": "Unité de base",
"BaseUnitHelp": "Unité standard pour la conversion automatique des unités",
"Basics": "Les bases",
"BatchDeleteConfirm": "",
"BatchDeleteHelp": "",
"Book": "Livre",
"Bookmarklet": "Signet",
"BookmarkletHelp1": "Faites glisser le bouton suivant dans votre barre de signets",

View File

@@ -26,6 +26,8 @@
"Automate": "אוטומט",
"Automation": "אוטומטציה",
"Back": "חזור",
"BatchDeleteConfirm": "",
"BatchDeleteHelp": "",
"Bookmarklet": "סימניה",
"Books": "ספרים",
"CREATE_ERROR": "",

View File

@@ -26,6 +26,8 @@
"Automate": "Automatiziraj",
"Automation": "Automatizacija",
"Back": "Nazad",
"BatchDeleteConfirm": "",
"BatchDeleteHelp": "",
"Bookmarklet": "Knjižna oznaka",
"Books": "Knjige",
"CREATE_ERROR": "",

View File

@@ -26,6 +26,8 @@
"Automate": "Automatizálás",
"Automation": "Automatizálás",
"Back": "Vissza",
"BatchDeleteConfirm": "",
"BatchDeleteHelp": "",
"Bookmarklet": "Könyvjelző",
"Books": "Könyvek",
"CREATE_ERROR": "",

View File

@@ -9,6 +9,8 @@
"Advanced Search Settings": "Ընդլայնված փնտրման կարգավորումներ",
"Apply": "",
"Automate": "Ավտոմատացնել",
"BatchDeleteConfirm": "",
"BatchDeleteHelp": "",
"Books": "",
"CREATE_ERROR": "",
"Calories": "",

View File

@@ -21,6 +21,8 @@
"Auto_Planner": "",
"Automate": "",
"Automation": "Automatis",
"BatchDeleteConfirm": "",
"BatchDeleteHelp": "",
"Bookmarklet": "",
"Books": "Buku",
"CREATE_ERROR": "",

View File

@@ -26,6 +26,8 @@
"Automate": "",
"Automation": "",
"Back": "",
"BatchDeleteConfirm": "",
"BatchDeleteHelp": "",
"Bookmarklet": "",
"Books": "",
"CREATE_ERROR": "",

View File

@@ -45,6 +45,8 @@
"BaseUnit": "Unità di base",
"BaseUnitHelp": "Unità standard per la conversione automatica di unità",
"Basics": "Informazioni di base",
"BatchDeleteConfirm": "",
"BatchDeleteHelp": "",
"Book": "Libro",
"Bookmarklet": "Segnalibro",
"BookmarkletHelp1": "Trascina il pulsante seguente nella barra dei tuoi segnalibri",

View File

@@ -26,6 +26,8 @@
"Automate": "",
"Automation": "",
"Back": "",
"BatchDeleteConfirm": "",
"BatchDeleteHelp": "",
"Bookmarklet": "",
"Books": "",
"CREATE_ERROR": "",

View File

@@ -26,6 +26,8 @@
"Automate": "",
"Automation": "",
"Back": "",
"BatchDeleteConfirm": "",
"BatchDeleteHelp": "",
"Bookmarklet": "",
"Books": "",
"CREATE_ERROR": "",

View File

@@ -25,6 +25,8 @@
"Auto_Sort_Help": "Flytt alle ingredienser til det mest passende steget.",
"Automate": "Automatiser",
"Automation": "Automatiser",
"BatchDeleteConfirm": "",
"BatchDeleteHelp": "",
"Bookmarklet": "",
"Books": "Bøker",
"CREATE_ERROR": "",

View File

@@ -46,6 +46,8 @@
"BaseUnit": "Basiseenheid",
"BaseUnitHelp": "Standaardeenheid om automatische eenheden om te rekenen",
"Basics": "Basisprincipes",
"BatchDeleteConfirm": "",
"BatchDeleteHelp": "",
"Book": "Boek",
"Bookmarklet": "Bladwijzer",
"BookmarkletHelp1": "Sleep de onderstaande knop naar je bladwijzerbalk",

View File

@@ -43,6 +43,8 @@
"BaseUnit": "Podstawowa jednostka",
"BaseUnitHelp": "Standardowa jednostka dla automatyczne konwersji jednostek",
"Basics": "Podstawy",
"BatchDeleteConfirm": "",
"BatchDeleteHelp": "",
"Book": "Książka",
"Bookmarklet": "Skryptozakładka",
"BookmarkletHelp1": "Przeciągnij następujący przycisk do twojego paska zakładek",

View File

@@ -21,6 +21,8 @@
"Auto_Sort_Help": "Mover todos os ingredientes para o passo mais indicado.",
"Automate": "Automatizar",
"Automation": "Automação",
"BatchDeleteConfirm": "",
"BatchDeleteHelp": "",
"Books": "Livros",
"CREATE_ERROR": "",
"Calculator": "Calculadora",

View File

@@ -44,6 +44,8 @@
"BaseUnit": "Unidade Base",
"BaseUnitHelp": "Unidade padrão para conversão de unidades",
"Basics": "Básicos",
"BatchDeleteConfirm": "",
"BatchDeleteHelp": "",
"Book": "Livro",
"Bookmarklet": "Marcador",
"BookmarkletHelp1": "Arraste o seguinte botão para sua barra de favoritos",

View File

@@ -25,6 +25,8 @@
"Auto_Sort_Help": "Mutați toate ingredientele la cel mai potrivit pas.",
"Automate": "Automatizat",
"Automation": "Automatizare",
"BatchDeleteConfirm": "",
"BatchDeleteHelp": "",
"Bookmarklet": "Marcaj",
"Books": "Cărți",
"CREATE_ERROR": "",

View File

@@ -45,6 +45,8 @@
"BaseUnit": "Базовая единица измерения",
"BaseUnitHelp": "Стандартная единица для автоконвертации",
"Basics": "Основные понятия",
"BatchDeleteConfirm": "",
"BatchDeleteHelp": "",
"Book": "Книга",
"Bookmarklet": "Букмарклет",
"BookmarkletHelp1": "Перетащите эту кнопку в панель закладок",

View File

@@ -45,6 +45,8 @@
"BaseUnit": "Osnovna enota",
"BaseUnitHelp": "Standardna enota za samodejno pretvorbo enot",
"Basics": "Osnove",
"BatchDeleteConfirm": "",
"BatchDeleteHelp": "",
"Book": "Knjiga",
"Bookmarklet": "Zaznamek",
"BookmarkletHelp1": "Povlecite naslednji gumb v vrstico z zaznamki",

View File

@@ -44,6 +44,8 @@
"BaseUnit": "Basenhet",
"BaseUnitHelp": "Standardenhet för automatisk enhetsomvandling",
"Basics": "Grunderna",
"BatchDeleteConfirm": "",
"BatchDeleteHelp": "",
"Book": "Bok",
"Bookmarklet": "Bokmärke",
"BookmarkletHelp1": "Dra följande knapp till ditt bokmärkesfält",

View File

@@ -26,6 +26,8 @@
"Automate": "Otomatikleştir",
"Automation": "Otomasyon",
"Back": "Geri",
"BatchDeleteConfirm": "",
"BatchDeleteHelp": "",
"Bookmarklet": "Yer İmi",
"Books": "Kitaplar",
"CREATE_ERROR": "",

View File

@@ -23,6 +23,8 @@
"Auto_Sort_Help": "Перемістити всі інгредієнти до більш підходящого кроку.",
"Automate": "Автоматично",
"Automation": "Автоматизація",
"BatchDeleteConfirm": "",
"BatchDeleteHelp": "",
"Bookmarklet": "",
"Books": "Книги",
"CREATE_ERROR": "",

View File

@@ -26,6 +26,8 @@
"Automate": "自动化",
"Automation": "自动化",
"Back": "后退",
"BatchDeleteConfirm": "",
"BatchDeleteHelp": "",
"Bookmarklet": "书签",
"Books": "烹饪手册",
"CREATE_ERROR": "",

View File

@@ -44,6 +44,8 @@
"BaseUnit": "基礎單位",
"BaseUnitHelp": "自動單位轉換的標準單位",
"Basics": "基礎",
"BatchDeleteConfirm": "",
"BatchDeleteHelp": "",
"Book": "書籍",
"Bookmarklet": "書籤小工具",
"BookmarkletHelp1": "將以下按鈕拖到您的書籤欄中",

View File

@@ -36,9 +36,10 @@
<v-row>
<v-col>
<v-text-field prepend-inner-icon="$search" :label="$t('Search')" v-model="searchQuery" clearable></v-text-field>
<v-data-table-server
v-model="selectedItems"
return-object
@update:options="loadItems"
:items="items"
:items-length="itemCount"
@@ -46,14 +47,23 @@
:search="searchQuery"
:headers="genericModel.getTableHeaders()"
:items-per-page-options="itemsPerPageOptions"
:show-select="tableShowSelect"
:show-select="!genericModel.model.disableDelete || genericModel.model.isMerge"
:page="tablePage"
:items-per-page="useUserPreferenceStore().deviceSettings.general_tableItemsPerPage"
disable-sort
>
<!-- <template v-slot:header.action v-if="selectedItems.length > 0">-->
<!-- <v-select density="compact" hide-details></v-select>-->
<!-- </template>-->
<template v-slot:header.action v-if="selectedItems.length > 0">
<v-btn icon="fa-solid fa-ellipsis-v" variant="plain" color="info">
<v-icon icon="fa-solid fa-ellipsis-v"></v-icon>
<v-menu activator="parent" close-on-content-click>
<v-list density="compact" class="pt-1 pb-1" activatable>
<v-list-item prepend-icon="$delete" @click="batchDeleteDialog = true">
{{ $t('Delete_All') }}
</v-list-item>
</v-list>
</v-menu>
</v-btn>
</template>
<template v-slot:item.action="{ item }">
<v-btn class="float-right" icon="$menu" variant="plain">
<v-icon icon="$menu"></v-icon>
@@ -90,6 +100,9 @@
</v-data-table-server>
</v-col>
</v-row>
<batch-delete-dialog :items="selectedItems" :model="props.model" v-model="batchDeleteDialog" activator="model"
@change="loadItems({page: tablePage, itemsPerPage: useUserPreferenceStore().deviceSettings.general_tableItemsPerPage, search: searchQuery})"></batch-delete-dialog>
</v-container>
</template>
@@ -99,7 +112,7 @@
import {onBeforeMount, PropType, ref, watch} from "vue";
import {ErrorMessageType, useMessageStore} from "@/stores/MessageStore";
import {useI18n} from "vue-i18n";
import {EditorSupportedModels, GenericModel, getGenericModelFromString, Model,} from "@/types/Models";
import {EditorSupportedModels, EditorSupportedTypes, GenericModel, getGenericModelFromString, Model,} from "@/types/Models";
import ModelEditDialog from "@/components/dialogs/ModelEditDialog.vue";
import {useRoute, useRouter} from "vue-router";
import {useUserPreferenceStore} from "@/stores/UserPreferenceStore";
@@ -108,6 +121,9 @@ import {VDataTableUpdateOptions} from "@/vuetify";
import SyncDialog from "@/components/dialogs/SyncDialog.vue";
import {ApiApi, RecipeImport} from "@/openapi";
import {useTitle} from "@vueuse/core";
import RecipeShareDialog from "@/components/dialogs/RecipeShareDialog.vue";
import AddToShoppingDialog from "@/components/dialogs/AddToShoppingDialog.vue";
import BatchDeleteDialog from "@/components/dialogs/BatchDeleteDialog.vue";
const {t} = useI18n()
const router = useRouter()
@@ -130,8 +146,9 @@ const itemsPerPageOptions = [
const tablePage = ref(1)
const tableShowSelect = ref(true)
const selectedItems = ref([] as GenericModel[])
const selectedItems = ref([] as EditorSupportedTypes[])
const batchDeleteDialog = ref(false)
// data
const loading = ref(false);
@@ -185,6 +202,7 @@ onBeforeMount(() => {
function loadItems(options: VDataTableUpdateOptions) {
loading.value = true
selectedItems.value = []
window.scrollTo({top: 0, behavior: 'smooth'})
if (tablePage.value != options.page) {