Options panels refactoring (#196)

* Refactor library options to match chapter options using shared component

* Disable some eslint rules

* Cleanup SourceOptions layout to use same components as other panels
This commit is contained in:
Valter Martinek
2022-11-24 09:41:03 +01:00
committed by GitHub
parent 3972d7757f
commit 154b357c40
35 changed files with 625 additions and 685 deletions

View File

@@ -6,22 +6,21 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
import React from 'react';
import FilterListIcon from '@mui/icons-material/FilterList';
import {
Drawer, Button, Fab,
} from '@mui/material';
import { Button, Fab, Stack } from '@mui/material';
import { Box } from '@mui/system';
import SelectFilter from './filters/SelectFilter';
import OptionsPanel from 'components/molecules/OptionsPanel';
import React from 'react';
import CheckBoxFilter from './filters/CheckBoxFilter';
import HeaderFilter from './filters/HeaderFilter';
import SeperatorFilter from './filters/SeparatorFilter';
import SelectFilter from './filters/SelectFilter';
import SortFilter from './filters/SortFilter';
import TextFilter from './filters/TextFilter';
import TriStateFilter from './filters/TriStateFilter';
// this can only cycle once, so should be fine
// eslint-disable-next-line import/no-cycle
import GroupFilter from './filters/GroupFilter';
import SeperatorFilter from './filters/SeparatorFilter';
interface IFilters {
sourceFilter: ISourceFilters[]
@@ -46,7 +45,7 @@ export function Options({
update,
}: IFilters) {
return (
<Box key={`filters ${group}`}>
<Stack key={`filters ${group}`}>
{ sourceFilter.map((e: ISourceFilters, index) => {
let checkif = update.find((el: {
group: number | undefined; position: number;
@@ -145,7 +144,7 @@ export function Options({
return (<Box key={`${e.filter.name}null`} />);
}
})}
</Box>
</Stack>
);
}
@@ -182,17 +181,11 @@ export default function SourceOptions({
Filter
</Fab>
<Drawer
anchor="bottom"
<OptionsPanel
open={FilterOptions}
onClose={() => setFilterOptions(false)}
PaperProps={{
style: {
maxWidth: 600, padding: '1em', marginLeft: 'auto', marginRight: 'auto',
},
}}
>
<Box sx={{ display: 'flex' }}>
<Box sx={{ display: 'flex', p: 2, pb: 0 }}>
<Button
onClick={handleReset}
>
@@ -206,13 +199,20 @@ export default function SourceOptions({
Submit
</Button>
</Box>
<Options
sourceFilter={sourceFilter}
updateFilterValue={updateFilterValue}
group={undefined}
update={update}
/>
</Drawer>
<Box
sx={{
pb: 2,
mx: 2,
}}
>
<Options
sourceFilter={sourceFilter}
updateFilterValue={updateFilterValue}
group={undefined}
update={update}
/>
</Box>
</OptionsPanel>
</>
);
}

View File

@@ -5,9 +5,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
import CheckboxInput from 'components/atoms/CheckboxInput';
import React from 'react';
import { Box } from '@mui/system';
import { Checkbox, FormControlLabel } from '@mui/material';
interface Props {
state: boolean
@@ -18,7 +17,7 @@ interface Props {
update: any
}
export default function CheckBoxFilter(props: Props) {
const CheckBoxFilter: React.FC<Props> = (props: Props) => {
const {
state,
name,
@@ -39,20 +38,10 @@ export default function CheckBoxFilter(props: Props) {
if (state !== undefined) {
return (
<Box sx={{ display: 'flex', flexDirection: 'column', minWidth: 120 }}>
<FormControlLabel
key={name}
control={(
<Checkbox
name={name}
checked={val}
onChange={handleChange}
/>
)}
label={name}
/>
</Box>
<CheckboxInput label={name} checked={val} onChange={handleChange} />
);
}
return (<></>);
}
return null;
};
export default CheckBoxFilter;

View File

@@ -5,11 +5,12 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
import {
Collapse, List, ListItemButton, ListItemText,
} from '@mui/material';
import React from 'react';
import { ExpandLess, ExpandMore } from '@mui/icons-material';
import {
Collapse, ListItemButton, ListItemText, Stack,
} from '@mui/material';
import { Box } from '@mui/system';
import React from 'react';
// eslint-disable-next-line import/no-cycle
import { Options } from '../SourceOptions';
@@ -21,7 +22,7 @@ interface Props {
update: any
}
export default function GroupFilter(props: Props) {
const GroupFilter: React.FC<Props> = (props: Props) => {
const {
state,
name,
@@ -32,26 +33,25 @@ export default function GroupFilter(props: Props) {
const [open, setOpen] = React.useState(false);
const handleClick = () => {
setOpen(!open);
};
return (
<>
<ListItemButton onClick={handleClick}>
<Box sx={{ mx: -2 }}>
<ListItemButton onClick={() => setOpen(!open)}>
<ListItemText primary={name} />
{open ? <ExpandLess /> : <ExpandMore />}
</ListItemButton>
<Collapse in={open}>
<List disablePadding>
{/* Container is moved outside 2, so content has to go inside 4 */}
<Stack sx={{ mx: 4 }}>
<Options
sourceFilter={state}
group={position}
updateFilterValue={updateFilterValue}
update={update}
/>
</List>
</Stack>
</Collapse>
</>
</Box>
);
}
};
export default GroupFilter;

View File

@@ -6,14 +6,13 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
import { Typography } from '@mui/material';
import React from 'react';
import { Box } from '@mui/system';
interface Props {
name: string
}
export default function HeaderFilter(props: Props) {
const { name } = props;
return (<Box key={name}>{name}</Box>);
}
const HeaderFilter: React.FC<Props> = ({ name }) => (<Typography key={name} sx={{ mt: 2 }} variant="subtitle2">{name}</Typography>);
export default HeaderFilter;

View File

@@ -7,7 +7,6 @@
*/
import React from 'react';
import { Box } from '@mui/system';
import InputLabel from '@mui/material/InputLabel';
import FormControl from '@mui/material/FormControl';
import MenuItem from '@mui/material/MenuItem';
@@ -61,26 +60,22 @@ function hasSelect(
</MenuItem>
));
return (
<Box key={name} sx={{ display: 'flex', flexDirection: 'column', minWidth: 120 }}>
<FormControl fullWidth>
<InputLabel sx={{ margin: '10px 0 10px 0' }}>
{name}
</InputLabel>
<Select
name={name}
value={values[val].displayname}
label={name}
onChange={handleChange}
autoWidth
sx={{ margin: '10px 0 10px 0' }}
>
{rett}
</Select>
</FormControl>
</Box>
<FormControl sx={{ my: 1 }} variant="standard">
<InputLabel>
{name}
</InputLabel>
<Select
name={name}
value={values[val].displayname}
label={name}
onChange={handleChange}
>
{rett}
</Select>
</FormControl>
);
}
return (<></>);
return null;
}
function noSelect(
@@ -106,29 +101,25 @@ function noSelect(
const rett = values.map((value: string) => (<MenuItem key={`${name} ${value}`} value={value}>{value}</MenuItem>));
return (
<Box key={name} sx={{ display: 'flex', flexDirection: 'column', minWidth: 120 }}>
<FormControl fullWidth>
<InputLabel sx={{ margin: '10px 0 10px 0' }}>
{name}
</InputLabel>
<Select
name={name}
value={values[val]}
label={name}
onChange={handleChange}
autoWidth
sx={{ margin: '10px 0 10px 0' }}
>
{rett}
</Select>
</FormControl>
</Box>
<FormControl sx={{ my: 1 }} variant="standard">
<InputLabel>
{name}
</InputLabel>
<Select
name={name}
value={values[val]}
label={name}
onChange={handleChange}
>
{rett}
</Select>
</FormControl>
);
}
return (<></>);
return null;
}
export default function SelectFilter({
const SelectFilter: React.FC<Props> = ({
values,
name,
state,
@@ -137,7 +128,7 @@ export default function SelectFilter({
updateFilterValue,
update,
group,
}: Props) {
}) => {
if (selected === undefined) {
return noSelect(
values,
@@ -159,4 +150,6 @@ export default function SelectFilter({
update,
group,
);
}
};
export default SelectFilter;

View File

@@ -5,14 +5,13 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
import { Divider } from '@mui/material';
import React from 'react';
import { Box } from '@mui/system';
interface Props {
name: string
}
export default function SeperatorFilter(props: Props) {
const { name } = props;
return (<Box key={name}>{name}</Box>);
}
const SeparatorFilter: React.FC<Props> = ({ name }) => (<Divider key={name} sx={{ my: 1 }} textAlign="center">{name}</Divider>);
export default SeparatorFilter;

View File

@@ -5,18 +5,13 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
import React from 'react';
import { Box } from '@mui/system';
import FormControl from '@mui/material/FormControl';
import {
Collapse,
List,
ListItem,
ListItemButton, ListItemIcon, ListItemText,
} from '@mui/material';
import ArrowDownwardIcon from '@mui/icons-material/ArrowDownward';
import ArrowUpwardIcon from '@mui/icons-material/ArrowUpward';
import { ExpandLess, ExpandMore } from '@mui/icons-material';
import {
Collapse, ListItemButton, ListItemText, Stack,
} from '@mui/material';
import { Box } from '@mui/system';
import SortRadioInput from 'components/atoms/SortRadioInput';
import React from 'react';
interface Props {
values: any
@@ -28,7 +23,7 @@ interface Props {
update: any
}
export default function SortFilter(props: Props) {
const SortFilter: React.FC<Props> = (props: Props) => {
const {
values,
name,
@@ -47,8 +42,7 @@ export default function SortFilter(props: Props) {
};
if (values) {
const handleChange = (event:
React.MouseEvent<HTMLDivElement, MouseEvent>, index: number) => {
const handleChange = (index: number) => {
const tmp = val;
if (tmp.index === index) {
tmp.ascending = !tmp.ascending;
@@ -63,42 +57,29 @@ export default function SortFilter(props: Props) {
updateFilterValue([...upd, { position, state: JSON.stringify(tmp), group }]);
};
const ret = (
<FormControl fullWidth>
return (
<Box sx={{ mx: -2 }}>
<ListItemButton onClick={handleClick}>
<ListItemText primary={name} />
{open ? <ExpandLess /> : <ExpandMore />}
</ListItemButton>
<Collapse in={open}>
<List>
{values.map((value: string, index: number) => {
let icon;
if (val.index === index) {
icon = val.ascending ? (<ArrowUpwardIcon color="primary" />)
: (<ArrowDownwardIcon color="primary" />);
}
return (
<ListItem disablePadding key={`${name} ${value}`}>
<ListItemButton
onClick={(event) => handleChange(event, index)}
>
<ListItemIcon>
{icon}
</ListItemIcon>
<ListItemText primary={value} />
</ListItemButton>
</ListItem>
);
})}
</List>
<Stack sx={{ mx: 4 }}>
{values.map((value: string, index: number) => (
<SortRadioInput
key={`${name} ${value}`}
label={value}
checked={val.index === index}
sortDescending={!val.ascending}
onClick={() => handleChange(index)}
/>
))}
</Stack>
</Collapse>
</FormControl>
);
return (
<Box key={name} sx={{ display: 'flex', flexDirection: 'column', minWidth: 120 }}>
{ret}
</Box>
);
}
return (<></>);
}
return null;
};
export default SortFilter;

View File

@@ -5,14 +5,11 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
import React from 'react';
import { Box } from '@mui/system';
import {
Input,
InputLabel,
FormControl,
} from '@mui/material';
import SearchIcon from '@mui/icons-material/Search';
import {
FormControl, Input, InputAdornment, InputLabel,
} from '@mui/material';
import React from 'react';
interface Props {
state: string
@@ -23,7 +20,7 @@ interface Props {
update: any
}
export default function TextFilter(props: Props) {
const TextFilter: React.FC<Props> = (props) => {
const {
state,
name,
@@ -51,27 +48,24 @@ export default function TextFilter(props: Props) {
if (state !== undefined) {
return (
<Box key={`${name}`} sx={{ display: 'flex', flexDirection: 'row', minWidth: 120 }}>
<>
<SearchIcon
sx={{
margin: 'auto',
}}
/>
<FormControl fullWidth>
<InputLabel sx={{ margin: '10px 0 10px 0' }}>
{name}
</InputLabel>
<Input
name={name}
value={Search || ''}
onChange={handleChange}
sx={{ margin: '10px 0 10px 0' }}
/>
</FormControl>
</>
</Box>
<FormControl sx={{ my: 1 }} variant="standard">
<InputLabel>
{name}
</InputLabel>
<Input
name={name}
value={Search || ''}
onChange={handleChange}
endAdornment={(
<InputAdornment position="end">
<SearchIcon />
</InputAdornment>
)}
/>
</FormControl>
);
}
return (<></>);
}
};
export default TextFilter;

View File

@@ -5,10 +5,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
import ThreeStateCheckboxInput from 'components/atoms/ThreeStateCheckboxInput';
import React from 'react';
import { Box } from '@mui/system';
import { FormControlLabel } from '@mui/material';
import ThreeStateCheckbox from 'components/util/ThreeStateCheckbox';
interface Props {
state: number
@@ -19,7 +17,7 @@ interface Props {
update: any
}
export default function TriStateFilter(props: Props) {
const TriStateFilter: React.FC<Props> = (props) => {
const {
state,
name,
@@ -28,48 +26,32 @@ export default function TriStateFilter(props: Props) {
updateFilterValue,
update,
} = props;
const [val, setval] = React.useState({
[name]: state,
});
const [val, setval] = React.useState<number>(Number(state));
const handleChange = (checked: boolean | null | undefined) => {
const tmp = val;
if (checked !== undefined) {
tmp[name] = checked ? 1 : 2;
} else {
delete tmp[name];
}
setval({
...tmp,
});
// eslint-disable-next-line no-nested-ternary
const newState = checked === undefined ? 0 : checked ? 1 : 2;
setval(newState);
const upd = update.filter((e: {
position: number; group: number | undefined;
}) => !(position === e.position && group === e.group));
updateFilterValue([...upd, {
position,
state: (tmp[name] === undefined ? 0 : tmp[name]).toString(),
state: newState.toString(),
group,
}]);
};
if (state !== undefined) {
let check;
if (val[name] !== 0) {
check = val[name] === 1;
} else {
check = undefined;
}
return (
<Box sx={{ marginLeft: 3 }}>
<FormControlLabel
key={name}
control={(
<ThreeStateCheckbox name="Unread" checked={check} onChange={(checked) => handleChange(checked)} />
)}
label={name}
/>
</Box>
<ThreeStateCheckboxInput
label={name}
checked={[undefined, true, false][val]}
onChange={(checked) => handleChange(checked)}
/>
);
}
return (<></>);
}
};
export default TriStateFilter;