mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
fix: join project screen flicker (#541)
This commit is contained in:
parent
21dd2e703b
commit
e13b679c28
@ -121,17 +121,17 @@ export const CreateProjectModal: React.FC<Props> = (props) => {
|
||||
false
|
||||
);
|
||||
setToastAlert({
|
||||
title: "Success",
|
||||
type: "success",
|
||||
message: "Project created successfully",
|
||||
title: "Success!",
|
||||
message: "Project created successfully.",
|
||||
});
|
||||
handleClose();
|
||||
})
|
||||
.catch((err) => {
|
||||
if (err.status === 403) {
|
||||
setToastAlert({
|
||||
title: "Error",
|
||||
type: "error",
|
||||
title: "Error!",
|
||||
message: "You don't have permission to create project.",
|
||||
});
|
||||
handleClose();
|
||||
|
@ -7,8 +7,6 @@ import useSWR from "swr";
|
||||
|
||||
// services
|
||||
import projectService from "services/project.service";
|
||||
// hooks
|
||||
import useUser from "hooks/use-user";
|
||||
// ui
|
||||
import { PrimaryButton, Spinner } from "components/ui";
|
||||
// icon
|
||||
@ -66,8 +64,6 @@ const AppLayout: FC<AppLayoutProps> = ({
|
||||
const router = useRouter();
|
||||
const { workspaceSlug, projectId } = router.query;
|
||||
|
||||
const { user } = useUser();
|
||||
|
||||
const { data: projectMembers, mutate: projectMembersMutate } = useSWR(
|
||||
workspaceSlug && projectId ? PROJECT_MEMBERS(projectId as string) : null,
|
||||
workspaceSlug && projectId
|
||||
@ -78,7 +74,12 @@ const AppLayout: FC<AppLayoutProps> = ({
|
||||
}
|
||||
);
|
||||
// flags
|
||||
const isMember = projectMembers?.find((member) => member.member.id === user?.id) || !projectId;
|
||||
const isMember =
|
||||
!projectId ||
|
||||
memberType?.isOwner ||
|
||||
memberType?.isMember ||
|
||||
memberType?.isViewer ||
|
||||
memberType?.isGuest;
|
||||
|
||||
const handleJoin = () => {
|
||||
setIsJoiningProject(true);
|
||||
|
@ -111,6 +111,7 @@ const SingleCycle: React.FC<UserAuth> = (props) => {
|
||||
handleOnSubmit={handleAddIssuesToCycle}
|
||||
/>
|
||||
<AppLayout
|
||||
memberType={props}
|
||||
breadcrumbs={
|
||||
<Breadcrumbs>
|
||||
<BreadcrumbItem
|
||||
@ -159,9 +160,19 @@ const SingleCycle: React.FC<UserAuth> = (props) => {
|
||||
}
|
||||
>
|
||||
<div className={`h-full ${cycleSidebar ? "mr-[24rem]" : ""} duration-300`}>
|
||||
<IssuesView type="cycle" userAuth={props} openIssuesListModal={openIssuesListModal} isCompleted={cycleStatus === "completed" ?? false} />
|
||||
<IssuesView
|
||||
type="cycle"
|
||||
userAuth={props}
|
||||
openIssuesListModal={openIssuesListModal}
|
||||
isCompleted={cycleStatus === "completed" ?? false}
|
||||
/>
|
||||
</div>
|
||||
<CycleDetailsSidebar cycleStatus={cycleStatus} cycle={cycleDetails} isOpen={cycleSidebar} isCompleted={cycleStatus === "completed" ?? false} />
|
||||
<CycleDetailsSidebar
|
||||
cycleStatus={cycleStatus}
|
||||
cycle={cycleDetails}
|
||||
isOpen={cycleSidebar}
|
||||
isCompleted={cycleStatus === "completed" ?? false}
|
||||
/>
|
||||
</AppLayout>
|
||||
</IssueViewContextProvider>
|
||||
);
|
||||
|
@ -8,7 +8,7 @@ import useSWR from "swr";
|
||||
import { PlusIcon } from "@heroicons/react/24/outline";
|
||||
import { Tab } from "@headlessui/react";
|
||||
// lib
|
||||
import { requiredAuth } from "lib/auth";
|
||||
import { requiredAdmin, requiredAuth } from "lib/auth";
|
||||
|
||||
// services
|
||||
import cycleService from "services/cycles.service";
|
||||
@ -23,7 +23,7 @@ import { HeaderButton, Loader } from "components/ui";
|
||||
import { BreadcrumbItem, Breadcrumbs } from "components/breadcrumbs";
|
||||
// icons
|
||||
// types
|
||||
import { SelectCycleType } from "types";
|
||||
import { SelectCycleType, UserAuth } from "types";
|
||||
import type { NextPage, GetServerSidePropsContext } from "next";
|
||||
// fetching keys
|
||||
import {
|
||||
@ -44,7 +44,7 @@ const CompletedCyclesList = dynamic<CompletedCyclesListProps>(
|
||||
}
|
||||
);
|
||||
|
||||
const ProjectCycles: NextPage = () => {
|
||||
const ProjectCycles: NextPage<UserAuth> = (props) => {
|
||||
const [selectedCycle, setSelectedCycle] = useState<SelectCycleType>();
|
||||
const [createUpdateCycleModal, setCreateUpdateCycleModal] = useState(false);
|
||||
|
||||
@ -86,6 +86,7 @@ const ProjectCycles: NextPage = () => {
|
||||
meta={{
|
||||
title: "Plane - Cycles",
|
||||
}}
|
||||
memberType={props}
|
||||
breadcrumbs={
|
||||
<Breadcrumbs>
|
||||
<BreadcrumbItem title="Projects" link={`/${workspaceSlug}/projects`} />
|
||||
@ -210,9 +211,17 @@ export const getServerSideProps = async (ctx: GetServerSidePropsContext) => {
|
||||
};
|
||||
}
|
||||
|
||||
const projectId = ctx.query.projectId as string;
|
||||
const workspaceSlug = ctx.query.workspaceSlug as string;
|
||||
|
||||
const memberDetail = await requiredAdmin(workspaceSlug, projectId, ctx.req?.headers.cookie);
|
||||
|
||||
return {
|
||||
props: {
|
||||
user,
|
||||
isOwner: memberDetail?.role === 20,
|
||||
isMember: memberDetail?.role === 15,
|
||||
isViewer: memberDetail?.role === 10,
|
||||
isGuest: memberDetail?.role === 5,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
@ -121,6 +121,7 @@ const IssueDetailsPage: NextPage<UserAuth> = (props) => {
|
||||
|
||||
return (
|
||||
<AppLayout
|
||||
memberType={props}
|
||||
noPadding={true}
|
||||
bg="secondary"
|
||||
breadcrumbs={
|
||||
|
@ -37,6 +37,7 @@ const ProjectIssues: NextPage<UserAuth> = (props) => {
|
||||
return (
|
||||
<IssueViewContextProvider>
|
||||
<AppLayout
|
||||
memberType={props}
|
||||
breadcrumbs={
|
||||
<Breadcrumbs>
|
||||
<BreadcrumbItem title="Projects" link={`/${workspaceSlug}/projects`} />
|
||||
|
@ -112,6 +112,7 @@ const SingleModule: React.FC<UserAuth> = (props) => {
|
||||
handleOnSubmit={handleAddIssuesToModule}
|
||||
/>
|
||||
<AppLayout
|
||||
memberType={props}
|
||||
breadcrumbs={
|
||||
<Breadcrumbs>
|
||||
<BreadcrumbItem
|
||||
|
@ -9,7 +9,7 @@ import emptyModule from "public/empty-state/empty-module.svg";
|
||||
// layouts
|
||||
import AppLayout from "layouts/app-layout";
|
||||
// lib
|
||||
import { requiredAuth } from "lib/auth";
|
||||
import { requiredAdmin, requiredAuth } from "lib/auth";
|
||||
// services
|
||||
import projectService from "services/project.service";
|
||||
import modulesService from "services/modules.service";
|
||||
@ -21,11 +21,12 @@ import { BreadcrumbItem, Breadcrumbs } from "components/breadcrumbs";
|
||||
// icons
|
||||
// types
|
||||
import { IModule, SelectModuleType } from "types/modules";
|
||||
// fetch-keys
|
||||
import { UserAuth } from "types";
|
||||
import type { NextPage, GetServerSidePropsContext } from "next";
|
||||
// fetch-keys
|
||||
import { MODULE_LIST, PROJECT_DETAILS } from "constants/fetch-keys";
|
||||
|
||||
const ProjectModules: NextPage = () => {
|
||||
const ProjectModules: NextPage<UserAuth> = (props) => {
|
||||
const router = useRouter();
|
||||
const { workspaceSlug, projectId } = router.query;
|
||||
const [selectedModule, setSelectedModule] = useState<SelectModuleType>();
|
||||
@ -63,6 +64,7 @@ const ProjectModules: NextPage = () => {
|
||||
meta={{
|
||||
title: "Plane - Modules",
|
||||
}}
|
||||
memberType={props}
|
||||
breadcrumbs={
|
||||
<Breadcrumbs>
|
||||
<BreadcrumbItem title="Projects" link={`/${workspaceSlug}/projects`} />
|
||||
@ -140,9 +142,17 @@ export const getServerSideProps = async (ctx: GetServerSidePropsContext) => {
|
||||
};
|
||||
}
|
||||
|
||||
const projectId = ctx.query.projectId as string;
|
||||
const workspaceSlug = ctx.query.workspaceSlug as string;
|
||||
|
||||
const memberDetail = await requiredAdmin(workspaceSlug, projectId, ctx.req?.headers.cookie);
|
||||
|
||||
return {
|
||||
props: {
|
||||
user,
|
||||
isOwner: memberDetail?.role === 20,
|
||||
isMember: memberDetail?.role === 15,
|
||||
isViewer: memberDetail?.role === 10,
|
||||
isGuest: memberDetail?.role === 5,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
@ -11,7 +11,7 @@ import { Popover, Transition } from "@headlessui/react";
|
||||
// react-color
|
||||
import { TwitterPicker } from "react-color";
|
||||
// lib
|
||||
import { requiredAuth } from "lib/auth";
|
||||
import { requiredAdmin, requiredAuth } from "lib/auth";
|
||||
// services
|
||||
import projectService from "services/project.service";
|
||||
import pagesService from "services/pages.service";
|
||||
@ -33,7 +33,7 @@ import { renderShortTime } from "helpers/date-time.helper";
|
||||
import { copyTextToClipboard } from "helpers/string.helper";
|
||||
// types
|
||||
import type { NextPage, GetServerSidePropsContext } from "next";
|
||||
import { IIssueLabels, IPage, IPageBlock } from "types";
|
||||
import { IIssueLabels, IPage, IPageBlock, UserAuth } from "types";
|
||||
// fetch-keys
|
||||
import {
|
||||
PAGE_BLOCKS_LIST,
|
||||
@ -42,7 +42,7 @@ import {
|
||||
PROJECT_ISSUE_LABELS,
|
||||
} from "constants/fetch-keys";
|
||||
|
||||
const SinglePage: NextPage = () => {
|
||||
const SinglePage: NextPage<UserAuth> = (props) => {
|
||||
const router = useRouter();
|
||||
const { workspaceSlug, projectId, pageId } = router.query;
|
||||
|
||||
@ -233,6 +233,7 @@ const SinglePage: NextPage = () => {
|
||||
meta={{
|
||||
title: "Plane - Pages",
|
||||
}}
|
||||
memberType={props}
|
||||
breadcrumbs={
|
||||
<Breadcrumbs>
|
||||
<BreadcrumbItem title="Projects" link={`/${workspaceSlug}/projects`} />
|
||||
@ -454,9 +455,17 @@ export const getServerSideProps = async (ctx: GetServerSidePropsContext) => {
|
||||
};
|
||||
}
|
||||
|
||||
const projectId = ctx.query.projectId as string;
|
||||
const workspaceSlug = ctx.query.workspaceSlug as string;
|
||||
|
||||
const memberDetail = await requiredAdmin(workspaceSlug, projectId, ctx.req?.headers.cookie);
|
||||
|
||||
return {
|
||||
props: {
|
||||
user,
|
||||
isOwner: memberDetail?.role === 20,
|
||||
isMember: memberDetail?.role === 15,
|
||||
isViewer: memberDetail?.role === 10,
|
||||
isGuest: memberDetail?.role === 5,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
@ -9,7 +9,7 @@ import useSWR from "swr";
|
||||
// react-hook-form
|
||||
import { useForm } from "react-hook-form";
|
||||
// lib
|
||||
import { requiredAuth } from "lib/auth";
|
||||
import { requiredAdmin, requiredAuth } from "lib/auth";
|
||||
// headless ui
|
||||
import { Tab } from "@headlessui/react";
|
||||
// services
|
||||
@ -29,7 +29,7 @@ import { BreadcrumbItem, Breadcrumbs } from "components/breadcrumbs";
|
||||
// icons
|
||||
import { ListBulletIcon, RectangleGroupIcon } from "@heroicons/react/20/solid";
|
||||
// types
|
||||
import { IPage, TPageViewProps } from "types";
|
||||
import { IPage, TPageViewProps, UserAuth } from "types";
|
||||
// fetch-keys
|
||||
import { PROJECT_DETAILS, RECENT_PAGES_LIST } from "constants/fetch-keys";
|
||||
|
||||
@ -61,7 +61,7 @@ const OtherPagesList = dynamic<{ viewType: TPageViewProps }>(
|
||||
}
|
||||
);
|
||||
|
||||
const ProjectPages: NextPage = () => {
|
||||
const ProjectPages: NextPage<UserAuth> = (props) => {
|
||||
const [createUpdatePageModal, setCreateUpdatePageModal] = useState(false);
|
||||
|
||||
const [viewType, setViewType] = useState<TPageViewProps>("list");
|
||||
@ -138,6 +138,7 @@ const ProjectPages: NextPage = () => {
|
||||
meta={{
|
||||
title: "Plane - Pages",
|
||||
}}
|
||||
memberType={props}
|
||||
breadcrumbs={
|
||||
<Breadcrumbs>
|
||||
<BreadcrumbItem title="Projects" link={`/${workspaceSlug}/projects`} />
|
||||
@ -260,9 +261,17 @@ export const getServerSideProps = async (ctx: GetServerSidePropsContext) => {
|
||||
};
|
||||
}
|
||||
|
||||
const projectId = ctx.query.projectId as string;
|
||||
const workspaceSlug = ctx.query.workspaceSlug as string;
|
||||
|
||||
const memberDetail = await requiredAdmin(workspaceSlug, projectId, ctx.req?.headers.cookie);
|
||||
|
||||
return {
|
||||
props: {
|
||||
user,
|
||||
isOwner: memberDetail?.role === 20,
|
||||
isMember: memberDetail?.role === 15,
|
||||
isViewer: memberDetail?.role === 10,
|
||||
isGuest: memberDetail?.role === 5,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
@ -57,6 +57,7 @@ const SingleView: React.FC<UserAuth> = (props) => {
|
||||
return (
|
||||
<IssueViewContextProvider>
|
||||
<AppLayout
|
||||
memberType={props}
|
||||
breadcrumbs={
|
||||
<Breadcrumbs>
|
||||
<BreadcrumbItem
|
||||
|
@ -6,7 +6,7 @@ import { useRouter } from "next/router";
|
||||
import useSWR from "swr";
|
||||
|
||||
// lib
|
||||
import { requiredAuth } from "lib/auth";
|
||||
import { requiredAdmin, requiredAuth } from "lib/auth";
|
||||
|
||||
// services
|
||||
import viewsService from "services/views.service";
|
||||
@ -26,11 +26,11 @@ import { PROJECT_DETAILS, VIEWS_LIST } from "constants/fetch-keys";
|
||||
import { CustomMenu, PrimaryButton, Loader, EmptyState } from "components/ui";
|
||||
import { DeleteViewModal, CreateUpdateViewModal } from "components/views";
|
||||
// types
|
||||
import { IView } from "types";
|
||||
import { IView, UserAuth } from "types";
|
||||
import type { NextPage, GetServerSidePropsContext } from "next";
|
||||
import { StackedLayersIcon } from "components/icons";
|
||||
|
||||
const ProjectViews: NextPage = () => {
|
||||
const ProjectViews: NextPage<UserAuth> = (props) => {
|
||||
const [isCreateViewModalOpen, setIsCreateViewModalOpen] = useState(false);
|
||||
const [selectedView, setSelectedView] = useState<IView | null>(null);
|
||||
|
||||
@ -57,6 +57,7 @@ const ProjectViews: NextPage = () => {
|
||||
meta={{
|
||||
title: "Plane - Views",
|
||||
}}
|
||||
memberType={props}
|
||||
breadcrumbs={
|
||||
<Breadcrumbs>
|
||||
<BreadcrumbItem title="Projects" link={`/${workspaceSlug}/projects`} />
|
||||
@ -147,9 +148,17 @@ export const getServerSideProps = async (ctx: GetServerSidePropsContext) => {
|
||||
};
|
||||
}
|
||||
|
||||
const projectId = ctx.query.projectId as string;
|
||||
const workspaceSlug = ctx.query.workspaceSlug as string;
|
||||
|
||||
const memberDetail = await requiredAdmin(workspaceSlug, projectId, ctx.req?.headers.cookie);
|
||||
|
||||
return {
|
||||
props: {
|
||||
user,
|
||||
isOwner: memberDetail?.role === 20,
|
||||
isMember: memberDetail?.role === 15,
|
||||
isViewer: memberDetail?.role === 10,
|
||||
isGuest: memberDetail?.role === 5,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
@ -14,7 +14,7 @@ import AppLayout from "layouts/app-layout";
|
||||
import { JoinProjectModal } from "components/project/join-project-modal";
|
||||
import { DeleteProjectModal, SingleProjectCard } from "components/project";
|
||||
// ui
|
||||
import { HeaderButton, Loader, EmptyState } from "components/ui";
|
||||
import { HeaderButton, Loader, EmptyState } from "components/ui";
|
||||
import { Breadcrumbs, BreadcrumbItem } from "components/breadcrumbs";
|
||||
// icons
|
||||
import { PlusIcon } from "@heroicons/react/24/outline";
|
||||
@ -83,11 +83,11 @@ const ProjectsPage: NextPage = () => {
|
||||
<>
|
||||
{projects.length === 0 ? (
|
||||
<EmptyState
|
||||
type="project"
|
||||
title="Create New Project"
|
||||
description="Projects are a collection of issues. They can be used to represent the development work for a product, project, or service."
|
||||
imgURL={emptyProject}
|
||||
/>
|
||||
type="project"
|
||||
title="Create New Project"
|
||||
description="Projects are a collection of issues. They can be used to represent the development work for a product, project, or service."
|
||||
imgURL={emptyProject}
|
||||
/>
|
||||
) : (
|
||||
<div className="grid grid-cols-1 gap-9 md:grid-cols-2 lg:grid-cols-3">
|
||||
{projects.map((project) => (
|
||||
|
Loading…
Reference in New Issue
Block a user