Some checks failed
CodeQL / Analyze (javascript) (push) Failing after 16s
CodeQL / Analyze (python) (push) Failing after 3s
i18n sync check / check:sync (push) Failing after 3s
React Doctor / react-doctor (push) Failing after 16s
Branch Build CE / Build-Push Admin Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge Admin Manifest (push) Has been cancelled
Branch Build CE / Build-Push Web Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge Web Manifest (push) Has been cancelled
Branch Build CE / Build-Push Space Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge Proxy Manifest (push) Has been cancelled
Branch Build CE / Merge Space Manifest (push) Has been cancelled
Branch Build CE / Prepare AIO Assets (push) Has been cancelled
Branch Build CE / Build Setup (push) Has been cancelled
Branch Build CE / Build-Push Live Collaboration Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge Live Collaboration Manifest (push) Has been cancelled
Branch Build CE / Build-Push API Server Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge API Server Manifest (push) Has been cancelled
Branch Build CE / Build-Push Proxy Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Build-Push AIO Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge AIO Manifest (push) Has been cancelled
Branch Build CE / Upload Build Assets (push) Has been cancelled
Branch Build CE / Build Release (push) Has been cancelled
162 lines
6.2 KiB
TypeScript
162 lines
6.2 KiB
TypeScript
/**
|
|
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
|
* SPDX-License-Identifier: AGPL-3.0-only
|
|
* See the LICENSE file for details.
|
|
*/
|
|
|
|
import type { ReactNode } from "react";
|
|
import { useEffect, useState } from "react";
|
|
import { observer } from "mobx-react";
|
|
import useSWR from "swr";
|
|
// plane imports
|
|
import { EUserPermissions, EUserPermissionsLevel } from "@plane/constants";
|
|
import { GANTT_TIMELINE_TYPE } from "@plane/types";
|
|
// components
|
|
import { ProjectAccessRestriction } from "@/components/auth-screens/project/project-access-restriction";
|
|
import {
|
|
PROJECT_DETAILS,
|
|
PROJECT_ME_INFORMATION,
|
|
PROJECT_LABELS,
|
|
PROJECT_MEMBERS,
|
|
PROJECT_MEMBER_PREFERENCES,
|
|
PROJECT_STATES,
|
|
PROJECT_ESTIMATES,
|
|
PROJECT_ALL_CYCLES,
|
|
PROJECT_MODULES,
|
|
PROJECT_VIEWS,
|
|
PROJECT_INTAKE_STATE,
|
|
} from "@plane/constants";
|
|
// hooks
|
|
import { useProjectEstimates } from "@/hooks/store/estimates";
|
|
import { useCycle } from "@/hooks/store/use-cycle";
|
|
import { useLabel } from "@/hooks/store/use-label";
|
|
import { useMember } from "@/hooks/store/use-member";
|
|
import { useModule } from "@/hooks/store/use-module";
|
|
import { useProject } from "@/hooks/store/use-project";
|
|
import { useProjectState } from "@/hooks/store/use-project-state";
|
|
import { useProjectView } from "@/hooks/store/use-project-view";
|
|
import { useUser, useUserPermissions } from "@/hooks/store/user";
|
|
import { useTimeLineChart } from "@/hooks/use-timeline-chart";
|
|
|
|
interface IProjectAuthWrapper {
|
|
workspaceSlug: string;
|
|
projectId: string;
|
|
children: ReactNode;
|
|
isLoading?: boolean;
|
|
}
|
|
|
|
export const ProjectAuthWrapper = observer(function ProjectAuthWrapper(props: IProjectAuthWrapper) {
|
|
const { workspaceSlug, projectId, children, isLoading: isParentLoading = false } = props;
|
|
// states
|
|
const [isJoiningProject, setIsJoiningProject] = useState(false);
|
|
// store hooks
|
|
const { fetchUserProjectInfo, allowPermissions, getProjectRoleByWorkspaceSlugAndProjectId } = useUserPermissions();
|
|
const { fetchProjectDetails } = useProject();
|
|
const { joinProject } = useUserPermissions();
|
|
const { fetchAllCycles } = useCycle();
|
|
const { fetchModulesSlim, fetchModules } = useModule();
|
|
const { initGantt } = useTimeLineChart(GANTT_TIMELINE_TYPE.MODULE);
|
|
const { fetchViews } = useProjectView();
|
|
const {
|
|
project: { fetchProjectMembers, fetchProjectUserProperties },
|
|
} = useMember();
|
|
const { fetchProjectStates, fetchProjectIntakeState } = useProjectState();
|
|
const { data: currentUserData } = useUser();
|
|
const { fetchProjectLabels } = useLabel();
|
|
const { getProjectEstimates } = useProjectEstimates();
|
|
// derived values
|
|
const hasPermissionToCurrentProject = allowPermissions(
|
|
[EUserPermissions.ADMIN, EUserPermissions.MEMBER, EUserPermissions.GUEST],
|
|
EUserPermissionsLevel.PROJECT,
|
|
workspaceSlug,
|
|
projectId
|
|
);
|
|
const currentProjectRole = getProjectRoleByWorkspaceSlugAndProjectId(workspaceSlug, projectId);
|
|
const isWorkspaceAdmin = allowPermissions([EUserPermissions.ADMIN], EUserPermissionsLevel.WORKSPACE, workspaceSlug);
|
|
// Initialize module timeline chart
|
|
useEffect(() => {
|
|
initGantt();
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, []);
|
|
|
|
// fetching project details
|
|
const { isLoading: isProjectDetailsLoading, error: projectDetailsError } = useSWR(
|
|
PROJECT_DETAILS(workspaceSlug, projectId),
|
|
() => fetchProjectDetails(workspaceSlug, projectId)
|
|
);
|
|
// fetching user project member information
|
|
useSWR(PROJECT_ME_INFORMATION(workspaceSlug, projectId), () => fetchUserProjectInfo(workspaceSlug, projectId));
|
|
// fetching project member preferences
|
|
useSWR(
|
|
currentUserData?.id ? PROJECT_MEMBER_PREFERENCES(projectId, currentProjectRole) : null,
|
|
currentUserData?.id ? () => fetchProjectUserProperties(workspaceSlug, projectId) : null,
|
|
{ revalidateIfStale: false, revalidateOnFocus: false }
|
|
);
|
|
// fetching project labels
|
|
useSWR(PROJECT_LABELS(projectId, currentProjectRole), () => fetchProjectLabels(workspaceSlug, projectId), {
|
|
revalidateIfStale: false,
|
|
revalidateOnFocus: false,
|
|
});
|
|
// fetching project members
|
|
useSWR(PROJECT_MEMBERS(projectId, currentProjectRole), () => fetchProjectMembers(workspaceSlug, projectId), {
|
|
revalidateIfStale: false,
|
|
revalidateOnFocus: false,
|
|
});
|
|
// fetching project states
|
|
useSWR(PROJECT_STATES(projectId, currentProjectRole), () => fetchProjectStates(workspaceSlug, projectId), {
|
|
revalidateIfStale: false,
|
|
revalidateOnFocus: false,
|
|
});
|
|
// fetching project intake state
|
|
useSWR(PROJECT_INTAKE_STATE(projectId, currentProjectRole), () => fetchProjectIntakeState(workspaceSlug, projectId), {
|
|
revalidateIfStale: false,
|
|
revalidateOnFocus: false,
|
|
});
|
|
// fetching project estimates
|
|
useSWR(PROJECT_ESTIMATES(projectId, currentProjectRole), () => getProjectEstimates(workspaceSlug, projectId), {
|
|
revalidateIfStale: false,
|
|
revalidateOnFocus: false,
|
|
});
|
|
// fetching project cycles
|
|
useSWR(PROJECT_ALL_CYCLES(projectId, currentProjectRole), () => fetchAllCycles(workspaceSlug, projectId), {
|
|
revalidateIfStale: false,
|
|
revalidateOnFocus: false,
|
|
});
|
|
// fetching project modules
|
|
useSWR(
|
|
PROJECT_MODULES(projectId, currentProjectRole),
|
|
async () => {
|
|
await Promise.all([fetchModulesSlim(workspaceSlug, projectId), fetchModules(workspaceSlug, projectId)]);
|
|
},
|
|
{ revalidateIfStale: false, revalidateOnFocus: false }
|
|
);
|
|
// fetching project views
|
|
useSWR(PROJECT_VIEWS(projectId, currentProjectRole), () => fetchViews(workspaceSlug, projectId), {
|
|
revalidateIfStale: false,
|
|
revalidateOnFocus: false,
|
|
});
|
|
|
|
// handle join project
|
|
const handleJoinProject = () => {
|
|
setIsJoiningProject(true);
|
|
joinProject(workspaceSlug, projectId).finally(() => setIsJoiningProject(false));
|
|
};
|
|
|
|
const isProjectLoading = (isParentLoading || isProjectDetailsLoading) && !projectDetailsError;
|
|
|
|
if (isProjectLoading) return null;
|
|
|
|
if (!isProjectLoading && hasPermissionToCurrentProject === false) {
|
|
return (
|
|
<ProjectAccessRestriction
|
|
errorStatusCode={projectDetailsError?.status}
|
|
isWorkspaceAdmin={isWorkspaceAdmin}
|
|
handleJoinProject={handleJoinProject}
|
|
isJoinButtonDisabled={isJoiningProject}
|
|
/>
|
|
);
|
|
}
|
|
|
|
return <>{children}</>;
|
|
});
|