Skip to content

Commit

Permalink
Merge pull request #688 from mirumee/metadata/orders
Browse files Browse the repository at this point in the history
Add metadata to orders
  • Loading branch information
dominik-zeglen authored Sep 4, 2020
2 parents 591f2ec + 9ff8f0f commit f2a309e
Show file tree
Hide file tree
Showing 24 changed files with 17,308 additions and 13,207 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ All notable, unreleased changes to this project will be documented in this file.
- Add metadata editor to creator views - #684 by @dominik-zeglen
- Update product visibility card component - #679 by @AlicjaSzu
- Update savebar design - #690 by @dominik-zeglen
- Add metadata to orders - #688 by @dominik-zeglen

## 2.10.1

Expand Down
3 changes: 3 additions & 0 deletions src/fragments/orders.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import gql from "graphql-tag";

import { fragmentAddress } from "./address";
import { metadataFragment } from "./metadata";

export const fragmentOrderEvent = gql`
fragment OrderEventFragment on OrderEvent {
Expand Down Expand Up @@ -87,8 +88,10 @@ export const fragmentOrderDetails = gql`
${fragmentOrderLine}
${fulfillmentFragment}
${invoiceFragment}
${metadataFragment}
fragment OrderDetailsFragment on Order {
id
...MetadataFragment
billingAddress {
...AddressFragment
}
Expand Down
14 changes: 14 additions & 0 deletions src/fragments/types/OrderDetailsFragment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,18 @@ import { OrderEventsEmailsEnum, OrderEventsEnum, FulfillmentStatus, PaymentCharg
// GraphQL fragment: OrderDetailsFragment
// ====================================================

export interface OrderDetailsFragment_metadata {
__typename: "MetadataItem";
key: string;
value: string;
}

export interface OrderDetailsFragment_privateMetadata {
__typename: "MetadataItem";
key: string;
value: string;
}

export interface OrderDetailsFragment_billingAddress_country {
__typename: "CountryDisplay";
code: string;
Expand Down Expand Up @@ -285,6 +297,8 @@ export interface OrderDetailsFragment_invoices {
export interface OrderDetailsFragment {
__typename: "Order";
id: string;
metadata: (OrderDetailsFragment_metadata | null)[];
privateMetadata: (OrderDetailsFragment_privateMetadata | null)[];
billingAddress: OrderDetailsFragment_billingAddress | null;
canFinalize: boolean;
created: any;
Expand Down
2 changes: 1 addition & 1 deletion src/misc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ export function hasErrors(errorList: UserError[] | null): boolean {
export function getMutationState(
called: boolean,
loading: boolean,
...errorList: UserError[][]
...errorList: any[][]
): ConfirmButtonTransitionState {
if (loading) {
return "loading";
Expand Down
242 changes: 147 additions & 95 deletions src/orders/components/OrderDetailsPage/OrderDetailsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,19 @@ import Typography from "@material-ui/core/Typography";
import AppHeader from "@saleor/components/AppHeader";
import CardMenu from "@saleor/components/CardMenu";
import { CardSpacer } from "@saleor/components/CardSpacer";
import { ConfirmButtonTransitionState } from "@saleor/components/ConfirmButton";
import { Container } from "@saleor/components/Container";
import { DateTime } from "@saleor/components/Date";
import Form from "@saleor/components/Form";
import Grid from "@saleor/components/Grid";
import Metadata, { MetadataFormData } from "@saleor/components/Metadata";
import PageHeader from "@saleor/components/PageHeader";
import SaveButtonBar from "@saleor/components/SaveButtonBar";
import Skeleton from "@saleor/components/Skeleton";
import { sectionNames } from "@saleor/intl";
import { UserPermissionProps } from "@saleor/types";
import { mapMetadataItemToInput } from "@saleor/utils/maps";
import useMetadataChangeTrigger from "@saleor/utils/metadata/useMetadataChangeTrigger";
import React from "react";
import { useIntl } from "react-intl";

Expand Down Expand Up @@ -49,6 +55,8 @@ export interface OrderDetailsPageProps extends UserPermissionProps {
code: string;
label: string;
}>;
disabled: boolean;
saveButtonBarState: ConfirmButtonTransitionState;
onBack();
onBillingAddressEdit();
onFulfillmentCancel(id: string);
Expand All @@ -66,11 +74,14 @@ export interface OrderDetailsPageProps extends UserPermissionProps {
onInvoiceClick(invoiceId: string);
onInvoiceGenerate();
onInvoiceSend(invoiceId: string);
onSubmit(data: MetadataFormData);
}

const OrderDetailsPage: React.FC<OrderDetailsPageProps> = props => {
const {
disabled,
order,
saveButtonBarState,
userPermissions,
onBack,
onBillingAddressEdit,
Expand All @@ -87,11 +98,17 @@ const OrderDetailsPage: React.FC<OrderDetailsPageProps> = props => {
onProfileView,
onInvoiceClick,
onInvoiceGenerate,
onInvoiceSend
onInvoiceSend,
onSubmit
} = props;
const classes = useStyles(props);

const intl = useIntl();
const {
isMetadataModified,
isPrivateMetadataModified,
makeChangeHandler: makeMetadataChangeHandler
} = useMetadataChangeTrigger();

const canCancel = maybe(() => order.status) !== OrderStatus.CANCELED;
const canEditAddresses = maybe(() => order.status) !== OrderStatus.CANCELED;
Expand All @@ -100,103 +117,138 @@ const OrderDetailsPage: React.FC<OrderDetailsPageProps> = props => {
line => line.quantityFulfilled < line.quantity
);

const handleSubmit = (data: MetadataFormData) => {
const metadata = isMetadataModified ? data.metadata : undefined;
const privateMetadata = isPrivateMetadataModified
? data.privateMetadata
: undefined;

onSubmit({
metadata,
privateMetadata
});
};

const initial: MetadataFormData = {
metadata: order?.metadata.map(mapMetadataItemToInput),
privateMetadata: order?.privateMetadata.map(mapMetadataItemToInput)
};

return (
<Container>
<AppHeader onBack={onBack}>
{intl.formatMessage(sectionNames.orders)}
</AppHeader>
<PageHeader
className={classes.header}
inline
title={maybe(() => order.number) ? "#" + order.number : undefined}
>
{canCancel && (
<CardMenu
menuItems={[
{
label: intl.formatMessage({
defaultMessage: "Cancel order",
description: "button"
}),
onSelect: onOrderCancel
}
]}
/>
)}
</PageHeader>
<div className={classes.date}>
{order && order.created ? (
<Typography variant="caption">
<DateTime date={order.created} />
</Typography>
) : (
<Skeleton style={{ width: "10em" }} />
)}
</div>
<Grid>
<div>
{unfulfilled.length > 0 && (
<OrderUnfulfilledItems
canFulfill={canFulfill}
lines={unfulfilled}
onFulfill={onOrderFulfill}
/>
)}
{renderCollection(
maybe(() => order.fulfillments),
(fulfillment, fulfillmentIndex) => (
<React.Fragment key={maybe(() => fulfillment.id, "loading")}>
{!(unfulfilled.length === 0 && fulfillmentIndex === 0) && (
<CardSpacer />
<Form initial={initial} onSubmit={handleSubmit}>
{({ change, data, hasChanged, submit }) => {
const changeMetadata = makeMetadataChangeHandler(change);

return (
<Container>
<AppHeader onBack={onBack}>
{intl.formatMessage(sectionNames.orders)}
</AppHeader>
<PageHeader
className={classes.header}
inline
title={maybe(() => order.number) ? "#" + order.number : undefined}
>
{canCancel && (
<CardMenu
menuItems={[
{
label: intl.formatMessage({
defaultMessage: "Cancel order",
description: "button"
}),
onSelect: onOrderCancel
}
]}
/>
)}
</PageHeader>
<div className={classes.date}>
{order && order.created ? (
<Typography variant="caption">
<DateTime date={order.created} />
</Typography>
) : (
<Skeleton style={{ width: "10em" }} />
)}
</div>
<Grid>
<div>
{unfulfilled.length > 0 && (
<OrderUnfulfilledItems
canFulfill={canFulfill}
lines={unfulfilled}
onFulfill={onOrderFulfill}
/>
)}
{renderCollection(
maybe(() => order.fulfillments),
(fulfillment, fulfillmentIndex) => (
<React.Fragment
key={maybe(() => fulfillment.id, "loading")}
>
{!(
unfulfilled.length === 0 && fulfillmentIndex === 0
) && <CardSpacer />}
<OrderFulfillment
fulfillment={fulfillment}
orderNumber={maybe(() => order.number)}
onOrderFulfillmentCancel={() =>
onFulfillmentCancel(fulfillment.id)
}
onTrackingCodeAdd={() =>
onFulfillmentTrackingNumberUpdate(fulfillment.id)
}
/>
</React.Fragment>
)
)}
<OrderFulfillment
fulfillment={fulfillment}
orderNumber={maybe(() => order.number)}
onOrderFulfillmentCancel={() =>
onFulfillmentCancel(fulfillment.id)
}
onTrackingCodeAdd={() =>
onFulfillmentTrackingNumberUpdate(fulfillment.id)
}
<CardSpacer />
<OrderPayment
order={order}
onCapture={onPaymentCapture}
onMarkAsPaid={onPaymentPaid}
onRefund={onPaymentRefund}
onVoid={onPaymentVoid}
/>
<CardSpacer />
<Metadata data={data} onChange={changeMetadata} />
<OrderHistory
history={maybe(() => order.events)}
onNoteAdd={onNoteAdd}
/>
</React.Fragment>
)
)}
<CardSpacer />
<OrderPayment
order={order}
onCapture={onPaymentCapture}
onMarkAsPaid={onPaymentPaid}
onRefund={onPaymentRefund}
onVoid={onPaymentVoid}
/>
<OrderHistory
history={maybe(() => order.events)}
onNoteAdd={onNoteAdd}
/>
</div>
<div>
<OrderCustomer
canEditAddresses={canEditAddresses}
canEditCustomer={false}
order={order}
userPermissions={userPermissions}
onBillingAddressEdit={onBillingAddressEdit}
onShippingAddressEdit={onShippingAddressEdit}
onProfileView={onProfileView}
/>
<CardSpacer />
<OrderInvoiceList
invoices={order?.invoices}
onInvoiceClick={onInvoiceClick}
onInvoiceGenerate={onInvoiceGenerate}
onInvoiceSend={onInvoiceSend}
/>
<CardSpacer />
<OrderCustomerNote note={maybe(() => order.customerNote)} />
</div>
</Grid>
</Container>
</div>
<div>
<OrderCustomer
canEditAddresses={canEditAddresses}
canEditCustomer={false}
order={order}
userPermissions={userPermissions}
onBillingAddressEdit={onBillingAddressEdit}
onShippingAddressEdit={onShippingAddressEdit}
onProfileView={onProfileView}
/>
<CardSpacer />
<OrderInvoiceList
invoices={order?.invoices}
onInvoiceClick={onInvoiceClick}
onInvoiceGenerate={onInvoiceGenerate}
onInvoiceSend={onInvoiceSend}
/>
<CardSpacer />
<OrderCustomerNote note={maybe(() => order.customerNote)} />
</div>
</Grid>
<SaveButtonBar
onCancel={onBack}
onSave={submit}
state={saveButtonBarState}
disabled={disabled || !hasChanged}
/>
</Container>
);
}}
</Form>
);
};
OrderDetailsPage.displayName = "OrderDetailsPage";
Expand Down
10 changes: 10 additions & 0 deletions src/orders/fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1096,8 +1096,16 @@ export const order = (placeholder: string): OrderDetails_order => ({
}
}
],
metadata: [
{
__typename: "MetadataItem",
key: "integration.key",
value: "some-value"
}
],
number: "9",
paymentStatus: PaymentChargeStatusEnum.NOT_CHARGED,
privateMetadata: [],
shippingAddress: {
__typename: "Address",
city: "West Patriciastad",
Expand Down Expand Up @@ -1256,8 +1264,10 @@ export const draftOrder = (placeholder: string): OrderDetails_order => ({
}
}
],
metadata: [],
number: "24",
paymentStatus: null,
privateMetadata: [],
shippingAddress: null,
shippingMethod: null,
shippingMethodName: null,
Expand Down
Loading

0 comments on commit f2a309e

Please sign in to comment.