Enable save button on channel pages (#2328)
* Enable save button on channel pages * Update changelog with enable save button * Remove disabling save while updating channel * Trigger CI Co-authored-by: Patryk Andrzejewski <vox3r69@gmail.com>
This commit is contained in:
parent
42d999a222
commit
943b96436c
5 changed files with 67 additions and 23 deletions
|
@ -10,12 +10,14 @@ All notable, unreleased changes to this project will be documented in this file.
|
||||||
- Fix invalid values in channel picker - #2313 by @orzechdev
|
- Fix invalid values in channel picker - #2313 by @orzechdev
|
||||||
- Fix missing metadata and payment balance on unconfirmed orders - #2314 by @orzechdev
|
- Fix missing metadata and payment balance on unconfirmed orders - #2314 by @orzechdev
|
||||||
- Fix exit form dialog false positive - #2311 by @orzechdev
|
- Fix exit form dialog false positive - #2311 by @orzechdev
|
||||||
|
- Enable save button on channel pages - #2328 by @orzechdev
|
||||||
- Handle form errors before product creation - #2299 by @orzechdev
|
- Handle form errors before product creation - #2299 by @orzechdev
|
||||||
- Fix no product error on unconfirmed order lines - #2324 by @orzechdev
|
- Fix no product error on unconfirmed order lines - #2324 by @orzechdev
|
||||||
- Enable save button on discount pages - #2319 by @orzechdev
|
- Enable save button on discount pages - #2319 by @orzechdev
|
||||||
- Enable save button on page pages - #2325 by @orzechdev
|
- Enable save button on page pages - #2325 by @orzechdev
|
||||||
- Fix pagination errors on voucher and sale pages - #2317 by @orzechdev
|
- Fix pagination errors on voucher and sale pages - #2317 by @orzechdev
|
||||||
|
|
||||||
|
|
||||||
## 3.4
|
## 3.4
|
||||||
|
|
||||||
- Added links instead of imperative navigation with onClick - #1969 by @taniotanio7
|
- Added links instead of imperative navigation with onClick - #1969 by @taniotanio7
|
||||||
|
|
|
@ -72,10 +72,11 @@ export const ChannelForm: React.FC<ChannelFormProps> = ({
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const [copied, copy] = useClipboard();
|
const [copied, copy] = useClipboard();
|
||||||
const formErrors = getFormErrors<keyof FormData, ChannelErrorFragment>(
|
const formErrors = getFormErrors<keyof FormData, ChannelErrorFragment>(
|
||||||
["name", "slug", "currencyCode"],
|
["name", "slug", "currencyCode", "defaultCountry"],
|
||||||
errors,
|
errors,
|
||||||
);
|
);
|
||||||
const classes = useStyles({});
|
const classes = useStyles();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Card>
|
<Card>
|
||||||
|
|
|
@ -2,6 +2,7 @@ import ChannelAllocationStrategy from "@saleor/channels/components/ChannelAlloca
|
||||||
import ShippingZones from "@saleor/channels/components/ShippingZones";
|
import ShippingZones from "@saleor/channels/components/ShippingZones";
|
||||||
import Warehouses from "@saleor/channels/components/Warehouses";
|
import Warehouses from "@saleor/channels/components/Warehouses";
|
||||||
import { channelsListUrl } from "@saleor/channels/urls";
|
import { channelsListUrl } from "@saleor/channels/urls";
|
||||||
|
import { validateChannelFormData } from "@saleor/channels/validation";
|
||||||
import CardSpacer from "@saleor/components/CardSpacer";
|
import CardSpacer from "@saleor/components/CardSpacer";
|
||||||
import Form from "@saleor/components/Form";
|
import Form from "@saleor/components/Form";
|
||||||
import Grid from "@saleor/components/Grid";
|
import Grid from "@saleor/components/Grid";
|
||||||
|
@ -41,7 +42,9 @@ import {
|
||||||
} from "./handlers";
|
} from "./handlers";
|
||||||
import { ChannelShippingZones, ChannelWarehouses } from "./types";
|
import { ChannelShippingZones, ChannelWarehouses } from "./types";
|
||||||
|
|
||||||
export interface ChannelDetailsPageProps<TErrors> {
|
export interface ChannelDetailsPageProps<
|
||||||
|
TErrors extends ChannelErrorFragment[]
|
||||||
|
> {
|
||||||
channel?: ChannelDetailsFragment;
|
channel?: ChannelDetailsFragment;
|
||||||
currencyCodes?: SingleAutocompleteChoiceType[];
|
currencyCodes?: SingleAutocompleteChoiceType[];
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
|
@ -58,13 +61,13 @@ export interface ChannelDetailsPageProps<TErrors> {
|
||||||
allWarehousesCount: number;
|
allWarehousesCount: number;
|
||||||
countries: CountryFragment[];
|
countries: CountryFragment[];
|
||||||
onDelete?: () => void;
|
onDelete?: () => void;
|
||||||
onSubmit: (data: FormData) => SubmitPromise<TErrors[]>;
|
onSubmit: (data: FormData) => SubmitPromise<TErrors>;
|
||||||
updateChannelStatus?: () => void;
|
updateChannelStatus?: () => void;
|
||||||
searchShippingZones: (query: string) => void;
|
searchShippingZones: (query: string) => void;
|
||||||
searchWarehouses: (query: string) => void;
|
searchWarehouses: (query: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ChannelDetailsPage = function<TErrors>({
|
const ChannelDetailsPage = function<TErrors extends ChannelErrorFragment[]>({
|
||||||
channel,
|
channel,
|
||||||
currencyCodes,
|
currencyCodes,
|
||||||
disabled,
|
disabled,
|
||||||
|
@ -88,6 +91,10 @@ const ChannelDetailsPage = function<TErrors>({
|
||||||
}: ChannelDetailsPageProps<TErrors>) {
|
}: ChannelDetailsPageProps<TErrors>) {
|
||||||
const navigate = useNavigator();
|
const navigate = useNavigator();
|
||||||
|
|
||||||
|
const [validationErrors, setValidationErrors] = useState<
|
||||||
|
ChannelErrorFragment[]
|
||||||
|
>([]);
|
||||||
|
|
||||||
const [selectedCurrencyCode, setSelectedCurrencyCode] = useState("");
|
const [selectedCurrencyCode, setSelectedCurrencyCode] = useState("");
|
||||||
const [
|
const [
|
||||||
selectedCountryDisplayName,
|
selectedCountryDisplayName,
|
||||||
|
@ -133,25 +140,21 @@ const ChannelDetailsPage = function<TErrors>({
|
||||||
!warehousesToDisplay.some(({ id }) => id === searchedWarehouseId),
|
!warehousesToDisplay.some(({ id }) => id === searchedWarehouseId),
|
||||||
);
|
);
|
||||||
|
|
||||||
const checkIfSaveIsDisabled = (data: FormData) => {
|
const handleSubmit = async (data: FormData) => {
|
||||||
const isValid =
|
const errors = validateChannelFormData(data);
|
||||||
!!data.name &&
|
|
||||||
!!data.slug &&
|
|
||||||
!!data.currencyCode &&
|
|
||||||
!!data.defaultCountry &&
|
|
||||||
data.name.trim().length > 0;
|
|
||||||
|
|
||||||
return disabled || !isValid;
|
setValidationErrors(errors);
|
||||||
|
|
||||||
|
if (errors.length) {
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
return onSubmit(data);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Form
|
<Form confirmLeave onSubmit={handleSubmit} initial={initialData}>
|
||||||
confirmLeave
|
{({ change, data, submit, set, triggerChange }) => {
|
||||||
onSubmit={onSubmit}
|
|
||||||
initial={initialData}
|
|
||||||
checkIfSaveIsDisabled={checkIfSaveIsDisabled}
|
|
||||||
>
|
|
||||||
{({ change, data, submit, set, isSaveDisabled, triggerChange }) => {
|
|
||||||
const handleCurrencyCodeSelect = createSingleAutocompleteSelectHandler(
|
const handleCurrencyCodeSelect = createSingleAutocompleteSelectHandler(
|
||||||
change,
|
change,
|
||||||
setSelectedCurrencyCode,
|
setSelectedCurrencyCode,
|
||||||
|
@ -188,6 +191,8 @@ const ChannelDetailsPage = function<TErrors>({
|
||||||
);
|
);
|
||||||
const reorderWarehouse = createWarehouseReorderHandler(data, set);
|
const reorderWarehouse = createWarehouseReorderHandler(data, set);
|
||||||
|
|
||||||
|
const allErrors = [...errors, ...validationErrors];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Grid>
|
<Grid>
|
||||||
|
@ -202,7 +207,7 @@ const ChannelDetailsPage = function<TErrors>({
|
||||||
onChange={change}
|
onChange={change}
|
||||||
onCurrencyCodeChange={handleCurrencyCodeSelect}
|
onCurrencyCodeChange={handleCurrencyCodeSelect}
|
||||||
onDefaultCountryChange={handleDefaultCountrySelect}
|
onDefaultCountryChange={handleDefaultCountrySelect}
|
||||||
errors={errors}
|
errors={allErrors}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
@ -267,7 +272,7 @@ const ChannelDetailsPage = function<TErrors>({
|
||||||
onSubmit={submit}
|
onSubmit={submit}
|
||||||
onDelete={onDelete}
|
onDelete={onDelete}
|
||||||
state={saveButtonBarState}
|
state={saveButtonBarState}
|
||||||
disabled={isSaveDisabled}
|
disabled={disabled}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
32
src/channels/validation.ts
Normal file
32
src/channels/validation.ts
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
import { ChannelErrorCode, ChannelErrorFragment } from "@saleor/graphql";
|
||||||
|
|
||||||
|
import { FormData } from "./components/ChannelForm";
|
||||||
|
|
||||||
|
const createEmptyRequiredError = (field: string): ChannelErrorFragment => ({
|
||||||
|
__typename: "ChannelError",
|
||||||
|
code: ChannelErrorCode.REQUIRED,
|
||||||
|
field,
|
||||||
|
message: null,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const validateChannelFormData = (data: FormData) => {
|
||||||
|
let errors: ChannelErrorFragment[] = [];
|
||||||
|
|
||||||
|
if (!data.name) {
|
||||||
|
errors = [...errors, createEmptyRequiredError("name")];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!data.slug) {
|
||||||
|
errors = [...errors, createEmptyRequiredError("slug")];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!data.currencyCode) {
|
||||||
|
errors = [...errors, createEmptyRequiredError("currencyCode")];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!data.defaultCountry) {
|
||||||
|
errors = [...errors, createEmptyRequiredError("defaultCountry")];
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors;
|
||||||
|
};
|
|
@ -46,7 +46,10 @@ export const ChannelCreateView = ({}) => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const [reorderChannelWarehouses] = useChannelReorderWarehousesMutation({
|
const [
|
||||||
|
reorderChannelWarehouses,
|
||||||
|
reorderChannelWarehousesOpts,
|
||||||
|
] = useChannelReorderWarehousesMutation({
|
||||||
onCompleted: data => {
|
onCompleted: data => {
|
||||||
const errors = data.channelReorderWarehouses.errors;
|
const errors = data.channelReorderWarehouses.errors;
|
||||||
if (errors.length) {
|
if (errors.length) {
|
||||||
|
@ -173,6 +176,7 @@ export const ChannelCreateView = ({}) => {
|
||||||
)}
|
)}
|
||||||
disabled={
|
disabled={
|
||||||
createChannelOpts.loading ||
|
createChannelOpts.loading ||
|
||||||
|
reorderChannelWarehousesOpts.loading ||
|
||||||
shippingZonesCountLoading ||
|
shippingZonesCountLoading ||
|
||||||
warehousesCountLoading
|
warehousesCountLoading
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue