warn before leaving model edit page

This commit is contained in:
vabene1111
2025-01-01 10:07:27 +01:00
parent 60f2494eae
commit 8159838fc3
52 changed files with 177 additions and 30 deletions

View File

@@ -1,13 +1,13 @@
<template> <template>
<v-card-title class="pb-0"> <v-card-title class="pb-0">
<v-row align="center" > <v-row align="center">
<v-col cols="10" md="11" class="text-truncate"> <v-col cols="10" md="11" class="text-truncate">
<i :class="props.icon" v-if="props.icon != ''"></i> <i :class="props.icon" v-if="props.icon != ''"></i>
{{ props.title }} {{ props.title }}
<v-card-subtitle class="pa-0" v-if="props.subTitle != ''">{{ props.subTitle}}</v-card-subtitle> <v-card-subtitle class="pa-0" v-if="props.subTitle != ''">{{ props.subTitle }}</v-card-subtitle>
</v-col> </v-col>
<v-col cols="2" md="1" v-if="!props.hideClose"> <v-col cols="2" md="1">
<v-btn class="float-right pr-2" icon="$close" variant="plain" @click="model = false; emit('close')"></v-btn> <v-btn class="float-right pr-2" icon="$close" variant="plain" @click="model = false; emit('close')" v-if="!props.hideClose"></v-btn>
</v-col> </v-col>
</v-row> </v-row>
</v-card-title> </v-card-title>
@@ -26,7 +26,7 @@ const props = defineProps({
title: {type: String, default: ''}, title: {type: String, default: ''},
icon: {type: String, default: ''}, icon: {type: String, default: ''},
subTitle: {type: String, default: ''}, subTitle: {type: String, default: ''},
hideClose: {type:Boolean, default: false}, hideClose: {type: Boolean, default: false},
}) })
const model = defineModel<Boolean>() const model = defineModel<Boolean>()

View File

@@ -6,6 +6,7 @@
@delete="deleteObject" @delete="deleteObject"
@close="emit('close')" @close="emit('close')"
:is-update="isUpdate()" :is-update="isUpdate()"
:is-changed="editingObjChanged"
:model-class="modelClass" :model-class="modelClass"
:object-name="editingObjName()"> :object-name="editingObjName()">
<v-card-text> <v-card-text>
@@ -45,7 +46,7 @@ const props = defineProps({
}) })
const emit = defineEmits(['create', 'save', 'delete', 'close']) const emit = defineEmits(['create', 'save', 'delete', 'close'])
const {setupState, deleteObject, saveObject, isUpdate, editingObjName, loading, editingObj, modelClass} = useModelEditorFunctions<AccessToken>('AccessToken', emit) const {setupState, deleteObject, saveObject, isUpdate, editingObjName, loading, editingObj, editingObjChanged, modelClass} = useModelEditorFunctions<AccessToken>('AccessToken', emit)
onMounted(() => { onMounted(() => {

View File

@@ -6,6 +6,7 @@
@delete="deleteObject" @delete="deleteObject"
@close="emit('close')" @close="emit('close')"
:is-update="isUpdate()" :is-update="isUpdate()"
:is-changed="editingObjChanged"
:model-class="modelClass" :model-class="modelClass"
:object-name="editingObjName()"> :object-name="editingObjName()">
<v-card-text> <v-card-text>
@@ -47,7 +48,7 @@ const props = defineProps({
}) })
const emit = defineEmits(['create', 'save', 'delete', 'close']) const emit = defineEmits(['create', 'save', 'delete', 'close'])
const {setupState, deleteObject, saveObject, isUpdate, editingObjName, loading, editingObj, modelClass} = useModelEditorFunctions<Automation>('Automation', emit) const {setupState, deleteObject, saveObject, isUpdate, editingObjName, loading, editingObj, editingObjChanged, modelClass} = useModelEditorFunctions<Automation>('Automation', emit)
// object specific data (for selects/display) // object specific data (for selects/display)

View File

@@ -6,6 +6,7 @@
@delete="deleteObject" @delete="deleteObject"
@close="emit('close')" @close="emit('close')"
:is-update="isUpdate()" :is-update="isUpdate()"
:is-changed="editingObjChanged"
:model-class="modelClass" :model-class="modelClass"
:object-name="editingObjName()"> :object-name="editingObjName()">
@@ -133,7 +134,7 @@ const props = defineProps({
}) })
const emit = defineEmits(['create', 'save', 'delete', 'close']) const emit = defineEmits(['create', 'save', 'delete', 'close'])
const {setupState, deleteObject, saveObject, isUpdate, editingObjName, loading, editingObj, modelClass} = useModelEditorFunctions<Food>('Food', emit) const {setupState, deleteObject, saveObject, isUpdate, editingObjName, loading, editingObj, editingObjChanged, modelClass} = useModelEditorFunctions<Food>('Food', emit)
// object specific data (for selects/display) // object specific data (for selects/display)

View File

@@ -6,6 +6,7 @@
@delete="deleteObject" @delete="deleteObject"
@close="emit('close')" @close="emit('close')"
:is-update="isUpdate()" :is-update="isUpdate()"
:is-changed="editingObjChanged"
:model-class="modelClass" :model-class="modelClass"
:object-name="editingObjName()"> :object-name="editingObjName()">
<v-card-text> <v-card-text>
@@ -39,7 +40,7 @@ const props = defineProps({
}) })
const emit = defineEmits(['create', 'save', 'delete', 'close']) const emit = defineEmits(['create', 'save', 'delete', 'close'])
const {setupState, deleteObject, saveObject, isUpdate, editingObjName, loading, editingObj, modelClass} = useModelEditorFunctions<InviteLink>('InviteLink', emit) const {setupState, deleteObject, saveObject, isUpdate, editingObjName, loading, editingObj, editingObjChanged, modelClass} = useModelEditorFunctions<InviteLink>('InviteLink', emit)
// object specific data (for selects/display) // object specific data (for selects/display)
const groups = ref([] as Group[]) const groups = ref([] as Group[])

View File

@@ -6,6 +6,7 @@
@delete="deleteObject" @delete="deleteObject"
@close="emit('close')" @close="emit('close')"
:is-update="isUpdate()" :is-update="isUpdate()"
:is-changed="editingObjChanged"
:model-class="modelClass" :model-class="modelClass"
:object-name="editingObjName()"> :object-name="editingObjName()">
<v-card-text> <v-card-text>
@@ -38,7 +39,7 @@ const props = defineProps({
}) })
const emit = defineEmits(['create', 'save', 'delete', 'close']) const emit = defineEmits(['create', 'save', 'delete', 'close'])
const {setupState, deleteObject, saveObject, isUpdate, editingObjName, loading, editingObj, modelClass} = useModelEditorFunctions<Keyword>('Keyword', emit) const {setupState, deleteObject, saveObject, isUpdate, editingObjName, loading, editingObj, editingObjChanged, modelClass} = useModelEditorFunctions<Keyword>('Keyword', emit)
// object specific data (for selects/display) // object specific data (for selects/display)

View File

@@ -6,6 +6,7 @@
@delete="deleteObject" @delete="deleteObject"
@close="emit('close')" @close="emit('close')"
:is-update="isUpdate()" :is-update="isUpdate()"
:is-changed="editingObjChanged"
:model-class="modelClass" :model-class="modelClass"
:object-name="editingObjName()"> :object-name="editingObjName()">
@@ -120,7 +121,7 @@ const props = defineProps({
}) })
const emit = defineEmits(['create', 'save', 'delete', 'close']) const emit = defineEmits(['create', 'save', 'delete', 'close'])
const {setupState, deleteObject, saveObject, isUpdate, editingObjName, applyItemDefaults, loading, editingObj, modelClass} = useModelEditorFunctions<MealPlan>('MealPlan', emit) const {setupState, deleteObject, saveObject, isUpdate, editingObjName, applyItemDefaults, loading, editingObj, editingObjChanged, modelClass} = useModelEditorFunctions<MealPlan>('MealPlan', emit)
// object specific data (for selects/display) // object specific data (for selects/display)
const tab = ref('plan') const tab = ref('plan')

