diff --git a/locale/defaultMessages.json b/locale/defaultMessages.json index 1f9035102e6..d38e59d05a6 100644 --- a/locale/defaultMessages.json +++ b/locale/defaultMessages.json @@ -7151,10 +7151,6 @@ "context": "button", "string": "Apply" }, - "iEeIhY": { - "context": "draft order", - "string": "Customer" - }, "iFM716": { "context": "grant refund, refund card subtitle", "string": "How much money do you want to return to the customer for the order?" @@ -9182,10 +9178,6 @@ "vuKrlW": { "string": "Stock" }, - "vwMO04": { - "context": "draft order", - "string": "Created" - }, "vz3yxp": { "string": "Channels permissions" }, diff --git a/src/components/ConditionalFilter/API/DraftOrderFilterAPIProvider.tsx b/src/components/ConditionalFilter/API/DraftOrderFilterAPIProvider.tsx new file mode 100644 index 00000000000..70d14c9d653 --- /dev/null +++ b/src/components/ConditionalFilter/API/DraftOrderFilterAPIProvider.tsx @@ -0,0 +1,15 @@ +import { FilterAPIProvider } from "@dashboard/components/ConditionalFilter/API/FilterAPIProvider"; + +export const useDraftOrderFilterAPIProvider = (): FilterAPIProvider => { + const fetchRightOptions = async () => { + return []; + }; + const fetchLeftOptions = async () => { + return []; + }; + + return { + fetchRightOptions, + fetchLeftOptions, + }; +}; diff --git a/src/components/ConditionalFilter/ValueProvider/useUrlValueProvider.ts b/src/components/ConditionalFilter/ValueProvider/useUrlValueProvider.ts index 16037fcffc0..29c07213824 100644 --- a/src/components/ConditionalFilter/ValueProvider/useUrlValueProvider.ts +++ b/src/components/ConditionalFilter/ValueProvider/useUrlValueProvider.ts @@ -18,7 +18,7 @@ import { prepareStructure } from "./utils"; export const useUrlValueProvider = ( locationSearch: string, - type: "product" | "order" | "discount", + type: "product" | "draft-order" | "order" | "discount", initialState?: InitialAPIState | InitialOrderAPIState, ): FilterValueProvider => { const router = useRouter(); diff --git a/src/components/ConditionalFilter/constants.ts b/src/components/ConditionalFilter/constants.ts index b3084e64327..262317ae7a4 100644 --- a/src/components/ConditionalFilter/constants.ts +++ b/src/components/ConditionalFilter/constants.ts @@ -273,10 +273,26 @@ export const STATIC_ORDER_OPTIONS: LeftOperand[] = [ }, ]; +export const STATIC_DRAFT_ORDER_OPTIONS: LeftOperand[] = [ + { + value: "customer", + label: "Customer", + type: "customer", + slug: "customer", + }, + { + value: "created", + label: "Created", + type: "created", + slug: "created", + }, +]; + export const STATIC_OPTIONS = [ ...STATIC_PRODUCT_OPTIONS, ...STATIC_DISCOUNT_OPTIONS, ...STATIC_ORDER_OPTIONS, + ...STATIC_DRAFT_ORDER_OPTIONS, ]; export const ATTRIBUTE_INPUT_TYPE_CONDITIONS = { diff --git a/src/components/ConditionalFilter/context/provider.tsx b/src/components/ConditionalFilter/context/provider.tsx index eaccbcd0001..b9cc6096baf 100644 --- a/src/components/ConditionalFilter/context/provider.tsx +++ b/src/components/ConditionalFilter/context/provider.tsx @@ -1,3 +1,4 @@ +import { useDraftOrderFilterAPIProvider } from "@dashboard/components/ConditionalFilter/API/DraftOrderFilterAPIProvider"; import React, { FC } from "react"; import { useDiscountFilterAPIProvider } from "../API/DiscountFiltersAPIProvider"; @@ -7,6 +8,7 @@ import { useOrderFilterAPIProvider } from "../API/OrderFilterAPIProvider"; import { useProductFilterAPIProvider } from "../API/ProductFilterAPIProvider"; import { STATIC_DISCOUNT_OPTIONS, + STATIC_DRAFT_ORDER_OPTIONS, STATIC_ORDER_OPTIONS, STATIC_PRODUCT_OPTIONS, } from "../constants"; @@ -90,3 +92,28 @@ export const ConditionalOrderFilterProvider: FC<{ ); }; + +export const ConditionalDraftOrderFilterProvider: FC<{ + locationSearch: string; +}> = ({ children, locationSearch }) => { + const apiProvider = useDraftOrderFilterAPIProvider(); + + const valueProvider = useUrlValueProvider(locationSearch, "draft-order"); + const leftOperandsProvider = useFilterLeftOperandsProvider(STATIC_DRAFT_ORDER_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 5cdbf379187..204e10ec8d3 100644 --- a/src/components/ConditionalFilter/queryVariables.ts +++ b/src/components/ConditionalFilter/queryVariables.ts @@ -5,6 +5,7 @@ import { DateTimeRangeInput, DecimalFilterInput, GlobalIdFilterInput, + OrderDraftFilterInput, ProductWhereInput, PromotionWhereInput, } from "@dashboard/graphql"; @@ -14,6 +15,7 @@ import { ConditionSelected } from "./FilterElement/ConditionSelected"; import { isItemOption, isItemOptionArray, isTuple } from "./FilterElement/ConditionValue"; type StaticQueryPart = string | GlobalIdFilterInput | boolean | DecimalFilterInput; +type StaticQueryPartForOldAPIFilters = string | DateRangeInput | string[] | boolean; const createStaticQueryPart = (selected: ConditionSelected): StaticQueryPart => { if (!selected.conditionValue) return ""; @@ -57,6 +59,51 @@ const createStaticQueryPart = (selected: ConditionSelected): StaticQueryPart => return value; }; +const createStaticQueryPartForOldAPIFilters = ( + selected: ConditionSelected, +): StaticQueryPartForOldAPIFilters => { + if (!selected.conditionValue) return ""; + + const { label } = selected.conditionValue; + const { value: selectedValue } = selected; + const value = Array.isArray(selectedValue) ? selectedValue[0] : selectedValue; + + if (label === "lower") { + return { lte: value }; + } + + if (label === "greater") { + return { gte: value }; + } + + if (isTuple(value) && label === "between") { + const [gte, lte] = value; + + return { lte, gte }; + } + + if (isItemOption(value) && ["true", "false"].includes(value.value)) { + return value.value === "true"; + } + + if (isItemOption(value)) { + return value.value; + } + + if (isItemOptionArray(value)) { + return value.map(x => x.value); + } + + if (typeof value === "string") { + return value; + } + + if (Array.isArray(value)) { + return value; + } + + return value; +}; const getRangeQueryPartByType = (value: [string, string], type: string) => { const [gte, lte] = value; @@ -199,3 +246,19 @@ export const createOrderQueryVariables = (value: FilterContainer) => { return p; }, {} as OrderQueryVars); }; + +export const creatDraftOrderQueryVariables = (value: FilterContainer): OrderDraftFilterInput => { + return value.reduce((p, c) => { + if (typeof c === "string" || Array.isArray(c)) return p; + + if (c.isStatic()) { + p[c.value.value as keyof OrderDraftFilterInput] = createStaticQueryPartForOldAPIFilters( + c.condition.selected, + ) as any; + + return p; + } + + return p; + }, {} as OrderDraftFilterInput); +}; diff --git a/src/orders/components/OrderDraftListPage/OrderDraftListPage.tsx b/src/orders/components/OrderDraftListPage/OrderDraftListPage.tsx index 535fca25951..b28e5f59a72 100644 --- a/src/orders/components/OrderDraftListPage/OrderDraftListPage.tsx +++ b/src/orders/components/OrderDraftListPage/OrderDraftListPage.tsx @@ -4,7 +4,13 @@ import { BulkDeleteButton } from "@dashboard/components/BulkDeleteButton"; import { DashboardCard } from "@dashboard/components/Card"; import { OrderDraftListQuery, RefreshLimitsQuery } from "@dashboard/graphql"; import { OrderDraftListUrlSortField } from "@dashboard/orders/urls"; -import { FilterPagePropsWithPresets, PageListProps, RelayToFlat, SortPage } from "@dashboard/types"; +import { + FilterPresetsProps, + PageListProps, + RelayToFlat, + SearchPageProps, + SortPage, +} from "@dashboard/types"; import { isLimitReached } from "@dashboard/utils/limits"; import { Box } from "@saleor/macaw-ui-next"; import React, { useState } from "react"; @@ -13,11 +19,11 @@ import { useIntl } from "react-intl"; import { OrderDraftListDatagrid } from "../OrderDraftListDatagrid"; import { OrderDraftListHeader } from "../OrderDraftListHeader/OrderDraftListHeader"; import OrderLimitReached from "../OrderLimitReached"; -import { createFilterStructure, OrderDraftFilterKeys, OrderDraftListFilterOpts } from "./filters"; export interface OrderDraftListPageProps extends PageListProps, - FilterPagePropsWithPresets, + SearchPageProps, + FilterPresetsProps, SortPage { limits: RefreshLimitsQuery["shop"]["limits"]; orders: RelayToFlat; @@ -31,12 +37,10 @@ export interface OrderDraftListPageProps const OrderDraftListPage: React.FC = ({ selectedFilterPreset, disabled, - filterOpts, initialSearch, limits, onAdd, onFilterPresetsAll, - onFilterChange, onSearchChange, onFilterPresetChange, onFilterPresetDelete, @@ -45,14 +49,11 @@ const OrderDraftListPage: React.FC = ({ filterPresets, hasPresetsChanged, onDraftOrdersDelete, - onFilterAttributeFocus, - currencySymbol, selectedOrderDraftIds, ...listProps }) => { const intl = useIntl(); const [isFilterPresetOpen, setFilterPresetOpen] = useState(false); - const filterStructure = createFilterStructure(intl, filterOpts); const limitsReached = isLimitReached(limits, "orders"); return ( @@ -84,12 +85,9 @@ const OrderDraftListPage: React.FC = ({ justifyContent="space-between" > ; - customer: FilterOpts; -} - -const messages = defineMessages({ - created: { - id: "vwMO04", - defaultMessage: "Created", - description: "draft order", - }, - customer: { - id: "iEeIhY", - defaultMessage: "Customer", - description: "draft order", - }, -}); - -export function createFilterStructure( - intl: IntlShape, - opts: OrderDraftListFilterOpts, -): IFilter { - return [ - { - ...createDateField( - OrderDraftFilterKeys.created, - intl.formatMessage(messages.created), - opts.created.value, - ), - active: opts.created.active, - }, - { - ...createTextField( - OrderDraftFilterKeys.customer, - intl.formatMessage(messages.customer), - opts.customer.value, - ), - active: opts.customer.active, - }, - ]; -} diff --git a/src/orders/components/OrderDraftListPage/index.ts b/src/orders/components/OrderDraftListPage/index.ts index 3fc3859a5a6..de5e8daab09 100644 --- a/src/orders/components/OrderDraftListPage/index.ts +++ b/src/orders/components/OrderDraftListPage/index.ts @@ -1,3 +1,2 @@ -export * from "./filters"; export { default } from "./OrderDraftListPage"; export * from "./OrderDraftListPage"; diff --git a/src/orders/index.tsx b/src/orders/index.tsx index 4eb6f85dd31..a5d23bea487 100644 --- a/src/orders/index.tsx +++ b/src/orders/index.tsx @@ -1,4 +1,7 @@ -import { ConditionalOrderFilterProvider } from "@dashboard/components/ConditionalFilter"; +import { + ConditionalDraftOrderFilterProvider, + ConditionalOrderFilterProvider, +} from "@dashboard/components/ConditionalFilter"; import { Route } from "@dashboard/components/Router"; import { sectionNames } from "@dashboard/intl"; import { asSortParams } from "@dashboard/utils/sort"; @@ -71,7 +74,11 @@ const OrderDraftList: React.FC> = ({ location }) => { false, ); - return ; + return ( + + + + ); }; const OrderDetails: React.FC> = ({ location, match }) => { const qs = parseQs(location.search.substr(1)) as any; diff --git a/src/orders/views/OrderDraftList/OrderDraftList.tsx b/src/orders/views/OrderDraftList/OrderDraftList.tsx index a5df5590dcd..6087972cce7 100644 --- a/src/orders/views/OrderDraftList/OrderDraftList.tsx +++ b/src/orders/views/OrderDraftList/OrderDraftList.tsx @@ -3,6 +3,7 @@ import { useUser } from "@dashboard/auth"; import ChannelPickerDialog from "@dashboard/channels/components/ChannelPickerDialog"; import ActionDialog from "@dashboard/components/ActionDialog"; import useAppChannel from "@dashboard/components/AppLayout/AppChannelContext"; +import { useConditionalFilterContext } from "@dashboard/components/ConditionalFilter"; import DeleteFilterTabDialog from "@dashboard/components/DeleteFilterTabDialog"; import SaveFilterTabDialog from "@dashboard/components/SaveFilterTabDialog"; import { useShopLimitsQuery } from "@dashboard/components/Shop/queries"; @@ -35,7 +36,7 @@ import { OrderDraftListUrlQueryParams, orderUrl, } from "../../urls"; -import { getFilterOpts, getFilterQueryParam, getFilterVariables, storageUtils } from "./filters"; +import { getFilterQueryParam, getFilterVariables, storageUtils } from "./filters"; import { getSortQueryVariables } from "./sort"; import { useBulkDeletion } from "./useBulkDeletion"; @@ -48,6 +49,7 @@ export const OrderDraftList: React.FC = ({ params }) => { const notify = useNotifier(); const intl = useIntl(); const { updateListSettings, settings } = useListSettings(ListViews.DRAFT_LIST); + const { valueProvider } = useConditionalFilterContext(); usePaginationReset(orderDraftListUrl, params, settings.rowNumber); @@ -82,7 +84,7 @@ export const OrderDraftList: React.FC = ({ params }) => { orders: true, }, }); - const [changeFilters, resetFilters, handleSearchChange] = createFilterHandlers({ + const [_, resetFilters, handleSearchChange] = createFilterHandlers({ cleanupFn: clearRowSelection, createUrl: orderDraftListUrl, getFilterQueryParam, @@ -114,10 +116,13 @@ export const OrderDraftList: React.FC = ({ params }) => { const queryVariables = React.useMemo( () => ({ ...paginationState, - filter: getFilterVariables(params), + filter: getFilterVariables({ + params, + filterContainer: valueProvider.value, + }), sort: getSortQueryVariables(params), }), - [paginationState, params], + [paginationState, params, valueProvider.value], ); const { data, refetch } = useOrderDraftListQuery({ displayLoader: true, @@ -152,11 +157,9 @@ export const OrderDraftList: React.FC = ({ params }) => { { @@ -172,7 +175,6 @@ export const OrderDraftList: React.FC = ({ params }) => { onAdd={() => openModal("create-order")} onSort={handleSort} sort={getSortParams(params)} - currencySymbol={channel?.currencyCode} hasPresetsChanged={hasPresetsChanged} onDraftOrdersDelete={() => openModal("remove", { diff --git a/src/orders/views/OrderDraftList/filters.test.ts b/src/orders/views/OrderDraftList/filters.test.ts index 25f07ec5330..bc41fe0241a 100644 --- a/src/orders/views/OrderDraftList/filters.test.ts +++ b/src/orders/views/OrderDraftList/filters.test.ts @@ -1,60 +1,31 @@ -import { date } from "@dashboard/fixtures"; -import { createFilterStructure } from "@dashboard/orders/components/OrderDraftListPage"; +import { FilterElement } from "@dashboard/components/ConditionalFilter/FilterElement"; import { OrderDraftListUrlFilters } from "@dashboard/orders/urls"; -import { getFilterQueryParams } from "@dashboard/utils/filters"; -import { stringifyQs } from "@dashboard/utils/urls"; -import { getExistingKeys, setFilterOptsStatus } from "@test/filters"; -import { config } from "@test/intl"; -import { createIntl } from "react-intl"; +import { getExistingKeys } from "@test/filters"; -import { getFilterQueryParam, getFilterVariables } from "./filters"; +import { getFilterVariables } from "./filters"; describe("Filtering query params", () => { it("should be empty object if no params given", () => { const params: OrderDraftListUrlFilters = {}; - const filterVariables = getFilterVariables(params); + const filterVariables = getFilterVariables({ + params, + filterContainer: [FilterElement.createEmpty()], + }); expect(getExistingKeys(filterVariables)).toHaveLength(0); }); it("should not be empty object if params given", () => { const params: OrderDraftListUrlFilters = { - createdFrom: date.from, - createdTo: date.to, - customer: "admin@example.com", + query: "test", }; - const filterVariables = getFilterVariables(params); + const filterVariables = getFilterVariables({ + params, + filterContainer: [ + FilterElement.createStaticBySlug("created"), + FilterElement.createStaticBySlug("customer"), + ], + }); - expect(getExistingKeys(filterVariables)).toHaveLength(2); - }); -}); -describe("Filtering URL params", () => { - const intl = createIntl(config); - const filters = createFilterStructure(intl, { - created: { - active: false, - value: { - max: date.to, - min: date.from, - }, - }, - customer: { - active: false, - value: "admin@example.com", - }, - }); - - it("should be empty if no active filters", () => { - const filterQueryParams = getFilterQueryParams(filters, getFilterQueryParam); - - expect(getExistingKeys(filterQueryParams)).toHaveLength(0); - }); - it("should not be empty if active filters are present", () => { - const filterQueryParams = getFilterQueryParams( - setFilterOptsStatus(filters, true), - getFilterQueryParam, - ); - - expect(filterQueryParams).toMatchSnapshot(); - expect(stringifyQs(filterQueryParams)).toMatchSnapshot(); + expect(getExistingKeys(filterVariables)).toHaveLength(3); }); }); diff --git a/src/orders/views/OrderDraftList/filters.ts b/src/orders/views/OrderDraftList/filters.ts index cc76072d6a8..d2a7ad115ed 100644 --- a/src/orders/views/OrderDraftList/filters.ts +++ b/src/orders/views/OrderDraftList/filters.ts @@ -1,16 +1,11 @@ // @ts-strict-ignore +import { FilterContainer } from "@dashboard/components/ConditionalFilter/FilterElement"; +import { creatDraftOrderQueryVariables } from "@dashboard/components/ConditionalFilter/queryVariables"; import { FilterElement } from "@dashboard/components/Filter"; -import { OrderDraftFilterInput } from "@dashboard/graphql"; -import { maybe } from "@dashboard/misc"; -import { - OrderDraftFilterKeys, - OrderDraftListFilterOpts, -} from "@dashboard/orders/components/OrderDraftListPage"; import { createFilterTabUtils, createFilterUtils, - getGteLteVariables, getMinMaxQueryParam, getSingleValueQueryParam, } from "../../../utils/filters"; @@ -22,34 +17,24 @@ import { export const ORDER_DRAFT_FILTERS_KEY = "orderDraftFilters"; -export function getFilterOpts(params: OrderDraftListUrlFilters): OrderDraftListFilterOpts { - return { - created: { - active: maybe( - () => [params.createdFrom, params.createdTo].some(field => field !== undefined), - false, - ), - value: { - max: maybe(() => params.createdTo), - min: maybe(() => params.createdFrom), - }, - }, - customer: { - active: !!maybe(() => params.customer), - value: params.customer, - }, - }; -} +export const getFilterVariables = ({ + filterContainer, + params, +}: { + filterContainer: FilterContainer; + params: OrderDraftListUrlFilters; +}) => { + const queryVars = creatDraftOrderQueryVariables(filterContainer); -export function getFilterVariables(params: OrderDraftListUrlFilters): OrderDraftFilterInput { return { - created: getGteLteVariables({ - gte: params.createdFrom, - lte: params.createdTo, - }), - customer: params.customer, + ...queryVars, search: params.query, }; +}; + +export enum OrderDraftFilterKeys { + created = "created", + customer = "customer", } export function getFilterQueryParam(