diff --git a/apiserver/plane/api/views/issue.py b/apiserver/plane/api/views/issue.py index 415e7e2fa..1c2c95a96 100644 --- a/apiserver/plane/api/views/issue.py +++ b/apiserver/plane/api/views/issue.py @@ -1087,7 +1087,7 @@ class IssueArchiveViewSet(BaseViewSet): issue.save() issue_activity.delay( type="issue.activity.updated", - requested_data=json.dumps({"archived_in": None}), + requested_data=json.dumps({"archived_at": None}), actor_id=str(request.user.id), issue_id=str(issue.id), project_id=str(project_id), diff --git a/apiserver/plane/api/views/notification.py b/apiserver/plane/api/views/notification.py index fa1e280d6..ac0082430 100644 --- a/apiserver/plane/api/views/notification.py +++ b/apiserver/plane/api/views/notification.py @@ -33,6 +33,7 @@ class NotificationViewSet(BaseViewSet): order_by = request.GET.get("order_by", "-created_at") snoozed = request.GET.get("snoozed", "false") archived = request.GET.get("archived", "false") + read = request.GET.get("read", "false") # Filter type type = request.GET.get("type", "all") @@ -49,20 +50,25 @@ class NotificationViewSet(BaseViewSet): if snoozed == "true": notifications = notifications.filter( - snoozed_till__lt=timezone.now(), + Q(snoozed_till__lt=timezone.now()) | Q(snoozed_till__isnull=False) ) + if read == "true": + notifications = notifications.filter(read_at__isnull=False) + if read == "false": + notifications = notifications.filter(read_at__isnull=True) + # Filter for archived or unarchive - if archived == "true": + if archived == "false": notifications = notifications.filter(archived_at__isnull=True) - if archived == "false": + if archived == "true": notifications = notifications.filter(archived_at__isnull=False) # Subscribed issues if type == "watching": issue_ids = IssueSubscriber.objects.filter( - workspace__slug=slug, subsriber_id=request.user.id + workspace__slug=slug, subscriber_id=request.user.id ).values_list("issue_id", flat=True) notifications = notifications.filter(entity_identifier__in=issue_ids) diff --git a/apiserver/plane/bgtasks/issue_activites_task.py b/apiserver/plane/bgtasks/issue_activites_task.py index 07de82a14..c05442163 100644 --- a/apiserver/plane/bgtasks/issue_activites_task.py +++ b/apiserver/plane/bgtasks/issue_activites_task.py @@ -558,22 +558,62 @@ def track_estimate_points( ) -def track_archive_in( +def track_archive_at( requested_data, current_instance, issue_id, project, actor, issue_activities ): - issue_activities.append( - IssueActivity( - issue_id=issue_id, - project=project, - workspace=project.workspace, - comment=f"{actor.email} has restored the issue", - verb="updated", - actor=actor, - field="archvied_at", - old_value="archive", - new_value="restore", + if requested_data.get("archived_at") is None: + issue_activities.append( + IssueActivity( + issue_id=issue_id, + project=project, + workspace=project.workspace, + comment=f"{actor.email} has restored the issue", + verb="updated", + actor=actor, + field="archvied_at", + old_value="archive", + new_value="restore", + ) + ) + else: + issue_activities.append( + IssueActivity( + issue_id=issue_id, + project=project, + workspace=project.workspace, + comment=f"Plane has archived the issue", + verb="updated", + actor=actor, + field="archvied_at", + old_value=None, + new_value="archive", + ) + ) + + +def track_closed_to( + requested_data, current_instance, issue_id, project, actor, issue_activities +): + if requested_data.get("closed_to") is not None: + updated_state = State.objects.get( + pk=requested_data.get("closed_to"), project=project + ) + + issue_activities.append( + IssueActivity( + issue_id=issue_id, + actor=actor, + verb="updated", + old_value=None, + new_value=updated_state.name, + field="state", + project=project, + workspace=project.workspace, + comment=f"Plane updated the state to {updated_state.name}", + old_identifier=None, + new_identifier=updated_state.id, + ) ) - ) def update_issue_activity( @@ -592,7 +632,8 @@ def update_issue_activity( "blocks_list": track_blocks, "blockers_list": track_blockings, "estimate_point": track_estimate_points, - "archived_in": track_archive_in, + "archived_at": track_archive_at, + "closed_to": track_closed_to, } requested_data = json.loads(requested_data) if requested_data is not None else None @@ -970,11 +1011,16 @@ def delete_attachment_activity( ) - # Receive message from room group @shared_task def issue_activity( - type, requested_data, current_instance, issue_id, actor_id, project_id + type, + requested_data, + current_instance, + issue_id, + actor_id, + project_id, + subscriber=True, ): try: issue_activities = [] @@ -986,12 +1032,15 @@ def issue_activity( if issue is not None: issue.updated_at = timezone.now() issue.save() - - # add the user to issue subscriber - try: - _ = IssueSubscriber.objects.create(issue_id=issue_id, subscriber=actor) - except Exception as e: - pass + + if subscriber: + # add the user to issue subscriber + try: + _ = IssueSubscriber.objects.get_or_create( + issue_id=issue_id, subscriber=actor + ) + except Exception as e: + pass ACTIVITY_MAPPER = { "issue.activity.created": create_issue_activity, diff --git a/apiserver/plane/bgtasks/issue_automation_task.py b/apiserver/plane/bgtasks/issue_automation_task.py index 0b64e546f..0fb6943ca 100644 --- a/apiserver/plane/bgtasks/issue_automation_task.py +++ b/apiserver/plane/bgtasks/issue_automation_task.py @@ -1,4 +1,5 @@ -# Python improts +# Python imports +import json from datetime import timedelta # Django imports @@ -12,6 +13,7 @@ from sentry_sdk import capture_exception # Module imports from plane.db.models import Issue, Project, IssueActivity, State +from plane.bgtasks.issue_activites_task import issue_activity @shared_task @@ -19,6 +21,7 @@ def archive_and_close_old_issues(): archive_old_issues() close_old_issues() + def archive_old_issues(): try: # Get all the projects whose archive_in is greater than 0 @@ -56,24 +59,21 @@ def archive_old_issues(): issues_to_update.append(issue) # Bulk Update the issues and log the activity - Issue.objects.bulk_update(issues_to_update, ["archived_at"], batch_size=100) - IssueActivity.objects.bulk_create( - [ - IssueActivity( - issue_id=issue.id, - actor=project.created_by, - verb="updated", - field="archived_at", - project=project, - workspace=project.workspace, - comment="Plane archived the issue", - new_value="archive", - old_value="" - ) - for issue in issues_to_update - ], - batch_size=100, + Issue.objects.bulk_update( + issues_to_update, ["archived_at"], batch_size=100 ) + [ + issue_activity.delay( + type="issue.activity.updated", + requested_data=json.dumps({"archive_at": issue.archived_at}), + actor_id=str(project.created_by_id), + issue_id=issue.id, + project_id=project_id, + current_instance=None, + subscriber=False, + ) + for issue in issues_to_update + ] return except Exception as e: if settings.DEBUG: @@ -81,10 +81,13 @@ def archive_old_issues(): capture_exception(e) return + def close_old_issues(): try: # Get all the projects whose close_in is greater than 0 - projects = Project.objects.filter(close_in__gt=0).select_related("default_state") + projects = Project.objects.filter(close_in__gt=0).select_related( + "default_state" + ) for project in projects: project_id = project.id @@ -117,7 +120,6 @@ def close_old_issues(): else: close_state = State.objects.filter(group="cancelled").first() - issues_to_update = [] for issue in issues: issue.state = close_state @@ -125,24 +127,21 @@ def close_old_issues(): # Bulk Update the issues and log the activity Issue.objects.bulk_update(issues_to_update, ["state"], batch_size=100) - IssueActivity.objects.bulk_create( - [ - IssueActivity( - issue_id=issue.id, - actor=project.created_by, - verb="updated", - field="state", - project=project, - workspace=project.workspace, - comment="Plane cancelled the issue", - ) - for issue in issues_to_update - ], - batch_size=100, - ) + [ + issue_activity.delay( + type="issue.activity.updated", + requested_data=json.dumps({"closed_to": issue.state_id}), + actor_id=str(project.created_by_id), + issue_id=issue.id, + project_id=project_id, + current_instance=None, + subscriber=False, + ) + for issue in issues_to_update + ] return except Exception as e: if settings.DEBUG: print(e) capture_exception(e) - return \ No newline at end of file + return