[WEB-1397] refactor: edition specific migration (#4847)

* refactor: edition specific migration

* revert: pagination from space endpoints

* fix: project publish

---------

Co-authored-by: pablohashescobar <nikhilschacko@gmail.com>
This commit is contained in:
Aaryan Khandelwal 2024-06-17 20:09:15 +05:30 committed by GitHub
parent 413d6d21b4
commit c9cf7cc631
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
135 changed files with 221 additions and 203 deletions

View file

@ -2,7 +2,20 @@
import json
from django.core.serializers.json import DjangoJSONEncoder
from django.db.models import Exists, F, Func, OuterRef, Q, Prefetch
from django.db.models import (
Exists,
F,
Func,
OuterRef,
Q,
Prefetch,
Case,
When,
CharField,
IntegerField,
Value,
Max,
)
# Django imports
from django.utils import timezone
@ -30,19 +43,11 @@ from plane.db.models import (
DeployBoard,
IssueVote,
ProjectPublicMember,
State,
Label,
)
from plane.bgtasks.issue_activites_task import issue_activity
from plane.utils.grouper import (
issue_group_values,
issue_on_results,
issue_queryset_grouper,
)
from plane.utils.issue_filters import issue_filters
from plane.utils.order_queryset import order_issue_queryset
from plane.utils.paginator import (
GroupedOffsetPaginator,
SubGroupedOffsetPaginator,
)
# Module imports
from .base import BaseAPIView, BaseViewSet
@ -516,24 +521,32 @@ class ProjectIssuesPublicEndpoint(BaseAPIView):
]
def get(self, request, anchor):
if not DeployBoard.objects.filter(
deploy_board = DeployBoard.objects.filter(
anchor=anchor, entity_name="project"
).exists():
).first()
if not deploy_board:
return Response(
{"error": "Project is not published"},
status=status.HTTP_404_NOT_FOUND,
)
project_deploy_board = DeployBoard.objects.get(
anchor=anchor, entity_name="project"
)
project_id = project_deploy_board.entity_identifier
slug = project_deploy_board.workspace.slug
filters = issue_filters(request.query_params, "GET")
# Custom ordering for priority and state
priority_order = ["urgent", "high", "medium", "low", "none"]
state_order = [
"backlog",
"unstarted",
"started",
"completed",
"cancelled",
]
order_by_param = request.GET.get("order_by", "-created_at")
project_id = deploy_board.entity_identifier
slug = deploy_board.workspace.slug
issue_queryset = (
Issue.issue_objects.annotate(
sub_issues_count=Issue.issue_objects.filter(
@ -543,8 +556,8 @@ class ProjectIssuesPublicEndpoint(BaseAPIView):
.annotate(count=Func(F("id"), function="Count"))
.values("count")
)
.filter(project_id=project_deploy_board.project_id)
.filter(workspace_id=project_deploy_board.workspace_id)
.filter(project_id=project_id)
.filter(workspace__slug=slug)
.select_related("project", "workspace", "state", "parent")
.prefetch_related("assignees", "labels")
.prefetch_related(
@ -561,6 +574,7 @@ class ProjectIssuesPublicEndpoint(BaseAPIView):
)
.filter(**filters)
.annotate(cycle_id=F("issue_cycle__cycle_id"))
.annotate(module_id=F("issue_module__module_id"))
.annotate(
link_count=IssueLink.objects.filter(issue=OuterRef("id"))
.order_by()
@ -575,118 +589,107 @@ class ProjectIssuesPublicEndpoint(BaseAPIView):
.annotate(count=Func(F("id"), function="Count"))
.values("count")
)
.annotate(
sub_issues_count=Issue.issue_objects.filter(
parent=OuterRef("id")
)
.order_by()
.annotate(count=Func(F("id"), function="Count"))
.values("count")
)
# Priority Ordering
if order_by_param == "priority" or order_by_param == "-priority":
priority_order = (
priority_order
if order_by_param == "priority"
else priority_order[::-1]
)
).distinct()
order_by_param = request.GET.get("order_by", "-created_at")
issue_queryset = self.get_queryset().filter(**filters)
# Issue queryset
issue_queryset, order_by_param = order_issue_queryset(
issue_queryset=issue_queryset,
order_by_param=order_by_param,
)
# Group by
group_by = request.GET.get("group_by", False)
sub_group_by = request.GET.get("sub_group_by", False)
# issue queryset
issue_queryset = issue_queryset_grouper(
queryset=issue_queryset,
group_by=group_by,
sub_group_by=sub_group_by,
)
if group_by:
# Check group and sub group value paginate
if sub_group_by:
if group_by == sub_group_by:
return Response(
{
"error": "Group by and sub group by cannot have same parameters"
},
status=status.HTTP_400_BAD_REQUEST,
)
else:
# group and sub group pagination
return self.paginate(
request=request,
order_by=order_by_param,
queryset=issue_queryset,
on_results=lambda issues: issue_on_results(
group_by=group_by,
issues=issues,
sub_group_by=sub_group_by,
),
paginator_cls=SubGroupedOffsetPaginator,
group_by_fields=issue_group_values(
field=group_by,
slug=slug,
project_id=project_id,
filters=filters,
),
sub_group_by_fields=issue_group_values(
field=sub_group_by,
slug=slug,
project_id=project_id,
filters=filters,
),
group_by_field_name=group_by,
sub_group_by_field_name=sub_group_by,
count_filter=Q(
Q(issue_inbox__status=1)
| Q(issue_inbox__status=-1)
| Q(issue_inbox__status=2)
| Q(issue_inbox__isnull=True),
archived_at__isnull=True,
is_draft=False,
),
)
# Group Paginate
else:
# Group paginate
return self.paginate(
request=request,
order_by=order_by_param,
queryset=issue_queryset,
on_results=lambda issues: issue_on_results(
group_by=group_by,
issues=issues,
sub_group_by=sub_group_by,
),
paginator_cls=GroupedOffsetPaginator,
group_by_fields=issue_group_values(
field=group_by,
slug=slug,
project_id=project_id,
filters=filters,
),
group_by_field_name=group_by,
count_filter=Q(
Q(issue_inbox__status=1)
| Q(issue_inbox__status=-1)
| Q(issue_inbox__status=2)
| Q(issue_inbox__isnull=True),
archived_at__isnull=True,
is_draft=False,
),
issue_queryset = issue_queryset.annotate(
priority_order=Case(
*[
When(priority=p, then=Value(i))
for i, p in enumerate(priority_order)
],
output_field=CharField(),
)
).order_by("priority_order")
# State Ordering
elif order_by_param in [
"state__name",
"state__group",
"-state__name",
"-state__group",
]:
state_order = (
state_order
if order_by_param in ["state__name", "state__group"]
else state_order[::-1]
)
issue_queryset = issue_queryset.annotate(
state_order=Case(
*[
When(state__group=state_group, then=Value(i))
for i, state_group in enumerate(state_order)
],
default=Value(len(state_order)),
output_field=CharField(),
)
).order_by("state_order")
# assignee and label ordering
elif order_by_param in [
"labels__name",
"-labels__name",
"assignees__first_name",
"-assignees__first_name",
]:
issue_queryset = issue_queryset.annotate(
max_values=Max(
order_by_param[1::]
if order_by_param.startswith("-")
else order_by_param
)
).order_by(
"-max_values"
if order_by_param.startswith("-")
else "max_values"
)
else:
# List Paginate
return self.paginate(
order_by=order_by_param,
request=request,
queryset=issue_queryset,
on_results=lambda issues: issue_on_results(
group_by=group_by, issues=issues, sub_group_by=sub_group_by
issue_queryset = issue_queryset.order_by(order_by_param)
issues = IssuePublicSerializer(issue_queryset, many=True).data
state_group_order = [
"backlog",
"unstarted",
"started",
"completed",
"cancelled",
]
states = (
State.objects.filter(
~Q(name="Triage"),
workspace__slug=slug,
project_id=project_id,
)
.annotate(
custom_order=Case(
*[
When(group=value, then=Value(index))
for index, value in enumerate(state_group_order)
],
default=Value(len(state_group_order)),
output_field=IntegerField(),
),
)
.values("name", "group", "color", "id")
.order_by("custom_order", "sequence")
)
labels = Label.objects.filter(
workspace__slug=slug, project_id=project_id
).values("id", "name", "color", "parent")
return Response(
{
"issues": issues,
"states": states,
"labels": labels,
},
status=status.HTTP_200_OK,
)

View file

@ -37,7 +37,9 @@ class WorkspaceProjectDeployBoardEndpoint(BaseAPIView):
]
def get(self, request, anchor):
deploy_board = DeployBoard.objects.filter(anchor=anchor, entity_name="project").values_list
deploy_board = DeployBoard.objects.filter(
anchor=anchor, entity_name="project"
).values_list
projects = (
Project.objects.filter(workspace=deploy_board.workspace)
.annotate(

View file

@ -16,7 +16,7 @@ def log_exception(e):
if settings.DEBUG:
# Print the traceback if in debug mode
traceback.print_exc(e)
print(traceback.format_exc())
# Capture in sentry if configured
capture_exception(e)

View file

@ -7,7 +7,7 @@ import useSWR from "swr";
import { LogoSpinner } from "@/components/common";
import { IssuesNavbarRoot } from "@/components/issues";
// hooks
import { usePublish, usePublishList } from "@/hooks/store";
import { useIssueFilter, usePublish, usePublishList } from "@/hooks/store";
// assets
import planeLogo from "@/public/plane-logo.svg";
@ -25,8 +25,25 @@ const IssuesLayout = observer((props: Props) => {
// store hooks
const { fetchPublishSettings } = usePublishList();
const publishSettings = usePublish(anchor);
const { updateLayoutOptions } = useIssueFilter();
// fetch publish settings
useSWR(anchor ? `PUBLISH_SETTINGS_${anchor}` : null, anchor ? () => fetchPublishSettings(anchor) : null);
useSWR(
anchor ? `PUBLISH_SETTINGS_${anchor}` : null,
anchor
? async () => {
const response = await fetchPublishSettings(anchor);
if (response.view_props) {
updateLayoutOptions({
list: !!response.view_props.list,
kanban: !!response.view_props.kanban,
calendar: !!response.view_props.calendar,
gantt: !!response.view_props.gantt,
spreadsheet: !!response.view_props.spreadsheet,
});
}
}
: null
);
if (!publishSettings) return <LogoSpinner />;

View file

@ -0,0 +1,8 @@
// store
import { CoreRootStore } from "@/store/root.store";
export class RootStore extends CoreRootStore {
constructor() {
super();
}
}

View file

@ -7,7 +7,7 @@ import { Search, X } from "lucide-react";
import { IStateLite } from "@plane/types";
import { IIssueLabel, IIssueFilterOptions, TIssueFilterKeys } from "@/types/issue";
// components
import { FilterPriority, FilterState } from "./";
import { FilterPriority, FilterState } from ".";
type Props = {
filters: IIssueFilterOptions;

View file

@ -1,4 +1,4 @@
import { Calendar, GanttChartSquare, Kanban, List, Sheet } from "lucide-react";
import { Kanban, List } from "lucide-react";
// types
import { TIssuePriorities } from "@plane/types";
import { TIssueLayout, TIssueFilterKeys, TIssueFilterPriorityObject } from "@/types/issue";
@ -29,9 +29,9 @@ export const ISSUE_LAYOUTS: {
}[] = [
{ key: "list", title: "List", icon: List },
{ key: "kanban", title: "Kanban", icon: Kanban },
{ key: "calendar", title: "Calendar", icon: Calendar },
{ key: "spreadsheet", title: "Spreadsheet", icon: Sheet },
{ key: "gantt", title: "Gantt chart", icon: GanttChartSquare },
// { key: "calendar", title: "Calendar", icon: Calendar },
// { key: "spreadsheet", title: "Spreadsheet", icon: Sheet },
// { key: "gantt", title: "Gantt chart", icon: GanttChartSquare },
];
export const issuePriorityFilters: TIssueFilterPriorityObject[] = [

Some files were not shown because too many files have changed in this diff Show more