added group tabs:
This commit is contained in:
parent
26f0b7081b
commit
bc8b0a3405
7 changed files with 380 additions and 41 deletions
|
|
@ -70,6 +70,7 @@ export default function SmartBreadcrumb(props: Props) {
|
|||
|
||||
const groupID = (): string => {
|
||||
const regexMatch = or(location.pathname.match(/\/groups\/([^/]+)/), [])
|
||||
// console.log(or(regexMatch[1], "0").toString())
|
||||
return or(regexMatch[1], "0").toString();
|
||||
};
|
||||
|
||||
|
|
@ -244,6 +245,7 @@ export default function SmartBreadcrumb(props: Props) {
|
|||
|
||||
const breadcrumbLinks = (): ReactNode[] => {
|
||||
const breadcrumbMap = getBreadcrumbMap();
|
||||
// console.log(breadcrumbMap)
|
||||
|
||||
let links: ReactNode[] = [];
|
||||
const pathnames = location.pathname.split("/").filter((x: any) => x);
|
||||
|
|
@ -266,12 +268,10 @@ export default function SmartBreadcrumb(props: Props) {
|
|||
if (result.length > 1) {
|
||||
if (result[result.length - 1] !== "components") {
|
||||
label = breadcrumbMap["/" + result[result.length - 1]];
|
||||
console.log(label)
|
||||
}
|
||||
}
|
||||
if (!label && result[result.length - 1] !== "components") {
|
||||
label = breadcrumbMap["/" + result[result.length - 2] + "/" + result[result.length - 1]];
|
||||
console.log(label)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Suspense } from "react";
|
||||
import { Suspense, useEffect, useState } from "react";
|
||||
import LoadingScreen from "../app/LoadingScreen";
|
||||
import { BrowserRouter, Navigate, Route, Routes } from "react-router-dom";
|
||||
import { Typography } from "@mui/material";
|
||||
|
|
@ -13,6 +13,9 @@ import Header from "app/Header";
|
|||
import Logout from "pages/Logout";
|
||||
import Devices from "pages/Devices";
|
||||
import DevicePage from "pages/Device";
|
||||
import { Groups } from "@mui/icons-material";
|
||||
import GroupsPage from "pages/Groups";
|
||||
import { Group } from "models";
|
||||
|
||||
interface Props {
|
||||
open: boolean,
|
||||
|
|
@ -21,11 +24,17 @@ interface Props {
|
|||
toggleTheme: () => void;
|
||||
}
|
||||
|
||||
export const appendToUrl = (appendage: number | string) => {
|
||||
const basePath = location.pathname.replace(/\/$/, "");
|
||||
return(`${basePath}/${appendage}`);
|
||||
};
|
||||
|
||||
export default function Router(props: Props) {
|
||||
|
||||
const {open, onOpen, onClose, toggleTheme } = props;
|
||||
const { isAuthenticated, loginWithRedirect, isLoading } = useAuth0();
|
||||
const isMobile = useMobile();
|
||||
const [groups, setGroups] = useState<Group[]>([]);
|
||||
|
||||
const RelativeRoutes = () => {
|
||||
console.log("relative route")
|
||||
|
|
@ -33,6 +42,7 @@ export default function Router(props: Props) {
|
|||
<Routes>
|
||||
<Route path="teams/*" element={<TeamsRoute/>} />
|
||||
<Route path="devices/*" element={<DevicesRoute/>} />
|
||||
<Route path="groups/*" element={<GroupsRoute/>} />
|
||||
</Routes>
|
||||
)
|
||||
}
|
||||
|
|
@ -59,17 +69,55 @@ export default function Router(props: Props) {
|
|||
|
||||
const DevicesRoute = () => {
|
||||
console.log("devices route")
|
||||
console.log(window.location.pathname)
|
||||
return (
|
||||
<div>
|
||||
<Routes>
|
||||
<Route
|
||||
key="Devices page route"
|
||||
path="" // "/settings/basic"
|
||||
element={<Devices />}
|
||||
element={<Devices groups={groups} setGroups={setGroups} key={"Devices page"} />}
|
||||
/>
|
||||
<Route
|
||||
path="/:deviceID" // "/settings/basic"
|
||||
element={<DevicePage />}
|
||||
/>
|
||||
<Route
|
||||
path="/:deviceID/*" // "/settings/basic"
|
||||
element={<RelativeRoutes />}
|
||||
/>
|
||||
</Routes>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
console.log(groups)
|
||||
}, [groups])
|
||||
|
||||
const GroupsRoute = () => {
|
||||
console.log("groups route")
|
||||
console.log(window.location.pathname)
|
||||
return (
|
||||
<div>
|
||||
<Routes>
|
||||
<Route
|
||||
path="/"
|
||||
element={<GroupsPage />}
|
||||
/>
|
||||
<Route
|
||||
key="Devices page route"
|
||||
path="/:groupID/devices/"
|
||||
element={<Devices groups={groups} setGroups={setGroups} key={"Devices page"}/>}
|
||||
/>
|
||||
<Route
|
||||
path="/:groupID/devices/:deviceID"
|
||||
element={<DevicePage />}
|
||||
/>
|
||||
<Route
|
||||
path="/:groupID/devices/:deviceID/*"
|
||||
element={<RelativeRoutes />}
|
||||
/>
|
||||
</Routes>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ const useStyles = makeStyles((theme: Theme) => {
|
|||
});
|
||||
|
||||
export default function DevicePage() {
|
||||
console.log("device")
|
||||
|
||||
const deviceAPI = useDeviceAPI()
|
||||
const snackbar = useSnackbar()
|
||||
|
|
@ -51,7 +52,6 @@ export default function DevicePage() {
|
|||
setPermissions(resp.data.permissions)
|
||||
let u = User.any(resp.data.user);
|
||||
setPreferences(u.preferences)
|
||||
console.log(u.preferences)
|
||||
}).catch(err => {
|
||||
setDevice(Device.create());
|
||||
// setComponents(new Map());
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { DeveloperBoard as ProvisionIcon, LibraryAdd as CreateGroupIcon } from "@mui/icons-material";
|
||||
import { Box, Chip, CircularProgress, IconButton, Tab, Tabs, Theme, Tooltip, Typography } from "@mui/material";
|
||||
import { Box, Chip, CircularProgress, IconButton, Tab, Tabs, Theme, Tooltip } from "@mui/material";
|
||||
import { blue, green } from "@mui/material/colors";
|
||||
import { makeStyles } from "@mui/styles";
|
||||
import ResponsiveTable, { Column } from "common/ResponsiveTable";
|
||||
|
|
@ -9,7 +9,7 @@ import { useDeviceAPI, useGroupAPI } from "providers";
|
|||
import { useEffect, useState } from "react";
|
||||
import PageContainer from "./PageContainer";
|
||||
import { useMobile } from "hooks";
|
||||
import { useLocation, useNavigate } from "react-router-dom";
|
||||
import { useLocation, useNavigate, useParams } from "react-router-dom";
|
||||
import { or } from "utils/types";
|
||||
import { getContextKeys, getContextTypes } from "pbHelpers/Context";
|
||||
import { getDeviceStateHelper } from "pbHelpers/DeviceState";
|
||||
|
|
@ -19,6 +19,22 @@ import SmartBreadcrumb from "common/SmartBreadcrumb";
|
|||
|
||||
const useStyles = makeStyles((theme: Theme) => {
|
||||
return ({
|
||||
buttonBox: {
|
||||
position: "absolute",
|
||||
zIndex: 1,
|
||||
right: theme.spacing(4),
|
||||
transform: "translateY(-50%)", // Move it up by half its height
|
||||
transition: "opacity 0.2s ease-in-out",
|
||||
opacity: 1,
|
||||
// top: 0,
|
||||
},
|
||||
fadeBox: {
|
||||
opacity: 0, // Fully transparent by default
|
||||
transition: "opacity 0.2s ease-in-out", // Smooth transition
|
||||
"&:hover": {
|
||||
opacity: 1, // Fully opaque on hover
|
||||
},
|
||||
},
|
||||
provisionIcon: {
|
||||
color: blue["700"]
|
||||
},
|
||||
|
|
@ -34,7 +50,13 @@ const useStyles = makeStyles((theme: Theme) => {
|
|||
});
|
||||
});
|
||||
|
||||
export default function Devices() {
|
||||
interface Props {
|
||||
groups: Group[];
|
||||
setGroups: React.Dispatch<React.SetStateAction<Group[]>>;
|
||||
}
|
||||
|
||||
export default function Devices(props: Props) {
|
||||
const { groups, setGroups } = props;
|
||||
const isMobile = useMobile();
|
||||
const classes = useStyles();
|
||||
const navigate = useNavigate();
|
||||
|
|
@ -52,13 +74,17 @@ export default function Devices() {
|
|||
const [isProvisionDialogOpen, setIsProvisionDialogOpen] = useState<boolean>(false);
|
||||
|
||||
const [groupsLoading, setGroupsLoading] = useState(false)
|
||||
const [groups, setGroups] = useState<Group[]>([])
|
||||
// const [groups, setGroups] = useState<Group[]>([]);
|
||||
const [groupLimit, ] = useState(10);
|
||||
const [groupPage, ] = useState(0);
|
||||
const [orderGroup, ] = useState<"asc" | "desc">("asc");
|
||||
const [orderGroupBy, ] = useState("name");
|
||||
const [searchGroup, ] = useState("");
|
||||
const [totalGroups, setTotalGroups] = useState(0);
|
||||
// const [totalGroups, setTotalGroups] = useState(0);
|
||||
|
||||
const updateGroups = (newGroups: Group[]) => {
|
||||
setGroups(newGroups); // Trigger UI update if needed
|
||||
};
|
||||
|
||||
const [selectedGroup, setSelectedGroup] = useState<Group | undefined>(undefined);
|
||||
const [groupSettingsMode, setGroupSettingsMode] = useState<
|
||||
|
|
@ -66,7 +92,8 @@ export default function Devices() {
|
|||
>(undefined);
|
||||
const [groupSettingsIsOpen, setGroupSettingsIsOpen] = useState<boolean>(false);
|
||||
|
||||
const [tab, setTab] = useState("all");
|
||||
const groupID = useParams<{ groupID: string }>()?.groupID ?? "all";
|
||||
const [tab, setTab] = useState(groupID==="all" ? groupID : groupID);
|
||||
|
||||
const openProvisionDialog = () => {
|
||||
setIsProvisionDialogOpen(true);
|
||||
|
|
@ -90,8 +117,26 @@ export default function Devices() {
|
|||
setGroupSettingsMode(undefined);
|
||||
setSelectedGroup(undefined);
|
||||
};
|
||||
|
||||
const getKeys = () => {
|
||||
if (tab !== "all") {
|
||||
let keys = getContextKeys()
|
||||
keys.splice(keys.length - 1, 0, tab);
|
||||
return keys
|
||||
}
|
||||
}
|
||||
|
||||
const getTypes = () => {
|
||||
if (tab !== "all") {
|
||||
let types = getContextTypes()
|
||||
types.splice(types.length - 1, 0, "group");
|
||||
return types
|
||||
}
|
||||
}
|
||||
|
||||
const loadGroups = () => {
|
||||
if (groupsLoading) return
|
||||
if (groups.length > 0) return
|
||||
setGroupsLoading(true)
|
||||
groupAPI.listGroups(
|
||||
groupLimit,
|
||||
|
|
@ -99,22 +144,19 @@ export default function Devices() {
|
|||
orderGroup,
|
||||
orderGroupBy,
|
||||
searchGroup,
|
||||
undefined
|
||||
).then(resp => {
|
||||
// console.log(resp.data)
|
||||
let newGroups: Group[] = []
|
||||
resp.data.groups.forEach((group: pond.Group) => {
|
||||
resp.data.groups?.forEach((group: pond.Group) => {
|
||||
newGroups.push(Group.create(group))
|
||||
})
|
||||
setGroups(newGroups)
|
||||
setTotalGroups(resp.data.total)
|
||||
updateGroups(newGroups)
|
||||
// setTotalGroups(resp.data.total)
|
||||
}).finally(() => {
|
||||
setGroupsLoading(false)
|
||||
})
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
console.log(groups)
|
||||
}, [groups])
|
||||
|
||||
const loadDevices = () => {
|
||||
setDevicesLoading(true)
|
||||
|
|
@ -130,8 +172,8 @@ export default function Devices() {
|
|||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
getContextKeys(),
|
||||
getContextTypes()
|
||||
getKeys(),
|
||||
getTypes()
|
||||
).then(resp => {
|
||||
setDevices(resp.data.devices)
|
||||
setTotal(resp.data.total)
|
||||
|
|
@ -142,13 +184,13 @@ export default function Devices() {
|
|||
|
||||
useEffect(() => {
|
||||
loadDevices()
|
||||
}, [limit, page, order, orderBy, search])
|
||||
}, [limit, page, order, orderBy, search, tab])
|
||||
|
||||
useEffect(() => {
|
||||
// console.log("groups loaded")
|
||||
loadGroups()
|
||||
}, [groupLimit, groupPage, orderGroup, orderGroupBy, searchGroup])
|
||||
|
||||
|
||||
const handleChange = (event: any) => {
|
||||
setLimit(event.target.value);
|
||||
};
|
||||
|
|
@ -208,8 +250,8 @@ export default function Devices() {
|
|||
<Box className={classes.cellContainer}>
|
||||
<Tooltip title={device.settings?.description}>
|
||||
<span>
|
||||
{description.length > 10
|
||||
? description.substring(0, 10) + "..."
|
||||
{description.length > 20
|
||||
? description.substring(0, 20) + "..."
|
||||
: description}
|
||||
</span>
|
||||
</Tooltip>
|
||||
|
|
@ -251,22 +293,104 @@ export default function Devices() {
|
|||
)
|
||||
}
|
||||
|
||||
// interface MyTabButtonProps {
|
||||
// onClick?: React.MouseEventHandler<HTMLButtonElement>;
|
||||
// disabled?: boolean;
|
||||
// }
|
||||
// const [leftButtonProps, setLeftButtonProps] = useState<MyTabButtonProps>({disabled: true})
|
||||
// const [rightButtonProps, setRightButtonProps] = useState<MyTabButtonProps>({disabled: true})
|
||||
// Use refs to store the props received during render
|
||||
// const leftButtonRef = useRef<MyTabButtonProps>({});
|
||||
// const rightButtonRef = useRef<MyTabButtonProps>({});
|
||||
// const [tabsHovered, setTabsHovered] = useState(false)
|
||||
// const location = useLocation()
|
||||
|
||||
// Update state using useEffect based on ref changes (the props received)
|
||||
// useEffect(() => {
|
||||
// if (leftButtonRef.current.disabled !== leftButtonProps.disabled) {
|
||||
// setLeftButtonProps({ disabled: leftButtonRef.current.disabled, onClick: leftButtonRef.current.onClick });
|
||||
// }
|
||||
// if (rightButtonRef.current.disabled !== rightButtonProps.disabled) {
|
||||
// setRightButtonProps({ disabled: rightButtonRef.current.disabled, onClick: rightButtonRef.current.onClick });
|
||||
// }
|
||||
// }, [leftButtonRef.current, rightButtonRef.current]);
|
||||
|
||||
// const handleScrollButtonProps = (props: TabScrollButtonProps) => {
|
||||
// if ((props.direction === "left" &&
|
||||
// leftButtonProps.disabled !== props.disabled)
|
||||
// ) {
|
||||
// let newProps: any = {}
|
||||
// newProps.disabled = props.disabled
|
||||
// newProps.onClick = props.onClick
|
||||
// setLeftButtonProps(newProps)
|
||||
// // leftButtonRef.current = newProps
|
||||
// }
|
||||
// if (props.direction === "right" &&
|
||||
// rightButtonProps.disabled !== props.disabled
|
||||
// ) {
|
||||
// let newProps: any = {}
|
||||
// newProps.disabled = props.disabled
|
||||
// newProps.onClick = props.onClick
|
||||
// setRightButtonProps(newProps)
|
||||
// // rightButtonRef.current = newProps
|
||||
// }
|
||||
// }
|
||||
|
||||
// useEffect(() => {
|
||||
// if (tab !== "all") {
|
||||
// const group = groups[typeof(tab) === "number" ? tab-1 : parseInt(tab)-1]
|
||||
// const url = location.pathname;
|
||||
// if (group) {
|
||||
// const updatedUrl = url.replace(
|
||||
// /(\/groups\/[^/]+)?\/devices$/, // Matches "/groups/some-id/devices" or just "/devices"
|
||||
// `/groups/${group.id()}/devices`
|
||||
// );
|
||||
// navigate(updatedUrl, { replace: true });
|
||||
// loadDevices()
|
||||
// }
|
||||
// } else {
|
||||
// const url = location.pathname;
|
||||
// const updatedUrl = url.replace(
|
||||
// /(\/groups\/[^/]+)?\/devices$/, // Matches "/groups/some-id/devices" or just "/devices"
|
||||
// `/devices`
|
||||
// );
|
||||
// navigate(updatedUrl, { replace: true });
|
||||
// loadDevices()
|
||||
// }
|
||||
// }, [tab])
|
||||
|
||||
return(
|
||||
<PageContainer padding={isMobile ? 0 : 2}>
|
||||
<SmartBreadcrumb />
|
||||
<Tabs
|
||||
value={tab}
|
||||
onChange={handleTabChange}
|
||||
<SmartBreadcrumb key={"Device page crumbs"}/>
|
||||
<Box
|
||||
// onMouseEnter={() => setTabsHovered(true)}
|
||||
// onMouseLeave={() => setTabsHovered(false)}
|
||||
sx={{
|
||||
borderRadius: 1,
|
||||
border: "1px solid rgba(150, 150, 150, 0.2)",
|
||||
marginTop: 1,
|
||||
marginBottom: 1
|
||||
}}
|
||||
>
|
||||
<Tab value={"all"} label="All" />
|
||||
{groups.map((group, index) => {
|
||||
if (group.id()) return (
|
||||
<Tab value={group.id()} label={group.name()} key={"group-tab-"+index}/>
|
||||
)
|
||||
})}
|
||||
{groupsLoading && <CircularProgress />}
|
||||
<Tab value={"never"} label={groupButton()} />
|
||||
</Tabs>
|
||||
<Tabs
|
||||
{...{}}
|
||||
value={groups.length > 0 ? tab : "all"}
|
||||
onChange={handleTabChange}
|
||||
variant="scrollable"
|
||||
scrollButtons="auto"
|
||||
sx={{ borderRadius: 1 }}
|
||||
>
|
||||
<Tab {...{}} value={"all"} label="All" />
|
||||
{groupsLoading ?
|
||||
<CircularProgress/>
|
||||
: groups.map((group, index) => {
|
||||
if (group.id()) return (
|
||||
<Tab {...{}} value={group.id().toString()} label={group.name()} key={"group-tab-"+index}/>
|
||||
)
|
||||
})}
|
||||
<Tab {...{}} value={"never"} label={<CreateGroupIcon className={classes.green} />} onClick={() => openGroupSettings(undefined, "add")} />
|
||||
</Tabs>
|
||||
</Box>
|
||||
<ResponsiveTable<pond.Device>
|
||||
title="Devices"
|
||||
subtitle={subtitle()}
|
||||
|
|
|
|||
25
src/pages/Group.tsx
Normal file
25
src/pages/Group.tsx
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
import { Grid2 } from "@mui/material";
|
||||
import SmartBreadcrumb from "common/SmartBreadcrumb";
|
||||
import { Group } from "models"
|
||||
import { useState } from "react"
|
||||
import { useLocation, useParams } from "react-router-dom";
|
||||
|
||||
|
||||
export default function GroupPage() {
|
||||
|
||||
const groupID = useParams<{ groupID: string }>()?.groupID ?? "";
|
||||
const { state } = useLocation();
|
||||
const [group, setGroup] = useState<Group>(state?.device ? Group.create(state.device) : Group.create())
|
||||
|
||||
|
||||
return (
|
||||
<Grid2 container justifyContent={"space-between"}>
|
||||
<Grid2>
|
||||
<SmartBreadcrumb groupName={group.name()} />
|
||||
</Grid2>
|
||||
<Grid2>
|
||||
{/* <GroupActions /> */}
|
||||
</Grid2>
|
||||
</Grid2>
|
||||
)
|
||||
}
|
||||
132
src/pages/Groups.tsx
Normal file
132
src/pages/Groups.tsx
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
import { Box, Chip, Theme, Tooltip, Typography } from "@mui/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";
|
||||
|
||||
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),
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
export default function GroupsPage() {
|
||||
const groupAPI = useGroupAPI()
|
||||
const navigate = useNavigate()
|
||||
const [limit, setLimit] = useState(10)
|
||||
const [page, setPage] = useState(0)
|
||||
const [order, setOrder] = useState<"asc" | "desc">("asc")
|
||||
const [orderBy, setOrderBy] = useState("")
|
||||
const [search, setSearch] = useState("")
|
||||
const [total, setTotal] = useState(0)
|
||||
const [loading, setLoading] = useState(false)
|
||||
|
||||
const [groups, setGroups] = useState<pond.Group[]>([])
|
||||
|
||||
const classes = useStyles()
|
||||
|
||||
const loadGroups = () => {
|
||||
setLoading(true)
|
||||
groupAPI.listGroups(limit, page*limit, order, orderBy, search).then(resp => {
|
||||
setGroups(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} })
|
||||
}
|
||||
|
||||
return (
|
||||
<ResponsiveTable<pond.Group>
|
||||
title={<SmartBreadcrumb />}
|
||||
rows={groups}
|
||||
columns={columns()}
|
||||
total={total}
|
||||
pageSize={limit}
|
||||
page={page}
|
||||
setPage={setPage}
|
||||
handleRowsPerPageChange={handleRowsPerPageChange}
|
||||
isLoading={loading}
|
||||
setSearchText={setSearch}
|
||||
onRowClick={handleRowClick}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
|
@ -21,7 +21,9 @@ export interface IGroupAPIContext {
|
|||
order?: "asc" | "desc",
|
||||
orderBy?: string,
|
||||
search?: string,
|
||||
asRoot?: boolean
|
||||
asRoot?: boolean,
|
||||
keys?: string[],
|
||||
types?: string[],
|
||||
) => Promise<any>;
|
||||
listGroupDevices: (
|
||||
id: number,
|
||||
|
|
@ -82,10 +84,18 @@ export default function GroupProvider(props: PropsWithChildren<Props>) {
|
|||
order?: "asc" | "desc",
|
||||
orderBy?: string,
|
||||
search?: string,
|
||||
asRoot?: boolean
|
||||
asRoot?: boolean,
|
||||
keys?: string[],
|
||||
types?: string[]
|
||||
) => {
|
||||
let keys = getContextKeys()
|
||||
let types = getContextTypes()
|
||||
keys = keys ? keys : getContextKeys();
|
||||
types = types? types : getContextTypes();
|
||||
types.forEach((type, index) => {
|
||||
if (type === "group") {
|
||||
types.splice(index, 1)
|
||||
keys.splice(index, 1)
|
||||
}
|
||||
})
|
||||
return get(
|
||||
pondURL(
|
||||
"/groups" +
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue