Feature: Shopping List Label Section Improvements (#2090)

* added backend for shopping list label config

* updated codegen

* refactored shopping list ops to service
removed unique contraint
removed label settings from main route/schema
added new route for label settings

* codegen

* made sure label settings output in position order

* implemented submenu for label order drag and drop

* removed redundant label and tweaked formatting

* added view by label to user preferences

* made items draggable within each label section

* moved reorder labels to its own button

* made dialog scrollable

* fixed broken model

* refactored labels to use a service
moved shopping list label logic to service
modified label seeder to use service

* added tests

* fix for first label missing the tag icon

* fixed wrong mapped type

* added statement to create existing relationships

* fix restore test, maybe
This commit is contained in:
Michael Genson
2023-02-21 21:58:41 -06:00
committed by GitHub
parent e14851531d
commit a6c46a7420
22 changed files with 715 additions and 61 deletions

View File

@@ -5,7 +5,11 @@ from sqlalchemy.ext.orderinglist import ordering_list
from sqlalchemy.orm import Mapped, mapped_column
from mealie.db.models.labels import MultiPurposeLabel
from mealie.db.models.recipe.api_extras import ShoppingListExtras, ShoppingListItemExtras, api_extras
from mealie.db.models.recipe.api_extras import (
ShoppingListExtras,
ShoppingListItemExtras,
api_extras,
)
from .._model_base import BaseMixins, SqlAlchemyBase
from .._model_utils import GUID, auto_init
@@ -99,6 +103,26 @@ class ShoppingListRecipeReference(BaseMixins, SqlAlchemyBase):
pass
class ShoppingListMultiPurposeLabel(SqlAlchemyBase, BaseMixins):
__tablename__ = "shopping_lists_multi_purpose_labels"
id: Mapped[GUID] = mapped_column(GUID, primary_key=True, default=GUID.generate)
shopping_list_id: Mapped[GUID] = mapped_column(GUID, ForeignKey("shopping_lists.id"), primary_key=True)
shopping_list: Mapped["ShoppingList"] = orm.relationship("ShoppingList", back_populates="label_settings")
label_id: Mapped[GUID] = mapped_column(GUID, ForeignKey("multi_purpose_labels.id"), primary_key=True)
label: Mapped["MultiPurposeLabel"] = orm.relationship(
"MultiPurposeLabel", back_populates="shopping_lists_label_settings"
)
position: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
class Config:
exclude = {"label"}
@auto_init()
def __init__(self, **_) -> None:
pass
class ShoppingList(SqlAlchemyBase, BaseMixins):
__tablename__ = "shopping_lists"
id: Mapped[GUID] = mapped_column(GUID, primary_key=True, default=GUID.generate)
@@ -117,6 +141,12 @@ class ShoppingList(SqlAlchemyBase, BaseMixins):
recipe_references: Mapped[ShoppingListRecipeReference] = orm.relationship(
ShoppingListRecipeReference, cascade="all, delete, delete-orphan"
)
label_settings: Mapped[list["ShoppingListMultiPurposeLabel"]] = orm.relationship(
ShoppingListMultiPurposeLabel,
cascade="all, delete, delete-orphan",
order_by="ShoppingListMultiPurposeLabel.position",
collection_class=ordering_list("position"),
)
extras: Mapped[list[ShoppingListExtras]] = orm.relationship("ShoppingListExtras", cascade="all, delete-orphan")
class Config:

View File

@@ -9,7 +9,8 @@ from ._model_utils import auto_init
from ._model_utils.guid import GUID
if TYPE_CHECKING:
from group import Group, ShoppingListItem
from group import Group
from group.shopping_list import ShoppingListItem, ShoppingListMultiPurposeLabel
from recipe import IngredientFoodModel
@@ -24,6 +25,9 @@ class MultiPurposeLabel(SqlAlchemyBase, BaseMixins):
shopping_list_items: Mapped["ShoppingListItem"] = orm.relationship("ShoppingListItem", back_populates="label")
foods: Mapped["IngredientFoodModel"] = orm.relationship("IngredientFoodModel", back_populates="label")
shopping_lists_label_settings: Mapped[list["ShoppingListMultiPurposeLabel"]] = orm.relationship(
"ShoppingListMultiPurposeLabel", back_populates="label", cascade="all, delete, delete-orphan"
)
@auto_init()
def __init__(self, **_) -> None: