implemented Add new Installation page for Sodiohome

This commit is contained in:
Yinyin Liu 2025-01-17 16:03:37 +01:00
parent 4116d4bd17
commit 63f60bdb3e
4 changed files with 282 additions and 9 deletions

View File

@ -0,0 +1,253 @@
import React, { useContext, useState } from 'react';
import {
Alert,
Box,
CircularProgress,
FormControl,
IconButton,
InputLabel,
MenuItem,
Modal,
Select,
TextField,
useTheme
} from '@mui/material';
import Button from '@mui/material/Button';
import { Close as CloseIcon } from '@mui/icons-material';
import { I_Installation } from 'src/interfaces/InstallationTypes';
import { InstallationsContext } from 'src/contexts/InstallationsContextProvider';
import { FormattedMessage } from 'react-intl';
interface SodiohomeInstallationFormProps {
cancel: () => void;
submit: () => void;
parentid: number;
}
function SodiohomeInstallationForm(props: SodiohomeInstallationFormProps) {
const theme = useTheme();
const [open, setOpen] = useState(true);
const [formValues, setFormValues] = useState<Partial<I_Installation>>({
name: '',
region: '',
location: '',
country: '',
serialNumber: ''
});
const requiredFields = ['name', 'location', 'country', 'serialNumber'];
const installationContext = useContext(InstallationsContext);
const { createInstallation, loading, setLoading, error, setError } =
installationContext;
const handleChange = (e) => {
const { name, value } = e.target;
setFormValues({
...formValues,
[name]: value
});
};
const handleSubmit = async (e) => {
setLoading(true);
formValues.parentId = props.parentid;
formValues.product = 2;
const responseData = await createInstallation(formValues);
props.submit();
};
const handleCancelSubmit = (e) => {
props.cancel();
};
const areRequiredFieldsFilled = () => {
for (const field of requiredFields) {
if (!formValues[field]) {
return false;
}
}
return true;
};
const isMobile = window.innerWidth <= 1490;
return (
<>
<Modal
open={open}
onClose={() => {}}
aria-labelledby="error-modal"
aria-describedby="error-modal-description"
>
<Box
sx={{
position: 'absolute',
top: isMobile ? '50%' : '40%',
left: '50%',
transform: 'translate(-50%, -50%)',
width: 500,
bgcolor: 'background.paper',
borderRadius: 4,
boxShadow: 24,
p: 4
}}
>
<Box
component="form"
sx={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center', // Center items horizontally
'& .MuiTextField-root': {
m: 1,
width: 390
}
}}
noValidate
autoComplete="off"
>
<div>
<TextField
label={
<FormattedMessage
id="installationName"
defaultMessage="Installation Name"
/>
}
name="name"
value={formValues.name}
onChange={handleChange}
required
error={formValues.name === ''}
/>
</div>
<div>
<TextField
label={<FormattedMessage id="region" defaultMessage="Region" />}
name="region"
value={formValues.region}
onChange={handleChange}
required
error={formValues.region === ''}
/>
</div>
<div>
<TextField
label={
<FormattedMessage id="location" defaultMessage="Location" />
}
name="location"
value={formValues.location}
onChange={handleChange}
required
error={formValues.location === ''}
/>
</div>
<div>
<TextField
label={
<FormattedMessage id="country" defaultMessage="Country" />
}
name="country"
value={formValues.country}
onChange={handleChange}
required
error={formValues.country === ''}
/>
</div>
<div>
<TextField
label={
<FormattedMessage id="serialNumber" defaultMessage="Serial Number" />
}
name="serialNumber"
value={formValues.serialNumber}
onChange={handleChange}
required
error={formValues.serialNumber === ''}
/>
</div>
<div>
<TextField
label={
<FormattedMessage
id="Information"
defaultMessage="Information"
/>
}
name="information"
value={formValues.information}
onChange={handleChange}
/>
</div>
</Box>
<div
style={{
display: 'flex',
alignItems: 'center',
marginTop: 10
}}
>
<Button
variant="contained"
onClick={handleSubmit}
sx={{
marginLeft: '20px'
}}
disabled={!areRequiredFieldsFilled()}
>
<FormattedMessage id="submit" defaultMessage="Submit" />
</Button>
<Button
variant="contained"
onClick={handleCancelSubmit}
sx={{
marginLeft: '10px'
}}
>
<FormattedMessage id="cancel" defaultMessage="Cancel" />
</Button>
{loading && (
<CircularProgress
sx={{
color: theme.palette.primary.main,
marginLeft: '20px'
}}
/>
)}
{error && (
<Alert
severity="error"
sx={{
ml: 1,
display: 'flex',
alignItems: 'center'
}}
>
<FormattedMessage
id="errorOccured"
defaultMessage="An error has occured"
/>
<IconButton
color="inherit"
size="small"
onClick={() => setError(false)}
sx={{ marginLeft: '4px' }}
>
<CloseIcon fontSize="small" />
</IconButton>
</Alert>
)}
</div>
</Box>
</Modal>
</>
);
}
export default SodiohomeInstallationForm;

