diff --git a/vue3/src/components/model_editors/AccessTokenEditor.vue b/vue3/src/components/model_editors/AccessTokenEditor.vue index c9f1b40ae..98d63e711 100644 --- a/vue3/src/components/model_editors/AccessTokenEditor.vue +++ b/vue3/src/components/model_editors/AccessTokenEditor.vue @@ -49,11 +49,10 @@ const {setupState, deleteObject, saveObject, isUpdate, editingObjName, loading, onMounted(() => { - if (!setupState(props.item, props.itemId)) { - // functions to populate defaults + setupState(props.item, props.itemId, () => { editingObj.value.expires = DateTime.now().plus({year: 1}).toJSDate() editingObj.value.scope = 'read write' - } + }) }) diff --git a/vue3/src/components/model_editors/AutomationEditor.vue b/vue3/src/components/model_editors/AutomationEditor.vue index 260cc2141..9da1fd7fc 100644 --- a/vue3/src/components/model_editors/AutomationEditor.vue +++ b/vue3/src/components/model_editors/AutomationEditor.vue @@ -36,6 +36,7 @@ import ModelEditorBase from "@/components/model_editors/ModelEditorBase.vue"; import {useModelEditorFunctions} from "@/composables/useModelEditorFunctions"; import {useI18n} from "vue-i18n"; import {VNumberInput} from "vuetify/labs/VNumberInput"; +import {DateTime} from "luxon"; const {t} = useI18n() @@ -64,10 +65,9 @@ const AUTOMATION_TYPES = [ ] onMounted(() => { - if (!setupState(props.item, props.itemId)) { - // functions to populate defaults + setupState(props.item, props.itemId, () => { editingObj.value.order = 0 - } + }) }) diff --git a/vue3/src/components/model_editors/FoodEditor.vue b/vue3/src/components/model_editors/FoodEditor.vue index 7ed595fbc..d12b36c52 100644 --- a/vue3/src/components/model_editors/FoodEditor.vue +++ b/vue3/src/components/model_editors/FoodEditor.vue @@ -189,11 +189,10 @@ const stopConversionsWatcher = watch(tab, (value, oldValue, onCleanup) => { onMounted(() => { - if (!setupState(props.item, props.itemId)) { - // functions to populate defaults + setupState(props.item, props.itemId, () => { editingObj.value.propertiesFoodAmount = 100 editingObj.value.propertiesFoodUnit = {name: 'g'} as Unit // TODO properly fetch default unit - } + }) }) diff --git a/vue3/src/components/model_editors/InviteLinkEditor.vue b/vue3/src/components/model_editors/InviteLinkEditor.vue index 51c5b65af..80e9dd197 100644 --- a/vue3/src/components/model_editors/InviteLinkEditor.vue +++ b/vue3/src/components/model_editors/InviteLinkEditor.vue @@ -50,11 +50,11 @@ onMounted(() => { api.apiGroupList().then(r => { groups.value = r - if (!setupState(props.item, props.itemId)) { - // functions to populate defaults + setupState(props.item, props.itemId, () => { editingObj.value.validUntil = DateTime.now().plus({month: 1}).toJSDate() editingObj.value.group = groups.value[0] - } + }) + }).catch(err => { useMessageStore().addError(ErrorMessageType.FETCH_ERROR, err) }) diff --git a/vue3/src/components/model_editors/KeywordEditor.vue b/vue3/src/components/model_editors/KeywordEditor.vue index 159e5929e..3d80f0424 100644 --- a/vue3/src/components/model_editors/KeywordEditor.vue +++ b/vue3/src/components/model_editors/KeywordEditor.vue @@ -27,6 +27,7 @@ import {Keyword} from "@/openapi"; import ModelEditorBase from "@/components/model_editors/ModelEditorBase.vue"; import {useModelEditorFunctions} from "@/composables/useModelEditorFunctions"; import {useI18n} from "vue-i18n"; +import {DateTime} from "luxon"; const {t} = useI18n() @@ -42,10 +43,7 @@ const {setupState, deleteObject, saveObject, isUpdate, editingObjName, loading, // object specific data (for selects/display) onMounted(() => { - if (!setupState(props.item, props.itemId)) { - // functions to populate defaults - - } + setupState(props.item, props.itemId) }) diff --git a/vue3/src/components/model_editors/MealTypeEditor.vue b/vue3/src/components/model_editors/MealTypeEditor.vue index e2b8073d1..adc7ab72b 100644 --- a/vue3/src/components/model_editors/MealTypeEditor.vue +++ b/vue3/src/components/model_editors/MealTypeEditor.vue @@ -43,6 +43,7 @@ import {MealType} from "@/openapi"; import {VTimePicker} from 'vuetify/labs/VTimePicker'; // TODO remove once out of labs import ModelEditorBase from "@/components/model_editors/ModelEditorBase.vue"; import {useModelEditorFunctions} from "@/composables/useModelEditorFunctions"; +import {DateTime} from "luxon"; const props = defineProps({ @@ -59,9 +60,7 @@ const timePickerMenu = ref(false) onMounted(() => { - if (!setupState(props.item, props.itemId)) { - // functions to populate defaults - } + setupState(props.item, props.itemId) }) diff --git a/vue3/src/components/model_editors/PropertyEditor.vue b/vue3/src/components/model_editors/PropertyEditor.vue index 0e1fbc772..031a9af78 100644 --- a/vue3/src/components/model_editors/PropertyEditor.vue +++ b/vue3/src/components/model_editors/PropertyEditor.vue @@ -45,9 +45,7 @@ const {setupState, deleteObject, saveObject, isUpdate, editingObjName, loading, onMounted(() => { - if (!setupState(props.item, props.itemId)) { - // functions to populate defaults - } + setupState(props.item, props.itemId) }) diff --git a/vue3/src/components/model_editors/PropertyTypeEditor.vue b/vue3/src/components/model_editors/PropertyTypeEditor.vue index 0caa2e84d..11aefc05e 100644 --- a/vue3/src/components/model_editors/PropertyTypeEditor.vue +++ b/vue3/src/components/model_editors/PropertyTypeEditor.vue @@ -44,10 +44,7 @@ const {setupState, deleteObject, saveObject, isUpdate, editingObjName, loading, // object specific data (for selects/display) onMounted(() => { - if (!setupState(props.item, props.itemId)) { - // functions to populate defaults - - } + setupState(props.item, props.itemId) }) diff --git a/vue3/src/components/model_editors/SupermarketCategoryEditor.vue b/vue3/src/components/model_editors/SupermarketCategoryEditor.vue index 66f5fd03a..60b604062 100644 --- a/vue3/src/components/model_editors/SupermarketCategoryEditor.vue +++ b/vue3/src/components/model_editors/SupermarketCategoryEditor.vue @@ -42,10 +42,7 @@ const {setupState, deleteObject, saveObject, isUpdate, editingObjName, loading, // object specific data (for selects/display) onMounted(() => { - if (!setupState(props.item, props.itemId)) { - // functions to populate defaults - - } + setupState(props.item, props.itemId) }) diff --git a/vue3/src/components/model_editors/SupermarketEditor.vue b/vue3/src/components/model_editors/SupermarketEditor.vue index be789aa3d..05a8ad5da 100644 --- a/vue3/src/components/model_editors/SupermarketEditor.vue +++ b/vue3/src/components/model_editors/SupermarketEditor.vue @@ -119,16 +119,13 @@ const unusedSupermarketCategories = computed(() => { onMounted(() => { const api = new ApiApi() - if (!setupState(props.item, props.itemId)) { - // functions to populate defaults - } - api.apiSupermarketCategoryList({pageSize: 100}).then(r => { supermarketCategories.value = r.results - - //TODO fix performing this in a way that async setupState works - editingObj.value.categoryToSupermarket.forEach(cTS => { - editingObjSupermarketCategories.value.push(cTS.category) + + setupState(props.item, props.itemId, undefined, () => { + editingObj.value.categoryToSupermarket.forEach(cTS => { + editingObjSupermarketCategories.value.push(cTS.category) + }) }) }) }) diff --git a/vue3/src/components/model_editors/UnitConversionEditor.vue b/vue3/src/components/model_editors/UnitConversionEditor.vue index 03fbb8142..7cbe2c01a 100644 --- a/vue3/src/components/model_editors/UnitConversionEditor.vue +++ b/vue3/src/components/model_editors/UnitConversionEditor.vue @@ -65,9 +65,7 @@ const {setupState, deleteObject, saveObject, isUpdate, editingObjName, loading, onMounted(() => { - if (!setupState(props.item, props.itemId)) { - // functions to populate defaults - } + setupState(props.item, props.itemId) }) diff --git a/vue3/src/components/model_editors/UnitEditor.vue b/vue3/src/components/model_editors/UnitEditor.vue index 48198aeeb..0d4e0f767 100644 --- a/vue3/src/components/model_editors/UnitEditor.vue +++ b/vue3/src/components/model_editors/UnitEditor.vue @@ -67,10 +67,7 @@ const BASE_UNITS = [ ] onMounted(() => { - if (!setupState(props.item, props.itemId)) { - // functions to populate defaults - - } + setupState(props.item, props.itemId) }) diff --git a/vue3/src/components/model_editors/UserSpaceEditor.vue b/vue3/src/components/model_editors/UserSpaceEditor.vue index 283fb16fb..df11d0c79 100644 --- a/vue3/src/components/model_editors/UserSpaceEditor.vue +++ b/vue3/src/components/model_editors/UserSpaceEditor.vue @@ -48,9 +48,7 @@ onMounted(() => { useMessageStore().addError(ErrorMessageType.FETCH_ERROR, err) }) - if (!setupState(props.item, props.itemId)) { - // functions to populate defaults - } + setupState(props.item, props.itemId) }) diff --git a/vue3/src/composables/useModelEditorFunctions.ts b/vue3/src/composables/useModelEditorFunctions.ts index 476aa60b5..ee73075bf 100644 --- a/vue3/src/composables/useModelEditorFunctions.ts +++ b/vue3/src/composables/useModelEditorFunctions.ts @@ -8,7 +8,7 @@ import {useI18n} from "vue-i18n"; export function useModelEditorFunctions(modelName: string, emit: any) { - const loading = ref(false) + const loading = ref(true) const editingObj = ref({} as T) const modelClass = ref({} as GenericModel) @@ -22,34 +22,54 @@ export function useModelEditorFunctions(modelName: string, emit: any) { }) /** - * if given an object or id, sets up the editingObj with that item or loads the data from the API using the ID - * if both item and itemId are undefined return false to indicate that no editingObj has been initialized + * if given an item or itemId, sets up the editingObj with that item or loads the data from the API using the ID + * once finished loading updates the loading state to false, indicating finished initialization + * + * @throws Error if an error if neither item or itemId are given and create is disabled * @param item item object to set as editingObj * @param itemId id of object to be retrieved and set as editingObj + * @param newItemFunction optional function to execute if no object is given (by either item or itemId) + * @param existingItemFunction optional function to execute once the existing item was loaded (instantly with item, async with itemId) + * @return promise resolving to either the editingObj or undefined if errored */ - function setupState(item: T | null, itemId: number|string | undefined) { + function setupState(item: T | null, itemId: number | string | undefined, + newItemFunction: () => void = () => {}, + existingItemFunction: () => void = () => {}): Promise { if (item === null && itemId === undefined) { + // neither item nor itemId given => new item + if (modelClass.value.model.disableCreate) { throw Error('Trying to use a ModelEditor without an item and a model that does not allow object creation!') } - return false + + newItemFunction() + loading.value = false + return Promise.resolve(editingObj.value) } else if (item !== null) { + // item is given so return that editingObj.value = item + existingItemFunction() + loading.value = false + return Promise.resolve(editingObj.value) } else if (itemId !== undefined) { + // itemId is given => fetch from server and return item loading.value = true - if(typeof itemId == "string"){ + + // itemId might be a string (router parameter) or number (component prop) + if (typeof itemId == "string") { itemId = Number(itemId) } - modelClass.value.retrieve(itemId).then((r: T) => { + return modelClass.value.retrieve(itemId).then((r: T) => { editingObj.value = r + existingItemFunction() + return editingObj.value }).catch((err: any) => { useMessageStore().addError(ErrorMessageType.FETCH_ERROR, err) + return undefined }).finally(() => { loading.value = false }) } - - return true } /**