View File

@@ -6,6 +6,7 @@
@delete="deleteObject" @delete="deleteObject"
@close="emit('close')" @close="emit('close')"
:is-update="isUpdate()" :is-update="isUpdate()"
:is-changed="editingObjChanged"
:model-class="modelClass" :model-class="modelClass"
:object-name="editingObjName()"> :object-name="editingObjName()">
<v-card-text> <v-card-text>
@@ -55,7 +56,7 @@ const props = defineProps({
}) })
const emit = defineEmits(['create', 'save', 'delete', 'close']) const emit = defineEmits(['create', 'save', 'delete', 'close'])
const {setupState, deleteObject, saveObject, isUpdate, editingObjName, loading, editingObj, modelClass} = useModelEditorFunctions<MealType>('MealType', emit) const {setupState, deleteObject, saveObject, isUpdate, editingObjName, loading, editingObj, editingObjChanged, modelClass} = useModelEditorFunctions<MealType>('MealType', emit)
// object specific data (for selects/display) // object specific data (for selects/display)
const timePickerMenu = ref(false) const timePickerMenu = ref(false)

View File

@@ -1,13 +1,19 @@
<template> <template>
<v-card :loading="loading"> <v-card :loading="loading">
<v-closable-card-title :title="$t(modelClass.model.localizationKey)" :sub-title="objectName" :icon="modelClass.model.icon" @close="emit('close');" :hide-close="!dialog"></v-closable-card-title> <v-closable-card-title
:title="$t(modelClass.model.localizationKey) + ((isChanged) ? '*' : '')"
:sub-title="objectName"
:icon="modelClass.model.icon"
@close="emit('close');"
:hide-close="!dialog"
></v-closable-card-title>
<v-divider></v-divider> <v-divider></v-divider>
<slot name="default"> <slot name="default">
</slot> </slot>
<v-divider></v-divider> <v-divider></v-divider>
<v-card-actions > <v-card-actions>
<v-btn color="delete" prepend-icon="$delete" v-if="isUpdate && !modelClass.model.disableDelete" :disabled="loading">{{ $t('Delete') }} <v-btn color="delete" prepend-icon="$delete" v-if="isUpdate && !modelClass.model.disableDelete" :disabled="loading">{{ $t('Delete') }}
<delete-confirm-dialog :object-name="objectName" :model-name="$t(modelClass.model.localizationKey)" @delete="emit('delete')"></delete-confirm-dialog> <delete-confirm-dialog :object-name="objectName" :model-name="$t(modelClass.model.localizationKey)" @delete="emit('delete')"></delete-confirm-dialog>
</v-btn> </v-btn>
@@ -15,6 +21,20 @@
<v-btn color="save" prepend-icon="$save" @click="emit('save')" v-if="isUpdate && !modelClass.model.disableUpdate" :disabled="loading">{{ $t('Save') }}</v-btn> <v-btn color="save" prepend-icon="$save" @click="emit('save')" v-if="isUpdate && !modelClass.model.disableUpdate" :disabled="loading">{{ $t('Save') }}</v-btn>
</v-card-actions> </v-card-actions>
</v-card> </v-card>
<v-dialog width="600px" v-model="leaveConfirmDialog">
<v-card>
<v-closable-card-title v-model="leaveConfirmDialog" :title="$t('Confirm')"></v-closable-card-title>
<v-card-text>
{{$t('WarnPageLeave')}}
</v-card-text>
<v-card-actions>
<v-btn @click="leaveConfirmDialog = false; leaveGoTo = null">{{ $t('Cancel') }}</v-btn>
<v-btn :to="leaveGoTo" color="warning">{{ $t('Confirm') }}</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@@ -22,6 +42,8 @@
import DeleteConfirmDialog from "@/components/dialogs/DeleteConfirmDialog.vue"; import DeleteConfirmDialog from "@/components/dialogs/DeleteConfirmDialog.vue";
import {GenericModel} from "@/types/Models"; import {GenericModel} from "@/types/Models";
import VClosableCardTitle from "@/components/dialogs/VClosableCardTitle.vue"; import VClosableCardTitle from "@/components/dialogs/VClosableCardTitle.vue";
import {onBeforeRouteLeave, RouteLocationNormalized} from "vue-router";
import {ref} from "vue";
const emit = defineEmits(['save', 'delete', 'close']) const emit = defineEmits(['save', 'delete', 'close'])
@@ -30,7 +52,20 @@ const props = defineProps({
dialog: {type: Boolean, default: false}, dialog: {type: Boolean, default: false},
objectName: {type: String, default: ''}, objectName: {type: String, default: ''},
modelClass: {type: GenericModel, default: null}, modelClass: {type: GenericModel, default: null},
isUpdate: {type: Boolean, default: false} isUpdate: {type: Boolean, default: false},
isChanged: {type: Boolean, default: false},
})
const leaveConfirmDialog = ref(false)
const leaveGoTo = ref<RouteLocationNormalized | null>(null)
onBeforeRouteLeave((to, from) => {
if (props.isChanged && !leaveConfirmDialog.value) {
leaveConfirmDialog.value = true
leaveGoTo.value = to
return false
}
return true
}) })
</script> </script>

View File

@@ -6,6 +6,7 @@
@delete="deleteObject" @delete="deleteObject"
@close="emit('close')" @close="emit('close')"
:is-update="isUpdate()" :is-update="isUpdate()"
:is-changed="editingObjChanged"
:model-class="modelClass" :model-class="modelClass"
:object-name="editingObjName()"> :object-name="editingObjName()">
<v-card-text> <v-card-text>
@@ -41,7 +42,7 @@ const props = defineProps({
}) })
const emit = defineEmits(['create', 'save', 'delete', 'close']) const emit = defineEmits(['create', 'save', 'delete', 'close'])
const {setupState, deleteObject, saveObject, isUpdate, editingObjName, loading, editingObj, modelClass} = useModelEditorFunctions<Property>('Property', emit) const {setupState, deleteObject, saveObject, isUpdate, editingObjName, loading, editingObj, editingObjChanged, modelClass} = useModelEditorFunctions<Property>('Property', emit)
onMounted(() => { onMounted(() => {

View File

@@ -6,6 +6,7 @@
@delete="deleteObject" @delete="deleteObject"
@close="emit('close')" @close="emit('close')"
:is-update="isUpdate()" :is-update="isUpdate()"
:is-changed="editingObjChanged"
:model-class="modelClass" :model-class="modelClass"
:object-name="editingObjName()"> :object-name="editingObjName()">
<v-card-text> <v-card-text>
@@ -39,7 +40,7 @@ const props = defineProps({
}) })
const emit = defineEmits(['create', 'save', 'delete', 'close']) const emit = defineEmits(['create', 'save', 'delete', 'close'])
const {setupState, deleteObject, saveObject, isUpdate, editingObjName, loading, editingObj, modelClass} = useModelEditorFunctions<PropertyType>('PropertyType', emit) const {setupState, deleteObject, saveObject, isUpdate, editingObjName, loading, editingObj, editingObjChanged, modelClass} = useModelEditorFunctions<PropertyType>('PropertyType', emit)
// object specific data (for selects/display) // object specific data (for selects/display)

View File

@@ -6,6 +6,7 @@
@delete="deleteObject" @delete="deleteObject"
@close="emit('close')" @close="emit('close')"
:is-update="isUpdate()" :is-update="isUpdate()"
:is-changed="editingObjChanged"
:model-class="modelClass" :model-class="modelClass"
:object-name="editingObjName()"> :object-name="editingObjName()">
@@ -145,7 +146,7 @@ const props = defineProps({
}) })
const emit = defineEmits(['create', 'save', 'delete', 'close']) const emit = defineEmits(['create', 'save', 'delete', 'close'])
const {setupState, deleteObject, saveObject, isUpdate, editingObjName, loading, editingObj, modelClass} = useModelEditorFunctions<Recipe>('Recipe', emit) const {setupState, deleteObject, saveObject, isUpdate, editingObjName, loading, editingObj, editingObjChanged, modelClass} = useModelEditorFunctions<Recipe>('Recipe', emit)
// object specific data (for selects/display) // object specific data (for selects/display)
const tab = ref("recipe") const tab = ref("recipe")

