Add order expiration (#3843)

* Add TTL expiration & migrate some components in channel details

* Migrate button

* Update fixtures

* Add changeset

* Typo & lint

* Reorder UI elements

* Set custom height to match old input

* Add explanatory comment

* test - created test for expired orderes functionality in channels, fixed validation test which checks using same slug twice when creating channel

* Fix create page

* Fix lint issue

* Fix error handling double notification

* tests added: creating channel with expiration days for orders, creating channel with expiration days for orders with boundary conditions exciding requirements

* function name typeExpirationDate changed to typeExpirationDays

---------

Co-authored-by: wojteknowacki <wojciech.nowacki@saleor.io>
This commit is contained in:
Michał Droń 2023-07-12 14:04:50 +02:00 committed by GitHub
parent 66976d547b
commit b386cf060f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 321 additions and 182 deletions

View file

@ -0,0 +1,5 @@
---
"saleor-dashboard": minor
---
Add order exipration TTL field to channel settings

View file

@ -8,6 +8,7 @@ import { CHANNELS_SELECTORS } from "../../../elements/channels/channels-selector
import { SELECT_CHANNELS_TO_ASSIGN } from "../../../elements/channels/select-channels-to-assign";
import { HEADER_SELECTORS } from "../../../elements/header/header-selectors";
import { BUTTON_SELECTORS } from "../../../elements/shared/button-selectors";
import { MESSAGES } from "../../../fixtures/";
import { productDetailsUrl, urlList } from "../../../fixtures/urlList";
import { ONE_PERMISSION_USERS } from "../../../fixtures/users";
import { createChannel } from "../../../support/api/requests/Channels";
@ -17,7 +18,11 @@ import {
getShippingZone,
} from "../../../support/api/requests/ShippingMethod";
import { createWarehouse as createWarehouseViaApi } from "../../../support/api/requests/Warehouse";
import { createChannelByView } from "../../../support/pages/channelsPage";
import {
createChannelByView,
setChannelRequiredFields,
typeExpirationDays,
} from "../../../support/pages/channelsPage";
describe("Channels", () => {
const channelStartsWith = `CyChannels`;
@ -91,6 +96,65 @@ describe("Channels", () => {
});
},
);
it(
"should create new channel with expired orders functionality set. TC: SALEOR_0713",
{ tags: ["@channel", "@allEnv", "@stable"] },
() => {
const randomChannel = `${channelStartsWith} ${faker.datatype.number()}`;
const orderExpiresAfter = 120;
cy.addAliasToGraphRequest("Channels");
cy.addAliasToGraphRequest("ChannelCreate");
cy.visit(urlList.channels);
cy.waitForRequestAndCheckIfNoErrors("@Channels");
setChannelRequiredFields({ name: randomChannel, currency });
typeExpirationDays(orderExpiresAfter);
cy.clickConfirmButton();
cy.waitForRequestAndCheckIfNoErrors("@ChannelCreate").then(
channelCreate => {
expect(
channelCreate.response.body.data.channelCreate.channel
.orderSettings,
).to.have.property("deleteExpiredOrdersAfter", orderExpiresAfter);
cy.get(CHANNELS_SELECTORS.orderExpirationInput)
.invoke("val")
.should("contain", orderExpiresAfter.toString());
},
);
},
);
it(
"should not be able to create new channel with expired orders functionality with values outside boundary conditions. TC: SALEOR_0714",
{ tags: ["@channel", "@allEnv"] },
() => {
const randomChannel = `${channelStartsWith} ${faker.datatype.number()}`;
const underBoundaryConditions = 0;
const overBoundaryConditions = 121;
cy.addAliasToGraphRequest("Channels");
cy.addAliasToGraphRequest("ChannelCreate");
cy.visit(urlList.channels);
cy.waitForRequestAndCheckIfNoErrors("@Channels");
setChannelRequiredFields({ name: randomChannel, currency });
typeExpirationDays(underBoundaryConditions);
cy.clickConfirmButton();
cy.wait("@ChannelCreate").then(createChannelResponse => {
cy.log(createChannelResponse);
expect(
createChannelResponse.response.body.data.channelCreate.errors.length,
).to.eq(1);
cy.confirmationErrorMessageShouldAppear();
});
typeExpirationDays(overBoundaryConditions);
cy.clickConfirmButton();
cy.wait("@ChannelCreate").then(createChannelResponse => {
cy.log(createChannelResponse);
expect(
createChannelResponse.response.body.data.channelCreate.errors.length,
).to.eq(1);
cy.confirmationErrorMessageShouldAppear();
});
},
);
it(
"should create channel with shippingZone and warehouse TC: SALEOR_0712",
{ tags: ["@channel", "@allEnv"] },
@ -101,7 +165,6 @@ describe("Channels", () => {
const randomChannel = `${channelStartsWith} ${faker.datatype.number()}`;
cy.addAliasToGraphRequest("Channels");
cy.visit(urlList.channels);
cy.expectSkeletonIsVisible();
cy.wait("@Channels");
createChannelByView({
name: randomChannel,
@ -120,7 +183,7 @@ describe("Channels", () => {
);
it(
"should validate slug name. TC: SALEOR_0703",
"should validate that creating channels with same slug name as other is not possible. TC: SALEOR_0703",
{ tags: ["@channel", "@allEnv", "@stable"] },
() => {
const randomChannel = `${channelStartsWith} ${faker.datatype.number()}`;
@ -133,8 +196,10 @@ describe("Channels", () => {
cy.visit(urlList.channels);
cy.expectSkeletonIsVisible();
createChannelByView({ name: randomChannel, currency });
cy.get(ADD_CHANNEL_FORM_SELECTORS.slugValidationMessage).should(
"be.visible",
cy.confirmationErrorMessageShouldAppear();
cy.get(ADD_CHANNEL_FORM_SELECTORS.generalInformationSection).should(
"contain.text",
MESSAGES.slugMustBeUnique,
);
},
);

View file

@ -15,4 +15,5 @@ export const ADD_CHANNEL_FORM_SELECTORS = {
warehouseAutocompleteSelect:
"[data-test-id='warehouse-auto-complete-select']",
countryAutocompleteInput: '[data-test-id="country-select-input"]',
generalInformationSection: '[data-test-id="general-information"]',
};

View file

@ -1,5 +1,6 @@
export const CHANNELS_SELECTORS = {
createChannelButton: "[data-test-id='add-channel']",
channelsTable: "[class='MuiTableBody-root']",
channelName: "[data-test-id='name']"
channelName: "[data-test-id='name']",
orderExpirationInput: "[data-test-id='delete-expired-order-input']",
};

View file

@ -2,4 +2,5 @@ export const MESSAGES = {
noProductFound: "No products found",
confirmProductsDeletion: "Are you sure you want to delete 2 products?",
invalidEmailAddress: "Enter a valid email address.",
slugMustBeUnique: "Slug must be unique",
};

View file

@ -16,13 +16,32 @@ export function createChannelByView({
defaultCountry = "Poland",
warehouse,
}) {
cy.addAliasToGraphRequest("Channel")
.get(CHANNELS_SELECTORS.createChannelButton)
.click()
.get(ADD_CHANNEL_FORM_SELECTORS.channelName)
.type(name)
setChannelRequiredFields({
name,
currency,
slug,
shippingZone,
defaultCountry,
warehouse,
});
cy.get(ADD_CHANNEL_FORM_SELECTORS.saveButton).click();
}
export function setChannelRequiredFields({
name,
currency,
slug = name,
shippingZone,
defaultCountry = "Poland",
warehouse,
}) {
cy.addAliasToGraphRequest("Channel");
clickCreateChannelButton();
cy.get(ADD_CHANNEL_FORM_SELECTORS.channelName)
.click({ force: true })
.type(name, { force: true })
.get(ADD_CHANNEL_FORM_SELECTORS.slug)
.type(slug)
.click({ force: true })
.type(slug, { force: true })
.get(ADD_CHANNEL_FORM_SELECTORS.currency)
.click();
cy.get(ADD_CHANNEL_FORM_SELECTORS.currency).type(currency);
@ -43,7 +62,6 @@ export function createChannelByView({
if (warehouse) {
addWarehouse(warehouse);
}
cy.get(ADD_CHANNEL_FORM_SELECTORS.saveButton).click();
}
export function addShippingZone(shippingZone) {
@ -57,6 +75,16 @@ export function addShippingZone(shippingZone) {
shippingZone,
);
}
export function typeExpirationDays(expirationDays) {
cy.get(CHANNELS_SELECTORS.orderExpirationInput)
.click({ force: true })
.clear()
.type(expirationDays);
}
export function clickCreateChannelButton() {
return cy.get(CHANNELS_SELECTORS.createChannelButton).click();
}
export function addWarehouse(warehouse) {
cy.get(BUTTON_SELECTORS.expandIcon)

View file

@ -4411,6 +4411,10 @@
"context": "page header, edit view",
"string": "Edit grant refund"
},
"U+79k0": {
"context": "order expiration card description",
"string": "The time in days after expired orders will be deleted. Allowed range between 1 and 120."
},
"U1eJIw": {
"context": "order history message",
"string": "Products were added to an order"
@ -5269,10 +5273,6 @@
"context": "header",
"string": "Password"
},
"ZhaXLU": {
"context": "button",
"string": "Copy"
},
"ZhqH8J": {
"context": "button",
"string": "Copy headers"
@ -6659,6 +6659,10 @@
"kTr2o8": {
"string": "Attribute name"
},
"kVKTwC": {
"context": "order expiration card title",
"string": "Order expiration"
},
"kVOslW": {
"context": "reason for discount label",
"string": "Reason for discount"

View file

@ -3,8 +3,7 @@ import {
ChannelShippingZones,
ChannelWarehouses,
} from "@dashboard/channels/pages/ChannelDetailsPage/types";
import CardSpacer from "@dashboard/components/CardSpacer";
import CardTitle from "@dashboard/components/CardTitle";
import { DashboardCard } from "@dashboard/components/Card";
import ControlledSwitch from "@dashboard/components/ControlledSwitch";
import FormSpacer from "@dashboard/components/FormSpacer";
import Link from "@dashboard/components/Link";
@ -23,18 +22,11 @@ import { ChangeEvent, FormChange } from "@dashboard/hooks/useForm";
import { commonMessages } from "@dashboard/intl";
import { getFormErrors } from "@dashboard/utils/errors";
import getChannelsErrorMessage from "@dashboard/utils/errors/channels";
import {
Card,
CardContent,
InputAdornment,
TextField,
Typography,
} from "@material-ui/core";
import { Box } from "@saleor/macaw-ui/next";
import { Box, Button, CopyIcon, Input, Text } from "@saleor/macaw-ui/next";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
import { useStyles } from "../styles";
import { messages } from "./messages";
import { ExtendedFormHelperTextProps } from "./types";
export interface FormData extends StockSettingsInput {
@ -49,6 +41,7 @@ export interface FormData extends StockSettingsInput {
warehousesToDisplay: ChannelWarehouses;
defaultCountry: CountryCode;
markAsPaidStrategy: MarkAsPaidStrategyEnum;
deleteExpiredOrdersAfter: number;
}
export interface ChannelFormProps {
@ -79,91 +72,62 @@ export const ChannelForm: React.FC<ChannelFormProps> = ({
onMarkAsPaidStrategyChange,
}) => {
const intl = useIntl();
const [copied, copy] = useClipboard();
const [, copy] = useClipboard();
const formErrors = getFormErrors<keyof FormData, ChannelErrorFragment>(
["name", "slug", "currencyCode", "defaultCountry"],
[
"name",
"slug",
"currencyCode",
"defaultCountry",
"deleteExpiredOrdersAfter",
],
errors,
);
const classes = useStyles();
return (
<>
<Card>
<CardTitle
title={intl.formatMessage(commonMessages.generalInformations)}
/>
<CardContent>
<TextField
<DashboardCard>
<DashboardCard.Title>
{intl.formatMessage(commonMessages.generalInformations)}
</DashboardCard.Title>
<DashboardCard.Content data-test-id="general-information">
<Input
error={!!formErrors.name}
helperText={getChannelsErrorMessage(formErrors?.name, intl)}
disabled={disabled}
fullWidth
label={intl.formatMessage({
id: "UymotP",
defaultMessage: "Channel name",
description: "channel name",
})}
label={intl.formatMessage(messages.channelName)}
name="name"
value={data.name}
onChange={onChange}
/>
<FormSpacer />
<TextField
<Input
error={!!formErrors.slug}
helperText={getChannelsErrorMessage(formErrors?.slug, intl)}
disabled={disabled}
fullWidth
FormHelperTextProps={
{
"data-test-id": "slug-text-input-helper-text",
} as ExtendedFormHelperTextProps
}
label={intl.formatMessage({
id: "74Zo/H",
defaultMessage: "Slug",
description: "channel slug",
})}
label={intl.formatMessage(messages.channelSlug)}
name="slug"
value={data.slug}
onChange={onChange}
InputProps={{
endAdornment: (
<InputAdornment
className={classes.copyBtn}
position="end"
disableTypography
onClick={() => copy(data.slug)}
>
{copied ? (
<FormattedMessage
id="r86alc"
defaultMessage="Copied"
description="button"
/>
) : (
<FormattedMessage
id="ZhaXLU"
defaultMessage="Copy"
description="button"
/>
)}
</InputAdornment>
),
}}
endAdornment={
<Button
variant="tertiary"
onClick={() => copy(data.slug)}
textTransform="uppercase"
icon={<CopyIcon />}
/>
}
/>
<FormSpacer />
</CardContent>
</Card>
<CardSpacer />
<Card>
<CardTitle
title={intl.formatMessage({
id: "3y4r+z",
defaultMessage: "Channel Settings",
description: "channel settings",
})}
/>
<CardContent>
</DashboardCard.Content>
</DashboardCard>
<Box display="grid" __gridTemplateColumns="2fr 1fr" rowGap={2}>
<Text variant="heading" margin={6}>
<FormattedMessage {...messages.channelSettings} />
</Text>
<Text variant="heading" margin={6}>
<FormattedMessage {...messages.orderExpiration} />
</Text>
<Box paddingX={6}>
{currencyCodes ? (
<SingleAutocompleteSelectField
data-test-id="channel-currency-select-input"
@ -179,11 +143,7 @@ export const ChannelForm: React.FC<ChannelFormProps> = ({
intl,
)}
disabled={disabled}
label={intl.formatMessage({
id: "9Sz0By",
defaultMessage: "Currency",
description: "channel currency",
})}
label={intl.formatMessage(messages.channelCurrency)}
choices={currencyCodes}
name="currencyCode"
displayValue={selectedCurrencyCode}
@ -191,18 +151,18 @@ export const ChannelForm: React.FC<ChannelFormProps> = ({
onChange={onCurrencyCodeChange}
/>
) : (
<>
<Typography variant="caption" className={classes.label}>
<FormattedMessage
id="39yi8w"
defaultMessage="Selected currency"
description="selected currency"
/>
</Typography>
<Typography>{data.currencyCode}</Typography>
</>
<Box display="flex" flexDirection="column">
<Text variant="caption">
<FormattedMessage {...messages.selectedCurrency} />
</Text>
<Text>{data.currencyCode}</Text>
</Box>
)}
<FormSpacer />
</Box>
<Text variant="caption" paddingX={6}>
<FormattedMessage {...messages.orderExpirationDescription} />
</Text>
<Box paddingX={6}>
<SingleAutocompleteSelectField
data-test-id="country-select-input"
error={!!formErrors.defaultCountry}
@ -216,73 +176,82 @@ export const ChannelForm: React.FC<ChannelFormProps> = ({
intl,
)}
disabled={disabled}
label={intl.formatMessage({
id: "tV+Dcm",
defaultMessage: "Default country",
})}
label={intl.formatMessage(messages.defaultCountry)}
choices={countries}
name="defaultCountry"
displayValue={selectedCountryDisplayName}
value={data.defaultCountry}
onChange={onDefaultCountryChange}
/>
<FormSpacer />
<Box display="flex" gap={1.5} alignItems="center">
<ControlledSwitch
data-test-id="order-settings-mark-as-paid"
disabled={disabled}
checked={
data.markAsPaidStrategy ===
MarkAsPaidStrategyEnum.TRANSACTION_FLOW
}
onChange={onMarkAsPaidStrategyChange}
name="markAsPaidStrategy"
label={
<span>
<FormattedMessage
defaultMessage='"Mark as paid" feature creates a'
id="MDOw8D"
/>{" "}
<Link
href="https://docs.saleor.io/docs/3.x/developer/payments#processing-a-payment-with-payment-app"
target="_blank"
rel="noopener noreferer"
>
<FormattedMessage
defaultMessage="Transaction"
id="1+ROfp"
/>
</Link>{" "}
<FormattedMessage
defaultMessage="- used by Payment Apps"
id="Fqe4aB"
/>
</span>
}
secondLabel={
<span>
<FormattedMessage
defaultMessage="If left unchecked it creates a"
id="hHv0ih"
/>{" "}
<Link
href="https://docs.saleor.io/docs/3.x/developer/payments#payment-plugin"
target="_blank"
rel="noopener noreferer"
>
<FormattedMessage defaultMessage="Payment" id="NmK6zy" />
</Link>{" "}
<FormattedMessage
defaultMessage="- used by Payment Plugins"
id="50lR2F"
/>
</span>
}
/>
<PreviewPill />
</Box>
</CardContent>
</Card>
</Box>
<Box paddingX={6}>
<Input
name="deleteExpiredOrdersAfter"
data-test-id="delete-expired-order-input"
value={data.deleteExpiredOrdersAfter}
error={!!formErrors.deleteExpiredOrdersAfter}
type="number"
label="TTL"
onChange={onChange}
min={0}
max={120}
// TODO: Should be removed after single autocomplete
// select is migrated to macaw inputs
__height={12.5}
/>
</Box>
<Box display="flex" gap={1.5} alignItems="center" paddingX={6}>
<ControlledSwitch
data-test-id="order-settings-mark-as-paid"
disabled={disabled}
checked={
data.markAsPaidStrategy ===
MarkAsPaidStrategyEnum.TRANSACTION_FLOW
}
onChange={onMarkAsPaidStrategyChange}
name="markAsPaidStrategy"
label={
<span>
<FormattedMessage
defaultMessage='"Mark as paid" feature creates a'
id="MDOw8D"
/>{" "}
<Link
href="https://docs.saleor.io/docs/3.x/developer/payments#processing-a-payment-with-payment-app"
target="_blank"
rel="noopener noreferer"
>
<FormattedMessage defaultMessage="Transaction" id="1+ROfp" />
</Link>{" "}
<FormattedMessage
defaultMessage="- used by Payment Apps"
id="Fqe4aB"
/>
</span>
}
secondLabel={
<span>
<FormattedMessage
defaultMessage="If left unchecked it creates a"
id="hHv0ih"
/>{" "}
<Link
href="https://docs.saleor.io/docs/3.x/developer/payments#payment-plugin"
target="_blank"
rel="noopener noreferer"
>
<FormattedMessage defaultMessage="Payment" id="NmK6zy" />
</Link>{" "}
<FormattedMessage
defaultMessage="- used by Payment Plugins"
id="50lR2F"
/>
</span>
}
/>
<PreviewPill />
</Box>
</Box>
</>
);
};

View file

@ -0,0 +1,44 @@
import { defineMessages } from "react-intl";
export const messages = defineMessages({
channelName: {
id: "UymotP",
defaultMessage: "Channel name",
description: "channel name",
},
channelSlug: {
id: "74Zo/H",
defaultMessage: "Slug",
description: "channel slug",
},
channelSettings: {
id: "3y4r+z",
defaultMessage: "Channel Settings",
description: "channel settings",
},
channelCurrency: {
id: "9Sz0By",
defaultMessage: "Currency",
description: "channel currency",
},
selectedCurrency: {
id: "39yi8w",
defaultMessage: "Selected currency",
description: "selected currency",
},
defaultCountry: {
id: "tV+Dcm",
defaultMessage: "Default country",
},
orderExpiration: {
id: "kVKTwC",
defaultMessage: "Order expiration",
description: "order expiration card title",
},
orderExpirationDescription: {
id: 'U+79k0',
defaultMessage:
"The time in days after expired orders will be deleted. Allowed range between 1 and 120.",
description: "order expiration card description",
},
});

View file

@ -1,6 +1,6 @@
import { Button } from "@dashboard/components/Button";
import CardTitle from "@dashboard/components/CardTitle";
import { Card, CardContent, Typography } from "@material-ui/core";
import { Button } from "@saleor/macaw-ui/next";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
@ -53,9 +53,10 @@ export const ChannelStatus: React.FC<ChannelStatusProps> = ({
)}
</Typography>
<Button
className={classes.activeBtn}
variant="secondary"
disabled={disabled}
onClick={() => updateChannelStatus()}
marginTop={2}
>
{isActive ? (
<FormattedMessage

View file

@ -50,6 +50,7 @@ export const channelsList: ChannelDetailsFragment[] = [
],
orderSettings: {
markAsPaidStrategy: MarkAsPaidStrategyEnum.TRANSACTION_FLOW,
deleteExpiredOrdersAfter: 60,
__typename: "OrderSettings",
},
},
@ -84,6 +85,7 @@ export const channelsList: ChannelDetailsFragment[] = [
],
orderSettings: {
markAsPaidStrategy: MarkAsPaidStrategyEnum.TRANSACTION_FLOW,
deleteExpiredOrdersAfter: 60,
__typename: "OrderSettings",
},
},
@ -118,6 +120,7 @@ export const channelsList: ChannelDetailsFragment[] = [
],
orderSettings: {
markAsPaidStrategy: MarkAsPaidStrategyEnum.TRANSACTION_FLOW,
deleteExpiredOrdersAfter: 60,
__typename: "OrderSettings",
},
},
@ -152,6 +155,7 @@ export const channelsList: ChannelDetailsFragment[] = [
],
orderSettings: {
markAsPaidStrategy: MarkAsPaidStrategyEnum.TRANSACTION_FLOW,
deleteExpiredOrdersAfter: 60,
__typename: "OrderSettings",
},
},
@ -186,6 +190,7 @@ export const channelsList: ChannelDetailsFragment[] = [
],
orderSettings: {
markAsPaidStrategy: MarkAsPaidStrategyEnum.TRANSACTION_FLOW,
deleteExpiredOrdersAfter: 60,
__typename: "OrderSettings",
},
},
@ -220,6 +225,7 @@ export const channelsList: ChannelDetailsFragment[] = [
],
orderSettings: {
markAsPaidStrategy: MarkAsPaidStrategyEnum.TRANSACTION_FLOW,
deleteExpiredOrdersAfter: 60,
__typename: "OrderSettings",
},
},
@ -254,6 +260,7 @@ export const channelsList: ChannelDetailsFragment[] = [
],
orderSettings: {
markAsPaidStrategy: MarkAsPaidStrategyEnum.TRANSACTION_FLOW,
deleteExpiredOrdersAfter: 60,
__typename: "OrderSettings",
},
},
@ -290,6 +297,7 @@ export const channel: ChannelDetailsFragment = {
],
orderSettings: {
markAsPaidStrategy: MarkAsPaidStrategyEnum.TRANSACTION_FLOW,
deleteExpiredOrdersAfter: 60,
__typename: "OrderSettings",
},
};

View file

@ -126,6 +126,7 @@ const ChannelDetailsPage = function <TErrors extends ChannelErrorFragment[]>({
shippingZonesToDisplay: channelShippingZones,
warehousesToDisplay: channelWarehouses,
markAsPaidStrategy: orderSettings?.markAsPaidStrategy,
deleteExpiredOrdersAfter: orderSettings?.deleteExpiredOrdersAfter,
};
const getFilteredShippingZonesChoices = (

View file

@ -11,8 +11,8 @@ import {
import { getSearchFetchMoreProps } from "@dashboard/hooks/makeTopLevelSearch/utils";
import useNavigator from "@dashboard/hooks/useNavigator";
import useNotifier from "@dashboard/hooks/useNotifier";
import { getDefaultNotifierSuccessErrorData } from "@dashboard/hooks/useNotifier/utils";
import useShop from "@dashboard/hooks/useShop";
import { commonMessages } from "@dashboard/intl";
import { extractMutationErrors } from "@dashboard/misc";
import getChannelsErrorMessage from "@dashboard/utils/errors/channels";
import currencyCodes from "currency-codes";
@ -25,7 +25,7 @@ import { calculateItemsOrderMoves } from "../ChannelDetails/handlers";
import { useShippingZones } from "../ChannelDetails/useShippingZones";
import { useWarehouses } from "../ChannelDetails/useWarehouses";
export const ChannelCreateView = ({}) => {
export const ChannelCreateView = () => {
const navigate = useNavigator();
const notify = useNotifier();
const intl = useIntl();
@ -40,7 +40,12 @@ export const ChannelCreateView = ({}) => {
const [createChannel, createChannelOpts] = useChannelCreateMutation({
onCompleted: ({ channelCreate: { errors } }: ChannelCreateMutation) => {
notify(getDefaultNotifierSuccessErrorData(errors, intl));
if (!errors.length) {
notify({
status: "success",
text: intl.formatMessage(commonMessages.savedChanges),
});
}
},
});
@ -66,6 +71,7 @@ export const ChannelCreateView = ({}) => {
slug,
defaultCountry,
markAsPaidStrategy,
deleteExpiredOrdersAfter,
}: FormData) => {
const input: ChannelCreateInput = {
defaultCountry,
@ -79,6 +85,7 @@ export const ChannelCreateView = ({}) => {
},
orderSettings: {
markAsPaidStrategy,
deleteExpiredOrdersAfter,
},
};

View file

@ -116,6 +116,7 @@ export const ChannelDetails: React.FC<ChannelDetailsProps> = ({
defaultCountry,
allocationStrategy,
markAsPaidStrategy,
deleteExpiredOrdersAfter,
}: FormData) => {
const updateChannelMutation = updateChannel({
variables: {
@ -133,6 +134,7 @@ export const ChannelDetails: React.FC<ChannelDetailsProps> = ({
},
orderSettings: {
markAsPaidStrategy,
deleteExpiredOrdersAfter,
},
},
},

View file

@ -34,6 +34,7 @@ export const channelDetailsFragment = gql`
}
orderSettings {
markAsPaidStrategy
deleteExpiredOrdersAfter
}
}
`;

View file

@ -254,6 +254,7 @@ export const ChannelDetailsFragmentDoc = gql`
}
orderSettings {
markAsPaidStrategy
deleteExpiredOrdersAfter
}
}
${ChannelFragmentDoc}

View file

@ -8255,7 +8255,7 @@ export type ChannelCreateMutationVariables = Exact<{
}>;
export type ChannelCreateMutation = { __typename: 'Mutation', channelCreate: { __typename: 'ChannelCreate', channel: { __typename: 'Channel', hasOrders: boolean, id: string, isActive: boolean, name: string, slug: string, currencyCode: string, warehouses: Array<{ __typename: 'Warehouse', id: string, name: string }>, orderSettings: { __typename: 'OrderSettings', markAsPaidStrategy: MarkAsPaidStrategyEnum }, defaultCountry: { __typename: 'CountryDisplay', code: string, country: string }, stockSettings: { __typename: 'StockSettings', allocationStrategy: AllocationStrategyEnum } } | null, errors: Array<{ __typename: 'ChannelError', code: ChannelErrorCode, field: string | null, message: string | null }> } | null };
export type ChannelCreateMutation = { __typename: 'Mutation', channelCreate: { __typename: 'ChannelCreate', channel: { __typename: 'Channel', hasOrders: boolean, id: string, isActive: boolean, name: string, slug: string, currencyCode: string, warehouses: Array<{ __typename: 'Warehouse', id: string, name: string }>, orderSettings: { __typename: 'OrderSettings', markAsPaidStrategy: MarkAsPaidStrategyEnum, deleteExpiredOrdersAfter: any }, defaultCountry: { __typename: 'CountryDisplay', code: string, country: string }, stockSettings: { __typename: 'StockSettings', allocationStrategy: AllocationStrategyEnum } } | null, errors: Array<{ __typename: 'ChannelError', code: ChannelErrorCode, field: string | null, message: string | null }> } | null };
export type ChannelUpdateMutationVariables = Exact<{
id: Scalars['ID'];
@ -8263,7 +8263,7 @@ export type ChannelUpdateMutationVariables = Exact<{
}>;
export type ChannelUpdateMutation = { __typename: 'Mutation', channelUpdate: { __typename: 'ChannelUpdate', channel: { __typename: 'Channel', hasOrders: boolean, id: string, isActive: boolean, name: string, slug: string, currencyCode: string, warehouses: Array<{ __typename: 'Warehouse', id: string, name: string }>, orderSettings: { __typename: 'OrderSettings', markAsPaidStrategy: MarkAsPaidStrategyEnum }, defaultCountry: { __typename: 'CountryDisplay', code: string, country: string }, stockSettings: { __typename: 'StockSettings', allocationStrategy: AllocationStrategyEnum } } | null, errors: Array<{ __typename: 'ChannelError', code: ChannelErrorCode, field: string | null, message: string | null }> } | null };
export type ChannelUpdateMutation = { __typename: 'Mutation', channelUpdate: { __typename: 'ChannelUpdate', channel: { __typename: 'Channel', hasOrders: boolean, id: string, isActive: boolean, name: string, slug: string, currencyCode: string, warehouses: Array<{ __typename: 'Warehouse', id: string, name: string }>, orderSettings: { __typename: 'OrderSettings', markAsPaidStrategy: MarkAsPaidStrategyEnum, deleteExpiredOrdersAfter: any }, defaultCountry: { __typename: 'CountryDisplay', code: string, country: string }, stockSettings: { __typename: 'StockSettings', allocationStrategy: AllocationStrategyEnum } } | null, errors: Array<{ __typename: 'ChannelError', code: ChannelErrorCode, field: string | null, message: string | null }> } | null };
export type ChannelDeleteMutationVariables = Exact<{
id: Scalars['ID'];
@ -8278,14 +8278,14 @@ export type ChannelActivateMutationVariables = Exact<{
}>;
export type ChannelActivateMutation = { __typename: 'Mutation', channelActivate: { __typename: 'ChannelActivate', channel: { __typename: 'Channel', hasOrders: boolean, id: string, isActive: boolean, name: string, slug: string, currencyCode: string, warehouses: Array<{ __typename: 'Warehouse', id: string, name: string }>, orderSettings: { __typename: 'OrderSettings', markAsPaidStrategy: MarkAsPaidStrategyEnum }, defaultCountry: { __typename: 'CountryDisplay', code: string, country: string }, stockSettings: { __typename: 'StockSettings', allocationStrategy: AllocationStrategyEnum } } | null, errors: Array<{ __typename: 'ChannelError', code: ChannelErrorCode, field: string | null, message: string | null }> } | null };
export type ChannelActivateMutation = { __typename: 'Mutation', channelActivate: { __typename: 'ChannelActivate', channel: { __typename: 'Channel', hasOrders: boolean, id: string, isActive: boolean, name: string, slug: string, currencyCode: string, warehouses: Array<{ __typename: 'Warehouse', id: string, name: string }>, orderSettings: { __typename: 'OrderSettings', markAsPaidStrategy: MarkAsPaidStrategyEnum, deleteExpiredOrdersAfter: any }, defaultCountry: { __typename: 'CountryDisplay', code: string, country: string }, stockSettings: { __typename: 'StockSettings', allocationStrategy: AllocationStrategyEnum } } | null, errors: Array<{ __typename: 'ChannelError', code: ChannelErrorCode, field: string | null, message: string | null }> } | null };
export type ChannelDeactivateMutationVariables = Exact<{
id: Scalars['ID'];
}>;
export type ChannelDeactivateMutation = { __typename: 'Mutation', channelDeactivate: { __typename: 'ChannelDeactivate', channel: { __typename: 'Channel', hasOrders: boolean, id: string, isActive: boolean, name: string, slug: string, currencyCode: string, warehouses: Array<{ __typename: 'Warehouse', id: string, name: string }>, orderSettings: { __typename: 'OrderSettings', markAsPaidStrategy: MarkAsPaidStrategyEnum }, defaultCountry: { __typename: 'CountryDisplay', code: string, country: string }, stockSettings: { __typename: 'StockSettings', allocationStrategy: AllocationStrategyEnum } } | null, errors: Array<{ __typename: 'ChannelError', code: ChannelErrorCode, field: string | null, message: string | null }> } | null };
export type ChannelDeactivateMutation = { __typename: 'Mutation', channelDeactivate: { __typename: 'ChannelDeactivate', channel: { __typename: 'Channel', hasOrders: boolean, id: string, isActive: boolean, name: string, slug: string, currencyCode: string, warehouses: Array<{ __typename: 'Warehouse', id: string, name: string }>, orderSettings: { __typename: 'OrderSettings', markAsPaidStrategy: MarkAsPaidStrategyEnum, deleteExpiredOrdersAfter: any }, defaultCountry: { __typename: 'CountryDisplay', code: string, country: string }, stockSettings: { __typename: 'StockSettings', allocationStrategy: AllocationStrategyEnum } } | null, errors: Array<{ __typename: 'ChannelError', code: ChannelErrorCode, field: string | null, message: string | null }> } | null };
export type ChannelReorderWarehousesMutationVariables = Exact<{
channelId: Scalars['ID'];
@ -8293,7 +8293,7 @@ export type ChannelReorderWarehousesMutationVariables = Exact<{
}>;
export type ChannelReorderWarehousesMutation = { __typename: 'Mutation', channelReorderWarehouses: { __typename: 'ChannelReorderWarehouses', channel: { __typename: 'Channel', hasOrders: boolean, id: string, isActive: boolean, name: string, slug: string, currencyCode: string, warehouses: Array<{ __typename: 'Warehouse', id: string, name: string }>, orderSettings: { __typename: 'OrderSettings', markAsPaidStrategy: MarkAsPaidStrategyEnum }, defaultCountry: { __typename: 'CountryDisplay', code: string, country: string }, stockSettings: { __typename: 'StockSettings', allocationStrategy: AllocationStrategyEnum } } | null, errors: Array<{ __typename: 'ChannelError', code: ChannelErrorCode, field: string | null, message: string | null }> } | null };
export type ChannelReorderWarehousesMutation = { __typename: 'Mutation', channelReorderWarehouses: { __typename: 'ChannelReorderWarehouses', channel: { __typename: 'Channel', hasOrders: boolean, id: string, isActive: boolean, name: string, slug: string, currencyCode: string, warehouses: Array<{ __typename: 'Warehouse', id: string, name: string }>, orderSettings: { __typename: 'OrderSettings', markAsPaidStrategy: MarkAsPaidStrategyEnum, deleteExpiredOrdersAfter: any }, defaultCountry: { __typename: 'CountryDisplay', code: string, country: string }, stockSettings: { __typename: 'StockSettings', allocationStrategy: AllocationStrategyEnum } } | null, errors: Array<{ __typename: 'ChannelError', code: ChannelErrorCode, field: string | null, message: string | null }> } | null };
export type BaseChannelsQueryVariables = Exact<{ [key: string]: never; }>;
@ -8303,14 +8303,14 @@ export type BaseChannelsQuery = { __typename: 'Query', channels: Array<{ __typen
export type ChannelsQueryVariables = Exact<{ [key: string]: never; }>;
export type ChannelsQuery = { __typename: 'Query', channels: Array<{ __typename: 'Channel', hasOrders: boolean, id: string, isActive: boolean, name: string, slug: string, currencyCode: string, warehouses: Array<{ __typename: 'Warehouse', id: string, name: string }>, orderSettings: { __typename: 'OrderSettings', markAsPaidStrategy: MarkAsPaidStrategyEnum }, defaultCountry: { __typename: 'CountryDisplay', code: string, country: string }, stockSettings: { __typename: 'StockSettings', allocationStrategy: AllocationStrategyEnum } }> | null };
export type ChannelsQuery = { __typename: 'Query', channels: Array<{ __typename: 'Channel', hasOrders: boolean, id: string, isActive: boolean, name: string, slug: string, currencyCode: string, warehouses: Array<{ __typename: 'Warehouse', id: string, name: string }>, orderSettings: { __typename: 'OrderSettings', markAsPaidStrategy: MarkAsPaidStrategyEnum, deleteExpiredOrdersAfter: any }, defaultCountry: { __typename: 'CountryDisplay', code: string, country: string }, stockSettings: { __typename: 'StockSettings', allocationStrategy: AllocationStrategyEnum } }> | null };
export type ChannelQueryVariables = Exact<{
id: Scalars['ID'];
}>;
export type ChannelQuery = { __typename: 'Query', channel: { __typename: 'Channel', hasOrders: boolean, id: string, isActive: boolean, name: string, slug: string, currencyCode: string, warehouses: Array<{ __typename: 'Warehouse', id: string, name: string }>, orderSettings: { __typename: 'OrderSettings', markAsPaidStrategy: MarkAsPaidStrategyEnum }, defaultCountry: { __typename: 'CountryDisplay', code: string, country: string }, stockSettings: { __typename: 'StockSettings', allocationStrategy: AllocationStrategyEnum } } | null };
export type ChannelQuery = { __typename: 'Query', channel: { __typename: 'Channel', hasOrders: boolean, id: string, isActive: boolean, name: string, slug: string, currencyCode: string, warehouses: Array<{ __typename: 'Warehouse', id: string, name: string }>, orderSettings: { __typename: 'OrderSettings', markAsPaidStrategy: MarkAsPaidStrategyEnum, deleteExpiredOrdersAfter: any }, defaultCountry: { __typename: 'CountryDisplay', code: string, country: string }, stockSettings: { __typename: 'StockSettings', allocationStrategy: AllocationStrategyEnum } } | null };
export type CollectionUpdateMutationVariables = Exact<{
id: Scalars['ID'];
@ -8924,7 +8924,7 @@ export type ChannelErrorFragment = { __typename: 'ChannelError', code: ChannelEr
export type ChannelFragment = { __typename: 'Channel', id: string, isActive: boolean, name: string, slug: string, currencyCode: string, defaultCountry: { __typename: 'CountryDisplay', code: string, country: string }, stockSettings: { __typename: 'StockSettings', allocationStrategy: AllocationStrategyEnum } };
export type ChannelDetailsFragment = { __typename: 'Channel', hasOrders: boolean, id: string, isActive: boolean, name: string, slug: string, currencyCode: string, warehouses: Array<{ __typename: 'Warehouse', id: string, name: string }>, orderSettings: { __typename: 'OrderSettings', markAsPaidStrategy: MarkAsPaidStrategyEnum }, defaultCountry: { __typename: 'CountryDisplay', code: string, country: string }, stockSettings: { __typename: 'StockSettings', allocationStrategy: AllocationStrategyEnum } };
export type ChannelDetailsFragment = { __typename: 'Channel', hasOrders: boolean, id: string, isActive: boolean, name: string, slug: string, currencyCode: string, warehouses: Array<{ __typename: 'Warehouse', id: string, name: string }>, orderSettings: { __typename: 'OrderSettings', markAsPaidStrategy: MarkAsPaidStrategyEnum, deleteExpiredOrdersAfter: any }, defaultCountry: { __typename: 'CountryDisplay', code: string, country: string }, stockSettings: { __typename: 'StockSettings', allocationStrategy: AllocationStrategyEnum } };
export type CollectionFragment = { __typename: 'Collection', id: string, name: string, channelListings: Array<{ __typename: 'CollectionChannelListing', isPublished: boolean, publicationDate: any | null, channel: { __typename: 'Channel', id: string, name: string } }> | null };