Skip to content

Commit

Permalink
Board layout re-arrangement (#324)
Browse files Browse the repository at this point in the history
* feat: Add @types/react-grid-layout dependency

* refactor: Simplify Board component props and update layout handling

* add board tool component and integrate with board layout

* remove unneccessary load

* add board canvas component and implement animation for reveal menu

---------

Co-authored-by: sokphaladam <[email protected]>
Co-authored-by: Visal .In <[email protected]>
  • Loading branch information
3 people authored Jan 31, 2025
1 parent ae8c677 commit d6896f4
Show file tree
Hide file tree
Showing 11 changed files with 884 additions and 7 deletions.
75 changes: 70 additions & 5 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
"@tiptap/core": "^2.3.0",
"@tiptap/react": "^2.3.0",
"@types/mdx": "^2.0.13",
"@types/react-grid-layout": "^1.3.5",
"@uiw/codemirror-extensions-langs": "^4.21.24",
"@uiw/codemirror-themes": "^4.21.21",
"@uiw/react-codemirror": "^4.21.21",
Expand Down Expand Up @@ -97,6 +98,7 @@
"oslo": "^1.1.3",
"react": "19.0.0",
"react-dom": "19.0.0",
"react-grid-layout": "^1.5.0",
"react-resizable-panels": "^2.1.7",
"sonner": "^1.4.41",
"sql-formatter": "^15.3.2",
Expand Down
32 changes: 32 additions & 0 deletions src/app/storybook/board/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
"use client";
import Board from "@/components/board";
import { BoardFilterProps } from "@/components/board/board-filter-dialog";
import { useState } from "react";
import ReactGridLayout from "react-grid-layout";

interface DashboardProps {
layout: ReactGridLayout.Layout[];
data: {
filters: BoardFilterProps[];
};
}

export default function StorybookBoardPage() {
const [value, setValue] = useState<DashboardProps>({
layout: [
{ x: 0, y: 0, w: 1, h: 1, i: "0" },
{ x: 1, y: 0, w: 1, h: 1, i: "1" },
{ x: 2, y: 0, w: 1, h: 1, i: "2" },
{ x: 3, y: 0, w: 1, h: 1, i: "3" },
],
data: { filters: [] },
});

console.log(value);

return (
<div className="relative h-full w-full flex-1">
<Board value={value} setValue={setValue} />
</div>
);
}
10 changes: 9 additions & 1 deletion src/app/storybook/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { SidebarMenuHeader, SidebarMenuItem } from "@/components/sidebar-menu";
import ThemeToggle from "@/components/theme-toggle";
import { Separator } from "@/components/ui/separator";
import { TooltipProvider } from "@/components/ui/tooltip";
import { Component, Layers2 } from "lucide-react";
import ThemeLayout from "../(theme)/theme_layout";

Expand Down Expand Up @@ -56,8 +57,15 @@ export default function StorybookRootLayout({
text="Chart"
href="/storybook/chart"
/>
<SidebarMenuItem
icon={Component}
text="Board"
href="/storybook/board"
/>
</div>
<div className="flex-1 overflow-y-auto p-4">
<TooltipProvider>{children}</TooltipProvider>
</div>
<div className="flex-1 overflow-y-auto p-4">{children}</div>
</div>
</ThemeLayout>
);
Expand Down
104 changes: 104 additions & 0 deletions src/components/board/board-canvas.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
"use client";
import { cn } from "@/lib/utils";
import { RectangleHorizontal, Square } from "lucide-react";
import { useCallback } from "react";
import RGL, { WidthProvider } from "react-grid-layout";
import { buttonVariants } from "../ui/button";
import "./board-style.css";

export interface BoardChartLayout {
x: number;
y: number;
w: number;
h: number;
i: number;
}

interface BoardProps {
layout: ReactGridLayout.Layout[];
onChange: (v: ReactGridLayout.Layout[]) => void;
editMode?: "ADD_CHART" | "REARRANGING_CHART" | null;
}

const ReactGridLayout = WidthProvider(RGL);

export function BoardCanvas(props: BoardProps) {
const sizes = [
{ w: 1, h: 1, name: "1", icon: <Square className="h-3 w-3" /> },
{
w: 2,
h: 1,
name: "2",
icon: <RectangleHorizontal className="h-4 w-4" />,
},
{ w: 2, h: 2, name: "3", icon: <Square className="h-4 w-4" /> },
{
w: 4,
h: 2,
name: "4",
icon: <RectangleHorizontal className="h-4 w-4" />,
},
];

const handleClickResize = useCallback(
(w: number, h: number, index: number) => {
const dummy = structuredClone(props.layout);
dummy[index].w = w;
dummy[index].h = h;
props.onChange(dummy);
},
[props]
);

const mapItem: JSX.Element[] = [...Array(props.layout.length)].map((_, i) => {
return (
<div
key={i}
className="group dark:bg-secondary relative flex items-center justify-center rounded-md bg-white shadow hover:bg-gray-50 dark:text-white"
data-grid={_}
>
{props.editMode === "REARRANGING_CHART" && (
<div className="absolute top-4 right-4 z-40 hidden gap-2 group-hover:flex">
{sizes.map((x, index) => {
return (
<button
className={cn(
buttonVariants({ variant: "secondary", size: "icon" }),
"cancelSelectorName h-6 w-6 p-0"
)}
onClick={() =>
handleClickResize(x.w as number, x.h as number, i)
}
onMouseDown={(e) => e.stopPropagation()}
onTouchStart={(e) => e.stopPropagation()}
key={index}
>
{x.icon}
</button>
);
})}
</div>
)}
<div>{i}</div>
</div>
);
});

return (
<div>
<ReactGridLayout
cols={4}
rowHeight={220}
draggableCancel=".cancelSelectorName"
className="layout overflow-x-hidden"
layout={props.layout}
onLayoutChange={props.onChange}
isDraggable={props.editMode === "REARRANGING_CHART"}
isResizable={props.editMode === "REARRANGING_CHART"}
compactType={"vertical"}
>
{mapItem}
</ReactGridLayout>
</div>
);
}
Loading

0 comments on commit d6896f4

Please sign in to comment.