View File

@@ -6,6 +6,7 @@
@delete="deleteObject" @delete="deleteObject"
@close="emit('close')" @close="emit('close')"
:is-update="isUpdate()" :is-update="isUpdate()"
:is-changed="editingObjChanged"
:model-class="modelClass" :model-class="modelClass"
:object-name="editingObjName()"> :object-name="editingObjName()">
<v-card-text> <v-card-text>
@@ -47,7 +48,7 @@ const props = defineProps({
}) })
const emit = defineEmits(['create', 'save', 'delete', 'close']) const emit = defineEmits(['create', 'save', 'delete', 'close'])
const {setupState, deleteObject, saveObject, isUpdate, editingObjName, loading, editingObj, modelClass} = useModelEditorFunctions<ShoppingListEntry>('ShoppingListEntry', emit) const {setupState, deleteObject, saveObject, isUpdate, editingObjName, loading, editingObj, editingObjChanged, modelClass} = useModelEditorFunctions<ShoppingListEntry>('ShoppingListEntry', emit)
// object specific data (for selects/display) // object specific data (for selects/display)

View File

@@ -6,6 +6,7 @@
@delete="deleteObject" @delete="deleteObject"
@close="emit('close')" @close="emit('close')"
:is-update="isUpdate()" :is-update="isUpdate()"
:is-changed="editingObjChanged"
:model-class="modelClass" :model-class="modelClass"
:object-name="editingObjName()"> :object-name="editingObjName()">
<v-card-text> <v-card-text>
@@ -37,7 +38,7 @@ const props = defineProps({
}) })
const emit = defineEmits(['create', 'save', 'delete', 'close']) const emit = defineEmits(['create', 'save', 'delete', 'close'])
const {setupState, deleteObject, saveObject, isUpdate, editingObjName, loading, editingObj, modelClass} = useModelEditorFunctions<SupermarketCategory>('SupermarketCategory', emit) const {setupState, deleteObject, saveObject, isUpdate, editingObjName, loading, editingObj, editingObjChanged, modelClass} = useModelEditorFunctions<SupermarketCategory>('SupermarketCategory', emit)
// object specific data (for selects/display) // object specific data (for selects/display)

View File

@@ -6,6 +6,7 @@
@delete="deleteObject" @delete="deleteObject"
@close="emit('close')" @close="emit('close')"
:is-update="isUpdate()" :is-update="isUpdate()"
:is-changed="editingObjChanged"
:model-class="modelClass" :model-class="modelClass"
:object-name="editingObjName()"> :object-name="editingObjName()">
@@ -115,7 +116,7 @@ const props = defineProps({
}) })
const emit = defineEmits(['create', 'save', 'delete', 'close']) const emit = defineEmits(['create', 'save', 'delete', 'close'])
const {setupState, deleteObject, saveObject, isUpdate, editingObjName, loading, editingObj, modelClass} = useModelEditorFunctions<Supermarket>('Supermarket', emit) const {setupState, deleteObject, saveObject, isUpdate, editingObjName, loading, editingObj, editingObjChanged, modelClass} = useModelEditorFunctions<Supermarket>('Supermarket', emit)
// object specific data (for selects/display) // object specific data (for selects/display)
const tab = ref("supermarket") const tab = ref("supermarket")

View File

@@ -6,6 +6,7 @@
@delete="deleteObject" @delete="deleteObject"
@close="emit('close')" @close="emit('close')"
:is-update="isUpdate()" :is-update="isUpdate()"
:is-changed="editingObjChanged"
:model-class="modelClass" :model-class="modelClass"
:object-name="editingObjName()"> :object-name="editingObjName()">
<v-card-text> <v-card-text>
@@ -61,7 +62,7 @@ const props = defineProps({
}) })
const emit = defineEmits(['create', 'save', 'delete', 'close']) const emit = defineEmits(['create', 'save', 'delete', 'close'])
const {setupState, deleteObject, saveObject, isUpdate, editingObjName, loading, editingObj, modelClass} = useModelEditorFunctions<UnitConversion>('UnitConversion', emit) const {setupState, deleteObject, saveObject, isUpdate, editingObjName, loading, editingObj, editingObjChanged, modelClass} = useModelEditorFunctions<UnitConversion>('UnitConversion', emit)
onMounted(() => { onMounted(() => {

View File

@@ -6,17 +6,16 @@
@delete="deleteObject" @delete="deleteObject"
@close="emit('close')" @close="emit('close')"
:is-update="isUpdate()" :is-update="isUpdate()"
:is-changed="editingObjChanged"
:model-class="modelClass" :model-class="modelClass"
:object-name="editingObjName()"> :object-name="editingObjName()">
<v-card-text> <v-card-text>
<v-form :disabled="loading"> <v-form :disabled="loading">
<v-text-field :label="$t('Name')" v-model="editingObj.name"></v-text-field> <v-text-field :label="$t('Name')" v-model="editingObj.name"></v-text-field>
<v-text-field :label="$t('Plural')" v-model="editingObj.pluralName"></v-text-field> <v-text-field :label="$t('Plural')" v-model="editingObj.pluralName"></v-text-field>
<v-textarea :label="$t('Description')" v-model="editingObj.description"></v-textarea> <v-textarea :label="$t('Description')" v-model="editingObj.description"></v-textarea>
<v-select :label="$t('BaseUnit')" :hint="$t('BaseUnitHelp')" :items="BASE_UNITS" v-model="editingObj.baseUnit"></v-select> <v-select :label="$t('BaseUnit')" :hint="$t('BaseUnitHelp')" :items="BASE_UNITS" v-model="editingObj.baseUnit"></v-select>
<v-text-field :label="$t('Open_Data_Slug')" :hint="$t('open_data_help_text')" persistent-hint v-model="editingObj.openDataSlug" disabled></v-text-field> <v-text-field :label="$t('Open_Data_Slug')" :hint="$t('open_data_help_text')" persistent-hint v-model="editingObj.openDataSlug" disabled></v-text-field>
</v-form> </v-form>
</v-card-text> </v-card-text>
</model-editor-base> </model-editor-base>
@@ -40,7 +39,7 @@ const props = defineProps({
}) })
const emit = defineEmits(['create', 'save', 'delete', 'close']) const emit = defineEmits(['create', 'save', 'delete', 'close'])
const {setupState, deleteObject, saveObject, isUpdate, editingObjName, loading, editingObj, modelClass} = useModelEditorFunctions<Unit>('Unit', emit) const {setupState, deleteObject, saveObject, isUpdate, editingObjName, loading, editingObj, editingObjChanged, modelClass} = useModelEditorFunctions<Unit>('Unit', emit)
// object specific data (for selects/display) // object specific data (for selects/display)

View File

@@ -6,6 +6,7 @@
@delete="deleteObject" @delete="deleteObject"
@close="emit('close')" @close="emit('close')"
:is-update="isUpdate()" :is-update="isUpdate()"
:is-changed="editingObjChanged"
:model-class="modelClass" :model-class="modelClass"
:object-name="editingObjName()"> :object-name="editingObjName()">
<v-card-text> <v-card-text>
@@ -62,7 +63,7 @@ const props = defineProps({
}) })
const emit = defineEmits(['create', 'save', 'delete', 'close']) const emit = defineEmits(['create', 'save', 'delete', 'close'])
const {setupState, deleteObject, saveObject, isUpdate, editingObjName, loading, editingObj, modelClass} = useModelEditorFunctions<UserFile>('UserFile', emit) const {setupState, deleteObject, saveObject, isUpdate, editingObjName, loading, editingObj, editingObjChanged, modelClass} = useModelEditorFunctions<UserFile>('UserFile', emit)
// object specific data (for selects/display) // object specific data (for selects/display)

