fix: mobx changes

This commit is contained in:
sriram veeraghanta 2023-08-30 17:39:11 +05:30
parent 91910d106c
commit d7c27b75fa
10 changed files with 115 additions and 109 deletions

View File

@ -9,6 +9,8 @@ import { observer } from "mobx-react-lite";
// mobx // mobx
import { useMobxStore } from "lib/mobx/store-provider"; import { useMobxStore } from "lib/mobx/store-provider";
import { RootStore } from "store/root"; import { RootStore } from "store/root";
import { useEffect } from "react";
import { useRouter } from "next/router";
const renderEmoji = (emoji: string | { name: string; color: string }) => { const renderEmoji = (emoji: string | { name: string; color: string }) => {
if (!emoji) return; if (!emoji) return;
@ -23,21 +25,30 @@ const renderEmoji = (emoji: string | { name: string; color: string }) => {
}; };
const IssueNavbar = observer(() => { const IssueNavbar = observer(() => {
const store: RootStore = useMobxStore(); const { project: projectStore }: RootStore = useMobxStore();
// router
const router = useRouter();
const { workspace_slug, project_slug } = router.query;
useEffect(() => {
if (workspace_slug && project_slug) {
projectStore.fetchProjectSettings(workspace_slug.toString(), project_slug.toString());
}
}, [projectStore, workspace_slug, project_slug]);
return ( return (
<div className="px-5 relative w-full flex items-center gap-4"> <div className="px-5 relative w-full flex items-center gap-4">
{/* project detail */} {/* project detail */}
<div className="flex-shrink-0 flex items-center gap-2"> <div className="flex-shrink-0 flex items-center gap-2">
<div className="w-[32px] h-[32px] rounded-sm flex justify-center items-center text-[24px]"> <div className="w-[32px] h-[32px] rounded-sm flex justify-center items-center text-[24px]">
{store?.project?.project && store?.project?.project?.emoji ? ( {projectStore?.project && projectStore?.project?.emoji ? (
renderEmoji(store?.project?.project?.emoji) renderEmoji(projectStore?.project?.emoji)
) : ( ) : (
<Image src="/plane-logo.webp" alt="plane logo" className="w-[24px] h-[24px]" height="24" width="24" /> <Image src="/plane-logo.webp" alt="plane logo" className="w-[24px] h-[24px]" height="24" width="24" />
)} )}
</div> </div>
<div className="font-medium text-lg max-w-[300px] line-clamp-1 overflow-hidden"> <div className="font-medium text-lg max-w-[300px] line-clamp-1 overflow-hidden">
{store?.project?.project?.name || `...`} {projectStore?.project?.name || `...`}
</div> </div>
</div> </div>
@ -49,7 +60,6 @@ const IssueNavbar = observer(() => {
{/* issue filters */} {/* issue filters */}
<div className="flex-shrink-0 relative flex items-center gap-2"> <div className="flex-shrink-0 relative flex items-center gap-2">
<NavbarIssueFilter /> <NavbarIssueFilter />
{/* <NavbarIssueView /> */}
</div> </div>
{/* issue views */} {/* issue views */}

View File

@ -10,52 +10,64 @@ import { IssuePeekOverview } from "components/issues/peek-overview";
// mobx store // mobx store
import { RootStore } from "store/root"; import { RootStore } from "store/root";
import { useMobxStore } from "lib/mobx/store-provider"; import { useMobxStore } from "lib/mobx/store-provider";
import { useEffect } from "react";
export const ProjectDetailsView = () => { export const ProjectDetailsView = () => {
const router = useRouter(); const router = useRouter();
const { workspace_slug } = router.query; const { workspace_slug, project_slug, states, labels, priorities } = router.query;
const store: RootStore = useMobxStore(); const { issue: issueStore }: RootStore = useMobxStore();
const activeIssueId = store.issue.activePeekOverviewIssueId; const activeIssueId = issueStore.activePeekOverviewIssueId;
useEffect(() => {
if (workspace_slug && project_slug) {
const params = {
state: states || null,
labels: labels || null,
priority: priorities || null,
};
issueStore.fetchPublicIssues(workspace_slug?.toString(), project_slug.toString(), params);
}
}, [workspace_slug, project_slug, issueStore, states, labels, priorities]);
return ( return (
<div className="relative w-full h-full overflow-hidden"> <div className="relative w-full h-full overflow-hidden">
{workspace_slug && ( {workspace_slug && (
<IssuePeekOverview <IssuePeekOverview
isOpen={Boolean(activeIssueId)} isOpen={Boolean(activeIssueId)}
onClose={() => store.issue.setActivePeekOverviewIssueId(null)} onClose={() => issueStore.setActivePeekOverviewIssueId(null)}
issue={store?.issue?.issues?.find((_issue) => _issue.id === activeIssueId) || null} issue={issueStore?.issues?.find((_issue) => _issue.id === activeIssueId) || null}
workspaceSlug={workspace_slug.toString()} workspaceSlug={workspace_slug.toString()}
/> />
)} )}
{store?.issue?.loader && !store.issue.issues ? ( {issueStore?.loader && !issueStore.issues ? (
<div className="text-sm text-center py-10 text-custom-text-100">Loading...</div> <div className="text-sm text-center py-10 text-custom-text-100">Loading...</div>
) : ( ) : (
<> <>
{store?.issue?.error ? ( {issueStore?.error ? (
<div className="text-sm text-center py-10 bg-custom-background-200 text-custom-text-100"> <div className="text-sm text-center py-10 bg-custom-background-200 text-custom-text-100">
Something went wrong. Something went wrong.
</div> </div>
) : ( ) : (
store?.issue?.currentIssueBoardView && ( issueStore?.currentIssueBoardView && (
<> <>
{store?.issue?.currentIssueBoardView === "list" && ( {issueStore?.currentIssueBoardView === "list" && (
<div className="relative w-full h-full overflow-y-auto"> <div className="relative w-full h-full overflow-y-auto">
<div className="mx-auto px-4"> <div className="mx-auto px-4">
<IssueListView /> <IssueListView />
</div> </div>
</div> </div>
)} )}
{store?.issue?.currentIssueBoardView === "kanban" && ( {issueStore?.currentIssueBoardView === "kanban" && (
<div className="relative w-full h-full mx-auto px-9 py-5"> <div className="relative w-full h-full mx-auto px-9 py-5">
<IssueKanbanView /> <IssueKanbanView />
</div> </div>
)} )}
{store?.issue?.currentIssueBoardView === "calendar" && <IssueCalendarView />} {issueStore?.currentIssueBoardView === "calendar" && <IssueCalendarView />}
{store?.issue?.currentIssueBoardView === "spreadsheet" && <IssueSpreadsheetView />} {issueStore?.currentIssueBoardView === "spreadsheet" && <IssueSpreadsheetView />}
{store?.issue?.currentIssueBoardView === "gantt" && <IssueGanttView />} {issueStore?.currentIssueBoardView === "gantt" && <IssueGanttView />}
</> </>
) )
)} )}

View File

@ -1,12 +1,9 @@
import Link from "next/link"; import Link from "next/link";
import Image from "next/image"; import Image from "next/image";
import { observer } from "mobx-react-lite";
// components // components
import IssueNavbar from "components/issues/navbar"; import IssueNavbar from "components/issues/navbar";
type LayoutProps = {
params: { workspace_slug: string; project_slug: string };
};
const ProjectLayout = ({ children }: { children: React.ReactNode }) => ( const ProjectLayout = ({ children }: { children: React.ReactNode }) => (
<div className="relative w-screen min-h-[500px] h-screen overflow-hidden flex flex-col"> <div className="relative w-screen min-h-[500px] h-screen overflow-hidden flex flex-col">
<div className="flex-shrink-0 h-[60px] border-b border-gray-300 relative flex items-center bg-white select-none"> <div className="flex-shrink-0 h-[60px] border-b border-gray-300 relative flex items-center bg-white select-none">
@ -28,4 +25,4 @@ const ProjectLayout = ({ children }: { children: React.ReactNode }) => (
</div> </div>
); );
export default ProjectLayout; export default observer(ProjectLayout);

View File

@ -109,12 +109,12 @@ const WorkspaceProjectPage = (props: any) => {
); );
}; };
export const getServerSideProps: GetServerSideProps<any> = async ({ query: { workspace_slug, project_slug } }) => { // export const getServerSideProps: GetServerSideProps<any> = async ({ query: { workspace_slug, project_slug } }) => {
const res = await fetch( // const res = await fetch(
`${process.env.NEXT_PUBLIC_API_BASE_URL}/api/public/workspaces/${workspace_slug}/project-boards/${project_slug}/settings/` // `${process.env.NEXT_PUBLIC_API_BASE_URL}/api/public/workspaces/${workspace_slug}/project-boards/${project_slug}/settings/`
); // );
const project_settings = await res.json(); // const project_settings = await res.json();
return { props: { project_settings } }; // return { props: { project_settings } };
}; // };
export default WorkspaceProjectPage; export default WorkspaceProjectPage;

View File

@ -6,7 +6,7 @@ class ProjectService extends APIService {
super(process.env.NEXT_PUBLIC_API_BASE_URL || "http://localhost:8000"); super(process.env.NEXT_PUBLIC_API_BASE_URL || "http://localhost:8000");
} }
async getProjectSettingsAsync(workspace_slug: string, project_slug: string): Promise<any> { async getProjectSettings(workspace_slug: string, project_slug: string): Promise<any> {
return this.get(`/api/public/workspaces/${workspace_slug}/project-boards/${project_slug}/settings/`) return this.get(`/api/public/workspaces/${workspace_slug}/project-boards/${project_slug}/settings/`)
.then((response) => response?.data) .then((response) => response?.data)
.catch((error) => { .catch((error) => {

View File

@ -4,9 +4,41 @@ import { observable, action, computed, makeObservable, runInAction, reaction } f
import IssueService from "services/issue.service"; import IssueService from "services/issue.service";
// types // types
import { IssueDetailType, TIssueBoardKeys } from "store/types/issue"; import { IssueDetailType, TIssueBoardKeys } from "store/types/issue";
import { IIssueStore, IIssue, IIssueState, IIssueLabel } from "./types"; import { IIssue, IIssueState, IIssueLabel } from "./types";
export interface IIssueStore {
currentIssueBoardView: TIssueBoardKeys | null;
loader: boolean;
error: any | null;
states: IIssueState[] | null;
labels: IIssueLabel[] | null;
issues: IIssue[] | null;
issue_detail: IssueDetailType;
userSelectedStates: string[];
userSelectedLabels: string[];
userSelectedPriorities: string[];
activePeekOverviewIssueId: string | null;
getCountOfIssuesByState: (state: string) => number;
getFilteredIssuesByState: (state: string) => IIssue[];
getUserSelectedFilter: (key: "state" | "priority" | "label", value: string) => boolean;
checkIfFilterExistsForKey: (key: "state" | "priority" | "label") => boolean;
clearUserSelectedFilter: (key: "state" | "priority" | "label" | "all") => void;
getIfFiltersIsEmpty: () => boolean;
getURLDefinition: (
workspaceSlug: string,
projectId: string,
action?: {
key: "state" | "priority" | "label" | "all";
value?: string;
removeAll?: boolean;
}
) => string;
setActivePeekOverviewIssueId: (value: any) => void;
setCurrentIssueBoardView: (view: TIssueBoardKeys) => void;
fetchPublicIssues: (workspaceSlug: string, projectId: string, params: any) => Promise<void>;
getIssueByIdAsync: (workspaceSlug: string, projectId: string, issueId: string) => Promise<IssueDetailType>;
}
// class IssueStore implements IIssueStore {
class IssueStore { class IssueStore {
currentIssueBoardView: TIssueBoardKeys | null = null; currentIssueBoardView: TIssueBoardKeys | null = null;
@ -49,7 +81,7 @@ class IssueStore {
userSelectedPriorities: observable.ref, userSelectedPriorities: observable.ref,
// action // action
setCurrentIssueBoardView: action, setCurrentIssueBoardView: action,
getIssuesAsync: action, fetchPublicIssues: action,
// computed // computed
}); });
@ -167,7 +199,7 @@ class IssueStore {
this.currentIssueBoardView = view; this.currentIssueBoardView = view;
}; };
getIssuesAsync = async (workspaceSlug: string, projectId: string, params: any) => { fetchPublicIssues = async (workspaceSlug: string, projectId: string, params: any) => {
try { try {
this.loader = true; this.loader = true;
this.error = null; this.error = null;

View File

@ -3,15 +3,26 @@ import { observable, action, makeObservable, runInAction } from "mobx";
// service // service
import ProjectService from "services/project.service"; import ProjectService from "services/project.service";
// types // types
import { IProjectStore, IWorkspace, IProject, IProjectSettings } from "./types"; import { IWorkspace, IProject, IProjectSettings } from "./types";
export interface IProjectStore {
loader: boolean;
error: any | null;
workspace: IWorkspace | null;
project: IProject | null;
projectDeploySettings: IProjectSettings | null;
viewOptions: any;
fetchProjectSettings: (workspace_slug: string, project_slug: string) => Promise<void>;
}
class ProjectStore implements IProjectStore { class ProjectStore implements IProjectStore {
loader: boolean = false; loader: boolean = false;
error: any | null = null; error: any | null = null;
// data
workspace: IWorkspace | null = null; workspace: IWorkspace | null = null;
project: IProject | null = null; project: IProject | null = null;
workspaceProjectSettings: IProjectSettings | null = null; projectDeploySettings: IProjectSettings | null = null;
viewOptions: any = null;
// root store // root store
rootStore; rootStore;
// service // service
@ -19,14 +30,16 @@ class ProjectStore implements IProjectStore {
constructor(_rootStore: any | null = null) { constructor(_rootStore: any | null = null) {
makeObservable(this, { makeObservable(this, {
// loaders and error observables
loader: observable,
error: observable.ref,
// observable // observable
workspace: observable.ref, workspace: observable.ref,
project: observable.ref, project: observable.ref,
workspaceProjectSettings: observable.ref, projectDeploySettings: observable.ref,
loader: observable, viewOptions: observable.ref,
error: observable.ref, // actions
// action fetchProjectSettings: action,
getProjectSettingsAsync: action,
// computed // computed
}); });
@ -34,26 +47,21 @@ class ProjectStore implements IProjectStore {
this.projectService = new ProjectService(); this.projectService = new ProjectService();
} }
getProjectSettingsAsync = async (workspace_slug: string, project_slug: string) => { fetchProjectSettings = async (workspace_slug: string, project_slug: string) => {
try { try {
this.loader = true; this.loader = true;
this.error = null; this.error = null;
const response = await this.projectService.getProjectSettingsAsync(workspace_slug, project_slug); const response = await this.projectService.getProjectSettings(workspace_slug, project_slug);
if (response) { if (response) {
const _project: IProject = { ...response?.project_details }; const _project: IProject = { ...response?.project_details };
const _workspace: IWorkspace = { ...response?.workspace_detail }; const _workspace: IWorkspace = { ...response?.workspace_detail };
const _workspaceProjectSettings: IProjectSettings = { const _viewOptions = { ...response?.views };
comments: response?.comments,
reactions: response?.reactions,
votes: response?.votes,
views: { ...response?.views },
};
runInAction(() => { runInAction(() => {
this.project = _project; this.project = _project;
this.workspace = _workspace; this.workspace = _workspace;
this.workspaceProjectSettings = _workspaceProjectSettings; this.viewOptions = _viewOptions;
this.loader = false; this.loader = false;
}); });
} }

View File

@ -3,17 +3,17 @@ import { enableStaticRendering } from "mobx-react-lite";
// store imports // store imports
import UserStore from "./user"; import UserStore from "./user";
import ThemeStore from "./theme"; import ThemeStore from "./theme";
import IssueStore from "./issue"; import IssueStore, { IIssueStore } from "./issue";
import ProjectStore from "./project"; import ProjectStore, { IProjectStore } from "./project";
// types // types
import { IIssueStore, IProjectStore, IThemeStore } from "./types"; import { IThemeStore } from "./types";
enableStaticRendering(typeof window === "undefined"); enableStaticRendering(typeof window === "undefined");
export class RootStore { export class RootStore {
user: UserStore; user: UserStore;
theme: IThemeStore; theme: IThemeStore;
issue: IssueStore; issue: IIssueStore;
project: IProjectStore; project: IProjectStore;
constructor() { constructor() {

View File

@ -143,45 +143,3 @@ export interface IssueDetailType {
votes: any[]; votes: any[];
}; };
} }
export interface IIssueStore {
currentIssueBoardView: TIssueBoardKeys | null;
loader: boolean;
error: any | null;
states: IIssueState[] | null;
labels: IIssueLabel[] | null;
issues: IIssue[] | null;
issue_detail: IssueDetailType;
userSelectedStates: string[];
userSelectedLabels: string[];
userSelectedPriorities: string[];
getCountOfIssuesByState: (state: string) => number;
getFilteredIssuesByState: (state: string) => IIssue[];
getUserSelectedFilter: (key: "state" | "priority" | "label", value: string) => boolean;
checkIfFilterExistsForKey: (key: "state" | "priority" | "label") => boolean;
clearUserSelectedFilter: (key: "state" | "priority" | "label" | "all") => void;
getIfFiltersIsEmpty: () => boolean;
getURLDefinition: (
workspaceSlug: string,
projectId: string,
action?: {
key: "state" | "priority" | "label" | "all";
value?: string;
removeAll?: boolean;
}
) => string;
setCurrentIssueBoardView: (view: TIssueBoardKeys) => void;
getIssuesAsync: (workspaceSlug: string, projectId: string, params: any) => Promise<void>;
getIssueByIdAsync: (workspaceSlug: string, projectId: string, issueId: string) => Promise<IssueDetailType>;
}

View File

@ -27,14 +27,3 @@ export interface IProjectSettings {
spreadsheet: boolean; spreadsheet: boolean;
}; };
} }
export interface IProjectStore {
loader: boolean;
error: any | null;
workspace: IWorkspace | null;
project: IProject | null;
workspaceProjectSettings: IProjectSettings | null;
getProjectSettingsAsync: (workspace_slug: string, project_slug: string) => Promise<void>;
}