diff --git a/.changeset/late-parents-cross.md b/.changeset/late-parents-cross.md
new file mode 100644
index 00000000000..05caa0bbf80
--- /dev/null
+++ b/.changeset/late-parents-cross.md
@@ -0,0 +1,5 @@
+---
+"saleor-dashboard": patch
+---
+
+Collection list filters have been ported to expression filtering. This means you can now use new filters in the Collection list.
diff --git a/.featureFlags/collection_filters.md b/.featureFlags/collection_filters.md
new file mode 100644
index 00000000000..039a48e704b
--- /dev/null
+++ b/.featureFlags/collection_filters.md
@@ -0,0 +1,11 @@
+---
+name: collection_filters
+displayName: Collection filtering
+enabled: true
+payload: "default"
+visible: true
+---
+
+
+Experience the new look and enhanced abilities of new filtering mechanism.
+Easily combine any criteria you want, and quickly browse their values.
\ No newline at end of file
diff --git a/.featureFlags/generated.tsx b/.featureFlags/generated.tsx
index 979585bde3b..ffa25c70ac1 100644
--- a/.featureFlags/generated.tsx
+++ b/.featureFlags/generated.tsx
@@ -1,30 +1,35 @@
// @ts-nocheck
-import J53093 from "./images/customers-filters.png"
-import Q09991 from "./images/discounts-list.png"
-import Z15989 from "./images/draft-orders-filters.png"
-import C33827 from "./images/gift-cards-filters.png"
-import H90846 from "./images/improved_refunds.png"
-import A12919 from "./images/page-filters.png"
-import X74531 from "./images/vouchers-filters.png"
+import W24585 from "./images/collection-filters.jpg"
+import L16463 from "./images/customers-filters.png"
+import L94878 from "./images/discounts-list.png"
+import E09437 from "./images/draft-orders-filters.png"
+import E78766 from "./images/gift-cards-filters.png"
+import X68306 from "./images/improved_refunds.png"
+import E85468 from "./images/page-filters.png"
+import B37301 from "./images/vouchers-filters.png"
-const customers_filters = () => (<>
+const collection_filters = () => (<>
+Experience the new look and enhanced abilities of new filtering mechanism.
+Easily combine any criteria you want, and quickly browse their values.
+>)
+const customers_filters = () => (<>
Experience the new look and enhanced abilities of new fitering mechanism.
Easily combine any criteria you want, and quickly browse their values.
>)
-const discounts_rules = () => (<>
+const discounts_rules = () => (<>
Apply the new discounts rules to narrow your promotions audience.
Set up conditions and channels that must be fulfilled to apply defined reward.
>)
-const draft_orders_filters = () => (<>
+const draft_orders_filters = () => (<>
Experience the new look and enhanced abilities of new fitering mechanism.
Easily combine any criteria you want, and quickly browse their values.
>)
-const gift_cards_filters = () => (<>
+const gift_cards_filters = () => (<>
Experience the new look and enhanced abilities of new fitering mechanism.
Easily combine any criteria you want, and quickly browse their values.
>)
-const improved_refunds = () => (<>
+const improved_refunds = () => (<>
Enable the enhanced refund feature to streamline your refund process:
>)
-const pages_filters = () => (<>
+const pages_filters = () => (<>
Experience the new look and enhanced abilities of new fitering mechanism.
Easily combine any criteria you want, and quickly browse their values.
>)
-const vouchers_filters = () => (<>
+const vouchers_filters = () => (<>
Experience the new look and enhanced abilities of new fitering mechanism.
Easily combine any criteria you want, and quickly browse their values.
>)
export const AVAILABLE_FLAGS = [{
+ name: "collection_filters",
+ displayName: "Collection filtering",
+ component: collection_filters,
+ visible: true,
+ content: {
+ enabled: true,
+ payload: "default",
+ }
+},{
name: "customers_filters",
displayName: "Customers filtering",
component: customers_filters,
diff --git a/.featureFlags/images/collection-filters.jpg b/.featureFlags/images/collection-filters.jpg
new file mode 100644
index 00000000000..cca098d5707
Binary files /dev/null and b/.featureFlags/images/collection-filters.jpg differ
diff --git a/locale/defaultMessages.json b/locale/defaultMessages.json
index 6cae3ea2ec4..a32f6309c4e 100644
--- a/locale/defaultMessages.json
+++ b/locale/defaultMessages.json
@@ -4938,6 +4938,9 @@
"context": "tax classes card header",
"string": "General information"
},
+ "ThUvIL": {
+ "string": "Hidden"
+ },
"TjGYna": {
"context": "product inventory, checkbox",
"string": "Track Inventory"
@@ -9262,6 +9265,9 @@
"w7jT4W": {
"string": "No channels selected"
},
+ "w7tf2z": {
+ "string": "Published"
+ },
"w9xgN9": {
"context": "see error log label in notification",
"string": "See error log"
diff --git a/src/collections/components/CollectionListPage/CollectionListPage.tsx b/src/collections/components/CollectionListPage/CollectionListPage.tsx
index 887ffb8dbf2..0dd2290735e 100644
--- a/src/collections/components/CollectionListPage/CollectionListPage.tsx
+++ b/src/collections/components/CollectionListPage/CollectionListPage.tsx
@@ -12,6 +12,7 @@ import { DashboardCard } from "@dashboard/components/Card";
import { getByName } from "@dashboard/components/Filter/utils";
import { FilterPresetsSelect } from "@dashboard/components/FilterPresetsSelect";
import { ListPageLayout } from "@dashboard/components/Layouts";
+import { useFlag } from "@dashboard/featureFlags";
import { getPrevLocationState } from "@dashboard/hooks/useBackLinkWithState";
import useNavigator from "@dashboard/hooks/useNavigator";
import { sectionNames } from "@dashboard/intl";
@@ -65,6 +66,7 @@ const CollectionListPage: React.FC = ({
const navigate = useNavigator();
const filterStructure = createFilterStructure(intl, filterOpts);
const [isFilterPresetOpen, setFilterPresetOpen] = useState(false);
+ const { enabled: isNewCollectionListEnabled } = useFlag("collection_filters");
const filterDependency = filterStructure.find(getByName("channel"));
return (
@@ -116,27 +118,47 @@ const CollectionListPage: React.FC = ({
-
- {selectedCollectionIds.length > 0 && (
-
-
-
- )}
-
- }
- />
+ {isNewCollectionListEnabled ? (
+
+ {selectedCollectionIds.length > 0 && (
+
+
+
+ )}
+
+ }
+ />
+ ) : (
+
+ {selectedCollectionIds.length > 0 && (
+
+
+
+ )}
+
+ }
+ onFilterChange={onFilterChange}
+ onFilterAttributeFocus={onFilterAttributeFocus}
+ filterStructure={filterStructure}
+ />
+ )}
> = ({ location }) => {
const qs = parseQs(location.search.substr(1)) as any;
const params: CollectionListUrlQueryParams = asSortParams(qs, CollectionListUrlSortField);
- return ;
+ return (
+
+
+
+ );
};
interface CollectionDetailsRouteProps {
diff --git a/src/collections/views/CollectionList/CollectionList.tsx b/src/collections/views/CollectionList/CollectionList.tsx
index 8298131cf9a..950956f631f 100644
--- a/src/collections/views/CollectionList/CollectionList.tsx
+++ b/src/collections/views/CollectionList/CollectionList.tsx
@@ -1,8 +1,11 @@
// @ts-strict-ignore
import ActionDialog from "@dashboard/components/ActionDialog";
import useAppChannel from "@dashboard/components/AppLayout/AppChannelContext";
+import { useConditionalFilterContext } from "@dashboard/components/ConditionalFilter";
+import { createCollectionsQueryVariables } from "@dashboard/components/ConditionalFilter/queryVariables";
import DeleteFilterTabDialog from "@dashboard/components/DeleteFilterTabDialog";
import SaveFilterTabDialog from "@dashboard/components/SaveFilterTabDialog";
+import { useFlag } from "@dashboard/featureFlags";
import { useCollectionBulkDeleteMutation, useCollectionListQuery } from "@dashboard/graphql";
import { useFilterPresets } from "@dashboard/hooks/useFilterPresets";
import useListSettings from "@dashboard/hooks/useListSettings";
@@ -44,10 +47,11 @@ export const CollectionList: React.FC = ({ params }) => {
const intl = useIntl();
const notify = useNotifier();
const { updateListSettings, settings } = useListSettings(ListViews.COLLECTION_LIST);
+ const { enabled: isNewCollectionFilterEnabled } = useFlag("collection_filters");
+ const { valueProvider } = useConditionalFilterContext();
usePaginationReset(collectionListUrl, params, settings.rowNumber);
- const { channel } = useAppChannel(false);
const {
clearRowSelection,
selectedRowIds,
@@ -62,11 +66,10 @@ export const CollectionList: React.FC = ({ params }) => {
params,
keepActiveTab: true,
});
- const { availableChannels } = useAppChannel(false);
+ const { availableChannels, channel } = useAppChannel(false);
const channelOpts = availableChannels
? mapNodeToChoice(availableChannels, channel => channel.slug)
: null;
- const selectedChannel = availableChannels.find(channel => channel.slug === params.channel);
const {
selectedPreset,
presets,
@@ -84,14 +87,28 @@ export const CollectionList: React.FC = ({ params }) => {
storageUtils,
});
const paginationState = createPaginationState(settings.rowNumber, params);
- const queryVariables = React.useMemo(
- () => ({
+ const selectedChannel_legacy = availableChannels.find(channel => channel.slug === params.channel);
+ const queryVariables = React.useMemo(() => {
+ if (!isNewCollectionFilterEnabled) {
+ return {
+ ...paginationState,
+ filter: getFilterVariables(params),
+ sort: getSortQueryVariables(params),
+ channel: selectedChannel_legacy?.slug,
+ };
+ }
+
+ const { channel, ...variables } = createCollectionsQueryVariables(valueProvider.value);
+
+ return {
...paginationState,
- filter: getFilterVariables(params),
+ filter: variables,
sort: getSortQueryVariables(params),
- channel: selectedChannel?.slug,
- }),
- [params, settings.rowNumber],
+ channel, // Saleor docs say 'channel' in filter is deprecated and should be moved to root
+ };
+ }, [params, settings.rowNumber, valueProvider.value, isNewCollectionFilterEnabled]);
+ const selectedChannel = availableChannels.find(
+ channel => channel.slug === queryVariables.channel,
);
const { data, refetch } = useCollectionListQuery({
displayLoader: true,
@@ -111,10 +128,9 @@ export const CollectionList: React.FC = ({ params }) => {
}
},
});
- const filterOpts = getFilterOpts(params, channelOpts);
useEffect(() => {
- if (!canBeSorted(params.sort, !!selectedChannel)) {
+ if (!canBeSorted(params.sort, !!queryVariables.channel)) {
navigate(
collectionListUrl({
...params,
@@ -160,6 +176,11 @@ export const CollectionList: React.FC = ({ params }) => {
clearRowSelection();
}, [selectedRowIds]);
+ const filterOpts = getFilterOpts(params, channelOpts);
+ const selectedChannelId = isNewCollectionFilterEnabled
+ ? selectedChannel?.id
+ : selectedChannel_legacy?.id;
+
return (
= ({ params }) => {
onSort={handleSort}
onUpdateListSettings={updateListSettings}
sort={getSortParams(params)}
- selectedChannelId={selectedChannel?.id}
+ selectedChannelId={selectedChannelId}
filterOpts={filterOpts}
onFilterChange={changeFilters}
selectedCollectionIds={selectedRowIds}
diff --git a/src/components/ConditionalFilter/API/Handler.ts b/src/components/ConditionalFilter/API/Handler.ts
index 4484dcce716..f4cd517120b 100644
--- a/src/components/ConditionalFilter/API/Handler.ts
+++ b/src/components/ConditionalFilter/API/Handler.ts
@@ -39,7 +39,7 @@ import { IntlShape } from "react-intl";
import { ItemOption } from "../FilterElement/ConditionValue";
import { LeftOperand } from "../LeftOperandsProvider";
-import { getLocalizedLabel } from "./initialState/orders/intl";
+import { getLocalizedLabel } from "./intl";
export interface Handler {
fetch: () => Promise;
diff --git a/src/components/ConditionalFilter/API/index.ts b/src/components/ConditionalFilter/API/index.ts
deleted file mode 100644
index ff44d0671a5..00000000000
--- a/src/components/ConditionalFilter/API/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from "./initialState";
diff --git a/src/components/ConditionalFilter/API/initialState/collections/InitialCollectionState.test.ts b/src/components/ConditionalFilter/API/initialState/collections/InitialCollectionState.test.ts
new file mode 100644
index 00000000000..a960a0bd633
--- /dev/null
+++ b/src/components/ConditionalFilter/API/initialState/collections/InitialCollectionState.test.ts
@@ -0,0 +1,72 @@
+import { CollectionPublished } from "@dashboard/graphql";
+
+import { UrlEntry, UrlToken } from "../../../ValueProvider/UrlToken";
+import { InitialCollectionStateResponse } from "./InitialCollectionState";
+
+describe("ConditionalFilter / API / Page / InitialCollectionStateResponse", () => {
+ it("should filter by channel", () => {
+ // Arrange
+ const initialCollectionState = InitialCollectionStateResponse.empty();
+
+ initialCollectionState.channel = [
+ {
+ label: "Channel 1",
+ value: "chan-1",
+ slug: "chan-1",
+ },
+ {
+ label: "Channel 2",
+ value: "chan-2",
+ slug: "chan-2",
+ },
+ ];
+
+ const token = UrlToken.fromUrlEntry(new UrlEntry("s0.channel", "chan-1"));
+ const expectedOutput = [
+ {
+ label: "Channel 1",
+ value: "chan-1",
+ slug: "chan-1",
+ },
+ ];
+
+ // Act
+ const result = initialCollectionState.filterByUrlToken(token);
+
+ // Assert
+ expect(result).toEqual(expectedOutput);
+ });
+
+ it("should filter by published", () => {
+ // Arrange
+ const initialCollectionState = InitialCollectionStateResponse.empty();
+
+ initialCollectionState.published = [
+ {
+ label: CollectionPublished.PUBLISHED,
+ value: CollectionPublished.PUBLISHED,
+ slug: CollectionPublished.PUBLISHED,
+ },
+ {
+ label: CollectionPublished.HIDDEN,
+ value: CollectionPublished.HIDDEN,
+ slug: CollectionPublished.HIDDEN,
+ },
+ ];
+
+ const token = UrlToken.fromUrlEntry(new UrlEntry("s0.published", "HIDDEN"));
+ const expectedOutput = [
+ {
+ label: CollectionPublished.HIDDEN,
+ value: CollectionPublished.HIDDEN,
+ slug: CollectionPublished.HIDDEN,
+ },
+ ];
+
+ // Act
+ const result = initialCollectionState.filterByUrlToken(token);
+
+ // Assert
+ expect(result).toEqual(expectedOutput);
+ });
+});
diff --git a/src/components/ConditionalFilter/API/initialState/collections/InitialCollectionState.ts b/src/components/ConditionalFilter/API/initialState/collections/InitialCollectionState.ts
new file mode 100644
index 00000000000..bd063dd54aa
--- /dev/null
+++ b/src/components/ConditionalFilter/API/initialState/collections/InitialCollectionState.ts
@@ -0,0 +1,49 @@
+import { ItemOption } from "@dashboard/components/ConditionalFilter/FilterElement/ConditionValue";
+import { UrlToken } from "@dashboard/components/ConditionalFilter/ValueProvider/UrlToken";
+
+export interface InitialCollectionState {
+ channel: ItemOption[];
+ published: ItemOption[];
+ metadata: ItemOption[];
+}
+
+export class InitialCollectionStateResponse implements InitialCollectionState {
+ constructor(
+ public channel: ItemOption[] = [],
+ public published: ItemOption[] = [],
+ public metadata: ItemOption[] = [],
+ ) {}
+
+ static empty() {
+ return new InitialCollectionStateResponse();
+ }
+
+ public filterByUrlToken(token: UrlToken) {
+ const entry = this.getEntryByName(token.name);
+
+ if (!token.isLoadable()) {
+ return [token.value] as string[];
+ }
+
+ return entry.filter(({ slug }) => {
+ if (Array.isArray(token.value)) {
+ return token.value.includes(slug);
+ }
+
+ return slug === token.value;
+ });
+ }
+
+ private getEntryByName(name: string): ItemOption[] {
+ switch (name) {
+ case "channel":
+ return this.channel;
+ case "published":
+ return this.published;
+ case "metadata":
+ return this.metadata;
+ default:
+ return [];
+ }
+ }
+}
diff --git a/src/components/ConditionalFilter/API/initialState/collections/useInitialCollectionsState.ts b/src/components/ConditionalFilter/API/initialState/collections/useInitialCollectionsState.ts
new file mode 100644
index 00000000000..44ef37b8f96
--- /dev/null
+++ b/src/components/ConditionalFilter/API/initialState/collections/useInitialCollectionsState.ts
@@ -0,0 +1,66 @@
+import { useApolloClient } from "@apollo/client";
+import { CollectionFetchingParams } from "@dashboard/components/ConditionalFilter/ValueProvider/TokenArray/fetchingParams";
+import {
+ _GetChannelOperandsDocument,
+ _GetChannelOperandsQuery,
+ _GetChannelOperandsQueryVariables,
+ CollectionPublished,
+} from "@dashboard/graphql";
+import { useState } from "react";
+import { useIntl } from "react-intl";
+
+import { EnumValuesHandler } from "../../Handler";
+import { createInitialCollectionState } from "../helpers";
+import { InitialCollectionAPIResponse } from "../types";
+import { InitialCollectionStateResponse } from "./InitialCollectionState";
+
+export interface InitialCollectionAPIState {
+ data: InitialCollectionStateResponse;
+ loading: boolean;
+ fetchQueries: (params: CollectionFetchingParams) => Promise;
+}
+
+export const useInitialCollectionState = (): InitialCollectionAPIState => {
+ const client = useApolloClient();
+ const intl = useIntl();
+
+ const [data, setData] = useState(
+ InitialCollectionStateResponse.empty(),
+ );
+ const [loading, setLoading] = useState(true);
+
+ const queriesToRun: Array> = [];
+
+ const fetchQueries = async ({ channel }: CollectionFetchingParams) => {
+ if (channel?.length > 0) {
+ queriesToRun.push(
+ client.query<_GetChannelOperandsQuery, _GetChannelOperandsQueryVariables>({
+ query: _GetChannelOperandsDocument,
+ }),
+ );
+ }
+
+ const publishedInit = new EnumValuesHandler(CollectionPublished, "published", intl);
+
+ const data = await Promise.all(queriesToRun);
+ const initialState = {
+ ...createInitialCollectionState(data, channel),
+ published: await publishedInit.fetch(),
+ };
+
+ setData(
+ new InitialCollectionStateResponse(
+ initialState.channel,
+ initialState.published,
+ initialState.metadata,
+ ),
+ );
+ setLoading(false);
+ };
+
+ return {
+ data,
+ loading,
+ fetchQueries,
+ };
+};
diff --git a/src/components/ConditionalFilter/API/initialState/helpers.test.ts b/src/components/ConditionalFilter/API/initialState/helpers.test.ts
index 59b5498d8ad..0499641e48c 100644
--- a/src/components/ConditionalFilter/API/initialState/helpers.test.ts
+++ b/src/components/ConditionalFilter/API/initialState/helpers.test.ts
@@ -7,7 +7,7 @@ import {
_SearchProductTypesOperandsQuery,
} from "@dashboard/graphql";
-import { createInitialStateFromData } from "./helpers";
+import { createInitialProductStateFromData } from "./helpers";
describe("ConditionalFilter / API / createInitialStateFromData", () => {
it("should create initial state from queries", () => {
@@ -99,7 +99,7 @@ describe("ConditionalFilter / API / createInitialStateFromData", () => {
const data = [channelQuery, collectionQuery, categoryQuery, productTypeQuery, attributeQuery];
const channel = ["channel-1"];
// Act
- const result = createInitialStateFromData(data, channel);
+ const result = createInitialProductStateFromData(data, channel);
// Assert
expect(result).toMatchSnapshot();
diff --git a/src/components/ConditionalFilter/API/initialState/helpers.ts b/src/components/ConditionalFilter/API/initialState/helpers.ts
index 7295921a66c..450ff9ca57c 100644
--- a/src/components/ConditionalFilter/API/initialState/helpers.ts
+++ b/src/components/ConditionalFilter/API/initialState/helpers.ts
@@ -1,7 +1,4 @@
import { ApolloQueryResult } from "@apollo/client";
-import { InitialGiftCardsState } from "@dashboard/components/ConditionalFilter/API/initialState/giftCards/InitialGiftCardsState";
-import { InitialPageState } from "@dashboard/components/ConditionalFilter/API/initialState/page/InitialPageState";
-import { InitialVouchersState } from "@dashboard/components/ConditionalFilter/API/initialState/vouchers/InitialVouchersState";
import {
_GetChannelOperandsQuery,
_GetLegacyChannelOperandsQuery,
@@ -17,33 +14,38 @@ import {
import { createBooleanOptions } from "../../constants";
import { createCustomerOptionsFromAPI, createOptionsFromAPI } from "../Handler";
-import { InitialState } from "../InitialStateResponse";
+import { InitialCollectionState } from "./collections/InitialCollectionState";
+import { InitialGiftCardsState } from "./giftCards/InitialGiftCardsState";
import { InitialOrderState } from "./orders/InitialOrderState";
+import { InitialPageState } from "./page/InitialPageState";
+import { InitialProductState } from "./product/InitialProductStateResponse";
import {
- InitialAPIResponse,
+ InitialCollectionAPIResponse,
InitialGiftCardsAPIResponse,
InitialOrderAPIResponse,
InitialPageAPIResponse,
+ InitialProductAPIResponse,
InitialVoucherAPIResponse,
} from "./types";
+import { InitialVouchersState } from "./vouchers/InitialVouchersState";
const isChannelQuery = (
- query: InitialAPIResponse,
+ query: InitialProductAPIResponse,
): query is ApolloQueryResult<_GetChannelOperandsQuery> => "channels" in query.data;
const isChannelsQuery = (
query: InitialOrderAPIResponse,
): query is ApolloQueryResult<_GetLegacyChannelOperandsQuery> => "channels" in query.data;
const isCollectionQuery = (
- query: InitialAPIResponse,
+ query: InitialProductAPIResponse,
): query is ApolloQueryResult<_SearchCollectionsOperandsQuery> => "collections" in query.data;
const isCategoryQuery = (
- query: InitialAPIResponse,
+ query: InitialProductAPIResponse,
): query is ApolloQueryResult<_SearchCategoriesOperandsQuery> => "categories" in query.data;
const isProductTypeQuery = (
- query: InitialAPIResponse,
+ query: InitialProductAPIResponse,
): query is ApolloQueryResult<_SearchProductTypesOperandsQuery> => "productTypes" in query.data;
const isAttributeQuery = (
- query: InitialAPIResponse,
+ query: InitialProductAPIResponse,
): query is ApolloQueryResult<_SearchAttributeOperandsQuery> => "attributes" in query.data;
const isPageTypesQuery = (
query: InitialPageAPIResponse,
@@ -58,8 +60,11 @@ const isCurrencyQuery = (
query: InitialGiftCardsAPIResponse,
): query is ApolloQueryResult => "shop" in query.data;
-export const createInitialStateFromData = (data: InitialAPIResponse[], channel: string[]) =>
- data.reduce(
+export const createInitialProductStateFromData = (
+ data: InitialProductAPIResponse[],
+ channel: string[],
+) =>
+ data.reduce(
(acc, query) => {
if (isChannelQuery(query)) {
return {
@@ -244,3 +249,27 @@ export const createInitialGiftCardsState = (
} as InitialGiftCardsState,
);
};
+
+export const createInitialCollectionState = (
+ data: InitialCollectionAPIResponse[],
+ channel: string[],
+) =>
+ data.reduce(
+ (acc, query) => {
+ if (isChannelQuery(query)) {
+ return {
+ ...acc,
+ channel: (query.data?.channels ?? [])
+ .filter(({ slug }) => channel.includes(slug))
+ .map(({ id, name, slug }) => ({ label: name, value: id, slug })),
+ };
+ }
+
+ return acc;
+ },
+ {
+ channel: [],
+ published: [],
+ metadata: [],
+ },
+ );
diff --git a/src/components/ConditionalFilter/API/initialState/index.ts b/src/components/ConditionalFilter/API/initialState/index.ts
deleted file mode 100644
index 174987ad9f9..00000000000
--- a/src/components/ConditionalFilter/API/initialState/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from "./useInitialAPIState";
diff --git a/src/components/ConditionalFilter/API/InitalStateResponse.test.ts b/src/components/ConditionalFilter/API/initialState/product/InitalProductStateResponse.test.ts
similarity index 83%
rename from src/components/ConditionalFilter/API/InitalStateResponse.test.ts
rename to src/components/ConditionalFilter/API/initialState/product/InitalProductStateResponse.test.ts
index be2439ff2a3..018b762ffbe 100644
--- a/src/components/ConditionalFilter/API/InitalStateResponse.test.ts
+++ b/src/components/ConditionalFilter/API/initialState/product/InitalProductStateResponse.test.ts
@@ -1,10 +1,10 @@
-import { UrlEntry, UrlToken } from "../ValueProvider/UrlToken";
-import { InitialStateResponse } from "./InitialStateResponse";
+import { UrlEntry, UrlToken } from "../../../ValueProvider/UrlToken";
+import { InitialProductStateResponse } from "./InitialProductStateResponse";
-describe("ConditionalFilter / API / InitialStateResponse", () => {
+describe("ConditionalFilter / API / InitialProductStateResponse", () => {
it("should filter by dynamic attribute token", () => {
// Arrange
- const initialState = InitialStateResponse.empty();
+ const initialState = InitialProductStateResponse.empty();
initialState.attribute = {
"attribute-1": {
@@ -29,7 +29,7 @@ describe("ConditionalFilter / API / InitialStateResponse", () => {
});
it("should filter by static token type", () => {
// Arrange
- const initialState = InitialStateResponse.empty();
+ const initialState = InitialProductStateResponse.empty();
initialState.category = [{ label: "Category 1", value: "1", slug: "category-1" }];
@@ -43,7 +43,7 @@ describe("ConditionalFilter / API / InitialStateResponse", () => {
});
it("should filter by boolean attribute token", () => {
// Arrange
- const initialState = InitialStateResponse.empty();
+ const initialState = InitialProductStateResponse.empty();
initialState.attribute = {
"attribute-2": {
@@ -73,7 +73,7 @@ describe("ConditionalFilter / API / InitialStateResponse", () => {
});
it("should filter by static attribute token", () => {
// Arrange
- const initialState = InitialStateResponse.empty();
+ const initialState = InitialProductStateResponse.empty();
initialState.attribute = {
size: {
diff --git a/src/components/ConditionalFilter/API/InitialStateResponse.ts b/src/components/ConditionalFilter/API/initialState/product/InitialProductStateResponse.ts
similarity index 86%
rename from src/components/ConditionalFilter/API/InitialStateResponse.ts
rename to src/components/ConditionalFilter/API/initialState/product/InitialProductStateResponse.ts
index b9fe30f96bb..758c7845430 100644
--- a/src/components/ConditionalFilter/API/InitialStateResponse.ts
+++ b/src/components/ConditionalFilter/API/initialState/product/InitialProductStateResponse.ts
@@ -1,9 +1,9 @@
import { AttributeInputTypeEnum } from "@dashboard/graphql";
-import { createBooleanOption } from "../constants";
-import { AttributeInputType } from "../FilterElement/ConditionOptions";
-import { ItemOption } from "../FilterElement/ConditionValue";
-import { UrlToken } from "../ValueProvider/UrlToken";
+import { createBooleanOption } from "../../../constants";
+import { AttributeInputType } from "../../../FilterElement/ConditionOptions";
+import { ItemOption } from "../../../FilterElement/ConditionValue";
+import { UrlToken } from "../../../ValueProvider/UrlToken";
export interface AttributeDTO {
choices: Array<{
@@ -18,7 +18,7 @@ export interface AttributeDTO {
value: string;
}
-export interface InitialState {
+export interface InitialProductState {
category: ItemOption[];
attribute: Record;
channel: ItemOption[];
@@ -34,7 +34,7 @@ export interface InitialState {
const isDateField = (name: string) =>
["created", "updatedAt", "startDate", "endDate"].includes(name);
-export class InitialStateResponse implements InitialState {
+export class InitialProductStateResponse implements InitialProductState {
constructor(
public category: ItemOption[] = [],
public attribute: Record = {},
@@ -53,7 +53,7 @@ export class InitialStateResponse implements InitialState {
}
public static empty() {
- return new InitialStateResponse();
+ return new InitialProductStateResponse();
}
public filterByUrlToken(token: UrlToken) {
diff --git a/src/components/ConditionalFilter/API/initialState/useInitialAPIState.tsx b/src/components/ConditionalFilter/API/initialState/product/useProductInitialAPIState.tsx
similarity index 81%
rename from src/components/ConditionalFilter/API/initialState/useInitialAPIState.tsx
rename to src/components/ConditionalFilter/API/initialState/product/useProductInitialAPIState.tsx
index 44d3c398d34..cc4b4753cb8 100644
--- a/src/components/ConditionalFilter/API/initialState/useInitialAPIState.tsx
+++ b/src/components/ConditionalFilter/API/initialState/product/useProductInitialAPIState.tsx
@@ -18,22 +18,24 @@ import {
} from "@dashboard/graphql";
import { useState } from "react";
-import { FetchingParams } from "../../ValueProvider/TokenArray/fetchingParams";
-import { InitialStateResponse } from "../InitialStateResponse";
-import { createInitialStateFromData } from "./helpers";
-import { InitialAPIResponse } from "./types";
+import { FetchingParams } from "../../../ValueProvider/TokenArray/fetchingParams";
+import { createInitialProductStateFromData } from "../helpers";
+import { InitialProductAPIResponse } from "../types";
+import { InitialProductStateResponse } from "./InitialProductStateResponse";
-export interface InitialAPIState {
- data: InitialStateResponse;
+export interface InitialProductAPIState {
+ data: InitialProductStateResponse;
loading: boolean;
fetchQueries: (params: FetchingParams) => Promise;
}
-export const useProductInitialAPIState = (): InitialAPIState => {
+export const useProductInitialAPIState = (): InitialProductAPIState => {
const client = useApolloClient();
- const [data, setData] = useState(InitialStateResponse.empty());
+ const [data, setData] = useState(
+ InitialProductStateResponse.empty(),
+ );
const [loading, setLoading] = useState(true);
- const queriesToRun: Array> = [];
+ const queriesToRun: Array> = [];
const fetchQueries = async ({
category,
collection,
@@ -99,10 +101,10 @@ export const useProductInitialAPIState = (): InitialAPIState => {
}
const data = await Promise.all(queriesToRun);
- const initialState = createInitialStateFromData(data, channel);
+ const initialState = createInitialProductStateFromData(data, channel);
setData(
- new InitialStateResponse(
+ new InitialProductStateResponse(
initialState.category,
initialState.attribute,
initialState.channel,
diff --git a/src/components/ConditionalFilter/API/initialState/types.ts b/src/components/ConditionalFilter/API/initialState/types.ts
index 5631d752f4e..9b2dd4260d8 100644
--- a/src/components/ConditionalFilter/API/initialState/types.ts
+++ b/src/components/ConditionalFilter/API/initialState/types.ts
@@ -11,7 +11,7 @@ import {
ChannelCurrenciesQuery,
} from "@dashboard/graphql";
-export type InitialAPIResponse = ApolloQueryResult<
+export type InitialProductAPIResponse = ApolloQueryResult<
| _GetChannelOperandsQuery
| _SearchCollectionsOperandsQuery
| _SearchCategoriesOperandsQuery
@@ -27,3 +27,5 @@ export type InitialPageAPIResponse = ApolloQueryResult<_SearchPageTypesOperandsQ
export type InitialGiftCardsAPIResponse = ApolloQueryResult<
_SearchProductOperandsQuery | _SearchCustomersOperandsQuery | ChannelCurrenciesQuery
>;
+
+export type InitialCollectionAPIResponse = ApolloQueryResult<_GetChannelOperandsQuery>;
diff --git a/src/components/ConditionalFilter/API/initialState/orders/intl.ts b/src/components/ConditionalFilter/API/intl.ts
similarity index 87%
rename from src/components/ConditionalFilter/API/initialState/orders/intl.ts
rename to src/components/ConditionalFilter/API/intl.ts
index 14eec7a21bc..4d25ab101d2 100644
--- a/src/components/ConditionalFilter/API/initialState/orders/intl.ts
+++ b/src/components/ConditionalFilter/API/intl.ts
@@ -1,5 +1,6 @@
import { LeftOperand } from "@dashboard/components/ConditionalFilter/LeftOperandsProvider";
import {
+ CollectionPublished,
DiscountStatusEnum,
OrderAuthorizeStatusEnum,
OrderChargeStatusEnum,
@@ -13,6 +14,7 @@ import { IntlShape } from "react-intl";
import {
authorizeStatusMessages,
chargeStatusMessages,
+ collectionFilterMessages,
discountTypeMessages,
voucherStatusMessages,
} from "./messages";
@@ -81,6 +83,17 @@ const getVoucherStatusLabel = (status: DiscountStatusEnum, intl: IntlShape) => {
}
};
+const getPublishedLabel = (status: CollectionPublished, intl: IntlShape) => {
+ switch (status) {
+ case CollectionPublished.PUBLISHED:
+ return intl.formatMessage(collectionFilterMessages.published);
+ case CollectionPublished.HIDDEN:
+ return intl.formatMessage(collectionFilterMessages.hidden);
+ default:
+ return status;
+ }
+};
+
export const getLocalizedLabel = (rowType: LeftOperand["type"], value: string, intl: IntlShape) => {
switch (rowType) {
case "paymentStatus":
@@ -91,6 +104,8 @@ export const getLocalizedLabel = (rowType: LeftOperand["type"], value: string, i
return getAuthorizeStatusLabel(value as OrderAuthorizeStatusEnum, intl);
case "chargeStatus":
return getChargeStatusLabel(value as OrderChargeStatusEnum, intl);
+ case "published":
+ return getPublishedLabel(value as CollectionPublished, intl);
case "discountType":
return getDiscountTypeLabel(value as VoucherDiscountType, intl);
case "voucherStatus":
diff --git a/src/components/ConditionalFilter/API/initialState/orders/messages.ts b/src/components/ConditionalFilter/API/messages.ts
similarity index 89%
rename from src/components/ConditionalFilter/API/initialState/orders/messages.ts
rename to src/components/ConditionalFilter/API/messages.ts
index 44d650d3d2d..b70e6216a24 100644
--- a/src/components/ConditionalFilter/API/initialState/orders/messages.ts
+++ b/src/components/ConditionalFilter/API/messages.ts
@@ -76,3 +76,14 @@ export const voucherStatusMessages = defineMessages({
description: "voucher status scheduled",
},
});
+
+export const collectionFilterMessages = defineMessages({
+ published: {
+ defaultMessage: "Published",
+ id: "w7tf2z",
+ },
+ hidden: {
+ defaultMessage: "Hidden",
+ id: "ThUvIL",
+ },
+});
diff --git a/src/components/ConditionalFilter/API/providers/CollectionFilterAPIProvider.tsx b/src/components/ConditionalFilter/API/providers/CollectionFilterAPIProvider.tsx
new file mode 100644
index 00000000000..db7ed0afcad
--- /dev/null
+++ b/src/components/ConditionalFilter/API/providers/CollectionFilterAPIProvider.tsx
@@ -0,0 +1,65 @@
+import { ApolloClient, useApolloClient } from "@apollo/client";
+import { CollectionPublished } from "@dashboard/graphql/types.generated";
+import { IntlShape, useIntl } from "react-intl";
+
+import { FilterContainer, FilterElement } from "../../FilterElement";
+import { FilterAPIProvider } from "../FilterAPIProvider";
+import { ChannelHandler, EnumValuesHandler, Handler, NoopValuesHandler } 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,
+ inputValue: string,
+ intl: IntlShape,
+): Handler => {
+ const rowType = selectedRow.rowType();
+
+ if (rowType === "published") {
+ return new EnumValuesHandler(CollectionPublished, "published", intl);
+ }
+
+ if (rowType === "metadata") {
+ return new NoopValuesHandler([]);
+ }
+
+ if (rowType === "channel") {
+ return new ChannelHandler(client, inputValue);
+ }
+
+ throw new Error(`Unknown filter element: "${rowType}"`);
+};
+
+export const useCollectionFilterAPIProvider = (): FilterAPIProvider => {
+ const intl = useIntl();
+ 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, intl);
+
+ return handler.fetch();
+ };
+ const fetchLeftOptions = async () => {
+ return [];
+ };
+
+ return {
+ fetchRightOptions,
+ fetchLeftOptions,
+ };
+};
diff --git a/src/components/ConditionalFilter/API/CustomerFilterAPIProvider.tsx b/src/components/ConditionalFilter/API/providers/CustomerFilterAPIProvider.tsx
similarity index 81%
rename from src/components/ConditionalFilter/API/CustomerFilterAPIProvider.tsx
rename to src/components/ConditionalFilter/API/providers/CustomerFilterAPIProvider.tsx
index 5bc80d3c68a..db66287a4c8 100644
--- a/src/components/ConditionalFilter/API/CustomerFilterAPIProvider.tsx
+++ b/src/components/ConditionalFilter/API/providers/CustomerFilterAPIProvider.tsx
@@ -1,4 +1,4 @@
-import { FilterAPIProvider } from "./FilterAPIProvider";
+import { FilterAPIProvider } from "../FilterAPIProvider";
export const useCustomerAPIProvider = (): FilterAPIProvider => {
const fetchRightOptions = async () => {
diff --git a/src/components/ConditionalFilter/API/DiscountFiltersAPIProvider.tsx b/src/components/ConditionalFilter/API/providers/DiscountFiltersAPIProvider.tsx
similarity index 100%
rename from src/components/ConditionalFilter/API/DiscountFiltersAPIProvider.tsx
rename to src/components/ConditionalFilter/API/providers/DiscountFiltersAPIProvider.tsx
diff --git a/src/components/ConditionalFilter/API/DraftOrderFilterAPIProvider.tsx b/src/components/ConditionalFilter/API/providers/DraftOrderFilterAPIProvider.tsx
similarity index 100%
rename from src/components/ConditionalFilter/API/DraftOrderFilterAPIProvider.tsx
rename to src/components/ConditionalFilter/API/providers/DraftOrderFilterAPIProvider.tsx
diff --git a/src/components/ConditionalFilter/API/GiftCardsFilterAPIProvider.tsx b/src/components/ConditionalFilter/API/providers/GiftCardsFilterAPIProvider.tsx
similarity index 100%
rename from src/components/ConditionalFilter/API/GiftCardsFilterAPIProvider.tsx
rename to src/components/ConditionalFilter/API/providers/GiftCardsFilterAPIProvider.tsx
diff --git a/src/components/ConditionalFilter/API/OrderFilterAPIProvider.tsx b/src/components/ConditionalFilter/API/providers/OrderFilterAPIProvider.tsx
similarity index 95%
rename from src/components/ConditionalFilter/API/OrderFilterAPIProvider.tsx
rename to src/components/ConditionalFilter/API/providers/OrderFilterAPIProvider.tsx
index 6547b935a07..102b960bbd6 100644
--- a/src/components/ConditionalFilter/API/OrderFilterAPIProvider.tsx
+++ b/src/components/ConditionalFilter/API/providers/OrderFilterAPIProvider.tsx
@@ -8,8 +8,8 @@ import {
} from "@dashboard/graphql";
import { IntlShape, useIntl } from "react-intl";
-import { RowType } from "../constants";
-import { FilterContainer, FilterElement } from "../FilterElement";
+import { RowType } from "../../constants";
+import { FilterContainer, FilterElement } from "../../FilterElement";
import {
BooleanValuesHandler,
EnumValuesHandler,
@@ -17,7 +17,7 @@ import {
LegacyChannelHandler,
NoopValuesHandler,
TextInputValuesHandler,
-} from "./Handler";
+} from "../Handler";
const getFilterElement = (value: FilterContainer, index: number): FilterElement => {
const possibleFilterElement = value[index];
diff --git a/src/components/ConditionalFilter/API/PageFilterAPIProvider.tsx b/src/components/ConditionalFilter/API/providers/PageFilterAPIProvider.tsx
similarity index 95%
rename from src/components/ConditionalFilter/API/PageFilterAPIProvider.tsx
rename to src/components/ConditionalFilter/API/providers/PageFilterAPIProvider.tsx
index d9069c2db3b..25f4432c695 100644
--- a/src/components/ConditionalFilter/API/PageFilterAPIProvider.tsx
+++ b/src/components/ConditionalFilter/API/providers/PageFilterAPIProvider.tsx
@@ -5,7 +5,7 @@ import {
FilterElement,
} from "@dashboard/components/ConditionalFilter/FilterElement";
-import { FilterAPIProvider } from "./FilterAPIProvider";
+import { FilterAPIProvider } from "../FilterAPIProvider";
const getFilterElement = (value: FilterContainer, index: number): FilterElement => {
const possibleFilterElement = value[index];
diff --git a/src/components/ConditionalFilter/API/ProductFilterAPIProvider.tsx b/src/components/ConditionalFilter/API/providers/ProductFilterAPIProvider.tsx
similarity index 93%
rename from src/components/ConditionalFilter/API/ProductFilterAPIProvider.tsx
rename to src/components/ConditionalFilter/API/providers/ProductFilterAPIProvider.tsx
index d55946486f4..0d68087751b 100644
--- a/src/components/ConditionalFilter/API/ProductFilterAPIProvider.tsx
+++ b/src/components/ConditionalFilter/API/providers/ProductFilterAPIProvider.tsx
@@ -1,9 +1,9 @@
import { ApolloClient, useApolloClient } from "@apollo/client";
import { AttributeInputTypeEnum } from "@dashboard/graphql";
-import { RowType } from "../constants";
-import { FilterContainer, FilterElement } from "../FilterElement";
-import { FilterAPIProvider } from "./FilterAPIProvider";
+import { RowType } from "../../constants";
+import { FilterContainer, FilterElement } from "../../FilterElement";
+import { FilterAPIProvider } from "../FilterAPIProvider";
import {
AttributeChoicesHandler,
AttributesHandler,
@@ -13,7 +13,7 @@ import {
CollectionHandler,
Handler,
ProductTypeHandler,
-} from "./Handler";
+} from "../Handler";
const getFilterElement = (value: FilterContainer, index: number): FilterElement => {
const possibleFilterElement = value[index];
diff --git a/src/components/ConditionalFilter/API/VoucherFilterAPIProvider.ts b/src/components/ConditionalFilter/API/providers/VoucherFilterAPIProvider.ts
similarity index 97%
rename from src/components/ConditionalFilter/API/VoucherFilterAPIProvider.ts
rename to src/components/ConditionalFilter/API/providers/VoucherFilterAPIProvider.ts
index b91fc1c33c6..9d9167720c5 100644
--- a/src/components/ConditionalFilter/API/VoucherFilterAPIProvider.ts
+++ b/src/components/ConditionalFilter/API/providers/VoucherFilterAPIProvider.ts
@@ -11,7 +11,7 @@ import {
import { DiscountStatusEnum, VoucherDiscountType } from "@dashboard/graphql";
import { IntlShape, useIntl } from "react-intl";
-import { FilterAPIProvider } from "./FilterAPIProvider";
+import { FilterAPIProvider } from "../FilterAPIProvider";
const getFilterElement = (value: FilterContainer, index: number): FilterElement => {
const possibleFilterElement = value[index];
diff --git a/src/components/ConditionalFilter/FilterElement/Condition.test.ts b/src/components/ConditionalFilter/FilterElement/Condition.test.ts
index c282ccaf3a8..2648080bb1e 100644
--- a/src/components/ConditionalFilter/FilterElement/Condition.test.ts
+++ b/src/components/ConditionalFilter/FilterElement/Condition.test.ts
@@ -1,4 +1,4 @@
-import { InitialStateResponse } from "../API/InitialStateResponse";
+import { InitialProductStateResponse } from "../API/initialState/product/InitialProductStateResponse";
import { STATIC_CONDITIONS } from "../constants";
import { UrlToken } from "../ValueProvider/UrlToken";
import { Condition } from "./Condition";
@@ -24,7 +24,7 @@ describe("ConditionalFilter / FilterElement / Condition", () => {
it.each([
{
token: new UrlToken("category", ["cat1"], "s", "is"),
- response: new InitialStateResponse([
+ response: new InitialProductStateResponse([
{
label: "Cat1",
value: "cat-1-id",
@@ -47,7 +47,7 @@ describe("ConditionalFilter / FilterElement / Condition", () => {
},
{
token: new UrlToken("some-attr1", ["some-attr-1z"], "m", "in"),
- response: new InitialStateResponse([], {
+ response: new InitialProductStateResponse([], {
"some-attr1": {
choices: [
{
diff --git a/src/components/ConditionalFilter/FilterElement/Condition.ts b/src/components/ConditionalFilter/FilterElement/Condition.ts
index 67c9065ce7c..27e7262d4bf 100644
--- a/src/components/ConditionalFilter/FilterElement/Condition.ts
+++ b/src/components/ConditionalFilter/FilterElement/Condition.ts
@@ -1,9 +1,6 @@
-import { InitialGiftCardsStateResponse } from "../API/initialState/giftCards/InitialGiftCardsState";
-import { InitialOrderStateResponse } from "../API/initialState/orders/InitialOrderState";
-import { InitialPageStateResponse } from "../API/initialState/page/InitialPageState";
-import { InitialVouchersStateResponse } from "../API/initialState/vouchers/InitialVouchersState";
-import { InitialStateResponse } from "../API/InitialStateResponse";
+import { InitialProductStateResponse } from "../API/initialState/product/InitialProductStateResponse";
import { LeftOperand } from "../LeftOperandsProvider";
+import { InitialResponseType } from "../types";
import { UrlToken } from "./../ValueProvider/UrlToken";
import { ConditionOptions, StaticElementName } from "./ConditionOptions";
import { ConditionSelected } from "./ConditionSelected";
@@ -48,15 +45,7 @@ export class Condition {
return new Condition(options, ConditionSelected.fromConditionItem(options.first()), false);
}
- public static fromUrlToken(
- token: UrlToken,
- response:
- | InitialStateResponse
- | InitialOrderStateResponse
- | InitialVouchersStateResponse
- | InitialPageStateResponse
- | InitialGiftCardsStateResponse,
- ) {
+ public static fromUrlToken(token: UrlToken, response: InitialResponseType) {
if (ConditionOptions.isStaticName(token.name)) {
const staticOptions = ConditionOptions.fromStaticElementName(token.name);
const selectedOption = staticOptions.findByLabel(token.conditionKind);
@@ -81,7 +70,7 @@ export class Condition {
}
if (token.isAttribute()) {
- const attribute = (response as InitialStateResponse).attributeByName(token.name);
+ const attribute = (response as InitialProductStateResponse).attributeByName(token.name);
const options = ConditionOptions.fromAttributeType(attribute.inputType);
const option = options.find(item => item.label === token.conditionKind)!;
const value = response.filterByUrlToken(token);
diff --git a/src/components/ConditionalFilter/FilterElement/Constraint.test.ts b/src/components/ConditionalFilter/FilterElement/Constraint.test.ts
index a44ab24ced4..228a0eb2bcc 100644
--- a/src/components/ConditionalFilter/FilterElement/Constraint.test.ts
+++ b/src/components/ConditionalFilter/FilterElement/Constraint.test.ts
@@ -21,7 +21,7 @@ describe("ConditionalFilter / FilterElement / Constraint", () => {
// Assert
expect(constraint).toEqual({
- dependsOn: ["price", "isVisibleInListing", "isAvailable", "isPublished"],
+ dependsOn: ["price", "isVisibleInListing", "isAvailable", "isPublished", "published"],
disabled: ["left", "condition"],
removable: false,
});
diff --git a/src/components/ConditionalFilter/FilterElement/FilterElement.ts b/src/components/ConditionalFilter/FilterElement/FilterElement.ts
index b07446d8c99..ea79aa31840 100644
--- a/src/components/ConditionalFilter/FilterElement/FilterElement.ts
+++ b/src/components/ConditionalFilter/FilterElement/FilterElement.ts
@@ -1,10 +1,7 @@
-import { InitialGiftCardsStateResponse } from "../API/initialState/giftCards/InitialGiftCardsState";
-import { InitialOrderStateResponse } from "../API/initialState/orders/InitialOrderState";
-import { InitialPageStateResponse } from "../API/initialState/page/InitialPageState";
-import { InitialVouchersStateResponse } from "../API/initialState/vouchers/InitialVouchersState";
-import { InitialStateResponse } from "../API/InitialStateResponse";
+import { InitialProductStateResponse } from "../API/initialState/product/InitialProductStateResponse";
import { RowType, STATIC_OPTIONS } from "../constants";
import { LeftOperand } from "../LeftOperandsProvider";
+import { InitialResponseType } from "../types";
import { TokenType, UrlEntry, UrlToken } from "./../ValueProvider/UrlToken";
import { Condition } from "./Condition";
import { ConditionItem, ConditionOptions, StaticElementName } from "./ConditionOptions";
@@ -49,7 +46,7 @@ export class ExpressionValue {
return new ExpressionValue(token.name, option.label, token.name);
}
- public static forAttribute(attributeName: string, response: InitialStateResponse) {
+ public static forAttribute(attributeName: string, response: InitialProductStateResponse) {
const attribute = response.attributeByName(attributeName);
return new ExpressionValue(attributeName, attribute.label, attribute.inputType);
@@ -178,15 +175,7 @@ export class FilterElement {
return new FilterElement(ExpressionValue.fromSlug(slug), Condition.emptyFromSlug(slug), false);
}
- public static fromUrlToken(
- token: UrlToken,
- response:
- | InitialStateResponse
- | InitialOrderStateResponse
- | InitialVouchersStateResponse
- | InitialPageStateResponse
- | InitialGiftCardsStateResponse,
- ) {
+ public static fromUrlToken(token: UrlToken, response: InitialResponseType) {
if (token.isStatic()) {
return new FilterElement(
ExpressionValue.fromUrlToken(token),
@@ -197,7 +186,7 @@ export class FilterElement {
if (token.isAttribute()) {
return new FilterElement(
- ExpressionValue.forAttribute(token.name, response as InitialStateResponse),
+ ExpressionValue.forAttribute(token.name, response as InitialProductStateResponse),
Condition.fromUrlToken(token, response),
false,
);
diff --git a/src/components/ConditionalFilter/ValueProvider/TokenArray/TokenArray.test.ts b/src/components/ConditionalFilter/ValueProvider/TokenArray/TokenArray.test.ts
index b29af42321f..63375e4af24 100644
--- a/src/components/ConditionalFilter/ValueProvider/TokenArray/TokenArray.test.ts
+++ b/src/components/ConditionalFilter/ValueProvider/TokenArray/TokenArray.test.ts
@@ -1,4 +1,4 @@
-import { InitialStateResponse } from "../../API/InitialStateResponse";
+import { InitialProductStateResponse } from "../../API/initialState/product/InitialProductStateResponse";
import { TokenArray } from ".";
import { FetchingParams } from "./fetchingParams";
@@ -15,7 +15,7 @@ describe("ConditionalFilter / ValueProvider / TokenArray", () => {
// Arrange
const url = new TokenArray("");
// Act
- const fetchingParams = url.getFetchingParams(productParams);
+ const fetchingParams = url.getFetchingParams(productParams, "product");
// Assert
expect(fetchingParams).toEqual({
@@ -44,7 +44,7 @@ describe("ConditionalFilter / ValueProvider / TokenArray", () => {
});
// Act
const url = new TokenArray(params.toString());
- const fetchingParams = url.getFetchingParams(productParams);
+ const fetchingParams = url.getFetchingParams(productParams, "product");
// Assert
expect(fetchingParams).toEqual({
@@ -64,7 +64,7 @@ describe("ConditionalFilter / ValueProvider / TokenArray", () => {
"1": "AND",
"2[s0.channel]": "channel-pln",
});
- const response = new InitialStateResponse(
+ const response = new InitialProductStateResponse(
[
{
label: "Cat1",
@@ -93,7 +93,7 @@ describe("ConditionalFilter / ValueProvider / TokenArray", () => {
const params = new URLSearchParams({
"0[s0.channel]": "channel-pln",
});
- const response = new InitialStateResponse(
+ const response = new InitialProductStateResponse(
[
{
label: "Cat1",
diff --git a/src/components/ConditionalFilter/ValueProvider/TokenArray/__snapshots__/TokenArray.test.ts.snap b/src/components/ConditionalFilter/ValueProvider/TokenArray/__snapshots__/TokenArray.test.ts.snap
index 75a346f834c..3e1e62796b8 100644
--- a/src/components/ConditionalFilter/ValueProvider/TokenArray/__snapshots__/TokenArray.test.ts.snap
+++ b/src/components/ConditionalFilter/ValueProvider/TokenArray/__snapshots__/TokenArray.test.ts.snap
@@ -116,6 +116,7 @@ TokenArray [
"isVisibleInListing",
"isAvailable",
"isPublished",
+ "published",
],
"disabled": Array [
"left",
diff --git a/src/components/ConditionalFilter/ValueProvider/TokenArray/fetchingParams.test.ts b/src/components/ConditionalFilter/ValueProvider/TokenArray/fetchingParams.test.ts
index a5d1291d58d..e83e784d74a 100644
--- a/src/components/ConditionalFilter/ValueProvider/TokenArray/fetchingParams.test.ts
+++ b/src/components/ConditionalFilter/ValueProvider/TokenArray/fetchingParams.test.ts
@@ -1,18 +1,19 @@
import { UrlToken } from "../UrlToken";
import {
- getFetchingPrams,
+ getEmptyFetchingPrams,
+ toCollectionFetchingParams,
toGiftCardsFetchingParams,
toPageFetchingParams,
toVouchersFetchingParams,
} from "./fetchingParams";
-describe("TokenArray / fetchingParams / getFetchingPrams", () => {
+describe("TokenArray / fetchingParams / getEmptyFetchingPrams", () => {
it("should return product fetching params", () => {
// Arrange
const type = "product";
// Act
- const fetchingParams = getFetchingPrams(type);
+ const fetchingParams = getEmptyFetchingPrams(type);
// Assert
expect(fetchingParams).toEqual({
@@ -29,7 +30,7 @@ describe("TokenArray / fetchingParams / getFetchingPrams", () => {
const type = "order";
// Act
- const fetchingParams = getFetchingPrams(type);
+ const fetchingParams = getEmptyFetchingPrams(type);
// Assert
expect(fetchingParams).toEqual({
@@ -48,7 +49,7 @@ describe("TokenArray / fetchingParams / getFetchingPrams", () => {
const type = "voucher";
// Act
- const fetchingParams = getFetchingPrams(type);
+ const fetchingParams = getEmptyFetchingPrams(type);
// Assert
expect(fetchingParams).toEqual({
@@ -63,7 +64,7 @@ describe("TokenArray / fetchingParams / getFetchingPrams", () => {
const type = "page";
// Act
- const fetchingParams = getFetchingPrams(type);
+ const fetchingParams = getEmptyFetchingPrams(type);
// Assert
expect(fetchingParams).toEqual({
@@ -76,7 +77,7 @@ describe("TokenArray / fetchingParams / getFetchingPrams", () => {
const type = "gift-cards";
// Act
- const fetchingParams = getFetchingPrams(type);
+ const fetchingParams = getEmptyFetchingPrams(type);
// Assert
expect(fetchingParams).toEqual({
@@ -169,3 +170,31 @@ describe("TokenArray / fetchingParams / toGiftCardsFetchingParams", () => {
});
});
});
+
+describe("TokenArray / fetchingParams / toCollectionFetchingParams", () => {
+ it("should return fetching params", () => {
+ // Arrange
+ const params = {
+ channel: [],
+ metadata: [],
+ published: [],
+ };
+
+ const token = {
+ conditionKind: "in",
+ name: "channel",
+ type: "s",
+ value: "chan-1",
+ } as UrlToken;
+
+ // Act
+ const fetchingParams = toCollectionFetchingParams(params, token);
+
+ // Assert
+ expect(fetchingParams).toEqual({
+ channel: ["chan-1"],
+ metadata: [],
+ published: [],
+ });
+ });
+});
diff --git a/src/components/ConditionalFilter/ValueProvider/TokenArray/fetchingParams.ts b/src/components/ConditionalFilter/ValueProvider/TokenArray/fetchingParams.ts
index a68e87f4cd4..b07d1f42ea8 100644
--- a/src/components/ConditionalFilter/ValueProvider/TokenArray/fetchingParams.ts
+++ b/src/components/ConditionalFilter/ValueProvider/TokenArray/fetchingParams.ts
@@ -1,3 +1,4 @@
+import { FilterProviderType } from "../../types";
import { TokenType, UrlToken } from "../UrlToken";
export interface FetchingParams {
@@ -35,6 +36,12 @@ export interface GiftCardsFetchingParams {
usedBy: string[];
}
+export interface CollectionFetchingParams {
+ channel: string[];
+ metadata: string[];
+ published: string[];
+}
+
type FetchingParamsKeys = keyof Omit;
type OrderParamsKeys = keyof OrderFetchingParams;
type VoucherParamsKeys = keyof VoucherFetchingParams;
@@ -76,6 +83,12 @@ export const emptyGiftCardsFetchingParams: GiftCardsFetchingParams = {
usedBy: [],
};
+export const emptyCollectionFetchingParams: CollectionFetchingParams = {
+ channel: [],
+ metadata: [],
+ published: [],
+};
+
const unique = (array: Iterable) => Array.from(new Set(array));
const includedInParams = (c: UrlToken) =>
TokenType.ATTRIBUTE_DROPDOWN === c.type || TokenType.ATTRIBUTE_MULTISELECT === c.type;
@@ -162,17 +175,27 @@ export const toGiftCardsFetchingParams = (p: GiftCardsFetchingParams, c: UrlToke
return p;
};
-export const getFetchingPrams = (
- type:
- | "product"
- | "order"
- | "discount"
- | "voucher"
- | "page"
- | "draft-order"
- | "gift-cards"
- | "customer",
-) => {
+export const toCollectionFetchingParams = (p: CollectionFetchingParams, c: UrlToken) => {
+ const key = c.name as keyof CollectionFetchingParams;
+
+ if (!p[key]) {
+ p[key] = [];
+ }
+
+ p[key] = unique(p[key].concat(c.value));
+
+ return p;
+};
+
+export type FetchingParamsType =
+ | OrderFetchingParams
+ | FetchingParams
+ | CollectionFetchingParams
+ | GiftCardsFetchingParams
+ | PageFetchingParams
+ | VoucherFetchingParams;
+
+export const getEmptyFetchingPrams = (type: FilterProviderType) => {
switch (type) {
case "product":
return emptyFetchingParams;
@@ -184,5 +207,7 @@ export const getFetchingPrams = (
return emptyPageFetchingParams;
case "gift-cards":
return emptyGiftCardsFetchingParams;
+ case "collection":
+ return emptyCollectionFetchingParams;
}
};
diff --git a/src/components/ConditionalFilter/ValueProvider/TokenArray/index.ts b/src/components/ConditionalFilter/ValueProvider/TokenArray/index.ts
index 26c47713790..0363230b796 100644
--- a/src/components/ConditionalFilter/ValueProvider/TokenArray/index.ts
+++ b/src/components/ConditionalFilter/ValueProvider/TokenArray/index.ts
@@ -1,17 +1,17 @@
import { parse, ParsedQs } from "qs";
-import { InitialGiftCardsStateResponse } from "../../API/initialState/giftCards/InitialGiftCardsState";
-import { InitialOrderStateResponse } from "../../API/initialState/orders/InitialOrderState";
-import { InitialPageStateResponse } from "../../API/initialState/page/InitialPageState";
-import { InitialVouchersStateResponse } from "../../API/initialState/vouchers/InitialVouchersState";
-import { InitialStateResponse } from "../../API/InitialStateResponse";
+import { InitialProductStateResponse } from "../../API/initialState/product/InitialProductStateResponse";
import { FilterContainer, FilterElement } from "../../FilterElement";
+import { FilterProviderType, InitialResponseType } from "../../types";
import { UrlEntry, UrlToken } from "../UrlToken";
import {
+ CollectionFetchingParams,
FetchingParams,
+ FetchingParamsType,
GiftCardsFetchingParams,
OrderFetchingParams,
PageFetchingParams,
+ toCollectionFetchingParams,
toFetchingParams,
toGiftCardsFetchingParams,
toOrderFetchingParams,
@@ -52,12 +52,7 @@ const tokenizeUrl = (urlParams: string) => {
};
const mapUrlTokensToFilterValues = (
urlTokens: TokenArray,
- response:
- | InitialStateResponse
- | InitialOrderStateResponse
- | InitialVouchersStateResponse
- | InitialPageStateResponse
- | InitialGiftCardsStateResponse,
+ response: InitialResponseType,
): FilterContainer =>
urlTokens.map(el => {
if (typeof el === "string") {
@@ -76,55 +71,46 @@ export class TokenArray extends Array {
super(...tokenizeUrl(url));
}
- public getFetchingParams(
- params:
- | OrderFetchingParams
- | FetchingParams
- | VoucherFetchingParams
- | PageFetchingParams
- | GiftCardsFetchingParams,
- ) {
- if ("paymentStatus" in params) {
- return this.asFlatArray()
- .filter(token => token.isLoadable())
- .reduce(toOrderFetchingParams, params);
+ public getFetchingParams(params: FetchingParamsType, type: FilterProviderType) {
+ switch (type) {
+ case "order":
+ return this.asFlatArray()
+ .filter(token => token.isLoadable())
+ .reduce(toOrderFetchingParams, params as OrderFetchingParams);
+ case "collection":
+ return this.asFlatArray()
+ .filter(token => token.isLoadable())
+ .reduce(
+ toCollectionFetchingParams,
+ params as CollectionFetchingParams,
+ );
+ case "voucher":
+ return this.asFlatArray()
+ .filter(token => token.isLoadable())
+ .reduce(toVouchersFetchingParams, params as VoucherFetchingParams);
+ case "page":
+ return this.asFlatArray()
+ .filter(token => token.isLoadable())
+ .reduce(toPageFetchingParams, params as PageFetchingParams);
+ case "gift-cards":
+ return this.asFlatArray()
+ .filter(token => token.isLoadable())
+ .reduce(
+ toGiftCardsFetchingParams,
+ params as GiftCardsFetchingParams,
+ );
+ default:
+ return this.asFlatArray()
+ .filter(token => token.isLoadable())
+ .reduce(toFetchingParams, params as FetchingParams);
}
-
- if ("discountType" in params) {
- return this.asFlatArray()
- .filter(token => token.isLoadable())
- .reduce(toVouchersFetchingParams, params);
- }
-
- if ("pageTypes" in params) {
- return this.asFlatArray()
- .filter(token => token.isLoadable())
- .reduce(toPageFetchingParams, params);
- }
-
- if ("currency" in params) {
- return this.asFlatArray()
- .filter(token => token.isLoadable())
- .reduce(toGiftCardsFetchingParams, params);
- }
-
- return this.asFlatArray()
- .filter(token => token.isLoadable())
- .reduce(toFetchingParams, params);
}
public asFlatArray() {
return flatenate(this);
}
- public asFilterValuesFromResponse(
- response:
- | InitialStateResponse
- | InitialOrderStateResponse
- | InitialVouchersStateResponse
- | InitialPageStateResponse
- | InitialGiftCardsStateResponse,
- ): FilterContainer {
+ public asFilterValuesFromResponse(response: InitialResponseType): FilterContainer {
return this.map(el => {
if (typeof el === "string") {
return el;
@@ -145,6 +131,6 @@ export class TokenArray extends Array {
}
public asFilterValueFromEmpty(): FilterContainer {
- return this.asFilterValuesFromResponse(InitialStateResponse.empty());
+ return this.asFilterValuesFromResponse(InitialProductStateResponse.empty());
}
}
diff --git a/src/components/ConditionalFilter/ValueProvider/TokenArray/ordersFetchingParams.ts b/src/components/ConditionalFilter/ValueProvider/TokenArray/ordersFetchingParams.ts
deleted file mode 100644
index e3425d48408..00000000000
--- a/src/components/ConditionalFilter/ValueProvider/TokenArray/ordersFetchingParams.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import { UrlToken } from "../UrlToken";
-
-export interface OrdersFetchingParams {
- paymentStatus: string[];
-}
-
-type FetchingParamsKeys = keyof Omit;
-
-export const emptyFetchingParams: OrdersFetchingParams = {
- paymentStatus: [],
-};
-
-const unique = (array: Iterable) => Array.from(new Set(array));
-
-export const toFetchingParams = (p: OrdersFetchingParams, c: UrlToken) => {
- const key = c.name as FetchingParamsKeys;
-
- if (!c.isAttribute() && !p[key]) {
- p[key] = [];
- }
-
- p[key] = unique(p[key].concat(c.value));
-
- return p;
-};
diff --git a/src/components/ConditionalFilter/ValueProvider/UrlToken.ts b/src/components/ConditionalFilter/ValueProvider/UrlToken.ts
index ec9a4728b94..676fc814bb0 100644
--- a/src/components/ConditionalFilter/ValueProvider/UrlToken.ts
+++ b/src/components/ConditionalFilter/ValueProvider/UrlToken.ts
@@ -6,6 +6,18 @@ import { slugFromConditionValue } from "../FilterElement/ConditionValue";
export const CONDITIONS = ["is", "equals", "in", "between", "lower", "greater"];
+const PRODUCT_STATICS = [
+ "category",
+ "collection",
+ "channel",
+ "productType",
+ "isAvailable",
+ "isPublished",
+ "isVisibleInListing",
+ "hasCategory",
+ "giftCard",
+];
+
const ORDER_STATICS = [
"paymentStatus",
"status",
@@ -25,20 +37,15 @@ const PAGE_STATIC = ["pageTypes"];
const GIFT_CARDS_STATICS = ["currency", "products", "isActive", "tags", "usedBy"];
+const COLLECTION_STATICS = ["channel", "published"];
+
const STATIC_TO_LOAD = [
- "category",
- "collection",
- "channel",
- "productType",
- "isAvailable",
- "isPublished",
- "isVisibleInListing",
- "hasCategory",
- "giftCard",
+ ...PRODUCT_STATICS,
...ORDER_STATICS,
...VOUCHER_STATICS,
...PAGE_STATIC,
...GIFT_CARDS_STATICS,
+ ...COLLECTION_STATICS,
];
export const TokenType = {
diff --git a/src/components/ConditionalFilter/ValueProvider/useUrlValueProvider.ts b/src/components/ConditionalFilter/ValueProvider/useUrlValueProvider.ts
index 65a4ba966da..fe48f3227d2 100644
--- a/src/components/ConditionalFilter/ValueProvider/useUrlValueProvider.ts
+++ b/src/components/ConditionalFilter/ValueProvider/useUrlValueProvider.ts
@@ -3,17 +3,20 @@ import { stringify } from "qs";
import { useEffect, useState } from "react";
import useRouter from "use-react-router";
-import { InitialAPIState } from "../API";
+import { InitialCollectionAPIState } from "../API/initialState/collections/useInitialCollectionsState";
import { InitialGiftCardsAPIState } from "../API/initialState/giftCards/useInitialGiftCardsState";
import { InitialOrderAPIState } from "../API/initialState/orders/useInitialOrderState";
import { InitialPageAPIState } from "../API/initialState/page/useInitialPageState";
+import { InitialProductAPIState } from "../API/initialState/product/useProductInitialAPIState";
import { InitialVoucherAPIState } from "../API/initialState/vouchers/useInitialVouchersState";
import { FilterContainer, FilterElement } from "../FilterElement";
import { FilterValueProvider } from "../FilterValueProvider";
+import { FilterProviderType, InitialAPIState } from "../types";
import { TokenArray } from "./TokenArray";
import {
+ CollectionFetchingParams,
FetchingParams,
- getFetchingPrams,
+ getEmptyFetchingPrams,
GiftCardsFetchingParams,
OrderFetchingParams,
PageFetchingParams,
@@ -23,21 +26,8 @@ import { prepareStructure } from "./utils";
export const useUrlValueProvider = (
locationSearch: string,
- type:
- | "product"
- | "order"
- | "discount"
- | "voucher"
- | "page"
- | "draft-order"
- | "gift-cards"
- | "customer",
- initialState?:
- | InitialAPIState
- | InitialOrderAPIState
- | InitialVoucherAPIState
- | InitialPageAPIState
- | InitialGiftCardsAPIState,
+ type: FilterProviderType,
+ initialState?: InitialAPIState,
): FilterValueProvider => {
const router = useRouter();
const params = new URLSearchParams(locationSearch);
@@ -55,14 +45,16 @@ export const useUrlValueProvider = (
params.delete("after");
const tokenizedUrl = new TokenArray(params.toString());
- const paramsFromType = getFetchingPrams(type);
- const fetchingParams = paramsFromType ? tokenizedUrl.getFetchingParams(paramsFromType) : null;
+ const paramsFromType = getEmptyFetchingPrams(type);
+ const fetchingParams = paramsFromType
+ ? tokenizedUrl.getFetchingParams(paramsFromType, type)
+ : null;
useEffect(() => {
if (initialState) {
switch (type) {
case "product":
- (initialState as InitialAPIState).fetchQueries(fetchingParams as FetchingParams);
+ (initialState as InitialProductAPIState).fetchQueries(fetchingParams as FetchingParams);
break;
case "order":
(initialState as InitialOrderAPIState).fetchQueries(
@@ -82,6 +74,11 @@ export const useUrlValueProvider = (
fetchingParams as GiftCardsFetchingParams,
);
break;
+ case "collection":
+ (initialState as InitialCollectionAPIState).fetchQueries(
+ fetchingParams as CollectionFetchingParams,
+ );
+ break;
}
}
}, [locationSearch]);
diff --git a/src/components/ConditionalFilter/constants.ts b/src/components/ConditionalFilter/constants.ts
index 5518f689761..acea0513748 100644
--- a/src/components/ConditionalFilter/constants.ts
+++ b/src/components/ConditionalFilter/constants.ts
@@ -182,11 +182,25 @@ export const STATIC_CONDITIONS = {
products: [{ type: "multiselect", label: "in", value: "input-1" }],
tags: [{ type: "multiselect", label: "in", value: "input-1" }],
usedBy: [{ type: "multiselect", label: "in", value: "input-1" }],
+ published: [
+ {
+ type: "select",
+ label: "is",
+ value: "input-1",
+ },
+ ],
+ slugs: [
+ {
+ type: "bulkselect",
+ label: "in",
+ value: "input-1",
+ },
+ ],
};
export const CONSTRAINTS = {
channel: {
- dependsOn: ["price", "isVisibleInListing", "isAvailable", "isPublished"],
+ dependsOn: ["price", "isVisibleInListing", "isAvailable", "isPublished", "published"],
removable: false,
disabled: ["left", "condition"],
},
@@ -375,6 +389,27 @@ export const STATIC_VOUCHER_OPTIONS: LeftOperand[] = [
},
];
+export const STATIC_COLLECTION_OPTIONS: LeftOperand[] = [
+ {
+ value: "published",
+ label: "Published",
+ type: "published",
+ slug: "published",
+ },
+ {
+ value: "metadata",
+ label: "Metadata",
+ type: "metadata",
+ slug: "metadata",
+ },
+ {
+ value: "channel",
+ label: "Channel",
+ type: "channel",
+ slug: "channel",
+ },
+];
+
export const STATIC_PAGE_OPTIONS: LeftOperand[] = [
{
value: "pageTypes",
@@ -468,6 +503,7 @@ export const STATIC_OPTIONS = [
...STATIC_DRAFT_ORDER_OPTIONS,
...STATIC_GIFT_CARDS_OPTIONS,
...STATIC_CUSTOMER_OPTIONS,
+ ...STATIC_COLLECTION_OPTIONS,
];
export const ATTRIBUTE_INPUT_TYPE_CONDITIONS = {
diff --git a/src/components/ConditionalFilter/context/provider.tsx b/src/components/ConditionalFilter/context/provider.tsx
index 7d6bfcd0c7d..71664358aaf 100644
--- a/src/components/ConditionalFilter/context/provider.tsx
+++ b/src/components/ConditionalFilter/context/provider.tsx
@@ -1,19 +1,22 @@
import React, { FC } from "react";
-import { useCustomerAPIProvider } from "../API/CustomerFilterAPIProvider";
-import { useDiscountFilterAPIProvider } from "../API/DiscountFiltersAPIProvider";
-import { useDraftOrderFilterAPIProvider } from "../API/DraftOrderFilterAPIProvider";
-import { useGiftCardsFiltersAPIProvider } from "../API/GiftCardsFilterAPIProvider";
+import { useInitialCollectionState } from "../API/initialState/collections/useInitialCollectionsState";
import { useInitialGiftCardsState } from "../API/initialState/giftCards/useInitialGiftCardsState";
import { useInitialOrderState } from "../API/initialState/orders/useInitialOrderState";
import { useInitialPageState } from "../API/initialState/page/useInitialPageState";
-import { useProductInitialAPIState } from "../API/initialState/useInitialAPIState";
+import { useProductInitialAPIState } from "../API/initialState/product/useProductInitialAPIState";
import { useInitialVouchersState } from "../API/initialState/vouchers/useInitialVouchersState";
-import { useOrderFilterAPIProvider } from "../API/OrderFilterAPIProvider";
-import { usePageAPIProvider } from "../API/PageFilterAPIProvider";
-import { useProductFilterAPIProvider } from "../API/ProductFilterAPIProvider";
-import { useVoucherAPIProvider } from "../API/VoucherFilterAPIProvider";
+import { useCollectionFilterAPIProvider } from "../API/providers/CollectionFilterAPIProvider";
+import { useCustomerAPIProvider } from "../API/providers/CustomerFilterAPIProvider";
+import { useDiscountFilterAPIProvider } from "../API/providers/DiscountFiltersAPIProvider";
+import { useDraftOrderFilterAPIProvider } from "../API/providers/DraftOrderFilterAPIProvider";
+import { useGiftCardsFiltersAPIProvider } from "../API/providers/GiftCardsFilterAPIProvider";
+import { useOrderFilterAPIProvider } from "../API/providers/OrderFilterAPIProvider";
+import { usePageAPIProvider } from "../API/providers/PageFilterAPIProvider";
+import { useProductFilterAPIProvider } from "../API/providers/ProductFilterAPIProvider";
+import { useVoucherAPIProvider } from "../API/providers/VoucherFilterAPIProvider";
import {
+ STATIC_COLLECTION_OPTIONS,
STATIC_CUSTOMER_OPTIONS,
STATIC_DISCOUNT_OPTIONS,
STATIC_DRAFT_ORDER_OPTIONS,
@@ -232,3 +235,30 @@ export const ConditionalCustomerFilterProvider: FC<{
);
};
+
+export const ConditionalCollectionFilterProvider: FC<{
+ locationSearch: string;
+}> = ({ children, locationSearch }) => {
+ const apiProvider = useCollectionFilterAPIProvider();
+
+ const initialState = useInitialCollectionState();
+
+ const valueProvider = useUrlValueProvider(locationSearch, "collection", initialState);
+ const leftOperandsProvider = useFilterLeftOperandsProvider(STATIC_COLLECTION_OPTIONS);
+ const containerState = useContainerState(valueProvider);
+ const filterWindow = useFilterWindow();
+
+ return (
+
+ {children}
+
+ );
+};
diff --git a/src/components/ConditionalFilter/queryVariables.ts b/src/components/ConditionalFilter/queryVariables.ts
index 01a72346437..06eec2f249c 100644
--- a/src/components/ConditionalFilter/queryVariables.ts
+++ b/src/components/ConditionalFilter/queryVariables.ts
@@ -1,5 +1,6 @@
import {
AttributeInput,
+ CollectionFilterInput,
CustomerFilterInput,
DateRangeInput,
DateTimeFilterInput,
@@ -340,3 +341,27 @@ export const createCustomerQueryVariables = (value: FilterContainer): CustomerFi
return p;
}, {} as CustomerFilterInput);
};
+
+type CollectionQueryVars = CollectionFilterInput & { channel?: { eq: string } };
+
+export const createCollectionsQueryVariables = (value: FilterContainer): CollectionQueryVars => {
+ return value.reduce((p, c) => {
+ if (typeof c === "string" || Array.isArray(c)) return p;
+
+ if (c.value.type === "metadata") {
+ p.metadata = p.metadata || [];
+
+ const [key, value] = c.condition.selected.value as [string, string];
+
+ p.metadata.push({ key, value });
+
+ return p;
+ }
+
+ p[c.value.value as keyof CollectionFilterInput] = mapStaticQueryPartToLegacyVariables(
+ createStaticQueryPart(c.condition.selected),
+ );
+
+ return p;
+ }, {} as CollectionQueryVars);
+};
diff --git a/src/components/ConditionalFilter/types.ts b/src/components/ConditionalFilter/types.ts
new file mode 100644
index 00000000000..762b6cab042
--- /dev/null
+++ b/src/components/ConditionalFilter/types.ts
@@ -0,0 +1,39 @@
+import { InitialCollectionStateResponse } from "./API/initialState/collections/InitialCollectionState";
+import { InitialCollectionAPIState } from "./API/initialState/collections/useInitialCollectionsState";
+import { InitialGiftCardsStateResponse } from "./API/initialState/giftCards/InitialGiftCardsState";
+import { InitialGiftCardsAPIState } from "./API/initialState/giftCards/useInitialGiftCardsState";
+import { InitialOrderStateResponse } from "./API/initialState/orders/InitialOrderState";
+import { InitialOrderAPIState } from "./API/initialState/orders/useInitialOrderState";
+import { InitialPageStateResponse } from "./API/initialState/page/InitialPageState";
+import { InitialPageAPIState } from "./API/initialState/page/useInitialPageState";
+import { InitialProductStateResponse } from "./API/initialState/product/InitialProductStateResponse";
+import { InitialProductAPIState } from "./API/initialState/product/useProductInitialAPIState";
+import { InitialVouchersStateResponse } from "./API/initialState/vouchers/InitialVouchersState";
+import { InitialVoucherAPIState } from "./API/initialState/vouchers/useInitialVouchersState";
+
+export type InitialResponseType =
+ | InitialProductStateResponse
+ | InitialOrderStateResponse
+ | InitialCollectionStateResponse
+ | InitialVouchersStateResponse
+ | InitialPageStateResponse
+ | InitialGiftCardsStateResponse;
+
+export type InitialAPIState =
+ | InitialProductAPIState
+ | InitialOrderAPIState
+ | InitialVoucherAPIState
+ | InitialPageAPIState
+ | InitialGiftCardsAPIState
+ | InitialCollectionAPIState;
+
+export type FilterProviderType =
+ | "product"
+ | "order"
+ | "discount"
+ | "customer"
+ | "voucher"
+ | "page"
+ | "draft-order"
+ | "gift-cards"
+ | "collection";