View File

@@ -6,6 +6,7 @@
@delete="deleteObject" @delete="deleteObject"
@close="emit('close')" @close="emit('close')"
:is-update="isUpdate()" :is-update="isUpdate()"
:is-changed="editingObjChanged"
:model-class="modelClass" :model-class="modelClass"
:object-name="editingObjName()"> :object-name="editingObjName()">
<v-card-text> <v-card-text>
@@ -35,7 +36,7 @@ const props = defineProps({
}) })
const emit = defineEmits(['create', 'save', 'delete', 'close']) const emit = defineEmits(['create', 'save', 'delete', 'close'])
const {setupState, deleteObject, saveObject, isUpdate, editingObjName, loading, editingObj, modelClass} = useModelEditorFunctions<UserSpace>('UserSpace', emit) const {setupState, deleteObject, saveObject, isUpdate, editingObjName, loading, editingObj, editingObjChanged, modelClass} = useModelEditorFunctions<UserSpace>('UserSpace', emit)
// object specific data (for selects/display) // object specific data (for selects/display)
const groups = ref([] as Group[]) const groups = ref([] as Group[])

View File

@@ -1,5 +1,5 @@
import {ErrorMessageType, PreparedMessage, useMessageStore} from "@/stores/MessageStore"; import {ErrorMessageType, PreparedMessage, useMessageStore} from "@/stores/MessageStore";
import {onBeforeMount, ref} from "vue"; import {onBeforeMount, onMounted, ref, watch} from "vue";
import {EditorSupportedModels, GenericModel, getGenericModelFromString} from "@/types/Models"; import {EditorSupportedModels, GenericModel, getGenericModelFromString} from "@/types/Models";
import {useI18n} from "vue-i18n"; import {useI18n} from "vue-i18n";
import {ResponseError} from "@/openapi"; import {ResponseError} from "@/openapi";
@@ -15,8 +15,16 @@ export function useModelEditorFunctions<T>(modelName: EditorSupportedModels, emi
const editingObj = ref({} as T) const editingObj = ref({} as T)
const modelClass = ref({} as GenericModel) const modelClass = ref({} as GenericModel)
const editingObjChanged = ref(false)
const {t} = useI18n() const {t} = useI18n()
watch(() => editingObj.value, (newValue, oldValue) => {
if (Object.keys(oldValue).length > 0) {
editingObjChanged.value = true
}
}, {deep: true})
/** /**
* before mounting the component UI set the model class based on the given model name * before mounting the component UI set the model class based on the given model name
*/ */
@@ -24,6 +32,26 @@ export function useModelEditorFunctions<T>(modelName: EditorSupportedModels, emi
modelClass.value = getGenericModelFromString(modelName, t) modelClass.value = getGenericModelFromString(modelName, t)
}) })
onMounted(() => {
setupPageLeaveWarning()
})
/**
* add event listener to page unload event (also triggered by router) to prevent accidentally closing with unsaved changes
*/
function setupPageLeaveWarning() {
window.onbeforeunload = (event) => {
if (editingObjChanged.value) {
event.returnValue = "this_string_cant_be_empty_because_of_firefox"
return "this_string_cant_be_empty_because_of_firefox"
}
}
}
/**
* apply the defaults to the item given in the itemsDefaults value of the setupState function
* @param itemDefaults
*/
function applyItemDefaults(itemDefaults: T) { function applyItemDefaults(itemDefaults: T) {
if (Object.keys(itemDefaults).length > 0) { if (Object.keys(itemDefaults).length > 0) {
Object.keys(itemDefaults).forEach(k => { Object.keys(itemDefaults).forEach(k => {
@@ -156,6 +184,7 @@ export function useModelEditorFunctions<T>(modelName: EditorSupportedModels, emi
console.error(err) console.error(err)
useMessageStore().addError(ErrorMessageType.UPDATE_ERROR, err) useMessageStore().addError(ErrorMessageType.UPDATE_ERROR, err)
}).finally(() => { }).finally(() => {
editingObjChanged.value = false
loading.value = false loading.value = false
}) })
} else { } else {
@@ -168,6 +197,7 @@ export function useModelEditorFunctions<T>(modelName: EditorSupportedModels, emi
console.error(err) console.error(err)
useMessageStore().addError(ErrorMessageType.CREATE_ERROR, err) useMessageStore().addError(ErrorMessageType.CREATE_ERROR, err)
}).finally(() => { }).finally(() => {
editingObjChanged.value = false
loading.value = false loading.value = false
}) })
} }
@@ -177,13 +207,18 @@ export function useModelEditorFunctions<T>(modelName: EditorSupportedModels, emi
* deletes the editing object from the database * deletes the editing object from the database
*/ */
function deleteObject() { function deleteObject() {
loading.value = true
modelClass.value.destroy(editingObj.value.id).then((r: any) => { modelClass.value.destroy(editingObj.value.id).then((r: any) => {
emit('delete', editingObj.value) emit('delete', editingObj.value)
editingObj.value = {} as T editingObj.value = {} as T
}).catch((err: any) => { }).catch((err: any) => {
useMessageStore().addError(ErrorMessageType.DELETE_ERROR, err) useMessageStore().addError(ErrorMessageType.DELETE_ERROR, err)
}).finally(() => {
editingObjChanged.value = false
loading.value = false
}) })
} }
return {setupState, saveObject, deleteObject, isUpdate, editingObjName, applyItemDefaults, loading, editingObj, modelClass} return {setupState, saveObject, deleteObject, isUpdate, editingObjName, applyItemDefaults, loading, editingObj, editingObjChanged, modelClass}
} }

View File

@@ -44,6 +44,7 @@
"Color": "", "Color": "",
"Coming_Soon": "", "Coming_Soon": "",
"Completed": "", "Completed": "",
"Confirm": "",
"Continue": "", "Continue": "",
"ConversionsHelp": "", "ConversionsHelp": "",
"CookLog": "", "CookLog": "",
@@ -352,6 +353,7 @@
"View_Recipes": "", "View_Recipes": "",
"Waiting": "", "Waiting": "",
"WaitingTime": "", "WaitingTime": "",
"WarnPageLeave": "",
"Warning": "", "Warning": "",
"Warning_Delete_Supermarket_Category": "", "Warning_Delete_Supermarket_Category": "",
"Website": "", "Website": "",

View File

@@ -44,6 +44,7 @@
"Color": "Цвят", "Color": "Цвят",
"Coming_Soon": "Очаквайте скоро", "Coming_Soon": "Очаквайте скоро",
"Completed": "Завършено", "Completed": "Завършено",
"Confirm": "",
"Continue": "", "Continue": "",
"ConversionsHelp": "", "ConversionsHelp": "",
"CookLog": "", "CookLog": "",
@@ -343,6 +344,7 @@
"View_Recipes": "Вижте рецепти", "View_Recipes": "Вижте рецепти",
"Waiting": "Очакване", "Waiting": "Очакване",
"WaitingTime": "", "WaitingTime": "",
"WarnPageLeave": "",
"Warning": "Внимание", "Warning": "Внимание",
"Warning_Delete_Supermarket_Category": "Изтриването на категория супермаркет ще изтрие и всички връзки с храни. Сигурен ли си?", "Warning_Delete_Supermarket_Category": "Изтриването на категория супермаркет ще изтрие и всички връзки с храни. Сигурен ли си?",
"Website": "уебсайт", "Website": "уебсайт",

View File

