Experimental filters: filter presets & date fixes (#4030)
This commit is contained in:
parent
5087dec2d5
commit
e033d6bf99
9 changed files with 41 additions and 24 deletions
5
.changeset/grumpy-eagles-sing.md
Normal file
5
.changeset/grumpy-eagles-sing.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
"saleor-dashboard": patch
|
||||
---
|
||||
|
||||
Experimental filters: filter presets & date fixes
|
|
@ -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<string | UrlToken | TokenArray> {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const useTokenArray = (url: string) => {
|
||||
const instance = useRef<TokenArray | null>(null);
|
||||
|
||||
if (!instance.current) {
|
||||
instance.current = new TokenArray(url);
|
||||
}
|
||||
|
||||
return instance.current;
|
||||
};
|
||||
|
|
|
@ -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<string | UrlEntry | Structure>;
|
||||
|
@ -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<FilterContainer>([]);
|
||||
|
||||
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;
|
||||
|
|
|
@ -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" }],
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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") {
|
||||
|
|
|
@ -159,6 +159,7 @@ export const FilterPresetsSelect = ({
|
|||
onRemove={() => {
|
||||
onRemove(index + 1);
|
||||
}}
|
||||
key={`filter-preset-${index}`}
|
||||
>
|
||||
{preset}
|
||||
</FilterPresetItem>
|
||||
|
|
|
@ -45,7 +45,7 @@ const ProductList: React.FC<RouteComponentProps<any>> = ({ location }) => {
|
|||
);
|
||||
|
||||
return (
|
||||
<ConditionalProductFilterProvider>
|
||||
<ConditionalProductFilterProvider locationSearch={location.search}>
|
||||
<ProductListComponent params={params} />
|
||||
</ConditionalProductFilterProvider>
|
||||
);
|
||||
|
|
|
@ -66,6 +66,7 @@ export function getSortQueryVariables(
|
|||
}
|
||||
|
||||
const field = getSortQueryField(params.sort);
|
||||
// TODO: how to handle search & sort
|
||||
return {
|
||||
direction,
|
||||
field,
|
||||
|
|
Loading…
Reference in a new issue