[WEB-1980] feat: user recent visited entities (#5211)
* feat: recent visited * chore: recent visited 20 records * chore: removed the old table * chore: view detail endpoint
This commit is contained in:
parent
e6526a31c8
commit
6748065456
8 changed files with 159 additions and 5 deletions
|
|
@ -49,6 +49,7 @@ from plane.db.models import (
|
|||
ProjectMember,
|
||||
)
|
||||
from plane.utils.analytics_plot import burndown_plot
|
||||
from plane.bgtasks.recent_visited_task import recent_visited_task
|
||||
|
||||
# Module imports
|
||||
from .. import BaseAPIView, BaseViewSet
|
||||
|
|
@ -1028,6 +1029,13 @@ class CycleViewSet(BaseViewSet):
|
|||
cycle_id=pk,
|
||||
)
|
||||
|
||||
recent_visited_task.delay(
|
||||
slug=slug,
|
||||
entity_name="cycle",
|
||||
entity_identifier=pk,
|
||||
user_id=request.user.id,
|
||||
project_id=project_id,
|
||||
)
|
||||
return Response(
|
||||
data,
|
||||
status=status.HTTP_200_OK,
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ from plane.utils.paginator import (
|
|||
)
|
||||
from .. import BaseAPIView, BaseViewSet
|
||||
from plane.utils.user_timezone_converter import user_timezone_converter
|
||||
from plane.bgtasks.recent_visited_task import recent_visited_task
|
||||
|
||||
|
||||
class IssueListEndpoint(BaseAPIView):
|
||||
|
|
@ -127,6 +128,14 @@ class IssueListEndpoint(BaseAPIView):
|
|||
sub_group_by=sub_group_by,
|
||||
)
|
||||
|
||||
recent_visited_task.delay(
|
||||
slug=slug,
|
||||
project_id=project_id,
|
||||
entity_name="project",
|
||||
entity_identifier=project_id,
|
||||
user_id=request.user.id,
|
||||
)
|
||||
|
||||
if self.fields or self.expand:
|
||||
issues = IssueSerializer(
|
||||
queryset, many=True, fields=self.fields, expand=self.expand
|
||||
|
|
@ -247,6 +256,13 @@ class IssueViewSet(BaseViewSet):
|
|||
sub_group_by=sub_group_by,
|
||||
)
|
||||
|
||||
recent_visited_task.delay(
|
||||
slug=slug,
|
||||
project_id=project_id,
|
||||
entity_name="project",
|
||||
entity_identifier=project_id,
|
||||
user_id=request.user.id,
|
||||
)
|
||||
if ProjectMember.objects.filter(
|
||||
workspace__slug=slug,
|
||||
project_id=project_id,
|
||||
|
|
@ -484,6 +500,14 @@ class IssueViewSet(BaseViewSet):
|
|||
status=status.HTTP_404_NOT_FOUND,
|
||||
)
|
||||
|
||||
recent_visited_task.delay(
|
||||
slug=slug,
|
||||
entity_name="issue",
|
||||
entity_identifier=pk,
|
||||
user_id=request.user.id,
|
||||
project_id=project_id,
|
||||
)
|
||||
|
||||
serializer = IssueDetailSerializer(issue, expand=self.expand)
|
||||
return Response(serializer.data, status=status.HTTP_200_OK)
|
||||
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ from plane.utils.analytics_plot import burndown_plot
|
|||
from plane.utils.user_timezone_converter import user_timezone_converter
|
||||
from plane.bgtasks.webhook_task import model_activity
|
||||
from .. import BaseAPIView, BaseViewSet
|
||||
from plane.bgtasks.recent_visited_task import recent_visited_task
|
||||
|
||||
|
||||
class ModuleViewSet(BaseViewSet):
|
||||
|
|
@ -670,6 +671,14 @@ class ModuleViewSet(BaseViewSet):
|
|||
module_id=pk,
|
||||
)
|
||||
|
||||
recent_visited_task.delay(
|
||||
slug=slug,
|
||||
entity_name="module",
|
||||
entity_identifier=pk,
|
||||
user_id=request.user.id,
|
||||
project_id=project_id,
|
||||
)
|
||||
|
||||
return Response(
|
||||
data,
|
||||
status=status.HTTP_200_OK,
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ from ..base import BaseAPIView, BaseViewSet
|
|||
|
||||
from plane.bgtasks.page_transaction_task import page_transaction
|
||||
from plane.bgtasks.page_version_task import page_version
|
||||
from plane.bgtasks.recent_visited_task import recent_visited_task
|
||||
|
||||
|
||||
def unarchive_archive_page_and_descendants(page_id, archived_at):
|
||||
|
|
@ -221,6 +222,13 @@ class PageViewSet(BaseViewSet):
|
|||
).values_list("entity_identifier", flat=True)
|
||||
data = PageDetailSerializer(page).data
|
||||
data["issue_ids"] = issue_ids
|
||||
recent_visited_task.delay(
|
||||
slug=slug,
|
||||
entity_name="page",
|
||||
entity_identifier=pk,
|
||||
user_id=request.user.id,
|
||||
project_id=project_id,
|
||||
)
|
||||
return Response(
|
||||
data,
|
||||
status=status.HTTP_200_OK,
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ from plane.db.models import (
|
|||
)
|
||||
from plane.utils.cache import cache_response
|
||||
from plane.bgtasks.webhook_task import model_activity
|
||||
from plane.bgtasks.recent_visited_task import recent_visited_task
|
||||
|
||||
|
||||
class ProjectViewSet(BaseViewSet):
|
||||
|
|
@ -264,6 +265,14 @@ class ProjectViewSet(BaseViewSet):
|
|||
status=status.HTTP_404_NOT_FOUND,
|
||||
)
|
||||
|
||||
recent_visited_task.delay(
|
||||
slug=slug,
|
||||
project_id=pk,
|
||||
entity_name="project",
|
||||
entity_identifier=pk,
|
||||
user_id=request.user.id,
|
||||
)
|
||||
|
||||
serializer = ProjectListSerializer(project)
|
||||
return Response(serializer.data, status=status.HTTP_200_OK)
|
||||
|
||||
|
|
|
|||
|
|
@ -13,12 +13,13 @@ from django.db.models import (
|
|||
from django.db.models.functions import Coalesce
|
||||
from django.utils.decorators import method_decorator
|
||||
from django.views.decorators.gzip import gzip_page
|
||||
from rest_framework import status
|
||||
from django.db import transaction
|
||||
|
||||
# Third party imports
|
||||
from rest_framework import status
|
||||
from rest_framework.response import Response
|
||||
|
||||
# Module imports
|
||||
from plane.app.permissions import (
|
||||
allow_permission,
|
||||
ROLE,
|
||||
|
|
@ -46,10 +47,8 @@ from plane.utils.paginator import (
|
|||
GroupedOffsetPaginator,
|
||||
SubGroupedOffsetPaginator,
|
||||
)
|
||||
|
||||
# Module imports
|
||||
from plane.bgtasks.recent_visited_task import recent_visited_task
|
||||
from .. import BaseViewSet
|
||||
|
||||
from plane.db.models import (
|
||||
UserFavorite,
|
||||
)
|
||||
|
|
@ -134,6 +133,21 @@ class WorkspaceViewViewSet(BaseViewSet):
|
|||
serializer.errors, status=status.HTTP_400_BAD_REQUEST
|
||||
)
|
||||
|
||||
def retrieve(self, request, slug, pk):
|
||||
issue_view = self.get_queryset().filter(pk=pk).first()
|
||||
serializer = IssueViewSerializer(issue_view)
|
||||
recent_visited_task.delay(
|
||||
slug=slug,
|
||||
project_id=None,
|
||||
entity_name="view",
|
||||
entity_identifier=pk,
|
||||
user_id=request.user.id,
|
||||
)
|
||||
return Response(
|
||||
serializer.data,
|
||||
status=status.HTTP_200_OK,
|
||||
)
|
||||
|
||||
@allow_permission(
|
||||
allowed_roles=[ROLE.ADMIN],
|
||||
level="WORKSPACE",
|
||||
|
|
@ -444,6 +458,27 @@ class IssueViewViewSet(BaseViewSet):
|
|||
).data
|
||||
return Response(views, status=status.HTTP_200_OK)
|
||||
|
||||
allow_permission(
|
||||
allowed_roles=[ROLE.ADMIN, ROLE.MEMBER, ROLE.VIEWER, ROLE.GUEST]
|
||||
)
|
||||
|
||||
def retrieve(self, request, slug, project_id, pk):
|
||||
issue_view = (
|
||||
self.get_queryset().filter(pk=pk, project_id=project_id).first()
|
||||
)
|
||||
serializer = IssueViewSerializer(issue_view)
|
||||
recent_visited_task.delay(
|
||||
slug=slug,
|
||||
project_id=project_id,
|
||||
entity_name="view",
|
||||
entity_identifier=pk,
|
||||
user_id=request.user.id,
|
||||
)
|
||||
return Response(
|
||||
serializer.data,
|
||||
status=status.HTTP_200_OK,
|
||||
)
|
||||
|
||||
allow_permission(allowed_roles=[], creator=True, model=IssueView)
|
||||
|
||||
def partial_update(self, request, slug, project_id, pk):
|
||||
|
|
|
|||
61
apiserver/plane/bgtasks/recent_visited_task.py
Normal file
61
apiserver/plane/bgtasks/recent_visited_task.py
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
# Python imports
|
||||
from django.utils import timezone
|
||||
|
||||
# Third party imports
|
||||
from celery import shared_task
|
||||
|
||||
# Module imports
|
||||
from plane.db.models import UserRecentVisit, Workspace
|
||||
from plane.utils.exception_logger import log_exception
|
||||
|
||||
|
||||
@shared_task
|
||||
def recent_visited_task(
|
||||
entity_name, entity_identifier, user_id, project_id, slug
|
||||
):
|
||||
try:
|
||||
workspace = Workspace.objects.get(slug=slug)
|
||||
recent_visited = UserRecentVisit.objects.filter(
|
||||
entity_name=entity_name,
|
||||
entity_identifier=entity_identifier,
|
||||
user_id=user_id,
|
||||
project_id=project_id,
|
||||
workspace_id=workspace.id,
|
||||
).first()
|
||||
|
||||
if recent_visited:
|
||||
recent_visited.visited_at = timezone.now()
|
||||
recent_visited.save(update_fields=["visited_at"])
|
||||
else:
|
||||
|
||||
recent_visited_count = UserRecentVisit.objects.filter(
|
||||
user_id=user_id, workspace_id=workspace.id
|
||||
).count()
|
||||
if recent_visited_count == 20:
|
||||
recent_visited = (
|
||||
UserRecentVisit.objects.filter(
|
||||
user_id=user_id, workspace_id=workspace.id
|
||||
)
|
||||
.order_by("created_at")
|
||||
.first()
|
||||
)
|
||||
recent_visited.delete()
|
||||
|
||||
recent_activity = UserRecentVisit.objects.create(
|
||||
entity_name=entity_name,
|
||||
entity_identifier=entity_identifier,
|
||||
user_id=user_id,
|
||||
visited_at=timezone.now(),
|
||||
project_id=project_id,
|
||||
workspace_id=workspace.id,
|
||||
)
|
||||
recent_activity.created_by_id = user_id
|
||||
recent_activity.updated_by_id = user_id
|
||||
recent_activity.save(
|
||||
update_fields=["created_by_id", "updated_by_id"]
|
||||
)
|
||||
|
||||
return
|
||||
except Exception as e:
|
||||
log_exception(e)
|
||||
return
|
||||
|
|
@ -111,4 +111,4 @@ from .favorite import UserFavorite
|
|||
|
||||
from .issue_type import IssueType
|
||||
|
||||
from .recent_visit import UserRecentVisit
|
||||
from .recent_visit import UserRecentVisit
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue