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 ? (
|
{user?.id ? (
|
||||||
<div className="flex items-center gap-2 rounded border border-custom-border-200 p-2">
|
<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" />
|
<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>
|
||||||
) : (
|
) : (
|
||||||
<div className="flex-shrink-0">
|
<div className="flex-shrink-0">
|
||||||
|
@ -36,8 +36,7 @@ export const ProjectDetailsView: FC<ProjectDetailsViewProps> = observer((props)
|
|||||||
// hooks
|
// hooks
|
||||||
const { fetchProjectSettings } = useProject();
|
const { fetchProjectSettings } = useProject();
|
||||||
const { issueFilters } = useIssueFilter();
|
const { issueFilters } = useIssueFilter();
|
||||||
const { loader, issues, error } = useIssue();
|
const { loader, issues, error, fetchPublicIssues } = useIssue();
|
||||||
const { fetchPublicIssues } = useIssue();
|
|
||||||
const issueDetailStore = useIssueDetails();
|
const issueDetailStore = useIssueDetails();
|
||||||
const { data: currentUser, fetchCurrentUser } = useUser();
|
const { data: currentUser, fetchCurrentUser } = useUser();
|
||||||
|
|
||||||
@ -51,12 +50,10 @@ export const ProjectDetailsView: FC<ProjectDetailsViewProps> = observer((props)
|
|||||||
? () => fetchPublicIssues(workspaceSlug, projectId, { states, priority, labels })
|
? () => fetchPublicIssues(workspaceSlug, projectId, { states, priority, labels })
|
||||||
: null
|
: null
|
||||||
);
|
);
|
||||||
|
useSWR(
|
||||||
useEffect(() => {
|
workspaceSlug && projectId && !currentUser ? "WORKSPACE_PROJECT_CURRENT_USER" : null,
|
||||||
if (!currentUser) {
|
workspaceSlug && projectId && !currentUser ? () => fetchCurrentUser() : null
|
||||||
fetchCurrentUser();
|
);
|
||||||
}
|
|
||||||
}, [currentUser, fetchCurrentUser]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (peekId && workspaceSlug && projectId) {
|
if (peekId && workspaceSlug && projectId) {
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
// mobx
|
// mobx
|
||||||
import { observable, action, makeObservable, runInAction } from "mobx";
|
import { observable, action, makeObservable, runInAction, computed } from "mobx";
|
||||||
// service
|
// service
|
||||||
import ProjectService from "@/services/project.service";
|
import ProjectService from "@/services/project.service";
|
||||||
// store types
|
// store types
|
||||||
import { RootStore } from "@/store/root.store";
|
import { RootStore } from "@/store/root.store";
|
||||||
// types
|
// types
|
||||||
import { IWorkspace, IProject, IProjectSettings } from "@/types/project";
|
import { TWorkspaceDetails, TProjectDetails, TProjectSettings } from "@/types/project";
|
||||||
|
|
||||||
export interface IProjectStore {
|
export interface IProjectStore {
|
||||||
// observables
|
// observables
|
||||||
loader: boolean;
|
loader: boolean;
|
||||||
error: any | null;
|
error: any | undefined;
|
||||||
workspace: IWorkspace | null;
|
settings: TProjectSettings | undefined;
|
||||||
project: IProject | null;
|
workspace: TWorkspaceDetails | undefined;
|
||||||
settings: IProjectSettings | null;
|
project: TProjectDetails | undefined;
|
||||||
canReact: boolean;
|
canReact: boolean;
|
||||||
canComment: boolean;
|
canComment: boolean;
|
||||||
canVote: boolean;
|
canVote: boolean;
|
||||||
@ -25,13 +25,10 @@ export interface IProjectStore {
|
|||||||
export class ProjectStore implements IProjectStore {
|
export class ProjectStore implements IProjectStore {
|
||||||
// observables
|
// observables
|
||||||
loader: boolean = false;
|
loader: boolean = false;
|
||||||
error: any | null = null;
|
error: any | undefined = undefined;
|
||||||
workspace: IWorkspace | null = null;
|
settings: TProjectSettings | undefined = undefined;
|
||||||
project: IProject | null = null;
|
workspace: TWorkspaceDetails | undefined = undefined;
|
||||||
settings: IProjectSettings | null = null;
|
project: TProjectDetails | undefined = undefined;
|
||||||
canReact: boolean = false;
|
|
||||||
canComment: boolean = false;
|
|
||||||
canVote: boolean = false;
|
|
||||||
// service
|
// service
|
||||||
projectService;
|
projectService;
|
||||||
|
|
||||||
@ -44,28 +41,28 @@ export class ProjectStore implements IProjectStore {
|
|||||||
workspace: observable,
|
workspace: observable,
|
||||||
project: observable,
|
project: observable,
|
||||||
settings: observable,
|
settings: observable,
|
||||||
canReact: observable.ref,
|
// computed
|
||||||
canComment: observable.ref,
|
canReact: computed,
|
||||||
canVote: observable.ref,
|
canComment: computed,
|
||||||
|
canVote: computed,
|
||||||
// actions
|
// actions
|
||||||
fetchProjectSettings: action,
|
fetchProjectSettings: action,
|
||||||
|
|
||||||
hydrate: action,
|
hydrate: action,
|
||||||
// computed
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// services
|
// services
|
||||||
this.projectService = new ProjectService();
|
this.projectService = new ProjectService();
|
||||||
}
|
}
|
||||||
|
|
||||||
hydrate = (projectSettings: any) => {
|
// computed
|
||||||
const { workspace_detail, project_details, votes, comments, reactions } = projectSettings;
|
get canReact() {
|
||||||
this.workspace = workspace_detail;
|
return this.settings?.reactions ?? false;
|
||||||
this.project = project_details;
|
}
|
||||||
this.canComment = comments;
|
get canComment() {
|
||||||
this.canVote = votes;
|
return this.settings?.comments ?? false;
|
||||||
this.canReact = reactions;
|
}
|
||||||
};
|
get canVote() {
|
||||||
|
return this.settings?.votes ?? false;
|
||||||
|
}
|
||||||
|
|
||||||
fetchProjectSettings = async (workspace_slug: string, project_slug: string) => {
|
fetchProjectSettings = async (workspace_slug: string, project_slug: string) => {
|
||||||
try {
|
try {
|
||||||
@ -75,14 +72,11 @@ export class ProjectStore implements IProjectStore {
|
|||||||
const response = await this.projectService.getProjectSettings(workspace_slug, project_slug);
|
const response = await this.projectService.getProjectSettings(workspace_slug, project_slug);
|
||||||
|
|
||||||
if (response) {
|
if (response) {
|
||||||
const currentProject: IProject = { ...response?.project_details };
|
|
||||||
const currentWorkspace: IWorkspace = { ...response?.workspace_detail };
|
|
||||||
const currentDeploySettings = { ...response };
|
|
||||||
this.store.issueFilter.updateLayoutOptions(response?.views);
|
this.store.issueFilter.updateLayoutOptions(response?.views);
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.project = currentProject;
|
this.project = response?.project_details;
|
||||||
this.workspace = currentWorkspace;
|
this.workspace = response?.workspace_detail;
|
||||||
this.settings = currentDeploySettings;
|
this.settings = response;
|
||||||
this.loader = false;
|
this.loader = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -93,4 +87,10 @@ export class ProjectStore implements IProjectStore {
|
|||||||
return error;
|
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
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
hydrate = (data: any) => {
|
hydrate = (data: any) => {
|
||||||
if (!data) return;
|
if (!data) return;
|
||||||
this.instance.hydrate(data?.instance || {});
|
this.instance.hydrate(data?.instance || undefined);
|
||||||
this.user.hydrate(data?.user || {});
|
this.user.hydrate(data?.user || undefined);
|
||||||
};
|
};
|
||||||
|
|
||||||
reset = () => {
|
reset = () => {
|
||||||
|
@ -29,7 +29,7 @@ export interface IUserStore {
|
|||||||
// actions
|
// actions
|
||||||
fetchCurrentUser: () => Promise<IUser | undefined>;
|
fetchCurrentUser: () => Promise<IUser | undefined>;
|
||||||
updateCurrentUser: (data: Partial<IUser>) => Promise<IUser | undefined>;
|
updateCurrentUser: (data: Partial<IUser>) => Promise<IUser | undefined>;
|
||||||
hydrate: (data: IUser) => void;
|
hydrate: (data: IUser | undefined) => void;
|
||||||
reset: () => void;
|
reset: () => void;
|
||||||
signOut: () => Promise<void>;
|
signOut: () => Promise<void>;
|
||||||
}
|
}
|
||||||
@ -91,7 +91,7 @@ export class UserStore implements IUserStore {
|
|||||||
fetchCurrentUser = async (): Promise<IUser> => {
|
fetchCurrentUser = async (): Promise<IUser> => {
|
||||||
try {
|
try {
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.isLoading = true;
|
if (this.data === undefined) this.isLoading = true;
|
||||||
this.error = undefined;
|
this.error = undefined;
|
||||||
});
|
});
|
||||||
const user = await this.userService.currentUser();
|
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 };
|
this.data = { ...this.data, ...data };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -329,3 +329,11 @@
|
|||||||
height: 0 !important;
|
height: 0 !important;
|
||||||
width: 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";
|
import { TProjectLogoProps } from "@plane/types";
|
||||||
|
|
||||||
export interface IWorkspace {
|
export type TWorkspaceDetails = {
|
||||||
id: string;
|
|
||||||
name: string;
|
name: string;
|
||||||
slug: string;
|
slug: string;
|
||||||
}
|
|
||||||
|
|
||||||
export interface IProject {
|
|
||||||
id: string;
|
id: string;
|
||||||
identifier: string;
|
};
|
||||||
name: string;
|
|
||||||
description: string;
|
|
||||||
cover_image: string | null;
|
|
||||||
logo_props: TProjectLogoProps;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IProjectSettings {
|
export type TViewDetails = {
|
||||||
comments: boolean;
|
|
||||||
reactions: boolean;
|
|
||||||
votes: boolean;
|
|
||||||
views: {
|
|
||||||
list: boolean;
|
list: boolean;
|
||||||
gantt: boolean;
|
gantt: boolean;
|
||||||
kanban: boolean;
|
kanban: boolean;
|
||||||
calendar: boolean;
|
calendar: boolean;
|
||||||
spreadsheet: 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 */
|
/* 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,
|
||||||
.disable-autofill-style:-webkit-autofill:hover,
|
.disable-autofill-style:-webkit-autofill:hover,
|
||||||
.disable-autofill-style:-webkit-autofill:focus,
|
.disable-autofill-style:-webkit-autofill:focus,
|
||||||
|
Loading…
Reference in New Issue
Block a user