food edit modal done

This commit is contained in:
vabene1111
2023-05-11 17:13:35 +02:00
parent 6030fa1d68
commit 0539e1ea15
3 changed files with 211 additions and 170 deletions

View File

@ -1,141 +1,153 @@
<template> <template>
<div> <div>
<div class="row" v-if="food">
<div class="col-12">
<h2>{{ food.name }} <small class="text-muted" v-if="food.plural_name">{{ food.plural_name }}</small>
</h2>
</div>
</div>
<div class="row"> <b-modal :id="id" size="xl" @hidden="cancelAction">
<div class="col-12">
<b-form v-if="food">
<b-form-group :label="$t('Name')" description="">
<b-form-input v-model="food.name"></b-form-input>
</b-form-group>
<b-form-group :label="$t('Plural')" description="">
<b-form-input v-model="food.plural_name"></b-form-input>
</b-form-group>
<!-- Food properties --> <template v-slot:modal-title>
<div class="row" v-if="food">
<div class="col-12">
<h2>{{ food.name }} <small class="text-muted" v-if="food.plural_name">{{
food.plural_name
}}</small>
</h2>
</div>
</div>
</template>
<h5><i class="fas fa-database"></i> {{ $t('Properties') }} <small class="text-muted">{{ <div class="row">
food.name <div class="col-12">
}}</small></h5> <b-form v-if="food">
<table class="table table-bordered" v-if="food_properties"> <b-form-group :label="$t('Name')" description="">
<tr v-for="fp in food_properties" v-bind:key="fp.id"> <b-form-input v-model="food.name"></b-form-input>
<td><input v-model="fp.property_amount" type="number"> {{ fp.property_type.unit }}</td> </b-form-group>
<td><b> {{ fp.property_type.name }} </b></td> <b-form-group :label="$t('Plural')" description="">
<td> /</td> <b-form-input v-model="food.plural_name"></b-form-input>
<td><input v-model="fp.food_amount" type="number"></td> </b-form-group>
<td>
<!-- Food properties -->
<h5><i class="fas fa-database"></i> {{ $t('Properties') }}</h5>
<table class="table table-bordered" v-if="food_properties">
<tr v-for="fp in food_properties" v-bind:key="fp.id">
<td><input v-model="fp.property_amount" type="number"> {{ fp.property_type.unit }}</td>
<td><b> {{ fp.property_type.name }} </b></td>
<td> /</td>
<td><input v-model="fp.food_amount" type="number"></td>
<td>
<generic-multiselect
@change="fp.food_unit = $event.val;"
:model="Models.UNIT"
:initial_single_selection="fp.food_unit"
label="name"
:multiple="false"
:placeholder="$t('Unit')"
></generic-multiselect>
</td>
</tr>
</table>
<!-- Unit conversion -->
<!-- ADVANCED FEATURES somehow hide this stuff -->
<b-collapse id="collapse-advanced">
<b-form-group :label="$t('Recipe')" :description="$t('food_recipe_help')">
<generic-multiselect <generic-multiselect
@change="fp.food_unit = $event.val;" @change="food.recipe = $event.val;"
:model="Models.UNIT" :model="Models.RECIPE"
:initial_single_selection="fp.food_unit" :initial_single_selection="food.recipe"
label="name" label="name"
:multiple="false" :multiple="false"
:placeholder="$t('Unit')" :placeholder="$t('Recipe')"
></generic-multiselect> ></generic-multiselect>
</td> </b-form-group>
</tr>
</table> <b-form-group :description="$t('OnHand_help')">
<b-form-checkbox v-model="food.food_onhand">{{ $t('OnHand') }}</b-form-checkbox>
</b-form-group>
<b-form-group :description="$t('ignore_shopping_help')">
<b-form-checkbox v-model="food.ignore_shopping">{{
$t('Ignore_Shopping')
}}
</b-form-checkbox>
</b-form-group>
<b-form-group :label="$t('Shopping_Category')" :description="$t('shopping_category_help')">
<generic-multiselect
@change="food.supermarket_category = $event.val;"
:model="Models.SHOPPING_CATEGORY"
:initial_single_selection="food.supermarket_category"
label="name"
:multiple="false"
:allow_create="true"
:placeholder="$t('Shopping_Category')"
></generic-multiselect>
</b-form-group>
<hr/>
<!-- todo add conditions if false disable dont hide -->
<b-form-group :label="$t('Substitutes')" :description="$t('substitute_help')">
<generic-multiselect
@change="food.substitute = $event.val;"
:model="Models.FOOD"
:initial_selection="food.substitute"
label="name"
:multiple="true"
:placeholder="$t('Substitutes')"
></generic-multiselect>
</b-form-group>
<b-form-group :description="$t('substitute_siblings_help')">
<b-form-checkbox v-model="food.substitute_siblings">{{
$t('substitute_siblings')
}}
</b-form-checkbox>
</b-form-group>
<b-form-group :label="$t('InheritFields')" :description="$t('InheritFields_help')">
<generic-multiselect
@change="food.inherit_fields = $event.val;"
:model="Models.FOOD_INHERIT_FIELDS"
:initial_selection="food.inherit_fields"
label="name"
:multiple="true"
:placeholder="$t('InheritFields')"
></generic-multiselect>
</b-form-group>
<b-form-group :label="$t('ChildInheritFields')"
:description="$t('ChildInheritFields_help')">
<generic-multiselect
@change="food.child_inherit_fields = $event.val;"
:model="Models.FOOD_INHERIT_FIELDS"
:initial_sselection="food.child_inherit_fields"
label="name"
:multiple="true"
:placeholder="$t('ChildInheritFields')"
></generic-multiselect>
</b-form-group>
<!-- TODO change to a button -->
<b-form-group :description="$t('reset_children_help')">
<b-form-checkbox v-model="food.reset_inherit">{{
$t('reset_children')
}}
</b-form-checkbox>
</b-form-group>
</b-collapse>
<!-- Unit conversion --> </b-form>
<b-button v-b-toggle.collapse-advanced class="m-1">{{$t('Advanced')}}</b-button>
<!-- ADVANCED FEATURES somehow hide this stuff -->
<b-collapse id="collapse-advanced">
<b-form-group :label="$t('Recipe')" :description="$t('food_recipe_help')">
<generic-multiselect
@change="food.recipe = $event.val;"
:model="Models.RECIPE"
:initial_selection="food.recipe"
label="name"
:multiple="false"
:placeholder="$t('Recipe')"
></generic-multiselect>
</b-form-group>
<b-form-group :description="$t('OnHand_help')">
<b-form-checkbox v-model="food.food_onhand">{{ $t('OnHand') }}</b-form-checkbox>
</b-form-group>
<b-form-group :description="$t('ignore_shopping_help')">
<b-form-checkbox v-model="food.ignore_shopping">{{
$t('Ignore_Shopping')
}}
</b-form-checkbox>
</b-form-group>
<b-form-group :label="$t('Shopping_Category')" :description="$t('shopping_category_help')">
<generic-multiselect
@change="food.supermarket_category = $event.val;"
:model="Models.SHOPPING_CATEGORY"
:initial_selection="food.supermarket_category"
label="name"
:multiple="false"
:allow_create="true"
:placeholder="$t('Shopping_Category')"
></generic-multiselect>
</b-form-group>
<hr/>
<!-- todo add conditions if false disable dont hide -->
<b-form-group :label="$t('Substitutes')" :description="$t('substitute_help')">
<generic-multiselect
@change="food.substitute = $event.val;"
:model="Models.FOOD"
:initial_selection="food.substitute"
label="name"
:multiple="false"
:placeholder="$t('Substitutes')"
></generic-multiselect>
</b-form-group>
<b-form-group :description="$t('substitute_siblings_help')">
<b-form-checkbox v-model="food.substitute_siblings">{{
$t('substitute_siblings')
}}
</b-form-checkbox>
</b-form-group>
<b-form-group :label="$t('InheritFields')" :description="$t('InheritFields_help')">
<generic-multiselect
@change="food.inherit_fields = $event.val;"
:model="Models.FOOD_INHERIT_FIELDS"
:initial_selection="food.inherit_fields"
label="name"
:multiple="false"
:placeholder="$t('InheritFields')"
></generic-multiselect>
</b-form-group>
<b-form-group :label="$t('ChildInheritFields')" :description="$t('ChildInheritFields_help')">
<generic-multiselect
@change="food.child_inherit_fields = $event.val;"
:model="Models.FOOD_INHERIT_FIELDS"
:initial_selection="food.child_inherit_fields"
label="name"
:multiple="false"
:placeholder="$t('ChildInheritFields')"
></generic-multiselect>
</b-form-group>
<!-- TODO change to a button -->
<b-form-group :description="$t('reset_children_help')">
<b-form-checkbox v-model="food.reset_inherit">{{ $t('reset_children') }}</b-form-checkbox>
</b-form-group>
</b-collapse>
<b-button variant="primary" @click="updateFood">{{ $t('Save') }}</b-button>
</b-form>
</div>
</div> </div>
</div> <template v-slot:modal-footer>
<b-button variant="primary" @click="updateFood">{{ $t('Save') }}</b-button>
<b-button v-b-toggle.collapse-advanced class="m-1">{{ $t('Advanced') }}</b-button>
</template>
</b-modal>
</div> </div>
</template> </template>
@ -147,7 +159,7 @@ import {BootstrapVue} from "bootstrap-vue"
import "bootstrap-vue/dist/bootstrap-vue.css" import "bootstrap-vue/dist/bootstrap-vue.css"
import {ApiApiFactory} from "@/utils/openapi/api"; import {ApiApiFactory} from "@/utils/openapi/api";
import GenericMultiselect from "@/components/GenericMultiselect.vue"; import GenericMultiselect from "@/components/GenericMultiselect.vue";
import {ApiMixin, StandardToasts} from "@/utils/utils"; import {ApiMixin, formFunctions, getForm, StandardToasts} from "@/utils/utils";
Vue.use(BootstrapVue) Vue.use(BootstrapVue)
@ -159,6 +171,22 @@ export default {
components: { components: {
GenericMultiselect GenericMultiselect
}, },
props: {
id: {type: String, default: 'id_food_edit_modal_modal'},
show: {required: true, type: Boolean, default: false},
},
watch: {
show: function () {
console.log('trigger')
if (this.show) {
console.log('show modal')
this.$bvModal.show(this.id)
} else {
console.log('show modal false')
this.$bvModal.hide(this.id)
}
},
},
data() { data() {
return { return {
food: undefined, food: undefined,
@ -166,6 +194,7 @@ export default {
} }
}, },
mounted() { mounted() {
this.$bvModal.show(this.id)
this.$i18n.locale = window.CUSTOM_LOCALE this.$i18n.locale = window.CUSTOM_LOCALE
let apiClient = new ApiApiFactory() let apiClient = new ApiApiFactory()
apiClient.retrieveFood('1').then((r) => { apiClient.retrieveFood('1').then((r) => {
@ -174,7 +203,7 @@ export default {
let property_types = [] let property_types = []
let property_values = [] let property_values = []
let p1 = apiClient.listFoodPropertyTypes().then((r) => { let p1 = apiClient.listPropertyTypes().then((r) => {
property_types = r.data property_types = r.data
}) })
@ -234,7 +263,10 @@ export default {
} }
}) })
} },
cancelAction: function () {
this.$emit("hidden", "")
},
}, },
} }
</script> </script>

