Merge branch 'feature/react-query' of https://github.com/abouolia/Bigcapital into feature/react-query

This commit is contained in:
elforjani3
2021-02-09 21:10:15 +02:00
32 changed files with 497 additions and 882 deletions

View File

@@ -67,7 +67,7 @@ function ItemCategoryForm({
const afterSubmit = () => {
closeDialog(dialogName);
};
// Handle the response success/
// Handle the response success.
const onSuccess = ({ response }) => {
AppToaster.show({
message: formatMessage({
@@ -80,7 +80,9 @@ function ItemCategoryForm({
afterSubmit(response);
};
// Handle the response error.
const onError = (errors) => {
const onError = (error) => {
const { response: { data: { errors } } } = error;
transformErrors(errors, { setErrors });
setSubmitting(false);
};

View File

@@ -1,195 +0,0 @@
import React, { useCallback, useMemo } from 'react';
import {
Button,
Popover,
Menu,
Intent,
MenuItem,
MenuDivider,
Position,
} from '@blueprintjs/core';
import { useIntl } from 'react-intl';
import moment from 'moment';
import classNames from 'classnames';
import { withRouter } from 'react-router-dom';
import { DataTable, Icon } from 'components';
import { CLASSES } from 'common/classes';
import {
PublishAccessor,
TypeAccessor,
} from './components';
import withDialogActions from 'containers/Dialog/withDialogActions';
import withInventoryAdjustmentActions from './withInventoryAdjustmentActions';
import { compose, saveInvoke } from 'utils';
function InventoryAdjustmentDataTable({
// withInventoryAdjustmentsActions
addInventoryAdjustmentTableQueries,
// #ownProps
isLoading,
inventoryAdjustments,
pagination,
onDeleteInventoryAdjustment,
onSelectedRowsChange,
}) {
const { formatMessage } = useIntl();
const handleDeleteInventoryAdjustment = useCallback(
(_adjustment) => () => {
saveInvoke(onDeleteInventoryAdjustment, _adjustment);
},
[onDeleteInventoryAdjustment],
);
const actionMenuList = useCallback(
(adjustment) => (
<Menu>
<MenuItem
icon={<Icon icon="reader-18" />}
text={formatMessage({ id: 'view_details' })}
/>
<MenuDivider />
<MenuItem
text={formatMessage({ id: 'delete_adjustment' })}
intent={Intent.DANGER}
onClick={handleDeleteInventoryAdjustment(adjustment)}
icon={<Icon icon="trash-16" iconSize={16} />}
/>
</Menu>
),
[handleDeleteInventoryAdjustment, formatMessage],
);
const onRowContextMenu = useCallback(
(cell) => actionMenuList(cell.row.original),
[actionMenuList],
);
const columns = useMemo(
() => [
{
id: 'date',
Header: formatMessage({ id: 'date' }),
accessor: (r) => moment(r.date).format('YYYY MMM DD'),
width: 115,
className: 'date',
},
{
id: 'type',
Header: formatMessage({ id: 'type' }),
accessor: TypeAccessor,
className: 'type',
width: 100,
},
{
id: 'reason',
Header: formatMessage({ id: 'reason' }),
accessor: 'reason',
className: 'reason',
width: 115,
},
{
id: 'reference_no',
Header: formatMessage({ id: 'reference_no' }),
accessor: 'reference_no',
className: 'reference_no',
width: 100,
},
{
id: 'publish',
Header: formatMessage({ id: 'status' }),
accessor: PublishAccessor,
width: 95,
className: 'publish',
},
{
id: 'description',
Header: formatMessage({ id: 'description' }),
accessor: 'description',
disableSorting: true,
width: 85,
className: 'description',
},
{
id: 'created_at',
Header: formatMessage({ id: 'created_at' }),
accessor: (r) => moment(r.created_at).format('YYYY MMM DD'),
width: 125,
className: 'created_at',
},
{
id: 'actions',
Header: '',
Cell: ({ cell }) => (
<Popover
content={actionMenuList(cell.row.original)}
position={Position.RIGHT_BOTTOM}
>
<Button icon={<Icon icon="more-h-16" iconSize={16} />} />
</Popover>
),
className: 'actions',
width: 50,
disableResizing: true,
},
],
[actionMenuList, formatMessage],
);
const handleDataTableFetchData = useCallback(
({ pageSize, pageIndex, sortBy }) => {
addInventoryAdjustmentTableQueries({
...(sortBy.length > 0
? {
column_sort_by: sortBy[0].id,
sort_order: sortBy[0].desc ? 'desc' : 'asc',
}
: {}),
page_size: pageSize,
page: pageIndex + 1,
});
},
[addInventoryAdjustmentTableQueries],
);
const handleSelectedRowsChange = useCallback(
(selectedRows) => {
onSelectedRowsChange &&
onSelectedRowsChange(selectedRows.map((s) => s.original));
},
[onSelectedRowsChange],
);
return (
<div className={classNames(CLASSES.DASHBOARD_DATATABLE)}>
<DataTable
columns={columns}
data={inventoryAdjustments}
onFetchData={handleDataTableFetchData}
manualSortBy={true}
selectionColumn={true}
noInitialFetch={true}
onSelectedRowsChange={handleSelectedRowsChange}
rowContextMenu={onRowContextMenu}
pagination={true}
autoResetSortBy={false}
autoResetPage={false}
isLoading={isLoading}
noResults={'There is no inventory adjustments transactions yet.'}
// pagesCount={inventoryAdjustmentsPagination.pagesCount}
// initialPageSize={inventoryAdjustmentsPagination.pageSize}
// initialPageIndex={inventoryAdjustmentsPagination.page - 1}
/>
</div>
);
}
export default compose(
withRouter,
withDialogActions,
withInventoryAdjustmentActions,
)(InventoryAdjustmentDataTable);

View File

@@ -6,12 +6,12 @@ import DashboardPageContent from 'components/Dashboard/DashboardPageContent';
import InventoryAdjustmentsAlerts from './InventoryAdjustmentsAlerts';
import { InventoryAdjustmentsProvider } from './InventoryAdjustmentsProvider';
import InventoryAdjustmentView from './InventoryAdjustmentView';
import InventoryAdjustmentTable from './InventoryAdjustmentTable';
import withInventoryAdjustments from './withInventoryAdjustments';
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
import { compose } from 'utils';
import { compose, transformTableStateToQuery } from 'utils';
/**
* Inventory Adjustment List.
@@ -21,18 +21,21 @@ function InventoryAdjustmentList({
changePageTitle,
// #withInventoryAdjustments
inventoryAdjustmentTableQuery,
inventoryAdjustmentTableState,
}) {
const { formatMessage } = useIntl();
// Changes the dashboard title once the page mount.
useEffect(() => {
changePageTitle(formatMessage({ id: 'inventory_adjustment_list' }));
}, [changePageTitle, formatMessage]);
return (
<InventoryAdjustmentsProvider query={inventoryAdjustmentTableQuery}>
<InventoryAdjustmentsProvider
query={transformTableStateToQuery(inventoryAdjustmentTableState)}
>
<DashboardPageContent>
<InventoryAdjustmentView />
<InventoryAdjustmentTable />
<InventoryAdjustmentsAlerts />
</DashboardPageContent>
</InventoryAdjustmentsProvider>
@@ -41,7 +44,7 @@ function InventoryAdjustmentList({
export default compose(
withDashboardActions,
withInventoryAdjustments(({ inventoryAdjustmentTableQuery }) => ({
inventoryAdjustmentTableQuery,
withInventoryAdjustments(({ inventoryAdjustmentTableState }) => ({
inventoryAdjustmentTableState,
})),
)(InventoryAdjustmentList);

View File

@@ -0,0 +1,101 @@
import React, { useCallback } from 'react';
import classNames from 'classnames';
import { DataTable } from 'components';
import { CLASSES } from 'common/classes';
import { useInventoryAdjustmentsColumns, ActionsMenu } from './components';
import withAlertsActions from 'containers/Alert/withAlertActions';
import withInventoryAdjustmentActions from './withInventoryAdjustmentActions';
import { useInventoryAdjustmentsContext } from './InventoryAdjustmentsProvider';
import withInventoryAdjustments from './withInventoryAdjustments';
import { compose } from 'utils';
/**
* Inventory adjustments datatable.
*/
function InventoryAdjustmentDataTable({
// #withInventoryAdjustmentsActions
setInventoryAdjustmentTableState,
// #withInventoryAdjustments
inventoryAdjustmentTableState,
// #withAlertsActions
openAlert,
// #ownProps
tableProps
}) {
const {
isAdjustmentsLoading,
isAdjustmentsFetching,
inventoryAdjustments,
pagination
} = useInventoryAdjustmentsContext();
// Handle delete inventory adjustment transaction.
const handleDeleteAdjustment = ({ id }) => {
openAlert('inventory-adjustment-delete', { inventoryId: id });
};
// Inventory adjustments columns.
const columns = useInventoryAdjustmentsColumns();
// Handle the table fetch data once states changing.
const handleDataTableFetchData = useCallback(
({ pageSize, pageIndex, sortBy }) => {
setInventoryAdjustmentTableState({
pageSize,
pageIndex,
sortBy
})
},
[setInventoryAdjustmentTableState],
);
return (
<div className={classNames(CLASSES.DASHBOARD_DATATABLE)}>
<DataTable
columns={columns}
data={inventoryAdjustments}
loading={isAdjustmentsLoading}
headerLoading={isAdjustmentsLoading}
progressBarLoading={isAdjustmentsFetching}
initialState={inventoryAdjustmentTableState}
noInitialFetch={true}
onFetchData={handleDataTableFetchData}
manualSortBy={true}
selectionColumn={true}
pagination={true}
pagesCount={pagination.pagesCount}
autoResetSortBy={false}
autoResetPage={false}
payload={{
onDelete: handleDeleteAdjustment,
}}
ContextMenu={ActionsMenu}
noResults={'There is no inventory adjustments transactions yet.'}
{...tableProps}
/>
</div>
);
}
export default compose(
withAlertsActions,
withInventoryAdjustmentActions,
withInventoryAdjustments(({ inventoryAdjustmentTableState }) => ({
inventoryAdjustmentTableState,
})),
)(InventoryAdjustmentDataTable);

View File

@@ -1,6 +1,6 @@
import React from 'react';
import InventoryAdjustmentDataTable from './InventoryAdjustmentDataTable';
import withAlertsActions from 'containers/Alert/withAlertActions';
import { useInventoryAdjustmentsContext } from './InventoryAdjustmentsProvider';
import { compose } from 'utils';
@@ -11,16 +11,7 @@ function InventoryAdjustmentsView({
// #withAlertsActions.
openAlert,
}) {
const {
isAdjustmentsLoading,
inventoryAdjustments,
} = useInventoryAdjustmentsContext();
// Handle delete inventory adjustment transaction.
const handleDeleteInventoryAdjustment = ({ id }) => {
openAlert('inventory-adjustment-delete', { inventoryId: id });
};
return (
<InventoryAdjustmentDataTable
inventoryAdjustments={inventoryAdjustments}

View File

@@ -3,7 +3,7 @@ import InventoryAdjustmentDeleteAlert from 'containers/Alerts/Items/InventoryAdj
export default function InventoryAdjustmentsAlerts() {
return (
<div>
<div className={'inventory-adjustments-alert'}>
<InventoryAdjustmentDeleteAlert name={'inventory-adjustment-delete'} />
</div>
);

View File

@@ -8,19 +8,19 @@ const InventoryAdjustmentsContext = createContext();
* Accounts chart data provider.
*/
function InventoryAdjustmentsProvider({ query, ...props }) {
// Handles the inventory adjustments fethcing of the given query.
const {
isFetching: isAdjustmentsLoading,
data: {
transactions: inventoryAdjustments,
pagination,
},
} = useInventoryAdjustments(query);
isLoading: isAdjustmentsLoading,
isFetching: isAdjustmentsFetching,
data: { transactions: inventoryAdjustments, pagination },
} = useInventoryAdjustments(query, { keepPreviousData: true });
// Provider payload.
const provider = {
inventoryAdjustments,
isAdjustmentsLoading,
pagination
isAdjustmentsFetching,
pagination,
};
return (

View File

@@ -10,6 +10,7 @@ import {
Popover,
} from '@blueprintjs/core';
import { useIntl, FormattedMessage as T } from 'react-intl';
import moment from 'moment';
import { formatMessage } from 'services/intl';
import { isNumber } from 'lodash';
import { Icon, Money, If } from 'components';
@@ -30,6 +31,9 @@ export const PublishAccessor = (r) => {
);
};
/**
* Type column accessor.
*/
export const TypeAccessor = (row) => {
return row.type ? (
<Tag minimal={true} round={true} intent={Intent.NONE}>
@@ -40,6 +44,9 @@ export const TypeAccessor = (row) => {
);
};
/**
* Item type accessor.
*/
export const ItemCodeAccessor = (row) =>
row.type ? (
<Tag minimal={true} round={true} intent={Intent.NONE}>
@@ -49,20 +56,32 @@ export const ItemCodeAccessor = (row) =>
''
);
/**
* Quantity on hand cell.
*/
export const QuantityOnHandCell = ({ cell: { value } }) => {
return isNumber(value) ? (
<span className={'quantity_on_hand'}>{value}</span>
) : null;
};
/**
* Cost price cell.
*/
export const CostPriceCell = ({ cell: { value } }) => {
return !isBlank(value) ? <Money amount={value} currency={'USD'} /> : null;
};
/**
* Sell price cell.
*/
export const SellPriceCell = ({ cell: { value } }) => {
return !isBlank(value) ? <Money amount={value} currency={'USD'} /> : null;
};
/**
* Item type accessor.
*/
export const ItemTypeAccessor = (row) => {
return row.type ? (
<Tag minimal={true} round={true} intent={Intent.NONE}>
@@ -71,67 +90,104 @@ export const ItemTypeAccessor = (row) => {
) : null;
};
export const ItemsActionMenuList = ({
export const ActionsMenu = ({
row: { original },
payload: {
onEditItem,
onInactivateItem,
onActivateItem,
onMakeAdjustment,
onDeleteItem,
},
payload: { onDelete },
}) => {
const { formatMessage } = useIntl();
return (
<Menu>
<MenuItem
icon={<Icon icon="reader-18" />}
text={<T id={'view_details'} />}
text={formatMessage({ id: 'view_details' })}
/>
<MenuDivider />
<MenuItem
icon={<Icon icon="pen-18" />}
text={formatMessage({ id: 'edit_item' })}
onClick={safeCallback(onEditItem, original)}
/>
<If condition={original.active}>
<MenuItem
text={formatMessage({ id: 'inactivate_item' })}
icon={<Icon icon="pause-16" iconSize={16} />}
onClick={safeCallback(onInactivateItem, original)}
/>
</If>
<If condition={!original.active}>
<MenuItem
text={formatMessage({ id: 'activate_item' })}
icon={<Icon icon="play-16" iconSize={16} />}
onClick={safeCallback(onActivateItem, original)}
/>
</If>
<If condition={original.type === 'inventory'}>
<MenuItem
text={formatMessage({ id: 'make_adjustment' })}
onClick={safeCallback(onMakeAdjustment, original)}
/>
</If>
<MenuItem
text={formatMessage({ id: 'delete_item' })}
icon={<Icon icon="trash-16" iconSize={16} />}
onClick={safeCallback(onDeleteItem, original)}
text={formatMessage({ id: 'delete_adjustment' })}
intent={Intent.DANGER}
onClick={safeCallback(onDelete, original)}
icon={<Icon icon="trash-16" iconSize={16} />}
/>
</Menu>
);
};
export const ItemsActionsTableCell = (props) => {
return (
<Popover
position={Position.RIGHT_BOTTOM}
content={<ItemsActionMenuList {...props} />}
>
<Button icon={<Icon icon="more-h-16" iconSize={16} />} />
</Popover>
export const ActionsCell = (props) => {
return (<Popover
content={<ActionsMenu {...props} />}
position={Position.RIGHT_BOTTOM}
>
<Button icon={<Icon icon="more-h-16" iconSize={16} />} />
</Popover>
);
};
/**
* Retrieve inventory adjustments columns.
*/
export const useInventoryAdjustmentsColumns = () => {
const { formatMessage } = useIntl();
return React.useMemo(
() => [
{
id: 'date',
Header: formatMessage({ id: 'date' }),
accessor: (r) => moment(r.date).format('YYYY MMM DD'),
width: 115,
className: 'date',
},
{
id: 'type',
Header: formatMessage({ id: 'type' }),
accessor: TypeAccessor,
className: 'type',
width: 100,
},
{
id: 'reason',
Header: formatMessage({ id: 'reason' }),
accessor: 'reason',
className: 'reason',
width: 115,
},
{
id: 'reference_no',
Header: formatMessage({ id: 'reference_no' }),
accessor: 'reference_no',
className: 'reference_no',
width: 100,
},
{
id: 'publish',
Header: formatMessage({ id: 'status' }),
accessor: PublishAccessor,
width: 95,
className: 'publish',
},
{
id: 'description',
Header: formatMessage({ id: 'description' }),
accessor: 'description',
disableSorting: true,
width: 85,
className: 'description',
},
{
id: 'created_at',
Header: formatMessage({ id: 'created_at' }),
accessor: (r) => moment(r.created_at).format('YYYY MMM DD'),
width: 125,
className: 'created_at',
},
{
id: 'actions',
Header: '',
Cell: ActionsCell,
className: 'actions',
width: 50,
disableResizing: true,
},
],
[formatMessage],
);
};

View File

@@ -1,24 +1,9 @@
import { connect } from 'react-redux';
import {
submitInventoryAdjustment,
deleteInventoryAdjustment,
fetchInventoryAdjustmentsTable,
} from 'store/inventoryAdjustments/inventoryAdjustment.actions';
import t from 'store/types';
import { setInventoryAdjustmentsTableState } from 'store/inventoryAdjustments/inventoryAdjustment.actions';
const mapDispatchToProps = (dispatch) => ({
requestSubmitInventoryAdjustment: ({ form }) =>
dispatch(submitInventoryAdjustment({ form })),
requestFetchInventoryAdjustmentTable: (query = {}) =>
dispatch(fetchInventoryAdjustmentsTable({ query: { ...query } })),
requestDeleteInventoryAdjustment: (id) =>
dispatch(deleteInventoryAdjustment({ id })),
addInventoryAdjustmentTableQueries: (queries) =>
dispatch({
type: t.INVENTORY_ADJUSTMENTS_TABLE_QUERIES_ADD,
payload: { queries },
}),
setInventoryAdjustmentTableState: (queries) =>
dispatch(setInventoryAdjustmentsTableState(queries)),
});
export default connect(null, mapDispatchToProps);

View File

@@ -1,32 +1,15 @@
import { connect } from 'react-redux';
import {
getInvoiceTableQueryFactory,
getInventoryAdjustmentCurrentPageFactory,
getInventoryAdjustmentPaginationMetaFactory,
} from 'store/inventoryAdjustments/inventoryAdjustment.selector';
import { getInventroyAdjsTableStateFactory } from 'store/inventoryAdjustments/inventoryAdjustment.selector';
export default (mapState) => {
const getInventoryAdjustmentItems = getInventoryAdjustmentCurrentPageFactory();
const getInventoryAdjustmentTableQuery = getInvoiceTableQueryFactory();
const getInventoryAdjustmentsPaginationMeta = getInventoryAdjustmentPaginationMetaFactory();
const getInventoryAdjustmentTableState = getInventroyAdjsTableStateFactory();
const mapStateToProps = (state, props) => {
const query = getInventoryAdjustmentTableQuery(state, props);
const mapped = {
inventoryAdjustmentCurrentPage: getInventoryAdjustmentItems(
inventoryAdjustmentTableState: getInventoryAdjustmentTableState(
state,
props,
query,
),
inventoryAdjustmentItems: Object.values(state.inventoryAdjustments.items),
inventoryAdjustmentTableQuery: query,
inventoryAdjustmentsPagination: getInventoryAdjustmentsPaginationMeta(
state,
props,
query,
),
inventoryAdjustmentLoading: state.inventoryAdjustments.loading,
inventoryAdjustmentsSelectedRows: state.inventoryAdjustments.selectedRows,
};
return mapState ? mapState(mapped, state, props) : mapped;

View File

@@ -7,7 +7,7 @@ import DashboardPageContent from 'components/Dashboard/DashboardPageContent';
import ItemsCategoriesAlerts from './ItemsCategoriesAlerts';
import ItemsCategoryActionsBar from './ItemsCategoryActionsBar';
import { ItemsCategoriesProvider } from './ItemsCategoriesProvider';
import ItemCategoriesViewPage from './ItemCategoriesViewPage';
import ItemCategoriesTable from './ItemCategoriesTable';
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
import { compose } from 'utils';
@@ -22,6 +22,7 @@ const ItemCategoryList = ({
const { id } = useParams();
const { formatMessage } = useIntl();
// Changes the dashboard page title once the page mount.
useEffect(() => {
id
? changePageTitle(formatMessage({ id: 'edit_category_details' }))
@@ -33,7 +34,7 @@ const ItemCategoryList = ({
<ItemsCategoryActionsBar />
<DashboardPageContent>
<ItemCategoriesViewPage />
<ItemCategoriesTable />
</DashboardPageContent>
<ItemsCategoriesAlerts />
</ItemsCategoriesProvider>

View File

@@ -1,60 +1,52 @@
import React, { useMemo } from 'react';
import { useIntl } from 'react-intl';
import React from 'react';
import classNames from 'classnames';
import { TableActionsCell } from './components';
import { useItemsCategoriesTableColumns, ActionMenuList } from './components';
import DataTable from 'components/DataTable';
import TableSkeletonRows from 'components/Datatable/TableSkeletonRows';
import { useItemsCategoriesContext } from './ItemsCategoriesProvider';
import { CLASSES } from 'common/classes';
import withAlertActions from 'containers/Alert/withAlertActions';
import withDialogActions from 'containers/Dialog/withDialogActions';
import { compose } from 'utils';
/**
* Items categories table.
*/
export default function ItemsCategoryTable({
function ItemsCategoryTable({
// #ownProps
tableProps,
// #withDialogActions
openDialog,
// #withAlertActions
openAlert
}) {
const { formatMessage } = useIntl();
// Items categories context.
const {
isItemsCategoriesFetching,
isCategoriesLoading,
isCategoriesFetching,
itemsCategories,
} = useItemsCategoriesContext();
// Table columns.
const columns = useMemo(
() => [
{
id: 'name',
Header: formatMessage({ id: 'category_name' }),
accessor: 'name',
width: 220,
},
{
id: 'description',
Header: formatMessage({ id: 'description' }),
accessor: 'description',
className: 'description',
width: 220,
},
{
id: 'count',
Header: formatMessage({ id: 'count' }),
accessor: 'count',
className: 'count',
width: 180,
},
{
id: 'actions',
Header: '',
Cell: TableActionsCell,
className: 'actions',
width: 50,
},
],
[formatMessage],
);
const columns = useItemsCategoriesTableColumns();
const handleSelectedRowsChange = (selectedRows) => {};
// Handle delete Item.
const handleDeleteCategory = ({ id }) => {
openAlert('item-category-delete', { itemCategoryId: id });
};
// Handle Edit item category.
const handleEditCategory = (category) => {
openDialog('item-category-form', { action: 'edit', id: category.id });
};
return (
<div className={classNames(CLASSES.DASHBOARD_DATATABLE)}>
@@ -62,14 +54,29 @@ export default function ItemsCategoryTable({
noInitialFetch={true}
columns={columns}
data={itemsCategories}
loading={isItemsCategoriesFetching}
loading={isCategoriesLoading}
headerLoading={isCategoriesLoading}
progressBarLoading={isCategoriesFetching}
manualSortBy={true}
expandable={true}
sticky={true}
selectionColumn={true}
TableLoadingRenderer={TableSkeletonRows}
noResults={'There is no items categories in table yet.'}
payload={{
onDeleteCategory: handleDeleteCategory,
onEditCategory: handleEditCategory
}}
ContextMenu={ActionMenuList}
{...tableProps}
/>
</div>
);
}
export default compose(
withDialogActions,
withAlertActions,
)(ItemsCategoryTable);

View File

@@ -1,47 +0,0 @@
import React from 'react';
import ItemCategoriesDataTable from './ItemCategoriesTable';
import withAlertActions from 'containers/Alert/withAlertActions';
import withDialogActions from 'containers/Dialog/withDialogActions';
import { compose } from 'utils';
/**
* Items categories view page.
*/
function ItemsCategoriesViewPage({
// #withAlertsActions
openAlert,
// #withDialogActions
openDialog,
}) {
// Handle selected rows change.
const handleSelectedRowsChange = (selectedRows) => {};
// Handle delete Item.
const handleDeleteCategory = ({ id }) => {
openAlert('item-category-delete', { itemCategoryId: id });
};
// Handle Edit item category.
const handleEditCategory = (category) => {
openDialog('item-category-form', { action: 'edit', id: category.id });
};
return (
<ItemCategoriesDataTable
tableProps={{
payload: {
onDeleteCategory: handleDeleteCategory,
onEditCategory: handleEditCategory,
},
}}
/>
);
}
export default compose(
withDialogActions,
withAlertActions,
)(ItemsCategoriesViewPage);

View File

@@ -10,13 +10,18 @@ const ItemsCategoriesContext = createContext();
function ItemsCategoriesProvider({ query, ...props }) {
const {
data: { itemsCategories, pagination },
isFetching: isItemsCategoriesFetching,
isFetching: isCategoriesFetching,
isLoading: isCategoriesLoading,
} = useItemsCategories();
const state = {
isItemsCategoriesFetching,
isCategoriesFetching,
isCategoriesLoading,
itemsCategories,
pagination,
query,
};
return (

View File

@@ -16,7 +16,7 @@ import { If, Icon } from 'components';
import DashboardActionsBar from 'components/Dashboard/DashboardActionsBar';
import withDialogActions from 'containers/Dialog/withDialogActions';
import withItemCategories from './withItemCategories';
// import withItemCategories from './withItemCategories';
import withAlertActions from 'containers/Alert/withAlertActions';
import { compose } from 'utils';
@@ -26,7 +26,7 @@ import { compose } from 'utils';
*/
function ItemsCategoryActionsBar({
// #withItemCategories
itemCategoriesSelectedRows,
itemCategoriesSelectedRows = [],
// #withDialog
openDialog,
@@ -103,8 +103,8 @@ function ItemsCategoryActionsBar({
export default compose(
withDialogActions,
withItemCategories(({ itemCategoriesSelectedRows }) => ({
itemCategoriesSelectedRows,
})),
// withItemCategories(({ itemCategoriesSelectedRows }) => ({
// itemCategoriesSelectedRows,
// })),
withAlertActions,
)(ItemsCategoryActionsBar);

View File

@@ -52,3 +52,44 @@ export function TableActionsCell(props) {
</Popover>
);
}
/**
* Retrieve the items categories table columns.
*/
export function useItemsCategoriesTableColumns() {
const { formatMessage } = useIntl();
return React.useMemo(
() => [
{
id: 'name',
Header: formatMessage({ id: 'category_name' }),
accessor: 'name',
width: 220,
},
{
id: 'count',
Header: formatMessage({ id: 'count' }),
accessor: 'count',
className: 'count',
width: 180,
},
{
id: 'description',
Header: formatMessage({ id: 'description' }),
accessor: 'description',
className: 'description',
width: 220,
},
{
id: 'actions',
Header: '',
Cell: TableActionsCell,
className: 'actions',
width: 50,
},
],
[formatMessage],
);
}

View File

@@ -1,19 +1,16 @@
import { connect } from 'react-redux';
import { getItemsCategoriesListFactory } from 'store/itemCategories/ItemsCategories.selectors';
import { getResourceViews } from 'store/customViews/customViews.selectors';
import {
getItemsCategoriesTableStateFactory,
} from 'store/itemCategories/itemsCategories.selectors';
export default (mapState) => {
const getItemsCategoriesList = getItemsCategoriesListFactory();
const getItemsCategoriesTableState = getItemsCategoriesTableStateFactory();
const mapStateToProps = (state, props) => {
const mapped = {
categoriesList: getItemsCategoriesList(state, props),
itemCategoriesViews: getResourceViews(state, props, 'items_categories'),
categoriesTableLoading: state.itemCategories.loading,
itemCategoriesSelectedRows: state.itemCategories.selectedRows,
const mapped = {
itemsCategoriesTableState: getItemsCategoriesTableState(state, props),
};
return mapState ? mapState(mapped, state, props) : mapState;
};
return connect(mapStateToProps);
};

View File

@@ -1,38 +1,9 @@
import { connect } from 'react-redux';
import {
fetchItemCategories,
submitItemCategory,
deleteItemCategory,
editItemCategory,
deleteBulkItemCategories,
} from 'store/itemCategories/itemsCategory.actions';
import t from 'store/types';
import { setItemsCategoriesTableState } from 'store/itemCategories/itemsCategory.actions';
export const mapDispatchToProps = (dispatch) => ({
requestSubmitItemCategory: (form) => dispatch(submitItemCategory({ form })),
requestFetchItemCategories: (query) =>
dispatch(fetchItemCategories({ query })),
requestDeleteItemCategory: (id) => dispatch(deleteItemCategory(id)),
requestEditItemCategory: (id, form) => dispatch(editItemCategory(id, form)),
requestDeleteBulkItemCategories: (ids) =>
dispatch(deleteBulkItemCategories({ ids })),
changeItemCategoriesView: (id) =>
dispatch({
type: t.ITEM_CATEGORIES_SET_CURRENT_VIEW,
currentViewId: parseInt(id, 10),
}),
addItemCategoriesTableQueries: (queries) =>
dispatch({
type: t.ITEM_CATEGORIES_TABLE_QUERIES_ADD,
queries,
}),
setSelectedRowsCategories: (selectedRows) =>
dispatch({
type: t.ITEM_CATEGORY_SELECTED_ROW_SET,
payload: { selectedRows },
}),
setItemsCategoriesTableState: (state) =>
dispatch(setItemsCategoriesTableState(state)),
});
export default connect(null, mapDispatchToProps);