diff --git a/apiserver/plane/app/views/exporter/base.py b/apiserver/plane/app/views/exporter/base.py index dba61d728..5649581dc 100644 --- a/apiserver/plane/app/views/exporter/base.py +++ b/apiserver/plane/app/views/exporter/base.py @@ -41,6 +41,7 @@ class ExportIssuesEndpoint(BaseAPIView): project=project_ids, initiated_by=request.user, provider=provider, + type="issue_exports", ) issue_export_task.delay( @@ -65,7 +66,8 @@ class ExportIssuesEndpoint(BaseAPIView): def get(self, request, slug): exporter_history = ExporterHistory.objects.filter( - workspace__slug=slug + workspace__slug=slug, + type="issue_exports", ).select_related("workspace", "initiated_by") if request.GET.get("per_page", False) and request.GET.get( diff --git a/apiserver/plane/utils/issue_filters.py b/apiserver/plane/utils/issue_filters.py index f551569ed..713276d0c 100644 --- a/apiserver/plane/utils/issue_filters.py +++ b/apiserver/plane/utils/issue_filters.py @@ -23,42 +23,42 @@ def filter_valid_uuids(uuid_list): # Get the 2_weeks, 3_months def string_date_filter( - filter, duration, subsequent, term, date_filter, offset + issue_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( + issue_filter[f"{date_filter}__gte"] = now + timedelta( days=duration * 30 ) else: - filter[f"{date_filter}__gte"] = now - timedelta( + issue_filter[f"{date_filter}__gte"] = now - timedelta( days=duration * 30 ) else: if offset == "fromnow": - filter[f"{date_filter}__lte"] = now + timedelta( + issue_filter[f"{date_filter}__lte"] = now + timedelta( days=duration * 30 ) else: - filter[f"{date_filter}__lte"] = now - timedelta( + issue_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) + issue_filter[f"{date_filter}__gte"] = now + timedelta(weeks=duration) else: - filter[f"{date_filter}__gte"] = now - timedelta(weeks=duration) + issue_filter[f"{date_filter}__gte"] = now - timedelta(weeks=duration) else: if offset == "fromnow": - filter[f"{date_filter}__lte"] = now + timedelta(weeks=duration) + issue_filter[f"{date_filter}__lte"] = now + timedelta(weeks=duration) else: - filter[f"{date_filter}__lte"] = now - timedelta(weeks=duration) + issue_filter[f"{date_filter}__lte"] = now - timedelta(weeks=duration) -def date_filter(filter, date_term, queries): +def date_filter(issue_filter, date_term, queries): """ Handle all date filters """ @@ -71,7 +71,7 @@ def date_filter(filter, date_term, queries): if len(date_query) == 3: digit, term = date_query[0].split("_") string_date_filter( - filter=filter, + issue_filter=issue_filter, duration=int(digit), subsequent=date_query[1], term=term, @@ -80,32 +80,32 @@ def date_filter(filter, date_term, queries): ) else: if "after" in date_query: - filter[f"{date_term}__gte"] = date_query[0] + issue_filter[f"{date_term}__gte"] = date_query[0] else: - filter[f"{date_term}__lte"] = date_query[0] + issue_filter[f"{date_term}__lte"] = date_query[0] else: - filter[f"{date_term}__contains"] = date_query[0] + issue_filter[f"{date_term}__contains"] = date_query[0] -def filter_state(params, filter, method, prefix=""): +def filter_state(params, issue_filter, method, prefix=""): if method == "GET": states = [ item for item in params.get("state").split(",") if item != "null" ] states = filter_valid_uuids(states) if len(states) and "" not in states: - filter[f"{prefix}state__in"] = states + issue_filter[f"{prefix}state__in"] = states else: if ( params.get("state", None) and len(params.get("state")) and params.get("state") != "null" ): - filter[f"{prefix}state__in"] = params.get("state") - return filter + issue_filter[f"{prefix}state__in"] = params.get("state") + return issue_filter -def filter_state_group(params, filter, method, prefix=""): +def filter_state_group(params, issue_filter, method, prefix=""): if method == "GET": state_group = [ item @@ -113,18 +113,18 @@ def filter_state_group(params, filter, method, prefix=""): if item != "null" ] if len(state_group) and "" not in state_group: - filter[f"{prefix}state__group__in"] = state_group + issue_filter[f"{prefix}state__group__in"] = state_group else: if ( params.get("state_group", None) and len(params.get("state_group")) and params.get("state_group") != "null" ): - filter[f"{prefix}state__group__in"] = params.get("state_group") - return filter + issue_filter[f"{prefix}state__group__in"] = params.get("state_group") + return issue_filter -def filter_estimate_point(params, filter, method, prefix=""): +def filter_estimate_point(params, issue_filter, method, prefix=""): if method == "GET": estimate_points = [ item @@ -132,20 +132,20 @@ def filter_estimate_point(params, filter, method, prefix=""): if item != "null" ] if len(estimate_points) and "" not in estimate_points: - filter[f"{prefix}estimate_point__in"] = estimate_points + issue_filter[f"{prefix}estimate_point__in"] = estimate_points else: if ( params.get("estimate_point", None) and len(params.get("estimate_point")) and params.get("estimate_point") != "null" ): - filter[f"{prefix}estimate_point__in"] = params.get( + issue_filter[f"{prefix}estimate_point__in"] = params.get( "estimate_point" ) - return filter + return issue_filter -def filter_priority(params, filter, method, prefix=""): +def filter_priority(params, issue_filter, method, prefix=""): if method == "GET": priorities = [ item @@ -153,58 +153,58 @@ def filter_priority(params, filter, method, prefix=""): if item != "null" ] if len(priorities) and "" not in priorities: - filter[f"{prefix}priority__in"] = priorities + issue_filter[f"{prefix}priority__in"] = priorities else: if ( params.get("priority", None) and len(params.get("priority")) and params.get("priority") != "null" ): - filter[f"{prefix}priority__in"] = params.get("priority") - return filter + issue_filter[f"{prefix}priority__in"] = params.get("priority") + return issue_filter -def filter_parent(params, filter, method, prefix=""): +def filter_parent(params, issue_filter, method, prefix=""): if method == "GET": parents = [ item for item in params.get("parent").split(",") if item != "null" ] if "None" in parents: - filter[f"{prefix}parent__isnull"] = True + issue_filter[f"{prefix}parent__isnull"] = True parents = filter_valid_uuids(parents) if len(parents) and "" not in parents: - filter[f"{prefix}parent__in"] = parents + issue_filter[f"{prefix}parent__in"] = parents else: if ( params.get("parent", None) and len(params.get("parent")) and params.get("parent") != "null" ): - filter[f"{prefix}parent__in"] = params.get("parent") - return filter + issue_filter[f"{prefix}parent__in"] = params.get("parent") + return issue_filter -def filter_labels(params, filter, method, prefix=""): +def filter_labels(params, issue_filter, method, prefix=""): if method == "GET": labels = [ item for item in params.get("labels").split(",") if item != "null" ] if "None" in labels: - filter[f"{prefix}labels__isnull"] = True + issue_filter[f"{prefix}labels__isnull"] = True labels = filter_valid_uuids(labels) if len(labels) and "" not in labels: - filter[f"{prefix}labels__in"] = labels + issue_filter[f"{prefix}labels__in"] = labels else: if ( params.get("labels", None) and len(params.get("labels")) and params.get("labels") != "null" ): - filter[f"{prefix}labels__in"] = params.get("labels") - return filter + issue_filter[f"{prefix}labels__in"] = params.get("labels") + return issue_filter -def filter_assignees(params, filter, method, prefix=""): +def filter_assignees(params, issue_filter, method, prefix=""): if method == "GET": assignees = [ item @@ -212,21 +212,21 @@ def filter_assignees(params, filter, method, prefix=""): if item != "null" ] if "None" in assignees: - filter[f"{prefix}assignees__isnull"] = True + issue_filter[f"{prefix}assignees__isnull"] = True assignees = filter_valid_uuids(assignees) if len(assignees) and "" not in assignees: - filter[f"{prefix}assignees__in"] = assignees + issue_filter[f"{prefix}assignees__in"] = assignees else: if ( params.get("assignees", None) and len(params.get("assignees")) and params.get("assignees") != "null" ): - filter[f"{prefix}assignees__in"] = params.get("assignees") - return filter + issue_filter[f"{prefix}assignees__in"] = params.get("assignees") + return issue_filter -def filter_mentions(params, filter, method, prefix=""): +def filter_mentions(params, issue_filter, method, prefix=""): if method == "GET": mentions = [ item @@ -235,20 +235,20 @@ def filter_mentions(params, filter, method, prefix=""): ] mentions = filter_valid_uuids(mentions) if len(mentions) and "" not in mentions: - filter[f"{prefix}issue_mention__mention__id__in"] = mentions + issue_filter[f"{prefix}issue_mention__mention__id__in"] = mentions else: if ( params.get("mentions", None) and len(params.get("mentions")) and params.get("mentions") != "null" ): - filter[f"{prefix}issue_mention__mention__id__in"] = params.get( + issue_filter[f"{prefix}issue_mention__mention__id__in"] = params.get( "mentions" ) - return filter + return issue_filter -def filter_created_by(params, filter, method, prefix=""): +def filter_created_by(params, issue_filter, method, prefix=""): if method == "GET": created_bys = [ item @@ -256,100 +256,100 @@ def filter_created_by(params, filter, method, prefix=""): if item != "null" ] if "None" in created_bys: - filter[f"{prefix}created_by__isnull"] = True + issue_filter[f"{prefix}created_by__isnull"] = True created_bys = filter_valid_uuids(created_bys) if len(created_bys) and "" not in created_bys: - filter[f"{prefix}created_by__in"] = created_bys + issue_filter[f"{prefix}created_by__in"] = created_bys else: if ( params.get("created_by", None) and len(params.get("created_by")) and params.get("created_by") != "null" ): - filter[f"{prefix}created_by__in"] = params.get("created_by") - return filter + issue_filter[f"{prefix}created_by__in"] = params.get("created_by") + return issue_filter -def filter_name(params, filter, method, prefix=""): +def filter_name(params, issue_filter, method, prefix=""): if params.get("name", "") != "": - filter[f"{prefix}name__icontains"] = params.get("name") - return filter + issue_filter[f"{prefix}name__icontains"] = params.get("name") + return issue_filter -def filter_created_at(params, filter, method, prefix=""): +def filter_created_at(params, issue_filter, method, prefix=""): if method == "GET": created_ats = params.get("created_at").split(",") if len(created_ats) and "" not in created_ats: date_filter( - filter=filter, + issue_filter=issue_filter, date_term=f"{prefix}created_at__date", queries=created_ats, ) else: if params.get("created_at", None) and len(params.get("created_at")): date_filter( - filter=filter, + issue_filter=issue_filter, date_term=f"{prefix}created_at__date", queries=params.get("created_at", []), ) - return filter + return issue_filter -def filter_updated_at(params, filter, method, prefix=""): +def filter_updated_at(params, issue_filter, method, prefix=""): if method == "GET": updated_ats = params.get("updated_at").split(",") if len(updated_ats) and "" not in updated_ats: date_filter( - filter=filter, + issue_filter=issue_filter, date_term=f"{prefix}created_at__date", queries=updated_ats, ) else: if params.get("updated_at", None) and len(params.get("updated_at")): date_filter( - filter=filter, + issue_filter=issue_filter, date_term=f"{prefix}created_at__date", queries=params.get("updated_at", []), ) - return filter + return issue_filter -def filter_start_date(params, filter, method, prefix=""): +def filter_start_date(params, issue_filter, method, prefix=""): if method == "GET": start_dates = params.get("start_date").split(",") if len(start_dates) and "" not in start_dates: date_filter( - filter=filter, + issue_filter=issue_filter, date_term=f"{prefix}start_date", queries=start_dates, ) else: if params.get("start_date", None) and len(params.get("start_date")): - filter[f"{prefix}start_date"] = params.get("start_date") - return filter + issue_filter[f"{prefix}start_date"] = params.get("start_date") + return issue_filter -def filter_target_date(params, filter, method, prefix=""): +def filter_target_date(params, issue_filter, method, prefix=""): if method == "GET": target_dates = params.get("target_date").split(",") if len(target_dates) and "" not in target_dates: date_filter( - filter=filter, + issue_filter=issue_filter, date_term=f"{prefix}target_date", queries=target_dates, ) else: if params.get("target_date", None) and len(params.get("target_date")): - filter[f"{prefix}target_date"] = params.get("target_date") - return filter + issue_filter[f"{prefix}target_date"] = params.get("target_date") + return issue_filter -def filter_completed_at(params, filter, method, prefix=""): +def filter_completed_at(params, issue_filter, method, prefix=""): if method == "GET": completed_ats = params.get("completed_at").split(",") if len(completed_ats) and "" not in completed_ats: date_filter( - filter=filter, + issue_filter=issue_filter, date_term=f"{prefix}completed_at__date", queries=completed_ats, ) @@ -358,14 +358,14 @@ def filter_completed_at(params, filter, method, prefix=""): params.get("completed_at") ): date_filter( - filter=filter, + issue_filter=issue_filter, date_term=f"{prefix}completed_at__date", queries=params.get("completed_at", []), ) - return filter + return issue_filter -def filter_issue_state_type(params, filter, method, prefix=""): +def filter_issue_state_type(params, issue_filter, method, prefix=""): type = params.get("type", "all") group = ["backlog", "unstarted", "started", "completed", "cancelled"] if type == "backlog": @@ -373,71 +373,71 @@ def filter_issue_state_type(params, filter, method, prefix=""): if type == "active": group = ["unstarted", "started"] - filter[f"{prefix}state__group__in"] = group - return filter + issue_filter[f"{prefix}state__group__in"] = group + return issue_filter -def filter_project(params, filter, method, prefix=""): +def filter_project(params, issue_filter, method, prefix=""): if method == "GET": projects = [ item for item in params.get("project").split(",") if item != "null" ] projects = filter_valid_uuids(projects) if len(projects) and "" not in projects: - filter[f"{prefix}project__in"] = projects + issue_filter[f"{prefix}project__in"] = projects else: if ( params.get("project", None) and len(params.get("project")) and params.get("project") != "null" ): - filter[f"{prefix}project__in"] = params.get("project") - return filter + issue_filter[f"{prefix}project__in"] = params.get("project") + return issue_filter -def filter_cycle(params, filter, method, prefix=""): +def filter_cycle(params, issue_filter, method, prefix=""): if method == "GET": cycles = [ item for item in params.get("cycle").split(",") if item != "null" ] if "None" in cycles: - filter[f"{prefix}issue_cycle__cycle_id__isnull"] = True + issue_filter[f"{prefix}issue_cycle__cycle_id__isnull"] = True cycles = filter_valid_uuids(cycles) if len(cycles) and "" not in cycles: - filter[f"{prefix}issue_cycle__cycle_id__in"] = cycles + issue_filter[f"{prefix}issue_cycle__cycle_id__in"] = cycles else: if ( params.get("cycle", None) and len(params.get("cycle")) and params.get("cycle") != "null" ): - filter[f"{prefix}issue_cycle__cycle_id__in"] = params.get("cycle") - return filter + issue_filter[f"{prefix}issue_cycle__cycle_id__in"] = params.get("cycle") + return issue_filter -def filter_module(params, filter, method, prefix=""): +def filter_module(params, issue_filter, method, prefix=""): if method == "GET": modules = [ item for item in params.get("module").split(",") if item != "null" ] if "None" in modules: - filter[f"{prefix}issue_module__module_id__isnull"] = True + issue_filter[f"{prefix}issue_module__module_id__isnull"] = True modules = filter_valid_uuids(modules) if len(modules) and "" not in modules: - filter[f"{prefix}issue_module__module_id__in"] = modules + issue_filter[f"{prefix}issue_module__module_id__in"] = modules else: if ( params.get("module", None) and len(params.get("module")) and params.get("module") != "null" ): - filter[f"{prefix}issue_module__module_id__in"] = params.get( + issue_filter[f"{prefix}issue_module__module_id__in"] = params.get( "module" ) - return filter + return issue_filter -def filter_inbox_status(params, filter, method, prefix=""): +def filter_inbox_status(params, issue_filter, method, prefix=""): if method == "GET": status = [ item @@ -445,32 +445,32 @@ def filter_inbox_status(params, filter, method, prefix=""): if item != "null" ] if len(status) and "" not in status: - filter[f"{prefix}issue_inbox__status__in"] = status + issue_filter[f"{prefix}issue_inbox__status__in"] = status else: if ( params.get("inbox_status", None) and len(params.get("inbox_status")) and params.get("inbox_status") != "null" ): - filter[f"{prefix}issue_inbox__status__in"] = params.get( + issue_filter[f"{prefix}issue_inbox__status__in"] = params.get( "inbox_status" ) - return filter + return issue_filter -def filter_sub_issue_toggle(params, filter, method, prefix=""): +def filter_sub_issue_toggle(params, issue_filter, method, prefix=""): if method == "GET": sub_issue = params.get("sub_issue", "false") if sub_issue == "false": - filter[f"{prefix}parent__isnull"] = True + issue_filter[f"{prefix}parent__isnull"] = True else: sub_issue = params.get("sub_issue", "false") if sub_issue == "false": - filter[f"{prefix}parent__isnull"] = True - return filter + issue_filter[f"{prefix}parent__isnull"] = True + return issue_filter -def filter_subscribed_issues(params, filter, method, prefix=""): +def filter_subscribed_issues(params, issue_filter, method, prefix=""): if method == "GET": subscribers = [ item @@ -479,7 +479,7 @@ def filter_subscribed_issues(params, filter, method, prefix=""): ] subscribers = filter_valid_uuids(subscribers) if len(subscribers) and "" not in subscribers: - filter[f"{prefix}issue_subscribers__subscriber_id__in"] = ( + issue_filter[f"{prefix}issue_subscribers__subscriber_id__in"] = ( subscribers ) else: @@ -488,22 +488,44 @@ def filter_subscribed_issues(params, filter, method, prefix=""): and len(params.get("subscriber")) and params.get("subscriber") != "null" ): - filter[f"{prefix}issue_subscribers__subscriber_id__in"] = ( + issue_filter[f"{prefix}issue_subscribers__subscriber_id__in"] = ( params.get("subscriber") ) - return filter + return issue_filter -def filter_start_target_date_issues(params, filter, method, prefix=""): +def filter_start_target_date_issues(params, issue_filter, method, prefix=""): start_target_date = params.get("start_target_date", "false") if start_target_date == "true": - filter[f"{prefix}target_date__isnull"] = False - filter[f"{prefix}start_date__isnull"] = False - return filter + issue_filter[f"{prefix}target_date__isnull"] = False + issue_filter[f"{prefix}start_date__isnull"] = False + return issue_filter + + +def filter_logged_by(params, issue_filter, method, prefix=""): + if method == "GET": + logged_bys = [ + item + for item in params.get("logged_by").split(",") + if item != "null" + ] + if "None" in logged_bys: + issue_filter[f"{prefix}logged_by__isnull"] = True + logged_bys = filter_valid_uuids(logged_bys) + if len(logged_bys) and "" not in logged_bys: + issue_filter[f"{prefix}logged_by__in"] = logged_bys + else: + if ( + params.get("logged_by", None) + and len(params.get("logged_by")) + and params.get("logged_by") != "null" + ): + issue_filter[f"{prefix}logged_by__in"] = params.get("logged_by") + return issue_filter def issue_filters(query_params, method, prefix=""): - filter = {} + issue_filter = {} ISSUE_FILTER = { "state": filter_state, @@ -515,6 +537,7 @@ def issue_filters(query_params, method, prefix=""): "assignees": filter_assignees, "mentions": filter_mentions, "created_by": filter_created_by, + "logged_by": filter_logged_by, "name": filter_name, "created_at": filter_created_at, "updated_at": filter_updated_at, @@ -534,5 +557,5 @@ def issue_filters(query_params, method, prefix=""): for key, value in ISSUE_FILTER.items(): if key in query_params: func = value - func(query_params, filter, method, prefix) - return filter + func(query_params, issue_filter, method, prefix) + return issue_filter