mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
chore: handled ui and preloading in init page (#4491)
This commit is contained in:
parent
7569c03cec
commit
9b92fd4a16
@ -118,7 +118,9 @@ export const NavbarControls: FC<NavbarControlsProps> = observer((props) => {
|
||||
{user?.id ? (
|
||||
<div className="flex items-center gap-2 rounded border border-custom-border-200 p-2">
|
||||
<Avatar name={user?.display_name} src={user?.avatar ?? undefined} shape="square" size="sm" />
|
||||
<h6 className="text-xs font-medium">{user.display_name}</h6>
|
||||
<h6 className="text-xs font-medium">
|
||||
{user?.display_name || `${user?.first_name} ${user?.first_name}` || user?.email || "User"}
|
||||
</h6>
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex-shrink-0">
|
||||
|
@ -36,8 +36,7 @@ export const ProjectDetailsView: FC<ProjectDetailsViewProps> = observer((props)
|
||||
// hooks
|
||||
const { fetchProjectSettings } = useProject();
|
||||
const { issueFilters } = useIssueFilter();
|
||||
const { loader, issues, error } = useIssue();
|
||||
const { fetchPublicIssues } = useIssue();
|
||||
const { loader, issues, error, fetchPublicIssues } = useIssue();
|
||||
const issueDetailStore = useIssueDetails();
|
||||
const { data: currentUser, fetchCurrentUser } = useUser();
|
||||
|
||||
@ -51,12 +50,10 @@ export const ProjectDetailsView: FC<ProjectDetailsViewProps> = observer((props)
|
||||
? () => fetchPublicIssues(workspaceSlug, projectId, { states, priority, labels })
|
||||
: null
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (!currentUser) {
|
||||
fetchCurrentUser();
|
||||
}
|
||||
}, [currentUser, fetchCurrentUser]);
|
||||
useSWR(
|
||||
workspaceSlug && projectId && !currentUser ? "WORKSPACE_PROJECT_CURRENT_USER" : null,
|
||||
workspaceSlug && projectId && !currentUser ? () => fetchCurrentUser() : null
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (peekId && workspaceSlug && projectId) {
|
||||
|
@ -1,19 +1,19 @@
|
||||
// mobx
|
||||
import { observable, action, makeObservable, runInAction } from "mobx";
|
||||
import { observable, action, makeObservable, runInAction, computed } from "mobx";
|
||||
// service
|
||||
import ProjectService from "@/services/project.service";
|
||||
// store types
|
||||
import { RootStore } from "@/store/root.store";
|
||||
// types
|
||||
import { IWorkspace, IProject, IProjectSettings } from "@/types/project";
|
||||
import { TWorkspaceDetails, TProjectDetails, TProjectSettings } from "@/types/project";
|
||||
|
||||
export interface IProjectStore {
|
||||
// observables
|
||||
loader: boolean;
|
||||
error: any | null;
|
||||
workspace: IWorkspace | null;
|
||||
project: IProject | null;
|
||||
settings: IProjectSettings | null;
|
||||
error: any | undefined;
|
||||
settings: TProjectSettings | undefined;
|
||||
workspace: TWorkspaceDetails | undefined;
|
||||
project: TProjectDetails | undefined;
|
||||
canReact: boolean;
|
||||
canComment: boolean;
|
||||
canVote: boolean;
|
||||
@ -25,13 +25,10 @@ export interface IProjectStore {
|
||||
export class ProjectStore implements IProjectStore {
|
||||
// observables
|
||||
loader: boolean = false;
|
||||
error: any | null = null;
|
||||
workspace: IWorkspace | null = null;
|
||||
project: IProject | null = null;
|
||||
settings: IProjectSettings | null = null;
|
||||
canReact: boolean = false;
|
||||
canComment: boolean = false;
|
||||
canVote: boolean = false;
|
||||
error: any | undefined = undefined;
|
||||
settings: TProjectSettings | undefined = undefined;
|
||||
workspace: TWorkspaceDetails | undefined = undefined;
|
||||
project: TProjectDetails | undefined = undefined;
|
||||
// service
|
||||
projectService;
|
||||
|
||||
@ -44,28 +41,28 @@ export class ProjectStore implements IProjectStore {
|
||||
workspace: observable,
|
||||
project: observable,
|
||||
settings: observable,
|
||||
canReact: observable.ref,
|
||||
canComment: observable.ref,
|
||||
canVote: observable.ref,
|
||||
// computed
|
||||
canReact: computed,
|
||||
canComment: computed,
|
||||
canVote: computed,
|
||||
// actions
|
||||
fetchProjectSettings: action,
|
||||
|
||||
hydrate: action,
|
||||
// computed
|
||||
});
|
||||
|
||||
// services
|
||||
this.projectService = new ProjectService();
|
||||
}
|
||||
|
||||
hydrate = (projectSettings: any) => {
|
||||
const { workspace_detail, project_details, votes, comments, reactions } = projectSettings;
|
||||
this.workspace = workspace_detail;
|
||||
this.project = project_details;
|
||||
this.canComment = comments;
|
||||
this.canVote = votes;
|
||||
this.canReact = reactions;
|
||||
};
|
||||
// computed
|
||||
get canReact() {
|
||||
return this.settings?.reactions ?? false;
|
||||
}
|
||||
get canComment() {
|
||||
return this.settings?.comments ?? false;
|
||||
}
|
||||
get canVote() {
|
||||
return this.settings?.votes ?? false;
|
||||
}
|
||||
|
||||
fetchProjectSettings = async (workspace_slug: string, project_slug: string) => {
|
||||
try {
|
||||
@ -75,14 +72,11 @@ export class ProjectStore implements IProjectStore {
|
||||
const response = await this.projectService.getProjectSettings(workspace_slug, project_slug);
|
||||
|
||||
if (response) {
|
||||
const currentProject: IProject = { ...response?.project_details };
|
||||
const currentWorkspace: IWorkspace = { ...response?.workspace_detail };
|
||||
const currentDeploySettings = { ...response };
|
||||
this.store.issueFilter.updateLayoutOptions(response?.views);
|
||||
runInAction(() => {
|
||||
this.project = currentProject;
|
||||
this.workspace = currentWorkspace;
|
||||
this.settings = currentDeploySettings;
|
||||
this.project = response?.project_details;
|
||||
this.workspace = response?.workspace_detail;
|
||||
this.settings = response;
|
||||
this.loader = false;
|
||||
});
|
||||
}
|
||||
@ -93,4 +87,10 @@ export class ProjectStore implements IProjectStore {
|
||||
return error;
|
||||
}
|
||||
};
|
||||
|
||||
hydrate = (projectSettings: TProjectSettings) => {
|
||||
const { workspace_detail, project_details } = projectSettings;
|
||||
this.workspace = workspace_detail;
|
||||
this.project = project_details;
|
||||
};
|
||||
}
|
||||
|
@ -32,8 +32,8 @@ export class RootStore {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
hydrate = (data: any) => {
|
||||
if (!data) return;
|
||||
this.instance.hydrate(data?.instance || {});
|
||||
this.user.hydrate(data?.user || {});
|
||||
this.instance.hydrate(data?.instance || undefined);
|
||||
this.user.hydrate(data?.user || undefined);
|
||||
};
|
||||
|
||||
reset = () => {
|
||||
|
@ -29,7 +29,7 @@ export interface IUserStore {
|
||||
// actions
|
||||
fetchCurrentUser: () => Promise<IUser | undefined>;
|
||||
updateCurrentUser: (data: Partial<IUser>) => Promise<IUser | undefined>;
|
||||
hydrate: (data: IUser) => void;
|
||||
hydrate: (data: IUser | undefined) => void;
|
||||
reset: () => void;
|
||||
signOut: () => Promise<void>;
|
||||
}
|
||||
@ -91,7 +91,7 @@ export class UserStore implements IUserStore {
|
||||
fetchCurrentUser = async (): Promise<IUser> => {
|
||||
try {
|
||||
runInAction(() => {
|
||||
this.isLoading = true;
|
||||
if (this.data === undefined) this.isLoading = true;
|
||||
this.error = undefined;
|
||||
});
|
||||
const user = await this.userService.currentUser();
|
||||
@ -155,7 +155,8 @@ export class UserStore implements IUserStore {
|
||||
}
|
||||
};
|
||||
|
||||
hydrate = (data: IUser): void => {
|
||||
hydrate = (data: IUser | undefined): void => {
|
||||
if (!data) return;
|
||||
this.data = { ...this.data, ...data };
|
||||
};
|
||||
|
||||
|
@ -329,3 +329,11 @@
|
||||
height: 0 !important;
|
||||
width: 0 !important;
|
||||
}
|
||||
|
||||
/* By applying below class, the autofilled text in form fields will not have the default autofill background color and styles applied by WebKit browsers */
|
||||
.disable-autofill-style:-webkit-autofill,
|
||||
.disable-autofill-style:-webkit-autofill:hover,
|
||||
.disable-autofill-style:-webkit-autofill:focus,
|
||||
.disable-autofill-style:-webkit-autofill:active {
|
||||
-webkit-background-clip: text;
|
||||
}
|
||||
|
49
space/types/project.d.ts
vendored
49
space/types/project.d.ts
vendored
@ -1,29 +1,42 @@
|
||||
import { TProjectLogoProps } from "@plane/types";
|
||||
|
||||
export interface IWorkspace {
|
||||
id: string;
|
||||
export type TWorkspaceDetails = {
|
||||
name: string;
|
||||
slug: string;
|
||||
}
|
||||
|
||||
export interface IProject {
|
||||
id: string;
|
||||
identifier: string;
|
||||
name: string;
|
||||
description: string;
|
||||
cover_image: string | null;
|
||||
logo_props: TProjectLogoProps;
|
||||
}
|
||||
};
|
||||
|
||||
export interface IProjectSettings {
|
||||
comments: boolean;
|
||||
reactions: boolean;
|
||||
votes: boolean;
|
||||
views: {
|
||||
export type TViewDetails = {
|
||||
list: boolean;
|
||||
gantt: boolean;
|
||||
kanban: boolean;
|
||||
calendar: boolean;
|
||||
spreadsheet: boolean;
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
export type TProjectDetails = {
|
||||
id: string;
|
||||
identifier: string;
|
||||
name: string;
|
||||
cover_image: string | undefined;
|
||||
logo_props: TProjectLogoProps;
|
||||
description: string;
|
||||
};
|
||||
|
||||
export type TProjectSettings = {
|
||||
id: string;
|
||||
anchor: string;
|
||||
comments: boolean;
|
||||
reactions: boolean;
|
||||
votes: boolean;
|
||||
inbox: unknown;
|
||||
workspace: string;
|
||||
workspace_detail: TWorkspaceDetails;
|
||||
project: string;
|
||||
project_details: TProjectDetails;
|
||||
views: TViewDetails;
|
||||
created_by: string;
|
||||
updated_by: string;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
};
|
||||
|
@ -668,7 +668,6 @@ div.web-view-spinner div.bar12 {
|
||||
}
|
||||
|
||||
/* By applying below class, the autofilled text in form fields will not have the default autofill background color and styles applied by WebKit browsers */
|
||||
|
||||
.disable-autofill-style:-webkit-autofill,
|
||||
.disable-autofill-style:-webkit-autofill:hover,
|
||||
.disable-autofill-style:-webkit-autofill:focus,
|
||||
|
Loading…
Reference in New Issue
Block a user