From 069bab1c018d87abae1022f27d06e95354211126 Mon Sep 17 00:00:00 2001 From: AlexSserb Date: Thu, 13 Mar 2025 19:29:15 +0400 Subject: [PATCH] feat: colors for card tags --- models/card_tag.py | 22 ++++++++++++++++++++-- routers/card_tag.py | 11 +++++++++++ schemas/card_tag.py | 14 +++++++++++++- services/card_tag.py | 18 ++++++++++++++++-- 4 files changed, 60 insertions(+), 5 deletions(-) diff --git a/models/card_tag.py b/models/card_tag.py index 61d4a23..a2c32fd 100644 --- a/models/card_tag.py +++ b/models/card_tag.py @@ -1,6 +1,6 @@ from typing import TYPE_CHECKING -from sqlalchemy import ForeignKey, Column, Table, UniqueConstraint, Index +from sqlalchemy import ForeignKey, Column, Table, Index from sqlalchemy.orm import mapped_column, Mapped, relationship from models import BaseModel @@ -8,7 +8,6 @@ from models import BaseModel if TYPE_CHECKING: from models import Project, Card - cards_card_tags = Table( 'cards_card_tags', BaseModel.metadata, @@ -17,6 +16,16 @@ cards_card_tags = Table( ) +class CardTagColor(BaseModel): + __tablename__ = "card_tag_colors" + + id: Mapped[int] = mapped_column(primary_key=True) + label: Mapped[str] = mapped_column(unique=True) + color: Mapped[str] = mapped_column(unique=True) + background_color: Mapped[str] = mapped_column(unique=True) + is_deleted: Mapped[bool] = mapped_column(default=False, nullable=False) + + class CardTag(BaseModel): __tablename__ = 'card_tags' @@ -40,6 +49,15 @@ class CardTag(BaseModel): back_populates='tags', ) + tag_color_id: Mapped[int] = mapped_column( + ForeignKey('card_tag_colors.id'), + nullable=False, + ) + tag_color: Mapped[CardTagColor] = relationship( + 'CardTagColor', + lazy='selectin', + ) + __table_args__ = ( Index('idx_card_name_project_id', 'name', 'project_id', 'is_deleted'), ) diff --git a/routers/card_tag.py b/routers/card_tag.py index 1810a7b..4b5323c 100644 --- a/routers/card_tag.py +++ b/routers/card_tag.py @@ -61,3 +61,14 @@ async def switch_tag( request: SwitchTagRequest, ): return await CardTagService(session).switch_tag(request) + + +@card_tag_router.get( + '/colors', + response_model=GetTagColorsResponse, + operation_id='get_colors', +) +async def get_colors( + session: Annotated[AsyncSession, Depends(get_session)], +): + return await CardTagService(session).get_tag_colors() diff --git a/schemas/card_tag.py b/schemas/card_tag.py index fed728c..39fe8a5 100644 --- a/schemas/card_tag.py +++ b/schemas/card_tag.py @@ -5,14 +5,22 @@ from schemas.base import BaseSchema, OkMessageSchema # region Entities +class CardTagColorSchema(BaseSchema): + id: int + color: str + background_color: str + label: str + + class BaseCardTagSchema(BaseSchema): name: str project_id: int + tag_color_id: int class CardTagSchema(BaseCardTagSchema): id: int - + tag_color: CardTagColorSchema # endregion @@ -50,4 +58,8 @@ class DeleteTagResponse(OkMessageSchema): class SwitchTagResponse(OkMessageSchema): pass + +class GetTagColorsResponse(BaseSchema): + colors: list[CardTagColorSchema] + # endregion diff --git a/services/card_tag.py b/services/card_tag.py index 50adf74..c20d3e1 100644 --- a/services/card_tag.py +++ b/services/card_tag.py @@ -1,7 +1,7 @@ from sqlalchemy import select from sqlalchemy.orm import selectinload -from models import CardTag, Card, CardGroup +from models import CardTag, Card, CardGroup, CardTagColor from schemas.card_tag import * from services.base import BaseService @@ -24,7 +24,11 @@ class CardTagService(BaseService): if existing_tag: return UpdateTagResponse(ok=False, message='Тег с таким названием уже существует') - tag = CardTag(name=request.tag.name, project_id=request.tag.project_id) + tag = CardTag( + name=request.tag.name, + project_id=request.tag.project_id, + tag_color_id=request.tag.tag_color_id, + ) self.session.add(tag) await self.session.commit() return CreateTagResponse(ok=True, message='Тег успешно создан') @@ -41,6 +45,8 @@ class CardTagService(BaseService): card_tag.name = request.tag.name + card_tag.tag_color_id = request.tag.tag_color_id + await self.session.commit() return UpdateTagResponse(ok=True, message='Тег успешно обновлен') @@ -127,3 +133,11 @@ class CardTagService(BaseService): card.tags = tags await self.session.flush() + + async def get_tag_colors(self) -> GetTagColorsResponse: + stmt = ( + select(CardTagColor) + .where(CardTagColor.is_deleted==False) + ) + colors = (await self.session.scalars(stmt)).all() + return GetTagColorsResponse(colors=colors)