
* Create change warehouse dialog (#1850) * Add allocations & variant stocks to order details query * Add asc sorting to warehouse search query * Add OrderChangeWarehouseDialog component * Add key to warehouse list in dialog * Update snapshots * Remove debug directive * Remove IDs from messages * Fix typo in method name & extract messages * Add quantity to allocations in order details query * Add types to functions * Move functions to local utils file * Add utility type WithOptional * Fix warehouse types * Change multiple items unavailable message name * Fix fetching onScroll * Fix types in utils * Add backdrop click support * Add id to stocks and allocations * Change unavailableLines from .map to .filter Co-authored-by: Wojciech Mista <wojciech.mista@hotmail.com> * Fix linter issue Co-authored-by: Wojciech Mista <wojciech.mista@hotmail.com> * Refactor order cards headers (#1875) * Add keys to TableLines * Bump macaw * Move & rename CardTitle used in Cards with order lines * Improve OrderCardTitle typography * Replace StatusLabels with CircleIndicators * Fix card title divs placement * Add warehouse selection button to OrderUnfulfilledCard * Fix fulfill button placement * Update snapshots * Make warehouse in order details view optional so that it works with uncofirmed orders * Fix undefined lines in warehouse dialog * Fix spacing in warehouse change button * Fix macaw dependency * Bump macaw-ui * Extract messages * Implement default warehouse selection logic * Move CircleIndicator render condition to wrapper * Fix failing reduce on orders with no lines * Improve warehousesAvailable early return * Drop counter in favor of filter().length * Fix tests post-rebase * Refactor fulfillment details page (#1915) * Add shipment information card * Refactor multiple warehouse fulfilling to one warehouse * Fix fulfill button navigation * Remove redundant code from OrderFulfill view * Fix OrderFulfill story * Move styling to seperate file & remove unused classes * Replace colQuantityTotal class with colStock * Add warehouse label under page header * Fix preorder cases * Change default values to maximum * Simplify logic * Add badge for preorder & deleted variant cases * Remove unused data * Add yellow outline for exceeding stock * Fix failing tests * Extract messages * Fix tests post-rebase * Add support for tracking number * Block fulfilling no items * Fix deleted variant order details bug * Fix preorder & deleted variant cases * Update snapshots * Remove redundant import * Fix linter issue * Extract fulfillment lines as separate component * Fix types * Export styles & messages to seperate files * Simplify formset changes * Fix warning input styling * Fix shouldEnableSave for overfulfillment cases * Simplify preorder rendering * Move empty line rendering * Change Warehouse prop to just id of it * Add endAdornment for deleted variant cases * Update snapshots * Fix linter issue * Extract messages * Fix incorrect operator precedence resulting in NaN values * Extract fulfillment lines to fragment * Replace nested types with fragment type * Match fragment names * Update snapshots * Create exceeding stock confirmation dialog (#1970) * Cherry-pick OrderFulfillStockExceededDialog * Fix types to graphql-codegen * Unify names in OrderFulfillStockExceededDialogLines * Fix types in OrderFulfillStockExceededDialogLines * Fix types in util * Change utils for usage with single warehouse context * Refactor OrderFulfillStockExceededDialogLine for usage with single warehouse context * Fix deleted variant cases in OrderFulfillStockExceededDialogLine * Include only exceeded lines * Display stock exceeded dialog on error * Add confirm button state * Change fixed height in OrderFulfillStockExceededDialog to responsive * Extract messages * Move initial form data after interfaces * Change nested type to fragment * Reuse logic * Remove unused import * Remove redundant isStockError * Remove unused imports * Fix minor bugs in fulfillment creation refactor (#1972) * Fix unfulfilled card header quantity calculation * Fix formset default value for deleted variants * Update snapshots * Fix default warehouse selection in order draft (#1971) * Fix default warehouse selection * Replace Skeleton with circular progress * Reuse logic * Reuse logic * Apply CR fixes * Remove unused imports * Fix canceled order header status * Update snapshots * Revert CircularProgress & change to Skeleton * Change complex types to fragments * Extract default warehouse logic to hook * Fix linter issue * Remove type assertion from OrderFulfillPage story * Handle exceeding stock fulfillment approvals (#1988) * wip Add OrderFulfillStockExceeded modal for fulfillment approvals * wip Fix types & imports * wip Fix union typing in stock exceeded dialog for both views * Add allowStockToBeExceeded flag on submit * Fix lines keys in FulfilledCard * Remove redundant import * Extract attributes caption function * Use getById util * Fix deleted warehouse cases in approvals * Fix typo * Fix styling for long warehouse names (#2019) * Fix styling in change warehouse dialog * Fix styling in warehouse selection button * Add extra margin in button * Update snapshots Co-authored-by: Wojciech Mista <wojciech.mista@hotmail.com>
213 lines
6.9 KiB
TypeScript
213 lines
6.9 KiB
TypeScript
import {
|
|
Dialog,
|
|
DialogActions,
|
|
DialogContent,
|
|
FormControlLabel,
|
|
InputAdornment,
|
|
Radio,
|
|
RadioGroup,
|
|
TableCell,
|
|
TableRow,
|
|
TextField,
|
|
Typography
|
|
} from "@material-ui/core";
|
|
import Debounce from "@saleor/components/Debounce";
|
|
import Skeleton from "@saleor/components/Skeleton";
|
|
import { OrderLineFragment, WarehouseFragment } from "@saleor/graphql";
|
|
import { buttonMessages } from "@saleor/intl";
|
|
import {
|
|
Button,
|
|
DialogHeader,
|
|
DialogTable,
|
|
isScrolledToBottom,
|
|
isScrolledToTop,
|
|
ScrollShadow,
|
|
SearchIcon,
|
|
useElementScroll
|
|
} from "@saleor/macaw-ui";
|
|
import { isLineAvailableInWarehouse } from "@saleor/orders/utils/data";
|
|
import useWarehouseSearch from "@saleor/searches/useWarehouseSearch";
|
|
import { mapEdgesToItems } from "@saleor/utils/maps";
|
|
import React from "react";
|
|
import { FormattedMessage, useIntl } from "react-intl";
|
|
|
|
import { getById } from "../OrderReturnPage/utils";
|
|
import { changeWarehouseDialogMessages as messages } from "./messages";
|
|
import { useStyles } from "./styles";
|
|
|
|
export interface OrderChangeWarehouseDialogProps {
|
|
open: boolean;
|
|
lines: OrderLineFragment[];
|
|
currentWarehouse: WarehouseFragment;
|
|
onConfirm: (warehouse: WarehouseFragment) => void;
|
|
onClose();
|
|
}
|
|
|
|
export const OrderChangeWarehouseDialog: React.FC<OrderChangeWarehouseDialogProps> = ({
|
|
open,
|
|
lines,
|
|
currentWarehouse,
|
|
onConfirm,
|
|
onClose
|
|
}) => {
|
|
const classes = useStyles();
|
|
const intl = useIntl();
|
|
|
|
const { anchor, position, setAnchor } = useElementScroll();
|
|
const topShadow = isScrolledToTop(anchor, position, 20) === false;
|
|
const bottomShadow = isScrolledToBottom(anchor, position, 20) === false;
|
|
|
|
const [query, setQuery] = React.useState<string>("");
|
|
const [selectedWarehouseId, setSelectedWarehouseId] = React.useState<
|
|
string | null
|
|
>(null);
|
|
|
|
React.useEffect(() => {
|
|
if (currentWarehouse?.id) {
|
|
setSelectedWarehouseId(currentWarehouse.id);
|
|
}
|
|
}, [currentWarehouse]);
|
|
|
|
const { result: warehousesOpts, loadMore, search } = useWarehouseSearch({
|
|
variables: {
|
|
after: null,
|
|
first: 20,
|
|
query: ""
|
|
}
|
|
});
|
|
const filteredWarehouses = mapEdgesToItems(warehousesOpts?.data?.search);
|
|
|
|
const selectedWarehouse = filteredWarehouses?.find(
|
|
getById(selectedWarehouseId ?? "")
|
|
);
|
|
|
|
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
setSelectedWarehouseId(e.target.value);
|
|
};
|
|
const handleSubmit = () => {
|
|
onConfirm(selectedWarehouse);
|
|
onClose();
|
|
};
|
|
|
|
React.useEffect(() => {
|
|
if (!bottomShadow) {
|
|
loadMore();
|
|
}
|
|
}, [bottomShadow]);
|
|
|
|
return (
|
|
<Dialog fullWidth open={open} onClose={onClose}>
|
|
<ScrollShadow variant="top" show={topShadow}>
|
|
<DialogHeader onClose={onClose}>
|
|
<FormattedMessage {...messages.dialogTitle} />
|
|
</DialogHeader>
|
|
|
|
<DialogContent className={classes.container}>
|
|
<FormattedMessage {...messages.dialogDescription} />
|
|
<Debounce debounceFn={search}>
|
|
{debounceSearchChange => {
|
|
const handleSearchChange = (
|
|
event: React.ChangeEvent<HTMLInputElement>
|
|
) => {
|
|
const value = event.target.value;
|
|
setQuery(value);
|
|
debounceSearchChange(value);
|
|
};
|
|
return (
|
|
<TextField
|
|
className={classes.searchBox}
|
|
value={query}
|
|
variant="outlined"
|
|
onChange={handleSearchChange}
|
|
placeholder={intl.formatMessage(
|
|
messages.searchFieldPlaceholder
|
|
)}
|
|
fullWidth
|
|
InputProps={{
|
|
startAdornment: (
|
|
<InputAdornment position="start">
|
|
<SearchIcon />
|
|
</InputAdornment>
|
|
)
|
|
}}
|
|
inputProps={{ className: classes.searchInput }}
|
|
/>
|
|
);
|
|
}}
|
|
</Debounce>
|
|
|
|
<Typography className={classes.supportHeader}>
|
|
<FormattedMessage {...messages.warehouseListLabel} />
|
|
</Typography>
|
|
</DialogContent>
|
|
</ScrollShadow>
|
|
|
|
<DialogTable ref={setAnchor}>
|
|
{filteredWarehouses ? (
|
|
<RadioGroup value={selectedWarehouseId} onChange={handleChange}>
|
|
{filteredWarehouses.map(warehouse => {
|
|
const unavailableLines = lines?.filter(
|
|
line => !isLineAvailableInWarehouse(line, warehouse)
|
|
);
|
|
const someLinesUnavailable = unavailableLines?.length > 0;
|
|
return (
|
|
<TableRow key={warehouse.id}>
|
|
<TableCell>
|
|
<FormControlLabel
|
|
value={warehouse.id}
|
|
control={<Radio color="primary" />}
|
|
label={
|
|
<div className={classes.radioLabelContainer}>
|
|
<span className={classes.warehouseName}>
|
|
{warehouse.name}
|
|
</span>
|
|
{someLinesUnavailable && (
|
|
<Typography className={classes.supportText}>
|
|
{unavailableLines.length === 1
|
|
? intl.formatMessage(
|
|
messages.productUnavailable,
|
|
{
|
|
productName:
|
|
unavailableLines[0].productName
|
|
}
|
|
)
|
|
: intl.formatMessage(
|
|
messages.multipleProductsUnavailable,
|
|
{ productCount: unavailableLines.length }
|
|
)}
|
|
</Typography>
|
|
)}
|
|
</div>
|
|
}
|
|
/>
|
|
{currentWarehouse?.id === warehouse?.id && (
|
|
<Typography className={classes.helpText}>
|
|
{intl.formatMessage(messages.currentSelection)}
|
|
</Typography>
|
|
)}
|
|
</TableCell>
|
|
</TableRow>
|
|
);
|
|
})}
|
|
</RadioGroup>
|
|
) : (
|
|
<Skeleton />
|
|
)}
|
|
</DialogTable>
|
|
<ScrollShadow variant="bottom" show={bottomShadow}>
|
|
<DialogActions>
|
|
<Button
|
|
onClick={handleSubmit}
|
|
color="primary"
|
|
variant="primary"
|
|
disabled={!selectedWarehouse}
|
|
>
|
|
{intl.formatMessage(buttonMessages.select)}
|
|
</Button>
|
|
</DialogActions>
|
|
</ScrollShadow>
|
|
</Dialog>
|
|
);
|
|
};
|
|
OrderChangeWarehouseDialog.displayName = "OrderChangeWarehouseDialog";
|
|
export default OrderChangeWarehouseDialog;
|