@@ -56,6 +56,7 @@
"Coming_Soon": "", "Coming_Soon": "",
"Comments_setting": "", "Comments_setting": "",
"Completed": "", "Completed": "",
"Confirm": "",
"Continue": "", "Continue": "",
"Conversion": "", "Conversion": "",
"ConversionsHelp": "", "ConversionsHelp": "",
@@ -448,6 +449,7 @@
"View_Recipes": "Mostreu les receptes", "View_Recipes": "Mostreu les receptes",
"Waiting": "", "Waiting": "",
"WaitingTime": "", "WaitingTime": "",
"WarnPageLeave": "",
"Warning": "", "Warning": "",
"Warning_Delete_Supermarket_Category": "", "Warning_Delete_Supermarket_Category": "",
"Website": "", "Website": "",

View File

@@ -56,6 +56,7 @@
"Coming_Soon": "Již brzy", "Coming_Soon": "Již brzy",
"Comments_setting": "Zobrazit komentáře", "Comments_setting": "Zobrazit komentáře",
"Completed": "Dokončeno", "Completed": "Dokončeno",
"Confirm": "",
"Continue": "", "Continue": "",
"Conversion": "Převod", "Conversion": "Převod",
"ConversionsHelp": "", "ConversionsHelp": "",
@@ -441,6 +442,7 @@
"View_Recipes": "Zobrazit recepty", "View_Recipes": "Zobrazit recepty",
"Waiting": "Čekající", "Waiting": "Čekající",
"WaitingTime": "", "WaitingTime": "",
"WarnPageLeave": "",
"Warning": "Varování", "Warning": "Varování",
"Warning_Delete_Supermarket_Category": "Vymazáním kategorie obchodu dojde k odstranění všech vazeb na potraviny. Jste si jistí?", "Warning_Delete_Supermarket_Category": "Vymazáním kategorie obchodu dojde k odstranění všech vazeb na potraviny. Jste si jistí?",
"Website": "Web", "Website": "Web",

View File

@@ -55,6 +55,7 @@
"Coming_Soon": "Kommer snart", "Coming_Soon": "Kommer snart",
"Comments_setting": "Vis kommentarer", "Comments_setting": "Vis kommentarer",
"Completed": "Afsluttet", "Completed": "Afsluttet",
"Confirm": "",
"Continue": "", "Continue": "",
"Conversion": "Konversion", "Conversion": "Konversion",
"ConversionsHelp": "", "ConversionsHelp": "",
@@ -419,6 +420,7 @@
"View_Recipes": "Vis opskrifter", "View_Recipes": "Vis opskrifter",
"Waiting": "Vente", "Waiting": "Vente",
"WaitingTime": "", "WaitingTime": "",
"WarnPageLeave": "",
"Warning": "Advarsel", "Warning": "Advarsel",
"Warning_Delete_Supermarket_Category": "At slette en supermarkedskategori vil også slette alle relationer til mad. Er du sikker?", "Warning_Delete_Supermarket_Category": "At slette en supermarkedskategori vil også slette alle relationer til mad. Er du sikker?",
"Website": "Hjemmeside", "Website": "Hjemmeside",

View File

@@ -57,6 +57,7 @@
"Coming_Soon": "Bald verfügbar", "Coming_Soon": "Bald verfügbar",
"Comments_setting": "Kommentare anzeigen", "Comments_setting": "Kommentare anzeigen",
"Completed": "Fertig", "Completed": "Fertig",
"Confirm": "Bestätigen",
"Continue": "Weiter", "Continue": "Weiter",
"Conversion": "Umrechnung", "Conversion": "Umrechnung",
"ConversionsHelp": "Mit Umrechnungen kann die Menge einens Lebensmittels in verschiedenen Einheiten ausgerechnet werden. Aktuell wird dies nur zur berechnung von Eigenschaften verwendet, später jedoch sollen auch andere Funktionen von Tandoor davon profitieren.", "ConversionsHelp": "Mit Umrechnungen kann die Menge einens Lebensmittels in verschiedenen Einheiten ausgerechnet werden. Aktuell wird dies nur zur berechnung von Eigenschaften verwendet, später jedoch sollen auch andere Funktionen von Tandoor davon profitieren.",
@@ -451,6 +452,7 @@
"View_Recipes": "Rezepte Ansehen", "View_Recipes": "Rezepte Ansehen",
"Waiting": "Wartezeit", "Waiting": "Wartezeit",
"WaitingTime": "Wartezeit", "WaitingTime": "Wartezeit",
"WarnPageLeave": "Deine Änderungen wurden noch nicht gespeichert und gehen verloren. Seite wirklich verlassen?",
"Warning": "Warnung", "Warning": "Warnung",
"Warning_Delete_Supermarket_Category": "Die Löschung einer Supermarktkategorie werden auch alle Beziehungen zu Lebensmitteln gelöscht. Bist du dir sicher?", "Warning_Delete_Supermarket_Category": "Die Löschung einer Supermarktkategorie werden auch alle Beziehungen zu Lebensmitteln gelöscht. Bist du dir sicher?",
"Website": "Webseite", "Website": "Webseite",

View File

@@ -54,6 +54,7 @@
"Coming_Soon": "Σύντομα διαθέσιμο", "Coming_Soon": "Σύντομα διαθέσιμο",
"Comments_setting": "Εμφάνιση σχολίων", "Comments_setting": "Εμφάνιση σχολίων",
"Completed": "Ολοκληρωμένο", "Completed": "Ολοκληρωμένο",
"Confirm": "",
"Continue": "", "Continue": "",
"Conversion": "Μετατροπή", "Conversion": "Μετατροπή",
"ConversionsHelp": "", "ConversionsHelp": "",
@@ -408,6 +409,7 @@
"View_Recipes": "Προβολή συνταγών", "View_Recipes": "Προβολή συνταγών",
"Waiting": "Αναμονή", "Waiting": "Αναμονή",
"WaitingTime": "", "WaitingTime": "",
"WarnPageLeave": "",
"Warning": "Προειδοποίηση", "Warning": "Προειδοποίηση",
"Warning_Delete_Supermarket_Category": "Η διαγραφή μιας κατηγορίας supermarket θα διαγράψει και όλες τις σχέσεις της με φαγητά. Είστε σίγουροι;", "Warning_Delete_Supermarket_Category": "Η διαγραφή μιας κατηγορίας supermarket θα διαγράψει και όλες τις σχέσεις της με φαγητά. Είστε σίγουροι;",
"Website": "Ιστοσελίδα", "Website": "Ιστοσελίδα",

View File

@@ -56,6 +56,7 @@
"Coming_Soon": "Coming-Soon", "Coming_Soon": "Coming-Soon",
"Comments_setting": "Show Comments", "Comments_setting": "Show Comments",
"Completed": "Completed", "Completed": "Completed",
"Confirm": "Confirm",
"Continue": "Continue", "Continue": "Continue",
"Conversion": "Conversion", "Conversion": "Conversion",
"ConversionsHelp": "With conversions you can calculate the amount of a food in different units. Currently this is only used for property calculation, later it might also be used in other parts of tandoor. ", "ConversionsHelp": "With conversions you can calculate the amount of a food in different units. Currently this is only used for property calculation, later it might also be used in other parts of tandoor. ",
@@ -450,6 +451,7 @@
"View_Recipes": "View Recipes", "View_Recipes": "View Recipes",
"Waiting": "Waiting", "Waiting": "Waiting",
"WaitingTime": "Waiting Time", "WaitingTime": "Waiting Time",
"WarnPageLeave": "There are unsaved changes that will get lost. Leave page anyway?",
"Warning": "Warning", "Warning": "Warning",
"Warning_Delete_Supermarket_Category": "Deleting a supermarket category will also delete all relations to foods. Are you sure?", "Warning_Delete_Supermarket_Category": "Deleting a supermarket category will also delete all relations to foods. Are you sure?",
"Website": "Website", "Website": "Website",

View File

