Experimental filters: refactor API hooks (#3882)
This commit is contained in:
parent
b09f2d556f
commit
cc0e0e58f3
14 changed files with 206 additions and 195 deletions
7
.changeset/popular-plants-sing.md
Normal file
7
.changeset/popular-plants-sing.md
Normal file
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
"saleor-dashboard": patch
|
||||
---
|
||||
|
||||
Experimental filters: refactor API hooks.
|
||||
|
||||
This PR refactors API hooks used to fetch data. Right now they return the provider which then is used by the filter container to update options coming from API.
|
|
@ -83,7 +83,7 @@
|
|||
"@typescript-eslint/ban-ts-comment": "warn",
|
||||
"@typescript-eslint/ban-types": "warn",
|
||||
"@typescript-eslint/consistent-type-assertions": "warn",
|
||||
"@typescript-eslint/explicit-function-return-type": "warn",
|
||||
"@typescript-eslint/explicit-function-return-type": "off",
|
||||
"@typescript-eslint/naming-convention": "warn",
|
||||
"@typescript-eslint/no-base-to-string": "warn",
|
||||
"@typescript-eslint/no-dynamic-delete": "warn",
|
||||
|
|
14
package-lock.json
generated
14
package-lock.json
generated
|
@ -27,7 +27,7 @@
|
|||
"@material-ui/lab": "^4.0.0-alpha.61",
|
||||
"@material-ui/styles": "^4.11.4",
|
||||
"@reach/auto-id": "^0.16.0",
|
||||
"@saleor/macaw-ui": "0.8.0-pre.103",
|
||||
"@saleor/macaw-ui": "0.8.0-pre.104",
|
||||
"@saleor/sdk": "0.6.0",
|
||||
"@sentry/react": "^6.0.0",
|
||||
"@types/faker": "^5.1.6",
|
||||
|
@ -7947,9 +7947,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@saleor/macaw-ui": {
|
||||
"version": "0.8.0-pre.103",
|
||||
"resolved": "https://registry.npmjs.org/@saleor/macaw-ui/-/macaw-ui-0.8.0-pre.103.tgz",
|
||||
"integrity": "sha512-Y6E4vHKhXf5cRZiQwLOy6LnabUH1FkyDQ9GZ03RH2PzXwoVA972v21ySJV4Vd3Kk8c7X5ugGzgV0Etovo963lA==",
|
||||
"version": "0.8.0-pre.104",
|
||||
"resolved": "https://registry.npmjs.org/@saleor/macaw-ui/-/macaw-ui-0.8.0-pre.104.tgz",
|
||||
"integrity": "sha512-5Et/UIsH6ZzVyJLMhhnbN5PDllRGhyhJXBXUlgOdD0yH47+PPeaN9BPDDrlX/eiJbLMimJOIuj5hhb+WhWT/Zw==",
|
||||
"dependencies": {
|
||||
"@dessert-box/react": "^0.4.0",
|
||||
"@floating-ui/react-dom-interactions": "^0.5.0",
|
||||
|
@ -41209,9 +41209,9 @@
|
|||
}
|
||||
},
|
||||
"@saleor/macaw-ui": {
|
||||
"version": "0.8.0-pre.103",
|
||||
"resolved": "https://registry.npmjs.org/@saleor/macaw-ui/-/macaw-ui-0.8.0-pre.103.tgz",
|
||||
"integrity": "sha512-Y6E4vHKhXf5cRZiQwLOy6LnabUH1FkyDQ9GZ03RH2PzXwoVA972v21ySJV4Vd3Kk8c7X5ugGzgV0Etovo963lA==",
|
||||
"version": "0.8.0-pre.104",
|
||||
"resolved": "https://registry.npmjs.org/@saleor/macaw-ui/-/macaw-ui-0.8.0-pre.104.tgz",
|
||||
"integrity": "sha512-5Et/UIsH6ZzVyJLMhhnbN5PDllRGhyhJXBXUlgOdD0yH47+PPeaN9BPDDrlX/eiJbLMimJOIuj5hhb+WhWT/Zw==",
|
||||
"requires": {
|
||||
"@dessert-box/react": "^0.4.0",
|
||||
"@floating-ui/react-dom-interactions": "^0.5.0",
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
"@material-ui/lab": "^4.0.0-alpha.61",
|
||||
"@material-ui/styles": "^4.11.4",
|
||||
"@reach/auto-id": "^0.16.0",
|
||||
"@saleor/macaw-ui": "0.8.0-pre.103",
|
||||
"@saleor/macaw-ui": "0.8.0-pre.104",
|
||||
"@saleor/sdk": "0.6.0",
|
||||
"@sentry/react": "^6.0.0",
|
||||
"@types/faker": "^5.1.6",
|
||||
|
|
12
src/components/ConditionalFilter/API/FilterAPIProvider.ts
Normal file
12
src/components/ConditionalFilter/API/FilterAPIProvider.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
import { FilterContainer } from "../FilterElement";
|
||||
import { ItemOption } from "../FilterElement/ConditionValue";
|
||||
import { LeftOperand } from "../LeftOperandsProvider";
|
||||
|
||||
export interface FilterAPIProvider {
|
||||
fetchRightOptions: (
|
||||
position: string,
|
||||
value: FilterContainer,
|
||||
inputValue: string,
|
||||
) => Promise<ItemOption[]>;
|
||||
fetchLeftOptions: (inputValue: string) => Promise<LeftOperand[]>;
|
||||
}
|
|
@ -21,7 +21,7 @@ import {
|
|||
} from "@dashboard/graphql";
|
||||
|
||||
import { ItemOption } from "../FilterElement/ConditionValue";
|
||||
|
||||
import { LeftOperand } from "../LeftOperandsProvider";
|
||||
|
||||
export interface Handler {
|
||||
client: ApolloClient<unknown>;
|
||||
|
@ -146,7 +146,7 @@ export class ChannelHandler implements Handler {
|
|||
export class AttributesHandler implements Handler {
|
||||
constructor(public client: ApolloClient<unknown>, public query: string) {}
|
||||
|
||||
fetch = async () => {
|
||||
fetch = async (): Promise<LeftOperand[]> => {
|
||||
const { data } = await this.client.query<
|
||||
_GetDynamicLeftOperandsQuery,
|
||||
_GetDynamicLeftOperandsQueryVariables
|
||||
|
@ -161,7 +161,7 @@ export class AttributesHandler implements Handler {
|
|||
data.attributes?.edges.map(({ node }) => ({
|
||||
label: node.name ?? "",
|
||||
value: node.id,
|
||||
type: node.inputType,
|
||||
type: node.inputType ?? ("" as LeftOperand["type"]),
|
||||
slug: node.slug ?? "",
|
||||
})) ?? []
|
||||
);
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
import { ApolloClient, useApolloClient } from "@apollo/client";
|
||||
|
||||
import { FilterContainer, FilterElement } from "../FilterElement";
|
||||
import { FilterAPIProvider } from "./FilterAPIProvider";
|
||||
import {
|
||||
AttributeChoicesHandler,
|
||||
AttributesHandler,
|
||||
CategoryHandler,
|
||||
ChannelHandler,
|
||||
CollectionHandler,
|
||||
Handler,
|
||||
ProductTypeHandler,
|
||||
} from "./Handler";
|
||||
|
||||
const getFilterElement = (
|
||||
value: FilterContainer,
|
||||
index: number,
|
||||
): FilterElement => {
|
||||
const possibleFilterElement = value[index];
|
||||
if (
|
||||
typeof possibleFilterElement !== "string" &&
|
||||
!Array.isArray(possibleFilterElement)
|
||||
) {
|
||||
return possibleFilterElement;
|
||||
}
|
||||
|
||||
throw new Error("Unknown filter element used to create API handler");
|
||||
};
|
||||
|
||||
const createAPIHandler = (
|
||||
selectedRow: FilterElement,
|
||||
client: ApolloClient<unknown>,
|
||||
inputValue: string,
|
||||
): Handler => {
|
||||
if (selectedRow.isAttribute()) {
|
||||
return new AttributeChoicesHandler(
|
||||
client,
|
||||
selectedRow.value.value,
|
||||
inputValue,
|
||||
);
|
||||
}
|
||||
|
||||
if (selectedRow.isCollection()) {
|
||||
return new CollectionHandler(client, inputValue);
|
||||
}
|
||||
|
||||
if (selectedRow.isCategory()) {
|
||||
return new CategoryHandler(client, inputValue);
|
||||
}
|
||||
|
||||
if (selectedRow.isProductType()) {
|
||||
return new ProductTypeHandler(client, inputValue);
|
||||
}
|
||||
|
||||
if (selectedRow.isChannel()) {
|
||||
return new ChannelHandler(client, inputValue);
|
||||
}
|
||||
|
||||
throw new Error("Unknown filter element");
|
||||
};
|
||||
|
||||
export const useProductFilterAPIProvider = (): FilterAPIProvider => {
|
||||
const client = useApolloClient();
|
||||
|
||||
const fetchRightOptions = async (
|
||||
position: string,
|
||||
value: FilterContainer,
|
||||
inputValue: string,
|
||||
) => {
|
||||
const index = parseInt(position, 10);
|
||||
const filterElement = getFilterElement(value, index);
|
||||
const handler = createAPIHandler(filterElement, client, inputValue);
|
||||
|
||||
return handler.fetch();
|
||||
};
|
||||
|
||||
const fetchLeftOptions = async (inputValue: string) => {
|
||||
const handler = new AttributesHandler(client, inputValue);
|
||||
return handler.fetch();
|
||||
};
|
||||
|
||||
return {
|
||||
fetchRightOptions,
|
||||
fetchLeftOptions,
|
||||
};
|
||||
};
|
|
@ -1,84 +0,0 @@
|
|||
import { ApolloClient } from "@apollo/client";
|
||||
|
||||
import { FilterContainer, FilterElement } from "../FilterElement";
|
||||
import {
|
||||
AttributeChoicesHandler,
|
||||
AttributesHandler,
|
||||
CategoryHandler,
|
||||
ChannelHandler,
|
||||
CollectionHandler,
|
||||
Handler,
|
||||
ProductTypeHandler,
|
||||
} from "./Handler";
|
||||
|
||||
const getFilterElement = (value: any, index: number): FilterElement => {
|
||||
const possibleFilterElement = value[index];
|
||||
return typeof possibleFilterElement !== "string"
|
||||
? possibleFilterElement
|
||||
: null;
|
||||
};
|
||||
|
||||
const createAPIHandler = (
|
||||
selectedRow: FilterElement,
|
||||
client: ApolloClient<unknown>,
|
||||
inputValue: string,
|
||||
): Handler => {
|
||||
if (selectedRow.isAttribute()) {
|
||||
return new AttributeChoicesHandler(
|
||||
client,
|
||||
selectedRow.value.value,
|
||||
inputValue,
|
||||
);
|
||||
}
|
||||
|
||||
if (selectedRow.isCollection()) {
|
||||
return new CollectionHandler(client, inputValue);
|
||||
}
|
||||
|
||||
if (selectedRow.isCategory()) {
|
||||
return new CategoryHandler(client, inputValue);
|
||||
}
|
||||
|
||||
if (selectedRow.isProductType()) {
|
||||
return new ProductTypeHandler(client, inputValue);
|
||||
}
|
||||
|
||||
if (selectedRow.isChannel()) {
|
||||
return new ChannelHandler(client, inputValue);
|
||||
}
|
||||
|
||||
throw new Error("Unknown filter element");
|
||||
};
|
||||
|
||||
export const getInitialRightOperatorOptions = async (
|
||||
client: ApolloClient<unknown>,
|
||||
position: string,
|
||||
value: FilterContainer,
|
||||
) => {
|
||||
const index = parseInt(position, 10);
|
||||
const filterElement = getFilterElement(value, index);
|
||||
const handler = createAPIHandler(filterElement, client, "");
|
||||
|
||||
return handler.fetch();
|
||||
};
|
||||
|
||||
export const getRightOperatorOptionsByQuery = async (
|
||||
client: ApolloClient<unknown>,
|
||||
position: string,
|
||||
value: FilterContainer,
|
||||
inputValue: string,
|
||||
) => {
|
||||
const index = parseInt(position, 10);
|
||||
const filterElement = getFilterElement(value, index);
|
||||
const handler = createAPIHandler(filterElement, client, inputValue);
|
||||
|
||||
return handler.fetch();
|
||||
};
|
||||
|
||||
export const getLeftOperatorOptions = async (
|
||||
client: ApolloClient<unknown>,
|
||||
inputValue: string,
|
||||
) => {
|
||||
const handler = new AttributesHandler(client, inputValue);
|
||||
return handler.fetch();
|
||||
};
|
|
@ -1,6 +1,6 @@
|
|||
/* eslint-disable @typescript-eslint/member-ordering */
|
||||
import { InitialStateResponse } from "../API/InitialStateResponse";
|
||||
import { LeftOperand } from "./../useLeftOperands";
|
||||
import { LeftOperand } from "../LeftOperandsProvider";
|
||||
import { UrlToken } from "./../ValueProvider/UrlToken";
|
||||
import { ConditionOptions } from "./ConditionOptions";
|
||||
import { ConditionSelected } from "./ConditionSelected";
|
||||
|
|
|
@ -1,48 +1,46 @@
|
|||
/* eslint-disable @typescript-eslint/member-ordering */
|
||||
import { InitialStateResponse } from "../API/InitialStateResponse";
|
||||
import { LeftOperand } from "./../useLeftOperands";
|
||||
import { LeftOperand } from "../LeftOperandsProvider";
|
||||
import { TokenType, UrlEntry, UrlToken } from "./../ValueProvider/UrlToken";
|
||||
import { Condition } from "./Condition";
|
||||
import { ConditionItem, ConditionOptions } from "./ConditionOptions";
|
||||
import { ConditionSelected } from "./ConditionSelected";
|
||||
import { ConditionValue, ItemOption } from "./ConditionValue";
|
||||
|
||||
|
||||
class ExpressionValue {
|
||||
constructor(
|
||||
public value: string,
|
||||
public label: string,
|
||||
public type: string
|
||||
public type: string,
|
||||
) {}
|
||||
|
||||
public static fromLeftOperand(leftOperand: LeftOperand) {
|
||||
return new ExpressionValue(
|
||||
leftOperand.slug,
|
||||
leftOperand.label,
|
||||
leftOperand.type
|
||||
)
|
||||
leftOperand.type,
|
||||
);
|
||||
}
|
||||
|
||||
public static fromUrlToken(token: UrlToken) {
|
||||
return new ExpressionValue(
|
||||
token.name,
|
||||
token.name,
|
||||
token.name
|
||||
)
|
||||
return new ExpressionValue(token.name, token.name, token.name);
|
||||
}
|
||||
|
||||
public static forAttribute(attributeName: string, response: InitialStateResponse) {
|
||||
public static forAttribute(
|
||||
attributeName: string,
|
||||
response: InitialStateResponse,
|
||||
) {
|
||||
const attribute = response.attributeByName(attributeName);
|
||||
|
||||
return new ExpressionValue(
|
||||
attributeName,
|
||||
attribute.label,
|
||||
attribute.inputType,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public static emptyStatic() {
|
||||
return new ExpressionValue("", "", TokenType.STATIC)
|
||||
return new ExpressionValue("", "", TokenType.STATIC);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -126,10 +124,10 @@ export class FilterElement {
|
|||
|
||||
public asUrlEntry(): UrlEntry {
|
||||
if (this.isAttribute()) {
|
||||
return UrlEntry.forAttribute(this.condition.selected, this.value.value)
|
||||
return UrlEntry.forAttribute(this.condition.selected, this.value.value);
|
||||
}
|
||||
|
||||
return UrlEntry.forStatic(this.condition.selected, this.value.value)
|
||||
return UrlEntry.forStatic(this.condition.selected, this.value.value);
|
||||
}
|
||||
|
||||
public static fromValueEntry(valueEntry: any) {
|
||||
|
@ -165,5 +163,4 @@ export class FilterElement {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
export type FilterContainer = Array<string | FilterElement | FilterContainer>;
|
||||
|
|
15
src/components/ConditionalFilter/LeftOperandsProvider.ts
Normal file
15
src/components/ConditionalFilter/LeftOperandsProvider.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
import { AttributeInputTypeEnum } from "@dashboard/graphql";
|
||||
|
||||
import { StaticElementName } from "./FilterElement/ConditionOptions";
|
||||
|
||||
export interface LeftOperand {
|
||||
type: AttributeInputTypeEnum | StaticElementName;
|
||||
label: string;
|
||||
value: string;
|
||||
slug: string;
|
||||
}
|
||||
|
||||
export interface LeftOperandsProvider {
|
||||
operands: LeftOperand[];
|
||||
setOperands: (operands: LeftOperand[]) => void;
|
||||
}
|
|
@ -1,6 +1,4 @@
|
|||
// @ts-strict-ignore
|
||||
import { useApolloClient } from "@apollo/client";
|
||||
import useDebounce from "@dashboard/hooks/useDebounce";
|
||||
import {
|
||||
_ExperimentalFilters,
|
||||
Box,
|
||||
|
@ -9,17 +7,14 @@ import {
|
|||
} from "@saleor/macaw-ui/next";
|
||||
import React from "react";
|
||||
|
||||
import {
|
||||
getInitialRightOperatorOptions,
|
||||
getLeftOperatorOptions,
|
||||
getRightOperatorOptionsByQuery,
|
||||
} from "./API/getAPIOptions";
|
||||
import { useProductFilterAPIProvider } from "./API/ProductFilterAPIProvider";
|
||||
import { useFilterContainer } from "./useFilterContainer";
|
||||
import { useLeftOperands } from "./useLeftOperands";
|
||||
import { useFilterLeftOperandsProvider } from "./useFilterLeftOperands";
|
||||
import { useUrlValueProvider } from "./ValueProvider/useUrlValueProvider";
|
||||
|
||||
const FiltersArea = ({ provider, onConfirm }) => {
|
||||
const client = useApolloClient();
|
||||
const apiProvider = useProductFilterAPIProvider();
|
||||
const leftOperandsProvider = useFilterLeftOperandsProvider();
|
||||
|
||||
const {
|
||||
value,
|
||||
|
@ -29,46 +24,8 @@ const FiltersArea = ({ provider, onConfirm }) => {
|
|||
updateRightOperator,
|
||||
updateCondition,
|
||||
updateRightOptions,
|
||||
updateRightLoadingState,
|
||||
updateLeftLoadingState,
|
||||
} = useFilterContainer(provider);
|
||||
|
||||
const { operands, setOperands } = useLeftOperands();
|
||||
|
||||
const handleLeftOperatorInputValueChange = (event: any) => {
|
||||
const fetchAPI = async () => {
|
||||
updateLeftLoadingState(event.path, true);
|
||||
const options = await getLeftOperatorOptions(client, event.value);
|
||||
updateLeftLoadingState(event.path, false);
|
||||
setOperands(prev => [...prev, ...options]);
|
||||
};
|
||||
fetchAPI();
|
||||
};
|
||||
|
||||
const handleLeftOperatorInputValueChangeDebounced = useDebounce(
|
||||
handleLeftOperatorInputValueChange,
|
||||
500,
|
||||
);
|
||||
|
||||
const handleRightOperatorInputValueChange = (event: any) => {
|
||||
const fetchAPI = async () => {
|
||||
updateRightLoadingState(event.path.split(".")[0], true);
|
||||
const options = await getRightOperatorOptionsByQuery(
|
||||
client,
|
||||
event.path.split(".")[0],
|
||||
value,
|
||||
event.value,
|
||||
);
|
||||
updateRightLoadingState(event.path.split(".")[0], false);
|
||||
updateRightOptions(event.path.split(".")[0], options);
|
||||
};
|
||||
fetchAPI();
|
||||
};
|
||||
|
||||
const handleRightOperatorInputValueChangeDebounced = useDebounce(
|
||||
handleRightOperatorInputValueChange,
|
||||
500,
|
||||
);
|
||||
updateLeftOptions,
|
||||
} = useFilterContainer(provider, apiProvider, leftOperandsProvider);
|
||||
|
||||
const handleStateChange = async (event: FilterEvent["detail"]) => {
|
||||
if (event.type === "row.add") {
|
||||
|
@ -88,24 +45,19 @@ const FiltersArea = ({ provider, onConfirm }) => {
|
|||
}
|
||||
|
||||
if (event.type === "rightOperator.onChange") {
|
||||
// @ts-expect-error slug in missing in MacawUI
|
||||
updateRightOperator(event.path.split(".")[0], event.value);
|
||||
}
|
||||
|
||||
if (event.type === "rightOperator.onFocus") {
|
||||
const path = event.path.split(".")[0];
|
||||
updateRightLoadingState(path, true);
|
||||
const options = await getInitialRightOperatorOptions(client, path, value);
|
||||
updateRightOptions(path, options);
|
||||
updateRightLoadingState(path, false);
|
||||
updateRightOptions(event.path.split(".")[0], "");
|
||||
}
|
||||
|
||||
if (event.type === "rightOperator.onInputValueChange") {
|
||||
handleRightOperatorInputValueChangeDebounced(event);
|
||||
updateRightOptions(event.path.split(".")[0], event.value);
|
||||
}
|
||||
|
||||
if (event.type === "leftOperator.onInputValueChange") {
|
||||
handleLeftOperatorInputValueChangeDebounced(event);
|
||||
updateLeftOptions(event.path.split(".")[0], event.value);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -114,7 +66,7 @@ const FiltersArea = ({ provider, onConfirm }) => {
|
|||
return (
|
||||
<Box>
|
||||
<_ExperimentalFilters
|
||||
leftOptions={operands}
|
||||
leftOptions={leftOperandsProvider.operands}
|
||||
// @ts-expect-error
|
||||
value={value}
|
||||
onChange={handleStateChange}
|
||||
|
|
|
@ -1,38 +1,72 @@
|
|||
import useDebounce from "@dashboard/hooks/useDebounce";
|
||||
|
||||
import { FilterAPIProvider } from "./API/FilterAPIProvider";
|
||||
import { FilterContainer } from "./FilterElement";
|
||||
import { ConditionValue, ItemOption } from "./FilterElement/ConditionValue";
|
||||
import { LeftOperandsProvider } from "./LeftOperandsProvider";
|
||||
import { useContainerState } from "./useContainerState";
|
||||
|
||||
export const useFilterContainer = (initialValue: FilterContainer) => {
|
||||
const { value, updateAt, removeAt, createEmpty } = useContainerState(initialValue)
|
||||
export const useFilterContainer = (
|
||||
initialValue: FilterContainer,
|
||||
apiProvider: FilterAPIProvider,
|
||||
leftOperandsProvider: LeftOperandsProvider,
|
||||
) => {
|
||||
const { value, updateAt, removeAt, createEmpty } =
|
||||
useContainerState(initialValue);
|
||||
|
||||
const addEmpty = () => {
|
||||
createEmpty()
|
||||
createEmpty();
|
||||
};
|
||||
|
||||
const updateLeftOperator = (position: string, leftOperator: any) => {
|
||||
updateAt(position, (el) => el.updateLeftOperator(leftOperator))
|
||||
updateAt(position, el => el.updateLeftOperator(leftOperator));
|
||||
};
|
||||
|
||||
const updateLeftLoadingState = (position: string, loading: boolean) => {
|
||||
updateAt(position, (el) => el.updateLeftLoadingState(loading))
|
||||
updateAt(position, el => el.updateLeftLoadingState(loading));
|
||||
};
|
||||
|
||||
const updateRightOperator = (position: string, rightOperator: ConditionValue) => {
|
||||
updateAt(position, (el) => el.updateRightOperator(rightOperator))
|
||||
const updateRightOperator = (
|
||||
position: string,
|
||||
rightOperator: ConditionValue,
|
||||
) => {
|
||||
updateAt(position, el => el.updateRightOperator(rightOperator));
|
||||
};
|
||||
|
||||
const updateRightOptions = (position: string, options: ItemOption[]) => {
|
||||
updateAt(position, (el) => el.updateRightOptions(options))
|
||||
const _updateRightOptions = (position: string, options: ItemOption[]) => {
|
||||
updateAt(position, el => el.updateRightOptions(options));
|
||||
};
|
||||
|
||||
const updateRightLoadingState = (position: string, loading: boolean) => {
|
||||
updateAt(position, (el) => el.updateRightLoadingState(loading))
|
||||
updateAt(position, el => el.updateRightLoadingState(loading));
|
||||
};
|
||||
|
||||
const updateCondition = (position: string, conditionValue: any) => {
|
||||
updateAt(position, (el) => el.updateCondition(conditionValue))
|
||||
updateAt(position, el => el.updateCondition(conditionValue));
|
||||
};
|
||||
|
||||
const _fetchRightOptions = async (position: string, inputValue: string) => {
|
||||
updateRightLoadingState(position, true);
|
||||
const options = await apiProvider.fetchRightOptions(
|
||||
position,
|
||||
value,
|
||||
inputValue,
|
||||
);
|
||||
updateRightLoadingState(position, false);
|
||||
_updateRightOptions(position, options);
|
||||
};
|
||||
|
||||
const updateRightOptions = useDebounce(_fetchRightOptions, 500);
|
||||
|
||||
const _fetchLeftOptions = async (position: string, inputValue: string) => {
|
||||
updateLeftLoadingState(position, true);
|
||||
const options = await apiProvider.fetchLeftOptions(inputValue);
|
||||
updateLeftLoadingState(position, false);
|
||||
leftOperandsProvider.setOperands(options);
|
||||
};
|
||||
|
||||
const updateLeftOptions = useDebounce(_fetchLeftOptions, 500);
|
||||
|
||||
return {
|
||||
value,
|
||||
addEmpty,
|
||||
|
@ -41,7 +75,6 @@ export const useFilterContainer = (initialValue: FilterContainer) => {
|
|||
updateRightOperator,
|
||||
updateCondition,
|
||||
updateRightOptions,
|
||||
updateRightLoadingState,
|
||||
updateLeftLoadingState,
|
||||
updateLeftOptions,
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,14 +1,6 @@
|
|||
import { AttributeInputTypeEnum } from "@dashboard/graphql";
|
||||
import { useState } from "react";
|
||||
|
||||
import { StaticElementName } from "./FilterElement/ConditionOptions";
|
||||
|
||||
export interface LeftOperand {
|
||||
type: AttributeInputTypeEnum | StaticElementName;
|
||||
label: string;
|
||||
value: string;
|
||||
slug: string;
|
||||
}
|
||||
import { LeftOperand, LeftOperandsProvider } from "./LeftOperandsProvider";
|
||||
|
||||
const STATIC_OPTIONS: LeftOperand[] = [
|
||||
{ value: "price", label: "Price", type: "price", slug: "price" },
|
||||
|
@ -22,11 +14,12 @@ const STATIC_OPTIONS: LeftOperand[] = [
|
|||
{ value: "channel", label: "Channel", type: "channel", slug: "channel" },
|
||||
];
|
||||
|
||||
export const useLeftOperands = () => {
|
||||
export const useFilterLeftOperandsProvider = (): LeftOperandsProvider => {
|
||||
const [operands, setOperands] = useState<LeftOperand[]>(STATIC_OPTIONS);
|
||||
|
||||
return {
|
||||
operands,
|
||||
setOperands,
|
||||
setOperands: (options: LeftOperand[]) =>
|
||||
setOperands(prev => [...prev, ...options]),
|
||||
};
|
||||
};
|
Loading…
Reference in a new issue