Merge pull request #747 from mirumee/fix/negative-price-input
Prevent negative price setting in input
This commit is contained in:
commit
deeefa6e8c
4 changed files with 48 additions and 3 deletions
|
@ -5,6 +5,7 @@ import CardTitle from "@saleor/components/CardTitle";
|
||||||
import PriceField from "@saleor/components/PriceField";
|
import PriceField from "@saleor/components/PriceField";
|
||||||
import { ProductErrorFragment } from "@saleor/fragments/types/ProductErrorFragment";
|
import { ProductErrorFragment } from "@saleor/fragments/types/ProductErrorFragment";
|
||||||
import { getFormErrors, getProductErrorMessage } from "@saleor/utils/errors";
|
import { getFormErrors, getProductErrorMessage } from "@saleor/utils/errors";
|
||||||
|
import createNonNegativeValueChangeHandler from "@saleor/utils/handlers/nonNegativeValueChangeHandler";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useIntl } from "react-intl";
|
import { useIntl } from "react-intl";
|
||||||
|
|
||||||
|
@ -37,6 +38,8 @@ const ProductPricing: React.FC<ProductPricingProps> = props => {
|
||||||
|
|
||||||
const formErrors = getFormErrors(["basePrice"], errors);
|
const formErrors = getFormErrors(["basePrice"], errors);
|
||||||
|
|
||||||
|
const handlePriceChange = createNonNegativeValueChangeHandler(onChange);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
<CardTitle
|
<CardTitle
|
||||||
|
@ -58,7 +61,7 @@ const ProductPricing: React.FC<ProductPricingProps> = props => {
|
||||||
name="basePrice"
|
name="basePrice"
|
||||||
value={data.basePrice}
|
value={data.basePrice}
|
||||||
currencySymbol={currency}
|
currencySymbol={currency}
|
||||||
onChange={onChange}
|
onChange={handlePriceChange}
|
||||||
InputProps={{
|
InputProps={{
|
||||||
inputProps: {
|
inputProps: {
|
||||||
min: 0
|
min: 0
|
||||||
|
|
|
@ -5,6 +5,7 @@ import CardTitle from "@saleor/components/CardTitle";
|
||||||
import PriceField from "@saleor/components/PriceField";
|
import PriceField from "@saleor/components/PriceField";
|
||||||
import { ProductErrorFragment } from "@saleor/fragments/types/ProductErrorFragment";
|
import { ProductErrorFragment } from "@saleor/fragments/types/ProductErrorFragment";
|
||||||
import { getFormErrors, getProductErrorMessage } from "@saleor/utils/errors";
|
import { getFormErrors, getProductErrorMessage } from "@saleor/utils/errors";
|
||||||
|
import createNonNegativeValueChangeHandler from "@saleor/utils/handlers/nonNegativeValueChangeHandler";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useIntl } from "react-intl";
|
import { useIntl } from "react-intl";
|
||||||
|
|
||||||
|
@ -36,6 +37,8 @@ const ProductVariantPrice: React.FC<ProductVariantPriceProps> = props => {
|
||||||
|
|
||||||
const formErrors = getFormErrors(["price", "cost_price"], errors);
|
const formErrors = getFormErrors(["price", "cost_price"], errors);
|
||||||
|
|
||||||
|
const handlePriceChange = createNonNegativeValueChangeHandler(onChange);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
<CardTitle
|
<CardTitle
|
||||||
|
@ -55,8 +58,13 @@ const ProductVariantPrice: React.FC<ProductVariantPriceProps> = props => {
|
||||||
})}
|
})}
|
||||||
value={price}
|
value={price}
|
||||||
currencySymbol={currencySymbol}
|
currencySymbol={currencySymbol}
|
||||||
onChange={onChange}
|
onChange={handlePriceChange}
|
||||||
disabled={loading}
|
disabled={loading}
|
||||||
|
InputProps={{
|
||||||
|
inputProps: {
|
||||||
|
min: "0"
|
||||||
|
}
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
@ -76,8 +84,13 @@ const ProductVariantPrice: React.FC<ProductVariantPriceProps> = props => {
|
||||||
}
|
}
|
||||||
value={costPrice}
|
value={costPrice}
|
||||||
currencySymbol={currencySymbol}
|
currencySymbol={currencySymbol}
|
||||||
onChange={onChange}
|
onChange={handlePriceChange}
|
||||||
disabled={loading}
|
disabled={loading}
|
||||||
|
InputProps={{
|
||||||
|
inputProps: {
|
||||||
|
min: "0"
|
||||||
|
}
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -141166,6 +141166,7 @@ exports[`Storyshots Views / Products / Create product variant add first variant
|
||||||
<input
|
<input
|
||||||
aria-invalid="false"
|
aria-invalid="false"
|
||||||
class="MuiInputBase-input-id MuiOutlinedInput-input-id MuiInputBase-inputAdornedEnd-id MuiOutlinedInput-inputAdornedEnd-id"
|
class="MuiInputBase-input-id MuiOutlinedInput-input-id MuiInputBase-inputAdornedEnd-id MuiOutlinedInput-inputAdornedEnd-id"
|
||||||
|
min="0"
|
||||||
name="price"
|
name="price"
|
||||||
type="number"
|
type="number"
|
||||||
value=""
|
value=""
|
||||||
|
@ -141212,6 +141213,7 @@ exports[`Storyshots Views / Products / Create product variant add first variant
|
||||||
<input
|
<input
|
||||||
aria-invalid="false"
|
aria-invalid="false"
|
||||||
class="MuiInputBase-input-id MuiOutlinedInput-input-id MuiInputBase-inputAdornedEnd-id MuiOutlinedInput-inputAdornedEnd-id"
|
class="MuiInputBase-input-id MuiOutlinedInput-input-id MuiInputBase-inputAdornedEnd-id MuiOutlinedInput-inputAdornedEnd-id"
|
||||||
|
min="0"
|
||||||
name="costPrice"
|
name="costPrice"
|
||||||
type="number"
|
type="number"
|
||||||
value=""
|
value=""
|
||||||
|
@ -142058,6 +142060,7 @@ exports[`Storyshots Views / Products / Create product variant default 1`] = `
|
||||||
<input
|
<input
|
||||||
aria-invalid="false"
|
aria-invalid="false"
|
||||||
class="MuiInputBase-input-id MuiOutlinedInput-input-id MuiInputBase-inputAdornedEnd-id MuiOutlinedInput-inputAdornedEnd-id"
|
class="MuiInputBase-input-id MuiOutlinedInput-input-id MuiInputBase-inputAdornedEnd-id MuiOutlinedInput-inputAdornedEnd-id"
|
||||||
|
min="0"
|
||||||
name="price"
|
name="price"
|
||||||
type="number"
|
type="number"
|
||||||
value=""
|
value=""
|
||||||
|
@ -142104,6 +142107,7 @@ exports[`Storyshots Views / Products / Create product variant default 1`] = `
|
||||||
<input
|
<input
|
||||||
aria-invalid="false"
|
aria-invalid="false"
|
||||||
class="MuiInputBase-input-id MuiOutlinedInput-input-id MuiInputBase-inputAdornedEnd-id MuiOutlinedInput-inputAdornedEnd-id"
|
class="MuiInputBase-input-id MuiOutlinedInput-input-id MuiInputBase-inputAdornedEnd-id MuiOutlinedInput-inputAdornedEnd-id"
|
||||||
|
min="0"
|
||||||
name="costPrice"
|
name="costPrice"
|
||||||
type="number"
|
type="number"
|
||||||
value=""
|
value=""
|
||||||
|
@ -142950,6 +142954,7 @@ exports[`Storyshots Views / Products / Create product variant no warehouses 1`]
|
||||||
<input
|
<input
|
||||||
aria-invalid="false"
|
aria-invalid="false"
|
||||||
class="MuiInputBase-input-id MuiOutlinedInput-input-id MuiInputBase-inputAdornedEnd-id MuiOutlinedInput-inputAdornedEnd-id"
|
class="MuiInputBase-input-id MuiOutlinedInput-input-id MuiInputBase-inputAdornedEnd-id MuiOutlinedInput-inputAdornedEnd-id"
|
||||||
|
min="0"
|
||||||
name="price"
|
name="price"
|
||||||
type="number"
|
type="number"
|
||||||
value=""
|
value=""
|
||||||
|
@ -142996,6 +143001,7 @@ exports[`Storyshots Views / Products / Create product variant no warehouses 1`]
|
||||||
<input
|
<input
|
||||||
aria-invalid="false"
|
aria-invalid="false"
|
||||||
class="MuiInputBase-input-id MuiOutlinedInput-input-id MuiInputBase-inputAdornedEnd-id MuiOutlinedInput-inputAdornedEnd-id"
|
class="MuiInputBase-input-id MuiOutlinedInput-input-id MuiInputBase-inputAdornedEnd-id MuiOutlinedInput-inputAdornedEnd-id"
|
||||||
|
min="0"
|
||||||
name="costPrice"
|
name="costPrice"
|
||||||
type="number"
|
type="number"
|
||||||
value=""
|
value=""
|
||||||
|
@ -143665,6 +143671,7 @@ exports[`Storyshots Views / Products / Create product variant when loading data
|
||||||
aria-invalid="false"
|
aria-invalid="false"
|
||||||
class="MuiInputBase-input-id MuiOutlinedInput-input-id MuiInputBase-disabled-id MuiOutlinedInput-disabled-id MuiInputBase-inputAdornedEnd-id MuiOutlinedInput-inputAdornedEnd-id"
|
class="MuiInputBase-input-id MuiOutlinedInput-input-id MuiInputBase-disabled-id MuiOutlinedInput-disabled-id MuiInputBase-inputAdornedEnd-id MuiOutlinedInput-inputAdornedEnd-id"
|
||||||
disabled=""
|
disabled=""
|
||||||
|
min="0"
|
||||||
name="price"
|
name="price"
|
||||||
type="number"
|
type="number"
|
||||||
value=""
|
value=""
|
||||||
|
@ -143712,6 +143719,7 @@ exports[`Storyshots Views / Products / Create product variant when loading data
|
||||||
aria-invalid="false"
|
aria-invalid="false"
|
||||||
class="MuiInputBase-input-id MuiOutlinedInput-input-id MuiInputBase-disabled-id MuiOutlinedInput-disabled-id MuiInputBase-inputAdornedEnd-id MuiOutlinedInput-inputAdornedEnd-id"
|
class="MuiInputBase-input-id MuiOutlinedInput-input-id MuiInputBase-disabled-id MuiOutlinedInput-disabled-id MuiInputBase-inputAdornedEnd-id MuiOutlinedInput-inputAdornedEnd-id"
|
||||||
disabled=""
|
disabled=""
|
||||||
|
min="0"
|
||||||
name="costPrice"
|
name="costPrice"
|
||||||
type="number"
|
type="number"
|
||||||
value=""
|
value=""
|
||||||
|
@ -144575,6 +144583,7 @@ exports[`Storyshots Views / Products / Create product variant with errors 1`] =
|
||||||
<input
|
<input
|
||||||
aria-invalid="false"
|
aria-invalid="false"
|
||||||
class="MuiInputBase-input-id MuiOutlinedInput-input-id MuiInputBase-inputAdornedEnd-id MuiOutlinedInput-inputAdornedEnd-id"
|
class="MuiInputBase-input-id MuiOutlinedInput-input-id MuiInputBase-inputAdornedEnd-id MuiOutlinedInput-inputAdornedEnd-id"
|
||||||
|
min="0"
|
||||||
name="price"
|
name="price"
|
||||||
type="number"
|
type="number"
|
||||||
value=""
|
value=""
|
||||||
|
@ -144621,6 +144630,7 @@ exports[`Storyshots Views / Products / Create product variant with errors 1`] =
|
||||||
<input
|
<input
|
||||||
aria-invalid="false"
|
aria-invalid="false"
|
||||||
class="MuiInputBase-input-id MuiOutlinedInput-input-id MuiInputBase-inputAdornedEnd-id MuiOutlinedInput-inputAdornedEnd-id"
|
class="MuiInputBase-input-id MuiOutlinedInput-input-id MuiInputBase-inputAdornedEnd-id MuiOutlinedInput-inputAdornedEnd-id"
|
||||||
|
min="0"
|
||||||
name="costPrice"
|
name="costPrice"
|
||||||
type="number"
|
type="number"
|
||||||
value=""
|
value=""
|
||||||
|
@ -173950,6 +173960,7 @@ exports[`Storyshots Views / Products / Product variant details attribute errors
|
||||||
<input
|
<input
|
||||||
aria-invalid="false"
|
aria-invalid="false"
|
||||||
class="MuiInputBase-input-id MuiOutlinedInput-input-id MuiInputBase-inputAdornedEnd-id MuiOutlinedInput-inputAdornedEnd-id"
|
class="MuiInputBase-input-id MuiOutlinedInput-input-id MuiInputBase-inputAdornedEnd-id MuiOutlinedInput-inputAdornedEnd-id"
|
||||||
|
min="0"
|
||||||
name="price"
|
name="price"
|
||||||
type="number"
|
type="number"
|
||||||
value="100"
|
value="100"
|
||||||
|
@ -173996,6 +174007,7 @@ exports[`Storyshots Views / Products / Product variant details attribute errors
|
||||||
<input
|
<input
|
||||||
aria-invalid="false"
|
aria-invalid="false"
|
||||||
class="MuiInputBase-input-id MuiOutlinedInput-input-id MuiInputBase-inputAdornedEnd-id MuiOutlinedInput-inputAdornedEnd-id"
|
class="MuiInputBase-input-id MuiOutlinedInput-input-id MuiInputBase-inputAdornedEnd-id MuiOutlinedInput-inputAdornedEnd-id"
|
||||||
|
min="0"
|
||||||
name="costPrice"
|
name="costPrice"
|
||||||
type="number"
|
type="number"
|
||||||
value="12"
|
value="12"
|
||||||
|
@ -175399,6 +175411,7 @@ exports[`Storyshots Views / Products / Product variant details no warehouses 1`]
|
||||||
<input
|
<input
|
||||||
aria-invalid="false"
|
aria-invalid="false"
|
||||||
class="MuiInputBase-input-id MuiOutlinedInput-input-id MuiInputBase-inputAdornedEnd-id MuiOutlinedInput-inputAdornedEnd-id"
|
class="MuiInputBase-input-id MuiOutlinedInput-input-id MuiInputBase-inputAdornedEnd-id MuiOutlinedInput-inputAdornedEnd-id"
|
||||||
|
min="0"
|
||||||
name="price"
|
name="price"
|
||||||
type="number"
|
type="number"
|
||||||
value="100"
|
value="100"
|
||||||
|
@ -175445,6 +175458,7 @@ exports[`Storyshots Views / Products / Product variant details no warehouses 1`]
|
||||||
<input
|
<input
|
||||||
aria-invalid="false"
|
aria-invalid="false"
|
||||||
class="MuiInputBase-input-id MuiOutlinedInput-input-id MuiInputBase-inputAdornedEnd-id MuiOutlinedInput-inputAdornedEnd-id"
|
class="MuiInputBase-input-id MuiOutlinedInput-input-id MuiInputBase-inputAdornedEnd-id MuiOutlinedInput-inputAdornedEnd-id"
|
||||||
|
min="0"
|
||||||
name="costPrice"
|
name="costPrice"
|
||||||
type="number"
|
type="number"
|
||||||
value="12"
|
value="12"
|
||||||
|
@ -176646,6 +176660,7 @@ exports[`Storyshots Views / Products / Product variant details when loaded data
|
||||||
<input
|
<input
|
||||||
aria-invalid="false"
|
aria-invalid="false"
|
||||||
class="MuiInputBase-input-id MuiOutlinedInput-input-id MuiInputBase-inputAdornedEnd-id MuiOutlinedInput-inputAdornedEnd-id"
|
class="MuiInputBase-input-id MuiOutlinedInput-input-id MuiInputBase-inputAdornedEnd-id MuiOutlinedInput-inputAdornedEnd-id"
|
||||||
|
min="0"
|
||||||
name="price"
|
name="price"
|
||||||
type="number"
|
type="number"
|
||||||
value="100"
|
value="100"
|
||||||
|
@ -176692,6 +176707,7 @@ exports[`Storyshots Views / Products / Product variant details when loaded data
|
||||||
<input
|
<input
|
||||||
aria-invalid="false"
|
aria-invalid="false"
|
||||||
class="MuiInputBase-input-id MuiOutlinedInput-input-id MuiInputBase-inputAdornedEnd-id MuiOutlinedInput-inputAdornedEnd-id"
|
class="MuiInputBase-input-id MuiOutlinedInput-input-id MuiInputBase-inputAdornedEnd-id MuiOutlinedInput-inputAdornedEnd-id"
|
||||||
|
min="0"
|
||||||
name="costPrice"
|
name="costPrice"
|
||||||
type="number"
|
type="number"
|
||||||
value="12"
|
value="12"
|
||||||
|
@ -177765,6 +177781,7 @@ exports[`Storyshots Views / Products / Product variant details when loading data
|
||||||
aria-invalid="false"
|
aria-invalid="false"
|
||||||
class="MuiInputBase-input-id MuiOutlinedInput-input-id MuiInputBase-disabled-id MuiOutlinedInput-disabled-id MuiInputBase-inputAdornedEnd-id MuiOutlinedInput-inputAdornedEnd-id"
|
class="MuiInputBase-input-id MuiOutlinedInput-input-id MuiInputBase-disabled-id MuiOutlinedInput-disabled-id MuiInputBase-inputAdornedEnd-id MuiOutlinedInput-inputAdornedEnd-id"
|
||||||
disabled=""
|
disabled=""
|
||||||
|
min="0"
|
||||||
name="price"
|
name="price"
|
||||||
type="number"
|
type="number"
|
||||||
value=""
|
value=""
|
||||||
|
@ -177804,6 +177821,7 @@ exports[`Storyshots Views / Products / Product variant details when loading data
|
||||||
aria-invalid="false"
|
aria-invalid="false"
|
||||||
class="MuiInputBase-input-id MuiOutlinedInput-input-id MuiInputBase-disabled-id MuiOutlinedInput-disabled-id MuiInputBase-inputAdornedEnd-id MuiOutlinedInput-inputAdornedEnd-id"
|
class="MuiInputBase-input-id MuiOutlinedInput-input-id MuiInputBase-disabled-id MuiOutlinedInput-disabled-id MuiInputBase-inputAdornedEnd-id MuiOutlinedInput-inputAdornedEnd-id"
|
||||||
disabled=""
|
disabled=""
|
||||||
|
min="0"
|
||||||
name="costPrice"
|
name="costPrice"
|
||||||
type="number"
|
type="number"
|
||||||
value=""
|
value=""
|
||||||
|
|
11
src/utils/handlers/nonNegativeValueChangeHandler.ts
Normal file
11
src/utils/handlers/nonNegativeValueChangeHandler.ts
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
import { FormChange } from "@saleor/hooks/useForm";
|
||||||
|
|
||||||
|
function createNonNegativeValueChangeHandler(change: FormChange) {
|
||||||
|
return (event: React.ChangeEvent<any>) => {
|
||||||
|
if (/^\d*(\.\d+)?$/.test(event.target.value)) {
|
||||||
|
change(event);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default createNonNegativeValueChangeHandler;
|
Loading…
Reference in a new issue