-
Notifications
You must be signed in to change notification settings - Fork 3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2550 from FooQoo/feature/user-editable-statics-co…
…lumns Customization Feature for Percentile Display on Statistics Page
- Loading branch information
Showing
22 changed files
with
362 additions
and
87 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,3 +27,4 @@ __pycache__ | |
.sass-cache/ | ||
.env | ||
yarn-error.log | ||
.venv |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
118 changes: 59 additions & 59 deletions
118
locust/webui/dist/assets/index-ea7131ad.js → locust/webui/dist/assets/index-5a4a3f83.js
Large diffs are not rendered by default.
Oops, something went wrong.
2 changes: 1 addition & 1 deletion
2
...t/webui/dist/assets/index-ea7131ad.js.map → ...t/webui/dist/assets/index-5a4a3f83.js.map
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
57 changes: 57 additions & 0 deletions
57
locust/webui/src/components/ViewColumnSelector/ViewColumnSelector.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import { render, fireEvent, screen } from '@testing-library/react'; | ||
import { describe, expect, test, vi } from 'vitest'; | ||
|
||
import ViewColumnSelector from './ViewColumnSelector'; | ||
|
||
describe('ViewColumnSelector', () => { | ||
const mockStructure = [ | ||
{ key: 'column1', title: 'Column 1' }, | ||
{ key: 'column2', title: 'Column 2' }, | ||
]; | ||
const mockSelectedColumns = ['column1']; | ||
const mockAddColumn = vi.fn(); | ||
const mockRemoveColumn = vi.fn(); | ||
|
||
test('should render switches for each structure item', () => { | ||
render( | ||
<ViewColumnSelector | ||
addColumn={mockAddColumn} | ||
removeColumn={mockRemoveColumn} | ||
selectedColumns={mockSelectedColumns} | ||
structure={mockStructure} | ||
/>, | ||
); | ||
|
||
const button = screen.getByRole('button'); | ||
fireEvent.click(button); | ||
|
||
const switches = screen.getAllByRole('checkbox'); | ||
expect(switches.length).toEqual(mockStructure.length); | ||
}); | ||
|
||
test('should toggle switches correctly', () => { | ||
render( | ||
<ViewColumnSelector | ||
addColumn={mockAddColumn} | ||
removeColumn={mockRemoveColumn} | ||
selectedColumns={mockSelectedColumns} | ||
structure={mockStructure} | ||
/>, | ||
); | ||
|
||
const button = screen.getByRole('button'); | ||
fireEvent.click(button); | ||
|
||
// Initial state check: 'column1' should be on and 'column2' should be off | ||
const switch1 = screen.getByLabelText('Column 1'); | ||
const switch2 = screen.getByLabelText('Column 2'); | ||
|
||
// Click on 'column2' switch to add the column | ||
fireEvent.click(switch2); | ||
expect(mockAddColumn).toHaveBeenCalledWith('column2'); | ||
|
||
// Click on 'column1' switch to remove the column | ||
fireEvent.click(switch1); | ||
expect(mockRemoveColumn).toHaveBeenCalledWith('column1'); | ||
}); | ||
}); |
61 changes: 61 additions & 0 deletions
61
locust/webui/src/components/ViewColumnSelector/ViewColumnSelector.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import { useState } from 'react'; | ||
import ViewColumnIcon from '@mui/icons-material/ViewColumn'; | ||
import { Button, FormControlLabel, FormGroup, Popover, Stack, Switch } from '@mui/material'; | ||
|
||
import { ITableStructure } from 'types/table.types'; | ||
|
||
interface IViewColumnSelector { | ||
structure: ITableStructure[]; | ||
selectedColumns: string[]; | ||
addColumn: (column: string) => void; | ||
removeColumn: (column: string) => void; | ||
} | ||
|
||
function ViewColumnSelector({ | ||
structure, | ||
selectedColumns, | ||
addColumn, | ||
removeColumn, | ||
}: IViewColumnSelector) { | ||
const [anchorEl, setAnchorEl] = useState(null as HTMLButtonElement | null); | ||
|
||
return ( | ||
<Stack direction='row' justifyContent='end' my={2} spacing={1}> | ||
<Button onClick={event => setAnchorEl(event.currentTarget)} variant='outlined'> | ||
<ViewColumnIcon /> | ||
</Button> | ||
<Popover | ||
anchorEl={anchorEl} | ||
anchorOrigin={{ | ||
vertical: 'bottom', | ||
horizontal: 'left', | ||
}} | ||
onClose={() => setAnchorEl(null)} | ||
open={Boolean(anchorEl)} | ||
> | ||
<FormGroup sx={{ p: 2 }}> | ||
{structure.map(({ key, title }) => ( | ||
<FormControlLabel | ||
control={ | ||
<Switch | ||
checked={selectedColumns.includes(key)} | ||
onChange={() => { | ||
if (selectedColumns.includes(key)) { | ||
removeColumn(key); | ||
} else { | ||
addColumn(key); | ||
} | ||
}} | ||
/> | ||
} | ||
key={key} | ||
label={title} | ||
/> | ||
))} | ||
</FormGroup> | ||
</Popover> | ||
</Stack> | ||
); | ||
} | ||
|
||
export default ViewColumnSelector; |
59 changes: 59 additions & 0 deletions
59
locust/webui/src/hooks/tests/useSelecteViewColumns.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import { act, renderHook } from '@testing-library/react'; | ||
import { describe, expect, test } from 'vitest'; | ||
|
||
import useSelectViewColumns from 'hooks/useSelectViewColumns'; | ||
|
||
const mockStructure = [ | ||
{ title: 'Method', key: 'method' }, | ||
{ title: 'Name', key: 'name' }, | ||
{ title: '# Requests', key: 'numRequests' }, | ||
]; | ||
|
||
describe('useSelectViewColumns hook', () => { | ||
test('should initialize with default columns', () => { | ||
const { result } = renderHook(() => useSelectViewColumns(mockStructure)); | ||
|
||
expect(result.current.selectedColumns).toEqual(mockStructure.map(s => s.key)); | ||
}); | ||
|
||
test('should add a new column', () => { | ||
const { result } = renderHook(() => useSelectViewColumns(mockStructure)); | ||
|
||
act(() => { | ||
result.current.addColumn('column3'); | ||
}); | ||
|
||
expect(result.current.selectedColumns).toEqual([...mockStructure.map(s => s.key), 'column3']); | ||
}); | ||
|
||
test('should remove an existing column', () => { | ||
const { result } = renderHook(() => useSelectViewColumns(mockStructure)); | ||
|
||
act(() => { | ||
result.current.removeColumn('method'); | ||
}); | ||
|
||
expect(result.current.selectedColumns).toEqual(['name', 'numRequests']); | ||
}); | ||
|
||
test('filterStructure should filter out unselected columns', () => { | ||
const { result } = renderHook(() => useSelectViewColumns(mockStructure)); | ||
|
||
act(() => { | ||
// remove column with key 'method' | ||
result.current.removeColumn('method'); | ||
}); | ||
|
||
const filteredStructure = result.current.filteredStructure; | ||
|
||
// expect only columns with keys 'name' and 'numRequests' to be returned | ||
expect(filteredStructure.length).toBe(2); | ||
expect(filteredStructure).toEqual( | ||
expect.arrayContaining([ | ||
expect.objectContaining({ key: 'name' }), | ||
expect.objectContaining({ key: 'numRequests' }), | ||
]), | ||
); | ||
expect(filteredStructure).not.toContainEqual(expect.objectContaining({ key: 'method' })); | ||
}); | ||
}); |
Oops, something went wrong.