@@ -56,6 +56,7 @@
"Coming_Soon": "Próximamente", "Coming_Soon": "Próximamente",
"Comments_setting": "Mostrar Comentarios", "Comments_setting": "Mostrar Comentarios",
"Completed": "Completado", "Completed": "Completado",
"Confirm": "",
"Continue": "", "Continue": "",
"Conversion": "Conversión", "Conversion": "Conversión",
"ConversionsHelp": "", "ConversionsHelp": "",
@@ -447,6 +448,7 @@
"View_Recipes": "Mostrar recetas", "View_Recipes": "Mostrar recetas",
"Waiting": "esperando", "Waiting": "esperando",
"WaitingTime": "", "WaitingTime": "",
"WarnPageLeave": "",
"Warning": "Advertencia", "Warning": "Advertencia",
"Warning_Delete_Supermarket_Category": "Borrar una categoría de supermercado borrará también todas las relaciones con alimentos. ¿Está seguro?", "Warning_Delete_Supermarket_Category": "Borrar una categoría de supermercado borrará también todas las relaciones con alimentos. ¿Está seguro?",
"Website": "Sitio Web", "Website": "Sitio Web",

View File

@@ -30,6 +30,7 @@
"Close": "Sulje", "Close": "Sulje",
"Color": "Väri", "Color": "Väri",
"Coming_Soon": "Tulossa pian", "Coming_Soon": "Tulossa pian",
"Confirm": "",
"Continue": "", "Continue": "",
"ConversionsHelp": "", "ConversionsHelp": "",
"CookLog": "", "CookLog": "",
@@ -263,6 +264,7 @@
"View_Recipes": "Näytä Reseptit", "View_Recipes": "Näytä Reseptit",
"Waiting": "Odottaa", "Waiting": "Odottaa",
"WaitingTime": "", "WaitingTime": "",
"WarnPageLeave": "",
"Wednesday": "", "Wednesday": "",
"Week": "Viikko", "Week": "Viikko",
"Week_Numbers": "Viikkonumerot", "Week_Numbers": "Viikkonumerot",

View File

@@ -55,6 +55,7 @@
"Coming_Soon": "Bientôt disponible", "Coming_Soon": "Bientôt disponible",
"Comments_setting": "Montrer les commentaires", "Comments_setting": "Montrer les commentaires",
"Completed": "Achevé", "Completed": "Achevé",
"Confirm": "",
"Continue": "", "Continue": "",
"Conversion": "Conversion", "Conversion": "Conversion",
"ConversionsHelp": "", "ConversionsHelp": "",
@@ -447,6 +448,7 @@
"View_Recipes": "Voir les recettes", "View_Recipes": "Voir les recettes",
"Waiting": "Attente", "Waiting": "Attente",
"WaitingTime": "", "WaitingTime": "",
"WarnPageLeave": "",
"Warning": "Avertissement", "Warning": "Avertissement",
"Warning_Delete_Supermarket_Category": "Supprimer une catégorie de supermarché supprimera également toutes les relations avec les aliments. Êtes-vous sûr ?", "Warning_Delete_Supermarket_Category": "Supprimer une catégorie de supermarché supprimera également toutes les relations avec les aliments. Êtes-vous sûr ?",
"Website": "Site", "Website": "Site",

View File

@@ -56,6 +56,7 @@
"Coming_Soon": "בקרוב", "Coming_Soon": "בקרוב",
"Comments_setting": "הצג תגובות", "Comments_setting": "הצג תגובות",
"Completed": "הושלם", "Completed": "הושלם",
"Confirm": "",
"Continue": "", "Continue": "",
"Conversion": "עברית", "Conversion": "עברית",
"ConversionsHelp": "", "ConversionsHelp": "",
@@ -449,6 +450,7 @@
"View_Recipes": "הצג מתכונים", "View_Recipes": "הצג מתכונים",
"Waiting": "המתנה", "Waiting": "המתנה",
"WaitingTime": "", "WaitingTime": "",
"WarnPageLeave": "",
"Warning": "אזהרה", "Warning": "אזהרה",
"Warning_Delete_Supermarket_Category": "מחיקת קטגורית סופרמרקט תמחוק גם את המאכלים הקשורים. האם אתה בטוח ?", "Warning_Delete_Supermarket_Category": "מחיקת קטגורית סופרמרקט תמחוק גם את המאכלים הקשורים. האם אתה בטוח ?",
"Website": "אתר", "Website": "אתר",

View File

@@ -55,6 +55,7 @@
"Coming_Soon": "Hamarosan", "Coming_Soon": "Hamarosan",
"Comments_setting": "Hozzászólások megjelenítése", "Comments_setting": "Hozzászólások megjelenítése",
"Completed": "Kész", "Completed": "Kész",
"Confirm": "",
"Continue": "", "Continue": "",
"Conversion": "Konverzió", "Conversion": "Konverzió",
"ConversionsHelp": "", "ConversionsHelp": "",
@@ -410,6 +411,7 @@
"View_Recipes": "Receptek megjelenítése", "View_Recipes": "Receptek megjelenítése",
"Waiting": "Várakozás", "Waiting": "Várakozás",
"WaitingTime": "", "WaitingTime": "",
"WarnPageLeave": "",
"Warning": "Figyelmeztetés", "Warning": "Figyelmeztetés",
"Warning_Delete_Supermarket_Category": "Egy szupermarket-kategória törlése az alapanyagokkal való összes kapcsolatot is törli. Biztos vagy benne?", "Warning_Delete_Supermarket_Category": "Egy szupermarket-kategória törlése az alapanyagokkal való összes kapcsolatot is törli. Biztos vagy benne?",
"Website": "Weboldal", "Website": "Weboldal",

View File

@@ -22,6 +22,7 @@
"Categories": "", "Categories": "",
"Category": "", "Category": "",
"Close": "", "Close": "",
"Confirm": "",
"Continue": "", "Continue": "",
"ConversionsHelp": "", "ConversionsHelp": "",
"CookLog": "", "CookLog": "",
@@ -193,6 +194,7 @@
"View_Recipes": "Դիտել բաղադրատոմսերը", "View_Recipes": "Դիտել բաղադրատոմսերը",
"Waiting": "", "Waiting": "",
"WaitingTime": "", "WaitingTime": "",
"WarnPageLeave": "",
"Wednesday": "", "Wednesday": "",
"WorkingTime": "", "WorkingTime": "",
"YourSpaces": "", "YourSpaces": "",

View File

@@ -48,6 +48,7 @@
"Coming_Soon": "", "Coming_Soon": "",
"Comments_setting": "", "Comments_setting": "",
"Completed": "", "Completed": "",
"Confirm": "",
"Continue": "", "Continue": "",
"ConversionsHelp": "", "ConversionsHelp": "",
"CookLog": "", "CookLog": "",
@@ -377,6 +378,7 @@
"View_Recipes": "Lihat Resep", "View_Recipes": "Lihat Resep",
"Waiting": "Menunggu", "Waiting": "Menunggu",
"WaitingTime": "", "WaitingTime": "",
"WarnPageLeave": "",
"Warning": "", "Warning": "",
"Warning_Delete_Supermarket_Category": "", "Warning_Delete_Supermarket_Category": "",
"Website": "", "Website": "",

View File

@@ -56,6 +56,7 @@
"Coming_Soon": "", "Coming_Soon": "",
"Comments_setting": "", "Comments_setting": "",
"Completed": "", "Completed": "",
"Confirm": "",
"Continue": "", "Continue": "",
"Conversion": "", "Conversion": "",
"ConversionsHelp": "", "ConversionsHelp": "",
@@ -447,6 +448,7 @@
"View_Recipes": "", "View_Recipes": "",
"Waiting": "", "Waiting": "",
"WaitingTime": "", "WaitingTime": "",
"WarnPageLeave": "",
"Warning": "", "Warning": "",
"Warning_Delete_Supermarket_Category": "", "Warning_Delete_Supermarket_Category": "",
"Website": "", "Website": "",

