[WEB-3251] fix: add to projects list API (#6550)
This commit is contained in:
parent
9bd70cdb4e
commit
89d1926727
7 changed files with 48 additions and 41 deletions
|
|
@ -91,7 +91,6 @@ class ProjectLiteSerializer(BaseSerializer):
|
|||
|
||||
class ProjectListSerializer(DynamicBaseSerializer):
|
||||
is_favorite = serializers.BooleanField(read_only=True)
|
||||
is_member = serializers.BooleanField(read_only=True)
|
||||
sort_order = serializers.FloatField(read_only=True)
|
||||
member_role = serializers.IntegerField(read_only=True)
|
||||
anchor = serializers.CharField(read_only=True)
|
||||
|
|
@ -120,7 +119,6 @@ class ProjectDetailSerializer(BaseSerializer):
|
|||
default_assignee = UserLiteSerializer(read_only=True)
|
||||
project_lead = UserLiteSerializer(read_only=True)
|
||||
is_favorite = serializers.BooleanField(read_only=True)
|
||||
is_member = serializers.BooleanField(read_only=True)
|
||||
sort_order = serializers.FloatField(read_only=True)
|
||||
member_role = serializers.IntegerField(read_only=True)
|
||||
anchor = serializers.CharField(read_only=True)
|
||||
|
|
|
|||
|
|
@ -70,16 +70,6 @@ class ProjectViewSet(BaseViewSet):
|
|||
)
|
||||
)
|
||||
)
|
||||
.annotate(
|
||||
is_member=Exists(
|
||||
ProjectMember.objects.filter(
|
||||
member=self.request.user,
|
||||
project_id=OuterRef("pk"),
|
||||
workspace__slug=self.kwargs.get("slug"),
|
||||
is_active=True,
|
||||
)
|
||||
)
|
||||
)
|
||||
.annotate(
|
||||
member_role=ProjectMember.objects.filter(
|
||||
project_id=OuterRef("pk"),
|
||||
|
|
@ -164,14 +154,11 @@ class ProjectViewSet(BaseViewSet):
|
|||
"workspace", "workspace__owner", "default_assignee", "project_lead"
|
||||
)
|
||||
.annotate(
|
||||
is_member=Exists(
|
||||
ProjectMember.objects.filter(
|
||||
member=self.request.user,
|
||||
project_id=OuterRef("pk"),
|
||||
workspace__slug=self.kwargs.get("slug"),
|
||||
is_active=True,
|
||||
)
|
||||
)
|
||||
member_role=ProjectMember.objects.filter(
|
||||
project_id=OuterRef("pk"),
|
||||
member_id=self.request.user.id,
|
||||
is_active=True,
|
||||
).values("role")
|
||||
)
|
||||
.annotate(inbox_view=F("intake_view"))
|
||||
.annotate(sort_order=Subquery(sort_order))
|
||||
|
|
@ -182,7 +169,7 @@ class ProjectViewSet(BaseViewSet):
|
|||
"identifier",
|
||||
"sort_order",
|
||||
"logo_props",
|
||||
"is_member",
|
||||
"member_role",
|
||||
"archived_at",
|
||||
"workspace",
|
||||
"cycle_view",
|
||||
|
|
|
|||
3
packages/types/src/project/projects.d.ts
vendored
3
packages/types/src/project/projects.d.ts
vendored
|
|
@ -16,7 +16,7 @@ export interface IPartialProject {
|
|||
identifier: string;
|
||||
sort_order: number | null;
|
||||
logo_props: TLogoProps;
|
||||
is_member: boolean;
|
||||
member_role: TUserPermissions | null;
|
||||
archived_at: string | null;
|
||||
workspace: IWorkspace | string;
|
||||
cycle_view: boolean;
|
||||
|
|
@ -50,7 +50,6 @@ export interface IProject extends IPartialProject {
|
|||
is_favorite?: boolean;
|
||||
is_issue_type_enabled?: boolean;
|
||||
is_time_tracking_enabled?: boolean;
|
||||
member_role?: TUserPermissions | null;
|
||||
members?: string[];
|
||||
network?: number;
|
||||
timezone?: string;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,25 @@
|
|||
import Root from "@/components/project/root";
|
||||
"use client";
|
||||
|
||||
export const ProjectPageRoot = () => <Root />;
|
||||
import { observer } from "mobx-react";
|
||||
import { useParams } from "next/navigation";
|
||||
import useSWR from "swr";
|
||||
// components
|
||||
import Root from "@/components/project/root";
|
||||
// hooks
|
||||
import { useProject, useWorkspace } from "@/hooks/store";
|
||||
|
||||
export const ProjectPageRoot = observer(() => {
|
||||
// router
|
||||
const { workspaceSlug } = useParams();
|
||||
// store
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { fetchProjects } = useProject();
|
||||
// fetching workspace projects
|
||||
useSWR(
|
||||
workspaceSlug && currentWorkspace ? `WORKSPACE_PROJECTS_${workspaceSlug}` : null,
|
||||
workspaceSlug && currentWorkspace ? () => fetchProjects(workspaceSlug.toString()) : null,
|
||||
{ revalidateIfStale: false, revalidateOnFocus: false }
|
||||
);
|
||||
|
||||
return <Root />;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -63,8 +63,9 @@ export const ProjectCard: React.FC<Props> = observer((props) => {
|
|||
EUserPermissionsLevel.WORKSPACE
|
||||
);
|
||||
// auth
|
||||
const isOwner = project.member_role === EUserPermissions.ADMIN;
|
||||
const isMember = project.member_role === EUserPermissions.MEMBER;
|
||||
const isMemberOfProject = !!project.member_role;
|
||||
const hasAdminRole = project.member_role === EUserPermissions.ADMIN;
|
||||
const hasMemberRole = project.member_role === EUserPermissions.MEMBER;
|
||||
// archive
|
||||
const isArchived = !!project.archived_at;
|
||||
|
||||
|
|
@ -119,21 +120,21 @@ export const ProjectCard: React.FC<Props> = observer((props) => {
|
|||
action: () => router.push(`/${workspaceSlug}/projects/${project.id}/settings`, {}, { showProgressBar: false }),
|
||||
title: "Settings",
|
||||
icon: Settings,
|
||||
shouldRender: !isArchived && (isOwner || isMember),
|
||||
shouldRender: !isArchived && (hasAdminRole || hasMemberRole),
|
||||
},
|
||||
{
|
||||
key: "join",
|
||||
action: () => setJoinProjectModal(true),
|
||||
title: "Join",
|
||||
icon: UserPlus,
|
||||
shouldRender: !project.is_member && !isArchived,
|
||||
shouldRender: !isMemberOfProject && !isArchived,
|
||||
},
|
||||
{
|
||||
key: "open-new-tab",
|
||||
action: handleOpenInNewTab,
|
||||
title: "Open in new tab",
|
||||
icon: ExternalLink,
|
||||
shouldRender: project.is_member && !isArchived,
|
||||
shouldRender: !isMemberOfProject && !isArchived,
|
||||
},
|
||||
{
|
||||
key: "copy-link",
|
||||
|
|
@ -147,14 +148,14 @@ export const ProjectCard: React.FC<Props> = observer((props) => {
|
|||
action: () => setRestoreProject(true),
|
||||
title: "Restore",
|
||||
icon: ArchiveRestoreIcon,
|
||||
shouldRender: isArchived && isOwner,
|
||||
shouldRender: isArchived && hasAdminRole,
|
||||
},
|
||||
{
|
||||
key: "delete",
|
||||
action: () => setDeleteProjectModal(true),
|
||||
title: "Delete",
|
||||
icon: Trash2,
|
||||
shouldRender: isArchived && isOwner,
|
||||
shouldRender: isArchived && hasAdminRole,
|
||||
},
|
||||
];
|
||||
|
||||
|
|
@ -189,13 +190,13 @@ export const ProjectCard: React.FC<Props> = observer((props) => {
|
|||
ref={projectCardRef}
|
||||
href={`/${workspaceSlug}/projects/${project.id}/issues`}
|
||||
onClick={(e) => {
|
||||
if (!project.is_member || isArchived) {
|
||||
if (!isMemberOfProject || isArchived) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
if (!isArchived) setJoinProjectModal(true);
|
||||
}
|
||||
}}
|
||||
data-prevent-nprogress={!project.is_member || isArchived}
|
||||
data-prevent-nprogress={!isMemberOfProject || isArchived}
|
||||
className="flex flex-col rounded border border-custom-border-200 bg-custom-background-100"
|
||||
>
|
||||
<ContextMenu parentRef={projectCardRef} items={MENU_ITEMS} />
|
||||
|
|
@ -297,7 +298,7 @@ export const ProjectCard: React.FC<Props> = observer((props) => {
|
|||
{isArchived && <div className="text-xs text-custom-text-400 font-medium">Archived</div>}
|
||||
</div>
|
||||
{isArchived ? (
|
||||
isOwner && (
|
||||
hasAdminRole && (
|
||||
<div className="flex items-center justify-center gap-2">
|
||||
<div
|
||||
className="flex items-center justify-center text-xs text-custom-text-400 font-medium hover:text-custom-text-200"
|
||||
|
|
@ -326,8 +327,8 @@ export const ProjectCard: React.FC<Props> = observer((props) => {
|
|||
)
|
||||
) : (
|
||||
<>
|
||||
{project.is_member &&
|
||||
(isOwner || isMember ? (
|
||||
{isMemberOfProject &&
|
||||
(hasAdminRole || hasMemberRole ? (
|
||||
<Link
|
||||
className="flex items-center justify-center rounded p-1 text-custom-text-400 hover:bg-custom-background-80 hover:text-custom-text-200"
|
||||
onClick={(e) => {
|
||||
|
|
@ -343,7 +344,7 @@ export const ProjectCard: React.FC<Props> = observer((props) => {
|
|||
Joined
|
||||
</span>
|
||||
))}
|
||||
{!project.is_member && (
|
||||
{!isMemberOfProject && (
|
||||
<div className="flex items-center">
|
||||
<Button
|
||||
variant="link-primary"
|
||||
|
|
|
|||
|
|
@ -215,7 +215,7 @@ export class ProjectStore implements IProjectStore {
|
|||
projects = sortBy(projects, "sort_order");
|
||||
|
||||
const projectIds = projects
|
||||
.filter((project) => project.workspace === currentWorkspace.id && project.is_member && !project.archived_at)
|
||||
.filter((project) => project.workspace === currentWorkspace.id && !!project.member_role && !project.archived_at)
|
||||
.map((project) => project.id);
|
||||
return projectIds;
|
||||
}
|
||||
|
|
@ -233,7 +233,7 @@ export class ProjectStore implements IProjectStore {
|
|||
const projectIds = projects
|
||||
.filter(
|
||||
(project) =>
|
||||
project.workspace === currentWorkspace.id && project.is_member && project.is_favorite && !project.archived_at
|
||||
project.workspace === currentWorkspace.id && !!project.member_role && project.is_favorite && !project.archived_at
|
||||
)
|
||||
.map((project) => project.id);
|
||||
return projectIds;
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ export const shouldFilterProject = (
|
|||
});
|
||||
}
|
||||
});
|
||||
if (displayFilters.my_projects && !project.is_member) fallsInFilters = false;
|
||||
if (displayFilters.my_projects && !project.member_role) fallsInFilters = false;
|
||||
if (displayFilters.archived_projects && !project.archived_at) fallsInFilters = false;
|
||||
if (project.archived_at) fallsInFilters = displayFilters.archived_projects ? fallsInFilters : false;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue