forked from github/plane
eb53876af3
* dev: remove default user * dev: initiate licensing * dev: remove migration file 0046 * feat: self hosted licensing initialize * dev: instance licenses * dev: change license response structure * dev: add default properties and issue mention migration * dev: reset migrations * dev: instance configuration * dev: instance configuration migration * dev: update instance configuration model to take null and empty values * dev: instance configuration variables * dev: set default values * dev: update instance configuration load * dev: email configuration settings moved to database * dev: instance configuration on instance bootup * dev: auto instance registration script * dev: instance admin * dev: enable instance configuration and instance admin roles * dev: instance owner fix * dev: instance configuration values * dev: fix instance permissions and serializer * dev: fix email senders * dev: remove deprecated variables * dev: fix current site domain registration * dev: update cors setup and local settings * dev: migrate instance registration and configuration to manage commands * dev: check email validity * dev: update script to use manage command * dev: default bucket creation script * dev: instance admin routes and initial set of screens * dev: admin api to check if the current user is admin * dev: instance admin unique constraints * dev: check magic link login * dev: fix email sending for ssl * dev: create instance activation route if the instance is not activated during startup * dev: removed DJANGO_SETTINGS_MODULE from environment files and deleted auto bucket create script * dev: environment configuration for backend * dev: fix access token variable error * feat: Instance Admin Panel: General Settings (#2792) --------- Co-authored-by: pablohashescobar <nikhilschacko@gmail.com> Co-authored-by: Prateek Shourya <prateekshourya29@gmail.com>
356 lines
9.6 KiB
TypeScript
356 lines
9.6 KiB
TypeScript
// mobx
|
|
import { action, observable, runInAction, makeObservable, computed } from "mobx";
|
|
// services
|
|
import { ProjectMemberService, ProjectService } from "services/project";
|
|
import { UserService } from "services/user.service";
|
|
import { WorkspaceService } from "services/workspace.service";
|
|
// interfaces
|
|
import { IUser, IUserSettings } from "types/users";
|
|
import { IWorkspaceMemberMe, IProjectMember, TUserProjectRole, TUserWorkspaceRole } from "types";
|
|
import { RootStore } from "./root";
|
|
|
|
export interface IUserStore {
|
|
loader: boolean;
|
|
|
|
isUserLoggedIn: boolean | null;
|
|
currentUser: IUser | null;
|
|
isUserInstanceAdmin: boolean | null;
|
|
currentUserSettings: IUserSettings | null;
|
|
|
|
dashboardInfo: any;
|
|
|
|
workspaceMemberInfo: {
|
|
[workspaceSlug: string]: IWorkspaceMemberMe;
|
|
};
|
|
hasPermissionToWorkspace: {
|
|
[workspaceSlug: string]: boolean | null;
|
|
};
|
|
|
|
projectMemberInfo: {
|
|
[projectId: string]: IProjectMember;
|
|
};
|
|
hasPermissionToProject: {
|
|
[projectId: string]: boolean | null;
|
|
};
|
|
|
|
currentProjectMemberInfo: IProjectMember | undefined;
|
|
currentWorkspaceMemberInfo: IWorkspaceMemberMe | undefined;
|
|
currentProjectRole: TUserProjectRole | undefined;
|
|
currentWorkspaceRole: TUserWorkspaceRole | undefined;
|
|
|
|
hasPermissionToCurrentWorkspace: boolean | undefined;
|
|
hasPermissionToCurrentProject: boolean | undefined;
|
|
|
|
fetchCurrentUser: () => Promise<IUser>;
|
|
fetchCurrentUserInstanceAdminStatus: () => Promise<boolean>;
|
|
fetchCurrentUserSettings: () => Promise<IUserSettings>;
|
|
|
|
fetchUserWorkspaceInfo: (workspaceSlug: string) => Promise<IWorkspaceMemberMe>;
|
|
fetchUserProjectInfo: (workspaceSlug: string, projectId: string) => Promise<IProjectMember>;
|
|
fetchUserDashboardInfo: (workspaceSlug: string, month: number) => Promise<any>;
|
|
|
|
updateUserOnBoard: () => Promise<void>;
|
|
updateTourCompleted: () => Promise<void>;
|
|
updateCurrentUser: (data: Partial<IUser>) => Promise<IUser>;
|
|
updateCurrentUserTheme: (theme: string) => Promise<IUser>;
|
|
}
|
|
|
|
class UserStore implements IUserStore {
|
|
loader: boolean = false;
|
|
|
|
isUserLoggedIn: boolean | null = null;
|
|
currentUser: IUser | null = null;
|
|
isUserInstanceAdmin: boolean | null = null;
|
|
currentUserSettings: IUserSettings | null = null;
|
|
|
|
dashboardInfo: any = null;
|
|
|
|
workspaceMemberInfo: {
|
|
[workspaceSlug: string]: IWorkspaceMemberMe;
|
|
} = {};
|
|
hasPermissionToWorkspace: {
|
|
[workspaceSlug: string]: boolean;
|
|
} = {};
|
|
|
|
projectMemberInfo: {
|
|
[projectId: string]: IProjectMember;
|
|
} = {};
|
|
hasPermissionToProject: {
|
|
[projectId: string]: boolean;
|
|
} = {};
|
|
// root store
|
|
rootStore;
|
|
// services
|
|
userService;
|
|
workspaceService;
|
|
projectService;
|
|
projectMemberService;
|
|
|
|
constructor(_rootStore: RootStore) {
|
|
makeObservable(this, {
|
|
// observable
|
|
loader: observable.ref,
|
|
isUserLoggedIn: observable.ref,
|
|
currentUser: observable.ref,
|
|
isUserInstanceAdmin: observable.ref,
|
|
currentUserSettings: observable.ref,
|
|
dashboardInfo: observable.ref,
|
|
workspaceMemberInfo: observable.ref,
|
|
hasPermissionToWorkspace: observable.ref,
|
|
projectMemberInfo: observable.ref,
|
|
hasPermissionToProject: observable.ref,
|
|
// action
|
|
fetchCurrentUser: action,
|
|
fetchCurrentUserInstanceAdminStatus: action,
|
|
fetchCurrentUserSettings: action,
|
|
fetchUserDashboardInfo: action,
|
|
fetchUserWorkspaceInfo: action,
|
|
fetchUserProjectInfo: action,
|
|
updateUserOnBoard: action,
|
|
updateTourCompleted: action,
|
|
updateCurrentUser: action,
|
|
updateCurrentUserTheme: action,
|
|
// computed
|
|
currentProjectMemberInfo: computed,
|
|
currentWorkspaceMemberInfo: computed,
|
|
currentProjectRole: computed,
|
|
currentWorkspaceRole: computed,
|
|
hasPermissionToCurrentWorkspace: computed,
|
|
hasPermissionToCurrentProject: computed,
|
|
});
|
|
this.rootStore = _rootStore;
|
|
this.userService = new UserService();
|
|
this.workspaceService = new WorkspaceService();
|
|
this.projectService = new ProjectService();
|
|
this.projectMemberService = new ProjectMemberService();
|
|
}
|
|
|
|
get currentWorkspaceMemberInfo() {
|
|
if (!this.rootStore.workspace.workspaceSlug) return;
|
|
return this.workspaceMemberInfo[this.rootStore.workspace.workspaceSlug];
|
|
}
|
|
|
|
get currentWorkspaceRole() {
|
|
if (!this.rootStore.workspace.workspaceSlug) return;
|
|
return this.workspaceMemberInfo[this.rootStore.workspace.workspaceSlug]?.role;
|
|
}
|
|
|
|
get currentProjectMemberInfo() {
|
|
if (!this.rootStore.project.projectId) return;
|
|
return this.projectMemberInfo[this.rootStore.project.projectId];
|
|
}
|
|
|
|
get currentProjectRole() {
|
|
if (!this.rootStore.project.projectId) return;
|
|
return this.projectMemberInfo[this.rootStore.project.projectId]?.role;
|
|
}
|
|
|
|
get hasPermissionToCurrentWorkspace() {
|
|
if (!this.rootStore.workspace.workspaceSlug) return;
|
|
return this.hasPermissionToWorkspace[this.rootStore.workspace.workspaceSlug];
|
|
}
|
|
|
|
get hasPermissionToCurrentProject() {
|
|
if (!this.rootStore.project.projectId) return;
|
|
return this.hasPermissionToProject[this.rootStore.project.projectId];
|
|
}
|
|
|
|
fetchCurrentUser = async () => {
|
|
try {
|
|
const response = await this.userService.currentUser();
|
|
if (response) {
|
|
runInAction(() => {
|
|
this.currentUser = response;
|
|
this.isUserLoggedIn = true;
|
|
});
|
|
}
|
|
return response;
|
|
} catch (error) {
|
|
runInAction(() => {
|
|
this.isUserLoggedIn = false;
|
|
});
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
fetchCurrentUserInstanceAdminStatus = async () => {
|
|
try {
|
|
const response = await this.userService.currentUserInstanceAdminStatus();
|
|
if (response) {
|
|
runInAction(() => {
|
|
this.isUserInstanceAdmin = response.is_instance_admin;
|
|
})
|
|
}
|
|
return response.is_instance_admin;
|
|
} catch (error) {
|
|
runInAction(() => {
|
|
this.isUserInstanceAdmin = false;
|
|
});
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
fetchCurrentUserSettings = async () => {
|
|
try {
|
|
const response = await this.userService.currentUserSettings();
|
|
if (response) {
|
|
runInAction(() => {
|
|
this.currentUserSettings = response;
|
|
});
|
|
}
|
|
return response;
|
|
} catch (error) {
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
fetchUserDashboardInfo = async (workspaceSlug: string, month: number) => {
|
|
try {
|
|
const response = await this.userService.userWorkspaceDashboard(workspaceSlug, month);
|
|
runInAction(() => {
|
|
this.dashboardInfo = response;
|
|
});
|
|
return response;
|
|
} catch (error) {
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
fetchUserWorkspaceInfo = async (workspaceSlug: string) => {
|
|
try {
|
|
const response = await this.workspaceService.workspaceMemberMe(workspaceSlug);
|
|
|
|
runInAction(() => {
|
|
this.workspaceMemberInfo = {
|
|
...this.workspaceMemberInfo,
|
|
[workspaceSlug]: response,
|
|
};
|
|
this.hasPermissionToWorkspace = {
|
|
...this.hasPermissionToWorkspace,
|
|
[workspaceSlug]: true,
|
|
};
|
|
});
|
|
return response;
|
|
} catch (error) {
|
|
runInAction(() => {
|
|
this.hasPermissionToWorkspace = {
|
|
...this.hasPermissionToWorkspace,
|
|
[workspaceSlug]: false,
|
|
};
|
|
});
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
fetchUserProjectInfo = async (workspaceSlug: string, projectId: string) => {
|
|
try {
|
|
const response = await this.projectMemberService.projectMemberMe(workspaceSlug, projectId);
|
|
|
|
runInAction(() => {
|
|
this.projectMemberInfo = {
|
|
...this.projectMemberInfo,
|
|
[projectId]: response,
|
|
};
|
|
this.hasPermissionToProject = {
|
|
...this.hasPermissionToProject,
|
|
[projectId]: true,
|
|
};
|
|
});
|
|
return response;
|
|
} catch (error: any) {
|
|
runInAction(() => {
|
|
this.hasPermissionToProject = {
|
|
...this.hasPermissionToProject,
|
|
[projectId]: false,
|
|
};
|
|
});
|
|
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
updateUserOnBoard = async () => {
|
|
try {
|
|
runInAction(() => {
|
|
this.currentUser = {
|
|
...this.currentUser,
|
|
is_onboarded: true,
|
|
} as IUser;
|
|
});
|
|
|
|
const user = this.currentUser ?? undefined;
|
|
|
|
if (!user) return;
|
|
|
|
await this.userService.updateUserOnBoard({ userRole: user.role }, user);
|
|
} catch (error) {
|
|
this.fetchCurrentUser();
|
|
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
updateTourCompleted = async () => {
|
|
try {
|
|
if (this.currentUser) {
|
|
runInAction(() => {
|
|
this.currentUser = {
|
|
...this.currentUser,
|
|
is_tour_completed: true,
|
|
} as IUser;
|
|
});
|
|
|
|
const response = await this.userService.updateUserTourCompleted(this.currentUser);
|
|
|
|
return response;
|
|
}
|
|
} catch (error) {
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
updateCurrentUser = async (data: Partial<IUser>) => {
|
|
try {
|
|
runInAction(() => {
|
|
this.currentUser = {
|
|
...this.currentUser,
|
|
...data,
|
|
} as IUser;
|
|
});
|
|
|
|
const response = await this.userService.updateUser(data);
|
|
|
|
runInAction(() => {
|
|
this.currentUser = response;
|
|
});
|
|
return response;
|
|
} catch (error) {
|
|
this.fetchCurrentUser();
|
|
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
updateCurrentUserTheme = async (theme: string) => {
|
|
try {
|
|
runInAction(() => {
|
|
this.currentUser = {
|
|
...this.currentUser,
|
|
theme: {
|
|
...this.currentUser?.theme,
|
|
theme,
|
|
},
|
|
} as IUser;
|
|
});
|
|
const response = await this.userService.updateUser({
|
|
theme: { ...this.currentUser?.theme, theme },
|
|
} as IUser);
|
|
return response;
|
|
} catch (error) {
|
|
throw error;
|
|
}
|
|
};
|
|
}
|
|
|
|
export default UserStore;
|