[WEB-5668] fix: add fetchWorkspaceLevelProjectEntities method and update project-related fetch keys (#8347)

This commit is contained in:
Prateek Shourya 2025-12-16 13:25:44 +05:30 committed by GitHub
parent 22339b9786
commit fc1c7fe235
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 61 additions and 36 deletions

View file

@ -21,4 +21,8 @@ export class UserPermissionStore extends BaseUserPermissionStore implements IUse
(workspaceSlug: string, projectId?: string): EUserPermissions | undefined =>
this.getProjectRole(workspaceSlug, projectId)
);
fetchWorkspaceLevelProjectEntities = (workspaceSlug: string, projectId: string): void => {
void this.store.projectRoot.project.fetchProjectDetails(workspaceSlug, projectId);
};
}

View file

@ -6,7 +6,6 @@ import { Button } from "@plane/propel/button";
import type { IProject } from "@plane/types";
// ui
// hooks
import { useProject } from "@/hooks/store/use-project";
import { useUserPermissions } from "@/hooks/store/user";
import { useAppRouter } from "@/hooks/use-app-router";
@ -24,7 +23,6 @@ export function JoinProjectModal(props: TJoinProjectModalProps) {
const [isJoiningLoading, setIsJoiningLoading] = useState(false);
// store hooks
const { joinProject } = useUserPermissions();
const { fetchProjectDetails } = useProject();
// router
const router = useAppRouter();
@ -34,7 +32,6 @@ export function JoinProjectModal(props: TJoinProjectModalProps) {
joinProject(workspaceSlug, project.id)
.then(() => {
router.push(`/${workspaceSlug}/projects/${project.id}/issues`);
fetchProjectDetails(workspaceSlug, project.id);
handleClose();
})
.finally(() => {

View file

@ -1,4 +1,4 @@
import type { IJiraMetadata } from "@plane/types";
import type { EUserPermissions, IJiraMetadata } from "@plane/types";
const paramsToKey = (params: any) => {
const {
@ -70,6 +70,9 @@ export const WORKSPACE_INVITATION = (invitationId: string) => `WORKSPACE_INVITAT
export const WORKSPACE_MEMBER_ME_INFORMATION = (workspaceSlug: string) =>
`WORKSPACE_MEMBER_ME_INFORMATION_${workspaceSlug.toUpperCase()}`;
export const WORKSPACE_MEMBER_ACTIVITY = (workspaceSlug: string) =>
`WORKSPACE_MEMBER_ACTIVITY_${workspaceSlug.toUpperCase()}`;
export const WORKSPACE_PROJECTS_ROLES_INFORMATION = (workspaceSlug: string) =>
`WORKSPACE_PROJECTS_ROLES_INFORMATION_${workspaceSlug.toUpperCase()}`;
@ -154,29 +157,41 @@ export const PROJECT_DETAILS = (workspaceSlug: string, projectId: string) =>
export const PROJECT_ME_INFORMATION = (workspaceSlug: string, projectId: string) =>
`PROJECT_ME_INFORMATION_${projectId.toString().toUpperCase()}`;
export const PROJECT_LABELS = (workspaceSlug: string, projectId: string) =>
`PROJECT_LABELS_${projectId.toString().toUpperCase()}`;
export const PROJECT_LABELS = (projectId: string, projectRole: EUserPermissions | undefined) =>
`PROJECT_LABELS_${projectId.toString().toUpperCase()}_${projectRole}`;
export const PROJECT_MEMBERS = (workspaceSlug: string, projectId: string) =>
`PROJECT_MEMBERS_${projectId.toString().toUpperCase()}`;
export const PROJECT_MEMBERS = (projectId: string, projectRole: EUserPermissions | undefined) =>
`PROJECT_MEMBERS_${projectId.toString().toUpperCase()}_${projectRole}`;
export const PROJECT_STATES = (workspaceSlug: string, projectId: string) =>
`PROJECT_STATES_${projectId.toString().toUpperCase()}`;
export const PROJECT_STATES = (projectId: string, projectRole: EUserPermissions | undefined) =>
`PROJECT_STATES_${projectId.toString().toUpperCase()}_${projectRole}`;
export const PROJECT_INTAKE_STATE = (workspaceSlug: string, projectId: string) =>
`PROJECT_INTAKE_STATE_${projectId.toString().toUpperCase()}`;
export const PROJECT_INTAKE_STATE = (projectId: string, projectRole: EUserPermissions | undefined) =>
`PROJECT_INTAKE_STATE_${projectId.toString().toUpperCase()}_${projectRole}`;
export const PROJECT_ESTIMATES = (workspaceSlug: string, projectId: string) =>
`PROJECT_ESTIMATES_${projectId.toString().toUpperCase()}`;
export const PROJECT_ESTIMATES = (projectId: string, projectRole: EUserPermissions | undefined) =>
`PROJECT_ESTIMATES_${projectId.toString().toUpperCase()}_${projectRole}`;
export const PROJECT_ALL_CYCLES = (workspaceSlug: string, projectId: string) =>
`PROJECT_ALL_CYCLES_${projectId.toString().toUpperCase()}`;
export const PROJECT_ALL_CYCLES = (projectId: string, projectRole: EUserPermissions | undefined) =>
`PROJECT_ALL_CYCLES_${projectId.toString().toUpperCase()}_${projectRole}`;
export const PROJECT_MODULES = (workspaceSlug: string, projectId: string) =>
`PROJECT_MODULES_${projectId.toString().toUpperCase()}`;
export const PROJECT_MODULES = (projectId: string, projectRole: EUserPermissions | undefined) =>
`PROJECT_MODULES_${projectId.toString().toUpperCase()}_${projectRole}`;
export const PROJECT_VIEWS = (workspaceSlug: string, projectId: string) =>
`PROJECT_VIEWS_${projectId.toString().toUpperCase()}`;
export const PROJECT_VIEWS = (projectId: string, projectRole: EUserPermissions | undefined) =>
`PROJECT_VIEWS_${projectId.toString().toUpperCase()}_${projectRole}`;
export const PROJECT_MEMBER_PREFERENCES = (workspaceSlug: string, projectId: string) =>
`PROJECT_MEMBER_PREFERENCES_${projectId.toString().toUpperCase()}`;
export const PROJECT_MEMBER_PREFERENCES = (projectId: string, projectRole: EUserPermissions | undefined) =>
`PROJECT_MEMBER_PREFERENCES_${projectId.toString().toUpperCase()}_${projectRole}`;
export const PROJECT_WORKFLOWS = (projectId: string, projectRole: EUserPermissions | undefined) =>
`PROJECT_WORKFLOWS_${projectId.toString().toUpperCase()}_${projectRole}`;
export const EPICS_PROPERTIES_AND_OPTIONS = (projectId: string, projectRole: EUserPermissions | undefined) =>
`EPICS_PROPERTIES_AND_OPTIONS_${projectId.toString().toUpperCase()}_${projectRole}`;
export const WORK_ITEM_TYPES_PROPERTIES_AND_OPTIONS = (projectId: string, projectRole: EUserPermissions | undefined) =>
`WORK_ITEM_TYPES_PROPERTIES_AND_OPTIONS_${projectId.toString().toUpperCase()}_${projectRole}`;
export const PROJECT_MILESTONES = (projectId: string, projectRole: EUserPermissions | undefined) =>
`PROJECT_MILESTONES_${projectId.toString().toUpperCase()}_${projectRole}`;

View file

@ -44,7 +44,7 @@ export const ProjectAuthWrapper = observer(function ProjectAuthWrapper(props: IP
// states
const [isJoiningProject, setIsJoiningProject] = useState(false);
// store hooks
const { fetchUserProjectInfo, allowPermissions } = useUserPermissions();
const { fetchUserProjectInfo, allowPermissions, getProjectRoleByWorkspaceSlugAndProjectId } = useUserPermissions();
const { fetchProjectDetails } = useProject();
const { joinProject } = useUserPermissions();
const { fetchAllCycles } = useCycle();
@ -65,8 +65,8 @@ export const ProjectAuthWrapper = observer(function ProjectAuthWrapper(props: IP
workspaceSlug,
projectId
);
const currentProjectRole = getProjectRoleByWorkspaceSlugAndProjectId(workspaceSlug, projectId);
const isWorkspaceAdmin = allowPermissions([EUserPermissions.ADMIN], EUserPermissionsLevel.WORKSPACE, workspaceSlug);
// Initialize module timeline chart
useEffect(() => {
initGantt();
@ -82,50 +82,50 @@ export const ProjectAuthWrapper = observer(function ProjectAuthWrapper(props: IP
useSWR(PROJECT_ME_INFORMATION(workspaceSlug, projectId), () => fetchUserProjectInfo(workspaceSlug, projectId));
// fetching project member preferences
useSWR(
currentUserData?.id ? PROJECT_MEMBER_PREFERENCES(workspaceSlug, projectId) : null,
currentUserData?.id ? PROJECT_MEMBER_PREFERENCES(projectId, currentProjectRole) : null,
currentUserData?.id ? () => fetchProjectMemberPreferences(workspaceSlug, projectId, currentUserData.id) : null,
{ revalidateIfStale: false, revalidateOnFocus: false }
);
// fetching project labels
useSWR(PROJECT_LABELS(workspaceSlug, projectId), () => fetchProjectLabels(workspaceSlug, projectId), {
useSWR(PROJECT_LABELS(projectId, currentProjectRole), () => fetchProjectLabels(workspaceSlug, projectId), {
revalidateIfStale: false,
revalidateOnFocus: false,
});
// fetching project members
useSWR(PROJECT_MEMBERS(workspaceSlug, projectId), () => fetchProjectMembers(workspaceSlug, projectId), {
useSWR(PROJECT_MEMBERS(projectId, currentProjectRole), () => fetchProjectMembers(workspaceSlug, projectId), {
revalidateIfStale: false,
revalidateOnFocus: false,
});
// fetching project states
useSWR(PROJECT_STATES(workspaceSlug, projectId), () => fetchProjectStates(workspaceSlug, projectId), {
useSWR(PROJECT_STATES(projectId, currentProjectRole), () => fetchProjectStates(workspaceSlug, projectId), {
revalidateIfStale: false,
revalidateOnFocus: false,
});
// fetching project intake state
useSWR(PROJECT_INTAKE_STATE(workspaceSlug, projectId), () => fetchProjectIntakeState(workspaceSlug, projectId), {
useSWR(PROJECT_INTAKE_STATE(projectId, currentProjectRole), () => fetchProjectIntakeState(workspaceSlug, projectId), {
revalidateIfStale: false,
revalidateOnFocus: false,
});
// fetching project estimates
useSWR(PROJECT_ESTIMATES(workspaceSlug, projectId), () => getProjectEstimates(workspaceSlug, projectId), {
useSWR(PROJECT_ESTIMATES(projectId, currentProjectRole), () => getProjectEstimates(workspaceSlug, projectId), {
revalidateIfStale: false,
revalidateOnFocus: false,
});
// fetching project cycles
useSWR(PROJECT_ALL_CYCLES(workspaceSlug, projectId), () => fetchAllCycles(workspaceSlug, projectId), {
useSWR(PROJECT_ALL_CYCLES(projectId, currentProjectRole), () => fetchAllCycles(workspaceSlug, projectId), {
revalidateIfStale: false,
revalidateOnFocus: false,
});
// fetching project modules
useSWR(
PROJECT_MODULES(workspaceSlug, projectId),
PROJECT_MODULES(projectId, currentProjectRole),
async () => {
await Promise.all([fetchModulesSlim(workspaceSlug, projectId), fetchModules(workspaceSlug, projectId)]);
},
{ revalidateIfStale: false, revalidateOnFocus: false }
);
// fetching project views
useSWR(PROJECT_VIEWS(workspaceSlug, projectId), () => fetchViews(workspaceSlug, projectId), {
useSWR(PROJECT_VIEWS(projectId, currentProjectRole), () => fetchViews(workspaceSlug, projectId), {
revalidateIfStale: false,
revalidateOnFocus: false,
});
@ -133,9 +133,7 @@ export const ProjectAuthWrapper = observer(function ProjectAuthWrapper(props: IP
// handle join project
const handleJoinProject = () => {
setIsJoiningProject(true);
joinProject(workspaceSlug, projectId)
.then(() => fetchProjectDetails(workspaceSlug, projectId))
.finally(() => setIsJoiningProject(false));
joinProject(workspaceSlug, projectId).finally(() => setIsJoiningProject(false));
};
const isProjectLoading = (isParentLoading || isProjectDetailsLoading) && !projectDetailsError;

View file

@ -36,6 +36,7 @@ export interface IBaseUserPermissionStore {
workspaceSlug: string,
projectId?: string
) => EUserPermissions | undefined;
fetchWorkspaceLevelProjectEntities: (workspaceSlug: string, projectId: string) => void;
allowPermissions: (
allowPermissions: ETempUserRole[],
level: TUserPermissionsLevel,
@ -148,6 +149,15 @@ export abstract class BaseUserPermissionStore implements IBaseUserPermissionStor
projectId?: string
) => EUserPermissions | undefined;
/**
* @description Fetches project-level entities that are not automatically loaded by the project wrapper.
* This is used when joining a project to ensure all necessary workspace-level project data is available.
* @param { string } workspaceSlug
* @param { string } projectId
* @returns { Promise<void> }
*/
abstract fetchWorkspaceLevelProjectEntities: (workspaceSlug: string, projectId: string) => void;
/**
* @description Returns whether the user has the permission to access a page
* @param { string } page
@ -309,6 +319,7 @@ export abstract class BaseUserPermissionStore implements IBaseUserPermissionStor
runInAction(() => {
set(this.workspaceProjectsPermissions, [workspaceSlug, projectId], projectMemberRole);
});
void this.fetchWorkspaceLevelProjectEntities(workspaceSlug, projectId);
}
} catch (error) {
console.error("Error user joining the project", error);