View File

@ -23,6 +23,7 @@ import { InstallationsContext } from '../../../contexts/InstallationsContextProv
import { UserType } from '../../../interfaces/UserTypes'; import { UserType } from '../../../interfaces/UserTypes';
import SalidomoInstallationForm from '../SalidomoInstallations/SalidomoInstallationForm'; import SalidomoInstallationForm from '../SalidomoInstallations/SalidomoInstallationForm';
import { ProductIdContext } from '../../../contexts/ProductIdContextProvider'; import { ProductIdContext } from '../../../contexts/ProductIdContextProvider';
import SodiohomeInstallationForm from '../SodiohomeInstallations/SodiohomeInstallationForm';
interface TreeInformationProps { interface TreeInformationProps {
folder: I_Folder; folder: I_Folder;
@ -213,6 +214,14 @@ function TreeInformation(props: TreeInformationProps) {
parentid={props.folder.id} parentid={props.folder.id}
/> />
)} )}
{openModalInstallation && product == 2 && (
<SodiohomeInstallationForm
cancel={handleFormCancel}
submit={handleInstallationFormSubmit}
parentid={props.folder.id}
/>
)}
<Container maxWidth="xl"> <Container maxWidth="xl">
<Grid <Grid
container container

View File

@ -19,12 +19,12 @@ export const ProductIdContext = createContext<ProductIdContextType | undefined>(
); );
// Define the product mapping for dynamic assignment // Define the product mapping for dynamic assignment
const productMapping: { [key: string]: number } = { // const productMapping: { [key: string]: number } = {
salimax: 0, // salimax: 0,
salidomo: 1, // salidomo: 1,
sodiohome: 2, // sodiohome: 2,
// Additional mappings can be added here // // Additional mappings can be added here
}; // };
// Create a UserContextProvider component // Create a UserContextProvider component
export const ProductIdContextProvider = ({ export const ProductIdContextProvider = ({
@ -46,9 +46,19 @@ export const ProductIdContextProvider = ({
return storedValue === 'true'; return storedValue === 'true';
}); });
// const [product, setProduct] = useState(location.includes('salidomo') ? 1 : 0); // const [product, setProduct] = useState(location.includes('salidomo') ? 1 : 0);
const [product, setProduct] = useState<number>( // const [product, setProduct] = useState<number>(
productMapping[Object.keys(productMapping).find((key) => location.includes(key)) || ''] || -1 // productMapping[Object.keys(productMapping).find((key) => location.includes(key)) || ''] || -1
); // );
const [product, setProduct] = useState<number>(() => {
if (location.includes('salidomo')) {
return 1;
} else if (location.includes('sodiohome')) {
return 2;
} else {
return 0;
}
});
const changeProductId = (new_product: number) => { const changeProductId = (new_product: number) => {
setProduct(new_product); setProduct(new_product);
}; };

View File

@ -20,6 +20,7 @@ export interface I_Installation extends I_S3Credentials {
device: number; device: number;
testingMode?: boolean; testingMode?: boolean;
status?: number; status?: number;
serialNumber?: string;
} }
export interface I_Folder { export interface I_Folder {