Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 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/little-pandas-travel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"saleor-dashboard": patch
---

Overcharged status pill has been added to order lists and details view. This means you can now see if an order has been overcharged.
8 changes: 8 additions & 0 deletions locale/defaultMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -1049,6 +1049,10 @@
"4T/RzC": {
"string": "Make sure to save token, you won’t be able to see it again."
},
"4VLj3S": {
"context": "overcharged order status",
"string": "Overcharged"
},
"4VOIum": {
"context": "product availability",
"string": "Enabling this checkbox will remove product from search and category pages. It will be available on collection pages."
Expand All @@ -1060,6 +1064,10 @@
"context": "modal button",
"string": "Upload URL"
},
"4WranC": {
"context": "payment status",
"string": "Overcharged"
},
"4XhJY+": {
"context": "dialog header",
"string": "Add product from {channelName}"
Expand Down
72 changes: 21 additions & 51 deletions src/customers/components/CustomerOrders/CustomerOrders.tsx
Original file line number Diff line number Diff line change
@@ -1,49 +1,32 @@
// @ts-strict-ignore
import { DashboardCard } from "@dashboard/components/Card";
import { DateTime } from "@dashboard/components/Date";
import Money from "@dashboard/components/Money";
import { Pill } from "@dashboard/components/Pill";
import ResponsiveTable from "@dashboard/components/ResponsiveTable";
import TableRowLink from "@dashboard/components/TableRowLink";
import { CustomerDetailsQuery } from "@dashboard/graphql";
import { OrderPaymentStatusPill } from "@dashboard/orders/components/OrderPaymentSummaryCard/components/OrderPaymentStatusPill";
import { orderUrl } from "@dashboard/orders/urls";
import { RelayToFlat } from "@dashboard/types";
import { TableBody, TableCell, TableHead } from "@material-ui/core";
import { makeStyles } from "@saleor/macaw-ui";
import { Button, Skeleton } from "@saleor/macaw-ui-next";
import { Button, Skeleton, sprinkles } from "@saleor/macaw-ui-next";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
import { Link } from "react-router-dom";

import { maybe, renderCollection, transformPaymentStatus } from "../../../misc";
import { renderCollection } from "../../../misc";

const useStyles = makeStyles(
{
link: {
cursor: "pointer",
},
textRight: {
textAlign: "right",
},
},
{ name: "CustomerOrders" },
);
const textRightStyle = sprinkles({
textAlign: "right",
});

export interface CustomerOrdersProps {
orders: RelayToFlat<CustomerDetailsQuery["user"]["orders"]>;
orders: RelayToFlat<NonNullable<NonNullable<CustomerDetailsQuery["user"]>["orders"]>>;
viewAllHref: string;
}

const CustomerOrders: React.FC<CustomerOrdersProps> = props => {
const { orders, viewAllHref } = props;
const classes = useStyles(props);
const intl = useIntl();
const orderList = orders
? orders.map(order => ({
...order,
paymentStatus: transformPaymentStatus(order.paymentStatus, intl),
}))
: undefined;

return (
<DashboardCard>
Expand Down Expand Up @@ -83,7 +66,7 @@ const CustomerOrders: React.FC<CustomerOrdersProps> = props => {
<TableCell>
<FormattedMessage id="pURrk1" defaultMessage="Status" description="order status" />
</TableCell>
<TableCell className={classes.textRight}>
<TableCell className={textRightStyle}>
<FormattedMessage
id="taX/V3"
defaultMessage="Total"
Expand All @@ -94,42 +77,29 @@ const CustomerOrders: React.FC<CustomerOrdersProps> = props => {
</TableHead>
<TableBody>
{renderCollection(
orderList,
orders,
order => (
<TableRowLink
hover={!!order}
className={order ? classes.link : undefined}
className={
order
? sprinkles({
cursor: "pointer",
})
: undefined
}
href={order && orderUrl(order.id)}
key={order ? order.id : "skeleton"}
>
<TableCell>{order?.number ? "#" + order.number : <Skeleton />}</TableCell>
<TableCell>
{maybe(() => order.number) ? "#" + order.number : <Skeleton />}
{order?.created ? <DateTime date={order.created} plain /> : <Skeleton />}
</TableCell>
<TableCell>
{maybe(() => order.created) ? (
<DateTime date={order.created} plain />
) : (
<Skeleton />
)}
{order ? <OrderPaymentStatusPill order={order} /> : <Skeleton />}
</TableCell>
<TableCell>
{maybe(() => order.paymentStatus.status) !== undefined ? (
order.paymentStatus.status === null ? null : (
<Pill
color={order.paymentStatus.status}
label={order.paymentStatus.localized}
/>
)
) : (
<Skeleton />
)}
</TableCell>
<TableCell className={classes.textRight} align="right">
{maybe(() => order.total.gross) ? (
<Money money={order.total.gross} />
) : (
<Skeleton />
)}
<TableCell className={textRightStyle} align="right">
{order?.total.gross ? <Money money={order.total.gross} /> : <Skeleton />}
</TableCell>
</TableRowLink>
),
Expand Down
2 changes: 2 additions & 0 deletions src/customers/fixtures.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
CustomerAddressesQuery,
CustomerDetailsQuery,
OrderChargeStatusEnum,
PaymentChargeStatusEnum,
} from "@dashboard/graphql";

Expand Down Expand Up @@ -1060,6 +1061,7 @@ export const customer: CustomerDetailsQuery["user"] & CustomerAddressesQuery["us
id: "T3JkZXI6MTk=",
number: "8234",
paymentStatus: PaymentChargeStatusEnum.FULLY_CHARGED,
chargeStatus: OrderChargeStatusEnum.FULL,
total: {
__typename: "TaxedMoney",
gross: {
Expand Down
5 changes: 3 additions & 2 deletions src/customers/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export const customerDetails = gql`
privateMetadata @include(if: $PERMISSION_MANAGE_STAFF) {
...MetadataItem
}
orders(last: 5) @include(if: $PERMISSION_MANAGE_ORDERS) {
orders(first: 5) @include(if: $PERMISSION_MANAGE_ORDERS) {
edges {
node {
id
Expand All @@ -63,10 +63,11 @@ export const customerDetails = gql`
amount
}
}
chargeStatus
}
}
}
lastPlacedOrder: orders(last: 1) @include(if: $PERMISSION_MANAGE_ORDERS) {
lastPlacedOrder: orders(first: 1) @include(if: $PERMISSION_MANAGE_ORDERS) {
edges {
node {
id
Expand Down
3 changes: 1 addition & 2 deletions src/fragments/orders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,8 +269,6 @@ export const orderDiscount = gql`
export const fragmentOrderDetails = gql`
fragment OrderDetails on Order {
id
# TODO: remove me
token
...Metadata
billingAddress {
...Address
Expand Down Expand Up @@ -428,6 +426,7 @@ export const fragmentOrderDetails = gql`
}
}
isPaid
chargeStatus
}
`;

Expand Down
8 changes: 5 additions & 3 deletions src/graphql/hooks.generated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1967,7 +1967,6 @@ export const InvoiceFragmentDoc = gql`
export const OrderDetailsFragmentDoc = gql`
fragment OrderDetails on Order {
id
token
...Metadata
billingAddress {
...Address
Expand Down Expand Up @@ -2123,6 +2122,7 @@ export const OrderDetailsFragmentDoc = gql`
}
}
isPaid
chargeStatus
}
${MetadataFragmentDoc}
${AddressFragmentDoc}
Expand Down Expand Up @@ -7810,7 +7810,7 @@ export const CustomerDetailsDocument = gql`
privateMetadata @include(if: $PERMISSION_MANAGE_STAFF) {
...MetadataItem
}
orders(last: 5) @include(if: $PERMISSION_MANAGE_ORDERS) {
orders(first: 5) @include(if: $PERMISSION_MANAGE_ORDERS) {
edges {
node {
id
Expand All @@ -7823,10 +7823,11 @@ export const CustomerDetailsDocument = gql`
amount
}
}
chargeStatus
}
}
}
lastPlacedOrder: orders(last: 1) @include(if: $PERMISSION_MANAGE_ORDERS) {
lastPlacedOrder: orders(first: 1) @include(if: $PERMISSION_MANAGE_ORDERS) {
edges {
node {
id
Expand Down Expand Up @@ -12245,6 +12246,7 @@ export const OrderListDocument = gql`
}
}
userEmail
chargeStatus
}
}
pageInfo {
Expand Down
58 changes: 29 additions & 29 deletions src/graphql/types.generated.ts

Large diffs are not rendered by default.

20 changes: 20 additions & 0 deletions src/misc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
AddressInput,
CountryCode,
DateRangeInput,
OrderChargeStatusEnum,
OrderStatus,
OrderStatusFilter,
PaymentChargeStatusEnum,
Expand Down Expand Up @@ -125,6 +126,25 @@
};
};

export const transformChargedStatus = (status: OrderChargeStatusEnum, intl: IntlShape) => {
switch (status) {
case OrderChargeStatusEnum.OVERCHARGED:
return {
localized: intl.formatMessage({
defaultMessage: "Overcharged",
id: "4VLj3S",
description: "overcharged order status",
}),
status: StatusType.WARNING,
};
default:
return {

Check warning on line 141 in src/misc.ts

View check run for this annotation

Codecov / codecov/patch

src/misc.ts#L140-L141

Added lines #L140 - L141 were not covered by tests
localized: status,
status: StatusType.ERROR,
};
}
};

export const transformOrderStatus = (
status: string,
intl: IntlShape,
Expand Down
44 changes: 42 additions & 2 deletions src/orders/components/OrderListDatagrid/datagrid.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
import { PillCell } from "@dashboard/components/Datagrid/customCells/PillCell";
import { GetCellContentOpts } from "@dashboard/components/Datagrid/Datagrid";
import { AvailableColumn } from "@dashboard/components/Datagrid/types";
import { OrderListQuery, OrderStatus, PaymentChargeStatusEnum } from "@dashboard/graphql";
import {
OrderChargeStatusEnum,
OrderListQuery,
OrderStatus,
PaymentChargeStatusEnum,
} from "@dashboard/graphql";
import { RelayToFlat } from "@dashboard/types";
import { TextCell } from "@glideapps/glide-data-grid";
import { renderHook } from "@testing-library/react-hooks";

import { getCustomerCellContent, useGetCellContent } from "./datagrid";
import { getCustomerCellContent, getPaymentCellContent, useGetCellContent } from "./datagrid";

jest.mock("react-intl", () => ({
useIntl: jest.fn(() => ({
Expand Down Expand Up @@ -205,3 +211,37 @@ describe("useGetCellContent", () => {
expect((getCellContent([0, 1], contentOpts) as TextCell).data).toBe("");
});
});

describe("getPaymentCellContent", () => {
it("should return Fully Paid when payment status is PAID", () => {
// Arrange
const data = {
paymentStatus: "PAID" as PaymentChargeStatusEnum,
} as RelayToFlat<NonNullable<OrderListQuery["orders"]>>[number];

// Act
const result = getPaymentCellContent({ formatMessage: jest.fn() } as any, "defaultLight", data);

// Assert
expect((result.data as PillCell["data"]).value).toEqual("PAID");
});

it("should return Overcharged when charge status is OVERCHARGED", () => {
// Arrange
const data = {
chargeStatus: "OVERCHARGED" as OrderChargeStatusEnum,
} as RelayToFlat<NonNullable<OrderListQuery["orders"]>>[number];

// Act
const result = getPaymentCellContent(
{
formatMessage: jest.fn().mockImplementation(({ defaultMessage }) => defaultMessage),
} as any,
"defaultLight",
data,
);

// Assert
expect((result.data as PillCell["data"]).value).toEqual("Overcharged");
});
});
22 changes: 20 additions & 2 deletions src/orders/components/OrderListDatagrid/datagrid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,13 @@ import {
} from "@dashboard/components/Datagrid/customCells/cells";
import { GetCellContentOpts } from "@dashboard/components/Datagrid/Datagrid";
import { AvailableColumn } from "@dashboard/components/Datagrid/types";
import { OrderListQuery } from "@dashboard/graphql";
import { getStatusColor, transformOrderStatus, transformPaymentStatus } from "@dashboard/misc";
import { OrderChargeStatusEnum, OrderListQuery } from "@dashboard/graphql";
import {
getStatusColor,
transformChargedStatus,
transformOrderStatus,
transformPaymentStatus,
} from "@dashboard/misc";
import { OrderListUrlSortField } from "@dashboard/orders/urls";
import { RelayToFlat, Sort } from "@dashboard/types";
import { getColumnSortDirectionIcon } from "@dashboard/utils/columns/getColumnSortDirectionIcon";
Expand Down Expand Up @@ -142,11 +147,24 @@ export function getStatusCellContent(
return readonlyTextCell("-");
}

const higherPriorityChargeStatuses = [OrderChargeStatusEnum.OVERCHARGED];

export function getPaymentCellContent(
intl: IntlShape,
currentTheme: DefaultTheme,
rowData: RelayToFlat<OrderListQuery["orders"]>[number],
) {
if (higherPriorityChargeStatuses.includes(rowData.chargeStatus)) {
const { localized, status } = transformChargedStatus(rowData.chargeStatus, intl);

const color = getStatusColor({
status,
currentTheme,
});

return pillCell(localized, color, COMMON_CELL_PROPS);
}

const paymentStatus = transformPaymentStatus(rowData.paymentStatus, intl);

if (paymentStatus) {
Expand Down
Loading
Loading