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

Feat/dashboard page UI #40

Merged
merged 4 commits into from
Jul 2, 2024
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
1 change: 0 additions & 1 deletion dashboard/.eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ module.exports = {
{ allowConstantExport: true },
],
"@typescript-eslint/prefer-optional-chain": "warn",
"@typescript-eslint/consistent-type-imports": "warn",
"@typescript-eslint/explicit-function-return-type": "warn",
"@typescript-eslint/no-empty-function": "off",
"@typescript-eslint/no-inferrable-types": "warn",
Expand Down
3 changes: 2 additions & 1 deletion dashboard/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@
"@radix-ui/react-label": "^2.1.0",
"@radix-ui/react-navigation-menu": "^1.2.0",
"@radix-ui/react-separator": "^1.1.0",
"@radix-ui/react-slot": "^1.1.0",
"@tanstack/react-query": "^5.45.1",
"@vitejs/plugin-react": "^4.3.1",
"@tanstack/react-table": "^8.17.3",
"@vitejs/plugin-react": "^4.3.1",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"flat": "^6.0.1",
Expand Down
9 changes: 6 additions & 3 deletions dashboard/pnpm-lock.yaml

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

6 changes: 3 additions & 3 deletions dashboard/src/components/Dashboard/Dashboard.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import SideMenu from "../SideMenu/SideMenu";
import TreeTable from "../Table/TreeTable";
import TopBar from "../TopBar/TopBar";
import TreeMonitorListingPage from "../TreeMonitorListingPage/TreeMonitorListingPage";

