Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: modules list page #2521

Merged
merged 4 commits into from
Oct 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion web/components/headers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export * from "./workspace-dashboard";
export * from "./projects";
export * from "./profile-preferences";
export * from "./cycles";
export * from "./modules";
export * from "./modules-list";
export * from "./project-settings";
export * from "./workspace-settings";
export * from "./pages";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
import { Dispatch, FC, SetStateAction } from "react";
import { useRouter } from "next/router";
import Link from "next/link";
import { observer } from "mobx-react-lite";
import { Plus } from "lucide-react";
// components
// mobx store
import { useMobxStore } from "lib/mobx/store-provider";
// hooks
import useLocalStorage from "hooks/use-local-storage";
// ui
import { Breadcrumbs, BreadcrumbItem, Button, Tooltip } from "@plane/ui";
import { Icon } from "components/ui";
// helper
import { replaceUnderscoreIfSnakeCase, truncateText } from "helpers/string.helper";

export interface IModulesHeader {
name: string | undefined;
modulesView: string;
setModulesView: Dispatch<SetStateAction<"grid" | "gantt_chart">>;
}

const moduleViewOptions: { type: "grid" | "gantt_chart"; icon: any }[] = [
{
type: "gantt_chart",
Expand All @@ -26,11 +23,15 @@ const moduleViewOptions: { type: "grid" | "gantt_chart"; icon: any }[] = [
},
];

export const ModulesHeader: FC<IModulesHeader> = (props) => {
const { name, modulesView, setModulesView } = props;
export const ModulesListHeader: React.FC = observer(() => {
// router
const router = useRouter();
const { workspaceSlug } = router.query;
const { workspaceSlug, projectId } = router.query;

const { project: projectStore } = useMobxStore();
const projectDetails = projectId ? projectStore.project_details[projectId.toString()] : undefined;

const { storedValue: modulesView, setValue: setModulesView } = useLocalStorage("modules_view", "grid");

return (
<div
Expand All @@ -48,7 +49,7 @@ export const ModulesHeader: FC<IModulesHeader> = (props) => {
</Link>
}
/>
<BreadcrumbItem title={`${truncateText(name ?? "Project", 32)} Modules`} />
<BreadcrumbItem title={`${truncateText(projectDetails?.name ?? "Project", 32)} Modules`} />
</Breadcrumbs>
</div>
</div>
Expand Down Expand Up @@ -83,4 +84,4 @@ export const ModulesHeader: FC<IModulesHeader> = (props) => {
</div>
</div>
);
};
});
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ export const CycleIssueQuickActions: React.FC<Props> = (props) => {
setDeleteIssueModal(true);
}}
>
<div className="flex items-center gap-2 text-red-500">
<div className="flex items-center gap-2">
<Trash2 className="h-3 w-3" />
Delete issue
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ export const ModuleIssueQuickActions: React.FC<Props> = (props) => {
setDeleteIssueModal(true);
}}
>
<div className="flex items-center gap-2 text-red-500">
<div className="flex items-center gap-2">
<Trash2 className="h-3 w-3" />
Delete issue
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ export const ProjectIssueQuickActions: React.FC<Props> = (props) => {
setDeleteIssueModal(true);
}}
>
<div className="flex items-center gap-2 text-red-500">
<div className="flex items-center gap-2">
<Trash2 className="h-3 w-3" />
Delete issue
</div>
Expand Down
39 changes: 8 additions & 31 deletions web/components/issues/modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ import { Dialog, Transition } from "@headlessui/react";
// mobx store
import { useMobxStore } from "lib/mobx/store-provider";
// services
import { ModuleService } from "services/module.service";
import { IssueService, IssueDraftService } from "services/issue";
import { IssueDraftService } from "services/issue";
// hooks
import useToast from "hooks/use-toast";
import useLocalStorage from "hooks/use-local-storage";
Expand Down Expand Up @@ -40,8 +39,6 @@ export interface IssuesModalProps {
onSubmit?: (data: Partial<IIssue>) => Promise<void>;
}

