Add warehouse create action button
This commit is contained in:
parent
3d838d8428
commit
60ec16961c
9 changed files with 108 additions and 9 deletions
|
@ -12,7 +12,8 @@ import Debounce, { DebounceProps } from "@saleor/components/Debounce";
|
|||
import ArrowDropdownIcon from "@saleor/icons/ArrowDropdown";
|
||||
import { FetchMoreProps } from "@saleor/types";
|
||||
import MultiAutocompleteSelectFieldContent, {
|
||||
MultiAutocompleteChoiceType
|
||||
MultiAutocompleteChoiceType,
|
||||
MultiAutocompleteActionType
|
||||
} from "./MultiAutocompleteSelectFieldContent";
|
||||
|
||||
const useStyles = makeStyles(
|
||||
|
@ -71,6 +72,7 @@ const useStyles = makeStyles(
|
|||
|
||||
export interface MultiAutocompleteSelectFieldProps
|
||||
extends Partial<FetchMoreProps> {
|
||||
add: MultiAutocompleteActionType;
|
||||
allowCustomValues?: boolean;
|
||||
displayValues: MultiAutocompleteChoiceType[];
|
||||
error?: boolean;
|
||||
|
@ -166,6 +168,13 @@ const MultiAutocompleteSelectFieldComponent: React.FC<MultiAutocompleteSelectFie
|
|||
/>
|
||||
{isOpen && (!!inputValue || !!choices.length) && (
|
||||
<MultiAutocompleteSelectFieldContent
|
||||
add={{
|
||||
...add,
|
||||
onClick: () => {
|
||||
add.onClick();
|
||||
closeMenu();
|
||||
}
|
||||
}}
|
||||
choices={choices.filter(
|
||||
choice => !value.includes(choice.value)
|
||||
)}
|
||||
|
|
|
@ -7,6 +7,7 @@ import { FormattedMessage } from "react-intl";
|
|||
import chevronDown from "@assets/images/ChevronDown.svg";
|
||||
import CircularProgress from "@material-ui/core/CircularProgress";
|
||||
import MenuItem from "@material-ui/core/MenuItem";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import Paper from "@material-ui/core/Paper";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import AddIcon from "@material-ui/icons/Add";
|
||||
|
@ -22,6 +23,10 @@ const menuItemHeight = 46;
|
|||
const maxMenuItems = 5;
|
||||
const offset = 24;
|
||||
|
||||
export interface MultiAutocompleteActionType {
|
||||
label: string;
|
||||
onClick: () => void;
|
||||
}
|
||||
export interface MultiAutocompleteChoiceType {
|
||||
label: string;
|
||||
value: any;
|
||||
|
@ -29,6 +34,7 @@ export interface MultiAutocompleteChoiceType {
|
|||
}
|
||||
export interface MultiAutocompleteSelectFieldContentProps
|
||||
extends Partial<FetchMoreProps> {
|
||||
add: MultiAutocompleteActionType;
|
||||
choices: MultiAutocompleteChoiceType[];
|
||||
displayCustomValue: boolean;
|
||||
displayValues: MultiAutocompleteChoiceType[];
|
||||
|
@ -145,6 +151,7 @@ function getChoiceIndex(
|
|||
|
||||
const MultiAutocompleteSelectFieldContent: React.FC<MultiAutocompleteSelectFieldContentProps> = props => {
|
||||
const {
|
||||
add,
|
||||
choices,
|
||||
displayCustomValue,
|
||||
displayValues,
|
||||
|
@ -156,6 +163,10 @@ const MultiAutocompleteSelectFieldContent: React.FC<MultiAutocompleteSelectField
|
|||
onFetchMore
|
||||
} = props;
|
||||
|
||||
if (!!add && !!displayCustomValue) {
|
||||
throw new Error("Add and custom value cannot be displayed simultaneously");
|
||||
}
|
||||
|
||||
const classes = useStyles(props);
|
||||
const anchor = React.useRef<HTMLDivElement>();
|
||||
const scrollPosition = useElementScroll(anchor);
|
||||
|
@ -183,6 +194,20 @@ const MultiAutocompleteSelectFieldContent: React.FC<MultiAutocompleteSelectField
|
|||
displayValues.length > 0 ||
|
||||
displayCustomValue ? (
|
||||
<>
|
||||
{add && (
|
||||
<MenuItem
|
||||
className={classes.menuItem}
|
||||
component="div"
|
||||
{...getItemProps({
|
||||
item: inputValue
|
||||
})}
|
||||
data-tc="multiautocomplete-select-option-add"
|
||||
onClick={add.onClick}
|
||||
>
|
||||
<AddIcon color="primary" className={classes.addIcon} />
|
||||
<Typography color="primary">{add.label}</Typography>
|
||||
</MenuItem>
|
||||
)}
|
||||
{displayCustomValue && (
|
||||
<MenuItem
|
||||
className={classes.menuItem}
|
||||
|
|
|
@ -69,6 +69,7 @@ const Story: React.FC<Partial<
|
|||
};
|
||||
|
||||
const contentProps: SingleAutocompleteSelectFieldContentProps = {
|
||||
add: undefined,
|
||||
choices: suggestions.slice(0, 10),
|
||||
displayCustomValue: false,
|
||||
emptyOption: false,
|
||||
|
@ -88,6 +89,15 @@ storiesOf("Generics / Select with autocomplete", module)
|
|||
.add("default", () => (
|
||||
<SingleAutocompleteSelectFieldContent {...contentProps} />
|
||||
))
|
||||
.add("with add", () => (
|
||||
<SingleAutocompleteSelectFieldContent
|
||||
{...contentProps}
|
||||
add={{
|
||||
label: "Add New Collection",
|
||||
onClick: () => undefined
|
||||
}}
|
||||
/>
|
||||
))
|
||||
.add("can load more", () => (
|
||||
<SingleAutocompleteSelectFieldContent {...contentProps} hasMore={true} />
|
||||
))
|
||||
|
|
|
@ -10,7 +10,8 @@ import { FetchMoreProps } from "@saleor/types";
|
|||
import ArrowDropdownIcon from "../../icons/ArrowDropdown";
|
||||
import Debounce, { DebounceProps } from "../Debounce";
|
||||
import SingleAutocompleteSelectFieldContent, {
|
||||
SingleAutocompleteChoiceType
|
||||
SingleAutocompleteChoiceType,
|
||||
SingleAutocompleteActionType
|
||||
} from "./SingleAutocompleteSelectFieldContent";
|
||||
|
||||
const useStyles = makeStyles(
|
||||
|
@ -25,6 +26,7 @@ const useStyles = makeStyles(
|
|||
|
||||
export interface SingleAutocompleteSelectFieldProps
|
||||
extends Partial<FetchMoreProps> {
|
||||
add: SingleAutocompleteActionType;
|
||||
error?: boolean;
|
||||
name: string;
|
||||
displayValue: string;
|
||||
|
@ -47,6 +49,7 @@ const DebounceAutocomplete: React.ComponentType<DebounceProps<
|
|||
|
||||
const SingleAutocompleteSelectFieldComponent: React.FC<SingleAutocompleteSelectFieldProps> = props => {
|
||||
const {
|
||||
add,
|
||||
allowCustomValues,
|
||||
choices,
|
||||
disabled,
|
||||
|
@ -144,6 +147,13 @@ const SingleAutocompleteSelectFieldComponent: React.FC<SingleAutocompleteSelectF
|
|||
/>
|
||||
{isOpen && (!!inputValue || !!choices.length) && (
|
||||
<SingleAutocompleteSelectFieldContent
|
||||
add={{
|
||||
...add,
|
||||
onClick: () => {
|
||||
add.onClick();
|
||||
closeMenu();
|
||||
}
|
||||
}}
|
||||
choices={choices}
|
||||
displayCustomValue={displayCustomValue}
|
||||
emptyOption={emptyOption}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import CircularProgress from "@material-ui/core/CircularProgress";
|
||||
import MenuItem from "@material-ui/core/MenuItem";
|
||||
import Add from "@material-ui/icons/Add";
|
||||
import Paper from "@material-ui/core/Paper";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
|
@ -24,8 +25,13 @@ export interface SingleAutocompleteChoiceType {
|
|||
label: string;
|
||||
value: any;
|
||||
}
|
||||
export interface SingleAutocompleteActionType {
|
||||
label: string;
|
||||
onClick: () => void;
|
||||
}
|
||||
export interface SingleAutocompleteSelectFieldContentProps
|
||||
extends Partial<FetchMoreProps> {
|
||||
add: SingleAutocompleteActionType;
|
||||
choices: SingleAutocompleteChoiceType[];
|
||||
displayCustomValue: boolean;
|
||||
emptyOption: boolean;
|
||||
|
@ -38,6 +44,14 @@ export interface SingleAutocompleteSelectFieldContentProps
|
|||
|
||||
const useStyles = makeStyles(
|
||||
theme => ({
|
||||
add: {
|
||||
background: theme.palette.background.default,
|
||||
border: `1px solid ${theme.palette.divider}`,
|
||||
borderRadius: "100%",
|
||||
height: 24,
|
||||
marginRight: theme.spacing(),
|
||||
width: 24
|
||||
},
|
||||
arrowContainer: {
|
||||
position: "relative"
|
||||
},
|
||||
|
@ -109,10 +123,9 @@ function getChoiceIndex(
|
|||
return choiceIndex;
|
||||
}
|
||||
|
||||
const SingleAutocompleteSelectFieldContent: React.FC<
|
||||
SingleAutocompleteSelectFieldContentProps
|
||||
> = props => {
|
||||
const SingleAutocompleteSelectFieldContent: React.FC<SingleAutocompleteSelectFieldContentProps> = props => {
|
||||
const {
|
||||
add,
|
||||
choices,
|
||||
displayCustomValue,
|
||||
emptyOption,
|
||||
|
@ -125,6 +138,10 @@ const SingleAutocompleteSelectFieldContent: React.FC<
|
|||
onFetchMore
|
||||
} = props;
|
||||
|
||||
if (!!add && !!displayCustomValue) {
|
||||
throw new Error("Add and custom value cannot be displayed simultaneously");
|
||||
}
|
||||
|
||||
const classes = useStyles(props);
|
||||
const anchor = React.useRef<HTMLDivElement>();
|
||||
const scrollPosition = useElementScroll(anchor);
|
||||
|
@ -164,6 +181,20 @@ const SingleAutocompleteSelectFieldContent: React.FC<
|
|||
</Typography>
|
||||
</MenuItem>
|
||||
)}
|
||||
{add && (
|
||||
<MenuItem
|
||||
className={classes.menuItem}
|
||||
component="div"
|
||||
{...getItemProps({
|
||||
item: inputValue
|
||||
})}
|
||||
data-tc="singleautocomplete-select-option-add"
|
||||
onClick={add.onClick}
|
||||
>
|
||||
<Add color="primary" className={classes.add} />
|
||||
<Typography color="primary">{add.label}</Typography>
|
||||
</MenuItem>
|
||||
)}
|
||||
{displayCustomValue && (
|
||||
<MenuItem
|
||||
className={classes.menuItem}
|
||||
|
@ -184,14 +215,14 @@ const SingleAutocompleteSelectFieldContent: React.FC<
|
|||
/>
|
||||
</MenuItem>
|
||||
)}
|
||||
{choices.length > 0 && displayCustomValue && (
|
||||
{choices.length > 0 && (!!add || displayCustomValue) && (
|
||||
<Hr className={classes.hr} />
|
||||
)}
|
||||
{choices.map((suggestion, index) => {
|
||||
const choiceIndex = getChoiceIndex(
|
||||
index,
|
||||
emptyOption,
|
||||
displayCustomValue
|
||||
!!add || displayCustomValue
|
||||
);
|
||||
|
||||
return (
|
||||
|
|
|
@ -43,6 +43,7 @@ export interface ShippingZoneDetailsPageProps {
|
|||
onPriceRateEdit: (id: string) => void;
|
||||
onRateRemove: (rateId: string) => void;
|
||||
onSubmit: (data: FormData) => void;
|
||||
onWarehouseAdd: () => void;
|
||||
onWeightRateAdd: () => void;
|
||||
onWeightRateEdit: (id: string) => void;
|
||||
}
|
||||
|
@ -67,6 +68,7 @@ const ShippingZoneDetailsPage: React.FC<ShippingZoneDetailsPageProps> = ({
|
|||
onPriceRateEdit,
|
||||
onRateRemove,
|
||||
onSubmit,
|
||||
onWarehouseAdd,
|
||||
onWeightRateAdd,
|
||||
onWeightRateEdit,
|
||||
saveButtonBarState,
|
||||
|
@ -165,9 +167,10 @@ const ShippingZoneDetailsPage: React.FC<ShippingZoneDetailsPageProps> = ({
|
|||
displayValue={warehouseDisplayValues}
|
||||
hasMore={false}
|
||||
loading={false}
|
||||
warehouses={warehouseChoices}
|
||||
onChange={handleWarehouseChange}
|
||||
onFetchMore={() => undefined}
|
||||
warehouses={warehouseChoices}
|
||||
onWarehouseAdd={onWarehouseAdd}
|
||||
/>
|
||||
</div>
|
||||
</Grid>
|
||||
|
|
|
@ -18,6 +18,7 @@ interface ShippingZonewWarehousesProps extends FetchMoreProps {
|
|||
displayValue: MultiAutocompleteChoiceType[];
|
||||
warehouses: MultiAutocompleteChoiceType[];
|
||||
onChange: FormChange;
|
||||
onWarehouseAdd: () => void;
|
||||
}
|
||||
|
||||
export const ShippingZoneWarehouses: React.FC<ShippingZonewWarehousesProps> = props => {
|
||||
|
@ -26,9 +27,10 @@ export const ShippingZoneWarehouses: React.FC<ShippingZonewWarehousesProps> = pr
|
|||
displayValue,
|
||||
hasMore,
|
||||
loading,
|
||||
warehouses,
|
||||
onChange,
|
||||
onFetchMore,
|
||||
warehouses
|
||||
onWarehouseAdd
|
||||
} = props;
|
||||
const intl = useIntl();
|
||||
|
||||
|
@ -42,6 +44,13 @@ export const ShippingZoneWarehouses: React.FC<ShippingZonewWarehousesProps> = pr
|
|||
/>
|
||||
<CardContent>
|
||||
<MultiAutocompleteSelectField
|
||||
add={{
|
||||
label: intl.formatMessage({
|
||||
defaultMessage: "Add New Warehouse",
|
||||
description: "button"
|
||||
}),
|
||||
onClick: onWarehouseAdd
|
||||
}}
|
||||
choices={warehouses}
|
||||
displayValues={displayValue}
|
||||
fetchChoices={() => undefined}
|
||||
|
|
|
@ -20,6 +20,7 @@ export const shippingZonePath = (id: string) =>
|
|||
urlJoin(shippingZonesListPath, id);
|
||||
export type ShippingZoneUrlDialog =
|
||||
| "add-rate"
|
||||
| "add-warehouse"
|
||||
| "assign-country"
|
||||
| "edit-rate"
|
||||
| "remove"
|
||||
|
|
|
@ -176,6 +176,7 @@ const ShippingZoneDetails: React.FC<ShippingZoneDetailsProps> = ({
|
|||
})
|
||||
}
|
||||
onSubmit={handleSubmit}
|
||||
onWarehouseAdd={() => openModal("add-warehouse")}
|
||||
onWeightRateAdd={() =>
|
||||
openModal("add-rate", {
|
||||
type: ShippingMethodTypeEnum.WEIGHT
|
||||
|
|
Loading…
Reference in a new issue