Skip to content

Commit

Permalink
Add clarity to order cancel dialog (#4673)
Browse files Browse the repository at this point in the history
* Improve order cancel dialog

* Add tests

* Extract messages

* Add changeset

* Trigger deployment

* Simplify test

* Improve test
  • Loading branch information
Droniu authored and poulch committed Feb 26, 2024
1 parent 1367d5c commit fda067f
Show file tree
Hide file tree
Showing 5 changed files with 153 additions and 53 deletions.
5 changes: 5 additions & 0 deletions .changeset/mean-phones-hide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"saleor-dashboard": patch
---

Add clarity to order cancel dialog
23 changes: 16 additions & 7 deletions locale/defaultMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -3713,6 +3713,10 @@
"context": "attribute values list: slug column header",
"string": "Swatch"
},
"NWA+MK": {
"context": "dialog content",
"string": "<b>Important:</b> Refunds need to be issued <b>manually</b> after order cancelation."
},
"NWxomz": {
"string": "Fulfillment status"
},
Expand Down Expand Up @@ -3973,10 +3977,6 @@
"context": "sum of all manual refunds for transaction",
"string": "Manual refund"
},
"PRXpBm": {
"context": "dialog header",
"string": "Cancel Order"
},
"PTW56s": {
"context": "alert",
"string": "Channel limit reached"
Expand Down Expand Up @@ -4897,9 +4897,6 @@
"context": "fulfill button label",
"string": "Fulfill anyway"
},
"VSztEE": {
"string": "Cancelling this order will release unfulfilled stocks, so they can be bought by other customers. <b>Order will not be refunded when cancelling order - You need to do it manually.</b> Are you sure you want to cancel this order?"
},
"VTITVe": {
"context": "section header",
"string": "Staff Member Information"
Expand Down Expand Up @@ -5776,6 +5773,10 @@
"context": "subsection header",
"string": "Address"
},
"bKTEnb": {
"context": "button to cancel order",
"string": "Cancel order"
},
"bL/Wrc": {
"context": "plugin status",
"string": "Status"
Expand Down Expand Up @@ -7689,6 +7690,10 @@
"context": "product no longer exists error title",
"string": "Product no longer exists"
},
"p6ugX0": {
"context": "button to keep order",
"string": "Keep order"
},
"pA8Mlv": {
"context": "alert",
"string": "Staff Member limit reached"
Expand Down Expand Up @@ -8792,6 +8797,10 @@
"context": "button",
"string": "Create Warehouse"
},
"wmeRVH": {
"context": "dialog header",
"string": "Cancel order #{orderNumber}"
},
"wn3di2": {
"string": "This password is too commonly used"
},
Expand Down
68 changes: 68 additions & 0 deletions src/orders/components/OrderCancelDialog/OrderCancelDialog.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { OrderErrorCode, OrderErrorFragment } from "@dashboard/graphql";
import { render, screen } from "@testing-library/react";
import React from "react";
import { FormattedMessage } from "react-intl";

import { OrderCancelDialog } from "./OrderCancelDialog";

jest.mock("react-intl", () => ({
useIntl: jest.fn(() => ({
formatMessage: jest.fn(x => x.defaultMessage),
})),
defineMessages: jest.fn(x => x),
FormattedMessage: jest.fn(() => <></>),
}));

const defaultProps = {
confirmButtonState: "default" as const,
errors: [],
open: true,
onClose: jest.fn(),
onSubmit: jest.fn(),
number: "123",
};

describe("OrderCancelDialog", () => {
it("displays order number in the dialog title", () => {
// Arrange
const orderNumber = "456";

// Act
render(<OrderCancelDialog {...defaultProps} number={orderNumber} />);

// Assert
expect(FormattedMessage).toHaveBeenCalledWith(
{
defaultMessage: "Cancel order #{orderNumber}",
description: "dialog header",
id: "wmeRVH",
values: { orderNumber: "456" },
},
{},
);
});

it("displays error messages when provided", () => {
// Arrange
const errors = [
{ code: OrderErrorCode.CANNOT_CANCEL_ORDER },
{ code: OrderErrorCode.GRAPHQL_ERROR },
] as unknown as OrderErrorFragment[];

// Act
render(<OrderCancelDialog {...defaultProps} errors={errors} />);

// Assert
const errorMessages = screen.getAllByTestId("dialog-error");
expect(errorMessages).toHaveLength(errors.length);
});

it("does not display error messages when none are provided", () => {
// Act
render(<OrderCancelDialog {...defaultProps} errors={[]} />);

// Assert
const errorMessages = screen.queryAllByTestId("dialog-error");
expect(errorMessages).toHaveLength(0);
});
});
85 changes: 39 additions & 46 deletions src/orders/components/OrderCancelDialog/OrderCancelDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,16 @@ import {
ConfirmButton,
ConfirmButtonTransitionState,
} from "@dashboard/components/ConfirmButton";
import FormSpacer from "@dashboard/components/FormSpacer";
import { DashboardModal } from "@dashboard/components/Modal";
import { OrderErrorFragment } from "@dashboard/graphql";
import useModalDialogErrors from "@dashboard/hooks/useModalDialogErrors";
import { buttonMessages } from "@dashboard/intl";
import getOrderErrorMessage from "@dashboard/utils/errors/order";
import {
Dialog,
DialogActions,
DialogContent,
DialogContentText,
DialogTitle,
} from "@material-ui/core";
import { Text } from "@saleor/macaw-ui-next";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";

