fix bugs in items form.

This commit is contained in:
Ahmed Bouhuolia
2020-04-15 01:29:46 +02:00
parent 26faaddfed
commit cac6620ffe
20 changed files with 378 additions and 129 deletions

View File

@@ -117,8 +117,7 @@ function AccountsChart({
console.log(accounts);
};
const handleFilterChanged = useCallback(() => {
const handleFilterChanged = useCallback(() => {
fetchAccountsHook.execute();
}, [fetchAccountsHook]);

View File

@@ -6,11 +6,13 @@ import ItemForm from 'components/Items/ItemForm';
import DashboardInsider from 'components/Dashboard/DashboardInsider';
import ItemsConnect from 'connectors/Items.connect';
import AccountsConnect from 'connectors/Accounts.connector';
import ItemCategoryConnect from 'connectors/ItemsCategory.connect';
import { compose } from 'utils';
const ItemFormContainer = ({
changePageTitle,
fetchAccounts,
requestFetchAccounts,
requestFetchItemCategories,
}) => {
const { id } = useParams();
useEffect(() => {
@@ -21,11 +23,12 @@ const ItemFormContainer = ({
const fetchHook = useAsync(async () => {
await Promise.all([
fetchAccounts(),
requestFetchAccounts(),
requestFetchItemCategories(),
]);
});
return (
<DashboardInsider isLoading={fetchHook.loading} name={'item-form'}>
<DashboardInsider loading={fetchHook.loading} name={'item-form'}>
<ItemForm />
</DashboardInsider>
);
@@ -35,4 +38,5 @@ export default compose(
DashboardConnect,
ItemsConnect,
AccountsConnect,
ItemCategoryConnect,
)(ItemFormContainer);

View File

@@ -1,4 +1,4 @@
import React, { useMemo } from 'react';
import React, { useMemo, useCallback } from 'react';
import { useRouteMatch, useHistory } from 'react-router-dom';
import DashboardActionsBar from 'components/Dashboard/DashboardActionsBar';
@@ -13,7 +13,7 @@ import {
Position,
Button,
Classes,
Intent
Intent,
} from '@blueprintjs/core';
import classNames from 'classnames';
import Icon from 'components/Icon';
@@ -28,8 +28,9 @@ const ItemsActionsBar = ({
getResourceFields,
getResourceViews,
views,
onFilterChange,
bulkSelected
onFilterChanged,
bulkSelected,
addItemsTableQueries,
}) => {
const { path } = useRouteMatch();
const history = useHistory();
@@ -46,7 +47,12 @@ const ItemsActionsBar = ({
const filterDropdown = FilterDropdown({
fields: itemsFields,
onFilterChange
onFilterChange: (filterConditions) => {
addItemsTableQueries({
filter_roles: filterConditions || '',
});
onFilterChanged && onFilterChanged(filterConditions);
}
});
const hasBulkActionsSelected = useMemo(
@@ -54,9 +60,9 @@ const ItemsActionsBar = ({
[bulkSelected]
);
const onClickNewCategory = () => {
const onClickNewCategory = useCallback(() => {
openDialog('item-form', {});
};
}, [openDialog]);
return (
<DashboardActionsBar>

View File

@@ -1,4 +1,4 @@
import React, {useEffect, useMemo} from 'react';
import React, {useEffect, useCallback, useMemo} from 'react';
import {
Button,
Popover,
@@ -6,87 +6,76 @@ import {
MenuItem,
MenuDivider,
Position,
Checkbox,
} from '@blueprintjs/core'
import LoadingIndicator from 'components/LoadingIndicator';
import CustomViewConnect from 'connectors/View.connector';
import ItemsConnect from 'connectors/Items.connect';
import {useParams} from 'react-router-dom'
import {compose} from 'utils';
import useAsync from 'hooks/async';
import DataTable from 'components/DataTable';
import Icon from 'components/Icon';
import {handleBooleanChange} from 'utils';
import Money from 'components/Money';
const ItemsDataTable = ({
requestFetchItems,
filterConditions,
itemsTableLoading,
currentPageItems,
onEditItem,
onDeleteItem,
addBulkActionItem,
removeBulkActionItem,
onFetchData,
}) => {
const { custom_view_id: customViewId } = useParams();
const fetchHook = useAsync(async () => {
await Promise.all([
requestFetchItems({
custom_view_id: customViewId,
stringified_filter_roles: JSON.stringify(filterConditions),
}),
]);
});
const handleEditItem = (item) => () => { onEditItem(item); };
const handleDeleteItem = (item) => () => { onDeleteItem(item); };
const handleClickCheckboxBulk = (item) => handleBooleanChange((value) => {
if (value) {
addBulkActionItem(item.id);
} else {
removeBulkActionItem(item.id);
}
});
const actionMenuList = (item) =>
const actionMenuList = useCallback((item) =>
(<Menu>
<MenuItem text="View Details" />
<MenuDivider />
<MenuItem text="Edit Item" onClick={handleEditItem(item)} />
<MenuItem text="Delete Item" onClick={handleDeleteItem(item)} />
</Menu>);
</Menu>), [handleEditItem, handleDeleteItem]);
const columns = useMemo(() => [
{
id: 'bulk_select',
Cell: ({ cell }) =>
(<Checkbox onChange={handleClickCheckboxBulk(cell.row.original)} />),
},
{
Header: 'Item Name',
accessor: 'name',
className: "actions",
},
{
Header: 'Cost Account',
accessor: 'cost_account.name',
className: "cost-account",
},
{
Header: 'Sell Account',
accessor: 'sell_account.name',
className: "sell-account",
},
{
Header: 'Inventory Account',
accessor: 'inventory_account.name',
className: "inventory-account",
Header: 'SKU',
accessor: 'sku',
className: "sku",
},
{
Header: 'Category',
accessor: 'category.name',
className: 'category',
},
{
Header: 'Sell Price',
accessor: row => (<Money amount={row.sell_price} currency={'USD'} />),
className: 'sell-price',
},
{
Header: 'Cost Price',
accessor: row => (<Money amount={row.cost_price} currency={'USD'} />),
className: 'cost-price',
},
// {
// Header: 'Cost Account',
// accessor: 'cost_account.name',
// className: "cost-account",
// },
// {
// Header: 'Sell Account',
// accessor: 'sell_account.name',
// className: "sell-account",
// },
// {
// Header: 'Inventory Account',
// accessor: 'inventory_account.name',
// className: "inventory-account",
// },
{
id: 'actions',
Cell: ({ cell }) => (
@@ -96,14 +85,28 @@ const ItemsDataTable = ({
<Button icon={<Icon icon="ellipsis-h" />} />
</Popover>
),
className: 'actions',
width: 50,
},
]);
], [actionMenuList]);
const selectionColumn = useMemo(() => ({
minWidth: 42,
width: 42,
maxWidth: 42,
}), []);
const handleFetchData = useCallback((...args) => {
onFetchData && onFetchData(...args)
}, [onFetchData])
return (
<LoadingIndicator loading={fetchHook.pending} spinnerSize={30}>
<LoadingIndicator loading={itemsTableLoading} spinnerSize={30}>
<DataTable
columns={columns}
data={currentPageItems} />
data={currentPageItems}
selectionColumn={selectionColumn}
onFetchData={handleFetchData} />
</LoadingIndicator>
);
};

View File

@@ -1,4 +1,4 @@
import React, { useEffect, useState } from 'react';
import React, { useEffect, useCallback, useState } from 'react';
import {
Route,
Switch,
@@ -17,22 +17,24 @@ import ResourceConnect from 'connectors/Resource.connector';
import DashboardConnect from 'connectors/Dashboard.connector';
import ItemsConnect from 'connectors/Items.connect';
import CustomViewsConnect from 'connectors/CustomView.connector'
import DashboardViewsTabs from 'components/Accounts/AccountsViewsTabs';
import ItemsViewsTabs from 'containers/Dashboard/Items/ItemsViewsTabs';
import AppToaster from 'components/AppToaster';
function ItemsList({
changePageTitle,
fetchResourceViews,
fetchResourceFields,
views,
requestDeleteItem,
requestFetchItems,
addItemsTableQueries,
}) {
const [filterConditions, setFilterConditions] = useState([]);
const [deleteItem, setDeleteItem] = useState(false);
useEffect(() => {
changePageTitle('Items List');
}, []);
}, [changePageTitle]);
const fetchHook = useAsync(async () => {
await Promise.all([
@@ -40,31 +42,68 @@ function ItemsList({
fetchResourceFields('items'),
])
});
const handleDeleteItem = (item) => { setDeleteItem(item); };
const fetchItems = useAsync(async () => {
await Promise.all([
requestFetchItems({ }),
])
});
const handleDeleteItem = useCallback((item) => {
setDeleteItem(item);
}, [setDeleteItem]);
const handleEditItem = () => {};
const handleCancelDeleteItem = () => { setDeleteItem(false) };
const handleConfirmDeleteItem = () => {
const handleCancelDeleteItem = useCallback(() => {
setDeleteItem(false);
}, [setDeleteItem]);
const handleConfirmDeleteItem = useCallback(() => {
requestDeleteItem(deleteItem.id).then(() => {
AppToaster.show({ message: 'the_item_has_been_deleted' });
setDeleteItem(false);
});
};
}, [requestDeleteItem, deleteItem]);
const handleFilterChange = (filter) => { setFilterConditions(filter); };
const handleFetchData = useCallback(({ pageIndex, pageSize, sortBy }) => {
addItemsTableQueries({
...(sortBy.length > 0) ? {
column_sort_by: sortBy[0].id,
sort_by: sortBy[0].desc ? 'desc' : 'asc',
} : {},
});
fetchItems.execute();
}, [fetchItems, addItemsTableQueries]);
const handleFilterChanged = useCallback(() => {
fetchItems.execute();
}, [fetchItems]);
const handleCustomViewChanged = useCallback(() => {
fetchItems.execute();
}, [fetchItems]);
return (
<DashboardInsider isLoading={fetchHook.pending} name={'items-list'}>
<ItemsActionsBar views={views} onFilterChange={handleFilterChange} />
<ItemsActionsBar
onFilterChanged={handleFilterChanged}
views={views} />
<DashboardPageContent>
<Switch>
<Route>
<DashboardViewsTabs resourceName={'items'} />
<Route
exact={true}
path={[
'/dashboard/items/:custom_view_id/custom_view',
'/dashboard/items'
]}>
<ItemsViewsTabs onViewChanged={handleCustomViewChanged} />
<ItemsDataTable
filterConditions={filterConditions}
onDeleteItem={handleDeleteItem}
onEditItem={handleEditItem} />
onEditItem={handleEditItem}
onFetchData={handleFetchData} />
<Alert
cancelButtonText="Cancel"

View File

@@ -0,0 +1,94 @@
import React, {useEffect} from 'react';
import { useHistory } from 'react-router';
import { connect } from 'react-redux';
import {
Alignment,
Navbar,
NavbarGroup,
Tabs,
Tab,
Button
} from '@blueprintjs/core';
import { useParams } from 'react-router-dom';
import Icon from 'components/Icon';
import { Link } from 'react-router-dom';
import { compose } from 'utils';
import ItemsConnect from 'connectors/Items.connect';
import DashboardConnect from 'connectors/Dashboard.connector';
import {useUpdateEffect} from 'hooks';
function ItemsViewsTabs({
views,
setTopbarEditView,
customViewChanged,
addItemsTableQueries,
onViewChanged,
}) {
const history = useHistory();
const { custom_view_id: customViewId } = useParams();
const handleClickNewView = () => {
setTopbarEditView(null);
history.push('/dashboard/custom_views/items/new');
};
const handleViewLinkClick = () => {
setTopbarEditView(customViewId);
}
useUpdateEffect(() => {
customViewChanged && customViewChanged(customViewId);
addItemsTableQueries({
custom_view_id: customViewId || null,
});
onViewChanged && onViewChanged(customViewId);
}, [customViewId]);
useEffect(() => {
addItemsTableQueries({
custom_view_id: customViewId,
})
}, [customViewId, addItemsTableQueries]);
const tabs = views.map(view => {
const baseUrl = '/dashboard/items';
const link = (
<Link
to={`${baseUrl}/${view.id}/custom_view`}
onClick={handleViewLinkClick}
>{view.name}</Link>
);
return <Tab
id={`custom_view_${view.id}`}
title={link} />;
});
return (
<Navbar className='navbar--dashboard-views'>
<NavbarGroup align={Alignment.LEFT}>
<Tabs
id='navbar'
large={true}
selectedTabId={`custom_view_${customViewId}`}
className='tabs--dashboard-views'
>
<Tab
id='all'
title={<Link to={`/dashboard/items`}>All</Link>} />
{tabs}
<Button
className='button--new-view'
icon={<Icon icon='plus' />}
onClick={handleClickNewView}
minimal={true}
/>
</Tabs>
</NavbarGroup>
</Navbar>
);
}
export default compose(
ItemsConnect,
DashboardConnect,
)(ItemsViewsTabs);