View File

@ -2,23 +2,21 @@
<div> <div>
<div class="card p-2" v-if="recipe !== undefined"> <div class="card p-4 pb-2" v-if="recipe !== undefined">
<div class="flex-row"> <b-row>
<div class="flex-column"> <b-col>
<h5><i class="fas fa-database"></i> {{ $t('Properties') }}</h5> <h5><i class="fas fa-database"></i> {{ $t('Properties') }}</h5>
</div> </b-col>
<div class="flex-column align-content-end text-right align-text-bottom"> <b-col class="text-right">
<span v-if="!show_total">{{ $t('per_serving') }} </span>
<span v-if="!show_total">{{ $t('per_serving') }}</span> <span v-if="show_total">{{ $t('total') }} </span>
<span v-if="show_total">{{ $t('total') }}</span>
<a href="#" @click="show_total = !show_total"> <a href="#" @click="show_total = !show_total">
<i class="fas fa-toggle-on" v-if="!show_total"></i> <i class="fas fa-toggle-on" v-if="!show_total"></i>
<i class="fas fa-toggle-off" v-if="show_total"></i> <i class="fas fa-toggle-off" v-if="show_total"></i>
</a> </a>
</b-col>
</div> </b-row>
</div>
<table class="table table-bordered table-sm"> <table class="table table-bordered table-sm">

