mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-17 13:20:31 +00:00
Merge branch 'feature/react-query' of https://github.com/abouolia/Bigcapital into feature/react-query
This commit is contained in:
@@ -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);
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
@@ -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}
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
@@ -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 (
|
||||
|
||||
@@ -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],
|
||||
);
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
@@ -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 (
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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],
|
||||
);
|
||||
}
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
import { useMutation, useQuery, useQueryClient } from 'react-query';
|
||||
import { defaultTo } from 'lodash';
|
||||
import ApiService from 'services/ApiService';
|
||||
import { transformPagination } from 'utils';
|
||||
|
||||
const invalidateQueries = (queryClient) => {
|
||||
queryClient.invalidateQueries('INVENTORY_ADJUSTMENTS');
|
||||
|
||||
queryClient.invalidateQueries('ITEMS');
|
||||
queryClient.invalidateQueries('ITEM');
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates the inventory adjustment to the given item.
|
||||
@@ -11,7 +20,7 @@ export function useCreateInventoryAdjustment(props) {
|
||||
(values) => ApiService.post('inventory_adjustments/quick', values),
|
||||
{
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries('INVENTORY_ADJUSTMENTS');
|
||||
invalidateQueries(queryClient)
|
||||
},
|
||||
...props,
|
||||
},
|
||||
@@ -28,7 +37,7 @@ export function useDeleteInventoryAdjustment(props) {
|
||||
(id) => ApiService.delete(`inventory_adjustments/${id}`),
|
||||
{
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries('INVENTORY_ADJUSTMENTS');
|
||||
invalidateQueries(queryClient)
|
||||
},
|
||||
...props
|
||||
},
|
||||
@@ -38,7 +47,7 @@ export function useDeleteInventoryAdjustment(props) {
|
||||
const inventoryAdjustmentsTransformer = (response) => {
|
||||
return {
|
||||
transactions: response.data.inventoy_adjustments,
|
||||
pagination: response.data.pagination,
|
||||
pagination: transformPagination(response.data.pagination),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -46,20 +55,22 @@ const inventoryAdjustmentsTransformer = (response) => {
|
||||
* Retrieve inventory adjustment list with pagination meta.
|
||||
*/
|
||||
export function useInventoryAdjustments(query, props) {
|
||||
return useQuery(
|
||||
const states = useQuery(
|
||||
['INVENTORY_ADJUSTMENTS', query],
|
||||
() => ApiService.get('inventory_adjustments', { params: query })
|
||||
.then(inventoryAdjustmentsTransformer),
|
||||
{
|
||||
initialData: {
|
||||
transactions: [],
|
||||
pagination: {
|
||||
page: 1,
|
||||
page_size: 12,
|
||||
total: 0
|
||||
},
|
||||
},
|
||||
...props,
|
||||
},
|
||||
props,
|
||||
);
|
||||
return {
|
||||
...states,
|
||||
data: defaultTo(states.data, {
|
||||
transactions: [],
|
||||
pagination: {
|
||||
page: 1,
|
||||
pageSize: 12,
|
||||
total: 0,
|
||||
pagesCount: 0,
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ export function useCreateItem(props) {
|
||||
return useMutation((values) => ApiService.post('items', values), {
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries('ITEMS');
|
||||
queryClient.invalidateQueries('ITEMS_CATEGORIES');
|
||||
},
|
||||
...props,
|
||||
});
|
||||
@@ -33,6 +34,7 @@ export function useEditItem(props) {
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries('ITEMS');
|
||||
queryClient.invalidateQueries('ITEM');
|
||||
queryClient.invalidateQueries('ITEMS_CATEGORIES');
|
||||
},
|
||||
...props,
|
||||
});
|
||||
@@ -48,6 +50,7 @@ export function useDeleteItem(props) {
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries('ITEMS');
|
||||
queryClient.invalidateQueries('ITEM');
|
||||
queryClient.invalidateQueries('ITEMS_CATEGORIES');
|
||||
},
|
||||
...props,
|
||||
});
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { useQuery, useMutation, useQueryClient } from 'react-query';
|
||||
import { defaultTo } from 'lodash';
|
||||
import ApiService from 'services/ApiService';
|
||||
|
||||
/**
|
||||
@@ -7,15 +8,12 @@ import ApiService from 'services/ApiService';
|
||||
export function useCreateItemCategory(props) {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation(
|
||||
(values) => ApiService.post('item_categories', values),
|
||||
{
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries('ITEMS_CATEGORIES');
|
||||
},
|
||||
...props
|
||||
}
|
||||
);
|
||||
return useMutation((values) => ApiService.post('item_categories', values), {
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries('ITEMS_CATEGORIES');
|
||||
},
|
||||
...props,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -29,9 +27,10 @@ export function useEditItemCategory(props) {
|
||||
{
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries('ITEMS_CATEGORIES');
|
||||
queryClient.invalidateQueries('ITEMS');
|
||||
},
|
||||
...props
|
||||
}
|
||||
...props,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -41,14 +40,13 @@ export function useEditItemCategory(props) {
|
||||
export function useDeleteItemCategory(props) {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation(
|
||||
(id) => ApiService.delete(`item_categories/${id}`),
|
||||
{
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries('ITEMS_CATEGORIES');
|
||||
},
|
||||
...props
|
||||
});
|
||||
return useMutation((id) => ApiService.delete(`item_categories/${id}`), {
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries('ITEMS_CATEGORIES');
|
||||
queryClient.invalidateQueries('ITEMS');
|
||||
},
|
||||
...props,
|
||||
});
|
||||
}
|
||||
|
||||
// Transforms items categories.
|
||||
@@ -63,18 +61,22 @@ const transformItemsCategories = (response) => {
|
||||
* Retrieve the items categories.
|
||||
*/
|
||||
export function useItemsCategories(query, props) {
|
||||
return useQuery(
|
||||
const states = useQuery(
|
||||
['ITEMS_CATEGORIES', query],
|
||||
() => ApiService.get(`item_categories`, { params: query })
|
||||
.then(transformItemsCategories),
|
||||
{
|
||||
initialData: {
|
||||
itemsCategories: [],
|
||||
pagination: {}
|
||||
},
|
||||
...props,
|
||||
},
|
||||
() =>
|
||||
ApiService.get(`item_categories`, { params: query }).then(
|
||||
transformItemsCategories,
|
||||
),
|
||||
props,
|
||||
);
|
||||
|
||||
return {
|
||||
...states,
|
||||
data: defaultTo(states.data, {
|
||||
itemsCategories: [],
|
||||
pagination: {},
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -82,13 +84,15 @@ export function useItemsCategories(query, props) {
|
||||
* @param {number} id - Item category.
|
||||
*/
|
||||
export function useItemCategory(id, props) {
|
||||
return useQuery(
|
||||
const states = useQuery(
|
||||
['ITEMS_CATEGORY', id],
|
||||
() => ApiService.get(`item_categories/${id}`)
|
||||
.then(res => res.data.category),
|
||||
{
|
||||
initialData: {},
|
||||
...props,
|
||||
},
|
||||
() =>
|
||||
ApiService.get(`item_categories/${id}`).then((res) => res.data.category),
|
||||
props,
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
...states,
|
||||
data: defaultTo(states.data, {}),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,87 +1,11 @@
|
||||
import ApiService from 'services/ApiService';
|
||||
import t from 'store/types';
|
||||
|
||||
export const submitInventoryAdjustment = ({ form }) => {
|
||||
return (dispatch) =>
|
||||
new Promise((resolve, reject) => {
|
||||
ApiService.post('inventory_adjustments/quick', form)
|
||||
.then((response) => {
|
||||
resolve(response);
|
||||
})
|
||||
.catch((error) => {
|
||||
const { response } = error;
|
||||
const { data } = response;
|
||||
|
||||
reject(data?.errors);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export const deleteInventoryAdjustment = ({ id }) => {
|
||||
return (dispatch) =>
|
||||
new Promise((resolve, reject) => {
|
||||
ApiService.delete(`inventory_adjustments/${id}`)
|
||||
.then((response) => {
|
||||
dispatch({
|
||||
type: t.INVENTORY_ADJUSTMENT_DELETE,
|
||||
payload: { id },
|
||||
});
|
||||
resolve(response);
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error.response.data.errors || []);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export const fetchInventoryAdjustmentsTable = ({ query } = {}) => {
|
||||
return (dispatch, getState) =>
|
||||
new Promise((resolve, reject) => {
|
||||
const pageQuery = getState().inventoryAdjustments.tableQuery;
|
||||
dispatch({
|
||||
type: t.INVENTORY_ADJUSTMENTS_LOADING,
|
||||
payload: {
|
||||
loading: true,
|
||||
},
|
||||
});
|
||||
|
||||
ApiService.get('inventory_adjustments', {
|
||||
params: { ...pageQuery, ...query },
|
||||
})
|
||||
.then((response) => {
|
||||
dispatch({
|
||||
type: t.INVENTORY_ADJUSTMENTS_PAGE_SET,
|
||||
payload: {
|
||||
inventory_adjustments: response.data.inventoy_adjustments,
|
||||
pagination: response.data.pagination,
|
||||
customViewId:
|
||||
response.data?.filter_meta?.view?.custom_view_id || -1,
|
||||
},
|
||||
});
|
||||
dispatch({
|
||||
type: t.INVENTORY_ADJUSTMENT_ITEMS_SET,
|
||||
payload: {
|
||||
inventory_adjustment: response.data.inventoy_adjustments,
|
||||
},
|
||||
});
|
||||
dispatch({
|
||||
type: t.INVENTORY_ADJUSTMENTS_PAGINATION_SET,
|
||||
payload: {
|
||||
pagination: response.data.pagination,
|
||||
customViewId:
|
||||
response.data?.filter_meta?.view?.custom_view_id || -1,
|
||||
},
|
||||
});
|
||||
dispatch({
|
||||
type: t.INVENTORY_ADJUSTMENTS_LOADING,
|
||||
payload: {
|
||||
loading: false,
|
||||
},
|
||||
});
|
||||
resolve(response);
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Sets the inventory adjustments table state.
|
||||
*/
|
||||
export const setInventoryAdjustmentsTableState = (queries) => {
|
||||
return {
|
||||
type: t.INVENTORY_ADJUSTMENTS_TABLE_STATE_SET,
|
||||
payload: { queries },
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,73 +1,17 @@
|
||||
import { createReducer } from '@reduxjs/toolkit';
|
||||
import {
|
||||
viewPaginationSetReducer,
|
||||
createTableQueryReducers,
|
||||
} from 'store/journalNumber.reducer';
|
||||
import t from 'store/types';
|
||||
createTableStateReducers,
|
||||
} from 'store/tableState.reducer';
|
||||
|
||||
const initialState = {
|
||||
items: {},
|
||||
views: {},
|
||||
loading: false,
|
||||
currentViewId: -1,
|
||||
tableQuery: {
|
||||
page_size: 12,
|
||||
page: 1,
|
||||
tableState: {
|
||||
pageSize: 12,
|
||||
pageIndex: 0,
|
||||
sortBy: [],
|
||||
},
|
||||
selectedRows: [],
|
||||
};
|
||||
|
||||
export default createReducer(initialState, {
|
||||
[t.INVENTORY_ADJUSTMENTS_LOADING]: (state, action) => {
|
||||
const { loading } = action.payload;
|
||||
state.loading = loading;
|
||||
},
|
||||
|
||||
[t.INVENTORY_ADJUSTMENT_DELETE]: (state, action) => {
|
||||
const { id } = action.payload;
|
||||
if (typeof state.items[id] !== 'undefined') {
|
||||
delete state.items[id];
|
||||
}
|
||||
},
|
||||
|
||||
[t.INVENTORY_ADJUSTMENTS_PAGE_SET]: (state, action) => {
|
||||
const { customViewId, inventory_adjustments, pagination } = action.payload;
|
||||
|
||||
const viewId = customViewId || -1;
|
||||
const view = state.views[viewId] || {};
|
||||
state.views[viewId] = {
|
||||
...view,
|
||||
pages: {
|
||||
...(state.views?.[viewId]?.pages || {}),
|
||||
[pagination.page]: {
|
||||
ids: inventory_adjustments.map((i) => i.id),
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
[t.INVENTORY_ADJUSTMENT_ITEMS_SET]: (state, action) => {
|
||||
const { inventory_adjustment } = action.payload;
|
||||
const _inventory_adjustment = {};
|
||||
|
||||
inventory_adjustment.forEach((_inventory) => {
|
||||
_inventory_adjustment[_inventory.id] = {
|
||||
..._inventory,
|
||||
};
|
||||
});
|
||||
state.items = {
|
||||
...state.items,
|
||||
..._inventory_adjustment,
|
||||
};
|
||||
},
|
||||
[t.INVENTORY_ADJUSTMENTS_SET_CURRENT_VIEW]: (state, action) => {
|
||||
state.currentViewId = action.currentViewId;
|
||||
},
|
||||
[t.INVENTORY_ADJUSTMENTS_SELECTED_ROW_SET]: (state, action) => {
|
||||
const { selectedRows } = action.payload;
|
||||
state.selectedRows = selectedRows;
|
||||
},
|
||||
|
||||
...viewPaginationSetReducer(t.INVENTORY_ADJUSTMENTS_PAGINATION_SET),
|
||||
...createTableQueryReducers('INVENTORY_ADJUSTMENTS'),
|
||||
...createTableStateReducers('INVENTORY_ADJUSTMENTS'),
|
||||
});
|
||||
|
||||
@@ -1,36 +1,18 @@
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import {
|
||||
pickItemsFromIds,
|
||||
paginationLocationQuery,
|
||||
defaultPaginationMeta,
|
||||
} from 'store/selectors';
|
||||
|
||||
const inventoryAdjustmentTableQuery = (state) =>
|
||||
state.inventoryAdjustments.tableQuery;
|
||||
const inventoryAdjustmentTableState = (state) =>
|
||||
state.inventoryAdjustments.tableState;
|
||||
|
||||
const inventoryAdjustmentsPaginationSelector = (state, props) => {
|
||||
const viewId = state.inventoryAdjustments.currentViewId;
|
||||
return state.inventoryAdjustments.views?.[viewId];
|
||||
};
|
||||
|
||||
const inventoryAdjustmentItemsSelector = (state) =>
|
||||
state.inventoryAdjustments.items;
|
||||
|
||||
const inventoryAdjustmentCurrentPageSelector = (state, props) => {
|
||||
const currentViewId = state.inventoryAdjustments.currentViewId;
|
||||
const currentView = state.inventoryAdjustments.views?.[currentViewId];
|
||||
const currentPageId = currentView?.paginationMeta?.page;
|
||||
|
||||
return currentView?.pages?.[currentPageId];
|
||||
};
|
||||
|
||||
const getinventoryAdjustmentCurrentViewIdSelector = (state) =>
|
||||
state.inventoryAdjustments.currentViewId;
|
||||
|
||||
export const getInvoiceTableQueryFactory = () =>
|
||||
/**
|
||||
* Retrieve the inventory adjustments table state.
|
||||
*/
|
||||
export const getInventroyAdjsTableStateFactory = () =>
|
||||
createSelector(
|
||||
paginationLocationQuery,
|
||||
inventoryAdjustmentTableQuery,
|
||||
inventoryAdjustmentTableState,
|
||||
(locationQuery, tableQuery) => {
|
||||
return {
|
||||
...locationQuery,
|
||||
@@ -38,22 +20,3 @@ export const getInvoiceTableQueryFactory = () =>
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
export const getInventoryAdjustmentCurrentPageFactory = () =>
|
||||
createSelector(
|
||||
inventoryAdjustmentCurrentPageSelector,
|
||||
inventoryAdjustmentItemsSelector,
|
||||
(currentPage, items) => {
|
||||
return typeof currentPage === 'object'
|
||||
? pickItemsFromIds(items, currentPage.ids) || []
|
||||
: [];
|
||||
},
|
||||
);
|
||||
|
||||
export const getInventoryAdjustmentPaginationMetaFactory = () =>
|
||||
createSelector(inventoryAdjustmentsPaginationSelector, (Page) => {
|
||||
return {
|
||||
...defaultPaginationMeta(),
|
||||
...(Page?.paginationMeta || {}),
|
||||
};
|
||||
});
|
||||
|
||||
@@ -1,15 +1,4 @@
|
||||
|
||||
export default {
|
||||
INVENTORY_ADJUSTMENT_ITEMS_SET: 'INVENTORY_ADJUSTMENT_ITEMS_SET',
|
||||
INVENTORY_ADJUSTMENT_DELETE: 'INVENTORY_ADJUSTMENT_DELETE',
|
||||
INVENTORY_ADJUSTMENTS_LOADING: 'INVENTORY_ADJUSTMENTS_LOADING',
|
||||
INVENTORY_ADJUSTMENTS_PAGE_SET: 'INVENTORY_ADJUSTMENTS_PAGE_SET',
|
||||
|
||||
INVENTORY_ADJUSTMENTS_PAGINATION_SET: 'INVENTORY_ADJUSTMENTS_PAGINATION_SET',
|
||||
|
||||
INVENTORY_ADJUSTMENTS_TABLE_QUERIES_ADD:
|
||||
'INVENTORY_ADJUSTMENTS/TABLE_QUERIES_ADD',
|
||||
INVENTORY_ADJUSTMENTS_SET_CURRENT_VIEW:
|
||||
'INVENTORY_ADJUSTMENTS_SET_CURRENT_VIEW',
|
||||
INVENTORY_ADJUSTMENTS_SELECTED_ROW_SET:
|
||||
'INVENTORY_ADJUSTMENTS_SELECTED_ROW_SET',
|
||||
};
|
||||
INVENTORY_ADJUSTMENTS_TABLE_STATE_SET: 'INVENTORY_ADJUSTMENTS/TABLE_STATE_SET',
|
||||
};
|
||||
@@ -1,18 +1,19 @@
|
||||
import { createSelector } from 'reselect';
|
||||
import { getItemById } from 'store/selectors';
|
||||
import { paginationLocationQuery } from 'store/selectors';
|
||||
import { createDeepEqualSelector } from 'utils';
|
||||
|
||||
const itemsCateogoriesDataSelector = (state) => state.itemCategories.categories;
|
||||
const itemCategoryIdFromProps = (state, props) => props.itemCategoryId;
|
||||
// Items categories table state.
|
||||
const itemsCategoriesTableStateSelector = (state) =>
|
||||
state.itemsCategories.tableState;
|
||||
|
||||
export const getItemsCategoriesListFactory = () =>
|
||||
createSelector(itemsCateogoriesDataSelector, (itemsCategories) => {
|
||||
return Object.values(itemsCategories);
|
||||
});
|
||||
|
||||
export const getItemCategoryByIdFactory = () => createSelector(
|
||||
itemsCateogoriesDataSelector,
|
||||
itemCategoryIdFromProps,
|
||||
(itemsCategories, itemCategoryid) => {
|
||||
return getItemById(itemsCategories, itemCategoryid);
|
||||
},
|
||||
);
|
||||
// Get items categories table state marged with location query.
|
||||
export const getItemsCategoriesTableStateFactory = () =>
|
||||
createDeepEqualSelector(
|
||||
paginationLocationQuery,
|
||||
itemsCategoriesTableStateSelector,
|
||||
(locationQuery, tableState) => {
|
||||
return {
|
||||
...locationQuery,
|
||||
...tableState,
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
@@ -1,102 +1,11 @@
|
||||
import ApiService from 'services/ApiService';
|
||||
import t from 'store/types';
|
||||
|
||||
export const submitItemCategory = ({ form }) => {
|
||||
return (dispatch) =>
|
||||
new Promise((resolve, reject) => {
|
||||
ApiService.post('item_categories', form)
|
||||
.then((response) => {
|
||||
resolve(response);
|
||||
})
|
||||
.catch((error) => {
|
||||
const { response } = error;
|
||||
const { data } = response;
|
||||
|
||||
reject(data?.errors);
|
||||
});
|
||||
});
|
||||
};
|
||||
export const fetchItemCategories = ({ query }) => {
|
||||
return (dispatch, getState) =>
|
||||
new Promise((resolve, reject) => {
|
||||
dispatch({
|
||||
type: t.SET_DASHBOARD_REQUEST_LOADING,
|
||||
});
|
||||
dispatch({
|
||||
type: t.ITEM_CATEGORIES_TABLE_LOADING,
|
||||
payload: {
|
||||
loading: true,
|
||||
},
|
||||
});
|
||||
ApiService.get('item_categories', { params: { ...query } })
|
||||
.then((response) => {
|
||||
dispatch({
|
||||
type: t.ITEMS_CATEGORY_LIST_SET,
|
||||
categories: response.data.item_categories,
|
||||
});
|
||||
dispatch({
|
||||
type: t.SET_DASHBOARD_REQUEST_COMPLETED,
|
||||
});
|
||||
dispatch({
|
||||
type: t.ITEM_CATEGORIES_TABLE_LOADING,
|
||||
payload: {
|
||||
loading: false,
|
||||
},
|
||||
});
|
||||
resolve(response);
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export const editItemCategory = (id, form) => {
|
||||
return (dispatch) =>
|
||||
new Promise((resolve, reject) => {
|
||||
ApiService.post(`item_categories/${id}`, form)
|
||||
.then((response) => {
|
||||
resolve(response);
|
||||
})
|
||||
.catch((error) => {
|
||||
const { response } = error;
|
||||
const { data } = response;
|
||||
|
||||
reject(data?.errors);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export const deleteItemCategory = (id) => {
|
||||
return (dispatch) =>
|
||||
new Promise((resolve, reject) => {
|
||||
ApiService.delete(`item_categories/${id}`)
|
||||
.then((response) => {
|
||||
dispatch({
|
||||
type: t.CATEGORY_DELETE,
|
||||
payload: { id },
|
||||
});
|
||||
resolve(response);
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export const deleteBulkItemCategories = ({ ids }) => {
|
||||
return (dispatch) =>
|
||||
new Promise((resolve, reject) => {
|
||||
ApiService.delete(`item_categories`, { params: { ids } })
|
||||
.then((response) => {
|
||||
dispatch({
|
||||
type: t.ITEM_CATEGORIES_BULK_DELETE,
|
||||
payload: { ids },
|
||||
});
|
||||
resolve(response);
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
/**
|
||||
* Sets the items categories table state.
|
||||
*/
|
||||
export const setItemsCategoriesTableState = (queries) => {
|
||||
return {
|
||||
type: t.ITEMS_CATEGORIES_TABLE_STATE_SET,
|
||||
payload: { queries },
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,58 +1,13 @@
|
||||
import t from 'store/types';
|
||||
import { createReducer } from '@reduxjs/toolkit';
|
||||
import {
|
||||
createTableStateReducers,
|
||||
} from 'store/tableState.reducer';
|
||||
|
||||
// Initial state.
|
||||
const initialState = {
|
||||
categories: {},
|
||||
loading: false,
|
||||
selectedRows: [],
|
||||
tableState: {},
|
||||
};
|
||||
|
||||
export default createReducer(initialState, {
|
||||
[t.ITEMS_CATEGORY_LIST_SET]: (state, action) => {
|
||||
const _categories = {};
|
||||
|
||||
action.categories.forEach((category) => {
|
||||
_categories[category.id] = category;
|
||||
});
|
||||
state.categories = {
|
||||
...state.categories,
|
||||
..._categories,
|
||||
};
|
||||
},
|
||||
|
||||
[t.ITEM_CATEGORIES_TABLE_SET]: (state, action) => {},
|
||||
|
||||
[t.CATEGORY_DELETE]: (state, action) => {
|
||||
const { id } = action.payload;
|
||||
|
||||
if (typeof state.categories[id] !== 'undefined') {
|
||||
delete state.categories[id];
|
||||
}
|
||||
},
|
||||
|
||||
[t.ITEM_CATEGORIES_TABLE_LOADING]: (state, action) => {
|
||||
const { loading } = action.payload;
|
||||
state.loading = !!loading;
|
||||
},
|
||||
|
||||
[t.ITEM_CATEGORIES_BULK_DELETE]: (state, action) => {
|
||||
const { ids } = action.payload;
|
||||
const categories = { ...state.categories };
|
||||
|
||||
ids.forEach((id) => {
|
||||
if (typeof categories[id] !== 'undefined') {
|
||||
delete categories[id];
|
||||
}
|
||||
});
|
||||
state.categories = categories;
|
||||
},
|
||||
|
||||
[t.ITEM_CATEGORY_SELECTED_ROW_SET]: (state, action) => {
|
||||
const { selectedRows } = action.payload;
|
||||
state.selectedRows = selectedRows;
|
||||
},
|
||||
...createTableStateReducers('ITEMS_CATEGORIES'),
|
||||
});
|
||||
|
||||
export const getCategoryId = (state, id) => {
|
||||
return state.itemCategories.categories[id] || {};
|
||||
};
|
||||
|
||||
@@ -1,10 +1,3 @@
|
||||
export default {
|
||||
ITEMS_CATEGORY_LIST_SET: 'ITEMS_CATEGORY_LIST_SET',
|
||||
ITEMS_CATEGORY_DATA_TABLE: 'ITEMS_CATEGORY_DATA_TABLE',
|
||||
CATEGORY_DELETE: 'CATEGORY_DELETE',
|
||||
ITEM_CATEGORIES_TABLE_LOADING: 'ITEM_CATEGORIES_TABLE_LOADING',
|
||||
ITEM_CATEGORIES_BULK_DELETE: 'ITEM_CATEGORIES_BULK_DELETE',
|
||||
ITEM_CATEGORIES_TABLE_QUERIES_ADD: 'ITEM_CATEGORIES_TABLE_QUERIES_ADD',
|
||||
ITEM_CATEGORIES_SET_CURRENT_VIEW: 'ITEM_CATEGORIES_SET_CURRENT_VIEW',
|
||||
ITEM_CATEGORY_SELECTED_ROW_SET: 'ITEM_CATEGORY_SELECTED_ROW_SET',
|
||||
ITEMS_CATEGORIES_TABLE_STATE_SET: 'ITEMS_CATEGORIES/TABLE_STATE_SET',
|
||||
};
|
||||
|
||||
@@ -11,7 +11,7 @@ import expenses from './expenses/expenses.reducer';
|
||||
import currencies from './currencies/currencies.reducer';
|
||||
import resources from './resources/resources.reducer';
|
||||
import financialStatements from './financialStatement/financialStatements.reducer';
|
||||
import itemCategories from './itemCategories/itemsCategory.reducer';
|
||||
import itemsCategories from './itemCategories/itemsCategory.reducer';
|
||||
import settings from './settings/settings.reducer';
|
||||
import manualJournals from './manualJournals/manualJournals.reducers';
|
||||
import globalSearch from './search/search.reducer';
|
||||
@@ -45,7 +45,7 @@ export default combineReducers({
|
||||
resources,
|
||||
financialStatements,
|
||||
items,
|
||||
itemCategories,
|
||||
itemsCategories,
|
||||
settings,
|
||||
globalSearch,
|
||||
exchangeRates,
|
||||
|
||||
@@ -531,8 +531,10 @@ export function globalTableStateToTable(globalState) {
|
||||
* Transformes the pagination meta repsonse.
|
||||
*/
|
||||
export function transformPagination(pagination) {
|
||||
const transformed = transformResponse(pagination);
|
||||
|
||||
return {
|
||||
...pagination,
|
||||
pagesCount: getPagesCountFromPaginationMeta(pagination),
|
||||
}
|
||||
...transformed,
|
||||
pagesCount: getPagesCountFromPaginationMeta(transformed),
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user