added tons of files for component functionality; manual component adding added temporarily

This commit is contained in:
Carter 2025-02-11 16:31:03 -06:00
parent 58830d480e
commit 45ff49bcea
121 changed files with 25883 additions and 65 deletions

417
src/fans/fanPicker.tsx Normal file
View file

@ -0,0 +1,417 @@
import {
Grid,
Button,
Typography,
DialogTitle,
DialogContent,
DialogActions,
Select,
MenuItem,
Switch,
FormControlLabel,
RadioGroup,
Radio,
Box
} from "@material-ui/core";
import { blue } from "@material-ui/core/colors";
import ResponsiveDialog from "common/ResponsiveDialog";
import React, { useState, useEffect } from "react";
import fans from "fans/fans_client.json";
import SearchSelect, { Option } from "common/SearchSelect";
import { pond } from "protobuf-ts/pond";
import { getFanIcon } from "pbHelpers/Fan";
interface Props {
fanID?: number;
useCardView?: boolean;
updateFan: (fanID: number) => void;
}
interface Fan {
id: number;
name: string;
kind: string;
horsepower: number;
}
export default function FanPicker(props: Props) {
const { fanID, useCardView, updateFan } = props;
const [openSelector, setOpenSelector] = useState(false);
const [fanMap, setFanMap] = useState<Map<number, Fan>>(new Map<number, Fan>());
const [genericFans, setGenericFans] = useState<Fan[]>([]);
const [hpOptions, setHPOptions] = useState<number[]>([]);
const [currentHP, setCurrentHP] = useState<number>(0);
const [fanTypes, setFanTypes] = useState<string[]>([]);
const [genericTypes, setGenericTypes] = useState<string[]>([]);
const [currentType, setCurrentType] = useState<string>("");
const [useAdvanced, setUseAdvanced] = useState(false);
const [fanOptions, setFanOptions] = useState<Option[]>([]);
const [selectedFan, setSelectedFan] = useState<Option | null>();
const [displayFan, setDisplayFan] = useState<string>("");
useEffect(() => {
let newMap: Map<number, Fan> = new Map<number, Fan>();
let initialTypes: string[] = [];
let initialHP: number[] = [];
let initialFanOptions: Option[] = [];
fans["bulk"].forEach(fan => {
newMap.set(fan.id, fan);
initialFanOptions.push({
value: fan.id,
label:
fan.name +
(fan.rpm !== 0 ? " " + fan.rpm + " rpm " : "") +
" " +
fan.horsepower +
"Hp " +
fan.kind
});
if (!initialTypes.includes(fan.kind) && fan.kind !== "axial" && fan.kind !== "centrifugal") {
initialTypes.push(fan.kind);
}
if (!initialHP.includes(fan.horsepower)) {
initialHP.push(fan.horsepower);
}
});
//set the options for the advanced selector
setFanMap(newMap);
initialHP.sort((a, b) => a - b);
setHPOptions(initialHP);
setFanOptions(initialFanOptions);
setFanTypes(initialTypes);
setGenericFans(fans["generic"]);
let gTypes: string[] = [];
fans["generic"].forEach(fan => {
if (!gTypes.includes(fan.kind)) {
gTypes.push(fan.kind);
}
});
//set the options for the simple picker NOTE: horsepower options are determined when a fan option is selected
setGenericTypes(gTypes);
if (fanID) {
let fanName = newMap.get(fanID)?.name;
setDisplayFan(fanName ? fanName : "No Fan Selected");
}
}, [fanID]);
//if we are using card view there will be no confirm button so when the selected fan changes call the update fan function
useEffect(() => {
if (useCardView) {
updateFan(selectedFan?.value);
//setDisplayFan(selectedFan?.label ?? "No Fan Selected");
}
}, [selectedFan, useCardView, updateFan]);
const closeSelector = () => {
setUseAdvanced(false);
setOpenSelector(false);
};
const determineBaseType = (type: string) => {
if (type === "axial(high speed)" || type === "axial(low speed)") {
return "axial";
} else {
return "centrifugal";
}
};
const findHPOptions = (type: string, generic?: boolean) => {
let ops: number[] = [];
let baseType = determineBaseType(type);
let list = Array.from(fanMap.values());
if (generic) {
list = genericFans;
}
list.forEach(fan => {
if ((fan.kind === type || fan.kind === baseType) && !ops.includes(fan.horsepower)) {
ops.push(fan.horsepower);
}
});
setHPOptions(ops);
};
//feel like there is a better way to do this but cant think of it at the moment
const filterOptions = (type: string, hp: number) => {
let filteredOps: Option[] = [];
let baseType = determineBaseType(type);
if (hp > 0 && type === "") {
fans["bulk"].forEach(fan => {
if (fan.horsepower === hp) {
filteredOps.push({
value: fan.id,
label: fan.name + (fan.rpm !== 0 ? " " + fan.rpm + " rpm " : "") + " " + fan.kind
});
}
});
} else if (hp === 0 && type !== "") {
fans["bulk"].forEach(fan => {
if (fan.kind === type || fan.kind === baseType) {
filteredOps.push({
value: fan.id,
label:
fan.name +
(fan.rpm !== 0 ? " " + fan.rpm + " rpm " : "") +
" " +
fan.horsepower +
"Hp"
});
}
});
} else {
fans["bulk"].forEach(fan => {
if ((fan.kind === type || fan.kind === baseType) && fan.horsepower === hp) {
filteredOps.push({
value: fan.id,
label: fan.name + (fan.rpm !== 0 ? " " + fan.rpm + " rpm " : "")
});
}
});
}
setFanOptions(filteredOps);
};
const findGenericFan = (hp: number) => {
genericFans.forEach(fan => {
if (fan.horsepower === hp && fan.kind === currentType) {
setSelectedFan({ label: fan.name, value: fan.id });
}
});
};
const determineFanIcon = (type: string) => {
if (type === "axial(high speed)" || type === "axial(low speed)") {
return getFanIcon(pond.FanType.FAN_TYPE_CENTRIFUGAL_INLINE);
} else {
return getFanIcon(pond.FanType.FAN_TYPE_CENTRIFUGAL_HIGH_SPEED);
}
};
const simpleSelector = () => {
return (
<React.Fragment>
<RadioGroup
value={currentType}
onChange={(_, value) => {
setCurrentType(value);
findHPOptions(value, true);
}}>
{genericTypes.map(type => (
<Grid
alignItems="center"
container
direction="row"
justify="space-between"
key={type}
style={{ marginTop: 20 }}>
<Grid item>
<FormControlLabel value={type} control={<Radio />} label={type} />
</Grid>
<Grid item>
<img width={100} height={100} src={determineFanIcon(type)} alt="fanimg" />
</Grid>
</Grid>
))}
</RadioGroup>
<Select
id="horsepower"
fullWidth
label="Horsepower"
displayEmpty
value={currentHP}
onChange={e => {
let value = e.target.value as number;
setCurrentHP(value);
findGenericFan(value);
}}>
<MenuItem key={0} value={0}>
Select Horsepower
</MenuItem>
{hpOptions.map(op => (
<MenuItem key={op} value={op}>
{op} Hp
</MenuItem>
))}
</Select>
</React.Fragment>
);
};
const advancedSelector = () => {
return (
<React.Fragment>
<Grid
container
direction="row"
justify="space-between"
style={{ marginBottom: 10, marginTop: 10 }}>
<Grid item xs={5}>
<Select
id="fantype"
fullWidth
label="Fan Type"
displayEmpty
value={currentType}
onChange={e => {
let value = e.target.value as string;
setCurrentType(value);
filterOptions(value, currentHP);
findHPOptions(value);
}}>
<MenuItem key={""} value={""}>
Select Fan Type
</MenuItem>
{fanTypes.map(op => (
<MenuItem key={op} value={op}>
{op}
</MenuItem>
))}
</Select>
</Grid>
<Grid item xs={5}>
<Select
id="horsepower"
fullWidth
label="Horsepower"
displayEmpty
value={currentHP}
onChange={e => {
let value = e.target.value as number;
setCurrentHP(value);
filterOptions(currentType, value);
}}>
<MenuItem key={0} value={0}>
Select Horsepower
</MenuItem>
{hpOptions.map(op => (
<MenuItem key={op} value={op}>
{op} Hp
</MenuItem>
))}
</Select>
</Grid>
</Grid>
<SearchSelect
selected={selectedFan}
changeSelection={(option: Option | null) => {
setSelectedFan(option);
}}
options={fanOptions}
label="Fan"
loading={false}
/>
</React.Fragment>
);
};
const selector = () => {
return (
<ResponsiveDialog
open={openSelector}
onClose={() => {
closeSelector();
}}
fullWidth>
<DialogTitle>
<Grid container direction="row" justify="space-between">
<Grid item>Select Fan</Grid>
<Grid item>
<FormControlLabel
control={
<Switch
value={useAdvanced}
title="Use Advance Selector"
onClick={() => {
setUseAdvanced(!useAdvanced);
setCurrentType("");
setCurrentHP(0);
setSelectedFan(null);
}}
/>
}
label="Use Advanced Selector"
labelPlacement="start"
/>
</Grid>
</Grid>
</DialogTitle>
<DialogContent>{useAdvanced ? advancedSelector() : simpleSelector()}</DialogContent>
<DialogActions>
<Button
onClick={() => {
closeSelector();
}}>
Cancel
</Button>
<Button
onClick={() => {
updateFan(selectedFan?.value);
setDisplayFan(selectedFan?.label ?? "No Fan Selected");
closeSelector();
}}>
Confirm
</Button>
</DialogActions>
</ResponsiveDialog>
);
};
const dialogView = () => {
return (
<React.Fragment>
{selector()}
<Grid container direction="row" alignItems="center">
<Grid item xs={3}>
<Button
onClick={() => {
setOpenSelector(true);
}}
style={{ background: blue["500"] }}
variant="contained">
FanPicker
</Button>
</Grid>
<Grid item xs={9}>
<Typography>{displayFan}</Typography>
</Grid>
</Grid>
</React.Fragment>
);
};
const cardView = () => {
return (
<React.Fragment>
<Box padding={2}>
<Typography style={{ fontSize: 15 }}>Current Fan</Typography>
<Typography style={{ fontWeight: 650, fontSize: 20 }}>{displayFan}</Typography>
<Grid container direction="row-reverse" justify="space-between">
<Grid item>
<FormControlLabel
control={
<Switch
value={useAdvanced}
title="Use Advance Selector"
onClick={() => {
setUseAdvanced(!useAdvanced);
setCurrentType("");
setCurrentHP(0);
setSelectedFan(null);
}}
/>
}
label="Use Advanced Selector"
labelPlacement="start"
/>
</Grid>
</Grid>
{useAdvanced ? advancedSelector() : simpleSelector()}
</Box>
</React.Fragment>
);
};
return useCardView ? cardView() : dialogView();
}

3130
src/fans/fans_client.json Normal file

File diff suppressed because it is too large Load diff