Refactor filter container (#3867)

* Refactor filter container

* Changeset

* Lint
This commit is contained in:
Patryk Andrzejewski 2023-07-05 16:32:34 +02:00 committed by GitHub
parent 8fbf0d4a88
commit 4433a9463a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 83 additions and 96 deletions

View file

@ -0,0 +1,5 @@
---
"saleor-dashboard": patch
---
Refactoring FilterContainer in filter feature

View file

@ -1,7 +1,6 @@
import { ApolloClient } from "@apollo/client"; import { ApolloClient } from "@apollo/client";
import { FilterElement } from "../FilterElement"; import { FilterContainer, FilterElement } from "../FilterElement";
import { FilterContainer } from "../useFilterContainer";
import { import {
AttributeChoicesHandler, AttributeChoicesHandler,
AttributesHandler, AttributesHandler,

View file

@ -164,3 +164,6 @@ export class FilterElement {
return null; return null;
} }
} }
export type FilterContainer = Array<string | FilterElement | FilterContainer>;

View file

@ -1,2 +1,2 @@
export { Condition } from "./Condition" export { Condition } from "./Condition"
export { FilterElement } from "./FilterElement" export { type FilterContainer,FilterElement } from "./FilterElement"

View file

@ -1,4 +1,4 @@
import { FilterContainer } from "./useFilterContainer"; import { FilterContainer } from "./FilterElement";
export interface FilterValueProvider { export interface FilterValueProvider {
value: FilterContainer; value: FilterContainer;

View file

@ -4,8 +4,7 @@ import { parse, ParsedQs } from "qs";
import { useRef } from "react"; import { useRef } from "react";
import { InitialStateResponse } from "../../API/InitialStateResponse"; import { InitialStateResponse } from "../../API/InitialStateResponse";
import { FilterElement } from "../../FilterElement"; import { FilterContainer, FilterElement } from "../../FilterElement";
import { FilterContainer } from "../../useFilterContainer";
import { UrlEntry, UrlToken } from "../UrlToken"; import { UrlEntry, UrlToken } from "../UrlToken";
import { import {
emptyFetchingParams, emptyFetchingParams,

View file

@ -4,8 +4,8 @@ import { stringify } from "qs";
import useRouter from "use-react-router"; import useRouter from "use-react-router";
import { useInitialAPIState } from "../API/initialState/useInitalAPIState"; import { useInitialAPIState } from "../API/initialState/useInitalAPIState";
import { FilterContainer } from "../FilterElement";
import { FilterValueProvider } from "../FilterValueProvider"; import { FilterValueProvider } from "../FilterValueProvider";
import { FilterContainer } from "../useFilterContainer";
import { useTokenArray } from "./TokenArray"; import { useTokenArray } from "./TokenArray";
const prepareStructure = filterValue => const prepareStructure = filterValue =>

View file

@ -0,0 +1,60 @@
import { useState } from "react";
import { FilterContainer,FilterElement } from "./FilterElement";
type StateCallback = (el: FilterElement) => void
type Element = FilterContainer[number]
export const useContainerState = (initialValue: FilterContainer) => {
const [value, setValue] = useState(initialValue);
const isFilterElement = (elIndex: number, index: number, el: Element): el is FilterElement => {
return elIndex === index && typeof el !== "string" && !Array.isArray(el)
}
const updateFilterElement = (index: number, cb: StateCallback) => (el: Element, elIndex: number) => {
if (isFilterElement(elIndex, index, el)) {
cb(el);
}
return el;
}
const updateAt = (position: string, cb: StateCallback) => {
const index = parseInt(position, 10);
setValue(v => v.map(updateFilterElement(index, cb)));
}
const removeAt = (position: string) => {
const index = parseInt(position, 10);
if (value.length > 0) {
setValue(v =>
v.filter((_, elIndex) => ![index - 1, index].includes(elIndex)),
);
return;
}
setValue(v => v.filter((_, elIndex) => ![index].includes(elIndex)));
};
const createEmpty = () => {
const newValue: FilterContainer = [];
if (value.length > 0) {
newValue.push("OR");
}
newValue.push(FilterElement.createEmpty());
setValue(v => v.concat(newValue));
};
return {
createEmpty,
updateAt,
removeAt,
value,
}
}

View file

@ -1,115 +1,36 @@
// @ts-strict-ignore import { FilterContainer } from "./FilterElement";
import { useState } from "react";
import { FilterElement } from "./FilterElement";
import { ConditionValue, ItemOption } from "./FilterElement/ConditionValue"; import { ConditionValue, ItemOption } from "./FilterElement/ConditionValue";
import { useContainerState } from "./useContainerState";
export type FilterContainer = Array<string | FilterElement | FilterContainer>;
export const useFilterContainer = (initialValue: FilterContainer) => { export const useFilterContainer = (initialValue: FilterContainer) => {
const [value, setValue] = useState(initialValue); const { value, updateAt, removeAt, createEmpty } = useContainerState(initialValue)
const addEmpty = () => { const addEmpty = () => {
const newValue = []; createEmpty()
if (value.length > 0) {
newValue.push("OR");
}
newValue.push(FilterElement.createEmpty());
setValue(v => v.concat(newValue));
};
const removeAt = (position: string) => {
const index = parseInt(position, 10);
if (value.length > 0) {
setValue(v =>
v.filter((_, elIndex) => ![index - 1, index].includes(elIndex)),
);
return;
}
setValue(v => v.filter((_, elIndex) => ![index].includes(elIndex)));
}; };
const updateLeftOperator = (position: string, leftOperator: any) => { const updateLeftOperator = (position: string, leftOperator: any) => {
const index = parseInt(position, 10); updateAt(position, (el) => el.updateLeftOperator(leftOperator))
setValue(v =>
v.map((el, elIndex) => {
if (elIndex === index && typeof el !== "string" && !Array.isArray(el)) {
el.updateLeftOperator(leftOperator);
}
return el;
}),
);
}; };
const updateLeftLoadingState = (position: string, loading: boolean) => { const updateLeftLoadingState = (position: string, loading: boolean) => {
const index = parseInt(position, 10); updateAt(position, (el) => el.updateLeftLoadingState(loading))
setValue(v =>
v.map((el, elIndex) => {
if (elIndex === index && typeof el !== "string" && !Array.isArray(el)) {
el.updateLeftLoadingState(loading);
}
return el;
}),
);
}; };
const updateRightOperator = (position: string, rightOperator: ConditionValue) => { const updateRightOperator = (position: string, rightOperator: ConditionValue) => {
const index = parseInt(position, 10); updateAt(position, (el) => el.updateRightOperator(rightOperator))
setValue(v =>
v.map((el, elIndex) => {
if (elIndex === index && typeof el !== "string" && !Array.isArray(el)) {
el.updateRightOperator(rightOperator);
}
return el;
}),
);
}; };
const updateRightOptions = (position: string, options: ItemOption[]) => { const updateRightOptions = (position: string, options: ItemOption[]) => {
const index = parseInt(position, 10); updateAt(position, (el) => el.updateRightOptions(options))
setValue(v =>
v.map((el, elIndex) => {
if (elIndex === index && typeof el !== "string" && !Array.isArray(el)) {
el.updateRightOptions(options);
}
return el;
}),
);
}; };
const updateRightLoadingState = (position: string, loading: boolean) => { const updateRightLoadingState = (position: string, loading: boolean) => {
const index = parseInt(position, 10); updateAt(position, (el) => el.updateRightLoadingState(loading))
setValue(v =>
v.map((el, elIndex) => {
if (elIndex === index && typeof el !== "string" && !Array.isArray(el)) {
el.updateRightLoadingState(loading);
}
return el;
}),
);
}; };
const updateCondition = (position: string, conditionValue: any) => { const updateCondition = (position: string, conditionValue: any) => {
const index = parseInt(position, 10); updateAt(position, (el) => el.updateCondition(conditionValue))
setValue(v =>
v.map((el, elIndex) => {
if (elIndex === index && typeof el !== "string" && !Array.isArray(el)) {
el.updateCondition(conditionValue);
}
return el;
}),
);
}; };
return { return {