diff --git a/.changeset/grumpy-eagles-sing.md b/.changeset/grumpy-eagles-sing.md new file mode 100644 index 000000000..17f74f463 --- /dev/null +++ b/.changeset/grumpy-eagles-sing.md @@ -0,0 +1,5 @@ +--- +"saleor-dashboard": patch +--- + +Experimental filters: filter presets & date fixes diff --git a/src/components/ConditionalFilter/ValueProvider/TokenArray/index.ts b/src/components/ConditionalFilter/ValueProvider/TokenArray/index.ts index 4c7e99a3d..eb01b6685 100644 --- a/src/components/ConditionalFilter/ValueProvider/TokenArray/index.ts +++ b/src/components/ConditionalFilter/ValueProvider/TokenArray/index.ts @@ -1,5 +1,4 @@ import { parse, ParsedQs } from "qs"; -import { useRef } from "react"; import { InitialStateResponse } from "../../API/InitialStateResponse"; import { FilterContainer, FilterElement } from "../../FilterElement"; @@ -91,13 +90,3 @@ export class TokenArray extends Array { }); } } - -export const useTokenArray = (url: string) => { - const instance = useRef(null); - - if (!instance.current) { - instance.current = new TokenArray(url); - } - - return instance.current; -}; diff --git a/src/components/ConditionalFilter/ValueProvider/useUrlValueProvider.ts b/src/components/ConditionalFilter/ValueProvider/useUrlValueProvider.ts index c5408b42c..9aa556133 100644 --- a/src/components/ConditionalFilter/ValueProvider/useUrlValueProvider.ts +++ b/src/components/ConditionalFilter/ValueProvider/useUrlValueProvider.ts @@ -5,7 +5,7 @@ import useRouter from "use-react-router"; import { InitialAPIState } from "../API"; import { FilterContainer, FilterElement } from "../FilterElement"; import { FilterValueProvider } from "../FilterValueProvider"; -import { useTokenArray } from "./TokenArray"; +import { TokenArray } from "./TokenArray"; import { UrlEntry } from "./UrlToken"; type Structure = Array; @@ -25,20 +25,22 @@ const prepareStructure = (filterValue: FilterContainer): Structure => export const useUrlValueProvider = ( initialState: InitialAPIState, + locationSearch: string, ): FilterValueProvider => { const router = useRouter(); - const params = new URLSearchParams(router.location.search); + const params = new URLSearchParams(locationSearch); const { data, loading, fetchQueries } = initialState; const [value, setValue] = useState([]); params.delete("asc"); params.delete("sort"); - const tokenizedUrl = useTokenArray(params.toString()); + const tokenizedUrl = new TokenArray(params.toString()); const fetchingParams = tokenizedUrl.getFetchingParams(); + useEffect(() => { fetchQueries(fetchingParams); - }, []); + }, [locationSearch]); useEffect(() => { if (loading) return; diff --git a/src/components/ConditionalFilter/constants.ts b/src/components/ConditionalFilter/constants.ts index ace1a9a94..dac787914 100644 --- a/src/components/ConditionalFilter/constants.ts +++ b/src/components/ConditionalFilter/constants.ts @@ -93,11 +93,13 @@ export const ATTRIBUTE_INPUT_TYPE_CONDITIONS = { { type: "number.range", label: "between", value: "input-4" }, ], DATE_TIME: [ - { type: "datetime", label: "is", value: "input-1" }, + { type: "datetime", label: "lower", value: "input-2" }, + { type: "datetime", label: "greater", value: "input-3" }, { type: "datetime.range", label: "between", value: "input-4" }, ], DATE: [ - { type: "date", label: "is", value: "input-1" }, + { type: "date", label: "lower", value: "input-1" }, + { type: "date", label: "greater", value: "input-2" }, { type: "date.range", label: "between", value: "input-4" }, ], SWATCH: [{ type: "multiselect", label: "in", value: "input-2" }], diff --git a/src/components/ConditionalFilter/context/provider.tsx b/src/components/ConditionalFilter/context/provider.tsx index 9b31f3408..d5941af94 100644 --- a/src/components/ConditionalFilter/context/provider.tsx +++ b/src/components/ConditionalFilter/context/provider.tsx @@ -7,10 +7,12 @@ import { useFilterLeftOperandsProvider } from "../useFilterLeftOperands"; import { useUrlValueProvider } from "../ValueProvider/useUrlValueProvider"; import { ConditionalFilterContext } from "./context"; -export const ConditionalProductFilterProvider: FC = ({ children }) => { +export const ConditionalProductFilterProvider: FC<{ + locationSearch: string; +}> = ({ children, locationSearch }) => { const apiProvider = useProductFilterAPIProvider(); const initialState = useProductInitialAPIState(); - const valueProvider = useUrlValueProvider(initialState); + const valueProvider = useUrlValueProvider(initialState, locationSearch); const leftOperandsProvider = useFilterLeftOperandsProvider(); const containerState = useContainerState(valueProvider); diff --git a/src/components/ConditionalFilter/queryVariables.ts b/src/components/ConditionalFilter/queryVariables.ts index 1bc247a68..e74c0d7b1 100644 --- a/src/components/ConditionalFilter/queryVariables.ts +++ b/src/components/ConditionalFilter/queryVariables.ts @@ -35,7 +35,7 @@ const createStaticQueryPart = ( } if (isTuple(value) && label === "between") { - const [lte, gte] = value; + const [gte, lte] = value; return { range: { lte, gte } }; } @@ -59,7 +59,7 @@ const createStaticQueryPart = ( }; const getRangeQueryPartByType = (value: [string, string], type: string) => { - const [lte, gte] = value; + const [gte, lte] = value; switch (type) { case "datetime.range": @@ -72,6 +72,21 @@ const getRangeQueryPartByType = (value: [string, string], type: string) => { } }; +const getQueryPartByType = ( + value: string, + type: string, + what: "lte" | "gte", +) => { + switch (type) { + case "datetime": + return { dateTime: { [what]: value } }; + case "date": + return { date: { [what]: value } }; + default: + return { valuesRange: { [what]: parseFloat(value) } }; + } +}; + const createAttributeQueryPart = ( attributeSlug: string, selected: ConditionSelected, @@ -82,11 +97,11 @@ const createAttributeQueryPart = ( const { value } = selected; if (label === "lower" && typeof value === "string") { - return { slug: attributeSlug, valuesRange: { lte: parseFloat(value) } }; + return { slug: attributeSlug, ...getQueryPartByType(value, type, "lte") }; } if (label === "greater" && typeof value === "string") { - return { slug: attributeSlug, valuesRange: { gte: parseFloat(value) } }; + return { slug: attributeSlug, ...getQueryPartByType(value, type, "gte") }; } if (isTuple(value) && label === "between") { diff --git a/src/components/FilterPresetsSelect/FilterPresetsSelect.tsx b/src/components/FilterPresetsSelect/FilterPresetsSelect.tsx index 982e32c6c..bf01c61f1 100644 --- a/src/components/FilterPresetsSelect/FilterPresetsSelect.tsx +++ b/src/components/FilterPresetsSelect/FilterPresetsSelect.tsx @@ -159,6 +159,7 @@ export const FilterPresetsSelect = ({ onRemove={() => { onRemove(index + 1); }} + key={`filter-preset-${index}`} > {preset} diff --git a/src/products/index.tsx b/src/products/index.tsx index 2311ddb9c..9939d3036 100644 --- a/src/products/index.tsx +++ b/src/products/index.tsx @@ -45,7 +45,7 @@ const ProductList: React.FC> = ({ location }) => { ); return ( - + ); diff --git a/src/products/views/ProductList/sort.ts b/src/products/views/ProductList/sort.ts index 63bf7313e..dbe528ca0 100644 --- a/src/products/views/ProductList/sort.ts +++ b/src/products/views/ProductList/sort.ts @@ -66,6 +66,7 @@ export function getSortQueryVariables( } const field = getSortQueryField(params.sort); + // TODO: how to handle search & sort return { direction, field,