UI - МЕЖПРОЕКТНАЯ КОММУНИКАЦИЯ: индикатор новых изменений во внешних контурах

This commit is contained in:
DCCONSTRUCTIONS
2026-04-19 09:52:27 +03:00
parent 0a584abf26
commit 4dff521f7f
8 changed files with 107 additions and 16 deletions
@@ -21,7 +21,7 @@ from plane.api.serializers import (
from plane.api.serializers.issue import IssueSerializer as IssueCreateSerializer
from plane.app.permissions import ProjectLitePermission
from plane.app.views.base import BaseAPIView
from plane.db.models import FileAsset, Intake, IntakeIssue, Label, Project, ProjectMember, State, StateGroup
from plane.db.models import FileAsset, Intake, IntakeIssue, Label, Notification, Project, ProjectMember, State, StateGroup
from plane.db.models.intake import IntakeIssueStatus, SourceType
from plane.settings.storage import S3Storage
from plane.utils.external_contours import create_external_contour_issue_comment
@@ -61,7 +61,11 @@ class ExternalContourListCreateEndpoint(BaseAPIView):
)
def get(self, request, slug, project_id):
serializer = ExternalContourRequestSerializer(self.get_queryset(), many=True)
serializer = ExternalContourRequestSerializer(
self.get_queryset(),
many=True,
context={"request": request},
)
return Response(
{
"results": serializer.data,
@@ -174,7 +178,8 @@ class ExternalContourListCreateEndpoint(BaseAPIView):
"issue__created_by",
)
.prefetch_related("issue__issue_assignee__assignee", "issue__label_issue__label")
.get(pk=intake_issue.id)
.get(pk=intake_issue.id),
context={"request": request},
)
return Response(response_serializer.data, status=status.HTTP_201_CREATED)
@@ -273,14 +278,28 @@ class ExternalContourDetailEndpoint(BaseAPIView):
.prefetch_related("issue__issue_assignee__assignee", "issue__label_issue__label")
)
def mark_request_notifications_read(self, user, contour_request):
user_id = getattr(user, "id", None)
if not user_id:
return
Notification.objects.filter(
receiver_id=user_id,
sender__startswith="in_app:external_contours:",
read_at__isnull=True,
data__issue__id=str(contour_request.id),
).update(read_at=timezone.now())
def get(self, request, slug, project_id, request_id):
contour_request = get_object_or_404(self.get_queryset())
self.mark_request_notifications_read(request.user, contour_request)
serializer = ExternalContourRequestSerializer(
contour_request,
context={
"include_mirror_data": True,
"workspace_slug": slug,
"source_project_id": str(project_id),
"request": request,
},
)
return Response(serializer.data, status=status.HTTP_200_OK)
@@ -366,6 +385,12 @@ class ExternalContourDecisionEndpoint(BaseAPIView):
contour_request.save(update_fields=["extra", "updated_at"])
contour_request.refresh_from_db()
Notification.objects.filter(
receiver_id=request.user.id,
sender__startswith="in_app:external_contours:",
read_at__isnull=True,
data__issue__id=str(contour_request.id),
).update(read_at=timezone.now())
serializer = ExternalContourRequestSerializer(
IntakeIssue.objects.select_related(
"issue",
@@ -379,6 +404,7 @@ class ExternalContourDecisionEndpoint(BaseAPIView):
"include_mirror_data": True,
"workspace_slug": slug,
"source_project_id": str(project_id),
"request": request,
},
)
return Response(serializer.data, status=status.HTTP_200_OK)
@@ -425,12 +451,19 @@ class ExternalContourReplyEndpoint(BaseAPIView):
return Response({"error": exc.message_dict if hasattr(exc, "message_dict") else str(exc)}, status=status.HTTP_400_BAD_REQUEST)
contour_request.refresh_from_db()
Notification.objects.filter(
receiver_id=request.user.id,
sender__startswith="in_app:external_contours:",
read_at__isnull=True,
data__issue__id=str(contour_request.id),
).update(read_at=timezone.now())
response_serializer = ExternalContourRequestSerializer(
contour_request,
context={
"include_mirror_data": True,
"workspace_slug": slug,
"source_project_id": str(project_id),
"request": request,
},
)
return Response(response_serializer.data, status=status.HTTP_200_OK)