Skip to content

Commit

Permalink
Merge pull request #2932 from andrewbaldwin44/bugfix/edit-form-errors
Browse files Browse the repository at this point in the history
Allow alerts and errors on new and edit form
  • Loading branch information
cyberw authored Oct 9, 2024
2 parents 9477459 + 7529d7c commit 3a1771d
Show file tree
Hide file tree
Showing 12 changed files with 140 additions and 241 deletions.
1 change: 0 additions & 1 deletion locust/webui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@
"jsdom": "^25.0.1",
"msw": "^2.4.9",
"prettier": "^3.0.3",
"rollup": "^4.22.4",
"typescript": "^5.2.2",
"vitest": "^0.34.6",
"vitest-webgl-canvas-mock": "^1.1.0"
Expand Down
8 changes: 4 additions & 4 deletions locust/webui/src/components/Modal/Modal.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import CloseIcon from '@mui/icons-material/Close';
import { Box, IconButton, Modal as MuiModal } from '@mui/material';
import { Container, IconButton, Modal as MuiModal } from '@mui/material';

interface IModal {
open: boolean;
Expand All @@ -10,13 +10,13 @@ interface IModal {
export default function Modal({ open, onClose, children }: IModal) {
return (
<MuiModal onClose={onClose} open={open}>
<Box
<Container
maxWidth='md'
sx={{
position: 'absolute',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
width: 'md',
maxHeight: '90vh',
overflowY: 'auto',
display: 'flex',
Expand All @@ -37,7 +37,7 @@ export default function Modal({ open, onClose, children }: IModal) {
<CloseIcon />
</IconButton>
{children}
</Box>
</Container>
</MuiModal>
);
}
6 changes: 3 additions & 3 deletions locust/webui/src/components/StateButtons/EditButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import { useState } from 'react';
import { Button } from '@mui/material';

import Modal from 'components/Modal/Modal';
import SwarmEditForm from 'components/SwarmForm/SwarmEditForm';
import SwarmForm, { ISwarmFormProps } from 'components/SwarmForm/SwarmForm';

export default function EditButton() {
export default function EditButton(swarmFormProps: ISwarmFormProps) {
const [open, setOpen] = useState(false);

return (
Expand All @@ -13,7 +13,7 @@ export default function EditButton() {
Edit
</Button>
<Modal onClose={() => setOpen(false)} open={open}>
<SwarmEditForm onSubmit={() => setOpen(false)} />
<SwarmForm {...swarmFormProps} isEditSwarm onFormSubmit={() => setOpen(false)} />
</Modal>
</>
);
Expand Down
6 changes: 3 additions & 3 deletions locust/webui/src/components/StateButtons/NewTestButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import { useState } from 'react';
import { Button } from '@mui/material';

import Modal from 'components/Modal/Modal';
import SwarmForm from 'components/SwarmForm/SwarmForm';
import SwarmForm, { ISwarmFormProps } from 'components/SwarmForm/SwarmForm';

export default function NewTestButton() {
export default function NewTestButton(swarmFormProps: ISwarmFormProps) {
const [open, setOpen] = useState(false);

return (
Expand All @@ -13,7 +13,7 @@ export default function NewTestButton() {
New
</Button>
<Modal onClose={() => setOpen(false)} open={open}>
<SwarmForm />
<SwarmForm {...swarmFormProps} />
</Modal>
</>
);
Expand Down
61 changes: 0 additions & 61 deletions locust/webui/src/components/SwarmForm/SwarmEditForm.tsx

This file was deleted.

89 changes: 54 additions & 35 deletions locust/webui/src/components/SwarmForm/SwarmForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,17 @@ interface IDispatchProps {
setSwarm: (swarmPayload: Partial<ISwarmState>) => void;
}

export interface ISwarmFormProps {
alert?: {
level?: AlertColor;
message: string;
};
isDisabled?: boolean;
isEditSwarm?: boolean;
onFormChange?: (formData: React.ChangeEvent<HTMLFormElement>) => void;
onFormSubmit?: (inputData: ISwarmFormInput) => void;
}

interface ISwarmForm
extends IDispatchProps,
Pick<
Expand All @@ -43,14 +54,9 @@ interface ISwarmForm
| 'showUserclassPicker'
| 'spawnRate'
| 'numUsers'
> {
alert?: {
level?: AlertColor;
message: string;
};
isDisabled?: boolean;
onFormChange?: (formData: React.ChangeEvent<HTMLFormElement>) => void;
}
| 'userCount'
>,
ISwarmFormProps {}

function SwarmForm({
availableShapeClasses,
Expand All @@ -59,14 +65,17 @@ function SwarmForm({
extraOptions,
isShape,
numUsers,
userCount,
overrideHostWarning,
runTime,
setSwarm,
showUserclassPicker,
spawnRate,
alert,
isDisabled = false,
isEditSwarm = false,
onFormChange,
onFormSubmit,
}: ISwarmForm) {
const [startSwarm] = useStartSwarmMutation();
const [errorMessage, setErrorMessage] = useState('');
Expand All @@ -84,11 +93,15 @@ function SwarmForm({
host: inputData.host || host,
runTime: inputData.runTime,
spawnRate: Number(inputData.spawnRate) || null,
numUsers: Number(inputData.userCount) || null,
userCount: Number(inputData.userCount),
});
} else {
setErrorMessage(data ? data.message : 'An unknown error occured.');
}

if (onFormSubmit) {
onFormSubmit(inputData);
}
};

const handleSwarmFormChange = (formEvent: React.ChangeEvent<HTMLFormElement>) => {
Expand All @@ -104,9 +117,9 @@ function SwarmForm({
return (
<Container maxWidth='md' sx={{ my: 2 }}>
<Typography component='h2' noWrap variant='h6'>
Start new load test
{isEditSwarm ? 'Edit running load test' : 'Start new load test'}
</Typography>
{showUserclassPicker && (
{!isEditSwarm && showUserclassPicker && (
<Box marginBottom={2} marginTop={2}>
<SwarmUserClassPicker
availableUserClasses={availableUserClasses}
Expand All @@ -125,11 +138,11 @@ function SwarmForm({
rowGap: 4,
}}
>
{showUserclassPicker && (
{!isEditSwarm && showUserclassPicker && (
<Select label='Shape Class' name='shapeClass' options={availableShapeClasses} />
)}
<TextField
defaultValue={(isShape && '-') || numUsers || 1}
defaultValue={(isShape && '-') || userCount || numUsers || 1}
disabled={!!isShape}
label='Number of users (peak concurrency)'
name='userCount'
Expand All @@ -141,36 +154,40 @@ function SwarmForm({
name='spawnRate'
title='Disabled for tests using LoadTestShape class'
/>
<TextField
defaultValue={host}
label={`Host ${
overrideHostWarning
? '(setting this will override the host for the User classes)'
: ''
}`}
name='host'
title='Disabled for tests using LoadTestShape class'
/>
<Accordion>
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
<Typography>Advanced options</Typography>
</AccordionSummary>
<AccordionDetails>
{!isEditSwarm && (
<>
<TextField
defaultValue={runTime}
label='Run time (e.g. 20, 20s, 3m, 2h, 1h20m, 3h30m10s, etc.)'
name='runTime'
sx={{ width: '100%' }}
defaultValue={host}
label={`Host ${
overrideHostWarning
? '(setting this will override the host for the User classes)'
: ''
}`}
name='host'
title='Disabled for tests using LoadTestShape class'
/>
</AccordionDetails>
</Accordion>
<Accordion>
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
<Typography>Advanced options</Typography>
</AccordionSummary>
<AccordionDetails>
<TextField
defaultValue={runTime}
label='Run time (e.g. 20, 20s, 3m, 2h, 1h20m, 3h30m10s, etc.)'
name='runTime'
sx={{ width: '100%' }}
/>
</AccordionDetails>
</Accordion>
</>
)}
{!isEmpty(extraOptions) && <CustomParameters extraOptions={extraOptions} />}
{alert && !errorMessage && (
<Alert severity={alert.level || 'info'}>{alert.message}</Alert>
)}
{errorMessage && <Alert severity={'error'}>{errorMessage}</Alert>}
<Button disabled={isDisabled} size='large' type='submit' variant='contained'>
Start
{isEditSwarm ? 'Update' : 'Start'}
</Button>
</Box>
</Form>
Expand All @@ -186,6 +203,7 @@ const storeConnector = ({
isShape,
host,
numUsers,
userCount,
overrideHostWarning,
runTime,
spawnRate,
Expand All @@ -200,6 +218,7 @@ const storeConnector = ({
overrideHostWarning,
showUserclassPicker,
numUsers,
userCount,
runTime,
spawnRate,
});
Expand Down
52 changes: 0 additions & 52 deletions locust/webui/src/components/SwarmForm/tests/SwarmEditForm.test.tsx

This file was deleted.

1 change: 1 addition & 0 deletions locust/webui/src/lib.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export { default as NewTestButton } from 'components/StateButtons/NewTestButton'
export { default as ResetButton } from 'components/StateButtons/ResetButton';
export { default as StopButton } from 'components/StateButtons/StopButton';
export { default as Logo } from 'assets/Logo';
export { default as Modal } from 'components/Modal/Modal';
export { default as useCreateTheme } from 'hooks/useCreateTheme';
export { tabConfig } from 'components/Tabs/Tabs.constants';
export { store as locustStore } from 'redux/store';
Expand Down
Loading

0 comments on commit 3a1771d

Please sign in to comment.