Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: date filters #2271

Merged
merged 4 commits into from
Oct 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions apiserver/plane/api/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@
GlobalViewViewSet,
GlobalViewIssuesViewSet,
IssueViewViewSet,
ViewIssuesEndpoint,
IssueViewFavoriteViewSet,
## End Views
# Cycles
Expand Down Expand Up @@ -657,11 +656,6 @@
),
name="project-view",
),
path(
"workspaces/<str:slug>/projects/<uuid:project_id>/views/<uuid:view_id>/issues/",
ViewIssuesEndpoint.as_view(),
name="project-view-issues",
),
path(
"workspaces/<str:slug>/views/",
GlobalViewViewSet.as_view(
Expand Down
2 changes: 1 addition & 1 deletion apiserver/plane/api/views/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
LeaveWorkspaceEndpoint,
)
from .state import StateViewSet
from .view import GlobalViewViewSet, GlobalViewIssuesViewSet, IssueViewViewSet, ViewIssuesEndpoint, IssueViewFavoriteViewSet
from .view import GlobalViewViewSet, GlobalViewIssuesViewSet, IssueViewViewSet, IssueViewFavoriteViewSet
from .cycle import (
CycleViewSet,
CycleIssueViewSet,
Expand Down
2 changes: 0 additions & 2 deletions apiserver/plane/api/views/issue.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
from django.utils.decorators import method_decorator
from django.views.decorators.gzip import gzip_page
from django.db import IntegrityError
from django.db import IntegrityError

# Third Party imports
from rest_framework.response import Response
Expand Down Expand Up @@ -84,7 +83,6 @@
from plane.bgtasks.issue_activites_task import issue_activity
from plane.utils.grouper import group_results
from plane.utils.issue_filters import issue_filters
from plane.bgtasks.export_task import issue_export_task


class IssueViewSet(BaseViewSet):
Expand Down
45 changes: 0 additions & 45 deletions apiserver/plane/api/views/view.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,51 +243,6 @@ def get_queryset(self):
)


class ViewIssuesEndpoint(BaseAPIView):
permission_classes = [
ProjectEntityPermission,
]

def get(self, request, slug, project_id, view_id):
try:
view = IssueView.objects.get(pk=view_id)
queries = view.query

filters = issue_filters(request.query_params, "GET")

issues = (
Issue.issue_objects.filter(
**queries, project_id=project_id, workspace__slug=slug
)
.filter(**filters)
.select_related("project")
.select_related("workspace")
.select_related("state")
.select_related("parent")
.prefetch_related("assignees")
.prefetch_related("labels")
.prefetch_related(
Prefetch(
"issue_reactions",
queryset=IssueReaction.objects.select_related("actor"),
)
)
)

serializer = IssueLiteSerializer(issues, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
except IssueView.DoesNotExist:
return Response(
{"error": "Issue View does not exist"}, status=status.HTTP_404_NOT_FOUND
)
except Exception as e:
capture_exception(e)
return Response(
{"error": "Something went wrong please try again later"},
status=status.HTTP_400_BAD_REQUEST,
)


class IssueViewFavoriteViewSet(BaseViewSet):
serializer_class = IssueViewFavoriteSerializer
model = IssueViewFavorite
Expand Down
133 changes: 70 additions & 63 deletions apiserver/plane/utils/issue_filters.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,62 @@
from django.utils.timezone import make_aware
from django.utils.dateparse import parse_datetime
import re
from datetime import timedelta
from django.utils import timezone

# The date from pattern
pattern = re.compile(r"\d+_(weeks|months)$")


# Get the 2_weeks, 3_months
def string_date_filter(filter, duration, subsequent, term, date_filter, offset):
now = timezone.now().date()
if term == "months":
if subsequent == "after":
if offset == "fromnow":
filter[f"{date_filter}__gte"] = now + timedelta(days=duration * 30)
else:
filter[f"{date_filter}__gte"] = now - timedelta(days=duration * 30)
else:
if offset == "fromnow":
filter[f"{date_filter}__lte"] = now + timedelta(days=duration * 30)
else:
filter[f"{date_filter}__lte"] = now - timedelta(days=duration * 30)
if term == "weeks":
if subsequent == "after":
if offset == "fromnow":
filter[f"{date_filter}__gte"] = now + timedelta(weeks=duration)
else:
filter[f"{date_filter}__gte"] = now - timedelta(weeks=duration)
else:
if offset == "fromnow":
filter[f"{date_filter}__lte"] = now + timedelta(days=duration)
else:
filter[f"{date_filter}__lte"] = now - timedelta(days=duration)


def date_filter(filter, date_term, queries):
"""
Handle all date filters
"""
for query in queries:
date_query = query.split(";")
if len(date_query) >= 2:
match = pattern.match(date_query[0])
if match:
if len(date_query) == 3:
digit, term = date_query[0].split("_")
string_date_filter(
filter=filter,
duration=int(digit),
subsequent=date_query[1],
term=term,
date_filter="created_at__date",
offset=date_query[2],
)
else:
if "after" in date_query:
filter[f"{date_term}__gte"] = date_query[0]
else:
filter[f"{date_term}__lte"] = date_query[0]


def filter_state(params, filter, method):
Expand Down Expand Up @@ -97,105 +154,55 @@ def filter_created_at(params, filter, method):
if method == "GET":
created_ats = params.get("created_at").split(",")
if len(created_ats) and "" not in created_ats:
for query in created_ats:
created_at_query = query.split(";")
if len(created_at_query) == 2 and "after" in created_at_query:
filter["created_at__date__gte"] = created_at_query[0]
else:
filter["created_at__date__lte"] = created_at_query[0]
date_filter(filter=filter, date_term="created_at__date", queries=created_ats)
else:
if params.get("created_at", None) and len(params.get("created_at")):
for query in params.get("created_at"):
created_at_query = query.split(";")
if len(created_at_query) == 2 and "after" in created_at_query:
filter["created_at__date__gte"] = created_at_query[0]
else:
filter["created_at__date__lte"] = created_at_query[0]
date_filter(filter=filter, date_term="created_at__date", queries=params.get("created_at", []))
return filter


def filter_updated_at(params, filter, method):
if method == "GET":
updated_ats = params.get("updated_at").split(",")
if len(updated_ats) and "" not in updated_ats:
for query in updated_ats:
updated_at_query = query.split(";")
if len(updated_at_query) == 2 and "after" in updated_at_query:
filter["updated_at__date__gte"] = updated_at_query[0]
else:
filter["updated_at__date__lte"] = updated_at_query[0]
date_filter(filter=filter, date_term="created_at__date", queries=updated_ats)
else:
if params.get("updated_at", None) and len(params.get("updated_at")):
for query in params.get("updated_at"):
updated_at_query = query.split(";")
if len(updated_at_query) == 2 and "after" in updated_at_query:
filter["updated_at__date__gte"] = updated_at_query[0]
else:
filter["updated_at__date__lte"] = updated_at_query[0]
date_filter(filter=filter, date_term="created_at__date", queries=params.get("updated_at", []))
return filter


def filter_start_date(params, filter, method):
if method == "GET":
start_dates = params.get("start_date").split(",")
if len(start_dates) and "" not in start_dates:
for query in start_dates:
start_date_query = query.split(";")
if len(start_date_query) == 2 and "after" in start_date_query:
filter["start_date__gte"] = start_date_query[0]
else:
filter["start_date__lte"] = start_date_query[0]
date_filter(filter=filter, date_term="start_date", queries=start_dates)
else:
if params.get("start_date", None) and len(params.get("start_date")):
for query in params.get("start_date"):
start_date_query = query.split(";")
if len(start_date_query) == 2 and "after" in start_date_query:
filter["start_date__gte"] = start_date_query[0]
else:
filter["start_date__lte"] = start_date_query[0]
date_filter(filter=filter, date_term="start_date", queries=params.get("start_date", []))
return filter


def filter_target_date(params, filter, method):
if method == "GET":
target_dates = params.get("target_date").split(",")
if len(target_dates) and "" not in target_dates:
for query in target_dates:
target_date_query = query.split(";")
if len(target_date_query) == 2 and "after" in target_date_query:
filter["target_date__gte"] = target_date_query[0]
else:
filter["target_date__lte"] = target_date_query[0]

date_filter(filter=filter, date_term="target_date", queries=target_dates)
else:
if params.get("target_date", None) and len(params.get("target_date")):
for query in params.get("target_date"):
target_date_query = query.split(";")
if len(target_date_query) == 2 and "after" in target_date_query:
filter["target_date__gte"] = target_date_query[0]
else:
filter["target_date__lte"] = target_date_query[0]

date_filter(filter=filter, date_term="target_date", queries=params.get("target_date", []))
return filter


def filter_completed_at(params, filter, method):
if method == "GET":
completed_ats = params.get("completed_at").split(",")
if len(completed_ats) and "" not in completed_ats:
for query in completed_ats:
completed_at_query = query.split(";")
if len(completed_at_query) == 2 and "after" in completed_at_query:
filter["completed_at__date__gte"] = completed_at_query[0]
else:
filter["completed_at__lte"] = completed_at_query[0]
date_filter(filter=filter, date_term="completed_at__date", queries=completed_ats)
else:
if params.get("completed_at", None) and len(params.get("completed_at")):
for query in params.get("completed_at"):
completed_at_query = query.split(";")
if len(completed_at_query) == 2 and "after" in completed_at_query:
filter["completed_at__date__gte"] = completed_at_query[0]
else:
filter["completed_at__lte"] = completed_at_query[0]
date_filter(filter=filter, date_term="completed_at__date", queries=params.get("completed_at", []))
return filter


Expand Down
Loading