property editor

This commit is contained in:
vabene1111
2023-11-29 22:04:23 +01:00
parent 0a0e3a48c3
commit f6ed49b5c4
4 changed files with 70 additions and 26 deletions

View File

@ -8,30 +8,61 @@
<thead> <thead>
<tr> <tr>
<td>{{ $t('Name') }}</td> <td>{{ $t('Name') }}</td>
<td v-for="pt in property_types" v-bind:key="pt.id">{{ pt.name }} <td>FDC</td>
<input class="form-control form-control-sm" type="text" v-model="pt.unit" @change="updatePropertyType(pt)"> <td>{{ $t('Properties_Food_Amount') }}</td>
<input class="form-control form-control-sm" v-model="pt.fdc_id" type="number" placeholder="FDC ID" @change="updatePropertyType(pt)"></td> <td>{{ $t('Properties_Food_Unit') }}</td>
<td v-for="pt in properties" v-bind:key="pt.id">
<b-input-group>
<b-form-input v-model="pt.name" ></b-form-input> <!-- TODO handle manual input -->
<b-input-group-append>
<b-input-group-text>{{ pt.unit }}</b-input-group-text>
<b-button variant="primary" @click="editing_property_type = pt"><i class="fas fa-pencil-alt"></i></b-button>
</b-input-group-append>
</b-input-group>
</td>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr v-for="f in this.foods" v-bind:key="f.food.id"> <tr v-for="f in this.foods" v-bind:key="f.food.id">
<td> <td>
{{ f.food.name }} #{{ f.food.id }} {{ f.food.name }}
{{ $t('Property') }} / <input class="form-control form-control-sm" type="number" v-model="f.food.properties_food_amount" @change="updateFood(f.food)"> </td>
<td>
<b-input-group>
<b-form-input v-model="f.food.fdc_id" type="number" @change="updateFood(f.food)"></b-form-input>
<b-input-group-append>
<b-button variant="success" @click="updateFoodFromFDC(f.food)"><i class="fas fa-sync-alt"></i></b-button>
</b-input-group-append>
</b-input-group>
</td>
<td>
<b-input v-model="f.food.properties_food_amount" type="number" @change="updateFood(f.food)"></b-input>
</td>
<td>
<generic-multiselect <generic-multiselect
@change="f.food.properties_food_unit = $event.val; updateFood(f.food)" @change="f.food.properties_food_unit = $event.val; updateFood(f.food)"
:initial_selection="f.food.properties_food_unit" :initial_selection="f.food.properties_food_unit"
label="name" :model="Models.UNIT" label="name" :model="Models.UNIT"
:multiple="false"/> :multiple="false"/>
<input class="form-control form-control-sm" v-model="f.food.fdc_id" placeholder="FDC ID" @change="updateFood(f.food)">
<button @click="updateFoodFromFDC(f.food)">Load FDC</button>
</td> </td>
<td v-for="p in f.properties" v-bind:key="`${f.id}_${p.property_type.id}`"> <td v-for="p in f.properties" v-bind:key="`${f.id}_${p.property_type.id}`">
<input class="form-control form-control-sm" type="number" v-model="p.property_amount"> {{ p.property_type.unit }} ({{ p.property_type.name }}) <b-input-group>
<b-form-input v-model="p.property_amount" type="number"></b-form-input> <!-- TODO handle manual input -->
</b-input-group>
</td> </td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
<generic-modal-form
:show="editing_property_type !== null"
:model="Models.PROPERTY_TYPE"
:action="Actions.UPDATE"
:item1="editing_property_type"
@finish-action="editing_property_type = null; loadPropertyTypes()">
</generic-modal-form>
</div> </div>
</div> </div>
</template> </template>
@ -47,6 +78,7 @@ import axios from "axios";
import BetaWarning from "@/components/BetaWarning.vue"; import BetaWarning from "@/components/BetaWarning.vue";
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 GenericModalForm from "@/components/Modals/GenericModalForm.vue";
Vue.use(BootstrapVue) Vue.use(BootstrapVue)
@ -55,10 +87,10 @@ Vue.use(BootstrapVue)
export default { export default {
name: "TestView", name: "TestView",
mixins: [ApiMixin], mixins: [ApiMixin],
components: {GenericMultiselect}, components: {GenericModalForm, GenericMultiselect},
computed: { computed: {
foods: function () { foods: function () {
let foods = [] let foods = {}
if (this.recipe !== null && this.property_types !== []) { if (this.recipe !== null && this.property_types !== []) {
this.recipe.steps.forEach(s => { this.recipe.steps.forEach(s => {
s.ingredients.forEach(i => { s.ingredients.forEach(i => {
@ -70,49 +102,53 @@ export default {
i.food.properties.forEach(fp => { i.food.properties.forEach(fp => {
food.properties[fp.property_type.id] = {changed: false, property_amount: fp.property_amount, property_type: fp.property_type} food.properties[fp.property_type.id] = {changed: false, property_amount: fp.property_amount, property_type: fp.property_type}
}) })
foods.push(food) foods[food.food.id] = food
}) })
}) })
} }
return foods return foods
},
properties: function () {
let properties = {}
this.property_types.forEach(pt => {
properties[pt.id] = pt
})
return properties
} }
}, },
data() { data() {
return { return {
recipe: null, recipe: null,
property_types: [] property_types: [],
editing_property_type: null,
} }
}, },
mounted() { mounted() {
this.$i18n.locale = window.CUSTOM_LOCALE this.$i18n.locale = window.CUSTOM_LOCALE
this.loadData(); this.loadRecipe();
this.loadPropertyTypes();
}, },
methods: { methods: {
loadData: function () { loadRecipe: function () {
let apiClient = new ApiApiFactory() let apiClient = new ApiApiFactory()
apiClient.retrieveRecipe("112").then(result => { apiClient.retrieveRecipe("112").then(result => {
this.recipe = result.data this.recipe = result.data
}) })
apiClient.listPropertyTypes().then(result => {
this.property_types = result.data
})
}, },
updateFood: function (food) { updateFood: function (food) {
let apiClient = new ApiApiFactory() let apiClient = new ApiApiFactory()
apiClient.partialUpdateFood(food.id, food).then(result => { apiClient.partialUpdateFood(food.id, food).then(result => {
//TODO handle properly
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)
}) })
}, },
updatePropertyType: function (pt) { loadPropertyTypes: function () {
let apiClient = new ApiApiFactory() let apiClient = new ApiApiFactory()
apiClient.partialUpdatePropertyType(pt.id, pt).then(result => { apiClient.listPropertyTypes().then(result => {
//TODO handle properly this.property_types = 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)
@ -122,7 +158,7 @@ export default {
let apiClient = new ApiApiFactory() let apiClient = new ApiApiFactory()
apiClient.fdcFood(food.id).then(result => { apiClient.fdcFood(food.id).then(result => {
this.loadData() this.loadRecipe()
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)

View File

@ -33,11 +33,11 @@
<h5><i class="fas fa-database"></i> {{ $t('Properties') }}</h5> <h5><i class="fas fa-database"></i> {{ $t('Properties') }}</h5>
<b-form-group :label="$t('Properties Food Amount')" description=""> <!-- TODO localize --> <b-form-group :label="$t('Properties_Food_Amount')" description="">
<b-form-input v-model="food.properties_food_amount"></b-form-input> <b-form-input v-model="food.properties_food_amount"></b-form-input>
</b-form-group> </b-form-group>
<b-form-group :label="$t('Properties Food Unit')" description=""> <!-- TODO localize --> <b-form-group :label="$t('Properties_Food_Unit')" description="">
<generic-multiselect <generic-multiselect
@change="food.properties_food_unit = $event.val;" @change="food.properties_food_unit = $event.val;"
:model="Models.UNIT" :model="Models.UNIT"

View File

@ -81,6 +81,8 @@
"open_data_help_text": "The Tandoor Open Data project provides community contributed data for Tandoor. This field is filled automatically when importing it and allows updates in the future.", "open_data_help_text": "The Tandoor Open Data project provides community contributed data for Tandoor. This field is filled automatically when importing it and allows updates in the future.",
"Open_Data_Slug": "Open Data Slug", "Open_Data_Slug": "Open Data Slug",
"Open_Data_Import": "Open Data Import", "Open_Data_Import": "Open Data Import",
"Properties_Food_Amount": "Properties Food Amount",
"Properties_Food_Unit": "Properties Food Unit",
"FDC_ID": "FDC ID", "FDC_ID": "FDC ID",
"FDC_ID_help": "FDC database ID", "FDC_ID_help": "FDC database ID",
"Data_Import_Info": "Enhance your Space by importing a community curated list of foods, units and more to improve your recipe collection.", "Data_Import_Info": "Enhance your Space by importing a community curated list of foods, units and more to improve your recipe collection.",

View File

@ -738,7 +738,13 @@ export class Models {
}, },
fdc_id: { fdc_id: {
form_field: true, form_field: true,
type: "text", type: "choice",
options: [
{ value: 1008, text: "Calories (1008)" },
{ value: 1005, text: "Carbohydrates (1005)" },
{ value: 1003, text: "Protein (1003)" },
{ value: 1004, text: "Fat (1004)" },
],
field: "fdc_id", field: "fdc_id",
label: "FDC_ID", label: "FDC_ID",
help_text: "FDC_ID_help", help_text: "FDC_ID_help",