const moduleService = new ModuleService();
const issueService = new IssueService();
const issueDraftService = new IssueDraftService();

export const CreateUpdateIssueModal: React.FC<IssuesModalProps> = observer((props) => {
Expand Down Expand Up @@ -170,35 +167,15 @@ export const CreateUpdateIssueModal: React.FC<IssuesModalProps> = observer((prop
}, [activeProject, data, projectId, projects, isOpen]);

const addIssueToCycle = async (issueId: string, cycleId: string) => {
if (!workspaceSlug || !activeProject || !user) return;
if (!workspaceSlug || !activeProject) return;

await issueService
.addIssueToCycle(
workspaceSlug.toString(),
activeProject,
cycleId,
{
issues: [issueId],
},
user
)
.then(() => cycleIssueStore.fetchIssues(workspaceSlug.toString(), activeProject, cycleId));
cycleIssueStore.addIssueToCycle(workspaceSlug.toString(), activeProject, cycleId, issueId);
};

const addIssueToModule = async (issueId: string, moduleId: string) => {
if (!workspaceSlug || !activeProject || !user) return;
if (!workspaceSlug || !activeProject) return;

await moduleService
.addIssuesToModule(
workspaceSlug.toString(),
activeProject,
moduleId,
{
issues: [issueId],
},
user
)
.then(() => moduleIssueStore.fetchIssues(workspaceSlug.toString(), activeProject, moduleId));
moduleIssueStore.addIssueToModule(workspaceSlug.toString(), activeProject, moduleId, issueId);
};

const createIssue = async (payload: Partial<IIssue>) => {
Expand Down Expand Up @@ -267,10 +244,10 @@ export const CreateUpdateIssueModal: React.FC<IssuesModalProps> = observer((prop
};

const updateIssue = async (payload: Partial<IIssue>) => {
if (!user) return;
if (!workspaceSlug || !activeProject || !data) return;

await issueService
.patchIssue(workspaceSlug as string, activeProject ?? "", data?.id ?? "", payload, user)
await issueDetailStore
.updateIssue(workspaceSlug.toString(), activeProject, data.id, payload)
.then(() => {
if (!createMore) onFormSubmitClose();

Expand Down
41 changes: 17 additions & 24 deletions web/components/modules/delete-module-modal.tsx
Original file line number Diff line number Diff line change
@@ -1,56 +1,47 @@
import React, { useState } from "react";

import { useRouter } from "next/router";

import { mutate } from "swr";

// headless ui
import { Dialog, Transition } from "@headlessui/react";
// services
import { ModuleService } from "services/module.service";
// hooks
import useToast from "hooks/use-toast";
// ui
import { Button } from "@plane/ui";
// icons
import { AlertTriangle } from "lucide-react";
// types
import type { IUser, IModule } from "types";
// fetch-keys
import { MODULE_LIST } from "constants/fetch-keys";
import type { IModule } from "types";
import { observer } from "mobx-react-lite";
import { useMobxStore } from "lib/mobx/store-provider";

type Props = {
data: IModule;
isOpen: boolean;
setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;
data?: IModule;
user: IUser | undefined;
onClose: () => void;
};

// services
const moduleService = new ModuleService();
export const DeleteModuleModal: React.FC<Props> = observer((props) => {
const { data, isOpen, onClose } = props;

export const DeleteModuleModal: React.FC<Props> = ({ isOpen, setIsOpen, data, user }) => {
const [isDeleteLoading, setIsDeleteLoading] = useState(false);

const router = useRouter();
const { workspaceSlug, projectId, moduleId } = router.query;

const { module: moduleStore } = useMobxStore();

const { setToastAlert } = useToast();

const handleClose = () => {
setIsOpen(false);
onClose();
setIsDeleteLoading(false);
};

const handleDeletion = async () => {
setIsDeleteLoading(true);
if (!workspaceSlug || !projectId) return;

if (!workspaceSlug || !projectId || !data) return;

mutate<IModule[]>(MODULE_LIST(projectId as string), (prevData) => prevData?.filter((m) => m.id !== data.id), false);
setIsDeleteLoading(true);

await moduleService
.deleteModule(workspaceSlug as string, projectId as string, data.id, user)
await moduleStore
.deleteModule(workspaceSlug.toString(), projectId.toString(), data.id)
.then(() => {
if (moduleId) router.push(`/${workspaceSlug}/projects/${data.project}/modules`);
handleClose();
Expand All @@ -61,6 +52,8 @@ export const DeleteModuleModal: React.FC<Props> = ({ isOpen, setIsOpen, data, us
title: "Error!",
message: "Module could not be deleted. Please try again.",
});
})
.finally(() => {
setIsDeleteLoading(false);
});
};
Expand Down Expand Up @@ -126,4 +119,4 @@ export const DeleteModuleModal: React.FC<Props> = ({ isOpen, setIsOpen, data, us
</Dialog>
</Transition.Root>
);
};
});
63 changes: 12 additions & 51 deletions web/components/modules/gantt-chart/modules-list-layout.tsx
Original file line number Diff line number Diff line change
@@ -1,65 +1,26 @@
import { FC } from "react";

import { useRouter } from "next/router";

import { KeyedMutator } from "swr";

// services
import { ModuleService } from "services/module.service";
// hooks
import useUser from "hooks/use-user";
import useProjectDetails from "hooks/use-project-details";
import { observer } from "mobx-react-lite";
// mobx store
import { useMobxStore } from "lib/mobx/store-provider";
// components
import { GanttChartRoot, IBlockUpdateData } from "components/gantt-chart";
import { ModuleGanttBlock, ModuleGanttSidebarBlock } from "components/modules";
// types
import { IModule } from "types";

type Props = {
modules: IModule[];
mutateModules: KeyedMutator<IModule[]>;
};

// services
const moduleService = new ModuleService();

export const ModulesListGanttChartView: FC<Props> = ({ modules, mutateModules }) => {
export const ModulesListGanttChartView: React.FC = observer(() => {
const router = useRouter();
const { workspaceSlug } = router.query;

const { user } = useUser();
const { projectDetails } = useProjectDetails();
const { workspaceSlug, projectId } = router.query;

const handleModuleUpdate = (module: IModule, payload: IBlockUpdateData) => {
if (!workspaceSlug || !user) return;

mutateModules((prevData: any) => {
if (!prevData) return prevData;

const newList = prevData.map((p: any) => ({
...p,
...(p.id === module.id
? {
start_date: payload.start_date ? payload.start_date : p.start_date,
target_date: payload.target_date ? payload.target_date : p.target_date,
sort_order: payload.sort_order ? payload.sort_order.newSortOrder : p.sort_order,
}
: {}),
}));
const { project: projectStore, module: moduleStore } = useMobxStore();

if (payload.sort_order) {
const removedElement = newList.splice(payload.sort_order.sourceIndex, 1)[0];
newList.splice(payload.sort_order.destinationIndex, 0, removedElement);
}
const projectDetails = projectId ? projectStore.project_details[projectId.toString()] : undefined;
const modules = moduleStore.projectModules;

return newList;
}, false);

const newPayload: any = { ...payload };

if (newPayload.sort_order && payload.sort_order) newPayload.sort_order = payload.sort_order.newSortOrder;
const handleModuleUpdate = (module: IModule, payload: IBlockUpdateData) => {
if (!workspaceSlug) return;

moduleService.patchModule(workspaceSlug.toString(), module.project, module.id, newPayload, user);
moduleStore.updateModuleGanttStructure(workspaceSlug.toString(), module.project, module, payload);
};

const blockFormat = (blocks: IModule[]) =>
Expand Down Expand Up @@ -93,4 +54,4 @@ export const ModulesListGanttChartView: FC<Props> = ({ modules, mutateModules })
/>
</div>
);
};
});
3 changes: 2 additions & 1 deletion web/components/modules/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ export * from "./delete-module-modal";
export * from "./form";
export * from "./gantt-chart";
export * from "./modal";
export * from "./modules-list-view";
export * from "./sidebar";
export * from "./single-module-card";
export * from "./module-card-item";
Loading
Loading