mirror of
https://github.com/TandoorRecipes/recipes.git
synced 2026-01-02 20:59:28 -05:00
WIP
This commit is contained in:
@@ -80,7 +80,7 @@
|
||||
spinner="waveDots">
|
||||
</infinite-loading>
|
||||
</div>
|
||||
<!-- right side keyword cards -->
|
||||
<!-- right side food cards -->
|
||||
<div class="col col-md mh-100 overflow-auto " v-if="show_split">
|
||||
<food-card
|
||||
v-for="f in foods2"
|
||||
@@ -108,51 +108,56 @@
|
||||
<!-- TODO Modals can probably be made generic and moved to component -->
|
||||
<!-- edit modal -->
|
||||
<b-modal class="modal"
|
||||
:id="'id_modal_keyword_edit'"
|
||||
@shown="prepareEmoji"
|
||||
:title="this.$t('Edit_Keyword')"
|
||||
:id="'id_modal_food_edit'"
|
||||
:title="this.$t('Edit_Food')"
|
||||
:ok-title="this.$t('Save')"
|
||||
:cancel-title="this.$t('Cancel')"
|
||||
@ok="saveKeyword">
|
||||
@ok="saveFood">
|
||||
<form>
|
||||
<label for="id_keyword_name_edit">{{ this.$t('Name') }}</label>
|
||||
<input class="form-control" type="text" id="id_keyword_name_edit" v-model="this_item.name">
|
||||
<label for="id_keyword_description_edit">{{ this.$t('Description') }}</label>
|
||||
<input class="form-control" type="text" id="id_keyword_description_edit" v-model="this_item.description">
|
||||
<label for="id_keyword_icon_edit">{{ this.$t('Icon') }}</label>
|
||||
<twemoji-textarea
|
||||
id="id_keyword_icon_edit"
|
||||
ref="_edit"
|
||||
:emojiData="emojiDataAll"
|
||||
:emojiGroups="emojiGroups"
|
||||
triggerType="hover"
|
||||
recentEmojisFeat="true"
|
||||
recentEmojisStorage="local"
|
||||
@contentChanged="setIcon"
|
||||
/>
|
||||
<label for="id_food_name_edit">{{ this.$t('Name') }}</label>
|
||||
<input class="form-control" type="text" id="id_food_name_edit" v-model="this_item.name">
|
||||
<label for="id_food_description_edit">{{ this.$t('Description') }}</label>
|
||||
<input class="form-control" type="text" id="id_food_description_edit" v-model="this_item.description">
|
||||
<label for="id_food_recipe_edit">{{ this.$t('Recipe') }}</label>
|
||||
<generic-multiselect
|
||||
@change="this_item.recipe=$event.val"
|
||||
label="name"
|
||||
:initial_selection="this_item.recipe"
|
||||
search_function="listRecipes"
|
||||
:multiple="false"
|
||||
:sticky_options="[{'id': null,'name': $t('None')}]"
|
||||
style="flex-grow: 1; flex-shrink: 1; flex-basis: 0"
|
||||
:placeholder="this.$t('Search')">
|
||||
</generic-multiselect>
|
||||
<div class="form-group form-check">
|
||||
<input type="checkbox" class="form-check-input" id="id_food_ignore_edit" v-model="this_item.ignore_shopping">
|
||||
<label class="form-check-label" for="id_food_ignore_edit">{{ this.$t('Ignore_Shopping') }}</label>
|
||||
</div>
|
||||
<label for="id_food_category_edit">{{ this.$t('Shopping_Category') }}</label>
|
||||
<input class="form-control" type="text" id="id_food_category_edit" >
|
||||
</form>
|
||||
</b-modal>
|
||||
<!-- delete modal -->
|
||||
<b-modal class="modal"
|
||||
:id="'id_modal_keyword_delete'"
|
||||
:title="this.$t('Delete_Keyword')"
|
||||
:id="'id_modal_food_delete'"
|
||||
:title="this.$t('Delete_Food')"
|
||||
:ok-title="this.$t('Delete')"
|
||||
:cancel-title="this.$t('Cancel')"
|
||||
@ok="delKeyword(this_item.id)">
|
||||
@ok="delFood(this_item.id)">
|
||||
{{this.$t("delete_confimation", {'kw': this_item.name})}} {{this_item.name}}
|
||||
</b-modal>
|
||||
<!-- move modal -->
|
||||
<b-modal class="modal"
|
||||
:id="'id_modal_keyword_move'"
|
||||
:title="this.$t('Move_Keyword')"
|
||||
:id="'id_modal_food_move'"
|
||||
:title="this.$t('Move_Food')"
|
||||
:ok-title="this.$t('Move')"
|
||||
:cancel-title="this.$t('Cancel')"
|
||||
@ok="moveKeyword(this_item.id, this_item.target.id)">
|
||||
@ok="moveFood(this_item.id, this_item.target.id)">
|
||||
{{ this.$t("move_selection", {'child': this_item.name}) }}
|
||||
<generic-multiselect
|
||||
@change="this_item.target=$event.val"
|
||||
label="name"
|
||||
search_function="listKeywords"
|
||||
search_function="listFood"
|
||||
:multiple="false"
|
||||
:sticky_options="[{'id': 0,'name': $t('Root')}]"
|
||||
:tree_api="true"
|
||||
@@ -162,16 +167,16 @@
|
||||
</b-modal>
|
||||
<!-- merge modal -->
|
||||
<b-modal class="modal"
|
||||
:id="'id_modal_keyword_merge'"
|
||||
:title="this.$t('Merge_Keyword')"
|
||||
:id="'id_modal_food_merge'"
|
||||
:title="this.$t('Merge_Food')"
|
||||
:ok-title="this.$t('Merge')"
|
||||
:cancel-title="this.$t('Cancel')"
|
||||
@ok="mergeKeyword(this_item.id, this_item.target.id)">
|
||||
{{ this.$t("merge_selection", {'source': this_item.name, 'type': this.$t('keyword')}) }}
|
||||
@ok="mergeFood(this_item.id, this_item.target.id)">
|
||||
{{ this.$t("merge_selection", {'source': this_item.name, 'type': this.$t('food')}) }}
|
||||
<generic-multiselect
|
||||
@change="this_item.target=$event.val"
|
||||
label="name"
|
||||
search_function="listKeywords"
|
||||
search_function="listFoods"
|
||||
:multiple="false"
|
||||
:tree_api="true"
|
||||
style="flex-grow: 1; flex-shrink: 1; flex-basis: 0"
|
||||
@@ -193,36 +198,19 @@ import {BootstrapVue} from 'bootstrap-vue'
|
||||
import 'bootstrap-vue/dist/bootstrap-vue.css'
|
||||
import _debounce from 'lodash/debounce'
|
||||
|
||||
import {ResolveUrlMixin} from "@/utils/utils";
|
||||
import {ToastMixin} from "@/utils/utils";
|
||||
|
||||
import {ApiApiFactory} from "@/utils/openapi/api.ts";
|
||||
import FoodCard from "@/components/FoodCard";
|
||||
import GenericMultiselect from "@/components/GenericMultiselect";
|
||||
import InfiniteLoading from 'vue-infinite-loading';
|
||||
|
||||
// would move with modals if made generic
|
||||
import {TwemojiTextarea} from '@kevinfaguiar/vue-twemoji-picker';
|
||||
// TODO add localization
|
||||
import EmojiAllData from '@kevinfaguiar/vue-twemoji-picker/emoji-data/en/emoji-all-groups.json';
|
||||
import EmojiGroups from '@kevinfaguiar/vue-twemoji-picker/emoji-data/emoji-groups.json';
|
||||
// end move with generic modals
|
||||
|
||||
Vue.use(BootstrapVue)
|
||||
|
||||
export default {
|
||||
name: 'FoodListView',
|
||||
mixins: [ResolveUrlMixin],
|
||||
components: {TwemojiTextarea, FoodCard, GenericMultiselect, InfiniteLoading},
|
||||
computed: {
|
||||
// move with generic modals
|
||||
emojiDataAll() {
|
||||
return EmojiAllData;
|
||||
},
|
||||
emojiGroups() {
|
||||
return EmojiGroups;
|
||||
}
|
||||
// end move with generic modals
|
||||
},
|
||||
mixins: [ToastMixin],
|
||||
components: {FoodCard, GenericMultiselect, InfiniteLoading},
|
||||
data() {
|
||||
return {
|
||||
foods: [],
|
||||
@@ -241,7 +229,9 @@ export default {
|
||||
'id': -1,
|
||||
'name': '',
|
||||
'description': '',
|
||||
'icon': '',
|
||||
'recipe': null,
|
||||
'ignore_shopping': '',
|
||||
'supermarket_category': null,
|
||||
'target': {
|
||||
'id': -1,
|
||||
'name': ''
|
||||
@@ -262,15 +252,6 @@ export default {
|
||||
}, 700)
|
||||
},
|
||||
methods: {
|
||||
makeToast: function (title, message, variant = null) {
|
||||
//TODO remove duplicate function in favor of central one
|
||||
this.$bvToast.toast(message, {
|
||||
title: title,
|
||||
variant: variant,
|
||||
toaster: 'b-toaster-top-center',
|
||||
solid: true
|
||||
})
|
||||
},
|
||||
resetSearch: function () {
|
||||
if (this.search_input !== '') {
|
||||
this.search_input = ''
|
||||
@@ -295,26 +276,26 @@ export default {
|
||||
|
||||
if (e.action == 'delete') {
|
||||
this.this_item = source
|
||||
this.$bvModal.show('id_modal_keyword_delete')
|
||||
this.$bvModal.show('id_modal_food_delete')
|
||||
} else if (e.action == 'new') {
|
||||
this.this_item = {}
|
||||
this.$bvModal.show('id_modal_keyword_edit')
|
||||
this.$bvModal.show('id_modal_food_edit')
|
||||
} else if (e.action == 'edit') {
|
||||
this.this_item = source
|
||||
this.$bvModal.show('id_modal_keyword_edit')
|
||||
this.$bvModal.show('id_modal_food_edit')
|
||||
} else if (e.action === 'move') {
|
||||
this.this_item = source
|
||||
if (target == null) {
|
||||
this.$bvModal.show('id_modal_keyword_move')
|
||||
this.$bvModal.show('id_modal_food_move')
|
||||
} else {
|
||||
this.moveKeyword(source.id, target.id)
|
||||
this.moveFood(source.id, target.id)
|
||||
}
|
||||
} else if (e.action === 'merge') {
|
||||
this.this_item = source
|
||||
if (target == null) {
|
||||
this.$bvModal.show('id_modal_keyword_merge')
|
||||
this.$bvModal.show('id_modal_food_merge')
|
||||
} else {
|
||||
this.mergeKeyword(e.source.id, e.target.id)
|
||||
this.mergeFood(e.source.id, e.target.id)
|
||||
}
|
||||
} else if (e.action === 'get-children') {
|
||||
if (source.expanded) {
|
||||
@@ -335,13 +316,14 @@ export default {
|
||||
},
|
||||
saveFood: function () {
|
||||
let apiClient = new ApiApiFactory()
|
||||
let food = {
|
||||
name: this.this_item.name,
|
||||
description: this.this_item.description,
|
||||
icon: this.this_item.icon,
|
||||
}
|
||||
console.log(this.this_item, !this.this_item.id)
|
||||
// let food = {
|
||||
// name: this.this_item.name,
|
||||
// description: this.this_item.description,
|
||||
// icon: this.this_item.icon,
|
||||
// }
|
||||
if (!this.this_item.id) { // if there is no item id assume its a new item
|
||||
apiClient.createFood(food).then(result => {
|
||||
apiClient.createFood(this.this_item).then(result => {
|
||||
// place all new foods at the top of the list - could sort instead
|
||||
this.foods = [result.data].concat(this.foods)
|
||||
// this creates a deep copy to make sure that columns stay independent
|
||||
@@ -356,7 +338,7 @@ export default {
|
||||
this.this_item = {}
|
||||
})
|
||||
} else {
|
||||
apiClient.partialUpdateFood(this.this_item.id, food).then(result => {
|
||||
apiClient.partialUpdateFood(this.this_item.id, this.this_item).then(result => {
|
||||
this.refreshCard(this.this_item.id)
|
||||
this.this_item={}
|
||||
}).catch((err) => {
|
||||
@@ -427,9 +409,9 @@ export default {
|
||||
|
||||
apiClient.listFoods(query, root, tree, page, pageSize).then(result => {
|
||||
if (col == 'left') {
|
||||
parent = this.findFood(this.keywords, food.id)
|
||||
parent = this.findFood(this.foods, food.id)
|
||||
} else if (col == 'right'){
|
||||
parent = this.findFood(this.keywords2, food.id)
|
||||
parent = this.findFood(this.foods2, food.id)
|
||||
}
|
||||
if (parent) {
|
||||
Vue.set(parent, 'children', result.data.results)
|
||||
|
||||
@@ -194,7 +194,7 @@ import {BootstrapVue} from 'bootstrap-vue'
|
||||
import 'bootstrap-vue/dist/bootstrap-vue.css'
|
||||
import _debounce from 'lodash/debounce'
|
||||
|
||||
import {ResolveUrlMixin} from "@/utils/utils";
|
||||
import {ToastMixin} from "@/utils/utils";
|
||||
|
||||
import {ApiApiFactory} from "@/utils/openapi/api.ts";
|
||||
import KeywordCard from "@/components/KeywordCard";
|
||||
@@ -212,7 +212,7 @@ Vue.use(BootstrapVue)
|
||||
|
||||
export default {
|
||||
name: 'KeywordListView',
|
||||
mixins: [ResolveUrlMixin],
|
||||
mixins: [ToastMixin],
|
||||
components: {TwemojiTextarea, KeywordCard, GenericMultiselect, InfiniteLoading},
|
||||
computed: {
|
||||
// move with generic modals
|
||||
@@ -263,15 +263,6 @@ export default {
|
||||
}, 700)
|
||||
},
|
||||
methods: {
|
||||
makeToast: function (title, message, variant = null) {
|
||||
//TODO remove duplicate function in favor of central one
|
||||
this.$bvToast.toast(message, {
|
||||
title: title,
|
||||
variant: variant,
|
||||
toaster: 'b-toaster-top-center',
|
||||
solid: true
|
||||
})
|
||||
},
|
||||
resetSearch: function () {
|
||||
if (this.search_input !== '') {
|
||||
this.search_input = ''
|
||||
|
||||
Reference in New Issue
Block a user