View File

@@ -52,6 +52,7 @@
"Coming_Soon": "In-Arrivo", "Coming_Soon": "In-Arrivo",
"Comments_setting": "Mostra commenti", "Comments_setting": "Mostra commenti",
"Completed": "Completato", "Completed": "Completato",
"Confirm": "",
"Continue": "", "Continue": "",
"ConversionsHelp": "", "ConversionsHelp": "",
"CookLog": "", "CookLog": "",
@@ -392,6 +393,7 @@
"View_Recipes": "Mostra ricette", "View_Recipes": "Mostra ricette",
"Waiting": "Attesa", "Waiting": "Attesa",
"WaitingTime": "", "WaitingTime": "",
"WarnPageLeave": "",
"Warning": "Attenzione", "Warning": "Attenzione",
"Warning_Delete_Supermarket_Category": "L'eliminazione di una categoria di supermercato comporta anche l'eliminazione di tutte le relazioni con gli alimenti. Sei sicuro?", "Warning_Delete_Supermarket_Category": "L'eliminazione di una categoria di supermercato comporta anche l'eliminazione di tutte le relazioni con gli alimenti. Sei sicuro?",
"Website": "Sito web", "Website": "Sito web",

View File

@@ -55,6 +55,7 @@
"Coming_Soon": "", "Coming_Soon": "",
"Comments_setting": "", "Comments_setting": "",
"Completed": "", "Completed": "",
"Confirm": "",
"Continue": "", "Continue": "",
"Conversion": "", "Conversion": "",
"ConversionsHelp": "", "ConversionsHelp": "",
@@ -417,6 +418,7 @@
"View_Recipes": "Žiūrėti receptus", "View_Recipes": "Žiūrėti receptus",
"Waiting": "", "Waiting": "",
"WaitingTime": "", "WaitingTime": "",
"WarnPageLeave": "",
"Warning": "", "Warning": "",
"Warning_Delete_Supermarket_Category": "", "Warning_Delete_Supermarket_Category": "",
"Website": "", "Website": "",

View File

@@ -53,6 +53,7 @@
"Coming_Soon": "Kommer snart", "Coming_Soon": "Kommer snart",
"Comments_setting": "", "Comments_setting": "",
"Completed": "Fullført", "Completed": "Fullført",
"Confirm": "",
"Continue": "", "Continue": "",
"Conversion": "Omregn enhet", "Conversion": "Omregn enhet",
"ConversionsHelp": "", "ConversionsHelp": "",
@@ -406,6 +407,7 @@
"View_Recipes": "Vis oppskrifter", "View_Recipes": "Vis oppskrifter",
"Waiting": "Venter", "Waiting": "Venter",
"WaitingTime": "", "WaitingTime": "",
"WarnPageLeave": "",
"Warning": "Advarsel", "Warning": "Advarsel",
"Warning_Delete_Supermarket_Category": "", "Warning_Delete_Supermarket_Category": "",
"Website": "Nettside", "Website": "Nettside",

View File

@@ -56,6 +56,7 @@
"Coming_Soon": "Binnenkort beschikbaar", "Coming_Soon": "Binnenkort beschikbaar",
"Comments_setting": "Commentaar weergeven", "Comments_setting": "Commentaar weergeven",
"Completed": "Voltooid", "Completed": "Voltooid",
"Confirm": "",
"Continue": "", "Continue": "",
"Conversion": "Omrekening", "Conversion": "Omrekening",
"ConversionsHelp": "", "ConversionsHelp": "",
@@ -410,6 +411,7 @@
"View_Recipes": "Bekijk Recepten", "View_Recipes": "Bekijk Recepten",
"Waiting": "Wachten", "Waiting": "Wachten",
"WaitingTime": "", "WaitingTime": "",
"WarnPageLeave": "",
"Warning": "Waarschuwing", "Warning": "Waarschuwing",
"Warning_Delete_Supermarket_Category": "Een supermarktcategorie verwijderen verwijdert ook alle relaties naar ingrediënten. Weet je het zeker?", "Warning_Delete_Supermarket_Category": "Een supermarktcategorie verwijderen verwijdert ook alle relaties naar ingrediënten. Weet je het zeker?",
"Website": "Website", "Website": "Website",

View File

@@ -57,6 +57,7 @@
"Coming_Soon": "Dostępne wkrótce", "Coming_Soon": "Dostępne wkrótce",
"Comments_setting": "Pokaż komentarze", "Comments_setting": "Pokaż komentarze",
"Completed": "Zakończone", "Completed": "Zakończone",
"Confirm": "",
"Continue": "", "Continue": "",
"Conversion": "Konwersja", "Conversion": "Konwersja",
"ConversionsHelp": "", "ConversionsHelp": "",
@@ -450,6 +451,7 @@
"View_Recipes": "Przeglądaj przepisy", "View_Recipes": "Przeglądaj przepisy",
"Waiting": "Oczekiwanie", "Waiting": "Oczekiwanie",
"WaitingTime": "", "WaitingTime": "",
"WarnPageLeave": "",
"Warning": "Ostrzeżenie", "Warning": "Ostrzeżenie",
"Warning_Delete_Supermarket_Category": "Usunięcie kategorii supermarketu spowoduje również usunięcie wszystkich relacji z żywnością. Jesteś pewny?", "Warning_Delete_Supermarket_Category": "Usunięcie kategorii supermarketu spowoduje również usunięcie wszystkich relacji z żywnością. Jesteś pewny?",
"Website": "Strona internetowa", "Website": "Strona internetowa",

View File

@@ -43,6 +43,7 @@
"Color": "Cor", "Color": "Cor",
"Coming_Soon": "", "Coming_Soon": "",
"Completed": "Completo", "Completed": "Completo",
"Confirm": "",
"Continue": "", "Continue": "",
"ConversionsHelp": "", "ConversionsHelp": "",
"CookLog": "", "CookLog": "",
@@ -339,6 +340,7 @@
"View_Recipes": "Ver Receitas", "View_Recipes": "Ver Receitas",
"Waiting": "Em espera", "Waiting": "Em espera",
"WaitingTime": "", "WaitingTime": "",
"WarnPageLeave": "",
"Warning": "Aviso", "Warning": "Aviso",
"Wednesday": "", "Wednesday": "",
"Week": "Semana", "Week": "Semana",

View File

@@ -55,6 +55,7 @@
"Coming_Soon": "Em breve", "Coming_Soon": "Em breve",
"Comments_setting": "Mostrar Comentários", "Comments_setting": "Mostrar Comentários",
"Completed": "Finalizado", "Completed": "Finalizado",
"Confirm": "",
"Continue": "", "Continue": "",
"Conversion": "Conversão", "Conversion": "Conversão",
"ConversionsHelp": "", "ConversionsHelp": "",
@@ -426,6 +427,7 @@
"View_Recipes": "Ver Receitas", "View_Recipes": "Ver Receitas",
"Waiting": "Espera", "Waiting": "Espera",
"WaitingTime": "", "WaitingTime": "",
"WarnPageLeave": "",
"Warning": "Alerta", "Warning": "Alerta",
"Website": "Website", "Website": "Website",
"Wednesday": "", "Wednesday": "",

View File

@@ -53,6 +53,7 @@
"Coming_Soon": "În curând", "Coming_Soon": "În curând",
"Comments_setting": "Afișează comentarii", "Comments_setting": "Afișează comentarii",
"Completed": "Completat", "Completed": "Completat",
"Confirm": "",
"Continue": "", "Continue": "",
"ConversionsHelp": "", "ConversionsHelp": "",
"CookLog": "", "CookLog": "",
@@ -396,6 +397,7 @@
"View_Recipes": "Vizionare rețete", "View_Recipes": "Vizionare rețete",
"Waiting": "Așteptare", "Waiting": "Așteptare",
"WaitingTime": "", "WaitingTime": "",
"WarnPageLeave": "",
"Warning": "Atenționare", "Warning": "Atenționare",
"Warning_Delete_Supermarket_Category": "Ștergerea unei categorii de supermarketuri va șterge, de asemenea, toate relațiile cu alimentele. Sunteți sigur?", "Warning_Delete_Supermarket_Category": "Ștergerea unei categorii de supermarketuri va șterge, de asemenea, toate relațiile cu alimentele. Sunteți sigur?",
"Website": "Site web", "Website": "Site web",

