This commit is contained in:
dominik-zeglen 2020-02-03 12:01:18 +01:00
parent 34698b7d6f
commit ed3e9fbc45
11 changed files with 316 additions and 80 deletions

View file

@ -0,0 +1,42 @@
/* tslint:disable */
/* eslint-disable */
// This file was automatically generated and should not be edited.
// ====================================================
// GraphQL query operation: SearchWarehouses
// ====================================================
export interface SearchWarehouses_search_edges_node {
__typename: "Warehouse";
id: string;
name: string;
}
export interface SearchWarehouses_search_edges {
__typename: "WarehouseCountableEdge";
node: SearchWarehouses_search_edges_node;
}
export interface SearchWarehouses_search_pageInfo {
__typename: "PageInfo";
endCursor: string | null;
hasNextPage: boolean;
hasPreviousPage: boolean;
startCursor: string | null;
}
export interface SearchWarehouses_search {
__typename: "WarehouseCountableConnection";
edges: SearchWarehouses_search_edges[];
pageInfo: SearchWarehouses_search_pageInfo;
}
export interface SearchWarehouses {
search: SearchWarehouses_search | null;
}
export interface SearchWarehousesVariables {
after?: string | null;
first: number;
query: string;
}

View file

@ -0,0 +1,33 @@
import gql from "graphql-tag";
import makeTopLevelSearch from "@saleor/hooks/makeTopLevelSearch";
import { pageInfoFragment } from "@saleor/queries";
import {
SearchWarehouses,
SearchWarehousesVariables
} from "./types/SearchWarehouses";
export const searchWarehouses = gql`
${pageInfoFragment}
query SearchWarehouses($after: String, $first: Int!, $query: String!) {
search: warehouses(
after: $after
first: $first
filter: { search: $query }
) {
edges {
node {
id
name
}
}
pageInfo {
...PageInfoFragment
}
}
}
`;
export default makeTopLevelSearch<SearchWarehouses, SearchWarehousesVariables>(
searchWarehouses
);

View file

