Feature/shopping lists second try (#927)

* generate types

* use generated types

* ui updates

* init button link for common styles

* add links

* setup label views

* add delete confirmation

* reset when not saved

* link label to foods and auto set when adding to shopping list

* generate types

* use inheritence to manage exception handling

* fix schema generation and add test for open_api generation

* add header to api docs

* move list consilidation to service

* split list and list items controller

* shopping list/list item tests - PARTIAL

* enable recipe add/remove in shopping lists

* generate types

* linting

* init global utility components

* update types and add list item api

* fix import cycle and database error

* add container and border classes

* new recipe list component

* fix tests

* breakout item editor

* refactor item editor

* update bulk actions

* update input / color contrast

* type generation

* refactor controller dependencies

* include food/unit editor

* remove console.logs

* fix and update type generation

* fix incorrect type for column

* fix postgres error

* fix delete by variable

* auto remove refs

* fix typo
This commit is contained in:
Hayden
2022-01-16 15:24:24 -09:00
committed by GitHub
parent f794208862
commit 92cf97e401
66 changed files with 2556 additions and 685 deletions

View File

@@ -48,7 +48,7 @@ class GroupEventNotifierModel(SqlAlchemyBase, BaseMixins):
id = Column(GUID, primary_key=True, default=GUID.generate)
name = Column(String, nullable=False)
enabled = Column(String, default=True, nullable=False)
enabled = Column(Boolean, default=True, nullable=False)
apprise_url = Column(String, nullable=False)
group = orm.relationship("Group", back_populates="group_event_notifiers", single_parent=True)

View File

@@ -8,6 +8,20 @@ from .._model_utils import GUID, auto_init
from ..recipe.ingredient import IngredientFoodModel, IngredientUnitModel
class ShoppingListItemRecipeReference(BaseMixins, SqlAlchemyBase):
__tablename__ = "shopping_list_item_recipe_reference"
id = Column(GUID, primary_key=True, default=GUID.generate)
shopping_list_item_id = Column(GUID, ForeignKey("shopping_list_items.id"), primary_key=True)
recipe_id = Column(Integer, ForeignKey("recipes.id"))
recipe = orm.relationship("RecipeModel", back_populates="shopping_list_item_refs")
recipe_quantity = Column(Float, nullable=False)
@auto_init()
def __init__(self, **_) -> None:
pass
class ShoppingListItem(SqlAlchemyBase, BaseMixins):
__tablename__ = "shopping_list_items"
@@ -16,7 +30,6 @@ class ShoppingListItem(SqlAlchemyBase, BaseMixins):
shopping_list_id = Column(GUID, ForeignKey("shopping_lists.id"))
# Meta
recipe_id = Column(Integer, nullable=True)
is_ingredient = Column(Boolean, default=True)
position = Column(Integer, nullable=False, default=0)
checked = Column(Boolean, default=False)
@@ -36,8 +49,30 @@ class ShoppingListItem(SqlAlchemyBase, BaseMixins):
label_id = Column(GUID, ForeignKey("multi_purpose_labels.id"))
label = orm.relationship(MultiPurposeLabel, uselist=False, back_populates="shopping_list_items")
# Recipe Reference
recipe_references = orm.relationship(ShoppingListItemRecipeReference, cascade="all, delete, delete-orphan")
class Config:
exclude = {"id", "label"}
exclude = {"id", "label", "food", "unit"}
@auto_init()
def __init__(self, **_) -> None:
pass
class ShoppingListRecipeReference(BaseMixins, SqlAlchemyBase):
__tablename__ = "shopping_list_recipe_reference"
id = Column(GUID, primary_key=True, default=GUID.generate)
shopping_list_id = Column(GUID, ForeignKey("shopping_lists.id"), primary_key=True)
recipe_id = Column(Integer, ForeignKey("recipes.id"))
recipe = orm.relationship("RecipeModel", uselist=False, back_populates="shopping_list_refs")
recipe_quantity = Column(Float, nullable=False)
class Config:
exclude = {"id", "recipe"}
@auto_init()
def __init__(self, **_) -> None:
@@ -59,6 +94,11 @@ class ShoppingList(SqlAlchemyBase, BaseMixins):
collection_class=ordering_list("position"),
)
recipe_references = orm.relationship(ShoppingListRecipeReference, cascade="all, delete, delete-orphan")
class Config:
exclude = {"id", "list_items"}
@auto_init()
def __init__(self, **_) -> None:
pass

View File

@@ -10,6 +10,7 @@ class MultiPurposeLabel(SqlAlchemyBase, BaseMixins):
__tablename__ = "multi_purpose_labels"
id = Column(GUID, default=GUID.generate, primary_key=True)
name = Column(String(255), nullable=False)
color = Column(String(10), nullable=False, default="")
group_id = Column(GUID, ForeignKey("groups.id"))
group = orm.relationship("Group", back_populates="labels")

View File

@@ -106,6 +106,18 @@ class RecipeModel(SqlAlchemyBase, BaseMixins):
date_added = sa.Column(sa.Date, default=date.today)
date_updated = sa.Column(sa.DateTime)
# Shopping List Refs
shopping_list_refs = orm.relationship(
"ShoppingListRecipeReference",
back_populates="recipe",
cascade="all, delete-orphan",
)
shopping_list_item_refs = orm.relationship(
"ShoppingListItemRecipeReference",
back_populates="recipe",
cascade="all, delete-orphan",
)
class Config:
get_attr = "slug"
exclude = {