mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-19 06:10:31 +00:00
WIP feature/Bulk delete items
This commit is contained in:
@@ -15,7 +15,7 @@ import { Row, Col } from 'react-grid-system';
|
||||
import { FormattedMessage as T, useIntl } from 'react-intl';
|
||||
import { Select } from '@blueprintjs/select';
|
||||
import { queryCache } from 'react-query';
|
||||
import {useParams} from 'react-router-dom';
|
||||
import {useParams ,useHistory} from 'react-router-dom';
|
||||
import AppToaster from 'components/AppToaster';
|
||||
import { compose } from 'utils';
|
||||
import ErrorMessage from 'components/ErrorMessage';
|
||||
@@ -27,13 +27,13 @@ import withAccounts from 'containers/Accounts/withAccounts';
|
||||
import withMediaActions from 'containers/Media/withMediaActions';
|
||||
|
||||
import MoneyInputGroup from 'components/MoneyInputGroup';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import Dragzone from 'components/Dragzone';
|
||||
import useMedia from 'hooks/useMedia';
|
||||
import withItems from './withItems';
|
||||
import withItemDetail from 'containers/Items/withItemDetail'
|
||||
import { pick } from 'lodash';
|
||||
import withDashboardActions from 'containers/Dashboard/withDashboard';
|
||||
import withAccountDetail from 'containers/Accounts/withAccountDetail';
|
||||
|
||||
|
||||
const ItemForm = ({
|
||||
@@ -42,11 +42,10 @@ const ItemForm = ({
|
||||
requestSubmitItem,
|
||||
requestEditItem,
|
||||
|
||||
|
||||
accounts,
|
||||
accountsTypes,
|
||||
itemDetail,
|
||||
|
||||
onFormSubmit,
|
||||
onCancelForm,
|
||||
|
||||
|
||||
// #withDashboard
|
||||
@@ -65,7 +64,7 @@ const ItemForm = ({
|
||||
}) => {
|
||||
|
||||
const [selectedAccounts, setSelectedAccounts] = useState({});
|
||||
const [selectedAccountType, setSelectedAccountType] = useState(null);
|
||||
const [payload, setPayload] = useState({});
|
||||
|
||||
const history = useHistory();
|
||||
const { formatMessage } = useIntl();
|
||||
@@ -132,6 +131,9 @@ const ItemForm = ({
|
||||
}
|
||||
}), [itemDetail, defaultInitialValues]);
|
||||
|
||||
const saveInvokeSubmit = useCallback((payload) => {
|
||||
onFormSubmit && onFormSubmit(payload)
|
||||
}, [onFormSubmit]);
|
||||
|
||||
useEffect(() => {
|
||||
itemDetail && itemDetail.id ?
|
||||
@@ -170,6 +172,8 @@ const ItemForm = ({
|
||||
intent:Intent.SUCCESS
|
||||
});
|
||||
setSubmitting(false);
|
||||
saveInvokeSubmit({action:'update',...payload})
|
||||
history.push('/items');
|
||||
resetForm();
|
||||
}).catch((errors)=>{
|
||||
setSubmitting(false)
|
||||
@@ -229,18 +233,6 @@ const ItemForm = ({
|
||||
};
|
||||
|
||||
|
||||
// Set default
|
||||
// useEffect(()=>{
|
||||
|
||||
// if(itemDetail && itemDetail.id){
|
||||
// const defaultType = itemDetail.find(
|
||||
// (t) => t.id === itemDetail.id
|
||||
// );
|
||||
|
||||
// defaultType && setSelectedAccountType(defaultType);
|
||||
// }
|
||||
|
||||
// },[])
|
||||
const onItemAccountSelect = useCallback(
|
||||
(filedName) => {
|
||||
return (account) => {
|
||||
@@ -637,10 +629,10 @@ const ItemForm = ({
|
||||
};
|
||||
|
||||
export default compose(
|
||||
withAccounts(({accounts,accountsTypes})=>({
|
||||
withAccounts(({accounts})=>({
|
||||
accounts,
|
||||
accountsTypes
|
||||
})),
|
||||
withAccountDetail,
|
||||
withItemsActions,
|
||||
withItemDetail,
|
||||
withItemCategories(({ categoriesList }) => ({
|
||||
|
||||
@@ -17,7 +17,7 @@ import { compose } from 'utils';
|
||||
import DashboardActionsBar from 'components/Dashboard/DashboardActionsBar';
|
||||
import Icon from 'components/Icon';
|
||||
import FilterDropdown from 'components/FilterDropdown';
|
||||
import DialogConnect from 'connectors/Dialog.connector';
|
||||
import withDialog from 'connectors/Dialog.connector';
|
||||
import withResourceDetail from 'containers/Resources/withResourceDetails';
|
||||
import withItems from 'containers/Items/withItems';
|
||||
import { If } from 'components';
|
||||
@@ -34,6 +34,7 @@ const ItemsActionsBar = ({
|
||||
|
||||
onFilterChanged,
|
||||
selectedRows = [],
|
||||
onBulkDelete,
|
||||
}) => {
|
||||
const { path } = useRouteMatch();
|
||||
const history = useHistory();
|
||||
@@ -43,9 +44,11 @@ const ItemsActionsBar = ({
|
||||
<MenuItem href={`${path}/${view.id}/custom_view`} text={view.name} />
|
||||
));
|
||||
|
||||
const onClickNewItem = () => {
|
||||
|
||||
const onClickNewItem = useCallback(() => {
|
||||
history.push('/items/new');
|
||||
};
|
||||
}, [history]);
|
||||
|
||||
const hasSelectedRows = useMemo(() => selectedRows.length > 0, [
|
||||
selectedRows,
|
||||
]);
|
||||
@@ -61,6 +64,11 @@ const ItemsActionsBar = ({
|
||||
const onClickNewCategory = useCallback(() => {
|
||||
openDialog('item-form', {});
|
||||
}, [openDialog]);
|
||||
|
||||
const handleBulkDelete = useCallback(() => {
|
||||
onBulkDelete && onBulkDelete(selectedRows.map(r => r.id));
|
||||
}, [onBulkDelete, selectedRows]);
|
||||
|
||||
|
||||
return (
|
||||
<DashboardActionsBar>
|
||||
@@ -116,9 +124,10 @@ const ItemsActionsBar = ({
|
||||
<If condition={hasSelectedRows}>
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
icon={<Icon icon='trash' iconSize={15} />}
|
||||
text={<T id={'delete'}/>}
|
||||
intent={Intent.DANGER}
|
||||
icon={<Icon icon='trash' />}
|
||||
text={<T id={'delete'} />}
|
||||
onClick={handleBulkDelete}
|
||||
/>
|
||||
</If>
|
||||
|
||||
@@ -138,7 +147,7 @@ const ItemsActionsBar = ({
|
||||
};
|
||||
|
||||
export default compose(
|
||||
DialogConnect,
|
||||
withDialog,
|
||||
withItems(({ itemsViews }) => ({
|
||||
itemsViews,
|
||||
})),
|
||||
|
||||
@@ -137,6 +137,9 @@ const ItemsDataTable = ({
|
||||
onFetchData={handleFetchData}
|
||||
loading={itemsTableLoading && !initialMount}
|
||||
noInitialFetch={true}
|
||||
expandable={true}
|
||||
treeGraph={true}
|
||||
spinnerProps={{size: 30}}
|
||||
onSelectedRowsChange={handleSelectedRowsChange} />
|
||||
</LoadingIndicator>
|
||||
);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useCallback, useState } from 'react';
|
||||
import React, { useEffect, useCallback, useState,useMemo } from 'react';
|
||||
import {
|
||||
Route,
|
||||
Switch,
|
||||
@@ -43,10 +43,12 @@ function ItemsList({
|
||||
requestDeleteItem,
|
||||
requestFetchItems,
|
||||
addItemsTableQueries,
|
||||
requestDeleteBulkItems,
|
||||
}) {
|
||||
const [deleteItem, setDeleteItem] = useState(false);
|
||||
const [selectedRows, setSelectedRows] = useState([]);
|
||||
const [tableLoading, setTableLoading] = useState(false);
|
||||
const [bulkDelete, setBulkDelete] = useState(false);
|
||||
|
||||
const { formatMessage } = useIntl();
|
||||
|
||||
@@ -130,8 +132,35 @@ function ItemsList({
|
||||
const handleSelectedRowsChange = useCallback((accounts) => {
|
||||
setSelectedRows(accounts);
|
||||
}, [setSelectedRows]);
|
||||
|
||||
|
||||
// Calculates the data table selected rows count.
|
||||
const selectedRowsCount = useMemo(() => Object.values(selectedRows).length, [selectedRows]);
|
||||
|
||||
|
||||
|
||||
// Handle items bulk delete button click.,
|
||||
|
||||
const handleBulkDelete = useCallback((itemsIds) => {
|
||||
setBulkDelete(itemsIds);
|
||||
}, [setBulkDelete]);
|
||||
|
||||
// Handle confirm items bulk delete.
|
||||
const handleConfirmBulkDelete = useCallback(() => {
|
||||
requestDeleteBulkItems(bulkDelete).then(() => {
|
||||
setBulkDelete(false);
|
||||
AppToaster.show({
|
||||
message: formatMessage({ id: 'the_items_has_been_successfully_deleted' }),
|
||||
intent: Intent.SUCCESS,
|
||||
});
|
||||
}).catch((errors) => {
|
||||
setBulkDelete(false);
|
||||
});
|
||||
}, [requestDeleteBulkItems, bulkDelete]);
|
||||
|
||||
// Handle cancel accounts bulk delete.
|
||||
const handleCancelBulkDelete = useCallback(() => {
|
||||
setBulkDelete(false);
|
||||
}, []);
|
||||
|
||||
|
||||
return (
|
||||
@@ -140,8 +169,9 @@ function ItemsList({
|
||||
name={'items-list'}>
|
||||
|
||||
<ItemsActionsBar
|
||||
selectedRows={selectedRows}
|
||||
onFilterChanged={handleFilterChanged}
|
||||
selectedRows={selectedRows} />
|
||||
onBulkDelete={handleBulkDelete}/>
|
||||
|
||||
<DashboardPageContent>
|
||||
<Switch>
|
||||
@@ -174,6 +204,20 @@ function ItemsList({
|
||||
id={'once_delete_this_item_you_will_able_to_restore_it'} />
|
||||
</p>
|
||||
</Alert>
|
||||
|
||||
<Alert
|
||||
cancelButtonText={<T id={'cancel'}/>}
|
||||
confirmButtonText={`${formatMessage({id:'delete'})} (${selectedRowsCount})`}
|
||||
icon="trash"
|
||||
intent={Intent.DANGER}
|
||||
isOpen={bulkDelete}
|
||||
onCancel={handleCancelBulkDelete}
|
||||
onConfirm={handleConfirmBulkDelete}
|
||||
>
|
||||
<p>
|
||||
<T id={'once_delete_these_items_you_will_not_able_restore_them'} />
|
||||
</p>
|
||||
</Alert>
|
||||
</Route>
|
||||
</Switch>
|
||||
</DashboardPageContent>
|
||||
|
||||
@@ -4,12 +4,14 @@ import {
|
||||
deleteItem,
|
||||
submitItem,
|
||||
editItem,
|
||||
deleteBulkItems
|
||||
} from 'store/items/items.actions';
|
||||
import t from 'store/types';
|
||||
|
||||
export const mapDispatchToProps = (dispatch) => ({
|
||||
requestFetchItems: (query) => dispatch(fetchItems({ query })),
|
||||
requestDeleteItem: (id) => dispatch(deleteItem({ id })),
|
||||
requestDeleteBulkItems:(ids)=>dispatch(deleteBulkItems({ids})),
|
||||
requestSubmitItem: (form) => dispatch(submitItem({ form })),
|
||||
requestEditItem:(id,form) => dispatch(editItem({id,form})),
|
||||
addBulkActionItem: (id) => dispatch({
|
||||
|
||||
Reference in New Issue
Block a user