Pass promise to reset form state

This commit is contained in:
dominik-zeglen 2020-10-22 13:33:29 +02:00
parent dfb2258406
commit a27a029452
47 changed files with 484 additions and 432 deletions

View file

@ -42,7 +42,7 @@ export interface CustomAppDetailsPageProps {
onTokenDelete: (id: string) => void; onTokenDelete: (id: string) => void;
onTokenClose: () => void; onTokenClose: () => void;
onTokenCreate: () => void; onTokenCreate: () => void;
onSubmit: (data: CustomAppDetailsPageFormData) => void; onSubmit: (data: CustomAppDetailsPageFormData) => Promise<any>;
onWebhookCreate: () => void; onWebhookCreate: () => void;
onWebhookRemove: (id: string) => void; onWebhookRemove: (id: string) => void;
navigateToWebhookDetails: (id: string) => () => void; navigateToWebhookDetails: (id: string) => () => void;

View file

@ -130,8 +130,8 @@ export const CustomAppDetails: React.FC<OrderListProps> = ({
onCompleted: onTokenDelete onCompleted: onTokenDelete
}); });
const handleSubmit = (data: CustomAppDetailsPageFormData) => const handleSubmit = async (data: CustomAppDetailsPageFormData) => {
updateApp({ const result = await updateApp({
variables: { variables: {
id, id,
input: { input: {
@ -144,6 +144,9 @@ export const CustomAppDetails: React.FC<OrderListProps> = ({
} }
}); });
return result.data.appUpdate.errors;
};
const handleTokenCreate = (name: string) => const handleTokenCreate = (name: string) =>
createToken({ createToken({
variables: { variables: {

View file

@ -126,7 +126,7 @@ const AttributePage: React.FC<AttributePageProps> = ({
? data.privateMetadata ? data.privateMetadata
: undefined; : undefined;
onSubmit({ return onSubmit({
...data, ...data,
metadata, metadata,
privateMetadata, privateMetadata,

View file

@ -61,7 +61,7 @@ export interface CategoryUpdatePageProps
}; };
saveButtonBarState: ConfirmButtonTransitionState; saveButtonBarState: ConfirmButtonTransitionState;
onImageDelete: () => void; onImageDelete: () => void;
onSubmit: (data: FormData) => void; onSubmit: (data: FormData) => Promise<any[]>;
onImageUpload(file: File); onImageUpload(file: File);
onNextPage(); onNextPage();
onPreviousPage(); onPreviousPage();
@ -139,7 +139,7 @@ export const CategoryUpdatePage: React.FC<CategoryUpdatePageProps> = ({
? data.privateMetadata ? data.privateMetadata
: undefined; : undefined;
onSubmit({ return onSubmit({
...data, ...data,
metadata, metadata,
privateMetadata privateMetadata

View file

@ -81,7 +81,7 @@ const CollectionDetailsPage: React.FC<CollectionDetailsPageProps> = ({
? data.privateMetadata ? data.privateMetadata
: undefined; : undefined;
onSubmit({ return onSubmit({
...data, ...data,
isPublished: data.isPublished || !!data.publicationDate, isPublished: data.isPublished || !!data.publicationDate,
metadata, metadata,

View file

@ -33,7 +33,7 @@ export interface CustomerDetailsPageProps {
errors: AccountErrorFragment[]; errors: AccountErrorFragment[];
saveButtonBar: ConfirmButtonTransitionState; saveButtonBar: ConfirmButtonTransitionState;
onBack: () => void; onBack: () => void;
onSubmit: (data: CustomerDetailsPageFormData) => void; onSubmit: (data: CustomerDetailsPageFormData) => Promise<any[]>;
onViewAllOrdersClick: () => void; onViewAllOrdersClick: () => void;
onRowClick: (id: string) => void; onRowClick: (id: string) => void;
onAddressManageClick: () => void; onAddressManageClick: () => void;

View file

@ -10,7 +10,9 @@ import { FormattedMessage, useIntl } from "react-intl";
import { maybe } from "../../misc"; import { maybe } from "../../misc";
import { orderListUrl, orderUrl } from "../../orders/urls"; import { orderListUrl, orderUrl } from "../../orders/urls";
import CustomerDetailsPage from "../components/CustomerDetailsPage/CustomerDetailsPage"; import CustomerDetailsPage, {
CustomerDetailsPageFormData
} from "../components/CustomerDetailsPage/CustomerDetailsPage";
import { import {
TypedRemoveCustomerMutation, TypedRemoveCustomerMutation,
TypedUpdateCustomerMutation TypedUpdateCustomerMutation
@ -76,6 +78,25 @@ export const CustomerDetailsView: React.FC<CustomerDetailsViewProps> = ({
return <NotFoundPage onBack={handleBack} />; return <NotFoundPage onBack={handleBack} />;
} }
const handleSubmit = async (
data: CustomerDetailsPageFormData
) => {
const result = await updateCustomer({
variables: {
id,
input: {
email: data.email,
firstName: data.firstName,
isActive: data.isActive,
lastName: data.lastName,
note: data.note
}
}
});
return result.data.customerUpdate.errors;
};
return ( return (
<> <>
<WindowTitle <WindowTitle
@ -97,20 +118,7 @@ export const CustomerDetailsView: React.FC<CustomerDetailsViewProps> = ({
} }
onBack={handleBack} onBack={handleBack}
onRowClick={id => navigate(orderUrl(id))} onRowClick={id => navigate(orderUrl(id))}
onSubmit={formData => onSubmit={handleSubmit}
updateCustomer({
variables: {
id,
input: {
email: formData.email,
firstName: formData.firstName,
isActive: formData.isActive,
lastName: formData.lastName,
note: formData.note
}
}
})
}
onDelete={() => onDelete={() =>
navigate( navigate(
customerUrl(id, { customerUrl(id, {

View file

@ -25,7 +25,7 @@ import SaleSummary from "../SaleSummary";
import SaleType from "../SaleType"; import SaleType from "../SaleType";
import SaleValue from "../SaleValue"; import SaleValue from "../SaleValue";
export interface FormData { export interface SaleDetailsPageFormData {
endDate: string; endDate: string;
endTime: string; endTime: string;
hasEndDate: boolean; hasEndDate: boolean;
@ -70,7 +70,7 @@ export interface SaleDetailsPageProps
onProductUnassign: (id: string) => void; onProductUnassign: (id: string) => void;
onProductClick: (id: string) => () => void; onProductClick: (id: string) => () => void;
onRemove: () => void; onRemove: () => void;
onSubmit: (data: FormData) => void; onSubmit: (data: SaleDetailsPageFormData) => void;
onTabClick: (index: SaleDetailsPageTab) => void; onTabClick: (index: SaleDetailsPageTab) => void;
} }
@ -111,7 +111,7 @@ const SaleDetailsPage: React.FC<SaleDetailsPageProps> = ({
}) => { }) => {
const intl = useIntl(); const intl = useIntl();
const initialForm: FormData = { const initialForm: SaleDetailsPageFormData = {
endDate: splitDateTime(maybe(() => sale.endDate, "")).date, endDate: splitDateTime(maybe(() => sale.endDate, "")).date,
endTime: splitDateTime(maybe(() => sale.endDate, "")).time, endTime: splitDateTime(maybe(() => sale.endDate, "")).time,
hasEndDate: maybe(() => !!sale.endDate), hasEndDate: maybe(() => !!sale.endDate),

View file

@ -9,10 +9,10 @@ import getDiscountErrorMessage from "@saleor/utils/errors/discounts";
import React from "react"; import React from "react";
import { useIntl } from "react-intl"; import { useIntl } from "react-intl";
import { FormData } from "../SaleDetailsPage"; import { SaleDetailsPageFormData } from "../SaleDetailsPage";
export interface SaleInfoProps { export interface SaleInfoProps {
data: FormData; data: SaleDetailsPageFormData;
disabled: boolean; disabled: boolean;
errors: DiscountErrorFragment[]; errors: DiscountErrorFragment[];
onChange: (event: React.ChangeEvent<any>) => void; onChange: (event: React.ChangeEvent<any>) => void;
@ -38,7 +38,7 @@ const SaleInfo: React.FC<SaleInfoProps> = ({
disabled={disabled} disabled={disabled}
error={!!formErrors.name} error={!!formErrors.name}
helperText={getDiscountErrorMessage(formErrors.name, intl)} helperText={getDiscountErrorMessage(formErrors.name, intl)}
name={"name" as keyof FormData} name={"name" as keyof SaleDetailsPageFormData}
onChange={onChange} onChange={onChange}
label={intl.formatMessage({ label={intl.formatMessage({
defaultMessage: "Name", defaultMessage: "Name",

View file

@ -10,10 +10,10 @@ import { SaleType as SaleTypeEnum } from "@saleor/types/globalTypes";
import React from "react"; import React from "react";
import { IntlShape, useIntl } from "react-intl"; import { IntlShape, useIntl } from "react-intl";
import { FormData } from "../SaleDetailsPage"; import { SaleDetailsPageFormData } from "../SaleDetailsPage";
export interface SaleTypeProps { export interface SaleTypeProps {
data: FormData; data: SaleDetailsPageFormData;
disabled: boolean; disabled: boolean;
onChange: FormChange; onChange: FormChange;
} }
@ -70,7 +70,7 @@ const SaleType: React.FC<SaleTypeProps> = props => {
<RadioGroupField <RadioGroupField
choices={choices} choices={choices}
disabled={disabled} disabled={disabled}
name={"type" as keyof FormData} name={"type" as keyof SaleDetailsPageFormData}
value={data.type} value={data.type}
onChange={onChange} onChange={onChange}
/> />

View file

@ -10,11 +10,11 @@ import getDiscountErrorMessage from "@saleor/utils/errors/discounts";
import React from "react"; import React from "react";
import { useIntl } from "react-intl"; import { useIntl } from "react-intl";
import { FormData } from "../SaleDetailsPage"; import { SaleDetailsPageFormData } from "../SaleDetailsPage";
export interface SaleValueProps { export interface SaleValueProps {
currencySymbol: string; currencySymbol: string;
data: FormData; data: SaleDetailsPageFormData;
disabled: boolean; disabled: boolean;
errors: DiscountErrorFragment[]; errors: DiscountErrorFragment[];
onChange: FormChange; onChange: FormChange;

View file

@ -11,10 +11,10 @@ import getDiscountErrorMessage from "@saleor/utils/errors/discounts";
import React from "react"; import React from "react";
import { useIntl } from "react-intl"; import { useIntl } from "react-intl";
import { FormData } from "../VoucherDetailsPage"; import { VoucherDetailsPageFormData } from "../VoucherDetailsPage";
interface VoucherDatesProps { interface VoucherDatesProps {
data: FormData; data: VoucherDetailsPageFormData;
defaultCurrency: string; defaultCurrency: string;
disabled: boolean; disabled: boolean;
errors: DiscountErrorFragment[]; errors: DiscountErrorFragment[];
@ -45,7 +45,7 @@ const VoucherDates = ({
disabled={disabled} disabled={disabled}
error={!!formErrors.startDate} error={!!formErrors.startDate}
helperText={getDiscountErrorMessage(formErrors.startDate, intl)} helperText={getDiscountErrorMessage(formErrors.startDate, intl)}
name={"startDate" as keyof FormData} name={"startDate" as keyof VoucherDetailsPageFormData}
onChange={onChange} onChange={onChange}
label={intl.formatMessage(commonMessages.startDate)} label={intl.formatMessage(commonMessages.startDate)}
value={data.startDate} value={data.startDate}
@ -59,7 +59,7 @@ const VoucherDates = ({
disabled={disabled} disabled={disabled}
error={!!formErrors.startDate} error={!!formErrors.startDate}
helperText={getDiscountErrorMessage(formErrors.startDate, intl)} helperText={getDiscountErrorMessage(formErrors.startDate, intl)}
name={"startTime" as keyof FormData} name={"startTime" as keyof VoucherDetailsPageFormData}
onChange={onChange} onChange={onChange}
label={intl.formatMessage(commonMessages.startHour)} label={intl.formatMessage(commonMessages.startHour)}
value={data.startTime} value={data.startTime}
@ -76,7 +76,7 @@ const VoucherDates = ({
defaultMessage: "Set end date", defaultMessage: "Set end date",
description: "voucher end date, switch button" description: "voucher end date, switch button"
})} })}
name={"hasEndDate" as keyof FormData} name={"hasEndDate" as keyof VoucherDetailsPageFormData}
onChange={onChange} onChange={onChange}
/> />
{data.hasEndDate && ( {data.hasEndDate && (
@ -85,7 +85,7 @@ const VoucherDates = ({
disabled={disabled} disabled={disabled}
error={!!formErrors.endDate} error={!!formErrors.endDate}
helperText={getDiscountErrorMessage(formErrors.endDate, intl)} helperText={getDiscountErrorMessage(formErrors.endDate, intl)}
name={"endDate" as keyof FormData} name={"endDate" as keyof VoucherDetailsPageFormData}
onChange={onChange} onChange={onChange}
label={intl.formatMessage(commonMessages.endDate)} label={intl.formatMessage(commonMessages.endDate)}
value={data.endDate} value={data.endDate}
@ -99,7 +99,7 @@ const VoucherDates = ({
disabled={disabled} disabled={disabled}
error={!!formErrors.endDate} error={!!formErrors.endDate}
helperText={getDiscountErrorMessage(formErrors.endDate, intl)} helperText={getDiscountErrorMessage(formErrors.endDate, intl)}
name={"endTime" as keyof FormData} name={"endTime" as keyof VoucherDetailsPageFormData}
onChange={onChange} onChange={onChange}
label={intl.formatMessage(commonMessages.endHour)} label={intl.formatMessage(commonMessages.endHour)}
value={data.endTime} value={data.endTime}

View file

@ -47,7 +47,7 @@ export function voucherDetailsPageTab(tab: string): VoucherDetailsPageTab {
: VoucherDetailsPageTab.categories; : VoucherDetailsPageTab.categories;
} }
export interface FormData { export interface VoucherDetailsPageFormData {
applyOncePerCustomer: boolean; applyOncePerCustomer: boolean;
applyOncePerOrder: boolean; applyOncePerOrder: boolean;
code: string; code: string;
@ -89,7 +89,7 @@ export interface VoucherDetailsPageProps
onProductUnassign: (id: string) => void; onProductUnassign: (id: string) => void;
onProductClick: (id: string) => () => void; onProductClick: (id: string) => () => void;
onRemove: () => void; onRemove: () => void;
onSubmit: (data: FormData) => void; onSubmit: (data: VoucherDetailsPageFormData) => void;
onTabClick: (index: VoucherDetailsPageTab) => void; onTabClick: (index: VoucherDetailsPageTab) => void;
} }
@ -141,7 +141,7 @@ const VoucherDetailsPage: React.FC<VoucherDetailsPageProps> = ({
requirementsPickerInitValue = RequirementsPicker.NONE; requirementsPickerInitValue = RequirementsPicker.NONE;
} }
const initialForm: FormData = { const initialForm: VoucherDetailsPageFormData = {
applyOncePerCustomer: maybe(() => voucher.applyOncePerCustomer, false), applyOncePerCustomer: maybe(() => voucher.applyOncePerCustomer, false),
applyOncePerOrder: maybe(() => voucher.applyOncePerOrder, false), applyOncePerOrder: maybe(() => voucher.applyOncePerOrder, false),
code: maybe(() => voucher.code, ""), code: maybe(() => voucher.code, ""),

View file

@ -11,10 +11,10 @@ import React from "react";
import { FormattedMessage, useIntl } from "react-intl"; import { FormattedMessage, useIntl } from "react-intl";
import { generateCode } from "../../../misc"; import { generateCode } from "../../../misc";
import { FormData } from "../VoucherDetailsPage"; import { VoucherDetailsPageFormData } from "../VoucherDetailsPage";
interface VoucherInfoProps { interface VoucherInfoProps {
data: FormData; data: VoucherDetailsPageFormData;
errors: DiscountErrorFragment[]; errors: DiscountErrorFragment[];
disabled: boolean; disabled: boolean;
variant: "create" | "update"; variant: "create" | "update";
@ -61,7 +61,7 @@ const VoucherInfo = ({
error={!!formErrors.code} error={!!formErrors.code}
fullWidth fullWidth
helperText={getDiscountErrorMessage(formErrors.code, intl)} helperText={getDiscountErrorMessage(formErrors.code, intl)}
name={"code" as keyof FormData} name={"code" as keyof VoucherDetailsPageFormData}
label={intl.formatMessage({ label={intl.formatMessage({
defaultMessage: "Discount Code" defaultMessage: "Discount Code"
})} })}

View file

@ -9,10 +9,10 @@ import getDiscountErrorMessage from "@saleor/utils/errors/discounts";
import React from "react"; import React from "react";
import { useIntl } from "react-intl"; import { useIntl } from "react-intl";
import { FormData } from "../VoucherDetailsPage"; import { VoucherDetailsPageFormData } from "../VoucherDetailsPage";
interface VoucherLimitsProps { interface VoucherLimitsProps {
data: FormData; data: VoucherDetailsPageFormData;
defaultCurrency: string; defaultCurrency: string;
disabled: boolean; disabled: boolean;
errors: DiscountErrorFragment[]; errors: DiscountErrorFragment[];
@ -44,7 +44,7 @@ const VoucherLimits = ({
defaultMessage: defaultMessage:
"Limit number of times this discount can be used in total" "Limit number of times this discount can be used in total"
})} })}
name={"hasUsageLimit" as keyof FormData} name={"hasUsageLimit" as keyof VoucherDetailsPageFormData}
onChange={onChange} onChange={onChange}
/> />
{data.hasUsageLimit && ( {data.hasUsageLimit && (
@ -56,7 +56,7 @@ const VoucherLimits = ({
defaultMessage: "Limit of Uses", defaultMessage: "Limit of Uses",
description: "voucher" description: "voucher"
})} })}
name={"usageLimit" as keyof FormData} name={"usageLimit" as keyof VoucherDetailsPageFormData}
value={data.usageLimit} value={data.usageLimit}
onChange={onChange} onChange={onChange}
type="number" type="number"
@ -72,7 +72,7 @@ const VoucherLimits = ({
defaultMessage: "Limit to one use per customer", defaultMessage: "Limit to one use per customer",
description: "limit voucher" description: "limit voucher"
})} })}
name={"applyOncePerCustomer" as keyof FormData} name={"applyOncePerCustomer" as keyof VoucherDetailsPageFormData}
onChange={onChange} onChange={onChange}
/> />
</CardContent> </CardContent>

View file

@ -11,10 +11,10 @@ import getDiscountErrorMessage from "@saleor/utils/errors/discounts";
import React from "react"; import React from "react";
import { useIntl } from "react-intl"; import { useIntl } from "react-intl";
import { FormData } from "../VoucherDetailsPage"; import { VoucherDetailsPageFormData } from "../VoucherDetailsPage";
interface VoucherRequirementsProps { interface VoucherRequirementsProps {
data: FormData; data: VoucherDetailsPageFormData;
defaultCurrency: string; defaultCurrency: string;
disabled: boolean; disabled: boolean;
errors: DiscountErrorFragment[]; errors: DiscountErrorFragment[];
@ -73,7 +73,7 @@ const VoucherRequirements = ({
<RadioGroupField <RadioGroupField
choices={requirementsPickerChoices} choices={requirementsPickerChoices}
disabled={disabled} disabled={disabled}
name={"requirementsPicker" as keyof FormData} name={"requirementsPicker" as keyof VoucherDetailsPageFormData}
value={data.requirementsPicker} value={data.requirementsPicker}
onChange={onChange} onChange={onChange}
/> />
@ -86,7 +86,7 @@ const VoucherRequirements = ({
error={!!formErrors.minSpent} error={!!formErrors.minSpent}
helperText={getDiscountErrorMessage(formErrors.minSpent, intl)} helperText={getDiscountErrorMessage(formErrors.minSpent, intl)}
label={minimalOrderValueText} label={minimalOrderValueText}
name={"minSpent" as keyof FormData} name={"minSpent" as keyof VoucherDetailsPageFormData}
value={data.minSpent} value={data.minSpent}
onChange={onChange} onChange={onChange}
fullWidth fullWidth
@ -100,7 +100,9 @@ const VoucherRequirements = ({
intl intl
)} )}
label={minimalQuantityText} label={minimalQuantityText}
name={"minCheckoutItemsQuantity" as keyof FormData} name={
"minCheckoutItemsQuantity" as keyof VoucherDetailsPageFormData
}
value={data.minCheckoutItemsQuantity} value={data.minCheckoutItemsQuantity}
onChange={onChange} onChange={onChange}
fullWidth fullWidth

View file

@ -10,10 +10,10 @@ import React from "react";
import { useIntl } from "react-intl"; import { useIntl } from "react-intl";
import { DiscountValueTypeEnum } from "../../../types/globalTypes"; import { DiscountValueTypeEnum } from "../../../types/globalTypes";
import { FormData } from "../VoucherDetailsPage"; import { VoucherDetailsPageFormData } from "../VoucherDetailsPage";
interface VoucherTypesProps { interface VoucherTypesProps {
data: FormData; data: VoucherDetailsPageFormData;
errors: DiscountErrorFragment[]; errors: DiscountErrorFragment[];
disabled: boolean; disabled: boolean;
onChange: (event: React.ChangeEvent<any>) => void; onChange: (event: React.ChangeEvent<any>) => void;
@ -68,7 +68,7 @@ const VoucherTypes = ({
disabled={disabled} disabled={disabled}
error={!!formErrors.discountType} error={!!formErrors.discountType}
hint={getDiscountErrorMessage(formErrors.discountType, intl)} hint={getDiscountErrorMessage(formErrors.discountType, intl)}
name={"discountType" as keyof FormData} name={"discountType" as keyof VoucherDetailsPageFormData}
value={data.discountType} value={data.discountType}
onChange={onChange} onChange={onChange}
/> />

View file

@ -16,10 +16,10 @@ import { FormattedMessage, useIntl } from "react-intl";
import { DiscountValueTypeEnum } from "../../../types/globalTypes"; import { DiscountValueTypeEnum } from "../../../types/globalTypes";
import { translateVoucherTypes } from "../../translations"; import { translateVoucherTypes } from "../../translations";
import { FormData } from "../VoucherDetailsPage"; import { VoucherDetailsPageFormData } from "../VoucherDetailsPage";
interface VoucherValueProps { interface VoucherValueProps {
data: FormData; data: VoucherDetailsPageFormData;
defaultCurrency: string; defaultCurrency: string;
errors: DiscountErrorFragment[]; errors: DiscountErrorFragment[];
disabled: boolean; disabled: boolean;
@ -74,11 +74,11 @@ const VoucherValue: React.FC<VoucherValueProps> = props => {
data.discountType === DiscountValueTypeEnum.FIXED data.discountType === DiscountValueTypeEnum.FIXED
? defaultCurrency ? defaultCurrency
: "%", : "%",
name: "discountType" as keyof FormData, name: "discountType" as keyof VoucherDetailsPageFormData,
values: null values: null
}} }}
helperText={getDiscountErrorMessage(formErrors.discountValue, intl)} helperText={getDiscountErrorMessage(formErrors.discountValue, intl)}
name={"value" as keyof FormData} name={"value" as keyof VoucherDetailsPageFormData}
onChange={onChange} onChange={onChange}
label={intl.formatMessage({ label={intl.formatMessage({
defaultMessage: "Discount Value" defaultMessage: "Discount Value"
@ -102,7 +102,7 @@ const VoucherValue: React.FC<VoucherValueProps> = props => {
label={intl.formatMessage({ label={intl.formatMessage({
defaultMessage: "Voucher Specific Information" defaultMessage: "Voucher Specific Information"
})} })}
name={"type" as keyof FormData} name={"type" as keyof VoucherDetailsPageFormData}
value={data.type} value={data.type}
onChange={onChange} onChange={onChange}
/> />
@ -111,7 +111,7 @@ const VoucherValue: React.FC<VoucherValueProps> = props => {
<Hr className={classes.hr} /> <Hr className={classes.hr} />
<FormSpacer /> <FormSpacer />
<ControlledCheckbox <ControlledCheckbox
name={"applyOncePerOrder" as keyof FormData} name={"applyOncePerOrder" as keyof VoucherDetailsPageFormData}
label={ label={
<> <>
<FormattedMessage <FormattedMessage

View file

@ -27,6 +27,7 @@ import { decimal, joinDateTime, maybe } from "../../misc";
import { productUrl } from "../../products/urls"; import { productUrl } from "../../products/urls";
import { DiscountValueTypeEnum, SaleType } from "../../types/globalTypes"; import { DiscountValueTypeEnum, SaleType } from "../../types/globalTypes";
import SaleDetailsPage, { import SaleDetailsPage, {
SaleDetailsPageFormData,
SaleDetailsPageTab SaleDetailsPageTab
} from "../components/SaleDetailsPage"; } from "../components/SaleDetailsPage";
import { import {
@ -192,6 +193,30 @@ export const SaleDetails: React.FC<SaleDetailsProps> = ({ id, params }) => {
} }
}); });
const handleSubmit = async (
data: SaleDetailsPageFormData
) => {
const result = await saleUpdate({
variables: {
id,
input: {
endDate: data.hasEndDate
? joinDateTime(data.endDate, data.endTime)
: null,
name: data.name,
startDate: joinDateTime(
data.startDate,
data.startTime
),
type: discountValueTypeEnum(data.type),
value: decimal(data.value)
}
}
});
return result.data.saleUpdate.errors;
};
const { const {
loadNextPage, loadNextPage,
loadPreviousPage, loadPreviousPage,
@ -244,30 +269,7 @@ export const SaleDetails: React.FC<SaleDetailsProps> = ({ id, params }) => {
activeTab={params.activeTab} activeTab={params.activeTab}
onBack={() => navigate(saleListUrl())} onBack={() => navigate(saleListUrl())}
onTabClick={changeTab} onTabClick={changeTab}
onSubmit={formData => onSubmit={handleSubmit}
saleUpdate({
variables: {
id,
input: {
endDate: formData.hasEndDate
? joinDateTime(
formData.endDate,
formData.endTime
)
: null,
name: formData.name,
startDate: joinDateTime(
formData.startDate,
formData.startTime
),
type: discountValueTypeEnum(
formData.type
),
value: decimal(formData.value)
}
}
})
}
onRemove={() => openModal("remove")} onRemove={() => openModal("remove")}
saveButtonBarState={saleUpdateOpts.status} saveButtonBarState={saleUpdateOpts.status}
categoryListToolbar={ categoryListToolbar={

View file

@ -31,6 +31,7 @@ import {
} from "../../types/globalTypes"; } from "../../types/globalTypes";
import DiscountCountrySelectDialog from "../components/DiscountCountrySelectDialog"; import DiscountCountrySelectDialog from "../components/DiscountCountrySelectDialog";
import VoucherDetailsPage, { import VoucherDetailsPage, {
VoucherDetailsPageFormData,
VoucherDetailsPageTab VoucherDetailsPageTab
} from "../components/VoucherDetailsPage"; } from "../components/VoucherDetailsPage";
import { import {
@ -195,6 +196,54 @@ export const VoucherDetails: React.FC<VoucherDetailsProps> = ({
} }
}); });
const handleSubmit = async (
data: VoucherDetailsPageFormData
) => {
const result = await voucherUpdate({
variables: {
id,
input: {
applyOncePerCustomer: data.applyOncePerCustomer,
applyOncePerOrder: data.applyOncePerOrder,
discountValue:
data.discountType.toString() === "SHIPPING"
? 100
: decimal(data.value),
discountValueType:
data.discountType.toString() === "SHIPPING"
? DiscountValueTypeEnum.PERCENTAGE
: data.discountType,
endDate: data.hasEndDate
? joinDateTime(data.endDate, data.endTime)
: null,
minAmountSpent:
data.requirementsPicker !==
RequirementsPicker.ORDER
? 0
: parseFloat(data.minSpent),
minCheckoutItemsQuantity:
data.requirementsPicker !==
RequirementsPicker.ITEM
? 0
: parseFloat(data.minCheckoutItemsQuantity),
startDate: joinDateTime(
data.startDate,
data.startTime
),
type:
data.discountType.toString() === "SHIPPING"
? VoucherTypeEnum.SHIPPING
: data.type,
usageLimit: data.hasUsageLimit
? parseInt(data.usageLimit, 10)
: null
}
}
});
return result.data.voucherUpdate.errors;
};
const { const {
loadNextPage, loadNextPage,
loadPreviousPage, loadPreviousPage,
@ -291,59 +340,7 @@ export const VoucherDetails: React.FC<VoucherDetailsProps> = ({
activeTab={params.activeTab} activeTab={params.activeTab}
onBack={() => navigate(voucherListUrl())} onBack={() => navigate(voucherListUrl())}
onTabClick={changeTab} onTabClick={changeTab}
onSubmit={formData => onSubmit={handleSubmit}
voucherUpdate({
variables: {
id,
input: {
applyOncePerCustomer:
formData.applyOncePerCustomer,
applyOncePerOrder:
formData.applyOncePerOrder,
discountValue:
formData.discountType.toString() ===
"SHIPPING"
? 100
: decimal(formData.value),
discountValueType:
formData.discountType.toString() ===
"SHIPPING"
? DiscountValueTypeEnum.PERCENTAGE
: formData.discountType,
endDate: formData.hasEndDate
? joinDateTime(
formData.endDate,
formData.endTime
)
: null,
minAmountSpent:
formData.requirementsPicker !==
RequirementsPicker.ORDER
? 0
: parseFloat(formData.minSpent),
minCheckoutItemsQuantity:
formData.requirementsPicker !==
RequirementsPicker.ITEM
? 0
: parseFloat(
formData.minCheckoutItemsQuantity
),
startDate: joinDateTime(
formData.startDate,
formData.startTime
),
type:
formData.discountType.toString() ===
"SHIPPING"
? VoucherTypeEnum.SHIPPING
: formData.type,
usageLimit: formData.hasUsageLimit
? parseInt(formData.usageLimit, 10)
: null
}
}
})
}
onRemove={() => openModal("remove")} onRemove={() => openModal("remove")}
saveButtonBarState={voucherUpdateOpts.status} saveButtonBarState={voucherUpdateOpts.status}
categoryListToolbar={ categoryListToolbar={

View file

@ -5,14 +5,14 @@ import { AccountErrorCode, AddressInput } from "@saleor/types/globalTypes";
import { add, remove } from "@saleor/utils/lists"; import { add, remove } from "@saleor/utils/lists";
import { useState } from "react"; import { useState } from "react";
interface UseAddressValidation<T> { interface UseAddressValidation<TInput, TOutput> {
errors: AccountErrorFragment[]; errors: AccountErrorFragment[];
submit: (data: T & AddressTypeInput) => void; submit: (data: TInput & AddressTypeInput) => TOutput;
} }
function useAddressValidation<T>( function useAddressValidation<TInput, TOutput>(
onSubmit: (address: T & AddressInput) => void onSubmit: (address: TInput & AddressInput) => TOutput
): UseAddressValidation<T> { ): UseAddressValidation<TInput, TOutput> {
const [validationErrors, setValidationErrors] = useState< const [validationErrors, setValidationErrors] = useState<
AccountErrorFragment[] AccountErrorFragment[]
>([]); >([]);
@ -25,7 +25,7 @@ function useAddressValidation<T>(
return { return {
errors: validationErrors, errors: validationErrors,
submit: (data: T & AddressTypeInput) => { submit: (data: TInput & AddressTypeInput) => {
try { try {
setValidationErrors( setValidationErrors(
remove( remove(
@ -34,7 +34,7 @@ function useAddressValidation<T>(
(a, b) => a.field === b.field (a, b) => a.field === b.field
) )
); );
onSubmit(transformFormToAddress(data)); return onSubmit(transformFormToAddress(data));
} catch { } catch {
setValidationErrors(add(countryRequiredError, validationErrors)); setValidationErrors(add(countryRequiredError, validationErrors));
} }

View file

@ -51,7 +51,7 @@ function handleRefresh<T extends FormData>(
function useForm<T extends FormData>( function useForm<T extends FormData>(
initial: T, initial: T,
onSubmit?: (data: T) => void onSubmit?: (data: T) => Promise<any[]> | void
): UseFormResult<T> { ): UseFormResult<T> {
const [hasChanged, setChanged] = useState(false); const [hasChanged, setChanged] = useState(false);
const [data, setData] = useStateFromProps(initial, { const [data, setData] = useStateFromProps(initial, {
@ -106,9 +106,15 @@ function useForm<T extends FormData>(
})); }));
} }
function submit() { async function submit() {
if (typeof onSubmit === "function") { if (typeof onSubmit === "function") {
onSubmit(data); const result = onSubmit(data);
if (result) {
const errors = await result;
if (errors.length === 0) {
setChanged(false);
}
}
} }
} }

View file

@ -36,7 +36,7 @@ export interface MenuDetailsPageProps {
onItemAdd: () => void; onItemAdd: () => void;
onItemClick: (id: string, type: MenuItemType) => void; onItemClick: (id: string, type: MenuItemType) => void;
onItemEdit: (id: string) => void; onItemEdit: (id: string) => void;
onSubmit: (data: MenuDetailsSubmitData) => Promise<boolean>; onSubmit: (data: MenuDetailsSubmitData) => Promise<any[]>;
} }
const MenuDetailsPage: React.FC<MenuDetailsPageProps> = ({ const MenuDetailsPage: React.FC<MenuDetailsPageProps> = ({
@ -62,14 +62,16 @@ const MenuDetailsPage: React.FC<MenuDetailsPageProps> = ({
); );
const handleSubmit = async (data: MenuDetailsFormData) => { const handleSubmit = async (data: MenuDetailsFormData) => {
if ( const result = await onSubmit({
await onSubmit({
name: data.name, name: data.name,
operations: treeOperations operations: treeOperations
}) });
) {
if (result) {
setTreeOperations([]); setTreeOperations([]);
} }
return result;
}; };
const handleChange = (operation: TreeOperation) => { const handleChange = (operation: TreeOperation) => {

View file

@ -141,7 +141,6 @@ const MenuDetails: React.FC<MenuDetailsProps> = ({ id, params }) => {
// that it should clean operation stack if mutations // that it should clean operation stack if mutations
// were successful // were successful
const handleSubmit = async (data: MenuDetailsSubmitData) => { const handleSubmit = async (data: MenuDetailsSubmitData) => {
try {
const result = await menuUpdate({ const result = await menuUpdate({
variables: { variables: {
id, id,
@ -150,19 +149,12 @@ const MenuDetails: React.FC<MenuDetailsProps> = ({ id, params }) => {
removeIds: getRemoveIds(data) removeIds: getRemoveIds(data)
} }
}); });
if (result) {
if ( return [
result.data.menuItemBulkDelete.errors.length > 0 || ...result.data.menuItemBulkDelete.errors,
result.data.menuItemMove.errors.length > 0 || ...result.data.menuItemMove.errors,
result.data.menuUpdate.errors.length > 0 ...result.data.menuUpdate.errors
) { ];
return false;
}
}
return true;
} catch {
return false;
}
}; };
return ( return (

View file

@ -74,7 +74,7 @@ export interface OrderDetailsPageProps extends UserPermissionProps {
onInvoiceClick(invoiceId: string); onInvoiceClick(invoiceId: string);
onInvoiceGenerate(); onInvoiceGenerate();
onInvoiceSend(invoiceId: string); onInvoiceSend(invoiceId: string);
onSubmit(data: MetadataFormData); onSubmit(data: MetadataFormData): Promise<any[]>;
} }
const OrderDetailsPage: React.FC<OrderDetailsPageProps> = props => { const OrderDetailsPage: React.FC<OrderDetailsPageProps> = props => {
@ -123,7 +123,7 @@ const OrderDetailsPage: React.FC<OrderDetailsPageProps> = props => {
? data.privateMetadata ? data.privateMetadata
: undefined; : undefined;
onSubmit({ return onSubmit({
metadata, metadata,
privateMetadata privateMetadata
}); });

View file

@ -127,6 +127,8 @@ export const OrderDetails: React.FC<OrderDetailsProps> = ({ id, params }) => {
text: intl.formatMessage(commonMessages.savedChanges) text: intl.formatMessage(commonMessages.savedChanges)
}); });
} }
return result;
}; };
return ( return (

View file

@ -27,7 +27,7 @@ import { maybe } from "../../../misc";
import { PageDetails_page } from "../../types/PageDetails"; import { PageDetails_page } from "../../types/PageDetails";
import PageInfo from "../PageInfo"; import PageInfo from "../PageInfo";
export interface FormData extends MetadataFormData { export interface PageDetailsPageFormData extends MetadataFormData {
content: RawDraftContentState; content: RawDraftContentState;
isPublished: boolean; isPublished: boolean;
publicationDate: string; publicationDate: string;
@ -45,7 +45,7 @@ export interface PageDetailsPageProps {
saveButtonBarState: ConfirmButtonTransitionState; saveButtonBarState: ConfirmButtonTransitionState;
onBack: () => void; onBack: () => void;
onRemove: () => void; onRemove: () => void;
onSubmit: (data: FormData) => void; onSubmit: (data: PageDetailsPageFormData) => void;
} }
const PageDetailsPage: React.FC<PageDetailsPageProps> = ({ const PageDetailsPage: React.FC<PageDetailsPageProps> = ({
@ -67,7 +67,7 @@ const PageDetailsPage: React.FC<PageDetailsPageProps> = ({
const pageExists = page !== null; const pageExists = page !== null;
const initialForm: FormData = { const initialForm: PageDetailsPageFormData = {
content: maybe( content: maybe(
() => JSON.parse(page.contentJson), () => JSON.parse(page.contentJson),
convertToRaw(ContentState.createFromText("")) convertToRaw(ContentState.createFromText(""))

View file

@ -14,10 +14,10 @@ import { useIntl } from "react-intl";
import { maybe } from "../../../misc"; import { maybe } from "../../../misc";
import { PageDetails_page } from "../../types/PageDetails"; import { PageDetails_page } from "../../types/PageDetails";
import { FormData } from "../PageDetailsPage"; import { PageDetailsPageFormData } from "../PageDetailsPage";
export interface PageInfoProps { export interface PageInfoProps {
data: FormData; data: PageDetailsPageFormData;
disabled: boolean; disabled: boolean;
errors: PageErrorFragment[]; errors: PageErrorFragment[];
page: PageDetails_page; page: PageDetails_page;
@ -56,7 +56,7 @@ const PageInfo: React.FC<PageInfoProps> = props => {
defaultMessage: "Title", defaultMessage: "Title",
description: "page title" description: "page title"
})} })}
name={"title" as keyof FormData} name={"title" as keyof PageDetailsPageFormData}
value={data.title} value={data.title}
onChange={onChange} onChange={onChange}
/> />
@ -70,7 +70,7 @@ const PageInfo: React.FC<PageInfoProps> = props => {
defaultMessage: "Content", defaultMessage: "Content",
description: "page content" description: "page content"
})} })}
name={"content" as keyof FormData} name={"content" as keyof PageDetailsPageFormData}
onChange={onChange} onChange={onChange}
/> />
</CardContent> </CardContent>

View file

@ -14,7 +14,9 @@ import { FormattedMessage, useIntl } from "react-intl";
import { getStringOrPlaceholder, maybe } from "../../misc"; import { getStringOrPlaceholder, maybe } from "../../misc";
import { PageInput } from "../../types/globalTypes"; import { PageInput } from "../../types/globalTypes";
import PageDetailsPage, { FormData } from "../components/PageDetailsPage"; import PageDetailsPage, {
PageDetailsPageFormData
} from "../components/PageDetailsPage";
import { TypedPageRemove, TypedPageUpdate } from "../mutations"; import { TypedPageRemove, TypedPageUpdate } from "../mutations";
import { TypedPageDetailsQuery } from "../queries"; import { TypedPageDetailsQuery } from "../queries";
import { PageRemove } from "../types/PageRemove"; import { PageRemove } from "../types/PageRemove";
@ -25,7 +27,7 @@ export interface PageDetailsProps {
params: PageUrlQueryParams; params: PageUrlQueryParams;
} }
const createPageInput = (data: FormData): PageInput => ({ const createPageInput = (data: PageDetailsPageFormData): PageInput => ({
contentJson: JSON.stringify(data.content), contentJson: JSON.stringify(data.content),
isPublished: data.isPublished, isPublished: data.isPublished,
publicationDate: data.publicationDate, publicationDate: data.publicationDate,
@ -61,7 +63,7 @@ export const PageDetails: React.FC<PageDetailsProps> = ({ id, params }) => {
{(pageUpdate, pageUpdateOpts) => ( {(pageUpdate, pageUpdateOpts) => (
<TypedPageDetailsQuery variables={{ id }}> <TypedPageDetailsQuery variables={{ id }}>
{pageDetails => { {pageDetails => {
const handleUpdate = async (data: FormData) => { const handleUpdate = async (data: PageDetailsPageFormData) => {
const result = await pageUpdate({ const result = await pageUpdate({
variables: { variables: {
id, id,

View file

@ -56,7 +56,7 @@ export interface PermissionGroupDetailsPageProps
onAssign: () => void; onAssign: () => void;
onBack: () => void; onBack: () => void;
onUnassign: (ids: string[]) => void; onUnassign: (ids: string[]) => void;
onSubmit(data: PermissionGroupDetailsPageFormData); onSubmit: (data: PermissionGroupDetailsPageFormData) => Promise<any[]>;
} }
const PermissionGroupDetailsPage: React.FC<PermissionGroupDetailsPageProps> = ({ const PermissionGroupDetailsPage: React.FC<PermissionGroupDetailsPageProps> = ({

View file

@ -21,7 +21,9 @@ import React, { useState } from "react";
import { useIntl } from "react-intl"; import { useIntl } from "react-intl";
import AssignMembersDialog from "../../components/AssignMembersDialog"; import AssignMembersDialog from "../../components/AssignMembersDialog";
import PermissionGroupDetailsPage from "../../components/PermissionGroupDetailsPage"; import PermissionGroupDetailsPage, {
PermissionGroupDetailsPageFormData
} from "../../components/PermissionGroupDetailsPage";
import UnassignMembersDialog from "../../components/UnassignMembersDialog"; import UnassignMembersDialog from "../../components/UnassignMembersDialog";
import { usePermissionGroupUpdate } from "../../mutations"; import { usePermissionGroupUpdate } from "../../mutations";
import { usePermissionGroupDetailsQuery } from "../../queries"; import { usePermissionGroupDetailsQuery } from "../../queries";
@ -131,6 +133,21 @@ export const PermissionGroupDetails: React.FC<PermissionGroupDetailsProps> = ({
); );
const disabled = loading || !isGroupEditable || permissionsExceeded; const disabled = loading || !isGroupEditable || permissionsExceeded;
const handleSubmit = async (formData: PermissionGroupDetailsPageFormData) => {
const result = await permissionGroupUpdate({
variables: {
id,
input: {
name: formData.name,
...permissionsDiff(data?.permissionGroup, formData),
...usersDiff(data?.permissionGroup, formData)
}
}
});
return result.data.permissionGroupUpdate.errors;
};
return ( return (
<> <>
<PermissionGroupDetailsPage <PermissionGroupDetailsPage
@ -144,18 +161,7 @@ export const PermissionGroupDetails: React.FC<PermissionGroupDetailsProps> = ({
errors={ errors={
permissionGroupUpdateResult?.data?.permissionGroupUpdate.errors || [] permissionGroupUpdateResult?.data?.permissionGroupUpdate.errors || []
} }
onSubmit={formData => onSubmit={handleSubmit}
permissionGroupUpdate({
variables: {
id,
input: {
name: formData.name,
...permissionsDiff(data?.permissionGroup, formData),
...usersDiff(data?.permissionGroup, formData)
}
}
})
}
permissions={permissions} permissions={permissions}
saveButtonBarState={permissionGroupUpdateResult.status} saveButtonBarState={permissionGroupUpdateResult.status}
disabled={disabled} disabled={disabled}

View file

@ -13,10 +13,10 @@ import getPluginErrorMessage from "@saleor/utils/errors/plugins";
import React from "react"; import React from "react";
import { FormattedMessage, useIntl } from "react-intl"; import { FormattedMessage, useIntl } from "react-intl";
import { FormData } from "../PluginsDetailsPage"; import { PluginDetailsPageFormData } from "../PluginsDetailsPage";
interface PluginInfoProps { interface PluginInfoProps {
data: FormData; data: PluginDetailsPageFormData;
description: string; description: string;
errors: PluginErrorFragment[]; errors: PluginErrorFragment[];
name: string; name: string;
@ -83,7 +83,7 @@ const PluginInfo: React.FC<PluginInfoProps> = ({
})} })}
</Typography> </Typography>
<ControlledCheckbox <ControlledCheckbox
name={"active" as keyof FormData} name={"active" as keyof PluginDetailsPageFormData}
label={intl.formatMessage({ label={intl.formatMessage({
defaultMessage: "Set plugin as Active" defaultMessage: "Set plugin as Active"
})} })}

View file

@ -14,10 +14,10 @@ import { getFieldError } from "@saleor/utils/errors";
import React from "react"; import React from "react";
import { useIntl } from "react-intl"; import { useIntl } from "react-intl";
import { FormData } from "../PluginsDetailsPage"; import { PluginDetailsPageFormData } from "../PluginsDetailsPage";
interface PluginSettingsProps { interface PluginSettingsProps {
data: FormData; data: PluginDetailsPageFormData;
errors: UserError[]; errors: UserError[];
disabled: boolean; disabled: boolean;
onChange: (event: React.ChangeEvent<any>) => void; onChange: (event: React.ChangeEvent<any>) => void;

View file

@ -23,7 +23,7 @@ import PluginAuthorization from "../PluginAuthorization";
import PluginInfo from "../PluginInfo"; import PluginInfo from "../PluginInfo";
import PluginSettings from "../PluginSettings"; import PluginSettings from "../PluginSettings";
export interface FormData { export interface PluginDetailsPageFormData {
active: boolean; active: boolean;
configuration: ConfigurationItemInput[]; configuration: ConfigurationItemInput[];
} }
@ -36,7 +36,7 @@ export interface PluginsDetailsPageProps {
onBack: () => void; onBack: () => void;
onClear: (field: string) => void; onClear: (field: string) => void;
onEdit: (field: string) => void; onEdit: (field: string) => void;
onSubmit: (data: FormData) => void; onSubmit: (data: PluginDetailsPageFormData) => void;
} }
const useStyles = makeStyles( const useStyles = makeStyles(
@ -64,7 +64,7 @@ const PluginsDetailsPage: React.FC<PluginsDetailsPageProps> = props => {
const classes = useStyles(props); const classes = useStyles(props);
const intl = useIntl(); const intl = useIntl();
const initialForm: FormData = { const initialForm: PluginDetailsPageFormData = {
active: plugin?.active || false, active: plugin?.active || false,
configuration: plugin?.configuration configuration: plugin?.configuration
?.filter(field => !isSecretField(plugin?.configuration || [], field.name)) ?.filter(field => !isSecretField(plugin?.configuration || [], field.name))

View file

@ -9,7 +9,9 @@ import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandl
import React from "react"; import React from "react";
import { FormattedMessage, useIntl } from "react-intl"; import { FormattedMessage, useIntl } from "react-intl";
import PluginsDetailsPage from "../components/PluginsDetailsPage"; import PluginsDetailsPage, {
PluginDetailsPageFormData
} from "../components/PluginsDetailsPage";
import PluginSecretFieldDialog from "../components/PluginSecretFieldDialog"; import PluginSecretFieldDialog from "../components/PluginSecretFieldDialog";
import { TypedPluginUpdate } from "../mutations"; import { TypedPluginUpdate } from "../mutations";
import { TypedPluginsDetailsQuery } from "../queries"; import { TypedPluginsDetailsQuery } from "../queries";
@ -89,6 +91,25 @@ export const PluginsDetails: React.FC<PluginsDetailsProps> = ({
} }
}); });
const handleSubmit = async (
formData: PluginDetailsPageFormData
) => {
const result = await pluginUpdate({
variables: {
id,
input: {
active: formData.active,
configuration: getConfigurationInput(
pluginDetails.data.plugin.configuration,
formData.configuration
)
}
}
});
return result.data.pluginUpdate.errors;
};
return ( return (
<> <>
<WindowTitle title={pluginDetails.data?.plugin?.name} /> <WindowTitle title={pluginDetails.data?.plugin?.name} />
@ -110,20 +131,7 @@ export const PluginsDetails: React.FC<PluginsDetailsProps> = ({
id id
}) })
} }
onSubmit={formData => onSubmit={handleSubmit}
pluginUpdate({
variables: {
id,
input: {
active: formData.active,
configuration: getConfigurationInput(
pluginDetails.data.plugin.configuration,
formData.configuration
)
}
}
})
}
/> />
{pluginDetails.data?.plugin?.configuration && ( {pluginDetails.data?.plugin?.configuration && (
<> <>

View file

@ -61,7 +61,7 @@ export interface ProductTypeDetailsPageProps {
onBack: () => void; onBack: () => void;
onDelete: () => void; onDelete: () => void;
onHasVariantsToggle: (hasVariants: boolean) => void; onHasVariantsToggle: (hasVariants: boolean) => void;
onSubmit: (data: ProductTypeForm) => void; onSubmit: (data: ProductTypeForm) => Promise<any[]>;
} }
function handleTaxTypeChange( function handleTaxTypeChange(
@ -141,7 +141,7 @@ const ProductTypeDetailsPage: React.FC<ProductTypeDetailsPageProps> = ({
? data.privateMetadata ? data.privateMetadata
: undefined; : undefined;
onSubmit({ return onSubmit({
...data, ...data,
metadata, metadata,
privateMetadata privateMetadata

View file

@ -46,7 +46,7 @@ export interface ShippingZoneDetailsPageProps
onPriceRateAdd: () => void; onPriceRateAdd: () => void;
onPriceRateEdit: (id: string) => void; onPriceRateEdit: (id: string) => void;
onRateRemove: (rateId: string) => void; onRateRemove: (rateId: string) => void;
onSubmit: (data: FormData) => void; onSubmit: (data: FormData) => Promise<any[]>;
onWarehouseAdd: () => void; onWarehouseAdd: () => void;
onWeightRateAdd: () => void; onWeightRateAdd: () => void;
onWeightRateEdit: (id: string) => void; onWeightRateEdit: (id: string) => void;

View file

@ -148,13 +148,13 @@ const ShippingZoneDetails: React.FC<ShippingZoneDetailsProps> = ({
} }
}); });
const handleSubmit = (submitData: FormData) => { const handleSubmit = async (submitData: FormData) => {
const warehouseDiff = diff( const warehouseDiff = diff(
data.shippingZone.warehouses.map(warehouse => warehouse.id), data.shippingZone.warehouses.map(warehouse => warehouse.id),
submitData.warehouses submitData.warehouses
); );
updateShippingZone({ const result = await updateShippingZone({
variables: { variables: {
id, id,
input: { input: {
@ -164,6 +164,8 @@ const ShippingZoneDetails: React.FC<ShippingZoneDetailsProps> = ({
} }
} }
}); });
return result.data.shippingZoneUpdate.errors;
}; };
if (data?.shippingZone === null) { if (data?.shippingZone === null) {

View file

@ -54,7 +54,7 @@ export interface SiteSettingsPageProps {
onBack: () => void; onBack: () => void;
onKeyAdd: () => void; onKeyAdd: () => void;
onKeyRemove: (keyType: AuthorizationKeyType) => void; onKeyRemove: (keyType: AuthorizationKeyType) => void;
onSubmit: (data: SiteSettingsPageFormData) => void; onSubmit: (data: SiteSettingsPageFormData) => Promise<any[]>;
} }
export function areAddressInputFieldsModified( export function areAddressInputFieldsModified(
@ -105,7 +105,7 @@ const SiteSettingsPage: React.FC<SiteSettingsPageProps> = props => {
const { const {
errors: validationErrors, errors: validationErrors,
submit: handleSubmitWithAddress submit: handleSubmitWithAddress
} = useAddressValidation<SiteSettingsPageFormData>(onSubmit); } = useAddressValidation(onSubmit);
const initialFormAddress: SiteSettingsPageAddressFormData = { const initialFormAddress: SiteSettingsPageAddressFormData = {
city: maybe(() => shop.companyAddress.city, ""), city: maybe(() => shop.companyAddress.city, ""),
@ -134,7 +134,7 @@ const SiteSettingsPage: React.FC<SiteSettingsPageProps> = props => {
const submitFunc = areAddressInputFieldsModified(data) const submitFunc = areAddressInputFieldsModified(data)
? handleSubmitWithAddress ? handleSubmitWithAddress
: onSubmit; : onSubmit;
submitFunc(data); return submitFunc(data);
}} }}
confirmLeave confirmLeave
> >

View file

@ -106,7 +106,7 @@ export const SiteSettings: React.FC<SiteSettingsProps> = ({ params }) => {
keyType: data.type keyType: data.type
} }
}); });
const handleUpdateShopSettings = ( const handleUpdateShopSettings = async (
data: SiteSettingsPageFormData data: SiteSettingsPageFormData
) => { ) => {
const addressInput = areAddressInputFieldsModified(data) const addressInput = areAddressInputFieldsModified(data)
@ -123,7 +123,7 @@ export const SiteSettings: React.FC<SiteSettingsProps> = ({ params }) => {
: { : {
companyName: data.companyName companyName: data.companyName
}; };
updateShopSettings({ const result = await updateShopSettings({
variables: { variables: {
addressInput, addressInput,
shopDomainInput: { shopDomainInput: {
@ -139,6 +139,12 @@ export const SiteSettings: React.FC<SiteSettingsProps> = ({ params }) => {
} }
} }
}); });
return [
result.data.shopAddressUpdate.errors,
result.data.shopDomainUpdate.errors,
result.data.shopSettingsUpdate.errors
];
}; };
return ( return (

View file

@ -50,7 +50,7 @@ export interface StaffDetailsPageProps extends SearchPageProps {
onChangePassword: () => void; onChangePassword: () => void;
onDelete: () => void; onDelete: () => void;
onImageDelete: () => void; onImageDelete: () => void;
onSubmit: (data: StaffDetailsFormData) => void; onSubmit: (data: StaffDetailsFormData) => Promise<any[]>;
onImageUpload(file: File); onImageUpload(file: File);
} }

View file

@ -12,7 +12,9 @@ import usePermissionGroupSearch from "@saleor/searches/usePermissionGroupSearch"
import React from "react"; import React from "react";
import { FormattedMessage, useIntl } from "react-intl"; import { FormattedMessage, useIntl } from "react-intl";
import StaffDetailsPage from "../components/StaffDetailsPage/StaffDetailsPage"; import StaffDetailsPage, {
StaffDetailsFormData
} from "../components/StaffDetailsPage/StaffDetailsPage";
import StaffPasswordResetDialog from "../components/StaffPasswordResetDialog"; import StaffPasswordResetDialog from "../components/StaffPasswordResetDialog";
import { import {
TypedStaffAvatarDeleteMutation, TypedStaffAvatarDeleteMutation,
@ -122,7 +124,25 @@ export const StaffDetails: React.FC<OrderListProps> = ({ id, params }) => {
return ( return (
<TypedStaffMemberUpdateMutation onCompleted={handleStaffMemberUpdate}> <TypedStaffMemberUpdateMutation onCompleted={handleStaffMemberUpdate}>
{(updateStaffMember, updateResult) => ( {(updateStaffMember, updateResult) => {
const handleSubmit = async (formData: StaffDetailsFormData) => {
const result = await updateStaffMember({
variables: {
id,
input: {
email: formData.email,
firstName: formData.firstName,
isActive: formData.isActive,
lastName: formData.lastName,
...groupsDiff(data?.user, formData)
}
}
});
return result.data.staffUpdate.errors;
};
return (
<TypedStaffMemberDeleteMutation <TypedStaffMemberDeleteMutation
variables={{ id }} variables={{ id }}
onCompleted={handleStaffMemberDelete} onCompleted={handleStaffMemberDelete}
@ -148,7 +168,8 @@ export const StaffDetails: React.FC<OrderListProps> = ({ id, params }) => {
/> />
<StaffDetailsPage <StaffDetailsPage
errors={ errors={
updateResult?.data?.staffUpdate?.errors || [] updateResult?.data?.staffUpdate?.errors ||
[]
} }
canEditAvatar={isUserSameAsViewer} canEditAvatar={isUserSameAsViewer}
canEditPreferences={isUserSameAsViewer} canEditPreferences={isUserSameAsViewer}
@ -171,20 +192,7 @@ export const StaffDetails: React.FC<OrderListProps> = ({ id, params }) => {
}) })
) )
} }
onSubmit={variables => { onSubmit={handleSubmit}
updateStaffMember({
variables: {
id,
input: {
email: variables.email,
firstName: variables.firstName,
isActive: variables.isActive,
lastName: variables.lastName,
...groupsDiff(data?.user, variables)
}
}
});
}}
onImageUpload={file => onImageUpload={file =>
updateStaffAvatar({ updateStaffAvatar({
variables: { variables: {
@ -283,7 +291,8 @@ export const StaffDetails: React.FC<OrderListProps> = ({ id, params }) => {
</TypedStaffAvatarUpdateMutation> </TypedStaffAvatarUpdateMutation>
)} )}
</TypedStaffMemberDeleteMutation> </TypedStaffMemberDeleteMutation>
)} );
}}
</TypedStaffMemberUpdateMutation> </TypedStaffMemberUpdateMutation>
); );
}} }}

View file

@ -3,7 +3,7 @@ import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import VoucherDetailsPage, { import VoucherDetailsPage, {
FormData, VoucherDetailsPageFormData,
VoucherDetailsPageProps, VoucherDetailsPageProps,
VoucherDetailsPageTab VoucherDetailsPageTab
} from "../../../discounts/components/VoucherDetailsPage"; } from "../../../discounts/components/VoucherDetailsPage";
@ -59,7 +59,7 @@ storiesOf("Views / Discounts / Voucher details", module)
"type", "type",
"usageLimit", "usageLimit",
"discountValue" "discountValue"
] as Array<keyof FormData>).map(field => ({ ] as Array<keyof VoucherDetailsPageFormData>).map(field => ({
__typename: "DiscountError", __typename: "DiscountError",
code: DiscountErrorCode.INVALID, code: DiscountErrorCode.INVALID,
field field

View file

@ -3,7 +3,7 @@ import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import PageDetailsPage, { import PageDetailsPage, {
FormData, PageDetailsPageFormData,
PageDetailsPageProps PageDetailsPageProps
} from "../../../pages/components/PageDetailsPage"; } from "../../../pages/components/PageDetailsPage";
import { page } from "../../../pages/fixtures"; import { page } from "../../../pages/fixtures";
@ -36,7 +36,7 @@ storiesOf("Views / Pages / Page details", module)
"isPublished", "isPublished",
"seoDescription", "seoDescription",
"seoTitle" "seoTitle"
] as Array<keyof FormData>).map(field => ({ ] as Array<keyof PageDetailsPageFormData>).map(field => ({
__typename: "PageError", __typename: "PageError",
code: PageErrorCode.INVALID, code: PageErrorCode.INVALID,
field field

View file

@ -3,7 +3,7 @@ import { storiesOf } from "@storybook/react";
import React from "react"; import React from "react";
import PluginsDetailsPage, { import PluginsDetailsPage, {
FormData, PluginDetailsPageFormData,
PluginsDetailsPageProps PluginsDetailsPageProps
} from "../../../plugins/components/PluginsDetailsPage"; } from "../../../plugins/components/PluginsDetailsPage";
import { plugin } from "../../../plugins/fixtures"; import { plugin } from "../../../plugins/fixtures";
@ -31,7 +31,7 @@ storiesOf("Views / Plugins / Plugin details", module)
{...props} {...props}
errors={[ errors={[
...(["active", "Username or account", "Password or license"] as Array< ...(["active", "Username or account", "Password or license"] as Array<
keyof FormData keyof PluginDetailsPageFormData
>).map(field => ({ >).map(field => ({
__typename: "PluginError" as "PluginError", __typename: "PluginError" as "PluginError",
code: PluginErrorCode.INVALID, code: PluginErrorCode.INVALID,

View file

@ -36,7 +36,7 @@ export interface WarehouseDetailsPageProps {
onBack: () => void; onBack: () => void;
onDelete: () => void; onDelete: () => void;
onShippingZoneClick: (id: string) => void; onShippingZoneClick: (id: string) => void;
onSubmit: (data: WarehouseDetailsPageFormData) => void; onSubmit: (data: WarehouseDetailsPageFormData) => Promise<any[]>;
} }
const WarehouseDetailsPage: React.FC<WarehouseDetailsPageProps> = ({ const WarehouseDetailsPage: React.FC<WarehouseDetailsPageProps> = ({
@ -58,7 +58,7 @@ const WarehouseDetailsPage: React.FC<WarehouseDetailsPageProps> = ({
const { const {
errors: validationErrors, errors: validationErrors,
submit: handleSubmit submit: handleSubmit
} = useAddressValidation<WarehouseDetailsPageFormData>(onSubmit); } = useAddressValidation(onSubmit);
const initialForm: WarehouseDetailsPageFormData = { const initialForm: WarehouseDetailsPageFormData = {
city: maybe(() => warehouse.address.city, ""), city: maybe(() => warehouse.address.city, ""),
@ -76,7 +76,7 @@ const WarehouseDetailsPage: React.FC<WarehouseDetailsPageProps> = ({
return ( return (
<Form initial={initialForm} onSubmit={handleSubmit}> <Form initial={initialForm} onSubmit={handleSubmit}>
{({ change, data, submit }) => { {({ change, data, hasChanged, submit }) => {
const countryChoices = mapCountriesToChoices(countries); const countryChoices = mapCountriesToChoices(countries);
const handleCountryChange = createSingleAutocompleteSelectHandler( const handleCountryChange = createSingleAutocompleteSelectHandler(
change, change,
@ -121,7 +121,7 @@ const WarehouseDetailsPage: React.FC<WarehouseDetailsPageProps> = ({
</div> </div>
</Grid> </Grid>
<SaveButtonBar <SaveButtonBar
disabled={disabled} disabled={disabled || !hasChanged}
onCancel={onBack} onCancel={onBack}
onDelete={onDelete} onDelete={onDelete}
onSave={submit} onSave={submit}

View file

@ -13,7 +13,9 @@ import { shippingZoneUrl } from "@saleor/shipping/urls";
import { CountryCode } from "@saleor/types/globalTypes"; import { CountryCode } from "@saleor/types/globalTypes";
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers"; import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
import WarehouseDeleteDialog from "@saleor/warehouses/components/WarehouseDeleteDialog"; import WarehouseDeleteDialog from "@saleor/warehouses/components/WarehouseDeleteDialog";
import WarehouseDetailsPage from "@saleor/warehouses/components/WarehouseDetailsPage"; import WarehouseDetailsPage, {
WarehouseDetailsPageFormData
} from "@saleor/warehouses/components/WarehouseDetailsPage";
import { import {
useWarehouseDelete, useWarehouseDelete,
useWarehouseUpdate useWarehouseUpdate
@ -76,20 +78,8 @@ const WarehouseDetails: React.FC<WarehouseDetailsProps> = ({ id, params }) => {
return <NotFoundPage onBack={() => navigate(warehouseListUrl())} />; return <NotFoundPage onBack={() => navigate(warehouseListUrl())} />;
} }
return ( const handleSubmit = async (data: WarehouseDetailsPageFormData) => {
<> const result = await updateWarehouse({
<WindowTitle title={data?.warehouse?.name} />
<WarehouseDetailsPage
countries={shop?.countries || []}
disabled={loading || updateWarehouseOpts.loading}
errors={updateWarehouseOpts.data?.updateWarehouse.errors || []}
saveButtonBarState={updateWarehouseTransitionState}
warehouse={data?.warehouse}
onBack={() => navigate(warehouseListUrl())}
onDelete={() => openModal("delete")}
onShippingZoneClick={id => navigate(shippingZoneUrl(id))}
onSubmit={data =>
updateWarehouse({
variables: { variables: {
id, id,
input: { input: {
@ -106,8 +96,23 @@ const WarehouseDetails: React.FC<WarehouseDetailsProps> = ({ id, params }) => {
name: data.name name: data.name
} }
} }
}) });
}
return result.data.updateWarehouse.errors;
};
return (
<>
<WindowTitle title={data?.warehouse?.name} />
<WarehouseDetailsPage
countries={shop?.countries || []}
disabled={loading || updateWarehouseOpts.loading}
errors={updateWarehouseOpts.data?.updateWarehouse.errors || []}
saveButtonBarState={updateWarehouseTransitionState}
warehouse={data?.warehouse}
onBack={() => navigate(warehouseListUrl())}
onDelete={() => openModal("delete")}
onShippingZoneClick={id => navigate(shippingZoneUrl(id))}
onSubmit={handleSubmit}
/> />
<WarehouseDeleteDialog <WarehouseDeleteDialog
confirmButtonState={deleteWarehouseTransitionState} confirmButtonState={deleteWarehouseTransitionState}