Merge branch 'master' into table_column_resize
This commit is contained in:
commit
bf65aefd68
21 changed files with 255 additions and 95 deletions
|
|
@ -184,16 +184,16 @@ export default function CableEstimator() {
|
||||||
if(tableSearch !== ""){
|
if(tableSearch !== ""){
|
||||||
//filter the data in the cloned list
|
//filter the data in the cloned list
|
||||||
clone = clone.filter(bin => {
|
clone = clone.filter(bin => {
|
||||||
if(tableSearch.toLowerCase() === bin.Manufacturer.toLowerCase()) return true
|
if(bin.Manufacturer.toLowerCase().includes(tableSearch.toLowerCase())) return true
|
||||||
if(tableSearch.toLowerCase() === bin.Model.toLowerCase()) return true
|
if(bin.Model.toLowerCase().includes(tableSearch.toLowerCase())) return true
|
||||||
if(tableSearch.toLowerCase() === bin.Capacity.toString().toLowerCase()) return true
|
if(bin.Capacity.toString().toLowerCase().includes(tableSearch.toLowerCase())) return true
|
||||||
if(tableSearch.toLowerCase() === bin.HopperAngle.toString().toLowerCase()) return true
|
if(bin.HopperAngle.toString().toLowerCase().includes(tableSearch.toLowerCase())) return true
|
||||||
if(tableSearch.toLowerCase() === bin.Diameter.toString().toLowerCase()) return true
|
if(bin.Diameter.toString().toLowerCase().includes(tableSearch.toLowerCase())) return true
|
||||||
if(tableSearch.toLowerCase() === bin.Sidewall.toString().toLowerCase()) return true
|
if(bin.Sidewall.toString().toLowerCase().includes(tableSearch.toLowerCase())) return true
|
||||||
if(tableSearch.toLowerCase() === bin.Peak.toString().toLowerCase()) return true
|
if(bin.Peak.toString().toLowerCase().includes(tableSearch.toLowerCase())) return true
|
||||||
if(tableSearch.toLowerCase() === bin.EaveToPeak.toString().toLowerCase()) return true
|
if(bin.EaveToPeak.toString().toLowerCase().includes(tableSearch.toLowerCase())) return true
|
||||||
if(tableSearch.toLowerCase() === bin.RoofAngle.toString().toLowerCase()) return true
|
if(bin.RoofAngle.toString().toLowerCase().includes(tableSearch.toLowerCase())) return true
|
||||||
if(tableSearch.toLowerCase() === bin.Rings.toString().toLowerCase()) return true
|
if(bin.Rings.toString().toLowerCase().includes(tableSearch.toLowerCase())) return true
|
||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 MaterialTable from "material-table";
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import ResponsiveDialog from "./ResponsiveDialog";
|
import ResponsiveDialog from "./ResponsiveDialog";
|
||||||
|
|
@ -36,7 +36,7 @@ export default function(props: Props) {
|
||||||
width: 500
|
width: 500
|
||||||
},
|
},
|
||||||
viewerMobile: {
|
viewerMobile: {
|
||||||
height: "100%",
|
height: 500,
|
||||||
width: "100%"
|
width: "100%"
|
||||||
},
|
},
|
||||||
page: {
|
page: {
|
||||||
|
|
@ -103,12 +103,12 @@ export default function(props: Props) {
|
||||||
selected.push(row)
|
selected.push(row)
|
||||||
}else{ //remove the page/index from the map
|
}else{ //remove the page/index from the map
|
||||||
if(pageSelect){
|
if(pageSelect){
|
||||||
pageSelect.splice(pageSelect.indexOf(index))
|
pageSelect.splice(pageSelect.indexOf(index), 1)
|
||||||
}
|
}
|
||||||
//remove the selected object from the array
|
//remove the selected object from the array
|
||||||
selected.forEach((codeKey, index) => {
|
selected.forEach((codeKey, index) => {
|
||||||
if(row.key === codeKey.key){
|
if(row.key === codeKey.key){
|
||||||
selected.splice(index)
|
selected.splice(index, 1)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -137,35 +137,27 @@ export default function(props: Props) {
|
||||||
total={keyList.length}
|
total={keyList.length}
|
||||||
setPage={(page) => {setTablePage(page)}}
|
setPage={(page) => {setTablePage(page)}}
|
||||||
handleRowsPerPageChange={handleRowsPerPageChange}
|
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 (
|
||||||
|
<Box display="flex">
|
||||||
|
<Checkbox
|
||||||
|
onChange={(e, checked) => {
|
||||||
|
rowSelected(row, index, checked)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Typography>
|
||||||
|
{row.name}
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
)
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
{/* <MaterialTable
|
|
||||||
icons={getTableIcons()}
|
|
||||||
title={""}
|
|
||||||
data={keyList}
|
|
||||||
options={{
|
|
||||||
paging: true,
|
|
||||||
// pageSize: pageSize,
|
|
||||||
// pageSizeOptions: [5, 10, 20],
|
|
||||||
padding: "dense",
|
|
||||||
showTitle: true,
|
|
||||||
toolbar: true,
|
|
||||||
sorting: true,
|
|
||||||
columnsButton: true,
|
|
||||||
search: false,
|
|
||||||
selection: true
|
|
||||||
}}
|
|
||||||
onSelectionChange={(data, rowData) => {
|
|
||||||
setSelectedKeys(data);
|
|
||||||
}}
|
|
||||||
columns={[
|
|
||||||
{
|
|
||||||
cellStyle: {
|
|
||||||
padding: 0
|
|
||||||
},
|
|
||||||
title: "Name",
|
|
||||||
field: "name"
|
|
||||||
}
|
|
||||||
]}></MaterialTable> */}
|
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@ interface Props<T> {
|
||||||
multiGutter?: boolean;
|
multiGutter?: boolean;
|
||||||
rowsPerPageOptions?: number[];
|
rowsPerPageOptions?: number[];
|
||||||
noDataMessage?: string;
|
noDataMessage?: string;
|
||||||
renderMobile?: (row: T) => JSX.Element;
|
renderMobile?: (row: T, index: number) => JSX.Element;
|
||||||
hideKeys?: boolean;
|
hideKeys?: boolean;
|
||||||
onRowClick?: (row: T) => void;
|
onRowClick?: (row: T) => void;
|
||||||
actions?: string | JSX.Element;
|
actions?: string | JSX.Element;
|
||||||
|
|
@ -272,9 +272,9 @@ export default function ResponsiveTable<T extends Object>(props: Props<T>) {
|
||||||
return String(val).charAt(0).toUpperCase() + String(val).slice(1);
|
return String(val).charAt(0).toUpperCase() + String(val).slice(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
const renderMobileRow = (row: T) => {
|
const renderMobileRow = (row: T, index: number) => {
|
||||||
if (renderMobile) return (
|
if (renderMobile) return (
|
||||||
renderMobile(row)
|
renderMobile(row, index)
|
||||||
)
|
)
|
||||||
if (columns) {
|
if (columns) {
|
||||||
return (
|
return (
|
||||||
|
|
@ -329,7 +329,7 @@ export default function ResponsiveTable<T extends Object>(props: Props<T>) {
|
||||||
{rows.map((row, index) => {
|
{rows.map((row, index) => {
|
||||||
return (
|
return (
|
||||||
<Card className={classNames(classes.card)} key={"mobile-card-"+index} onClick={() => onRowClick&&onRowClick(row)}>
|
<Card className={classNames(classes.card)} key={"mobile-card-"+index} onClick={() => onRowClick&&onRowClick(row)}>
|
||||||
{renderMobileRow(row)}
|
{renderMobileRow(row, index)}
|
||||||
{renderGutter &&
|
{renderGutter &&
|
||||||
<>
|
<>
|
||||||
<Divider/>
|
<Divider/>
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import {
|
||||||
LinkProps,
|
LinkProps,
|
||||||
Skeleton,
|
Skeleton,
|
||||||
Theme,
|
Theme,
|
||||||
|
Tooltip,
|
||||||
Typography,
|
Typography,
|
||||||
useTheme
|
useTheme
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
|
|
@ -334,22 +335,23 @@ export default function SmartBreadcrumb(props: Props) {
|
||||||
|
|
||||||
const linkComponent = (to: string, label: string, lastPath: boolean) => {
|
const linkComponent = (to: string, label: string, lastPath: boolean) => {
|
||||||
return (
|
return (
|
||||||
<Chip
|
<Tooltip title={label} key={"breadcrumb-"+to}>
|
||||||
key={to}
|
<Chip
|
||||||
variant={lastPath ? "filled" : "outlined"}
|
variant={lastPath ? "filled" : "outlined"}
|
||||||
label={
|
label={
|
||||||
<LinkRouter
|
<LinkRouter
|
||||||
color={lastPath ? "textPrimary" : "textSecondary"}
|
color={lastPath ? "textPrimary" : "textSecondary"}
|
||||||
variant="subtitle1"
|
variant="subtitle1"
|
||||||
to={to}
|
to={to}
|
||||||
state={state}
|
state={state}
|
||||||
sx={{ '&:hover': { color: getThemeType() === "dark" ? 'white' : "black" }}}
|
sx={{ '&:hover': { color: getThemeType() === "dark" ? 'white' : "black" }}}
|
||||||
className={classes.textOverflow}>
|
className={classes.textOverflow}>
|
||||||
{label}
|
{label}
|
||||||
</LinkRouter>
|
</LinkRouter>
|
||||||
}
|
}
|
||||||
className={classes.chip}
|
className={classes.chip}
|
||||||
/>
|
/>
|
||||||
|
</Tooltip>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -369,6 +369,12 @@ export default function ContractTransactionTable(props: Props) {
|
||||||
total={tableData.length}
|
total={tableData.length}
|
||||||
handleRowsPerPageChange={(e)=>{setPageSize(e.target.value)}}
|
handleRowsPerPageChange={(e)=>{setPageSize(e.target.value)}}
|
||||||
setPage={(page)=>{setTablePage(page)}}
|
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))
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
{/* <MaterialTable
|
{/* <MaterialTable
|
||||||
title={"Deliveries"}
|
title={"Deliveries"}
|
||||||
|
|
|
||||||
|
|
@ -233,7 +233,7 @@ export default function DeviceOverview(props: Props) {
|
||||||
<StatusChip status="pending" />
|
<StatusChip status="pending" />
|
||||||
</Grid>
|
</Grid>
|
||||||
)}
|
)}
|
||||||
{user.allowedTo("provision") && <DeviceTags device={device} disableAdd={disableAddTag} />}
|
{<DeviceTags device={device} disableAdd={disableAddTag} />}
|
||||||
</Grid>
|
</Grid>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,7 @@ function AddDeviceTag(props: AddDeviceTagProps) {
|
||||||
<TagUI tag={tag} onClick={() => addTagToDevice(tag)} />
|
<TagUI tag={tag} onClick={() => addTagToDevice(tag)} />
|
||||||
</ListItem>
|
</ListItem>
|
||||||
));
|
));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<IconButton aria-label="add tag" onClick={() => setOpen(true)} size="small">
|
<IconButton aria-label="add tag" onClick={() => setOpen(true)} size="small">
|
||||||
|
|
|
||||||
|
|
@ -127,6 +127,7 @@ export default function GateFlowGraph(props: Props) {
|
||||||
setRuntime(moment.duration(runtime));
|
setRuntime(moment.duration(runtime));
|
||||||
let state = false;
|
let state = false;
|
||||||
if (
|
if (
|
||||||
|
data.length > 1 &&
|
||||||
data[data.length - 1].value > gate.lowerFlow() &&
|
data[data.length - 1].value > gate.lowerFlow() &&
|
||||||
data[data.length - 1].value < gate.upperFlow()
|
data[data.length - 1].value < gate.upperFlow()
|
||||||
) {
|
) {
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ import AddGateFab from "./AddGateFab";
|
||||||
import GateSettings from "./GateSettings";
|
import GateSettings from "./GateSettings";
|
||||||
import { useGateAPI, useGlobalState } from "providers";
|
import { useGateAPI, useGlobalState } from "providers";
|
||||||
import { Settings } from "@mui/icons-material";
|
import { Settings } from "@mui/icons-material";
|
||||||
|
import { cloneDeep } from "lodash";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
//gates: Gate[];
|
//gates: Gate[];
|
||||||
|
|
@ -219,6 +220,19 @@ export default function GateList(props: Props) {
|
||||||
onRowClick={(gate) => {goToGate(gate)}}
|
onRowClick={(gate) => {goToGate(gate)}}
|
||||||
hideKeys={isMobile || props.useMobile}
|
hideKeys={isMobile || props.useMobile}
|
||||||
setSearchText={(search) => setSearch(search)}
|
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))
|
||||||
|
})
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import DisplayDrawer from "common/DisplayDrawer";
|
||||||
import ResponsiveTable from "common/ResponsiveTable";
|
import ResponsiveTable from "common/ResponsiveTable";
|
||||||
//import DeviceCardList from "device/DeviceCardList";
|
//import DeviceCardList from "device/DeviceCardList";
|
||||||
import { useGroupAPI, useSnackbar } from "hooks";
|
import { useGroupAPI, useSnackbar } from "hooks";
|
||||||
|
import { cloneDeep } from "lodash";
|
||||||
import { Group } from "models";
|
import { Group } from "models";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import { describePower } from "pbHelpers/Power";
|
import { describePower } from "pbHelpers/Power";
|
||||||
|
|
@ -28,18 +29,19 @@ export default function GroupDrawer(props: Props) {
|
||||||
const { openSnack } = useSnackbar();
|
const { openSnack } = useSnackbar();
|
||||||
const [grpDevs, setGrpDevs] = useState<pond.ComprehensiveDevice[]>([]);
|
const [grpDevs, setGrpDevs] = useState<pond.ComprehensiveDevice[]>([]);
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [tablePage, setTablePage] = useState(0)
|
const loadLimit = 10
|
||||||
const [pageSize, setPageSize] = useState(10)
|
const [groupTotal, setGroupTotal] = useState(0)
|
||||||
|
|
||||||
const loadDevs = useCallback(() => {
|
const loadDevs = useCallback(() => {
|
||||||
groupAPI
|
groupAPI
|
||||||
.listGroupDevices(group.id(), 100, 0, "asc", undefined, true)
|
.listGroupDevices(group.id(), loadLimit, 0, "asc", undefined, true)
|
||||||
.then(resp => {
|
.then(resp => {
|
||||||
const groupDevices: pond.ComprehensiveDevice[] = or(
|
const groupDevices: pond.ComprehensiveDevice[] = or(
|
||||||
resp.data.comprehensiveDevices,
|
resp.data.comprehensiveDevices,
|
||||||
[]
|
[]
|
||||||
).map(d => pond.ComprehensiveDevice.fromObject(d));
|
).map(d => pond.ComprehensiveDevice.fromObject(d));
|
||||||
setGrpDevs(groupDevices);
|
setGrpDevs(groupDevices);
|
||||||
|
setGroupTotal(resp.data.total)
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
openSnack("Failed to get devices for group");
|
openSnack("Failed to get devices for group");
|
||||||
|
|
@ -174,21 +176,37 @@ export default function GroupDrawer(props: Props) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const drawerBody = () => {
|
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 (
|
return (
|
||||||
<Box>
|
<Box>
|
||||||
<ResponsiveTable<pond.ComprehensiveDevice>
|
<ResponsiveTable<pond.ComprehensiveDevice>
|
||||||
page={tablePage}
|
page={0}
|
||||||
pageSize={pageSize}
|
pageSize={loadLimit}
|
||||||
onRowClick={toDevice}
|
onRowClick={toDevice}
|
||||||
handleRowsPerPageChange={()=>{}}
|
total={groupTotal}
|
||||||
setPage={()=>{}}
|
|
||||||
total={0}
|
|
||||||
rows={grpDevs}
|
rows={grpDevs}
|
||||||
renderMobile={mobile}
|
renderMobile={mobile}
|
||||||
renderGutter={gutter}
|
renderGutter={gutter}
|
||||||
gutterPadding={0}
|
gutterPadding={0}
|
||||||
mobileView
|
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={()=>{}}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -371,7 +371,7 @@ export default function ObjectHeaterCard(props: Props) {
|
||||||
}else {
|
}else {
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<CardContent style={{ paddingLeft: 30, paddingRight: 30 }}>
|
<CardContent style={{ padding: 20 }}>
|
||||||
<Grid
|
<Grid
|
||||||
container
|
container
|
||||||
direction="row"
|
direction="row"
|
||||||
|
|
|
||||||
|
|
@ -1117,6 +1117,7 @@ export default function Bins(props: Props) {
|
||||||
<MenuItem
|
<MenuItem
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setOpenQrGenerator(true);
|
setOpenQrGenerator(true);
|
||||||
|
setBinMenuAnchorEl(null)
|
||||||
}}>
|
}}>
|
||||||
<Typography>Generate QR Codes</Typography>
|
<Typography>Generate QR Codes</Typography>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@ import { useGlobalState } from "providers";
|
||||||
import { useCallback, useEffect, useState } from "react";
|
import { useCallback, useEffect, useState } from "react";
|
||||||
import { downloadFile } from "utils/download";
|
import { downloadFile } from "utils/download";
|
||||||
import { or } from "utils/types";
|
import { or } from "utils/types";
|
||||||
|
import { cloneDeep } from "lodash";
|
||||||
|
|
||||||
const useStyles = makeStyles((theme: Theme) => {
|
const useStyles = makeStyles((theme: Theme) => {
|
||||||
const themeType = useThemeType()
|
const themeType = useThemeType()
|
||||||
|
|
@ -463,6 +464,22 @@ export default function Firmware() {
|
||||||
columns={columns(width === "xs" || width === "sm")}
|
columns={columns(width === "xs" || width === "sm")}
|
||||||
setPage={(page)=>{setTablePage(page)}}
|
setPage={(page)=>{setTablePage(page)}}
|
||||||
handleRowsPerPageChange={(e)=>{setPageSize(e.target.value)}}
|
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")
|
||||||
|
});
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
<UploadFirmware
|
<UploadFirmware
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ import { appendToUrl } from "navigation/Router";
|
||||||
import { getDeviceStateHelper } from "pbHelpers/DeviceState";
|
import { getDeviceStateHelper } from "pbHelpers/DeviceState";
|
||||||
import { makeStyles } from "@mui/styles";
|
import { makeStyles } from "@mui/styles";
|
||||||
import { blue, green } from "@mui/material/colors";
|
import { blue, green } from "@mui/material/colors";
|
||||||
|
import { cloneDeep } from "lodash";
|
||||||
|
|
||||||
const useStyles = makeStyles((theme: Theme) => {
|
const useStyles = makeStyles((theme: Theme) => {
|
||||||
return ({
|
return ({
|
||||||
|
|
@ -241,6 +242,36 @@ export default function GroupPage() {
|
||||||
onRowClick={toDevice}
|
onRowClick={toDevice}
|
||||||
setSearchText={setSearch}
|
setSearchText={setSearch}
|
||||||
isLoading={loadingDevices}
|
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)
|
||||||
|
})
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</PageContainer>
|
</PageContainer>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import { or } from "utils/types";
|
||||||
import PageContainer from "./PageContainer";
|
import PageContainer from "./PageContainer";
|
||||||
import GroupSettings from "group/GroupSettings";
|
import GroupSettings from "group/GroupSettings";
|
||||||
import { green } from "@mui/material/colors";
|
import { green } from "@mui/material/colors";
|
||||||
|
import { cloneDeep } from "lodash";
|
||||||
|
|
||||||
const useStyles = makeStyles((theme: Theme) => {
|
const useStyles = makeStyles((theme: Theme) => {
|
||||||
const isMobile = useMobile()
|
const isMobile = useMobile()
|
||||||
|
|
@ -163,6 +164,15 @@ export default function GroupsPage() {
|
||||||
isLoading={loading}
|
isLoading={loading}
|
||||||
setSearchText={setSearch}
|
setSearchText={setSearch}
|
||||||
onRowClick={handleRowClick}
|
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)
|
||||||
|
})
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
<GroupSettings
|
<GroupSettings
|
||||||
// initialGroup={selectedGroup}
|
// initialGroup={selectedGroup}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import DeviceLinkDrawer from "common/DeviceLinkDrawer";
|
||||||
import ResponsiveTable, { Column } from "common/ResponsiveTable";
|
import ResponsiveTable, { Column } from "common/ResponsiveTable";
|
||||||
//import { getTableIcons } from "common/ResponsiveTable";
|
//import { getTableIcons } from "common/ResponsiveTable";
|
||||||
import { useMobile } from "hooks";
|
import { useMobile } from "hooks";
|
||||||
|
import { cloneDeep } from "lodash";
|
||||||
//import MaterialTable from "material-table";
|
//import MaterialTable from "material-table";
|
||||||
import { Device } from "models";
|
import { Device } from "models";
|
||||||
import { ObjectHeater } from "models/ObjectHeater";
|
import { ObjectHeater } from "models/ObjectHeater";
|
||||||
|
|
@ -109,17 +110,19 @@ export default function Heaters() {
|
||||||
setPage={(page)=>{setTablePage(page)}}
|
setPage={(page)=>{setTablePage(page)}}
|
||||||
handleRowsPerPageChange={handleChange}
|
handleRowsPerPageChange={handleChange}
|
||||||
onRowClick={goToHeater}
|
onRowClick={goToHeater}
|
||||||
/>
|
loadMore={()=>{
|
||||||
)
|
let current = cloneDeep(heaters)
|
||||||
};
|
objectHeaterAPI
|
||||||
|
.listObjectHeatersPageData(pageSize, current.length, undefined, undefined, searchText, as)
|
||||||
const mobileList = () => {
|
.then(resp => {
|
||||||
return (
|
setHeaters(heaters.concat(resp.data.heaterData));
|
||||||
<List>
|
});
|
||||||
{heaters.map(h => (
|
}}
|
||||||
<ObjectHeaterCard
|
renderMobile={(row)=>{
|
||||||
key={h.heater?.key}
|
return (
|
||||||
heaterData={h}
|
<ObjectHeaterCard
|
||||||
|
key={row.heater?.key}
|
||||||
|
heaterData={row}
|
||||||
linkDevice={(heater, linkedDevices) => {
|
linkDevice={(heater, linkedDevices) => {
|
||||||
setHeaterToLink(heater);
|
setHeaterToLink(heater);
|
||||||
setOpenLinkDrawer(true);
|
setOpenLinkDrawer(true);
|
||||||
|
|
@ -131,9 +134,10 @@ export default function Heaters() {
|
||||||
setDevices(d);
|
setDevices(d);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
))}
|
)
|
||||||
</List>
|
}}
|
||||||
);
|
/>
|
||||||
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -180,7 +184,7 @@ export default function Heaters() {
|
||||||
}}
|
}}
|
||||||
pulse={heaters.length < 1}
|
pulse={heaters.length < 1}
|
||||||
/>
|
/>
|
||||||
{isMobile ? mobileList() : desktopTable()}
|
{desktopTable()}
|
||||||
</PageContainer>
|
</PageContainer>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ import ResponsiveTable, { Column } from "common/ResponsiveTable";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { or } from "utils";
|
import { or } from "utils";
|
||||||
import { useGlobalState } from "providers";
|
import { useGlobalState } from "providers";
|
||||||
|
import { cloneDeep } from "lodash";
|
||||||
|
|
||||||
interface MineRow {
|
interface MineRow {
|
||||||
mine: pond.Mine;
|
mine: pond.Mine;
|
||||||
|
|
@ -110,6 +111,24 @@ export default function Mines() {
|
||||||
hideKeys
|
hideKeys
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
onRowClick={onRowClick}
|
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);
|
||||||
|
});
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
<AddMine open={mineDialog} closeCallback={closeCallback} refreshCallback={load} />
|
<AddMine open={mineDialog} closeCallback={closeCallback} refreshCallback={load} />
|
||||||
</PageContainer>
|
</PageContainer>
|
||||||
|
|
|
||||||
|
|
@ -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 { Group } from "@mui/icons-material";
|
||||||
//import MaterialTable from "material-table";
|
//import MaterialTable from "material-table";
|
||||||
import { Site, User } from "models";
|
import { Site, User } from "models";
|
||||||
|
|
@ -12,6 +12,7 @@ import { useMobile } from "hooks";
|
||||||
import JobsiteIcon from "products/Construction/JobSiteIcon";
|
import JobsiteIcon from "products/Construction/JobSiteIcon";
|
||||||
import ResponsiveTable, { Column } from "common/ResponsiveTable";
|
import ResponsiveTable, { Column } from "common/ResponsiveTable";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import { cloneDeep } from "lodash";
|
||||||
|
|
||||||
interface SiteWithData {
|
interface SiteWithData {
|
||||||
site: Site;
|
site: Site;
|
||||||
|
|
@ -46,7 +47,7 @@ export default function Sites() {
|
||||||
.listSitesPageData(pageSize, tablePage * pageSize, "asc", "siteName", undefined, as)
|
.listSitesPageData(pageSize, tablePage * pageSize, "asc", "siteName", undefined, as)
|
||||||
.then(resp => {
|
.then(resp => {
|
||||||
setTotal(resp.data.total);
|
setTotal(resp.data.total);
|
||||||
buildTableData(resp.data.sites);
|
setSites(buildTableData(resp.data.sites));
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
|
|
@ -71,7 +72,7 @@ export default function Sites() {
|
||||||
data.push(newTableData);
|
data.push(newTableData);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
setSites([...data]);
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -186,6 +187,19 @@ export default function Sites() {
|
||||||
rows={sites}
|
rows={sites}
|
||||||
handleRowsPerPageChange={handleTablePage}
|
handleRowsPerPageChange={handleTablePage}
|
||||||
onRowClick={goToSite}
|
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);
|
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 = () => {
|
const mobileView = () => {
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
|
|
@ -297,6 +325,9 @@ export default function Sites() {
|
||||||
return siteCards;
|
return siteCards;
|
||||||
})}
|
})}
|
||||||
</TabPanelMine>
|
</TabPanelMine>
|
||||||
|
{sites.length < total &&
|
||||||
|
<Button onClick={loadMore} variant="contained" color="primary" fullWidth>Load More</Button>
|
||||||
|
}
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -112,7 +112,7 @@ export function dragerGasDongle(subtype: number = 0): ComponentTypeExtension {
|
||||||
excludedNodes?: number[]
|
excludedNodes?: number[]
|
||||||
): Summary[] => {
|
): Summary[] => {
|
||||||
//if it is O2 display percentage rather than ppm
|
//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[] = [];
|
let summaries: Summary[] = [];
|
||||||
measurements.measurementsFor.forEach(measurement => {
|
measurements.measurementsFor.forEach(measurement => {
|
||||||
let describer = describeMeasurement(
|
let describer = describeMeasurement(
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import { useGlobalState } from "providers";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import { or } from "utils/types";
|
import { or } from "utils/types";
|
||||||
import { dateRange } from "providers/http";
|
import { dateRange } from "providers/http";
|
||||||
|
import { getContextKeys, getContextTypes } from "pbHelpers/Context";
|
||||||
|
|
||||||
export interface IDeviceAPIContext {
|
export interface IDeviceAPIContext {
|
||||||
add: (name: string, description: string, backpack: pond.BackpackSettings, otherTeam?: string) => Promise<AxiosResponse<pond.AddDeviceResponse>>;
|
add: (name: string, description: string, backpack: pond.BackpackSettings, otherTeam?: string) => Promise<AxiosResponse<pond.AddDeviceResponse>>;
|
||||||
|
|
@ -725,8 +726,12 @@ export default function DeviceProvider(props: PropsWithChildren<Props>) {
|
||||||
};
|
};
|
||||||
|
|
||||||
const tag = (id: number, tag: string) => {
|
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<AxiosResponse>((resolve, reject) => {
|
return new Promise<AxiosResponse>((resolve, reject) => {
|
||||||
put(pondURL("/devices/" + id + "/tags/" + tag), {}).then(resp => {
|
put(pondURL(url), {}).then(resp => {
|
||||||
return resolve(resp)
|
return resolve(resp)
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
return reject(err)
|
return reject(err)
|
||||||
|
|
|
||||||
|
|
@ -33,8 +33,16 @@ export default function TagProvider(props: PropsWithChildren<Props>) {
|
||||||
const [{ as }] = useGlobalState()
|
const [{ as }] = useGlobalState()
|
||||||
|
|
||||||
const addTag = (tag: pond.TagSettings) => {
|
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<AxiosResponse>((resolve, reject) => {
|
return new Promise<AxiosResponse>((resolve, reject) => {
|
||||||
post(pondURL("/tags"), tag).then(resp => {
|
post(pondURL(url), tag).then(resp => {
|
||||||
return resolve(resp)
|
return resolve(resp)
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
return reject(err)
|
return reject(err)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue