Skip to content

Commit

Permalink
Support order conditions in rule summary (#4647)
Browse files Browse the repository at this point in the history
* Refactor rule model

* Add changeset

* Add discount type component

* Add type to initial form values

* Bump macaw

* Refactor Add button

* Update test

* Refactor DiscountRule isLoaded

* Add type support

* Remve useeffect

* Add changeset

* Extract messages

* Init context

* Context intro

* Remove empty import

* Fix tests, fix useDiscountRulesContext imports

* Add changeset

* Support mutliple condition types

* Update label map after rule add

* Add sorting

* Extract messages

* Add changeset

* Refactor RuleList

* Refactor rule summary to support order conditions

* Update test

* Add changeset

* Improve useVariantOptions

* Remove unused hooks
  • Loading branch information
poulch authored Jan 30, 2024
1 parent 01115af commit c09ef4d
Show file tree
Hide file tree
Showing 23 changed files with 329 additions and 122 deletions.
5 changes: 5 additions & 0 deletions .changeset/perfect-olives-matter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"saleor-dashboard": minor
---

Support order conditions in rule summary
12 changes: 9 additions & 3 deletions locale/defaultMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -3455,6 +3455,9 @@
"context": "attribute's editor component entity",
"string": "Entity"
},
"Lrp9WW": {
"string": "Discount of {value} on the purchase of {conditions} through the {channel}"
},
"LsgHmZ": {
"context": "delete shipping zone",
"string": "Are you sure you want to delete {name}?"
Expand Down Expand Up @@ -3693,9 +3696,6 @@
"context": "order line discount updated title",
"string": "{productName} discount was updated by"
},
"NgRa6m": {
"string": "Discount of {value} on the purchase of {items} through the {channel}"
},
"NhQboB": {
"context": "dialog header",
"string": "Saleor couldn’t cancel order"
Expand Down Expand Up @@ -7192,6 +7192,9 @@
"context": "checkbox",
"string": "Refund shipment: {currency} {amount}"
},
"lZC/1a": {
"string": "greater than {value}"
},
"laax5C": {
"context": "order returned success message",
"string": "Successfully returned products and granted refund!"
Expand Down Expand Up @@ -7820,6 +7823,9 @@
"qPSWmL": {
"string": "Enter usage"
},
"qSCmIG": {
"string": "lower than {value}"
},
"qT6YYk": {
"context": "order line total price",
"string": "Total"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ describe("DiscountRules", () => {
).toBeInTheDocument();
expect(
screen.getAllByText(
/discount of {value} on the purchase of {items} through the {channel}/i,
/discount of {value} on the purchase of {conditions} through the {channel}/i,
).length,
).toBe(2);
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,23 @@
import { Rule } from "@dashboard/discounts/models";
import { CommonError } from "@dashboard/utils/errors/common";
import {
Box,
Button,
EditIcon,
Text,
TrashBinIcon,
} from "@saleor/macaw-ui-next";
import { Box, Text } from "@saleor/macaw-ui-next";
import React from "react";
import { useIntl } from "react-intl";

import { useDiscountRulesContext } from "../../context";
import { messages } from "../../messages";
import { getCurencySymbol } from "../../utils";
import { Placeholder } from "../Placeholder";
import { RuleActions } from "./components/RuleActions";
import { RuleLabel } from "./components/RuleLabel";
import { RuleListContainer } from "./components/RuleListContainer";
import { RuleListLoading } from "./components/RuleListLoading";
import { RuleSummary } from "./components/RuleSummary";
import { RuleWrapper } from "./components/RuleWrapper";

interface RulesListProps<ErrorCode> {
rules: Rule[];
disabled?: boolean;
errors: Array<CommonError<ErrorCode> & { index?: number }>;
loading?: boolean;
onRuleDelete: (index: number) => void;
Expand All @@ -35,7 +32,7 @@ export const RulesList = <ErrorCode,>({
loading,
}: RulesListProps<ErrorCode>) => {
const intl = useIntl();
const { channels, disabled } = useDiscountRulesContext();
const { channels } = useDiscountRulesContext();

if (loading) {
return <RuleListLoading />;
Expand All @@ -45,13 +42,6 @@ export const RulesList = <ErrorCode,>({
return <Placeholder />;
}

const getRuleName = (name: string | undefined) => {
if (name) {
return `: ${name}`;
}
return "";
};

return (
<RuleListContainer>
{rules.map((rule, index) => {
Expand All @@ -65,33 +55,12 @@ export const RulesList = <ErrorCode,>({
justifyContent="space-between"
alignItems="center"
>
{intl.formatMessage(messages.catalogRule) +
getRuleName(rule.name)}
<RuleLabel ruleName={rule.name} />

<Box display="flex">
<Button
size="small"
variant="tertiary"
onClick={() => onRuleEdit(index)}
cursor={disabled ? "not-allowed" : "pointer"}
disabled={disabled}
data-test-id="rule-edit-button"
>
<EditIcon />
</Button>
<Button
size="small"
disabled={disabled}
variant="tertiary"
data-test-id="rule-delete-button"
onClick={e => {
e.stopPropagation();
onRuleDelete(index);
}}
>
<TrashBinIcon />
</Button>
</Box>
<RuleActions
onDelete={() => onRuleDelete(index)}
onEdit={() => onRuleEdit(index)}
/>
</Box>
<RuleSummary
rule={rule}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { useDiscountRulesContext } from "@dashboard/discounts/components/DiscountRules/context";
import { Box, Button, EditIcon, TrashBinIcon } from "@saleor/macaw-ui-next";
import React from "react";

interface RuleActionsProps {
onEdit: () => void;
onDelete: () => void;
}

export const RuleActions = ({ onEdit, onDelete }: RuleActionsProps) => {
const { disabled } = useDiscountRulesContext();

return (
<Box display="flex">
<Button
size="small"
variant="tertiary"
onClick={onEdit}
cursor={disabled ? "not-allowed" : "pointer"}
disabled={disabled}
data-test-id="rule-edit-button"
>
<EditIcon />
</Button>
<Button
size="small"
disabled={disabled}
variant="tertiary"
data-test-id="rule-delete-button"
onClick={e => {
e.stopPropagation();
onDelete();
}}
>
<TrashBinIcon />
</Button>
</Box>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./RuleActions";
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { messages } from "@dashboard/discounts/components/DiscountRules/messages";
import React from "react";
import { useIntl } from "react-intl";

interface RuleLabelProps {
ruleName: string | undefined;
}

export const RuleLabel = ({ ruleName }: RuleLabelProps) => {
const intl = useIntl();

const getRuleName = (name: string | undefined) => {
if (name) {
return `: ${name}`;
}
return "";
};

// const ruleTypeLabel = useMemo(() => {
// if (discountType === PromotionTypeEnum.CATALOGUE) {
// return intl.formatMessage(messages.catalogRule);
// }

// return intl.formatMessage(messages.orderRule);
// }, [discountType]);

return (
<>{intl.formatMessage(messages.catalogRule) + getRuleName(ruleName)}</>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./RuleLabel";
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { messages } from "@dashboard/discounts/components/DiscountRules/messages";
import { Rule } from "@dashboard/discounts/models";
import { Text } from "@saleor/macaw-ui-next";
import React from "react";
import { FormattedMessage } from "react-intl";

import { messages } from "../../../../messages";
import { RuleChannelChips } from "./components/RuleChannelChips/RuleChannelChips";
import { RuleChips } from "./components/RuleChips";
import { RuleChannelChips } from "./components/RuleChannelChips";
import { RuleConditionsChips } from "./components/RuleConditionsChips";
import { RuleValueChips } from "./components/RuleValueChips";
import { hasNoRuleConditions } from "./utils";

Expand Down Expand Up @@ -41,7 +41,9 @@ export const RuleSummary = ({ rule, currencySymbol }: RuleSummaryProps) => {
{...messages.ruleSummary}
values={{
value: <RuleValueChips rule={rule} currencySymbol={currencySymbol} />,
items: <RuleChips rule={rule} />,
conditions: (
<RuleConditionsChips rule={rule} currencySymbol={currencySymbol} />
),
channel: <RuleChannelChips channel={rule.channel} />,
}}
/>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./RuleChannelChips";

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Rule } from "@dashboard/discounts/models";
import React from "react";

import { mapConditionToOption, splitConditions } from "../../utils";
import { RuleSummaryChips } from "../RuleSummaryChips";
import { RuleSummaryTooltip } from "../RuleSummaryTooltip";
import { useEnrichConditions } from "./useEnrichConditions";

interface RuleChipsProps {
rule: Rule;
currencySymbol: string;
}

export const RuleConditionsChips = ({
rule,
currencySymbol,
}: RuleChipsProps) => {
const enrichConditions = useEnrichConditions(rule.conditions, currencySymbol);

const conditions = mapConditionToOption(enrichConditions);

const { conditionsInSummary, conditionsInTooltip } =
splitConditions(conditions);

const hasConditionInTooltip = conditionsInTooltip.length > 0;

return (
<>
{conditionsInSummary.map(({ label, value }) => (
<RuleSummaryChips key={value} value={value} label={label} />
))}
{hasConditionInTooltip ? (
<RuleSummaryTooltip conditionsValues={conditionsInTooltip} />
) : null}
</>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { Locale } from "@dashboard/components/Locale";
import {
formatMoney as formatMoneyUtils,
formatMoneyRange as formatMoneyRangeUtils,
} from "@dashboard/components/Money";
import { Condition, isTuple } from "@dashboard/discounts/models";

export const formatMoneyRange = (
condition: Condition,
currencySymbol: string,
locale: Locale,
) => {
if (!isTuple(condition.value)) {
return "";
}

return formatMoneyRangeUtils(
{
amount: Number(condition.value[0]),
currency: currencySymbol,
},
{
amount: Number(condition.value[1]),
currency: currencySymbol,
},
locale,
);
};

export const formatMoney = (
condition: Condition,
currencySymbol: string,
locale: Locale,
) => {
return formatMoneyUtils(
{
amount: Number(condition.value),
currency: currencySymbol,
},
locale,
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./RuleConditionsChips";
Loading

0 comments on commit c09ef4d

Please sign in to comment.