diff --git a/pkgs/ui/src/app/machines/page.tsx b/pkgs/ui/src/app/machines/page.tsx index 3348142..6440a95 100644 --- a/pkgs/ui/src/app/machines/page.tsx +++ b/pkgs/ui/src/app/machines/page.tsx @@ -1,16 +1,12 @@ "use client"; -import { tableData } from "@/data/nodeDataStatic"; import { StrictMode } from "react"; import { NodeTable } from "@/components/table"; -import { useMachines } from "@/components/hooks/useMachines"; export default function Page() { - //const { data, isLoading } = useMachines(); - //console.log({ data, isLoading }); return ( - + ); } diff --git a/pkgs/ui/src/components/table/enhancedTableToolbar.tsx b/pkgs/ui/src/components/table/enhancedTableToolbar.tsx index c68562f..2210f8f 100644 --- a/pkgs/ui/src/components/table/enhancedTableToolbar.tsx +++ b/pkgs/ui/src/components/table/enhancedTableToolbar.tsx @@ -2,17 +2,17 @@ import React, { useMemo } from "react"; import Box from "@mui/material/Box"; -import Toolbar from "@mui/material/Toolbar"; import Grid2 from "@mui/material/Unstable_Grid2"; import useMediaQuery from "@mui/material/useMediaQuery"; import { useTheme } from "@mui/material"; -import { NodeStatus, TableData } from "@/data/nodeData"; import { PieCards } from "./pieCards"; import { PieData, NodePieChart } from "./nodePieChart"; +import { Machine } from "@/api/model/machine"; +import { Status } from "@/api/model"; interface EnhancedTableToolbarProps { - tableData: TableData[]; + tableData: readonly Machine[]; } export function EnhancedTableToolbar( @@ -24,13 +24,13 @@ export function EnhancedTableToolbar( const pieData: PieData[] = useMemo(() => { const online = tableData.filter( - (row) => row.status === NodeStatus.Online, + (row) => row.status === Status.online, ).length; const offline = tableData.filter( - (row) => row.status === NodeStatus.Offline, + (row) => row.status === Status.offline, ).length; const pending = tableData.filter( - (row) => row.status === NodeStatus.Pending, + (row) => row.status === Status.unknown, ).length; return [ diff --git a/pkgs/ui/src/components/table/nodeRow.tsx b/pkgs/ui/src/components/table/nodeRow.tsx index 06bf633..ef1ae43 100644 --- a/pkgs/ui/src/components/table/nodeRow.tsx +++ b/pkgs/ui/src/components/table/nodeRow.tsx @@ -10,15 +10,13 @@ import CircleIcon from "@mui/icons-material/Circle"; import Stack from "@mui/material/Stack/Stack"; import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown"; import KeyboardArrowUpIcon from "@mui/icons-material/KeyboardArrowUp"; - import Grid2 from "@mui/material/Unstable_Grid2"; // Grid version 2 -import { Collapse, useMediaQuery, useTheme } from "@mui/material"; +import { Collapse } from "@mui/material"; +import { Machine, Status } from "@/api/model"; -import { NodeStatus, NodeStatusKeys, TableData } from "@/data/nodeData"; - -function renderStatus(status: NodeStatusKeys) { +function renderStatus(status: Status) { switch (status) { - case NodeStatus.Online: + case Status.online: return ( @@ -28,7 +26,7 @@ function renderStatus(status: NodeStatusKeys) { ); - case NodeStatus.Offline: + case Status.offline: return ( @@ -37,7 +35,7 @@ function renderStatus(status: NodeStatusKeys) { ); - case NodeStatus.Pending: + case Status.unknown: return ( @@ -49,16 +47,12 @@ function renderStatus(status: NodeStatusKeys) { } } export function NodeRow(props: { - row: TableData; + row: Machine; selected: string | undefined; setSelected: (a: string | undefined) => void; }) { - const theme = useTheme(); - const is_phone = useMediaQuery(theme.breakpoints.down("md")); - const { row, selected, setSelected } = props; const [open, setOpen] = React.useState(false); - //const labelId = `enhanced-table-checkbox-${index}`; // Speed optimization. We compare string pointers here instead of the string content. const isSelected = selected == row.name; @@ -109,15 +103,6 @@ export function NodeRow(props: { > {renderStatus(row.status)} - handleClick(event, row.name)} - > - - {String(row.last_seen).padStart(3, "0")}{" "} - {is_phone ? "days" : "days ago"} - - {/* Row Expansion */} diff --git a/pkgs/ui/src/components/table/nodeTable.tsx b/pkgs/ui/src/components/table/nodeTable.tsx index ffd6f24..0230e56 100644 --- a/pkgs/ui/src/components/table/nodeTable.tsx +++ b/pkgs/ui/src/components/table/nodeTable.tsx @@ -1,28 +1,22 @@ "use client"; -import { useState, ChangeEvent, SetStateAction, Dispatch } from "react"; +import { useState, ChangeEvent, useMemo } from "react"; import Box from "@mui/material/Box"; import TablePagination from "@mui/material/TablePagination"; import Paper from "@mui/material/Paper"; -import IconButton from "@mui/material/IconButton"; -import Tooltip from "@mui/material/Tooltip"; -import SearchIcon from "@mui/icons-material/Search"; -import { useTheme } from "@mui/material"; +import { CircularProgress, Grid, useTheme } from "@mui/material"; import useMediaQuery from "@mui/material/useMediaQuery"; -import { TableData } from "@/data/nodeData"; import { EnhancedTableToolbar } from "./enhancedTableToolbar"; import { StickySpeedDial } from "./stickySpeedDial"; import { NodeTableContainer } from "./nodeTableContainer"; import { SearchBar } from "./searchBar"; import Grid2 from "@mui/material/Unstable_Grid2/Grid2"; +import { useMachines } from "../hooks/useMachines"; +import { Machine } from "@/api/model/machine"; -export interface NodeTableProps { - tableData: TableData[]; -} - -export function NodeTable(props: NodeTableProps) { - let { tableData } = props; +export function NodeTable() { + const machines = useMachines(); const theme = useTheme(); const is_xs = useMediaQuery(theme.breakpoints.only("xs")); @@ -30,7 +24,15 @@ export function NodeTable(props: NodeTableProps) { const [selected, setSelected] = useState(undefined); const [page, setPage] = useState(0); const [rowsPerPage, setRowsPerPage] = useState(5); - const [filteredList, setFilteredList] = useState(tableData); + const [filteredList, setFilteredList] = useState([]); + + const tableData = useMemo(() => { + const tableData = machines.data.map((machine) => { + return { name: machine.name, status: machine.status }; + }); + setFilteredList(tableData); + return tableData; + }, [machines.data]); const handleChangePage = (event: unknown, newPage: number) => { setPage(newPage); @@ -41,38 +43,53 @@ export function NodeTable(props: NodeTableProps) { setPage(0); }; - return ( - - - - - - - - - - {/* TODO: This creates the error Warning: Prop `id` did not match. Server: ":RspmmcqH1:" Client: ":R3j6qpj9H1:" */} - - - - ); + if (machines.isLoading) { + return ( + + + + ); + } else { + return ( + + + + + + + + + + + + {/* TODO: This creates the error Warning: Prop `id` did not match. Server: ":RspmmcqH1:" Client: ":R3j6qpj9H1:" */} + + + + ); + } } diff --git a/pkgs/ui/src/components/table/nodeTableContainer.tsx b/pkgs/ui/src/components/table/nodeTableContainer.tsx index 084d2a0..59bc2b6 100644 --- a/pkgs/ui/src/components/table/nodeTableContainer.tsx +++ b/pkgs/ui/src/components/table/nodeTableContainer.tsx @@ -12,13 +12,11 @@ import TableSortLabel from "@mui/material/TableSortLabel"; import { visuallyHidden } from "@mui/utils"; import { NodeRow } from "./nodeRow"; -import { TableData } from "@/data/nodeData"; - -import { useMediaQuery, useTheme } from "@mui/material"; +import { Machine } from "@/api/model/machine"; interface HeadCell { disablePadding: boolean; - id: keyof TableData; + id: keyof Machine; label: string; alignRight: boolean; } @@ -28,7 +26,7 @@ const headCells: readonly HeadCell[] = [ id: "name", alignRight: false, disablePadding: false, - label: "DISPLAY NAME & ID", + label: "DOMAIN NAME", }, { id: "status", @@ -36,12 +34,6 @@ const headCells: readonly HeadCell[] = [ disablePadding: false, label: "STATUS", }, - { - id: "last_seen", - alignRight: false, - disablePadding: false, - label: "LAST SEEN", - }, ]; function descendingComparator(a: T, b: T, orderBy: keyof T) { @@ -90,7 +82,7 @@ function stableSort( interface EnhancedTableProps { onRequestSort: ( event: React.MouseEvent, - property: keyof TableData, + property: keyof Machine, ) => void; order: NodeOrder; orderBy: string; @@ -100,7 +92,7 @@ interface EnhancedTableProps { function EnhancedTableHead(props: EnhancedTableProps) { const { order, orderBy, onRequestSort } = props; const createSortHandler = - (property: keyof TableData) => (event: React.MouseEvent) => { + (property: keyof Machine) => (event: React.MouseEvent) => { onRequestSort(event, property); }; @@ -135,7 +127,7 @@ function EnhancedTableHead(props: EnhancedTableProps) { } interface NodeTableContainerProps { - tableData: readonly TableData[]; + tableData: readonly Machine[]; page: number; rowsPerPage: number; dense: boolean; @@ -146,10 +138,7 @@ interface NodeTableContainerProps { export function NodeTableContainer(props: NodeTableContainerProps) { const { tableData, page, rowsPerPage, dense, selected, setSelected } = props; const [order, setOrder] = React.useState("asc"); - const [orderBy, setOrderBy] = React.useState("status"); - - const theme = useTheme(); - const is_phone = useMediaQuery(theme.breakpoints.down("sm")); + const [orderBy, setOrderBy] = React.useState("status"); // Avoid a layout jump when reaching the last page with empty rows. const emptyRows = @@ -157,7 +146,7 @@ export function NodeTableContainer(props: NodeTableContainerProps) { const handleRequestSort = ( event: React.MouseEvent, - property: keyof TableData, + property: keyof Machine, ) => { const isAsc = orderBy === property && order === "asc"; setOrder(isAsc ? "desc" : "asc"); @@ -185,7 +174,7 @@ export function NodeTableContainer(props: NodeTableContainerProps) { {visibleRows.map((row, index) => { return ( >; + tableData: readonly Machine[]; + setFilteredList: Dispatch>; } export function SearchBar(props: SearchBarProps) { @@ -52,7 +33,7 @@ export function SearchBar(props: SearchBarProps) { useEffect(() => { if (debouncedSearch) { - const filtered: TableData[] = tableData.filter((row) => { + const filtered: Machine[] = tableData.filter((row) => { return row.name.toLowerCase().includes(debouncedSearch.toLowerCase()); }); setFilteredList(filtered);