feat/delete-item-warehouse (#78)
Delete item Delete warehouse Delete confirmation messages Bonus: Full cover image Co-authored-by: Llewellyn Dsouza <lledsouza2209@gmail.com>
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,7 +1,7 @@
|
||||
# See https://help.github.com/ignore-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
node_modules
|
||||
.DS_Store
|
||||
|
||||
# testing
|
||||
|
||||
@@ -41,10 +41,11 @@ const StyledTableRow = styled(TableRow)(({ theme }) => ({
|
||||
Row.propTypes = {
|
||||
rowData: PropTypes.array,
|
||||
tHeads: PropTypes.array,
|
||||
editHandler: PropTypes.any
|
||||
editHandler: PropTypes.any,
|
||||
deleteHandler: PropTypes.any
|
||||
};
|
||||
|
||||
function Row({ tHeads, rowData, editHandler }) {
|
||||
function Row({ tHeads, rowData, editHandler, deleteHandler }) {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<StyledTableRow sx={{ '&odd > *': { borderBottom: 'unset' } }}>
|
||||
@@ -68,6 +69,25 @@ function Row({ tHeads, rowData, editHandler }) {
|
||||
>
|
||||
EDIT
|
||||
</MDButton>
|
||||
<MDButton
|
||||
size="small"
|
||||
variant="contained"
|
||||
color="error"
|
||||
sx={{
|
||||
textTransform: 'capitalize',
|
||||
minWidth: '45px',
|
||||
minHeight: '28px',
|
||||
marginLeft: '10px',
|
||||
boxShadow: 'none',
|
||||
fontWeight: '500',
|
||||
padding: '0'
|
||||
}}
|
||||
onClick={() => {
|
||||
deleteHandler(rowData._id);
|
||||
}}
|
||||
>
|
||||
DELETE
|
||||
</MDButton>
|
||||
</StyledTableCell>
|
||||
{tHeads &&
|
||||
tHeads
|
||||
@@ -87,6 +107,7 @@ function EnhancedTable({
|
||||
data,
|
||||
tHeads,
|
||||
editHandler,
|
||||
deleteHandler,
|
||||
filtersControl,
|
||||
resetFilters
|
||||
}) {
|
||||
@@ -172,6 +193,7 @@ function EnhancedTable({
|
||||
<Row
|
||||
key={rowData._id}
|
||||
editHandler={editHandler}
|
||||
deleteHandler={deleteHandler}
|
||||
rowData={rowData}
|
||||
tHeads={tHeads}
|
||||
/>
|
||||
@@ -304,6 +326,7 @@ EnhancedTable.propTypes = {
|
||||
data: PropTypes.array,
|
||||
tHeads: PropTypes.array,
|
||||
editHandler: PropTypes.any,
|
||||
deleteHandler: PropTypes.any,
|
||||
filtersControl: PropTypes.any,
|
||||
resetFilters: PropTypes.any
|
||||
};
|
||||
|
||||
@@ -38,6 +38,7 @@ function AuthLayout({ header, title, description, illustration, children }) {
|
||||
mt={2}
|
||||
sx={{
|
||||
backgroundImage: `url(${illustration})`,
|
||||
backgroundSize: 'cover',
|
||||
backgroundRepeat: 'no-repeat',
|
||||
backgroundPosition: 'center'
|
||||
}}
|
||||
|
||||
@@ -12,7 +12,9 @@ import {
|
||||
DialogTitle,
|
||||
DialogContent,
|
||||
TextField,
|
||||
DialogActions
|
||||
DialogActions,
|
||||
Button,
|
||||
DialogContentText
|
||||
} from '@mui/material';
|
||||
import DashboardNavbar from 'components/DashboardNavbar';
|
||||
import DashboardLayout from 'layouts/DashboardLayout';
|
||||
@@ -319,6 +321,9 @@ const WarehouseNestedDetails = () => {
|
||||
function EditWarehouseDetails() {
|
||||
const { warehouseId } = useParams();
|
||||
const navigate = useNavigate();
|
||||
const navigateTo = (to) => {
|
||||
navigate(to);
|
||||
};
|
||||
const warehouseData = useSelector(WarehouseSelectors.getWarehouseDetailById(warehouseId));
|
||||
|
||||
const inventoryTypes = useSelector(InventorySelectors.getInventoryDetail);
|
||||
@@ -372,6 +377,14 @@ function EditWarehouseDetails() {
|
||||
}
|
||||
});
|
||||
|
||||
const [deleteAlertOpen, setDeleteAlertOpen] = React.useState(null);
|
||||
const handleDeleteAlertClose = () => {
|
||||
setDeleteAlertOpen(false);
|
||||
};
|
||||
const handleDeleteAlertOpen = () => {
|
||||
setDeleteAlertOpen(true);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<DashboardLayout>
|
||||
@@ -516,7 +529,49 @@ function EditWarehouseDetails() {
|
||||
/>
|
||||
</Box>
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={6} md={6}>
|
||||
<Grid item sx={{ textAlign: 'end' }} xs={12} sm={6} md={6}>
|
||||
<MDButton
|
||||
size="large"
|
||||
color="error"
|
||||
variant="outlined"
|
||||
onClick={handleDeleteAlertOpen}
|
||||
>
|
||||
Delete Warehouse
|
||||
</MDButton>
|
||||
<Dialog
|
||||
open={deleteAlertOpen}
|
||||
aria-labelledby="alert-dialog-title"
|
||||
aria-describedby="alert-dialog-description"
|
||||
onClose={handleDeleteAlertClose}
|
||||
>
|
||||
<DialogTitle id="alert-dialog-title">Confirm Warehouse Delete</DialogTitle>
|
||||
<DialogContent>
|
||||
<DialogContentText id="alert-dialog-description">
|
||||
Are you sure you want to delete this warehouse?
|
||||
</DialogContentText>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button autoFocus onClick={handleDeleteAlertClose}>
|
||||
No
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => {
|
||||
dispatch(
|
||||
WarehouseActions.deleteWarehouseAction({
|
||||
loader: 'loading-request',
|
||||
slug: '/warehouse/',
|
||||
method: 'delete',
|
||||
warehouseId: warehouseData._id,
|
||||
navigateTo
|
||||
})
|
||||
);
|
||||
handleDeleteAlertClose();
|
||||
}}
|
||||
>
|
||||
Yes
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
<Box sx={{ marginTop: '30px' }}>
|
||||
<ImageUploadSingle
|
||||
heading="Upload Warehouse Image"
|
||||
|
||||
@@ -14,7 +14,17 @@ import EnhancedTable from 'components/EnhancedTable';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import WidgetActions from 'redux/WidgetRedux';
|
||||
import { WidgetSelectors } from 'redux/WidgetRedux';
|
||||
import { Grid, MenuItem, Select } from '@mui/material';
|
||||
import {
|
||||
Button,
|
||||
Dialog,
|
||||
DialogActions,
|
||||
DialogContent,
|
||||
DialogContentText,
|
||||
DialogTitle,
|
||||
Grid,
|
||||
MenuItem,
|
||||
Select
|
||||
} from '@mui/material';
|
||||
|
||||
const tHeads = [
|
||||
{ key: 'name', name: '' },
|
||||
@@ -76,6 +86,14 @@ function ItemListing() {
|
||||
);
|
||||
}, []);
|
||||
|
||||
const [deleteAlertOpen, setDeleteAlertOpen] = React.useState(null);
|
||||
const handleDeleteAlertClose = () => {
|
||||
setDeleteAlertOpen(null);
|
||||
};
|
||||
const handleDeleteAlertOpen = (id) => {
|
||||
setDeleteAlertOpen(id);
|
||||
};
|
||||
|
||||
return (
|
||||
<DashboardLayout>
|
||||
<DashboardNavbar />
|
||||
@@ -90,6 +108,53 @@ function ItemListing() {
|
||||
/>
|
||||
|
||||
<MDBox px={5} py={3}>
|
||||
<Dialog
|
||||
open={deleteAlertOpen}
|
||||
aria-labelledby="alert-dialog-title"
|
||||
aria-describedby="alert-dialog-description"
|
||||
onClose={handleDeleteAlertClose}
|
||||
>
|
||||
<DialogTitle id="alert-dialog-title">Confirm Delete</DialogTitle>
|
||||
<DialogContent>
|
||||
<DialogContentText id="alert-dialog-description">
|
||||
Are you sure you want to delete this item?
|
||||
</DialogContentText>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button autoFocus onClick={handleDeleteAlertClose}>
|
||||
No
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => {
|
||||
const refreshDispatch = () => {
|
||||
dispatch(
|
||||
ItemActions.itemRequest({
|
||||
loader: 'loading-request',
|
||||
slug: API.GET_ITEMS_BY_INVENTORY,
|
||||
method: 'get',
|
||||
page: page - 1,
|
||||
perPage,
|
||||
inventoryId,
|
||||
family: sFam || pFam || null
|
||||
})
|
||||
);
|
||||
};
|
||||
dispatch(
|
||||
ItemActions.deleteItemRequest({
|
||||
loader: 'loading-request',
|
||||
slug: '/item/',
|
||||
method: 'delete',
|
||||
itemId: deleteAlertOpen,
|
||||
refreshDispatch
|
||||
})
|
||||
);
|
||||
handleDeleteAlertClose();
|
||||
}}
|
||||
>
|
||||
Yes
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
<EnhancedTable
|
||||
count={count}
|
||||
page={page}
|
||||
@@ -99,6 +164,9 @@ function ItemListing() {
|
||||
editHandler={(id) => {
|
||||
navigateTo(`/setup/inventory/browse/${widgetName}/${inventoryId}/edit/${id}`);
|
||||
}}
|
||||
deleteHandler={(id) => {
|
||||
handleDeleteAlertOpen(id);
|
||||
}}
|
||||
resetFilters={() => {
|
||||
setPFam('');
|
||||
setSFam('');
|
||||
|
||||
@@ -20,7 +20,7 @@ function SetupHome() {
|
||||
icon: <InventoryIcon width={96} height={96} color="#007AFF" />
|
||||
},
|
||||
{
|
||||
name: 'User & Access',
|
||||
name: 'User Access',
|
||||
path: '/setup/users-access',
|
||||
icon: <ProfileCircleIcon width={96} height={96} color="#007AFF" />
|
||||
},
|
||||
@@ -33,7 +33,7 @@ function SetupHome() {
|
||||
return (
|
||||
<DashboardLayout>
|
||||
<DashboardNavbar />
|
||||
<Breadcrumbs title="Setup Warehouse, Inventory, Users" route={[{ name: 'Home', path: '/home' }, { name: 'Setup' }]} />
|
||||
<Breadcrumbs title="Warehouse Management System Setup" route={[{ name: 'Home', path: '/home' }, { name: 'Setup' }]} />
|
||||
<TileBasic tiles={data} />
|
||||
</DashboardLayout>
|
||||
);
|
||||
|
||||
@@ -221,7 +221,7 @@ function UserAccessScreen() {
|
||||
route={[
|
||||
{ name: 'Home', path: '/home' },
|
||||
{ name: 'Setup', path: '/setup' },
|
||||
{ name: 'Users and Access', path: '/setup/users-access' }
|
||||
{ name: 'Users Access' }
|
||||
]}
|
||||
/>
|
||||
<MDBox px={5} py={3}>
|
||||
|
||||
@@ -12,6 +12,8 @@ const { Types, Creators } = createActions({
|
||||
addItemSuccess: ['data'],
|
||||
editItemRequest: ['payload'],
|
||||
editItemSuccess: ['data'],
|
||||
deleteItemRequest: ['payload'],
|
||||
deleteItemSuccess: ['data'],
|
||||
oneItemRequest: ['payload'],
|
||||
oneItemSuccess: ['data']
|
||||
});
|
||||
@@ -91,6 +93,18 @@ export const onEditItemSuccess = (state, { data }) =>
|
||||
item: null
|
||||
});
|
||||
|
||||
export const onDeleteItemRequest = (state, { payload }) =>
|
||||
state.merge({
|
||||
fetching: _.uniq([...state.fetching, payload?.loader]),
|
||||
error: getErrorValue(state?.error, payload?.loader)
|
||||
});
|
||||
|
||||
export const onDeleteItemSuccess = (state, { data }) =>
|
||||
state.merge({
|
||||
fetching: getFetchingValue(state.fetching, data?.loader),
|
||||
error: getErrorValue(state?.error, data?.loader)
|
||||
});
|
||||
|
||||
export const onItemFailure = (state, { error }) =>
|
||||
state.merge({
|
||||
fetching: _.without(state.fetching, error?.loader),
|
||||
@@ -106,6 +120,8 @@ export const itemReducer = createReducer(INITIAL_STATE, {
|
||||
[Types.ADD_ITEM_SUCCESS]: onAddItemSuccess,
|
||||
[Types.EDIT_ITEM_REQUEST]: onEditItemRequest,
|
||||
[Types.EDIT_ITEM_SUCCESS]: onEditItemSuccess,
|
||||
[Types.DELETE_ITEM_REQUEST]: onDeleteItemRequest,
|
||||
[Types.DELETE_ITEM_SUCCESS]: onDeleteItemSuccess,
|
||||
[Types.ONE_ITEM_REQUEST]: onOneItemRequest,
|
||||
[Types.ONE_ITEM_SUCCESS]: onOneItemSuccess
|
||||
});
|
||||
|
||||
@@ -15,7 +15,10 @@ const { Types, Creators } = createActions({
|
||||
|
||||
editWarehouseAction: ['payload'],
|
||||
editWarehouseSuccess: ['data'],
|
||||
editWarehouseFailure: ['error']
|
||||
editWarehouseFailure: ['error'],
|
||||
|
||||
deleteWarehouseAction: ['payload'],
|
||||
deleteWarehouseSuccess: ['data']
|
||||
});
|
||||
|
||||
export const WarehouseTypes = Types;
|
||||
@@ -96,6 +99,21 @@ export const onEditWarehouseSuccess = (state, { data }) =>
|
||||
]
|
||||
});
|
||||
|
||||
export const onDeleteWarehouseAction = (state, { payload }) =>
|
||||
state.merge({
|
||||
fetching: _.uniq([state.fetching, payload?.loader]),
|
||||
error: getErrorValue(state?.error, payload?.loader)
|
||||
});
|
||||
|
||||
export const onDeleteWarehouseSuccess = (state, { data }) =>
|
||||
state.merge({
|
||||
fetching: getFetchingValue(state.fetching, data?.loader),
|
||||
error: getErrorValue(state?.error, data?.loader),
|
||||
warehouseDetail: data?.deletedWarehouseID
|
||||
? [...state.warehouseDetail.filter((x) => x._id !== data?.deletedWarehouseID)]
|
||||
: state.warehouseDetail
|
||||
});
|
||||
|
||||
export const onEditWarehouseFailure = (state, { error }) =>
|
||||
state.merge({
|
||||
fetching: _.without(state.fetching, error?.loader),
|
||||
@@ -113,5 +131,7 @@ export const warehouseReducer = createReducer(INITIAL_STATE, {
|
||||
|
||||
[Types.EDIT_WAREHOUSE_ACTION]: onEditWarehouseAction,
|
||||
[Types.EDIT_WAREHOUSE_SUCCESS]: onEditWarehouseSuccess,
|
||||
[Types.EDIT_WAREHOUSE_FAILURE]: onEditWarehouseFailure
|
||||
[Types.EDIT_WAREHOUSE_FAILURE]: onEditWarehouseFailure,
|
||||
[Types.DELETE_WAREHOUSE_ACTION]: onDeleteWarehouseAction,
|
||||
[Types.DELETE_WAREHOUSE_SUCCESS]: onDeleteWarehouseSuccess
|
||||
});
|
||||
|
||||
@@ -159,9 +159,40 @@ export function* onEditRequestItem({ payload }) {
|
||||
}
|
||||
}
|
||||
|
||||
export function* onDeleteRequestItem({ payload }) {
|
||||
const response = yield call(
|
||||
ApiServices[payload?.method],
|
||||
AuthorizedAPI,
|
||||
payload?.slug + payload?.itemId
|
||||
);
|
||||
if (response?.status === 200) {
|
||||
toast.success(`Successfully deleted item`, {
|
||||
theme: 'colored'
|
||||
});
|
||||
payload.refreshDispatch();
|
||||
yield put(
|
||||
ItemActions.deleteItemSuccess({
|
||||
loader: payload?.loader,
|
||||
item: response?.data?.data
|
||||
})
|
||||
);
|
||||
} else {
|
||||
toast.error('Failed to delete item', {
|
||||
theme: 'colored'
|
||||
});
|
||||
yield put(
|
||||
ItemActions.itemFailure({
|
||||
loader: payload?.loader,
|
||||
error: response?.data
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default [
|
||||
takeEvery(ItemTypes.ITEM_REQUEST, onRequestItem),
|
||||
takeEvery(ItemTypes.ONE_ITEM_REQUEST, onRequestOneItem),
|
||||
takeEvery(ItemTypes.ADD_ITEM_REQUEST, onAddRequestItem),
|
||||
takeEvery(ItemTypes.EDIT_ITEM_REQUEST, onEditRequestItem)
|
||||
takeEvery(ItemTypes.EDIT_ITEM_REQUEST, onEditRequestItem),
|
||||
takeEvery(ItemTypes.DELETE_ITEM_REQUEST, onDeleteRequestItem)
|
||||
];
|
||||
|
||||
@@ -112,8 +112,39 @@ export function* onRequestEditWarehouse({ payload }) {
|
||||
}
|
||||
}
|
||||
|
||||
export function* onRequestDeleteWarehouse({ payload }) {
|
||||
const response = yield call(
|
||||
ApiServices[payload?.method],
|
||||
AuthorizedAPI,
|
||||
payload?.slug + payload?.warehouseId
|
||||
);
|
||||
if (response?.status === 200) {
|
||||
toast.success('Warehouse deleted successfully', {
|
||||
theme: 'colored'
|
||||
});
|
||||
payload.navigateTo('/setup/warehouse');
|
||||
yield put(
|
||||
WarehouseActions.deleteWarehouseSuccess({
|
||||
loader: payload?.loader,
|
||||
deletedWarehouseID: payload?.warehouseId
|
||||
})
|
||||
);
|
||||
} else {
|
||||
toast.error('Failed to delete warehouse', {
|
||||
theme: 'colored'
|
||||
});
|
||||
yield put(
|
||||
WarehouseActions.editWarehouseFailure({
|
||||
loader: payload?.loader,
|
||||
error: response?.data
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default [
|
||||
takeLatest(WarehouseTypes.WAREHOUSE_DATA_ACTION, onRequestWarehouseData),
|
||||
takeLatest(WarehouseTypes.CREATE_WAREHOUSE_ACTION, onRequestCreateWarehouse),
|
||||
takeLatest(WarehouseTypes.EDIT_WAREHOUSE_ACTION, onRequestEditWarehouse)
|
||||
takeLatest(WarehouseTypes.EDIT_WAREHOUSE_ACTION, onRequestEditWarehouse),
|
||||
takeLatest(WarehouseTypes.DELETE_WAREHOUSE_ACTION, onRequestDeleteWarehouse)
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user