From a6c46a7420194804bb80ce4c42a2c11fc8e73344 Mon Sep 17 00:00:00 2001 From: Michael Genson <71845777+michael-genson@users.noreply.github.com> Date: Tue, 21 Feb 2023 21:58:41 -0600 Subject: [PATCH] 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 --- ...2108_added_shopping_list_label_settings.py | 69 +++++++ .../ShoppingList/MultiPurposeLabelSection.vue | 65 ++++++ .../Domain/ShoppingList/ShoppingListItem.vue | 11 +- frontend/composables/use-users/preferences.ts | 19 ++ frontend/lang/messages/en-US.json | 1 + frontend/lib/api/types/group.ts | 21 ++ frontend/lib/api/user/group-shopping-lists.ts | 6 + frontend/lib/icons/icons.ts | 2 + frontend/pages/shopping-lists/_id.vue | 130 ++++++++++-- mealie/db/models/group/shopping_list.py | 32 ++- mealie/db/models/labels.py | 6 +- mealie/repos/repository_factory.py | 8 + mealie/repos/seed/seeders.py | 13 +- mealie/routes/groups/controller_labels.py | 12 +- .../groups/controller_shopping_lists.py | 46 +++-- mealie/schema/group/__init__.py | 28 ++- mealie/schema/group/group_shopping_list.py | 39 +++- .../services/group_services/labels_service.py | 45 +++++ .../services/group_services/shopping_lists.py | 25 ++- .../test_shopping_list_labels.py | 191 ++++++++++++++++++ .../backup_v2_tests/test_backup_v2.py | 2 +- tests/utils/api_routes/__init__.py | 5 + 22 files changed, 715 insertions(+), 61 deletions(-) create mode 100644 alembic/versions/2023-02-21-22.03.19_b04a08da2108_added_shopping_list_label_settings.py create mode 100644 frontend/components/Domain/ShoppingList/MultiPurposeLabelSection.vue create mode 100644 mealie/services/group_services/labels_service.py create mode 100644 tests/integration_tests/user_group_tests/test_shopping_list_labels.py diff --git a/alembic/versions/2023-02-21-22.03.19_b04a08da2108_added_shopping_list_label_settings.py b/alembic/versions/2023-02-21-22.03.19_b04a08da2108_added_shopping_list_label_settings.py new file mode 100644 index 000000000..da426cb7a --- /dev/null +++ b/alembic/versions/2023-02-21-22.03.19_b04a08da2108_added_shopping_list_label_settings.py @@ -0,0 +1,69 @@ +"""added shopping list label settings + +Revision ID: b04a08da2108 +Revises: 5ab195a474eb +Create Date: 2023-21-02 22:03:19.837244 + +""" +from uuid import uuid4 + +import sqlalchemy as sa +from sqlalchemy.orm.session import Session + +import mealie.db.migration_types +from alembic import op +from mealie.db.models.group.shopping_list import ShoppingList +from mealie.db.models.labels import MultiPurposeLabel + +# revision identifiers, used by Alembic. +revision = "b04a08da2108" +down_revision = "5ab195a474eb" +branch_labels = None +depends_on = None + + +def populate_shopping_lists_multi_purpose_labels(shopping_lists_multi_purpose_labels_table: sa.Table, session: Session): + shopping_lists = session.query(ShoppingList).all() + labels = session.query(MultiPurposeLabel).all() + + shopping_lists_labels_data: list[dict] = [] + for shopping_list in shopping_lists: + for i, label in enumerate(labels): + shopping_lists_labels_data.append( + {"id": uuid4(), "shopping_list_id": shopping_list.id, "label_id": label.id, "position": i} + ) + + op.bulk_insert(shopping_lists_multi_purpose_labels_table, shopping_lists_labels_data) + session.commit() + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + shopping_lists_multi_purpose_labels_table = op.create_table( + "shopping_lists_multi_purpose_labels", + sa.Column("created_at", sa.DateTime(), nullable=True), + sa.Column("update_at", sa.DateTime(), nullable=True), + sa.Column("id", mealie.db.migration_types.GUID(), nullable=False), + sa.Column("shopping_list_id", mealie.db.migration_types.GUID(), nullable=False), + sa.Column("label_id", mealie.db.migration_types.GUID(), nullable=False), + sa.Column("position", sa.Integer(), nullable=False), + sa.ForeignKeyConstraint( + ["label_id"], + ["multi_purpose_labels.id"], + ), + sa.ForeignKeyConstraint( + ["shopping_list_id"], + ["shopping_lists.id"], + ), + sa.PrimaryKeyConstraint("id", "shopping_list_id", "label_id"), + ) + # ### end Alembic commands ### + + session = Session(bind=op.get_bind()) + populate_shopping_lists_multi_purpose_labels(shopping_lists_multi_purpose_labels_table, session) + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_table("shopping_lists_multi_purpose_labels") + # ### end Alembic commands ### diff --git a/frontend/components/Domain/ShoppingList/MultiPurposeLabelSection.vue b/frontend/components/Domain/ShoppingList/MultiPurposeLabelSection.vue new file mode 100644 index 000000000..53c2a8bc1 --- /dev/null +++ b/frontend/components/Domain/ShoppingList/MultiPurposeLabelSection.vue @@ -0,0 +1,65 @@ + + + diff --git a/frontend/components/Domain/ShoppingList/ShoppingListItem.vue b/frontend/components/Domain/ShoppingList/ShoppingListItem.vue index 5c9a09eb9..f3a3b3a6c 100644 --- a/frontend/components/Domain/ShoppingList/ShoppingListItem.vue +++ b/frontend/components/Domain/ShoppingList/ShoppingListItem.vue @@ -2,6 +2,7 @@
- +