From 0a58c3a5e19cf0906c928be9c30449da4241817a Mon Sep 17 00:00:00 2001 From: dominik-zeglen Date: Thu, 16 Jan 2020 14:44:16 +0100 Subject: [PATCH] Refactor multiple choice field widget --- .../Filter/FilterAutocompleteField.tsx | 145 ++++++++++++++++++ src/components/Filter/FilterContent.tsx | 96 ++++++------ src/components/Filter/reducer.ts | 3 +- src/components/Link.tsx | 2 +- 4 files changed, 200 insertions(+), 46 deletions(-) create mode 100644 src/components/Filter/FilterAutocompleteField.tsx diff --git a/src/components/Filter/FilterAutocompleteField.tsx b/src/components/Filter/FilterAutocompleteField.tsx new file mode 100644 index 000000000..e880d0da4 --- /dev/null +++ b/src/components/Filter/FilterAutocompleteField.tsx @@ -0,0 +1,145 @@ +import React from "react"; +import FormControlLabel from "@material-ui/core/FormControlLabel"; +import TextField from "@material-ui/core/TextField"; +import makeStyles from "@material-ui/core/styles/makeStyles"; +import { FormattedMessage } from "react-intl"; + +import { toggle } from "@saleor/utils/lists"; +import { MultiAutocompleteChoiceType } from "../MultiAutocompleteSelectField"; +import Link from "../Link"; +import Checkbox from "../Checkbox"; +import Hr from "../Hr"; +import { IFilterElement } from "./types"; +import { FilterReducerAction } from "./reducer"; + +interface FilterAutocompleteFieldProps { + displayValues: Record; + filterField: IFilterElement; + setDisplayValues: ( + values: Record + ) => void; + onFilterPropertyChange: React.Dispatch>; +} + +const useStyles = makeStyles( + theme => ({ + hr: { + backgroundColor: theme.palette.primary.light, + margin: theme.spacing(1, 0) + }, + input: { + padding: "12px 0 9px 12px" + }, + inputContainer: { + marginBottom: theme.spacing(1) + }, + option: { + left: -theme.spacing(0.5), + position: "relative" + }, + showMore: { + display: "inline-block", + marginTop: theme.spacing(1) + } + }), + { name: "FilterAutocompleteField" } +); + +const FilterAutocompleteField: React.FC = ({ + displayValues, + filterField, + setDisplayValues, + onFilterPropertyChange +}) => { + const classes = useStyles({}); + + const fieldDisplayValues = displayValues[filterField.name]; + const availableOptions = filterField.options.filter(option => + fieldDisplayValues.every( + displayValue => displayValue.value !== option.value + ) + ); + const displayHr = !( + (fieldDisplayValues.length === 0 && availableOptions.length > 0) || + (availableOptions.length === 0 && fieldDisplayValues.length > 0) + ); + + const handleChange = (option: MultiAutocompleteChoiceType) => { + onFilterPropertyChange({ + payload: { + name: filterField.name, + update: { + value: toggle(option.value, filterField.value, (a, b) => a === b) + } + }, + type: "set-property" + }); + + setDisplayValues({ + ...displayValues, + [filterField.name]: toggle( + option, + fieldDisplayValues, + (a, b) => a.value === b.value + ) + }); + }; + + return ( +
+ filterField.onSearchChange(event.target.value)} + /> + {fieldDisplayValues.map(displayValue => ( +
+ + } + label={displayValue.label} + name={filterField.name} + onChange={() => handleChange(displayValue)} + /> +
+ ))} + {displayHr &&
} + {availableOptions.map(option => ( +
+ + } + label={option.label} + name={filterField.name} + onChange={() => handleChange(option)} + /> +
+ ))} + {filterField.hasMore && ( + + + + )} +
+ ); +}; + +FilterAutocompleteField.displayName = "FilterAutocompleteField"; +export default FilterAutocompleteField; diff --git a/src/components/Filter/FilterContent.tsx b/src/components/Filter/FilterContent.tsx index 584336963..908329dfc 100644 --- a/src/components/Filter/FilterContent.tsx +++ b/src/components/Filter/FilterContent.tsx @@ -22,9 +22,11 @@ import FormSpacer from "../FormSpacer"; import MultiAutocompleteSelectField, { MultiAutocompleteChoiceType } from "../MultiAutocompleteSelectField"; +import Link from "../Link"; import { IFilter, FieldType, FilterType } from "./types"; import Arrow from "./Arrow"; import { FilterReducerAction } from "./reducer"; +import FilterAutocompleteField from "./FilterAutocompleteField"; export interface FilterContentProps { currencySymbol: string; @@ -428,51 +430,57 @@ const FilterContent: React.FC = ({ ))} {filterField.type === FieldType.autocomplete && filterField.multiple && ( - - onFilterPropertyChange({ - payload: { - name: filterField.name, - update: { - value: toggle( - event.target.value, - filterField.value, - (a, b) => a === b - ) - } - }, - type: "set-property" - }), - value => - setAutocompleteDisplayValues({ - ...autocompleteDisplayValues, - [filterField.name]: toggle( - value[0], - autocompleteDisplayValues[filterField.name], - (a, b) => a.value === b.value - ) - }), - [], - filterField.options - )} - fetchChoices={filterField.onSearchChange} - loading={filterField.loading} - data-tc={filterField.name} - key={filterField.name} + + // + // onFilterPropertyChange({ + // payload: { + // name: filterField.name, + // update: { + // value: toggle( + // event.target.value, + // filterField.value, + // (a, b) => a === b + // ) + // } + // }, + // type: "set-property" + // }), + // value => + // setAutocompleteDisplayValues({ + // ...autocompleteDisplayValues, + // [filterField.name]: toggle( + // value[0], + // autocompleteDisplayValues[filterField.name], + // (a, b) => a.value === b.value + // ) + // }), + // [], + // filterField.options + // )} + // fetchChoices={filterField.onSearchChange} + // loading={filterField.loading} + // data-tc={filterField.name} + // key={filterField.name} + // /> )} )} diff --git a/src/components/Filter/reducer.ts b/src/components/Filter/reducer.ts index 33eb850db..e8d837c7c 100644 --- a/src/components/Filter/reducer.ts +++ b/src/components/Filter/reducer.ts @@ -26,7 +26,8 @@ function merge( if (!!prevFilter) { return { ...newFilter, - active: prevFilter.active + active: prevFilter.active, + value: prevFilter.value }; } diff --git a/src/components/Link.tsx b/src/components/Link.tsx index 3086f1bc5..3ddcec8a6 100644 --- a/src/components/Link.tsx +++ b/src/components/Link.tsx @@ -44,7 +44,7 @@ const Link: React.FC = props => { return (