178 lines
No EOL
4.9 KiB
TypeScript
178 lines
No EOL
4.9 KiB
TypeScript
import { Box, Chip, Grid2, IconButton, Theme, Tooltip, Typography } from "@mui/material";
|
|
import { LibraryAdd as CreateGroupIcon } from "@mui/icons-material"
|
|
import { makeStyles } from "@mui/styles";
|
|
import ResponsiveTable, { Column } from "common/ResponsiveTable";
|
|
import SmartBreadcrumb from "common/SmartBreadcrumb";
|
|
import { useMobile } from "hooks";
|
|
import { appendToUrl } from "navigation/Router";
|
|
import { pond } from "protobuf-ts/pond";
|
|
import { useGroupAPI } from "providers";
|
|
import { useEffect, useState } from "react";
|
|
import { useNavigate } from "react-router-dom";
|
|
import { or } from "utils/types";
|
|
import PageContainer from "./PageContainer";
|
|
import GroupSettings from "group/GroupSettings";
|
|
import { green } from "@mui/material/colors";
|
|
|
|
const useStyles = makeStyles((theme: Theme) => {
|
|
const isMobile = useMobile()
|
|
return ({
|
|
cellContainer: {
|
|
margin: theme.spacing(1),
|
|
marginLeft: theme.spacing(2),
|
|
display: "flex",
|
|
maxWidth: theme.spacing(isMobile ? 18 : 32),
|
|
},
|
|
bigCellContainer: {
|
|
margin: theme.spacing(1),
|
|
marginLeft: theme.spacing(2),
|
|
display: "flex",
|
|
width: "auto",
|
|
},
|
|
smallCellContainer: {
|
|
margin: theme.spacing(1),
|
|
marginLeft: theme.spacing(2),
|
|
display: "flex",
|
|
width: theme.spacing(1),
|
|
},
|
|
green: {
|
|
color: green["600"]
|
|
},
|
|
});
|
|
});
|
|
|
|
export default function GroupsPage() {
|
|
const groupAPI = useGroupAPI()
|
|
const navigate = useNavigate()
|
|
const [limit, setLimit] = useState(10)
|
|
const [page, setPage] = useState(0)
|
|
const [order, ] = useState<"asc" | "desc">("asc")
|
|
const [orderBy, ] = useState("")
|
|
const [search, setSearch] = useState("")
|
|
const [total, setTotal] = useState(0)
|
|
const [loading, setLoading] = useState(false)
|
|
|
|
const [groups, setGroups] = useState<pond.Group[]>([])
|
|
const [groupSettingsIsOpen, setGroupSettingsIsOpen] = useState(false)
|
|
|
|
const classes = useStyles()
|
|
|
|
const loadGroups = () => {
|
|
setLoading(true)
|
|
groupAPI.listGroups(limit, page*limit, order, orderBy, search).then(resp => {
|
|
setGroups(or(resp.data.groups, []))
|
|
setTotal(resp.data.total)
|
|
}).finally(() => {
|
|
setLoading(false)
|
|
})
|
|
}
|
|
|
|
useEffect(() => {
|
|
loadGroups()
|
|
}, [limit, page, order, orderBy, search])
|
|
|
|
const handleRowsPerPageChange = (event: any) => {
|
|
setLimit(event.target.value);
|
|
};
|
|
|
|
const columns = (): Column<pond.Group>[] => {
|
|
return [
|
|
{
|
|
title: "Size",
|
|
render: (group) => {
|
|
return (
|
|
<Box className={classes.smallCellContainer}>
|
|
{group.settings?.devices?.length ? group.settings.devices.length : 0}
|
|
</Box>
|
|
)
|
|
}
|
|
},
|
|
{
|
|
title: "Group Name",
|
|
render: (group) => {
|
|
return (
|
|
<Box className={classes.cellContainer}>
|
|
<Chip
|
|
variant="outlined"
|
|
label={group.settings?.name ? group.settings.name : "Group " + group.settings?.groupId}
|
|
/>
|
|
</Box>
|
|
)
|
|
}
|
|
},
|
|
{
|
|
title: "Description",
|
|
render: device => {
|
|
const description = device.settings?.description ?? ""
|
|
return (
|
|
<Box className={classes.bigCellContainer}>
|
|
<Tooltip title={device.settings?.description}>
|
|
<Typography variant="body2">
|
|
{description}
|
|
</Typography>
|
|
</Tooltip>
|
|
</Box>
|
|
)
|
|
}
|
|
},
|
|
]
|
|
}
|
|
|
|
const handleRowClick = (row: pond.Group) => {
|
|
if (row.settings?.groupId) navigate(appendToUrl(or(row.settings?.groupId, "")), { state: {group: row} })
|
|
}
|
|
|
|
const groupButton = () => {
|
|
return (
|
|
<Tooltip title="Create Group">
|
|
<IconButton
|
|
onClick={() => setGroupSettingsIsOpen(true)}
|
|
aria-label="Create Group"
|
|
size="small"
|
|
>
|
|
<CreateGroupIcon className={classes.green} />
|
|
</IconButton>
|
|
</Tooltip>
|
|
)
|
|
}
|
|
|
|
const title = () => {
|
|
return (
|
|
<Grid2 container alignItems={"center"} spacing={1}>
|
|
<Grid2>
|
|
<SmartBreadcrumb />
|
|
</Grid2>
|
|
<Grid2>
|
|
{groupButton()}
|
|
</Grid2>
|
|
</Grid2>
|
|
)
|
|
}
|
|
|
|
return (
|
|
<PageContainer >
|
|
<ResponsiveTable<pond.Group>
|
|
title={title()}
|
|
rows={groups}
|
|
columns={columns()}
|
|
total={total}
|
|
pageSize={limit}
|
|
page={page}
|
|
setPage={setPage}
|
|
handleRowsPerPageChange={handleRowsPerPageChange}
|
|
isLoading={loading}
|
|
setSearchText={setSearch}
|
|
onRowClick={handleRowClick}
|
|
/>
|
|
<GroupSettings
|
|
// initialGroup={selectedGroup}
|
|
// mode={groupSettingsMode}
|
|
mode={"add"}
|
|
isDialogOpen={groupSettingsIsOpen}
|
|
closeDialogCallback={() => setGroupSettingsIsOpen(false)}
|
|
refreshCallback={loadGroups}
|
|
canEdit={true}
|
|
/>
|
|
</PageContainer>
|
|
)
|
|
} |