Skip to content

Commit

Permalink
feat: Gantt chart (#1062)
Browse files Browse the repository at this point in the history
* dev: Helpers

* dev: views

* dev: Chart views Month, Year and Day

* dev: Chart Workflow updates

* update: scroll functionality implementation

* update: data vaidation

* update: date renders and issue filter in the month view

* update: new date render month view

* update: scroll enabled left in chart

* update: Item render from the date it created.

* update: width implementation in chat view

* dev: chart render functionality in the gantt chart

* update: month view fix

* dev: chart render issues resolved

* update: fixed allchat views

* update: updated week view default values

* update: integrated chart view in issues

* update: grabble and sidebar logic impleemntation and integrated gantt in issues

* update: Preview gantt chart in month view

* fix: mutation in gantt chart after creating a new issue

* chore: cycles and modules list gantt chart

* update: Ui changes on gantt view

* fix: gantt chart height, chore: remove link from issue

---------

Co-authored-by: Aaryan Khandelwal <aaryankhandu123@gmail.com>
  • Loading branch information
gurusainath and aaryan610 committed May 20, 2023
1 parent 9ccc35d commit e1e9a5e
Show file tree
Hide file tree
Showing 49 changed files with 3,251 additions and 140 deletions.
26 changes: 26 additions & 0 deletions apps/app/components/core/gantt-chart-view/index.tsx
@@ -0,0 +1,26 @@
import { useRouter } from "next/router";

// components
import { CycleIssuesGanttChartView } from "components/cycles";
import { IssueGanttChartView } from "components/issues/gantt-chart";
import { ModuleIssuesGanttChartView } from "components/modules";
import { ViewIssuesGanttChartView } from "components/views";

export const GanttChartView = () => {
const router = useRouter();
const { cycleId, moduleId, viewId } = router.query;

return (
<>
{cycleId ? (
<CycleIssuesGanttChartView />
) : moduleId ? (
<ModuleIssuesGanttChartView />
) : viewId ? (
<ViewIssuesGanttChartView />
) : (
<IssueGanttChartView />
)}
</>
);
};
1 change: 1 addition & 0 deletions apps/app/components/core/index.ts
@@ -1,5 +1,6 @@
export * from "./board-view";
export * from "./calendar-view";
export * from "./gantt-chart-view";
export * from "./list-view";
export * from "./sidebar";
export * from "./bulk-delete-issues-modal";
Expand Down
10 changes: 10 additions & 0 deletions apps/app/components/core/issues-view-filter.tsx
Expand Up @@ -17,6 +17,7 @@ import {
ListBulletIcon,
Squares2X2Icon,
CalendarDaysIcon,
ChartBarIcon,
} from "@heroicons/react/24/outline";
// helpers
import { replaceUnderscoreIfSnakeCase } from "helpers/string.helper";
Expand Down Expand Up @@ -82,6 +83,15 @@ export const IssuesFilterView: React.FC = () => {
>
<CalendarDaysIcon className="h-4 w-4 text-brand-secondary" />
</button>
<button
type="button"
className={`grid h-7 w-7 place-items-center rounded p-1 outline-none duration-300 hover:bg-brand-surface-2 ${
issueView === "gantt_chart" ? "bg-brand-surface-2" : ""
}`}
onClick={() => setIssueView("gantt_chart")}
>
<ChartBarIcon className="h-4 w-4 text-brand-secondary" />
</button>
</div>
<SelectFilters
filters={filters}
Expand Down
10 changes: 7 additions & 3 deletions apps/app/components/core/issues-view.tsx
Expand Up @@ -18,10 +18,11 @@ import { useProjectMyMembership } from "contexts/project-member.context";
import useToast from "hooks/use-toast";
import useIssuesView from "hooks/use-issues-view";
// components
import { AllLists, AllBoards, FilterList, CalendarView } from "components/core";
import { AllLists, AllBoards, FilterList, CalendarView, GanttChartView } from "components/core";
import { CreateUpdateIssueModal, DeleteIssueModal } from "components/issues";
import { CreateUpdateViewModal } from "components/views";
import { TransferIssues, TransferIssuesModal } from "components/cycles";
import { CycleIssuesGanttChartView, TransferIssues, TransferIssuesModal } from "components/cycles";
import { IssueGanttChartView } from "components/issues/gantt-chart";
// ui
import { EmptySpace, EmptySpaceItem, EmptyState, PrimaryButton, Spinner } from "components/ui";
// icons
Expand All @@ -47,6 +48,7 @@ import {
PROJECT_ISSUES_LIST_WITH_PARAMS,
STATES_LIST,
} from "constants/fetch-keys";
import { ModuleIssuesGanttChartView } from "components/modules";

type Props = {
type?: "issue" | "cycle" | "module";
Expand Down Expand Up @@ -528,14 +530,16 @@ export const IssuesView: React.FC<Props> = ({
isCompleted={isCompleted}
userAuth={memberRole}
/>
) : (
) : issueView === "calendar" ? (
<CalendarView
handleEditIssue={handleEditIssue}
handleDeleteIssue={handleDeleteIssue}
addIssueToDate={addIssueToDate}
isCompleted={isCompleted}
userAuth={memberRole}
/>
) : (
issueView === "gantt_chart" && <GanttChartView />
)}
</>
) : type === "issue" ? (
Expand Down
67 changes: 67 additions & 0 deletions apps/app/components/cycles/cycles-list-gantt-chart.tsx
@@ -0,0 +1,67 @@
import { FC } from "react";

// components
import { GanttChartRoot } from "components/gantt-chart";
// types
import { ICycle } from "types";

type Props = {
cycles: ICycle[];
};

export const CyclesListGanttChartView: FC<Props> = ({ cycles }) => {
// rendering issues on gantt sidebar
const GanttSidebarBlockView = ({ data }: any) => (
<div className="relative flex w-full h-full items-center p-1 overflow-hidden gap-1">
<div
className="rounded-sm flex-shrink-0 w-[10px] h-[10px] flex justify-center items-center"
style={{ backgroundColor: "#858e96" }}
/>
<div className="text-brand-base text-sm">{data?.name}</div>
</div>
);

// rendering issues on gantt card
const GanttBlockView = ({ data }: { data: ICycle }) => (
<div className="relative flex w-full h-full overflow-hidden">
<div className="flex-shrink-0 w-[4px] h-auto" style={{ backgroundColor: "#858e96" }} />
<div className="inline-block text-brand-base text-sm whitespace-nowrap py-[4px] px-1.5">
{data?.name}
</div>
</div>
);

// handle gantt issue start date and target date
const handleUpdateDates = async (data: any) => {
const payload = {
id: data?.id,
start_date: data?.start_date,
target_date: data?.target_date,
};
};

const blockFormat = (blocks: any) =>
blocks && blocks.length > 0
? blocks.map((_block: any) => {
if (_block?.start_date && _block.target_date) console.log("_block", _block);
return {
start_date: new Date(_block.created_at),
target_date: new Date(_block.updated_at),
data: _block,
};
})
: [];

return (
<div className="w-full h-full overflow-y-auto">
<GanttChartRoot
title={"Cycles"}
loaderTitle="Cycles"
blocks={cycles ? blockFormat(cycles) : null}
blockUpdateHandler={handleUpdateDates}
sidebarBlockRender={(data: any) => <GanttSidebarBlockView data={data} />}
blockRender={(data: any) => <GanttBlockView data={data} />}
/>
</div>
);
};

1 comment on commit e1e9a5e

@vercel
Copy link

@vercel vercel bot commented on e1e9a5e May 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

plane-dev – ./apps/app

plane-dev-plane.vercel.app
plane-dev-git-develop-plane.vercel.app
plane-dev.vercel.app

Please sign in to comment.