const Dashboard = () : JSX.Element => {
return (
<div className="w-full h-full">
<div className="flex flex-row w-full justify-between">
<SideMenu />
<TopBar />
<div className="w-full px-16 pt-64 bg-lightGray">
<TreeTable />
<div className="w-full px-16 pt-24 bg-lightGray">
<TreeMonitorListingPage />
</div>
</div>
</div>
Expand Down
46 changes: 6 additions & 40 deletions dashboard/src/components/Table/TreeTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,18 @@ import { TableRow, TableCell } from "../ui/table";

import BaseTable from "./BaseTable";

interface ITreeTableBody {
export interface ITreeTableBody {
name: string;
branch: string;
commit: string;
buildStatus: string;
testStatus: string;
}

interface ITreeTable {
treeTableRows: ITreeTableBody[];
}

const treeTableColumnsLabelId = [
'treeTable.tree',
'treeTable.branch',
Expand All @@ -20,44 +24,6 @@ const treeTableColumnsLabelId = [
'treeTable.test'
];

const treeTableRows: ITreeTableBody[] = [
{
name: "stable-rc",
branch: "linux-5.15",
commit: "asidnasidn-oqiwejeoij-oaidnosdnk",
buildStatus: "150 completed",
testStatus: "80 completed"
},
{
name: "stable-rc",
branch: "linux-5.15",
commit: "asidnasidn-oqiwejeoij-oaidnosdnk",
buildStatus: "10 completed",
testStatus: "150 completed"
},
{
name: "stable-rc",
branch: "linux-5.15",
commit: "asidnasidn-oqiwejeoij-oaidnosdnk",
buildStatus: "10 completed",
testStatus: "150 completed"
},
{
name: "stable-rc",
branch: "linux-5.15",
commit: "asidnasidn-oqiwejeoij-oaidnosdnk",
buildStatus: "10 completed",
testStatus: "150 completed"
},
{
name: "stable-rc",
branch: "linux-5.15",
commit: "asidnasidn-oqiwejeoij-oaidnosdnk",
buildStatus: "10 completed",
testStatus: "150 completed"
}
];

const TreeTableRow = (row: ITreeTableBody): JSX.Element => {
return (
<TableRow>
Expand All @@ -70,7 +36,7 @@ const TreeTableRow = (row: ITreeTableBody): JSX.Element => {
);
};

const TreeTable = () : JSX.Element => {
const TreeTable = ({treeTableRows}: ITreeTable) : JSX.Element => {
const treeTableBody = useMemo(() => {
return (
treeTableRows.map((row: ITreeTableBody) => (
Expand Down
3 changes: 2 additions & 1 deletion dashboard/src/components/TopBar/TopBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ const TopBar = (): JSX.Element => {
</span>
<div className="flex w-2/3 px-6 items-center">
{/* placeholder for search */}
<Input className="w-2/3" type="text" placeholder="Search" />
{/* TODO: use i18n for the input placeholder */}
<Input className="w-2/3" type="text" placeholder="Search by tree, branch or tag" />
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
import { FormattedMessage } from "react-intl";

import { MdArrowBackIos, MdArrowForwardIos, MdExpandMore } from "react-icons/md";

import { useCallback, useState } from "react";

import TreeTable, { ITreeTableBody } from "../Table/TreeTable";
import { Button } from "../ui/button";


interface ITableInformation {
startIndex: number;
endIndex: number;
totalTrees: number;
itemsPerPage: number;
onClickForward: () => void;
onClickBack: () => void;
}

const TableInfo = ({
startIndex,
endIndex,
totalTrees,
itemsPerPage,
onClickForward,
onClickBack,
}: ITableInformation): JSX.Element => {
const buttonsClassName = "text-lightBlue font-bold"
const groupsClassName = "flex flex-row items-center gap-2"
return (
<div className="flex flex-row gap-4 text-sm">
<div className={groupsClassName}>
<FormattedMessage id="table.showing"/>
<span className="font-bold">{startIndex} - {endIndex}</span>
<FormattedMessage id="table.of"/>
<span className="font-bold">{totalTrees}</span>
<FormattedMessage id="table.tree"/>
</div>
<div className={groupsClassName}>
<FormattedMessage id="table.itemsPerPage"/>
<span className="font-bold">{itemsPerPage}</span>
<MdExpandMore className={buttonsClassName}/>
</div>
<div className="flex flex-row gap-2 items-center">
<Button variant="outline" onClick={onClickBack}>
<MdArrowBackIos className={buttonsClassName}/>
</Button>
<Button variant="outline" onClick={onClickForward}>
<MdArrowForwardIos className={buttonsClassName}/>
</Button>
</div>
</div>
);
};

const TreeMonitorListingPage = (): JSX.Element => {
const listItems = treeTableRows;
const itemsPerPage = 10;
const [startIndex, setStartIndex] = useState(0);
const [endIndex, setEndIndex] = useState(listItems.length+1 > itemsPerPage ? itemsPerPage : listItems.length+1);

const onClickGoForward = useCallback(() => {
setStartIndex(endIndex);
setEndIndex(endIndex+itemsPerPage >= listItems.length ? listItems.length : endIndex+itemsPerPage)
}, [endIndex, listItems]);

const onClickGoBack = useCallback(() => {
setStartIndex(startIndex-itemsPerPage);
setEndIndex(endIndex % itemsPerPage !== 0 ? endIndex - endIndex % itemsPerPage : endIndex - itemsPerPage);
}, [startIndex, endIndex]);

return (
<div className="flex flex-col gap-6">
<div className="flex flex-col items-end gap-4">
<Button variant="outline" className="rounded-full w-[128px] border-black">
<div className="flex flex-row gap-1 items-center">
<FormattedMessage id="global.filters" />
<MdExpandMore />
</div>
</Button>
<TableInfo
startIndex={startIndex+1}
endIndex={endIndex}
totalTrees={listItems.length}
itemsPerPage={itemsPerPage}
onClickBack={onClickGoBack}
onClickForward={onClickGoForward}
/>
</div>
<TreeTable treeTableRows={listItems.slice(startIndex, endIndex)}/>
<div className="flex flex-col items-end">
<TableInfo
startIndex={startIndex+1}
endIndex={endIndex}
totalTrees={listItems.length}
itemsPerPage={itemsPerPage}
onClickBack={onClickGoBack}
onClickForward={onClickGoForward}
/>
</div>
</div>
);
};

const treeTableRows: ITreeTableBody[] = [
{
name: "stable-rc1",
branch: "linux-5.15",
commit: "asidnasidn-oqiwejeoij-oaidnosdnk",
buildStatus: "150 completed",
testStatus: "80 completed"
},
{
name: "stable-rc2",
branch: "linux-5.15",
commit: "asidnasidn-oqiwejeoij-oaidnosdnk",
buildStatus: "10 completed",
testStatus: "150 completed"
},
{
name: "stable-rc3",
branch: "linux-5.15",
commit: "asidnasidn-oqiwejeoij-oaidnosdnk",
buildStatus: "10 completed",
testStatus: "150 completed"
},
{
name: "stable-rc4",
branch: "linux-5.15",
commit: "asidnasidn-oqiwejeoij-oaidnosdnk",
buildStatus: "10 completed",
testStatus: "150 completed"
},
{
name: "stable-rc5",
branch: "linux-5.15",
commit: "asidnasidn-oqiwejeoij-oaidnosdnk",
buildStatus: "10 completed",
testStatus: "150 completed"
},
{
name: "stable-rc6",
branch: "linux-5.15",
commit: "asidnasidn-oqiwejeoij-oaidnosdnk",
buildStatus: "150 completed",
testStatus: "80 completed"
},
{
name: "stable-rc7",
branch: "linux-5.15",
commit: "asidnasidn-oqiwejeoij-oaidnosdnk",
buildStatus: "10 completed",
testStatus: "150 completed"
},
{
name: "stable-rc8",
branch: "linux-5.15",
commit: "asidnasidn-oqiwejeoij-oaidnosdnk",
buildStatus: "10 completed",
testStatus: "150 completed"
},
{
name: "stable-rc9",
branch: "linux-5.15",
commit: "asidnasidn-oqiwejeoij-oaidnosdnk",
buildStatus: "10 completed",
testStatus: "150 completed"
},
{
name: "stable-rc10",
branch: "linux-5.15",
commit: "asidnasidn-oqiwejeoij-oaidnosdnk",
buildStatus: "10 completed",
testStatus: "150 completed"
},
{
name: "stable-rc11",
branch: "linux-5.15",
commit: "asidnasidn-oqiwejeoij-oaidnosdnk",
buildStatus: "10 completed",
testStatus: "150 completed"
},
{
name: "stable-rc12",
branch: "linux-5.15",
commit: "asidnasidn-oqiwejeoij-oaidnosdnk",
buildStatus: "10 completed",
testStatus: "150 completed"
}
];

export default TreeMonitorListingPage;
56 changes: 56 additions & 0 deletions dashboard/src/components/ui/button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import * as React from "react"
import { Slot } from "@radix-ui/react-slot"
import { cva, type VariantProps } from "class-variance-authority"

import { cn } from "../../lib/utils"

const buttonVariants = cva(
"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-white transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-slate-950 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 dark:ring-offset-slate-950 dark:focus-visible:ring-slate-300",
{
variants: {
variant: {
default: "bg-slate-900 text-slate-50 hover:bg-slate-900/90 dark:bg-slate-50 dark:text-slate-900 dark:hover:bg-slate-50/90",
destructive:
"bg-red-500 text-slate-50 hover:bg-red-500/90 dark:bg-red-900 dark:text-slate-50 dark:hover:bg-red-900/90",
outline:
"border border-slate-200 bg-white hover:bg-slate-100 hover:text-slate-900 dark:border-slate-800 dark:bg-slate-950 dark:hover:bg-slate-800 dark:hover:text-slate-50",
secondary:
"bg-slate-100 text-slate-900 hover:bg-slate-100/80 dark:bg-slate-800 dark:text-slate-50 dark:hover:bg-slate-800/80",
ghost: "hover:bg-slate-100 hover:text-slate-900 dark:hover:bg-slate-800 dark:hover:text-slate-50",
link: "text-slate-900 underline-offset-4 hover:underline dark:text-slate-50",
},
size: {
default: "h-10 px-4 py-2",
sm: "h-9 rounded-md px-3",
lg: "h-11 rounded-md px-8",
icon: "h-10 w-10",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
}
)

export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
asChild?: boolean
}

const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant, size, asChild = false, ...props }, ref) => {
const Comp = asChild ? Slot : "button"
return (
<Comp
className={cn(buttonVariants({ variant, size, className }))}
ref={ref}
{...props}
/>
)
}
)
Button.displayName = "Button"

export { Button, buttonVariants }
Loading
Loading