@ -11,14 +11,21 @@ import Grid from "@saleor/components/Grid";
import PageHeader from "@saleor/components/PageHeader";
import SaveButtonBar from "@saleor/components/SaveButtonBar";
import { ShippingErrorFragment } from "@saleor/shipping/types/ShippingErrorFragment";
import createMultiAutocompleteSelectHandler from "@saleor/utils/handlers/multiAutocompleteSelectChangeHandler";
import { MultiAutocompleteChoiceType } from "@saleor/components/MultiAutocompleteSelectField";
import { maybe, getStringOrPlaceholder } from "../../../misc";
import { ShippingMethodTypeEnum } from "../../../types/globalTypes";
import { ShippingZoneDetailsFragment } from "../../types/ShippingZoneDetailsFragment";
import {
ShippingZoneDetailsFragment,
ShippingZoneDetailsFragment_warehouses
} from "../../types/ShippingZoneDetailsFragment";
import ShippingZoneInfo from "../ShippingZoneInfo";
import ShippingZoneRates from "../ShippingZoneRates";
import ShippingZoneWarehouses from "../ShippingZoneWarehouses";
export interface FormData {
name: string;
warehouses: string[];
}
export interface ShippingZoneDetailsPageProps {
@ -26,6 +33,7 @@ export interface ShippingZoneDetailsPageProps {
errors: ShippingErrorFragment[];
saveButtonBarState: ConfirmButtonTransitionState;
shippingZone: ShippingZoneDetailsFragment;
warehouses: ShippingZoneDetailsFragment_warehouses[];
onBack: () => void;
onCountryAdd: () => void;
onCountryRemove: (code: string) => void;
@ -38,6 +46,15 @@ export interface ShippingZoneDetailsPageProps {
onWeightRateEdit: (id: string) => void;
}
function warehouseToChoice(
warehouse: Record<"id" | "name", string>
): MultiAutocompleteChoiceType {
return {
label: warehouse.name,
value: warehouse.id
};
}
const ShippingZoneDetailsPage: React.FC<ShippingZoneDetailsPageProps> = ({
disabled,
errors,
@ -52,90 +69,117 @@ const ShippingZoneDetailsPage: React.FC<ShippingZoneDetailsPageProps> = ({
onWeightRateAdd,
onWeightRateEdit,
saveButtonBarState,
shippingZone
shippingZone,
warehouses
}) => {
const intl = useIntl();
const initialForm: FormData = {
name: shippingZone?.name || ""
name: shippingZone?.name || "",
warehouses: shippingZone?.warehouses.map(warehouse => warehouse.id) || []
};
const [warehouseDisplayValues, setWarehouseDisplayValues] = React.useState(
shippingZone?.warehouses.map(warehouseToChoice)
);
const warehouseChoices = warehouses.map(warehouseToChoice);
return (
<Form initial={initialForm} onSubmit={onSubmit}>
{({ change, data, hasChanged, submit }) => (
<Container>
<AppHeader onBack={onBack}>
<FormattedMessage defaultMessage="Shipping" />
</AppHeader>
<PageHeader title={getStringOrPlaceholder(shippingZone?.name)} />
<Grid>
<div>
<ShippingZoneInfo
data={data}
disabled={disabled}
errors={errors}
onChange={change}
/>
<CardSpacer />
<CountryList
countries={shippingZone?.countries}
disabled={disabled}
emptyText={maybe(
() =>
shippingZone.default
? intl.formatMessage({
defaultMessage:
"This is default shipping zone, which means that it covers all of the countries which are not assigned to other shipping zones"
})
: intl.formatMessage({
defaultMessage:
"Currently, there are no countries assigned to this shipping zone"
}),
"..."
)}
onCountryAssign={onCountryAdd}
onCountryUnassign={onCountryRemove}
title={intl.formatMessage({
defaultMessage: "Countries"
})}
/>
<CardSpacer />
<ShippingZoneRates
disabled={disabled}
onRateAdd={onPriceRateAdd}
onRateEdit={onPriceRateEdit}
onRateRemove={onRateRemove}
rates={maybe(() =>
shippingZone.shippingMethods.filter(
method => method.type === ShippingMethodTypeEnum.PRICE
)
)}
variant="price"
/>
<CardSpacer />
<ShippingZoneRates
disabled={disabled}
onRateAdd={onWeightRateAdd}
onRateEdit={onWeightRateEdit}
onRateRemove={onRateRemove}
rates={maybe(() =>
shippingZone.shippingMethods.filter(
method => method.type === ShippingMethodTypeEnum.WEIGHT
)
)}
variant="weight"
/>
</div>
</Grid>
<SaveButtonBar
disabled={disabled || !hasChanged}
onCancel={onBack}
onDelete={onDelete}
onSave={submit}
state={saveButtonBarState}
/>
</Container>
)}
{({ change, data, hasChanged, submit }) => {
const handleWarehouseChange = createMultiAutocompleteSelectHandler(
change,
setWarehouseDisplayValues,
warehouseDisplayValues,
warehouseChoices
);
return (
<Container>
<AppHeader onBack={onBack}>
<FormattedMessage defaultMessage="Shipping" />
</AppHeader>
<PageHeader title={shippingZone?.name} />
<Grid>
<div>
<ShippingZoneInfo
data={data}
disabled={disabled}
errors={errors}
onChange={change}
/>
<CardSpacer />
<CountryList
countries={shippingZone?.countries}
disabled={disabled}
emptyText={maybe(
() =>
shippingZone.default
? intl.formatMessage({
defaultMessage:
"This is default shipping zone, which means that it covers all of the countries which are not assigned to other shipping zones"
})
: intl.formatMessage({
defaultMessage:
"Currently, there are no countries assigned to this shipping zone"
}),
"..."
)}
onCountryAssign={onCountryAdd}
onCountryUnassign={onCountryRemove}
title={intl.formatMessage({
defaultMessage: "Countries"
})}
/>
<CardSpacer />
<ShippingZoneRates
disabled={disabled}
onRateAdd={onPriceRateAdd}
onRateEdit={onPriceRateEdit}
onRateRemove={onRateRemove}
rates={maybe(() =>
shippingZone.shippingMethods.filter(
method => method.type === ShippingMethodTypeEnum.PRICE
)
)}
variant="price"
/>
<CardSpacer />
<ShippingZoneRates
disabled={disabled}
onRateAdd={onWeightRateAdd}
onRateEdit={onWeightRateEdit}
onRateRemove={onRateRemove}
rates={maybe(() =>
shippingZone.shippingMethods.filter(
method => method.type === ShippingMethodTypeEnum.WEIGHT
)
)}
variant="weight"
/>
</div>
<div>
<ShippingZoneWarehouses
data={data}
displayValue={warehouseDisplayValues}
hasMore={false}
loading={false}
onChange={handleWarehouseChange}
onFetchMore={() => undefined}
warehouses={warehouseChoices}
/>
</div>
</Grid>
<SaveButtonBar
disabled={disabled || !hasChanged}
onCancel={onBack}
onDelete={onDelete}
onSave={submit}
state={saveButtonBarState}
/>
</Container>
);
}}
</Form>
);
};

View file

@ -0,0 +1,60 @@
import Card from "@material-ui/core/Card";
import CardContent from "@material-ui/core/CardContent";
import React from "react";
import { useIntl } from "react-intl";
import CardTitle from "@saleor/components/CardTitle";
import { FetchMoreProps } from "@saleor/types";
import { FormChange } from "@saleor/hooks/useForm";
import MultiAutocompleteSelectField, {
MultiAutocompleteChoiceType
} from "@saleor/components/MultiAutocompleteSelectField";
interface ShippingZoneWarehousesFormData {
warehouses: string[];
}
interface ShippingZonewWarehousesProps extends FetchMoreProps {
data: ShippingZoneWarehousesFormData;
displayValue: MultiAutocompleteChoiceType[];
warehouses: MultiAutocompleteChoiceType[];
onChange: FormChange;
}
export const ShippingZoneWarehouses: React.FC<ShippingZonewWarehousesProps> = props => {
const {
data,
displayValue,
hasMore,
loading,
onChange,
onFetchMore,
warehouses
} = props;
const intl = useIntl();
return (
<Card>
<CardTitle
title={intl.formatMessage({
defaultMessage: "Visibility",
description: "section header"
})}
/>
<CardContent>
<MultiAutocompleteSelectField
choices={warehouses}
displayValues={displayValue}
fetchChoices={() => undefined}
hasMore={hasMore}
loading={loading}
name="warehouse"
onChange={onChange}
onFetchMore={onFetchMore}
value={data.warehouses}
/>
</CardContent>
</Card>
);
};
ShippingZoneWarehouses.displayName = "ShippingZoneWarehouses";
export default ShippingZoneWarehouses;

View file

@ -0,0 +1,2 @@
export { default } from "./ShippingZoneWarehouses";
export * from "./ShippingZoneWarehouses";

View file

@ -50,6 +50,10 @@ export const shippingZoneDetailsFragment = gql`
shippingMethods {
...ShippingMethodFragment
}
warehouses {
id
name
}
}
`;

View file

@ -62,6 +62,12 @@ export interface CreateShippingRate_shippingPriceCreate_shippingZone_shippingMet
type: ShippingMethodTypeEnum | null;
}
export interface CreateShippingRate_shippingPriceCreate_shippingZone_warehouses {
__typename: "Warehouse";
id: string;
name: string;
}
export interface CreateShippingRate_shippingPriceCreate_shippingZone {
__typename: "ShippingZone";
id: string;
@ -69,6 +75,7 @@ export interface CreateShippingRate_shippingPriceCreate_shippingZone {
name: string;
default: boolean;
shippingMethods: (CreateShippingRate_shippingPriceCreate_shippingZone_shippingMethods | null)[] | null;
warehouses: (CreateShippingRate_shippingPriceCreate_shippingZone_warehouses | null)[] | null;
}
export interface CreateShippingRate_shippingPriceCreate {

View file

@ -62,6 +62,12 @@ export interface DeleteShippingRate_shippingPriceDelete_shippingZone_shippingMet
type: ShippingMethodTypeEnum | null;
}
export interface DeleteShippingRate_shippingPriceDelete_shippingZone_warehouses {
__typename: "Warehouse";
id: string;
name: string;
}
export interface DeleteShippingRate_shippingPriceDelete_shippingZone {
__typename: "ShippingZone";
id: string;
@ -69,6 +75,7 @@ export interface DeleteShippingRate_shippingPriceDelete_shippingZone {
name: string;
default: boolean;
shippingMethods: (DeleteShippingRate_shippingPriceDelete_shippingZone_shippingMethods | null)[] | null;
warehouses: (DeleteShippingRate_shippingPriceDelete_shippingZone_warehouses | null)[] | null;
}
export interface DeleteShippingRate_shippingPriceDelete {

View file

@ -56,6 +56,12 @@ export interface ShippingZone_shippingZone_shippingMethods {
type: ShippingMethodTypeEnum | null;
}
export interface ShippingZone_shippingZone_warehouses {
__typename: "Warehouse";
id: string;
name: string;
}
export interface ShippingZone_shippingZone {
__typename: "ShippingZone";
id: string;
@ -63,6 +69,7 @@ export interface ShippingZone_shippingZone {
name: string;
default: boolean;
shippingMethods: (ShippingZone_shippingZone_shippingMethods | null)[] | null;
warehouses: (ShippingZone_shippingZone_warehouses | null)[] | null;
}
export interface ShippingZone {

View file

@ -56,6 +56,12 @@ export interface ShippingZoneDetailsFragment_shippingMethods {
type: ShippingMethodTypeEnum | null;
}
export interface ShippingZoneDetailsFragment_warehouses {
__typename: "Warehouse";
id: string;
name: string;
}
export interface ShippingZoneDetailsFragment {
__typename: "ShippingZone";
id: string;
@ -63,4 +69,5 @@ export interface ShippingZoneDetailsFragment {
name: string;
default: boolean;
shippingMethods: (ShippingZoneDetailsFragment_shippingMethods | null)[] | null;
warehouses: (ShippingZoneDetailsFragment_warehouses | null)[] | null;
}

View file

@ -4,6 +4,9 @@ import { useIntl } from "react-intl";
import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier";
import { commonMessages } from "@saleor/intl";
import useWarehouseSearch from "@saleor/searches/useWarehouseSearch";
import { DEFAULT_INITIAL_SEARCH_DATA } from "@saleor/config";
import { useWarehouseUpdate } from "@saleor/warehouses/mutations";
import { maybe } from "../../../misc";
import { ShippingMethodTypeEnum } from "../../../types/globalTypes";
import ShippingZoneDetailsPage from "../../components/ShippingZoneDetailsPage";
@ -33,6 +36,14 @@ const ShippingZoneDetails: React.FC<ShippingZoneDetailsProps> = ({
const navigate = useNavigator();
const notify = useNotifier();
const intl = useIntl();
const [updateWarehouse, updateWarehouseOpts] = useWarehouseUpdate({});
const {
search: searchWarehouses,
result: searchWarehousesOpts
} = useWarehouseSearch({
variables: DEFAULT_INITIAL_SEARCH_DATA
});
const closeModal = () => navigate(shippingZoneUrl(id), true);
@ -146,14 +157,19 @@ const ShippingZoneDetails: React.FC<ShippingZoneDetailsProps> = ({
})
)
}
onSubmit={formData =>
onSubmit={formData => {
ops.shippingZoneUpdate.mutate({
id,
input: {
name: formData.name
}
})
}
});
updateWarehouse({
variables: {
id: formData.warehouse
}
});
}}
onWeightRateAdd={() =>
navigate(
shippingZoneUrl(id, {
@ -172,6 +188,13 @@ const ShippingZoneDetails: React.FC<ShippingZoneDetailsProps> = ({
}
saveButtonBarState={ops.shippingZoneUpdate.opts.status}
shippingZone={maybe(() => data.shippingZone)}
warehouses={maybe(
() =>
searchWarehousesOpts.data.search.edges.map(
edge => edge.node
),
[]
)}
/>
<ShippingZoneDetailsDialogs
assignCountryTransitionState={