@@ -159,25 +93,54 @@
-
-
+
+
- {{ $t("MoveCategory") }}
+ {{ $t("MoveCategory", { category: categoryName(shopcat) }) }}
-
+
+
+
+
+ {{ $t("OnHand") }}
+
+
+
+
+ {{ $t("DelayFor", { hours: delay }) }}
+
+
+
+
+
+
+
+ {{ $t("IgnoreThis", { food: foodName(contextData) }) }}
+
+
x.id === e)[0],
+ id: item?.[0]?.food?.id ?? item?.food?.id,
+ supermarket_category: this.shopping_categories.filter((x) => x?.id === e)?.[0],
}
console.log("food", food, "event", e, "item", item)
this.genericAPI(this.Models.FOOD, this.Actions.UPDATE, food)
.then((result) => {
StandardToasts.makeStandardToast(StandardToasts.SUCCESS_UPDATE)
+ // TODO this needs to change order of saved item to match category or category sort needs to be local instead of based on API
this.items
.filter((x) => x.food.id == food.id)
.forEach((y) => {
@@ -445,6 +416,26 @@ export default {
let idx = this.items.indexOf((x) => x.id === newItem.id)
Vue.set(this.items, idx, newItem)
},
+ foodName: function(value) {
+ console.log(value?.food?.name ?? value?.[0]?.food?.name ?? "")
+ return value?.food?.name ?? value?.[0]?.food?.name ?? ""
+ },
+ ignoreThis: function(item) {
+ return item
+ },
+ onHand: function(item) {
+ return item
+ },
+ delayThis: function(item) {
+ return item
+ },
+ categoryName: function(value) {
+ return this.shopping_categories.filter((x) => x.id == value)[0]?.name ?? ""
+ },
+ stop: function(e) {
+ e.stopPropagation() // default @click.stop not working
+ e.preventDefault() // default @click.stop not working
+ },
},
}
diff --git a/vue/src/components/Ingredient.vue b/vue/src/components/Ingredient.vue
index a15c0ff7d..c9241bfd0 100644
--- a/vue/src/components/Ingredient.vue
+++ b/vue/src/components/Ingredient.vue
@@ -19,18 +19,14 @@
-
- {{ ingredient.food.name }}
+ > -->
+ {{
+ ingredient.food.name
+ }}
{{ ingredient.food.name }}
@@ -44,9 +40,7 @@
-
- {{ ingredient.note }}
-
+ {{ ingredient.note }}
@@ -71,13 +65,7 @@
-
+
@@ -158,10 +146,7 @@ export default {
}
// if we are in add shopping mode start with all checks marked
if (this.add_shopping_mode) {
- this.shop =
- !this.ingredient.food.on_hand &&
- !this.ingredient.food.ignore_shopping &&
- !this.ingredient.food.recipe
+ this.shop = !this.ingredient.food.on_hand && !this.ingredient.food.ignore_shopping && !this.ingredient.food.recipe
}
},
},
@@ -177,9 +162,7 @@ export default {
return this.$t("NotInShopping", { food: this.ingredient.food.name })
} else {
let list = this.shopping_list.filter((x) => x.food.id == this.ingredient.food.id)
- let category =
- this.$t("Category") + ": " + this.ingredient?.food?.supermarket_category?.name ??
- this.$t("Undefined")
+ let category = this.$t("Category") + ": " + this.ingredient?.food?.supermarket_category?.name ?? this.$t("Undefined")
let popover = []
list.forEach((x) => {
@@ -200,9 +183,7 @@ export default {
].join("")
)
})
- return (
- "" + category + " " + popover.join("") + "
"
- )
+ return "" + category + " " + popover.join("") + "
"
}
},
},
diff --git a/vue/src/components/ShoppingLineItem.vue b/vue/src/components/ShoppingLineItem.vue
index f3fe29be6..c56b78409 100644
--- a/vue/src/components/ShoppingLineItem.vue
+++ b/vue/src/components/ShoppingLineItem.vue
@@ -4,7 +4,7 @@
-
+
@@ -13,7 +13,7 @@
aria-expanded="false"
type="button"
class="btn dropdown-toggle btn-link text-decoration-none text-body pr-1 dropdown-toggle-no-caret"
- @click.stop="$emit('open-context-menu', $event, entries[0])"
+ @click.stop="$emit('open-context-menu', $event, entries)"
>
@@ -25,45 +25,75 @@
{{ formatAmount }}
{{ formatUnit }}
-
- {{ formatFood }}
({{ formatHint }})
+
+ {{ formatFood }} {{ formatHint }}
-
{{ formatNotes }}
{{ showDetails ? "Hide" : "Show" }} Details
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+ {{ formatOneRecipe(e) }}
+
-
-
- {{ e.amount }} - {{ e.unit }}- {{ e.recipe }}- {{ e.mealplan }}- {{ e.note }}- {{ e.unit }}
+
{{ formatOneMealPlan(e) }}
+
{{ formatOneCreatedBy(e) }}
+
+
+
{{ formatOneAmount(e) }}
+
{{ formatOneUnit(e) }}
+
{{ formatOneFood(e) }}
+
+
+
+
+
+
+
+
@@ -71,6 +101,10 @@
import Vue from "vue"
import { BootstrapVue } from "bootstrap-vue"
import "bootstrap-vue/dist/bootstrap-vue.css"
+import ContextMenu from "@/components/ContextMenu/ContextMenu"
+import ContextMenuItem from "@/components/ContextMenu/ContextMenuItem"
+import { ApiMixin } from "@/utils/utils"
+import RecipeCard from "./RecipeCard.vue"
Vue.use(BootstrapVue)
@@ -78,8 +112,8 @@ export default {
// TODO ApiGenerator doesn't capture and share error information - would be nice to share error details when available
// or i'm capturing it incorrectly
name: "ShoppingLineItem",
- mixins: [],
- components: {},
+ mixins: [ApiMixin],
+ components: { RecipeCard, ContextMenu, ContextMenuItem },
props: {
entries: {
type: Array,
@@ -89,14 +123,15 @@ export default {
data() {
return {
showDetails: false,
+ recipe: undefined,
}
},
computed: {
formatAmount: function() {
- return this.entries[0].amount
+ return this.formatOneAmount(this.entries[0])
},
formatCategory: function() {
- return this.entries[0]?.food?.supermarket_category?.name ?? this.$t("Undefined")
+ return this.formatOneCategory(this.entries[0]) || this.$t("Undefined")
},
formatChecked: function() {
return false
@@ -109,20 +144,24 @@ export default {
}
},
formatFood: function() {
- return this.entries[0]?.food?.name ?? this.$t("Undefined")
+ return this.formatOneFood(this.entries[0])
},
formatUnit: function() {
- return this.entries[0]?.unit?.name ?? this.$t("Undefined")
+ return this.formatOneUnit(this.entries[0])
},
formatRecipe: function() {
- if (this.entries.length == 1) {
- return this.entries[0]?.recipe_mealplan?.name ?? this.$t("Undefined")
+ if (this.entries?.length == 1) {
+ return this.formatOneMealPlan(this.entries[0]) || ""
} else {
- return [this.entries[0]?.recipe_mealplan?.name ?? this.$t("Undefined"), this.$t("CountMore", { count: this.entries.length - 1 })].join(" ")
+ let mealplan_name = this.entries.filter((x) => x?.recipe_mealplan?.name)
+ return [this.formatOneMealPlan(mealplan_name?.[0]), this.$t("CountMore", { count: this.entries?.length - 1 })].join(" ")
}
},
formatNotes: function() {
- return [this.entries[0]?.recipe_mealplan?.mealplan_note, this.entries?.ingredient_note].filter(String).join("\n")
+ if (this.entries?.length == 1) {
+ return this.formatOneNote(this.entries[0]) || ""
+ }
+ return ""
},
},
watch: {},
@@ -146,10 +185,57 @@ export default {
// this.saveThis(item, false)
// this.$refs.table.refresh()
},
+ formatOneAmount: function(item) {
+ return item?.amount ?? 1
+ },
+ formatOneUnit: function(item) {
+ return item?.unit?.name ?? ""
+ },
+ formatOneCategory: function(item) {
+ return item?.food?.supermarket_category?.name
+ },
+ formatOneFood: function(item) {
+ return item.food.name
+ },
+ formatOneChecked: function(item) {
+ return item.checked
+ },
+ formatOneMealPlan: function(item) {
+ return item?.recipe_mealplan?.name
+ },
+ formatOneRecipe: function(item) {
+ return item?.recipe_mealplan?.recipe_name
+ },
+ formatOneNote: function(item) {
+ if (!item) {
+ item = this.entries[0]
+ }
+ return [item?.recipe_mealplan?.mealplan_note, item?.ingredient_note].filter(String)
+ },
+ formatOneCreatedBy: function(item) {
+ return [item?.created_by.username, "@", this.formatDate(item.created_at)].join(" ")
+ },
+ openRecipeCard: function(e, item) {
+ this.genericAPI(this.Models.RECIPE, this.Actions.FETCH, { id: item.recipe_mealplan.recipe }).then((result) => {
+ let recipe = result.data
+ recipe.steps = undefined
+ this.recipe = true
+ this.$refs.recipe_card.open(e, recipe)
+ })
+ },
},
}
-
+