fix: notifications (#1498)

* fix: notification filtering

* dev: reverse logic for archive filtering

* dev: fix watching notification

* dev: read filter

* dev: update automatic issue archival and close to send notifications

* dev: update archival structure for auto close issues

* Closing of dialog when we click around the dialog (#1364)

* style: new empty states (#1497)

* fix: custom colors opacity

* chore: update text colors for dark mode

* fix: dropdown text colors, datepicker bg color

* chore: update text colors

* chore: updated primary bg color

* style: new empty states added

* refactor: empty state for issues

* style: empty state for estimates

* chore: update labels, estimates and integrations empty states

* fix: custom analytics sidebar

* fix: archival spelling mistake

* fix: updated the default state logic

* dev: fix key

---------

Co-authored-by: Khrystyna Derenivska <56432889+kblueberry@users.noreply.github.com>
Co-authored-by: Aaryan Khandelwal <65252264+aaryan610@users.noreply.github.com>
Co-authored-by: NarayanBavisetti <narayan3119@gmail.com>
This commit is contained in:
pablohashescobar 2023-07-13 13:47:24 +05:30 committed by GitHub
parent 120d06983d
commit 2ff49c93bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 120 additions and 66 deletions

View File

@ -1087,7 +1087,7 @@ class IssueArchiveViewSet(BaseViewSet):
issue.save() issue.save()
issue_activity.delay( issue_activity.delay(
type="issue.activity.updated", type="issue.activity.updated",
requested_data=json.dumps({"archived_in": None}), requested_data=json.dumps({"archived_at": None}),
actor_id=str(request.user.id), actor_id=str(request.user.id),
issue_id=str(issue.id), issue_id=str(issue.id),
project_id=str(project_id), project_id=str(project_id),

View File

@ -33,6 +33,7 @@ class NotificationViewSet(BaseViewSet):
order_by = request.GET.get("order_by", "-created_at") order_by = request.GET.get("order_by", "-created_at")
snoozed = request.GET.get("snoozed", "false") snoozed = request.GET.get("snoozed", "false")
archived = request.GET.get("archived", "false") archived = request.GET.get("archived", "false")
read = request.GET.get("read", "false")
# Filter type # Filter type
type = request.GET.get("type", "all") type = request.GET.get("type", "all")
@ -49,20 +50,25 @@ class NotificationViewSet(BaseViewSet):
if snoozed == "true": if snoozed == "true":
notifications = notifications.filter( 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 # Filter for archived or unarchive
if archived == "true": if archived == "false":
notifications = notifications.filter(archived_at__isnull=True) notifications = notifications.filter(archived_at__isnull=True)
if archived == "false": if archived == "true":
notifications = notifications.filter(archived_at__isnull=False) notifications = notifications.filter(archived_at__isnull=False)
# Subscribed issues # Subscribed issues
if type == "watching": if type == "watching":
issue_ids = IssueSubscriber.objects.filter( 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) ).values_list("issue_id", flat=True)
notifications = notifications.filter(entity_identifier__in=issue_ids) notifications = notifications.filter(entity_identifier__in=issue_ids)

View File

@ -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 requested_data, current_instance, issue_id, project, actor, issue_activities
): ):
issue_activities.append( if requested_data.get("archived_at") is None:
IssueActivity( issue_activities.append(
issue_id=issue_id, IssueActivity(
project=project, issue_id=issue_id,
workspace=project.workspace, project=project,
comment=f"{actor.email} has restored the issue", workspace=project.workspace,
verb="updated", comment=f"{actor.email} has restored the issue",
actor=actor, verb="updated",
field="archvied_at", actor=actor,
old_value="archive", field="archived_at",
new_value="restore", 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="archived_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( def update_issue_activity(
@ -592,7 +632,8 @@ def update_issue_activity(
"blocks_list": track_blocks, "blocks_list": track_blocks,
"blockers_list": track_blockings, "blockers_list": track_blockings,
"estimate_point": track_estimate_points, "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 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 # Receive message from room group
@shared_task @shared_task
def issue_activity( 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: try:
issue_activities = [] issue_activities = []
@ -987,11 +1033,14 @@ def issue_activity(
issue.updated_at = timezone.now() issue.updated_at = timezone.now()
issue.save() issue.save()
# add the user to issue subscriber if subscriber:
try: # add the user to issue subscriber
_ = IssueSubscriber.objects.create(issue_id=issue_id, subscriber=actor) try:
except Exception as e: _ = IssueSubscriber.objects.get_or_create(
pass issue_id=issue_id, subscriber=actor
)
except Exception as e:
pass
ACTIVITY_MAPPER = { ACTIVITY_MAPPER = {
"issue.activity.created": create_issue_activity, "issue.activity.created": create_issue_activity,

View File

@ -1,4 +1,5 @@
# Python improts # Python imports
import json
from datetime import timedelta from datetime import timedelta
# Django imports # Django imports
@ -11,7 +12,8 @@ from celery import shared_task
from sentry_sdk import capture_exception from sentry_sdk import capture_exception
# Module imports # Module imports
from plane.db.models import Issue, Project, IssueActivity, State from plane.db.models import Issue, Project, State
from plane.bgtasks.issue_activites_task import issue_activity
@shared_task @shared_task
@ -19,6 +21,7 @@ def archive_and_close_old_issues():
archive_old_issues() archive_old_issues()
close_old_issues() close_old_issues()
def archive_old_issues(): def archive_old_issues():
try: try:
# Get all the projects whose archive_in is greater than 0 # Get all the projects whose archive_in is greater than 0
@ -56,24 +59,21 @@ def archive_old_issues():
issues_to_update.append(issue) issues_to_update.append(issue)
# Bulk Update the issues and log the activity # Bulk Update the issues and log the activity
Issue.objects.bulk_update(issues_to_update, ["archived_at"], batch_size=100) Issue.objects.bulk_update(
IssueActivity.objects.bulk_create( issues_to_update, ["archived_at"], batch_size=100
[
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_activity.delay(
type="issue.activity.updated",
requested_data=json.dumps({"archived_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 return
except Exception as e: except Exception as e:
if settings.DEBUG: if settings.DEBUG:
@ -81,10 +81,13 @@ def archive_old_issues():
capture_exception(e) capture_exception(e)
return return
def close_old_issues(): def close_old_issues():
try: try:
# Get all the projects whose close_in is greater than 0 # 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: for project in projects:
project_id = project.id project_id = project.id
@ -113,10 +116,9 @@ def close_old_issues():
# Check if Issues # Check if Issues
if issues: if issues:
if project.default_state is None: if project.default_state is None:
close_state = project.default_state
else:
close_state = State.objects.filter(group="cancelled").first() close_state = State.objects.filter(group="cancelled").first()
else:
close_state = project.default_state
issues_to_update = [] issues_to_update = []
for issue in issues: for issue in issues:
@ -125,21 +127,18 @@ def close_old_issues():
# Bulk Update the issues and log the activity # Bulk Update the issues and log the activity
Issue.objects.bulk_update(issues_to_update, ["state"], batch_size=100) Issue.objects.bulk_update(issues_to_update, ["state"], batch_size=100)
IssueActivity.objects.bulk_create( [
[ issue_activity.delay(
IssueActivity( type="issue.activity.updated",
issue_id=issue.id, requested_data=json.dumps({"closed_to": issue.state_id}),
actor=project.created_by, actor_id=str(project.created_by_id),
verb="updated", issue_id=issue.id,
field="state", project_id=project_id,
project=project, current_instance=None,
workspace=project.workspace, subscriber=False,
comment="Plane cancelled the issue", )
) for issue in issues_to_update
for issue in issues_to_update ]
],
batch_size=100,
)
return return
except Exception as e: except Exception as e:
if settings.DEBUG: if settings.DEBUG: