FIX - МЕЖПРОЕКТНАЯ КОММУНИКАЦИЯ: бесшовный realtime проектов Tasker
This commit is contained in:
@@ -46,6 +46,17 @@ const isProjectPath = (pathname: string | null, workspaceSlug: string, projectId
|
||||
pathname === `/${workspaceSlug}/projects/${projectId}` ||
|
||||
!!pathname?.startsWith(`/${workspaceSlug}/projects/${projectId}/`);
|
||||
|
||||
const getProjectIdFromPath = (pathname: string | null, workspaceSlug: string) => {
|
||||
if (!pathname) return undefined;
|
||||
const match = pathname.match(new RegExp(`^/${workspaceSlug}/projects/([^/]+)`));
|
||||
return match?.[1];
|
||||
};
|
||||
|
||||
const getProjectWorkspaceId = (project?: { workspace?: string | { id?: string } | null }) => {
|
||||
if (!project) return undefined;
|
||||
return typeof project.workspace === "string" ? project.workspace : project.workspace?.id;
|
||||
};
|
||||
|
||||
const isCurrentUserAffected = (event: TNodeDCRealtimeEvent, currentUserId?: string) => {
|
||||
if (!currentUserId) return false;
|
||||
if (event.member_id === currentUserId) return true;
|
||||
@@ -100,24 +111,65 @@ export const useNodeDCRealtimeEvents = (enabled: boolean, currentUserId?: string
|
||||
const workspaceSlug = event.workspace_slug;
|
||||
if (!workspaceSlug) return;
|
||||
const projectIds = [...new Set(event.project_ids?.filter(Boolean) ?? [])];
|
||||
const affectsCurrentUser = isCurrentUserAffected(event, currentUserIdRef.current);
|
||||
const workspaceWasRemovedForCurrentUser = event.type === "workspace_member.deleted" && affectsCurrentUser;
|
||||
const workspaceWasUpdatedForCurrentUser = event.type === "workspace_member.updated" && affectsCurrentUser;
|
||||
const shouldRefreshWorkspaceList =
|
||||
workspaceWasRemovedForCurrentUser || (event.type === "workspace_member.created" && affectsCurrentUser);
|
||||
const shouldRefreshCurrentUserPermissions = affectsCurrentUser && event.type !== "workspace_member.deleted";
|
||||
const shouldRefreshProjectsForCurrentUser = affectsCurrentUser && event.type !== "workspace_member.deleted";
|
||||
|
||||
if (workspaceWasUpdatedForCurrentUser) {
|
||||
await Promise.allSettled([
|
||||
userStore.permission.fetchUserWorkspaceInfo(workspaceSlug, { silent: true }),
|
||||
userStore.permission.fetchUserProjectPermissions(workspaceSlug),
|
||||
projectStore.fetchProjects(workspaceSlug, { silent: true }),
|
||||
memberRoot.workspace.fetchWorkspaceMembers(workspaceSlug),
|
||||
memberRoot.workspace.fetchWorkspaceMemberInvitations(workspaceSlug),
|
||||
mutate("NODEDC_WORKSPACE_POLICY"),
|
||||
mutate(`NODEDC_WORKSPACE_POLICY_${workspaceSlug}`),
|
||||
...projectIds.map((projectId) => memberRoot.project.fetchProjectMembers(workspaceSlug, projectId, true)),
|
||||
]);
|
||||
|
||||
const routeProjectId = getProjectIdFromPath(pathnameRef.current, workspaceSlug);
|
||||
const workspaceId = workspaceRoot.getWorkspaceBySlug(workspaceSlug)?.id;
|
||||
const routeProject = routeProjectId ? projectStore.projectMap?.[routeProjectId] : undefined;
|
||||
const routeProjectBelongsToWorkspace =
|
||||
!!routeProject && !!workspaceId && getProjectWorkspaceId(routeProject) === workspaceId;
|
||||
|
||||
if (
|
||||
routeProjectId &&
|
||||
isProjectPath(pathnameRef.current, workspaceSlug, routeProjectId) &&
|
||||
!routeProjectBelongsToWorkspace
|
||||
) {
|
||||
router.replace(`/${workspaceSlug}`);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
await Promise.allSettled([
|
||||
workspaceRoot.fetchWorkspaces(),
|
||||
userStore.permission.fetchUserWorkspaceInfo(workspaceSlug),
|
||||
shouldRefreshWorkspaceList ? workspaceRoot.fetchWorkspaces() : Promise.resolve(),
|
||||
shouldRefreshCurrentUserPermissions
|
||||
? userStore.permission.fetchUserWorkspaceInfo(workspaceSlug, { silent: true })
|
||||
: Promise.resolve(),
|
||||
memberRoot.workspace.fetchWorkspaceMembers(workspaceSlug),
|
||||
memberRoot.workspace.fetchWorkspaceMemberInvitations(workspaceSlug),
|
||||
projectStore.fetchProjects(workspaceSlug),
|
||||
userStore.permission.fetchUserProjectPermissions(workspaceSlug),
|
||||
mutate("NODEDC_WORKSPACE_POLICY"),
|
||||
mutate(`NODEDC_WORKSPACE_POLICY_${workspaceSlug}`),
|
||||
shouldRefreshProjectsForCurrentUser
|
||||
? projectStore.fetchProjects(workspaceSlug, { silent: true })
|
||||
: Promise.resolve(),
|
||||
shouldRefreshCurrentUserPermissions
|
||||
? userStore.permission.fetchUserProjectPermissions(workspaceSlug)
|
||||
: Promise.resolve(),
|
||||
shouldRefreshCurrentUserPermissions || workspaceWasRemovedForCurrentUser
|
||||
? mutate("NODEDC_WORKSPACE_POLICY")
|
||||
: Promise.resolve(),
|
||||
shouldRefreshCurrentUserPermissions || workspaceWasRemovedForCurrentUser
|
||||
? mutate(`NODEDC_WORKSPACE_POLICY_${workspaceSlug}`)
|
||||
: Promise.resolve(),
|
||||
...projectIds.map((projectId) => memberRoot.project.fetchProjectMembers(workspaceSlug, projectId, true)),
|
||||
]);
|
||||
|
||||
if (
|
||||
event.type === "workspace_member.deleted" &&
|
||||
isCurrentUserAffected(event, currentUserIdRef.current) &&
|
||||
isWorkspacePath(pathnameRef.current, workspaceSlug)
|
||||
) {
|
||||
if (workspaceWasRemovedForCurrentUser && isWorkspacePath(pathnameRef.current, workspaceSlug)) {
|
||||
router.replace(workspaceRoot.getWorkspaceRedirectionUrl());
|
||||
}
|
||||
};
|
||||
@@ -126,21 +178,34 @@ export const useNodeDCRealtimeEvents = (enabled: boolean, currentUserId?: string
|
||||
const workspaceSlug = event.workspace_slug;
|
||||
const projectId = event.project_id;
|
||||
if (!workspaceSlug) return;
|
||||
const affectsCurrentUser = isCurrentUserAffected(event, currentUserIdRef.current);
|
||||
const projectWasRemovedForCurrentUser = event.type === "project_member.deleted" && affectsCurrentUser;
|
||||
const shouldRefreshCurrentProjectDetails =
|
||||
!!projectId && affectsCurrentUser && event.type !== "project_member.deleted";
|
||||
|
||||
if (projectId && projectWasRemovedForCurrentUser) {
|
||||
projectStore.removeProjectFromStore(workspaceSlug, projectId);
|
||||
}
|
||||
|
||||
await Promise.allSettled([
|
||||
workspaceRoot.fetchWorkspaces(),
|
||||
workspaceRoot.fetchWorkspaces({ silent: true }),
|
||||
memberRoot.workspace.fetchWorkspaceMembers(workspaceSlug),
|
||||
projectStore.fetchProjects(workspaceSlug),
|
||||
shouldRefreshCurrentProjectDetails && projectId
|
||||
? projectStore.fetchProjectDetails(workspaceSlug, projectId)
|
||||
: !projectId && affectsCurrentUser
|
||||
? projectStore.fetchProjects(workspaceSlug, { silent: true })
|
||||
: Promise.resolve(),
|
||||
userStore.permission.fetchUserProjectPermissions(workspaceSlug),
|
||||
mutate("NODEDC_WORKSPACE_POLICY"),
|
||||
mutate(`NODEDC_WORKSPACE_POLICY_${workspaceSlug}`),
|
||||
projectId ? memberRoot.project.fetchProjectMembers(workspaceSlug, projectId, true) : Promise.resolve(),
|
||||
projectId && !projectWasRemovedForCurrentUser
|
||||
? memberRoot.project.fetchProjectMembers(workspaceSlug, projectId, true)
|
||||
: Promise.resolve(),
|
||||
]);
|
||||
|
||||
if (
|
||||
projectId &&
|
||||
event.type === "project_member.deleted" &&
|
||||
isCurrentUserAffected(event, currentUserIdRef.current) &&
|
||||
projectWasRemovedForCurrentUser &&
|
||||
isProjectPath(pathnameRef.current, workspaceSlug, projectId)
|
||||
) {
|
||||
router.replace(`/${workspaceSlug}`);
|
||||
|
||||
Reference in New Issue
Block a user