Make warehouse and shipping work

This commit is contained in:
dominik-zeglen 2020-03-18 18:24:55 +01:00
parent 61db9d1476
commit 97ffc07738
9 changed files with 52 additions and 43 deletions

View file

@ -72,7 +72,7 @@ const useStyles = makeStyles(
export interface MultiAutocompleteSelectFieldProps export interface MultiAutocompleteSelectFieldProps
extends Partial<FetchMoreProps> { extends Partial<FetchMoreProps> {
add: MultiAutocompleteActionType; add?: MultiAutocompleteActionType;
allowCustomValues?: boolean; allowCustomValues?: boolean;
displayValues: MultiAutocompleteChoiceType[]; displayValues: MultiAutocompleteChoiceType[];
error?: boolean; error?: boolean;
@ -93,6 +93,7 @@ const DebounceAutocomplete: React.ComponentType<DebounceProps<
const MultiAutocompleteSelectFieldComponent: React.FC<MultiAutocompleteSelectFieldProps> = props => { const MultiAutocompleteSelectFieldComponent: React.FC<MultiAutocompleteSelectFieldProps> = props => {
const { const {
add,
allowCustomValues, allowCustomValues,
choices, choices,
displayValues, displayValues,
@ -131,6 +132,7 @@ const MultiAutocompleteSelectFieldComponent: React.FC<MultiAutocompleteSelectFie
itemToString={() => ""} itemToString={() => ""}
> >
{({ {({
closeMenu,
getInputProps, getInputProps,
getItemProps, getItemProps,
isOpen, isOpen,

View file

@ -34,7 +34,7 @@ export interface MultiAutocompleteChoiceType {
} }
export interface MultiAutocompleteSelectFieldContentProps export interface MultiAutocompleteSelectFieldContentProps
extends Partial<FetchMoreProps> { extends Partial<FetchMoreProps> {
add: MultiAutocompleteActionType; add?: MultiAutocompleteActionType;
choices: MultiAutocompleteChoiceType[]; choices: MultiAutocompleteChoiceType[];
displayCustomValue: boolean; displayCustomValue: boolean;
displayValues: MultiAutocompleteChoiceType[]; displayValues: MultiAutocompleteChoiceType[];
@ -45,6 +45,14 @@ export interface MultiAutocompleteSelectFieldContentProps
const useStyles = makeStyles( const useStyles = makeStyles(
theme => ({ theme => ({
add: {
background: theme.palette.background.default,
border: `1px solid ${theme.palette.divider}`,
borderRadius: "100%",
height: 24,
marginRight: theme.spacing(),
width: 24
},
addIcon: { addIcon: {
height: 24, height: 24,
margin: 9, margin: 9,
@ -106,6 +114,7 @@ const useStyles = makeStyles(
gridColumnGap: theme.spacing(1), gridColumnGap: theme.spacing(1),
gridTemplateColumns: "30px 1fr", gridTemplateColumns: "30px 1fr",
height: "auto", height: "auto",
marginBottom: theme.spacing(0.5),
padding: 0, padding: 0,
whiteSpace: "normal" whiteSpace: "normal"
}, },
@ -136,10 +145,11 @@ const useStyles = makeStyles(
function getChoiceIndex( function getChoiceIndex(
index: number, index: number,
displayValues: MultiAutocompleteChoiceType[], displayValues: MultiAutocompleteChoiceType[],
displayCustomValue: boolean displayCustomValue: boolean,
add: boolean
) { ) {
let choiceIndex = index; let choiceIndex = index;
if (displayCustomValue) { if (add || displayCustomValue) {
choiceIndex += 2; choiceIndex += 2;
} }
if (displayValues.length > 0) { if (displayValues.length > 0) {
@ -258,7 +268,8 @@ const MultiAutocompleteSelectFieldContent: React.FC<MultiAutocompleteSelectField
const choiceIndex = getChoiceIndex( const choiceIndex = getChoiceIndex(
index, index,
displayValues, displayValues,
displayCustomValue displayCustomValue,
!!add
); );
return ( return (

View file

@ -31,7 +31,7 @@ export interface SingleAutocompleteActionType {
} }
export interface SingleAutocompleteSelectFieldContentProps export interface SingleAutocompleteSelectFieldContentProps
extends Partial<FetchMoreProps> { extends Partial<FetchMoreProps> {
add: SingleAutocompleteActionType; add?: SingleAutocompleteActionType;
choices: SingleAutocompleteChoiceType[]; choices: SingleAutocompleteChoiceType[];
displayCustomValue: boolean; displayCustomValue: boolean;
emptyOption: boolean; emptyOption: boolean;

View file

@ -104,8 +104,8 @@ const ShippingZoneAddWarehouseDialog: React.FC<ShippingZoneAddWarehouseDialogPro
description="header, dialog" description="header, dialog"
/> />
</DialogTitle> </DialogTitle>
<Form errors={errors} initial={initialForm} onSubmit={handleSubmit}> <Form initial={initialForm} onSubmit={handleSubmit}>
{({ change, data, errors: formErrors }) => { {({ change, data }) => {
const handleCountrySelect = createSingleAutocompleteSelectHandler( const handleCountrySelect = createSingleAutocompleteSelectHandler(
change, change,
setCountryDisplayName, setCountryDisplayName,
@ -132,7 +132,7 @@ const ShippingZoneAddWarehouseDialog: React.FC<ShippingZoneAddWarehouseDialogPro
data={data} data={data}
disabled={disabled} disabled={disabled}
displayCountry={countryDisplayName} displayCountry={countryDisplayName}
errors={formErrors} errors={errors}
onChange={change} onChange={change}
onCountryChange={handleCountrySelect} onCountryChange={handleCountrySelect}
/> />

View file

@ -89,7 +89,7 @@ const ShippingZoneDetailsPage: React.FC<ShippingZoneDetailsPageProps> = ({
warehouses: shippingZone?.warehouses.map(warehouse => warehouse.id) || [] warehouses: shippingZone?.warehouses.map(warehouse => warehouse.id) || []
}; };
const [warehouseDisplayValues, setWarehouseDisplayValues] = useStateFromProps( const [warehouseDisplayValues, setWarehouseDisplayValues] = useStateFromProps(
shippingZone?.warehouses.map(warehouseToChoice) shippingZone?.warehouses.map(warehouseToChoice) || []
); );
const warehouseChoices = warehouses.map(warehouseToChoice); const warehouseChoices = warehouses.map(warehouseToChoice);

View file

@ -47,7 +47,7 @@ const initialForm: WarehouseCreatePageFormData = {
const WarehouseCreatePage: React.FC<WarehouseCreatePageProps> = ({ const WarehouseCreatePage: React.FC<WarehouseCreatePageProps> = ({
countries, countries,
disabled, disabled,
errors: apiErrors, errors,
saveButtonBarState, saveButtonBarState,
onBack, onBack,
onSubmit onSubmit
@ -61,12 +61,8 @@ const WarehouseCreatePage: React.FC<WarehouseCreatePageProps> = ({
} = useAddressValidation<WarehouseCreatePageFormData>(onSubmit); } = useAddressValidation<WarehouseCreatePageFormData>(onSubmit);
return ( return (
<Form <Form initial={initialForm} onSubmit={handleSubmit}>
initial={initialForm} {({ change, data, submit }) => {
errors={[...apiErrors, ...validationErrors]}
onSubmit={handleSubmit}
>
{({ change, data, errors, submit }) => {
const countryChoices = mapCountriesToChoices(countries); const countryChoices = mapCountriesToChoices(countries);
const handleCountryChange = createSingleAutocompleteSelectHandler( const handleCountryChange = createSingleAutocompleteSelectHandler(
change, change,
@ -99,7 +95,7 @@ const WarehouseCreatePage: React.FC<WarehouseCreatePageProps> = ({
data={data} data={data}
disabled={disabled} disabled={disabled}
displayCountry={displayCountry} displayCountry={displayCountry}
errors={errors} errors={[...errors, ...validationErrors]}
header={intl.formatMessage({ header={intl.formatMessage({
defaultMessage: "Address Information", defaultMessage: "Address Information",
description: "warehouse" description: "warehouse"

View file

@ -42,7 +42,7 @@ export interface WarehouseDetailsPageProps {
const WarehouseDetailsPage: React.FC<WarehouseDetailsPageProps> = ({ const WarehouseDetailsPage: React.FC<WarehouseDetailsPageProps> = ({
countries, countries,
disabled, disabled,
errors: apiErrors, errors,
saveButtonBarState, saveButtonBarState,
warehouse, warehouse,
onBack, onBack,
@ -73,12 +73,8 @@ const WarehouseDetailsPage: React.FC<WarehouseDetailsPageProps> = ({
}; };
return ( return (
<Form <Form initial={initialForm} onSubmit={handleSubmit}>
initial={initialForm} {({ change, data, submit }) => {
errors={[...apiErrors, ...validationErrors]}
onSubmit={handleSubmit}
>
{({ change, data, errors, submit }) => {
const countryChoices = mapCountriesToChoices(countries); const countryChoices = mapCountriesToChoices(countries);
const handleCountryChange = createSingleAutocompleteSelectHandler( const handleCountryChange = createSingleAutocompleteSelectHandler(
change, change,
@ -106,7 +102,7 @@ const WarehouseDetailsPage: React.FC<WarehouseDetailsPageProps> = ({
data={data} data={data}
disabled={disabled} disabled={disabled}
displayCountry={displayCountry} displayCountry={displayCountry}
errors={errors} errors={[...errors, ...validationErrors]}
header={intl.formatMessage({ header={intl.formatMessage({
defaultMessage: "Address Information", defaultMessage: "Address Information",
description: "warehouse" description: "warehouse"
@ -117,9 +113,7 @@ const WarehouseDetailsPage: React.FC<WarehouseDetailsPageProps> = ({
</div> </div>
<div> <div>
<WarehouseZones <WarehouseZones
zones={maybe(() => zones={warehouse?.shippingZones?.edges.map(edge => edge.node)}
warehouse.shippingZones.edges.map(edge => edge.node)
)}
onShippingZoneClick={onShippingZoneClick} onShippingZoneClick={onShippingZoneClick}
/> />
</div> </div>

View file

@ -7,12 +7,13 @@ import { useIntl } from "react-intl";
import CardTitle from "@saleor/components/CardTitle"; import CardTitle from "@saleor/components/CardTitle";
import { commonMessages } from "@saleor/intl"; import { commonMessages } from "@saleor/intl";
import { FormChange } from "@saleor/hooks/useForm"; import { FormChange } from "@saleor/hooks/useForm";
import { FormErrors } from "@saleor/types"; import { UserError } from "@saleor/types";
import { getFieldError } from "@saleor/utils/errors";
export interface WarehouseInfoProps { export interface WarehouseInfoProps {
data: Record<"name", string>; data: Record<"name", string>;
disabled: boolean; disabled: boolean;
errors: FormErrors<"name">; errors: UserError[];
onChange: FormChange; onChange: FormChange;
} }
@ -32,9 +33,9 @@ const WarehouseInfo: React.FC<WarehouseInfoProps> = ({
<CardContent> <CardContent>
<TextField <TextField
disabled={disabled} disabled={disabled}
error={!!errors.name} error={!!getFieldError(errors, "name")}
fullWidth fullWidth
helperText={errors.name} helperText={getFieldError(errors, "name")?.message}
label={intl.formatMessage({ label={intl.formatMessage({
defaultMessage: "Warehouse Name" defaultMessage: "Warehouse Name"
})} })}

View file

@ -11,7 +11,11 @@ import {
import { useWarehouseDetails } from "@saleor/warehouses/queries"; import { useWarehouseDetails } from "@saleor/warehouses/queries";
import { commonMessages } from "@saleor/intl"; import { commonMessages } from "@saleor/intl";
import useNotifier from "@saleor/hooks/useNotifier"; import useNotifier from "@saleor/hooks/useNotifier";
import { maybe, findValueInEnum, getMutationStatus } from "@saleor/misc"; import {
findValueInEnum,
getMutationStatus,
getStringOrPlaceholder
} from "@saleor/misc";
import { CountryCode } from "@saleor/types/globalTypes"; import { CountryCode } from "@saleor/types/globalTypes";
import useShop from "@saleor/hooks/useShop"; import useShop from "@saleor/hooks/useShop";
import { WindowTitle } from "@saleor/components/WindowTitle"; import { WindowTitle } from "@saleor/components/WindowTitle";
@ -22,6 +26,7 @@ import {
import { shippingZoneUrl } from "@saleor/shipping/urls"; import { shippingZoneUrl } from "@saleor/shipping/urls";
import WarehouseDeleteDialog from "@saleor/warehouses/components/WarehouseDeleteDialog"; import WarehouseDeleteDialog from "@saleor/warehouses/components/WarehouseDeleteDialog";
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers"; import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
import NotFoundPage from "@saleor/components/NotFoundPage";
export interface WarehouseDetailsProps { export interface WarehouseDetailsProps {
id: string; id: string;
@ -35,7 +40,6 @@ const WarehouseDetails: React.FC<WarehouseDetailsProps> = ({ id, params }) => {
const shop = useShop(); const shop = useShop();
const { data, loading } = useWarehouseDetails({ const { data, loading } = useWarehouseDetails({
displayLoader: true, displayLoader: true,
require: ["warehouse"],
variables: { id } variables: { id }
}); });
const [updateWarehouse, updateWarehouseOpts] = useWarehouseUpdate({ const [updateWarehouse, updateWarehouseOpts] = useWarehouseUpdate({
@ -65,18 +69,19 @@ const WarehouseDetails: React.FC<WarehouseDetailsProps> = ({ id, params }) => {
params params
); );
if (data?.warehouse === null) {
return <NotFoundPage onBack={() => navigate(warehouseListUrl())} />;
}
return ( return (
<> <>
<WindowTitle title={maybe(() => data.warehouse.name)} /> <WindowTitle title={data?.warehouse?.name} />
<WarehouseDetailsPage <WarehouseDetailsPage
countries={maybe(() => shop.countries, [])} countries={shop?.countries || []}
disabled={loading || updateWarehouseOpts.loading} disabled={loading || updateWarehouseOpts.loading}
errors={maybe( errors={updateWarehouseOpts.data?.updateWarehouse.errors || []}
() => updateWarehouseOpts.data.updateWarehouse.errors,
[]
)}
saveButtonBarState={updateWarehouseTransitionState} saveButtonBarState={updateWarehouseTransitionState}
warehouse={maybe(() => data.warehouse)} warehouse={data?.warehouse}
onBack={() => navigate(warehouseListUrl())} onBack={() => navigate(warehouseListUrl())}
onDelete={() => openModal("delete")} onDelete={() => openModal("delete")}
onShippingZoneClick={id => navigate(shippingZoneUrl(id))} onShippingZoneClick={id => navigate(shippingZoneUrl(id))}
@ -103,7 +108,7 @@ const WarehouseDetails: React.FC<WarehouseDetailsProps> = ({ id, params }) => {
/> />
<WarehouseDeleteDialog <WarehouseDeleteDialog
confirmButtonState={deleteWarehouseTransitionState} confirmButtonState={deleteWarehouseTransitionState}
name={maybe(() => data.warehouse.name)} name={getStringOrPlaceholder(data?.warehouse?.name)}
onClose={closeModal} onClose={closeModal}
onConfirm={() => onConfirm={() =>
deleteWarehouse({ deleteWarehouse({