Skip to content

Commit

Permalink
feat(notifications): u#4007 notify when a new comment has been created
Browse files Browse the repository at this point in the history
  • Loading branch information
bameda committed Oct 23, 2023
1 parent 5198f51 commit 6ee86c5
Show file tree
Hide file tree
Showing 8 changed files with 109 additions and 4 deletions.
16 changes: 16 additions & 0 deletions python/apps/taiga/src/taiga/comments/notifications.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# -*- coding: utf-8 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# Copyright (c) 2023-present Kaleidos INC

from typing import Awaitable, Protocol

from taiga.comments.models import Comment
from taiga.users.models import User


class NotificationOnCreateCallable(Protocol):
def __call__(self, comment: Comment, emitted_by: User) -> Awaitable[None]:
...
21 changes: 21 additions & 0 deletions python/apps/taiga/src/taiga/comments/serializers/nested.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# Copyright (c) 2023-present Kaleidos INC

from datetime import datetime

from taiga.base.serializers import UUIDB64, BaseModel
from taiga.users.serializers.nested import UserNestedSerializer


class CommentNestedSerializer(BaseModel):
id: UUIDB64
text: str
created_at: datetime
created_by: UserNestedSerializer | None

class Config:
orm_mode = True
4 changes: 4 additions & 0 deletions python/apps/taiga/src/taiga/comments/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from taiga.comments import repositories as comments_repositories
from taiga.comments.events import EventOnCreateCallable, EventOnDeleteCallable, EventOnUpdateCallable
from taiga.comments.models import Comment
from taiga.comments.notifications import NotificationOnCreateCallable
from taiga.comments.repositories import CommentFilters, CommentOrderBy
from taiga.stories.stories.models import Story
from taiga.users.models import User
Expand All @@ -28,6 +29,7 @@ async def create_comment(
text: str,
created_by: User,
event_on_create: EventOnCreateCallable | None = None,
notification_on_create: NotificationOnCreateCallable | None = None,
) -> Comment:
comment = await comments_repositories.create_comment(
content_object=content_object,
Expand All @@ -37,6 +39,8 @@ async def create_comment(

if event_on_create:
await event_on_create(comment=comment)
if notification_on_create:
await notification_on_create(comment=comment, emitted_by=created_by)

return comment

Expand Down
17 changes: 14 additions & 3 deletions python/apps/taiga/src/taiga/stories/comments/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from taiga.exceptions.api.errors import ERROR_403, ERROR_404, ERROR_422
from taiga.permissions import HasPerm, IsNotDeleted, IsProjectAdmin, IsRelatedToTheUser
from taiga.routers import routes
from taiga.stories.comments import events
from taiga.stories.comments import events, notifications
from taiga.stories.stories.api import get_story_or_404
from taiga.stories.stories.models import Story

Expand Down Expand Up @@ -60,9 +60,20 @@ async def create_story_comments(
story = await get_story_or_404(project_id=project_id, ref=ref)
await check_permissions(permissions=CREATE_STORY_COMMENT, user=request.user, obj=story)

event_on_create = partial(events.emit_event_when_story_comment_is_created, project=story.project)
event_on_create = partial(
events.emit_event_when_story_comment_is_created,
project=story.project,
)
notification_on_create = partial(
notifications.notify_when_story_comment_is_created,
story=story,
)
return await comments_services.create_comment(
text=form.text, content_object=story, created_by=request.user, event_on_create=event_on_create
text=form.text,
content_object=story,
created_by=request.user,
event_on_create=event_on_create,
notification_on_create=notification_on_create,
)


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# -*- coding: utf-8 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# Copyright (c) 2023-present Kaleidos INC

from taiga.comments.models import Comment
from taiga.notifications import services as notifications_services
from taiga.stories.comments.notifications.content import StoryCommentCreateNotificationContent
from taiga.stories.stories.models import Story
from taiga.users.models import User

STORY_COMMENT_CREATE = "story_comment.create"


async def notify_when_story_comment_is_created(story: Story, comment: Comment, emitted_by: User) -> None:
notified_users = {u async for u in story.assignees.all()}
if story.created_by:
notified_users.add(story.created_by)
notified_users.discard(emitted_by)

await notifications_services.notify_users(
type=STORY_COMMENT_CREATE,
emitted_by=emitted_by,
notified_users=notified_users,
content=StoryCommentCreateNotificationContent(
project=story.project,
story=story,
commented_by=emitted_by,
comment=comment,
),
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# Copyright (c) 2023-present Kaleidos INC

from taiga.base.serializers import BaseModel
from taiga.comments.serializers.nested import CommentNestedSerializer
from taiga.projects.projects.serializers.nested import ProjectLinkNestedSerializer
from taiga.stories.stories.serializers.nested import StoryNestedSerializer
from taiga.users.serializers.nested import UserNestedSerializer


class StoryCommentCreateNotificationContent(BaseModel):
project: ProjectLinkNestedSerializer
story: StoryNestedSerializer
commented_by: UserNestedSerializer
comment: CommentNestedSerializer
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ async def get_story(project_id: UUID, ref: int) -> Story | None:
return await stories_repositories.get_story(
filters={"ref": ref, "project_id": project_id},
select_related=["project", "workspace", "workflow", "created_by"],
prefetch_related=["assignees"],
)


Expand Down Expand Up @@ -362,4 +363,4 @@ async def delete_story(story: Story, deleted_by: AnyUser) -> bool:
)
return True

return False
return False

0 comments on commit 6ee86c5

Please sign in to comment.