diff --git a/src/cableEstimator/cableEstimator.tsx b/src/cableEstimator/cableEstimator.tsx
index 960e06a..17f909c 100644
--- a/src/cableEstimator/cableEstimator.tsx
+++ b/src/cableEstimator/cableEstimator.tsx
@@ -184,16 +184,16 @@ export default function CableEstimator() {
if(tableSearch !== ""){
//filter the data in the cloned list
clone = clone.filter(bin => {
- if(tableSearch.toLowerCase() === bin.Manufacturer.toLowerCase()) return true
- if(tableSearch.toLowerCase() === bin.Model.toLowerCase()) return true
- if(tableSearch.toLowerCase() === bin.Capacity.toString().toLowerCase()) return true
- if(tableSearch.toLowerCase() === bin.HopperAngle.toString().toLowerCase()) return true
- if(tableSearch.toLowerCase() === bin.Diameter.toString().toLowerCase()) return true
- if(tableSearch.toLowerCase() === bin.Sidewall.toString().toLowerCase()) return true
- if(tableSearch.toLowerCase() === bin.Peak.toString().toLowerCase()) return true
- if(tableSearch.toLowerCase() === bin.EaveToPeak.toString().toLowerCase()) return true
- if(tableSearch.toLowerCase() === bin.RoofAngle.toString().toLowerCase()) return true
- if(tableSearch.toLowerCase() === bin.Rings.toString().toLowerCase()) return true
+ if(bin.Manufacturer.toLowerCase().includes(tableSearch.toLowerCase())) return true
+ if(bin.Model.toLowerCase().includes(tableSearch.toLowerCase())) return true
+ if(bin.Capacity.toString().toLowerCase().includes(tableSearch.toLowerCase())) return true
+ if(bin.HopperAngle.toString().toLowerCase().includes(tableSearch.toLowerCase())) return true
+ if(bin.Diameter.toString().toLowerCase().includes(tableSearch.toLowerCase())) return true
+ if(bin.Sidewall.toString().toLowerCase().includes(tableSearch.toLowerCase())) return true
+ if(bin.Peak.toString().toLowerCase().includes(tableSearch.toLowerCase())) return true
+ if(bin.EaveToPeak.toString().toLowerCase().includes(tableSearch.toLowerCase())) return true
+ if(bin.RoofAngle.toString().toLowerCase().includes(tableSearch.toLowerCase())) return true
+ if(bin.Rings.toString().toLowerCase().includes(tableSearch.toLowerCase())) return true
return false
})
}
diff --git a/src/common/QrCodeGenerator.tsx b/src/common/QrCodeGenerator.tsx
index 8d5ddcb..27eaff0 100644
--- a/src/common/QrCodeGenerator.tsx
+++ b/src/common/QrCodeGenerator.tsx
@@ -1,4 +1,4 @@
-import { Box, Button, DialogActions, DialogContent, DialogTitle } from "@mui/material";
+import { Box, Button, Checkbox, DialogActions, DialogContent, DialogTitle, Typography } from "@mui/material";
// import MaterialTable from "material-table";
import React, { useEffect, useState } from "react";
import ResponsiveDialog from "./ResponsiveDialog";
@@ -36,7 +36,7 @@ export default function(props: Props) {
width: 500
},
viewerMobile: {
- height: "100%",
+ height: 500,
width: "100%"
},
page: {
@@ -103,12 +103,12 @@ export default function(props: Props) {
selected.push(row)
}else{ //remove the page/index from the map
if(pageSelect){
- pageSelect.splice(pageSelect.indexOf(index))
+ pageSelect.splice(pageSelect.indexOf(index), 1)
}
//remove the selected object from the array
selected.forEach((codeKey, index) => {
if(row.key === codeKey.key){
- selected.splice(index)
+ selected.splice(index, 1)
}
})
}
@@ -137,35 +137,27 @@ export default function(props: Props) {
total={keyList.length}
setPage={(page) => {setTablePage(page)}}
handleRowsPerPageChange={handleRowsPerPageChange}
+ loadMore={() => {
+ let clone: QrCodeKey[] = cloneDeep(keyList)
+ let current = cloneDeep(displayedRows)
+ let newRows = clone.splice(current.length, pageSize)
+ setDisplayedRows(current.concat(newRows))
+ }}
+ renderMobile={(row, index) => {
+ return (
+
+ {
+ rowSelected(row, index, checked)
+ }}
+ />
+
+ {row.name}
+
+
+ )
+ }}
/>
- {/* {
- setSelectedKeys(data);
- }}
- columns={[
- {
- cellStyle: {
- padding: 0
- },
- title: "Name",
- field: "name"
- }
- ]}> */}
);
};
diff --git a/src/common/ResponsiveTable.tsx b/src/common/ResponsiveTable.tsx
index de6ae6a..b2fa240 100644
--- a/src/common/ResponsiveTable.tsx
+++ b/src/common/ResponsiveTable.tsx
@@ -85,7 +85,7 @@ interface Props {
multiGutter?: boolean;
rowsPerPageOptions?: number[];
noDataMessage?: string;
- renderMobile?: (row: T) => JSX.Element;
+ renderMobile?: (row: T, index: number) => JSX.Element;
hideKeys?: boolean;
onRowClick?: (row: T) => void;
actions?: string | JSX.Element;
@@ -272,9 +272,9 @@ export default function ResponsiveTable(props: Props) {
return String(val).charAt(0).toUpperCase() + String(val).slice(1);
}
- const renderMobileRow = (row: T) => {
+ const renderMobileRow = (row: T, index: number) => {
if (renderMobile) return (
- renderMobile(row)
+ renderMobile(row, index)
)
if (columns) {
return (
@@ -329,7 +329,7 @@ export default function ResponsiveTable(props: Props) {
{rows.map((row, index) => {
return (
onRowClick&&onRowClick(row)}>
- {renderMobileRow(row)}
+ {renderMobileRow(row, index)}
{renderGutter &&
<>
diff --git a/src/common/SmartBreadcrumb.tsx b/src/common/SmartBreadcrumb.tsx
index be1d0fe..a30d60a 100644
--- a/src/common/SmartBreadcrumb.tsx
+++ b/src/common/SmartBreadcrumb.tsx
@@ -7,6 +7,7 @@ import {
LinkProps,
Skeleton,
Theme,
+ Tooltip,
Typography,
useTheme
} from "@mui/material";
@@ -334,22 +335,23 @@ export default function SmartBreadcrumb(props: Props) {
const linkComponent = (to: string, label: string, lastPath: boolean) => {
return (
-
- {label}
-
- }
- className={classes.chip}
- />
+
+
+ {label}
+
+ }
+ className={classes.chip}
+ />
+
);
};
diff --git a/src/contract/contractTransactionTable.tsx b/src/contract/contractTransactionTable.tsx
index 4508377..ebee9ba 100644
--- a/src/contract/contractTransactionTable.tsx
+++ b/src/contract/contractTransactionTable.tsx
@@ -369,6 +369,12 @@ export default function ContractTransactionTable(props: Props) {
total={tableData.length}
handleRowsPerPageChange={(e)=>{setPageSize(e.target.value)}}
setPage={(page)=>{setTablePage(page)}}
+ loadMore={()=>{
+ let clone: Transaction[] = cloneDeep(tableData)
+ let current = cloneDeep(displayData)
+ let newRows = clone.splice(current.length, pageSize)
+ setDisplayData(current.concat(newRows))
+ }}
/>
{/*
)}
- {user.allowedTo("provision") && }
+ {}
);
};
diff --git a/src/device/DeviceTags.tsx b/src/device/DeviceTags.tsx
index 82981d1..7806a59 100644
--- a/src/device/DeviceTags.tsx
+++ b/src/device/DeviceTags.tsx
@@ -68,6 +68,7 @@ function AddDeviceTag(props: AddDeviceTagProps) {
addTagToDevice(tag)} />
));
+
return (
setOpen(true)} size="small">
diff --git a/src/gate/GateFlowGraph.tsx b/src/gate/GateFlowGraph.tsx
index 9e05ea9..6e060c6 100644
--- a/src/gate/GateFlowGraph.tsx
+++ b/src/gate/GateFlowGraph.tsx
@@ -127,6 +127,7 @@ export default function GateFlowGraph(props: Props) {
setRuntime(moment.duration(runtime));
let state = false;
if (
+ data.length > 1 &&
data[data.length - 1].value > gate.lowerFlow() &&
data[data.length - 1].value < gate.upperFlow()
) {
diff --git a/src/gate/GateList.tsx b/src/gate/GateList.tsx
index 8f0c8bc..5c548e2 100644
--- a/src/gate/GateList.tsx
+++ b/src/gate/GateList.tsx
@@ -12,6 +12,7 @@ import AddGateFab from "./AddGateFab";
import GateSettings from "./GateSettings";
import { useGateAPI, useGlobalState } from "providers";
import { Settings } from "@mui/icons-material";
+import { cloneDeep } from "lodash";
interface Props {
//gates: Gate[];
@@ -219,6 +220,19 @@ export default function GateList(props: Props) {
onRowClick={(gate) => {goToGate(gate)}}
hideKeys={isMobile || props.useMobile}
setSearchText={(search) => setSearch(search)}
+ loadMore={()=>{
+ let current = cloneDeep(gates)
+ let keys = undefined
+ let types = undefined
+ if(currentTerminal) {
+ keys = [currentTerminal]
+ types = ["terminal"]
+ }
+ gateAPI.listGates(pageSize, current.length , "asc", "name", search, undefined, keys, types, undefined, undefined, as).then(resp => {
+ let newGates = resp.data.gates.map(gate => Gate.create(gate))
+ setGates(current.concat(newGates))
+ })
+ }}
/>
)
};
diff --git a/src/maps/mapDrawers/GroupDrawer.tsx b/src/maps/mapDrawers/GroupDrawer.tsx
index 4048245..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={0}
+ 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 (
-
+
{
setOpenQrGenerator(true);
+ setBinMenuAnchorEl(null)
}}>
Generate QR Codes
diff --git a/src/pages/Firmware.tsx b/src/pages/Firmware.tsx
index ecd628a..b3a7c58 100644
--- a/src/pages/Firmware.tsx
+++ b/src/pages/Firmware.tsx
@@ -39,6 +39,7 @@ import { useGlobalState } from "providers";
import { useCallback, useEffect, useState } from "react";
import { downloadFile } from "utils/download";
import { or } from "utils/types";
+import { cloneDeep } from "lodash";
const useStyles = makeStyles((theme: Theme) => {
const themeType = useThemeType()
@@ -463,6 +464,22 @@ export default function Firmware() {
columns={columns(width === "xs" || width === "sm")}
setPage={(page)=>{setTablePage(page)}}
handleRowsPerPageChange={(e)=>{setPageSize(e.target.value)}}
+ loadMore={() => {
+ let current = cloneDeep(tableData)
+ firmwareAPI.listFirmware(pageSize, current.length, "desc", "version", searchText)
+ .then((response) => {
+ let newRows: FirmwareModel[] = or(response.data.firmware, []).map(
+ (firmwareData: any) => {
+ return FirmwareModel.create(pond.Firmware.fromObject(firmwareData));
+ }
+ );
+ setTableData(current.concat(newRows))
+ })
+ .catch(() => {
+ //failed to load
+ error("Failed to load more firmware versions")
+ });
+ }}
/>
{
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)
+ })
+ }}
/>
{setTablePage(page)}}
handleRowsPerPageChange={handleChange}
onRowClick={goToHeater}
- />
- )
- };
-
- const mobileList = () => {
- return (
-
- {heaters.map(h => (
- {
+ let current = cloneDeep(heaters)
+ objectHeaterAPI
+ .listObjectHeatersPageData(pageSize, current.length, undefined, undefined, searchText, as)
+ .then(resp => {
+ setHeaters(heaters.concat(resp.data.heaterData));
+ });
+ }}
+ renderMobile={(row)=>{
+ return (
+ {
setHeaterToLink(heater);
setOpenLinkDrawer(true);
@@ -131,9 +134,10 @@ export default function Heaters() {
setDevices(d);
}}
/>
- ))}
-
- );
+ )
+ }}
+ />
+ )
};
return (
@@ -180,7 +184,7 @@ export default function Heaters() {
}}
pulse={heaters.length < 1}
/>
- {isMobile ? mobileList() : desktopTable()}
+ {desktopTable()}
);
}
diff --git a/src/pages/Mines.tsx b/src/pages/Mines.tsx
index 5e73bae..fcaeac6 100644
--- a/src/pages/Mines.tsx
+++ b/src/pages/Mines.tsx
@@ -14,6 +14,7 @@ import ResponsiveTable, { Column } from "common/ResponsiveTable";
import { useNavigate } from "react-router-dom";
import { or } from "utils";
import { useGlobalState } from "providers";
+import { cloneDeep } from "lodash";
interface MineRow {
mine: pond.Mine;
@@ -110,6 +111,24 @@ export default function Mines() {
hideKeys
isLoading={isLoading}
onRowClick={onRowClick}
+ loadMore={()=>{
+ 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..b17fe0e 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 (
@@ -230,7 +258,7 @@ export default function Sites() {
siteCards.push(
{
goToSite(site);
}}>
@@ -297,6 +325,9 @@ export default function Sites() {
return siteCards;
})}
+ {sites.length < total &&
+
+ }
);
};
diff --git a/src/pbHelpers/ComponentTypes/DragerGasDongle.ts b/src/pbHelpers/ComponentTypes/DragerGasDongle.ts
index a8f2090..db71771 100644
--- a/src/pbHelpers/ComponentTypes/DragerGasDongle.ts
+++ b/src/pbHelpers/ComponentTypes/DragerGasDongle.ts
@@ -112,7 +112,7 @@ export function dragerGasDongle(subtype: number = 0): ComponentTypeExtension {
excludedNodes?: number[]
): Summary[] => {
//if it is O2 display percentage rather than ppm
- if (subtype === quack.DragerGasDongleSubtype.DRAGER_GAS_DONGLE_SUBTYPE_O2) {
+ if (subtype === quack.DragerGasDongleSubtype.DRAGER_GAS_DONGLE_SUBTYPE_O2 || subtype === quack.DragerGasDongleSubtype.DRAGER_GAS_DONGLE_SUBTYPE_LEL) {
let summaries: Summary[] = [];
measurements.measurementsFor.forEach(measurement => {
let describer = describeMeasurement(
diff --git a/src/providers/pond/deviceAPI.tsx b/src/providers/pond/deviceAPI.tsx
index 27ea776..6a940e2 100644
--- a/src/providers/pond/deviceAPI.tsx
+++ b/src/providers/pond/deviceAPI.tsx
@@ -8,6 +8,7 @@ import { useGlobalState } from "providers";
import moment from "moment";
import { or } from "utils/types";
import { dateRange } from "providers/http";
+import { getContextKeys, getContextTypes } from "pbHelpers/Context";
export interface IDeviceAPIContext {
add: (name: string, description: string, backpack: pond.BackpackSettings, otherTeam?: string) => Promise>;
@@ -725,8 +726,12 @@ export default function DeviceProvider(props: PropsWithChildren) {
};
const tag = (id: number, tag: string) => {
+ const keys = getContextKeys()
+ const types = getContextTypes()
+ let url = "/devices/" + id + "/tags/" + tag + "?keys=" + keys + "&types=" + types
+ if (as && !keys.includes(as)) url += "&as=" + as
return new Promise((resolve, reject) => {
- put(pondURL("/devices/" + id + "/tags/" + tag), {}).then(resp => {
+ put(pondURL(url), {}).then(resp => {
return resolve(resp)
}).catch(err => {
return reject(err)
diff --git a/src/providers/pond/tagAPI.tsx b/src/providers/pond/tagAPI.tsx
index 235e622..071591b 100644
--- a/src/providers/pond/tagAPI.tsx
+++ b/src/providers/pond/tagAPI.tsx
@@ -33,8 +33,16 @@ export default function TagProvider(props: PropsWithChildren) {
const [{ as }] = useGlobalState()
const addTag = (tag: pond.TagSettings) => {
+ let keys = getContextKeys()
+ let types = getContextTypes()
+ let url = "/tags"
+ if (keys.includes(as)) {
+ url += "?keys=" + keys + "&types=" + types
+ } else {
+ url += "?as=" + as + "&keys=" + keys + "&types=" + types
+ }
return new Promise((resolve, reject) => {
- post(pondURL("/tags"), tag).then(resp => {
+ post(pondURL(url), tag).then(resp => {
return resolve(resp)
}).catch(err => {
return reject(err)