bananas-commerce-admin 0.3.21 → 0.3.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/api.js +13 -0
- package/dist/cjs/api.js.map +1 -1
- package/dist/cjs/contexts/ApiContext.js +13 -14
- package/dist/cjs/contexts/ApiContext.js.map +1 -1
- package/dist/cjs/extensions/fulfillment/components/AddressInfo.js +7 -5
- package/dist/cjs/extensions/fulfillment/components/AddressInfo.js.map +1 -1
- package/dist/cjs/extensions/fulfillment/components/RecipientCard.js +18 -15
- package/dist/cjs/extensions/fulfillment/components/RecipientCard.js.map +1 -1
- package/dist/cjs/extensions/fulfillment/components/ShipmentCard.js +22 -37
- package/dist/cjs/extensions/fulfillment/components/ShipmentCard.js.map +1 -1
- package/dist/cjs/extensions/fulfillment/components/contrib/PurchaseOrderList.js +2 -2
- package/dist/cjs/extensions/fulfillment/components/contrib/PurchaseOrderList.js.map +1 -1
- package/dist/cjs/extensions/fulfillment/components/order/OrderDestinationCard.js +38 -0
- package/dist/cjs/extensions/fulfillment/components/order/OrderDestinationCard.js.map +1 -0
- package/dist/cjs/extensions/fulfillment/components/order/OrderDetail.js +276 -0
- package/dist/cjs/extensions/fulfillment/components/order/OrderDetail.js.map +1 -0
- package/dist/cjs/extensions/fulfillment/index.js +21 -25
- package/dist/cjs/extensions/fulfillment/index.js.map +1 -1
- package/dist/cjs/extensions/pos/pages/purchase/detail.js +6 -21
- package/dist/cjs/extensions/pos/pages/purchase/detail.js.map +1 -1
- package/dist/esm/api.js +13 -0
- package/dist/esm/api.js.map +1 -1
- package/dist/esm/contexts/ApiContext.js +13 -14
- package/dist/esm/contexts/ApiContext.js.map +1 -1
- package/dist/esm/extensions/fulfillment/components/AddressInfo.js +7 -5
- package/dist/esm/extensions/fulfillment/components/AddressInfo.js.map +1 -1
- package/dist/esm/extensions/fulfillment/components/RecipientCard.js +18 -15
- package/dist/esm/extensions/fulfillment/components/RecipientCard.js.map +1 -1
- package/dist/esm/extensions/fulfillment/components/ShipmentCard.js +22 -37
- package/dist/esm/extensions/fulfillment/components/ShipmentCard.js.map +1 -1
- package/dist/esm/extensions/fulfillment/components/contrib/PurchaseOrderList.js +2 -2
- package/dist/esm/extensions/fulfillment/components/contrib/PurchaseOrderList.js.map +1 -1
- package/dist/esm/extensions/fulfillment/components/order/OrderDestinationCard.js +31 -0
- package/dist/esm/extensions/fulfillment/components/order/OrderDestinationCard.js.map +1 -0
- package/dist/esm/extensions/fulfillment/components/order/OrderDetail.js +248 -0
- package/dist/esm/extensions/fulfillment/components/order/OrderDetail.js.map +1 -0
- package/dist/esm/extensions/fulfillment/index.js +21 -25
- package/dist/esm/extensions/fulfillment/index.js.map +1 -1
- package/dist/esm/extensions/pos/pages/purchase/detail.js +6 -21
- package/dist/esm/extensions/pos/pages/purchase/detail.js.map +1 -1
- package/dist/types/App.d.ts +2 -2
- package/dist/types/api.d.ts +1 -0
- package/dist/types/contexts/ApiContext.d.ts +2 -2
- package/dist/types/extensions/fulfillment/components/AddressInfo.d.ts +1 -0
- package/dist/types/extensions/fulfillment/components/RecipientCard.d.ts +3 -1
- package/dist/types/extensions/fulfillment/components/ShipmentCard.d.ts +3 -2
- package/dist/types/extensions/fulfillment/components/order/OrderDestinationCard.d.ts +7 -0
- package/dist/types/extensions/fulfillment/components/order/OrderDetail.d.ts +7 -0
- package/dist/types/extensions/fulfillment/index.d.ts +2 -2
- package/dist/types/extensions/fulfillment/types/order.d.ts +6 -5
- package/dist/types/extensions/fulfillment/types/recipient.d.ts +1 -5
- package/dist/types/extensions/fulfillment/types/shipment.d.ts +2 -57
- package/dist/types/extensions/pos/types/purchase.d.ts +1 -0
- package/dist/types/types/index.d.ts +4 -4
- package/example/index.tsx +4 -1
- package/example/package-lock.json +1 -1
- package/package.json +1 -1
- package/src/App.tsx +2 -2
- package/src/api.ts +14 -0
- package/src/contexts/ApiContext.tsx +10 -8
- package/src/extensions/fulfillment/components/AddressInfo.tsx +9 -5
- package/src/extensions/fulfillment/components/RecipientCard.tsx +47 -22
- package/src/extensions/fulfillment/components/ShipmentCard.tsx +57 -63
- package/src/extensions/fulfillment/components/contrib/PurchaseOrderList.tsx +2 -2
- package/src/extensions/fulfillment/components/order/OrderDestinationCard.tsx +68 -0
- package/src/extensions/fulfillment/components/order/OrderDetail.tsx +262 -0
- package/src/extensions/fulfillment/index.tsx +13 -35
- package/src/extensions/fulfillment/types/order.ts +7 -5
- package/src/extensions/fulfillment/types/recipient.ts +1 -6
- package/src/extensions/fulfillment/types/shipment.ts +2 -60
- package/src/extensions/pos/pages/purchase/detail.tsx +8 -12
- package/src/extensions/pos/types/purchase.ts +1 -0
- package/src/types/index.ts +8 -4
- package/dist/cjs/extensions/fulfillment/components/ContactInfo.js +0 -21
- package/dist/cjs/extensions/fulfillment/components/ContactInfo.js.map +0 -1
- package/dist/cjs/extensions/fulfillment/components/ShipmentAccordion.js +0 -215
- package/dist/cjs/extensions/fulfillment/components/ShipmentAccordion.js.map +0 -1
- package/dist/cjs/extensions/fulfillment/components/ShipmentItemsCard.js +0 -131
- package/dist/cjs/extensions/fulfillment/components/ShipmentItemsCard.js.map +0 -1
- package/dist/cjs/extensions/fulfillment/components/ShipmentItemsTable.js +0 -85
- package/dist/cjs/extensions/fulfillment/components/ShipmentItemsTable.js.map +0 -1
- package/dist/cjs/extensions/fulfillment/components/ShipmentRow.js +0 -29
- package/dist/cjs/extensions/fulfillment/components/ShipmentRow.js.map +0 -1
- package/dist/esm/extensions/fulfillment/components/ContactInfo.js +0 -14
- package/dist/esm/extensions/fulfillment/components/ContactInfo.js.map +0 -1
- package/dist/esm/extensions/fulfillment/components/ShipmentAccordion.js +0 -208
- package/dist/esm/extensions/fulfillment/components/ShipmentAccordion.js.map +0 -1
- package/dist/esm/extensions/fulfillment/components/ShipmentItemsCard.js +0 -124
- package/dist/esm/extensions/fulfillment/components/ShipmentItemsCard.js.map +0 -1
- package/dist/esm/extensions/fulfillment/components/ShipmentItemsTable.js +0 -78
- package/dist/esm/extensions/fulfillment/components/ShipmentItemsTable.js.map +0 -1
- package/dist/esm/extensions/fulfillment/components/ShipmentRow.js +0 -22
- package/dist/esm/extensions/fulfillment/components/ShipmentRow.js.map +0 -1
- package/dist/types/extensions/fulfillment/components/ContactInfo.d.ts +0 -7
- package/dist/types/extensions/fulfillment/components/ShipmentAccordion.d.ts +0 -7
- package/dist/types/extensions/fulfillment/components/ShipmentItemsCard.d.ts +0 -6
- package/dist/types/extensions/fulfillment/components/ShipmentItemsTable.d.ts +0 -8
- package/dist/types/extensions/fulfillment/components/ShipmentRow.d.ts +0 -7
- package/src/extensions/fulfillment/components/ContactInfo.tsx +0 -33
- package/src/extensions/fulfillment/components/ShipmentAccordion.tsx +0 -209
- package/src/extensions/fulfillment/components/ShipmentItemsCard.tsx +0 -170
- package/src/extensions/fulfillment/components/ShipmentItemsTable.tsx +0 -116
- package/src/extensions/fulfillment/components/ShipmentRow.tsx +0 -32
|
@@ -1,209 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
|
|
3
|
-
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
|
|
4
|
-
import { LoadingButton, LoadingButtonProps } from "@mui/lab";
|
|
5
|
-
import Accordion from "@mui/material/Accordion";
|
|
6
|
-
import AccordionActions from "@mui/material/AccordionActions";
|
|
7
|
-
import AccordionDetails from "@mui/material/AccordionDetails";
|
|
8
|
-
import AccordionSummary from "@mui/material/AccordionSummary";
|
|
9
|
-
import Button from "@mui/material/Button";
|
|
10
|
-
import CircularProgress from "@mui/material/CircularProgress";
|
|
11
|
-
import Typography from "@mui/material/Typography";
|
|
12
|
-
|
|
13
|
-
import { useSnackbar } from "notistack";
|
|
14
|
-
|
|
15
|
-
import { useApi } from "../../../contexts/ApiContext";
|
|
16
|
-
import { formatPurchaseNumber } from "../../../util/format_purchase_number";
|
|
17
|
-
import { ShipmentDetail, ShipmentItem, ShipmentListItem } from "../types/shipment";
|
|
18
|
-
import { ShipmentDestinationIcon } from "./ShipmentDestinationIcon";
|
|
19
|
-
import { ShipmentItemsTable } from "./ShipmentItemsTable";
|
|
20
|
-
|
|
21
|
-
interface ShipmentAccordionProps {
|
|
22
|
-
shipment: ShipmentListItem;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export const ShipmentAccordion: React.FC<ShipmentAccordionProps> = ({ shipment }) => {
|
|
26
|
-
const api = useApi();
|
|
27
|
-
const { enqueueSnackbar } = useSnackbar();
|
|
28
|
-
const [details, setDetails] = React.useState<ShipmentDetail | null>(null);
|
|
29
|
-
const [buttonsLoading, setButtonsLoading] = React.useState(false);
|
|
30
|
-
const [selected, setSelected] = React.useState<ShipmentItem[]>([]);
|
|
31
|
-
const title = [
|
|
32
|
-
formatPurchaseNumber(shipment.purchase_number),
|
|
33
|
-
shipment.name,
|
|
34
|
-
shipment.email,
|
|
35
|
-
shipment.phone,
|
|
36
|
-
]
|
|
37
|
-
.filter((entry) => entry != null)
|
|
38
|
-
.join(" • ");
|
|
39
|
-
|
|
40
|
-
const loadDetails = () => {
|
|
41
|
-
setDetails(null);
|
|
42
|
-
api.operations["fulfillment.shipment:detail"]
|
|
43
|
-
.call({
|
|
44
|
-
params: {
|
|
45
|
-
shipment_reference: shipment.shipment_reference,
|
|
46
|
-
},
|
|
47
|
-
})
|
|
48
|
-
.then(async (response) => setDetails(await response.json()));
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
const markAsArrived = () => {
|
|
52
|
-
setButtonsLoading(true);
|
|
53
|
-
api.operations["fulfillment.shipment:arrived"]
|
|
54
|
-
.call({
|
|
55
|
-
params: { shipment_reference: shipment.shipment_reference },
|
|
56
|
-
body: selected,
|
|
57
|
-
})
|
|
58
|
-
.then((response) => {
|
|
59
|
-
if (response.ok) {
|
|
60
|
-
enqueueSnackbar("Successfully marked shipment items as arrived!", {
|
|
61
|
-
variant: "success",
|
|
62
|
-
});
|
|
63
|
-
} else {
|
|
64
|
-
enqueueSnackbar("Failed to mark shipment items as arrived, view console for more info", {
|
|
65
|
-
variant: "error",
|
|
66
|
-
});
|
|
67
|
-
throw response;
|
|
68
|
-
}
|
|
69
|
-
})
|
|
70
|
-
.finally(() => {
|
|
71
|
-
setButtonsLoading(false);
|
|
72
|
-
loadDetails();
|
|
73
|
-
});
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
const markAsDelivered = () => {
|
|
77
|
-
setButtonsLoading(true);
|
|
78
|
-
api.operations["fulfillment.shipment:delivered"]
|
|
79
|
-
.call({
|
|
80
|
-
params: { shipment_reference: shipment.shipment_reference },
|
|
81
|
-
})
|
|
82
|
-
.then((response) => {
|
|
83
|
-
if (response.ok) {
|
|
84
|
-
enqueueSnackbar("Successfully marked shipment as delivered!", {
|
|
85
|
-
variant: "success",
|
|
86
|
-
});
|
|
87
|
-
} else {
|
|
88
|
-
enqueueSnackbar("Failed to mark shipment as delivered, view console for more info", {
|
|
89
|
-
variant: "error",
|
|
90
|
-
});
|
|
91
|
-
throw response;
|
|
92
|
-
}
|
|
93
|
-
})
|
|
94
|
-
.finally(() => {
|
|
95
|
-
setButtonsLoading(false);
|
|
96
|
-
loadDetails();
|
|
97
|
-
});
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
const doCancel = () => {
|
|
101
|
-
api.operations["fulfillment.shipment:cancel"]
|
|
102
|
-
.call({
|
|
103
|
-
params: { shipment_reference: shipment.shipment_reference },
|
|
104
|
-
})
|
|
105
|
-
.then((response) => {
|
|
106
|
-
if (response.ok) {
|
|
107
|
-
enqueueSnackbar("Successfully cancelled shipment!", {
|
|
108
|
-
variant: "success",
|
|
109
|
-
});
|
|
110
|
-
} else {
|
|
111
|
-
enqueueSnackbar("Failed to cancel shipment, view console for more info", {
|
|
112
|
-
variant: "error",
|
|
113
|
-
});
|
|
114
|
-
throw response;
|
|
115
|
-
}
|
|
116
|
-
})
|
|
117
|
-
.finally(() => {
|
|
118
|
-
setButtonsLoading(false);
|
|
119
|
-
loadDetails();
|
|
120
|
-
});
|
|
121
|
-
};
|
|
122
|
-
|
|
123
|
-
const StatusButton = () => {
|
|
124
|
-
if (!details) {
|
|
125
|
-
return null;
|
|
126
|
-
}
|
|
127
|
-
const props: LoadingButtonProps = {
|
|
128
|
-
variant: "contained",
|
|
129
|
-
color: "secondary",
|
|
130
|
-
loading: buttonsLoading,
|
|
131
|
-
disabled: buttonsLoading,
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
if (details.date_delivered || details.date_cancelled) {
|
|
135
|
-
return null;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
if (!details.date_arrived_at_destination) {
|
|
139
|
-
props.disabled ||= selected.length === 0;
|
|
140
|
-
return (
|
|
141
|
-
<LoadingButton {...props} onClick={markAsArrived}>
|
|
142
|
-
Ready for pickup
|
|
143
|
-
</LoadingButton>
|
|
144
|
-
);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
if (details.date_arrived_at_destination) {
|
|
148
|
-
return (
|
|
149
|
-
<LoadingButton {...props} onClick={markAsDelivered}>
|
|
150
|
-
Delivered
|
|
151
|
-
</LoadingButton>
|
|
152
|
-
);
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
return null;
|
|
156
|
-
};
|
|
157
|
-
|
|
158
|
-
return (
|
|
159
|
-
<Accordion onChange={() => (details == null ? loadDetails() : void 0)}>
|
|
160
|
-
<AccordionSummary sx={{ margin: 1 }} expandIcon={<ExpandMoreIcon />}>
|
|
161
|
-
{/* TODO: Re-enable when we implement some kind of bulk update thing
|
|
162
|
-
<Checkbox
|
|
163
|
-
color="secondary"
|
|
164
|
-
onClick={(event) => event.stopPropagation()}
|
|
165
|
-
/>
|
|
166
|
-
*/}
|
|
167
|
-
<Typography sx={{ marginY: "auto", flexGrow: 1 }}>{title}</Typography>
|
|
168
|
-
<ShipmentDestinationIcon
|
|
169
|
-
sx={{ marginY: "auto", marginX: 1 }}
|
|
170
|
-
type={shipment.destination_type}
|
|
171
|
-
/>
|
|
172
|
-
</AccordionSummary>
|
|
173
|
-
{details != null ? (
|
|
174
|
-
<>
|
|
175
|
-
<AccordionDetails>
|
|
176
|
-
<ShipmentItemsTable
|
|
177
|
-
items={details.items}
|
|
178
|
-
editable={
|
|
179
|
-
!details.date_confirmed &&
|
|
180
|
-
!details.date_cancelled &&
|
|
181
|
-
!details.date_arrived_at_destination
|
|
182
|
-
}
|
|
183
|
-
onSelect={setSelected}
|
|
184
|
-
/>
|
|
185
|
-
</AccordionDetails>
|
|
186
|
-
<AccordionActions>
|
|
187
|
-
{!details.date_confirmed && !details.date_cancelled ? (
|
|
188
|
-
<Button variant="outlined" color="error" onClick={doCancel}>
|
|
189
|
-
Cancel order
|
|
190
|
-
</Button>
|
|
191
|
-
) : null}
|
|
192
|
-
<StatusButton />
|
|
193
|
-
</AccordionActions>
|
|
194
|
-
</>
|
|
195
|
-
) : (
|
|
196
|
-
<AccordionDetails
|
|
197
|
-
sx={{
|
|
198
|
-
display: "flex",
|
|
199
|
-
justifyContent: "center",
|
|
200
|
-
alignItems: "center",
|
|
201
|
-
minHeight: 100,
|
|
202
|
-
}}
|
|
203
|
-
>
|
|
204
|
-
<CircularProgress color="secondary" />
|
|
205
|
-
</AccordionDetails>
|
|
206
|
-
)}
|
|
207
|
-
</Accordion>
|
|
208
|
-
);
|
|
209
|
-
};
|
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
|
|
3
|
-
import Inventory2OutlinedIcon from "@mui/icons-material/Inventory2Outlined";
|
|
4
|
-
import LoadingButton from "@mui/lab/LoadingButton";
|
|
5
|
-
import Card from "@mui/material/Card";
|
|
6
|
-
import CardActions from "@mui/material/CardActions";
|
|
7
|
-
import CardContent from "@mui/material/CardContent";
|
|
8
|
-
import CardHeader from "@mui/material/CardHeader";
|
|
9
|
-
import Checkbox from "@mui/material/Checkbox";
|
|
10
|
-
import Input from "@mui/material/Input";
|
|
11
|
-
import { useTheme } from "@mui/material/styles";
|
|
12
|
-
import Table from "@mui/material/Table";
|
|
13
|
-
import TableBody from "@mui/material/TableBody";
|
|
14
|
-
import TableCell from "@mui/material/TableCell";
|
|
15
|
-
import TableContainer from "@mui/material/TableContainer";
|
|
16
|
-
import TableHead from "@mui/material/TableHead";
|
|
17
|
-
import TableRow from "@mui/material/TableRow";
|
|
18
|
-
import Typography from "@mui/material/Typography";
|
|
19
|
-
|
|
20
|
-
import { useSnackbar } from "notistack";
|
|
21
|
-
|
|
22
|
-
import { useApi } from "../../../contexts/ApiContext";
|
|
23
|
-
import { Shipment, ShipmentItem } from "../types/shipment";
|
|
24
|
-
|
|
25
|
-
export interface ShipmentItemsCardProps {
|
|
26
|
-
shipment: Shipment;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export const ShipmentItemsCard: React.FC<ShipmentItemsCardProps> = ({ shipment }) => {
|
|
30
|
-
const theme = useTheme();
|
|
31
|
-
const api = useApi();
|
|
32
|
-
const { enqueueSnackbar } = useSnackbar();
|
|
33
|
-
const [selected, setSelected] = React.useState<ShipmentItem[]>([]);
|
|
34
|
-
const [loading, setLoading] = React.useState(false);
|
|
35
|
-
const [disabled, setDisabled] = React.useState(
|
|
36
|
-
false /* "date_arrived_at_destination" in shipment && shipment.date_arrived_at_destination != null */
|
|
37
|
-
);
|
|
38
|
-
|
|
39
|
-
const toggleSelectAll = (_: React.ChangeEvent<HTMLInputElement>, checked: boolean) => {
|
|
40
|
-
setSelected(checked ? shipment.items : []);
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
const toggleItem = (item: ShipmentItem, checked: boolean) => {
|
|
44
|
-
const index = selected.map(({ code }) => code).indexOf(item.code);
|
|
45
|
-
|
|
46
|
-
if (checked && index === -1) {
|
|
47
|
-
setSelected([...selected, item]);
|
|
48
|
-
} else {
|
|
49
|
-
const unselected = [...selected];
|
|
50
|
-
unselected.splice(index, 1);
|
|
51
|
-
setSelected(unselected);
|
|
52
|
-
}
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
const itemQuantityChange = (item: ShipmentItem) => {
|
|
56
|
-
const index = selected.map(({ code }) => code).indexOf(item.code);
|
|
57
|
-
const changed = [...selected];
|
|
58
|
-
changed[index] = item;
|
|
59
|
-
setSelected(changed);
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
const markAsArrived = () => {
|
|
63
|
-
setLoading(true);
|
|
64
|
-
api.operations["fulfillment.shipment:arrived"]
|
|
65
|
-
.call({
|
|
66
|
-
params: { shipment_reference: shipment.shipment_reference },
|
|
67
|
-
body: selected,
|
|
68
|
-
})
|
|
69
|
-
.then((response) => {
|
|
70
|
-
if (response.ok) {
|
|
71
|
-
enqueueSnackbar("Successfully marked shipment items as arrived!", {
|
|
72
|
-
variant: "success",
|
|
73
|
-
});
|
|
74
|
-
setDisabled(true);
|
|
75
|
-
} else {
|
|
76
|
-
enqueueSnackbar("Failed to mark order as ready for pickup", {
|
|
77
|
-
variant: "error",
|
|
78
|
-
});
|
|
79
|
-
throw response;
|
|
80
|
-
}
|
|
81
|
-
})
|
|
82
|
-
.finally(() => {
|
|
83
|
-
setLoading(false);
|
|
84
|
-
});
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
return (
|
|
88
|
-
<Card>
|
|
89
|
-
<CardHeader
|
|
90
|
-
title={
|
|
91
|
-
<Typography variant="h6">
|
|
92
|
-
<b>Items</b>
|
|
93
|
-
</Typography>
|
|
94
|
-
}
|
|
95
|
-
avatar={<Inventory2OutlinedIcon />}
|
|
96
|
-
sx={{
|
|
97
|
-
borderBottomWidth: 1,
|
|
98
|
-
borderBottomStyle: "solid",
|
|
99
|
-
borderBottomColor: theme.palette.divider,
|
|
100
|
-
}}
|
|
101
|
-
/>
|
|
102
|
-
<CardContent>
|
|
103
|
-
<TableContainer>
|
|
104
|
-
<Table>
|
|
105
|
-
<TableHead>
|
|
106
|
-
<TableRow>
|
|
107
|
-
<TableCell align="left" padding="checkbox">
|
|
108
|
-
<Checkbox
|
|
109
|
-
color="secondary"
|
|
110
|
-
indeterminate={selected.length > 0 && selected.length < shipment.items.length}
|
|
111
|
-
checked={
|
|
112
|
-
shipment.items.length !== 0 && selected.length === shipment.items.length
|
|
113
|
-
}
|
|
114
|
-
onChange={toggleSelectAll}
|
|
115
|
-
disabled={disabled || shipment.items.length === 0}
|
|
116
|
-
/>
|
|
117
|
-
</TableCell>
|
|
118
|
-
<TableCell align="left">Reference</TableCell>
|
|
119
|
-
<TableCell align="right">Quantity</TableCell>
|
|
120
|
-
</TableRow>
|
|
121
|
-
</TableHead>
|
|
122
|
-
<TableBody>
|
|
123
|
-
{shipment.items.map((item) => {
|
|
124
|
-
const isSelected = selected.map(({ code }) => code).includes(item.code);
|
|
125
|
-
return (
|
|
126
|
-
<TableRow key={item.code}>
|
|
127
|
-
<TableCell align="left" padding="checkbox">
|
|
128
|
-
<Checkbox
|
|
129
|
-
disabled={disabled}
|
|
130
|
-
color="secondary"
|
|
131
|
-
checked={isSelected}
|
|
132
|
-
onChange={(_, checked) => toggleItem(item, checked)}
|
|
133
|
-
/>
|
|
134
|
-
</TableCell>
|
|
135
|
-
<TableCell align="left">{item.code}</TableCell>
|
|
136
|
-
<TableCell align="right">
|
|
137
|
-
<Input
|
|
138
|
-
type="number"
|
|
139
|
-
defaultValue={item.quantity}
|
|
140
|
-
inputProps={{ min: 0, max: item.quantity }}
|
|
141
|
-
disabled={disabled || !isSelected}
|
|
142
|
-
onChange={(event) =>
|
|
143
|
-
itemQuantityChange({
|
|
144
|
-
code: item.code,
|
|
145
|
-
quantity: parseInt(event.target.value),
|
|
146
|
-
})
|
|
147
|
-
}
|
|
148
|
-
/>
|
|
149
|
-
</TableCell>
|
|
150
|
-
</TableRow>
|
|
151
|
-
);
|
|
152
|
-
})}
|
|
153
|
-
</TableBody>
|
|
154
|
-
</Table>
|
|
155
|
-
</TableContainer>
|
|
156
|
-
</CardContent>
|
|
157
|
-
<CardActions sx={{ justifyContent: "end" }}>
|
|
158
|
-
<LoadingButton
|
|
159
|
-
variant="contained"
|
|
160
|
-
color="secondary"
|
|
161
|
-
loading={loading}
|
|
162
|
-
disabled={disabled || loading || selected.length === 0}
|
|
163
|
-
onClick={markAsArrived}
|
|
164
|
-
>
|
|
165
|
-
Mark as arrived
|
|
166
|
-
</LoadingButton>
|
|
167
|
-
</CardActions>
|
|
168
|
-
</Card>
|
|
169
|
-
);
|
|
170
|
-
};
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
|
|
3
|
-
import Checkbox from "@mui/material/Checkbox";
|
|
4
|
-
import Input from "@mui/material/Input";
|
|
5
|
-
import Table from "@mui/material/Table";
|
|
6
|
-
import TableBody from "@mui/material/TableBody";
|
|
7
|
-
import TableCell from "@mui/material/TableCell";
|
|
8
|
-
import TableContainer from "@mui/material/TableContainer";
|
|
9
|
-
import TableHead from "@mui/material/TableHead";
|
|
10
|
-
import TableRow from "@mui/material/TableRow";
|
|
11
|
-
|
|
12
|
-
import { ShipmentItem } from "../types/shipment";
|
|
13
|
-
|
|
14
|
-
export interface ShipmentItemsTableProps {
|
|
15
|
-
items: ShipmentItem[];
|
|
16
|
-
editable?: boolean;
|
|
17
|
-
onSelect?: (selected: ShipmentItem[]) => void;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export const ShipmentItemsTable: React.FC<ShipmentItemsTableProps> = ({
|
|
21
|
-
items,
|
|
22
|
-
editable,
|
|
23
|
-
onSelect,
|
|
24
|
-
}) => {
|
|
25
|
-
const [selected, setSelected] = React.useState<ShipmentItem[]>([]);
|
|
26
|
-
|
|
27
|
-
const toggleSelectAll = (_: React.ChangeEvent<HTMLInputElement>, checked: boolean) => {
|
|
28
|
-
setSelected(checked ? items : []);
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
const toggleItem = (item: ShipmentItem, checked: boolean) => {
|
|
32
|
-
const index = selected.map(({ code }) => code).indexOf(item.code);
|
|
33
|
-
|
|
34
|
-
if (checked && index === -1) {
|
|
35
|
-
setSelected([...selected, item]);
|
|
36
|
-
} else {
|
|
37
|
-
const unselected = [...selected];
|
|
38
|
-
unselected.splice(index, 1);
|
|
39
|
-
setSelected(unselected);
|
|
40
|
-
}
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
const itemQuantityChange = (item: ShipmentItem) => {
|
|
44
|
-
const index = selected.map(({ code }) => code).indexOf(item.code);
|
|
45
|
-
const changed = [...selected];
|
|
46
|
-
changed[index] = item;
|
|
47
|
-
setSelected(changed);
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
React.useEffect(() => {
|
|
51
|
-
if (onSelect !== undefined) {
|
|
52
|
-
onSelect(selected);
|
|
53
|
-
}
|
|
54
|
-
}, [onSelect, selected]);
|
|
55
|
-
|
|
56
|
-
return (
|
|
57
|
-
<TableContainer>
|
|
58
|
-
<Table>
|
|
59
|
-
<TableHead>
|
|
60
|
-
<TableRow>
|
|
61
|
-
{editable ? (
|
|
62
|
-
<TableCell align="left" padding="checkbox">
|
|
63
|
-
<Checkbox
|
|
64
|
-
color="secondary"
|
|
65
|
-
indeterminate={selected.length > 0 && selected.length < items.length}
|
|
66
|
-
checked={items.length !== 0 && selected.length === items.length}
|
|
67
|
-
onChange={toggleSelectAll}
|
|
68
|
-
disabled={items.length === 0}
|
|
69
|
-
/>
|
|
70
|
-
</TableCell>
|
|
71
|
-
) : null}
|
|
72
|
-
<TableCell align="left">Reference</TableCell>
|
|
73
|
-
<TableCell align="right">Quantity</TableCell>
|
|
74
|
-
</TableRow>
|
|
75
|
-
</TableHead>
|
|
76
|
-
<TableBody>
|
|
77
|
-
{items.map((item) => {
|
|
78
|
-
const isSelected = selected.map(({ code }) => code).includes(item.code);
|
|
79
|
-
return (
|
|
80
|
-
<TableRow key={item.code}>
|
|
81
|
-
{editable ? (
|
|
82
|
-
<TableCell align="left" padding="checkbox">
|
|
83
|
-
<Checkbox
|
|
84
|
-
color="secondary"
|
|
85
|
-
checked={isSelected}
|
|
86
|
-
onChange={(_, checked) => toggleItem(item, checked)}
|
|
87
|
-
/>
|
|
88
|
-
</TableCell>
|
|
89
|
-
) : null}
|
|
90
|
-
<TableCell align="left">{item.code}</TableCell>
|
|
91
|
-
<TableCell align="right">
|
|
92
|
-
{editable ? (
|
|
93
|
-
<Input
|
|
94
|
-
type="number"
|
|
95
|
-
defaultValue={item.quantity}
|
|
96
|
-
inputProps={{ min: 0, max: item.quantity }}
|
|
97
|
-
disabled={!isSelected}
|
|
98
|
-
onChange={(event) =>
|
|
99
|
-
itemQuantityChange({
|
|
100
|
-
code: item.code,
|
|
101
|
-
quantity: parseInt(event.target.value),
|
|
102
|
-
})
|
|
103
|
-
}
|
|
104
|
-
/>
|
|
105
|
-
) : (
|
|
106
|
-
item.quantity
|
|
107
|
-
)}
|
|
108
|
-
</TableCell>
|
|
109
|
-
</TableRow>
|
|
110
|
-
);
|
|
111
|
-
})}
|
|
112
|
-
</TableBody>
|
|
113
|
-
</Table>
|
|
114
|
-
</TableContainer>
|
|
115
|
-
);
|
|
116
|
-
};
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
|
|
3
|
-
import TableCell from "@mui/material/TableCell";
|
|
4
|
-
import TableRow from "@mui/material/TableRow";
|
|
5
|
-
|
|
6
|
-
import { useRouter } from "../../../contexts/RouterContext";
|
|
7
|
-
import { ShipmentListItem } from "../types/shipment";
|
|
8
|
-
|
|
9
|
-
interface ShipmentRowProps {
|
|
10
|
-
shipment: ShipmentListItem;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export const ShipmentRow: React.FC<ShipmentRowProps> = ({ shipment }) => {
|
|
14
|
-
const { navigate } = useRouter();
|
|
15
|
-
|
|
16
|
-
const onClick = () => {
|
|
17
|
-
navigate(`fulfillment.shipment:detail`, {
|
|
18
|
-
params: {
|
|
19
|
-
shipment_reference: shipment.shipment_reference,
|
|
20
|
-
},
|
|
21
|
-
});
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
return (
|
|
25
|
-
<TableRow onClick={onClick} hover>
|
|
26
|
-
<TableCell>{shipment.shipment_reference}</TableCell>
|
|
27
|
-
<TableCell>{shipment.purchase_number}</TableCell>
|
|
28
|
-
<TableCell>{shipment.email}</TableCell>
|
|
29
|
-
<TableCell>{shipment.phone ?? "-"}</TableCell>
|
|
30
|
-
</TableRow>
|
|
31
|
-
);
|
|
32
|
-
};
|