View File

@ -1,10 +1,7 @@
<template> <template>
<div> <div>
<template v-if="form_component !== undefined"> <template v-if="form_component !== undefined">
<b-modal :id="'modal_' + id" @hidden="cancelAction" size="xl"> <component :is="form_component" :id="'modal_' + id" :show="show" @hidden="cancelAction"></component>
<component :is="form_component"></component>
</b-modal>
</template> </template>
<template v-else> <template v-else>
<b-modal :id="'modal_' + id" @hidden="cancelAction" size="lg"> <b-modal :id="'modal_' + id" @hidden="cancelAction" size="lg">
@ -43,13 +40,13 @@
<script> <script>
import Vue from "vue" import Vue from "vue"
import { BootstrapVue } from "bootstrap-vue" import {BootstrapVue} from "bootstrap-vue"
import { getForm, formFunctions } from "@/utils/utils" import {getForm, formFunctions} from "@/utils/utils"
Vue.use(BootstrapVue) Vue.use(BootstrapVue)
import { ApiApiFactory } from "@/utils/openapi/api" import {ApiApiFactory} from "@/utils/openapi/api"
import { ApiMixin, StandardToasts, ToastMixin, getUserPreference } from "@/utils/utils" import {ApiMixin, StandardToasts, ToastMixin, getUserPreference} from "@/utils/utils"
import CheckboxInput from "@/components/Modals/CheckboxInput" import CheckboxInput from "@/components/Modals/CheckboxInput"
import LookupInput from "@/components/Modals/LookupInput" import LookupInput from "@/components/Modals/LookupInput"
import TextInput from "@/components/Modals/TextInput" import TextInput from "@/components/Modals/TextInput"
@ -63,10 +60,21 @@ import NumberInput from "@/components/Modals/NumberInput.vue";
export default { export default {
name: "GenericModalForm", name: "GenericModalForm",
components: { FileInput, CheckboxInput, LookupInput, TextInput, EmojiInput, ChoiceInput, SmallText, HelpBadge,DateInput, NumberInput }, components: {
FileInput,
CheckboxInput,
LookupInput,
TextInput,
EmojiInput,
ChoiceInput,
SmallText,
HelpBadge,
DateInput,
NumberInput
},
mixins: [ApiMixin, ToastMixin], mixins: [ApiMixin, ToastMixin],
props: { props: {
model: { required: true, type: Object }, model: {required: true, type: Object},
action: { action: {
type: Object, type: Object,
default() { default() {
@ -85,7 +93,7 @@ export default {
return {} return {}
}, },
}, },
show: { required: true, type: Boolean, default: false }, show: {required: true, type: Boolean, default: false},
}, },
data() { data() {
return { return {
@ -123,9 +131,9 @@ export default {
form_component() { form_component() {
// TODO this leads webpack to create one .js file for each component in this folder because at runtime any one of them could be requested // TODO this leads webpack to create one .js file for each component in this folder because at runtime any one of them could be requested
// TODO this is not necessarily bad but maybe there are better options to do this // TODO this is not necessarily bad but maybe there are better options to do this
if (this.form.component !== undefined){ if (this.form.component !== undefined) {
return () => import(/* webpackChunkName: "header-component" */ `@/components/${this.form.component}`) return () => import(/* webpackChunkName: "header-component" */ `@/components/${this.form.component}`)
}else{ } else {
return undefined return undefined
} }
}, },
@ -192,16 +200,16 @@ export default {
return form return form
}, },
delete: function () { delete: function () {
this.genericAPI(this.model, this.Actions.DELETE, { id: this.item1.id }) this.genericAPI(this.model, this.Actions.DELETE, {id: this.item1.id})
.then((result) => { .then((result) => {
this.$emit("finish-action") this.$emit("finish-action")
StandardToasts.makeStandardToast(this,StandardToasts.SUCCESS_DELETE) StandardToasts.makeStandardToast(this, StandardToasts.SUCCESS_DELETE)
}) })
.catch((err) => { .catch((err) => {
if (err.response.status === 403){ if (err.response.status === 403) {
StandardToasts.makeStandardToast(this,StandardToasts.FAIL_DELETE_PROTECTED, err) StandardToasts.makeStandardToast(this, StandardToasts.FAIL_DELETE_PROTECTED, err)
}else { } else {
StandardToasts.makeStandardToast(this,StandardToasts.FAIL_DELETE, err) StandardToasts.makeStandardToast(this, StandardToasts.FAIL_DELETE, err)
} }
this.$emit("finish-action", "cancel") this.$emit("finish-action", "cancel")
}) })
@ -211,22 +219,22 @@ export default {
// if there is no item id assume it's a new item // if there is no item id assume it's a new item
this.genericAPI(this.model, this.Actions.CREATE, this.form_data) this.genericAPI(this.model, this.Actions.CREATE, this.form_data)
.then((result) => { .then((result) => {
this.$emit("finish-action", { item: result.data }) this.$emit("finish-action", {item: result.data})
StandardToasts.makeStandardToast(this,StandardToasts.SUCCESS_CREATE) StandardToasts.makeStandardToast(this, StandardToasts.SUCCESS_CREATE)
}) })
.catch((err) => { .catch((err) => {
console.log(err) console.log(err)
StandardToasts.makeStandardToast(this,StandardToasts.FAIL_CREATE) StandardToasts.makeStandardToast(this, StandardToasts.FAIL_CREATE)
this.$emit("finish-action", "cancel") this.$emit("finish-action", "cancel")
}) })
} else { } else {
this.genericAPI(this.model, this.Actions.UPDATE, this.form_data) this.genericAPI(this.model, this.Actions.UPDATE, this.form_data)
.then((result) => { .then((result) => {
this.$emit("finish-action", { item: result.data }) this.$emit("finish-action", {item: result.data})
StandardToasts.makeStandardToast(this,StandardToasts.SUCCESS_UPDATE) StandardToasts.makeStandardToast(this, StandardToasts.SUCCESS_UPDATE)
}) })
.catch((err) => { .catch((err) => {
StandardToasts.makeStandardToast(this,StandardToasts.FAIL_UPDATE, err) StandardToasts.makeStandardToast(this, StandardToasts.FAIL_UPDATE, err)
this.$emit("finish-action", "cancel") this.$emit("finish-action", "cancel")
}) })
} }
@ -242,13 +250,13 @@ export default {
this.$emit("finish-action", "cancel") this.$emit("finish-action", "cancel")
return return
} }
this.genericAPI(this.model, this.Actions.MOVE, { source: this.item1.id, target: this.form_data.target.id }) this.genericAPI(this.model, this.Actions.MOVE, {source: this.item1.id, target: this.form_data.target.id})
.then((result) => { .then((result) => {
this.$emit("finish-action", { target: this.form_data.target.id }) this.$emit("finish-action", {target: this.form_data.target.id})
StandardToasts.makeStandardToast(this,StandardToasts.SUCCESS_MOVE) StandardToasts.makeStandardToast(this, StandardToasts.SUCCESS_MOVE)
}) })
.catch((err) => { .catch((err) => {
StandardToasts.makeStandardToast(this,StandardToasts.FAIL_MOVE, err) StandardToasts.makeStandardToast(this, StandardToasts.FAIL_MOVE, err)
this.$emit("finish-action", "cancel") this.$emit("finish-action", "cancel")
}) })
}, },
@ -268,11 +276,14 @@ export default {
target: this.form_data.target.id, target: this.form_data.target.id,
}) })
.then((result) => { .then((result) => {
this.$emit("finish-action", { target: this.form_data.target.id, target_object: this.form_data.target }) //TODO temporary workaround to not change other apis this.$emit("finish-action", {
StandardToasts.makeStandardToast(this,StandardToasts.SUCCESS_MERGE) target: this.form_data.target.id,
target_object: this.form_data.target
}) //TODO temporary workaround to not change other apis
StandardToasts.makeStandardToast(this, StandardToasts.SUCCESS_MERGE)
}) })
.catch((err) => { .catch((err) => {
StandardToasts.makeStandardToast(this,StandardToasts.FAIL_MERGE, err) StandardToasts.makeStandardToast(this, StandardToasts.FAIL_MERGE, err)
this.$emit("finish-action", "cancel") this.$emit("finish-action", "cancel")
}) })