added basic ingredient editor
This commit is contained in:
118
vue/src/apps/IngredientEditorView/IngredientEditorView.vue
Normal file
118
vue/src/apps/IngredientEditorView/IngredientEditorView.vue
Normal file
@ -0,0 +1,118 @@
|
||||
<template>
|
||||
<div id="app">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<generic-multiselect @change="food = $event.val; refreshList()"
|
||||
:model="Models.FOOD"
|
||||
:multiple="false"></generic-multiselect>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<generic-multiselect @change="unit = $event.val; refreshList()"
|
||||
:model="Models.UNIT"
|
||||
:multiple="false"></generic-multiselect>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Amount</th>
|
||||
<th>Unit</th>
|
||||
<th>Food</th>
|
||||
<th>Note</th>
|
||||
<th>Save</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr v-for="i in ingredients" v-bind:key="i.id">
|
||||
<td style="width: 10vw">
|
||||
<input type="number" class="form-control" v-model="i.amount">
|
||||
</td>
|
||||
<td style="width: 30vw">
|
||||
<generic-multiselect @change="i.unit = $event.val;"
|
||||
:initial_selection="i.unit"
|
||||
:model="Models.UNIT"
|
||||
:search_on_load="false"
|
||||
:multiple="false"></generic-multiselect>
|
||||
</td>
|
||||
<td style="width: 30vw">
|
||||
<generic-multiselect @change="i.food = $event.val;"
|
||||
:initial_selection="i.food"
|
||||
:model="Models.FOOD"
|
||||
:search_on_load="false"
|
||||
:multiple="false"></generic-multiselect>
|
||||
</td>
|
||||
<td style="width: 30vw">
|
||||
<input class="form-control" v-model="i.note">
|
||||
|
||||
</td>
|
||||
<td>
|
||||
<b-button variant="primary" @click="updateIngredient(i)">Save</b-button>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Vue from "vue"
|
||||
import {BootstrapVue} from "bootstrap-vue"
|
||||
|
||||
import "bootstrap-vue/dist/bootstrap-vue.css"
|
||||
import {ApiMixin, StandardToasts} from "@/utils/utils"
|
||||
import {ApiApiFactory} from "@/utils/openapi/api";
|
||||
import GenericMultiselect from "@/components/GenericMultiselect";
|
||||
|
||||
Vue.use(BootstrapVue)
|
||||
|
||||
export default {
|
||||
name: "IngredientEditorView",
|
||||
mixins: [ApiMixin],
|
||||
components: {GenericMultiselect},
|
||||
data() {
|
||||
return {
|
||||
ingredients: [],
|
||||
food: null,
|
||||
unit: null,
|
||||
}
|
||||
},
|
||||
computed: {},
|
||||
mounted() {
|
||||
this.$i18n.locale = window.CUSTOM_LOCALE
|
||||
this.refreshList()
|
||||
},
|
||||
methods: {
|
||||
refreshList: function () {
|
||||
if (this.food === null && this.unit === null) {
|
||||
this.ingredients = []
|
||||
} else {
|
||||
let apiClient = new ApiApiFactory()
|
||||
let params = {'query': {'simple': 1}}
|
||||
if (this.food !== null) {
|
||||
params.query.food = this.food.id
|
||||
}
|
||||
if (this.unit !== null) {
|
||||
params.query.unit = this.unit.id
|
||||
}
|
||||
apiClient.listIngredients(params).then(result => {
|
||||
this.ingredients = result.data
|
||||
})
|
||||
}
|
||||
},
|
||||
updateIngredient: function (i) {
|
||||
let apiClient = new ApiApiFactory()
|
||||
apiClient.updateIngredient(i.id, i).then(r => {
|
||||
StandardToasts.makeStandardToast(StandardToasts.SUCCESS_UPDATE)
|
||||
}).catch((r, e) => {
|
||||
StandardToasts.makeStandardToast(StandardToasts.FAIL_UPDATE)
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
18
vue/src/apps/IngredientEditorView/main.js
Normal file
18
vue/src/apps/IngredientEditorView/main.js
Normal file
@ -0,0 +1,18 @@
|
||||
import Vue from 'vue'
|
||||
import App from './IngredientEditorView.vue'
|
||||
import i18n from '@/i18n'
|
||||
|
||||
Vue.config.productionTip = false
|
||||
|
||||
// TODO move this and other default stuff to centralized JS file (verify nothing breaks)
|
||||
let publicPath = localStorage.STATIC_URL + 'vue/'
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
publicPath = 'http://localhost:8080/'
|
||||
}
|
||||
export default __webpack_public_path__ = publicPath // eslint-disable-line
|
||||
|
||||
|
||||
new Vue({
|
||||
i18n,
|
||||
render: h => h(App),
|
||||
}).$mount('#app')
|
@ -26,11 +26,11 @@
|
||||
<script>
|
||||
import Vue from "vue"
|
||||
import Multiselect from "vue-multiselect"
|
||||
import { ApiMixin } from "@/utils/utils"
|
||||
import {ApiMixin} from "@/utils/utils"
|
||||
|
||||
export default {
|
||||
name: "GenericMultiselect",
|
||||
components: { Multiselect },
|
||||
components: {Multiselect},
|
||||
mixins: [ApiMixin],
|
||||
data() {
|
||||
return {
|
||||
@ -42,16 +42,16 @@ export default {
|
||||
}
|
||||
},
|
||||
props: {
|
||||
placeholder: { type: String, default: undefined },
|
||||
placeholder: {type: String, default: undefined},
|
||||
model: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {}
|
||||
},
|
||||
},
|
||||
label: { type: String, default: "name" },
|
||||
parent_variable: { type: String, default: undefined },
|
||||
limit: { type: Number, default: 25 },
|
||||
label: {type: String, default: "name"},
|
||||
parent_variable: {type: String, default: undefined},
|
||||
limit: {type: Number, default: 25},
|
||||
sticky_options: {
|
||||
type: Array,
|
||||
default() {
|
||||
@ -68,10 +68,11 @@ export default {
|
||||
type: Object,
|
||||
default: undefined,
|
||||
},
|
||||
multiple: { type: Boolean, default: true },
|
||||
allow_create: { type: Boolean, default: false },
|
||||
create_placeholder: { type: String, default: "You Forgot to Add a Tag Placeholder" },
|
||||
clear: { type: Number },
|
||||
search_on_load: {type: Boolean, default: true},
|
||||
multiple: {type: Boolean, default: true},
|
||||
allow_create: {type: Boolean, default: false},
|
||||
create_placeholder: {type: String, default: "You Forgot to Add a Tag Placeholder"},
|
||||
clear: {type: Number},
|
||||
},
|
||||
watch: {
|
||||
initial_selection: function (newVal, oldVal) {
|
||||
@ -82,12 +83,12 @@ export default {
|
||||
empty[this.label] = `..${this.$t("loading")}..`
|
||||
this.selected_objects.forEach((x) => {
|
||||
if (typeof x !== "object") {
|
||||
this.selected_objects[this.selected_objects.indexOf(x)] = { ...empty, id: x }
|
||||
this.selected_objects[this.selected_objects.indexOf(x)] = {...empty, id: x}
|
||||
get_details.push(x)
|
||||
}
|
||||
})
|
||||
get_details.forEach((x) => {
|
||||
this.genericAPI(this.model, this.Actions.FETCH, { id: x })
|
||||
this.genericAPI(this.model, this.Actions.FETCH, {id: x})
|
||||
.then((result) => {
|
||||
// this.selected_objects[this.selected_objects.map((y) => y.id).indexOf(x)] = result.data
|
||||
Vue.set(this.selected_objects, this.selected_objects.map((y) => y.id).indexOf(x), result.data)
|
||||
@ -103,8 +104,8 @@ export default {
|
||||
if (typeof this.selected_objects !== "object") {
|
||||
let empty = {}
|
||||
empty[this.label] = `..${this.$t("loading")}..`
|
||||
this.selected_objects = { ...empty, id: this.selected_objects }
|
||||
this.genericAPI(this.model, this.Actions.FETCH, { id: this.selected_objects })
|
||||
this.selected_objects = {...empty, id: this.selected_objects}
|
||||
this.genericAPI(this.model, this.Actions.FETCH, {id: this.selected_objects})
|
||||
.then((result) => {
|
||||
this.selected_objects = result.data
|
||||
})
|
||||
@ -123,7 +124,9 @@ export default {
|
||||
},
|
||||
mounted() {
|
||||
this.id = Math.random()
|
||||
this.search("")
|
||||
if (this.search_on_load) {
|
||||
this.search("")
|
||||
}
|
||||
if (this.multiple || !this.initial_single_selection) {
|
||||
this.selected_objects = this.initial_selection
|
||||
} else {
|
||||
@ -171,7 +174,7 @@ export default {
|
||||
})
|
||||
},
|
||||
selectionChanged: function () {
|
||||
this.$emit("change", { var: this.parent_variable, val: this.selected_objects })
|
||||
this.$emit("change", {var: this.parent_variable, val: this.selected_objects})
|
||||
},
|
||||
addNew(e) {
|
||||
this.$emit("new", e)
|
||||
|
@ -472,7 +472,7 @@ export interface FoodRecipe {
|
||||
* @type {string}
|
||||
* @memberof FoodRecipe
|
||||
*/
|
||||
name?: string;
|
||||
name: string;
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
@ -537,7 +537,7 @@ export interface FoodSubstitute {
|
||||
* @type {string}
|
||||
* @memberof FoodSubstitute
|
||||
*/
|
||||
name?: string;
|
||||
name: string;
|
||||
}
|
||||
/**
|
||||
*
|
||||
@ -746,6 +746,12 @@ export interface Ingredient {
|
||||
* @memberof Ingredient
|
||||
*/
|
||||
no_amount?: boolean;
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof Ingredient
|
||||
*/
|
||||
original_text?: string | null;
|
||||
}
|
||||
/**
|
||||
*
|
||||
@ -1905,6 +1911,12 @@ export interface RecipeIngredients {
|
||||
* @memberof RecipeIngredients
|
||||
*/
|
||||
no_amount?: boolean;
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof RecipeIngredients
|
||||
*/
|
||||
original_text?: string | null;
|
||||
}
|
||||
/**
|
||||
*
|
||||
@ -2173,7 +2185,7 @@ export interface RecipeSimple {
|
||||
* @type {string}
|
||||
* @memberof RecipeSimple
|
||||
*/
|
||||
name?: string;
|
||||
name: string;
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
|
Reference in New Issue
Block a user