added unit conversion editor to food editor
This commit is contained in:
parent
c0577abb89
commit
326549568f
@ -816,30 +816,30 @@ class RecipeViewSet(viewsets.ModelViewSet):
|
|||||||
if self.detail: # if detail request and not list, private condition is verified by permission class
|
if self.detail: # if detail request and not list, private condition is verified by permission class
|
||||||
if not share: # filter for space only if not shared
|
if not share: # filter for space only if not shared
|
||||||
self.queryset = self.queryset.filter(space=self.request.space).prefetch_related(
|
self.queryset = self.queryset.filter(space=self.request.space).prefetch_related(
|
||||||
'keywords',
|
'keywords',
|
||||||
'shared',
|
'shared',
|
||||||
'properties',
|
'properties',
|
||||||
'properties__property_type',
|
'properties__property_type',
|
||||||
'steps',
|
'steps',
|
||||||
'steps__ingredients',
|
'steps__ingredients',
|
||||||
'steps__ingredients__step_set',
|
'steps__ingredients__step_set',
|
||||||
'steps__ingredients__step_set__recipe_set',
|
'steps__ingredients__step_set__recipe_set',
|
||||||
'steps__ingredients__food',
|
'steps__ingredients__food',
|
||||||
'steps__ingredients__food__properties',
|
'steps__ingredients__food__properties',
|
||||||
'steps__ingredients__food__properties__property_type',
|
'steps__ingredients__food__properties__property_type',
|
||||||
'steps__ingredients__food__inherit_fields',
|
'steps__ingredients__food__inherit_fields',
|
||||||
'steps__ingredients__food__supermarket_category',
|
'steps__ingredients__food__supermarket_category',
|
||||||
'steps__ingredients__food__onhand_users',
|
'steps__ingredients__food__onhand_users',
|
||||||
'steps__ingredients__food__substitute',
|
'steps__ingredients__food__substitute',
|
||||||
'steps__ingredients__food__child_inherit_fields',
|
'steps__ingredients__food__child_inherit_fields',
|
||||||
|
|
||||||
'steps__ingredients__unit',
|
'steps__ingredients__unit',
|
||||||
'steps__ingredients__unit__unit_conversion_base_relation',
|
'steps__ingredients__unit__unit_conversion_base_relation',
|
||||||
'steps__ingredients__unit__unit_conversion_base_relation__base_unit',
|
'steps__ingredients__unit__unit_conversion_base_relation__base_unit',
|
||||||
'steps__ingredients__unit__unit_conversion_converted_relation',
|
'steps__ingredients__unit__unit_conversion_converted_relation',
|
||||||
'steps__ingredients__unit__unit_conversion_converted_relation__converted_unit',
|
'steps__ingredients__unit__unit_conversion_converted_relation__converted_unit',
|
||||||
'cooklog_set',
|
'cooklog_set',
|
||||||
).select_related('nutrition')
|
).select_related('nutrition')
|
||||||
|
|
||||||
return super().get_queryset()
|
return super().get_queryset()
|
||||||
|
|
||||||
@ -973,8 +973,16 @@ class UnitConversionViewSet(viewsets.ModelViewSet):
|
|||||||
queryset = UnitConversion.objects
|
queryset = UnitConversion.objects
|
||||||
serializer_class = UnitConversionSerializer
|
serializer_class = UnitConversionSerializer
|
||||||
permission_classes = [CustomIsUser & CustomTokenHasReadWriteScope]
|
permission_classes = [CustomIsUser & CustomTokenHasReadWriteScope]
|
||||||
|
query_params = [
|
||||||
|
QueryParam(name='food_id', description='ID of food to filter for', qtype='int'),
|
||||||
|
]
|
||||||
|
schema = QueryParamAutoSchema()
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
|
food_id = self.request.query_params.get('food_id', None)
|
||||||
|
if food_id is not None:
|
||||||
|
self.queryset = self.queryset.filter(food_id=food_id)
|
||||||
|
|
||||||
return self.queryset.filter(space=self.request.space)
|
return self.queryset.filter(space=self.request.space)
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
|
|
||||||
<b-modal :id="id" size="xl" @hidden="cancelAction">
|
<b-modal :id="id" size="xl" @hidden="cancelAction" :body-class="`pr-3 pl-3`">
|
||||||
|
|
||||||
<template v-slot:modal-title>
|
<template v-slot:modal-title>
|
||||||
<div class="row" v-if="food">
|
<div class="row" v-if="food">
|
||||||
@ -15,95 +15,147 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<div class="row">
|
<div>
|
||||||
<div class="col-12">
|
<b-tabs content-class="mt-3" v-if="food">
|
||||||
<b-form v-if="food">
|
<b-tab title="General" active>
|
||||||
<b-form-group :label="$t('Name')" description="">
|
<b-form>
|
||||||
<b-form-input v-model="food.name"></b-form-input>
|
<b-form-group :label="$t('Name')" description="">
|
||||||
</b-form-group>
|
<b-form-input v-model="food.name"></b-form-input>
|
||||||
<b-form-group :label="$t('Plural')" description="">
|
</b-form-group>
|
||||||
<b-form-input v-model="food.plural_name"></b-form-input>
|
<b-form-group :label="$t('Plural')" description="">
|
||||||
</b-form-group>
|
<b-form-input v-model="food.plural_name"></b-form-input>
|
||||||
|
</b-form-group>
|
||||||
|
|
||||||
<!-- Food properties -->
|
<!-- Food properties -->
|
||||||
|
|
||||||
<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=""> <!-- TODO localize -->
|
||||||
<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=""> <!-- TODO localize -->
|
||||||
<generic-multiselect
|
<generic-multiselect
|
||||||
@change="food.properties_food_unit = $event.val;"
|
@change="food.properties_food_unit = $event.val;"
|
||||||
:model="Models.UNIT"
|
:model="Models.UNIT"
|
||||||
:initial_single_selection="food.properties_food_unit"
|
:initial_single_selection="food.properties_food_unit"
|
||||||
label="name"
|
label="name"
|
||||||
:multiple="false"
|
:multiple="false"
|
||||||
:placeholder="$t('Unit')"
|
:placeholder="$t('Unit')"
|
||||||
></generic-multiselect>
|
></generic-multiselect>
|
||||||
</b-form-group>
|
</b-form-group>
|
||||||
|
|
||||||
|
|
||||||
<table class="table table-bordered">
|
<table class="table table-bordered">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th> {{ $t('Property Amount') }}</th> <!-- TODO localize -->
|
<th> {{ $t('Property Amount') }}</th> <!-- TODO localize -->
|
||||||
<th> {{ $t('Property Type') }}</th> <!-- TODO localize -->
|
<th> {{ $t('Property Type') }}</th> <!-- TODO localize -->
|
||||||
<th></th>
|
<th></th>
|
||||||
<th></th>
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tr v-for="fp in food.properties" v-bind:key="fp.id">
|
<tr v-for="fp in food.properties" v-bind:key="fp.id">
|
||||||
<td><input v-model="fp.property_amount" type="number"> <span
|
<td><input v-model="fp.property_amount" type="number"> <span
|
||||||
v-if="fp.property_type">{{ fp.property_type.unit }}</span></td>
|
v-if="fp.property_type">{{ fp.property_type.unit }}</span></td>
|
||||||
<td>
|
<td>
|
||||||
<generic-multiselect
|
<generic-multiselect
|
||||||
@change="fp.property_type = $event.val"
|
@change="fp.property_type = $event.val"
|
||||||
:initial_single_selection="fp.property_type"
|
:initial_single_selection="fp.property_type"
|
||||||
label="name" :model="Models.PROPERTY_TYPE"
|
label="name" :model="Models.PROPERTY_TYPE"
|
||||||
:multiple="false"/>
|
:multiple="false"/>
|
||||||
</td>
|
</td>
|
||||||
<td> / <span>{{ food.properties_food_amount }} <span
|
<td> / <span>{{ food.properties_food_amount }} <span
|
||||||
v-if="food.properties_food_unit !== null">{{
|
v-if="food.properties_food_unit !== null">{{
|
||||||
food.properties_food_unit.name
|
food.properties_food_unit.name
|
||||||
}}</span></span>
|
}}</span></span>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<button class="btn btn-danger btn-small" @click="deleteProperty(fp)"><i
|
<button class="btn btn-danger btn-small" @click="deleteProperty(fp)"><i
|
||||||
class="fas fa-trash-alt"></i></button>
|
class="fas fa-trash-alt"></i></button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
<b-button-group>
|
<b-button-group>
|
||||||
<b-btn class="btn btn-success shadow-none" @click="addProperty()"><i
|
<b-btn class="btn btn-success shadow-none" @click="addProperty()"><i
|
||||||
class="fa fa-plus"></i>
|
class="fa fa-plus"></i>
|
||||||
</b-btn>
|
</b-btn>
|
||||||
<b-btn class="btn btn-secondary shadow-none" @click="addAllProperties()"><i
|
<b-btn class="btn btn-secondary shadow-none" @click="addAllProperties()"><i
|
||||||
class="fa fa-plus"> <i class="ml-1 fas fa-list"></i></i>
|
class="fa fa-plus"> <i class="ml-1 fas fa-list"></i></i>
|
||||||
</b-btn>
|
</b-btn>
|
||||||
</b-button-group>
|
</b-button-group>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<b-form-group :label="$t('Shopping_Category')" :description="$t('shopping_category_help')">
|
<b-form-group :label="$t('Shopping_Category')" :description="$t('shopping_category_help')">
|
||||||
<generic-multiselect
|
<generic-multiselect
|
||||||
@change="food.supermarket_category = $event.val;"
|
@change="food.supermarket_category = $event.val;"
|
||||||
:model="Models.SHOPPING_CATEGORY"
|
:model="Models.SHOPPING_CATEGORY"
|
||||||
:initial_single_selection="food.supermarket_category"
|
:initial_single_selection="food.supermarket_category"
|
||||||
label="name"
|
label="name"
|
||||||
:multiple="false"
|
:multiple="false"
|
||||||
:allow_create="true"
|
:allow_create="true"
|
||||||
:placeholder="$t('Shopping_Category')"
|
:placeholder="$t('Shopping_Category')"
|
||||||
></generic-multiselect>
|
></generic-multiselect>
|
||||||
</b-form-group>
|
</b-form-group>
|
||||||
|
|
||||||
|
|
||||||
|
</b-form>
|
||||||
|
</b-tab>
|
||||||
|
<b-tab title="Conversions" @click="loadUnitConversions" v-if="this.food.id !== undefined">
|
||||||
|
|
||||||
|
<b-row v-for="uc in unit_conversions" :key="uc">
|
||||||
|
<b-col>
|
||||||
|
<span v-if="uc.id">
|
||||||
|
<b-btn class="btn btn-sm" variant="danger" @click="deleteUnitConversion(uc)"><i class="fas fa-trash-alt"></i></b-btn>
|
||||||
|
{{uc.base_amount}}
|
||||||
|
{{uc.base_unit.name}}
|
||||||
|
=
|
||||||
|
{{uc.converted_amount}}
|
||||||
|
{{uc.converted_unit.name}}
|
||||||
|
</span>
|
||||||
|
<b-form class="mt-1">
|
||||||
|
<b-input-group>
|
||||||
|
<b-input v-model="uc.base_amount" @change="uc.changed = true"></b-input>
|
||||||
|
<b-input-group-append>
|
||||||
|
<generic-multiselect
|
||||||
|
@change="uc.base_unit = $event.val; uc.changed = true"
|
||||||
|
:initial_single_selection="uc.base_unit"
|
||||||
|
label="name" :model="Models.UNIT"
|
||||||
|
:multiple="false"/>
|
||||||
|
</b-input-group-append>
|
||||||
|
|
||||||
|
</b-input-group>
|
||||||
|
|
||||||
|
<b-input-group>
|
||||||
|
<b-input v-model="uc.converted_amount" @change="uc.changed = true"></b-input>
|
||||||
|
<b-input-group-append>
|
||||||
|
<generic-multiselect
|
||||||
|
@change="uc.converted_unit = $event.val; uc.changed = true"
|
||||||
|
:initial_single_selection="uc.converted_unit"
|
||||||
|
label="name" :model="Models.UNIT"
|
||||||
|
:multiple="false"/>
|
||||||
|
</b-input-group-append>
|
||||||
|
</b-input-group>
|
||||||
|
|
||||||
|
</b-form>
|
||||||
|
</b-col>
|
||||||
|
<hr style="height: 1px"/>
|
||||||
|
</b-row>
|
||||||
|
|
||||||
|
<b-row>
|
||||||
|
<b-col class="text-center">
|
||||||
|
<b-btn variant="success" @click="addUnitConversion"><i class="fa fa-plus"></i></b-btn>
|
||||||
|
</b-col>
|
||||||
|
</b-row>
|
||||||
|
|
||||||
|
</b-tab>
|
||||||
|
<b-tab title="More">
|
||||||
|
<b-form>
|
||||||
|
|
||||||
<!-- Unit conversion -->
|
|
||||||
|
|
||||||
<!-- ADVANCED FEATURES somehow hide this stuff -->
|
|
||||||
<b-collapse id="collapse-advanced">
|
|
||||||
<b-form-group :label="$t('Recipe')" :description="$t('food_recipe_help')">
|
<b-form-group :label="$t('Recipe')" :description="$t('food_recipe_help')">
|
||||||
<generic-multiselect
|
<generic-multiselect
|
||||||
@change="food.recipe = $event.val;"
|
@change="food.recipe = $event.val;"
|
||||||
@ -176,16 +228,15 @@
|
|||||||
}}
|
}}
|
||||||
</b-form-checkbox>
|
</b-form-checkbox>
|
||||||
</b-form-group>
|
</b-form-group>
|
||||||
</b-collapse>
|
|
||||||
|
|
||||||
|
|
||||||
</b-form>
|
</b-form>
|
||||||
|
</b-tab>
|
||||||
</div>
|
</b-tabs>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<template v-slot:modal-footer>
|
<template v-slot:modal-footer>
|
||||||
<b-button variant="primary" @click="updateFood">{{ $t('Save') }}</b-button>
|
<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>
|
</template>
|
||||||
</b-modal>
|
</b-modal>
|
||||||
</div>
|
</div>
|
||||||
@ -231,6 +282,7 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
food: undefined,
|
food: undefined,
|
||||||
|
unit_conversions: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
@ -286,6 +338,24 @@ export default {
|
|||||||
StandardToasts.makeStandardToast(this, StandardToasts.FAIL_UPDATE, err)
|
StandardToasts.makeStandardToast(this, StandardToasts.FAIL_UPDATE, err)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.unit_conversions.forEach(uc => {
|
||||||
|
if (uc.changed === true) {
|
||||||
|
if (uc.id === undefined) {
|
||||||
|
apiClient.createUnitConversion(uc).then(r => {
|
||||||
|
uc = r.data
|
||||||
|
}).catch(err => {
|
||||||
|
StandardToasts.makeStandardToast(this, StandardToasts.FAIL_CREATE, err, true)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
apiClient.updateUnitConversion(uc.id, uc).then(r => {
|
||||||
|
uc = r.data
|
||||||
|
}).catch(err => {
|
||||||
|
StandardToasts.makeStandardToast(this, StandardToasts.FAIL_UPDATE, err, true)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
},
|
},
|
||||||
addProperty: function () {
|
addProperty: function () {
|
||||||
this.food.properties.push({property_type: null, property_amount: 0})
|
this.food.properties.push({property_type: null, property_amount: 0})
|
||||||
@ -306,6 +376,32 @@ export default {
|
|||||||
cancelAction: function () {
|
cancelAction: function () {
|
||||||
this.$emit("hidden", "")
|
this.$emit("hidden", "")
|
||||||
},
|
},
|
||||||
|
loadUnitConversions: function () {
|
||||||
|
let apiClient = new ApiApiFactory()
|
||||||
|
apiClient.listUnitConversions(this.food.id).then(r => {
|
||||||
|
this.unit_conversions = r.data
|
||||||
|
})
|
||||||
|
},
|
||||||
|
addUnitConversion: function () {
|
||||||
|
this.unit_conversions.push(
|
||||||
|
{
|
||||||
|
food: this.food,
|
||||||
|
base_amount: 1,
|
||||||
|
base_unit: null,
|
||||||
|
converted_amount: 0,
|
||||||
|
converted_unit: null,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
},
|
||||||
|
deleteUnitConversion: function (uc){
|
||||||
|
this.unit_conversions = this.unit_conversions.filter(u => u !== uc)
|
||||||
|
let apiClient = new ApiApiFactory()
|
||||||
|
apiClient.destroyUnitConversion(uc.id).then(r => {
|
||||||
|
StandardToasts.makeStandardToast(this, StandardToasts.SUCCESS_DELETE)
|
||||||
|
}).catch(err => {
|
||||||
|
StandardToasts.makeStandardToast(this, StandardToasts.FAIL_DELETE, err)
|
||||||
|
})
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user