mirror of
https://github.com/TandoorRecipes/recipes.git
synced 2026-01-07 07:08:03 -05:00
some things actually working
This commit is contained in:
@@ -4,10 +4,7 @@
|
|||||||
|
|
||||||
<div class="row float-top w-100">
|
<div class="row float-top w-100">
|
||||||
<div class="col-auto no-gutter ml-auto">
|
<div class="col-auto no-gutter ml-auto">
|
||||||
<b-button variant="link" class="px-1 pt-0 pb-1 d-none d-md-inline-block">
|
|
||||||
<i class="btn fas fa-plus-circle fa-lg px-0" @click="entrymode = !entrymode"
|
|
||||||
:class="entrymode ? 'text-success' : 'text-primary'"/>
|
|
||||||
</b-button>
|
|
||||||
<b-button variant="link" class="px-1 pt-0 pb-1 d-none d-md-inline-block">
|
<b-button variant="link" class="px-1 pt-0 pb-1 d-none d-md-inline-block">
|
||||||
<i class="fas fa-download fa-lg nav-link dropdown-toggle text-primary px-1"
|
<i class="fas fa-download fa-lg nav-link dropdown-toggle text-primary px-1"
|
||||||
id="downloadShoppingLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"></i>
|
id="downloadShoppingLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"></i>
|
||||||
@@ -37,102 +34,41 @@
|
|||||||
<span
|
<span
|
||||||
class="d-none d-md-inline-block">{{ $t('Shopping_list') + ` (${items.filter(x => x.checked === false).length})` }}</span>
|
class="d-none d-md-inline-block">{{ $t('Shopping_list') + ` (${items.filter(x => x.checked === false).length})` }}</span>
|
||||||
</template>
|
</template>
|
||||||
<div class="container p-0 p-md-3 pb-5" id="shoppinglist">
|
|
||||||
<div class="row pb-5">
|
|
||||||
<div class="col col-md-12 p-0 p-lg-3">
|
|
||||||
<div role="tablist">
|
|
||||||
<!-- add to shopping form -->
|
|
||||||
<div class="container d-lg-block d-print-none d-none">
|
|
||||||
<b-row class="justify-content-md-center align-items-center pl-1 pr-1"
|
|
||||||
v-if="entrymode">
|
|
||||||
<b-col cols="12" md="3" v-if="!ui.entry_mode_simple"
|
|
||||||
class="d-none d-md-block mt-1">
|
|
||||||
<b-form-input
|
|
||||||
size="lg"
|
|
||||||
min="1"
|
|
||||||
type="number"
|
|
||||||
:description="$t('Amount')"
|
|
||||||
v-model="new_item.amount"
|
|
||||||
style="font-size: 16px; border-radius: 5px !important; border: 1px solid #e8e8e8 !important"
|
|
||||||
ref="amount_input_complex"
|
|
||||||
></b-form-input>
|
|
||||||
</b-col>
|
|
||||||
<b-col cols="12" md="4" v-if="!ui.entry_mode_simple" class="mt-1">
|
|
||||||
<lookup-input :class_list="'mb-0'" :form="formUnit" :model="Models.UNIT"
|
|
||||||
@change="new_item.unit = $event" :show_label="false"
|
|
||||||
:clear="clear"/>
|
|
||||||
</b-col>
|
|
||||||
<b-col cols="12" md="4" v-if="!ui.entry_mode_simple" class="mt-1">
|
|
||||||
<lookup-input :class_list="'mb-0'" :form="formFood" :model="Models.FOOD"
|
|
||||||
@change="new_item.food = $event" :show_label="false"
|
|
||||||
:clear="clear"/>
|
|
||||||
</b-col>
|
|
||||||
<b-col cols="12" md="11" v-if="ui.entry_mode_simple" class="mt-1">
|
|
||||||
<b-form-input size="lg" type="text" :placeholder="$t('QuickEntry')"
|
|
||||||
v-model="new_item.ingredient"
|
|
||||||
@keyup.enter="addItem"
|
|
||||||
ref="amount_input_simple"></b-form-input>
|
|
||||||
</b-col>
|
|
||||||
<b-col cols="12" md="1" class="d-none d-md-block mt-1">
|
|
||||||
<b-button variant="link" class="px-0" type="submit">
|
|
||||||
<i class="btn fas fa-cart-plus fa-lg px-0 text-success"
|
|
||||||
@click="addItem"/>
|
|
||||||
</b-button>
|
|
||||||
</b-col>
|
|
||||||
<b-col cols="12" md="3" v-if="!ui.entry_mode_simple"
|
|
||||||
class="d-block d-md-none mt-1">
|
|
||||||
<b-row>
|
|
||||||
<b-col cols="9">
|
|
||||||
<b-form-input
|
|
||||||
size="lg"
|
|
||||||
min="1"
|
|
||||||
type="number"
|
|
||||||
:description="$t('Amount')"
|
|
||||||
v-model="new_item.amount"
|
|
||||||
style="font-size: 16px; border-radius: 5px !important; border: 1px solid #e8e8e8 !important"
|
|
||||||
></b-form-input>
|
|
||||||
</b-col>
|
|
||||||
<b-col cols="3" class="flex-grow-1">
|
|
||||||
<b-button variant="success" class="p-0 pt-1 w-100 h-100">
|
|
||||||
<i class="btn fas fa-cart-plus fa-lg" @click="addItem"/>
|
|
||||||
</b-button>
|
|
||||||
</b-col>
|
|
||||||
</b-row>
|
|
||||||
</b-col>
|
|
||||||
</b-row>
|
|
||||||
|
|
||||||
<b-row class="row justify-content-around mt-2" v-if="entrymode">
|
<b-row class="d-lg-block d-print-none d-none pr-4 pl-4 mb-3 mt-3">
|
||||||
<b-form-checkbox switch v-model="ui.entry_mode_simple">
|
<b-col cols="12">
|
||||||
{{ $t("QuickEntry") }}
|
<b-input-group>
|
||||||
</b-form-checkbox>
|
<b-form-input type="text" :placeholder="$t('Food')"
|
||||||
<b-button variant="success" size="sm" class="d-flex d-md-none p-0"
|
v-model="new_item.ingredient"
|
||||||
v-if="ui.entry_mode_simple">
|
@keyup.enter="addItem"
|
||||||
<i class="btn fas fa-cart-plus" @click="addItem"/>
|
ref="amount_input_simple"></b-form-input>
|
||||||
</b-button>
|
<b-input-group-append>
|
||||||
</b-row>
|
<b-button variant="success">
|
||||||
|
<i class="fas fa-cart-plus" @click="addItem"/>
|
||||||
|
</b-button>
|
||||||
|
</b-input-group-append>
|
||||||
|
</b-input-group>
|
||||||
|
</b-col>
|
||||||
|
</b-row>
|
||||||
|
|
||||||
</div>
|
<!-- shopping list table -->
|
||||||
<!-- shopping list table -->
|
|
||||||
|
|
||||||
<b-row v-for="c in shopping_list_store.category_food_entries" v-bind:key="c.id" class="pr-4 pl-4">
|
<b-row v-for="c in shopping_list_store.category_food_entries" v-bind:key="c.id" class="pr-4 pl-4">
|
||||||
<b-col cols="12">
|
<b-col cols="12">
|
||||||
<b-button-group class="w-100 mt-1">
|
<b-button-group class="w-100 mt-1">
|
||||||
<b-button variant="light" block class="btn btn-block text-left">
|
<b-button variant="light" block class="btn btn-block text-left">
|
||||||
<span v-if="c.id === -1">{{$t('Undefined')}}</span>
|
<span v-if="c.id === -1">{{ $t('Undefined') }}</span>
|
||||||
<span v-else>{{ c.name}}</span>
|
<span v-else>{{ c.name }}</span>
|
||||||
</b-button>
|
</b-button>
|
||||||
<b-button variant="success"><i class="fas fa-check"></i></b-button> <!-- todo implement -->
|
<b-button variant="success"><i class="fas fa-check"></i></b-button> <!-- todo implement -->
|
||||||
</b-button-group>
|
</b-button-group>
|
||||||
|
|
||||||
<span v-for="f in c.foods" v-bind:key="f.id">
|
<span v-for="f in c.foods" v-bind:key="f.id">
|
||||||
<shopping-line-item :entries="f['entries']" class="mt-1"/>
|
<shopping-line-item :entries="f['entries']" class="mt-1"/>
|
||||||
</span>
|
</span>
|
||||||
</b-col>
|
</b-col>
|
||||||
</b-row>
|
</b-row>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</b-tab>
|
</b-tab>
|
||||||
<!-- recipe tab -->
|
<!-- recipe tab -->
|
||||||
<b-tab :title="$t('Recipes')">
|
<b-tab :title="$t('Recipes')">
|
||||||
@@ -530,7 +466,7 @@
|
|||||||
<div class="d-flex flex-row justify-content-around mb-3">
|
<div class="d-flex flex-row justify-content-around mb-3">
|
||||||
|
|
||||||
<b-input-group>
|
<b-input-group>
|
||||||
<b-form-input v-model="new_item.ingredient" :placeholder="$t('Food')"></b-form-input>
|
<b-form-input v-model="new_item.ingredient" :placeholder="$t('Food')" @keyup.enter="addItem"></b-form-input>
|
||||||
<b-input-group-append>
|
<b-input-group-append>
|
||||||
<b-button @click="addItem" variant="success">
|
<b-button @click="addItem" variant="success">
|
||||||
<i class="fas fa-cart-plus "/>
|
<i class="fas fa-cart-plus "/>
|
||||||
@@ -597,7 +533,6 @@ export default {
|
|||||||
ContextMenuItem,
|
ContextMenuItem,
|
||||||
ShoppingLineItem,
|
ShoppingLineItem,
|
||||||
GenericMultiselect,
|
GenericMultiselect,
|
||||||
LookupInput,
|
|
||||||
DownloadPDF,
|
DownloadPDF,
|
||||||
DownloadCSV,
|
DownloadCSV,
|
||||||
CopyToClipboard,
|
CopyToClipboard,
|
||||||
@@ -918,43 +853,27 @@ export default {
|
|||||||
},
|
},
|
||||||
// this.genericAPI inherited from ApiMixin
|
// this.genericAPI inherited from ApiMixin
|
||||||
addItem: function () {
|
addItem: function () {
|
||||||
if (this.ui.entry_mode_simple) {
|
|
||||||
if (this.new_item.ingredient !== "" && this.new_item.ingredient !== undefined) {
|
|
||||||
this.genericPostAPI("api_ingredient_from_string", {text: this.new_item.ingredient}).then((result) => {
|
|
||||||
let unit = null
|
|
||||||
if (result.data.unit !== null) {
|
|
||||||
unit = {name: result.data.unit}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.new_item = {
|
if (this.new_item.ingredient !== "" && this.new_item.ingredient !== undefined) {
|
||||||
amount: result.data.amount,
|
this.genericPostAPI("api_ingredient_from_string", {text: this.new_item.ingredient}).then((result) => {
|
||||||
unit: unit,
|
let unit = null
|
||||||
food: {name: result.data.food},
|
if (result.data.unit !== null) {
|
||||||
}
|
unit = {name: result.data.unit}
|
||||||
this.addEntry()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.addEntry()
|
|
||||||
}
|
|
||||||
this.setFocus()
|
|
||||||
},
|
|
||||||
addEntry: function (x) {
|
|
||||||
let api = new ApiApiFactory()
|
|
||||||
api.createShoppingListEntry(this.new_item)
|
|
||||||
.then((results) => {
|
|
||||||
if (results?.data) {
|
|
||||||
this.items.push(results.data)
|
|
||||||
StandardToasts.makeStandardToast(this, StandardToasts.SUCCESS_CREATE)
|
|
||||||
} else {
|
|
||||||
console.log("no data returned")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO clean up from here on
|
||||||
|
this.new_item = {
|
||||||
|
amount: result.data.amount,
|
||||||
|
unit: unit,
|
||||||
|
food: {name: result.data.food, supermarket_category: null},
|
||||||
|
}
|
||||||
|
this.useShoppingListStore().createObject(this.new_item)
|
||||||
this.new_item = {amount: 1, unit: undefined, food: undefined, ingredient: undefined}
|
this.new_item = {amount: 1, unit: undefined, food: undefined, ingredient: undefined}
|
||||||
this.clear += 1
|
this.clear += 1
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
}
|
||||||
StandardToasts.makeStandardToast(this, StandardToasts.FAIL_CREATE, err)
|
|
||||||
})
|
this.setFocus()
|
||||||
},
|
},
|
||||||
resetFilters: function () {
|
resetFilters: function () {
|
||||||
this.ui.selected_supermarket = undefined
|
this.ui.selected_supermarket = undefined
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="shopping_line_item">
|
<div id="shopping_line_item">
|
||||||
|
|
||||||
<b-button-group class="w-100">
|
<b-button-group class="w-100" v-if="useShoppingListStore().show_checked_entries || !is_checked">
|
||||||
<b-button variant="dark" block class="btn btn-block text-left" @click="detail_modal_visible = true">
|
<b-button :class="{'btn-dark': !is_checked, 'btn-success': is_checked}" block class="btn btn-block text-left" @click="detail_modal_visible = true">
|
||||||
<div class="d-flex ">
|
<div class="d-flex ">
|
||||||
<div class="d-flex flex-column pr-2" v-if="Object.keys(amounts).length> 0">
|
<div class="d-flex flex-column pr-2" v-if="Object.keys(amounts).length> 0">
|
||||||
<span v-for="a in amounts" v-bind:key="a.id">{{ a.amount }} {{ a.unit }}<br/></span>
|
<span v-for="a in amounts" v-bind:key="a.id">{{ a.amount }} {{ a.unit }}<br/></span>
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
|
|
||||||
</b-button>
|
</b-button>
|
||||||
<b-button variant="success" @click="useShoppingListStore().toggleFoodCheckedState(food)"><i class="fas fa-check"></i></b-button>
|
<b-button variant="success" @click="useShoppingListStore().toggleFoodCheckedState(food)" :class="{'btn-success': !is_checked, 'btn-warning': is_checked}"><i class="fas" :class="{'fa-check': !is_checked, 'fa-times': is_checked}"></i></b-button>
|
||||||
</b-button-group>
|
</b-button-group>
|
||||||
|
|
||||||
|
|
||||||
@@ -37,7 +37,7 @@
|
|||||||
|
|
||||||
<b-button variant="info" block @click="detail_modal_visible = false;useShoppingListStore().delayFood(food)">{{$t('Delay')}}</b-button>
|
<b-button variant="info" block @click="detail_modal_visible = false;useShoppingListStore().delayFood(food)">{{$t('Delay')}}</b-button>
|
||||||
|
|
||||||
<b-button variant="danger" block @click="detail_modal_visible = false;useShoppingListStore().deleteFood(food)">{{ $t('Delete') }}</b-button>
|
<b-button variant="danger" block @click="detail_modal_visible = false;useShoppingListStore().deleteFood(food)">{{ $t('Delete_All') }}</b-button>
|
||||||
|
|
||||||
<h6 class="mt-2">Details</h6> <!-- TODO localize -->
|
<h6 class="mt-2">Details</h6> <!-- TODO localize -->
|
||||||
<b-row v-for="e in entries" v-bind:key="e.id">
|
<b-row v-for="e in entries" v-bind:key="e.id">
|
||||||
@@ -60,7 +60,7 @@
|
|||||||
</small></span>
|
</small></span>
|
||||||
|
|
||||||
</b-button>
|
</b-button>
|
||||||
<b-button variant="success"><i class="fas fa-check"></i></b-button> <!-- TODO implement -->
|
<b-button variant="warning" @click="detail_modal_visible = false; useShoppingListStore().deleteObject(e)"><i class="fas fa-trash"></i></b-button> <!-- TODO implement -->
|
||||||
</b-button-group>
|
</b-button-group>
|
||||||
|
|
||||||
</b-col>
|
</b-col>
|
||||||
@@ -99,6 +99,14 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
is_checked: function (){
|
||||||
|
for (let i in this.entries) {
|
||||||
|
if(!this.entries[i].checked){
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
},
|
||||||
food: function () {
|
food: function () {
|
||||||
return this.entries[Object.keys(this.entries)[0]]['food']
|
return this.entries[Object.keys(this.entries)[0]]['food']
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -181,6 +181,7 @@
|
|||||||
"Unit_Alias": "Unit Alias",
|
"Unit_Alias": "Unit Alias",
|
||||||
"Keyword_Alias": "Keyword Alias",
|
"Keyword_Alias": "Keyword Alias",
|
||||||
"Delete_Food": "Delete Food",
|
"Delete_Food": "Delete Food",
|
||||||
|
"Delete_All": "Delete All",
|
||||||
"No_ID": "ID not found, cannot delete.",
|
"No_ID": "ID not found, cannot delete.",
|
||||||
"Meal_Plan_Days": "Future meal plans",
|
"Meal_Plan_Days": "Future meal plans",
|
||||||
"merge_title": "Merge {type}",
|
"merge_title": "Merge {type}",
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ export const useShoppingListStore = defineStore(_STORE_ID, {
|
|||||||
state: () => ({
|
state: () => ({
|
||||||
category_food_entries: {},
|
category_food_entries: {},
|
||||||
|
|
||||||
|
show_checked_entries: false,
|
||||||
|
|
||||||
currently_updating: false,
|
currently_updating: false,
|
||||||
settings: null,
|
settings: null,
|
||||||
}),
|
}),
|
||||||
@@ -31,21 +33,14 @@ export const useShoppingListStore = defineStore(_STORE_ID, {
|
|||||||
* Retrieves all shopping list entries from the API and parses them into a structured object category > food > entry
|
* Retrieves all shopping list entries from the API and parses them into a structured object category > food > entry
|
||||||
*/
|
*/
|
||||||
this.category_food_entries = {}
|
this.category_food_entries = {}
|
||||||
Vue.set(this.category_food_entries, -1, {'id': -1, 'name': '', foods: {}}) //TODO use localization to get name for undefined category
|
Vue.set(this.category_food_entries, -1, {'id': -1, 'name': '', foods: {}})
|
||||||
|
|
||||||
if (!this.currently_updating) {
|
if (!this.currently_updating) {
|
||||||
this.currently_updating = true
|
this.currently_updating = true
|
||||||
let apiClient = new ApiApiFactory()
|
let apiClient = new ApiApiFactory()
|
||||||
apiClient.listShoppingListEntrys().then((r) => {
|
apiClient.listShoppingListEntrys().then((r) => {
|
||||||
r.data.forEach((e) => {
|
r.data.forEach((e) => {
|
||||||
let category = this.getFoodCategory(e.food)
|
this.updateEntryInStructure(e)
|
||||||
if (!(category in this.category_food_entries)) {
|
|
||||||
Vue.set(this.category_food_entries, category, {'id': category, 'name': e.food.supermarket_category.name, foods: {}})
|
|
||||||
}
|
|
||||||
if (!(e.food.id in this.category_food_entries[category]['foods'])) {
|
|
||||||
Vue.set(this.category_food_entries[category]['foods'], e.food.id, {'id': e.food.id, 'name': e.food.name, 'entries': {}})
|
|
||||||
}
|
|
||||||
Vue.set(this.category_food_entries[category]['foods'][e.food.id]['entries'], e.id, e)
|
|
||||||
})
|
})
|
||||||
this.currently_updating = false
|
this.currently_updating = false
|
||||||
})
|
})
|
||||||
@@ -57,7 +52,7 @@ export const useShoppingListStore = defineStore(_STORE_ID, {
|
|||||||
// TODO shared handled in backend?
|
// TODO shared handled in backend?
|
||||||
|
|
||||||
return apiClient.createShoppingListEntry(object).then((r) => {
|
return apiClient.createShoppingListEntry(object).then((r) => {
|
||||||
Vue.set(this.category_food_entries[this.getFoodCategory(r.food)]['foods'][r.food.id][r.id], r.id, r)
|
this.updateEntryInStructure(r.data)
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
StandardToasts.makeStandardToast(this, StandardToasts.FAIL_UPDATE, err)
|
StandardToasts.makeStandardToast(this, StandardToasts.FAIL_UPDATE, err)
|
||||||
})
|
})
|
||||||
@@ -65,7 +60,7 @@ export const useShoppingListStore = defineStore(_STORE_ID, {
|
|||||||
updateObject(object) {
|
updateObject(object) {
|
||||||
let apiClient = new ApiApiFactory()
|
let apiClient = new ApiApiFactory()
|
||||||
return apiClient.updateShoppingListEntry(object.id, object).then((r) => {
|
return apiClient.updateShoppingListEntry(object.id, object).then((r) => {
|
||||||
Vue.set(this.category_food_entries[this.getFoodCategory(r.food)]['foods'][r.food.id][r.id], r.id, r)
|
this.updateEntryInStructure(r.data)
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
StandardToasts.makeStandardToast(this, StandardToasts.FAIL_UPDATE, err)
|
StandardToasts.makeStandardToast(this, StandardToasts.FAIL_UPDATE, err)
|
||||||
})
|
})
|
||||||
@@ -110,6 +105,16 @@ export const useShoppingListStore = defineStore(_STORE_ID, {
|
|||||||
}
|
}
|
||||||
return -1
|
return -1
|
||||||
},
|
},
|
||||||
|
updateEntryInStructure(entry) {
|
||||||
|
let category = this.getFoodCategory(entry.food)
|
||||||
|
if (!(category in this.category_food_entries)) {
|
||||||
|
Vue.set(this.category_food_entries, category, {'id': category, 'name': entry.food.supermarket_category.name, 'foods': {}})
|
||||||
|
}
|
||||||
|
if (!(entry.food.id in this.category_food_entries[category]['foods'])) {
|
||||||
|
Vue.set(this.category_food_entries[category]['foods'], entry.food.id, {'id': entry.food.id, 'name': entry.food.name, 'entries': {}})
|
||||||
|
}
|
||||||
|
Vue.set(this.category_food_entries[category]['foods'][entry.food.id]['entries'], entry.id, entry)
|
||||||
|
},
|
||||||
toggleFoodCheckedState(food) {
|
toggleFoodCheckedState(food) {
|
||||||
/**
|
/**
|
||||||
* function to handle user checking or unchecking a food
|
* function to handle user checking or unchecking a food
|
||||||
|
|||||||
Reference in New Issue
Block a user