View File

@@ -38,6 +38,7 @@
"Color": "Цвет", "Color": "Цвет",
"Coming_Soon": "Скоро", "Coming_Soon": "Скоро",
"Completed": "Завершено", "Completed": "Завершено",
"Confirm": "",
"Continue": "", "Continue": "",
"ConversionsHelp": "", "ConversionsHelp": "",
"CookLog": "", "CookLog": "",
@@ -314,6 +315,7 @@
"View_Recipes": "Просмотр рецепта", "View_Recipes": "Просмотр рецепта",
"Waiting": "Ожидание", "Waiting": "Ожидание",
"WaitingTime": "", "WaitingTime": "",
"WarnPageLeave": "",
"Warning": "Предупреждение", "Warning": "Предупреждение",
"Warning_Delete_Supermarket_Category": "Удаление категории супермаркета также приведет к удалению всех связей с продуктами. Вы уверены?", "Warning_Delete_Supermarket_Category": "Удаление категории супермаркета также приведет к удалению всех связей с продуктами. Вы уверены?",
"Wednesday": "", "Wednesday": "",

View File

@@ -39,6 +39,7 @@
"Color": "Barva", "Color": "Barva",
"Coming_Soon": "Kmalu", "Coming_Soon": "Kmalu",
"Completed": "Končano", "Completed": "Končano",
"Confirm": "",
"Continue": "", "Continue": "",
"ConversionsHelp": "", "ConversionsHelp": "",
"CookLog": "", "CookLog": "",
@@ -309,6 +310,7 @@
"View_Recipes": "Preglej recepte", "View_Recipes": "Preglej recepte",
"Waiting": "Čakanje", "Waiting": "Čakanje",
"WaitingTime": "", "WaitingTime": "",
"WarnPageLeave": "",
"Warning": "Opozorilo", "Warning": "Opozorilo",
"Wednesday": "", "Wednesday": "",
"Week": "Teden", "Week": "Teden",

View File

@@ -57,6 +57,7 @@
"Coming_Soon": "Kommer snart", "Coming_Soon": "Kommer snart",
"Comments_setting": "Visa Kommentarer", "Comments_setting": "Visa Kommentarer",
"Completed": "Avslutad", "Completed": "Avslutad",
"Confirm": "",
"Continue": "", "Continue": "",
"Conversion": "Omvandling", "Conversion": "Omvandling",
"ConversionsHelp": "", "ConversionsHelp": "",
@@ -450,6 +451,7 @@
"View_Recipes": "Visa recept", "View_Recipes": "Visa recept",
"Waiting": "Väntan", "Waiting": "Väntan",
"WaitingTime": "", "WaitingTime": "",
"WarnPageLeave": "",
"Warning": "Varning", "Warning": "Varning",
"Warning_Delete_Supermarket_Category": "Om du tar bort en mataffärskategori raderas också alla relationer till livsmedel. Är du säker?", "Warning_Delete_Supermarket_Category": "Om du tar bort en mataffärskategori raderas också alla relationer till livsmedel. Är du säker?",
"Website": "Hemsida", "Website": "Hemsida",

View File

@@ -56,6 +56,7 @@
"Coming_Soon": "Yakında Gelecek", "Coming_Soon": "Yakında Gelecek",
"Comments_setting": "Yorumları Göster", "Comments_setting": "Yorumları Göster",
"Completed": "Tamamlandı", "Completed": "Tamamlandı",
"Confirm": "",
"Continue": "", "Continue": "",
"Conversion": "Dönüşüm", "Conversion": "Dönüşüm",
"ConversionsHelp": "", "ConversionsHelp": "",
@@ -449,6 +450,7 @@
"View_Recipes": "Tarifleri Görüntüle", "View_Recipes": "Tarifleri Görüntüle",
"Waiting": "Bekleniyor", "Waiting": "Bekleniyor",
"WaitingTime": "", "WaitingTime": "",
"WarnPageLeave": "",
"Warning": "Uyarı", "Warning": "Uyarı",
"Warning_Delete_Supermarket_Category": "Bir market kategorisinin silinmesi, gıdalarla olan tüm ilişkileri de silecektir. Emin misiniz?", "Warning_Delete_Supermarket_Category": "Bir market kategorisinin silinmesi, gıdalarla olan tüm ilişkileri de silecektir. Emin misiniz?",
"Website": "Website", "Website": "Website",

View File

@@ -47,6 +47,7 @@
"Color": "Колір", "Color": "Колір",
"Coming_Soon": "", "Coming_Soon": "",
"Completed": "Виконано", "Completed": "Виконано",
"Confirm": "",
"Continue": "", "Continue": "",
"ConversionsHelp": "", "ConversionsHelp": "",
"CookLog": "", "CookLog": "",
@@ -361,6 +362,7 @@
"View_Recipes": "Подивитися Рецепт", "View_Recipes": "Подивитися Рецепт",
"Waiting": "Очікування", "Waiting": "Очікування",
"WaitingTime": "", "WaitingTime": "",
"WarnPageLeave": "",
"Warning": "Увага", "Warning": "Увага",
"Warning_Delete_Supermarket_Category": "", "Warning_Delete_Supermarket_Category": "",
"Website": "", "Website": "",

View File

@@ -55,6 +55,7 @@
"Coming_Soon": "即将到来", "Coming_Soon": "即将到来",
"Comments_setting": "显示评论", "Comments_setting": "显示评论",
"Completed": "完成", "Completed": "完成",
"Confirm": "",
"Continue": "", "Continue": "",
"Conversion": "转换", "Conversion": "转换",
"ConversionsHelp": "", "ConversionsHelp": "",
@@ -440,6 +441,7 @@
"View_Recipes": "查看食谱", "View_Recipes": "查看食谱",
"Waiting": "等待", "Waiting": "等待",
"WaitingTime": "", "WaitingTime": "",
"WarnPageLeave": "",
"Warning": "警告", "Warning": "警告",
"Warning_Delete_Supermarket_Category": "删除超市类别也会删除与食品的所有关系。 你确定吗?", "Warning_Delete_Supermarket_Category": "删除超市类别也会删除与食品的所有关系。 你确定吗?",
"Website": "网站", "Website": "网站",

View File

@@ -19,6 +19,7 @@
"Categories": "", "Categories": "",
"Category": "", "Category": "",
"Close": "", "Close": "",
"Confirm": "",
"Continue": "", "Continue": "",
"ConversionsHelp": "", "ConversionsHelp": "",
"CookLog": "", "CookLog": "",
@@ -162,6 +163,7 @@
"View_Recipes": "", "View_Recipes": "",
"Waiting": "", "Waiting": "",
"WaitingTime": "", "WaitingTime": "",
"WarnPageLeave": "",
"Wednesday": "", "Wednesday": "",
"WorkingTime": "", "WorkingTime": "",
"YourSpaces": "", "YourSpaces": "",

View File

@@ -21,7 +21,7 @@
import {useRouter} from "vue-router"; import {useRouter} from "vue-router";
import {EditorSupportedModels, getGenericModelFromString} from "@/types/Models"; import {EditorSupportedModels, getGenericModelFromString} from "@/types/Models";
import {defineAsyncComponent, PropType, shallowRef} from "vue"; import {defineAsyncComponent, onMounted, PropType, shallowRef} from "vue";
import {useI18n} from "vue-i18n"; import {useI18n} from "vue-i18n";
const {t} = useI18n() const {t} = useI18n()