bb-plane-fork/apps/space/store/user.store.ts
darkingtail d9695afcdc fix: remove unused imports and variables (part 1 — packages & non-web-core) (#8751)
* fix: remove unused imports and variables (part 1)

Resolve oxlint no-unused-vars warnings in packages/*, apps/admin,
apps/space, apps/live, and apps/web (non-core).

* fix: resolve CI check failures

* fix: resolve check:types failures

* fix: resolve check:types and check:format failures

- Use destructuring alias for activeCycleResolvedPath
- Format propel tab-navigation file

* fix: format propel button helper with oxfmt

Reorder Tailwind classes to match oxfmt canonical ordering.
2026-03-25 02:04:20 +05:30

190 lines
5 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 { AxiosError } from "axios";
import { set } from "lodash-es";
import { action, computed, makeObservable, observable, runInAction } from "mobx";
// plane imports
import { UserService } from "@plane/services";
import type { ActorDetail, IUser } from "@plane/types";
// store types
import type { IProfileStore } from "@/store/profile.store";
import { ProfileStore } from "@/store/profile.store";
// store
import type { RootStore } from "@/store/root.store";
type TUserErrorStatus = {
status: string;
message: string;
};
export interface IUserStore {
// observables
isAuthenticated: boolean;
isInitializing: boolean;
error: TUserErrorStatus | undefined;
data: IUser | undefined;
// store observables
profile: IProfileStore;
// computed
currentActor: ActorDetail;
// actions
fetchCurrentUser: () => Promise<IUser | undefined>;
updateCurrentUser: (data: Partial<IUser>) => Promise<IUser | undefined>;
hydrate: (data: IUser | undefined) => void;
reset: () => void;
signOut: () => Promise<void>;
}
export class UserStore implements IUserStore {
// observables
isAuthenticated: boolean = false;
isInitializing: boolean = true;
error: TUserErrorStatus | undefined = undefined;
data: IUser | undefined = undefined;
// store observables
profile: IProfileStore;
// service
userService: UserService;
constructor(private store: RootStore) {
// stores
this.profile = new ProfileStore(store);
// service
this.userService = new UserService();
// observables
makeObservable(this, {
// observables
isAuthenticated: observable.ref,
isInitializing: observable.ref,
error: observable,
// model observables
data: observable,
profile: observable,
// computed
currentActor: computed,
// actions
fetchCurrentUser: action,
updateCurrentUser: action,
reset: action,
signOut: action,
});
}
// computed
get currentActor(): ActorDetail {
return {
id: this.data?.id,
first_name: this.data?.first_name,
last_name: this.data?.last_name,
display_name: this.data?.display_name,
avatar_url: this.data?.avatar_url || undefined,
is_bot: false,
};
}
// actions
/**
* @description fetches the current user
* @returns {Promise<IUser>}
*/
fetchCurrentUser = async (): Promise<IUser> => {
try {
runInAction(() => {
if (this.data === undefined && !this.error) this.isInitializing = true;
this.error = undefined;
});
const user = await this.userService.me();
if (user && user?.id) {
await this.profile.fetchUserProfile();
runInAction(() => {
this.data = user;
this.isInitializing = false;
this.isAuthenticated = true;
});
} else
runInAction(() => {
this.data = user;
this.isInitializing = false;
this.isAuthenticated = false;
});
return user;
} catch (error) {
runInAction(() => {
this.isInitializing = false;
this.isAuthenticated = false;
this.error = {
status: "user-fetch-error",
message: "Failed to fetch current user",
};
if (error instanceof AxiosError && error.status === 401) {
this.data = undefined;
}
});
throw error;
}
};
/**
* @description updates the current user
* @param data
* @returns {Promise<IUser>}
*/
updateCurrentUser = async (data: Partial<IUser>): Promise<IUser> => {
const currentUserData = this.data;
try {
if (currentUserData) {
Object.keys(data).forEach((key: string) => {
const userKey: keyof IUser = key as keyof IUser;
if (this.data) set(this.data, userKey, data[userKey]);
});
}
const user = await this.userService.update(data);
return user;
} catch (error) {
if (currentUserData) {
Object.keys(currentUserData).forEach((key: string) => {
const userKey: keyof IUser = key as keyof IUser;
if (this.data) set(this.data, userKey, currentUserData[userKey]);
});
}
runInAction(() => {
this.error = {
status: "user-update-error",
message: "Failed to update current user",
};
});
throw error;
}
};
hydrate = (data: IUser | undefined): void => {
if (!data) return;
this.data = { ...this.data, ...data };
};
/**
* @description resets the user store
* @returns {void}
*/
reset = (): void => {
runInAction(() => {
this.isAuthenticated = false;
this.isInitializing = false;
this.error = undefined;
this.data = undefined;
this.profile = new ProfileStore(this.store);
});
};
/**
* @description signs out the current user
* @returns {Promise<void>}
*/
signOut = async (): Promise<void> => {
this.store.reset();
};
}