diff --git a/apiserver/plane/api/serializers/view.py b/apiserver/plane/api/serializers/view.py index 021bcfb72..076228ae0 100644 --- a/apiserver/plane/api/serializers/view.py +++ b/apiserver/plane/api/serializers/view.py @@ -25,22 +25,18 @@ class IssueViewSerializer(BaseSerializer): def create(self, validated_data): query_params = validated_data.get("query_data", {}) - - if not bool(query_params): - raise serializers.ValidationError( - {"query_data": ["Query data field cannot be empty"]} - ) - - validated_data["query"] = issue_filters(query_params, "POST") + if bool(query_params): + validated_data["query"] = issue_filters(query_params, "POST") + else: + validated_data["query"] = dict() return IssueView.objects.create(**validated_data) def update(self, instance, validated_data): query_params = validated_data.get("query_data", {}) - if not bool(query_params): - raise serializers.ValidationError( - {"query_data": ["Query data field cannot be empty"]} - ) - + if bool(query_params): + validated_data["query"] = issue_filters(query_params, "POST") + else: + validated_data["query"] = dict() validated_data["query"] = issue_filters(query_params, "PATCH") return super().update(instance, validated_data) diff --git a/apiserver/plane/api/views/issue.py b/apiserver/plane/api/views/issue.py index 963115c96..1f604d271 100644 --- a/apiserver/plane/api/views/issue.py +++ b/apiserver/plane/api/views/issue.py @@ -246,6 +246,20 @@ class UserWorkSpaceIssues(BaseAPIView): .prefetch_related("assignees") .prefetch_related("labels") .order_by("-created_at") + .annotate( + link_count=IssueLink.objects.filter(issue=OuterRef("id")) + .order_by() + .annotate(count=Func(F("id"), function="Count")) + .values("count") + ) + .annotate( + attachment_count=IssueAttachment.objects.filter( + issue=OuterRef("id") + ) + .order_by() + .annotate(count=Func(F("id"), function="Count")) + .values("count") + ) ) serializer = IssueLiteSerializer(issues, many=True) return Response(serializer.data, status=status.HTTP_200_OK) diff --git a/apps/app/components/auth-screens/project/join-project.tsx b/apps/app/components/auth-screens/project/join-project.tsx index 1c2018db0..402fff42b 100644 --- a/apps/app/components/auth-screens/project/join-project.tsx +++ b/apps/app/components/auth-screens/project/join-project.tsx @@ -5,15 +5,16 @@ import { useRouter } from "next/router"; import { mutate } from "swr"; +// services +import projectService from "services/project.service"; // ui import { PrimaryButton } from "components/ui"; -// icon +// icons import { AssignmentClipboardIcon } from "components/icons"; -// img +// images import JoinProjectImg from "public/auth/project-not-authorized.svg"; -import projectService from "services/project.service"; // fetch-keys -import { PROJECT_MEMBERS } from "constants/fetch-keys"; +import { USER_PROJECT_VIEW } from "constants/fetch-keys"; export const JoinProject: React.FC = () => { const [isJoiningProject, setIsJoiningProject] = useState(false); @@ -22,13 +23,16 @@ export const JoinProject: React.FC = () => { const { workspaceSlug, projectId } = router.query; const handleJoin = () => { + if (!workspaceSlug || !projectId) return; + setIsJoiningProject(true); projectService .joinProject(workspaceSlug as string, { project_ids: [projectId as string], }) - .then(() => { - mutate(PROJECT_MEMBERS(projectId as string)); + .then(async () => { + await mutate(USER_PROJECT_VIEW(workspaceSlug.toString())); + setIsJoiningProject(false); }) .catch((err) => { console.error(err); diff --git a/apps/app/components/core/existing-issues-list-modal.tsx b/apps/app/components/core/existing-issues-list-modal.tsx index 4d9ec5909..2e255ae19 100644 --- a/apps/app/components/core/existing-issues-list-modal.tsx +++ b/apps/app/components/core/existing-issues-list-modal.tsx @@ -19,7 +19,12 @@ import { LayerDiagonalIcon } from "components/icons"; // types import { IIssue } from "types"; // fetch-keys -import { CYCLE_ISSUES_WITH_PARAMS, MODULE_ISSUES_WITH_PARAMS } from "constants/fetch-keys"; +import { + CYCLE_DETAILS, + CYCLE_ISSUES_WITH_PARAMS, + MODULE_DETAILS, + MODULE_ISSUES_WITH_PARAMS, +} from "constants/fetch-keys"; type FormInput = { issues: string[]; @@ -76,8 +81,14 @@ export const ExistingIssuesListModal: React.FC = ({ } await handleOnSubmit(data); - if (cycleId) mutate(CYCLE_ISSUES_WITH_PARAMS(cycleId as string, params)); - if (moduleId) mutate(MODULE_ISSUES_WITH_PARAMS(moduleId as string, params)); + if (cycleId) { + mutate(CYCLE_ISSUES_WITH_PARAMS(cycleId as string, params)); + mutate(CYCLE_DETAILS(cycleId as string)); + } + if (moduleId) { + mutate(MODULE_ISSUES_WITH_PARAMS(moduleId as string, params)); + mutate(MODULE_DETAILS(moduleId as string)); + } handleClose(); diff --git a/apps/app/components/core/feeds.tsx b/apps/app/components/core/feeds.tsx index 1a8e6ca24..c16fcd10f 100644 --- a/apps/app/components/core/feeds.tsx +++ b/apps/app/components/core/feeds.tsx @@ -73,6 +73,10 @@ const activityDetails: { message: "updated the description.", icon: