mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
dev: notification models and operations
This commit is contained in:
parent
f80f98ddef
commit
0af49306a9
@ -75,4 +75,7 @@ from .estimate import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
from .inbox import InboxSerializer, InboxIssueSerializer, IssueStateInboxSerializer
|
from .inbox import InboxSerializer, InboxIssueSerializer, IssueStateInboxSerializer
|
||||||
|
|
||||||
from .analytic import AnalyticViewSerializer
|
from .analytic import AnalyticViewSerializer
|
||||||
|
|
||||||
|
from .notification import NotificationSerializer
|
||||||
|
10
apiserver/plane/api/serializers/notification.py
Normal file
10
apiserver/plane/api/serializers/notification.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# Module imports
|
||||||
|
from .base import BaseSerializer
|
||||||
|
from plane.db.models import Notification
|
||||||
|
|
||||||
|
class NotificationSerializer(BaseSerializer):
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = Notification
|
||||||
|
fields = "__all__"
|
||||||
|
|
@ -149,6 +149,9 @@ from plane.api.views import (
|
|||||||
ExportAnalyticsEndpoint,
|
ExportAnalyticsEndpoint,
|
||||||
DefaultAnalyticsEndpoint,
|
DefaultAnalyticsEndpoint,
|
||||||
## End Analytics
|
## End Analytics
|
||||||
|
# Notification
|
||||||
|
NotificationViewSet,
|
||||||
|
## End Notification
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -803,11 +806,7 @@ urlpatterns = [
|
|||||||
path(
|
path(
|
||||||
"workspaces/<str:slug>/projects/<uuid:project_id>/issues/<uuid:issue_id>/subscribers/",
|
"workspaces/<str:slug>/projects/<uuid:project_id>/issues/<uuid:issue_id>/subscribers/",
|
||||||
IssueSubscriberViewSet.as_view(
|
IssueSubscriberViewSet.as_view(
|
||||||
{
|
{"get": "list", "post": "create", "delete": "destroy"}
|
||||||
"get": "list",
|
|
||||||
"post": "create",
|
|
||||||
"delete": "destroy"
|
|
||||||
}
|
|
||||||
),
|
),
|
||||||
name="project-issue-subscriber",
|
name="project-issue-subscriber",
|
||||||
),
|
),
|
||||||
@ -1288,4 +1287,26 @@ urlpatterns = [
|
|||||||
name="default-analytics",
|
name="default-analytics",
|
||||||
),
|
),
|
||||||
## End Analytics
|
## End Analytics
|
||||||
|
# Notification
|
||||||
|
path(
|
||||||
|
"workspaces/<str:slug>/users/notifications/",
|
||||||
|
NotificationViewSet.as_view(
|
||||||
|
{
|
||||||
|
"get": "list",
|
||||||
|
}
|
||||||
|
),
|
||||||
|
name="notifications",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"workspaces/<str:slug>/users/notifications/<uuid:pk>/",
|
||||||
|
NotificationViewSet.as_view(
|
||||||
|
{
|
||||||
|
"get": "retrieve",
|
||||||
|
"patch": "partial_update",
|
||||||
|
"delete": "destroy",
|
||||||
|
}
|
||||||
|
),
|
||||||
|
name="notifications",
|
||||||
|
),
|
||||||
|
## End Notification
|
||||||
]
|
]
|
||||||
|
@ -134,6 +134,7 @@ from .estimate import (
|
|||||||
from .release import ReleaseNotesEndpoint
|
from .release import ReleaseNotesEndpoint
|
||||||
|
|
||||||
from .inbox import InboxViewSet, InboxIssueViewSet
|
from .inbox import InboxViewSet, InboxIssueViewSet
|
||||||
|
|
||||||
from .analytic import (
|
from .analytic import (
|
||||||
AnalyticsEndpoint,
|
AnalyticsEndpoint,
|
||||||
AnalyticViewViewset,
|
AnalyticViewViewset,
|
||||||
@ -141,3 +142,5 @@ from .analytic import (
|
|||||||
ExportAnalyticsEndpoint,
|
ExportAnalyticsEndpoint,
|
||||||
DefaultAnalyticsEndpoint,
|
DefaultAnalyticsEndpoint,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from .notification import NotificationViewSet
|
24
apiserver/plane/api/views/notification.py
Normal file
24
apiserver/plane/api/views/notification.py
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# Third party imports
|
||||||
|
from rest_framework import status
|
||||||
|
from rest_framework.response import Response
|
||||||
|
|
||||||
|
# Module imports
|
||||||
|
from .base import BaseViewSet
|
||||||
|
from plane.db.models import Notification
|
||||||
|
from plane.api.serializers import NotificationSerializer
|
||||||
|
|
||||||
|
|
||||||
|
class NotificationViewSet(BaseViewSet):
|
||||||
|
model = Notification
|
||||||
|
serializer_class = NotificationSerializer
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return (
|
||||||
|
super()
|
||||||
|
.get_queryset()
|
||||||
|
.filter(
|
||||||
|
workspace__slug=self.kwargs.get("slug"),
|
||||||
|
)
|
||||||
|
.select_related("workspace")
|
||||||
|
)
|
||||||
|
|
@ -20,8 +20,10 @@ from plane.db.models import (
|
|||||||
State,
|
State,
|
||||||
Cycle,
|
Cycle,
|
||||||
Module,
|
Module,
|
||||||
|
IssueSubscriber,
|
||||||
|
Notification,
|
||||||
)
|
)
|
||||||
from plane.api.serializers import IssueActivitySerializer
|
from plane.api.serializers import IssueActivitySerializer, IssueFlatSerializer
|
||||||
|
|
||||||
|
|
||||||
# Track Chnages in name
|
# Track Chnages in name
|
||||||
@ -992,6 +994,7 @@ def issue_activity(
|
|||||||
# Post the updates to segway for integrations and webhooks
|
# Post the updates to segway for integrations and webhooks
|
||||||
if len(issue_activities_created):
|
if len(issue_activities_created):
|
||||||
# Don't send activities if the actor is a bot
|
# Don't send activities if the actor is a bot
|
||||||
|
try:
|
||||||
if settings.PROXY_BASE_URL:
|
if settings.PROXY_BASE_URL:
|
||||||
for issue_activity in issue_activities_created:
|
for issue_activity in issue_activities_created:
|
||||||
headers = {"Content-Type": "application/json"}
|
headers = {"Content-Type": "application/json"}
|
||||||
@ -1004,6 +1007,44 @@ def issue_activity(
|
|||||||
json=issue_activity_json,
|
json=issue_activity_json,
|
||||||
headers=headers,
|
headers=headers,
|
||||||
)
|
)
|
||||||
|
except Exception as e:
|
||||||
|
capture_exception(e)
|
||||||
|
|
||||||
|
# Create Notifications
|
||||||
|
bulk_notifications = []
|
||||||
|
|
||||||
|
issue_subscribers = (
|
||||||
|
IssueSubscriber.objects.filter(project=project)
|
||||||
|
.exclude(subscriber_id=actor_id)
|
||||||
|
.values_list("subscriber")
|
||||||
|
)
|
||||||
|
|
||||||
|
issue = Issue.objects.get(project=project, pk=issue_id)
|
||||||
|
for subscriber in issue_subscribers:
|
||||||
|
for issue_activity in issue_activities_created:
|
||||||
|
bulk_notifications.append(
|
||||||
|
Notification(
|
||||||
|
workspace=project.workspace,
|
||||||
|
sender="in_app:issue_activities",
|
||||||
|
triggered_by=actor,
|
||||||
|
receiver_id=subscriber,
|
||||||
|
entity_identifier=issue_id,
|
||||||
|
entity_name="issue",
|
||||||
|
project=project,
|
||||||
|
title=issue_activity.comment,
|
||||||
|
data={
|
||||||
|
"issue": {
|
||||||
|
"id": str(issue_id),
|
||||||
|
"identifier": str(project.identifier),
|
||||||
|
"sequence_id": issue.sequence_id,
|
||||||
|
"state_name": issue.state.name,
|
||||||
|
"state_group": issue.state.group,
|
||||||
|
},
|
||||||
|
"issue_activity": str(issue_activity.id),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
return
|
return
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
capture_exception(e)
|
capture_exception(e)
|
||||||
|
@ -67,4 +67,7 @@ from .page import Page, PageBlock, PageFavorite, PageLabel
|
|||||||
from .estimate import Estimate, EstimatePoint
|
from .estimate import Estimate, EstimatePoint
|
||||||
|
|
||||||
from .inbox import Inbox, InboxIssue
|
from .inbox import Inbox, InboxIssue
|
||||||
|
|
||||||
from .analytic import AnalyticView
|
from .analytic import AnalyticView
|
||||||
|
|
||||||
|
from .notification import Notification
|
@ -12,12 +12,15 @@ class Notification(BaseModel):
|
|||||||
project = models.ForeignKey(
|
project = models.ForeignKey(
|
||||||
"db.Project", related_name="notifications", on_delete=models.CASCADE, null=True
|
"db.Project", related_name="notifications", on_delete=models.CASCADE, null=True
|
||||||
)
|
)
|
||||||
|
data = models.JSONField(null=True)
|
||||||
entity_identifier = models.UUIDField(null=True)
|
entity_identifier = models.UUIDField(null=True)
|
||||||
|
entity_name = models.CharField(max_length=255)
|
||||||
title = models.TextField()
|
title = models.TextField()
|
||||||
message = models.JSONField(null=True)
|
message = models.JSONField(null=True)
|
||||||
message_html = models.TextField(blank=True, default="<p></p>")
|
message_html = models.TextField(blank=True, default="<p></p>")
|
||||||
message_stripped = models.TextField(blank=True, null=True)
|
message_stripped = models.TextField(blank=True, null=True)
|
||||||
sender = models.ForeignKey("db.User", related_name="sent_notifications", on_delete=models.SET_NULL, null=True)
|
sender = models.CharField(max_length=255)
|
||||||
|
triggered_by = models.ForeignKey("db.User", related_name="triggered_notifications", on_delete=models.SET_NULL, null=True)
|
||||||
receiver = models.ForeignKey("db.User", related_name="received_notifications", on_delete=models.CASCADE)
|
receiver = models.ForeignKey("db.User", related_name="received_notifications", on_delete=models.CASCADE)
|
||||||
read_at = models.DateTimeField(null=True)
|
read_at = models.DateTimeField(null=True)
|
||||||
snoozed_till = models.DateTimeField(null=True)
|
snoozed_till = models.DateTimeField(null=True)
|
||||||
|
Loading…
Reference in New Issue
Block a user