From d6e4829e6f932bd2fa0fee548ac7d3f84b24ce7d Mon Sep 17 00:00:00 2001 From: Michael Genson <71845777+michael-genson@users.noreply.github.com> Date: Mon, 21 Aug 2023 12:18:37 -0500 Subject: [PATCH] feat: Display Shopping List Item Recipe Refs (#2501) * added recipe ref display to shopping list items * added backend support for recipe notes * added recipe note to item recipe ref display * fixed note merge bug with 3+ notes * tweak display * lint * updated alembic refs --------- Co-authored-by: Hayden <64056131+hay-kot@users.noreply.github.com> --- ...403_added_recipe_note_to_shopping_list_.py | 28 ++++ .../components/Domain/Recipe/RecipeList.vue | 147 ++++++++++++++++-- .../Domain/ShoppingList/ShoppingListItem.vue | 64 +++++++- frontend/lib/api/types/group.ts | 3 + frontend/pages/shopping-lists/_id.vue | 15 +- mealie/db/models/group/shopping_list.py | 7 +- mealie/schema/group/group_shopping_list.py | 3 + .../services/group_services/shopping_lists.py | 22 ++- 8 files changed, 247 insertions(+), 42 deletions(-) create mode 100644 alembic/versions/2023-08-14-19.30.49_1825b5225403_added_recipe_note_to_shopping_list_.py diff --git a/alembic/versions/2023-08-14-19.30.49_1825b5225403_added_recipe_note_to_shopping_list_.py b/alembic/versions/2023-08-14-19.30.49_1825b5225403_added_recipe_note_to_shopping_list_.py new file mode 100644 index 000000000000..b6a6489016b3 --- /dev/null +++ b/alembic/versions/2023-08-14-19.30.49_1825b5225403_added_recipe_note_to_shopping_list_.py @@ -0,0 +1,28 @@ +"""added recipe note to shopping list recipe ref + +Revision ID: 1825b5225403 +Revises: 04ac51cbe9a4 +Create Date: 2023-08-14 19:30:49.103185 + +""" +import sqlalchemy as sa + +from alembic import op + +# revision identifiers, used by Alembic. +revision = "1825b5225403" +down_revision = "04ac51cbe9a4" +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.add_column("shopping_list_item_recipe_reference", sa.Column("recipe_note", sa.String(), nullable=True)) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_column("shopping_list_item_recipe_reference", "recipe_note") + # ### end Alembic commands ### diff --git a/frontend/components/Domain/Recipe/RecipeList.vue b/frontend/components/Domain/Recipe/RecipeList.vue index 1a3ef0c56186..258714349e1c 100644 --- a/frontend/components/Domain/Recipe/RecipeList.vue +++ b/frontend/components/Domain/Recipe/RecipeList.vue @@ -1,22 +1,28 @@ diff --git a/frontend/components/Domain/ShoppingList/ShoppingListItem.vue b/frontend/components/Domain/ShoppingList/ShoppingListItem.vue index b7d71cac38c6..8934ae1898f9 100644 --- a/frontend/components/Domain/ShoppingList/ShoppingListItem.vue +++ b/frontend/components/Domain/ShoppingList/ShoppingListItem.vue @@ -26,11 +26,37 @@
@@ -38,14 +64,14 @@ - - - {{ $globals.icons.edit }} - -
+ + + + +
@@ -75,7 +101,8 @@ import ShoppingListItemEditor from "./ShoppingListItemEditor.vue"; import MultiPurposeLabel from "./MultiPurposeLabel.vue"; import { ShoppingListItemOut } from "~/lib/api/types/group"; import { MultiPurposeLabelOut, MultiPurposeLabelSummary } from "~/lib/api/types/labels"; -import { IngredientFood, IngredientUnit } from "~/lib/api/types/recipe"; +import { IngredientFood, IngredientUnit, RecipeSummary } from "~/lib/api/types/recipe"; +import RecipeList from "~/components/Domain/Recipe/RecipeList.vue"; interface actions { text: string; @@ -105,10 +132,15 @@ export default defineComponent({ type: Array as () => IngredientFood[], required: true, }, + recipes: { + type: Map, + default: undefined, + } }, setup(props, context) { const { i18n } = useContext(); - const itemLabelCols = ref(props.value.checked ? "auto" : props.showLabel ? "6" : "8"); + const displayRecipeRefs = ref(false); + const itemLabelCols = ref(props.value.checked ? "auto" : props.showLabel ? "4" : "6"); const contextMenu: actions[] = [ { @@ -190,16 +222,34 @@ export default defineComponent({ return undefined; }); + const recipeList = computed(() => { + const recipeList: RecipeSummary[] = []; + if (!listItem.value.recipeReferences) { + return recipeList; + } + + listItem.value.recipeReferences.forEach((ref) => { + const recipe = props.recipes.get(ref.recipeId) + if (recipe) { + recipeList.push(recipe); + } + }); + + return recipeList; + }); + return { updatedLabels, save, contextHandler, + displayRecipeRefs, edit, contextMenu, itemLabelCols, listItem, localListItem, label, + recipeList, toggleEdit, }; }, diff --git a/frontend/lib/api/types/group.ts b/frontend/lib/api/types/group.ts index a0dd0517e00b..42fb45a85461 100644 --- a/frontend/lib/api/types/group.ts +++ b/frontend/lib/api/types/group.ts @@ -359,6 +359,7 @@ export interface ShoppingListItemRecipeRefCreate { recipeId: string; recipeQuantity?: number; recipeScale?: number; + recipeNote?: string; } export interface ShoppingListItemOut { quantity?: number; @@ -387,6 +388,7 @@ export interface ShoppingListItemRecipeRefOut { recipeId: string; recipeQuantity?: number; recipeScale?: number; + recipeNote?: string; id: string; shoppingListItemId: string; } @@ -394,6 +396,7 @@ export interface ShoppingListItemRecipeRefUpdate { recipeId: string; recipeQuantity?: number; recipeScale?: number; + recipeNote?: string; id: string; shoppingListItemId: string; } diff --git a/frontend/pages/shopping-lists/_id.vue b/frontend/pages/shopping-lists/_id.vue index f80f1ff1a9d9..7452ecc8fe32 100644 --- a/frontend/pages/shopping-lists/_id.vue +++ b/frontend/pages/shopping-lists/_id.vue @@ -19,6 +19,7 @@ :labels="allLabels || []" :units="allUnits || []" :foods="allFoods || []" + :recipes="recipeMap" @checked="saveListItem" @save="saveListItem" @delete="deleteListItem(item)" @@ -46,6 +47,7 @@ :labels="allLabels || []" :units="allUnits || []" :foods="allFoods || []" + :recipes="recipeMap" @checked="saveListItem" @save="saveListItem" @delete="deleteListItem(item)" @@ -175,8 +177,8 @@ {{ $tc('shopping-list.linked-recipes-count', shoppingList.recipeReferences ? shoppingList.recipeReferences.length : 0) }}
- -