fix: join project screen flicker (#541)

This commit is contained in:
Aaryan Khandelwal 2023-03-27 16:53:31 +05:30 committed by GitHub
parent 21dd2e703b
commit e13b679c28
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 98 additions and 36 deletions

View File

@ -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();

View File

@ -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);

View File

@ -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>
);

View File

@ -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,
},
};
};

View File

@ -121,6 +121,7 @@ const IssueDetailsPage: NextPage<UserAuth> = (props) => {
return (
<AppLayout
memberType={props}
noPadding={true}
bg="secondary"
breadcrumbs={

View File

@ -37,6 +37,7 @@ const ProjectIssues: NextPage<UserAuth> = (props) => {
return (
<IssueViewContextProvider>
<AppLayout
memberType={props}
breadcrumbs={
<Breadcrumbs>
<BreadcrumbItem title="Projects" link={`/${workspaceSlug}/projects`} />

View File

@ -112,6 +112,7 @@ const SingleModule: React.FC<UserAuth> = (props) => {
handleOnSubmit={handleAddIssuesToModule}
/>
<AppLayout
memberType={props}
breadcrumbs={
<Breadcrumbs>
<BreadcrumbItem

View File

@ -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,
},
};
};

View File

@ -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,
},
};
};

View File

@ -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,
},
};
};

View File

@ -57,6 +57,7 @@ const SingleView: React.FC<UserAuth> = (props) => {
return (
<IssueViewContextProvider>
<AppLayout
memberType={props}
breadcrumbs={
<Breadcrumbs>
<BreadcrumbItem

View File

@ -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,
},
};
};

View File

@ -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) => (