From e97773ffc9a803ec908ab3de32f669ade6ce8d56 Mon Sep 17 00:00:00 2001 From: csawatzky Date: Mon, 26 May 2025 16:04:13 -0600 Subject: [PATCH] added load more function to mobile view of responsive table to the remaining uses --- src/maps/mapDrawers/GroupDrawer.tsx | 36 +++++++++++++++++++------- src/objectHeater/ObjectHeaterCard.tsx | 2 +- src/pages/Group.tsx | 31 ++++++++++++++++++++++ src/pages/Groups.tsx | 10 ++++++++ src/pages/Mines.tsx | 19 ++++++++++++++ src/pages/Sites.tsx | 37 ++++++++++++++++++++++++--- 6 files changed, 122 insertions(+), 13 deletions(-) diff --git a/src/maps/mapDrawers/GroupDrawer.tsx b/src/maps/mapDrawers/GroupDrawer.tsx index 8eae42d..e9d2768 100644 --- a/src/maps/mapDrawers/GroupDrawer.tsx +++ b/src/maps/mapDrawers/GroupDrawer.tsx @@ -3,6 +3,7 @@ import DisplayDrawer from "common/DisplayDrawer"; import ResponsiveTable from "common/ResponsiveTable"; //import DeviceCardList from "device/DeviceCardList"; import { useGroupAPI, useSnackbar } from "hooks"; +import { cloneDeep } from "lodash"; import { Group } from "models"; import moment from "moment"; import { describePower } from "pbHelpers/Power"; @@ -28,18 +29,19 @@ export default function GroupDrawer(props: Props) { const { openSnack } = useSnackbar(); const [grpDevs, setGrpDevs] = useState([]); const navigate = useNavigate(); - const [tablePage, setTablePage] = useState(0) - const [pageSize, setPageSize] = useState(10) + const loadLimit = 10 + const [groupTotal, setGroupTotal] = useState(0) const loadDevs = useCallback(() => { groupAPI - .listGroupDevices(group.id(), 100, 0, "asc", undefined, true) + .listGroupDevices(group.id(), loadLimit, 0, "asc", undefined, true) .then(resp => { const groupDevices: pond.ComprehensiveDevice[] = or( resp.data.comprehensiveDevices, [] ).map(d => pond.ComprehensiveDevice.fromObject(d)); setGrpDevs(groupDevices); + setGroupTotal(resp.data.total) }) .catch(err => { openSnack("Failed to get devices for group"); @@ -174,21 +176,37 @@ export default function GroupDrawer(props: Props) { } const drawerBody = () => { - // TODO: will need to update the rows and setPage functions if we decide to have the table only show a number of items matching its page size rether than everything passed in return ( - page={tablePage} - pageSize={pageSize} + page={0} + pageSize={loadLimit} onRowClick={toDevice} - handleRowsPerPageChange={()=>{}} - setPage={()=>{}} - total={grpDevs.length} + total={groupTotal} rows={grpDevs} renderMobile={mobile} renderGutter={gutter} gutterPadding={0} mobileView + loadMore={() => { + let current = cloneDeep(grpDevs) + groupAPI + .listGroupDevices(group.id(), loadLimit, current.length, "asc", undefined, true) + .then(resp => { + let newDevices: pond.ComprehensiveDevice[] = or( + resp.data.comprehensiveDevices, + [] + ).map(d => pond.ComprehensiveDevice.fromObject(d)); + setGrpDevs(current.concat(newDevices)); + setGroupTotal(resp.data.total) + }) + .catch(err => { + openSnack("Failed to get devices for group"); + }); + }} + //these two function are uneccessary as this will always be in a list as mobile view + handleRowsPerPageChange={()=>{}} + setPage={()=>{}} /> ) diff --git a/src/objectHeater/ObjectHeaterCard.tsx b/src/objectHeater/ObjectHeaterCard.tsx index 4255b1f..651ae7c 100644 --- a/src/objectHeater/ObjectHeaterCard.tsx +++ b/src/objectHeater/ObjectHeaterCard.tsx @@ -371,7 +371,7 @@ export default function ObjectHeaterCard(props: Props) { }else { return ( - + { return ({ @@ -241,6 +242,36 @@ export default function GroupPage() { onRowClick={toDevice} setSearchText={setSearch} isLoading={loadingDevices} + loadMore={()=>{ + let current = cloneDeep(devices) + setLoadingDevices(true) + deviceAPI.list( + limit, + current.length, + order, + orderBy, + search, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + getKeys(), + getTypes(), + undefined, + undefined, + as + ).then(resp => { + let newDevices: Device[] = []; + resp.data.devices.forEach(device => { + newDevices.push(Device.create(device)) + }) + setDevices(current.concat(newDevices)) + }).finally(() => { + setLoadingDevices(false) + }) + }} /> ) diff --git a/src/pages/Groups.tsx b/src/pages/Groups.tsx index 0d06947..acc6673 100644 --- a/src/pages/Groups.tsx +++ b/src/pages/Groups.tsx @@ -13,6 +13,7 @@ import { or } from "utils/types"; import PageContainer from "./PageContainer"; import GroupSettings from "group/GroupSettings"; import { green } from "@mui/material/colors"; +import { cloneDeep } from "lodash"; const useStyles = makeStyles((theme: Theme) => { const isMobile = useMobile() @@ -163,6 +164,15 @@ export default function GroupsPage() { isLoading={loading} setSearchText={setSearch} onRowClick={handleRowClick} + loadMore={()=>{ + let current = cloneDeep(groups) + setLoading(true) + groupAPI.listGroups(limit, current.length, order, orderBy, search).then(resp => { + setGroups(or(current.concat(resp.data.groups), current)) + }).finally(() => { + setLoading(false) + }) + }} /> { + let current = cloneDeep(mineTableData) + setIsLoading(true); + mineAPI + .listMines(pageSize, current.length, "desc", undefined, searchValue, false, as) + .then(resp => { + let newMines: MineRow[] = []; + resp.data.mines.forEach(mine => { + newMines.push({ + mine: mine + }); + }); + setMineTableData(current.concat(newMines)); + }) + .finally(() => { + setIsLoading(false); + }); + }} /> diff --git a/src/pages/Sites.tsx b/src/pages/Sites.tsx index e749643..91ac28b 100644 --- a/src/pages/Sites.tsx +++ b/src/pages/Sites.tsx @@ -1,4 +1,4 @@ -import { Avatar, Box, Card, Grid2 as Grid, Switch, Tab, Tabs, Tooltip, Typography } from "@mui/material"; +import { Avatar, Box, Button, Card, Grid2 as Grid, Switch, Tab, Tabs, Tooltip, Typography } from "@mui/material"; import { Group } from "@mui/icons-material"; //import MaterialTable from "material-table"; import { Site, User } from "models"; @@ -12,6 +12,7 @@ import { useMobile } from "hooks"; import JobsiteIcon from "products/Construction/JobSiteIcon"; import ResponsiveTable, { Column } from "common/ResponsiveTable"; import { useNavigate } from "react-router-dom"; +import { cloneDeep } from "lodash"; interface SiteWithData { site: Site; @@ -46,7 +47,7 @@ export default function Sites() { .listSitesPageData(pageSize, tablePage * pageSize, "asc", "siteName", undefined, as) .then(resp => { setTotal(resp.data.total); - buildTableData(resp.data.sites); + setSites(buildTableData(resp.data.sites)); }) .finally(() => { setLoading(false); @@ -71,7 +72,7 @@ export default function Sites() { data.push(newTableData); } }); - setSites([...data]); + return data; }; useEffect(() => { @@ -186,6 +187,19 @@ export default function Sites() { rows={sites} handleRowsPerPageChange={handleTablePage} onRowClick={goToSite} + loadMore={()=>{ + let current = cloneDeep(sites) + setLoading(true); + siteAPI + .listSitesPageData(pageSize, current.length, "asc", "siteName", undefined, as) + .then(resp => { + let newData = buildTableData(resp.data.sites); + setSites(current.concat(newData)) + }) + .finally(() => { + setLoading(false); + }); + }} /> ) }; @@ -208,6 +222,20 @@ export default function Sites() { setCurrentTab(newValue); }; + const loadMore = () => { + let current = cloneDeep(sites) + setLoading(true); + siteAPI + .listSitesPageData(pageSize, current.length, "asc", "siteName", undefined, as) + .then(resp => { + let newData = buildTableData(resp.data.sites); + setSites(current.concat(newData)) + }) + .finally(() => { + setLoading(false); + }); + } + const mobileView = () => { return ( @@ -297,6 +325,9 @@ export default function Sites() { return siteCards; })} + {sites.length < total && + + } ); };