Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/seven-moons-talk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"saleor-dashboard": patch
---

List of customers now uses conditional filters
11 changes: 11 additions & 0 deletions .featureFlags/customers_filters.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
name: customers_filters
displayName: Customers filtering
enabled: true
payload: "default"
visible: true
---

![new filters](./images/customers-filters.png)
Experience the new look and enhanced abilities of new fitering mechanism.
Easily combine any criteria you want, and quickly browse their values.
38 changes: 26 additions & 12 deletions .featureFlags/generated.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,30 @@
// @ts-nocheck

import K01586 from "./images/discounts-list.png"
import J60656 from "./images/draft-orders-filters.png"
import W15309 from "./images/gift-cards-filters.png"
import P14884 from "./images/improved_refunds.png"
import J91775 from "./images/page-filters.png"
import F54595 from "./images/vouchers-filters.png"
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"

const discounts_rules = () => (<><p><img src={K01586} alt="Discount rules"/></p>
const customers_filters = () => (<><p><img src={J53093} alt="new filters"/>
Experience the new look and enhanced abilities of new fitering mechanism.
Easily combine any criteria you want, and quickly browse their values.</p>
</>)
const discounts_rules = () => (<><p><img src={Q09991} alt="Discount rules"/></p>
<p>Apply the new discounts rules to narrow your promotions audience.
Set up conditions and channels that must be fulfilled to apply defined reward.</p>
</>)
const draft_orders_filters = () => (<><p><img src={J60656} alt="new filters"/>
const draft_orders_filters = () => (<><p><img src={Z15989} alt="new filters"/>
Experience the new look and enhanced abilities of new fitering mechanism.
Easily combine any criteria you want, and quickly browse their values.</p>
</>)
const gift_cards_filters = () => (<><p><img src={W15309} alt="new filters"/>
const gift_cards_filters = () => (<><p><img src={C33827} alt="new filters"/>
Experience the new look and enhanced abilities of new fitering mechanism.
Easily combine any criteria you want, and quickly browse their values.</p>
</>)
const improved_refunds = () => (<><p><img src={P14884} alt="Improved refunds"/></p>
const improved_refunds = () => (<><p><img src={H90846} alt="Improved refunds"/></p>
<h3 id="enable-the-enhanced-refund-feature-to-streamline-your-refund-process">Enable the enhanced refund feature to streamline your refund process:</h3>
<ul>
<li><p>• Choose between automatic calculations based on selected items or enter refund amounts directly for overcharges and custom adjustments.</p>
Expand All @@ -29,16 +34,25 @@ const improved_refunds = () => (<><p><img src={P14884} alt="Improved refunds"/><
</ul>

</>)
const pages_filters = () => (<><p><img src={J91775} alt="new filters"/>
const pages_filters = () => (<><p><img src={A12919} alt="new filters"/>
Experience the new look and enhanced abilities of new fitering mechanism.
Easily combine any criteria you want, and quickly browse their values.</p>
</>)
const vouchers_filters = () => (<><p><img src={F54595} alt="new filters"/>
const vouchers_filters = () => (<><p><img src={X74531} alt="new filters"/>
Experience the new look and enhanced abilities of new fitering mechanism.
Easily combine any criteria you want, and quickly browse their values.</p>
</>)

export const AVAILABLE_FLAGS = [{
name: "customers_filters",
displayName: "Customers filtering",
component: customers_filters,
visible: true,
content: {
enabled: true,
payload: "default",
}
},{
name: "discounts_rules",
displayName: "Discounts rules",
component: discounts_rules,
Expand Down
Binary file added .featureFlags/images/customers-filters.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { FilterAPIProvider } from "./FilterAPIProvider";

export const useCustomerAPIProvider = (): FilterAPIProvider => {
const fetchRightOptions = async () => {
return [];
};

const fetchLeftOptions = async () => {
return [];
};

return {
fetchRightOptions,
fetchLeftOptions,
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,15 @@ export const toGiftCardsFetchingParams = (p: GiftCardsFetchingParams, c: UrlToke
};

export const getFetchingPrams = (
type: "product" | "order" | "discount" | "voucher" | "page" | "draft-order" | "gift-cards",
type:
| "product"
| "order"
| "discount"
| "voucher"
| "page"
| "draft-order"
| "gift-cards"
| "customer",
) => {
switch (type) {
case "product":
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,15 @@ import { prepareStructure } from "./utils";

export const useUrlValueProvider = (
locationSearch: string,
type: "product" | "order" | "discount" | "voucher" | "page" | "draft-order" | "gift-cards",
type:
| "product"
| "order"
| "discount"
| "voucher"
| "page"
| "draft-order"
| "gift-cards"
| "customer",
initialState?:
| InitialAPIState
| InitialOrderAPIState
Expand Down
27 changes: 27 additions & 0 deletions src/components/ConditionalFilter/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,17 @@ export const STATIC_CONDITIONS = {
{ type: "date", label: "greater", value: "input-2" },
{ type: "date.range", label: "between", value: "input-3" },
],
dateJoined: [
{ type: "date", label: "lower", value: "input-1" },
{ type: "date", label: "greater", value: "input-2" },
{ type: "date.range", label: "between", value: "input-3" },
],
numberOfOrders: [
{ type: "number", label: "is", value: "input-1" },
{ type: "number", label: "lower", value: "input-1" },
{ type: "number", label: "greater", value: "input-2" },
{ type: "number.range", label: "between", value: "input-2" },
],
started: [
{ type: "datetime", label: "lower", value: "input-1" },
{ type: "datetime", label: "greater", value: "input-2" },
Expand Down Expand Up @@ -433,6 +444,21 @@ export const STATIC_GIFT_CARDS_OPTIONS: LeftOperand[] = [
},
];

export const STATIC_CUSTOMER_OPTIONS: LeftOperand[] = [
{
value: "dateJoined",
label: "Join date",
type: "dateJoined",
slug: "dateJoined",
},
{
value: "numberOfOrders",
label: "Number of orders",
type: "numberOfOrders",
slug: "numberOfOrders",
},
];

export const STATIC_OPTIONS = [
...STATIC_PRODUCT_OPTIONS,
...STATIC_DISCOUNT_OPTIONS,
Expand All @@ -441,6 +467,7 @@ export const STATIC_OPTIONS = [
...STATIC_PAGE_OPTIONS,
...STATIC_DRAFT_ORDER_OPTIONS,
...STATIC_GIFT_CARDS_OPTIONS,
...STATIC_CUSTOMER_OPTIONS,
];

export const ATTRIBUTE_INPUT_TYPE_CONDITIONS = {
Expand Down
27 changes: 27 additions & 0 deletions src/components/ConditionalFilter/context/provider.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
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";
Expand All @@ -13,6 +14,7 @@ import { usePageAPIProvider } from "../API/PageFilterAPIProvider";
import { useProductFilterAPIProvider } from "../API/ProductFilterAPIProvider";
import { useVoucherAPIProvider } from "../API/VoucherFilterAPIProvider";
import {
STATIC_CUSTOMER_OPTIONS,
STATIC_DISCOUNT_OPTIONS,
STATIC_DRAFT_ORDER_OPTIONS,
STATIC_GIFT_CARDS_OPTIONS,
Expand Down Expand Up @@ -205,3 +207,28 @@ export const ConditionalGiftCardsFilterProver: FC<{ locationSearch: string }> =
</ConditionalFilterContext.Provider>
);
};

export const ConditionalCustomerFilterProvider: FC<{
locationSearch: string;
}> = ({ children, locationSearch }) => {
const apiProvider = useCustomerAPIProvider();

const valueProvider = useUrlValueProvider(locationSearch, "customer");
const leftOperandsProvider = useFilterLeftOperandsProvider(STATIC_CUSTOMER_OPTIONS);
const containerState = useContainerState(valueProvider);
const filterWindow = useFilterWindow();

return (
<ConditionalFilterContext.Provider
value={{
apiProvider,
valueProvider,
leftOperandsProvider,
containerState,
filterWindow,
}}
>
{children}
</ConditionalFilterContext.Provider>
);
};
106 changes: 58 additions & 48 deletions src/components/ConditionalFilter/queryVariables.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { ConditionSelected } from "./FilterElement/ConditionSelected";
import { ExpressionValue } from "./FilterElement/FilterElement";
import {
creatDraftOrderQueryVariables,
createCustomerQueryVariables,
createGiftCardQueryVariables,
createPageQueryVariables,
createProductQueryVariables,
Expand Down Expand Up @@ -302,54 +303,6 @@ describe("ConditionalFilter / queryVariables / creatDraftOrderQueryVariables", (
});
});

describe("ConditionalFilter / queryVariables / mapStaticQueryPartToLegacyVariables", () => {
it("should return queryPart if it is not an object", () => {
// Arrange
const queryPart = "queryPart";
const expectedOutput = "queryPart";

// Act
const result = mapStaticQueryPartToLegacyVariables(queryPart);

// Assert
expect(result).toEqual(expectedOutput);
});

it("should transform range input to legacy format", () => {
// Arrange
const queryPart = { range: { lte: "value" } };
const expectedOutput = { lte: "value" };

// Act
const result = mapStaticQueryPartToLegacyVariables(queryPart);

// Assert
expect(result).toEqual(expectedOutput);
});

it("should transform eq input to legacy format", () => {
// Arrange
const queryPart = { eq: "value" };
const expectedOutput = "value";
// Act
const result = mapStaticQueryPartToLegacyVariables(queryPart);

// Assert
expect(result).toEqual(expectedOutput);
});

it("should transform oneOf input to legacy format", () => {
// Arrange
const queryPart = { oneOf: ["value1", "value2"] };
const expectedOutput = ["value1", "value2"];
// Act
const result = mapStaticQueryPartToLegacyVariables(queryPart);

// Assert
expect(result).toEqual(expectedOutput);
});
});

describe("ConditionalFilter / queryVariables / createGiftCardQueryVariables", () => {
it("should return empty variables for empty filters", () => {
// Arrange
Expand Down Expand Up @@ -516,6 +469,63 @@ describe("ConditionalFilter / queryVariables / createGiftCardQueryVariables", ()
});
});

describe("ConditionalFilter / queryVariables / createCustomerQueryVariables", () => {
it("should return empty variables for empty filters", () => {
// Arrange
const filters: FilterContainer = [];
const expectedOutput = {};
// Act
const result = createCustomerQueryVariables(filters);

// Assert
expect(result).toEqual(expectedOutput);
});

it("should create variables with selected filters", () => {
// Arrange
const filters: FilterContainer = [
new FilterElement(
new ExpressionValue("dateJoined", "Date joined", "dateJoined"),
new Condition(
ConditionOptions.fromStaticElementName("dateJoined"),
new ConditionSelected(
["2025-02-01", "2025-02-08"],
{ type: "number.range", label: "between", value: "input-2" },
[],
false,
),
false,
),
false,
),
"AND",
new FilterElement(
new ExpressionValue("numberOfOrders", "Number of orders", "numberOfOrders"),
new Condition(
ConditionOptions.fromStaticElementName("numberOfOrders"),
new ConditionSelected(
["1", "100"],
{ type: "number.range", label: "between", value: "input-2" },
[],
false,
),
false,
),
false,
),
];
const expectedOutput = {
dateJoined: { gte: "2025-02-01", lte: "2025-02-08" },
numberOfOrders: { gte: "1", lte: "100" },
};
// Act
const result = createCustomerQueryVariables(filters);

// Assert
expect(result).toEqual(expectedOutput);
});
});

describe("ConditionalFilter / queryVariables / mapStaticQueryPartToLegacyVariables", () => {
it("should return queryPart if it is not an object", () => {
// Arrange
Expand Down
22 changes: 22 additions & 0 deletions src/components/ConditionalFilter/queryVariables.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
AttributeInput,
CustomerFilterInput,
DateRangeInput,
DateTimeFilterInput,
DateTimeRangeInput,
Expand Down Expand Up @@ -318,3 +319,24 @@ export const createGiftCardQueryVariables = (value: FilterContainer) => {
return p;
}, {} as GiftCardFilterInput);
};

export const createCustomerQueryVariables = (value: FilterContainer): CustomerFilterInput => {
return value.reduce((p, c) => {
if (typeof c === "string" || Array.isArray(c)) return p;

if (c.value.type === "numberOfOrders" && c.condition.selected.conditionValue?.label === "is") {
p["numberOfOrders"] = {
gte: Number(c.condition.selected.value),
lte: Number(c.condition.selected.value),
};

return p;
}

p[c.value.value as keyof CustomerFilterInput] = mapStaticQueryPartToLegacyVariables(
createStaticQueryPart(c.condition.selected),
);

return p;
}, {} as CustomerFilterInput);
};
Loading
Loading