From 8d534dae7e4b739e60722a2727c26de14ef15185 Mon Sep 17 00:00:00 2001 From: Matthias Van Parijs Date: Thu, 26 Sep 2024 22:25:15 +0200 Subject: [PATCH] chore: Refactored React components folder structure --- .../src/components/{editor => }/Editor.tsx | 0 .../dashboard/src/components/JobStatsTile.tsx | 42 +++++ .../dashboard/src/components/JobsStats.tsx | 51 +------ .../src/components/{player => }/Player.tsx | 0 packages/dashboard/src/components/Sidebar.tsx | 57 ++----- .../src/components/SidebarNavLink.tsx | 25 +++ .../dashboard/src/components/SidebarTitle.tsx | 15 ++ .../src/components/StorageExplorer.tsx | 144 +++--------------- .../src/components/StoragePathBreadcrumbs.tsx | 62 ++++++++ .../dashboard/src/components/StorageRow.tsx | 44 ++++++ packages/dashboard/src/pages/JobPage.tsx | 2 +- packages/dashboard/src/pages/PlayerPage.tsx | 5 +- 12 files changed, 233 insertions(+), 214 deletions(-) rename packages/dashboard/src/components/{editor => }/Editor.tsx (100%) create mode 100644 packages/dashboard/src/components/JobStatsTile.tsx rename packages/dashboard/src/components/{player => }/Player.tsx (100%) create mode 100644 packages/dashboard/src/components/SidebarNavLink.tsx create mode 100644 packages/dashboard/src/components/SidebarTitle.tsx create mode 100644 packages/dashboard/src/components/StoragePathBreadcrumbs.tsx create mode 100644 packages/dashboard/src/components/StorageRow.tsx diff --git a/packages/dashboard/src/components/editor/Editor.tsx b/packages/dashboard/src/components/Editor.tsx similarity index 100% rename from packages/dashboard/src/components/editor/Editor.tsx rename to packages/dashboard/src/components/Editor.tsx diff --git a/packages/dashboard/src/components/JobStatsTile.tsx b/packages/dashboard/src/components/JobStatsTile.tsx new file mode 100644 index 00000000..1ab3ba19 --- /dev/null +++ b/packages/dashboard/src/components/JobStatsTile.tsx @@ -0,0 +1,42 @@ +import { cn } from "@/lib/utils"; +import { + Tooltip, + TooltipContent, + TooltipTrigger, +} from "@/components/ui/tooltip"; + +type JobStatsTileProps = { + value: number; + className: string; + onClick: () => void; + active: boolean; + tooltip: string; +}; + +export function JobStatsTile({ + value, + className, + onClick, + active, + tooltip, +}: JobStatsTileProps) { + return ( + + +
  • + {value} +
    +
  • +
    + +

    {tooltip}

    +
    +
    + ); +} diff --git a/packages/dashboard/src/components/JobsStats.tsx b/packages/dashboard/src/components/JobsStats.tsx index 6a29ec47..1fe5f594 100644 --- a/packages/dashboard/src/components/JobsStats.tsx +++ b/packages/dashboard/src/components/JobsStats.tsx @@ -1,10 +1,5 @@ -import { cn } from "@/lib/utils"; -import { - Tooltip, - TooltipContent, - TooltipProvider, - TooltipTrigger, -} from "@/components/ui/tooltip"; +import { TooltipProvider } from "@/components/ui/tooltip"; +import { JobStatsTile } from "./JobStatsTile"; import type { JobDto } from "@/tsr"; import type { JobsFilterData } from "./types"; @@ -45,28 +40,28 @@ export function JobsStats({ jobs, filter, onChange }: JobsStatsProps) { return (
    - filterJobState("completed")} active={filter.state === "completed"} tooltip="Completed" /> - filterJobState("failed")} active={filter.state === "failed"} tooltip="Failed" /> - filterJobState("running")} active={filter.state === "running"} tooltip="Running" /> - filterJobState("waiting")} @@ -77,37 +72,3 @@ export function JobsStats({ jobs, filter, onChange }: JobsStatsProps) { ); } - -function Tile({ - value, - className, - onClick, - active, - tooltip, -}: { - value: number; - className: string; - onClick: () => void; - active: boolean; - tooltip: string; -}) { - return ( - - -
  • - {value} -
    -
  • -
    - -

    {tooltip}

    -
    -
    - ); -} diff --git a/packages/dashboard/src/components/player/Player.tsx b/packages/dashboard/src/components/Player.tsx similarity index 100% rename from packages/dashboard/src/components/player/Player.tsx rename to packages/dashboard/src/components/Player.tsx diff --git a/packages/dashboard/src/components/Sidebar.tsx b/packages/dashboard/src/components/Sidebar.tsx index 3fc2c066..5d68d800 100644 --- a/packages/dashboard/src/components/Sidebar.tsx +++ b/packages/dashboard/src/components/Sidebar.tsx @@ -1,11 +1,11 @@ import logo from "../assets/logo.svg"; -import { cn } from "@/lib/utils"; -import { Link, useLocation } from "react-router-dom"; +import { SidebarTitle } from "./SidebarTitle"; +import { Link } from "react-router-dom"; import Rows3 from "lucide-react/icons/rows-3"; import Sailboat from "lucide-react/icons/sailboat"; import Play from "lucide-react/icons/play"; import Box from "lucide-react/icons/box"; -import type { ReactNode } from "react"; +import { SidebarNavLink } from "./SidebarNavLink"; export function Sidebar() { return ( @@ -17,60 +17,29 @@ export function Sidebar() {
    - Manage + Manage - Tools + Tools
    ); } - -function NavLink({ children, to }: { children: ReactNode; to: string }) { - const { pathname } = useLocation(); - - return ( - - {children} - - ); -} - -function Title({ - children, - className, -}: { - children: ReactNode; - className?: string; -}) { - return ( -
    - {children} -
    - ); -} diff --git a/packages/dashboard/src/components/SidebarNavLink.tsx b/packages/dashboard/src/components/SidebarNavLink.tsx new file mode 100644 index 00000000..b391815e --- /dev/null +++ b/packages/dashboard/src/components/SidebarNavLink.tsx @@ -0,0 +1,25 @@ +import { Link, useLocation } from "react-router-dom"; +import { cn } from "@/lib/utils"; +import type { ReactNode } from "react"; + +type SidebarNavLinkProps = { + children: ReactNode; + to: string; +}; + +export function SidebarNavLink({ children, to }: SidebarNavLinkProps) { + const { pathname } = useLocation(); + + return ( + + {children} + + ); +} diff --git a/packages/dashboard/src/components/SidebarTitle.tsx b/packages/dashboard/src/components/SidebarTitle.tsx new file mode 100644 index 00000000..3d5017fa --- /dev/null +++ b/packages/dashboard/src/components/SidebarTitle.tsx @@ -0,0 +1,15 @@ +import { cn } from "@/lib/utils"; +import type { ReactNode } from "react"; + +type SidebarTitleProps = { + children: ReactNode; + className?: string; +}; + +export function SidebarTitle({ children, className }: SidebarTitleProps) { + return ( +
    + {children} +
    + ); +} diff --git a/packages/dashboard/src/components/StorageExplorer.tsx b/packages/dashboard/src/components/StorageExplorer.tsx index 856fd222..c9f5702d 100644 --- a/packages/dashboard/src/components/StorageExplorer.tsx +++ b/packages/dashboard/src/components/StorageExplorer.tsx @@ -1,23 +1,14 @@ -import { Link } from "react-router-dom"; -import { - Breadcrumb, - BreadcrumbItem, - BreadcrumbLink, - BreadcrumbList, - BreadcrumbPage, - BreadcrumbSeparator, -} from "@/components/ui/breadcrumb"; import { Table, TableBody, - TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table"; -import { Fragment, UIEventHandler, useRef } from "react"; -import Folder from "lucide-react/icons/folder"; +import { StoragePathBreadcrumbs } from "./StoragePathBreadcrumbs"; +import { StorageRow } from "./StorageRow"; import type { FolderDto } from "@/tsr"; +import type { UIEventHandler } from "react"; type StorageExplorerProps = { path: string; @@ -30,16 +21,10 @@ export function StorageExplorer({ contents, onNext, }: StorageExplorerProps) { - const ref = useRef(null); - - const onScroll: UIEventHandler = () => { - if (!ref.current) { - return; - } - - const totalHeight = ref.current.scrollHeight - ref.current.offsetHeight; - - if (totalHeight - ref.current.scrollTop < 10) { + const onScroll: UIEventHandler = (event) => { + const target = event.target as HTMLDivElement; + const totalHeight = target.scrollHeight - target.offsetHeight; + if (totalHeight - target.scrollTop < 10) { onNext(); } }; @@ -47,107 +32,24 @@ export function StorageExplorer({ return (
    - +
    -
    -
    - - - - - Name - Size - - - - {contents.map((content) => { - return ; - })} - -
    -
    +
    + + + + + Name + Size + + + + {contents.map((content) => { + return ; + })} + +
    ); } - -function PathBreadcrumbs({ path }: { path: string }) { - const splits = path.split("/"); - splits.pop(); - - let prevPath = ""; - const chunks = splits.map((part) => { - const result = { - name: part, - path: prevPath + part + "/", - }; - prevPath += part + "/"; - return result; - }); - - const lastChunk = chunks.pop(); - - return ( - - - {chunks.map((chunk) => { - return ( - - - - {chunk.name} - - - - - ); - })} - {lastChunk ? ( - - {lastChunk.name} - - ) : null} - - - ); -} - -function Row({ content }: { content: FolderDto["contents"][0] }) { - const chunks = content.path.split("/"); - - if (content.type === "folder") { - const name = chunks[chunks.length - 2]; - return ( - - - - - - - {name} - - - - - ); - } - - if (content.type === "file") { - const name = chunks[chunks.length - 1]; - return ( - - - {name} - {content.size} bytes - - ); - } - return null; -} diff --git a/packages/dashboard/src/components/StoragePathBreadcrumbs.tsx b/packages/dashboard/src/components/StoragePathBreadcrumbs.tsx new file mode 100644 index 00000000..bfef63b6 --- /dev/null +++ b/packages/dashboard/src/components/StoragePathBreadcrumbs.tsx @@ -0,0 +1,62 @@ +import { + Breadcrumb, + BreadcrumbItem, + BreadcrumbLink, + BreadcrumbList, + BreadcrumbPage, + BreadcrumbSeparator, +} from "@/components/ui/breadcrumb"; +import { Fragment } from "react"; +import { Link } from "react-router-dom"; + +type StoragePathBreadcrumbsProps = { + path: string; +}; + +export function StoragePathBreadcrumbs({ path }: StoragePathBreadcrumbsProps) { + const { paths, target } = parsePathInPaths(path); + + return ( + + + {paths.map(({ path, name }) => { + return ( + + + + {name} + + + + + ); + })} + {target ? ( + + {target.name} + + ) : null} + + + ); +} + +function parsePathInPaths(path: string) { + let prevPath = ""; + + const paths = path.split("/").map((part) => { + const result = { + name: part, + path: prevPath + part + "/", + }; + prevPath += part + "/"; + return result; + }); + + paths.pop(); + + return { + paths, + target: paths.pop(), + }; +} diff --git a/packages/dashboard/src/components/StorageRow.tsx b/packages/dashboard/src/components/StorageRow.tsx new file mode 100644 index 00000000..42dd6320 --- /dev/null +++ b/packages/dashboard/src/components/StorageRow.tsx @@ -0,0 +1,44 @@ +import { Link } from "react-router-dom"; +import { TableCell, TableRow } from "@/components/ui/table"; +import Folder from "lucide-react/icons/folder"; +import type { FolderDto } from "@/tsr"; + +type StorageRowProps = { + content: FolderDto["contents"][0]; +}; + +export function StorageRow({ content }: StorageRowProps) { + const chunks = content.path.split("/"); + + if (content.type === "folder") { + const name = chunks[chunks.length - 2]; + return ( + + + + + + + {name} + + + + + ); + } + + if (content.type === "file") { + const name = chunks[chunks.length - 1]; + return ( + + + {name} + {content.size} bytes + + ); + } + return null; +} diff --git a/packages/dashboard/src/pages/JobPage.tsx b/packages/dashboard/src/pages/JobPage.tsx index 3a9d61ab..4ac21ff5 100644 --- a/packages/dashboard/src/pages/JobPage.tsx +++ b/packages/dashboard/src/pages/JobPage.tsx @@ -25,7 +25,7 @@ export function JobPage() { return ( <> -
    +
    diff --git a/packages/dashboard/src/pages/PlayerPage.tsx b/packages/dashboard/src/pages/PlayerPage.tsx index 8b233fa4..28aee63f 100644 --- a/packages/dashboard/src/pages/PlayerPage.tsx +++ b/packages/dashboard/src/pages/PlayerPage.tsx @@ -1,9 +1,8 @@ import { useEffect, useState } from "react"; import { Input } from "@/components/ui/input"; -import { Label } from "@/components/ui/label"; import { Alert } from "@/components/ui/alert"; -import { Editor } from "@/components/editor/Editor"; -import { Player } from "@/components/player/Player"; +import { Editor } from "@/components/Editor"; +import { Player } from "@/components/Player"; import { Loader } from "@/components/Loader"; export function PlayerPage() {