Add epic order in userstories if filter by epic ide is enabled
parent
d461b1962d
commit
e2f6245fbb
|
@ -337,10 +337,16 @@ class IsProjectAdminFromWebhookLogFilterBackend(FilterBackend, BaseIsProjectAdmi
|
||||||
#####################################################################
|
#####################################################################
|
||||||
|
|
||||||
class BaseRelatedFieldsFilter(FilterBackend):
|
class BaseRelatedFieldsFilter(FilterBackend):
|
||||||
def __init__(self, filter_name=None):
|
filter_name = None
|
||||||
|
param_name = None
|
||||||
|
|
||||||
|
def __init__(self, filter_name=None, param_name=None):
|
||||||
if filter_name:
|
if filter_name:
|
||||||
self.filter_name = filter_name
|
self.filter_name = filter_name
|
||||||
|
|
||||||
|
if param_name:
|
||||||
|
self.param_name = param_name
|
||||||
|
|
||||||
def _prepare_filter_data(self, query_param_value):
|
def _prepare_filter_data(self, query_param_value):
|
||||||
def _transform_value(value):
|
def _transform_value(value):
|
||||||
try:
|
try:
|
||||||
|
@ -355,7 +361,8 @@ class BaseRelatedFieldsFilter(FilterBackend):
|
||||||
return list(values)
|
return list(values)
|
||||||
|
|
||||||
def _get_queryparams(self, params):
|
def _get_queryparams(self, params):
|
||||||
raw_value = params.get(self.filter_name, None)
|
param_name = self.param_name or self.filter_name
|
||||||
|
raw_value = params.get(param_name, None)
|
||||||
|
|
||||||
if raw_value:
|
if raw_value:
|
||||||
value = self._prepare_filter_data(raw_value)
|
value = self._prepare_filter_data(raw_value)
|
||||||
|
|
|
@ -60,6 +60,7 @@ class UserStoryViewSet(OCCResourceMixin, VotedResourceMixin, HistoryResourceMixi
|
||||||
permission_classes = (permissions.UserStoryPermission,)
|
permission_classes = (permissions.UserStoryPermission,)
|
||||||
filter_backends = (base_filters.CanViewUsFilterBackend,
|
filter_backends = (base_filters.CanViewUsFilterBackend,
|
||||||
filters.EpicsFilter,
|
filters.EpicsFilter,
|
||||||
|
filters.EpicFilter,
|
||||||
base_filters.OwnersFilter,
|
base_filters.OwnersFilter,
|
||||||
base_filters.AssignedToFilter,
|
base_filters.AssignedToFilter,
|
||||||
base_filters.StatusesFilter,
|
base_filters.StatusesFilter,
|
||||||
|
@ -80,6 +81,7 @@ class UserStoryViewSet(OCCResourceMixin, VotedResourceMixin, HistoryResourceMixi
|
||||||
order_by_fields = ["backlog_order",
|
order_by_fields = ["backlog_order",
|
||||||
"sprint_order",
|
"sprint_order",
|
||||||
"kanban_order",
|
"kanban_order",
|
||||||
|
"epic_order",
|
||||||
"total_voters"]
|
"total_voters"]
|
||||||
|
|
||||||
def get_serializer_class(self, *args, **kwargs):
|
def get_serializer_class(self, *args, **kwargs):
|
||||||
|
@ -102,9 +104,11 @@ class UserStoryViewSet(OCCResourceMixin, VotedResourceMixin, HistoryResourceMixi
|
||||||
|
|
||||||
include_attachments = "include_attachments" in self.request.QUERY_PARAMS
|
include_attachments = "include_attachments" in self.request.QUERY_PARAMS
|
||||||
include_tasks = "include_tasks" in self.request.QUERY_PARAMS
|
include_tasks = "include_tasks" in self.request.QUERY_PARAMS
|
||||||
|
epic_id = self.request.QUERY_PARAMS.get("epic", None)
|
||||||
qs = attach_extra_info(qs, user=self.request.user,
|
qs = attach_extra_info(qs, user=self.request.user,
|
||||||
include_attachments=include_attachments,
|
include_attachments=include_attachments,
|
||||||
include_tasks=include_tasks)
|
include_tasks=include_tasks,
|
||||||
|
epic_id=epic_id)
|
||||||
|
|
||||||
return qs
|
return qs
|
||||||
|
|
||||||
|
|
|
@ -20,5 +20,10 @@
|
||||||
from taiga.base import filters
|
from taiga.base import filters
|
||||||
|
|
||||||
|
|
||||||
|
class EpicFilter(filters.BaseRelatedFieldsFilter):
|
||||||
|
filter_name = "epics"
|
||||||
|
param_name = "epic"
|
||||||
|
|
||||||
|
|
||||||
class EpicsFilter(filters.BaseRelatedFieldsFilter):
|
class EpicsFilter(filters.BaseRelatedFieldsFilter):
|
||||||
filter_name = 'epics'
|
filter_name = "epics"
|
||||||
|
|
|
@ -78,8 +78,20 @@ class UserStoryListSerializer(ProjectExtraInfoSerializerMixin,
|
||||||
comment = MethodField()
|
comment = MethodField()
|
||||||
origin_issue = OriginIssueSerializer(attr="generated_from_issue")
|
origin_issue = OriginIssueSerializer(attr="generated_from_issue")
|
||||||
epics = MethodField()
|
epics = MethodField()
|
||||||
|
epic_order = MethodField()
|
||||||
tasks = MethodField()
|
tasks = MethodField()
|
||||||
|
|
||||||
|
def get_epic_order(self, obj):
|
||||||
|
include_epic_order = getattr(obj, "include_epic_order", False)
|
||||||
|
|
||||||
|
if include_epic_order:
|
||||||
|
assert hasattr(obj, "epic_order"), "instance must have a epic_order attribute"
|
||||||
|
|
||||||
|
if not include_epic_order or obj.epic_order is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return obj.epic_order
|
||||||
|
|
||||||
def get_epics(self, obj):
|
def get_epics(self, obj):
|
||||||
assert hasattr(obj, "epics_attr"), "instance must have a epics_attr attribute"
|
assert hasattr(obj, "epics_attr"), "instance must have a epics_attr attribute"
|
||||||
return obj.epics_attr
|
return obj.epics_attr
|
||||||
|
|
|
@ -120,14 +120,36 @@ def attach_epics(queryset, as_field="epics_attr"):
|
||||||
FROM "epics_relateduserstory"
|
FROM "epics_relateduserstory"
|
||||||
INNER JOIN "epics_epic" ON "epics_epic"."id" = "epics_relateduserstory"."epic_id"
|
INNER JOIN "epics_epic" ON "epics_epic"."id" = "epics_relateduserstory"."epic_id"
|
||||||
INNER JOIN "projects_project" ON "projects_project"."id" = "epics_epic"."project_id"
|
INNER JOIN "projects_project" ON "projects_project"."id" = "epics_epic"."project_id"
|
||||||
WHERE "epics_relateduserstory"."user_story_id" = {tbl}.id) t"""
|
WHERE "epics_relateduserstory"."user_story_id" = {tbl}.id
|
||||||
|
ORDER BY "projects_project"."name", "epics_epic"."ref") t"""
|
||||||
|
|
||||||
sql = sql.format(tbl=model._meta.db_table)
|
sql = sql.format(tbl=model._meta.db_table)
|
||||||
queryset = queryset.extra(select={as_field: sql})
|
queryset = queryset.extra(select={as_field: sql})
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
|
|
||||||
def attach_extra_info(queryset, user=None, include_attachments=False, include_tasks=False):
|
def attach_epic_order(queryset, epic_id, as_field="epic_order"):
|
||||||
|
"""Attach epic_order column to each object of the queryset.
|
||||||
|
|
||||||
|
:param queryset: A Django user stories queryset object.
|
||||||
|
:param epic_id: Order related to this epic.
|
||||||
|
:param as_field: Attach order as an attribute with this name.
|
||||||
|
|
||||||
|
:return: Queryset object with the additional `as_field` field.
|
||||||
|
"""
|
||||||
|
|
||||||
|
model = queryset.model
|
||||||
|
sql = """SELECT "epics_relateduserstory"."order" AS "epic_order"
|
||||||
|
FROM "epics_relateduserstory"
|
||||||
|
WHERE "epics_relateduserstory"."user_story_id" = {tbl}.id and
|
||||||
|
"epics_relateduserstory"."epic_id" = {epic_id}"""
|
||||||
|
|
||||||
|
sql = sql.format(tbl=model._meta.db_table, epic_id=epic_id)
|
||||||
|
queryset = queryset.extra(select={as_field: sql})
|
||||||
|
return queryset
|
||||||
|
|
||||||
|
|
||||||
|
def attach_extra_info(queryset, user=None, include_attachments=False, include_tasks=False, epic_id=None):
|
||||||
queryset = attach_total_points(queryset)
|
queryset = attach_total_points(queryset)
|
||||||
queryset = attach_role_points(queryset)
|
queryset = attach_role_points(queryset)
|
||||||
queryset = attach_epics(queryset)
|
queryset = attach_epics(queryset)
|
||||||
|
@ -140,6 +162,10 @@ def attach_extra_info(queryset, user=None, include_attachments=False, include_ta
|
||||||
queryset = attach_tasks(queryset)
|
queryset = attach_tasks(queryset)
|
||||||
queryset = queryset.extra(select={"include_tasks": "True"})
|
queryset = queryset.extra(select={"include_tasks": "True"})
|
||||||
|
|
||||||
|
if epic_id is not None:
|
||||||
|
queryset = attach_epic_order(queryset, epic_id)
|
||||||
|
queryset = queryset.extra(select={"include_epic_order": "True"})
|
||||||
|
|
||||||
queryset = attach_total_voters_to_queryset(queryset)
|
queryset = attach_total_voters_to_queryset(queryset)
|
||||||
queryset = attach_watchers_to_queryset(queryset)
|
queryset = attach_watchers_to_queryset(queryset)
|
||||||
queryset = attach_total_watchers_to_queryset(queryset)
|
queryset = attach_total_watchers_to_queryset(queryset)
|
||||||
|
|
Loading…
Reference in New Issue