diff --git a/ui/v2.5/src/components/List/CriterionEditor.tsx b/ui/v2.5/src/components/List/CriterionEditor.tsx index fdf5bcad7..e35ba50c2 100644 --- a/ui/v2.5/src/components/List/CriterionEditor.tsx +++ b/ui/v2.5/src/components/List/CriterionEditor.tsx @@ -77,17 +77,15 @@ const GenericCriterionEditor: React.FC = ({ return ( - {modifierOptions.map((c) => ( + {modifierOptions.map((m) => ( ))} diff --git a/ui/v2.5/src/components/List/Filters/PerformersFilter.tsx b/ui/v2.5/src/components/List/Filters/PerformersFilter.tsx index 8d056af0d..483cb7400 100644 --- a/ui/v2.5/src/components/List/Filters/PerformersFilter.tsx +++ b/ui/v2.5/src/components/List/Filters/PerformersFilter.tsx @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useMemo } from "react"; import { PerformersCriterion } from "src/models/list-filter/criteria/performers"; import { useFindPerformersQuery } from "src/core/generated-graphql"; import { ObjectsFilter } from "./SelectableFilter"; @@ -9,7 +9,7 @@ interface IPerformersFilter { } function usePerformerQuery(query: string) { - const results = useFindPerformersQuery({ + const { data, loading } = useFindPerformersQuery({ variables: { filter: { q: query, @@ -18,14 +18,18 @@ function usePerformerQuery(query: string) { }, }); - return ( - results.data?.findPerformers.performers.map((p) => { - return { - id: p.id, - label: p.name, - }; - }) ?? [] + const results = useMemo( + () => + data?.findPerformers.performers.map((p) => { + return { + id: p.id, + label: p.name, + }; + }) ?? [], + [data] ); + + return { results, loading }; } const PerformersFilter: React.FC = ({ @@ -36,7 +40,7 @@ const PerformersFilter: React.FC = ({ ); }; diff --git a/ui/v2.5/src/components/List/Filters/SelectableFilter.tsx b/ui/v2.5/src/components/List/Filters/SelectableFilter.tsx index 48caccb16..2c13eb57e 100644 --- a/ui/v2.5/src/components/List/Filters/SelectableFilter.tsx +++ b/ui/v2.5/src/components/List/Filters/SelectableFilter.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useMemo, useState } from "react"; +import React, { useCallback, useEffect, useMemo, useState } from "react"; import { Button, Form } from "react-bootstrap"; import { Icon } from "src/components/Shared/Icon"; import { @@ -14,7 +14,7 @@ import { ILabeledId, ILabeledValueListValue, } from "src/models/list-filter/types"; -import { cloneDeep, debounce } from "lodash-es"; +import { cloneDeep } from "lodash-es"; import { Criterion, IHierarchicalLabeledIdCriterion, @@ -22,6 +22,8 @@ import { import { defineMessages, MessageDescriptor, useIntl } from "react-intl"; import { CriterionModifier } from "src/core/generated-graphql"; import { keyboardClickHandler } from "src/utils/keyboard"; +import { useDebouncedSetState } from "src/hooks/debounce"; +import useFocus from "src/utils/focus"; interface ISelectedItem { item: ILabeledId; @@ -77,40 +79,29 @@ const SelectedItem: React.FC = ({ interface ISelectableFilter { query: string; - setQuery: (query: string) => void; - single: boolean; - includeOnly: boolean; + onQueryChange: (query: string) => void; + modifier: CriterionModifier; + inputFocus: ReturnType; + canExclude: boolean; queryResults: ILabeledId[]; selected: ILabeledId[]; excluded: ILabeledId[]; - onSelect: (value: ILabeledId, include: boolean) => void; + onSelect: (value: ILabeledId, exclude: boolean) => void; onUnselect: (value: ILabeledId) => void; } const SelectableFilter: React.FC = ({ query, - setQuery, - single, + onQueryChange, + modifier, + inputFocus, + canExclude, queryResults, selected, excluded, - includeOnly, onSelect, onUnselect, }) => { - const [internalQuery, setInternalQuery] = useState(query); - - const onInputChange = useMemo(() => { - return debounce((input: string) => { - setQuery(input); - }, 250); - }, [setQuery]); - - function onInternalInputChange(input: string) { - setInternalQuery(input); - onInputChange(input); - } - const objects = useMemo(() => { return queryResults.filter( (p) => @@ -119,8 +110,10 @@ const SelectableFilter: React.FC = ({ ); }, [queryResults, selected, excluded]); - const includingOnly = includeOnly || (selected.length > 0 && single); - const excludingOnly = excluded.length > 0 && single; + const includingOnly = modifier == CriterionModifier.Equals; + const excludingOnly = + modifier == CriterionModifier.Excludes || + modifier == CriterionModifier.NotEquals; const includeIcon = ; const excludeIcon = ; @@ -128,13 +121,18 @@ const SelectableFilter: React.FC = ({ return (
onInternalInputChange(v)} + focus={inputFocus} + value={query} + setValue={(v) => onQueryChange(v)} />