import { cancelOrderDialogMessages } from "./messages";

export interface OrderCancelDialogProps {
confirmButtonState: ConfirmButtonTransitionState;
errors: OrderErrorFragment[];
Expand All @@ -27,7 +22,7 @@ export interface OrderCancelDialogProps {
onSubmit: () => void;
}

const OrderCancelDialog: React.FC<OrderCancelDialogProps> = props => {
export const OrderCancelDialog: React.FC<OrderCancelDialogProps> = props => {
const {
confirmButtonState,
errors: apiErrors,
Expand All @@ -41,47 +36,45 @@ const OrderCancelDialog: React.FC<OrderCancelDialogProps> = props => {
const errors = useModalDialogErrors(apiErrors, open);

return (
<Dialog onClose={onClose} open={open} maxWidth="sm">
<DialogTitle disableTypography>
<FormattedMessage
id="PRXpBm"
defaultMessage="Cancel Order"
description="dialog header"
/>
</DialogTitle>
<DialogContent>
<DialogContentText key="cancel">
<DashboardModal onChange={onClose} open={open}>
<DashboardModal.Content>
<DashboardModal.Title data-test-id="dialog-title">
<FormattedMessage
id="VSztEE"
defaultMessage="Cancelling this order will release unfulfilled stocks, so they can be bought by other customers. <b>Order will not be refunded when cancelling order - You need to do it manually.</b> Are you sure you want to cancel this order?"
{...cancelOrderDialogMessages.dialogTitle}
values={{ orderNumber }}
/>
</DashboardModal.Title>
<Text>
<FormattedMessage
{...cancelOrderDialogMessages.dialogContent}
values={{
b: (...chunks) => <b>{chunks}</b>,
orderNumber,
}}
/>
</DialogContentText>
{errors.length > 0 && (
<>
<FormSpacer />
{errors.map((err, index) => (
<DialogContentText color="error" key={index}>
{getOrderErrorMessage(err, intl)}
</DialogContentText>
))}
</>
)}
</DialogContent>
<DialogActions>
<BackButton onClick={onClose} />
<ConfirmButton
onClick={onSubmit}
transitionState={confirmButtonState}
type="submit"
>
<FormattedMessage {...buttonMessages.accept} />
</ConfirmButton>
</DialogActions>
</Dialog>
</Text>
{errors.length > 0 &&
errors.map((err, index) => (
<Text color="critical1" key={index} data-test-id="dialog-error">
{getOrderErrorMessage(err, intl)}
</Text>
))}

<DashboardModal.Actions>
<BackButton onClick={onClose}>
<FormattedMessage {...cancelOrderDialogMessages.buttonKeepOrder} />
</BackButton>
<ConfirmButton
onClick={onSubmit}
transitionState={confirmButtonState}
type="submit"
>
<FormattedMessage
{...cancelOrderDialogMessages.buttonCancelOrder}
/>
</ConfirmButton>
</DashboardModal.Actions>
</DashboardModal.Content>
</DashboardModal>
);
};
OrderCancelDialog.displayName = "OrderCancelDialog";
Expand Down
25 changes: 25 additions & 0 deletions src/orders/components/OrderCancelDialog/messages.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { defineMessages } from "react-intl";

export const cancelOrderDialogMessages = defineMessages({
dialogTitle: {
id: "wmeRVH",
defaultMessage: "Cancel order #{orderNumber}",
description: "dialog header",
},
dialogContent: {
id: "NWA+MK",
defaultMessage:
"<b>Important:</b> Refunds need to be issued <b>manually</b> after order cancelation.",
description: "dialog content",
},
buttonKeepOrder: {
id: "p6ugX0",
defaultMessage: "Keep order",
description: "button to keep order",
},
buttonCancelOrder: {
id: "bKTEnb",
defaultMessage: "Cancel order",
description: "button to cancel order",
},
});

0 comments on commit fda067f

Please sign in to comment.