forked from github/plane
fix: user state after logout (#2849)
* fix: user state after logout * chore: user state handle with mobx * chore: signout update for profile setting * fix: minor fixes --------- Co-authored-by: sriram veeraghanta <veeraghanta.sriram@gmail.com>
This commit is contained in:
parent
e89f152779
commit
51dff31926
@ -10,16 +10,12 @@ import { useMobxStore } from "lib/mobx/store-provider";
|
|||||||
import { Button } from "@plane/ui";
|
import { Button } from "@plane/ui";
|
||||||
// hooks
|
// hooks
|
||||||
import useToast from "hooks/use-toast";
|
import useToast from "hooks/use-toast";
|
||||||
// services
|
|
||||||
import { AuthService } from "services/auth.service";
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
const authService = new AuthService();
|
|
||||||
|
|
||||||
export const DeactivateAccountModal: React.FC<Props> = (props) => {
|
export const DeactivateAccountModal: React.FC<Props> = (props) => {
|
||||||
const { isOpen, onClose } = props;
|
const { isOpen, onClose } = props;
|
||||||
|
|
||||||
@ -28,7 +24,7 @@ export const DeactivateAccountModal: React.FC<Props> = (props) => {
|
|||||||
const [isDeactivating, setIsDeactivating] = useState(false);
|
const [isDeactivating, setIsDeactivating] = useState(false);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
user: { deactivateAccount },
|
user: { deactivateAccount, signOut },
|
||||||
} = useMobxStore();
|
} = useMobxStore();
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@ -46,8 +42,7 @@ export const DeactivateAccountModal: React.FC<Props> = (props) => {
|
|||||||
const handleSwitchAccount = async () => {
|
const handleSwitchAccount = async () => {
|
||||||
setSwitchingAccount(true);
|
setSwitchingAccount(true);
|
||||||
|
|
||||||
await authService
|
await signOut()
|
||||||
.signOut()
|
|
||||||
.then(() => {
|
.then(() => {
|
||||||
mutate("CURRENT_USER_DETAILS", null);
|
mutate("CURRENT_USER_DETAILS", null);
|
||||||
setTheme("system");
|
setTheme("system");
|
||||||
|
@ -12,8 +12,6 @@ import { LogIn, LogOut, Settings, UserCog2 } from "lucide-react";
|
|||||||
import { useMobxStore } from "lib/mobx/store-provider";
|
import { useMobxStore } from "lib/mobx/store-provider";
|
||||||
// hooks
|
// hooks
|
||||||
import useToast from "hooks/use-toast";
|
import useToast from "hooks/use-toast";
|
||||||
// services
|
|
||||||
import { AuthService } from "services/auth.service";
|
|
||||||
// ui
|
// ui
|
||||||
import { Avatar, Tooltip } from "@plane/ui";
|
import { Avatar, Tooltip } from "@plane/ui";
|
||||||
|
|
||||||
@ -27,15 +25,13 @@ const PROFILE_LINKS = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const authService = new AuthService();
|
|
||||||
|
|
||||||
export const InstanceSidebarDropdown = observer(() => {
|
export const InstanceSidebarDropdown = observer(() => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
// store
|
// store
|
||||||
const {
|
const {
|
||||||
theme: { sidebarCollapsed },
|
theme: { sidebarCollapsed },
|
||||||
workspace: { workspaceSlug },
|
workspace: { workspaceSlug },
|
||||||
user: { currentUser, currentUserSettings },
|
user: { signOut, currentUser, currentUserSettings },
|
||||||
} = useMobxStore();
|
} = useMobxStore();
|
||||||
// hooks
|
// hooks
|
||||||
const { setToastAlert } = useToast();
|
const { setToastAlert } = useToast();
|
||||||
@ -49,8 +45,7 @@ export const InstanceSidebarDropdown = observer(() => {
|
|||||||
"";
|
"";
|
||||||
|
|
||||||
const handleSignOut = async () => {
|
const handleSignOut = async () => {
|
||||||
await authService
|
await signOut()
|
||||||
.signOut()
|
|
||||||
.then(() => {
|
.then(() => {
|
||||||
mutate("CURRENT_USER_DETAILS", null);
|
mutate("CURRENT_USER_DETAILS", null);
|
||||||
setTheme("system");
|
setTheme("system");
|
||||||
|
@ -10,8 +10,6 @@ import { Check, ChevronDown, LogOut, Plus, Settings, UserCircle2 } from "lucide-
|
|||||||
import { useMobxStore } from "lib/mobx/store-provider";
|
import { useMobxStore } from "lib/mobx/store-provider";
|
||||||
// hooks
|
// hooks
|
||||||
import useToast from "hooks/use-toast";
|
import useToast from "hooks/use-toast";
|
||||||
// services
|
|
||||||
import { AuthService } from "services/auth.service";
|
|
||||||
// ui
|
// ui
|
||||||
import { Avatar, Loader } from "@plane/ui";
|
import { Avatar, Loader } from "@plane/ui";
|
||||||
// types
|
// types
|
||||||
@ -46,8 +44,6 @@ const profileLinks = (workspaceSlug: string, userId: string) => [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const authService = new AuthService();
|
|
||||||
|
|
||||||
export const WorkspaceSidebarDropdown = observer(() => {
|
export const WorkspaceSidebarDropdown = observer(() => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug } = router.query;
|
const { workspaceSlug } = router.query;
|
||||||
@ -55,8 +51,8 @@ export const WorkspaceSidebarDropdown = observer(() => {
|
|||||||
const {
|
const {
|
||||||
theme: { sidebarCollapsed },
|
theme: { sidebarCollapsed },
|
||||||
workspace: { workspaces, currentWorkspace: activeWorkspace },
|
workspace: { workspaces, currentWorkspace: activeWorkspace },
|
||||||
user: { currentUser, updateCurrentUser, isUserInstanceAdmin },
|
user: { currentUser, updateCurrentUser, isUserInstanceAdmin, signOut },
|
||||||
trackEvent: { setTrackElement }
|
trackEvent: { setTrackElement },
|
||||||
} = useMobxStore();
|
} = useMobxStore();
|
||||||
// hooks
|
// hooks
|
||||||
const { setToastAlert } = useToast();
|
const { setToastAlert } = useToast();
|
||||||
@ -79,8 +75,7 @@ export const WorkspaceSidebarDropdown = observer(() => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleSignOut = async () => {
|
const handleSignOut = async () => {
|
||||||
await authService
|
await signOut()
|
||||||
.signOut()
|
|
||||||
.then(() => {
|
.then(() => {
|
||||||
mutate("CURRENT_USER_DETAILS", null);
|
mutate("CURRENT_USER_DETAILS", null);
|
||||||
setTheme("system");
|
setTheme("system");
|
||||||
|
@ -5,22 +5,30 @@ import useSWR from "swr";
|
|||||||
import { Spinner } from "@plane/ui";
|
import { Spinner } from "@plane/ui";
|
||||||
// store
|
// store
|
||||||
import { useMobxStore } from "lib/mobx/store-provider";
|
import { useMobxStore } from "lib/mobx/store-provider";
|
||||||
|
import { observer } from "mobx-react-lite";
|
||||||
|
|
||||||
export interface IUserAuthWrapper {
|
export interface IUserAuthWrapper {
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const UserAuthWrapper: FC<IUserAuthWrapper> = (props) => {
|
export const UserAuthWrapper: FC<IUserAuthWrapper> = observer((props) => {
|
||||||
const { children } = props;
|
const { children } = props;
|
||||||
// store
|
// store
|
||||||
const {
|
const {
|
||||||
user: { fetchCurrentUser, fetchCurrentUserInstanceAdminStatus, fetchCurrentUserSettings },
|
user: {
|
||||||
|
currentUser,
|
||||||
|
currentUserError,
|
||||||
|
fetchCurrentUser,
|
||||||
|
fetchCurrentUserInstanceAdminStatus,
|
||||||
|
fetchCurrentUserSettings,
|
||||||
|
|
||||||
|
},
|
||||||
workspace: { fetchWorkspaces },
|
workspace: { fetchWorkspaces },
|
||||||
} = useMobxStore();
|
} = useMobxStore();
|
||||||
// router
|
// router
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
// fetching user information
|
// fetching user information
|
||||||
const { data: currentUser, error } = useSWR("CURRENT_USER_DETAILS", () => fetchCurrentUser(), {
|
useSWR("CURRENT_USER_DETAILS", () => fetchCurrentUser(), {
|
||||||
shouldRetryOnError: false,
|
shouldRetryOnError: false,
|
||||||
});
|
});
|
||||||
// fetching current user instance admin status
|
// fetching current user instance admin status
|
||||||
@ -36,7 +44,7 @@ export const UserAuthWrapper: FC<IUserAuthWrapper> = (props) => {
|
|||||||
shouldRetryOnError: false,
|
shouldRetryOnError: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!currentUser && !error) {
|
if (!currentUser && !currentUserError) {
|
||||||
return (
|
return (
|
||||||
<div className="h-screen grid place-items-center p-4 bg-custom-background-100">
|
<div className="h-screen grid place-items-center p-4 bg-custom-background-100">
|
||||||
<div className="flex flex-col items-center gap-3 text-center">
|
<div className="flex flex-col items-center gap-3 text-center">
|
||||||
@ -46,11 +54,11 @@ export const UserAuthWrapper: FC<IUserAuthWrapper> = (props) => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error) {
|
if (currentUserError) {
|
||||||
const redirectTo = router.asPath;
|
const redirectTo = router.asPath;
|
||||||
router.push(`/?next=${redirectTo}`);
|
router.push(`/?next=${redirectTo}`);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return <>{children}</>;
|
return <>{children}</>;
|
||||||
};
|
});
|
||||||
|
@ -4,8 +4,6 @@ import { Menu, Transition } from "@headlessui/react";
|
|||||||
import { LogIn, LogOut, MoveLeft, Plus, User, UserPlus } from "lucide-react";
|
import { LogIn, LogOut, MoveLeft, Plus, User, UserPlus } from "lucide-react";
|
||||||
// mobx store
|
// mobx store
|
||||||
import { useMobxStore } from "lib/mobx/store-provider";
|
import { useMobxStore } from "lib/mobx/store-provider";
|
||||||
// services
|
|
||||||
import { AuthService } from "services/auth.service";
|
|
||||||
// ui
|
// ui
|
||||||
import { Avatar, Tooltip } from "@plane/ui";
|
import { Avatar, Tooltip } from "@plane/ui";
|
||||||
import { Fragment } from "react";
|
import { Fragment } from "react";
|
||||||
@ -29,8 +27,6 @@ const SIDEBAR_LINKS = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const authService = new AuthService();
|
|
||||||
|
|
||||||
export const ProfileLayoutSidebar = observer(() => {
|
export const ProfileLayoutSidebar = observer(() => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
@ -41,7 +37,7 @@ export const ProfileLayoutSidebar = observer(() => {
|
|||||||
const {
|
const {
|
||||||
theme: { sidebarCollapsed, toggleSidebar },
|
theme: { sidebarCollapsed, toggleSidebar },
|
||||||
workspace: { workspaces },
|
workspace: { workspaces },
|
||||||
user: { currentUser, currentUserSettings, isUserInstanceAdmin },
|
user: { currentUser, currentUserSettings, isUserInstanceAdmin, signOut },
|
||||||
} = useMobxStore();
|
} = useMobxStore();
|
||||||
|
|
||||||
// redirect url for normal mode
|
// redirect url for normal mode
|
||||||
@ -51,8 +47,7 @@ export const ProfileLayoutSidebar = observer(() => {
|
|||||||
"";
|
"";
|
||||||
|
|
||||||
const handleSignOut = async () => {
|
const handleSignOut = async () => {
|
||||||
await authService
|
await signOut()
|
||||||
.signOut()
|
|
||||||
.then(() => {
|
.then(() => {
|
||||||
mutate("CURRENT_USER_DETAILS", null);
|
mutate("CURRENT_USER_DETAILS", null);
|
||||||
setTheme("system");
|
setTheme("system");
|
||||||
|
@ -4,6 +4,7 @@ import { action, observable, runInAction, makeObservable, computed } from "mobx"
|
|||||||
import { ProjectMemberService, ProjectService } from "services/project";
|
import { ProjectMemberService, ProjectService } from "services/project";
|
||||||
import { UserService } from "services/user.service";
|
import { UserService } from "services/user.service";
|
||||||
import { WorkspaceService } from "services/workspace.service";
|
import { WorkspaceService } from "services/workspace.service";
|
||||||
|
import { AuthService } from "services/auth.service";
|
||||||
// interfaces
|
// interfaces
|
||||||
import { IUser, IUserSettings } from "types/users";
|
import { IUser, IUserSettings } from "types/users";
|
||||||
import { IWorkspaceMemberMe, IProjectMember, TUserProjectRole, TUserWorkspaceRole } from "types";
|
import { IWorkspaceMemberMe, IProjectMember, TUserProjectRole, TUserWorkspaceRole } from "types";
|
||||||
@ -11,6 +12,7 @@ import { RootStore } from "./root";
|
|||||||
|
|
||||||
export interface IUserStore {
|
export interface IUserStore {
|
||||||
loader: boolean;
|
loader: boolean;
|
||||||
|
currentUserError: any;
|
||||||
|
|
||||||
isUserLoggedIn: boolean | null;
|
isUserLoggedIn: boolean | null;
|
||||||
currentUser: IUser | null;
|
currentUser: IUser | null;
|
||||||
@ -55,6 +57,7 @@ export interface IUserStore {
|
|||||||
updateCurrentUserTheme: (theme: string) => Promise<IUser>;
|
updateCurrentUserTheme: (theme: string) => Promise<IUser>;
|
||||||
|
|
||||||
deactivateAccount: () => Promise<void>;
|
deactivateAccount: () => Promise<void>;
|
||||||
|
signOut: () => Promise<void>;
|
||||||
|
|
||||||
leaveWorkspace: (workspaceSlug: string) => Promise<void>;
|
leaveWorkspace: (workspaceSlug: string) => Promise<void>;
|
||||||
|
|
||||||
@ -64,6 +67,7 @@ export interface IUserStore {
|
|||||||
|
|
||||||
class UserStore implements IUserStore {
|
class UserStore implements IUserStore {
|
||||||
loader: boolean = false;
|
loader: boolean = false;
|
||||||
|
currentUserError: any = null;
|
||||||
|
|
||||||
isUserLoggedIn: boolean | null = null;
|
isUserLoggedIn: boolean | null = null;
|
||||||
currentUser: IUser | null = null;
|
currentUser: IUser | null = null;
|
||||||
@ -92,6 +96,7 @@ class UserStore implements IUserStore {
|
|||||||
workspaceService;
|
workspaceService;
|
||||||
projectService;
|
projectService;
|
||||||
projectMemberService;
|
projectMemberService;
|
||||||
|
authService;
|
||||||
|
|
||||||
constructor(_rootStore: RootStore) {
|
constructor(_rootStore: RootStore) {
|
||||||
makeObservable(this, {
|
makeObservable(this, {
|
||||||
@ -121,6 +126,7 @@ class UserStore implements IUserStore {
|
|||||||
leaveWorkspace: action,
|
leaveWorkspace: action,
|
||||||
joinProject: action,
|
joinProject: action,
|
||||||
leaveProject: action,
|
leaveProject: action,
|
||||||
|
signOut: action,
|
||||||
// computed
|
// computed
|
||||||
currentProjectMemberInfo: computed,
|
currentProjectMemberInfo: computed,
|
||||||
currentWorkspaceMemberInfo: computed,
|
currentWorkspaceMemberInfo: computed,
|
||||||
@ -134,6 +140,7 @@ class UserStore implements IUserStore {
|
|||||||
this.workspaceService = new WorkspaceService();
|
this.workspaceService = new WorkspaceService();
|
||||||
this.projectService = new ProjectService();
|
this.projectService = new ProjectService();
|
||||||
this.projectMemberService = new ProjectMemberService();
|
this.projectMemberService = new ProjectMemberService();
|
||||||
|
this.authService = new AuthService();
|
||||||
}
|
}
|
||||||
|
|
||||||
get currentWorkspaceMemberInfo() {
|
get currentWorkspaceMemberInfo() {
|
||||||
@ -171,6 +178,7 @@ class UserStore implements IUserStore {
|
|||||||
const response = await this.userService.currentUser();
|
const response = await this.userService.currentUser();
|
||||||
if (response) {
|
if (response) {
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
|
this.currentUserError = null;
|
||||||
this.currentUser = response;
|
this.currentUser = response;
|
||||||
this.isUserLoggedIn = true;
|
this.isUserLoggedIn = true;
|
||||||
});
|
});
|
||||||
@ -178,6 +186,7 @@ class UserStore implements IUserStore {
|
|||||||
return response;
|
return response;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
|
this.currentUserError = error;
|
||||||
this.isUserLoggedIn = false;
|
this.isUserLoggedIn = false;
|
||||||
});
|
});
|
||||||
throw error;
|
throw error;
|
||||||
@ -422,6 +431,19 @@ class UserStore implements IUserStore {
|
|||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
signOut = async () => {
|
||||||
|
try {
|
||||||
|
await this.authService.signOut();
|
||||||
|
runInAction(() => {
|
||||||
|
this.currentUserError = null;
|
||||||
|
this.currentUser = null;
|
||||||
|
this.isUserLoggedIn = false;
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default UserStore;
|
export default UserStore;
|
||||||
|
Loading…
Reference in New Issue
Block a user