shopping list supermarket rework

This commit is contained in:
Kaibu
2022-04-23 20:44:46 +02:00
parent b79bc0d9a8
commit fcfef255c1
3 changed files with 368 additions and 278 deletions

View File

@@ -93,7 +93,7 @@
<b-card-body class="p-4" v-if="meal_type.editing"> <b-card-body class="p-4" v-if="meal_type.editing">
<div class="form-group"> <div class="form-group">
<label>{{ $t("Name") }}</label> <label>{{ $t("Name") }}</label>
<input class="form-control" placeholder="Name" v-model="meal_type.name" /> <input class="form-control" :placeholder="$t('Name')" v-model="meal_type.name" />
</div> </div>
<div class="form-group"> <div class="form-group">
<emoji-input :field="'icon'" :label="$t('Icon')" :value="meal_type.icon"></emoji-input> <emoji-input :field="'icon'" :label="$t('Icon')" :value="meal_type.icon"></emoji-input>

View File

@@ -33,7 +33,7 @@
<template #title> <template #title>
<b-spinner v-if="loading" type="border" small class="d-inline-block"></b-spinner> <b-spinner v-if="loading" type="border" small class="d-inline-block"></b-spinner>
<i v-if="!loading" class="fas fa-shopping-cart fa-fw d-inline-block d-md-none"></i> <i v-if="!loading" class="fas fa-shopping-cart fa-fw d-inline-block d-md-none"></i>
<span class="d-none d-md-block">{{ $t('Shopping_list') }}</span> <span class="d-none d-inline-block">{{ $t('Shopping_list') }}</span>
</template> </template>
<div class="container p-0 p-md-3" id="shoppinglist"> <div class="container p-0 p-md-3" id="shoppinglist">
<div class="row"> <div class="row">
@@ -260,236 +260,179 @@
<div class="container p-0"> <div class="container p-0">
<div class="row"> <div class="row">
<div class="col col-md-12 p-0 p-lg-3"> <div class="col col-md-12 p-0 p-lg-3">
<div role="tablist"> <b-col role="tablist">
<!-- add to shopping form --> <!-- add to shopping form -->
<div class="container"> <div class="container">
<div class="row justify-content-center"> <b-row>
<!-- supermarkets column --> <b-col cols="12" md="6">
<div class="col col-md-5"> <h5>{{ $t("Supermarkets") }}</h5>
<b-card no-body> <b-list-group>
<template #header> <b-card no-body class="mt-1 list-group-item p-2"
<h4 class="mb-0"> v-for="(supermarket, index) in supermarkets" v-hover
{{ $t("Supermarkets") }} :key="supermarket.id">
<b-button <b-card-header class="p-2 border-0">
variant="link" <b-row>
class="p-0 m-0 float-right" <b-col cols="12">
@click=" <h5 class="mt-1 mb-1">
new_supermarket.entrymode = !new_supermarket.entrymode {{ supermarket.name }}
new_supermarket.value = undefined <span class="float-right text-primary"
new_supermarket.editmode = false style="cursor: pointer"
new_category.entrymode = false ><i class="fa"
supermarkets = supermarkets.map((x) => { v-bind:class="{ 'fa-pen': !supermarket.editing, 'fa-save': supermarket.editing }"
return { ...x, editmode: false } @click="editOrSaveSupermarket(index)"
}) aria-hidden="true"></i
" ></span>
> </h5>
<i class="btn fas fa-plus-circle fa-lg px-0" </b-col>
:class="new_supermarket.entrymode ? 'text-success' : 'text-primary'"/> </b-row>
</b-button> </b-card-header>
</h4> <b-card-body class="p-4" v-if="supermarket.editing">
</template> <div class="form-group">
<b-card <label>{{ $t("Name") }}</label>
class="pt-5 pl-5 pr-5" <input class="form-control" :placeholder="$t('Name')"
border-variant="success" v-model="supermarket.name"/>
header-bg-variant="success" </div>
header-text-variant="white" <div class="form-group">
align="center" <label>{{ $t("Description") }}</label>
v-if="new_supermarket.entrymode" <input class="form-control" :placeholder="$t('Description')"
:header="new_supermarket.value ? new_supermarket.value : $t('SupermarketName')" v-model="supermarket.description"/>
> </div>
<b-input-group> <button class="btn btn-danger"
<b-form-input type="text" class="form-control-append" @click="deleteSupermarket(index)">
:placeholder="$t('SupermarketName')" {{ $t("Delete") }}
v-model="new_supermarket.value"/> </button>
<b-input-group-append> <button class="btn btn-primary float-right" @click="editOrSaveSupermarket(index)">
<b-button class="input-group-append" variant="success" {{ $t("Save") }}
</button>
</b-card-body>
</b-card>
</b-list-group>
<button class="btn btn-success float-right mt-1"
@click="addSupermarket"> @click="addSupermarket">
<i class="pr-2 pt-1 fas fa-save"></i> {{ $t("Create") }} <i class="fas fa-plus"></i>
</b-button> {{ $t("New_Supermarket") }}
</b-input-group-append> </button>
</b-input-group> </b-col>
</b-card> <b-col cols="12" md="6">
<h5 v-if="editingSupermarket.length > 0">{{ $t("Shopping_Categories") }} -
<b-card-body class="m-0 p-0"> {{ editingSupermarket[0].name }}</h5>
<b-card class="mt-1 p-0" v-for="s in supermarkets" <h5 v-else>{{ $t("Shopping_Categories") }}</h5>
v-bind:key="s.id"> <div v-if="editingSupermarket.length === 0">
<b-card-header class="p-2 border-0 pt-3"> <b-list-group>
<div class="row"> <b-card no-body class="mt-1 list-group-item p-2"
<div class="col-12"> v-for="(category, index) in supermarket_categories" v-hover
<h5 class="mt-1 mb-1"> :key="category.id">
{{ s.name }}
<b-button
variant="link"
class="p-0 m-0 float-right"
@click="
s.editmode = !s.editmode
new_category.entrymode = false
new_supermarket.entrymode = false
editSupermarket(s)
"
>
<i class="btn fas fa-edit fa-lg px-0"
:class="s.editmode ? 'text-success' : 'text-primary'"/>
</b-button>
<b-button variant="link"
class="p-0 m-0 float-right"
@click="deleteSupermarket(s)">
<i class="btn fas fa-trash fa-lg px-2 text-danger"/>
</b-button>
</h5>
</div>
</div>
</b-card-header>
<b-card-body class="m-0 p-0">
<generic-pill :item_list="s.category_to_supermarket"
label="category::name"
color="info"></generic-pill>
</b-card-body>
</b-card>
</b-card-body>
</b-card>
</div>
<div class="col col-md-5">
<b-card>
<template #header>
<h4 class="mb-0">
{{ $t("Shopping_Categories") }}
<b-button
variant="link"
class="p-0 m-0 float-right"
@click="
new_category.entrymode = !new_category.entrymode
new_supermarket.entrymode = false
"
>
<i class="btn fas fa-plus-circle fa-lg px-0"
:class="new_category.entrymode ? 'text-success' : 'text-primary'"/>
</b-button>
</h4>
</template>
<b-card
class="m-1 p-1 no-body"
border-variant="success"
header-bg-variant="success"
header-text-variant="white"
align="center"
v-if="new_category.entrymode"
:header="new_category.value ? new_category.value : $t('CategoryName')"
>
<b-input-group>
<b-form-input type="text" class="form-control-append"
:placeholder="$t('CategoryName')"
v-model="new_category.value"/>
<b-input-group-append>
<b-button class="input-group-append" variant="success"
@click="addCategory"><i
class="pr-2 pt-1 fas fa-save"></i> {{ $t("Create") }}
</b-button>
</b-input-group-append>
</b-input-group>
</b-card>
<b-card-sub-title v-if="new_supermarket.editmode" class="pt-0 pb-3">
{{ $t("CategoryInstruction") }}
</b-card-sub-title>
<b-card
v-if="new_supermarket.editmode && supermarketCategory.length === 0"
class="m-0 p-0 font-weight-bold no-body" border-variant="success"
v-bind:key="-1"/>
<draggable
class="list-group"
:list="supermarketCategory"
group="category"
@start="drag = true"
@end="drag = false"
ghost-class="ghost"
@change="saveSupermarketCategoryOrder"
v-bind="{ animation: 200, disabled: !new_supermarket.editmode }"
>
<transition-group type="transition"
:name="!drag ? 'flip-list' : null">
<b-card
no-body
v-hover
class="mt-1 list-group-item p-2"
:style="new_supermarket.editmode ? 'cursor:move' : ''"
v-for="c in supermarketCategory"
v-bind:key="c.id"
:border-variant="new_supermarket.editmode ? 'success' : ''"
>
<b-card-header class="p-2 border-0"> <b-card-header class="p-2 border-0">
<div class="row"> <b-row>
<div class="col-2" v-if="new_supermarket.editmode"> <b-col cols="12">
<button type="button"
class="btn btn-lg shadow-none"><i
class="fas fa-arrows-alt-v"></i></button>
</div>
<div
:class="new_supermarket.editmode ? 'col-10' : 'col-12'">
<h5 class="mt-1 mb-1"> <h5 class="mt-1 mb-1">
{{ categoryName(c) }} {{ category.name }}
<b-button variant="link" <span class="float-right text-primary"
class="p-0 m-0 float-right" style="cursor: pointer"
@click="deleteCategory(c)"> ><i class="fa"
<i class="btn fas fa-trash fa-lg px-2 text-danger"/> v-bind:class="{ 'fa-pen': !category.editing, 'fa-save': category.editing }"
</b-button> @click="editOrSaveSupermarketCategory(index)"
aria-hidden="true"></i
></span>
</h5> </h5>
</div> </b-col>
</div> </b-row>
</b-card-header> </b-card-header>
<b-card-body class="p-4" v-if="category.editing">
<div class="form-group">
<label>{{ $t("Name") }}</label>
<input class="form-control" :placeholder="$t('Name')"
v-model="category.name"/>
</div>
<div class="form-group">
<label>{{ $t("Description") }}</label>
<input class="form-control"
:placeholder="$t('Description')"
v-model="category.description"/>
</div>
<button class="btn btn-danger"
@click="deleteSupermarketCategory(index)">
{{ $t("Delete") }}
</button>
<button class="btn btn-primary float-right"
@click="editOrSaveSupermarketCategory(index)">
{{ $t("Save") }}
</button>
</b-card-body>
</b-card> </b-card>
</transition-group> </b-list-group>
</draggable> <button class="btn btn-success float-right mt-1"
<hr style="height: 2px; background-color: black" @click="addSupermarketCategory">
v-if="new_supermarket.editmode"/> <i class="fas fa-plus"></i>
<b-card {{ $t("New_Supermarket_Category") }}
v-if="new_supermarket.editmode && notSupermarketCategory.length === 0" </button>
v-bind:key="-2" class="m-0 p-0 font-weight-bold no-body" </div>
border-variant="danger"/> <div v-else>
<draggable <draggable :list="editing_supermarket_categories" group="categories"
class="list-group" :empty-insert-threshold="10"
:list="notSupermarketCategory" @sort="sortSupermarketCategories"
group="category" ghost-class="ghost">
@start="drag = true" <b-card no-body class="mt-1 list-group-item p-2"
@end="drag = false"
ghost-class="ghost"
v-if="new_supermarket.editmode"
v-bind="{ animation: 200 }"
>
<transition-group type="transition"
:name="!drag ? 'flip-list' : null">
<b-card no-body v-hover class="mt-1 list-group-item p-2"
style="cursor: move" style="cursor: move"
v-for="c in notSupermarketCategory" v-bind:key="c.id" v-for="(category, index) in editing_supermarket_categories"
:border-variant="'danger'"> v-hover
:key="category.id">
<b-card-header class="p-2 border-0"> <b-card-header class="p-2 border-0">
<div class="row"> <div class="row">
<div class="col-2" v-if="new_supermarket.editmode"> <div class="col-2">
<button type="button" <button type="button"
class="btn btn-lg shadow-none"><i class="btn btn-lg shadow-none"><i
class="fas fa-arrows-alt-v"></i></button> class="fas fa-arrows-alt-v"></i></button>
</div> </div>
<div <div class="col-10">
:class="new_supermarket.editmode ? 'col-10' : 'col-12'">
<h5 class="mt-1 mb-1"> <h5 class="mt-1 mb-1">
{{ categoryName(c) }} <b-badge class="float-left text-white mr-2">
<b-button variant="link" #{{ index + 1 }}
class="p-0 m-0 float-right" </b-badge>
@click="deleteCategory(c)"> {{ category.name }}
<i class="btn fas fa-trash fa-lg px-2 text-primary"/> <span class="float-right text-primary"
</b-button> style="cursor: pointer"
><i class="fa fa-minus-circle"
@click="removeSupermarketCategoryRelation(index)"
aria-hidden="true"></i
></span>
</h5> </h5>
</div> </div>
</div> </div>
</b-card-header> </b-card-header>
</b-card> </b-card>
</transition-group>
</draggable> </draggable>
<h5>{{ $t("Available") }}</h5>
<draggable :list="unusedSupermarketCategories" group="categories"
:empty-insert-threshold="10"
@sort="sortSupermarketCategories"
ghost-class="ghost">
<b-card no-body class="mt-1 list-group-item p-2"
style="cursor: move"
v-for="(category) in unusedSupermarketCategories"
v-hover
:key="category.id">
<b-card-header class="p-2 border-0">
<div class="row">
<div class="col-2">
<button type="button"
class="btn btn-lg shadow-none"><i
class="fas fa-arrows-alt-v"></i></button>
</div>
<div class="col-10">
<h5 class="mt-1 mb-1">
{{ category.name }}
</h5>
</div>
</div>
</b-card-header>
</b-card> </b-card>
</draggable>
</div> </div>
</b-col>
</b-row>
</div> </div>
</div> </b-col>
</div>
</div> </div>
</div> </div>
</div> </div>
@@ -811,6 +754,7 @@ import Vue from "vue"
import {BootstrapVue} from "bootstrap-vue" import {BootstrapVue} from "bootstrap-vue"
import "bootstrap-vue/dist/bootstrap-vue.css" import "bootstrap-vue/dist/bootstrap-vue.css"
import VueCookies from "vue-cookies" import VueCookies from "vue-cookies"
import draggable from "vuedraggable"
import ContextMenu from "@/components/ContextMenu/ContextMenu" import ContextMenu from "@/components/ContextMenu/ContextMenu"
import ContextMenuItem from "@/components/ContextMenu/ContextMenuItem" import ContextMenuItem from "@/components/ContextMenu/ContextMenuItem"
@@ -819,10 +763,8 @@ import DownloadPDF from "@/components/Buttons/DownloadPDF"
import DownloadCSV from "@/components/Buttons/DownloadCSV" import DownloadCSV from "@/components/Buttons/DownloadCSV"
import CopyToClipboard from "@/components/Buttons/CopyToClipboard" import CopyToClipboard from "@/components/Buttons/CopyToClipboard"
import GenericMultiselect from "@/components/GenericMultiselect" import GenericMultiselect from "@/components/GenericMultiselect"
import GenericPill from "@/components/GenericPill"
import LookupInput from "@/components/Modals/LookupInput" import LookupInput from "@/components/Modals/LookupInput"
import ShoppingModal from "@/components/Modals/ShoppingModal" import ShoppingModal from "@/components/Modals/ShoppingModal"
import draggable from "vuedraggable"
import {ApiMixin, getUserPreference, StandardToasts, makeToast} from "@/utils/utils" import {ApiMixin, getUserPreference, StandardToasts, makeToast} from "@/utils/utils"
import {ApiApiFactory} from "@/utils/openapi/api" import {ApiApiFactory} from "@/utils/openapi/api"
@@ -839,13 +781,12 @@ export default {
ContextMenuItem, ContextMenuItem,
ShoppingLineItem, ShoppingLineItem,
GenericMultiselect, GenericMultiselect,
GenericPill,
draggable,
LookupInput, LookupInput,
DownloadPDF, DownloadPDF,
DownloadCSV, DownloadCSV,
CopyToClipboard, CopyToClipboard,
ShoppingModal, ShoppingModal,
draggable
}, },
data() { data() {
@@ -862,6 +803,8 @@ export default {
shopcat: null, shopcat: null,
delay: 0, delay: 0,
clear: Math.random(), clear: Math.random(),
generic_action: null,
generic_model: null,
ui: { ui: {
entry_mode_simple: true, entry_mode_simple: true,
selected_supermarket: undefined, selected_supermarket: undefined,
@@ -879,6 +822,8 @@ export default {
shopping_add_onhand: true, shopping_add_onhand: true,
left_handed: false, left_handed: false,
}, },
editing_supermarket_categories: [],
editing_supermarket: null,
new_supermarket: {entrymode: false, value: undefined, editmode: undefined}, new_supermarket: {entrymode: false, value: undefined, editmode: undefined},
new_category: {entrymode: false, value: undefined}, new_category: {entrymode: false, value: undefined},
autosync_id: undefined, autosync_id: undefined,
@@ -979,6 +924,18 @@ export default {
defaultDelay() { defaultDelay() {
return Number(getUserPreference("default_delay")) || 2 return Number(getUserPreference("default_delay")) || 2
}, },
editingSupermarket() {
return this.supermarkets.filter((el) => {
return el.editing
})
},
unusedSupermarketCategories() {
if (this.editingSupermarket.length > 0) {
return this.supermarket_categories.filter(a => !this.editing_supermarket_categories.map(b => b.id).includes(a.id))
} else {
return []
}
},
formUnit() { formUnit() {
let unit = this.Models.SHOPPING_LIST.create.form.unit let unit = this.Models.SHOPPING_LIST.create.form.unit
unit.value = this.new_item.unit unit.value = this.new_item.unit
@@ -999,10 +956,10 @@ export default {
// hiding recipes associated with shopping list items that are complete // hiding recipes associated with shopping list items that are complete
return [...new Map(this.items.filter((x) => x.list_recipe && !x.checked).map((item) => [item["list_recipe"], item])).values()] return [...new Map(this.items.filter((x) => x.list_recipe && !x.checked).map((item) => [item["list_recipe"], item])).values()]
}, },
supermarketCategory() { supermarket_categories() {
return this.new_supermarket.editmode ? this.new_supermarket.value.category_to_supermarket : this.shopping_categories return this.new_supermarket.editmode ? this.new_supermarket.value.category_to_supermarket : this.shopping_categories
}, },
notSupermarketCategory() { notsupermarket_categories() {
let supercats = this.new_supermarket.value.category_to_supermarket let supercats = this.new_supermarket.value.category_to_supermarket
.map((x) => x.category) .map((x) => x.category)
.flat() .flat()
@@ -1146,32 +1103,6 @@ export default {
StandardToasts.makeStandardToast(this, StandardToasts.FAIL_CREATE, err) StandardToasts.makeStandardToast(this, StandardToasts.FAIL_CREATE, err)
}) })
}, },
deleteSupermarket: function (s) {
let api = new ApiApiFactory()
api.destroySupermarket(s.id)
.then(() => {
this.getSupermarkets()
StandardToasts.makeStandardToast(this, StandardToasts.SUCCESS_DELETE)
})
.catch((err) => {
StandardToasts.makeStandardToast(this, StandardToasts.FAIL_DELETE, err)
})
},
deleteCategory: function (c) {
// could be category relation or a catory
let c_id = c?.category?.id ?? c.id
let api = new ApiApiFactory()
api.destroySupermarketCategory(c_id)
.then(() => {
this.getSupermarkets()
this.getShoppingCategories()
this.new_supermarket.value.category_to_supermarket = this.new_supermarket.value.category_to_supermarket.filter((x) => x.category.id != c_id)
StandardToasts.makeStandardToast(this, StandardToasts.SUCCESS_DELETE)
})
.catch((err) => {
StandardToasts.makeStandardToast(this, StandardToasts.FAIL_DELETE, err)
})
},
resetFilters: function () { resetFilters: function () {
this.ui.selected_supermarket = undefined this.ui.selected_supermarket = undefined
this.supermarket_categories_only = this.settings.filter_to_supermarket this.supermarket_categories_only = this.settings.filter_to_supermarket
@@ -1237,22 +1168,15 @@ export default {
StandardToasts.makeStandardToast(this, StandardToasts.SUCCESS_DELETE) StandardToasts.makeStandardToast(this, StandardToasts.SUCCESS_DELETE)
}) })
}, },
editSupermarket(s) {
if (!s.editmode) {
this.new_supermarket = {entrymode: false, value: undefined, editmode: undefined}
this.supermarkets.map((x) => (x.editmode = false))
} else {
this.new_supermarket.value = s
this.new_supermarket.editmode = true
this.supermarkets.filter((x) => x.id !== s.id).map((x) => (x.editmode = false))
}
},
foodName: function (value) { foodName: function (value) {
return value?.food?.name ?? value?.[0]?.food?.name ?? "" return value?.food?.name ?? value?.[0]?.food?.name ?? ""
}, },
getShoppingCategories: function () { getShoppingCategories: function () {
let api = new ApiApiFactory() let api = new ApiApiFactory()
api.listSupermarketCategorys().then((result) => { api.listSupermarketCategorys().then((result) => {
result.data.forEach((category) => {
category.editing = false
})
this.shopping_categories = result.data this.shopping_categories = result.data
}) })
}, },
@@ -1290,6 +1214,9 @@ export default {
getSupermarkets: function () { getSupermarkets: function () {
let api = new ApiApiFactory() let api = new ApiApiFactory()
api.listSupermarkets().then((result) => { api.listSupermarkets().then((result) => {
result.data.forEach((supermarket) => {
supermarket.editing = false
})
this.supermarkets = result.data this.supermarkets = result.data
}) })
}, },
@@ -1457,22 +1384,36 @@ export default {
this.getShoppingList() this.getShoppingList()
}) })
}, },
addCategory: function () { deleteSupermarket(index) {
let api = new ApiApiFactory() this.$bvModal.msgBoxConfirm(this.$t('Are_You_Sure'), {
api.createSupermarketCategory({name: this.new_category.value}) title: this.$t('Confirm'),
.then((result) => { size: 'md',
StandardToasts.makeStandardToast(this, StandardToasts.SUCCESS_CREATE) buttonSize: 'sm',
this.shopping_categories.push(result.data) okVariant: 'success',
this.new_category.value = undefined headerClass: 'p-3 border-bottom-0',
footerClass: 'p-3 border-top-0 justify-content-center',
centered: true,
cancelTitle: this.$t('Cancel'),
okTitle: this.$t('Delete')
}).then(value => {
if (value) {
let apiClient = new ApiApiFactory()
apiClient.destroySupermarket(this.supermarkets[index].id)
.then((e) => {
this.getShoppingList()
this.getSupermarkets()
this.getShoppingCategories()
StandardToasts.makeStandardToast(this, StandardToasts.SUCCESS_DELETE)
}) })
.catch((err) => { .catch((err) => {
console.log(err, Object.keys(err)) StandardToasts.makeStandardToast(this, StandardToasts.FAIL_DELETE, err)
StandardToasts.makeStandardToast(this, StandardToasts.FAIL_CREATE) })
}
}) })
}, },
addSupermarket: function () { addSupermarket: function () {
let api = new ApiApiFactory() let api = new ApiApiFactory()
api.createSupermarket({name: this.new_supermarket.value}) api.createSupermarket({name: this.$t('Supermarket') + Math.floor(1000 + Math.random() * 9000)})
.then((result) => { .then((result) => {
StandardToasts.makeStandardToast(this, StandardToasts.SUCCESS_CREATE) StandardToasts.makeStandardToast(this, StandardToasts.SUCCESS_CREATE)
this.supermarkets.push(result.data) this.supermarkets.push(result.data)
@@ -1483,7 +1424,152 @@ export default {
StandardToasts.makeStandardToast(this, StandardToasts.FAIL_CREATE) StandardToasts.makeStandardToast(this, StandardToasts.FAIL_CREATE)
}) })
}, },
saveSupermarketCategoryOrder(e) { editOrSaveSupermarket(index) {
let supermarket = this.supermarkets[index]
if (supermarket.editing) {
this.$set(this.supermarkets[index], "editing", false)
this.editing_supermarket_categories = []
let apiClient = new ApiApiFactory()
apiClient
.updateSupermarket(this.supermarkets[index].id, this.supermarkets[index])
.then((e) => {
this.periodChangedCallback(this.current_period)
StandardToasts.makeStandardToast(this, StandardToasts.SUCCESS_UPDATE)
})
.catch((err) => {
StandardToasts.makeStandardToast(this, StandardToasts.FAIL_UPDATE, err)
})
} else {
this.supermarkets.forEach((market, i) => {
if (i !== index) {
this.$set(this.supermarkets[i], "editing", false)
}
})
this.$set(this.supermarkets[index], "editing", true)
this.editing_supermarket_categories = []
this.supermarkets[index].category_to_supermarket.forEach((cur, i) => {
this.editing_supermarket_categories.push({
name: cur.category.name,
description: cur.category.description,
id: cur.category.id,
relation_id: cur.id,
order: cur.order,
supermarket: cur.supermarket,
category: cur.category
})
})
}
},
deleteSupermarketCategory(index) {
this.$bvModal.msgBoxConfirm(this.$t('Warning_Delete_Supermarket_Category'), {
title: this.$t('Confirm'),
size: 'md',
buttonSize: 'sm',
okVariant: 'success',
headerClass: 'p-3 border-bottom-0',
footerClass: 'p-3 border-top-0 justify-content-center',
centered: true,
cancelTitle: this.$t('Cancel'),
okTitle: this.$t('Delete')
}).then(value => {
if (value) {
let apiClient = new ApiApiFactory()
apiClient.destroySupermarketCategory(this.supermarket_categories[index].id)
.then((e) => {
this.getShoppingList()
this.getSupermarkets()
this.getShoppingCategories()
StandardToasts.makeStandardToast(this, StandardToasts.SUCCESS_DELETE)
})
.catch((err) => {
StandardToasts.makeStandardToast(this, StandardToasts.FAIL_DELETE, err)
})
}
})
},
addSupermarketCategory() {
let apiClient = new ApiApiFactory()
apiClient.createSupermarketCategory({name: this.$t("Shopping_Category") + Math.floor(1000 + Math.random() * 9000)})
.then((result) => {
StandardToasts.makeStandardToast(this, StandardToasts.SUCCESS_CREATE)
this.shopping_categories.push(result.data)
})
.catch((err) => {
StandardToasts.makeStandardToast(this, StandardToasts.FAIL_CREATE, err)
})
},
editOrSaveSupermarketCategory(index) {
let category = this.supermarket_categories[index]
this.supermarkets.forEach((supermarket) => {
supermarket.category_to_supermarket.forEach((cat) => {
if (cat.category.id === this.supermarket_categories[index].id) {
cat.category = this.supermarket_categories[index]
}
})
})
let apiClient = new ApiApiFactory()
apiClient
.updateSupermarketCategory(this.supermarket_categories[index].id, this.supermarket_categories[index])
.then((e) => {
this.periodChangedCallback(this.current_period)
StandardToasts.makeStandardToast(this, StandardToasts.SUCCESS_UPDATE)
})
.catch((err) => {
StandardToasts.makeStandardToast(this, StandardToasts.FAIL_UPDATE, err)
})
if (category.editing) {
this.$set(this.supermarket_categories[index], "editing", false)
} else {
this.supermarket_categories.forEach((market, i) => {
if (i !== index) {
this.$set(this.supermarket_categories[i], "editing", false)
}
})
this.$set(this.supermarket_categories[index], "editing", true)
}
},
removeSupermarketCategoryRelation(index) {
this.editing_supermarket_categories[index].relation_id
let apiClient = new ApiApiFactory()
apiClient.destroySupermarketCategoryRelation(this.editing_supermarket_categories[index].relation_id)
.then((e) => {
this.editing_supermarket_categories.splice(index, 1);
})
.catch((err) => {
StandardToasts.makeStandardToast(this, StandardToasts.FAIL_DELETE, err)
})
},
sortSupermarketCategories() {
this.editing_supermarket_categories.forEach((element, index) => {
element.order = index
})
this.editing_supermarket_categories.forEach((element, index) => {
let apiClient = new ApiApiFactory()
apiClient.updateSupermarketCategoryRelation(element.relation_id, element)
.then((e) => {
})
.catch((err) => {
StandardToasts.makeStandardToast(this, StandardToasts.FAIL_UPDATE, err)
})
})
},
sortSupermarketCategoriesR(e) {
// TODO: all of this complexity should be moved to the backend // TODO: all of this complexity should be moved to the backend
let apiClient = new ApiApiFactory() let apiClient = new ApiApiFactory()
let supermarket = this.new_supermarket.value let supermarket = this.new_supermarket.value
@@ -1492,7 +1578,7 @@ export default {
var promises = [] var promises = []
supermarket.category_to_supermarket.forEach((x, i) => { supermarket.category_to_supermarket.forEach((x, i) => {
x.order = i x.order = i
promises.push(apiClient.partialUpdateSupermarketCategoryRelation(x.id, {order: i})) promises.push(apiClient.partialUpdatesupermarket_categoriesRelation(x.id, {order: i}))
}) })
return Promise.all(promises).then(() => { return Promise.all(promises).then(() => {
return supermarket return supermarket
@@ -1504,7 +1590,7 @@ export default {
let idx = this.supermarkets.indexOf((x) => x.id === supermarket.id) let idx = this.supermarkets.indexOf((x) => x.id === supermarket.id)
Vue.set(this.supermarkets, idx, supermarket) Vue.set(this.supermarkets, idx, supermarket)
apiClient apiClient
.destroySupermarketCategoryRelation(e.removed.element.id) .destroysupermarket_categoriesRelation(e.removed.element.id)
.then((result) => { .then((result) => {
StandardToasts.makeStandardToast(this, StandardToasts.SUCCESS_UPDATE) StandardToasts.makeStandardToast(this, StandardToasts.SUCCESS_UPDATE)
}) })
@@ -1520,7 +1606,7 @@ export default {
let category = e.added.element.category let category = e.added.element.category
apiClient apiClient
.createSupermarketCategoryRelation({ .createsupermarket_categoriesRelation({
supermarket: supermarket.id, supermarket: supermarket.id,
category: category, category: category,
order: e.added.element.newIndex, order: e.added.element.newIndex,

View File

@@ -403,5 +403,9 @@
"Import_Result_Info": "{imported} of {total} recipes were imported", "Import_Result_Info": "{imported} of {total} recipes were imported",
"Recipes_In_Import": "Recipes in your import file", "Recipes_In_Import": "Recipes in your import file",
"Toggle": "Toggle", "Toggle": "Toggle",
"Import_Error": "An Error occurred during your import. Please expand the Details at the bottom of the page to view it." "Import_Error": "An Error occurred during your import. Please expand the Details at the bottom of the page to view it.",
"Warning_Delete_Supermarket_Category": "Deleting a supermarket category will also delete all relations to foods. Are you sure?",
"New_Supermarket": "Create new supermarket",
"New_Supermarket_Category": "Create new supermarket category",
"Are_You_Sure": "Are you sure?"
} }