Fix/source options filters state (#320)

* Prevent mutating passed object

Causes the options to not get reset correctly and/or to get set without "submitting" them

* Always use local filter state instead of requested one

The local filter state sometimes got overwritten by the state from the server response.
This resulted in showing an incorrect filter state while still sending the correct one to the server when filtering

* Update text filter faster

The timeout (2.5s) is too long and can cause the filter state to not have been updated by the time the filters are getting submitted.
Thus, causing a request with outdated filters and requiring a "re-submit" for the actual filters to get used.
This commit is contained in:
schroda
2023-05-28 02:18:37 +02:00
committed by GitHub
parent f852255d82
commit 1480507c35
2 changed files with 13 additions and 21 deletions

View File

@@ -56,7 +56,7 @@ export function Options({ sourceFilter, group, updateFilterValue, update }: IFil
<CheckBoxFilter
key={`filters ${e.filter.name}`}
name={e.filter.name}
state={checkif === 'false' || (e.filter.state as boolean)}
state={checkif != null ? checkif === 'true' : (e.filter.state as boolean)}
position={index}
group={group}
updateFilterValue={updateFilterValue}
@@ -82,7 +82,7 @@ export function Options({ sourceFilter, group, updateFilterValue, update }: IFil
key={`filters ${e.filter.name}`}
name={e.filter.name}
values={e.filter.displayValues}
state={parseInt(checkif, 10) || (e.filter.state as number)}
state={checkif != null ? parseInt(checkif, 10) : (e.filter.state as number)}
selected={e.filter.selected}
position={index}
group={group}
@@ -98,7 +98,7 @@ export function Options({ sourceFilter, group, updateFilterValue, update }: IFil
key={`filters ${e.filter.name}`}
name={e.filter.name}
values={e.filter.values}
state={checkif ? JSON.parse(checkif) : (e.filter.state as IState)}
state={checkif ? JSON.parse(checkif) : { ...(e.filter.state as IState) }}
position={index}
group={group}
updateFilterValue={updateFilterValue}
@@ -110,7 +110,7 @@ export function Options({ sourceFilter, group, updateFilterValue, update }: IFil
<TextFilter
key={`filters ${e.filter.name}`}
name={e.filter.name}
state={checkif || (e.filter.state as string)}
state={checkif ?? (e.filter.state as string)}
position={index}
group={group}
updateFilterValue={updateFilterValue}
@@ -122,7 +122,7 @@ export function Options({ sourceFilter, group, updateFilterValue, update }: IFil
<TriStateFilter
key={`filters ${e.filter.name}`}
name={e.filter.name}
state={parseInt(checkif, 10) || (e.filter.state as number)}
state={checkif != null ? parseInt(checkif, 10) : (e.filter.state as number)}
position={index}
group={group}
updateFilterValue={updateFilterValue}

View File

@@ -8,7 +8,8 @@
import SearchIcon from '@mui/icons-material/Search';
import { FormControl, Input, InputAdornment, InputLabel } from '@mui/material';
import React from 'react';
import React, { useEffect } from 'react';
import { useDebounce } from 'components/manga/hooks';
interface Props {
state: string;
@@ -22,23 +23,14 @@ interface Props {
const TextFilter: React.FC<Props> = (props) => {
const { state, name, position, group, updateFilterValue, update } = props;
const [Search, setsearch] = React.useState(state || '');
let typingTimer: NodeJS.Timeout;
const inputText = useDebounce(Search, 500);
function doneTyping(e: React.ChangeEvent<HTMLInputElement>) {
useEffect(() => {
const upd = update.filter(
(el: { position: number; group: number | undefined }) => !(position === el.position && group === el.group),
);
updateFilterValue([...upd, { position, state: e.target.value, group }]);
}
function handleChange(e: React.ChangeEvent<HTMLInputElement>) {
setsearch(e.target.value);
clearTimeout(typingTimer);
typingTimer = setTimeout(() => {
doneTyping(e);
}, 2500);
}
updateFilterValue([...upd, { position, state: inputText, group }]);
}, [inputText]);
if (state !== undefined) {
return (
@@ -46,8 +38,8 @@ const TextFilter: React.FC<Props> = (props) => {
<InputLabel>{name}</InputLabel>
<Input
name={name}
value={Search || ''}
onChange={handleChange}
value={Search}
onChange={({ target: { value } }) => setsearch(value)}
endAdornment={
<InputAdornment position="end">
<SearchIcon />