mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-20 23:00:34 +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 = () => {
|
const afterSubmit = () => {
|
||||||
closeDialog(dialogName);
|
closeDialog(dialogName);
|
||||||
};
|
};
|
||||||
// Handle the response success/
|
// Handle the response success.
|
||||||
const onSuccess = ({ response }) => {
|
const onSuccess = ({ response }) => {
|
||||||
AppToaster.show({
|
AppToaster.show({
|
||||||
message: formatMessage({
|
message: formatMessage({
|
||||||
@@ -80,7 +80,9 @@ function ItemCategoryForm({
|
|||||||
afterSubmit(response);
|
afterSubmit(response);
|
||||||
};
|
};
|
||||||
// Handle the response error.
|
// Handle the response error.
|
||||||
const onError = (errors) => {
|
const onError = (error) => {
|
||||||
|
const { response: { data: { errors } } } = error;
|
||||||
|
|
||||||
transformErrors(errors, { setErrors });
|
transformErrors(errors, { setErrors });
|
||||||
setSubmitting(false);
|
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 InventoryAdjustmentsAlerts from './InventoryAdjustmentsAlerts';
|
||||||
|
|
||||||
import { InventoryAdjustmentsProvider } from './InventoryAdjustmentsProvider';
|
import { InventoryAdjustmentsProvider } from './InventoryAdjustmentsProvider';
|
||||||
import InventoryAdjustmentView from './InventoryAdjustmentView';
|
import InventoryAdjustmentTable from './InventoryAdjustmentTable';
|
||||||
|
|
||||||
import withInventoryAdjustments from './withInventoryAdjustments';
|
import withInventoryAdjustments from './withInventoryAdjustments';
|
||||||
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
|
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
|
||||||
|
|
||||||
import { compose } from 'utils';
|
import { compose, transformTableStateToQuery } from 'utils';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inventory Adjustment List.
|
* Inventory Adjustment List.
|
||||||
@@ -21,18 +21,21 @@ function InventoryAdjustmentList({
|
|||||||
changePageTitle,
|
changePageTitle,
|
||||||
|
|
||||||
// #withInventoryAdjustments
|
// #withInventoryAdjustments
|
||||||
inventoryAdjustmentTableQuery,
|
inventoryAdjustmentTableState,
|
||||||
}) {
|
}) {
|
||||||
const { formatMessage } = useIntl();
|
const { formatMessage } = useIntl();
|
||||||
|
|
||||||
|
// Changes the dashboard title once the page mount.
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
changePageTitle(formatMessage({ id: 'inventory_adjustment_list' }));
|
changePageTitle(formatMessage({ id: 'inventory_adjustment_list' }));
|
||||||
}, [changePageTitle, formatMessage]);
|
}, [changePageTitle, formatMessage]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<InventoryAdjustmentsProvider query={inventoryAdjustmentTableQuery}>
|
<InventoryAdjustmentsProvider
|
||||||
|
query={transformTableStateToQuery(inventoryAdjustmentTableState)}
|
||||||
|
>
|
||||||
<DashboardPageContent>
|
<DashboardPageContent>
|
||||||
<InventoryAdjustmentView />
|
<InventoryAdjustmentTable />
|
||||||
<InventoryAdjustmentsAlerts />
|
<InventoryAdjustmentsAlerts />
|
||||||
</DashboardPageContent>
|
</DashboardPageContent>
|
||||||
</InventoryAdjustmentsProvider>
|
</InventoryAdjustmentsProvider>
|
||||||
@@ -41,7 +44,7 @@ function InventoryAdjustmentList({
|
|||||||
|
|
||||||
export default compose(
|
export default compose(
|
||||||
withDashboardActions,
|
withDashboardActions,
|
||||||
withInventoryAdjustments(({ inventoryAdjustmentTableQuery }) => ({
|
withInventoryAdjustments(({ inventoryAdjustmentTableState }) => ({
|
||||||
inventoryAdjustmentTableQuery,
|
inventoryAdjustmentTableState,
|
||||||
})),
|
})),
|
||||||
)(InventoryAdjustmentList);
|
)(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 React from 'react';
|
||||||
import InventoryAdjustmentDataTable from './InventoryAdjustmentDataTable';
|
import InventoryAdjustmentDataTable from './InventoryAdjustmentDataTable';
|
||||||
import withAlertsActions from 'containers/Alert/withAlertActions';
|
|
||||||
import { useInventoryAdjustmentsContext } from './InventoryAdjustmentsProvider';
|
import { useInventoryAdjustmentsContext } from './InventoryAdjustmentsProvider';
|
||||||
import { compose } from 'utils';
|
import { compose } from 'utils';
|
||||||
|
|
||||||
@@ -11,16 +11,7 @@ function InventoryAdjustmentsView({
|
|||||||
// #withAlertsActions.
|
// #withAlertsActions.
|
||||||
openAlert,
|
openAlert,
|
||||||
}) {
|
}) {
|
||||||
const {
|
|
||||||
isAdjustmentsLoading,
|
|
||||||
inventoryAdjustments,
|
|
||||||
} = useInventoryAdjustmentsContext();
|
|
||||||
|
|
||||||
// Handle delete inventory adjustment transaction.
|
|
||||||
const handleDeleteInventoryAdjustment = ({ id }) => {
|
|
||||||
openAlert('inventory-adjustment-delete', { inventoryId: id });
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<InventoryAdjustmentDataTable
|
<InventoryAdjustmentDataTable
|
||||||
inventoryAdjustments={inventoryAdjustments}
|
inventoryAdjustments={inventoryAdjustments}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import InventoryAdjustmentDeleteAlert from 'containers/Alerts/Items/InventoryAdj
|
|||||||
|
|
||||||
export default function InventoryAdjustmentsAlerts() {
|
export default function InventoryAdjustmentsAlerts() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className={'inventory-adjustments-alert'}>
|
||||||
<InventoryAdjustmentDeleteAlert name={'inventory-adjustment-delete'} />
|
<InventoryAdjustmentDeleteAlert name={'inventory-adjustment-delete'} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -8,19 +8,19 @@ const InventoryAdjustmentsContext = createContext();
|
|||||||
* Accounts chart data provider.
|
* Accounts chart data provider.
|
||||||
*/
|
*/
|
||||||
function InventoryAdjustmentsProvider({ query, ...props }) {
|
function InventoryAdjustmentsProvider({ query, ...props }) {
|
||||||
|
// Handles the inventory adjustments fethcing of the given query.
|
||||||
const {
|
const {
|
||||||
isFetching: isAdjustmentsLoading,
|
isLoading: isAdjustmentsLoading,
|
||||||
data: {
|
isFetching: isAdjustmentsFetching,
|
||||||
transactions: inventoryAdjustments,
|
data: { transactions: inventoryAdjustments, pagination },
|
||||||
pagination,
|
} = useInventoryAdjustments(query, { keepPreviousData: true });
|
||||||
},
|
|
||||||
} = useInventoryAdjustments(query);
|
|
||||||
|
|
||||||
// Provider payload.
|
// Provider payload.
|
||||||
const provider = {
|
const provider = {
|
||||||
inventoryAdjustments,
|
inventoryAdjustments,
|
||||||
isAdjustmentsLoading,
|
isAdjustmentsLoading,
|
||||||
pagination
|
isAdjustmentsFetching,
|
||||||
|
pagination,
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import {
|
|||||||
Popover,
|
Popover,
|
||||||
} from '@blueprintjs/core';
|
} from '@blueprintjs/core';
|
||||||
import { useIntl, FormattedMessage as T } from 'react-intl';
|
import { useIntl, FormattedMessage as T } from 'react-intl';
|
||||||
|
import moment from 'moment';
|
||||||
import { formatMessage } from 'services/intl';
|
import { formatMessage } from 'services/intl';
|
||||||
import { isNumber } from 'lodash';
|
import { isNumber } from 'lodash';
|
||||||
import { Icon, Money, If } from 'components';
|
import { Icon, Money, If } from 'components';
|
||||||
@@ -30,6 +31,9 @@ export const PublishAccessor = (r) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type column accessor.
|
||||||
|
*/
|
||||||
export const TypeAccessor = (row) => {
|
export const TypeAccessor = (row) => {
|
||||||
return row.type ? (
|
return row.type ? (
|
||||||
<Tag minimal={true} round={true} intent={Intent.NONE}>
|
<Tag minimal={true} round={true} intent={Intent.NONE}>
|
||||||
@@ -40,6 +44,9 @@ export const TypeAccessor = (row) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Item type accessor.
|
||||||
|
*/
|
||||||
export const ItemCodeAccessor = (row) =>
|
export const ItemCodeAccessor = (row) =>
|
||||||
row.type ? (
|
row.type ? (
|
||||||
<Tag minimal={true} round={true} intent={Intent.NONE}>
|
<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 } }) => {
|
export const QuantityOnHandCell = ({ cell: { value } }) => {
|
||||||
return isNumber(value) ? (
|
return isNumber(value) ? (
|
||||||
<span className={'quantity_on_hand'}>{value}</span>
|
<span className={'quantity_on_hand'}>{value}</span>
|
||||||
) : null;
|
) : null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cost price cell.
|
||||||
|
*/
|
||||||
export const CostPriceCell = ({ cell: { value } }) => {
|
export const CostPriceCell = ({ cell: { value } }) => {
|
||||||
return !isBlank(value) ? <Money amount={value} currency={'USD'} /> : null;
|
return !isBlank(value) ? <Money amount={value} currency={'USD'} /> : null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sell price cell.
|
||||||
|
*/
|
||||||
export const SellPriceCell = ({ cell: { value } }) => {
|
export const SellPriceCell = ({ cell: { value } }) => {
|
||||||
return !isBlank(value) ? <Money amount={value} currency={'USD'} /> : null;
|
return !isBlank(value) ? <Money amount={value} currency={'USD'} /> : null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Item type accessor.
|
||||||
|
*/
|
||||||
export const ItemTypeAccessor = (row) => {
|
export const ItemTypeAccessor = (row) => {
|
||||||
return row.type ? (
|
return row.type ? (
|
||||||
<Tag minimal={true} round={true} intent={Intent.NONE}>
|
<Tag minimal={true} round={true} intent={Intent.NONE}>
|
||||||
@@ -71,67 +90,104 @@ export const ItemTypeAccessor = (row) => {
|
|||||||
) : null;
|
) : null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ItemsActionMenuList = ({
|
export const ActionsMenu = ({
|
||||||
row: { original },
|
row: { original },
|
||||||
payload: {
|
payload: { onDelete },
|
||||||
onEditItem,
|
|
||||||
onInactivateItem,
|
|
||||||
onActivateItem,
|
|
||||||
onMakeAdjustment,
|
|
||||||
onDeleteItem,
|
|
||||||
},
|
|
||||||
}) => {
|
}) => {
|
||||||
const { formatMessage } = useIntl();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Menu>
|
<Menu>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
icon={<Icon icon="reader-18" />}
|
icon={<Icon icon="reader-18" />}
|
||||||
text={<T id={'view_details'} />}
|
text={formatMessage({ id: 'view_details' })}
|
||||||
/>
|
/>
|
||||||
<MenuDivider />
|
<MenuDivider />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
icon={<Icon icon="pen-18" />}
|
text={formatMessage({ id: 'delete_adjustment' })}
|
||||||
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)}
|
|
||||||
intent={Intent.DANGER}
|
intent={Intent.DANGER}
|
||||||
|
onClick={safeCallback(onDelete, original)}
|
||||||
|
icon={<Icon icon="trash-16" iconSize={16} />}
|
||||||
/>
|
/>
|
||||||
</Menu>
|
</Menu>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ItemsActionsTableCell = (props) => {
|
export const ActionsCell = (props) => {
|
||||||
return (
|
return (<Popover
|
||||||
<Popover
|
content={<ActionsMenu {...props} />}
|
||||||
position={Position.RIGHT_BOTTOM}
|
position={Position.RIGHT_BOTTOM}
|
||||||
content={<ItemsActionMenuList {...props} />}
|
>
|
||||||
>
|
<Button icon={<Icon icon="more-h-16" iconSize={16} />} />
|
||||||
<Button icon={<Icon icon="more-h-16" iconSize={16} />} />
|
</Popover>
|
||||||
</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 { connect } from 'react-redux';
|
||||||
import {
|
import { setInventoryAdjustmentsTableState } from 'store/inventoryAdjustments/inventoryAdjustment.actions';
|
||||||
submitInventoryAdjustment,
|
|
||||||
deleteInventoryAdjustment,
|
|
||||||
fetchInventoryAdjustmentsTable,
|
|
||||||
} from 'store/inventoryAdjustments/inventoryAdjustment.actions';
|
|
||||||
import t from 'store/types';
|
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch) => ({
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
requestSubmitInventoryAdjustment: ({ form }) =>
|
setInventoryAdjustmentTableState: (queries) =>
|
||||||
dispatch(submitInventoryAdjustment({ form })),
|
dispatch(setInventoryAdjustmentsTableState(queries)),
|
||||||
requestFetchInventoryAdjustmentTable: (query = {}) =>
|
|
||||||
dispatch(fetchInventoryAdjustmentsTable({ query: { ...query } })),
|
|
||||||
requestDeleteInventoryAdjustment: (id) =>
|
|
||||||
dispatch(deleteInventoryAdjustment({ id })),
|
|
||||||
|
|
||||||
addInventoryAdjustmentTableQueries: (queries) =>
|
|
||||||
dispatch({
|
|
||||||
type: t.INVENTORY_ADJUSTMENTS_TABLE_QUERIES_ADD,
|
|
||||||
payload: { queries },
|
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(null, mapDispatchToProps);
|
export default connect(null, mapDispatchToProps);
|
||||||
|
|||||||
@@ -1,32 +1,15 @@
|
|||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import {
|
import { getInventroyAdjsTableStateFactory } from 'store/inventoryAdjustments/inventoryAdjustment.selector';
|
||||||
getInvoiceTableQueryFactory,
|
|
||||||
getInventoryAdjustmentCurrentPageFactory,
|
|
||||||
getInventoryAdjustmentPaginationMetaFactory,
|
|
||||||
} from 'store/inventoryAdjustments/inventoryAdjustment.selector';
|
|
||||||
|
|
||||||
export default (mapState) => {
|
export default (mapState) => {
|
||||||
const getInventoryAdjustmentItems = getInventoryAdjustmentCurrentPageFactory();
|
const getInventoryAdjustmentTableState = getInventroyAdjsTableStateFactory();
|
||||||
const getInventoryAdjustmentTableQuery = getInvoiceTableQueryFactory();
|
|
||||||
const getInventoryAdjustmentsPaginationMeta = getInventoryAdjustmentPaginationMetaFactory();
|
|
||||||
|
|
||||||
const mapStateToProps = (state, props) => {
|
const mapStateToProps = (state, props) => {
|
||||||
const query = getInventoryAdjustmentTableQuery(state, props);
|
|
||||||
|
|
||||||
const mapped = {
|
const mapped = {
|
||||||
inventoryAdjustmentCurrentPage: getInventoryAdjustmentItems(
|
inventoryAdjustmentTableState: getInventoryAdjustmentTableState(
|
||||||
state,
|
state,
|
||||||
props,
|
props,
|
||||||
query,
|
|
||||||
),
|
),
|
||||||
inventoryAdjustmentItems: Object.values(state.inventoryAdjustments.items),
|
|
||||||
inventoryAdjustmentTableQuery: query,
|
|
||||||
inventoryAdjustmentsPagination: getInventoryAdjustmentsPaginationMeta(
|
|
||||||
state,
|
|
||||||
props,
|
|
||||||
query,
|
|
||||||
),
|
|
||||||
inventoryAdjustmentLoading: state.inventoryAdjustments.loading,
|
|
||||||
inventoryAdjustmentsSelectedRows: state.inventoryAdjustments.selectedRows,
|
inventoryAdjustmentsSelectedRows: state.inventoryAdjustments.selectedRows,
|
||||||
};
|
};
|
||||||
return mapState ? mapState(mapped, state, props) : mapped;
|
return mapState ? mapState(mapped, state, props) : mapped;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import DashboardPageContent from 'components/Dashboard/DashboardPageContent';
|
|||||||
import ItemsCategoriesAlerts from './ItemsCategoriesAlerts';
|
import ItemsCategoriesAlerts from './ItemsCategoriesAlerts';
|
||||||
import ItemsCategoryActionsBar from './ItemsCategoryActionsBar';
|
import ItemsCategoryActionsBar from './ItemsCategoryActionsBar';
|
||||||
import { ItemsCategoriesProvider } from './ItemsCategoriesProvider';
|
import { ItemsCategoriesProvider } from './ItemsCategoriesProvider';
|
||||||
import ItemCategoriesViewPage from './ItemCategoriesViewPage';
|
import ItemCategoriesTable from './ItemCategoriesTable';
|
||||||
|
|
||||||
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
|
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
|
||||||
import { compose } from 'utils';
|
import { compose } from 'utils';
|
||||||
@@ -22,6 +22,7 @@ const ItemCategoryList = ({
|
|||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
const { formatMessage } = useIntl();
|
const { formatMessage } = useIntl();
|
||||||
|
|
||||||
|
// Changes the dashboard page title once the page mount.
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
id
|
id
|
||||||
? changePageTitle(formatMessage({ id: 'edit_category_details' }))
|
? changePageTitle(formatMessage({ id: 'edit_category_details' }))
|
||||||
@@ -33,7 +34,7 @@ const ItemCategoryList = ({
|
|||||||
<ItemsCategoryActionsBar />
|
<ItemsCategoryActionsBar />
|
||||||
|
|
||||||
<DashboardPageContent>
|
<DashboardPageContent>
|
||||||
<ItemCategoriesViewPage />
|
<ItemCategoriesTable />
|
||||||
</DashboardPageContent>
|
</DashboardPageContent>
|
||||||
<ItemsCategoriesAlerts />
|
<ItemsCategoriesAlerts />
|
||||||
</ItemsCategoriesProvider>
|
</ItemsCategoriesProvider>
|
||||||
|
|||||||
@@ -1,60 +1,52 @@
|
|||||||
import React, { useMemo } from 'react';
|
import React from 'react';
|
||||||
import { useIntl } from 'react-intl';
|
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
|
||||||
import { TableActionsCell } from './components';
|
import { useItemsCategoriesTableColumns, ActionMenuList } from './components';
|
||||||
import DataTable from 'components/DataTable';
|
import DataTable from 'components/DataTable';
|
||||||
import TableSkeletonRows from 'components/Datatable/TableSkeletonRows';
|
import TableSkeletonRows from 'components/Datatable/TableSkeletonRows';
|
||||||
|
|
||||||
import { useItemsCategoriesContext } from './ItemsCategoriesProvider';
|
import { useItemsCategoriesContext } from './ItemsCategoriesProvider';
|
||||||
import { CLASSES } from 'common/classes';
|
import { CLASSES } from 'common/classes';
|
||||||
|
|
||||||
|
import withAlertActions from 'containers/Alert/withAlertActions';
|
||||||
|
import withDialogActions from 'containers/Dialog/withDialogActions';
|
||||||
|
|
||||||
|
import { compose } from 'utils';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Items categories table.
|
* Items categories table.
|
||||||
*/
|
*/
|
||||||
export default function ItemsCategoryTable({
|
function ItemsCategoryTable({
|
||||||
// #ownProps
|
// #ownProps
|
||||||
tableProps,
|
tableProps,
|
||||||
|
|
||||||
|
// #withDialogActions
|
||||||
|
openDialog,
|
||||||
|
|
||||||
|
// #withAlertActions
|
||||||
|
openAlert
|
||||||
}) {
|
}) {
|
||||||
const { formatMessage } = useIntl();
|
// Items categories context.
|
||||||
const {
|
const {
|
||||||
isItemsCategoriesFetching,
|
isCategoriesLoading,
|
||||||
|
isCategoriesFetching,
|
||||||
itemsCategories,
|
itemsCategories,
|
||||||
} = useItemsCategoriesContext();
|
} = useItemsCategoriesContext();
|
||||||
|
|
||||||
// Table columns.
|
// Table columns.
|
||||||
const columns = useMemo(
|
const columns = useItemsCategoriesTableColumns();
|
||||||
() => [
|
|
||||||
{
|
const handleSelectedRowsChange = (selectedRows) => {};
|
||||||
id: 'name',
|
|
||||||
Header: formatMessage({ id: 'category_name' }),
|
// Handle delete Item.
|
||||||
accessor: 'name',
|
const handleDeleteCategory = ({ id }) => {
|
||||||
width: 220,
|
openAlert('item-category-delete', { itemCategoryId: id });
|
||||||
},
|
};
|
||||||
{
|
|
||||||
id: 'description',
|
// Handle Edit item category.
|
||||||
Header: formatMessage({ id: 'description' }),
|
const handleEditCategory = (category) => {
|
||||||
accessor: 'description',
|
openDialog('item-category-form', { action: 'edit', id: category.id });
|
||||||
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],
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classNames(CLASSES.DASHBOARD_DATATABLE)}>
|
<div className={classNames(CLASSES.DASHBOARD_DATATABLE)}>
|
||||||
@@ -62,14 +54,29 @@ export default function ItemsCategoryTable({
|
|||||||
noInitialFetch={true}
|
noInitialFetch={true}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
data={itemsCategories}
|
data={itemsCategories}
|
||||||
loading={isItemsCategoriesFetching}
|
|
||||||
|
loading={isCategoriesLoading}
|
||||||
|
headerLoading={isCategoriesLoading}
|
||||||
|
progressBarLoading={isCategoriesFetching}
|
||||||
|
|
||||||
manualSortBy={true}
|
manualSortBy={true}
|
||||||
expandable={true}
|
expandable={true}
|
||||||
sticky={true}
|
sticky={true}
|
||||||
selectionColumn={true}
|
selectionColumn={true}
|
||||||
TableLoadingRenderer={TableSkeletonRows}
|
TableLoadingRenderer={TableSkeletonRows}
|
||||||
noResults={'There is no items categories in table yet.'}
|
noResults={'There is no items categories in table yet.'}
|
||||||
|
payload={{
|
||||||
|
onDeleteCategory: handleDeleteCategory,
|
||||||
|
onEditCategory: handleEditCategory
|
||||||
|
}}
|
||||||
|
ContextMenu={ActionMenuList}
|
||||||
|
{...tableProps}
|
||||||
/>
|
/>
|
||||||
</div>
|
</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 }) {
|
function ItemsCategoriesProvider({ query, ...props }) {
|
||||||
const {
|
const {
|
||||||
data: { itemsCategories, pagination },
|
data: { itemsCategories, pagination },
|
||||||
isFetching: isItemsCategoriesFetching,
|
isFetching: isCategoriesFetching,
|
||||||
|
isLoading: isCategoriesLoading,
|
||||||
} = useItemsCategories();
|
} = useItemsCategories();
|
||||||
|
|
||||||
const state = {
|
const state = {
|
||||||
isItemsCategoriesFetching,
|
isCategoriesFetching,
|
||||||
|
isCategoriesLoading,
|
||||||
|
|
||||||
itemsCategories,
|
itemsCategories,
|
||||||
pagination,
|
pagination,
|
||||||
|
|
||||||
|
query,
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import { If, Icon } from 'components';
|
|||||||
import DashboardActionsBar from 'components/Dashboard/DashboardActionsBar';
|
import DashboardActionsBar from 'components/Dashboard/DashboardActionsBar';
|
||||||
|
|
||||||
import withDialogActions from 'containers/Dialog/withDialogActions';
|
import withDialogActions from 'containers/Dialog/withDialogActions';
|
||||||
import withItemCategories from './withItemCategories';
|
// import withItemCategories from './withItemCategories';
|
||||||
import withAlertActions from 'containers/Alert/withAlertActions';
|
import withAlertActions from 'containers/Alert/withAlertActions';
|
||||||
|
|
||||||
import { compose } from 'utils';
|
import { compose } from 'utils';
|
||||||
@@ -26,7 +26,7 @@ import { compose } from 'utils';
|
|||||||
*/
|
*/
|
||||||
function ItemsCategoryActionsBar({
|
function ItemsCategoryActionsBar({
|
||||||
// #withItemCategories
|
// #withItemCategories
|
||||||
itemCategoriesSelectedRows,
|
itemCategoriesSelectedRows = [],
|
||||||
|
|
||||||
// #withDialog
|
// #withDialog
|
||||||
openDialog,
|
openDialog,
|
||||||
@@ -103,8 +103,8 @@ function ItemsCategoryActionsBar({
|
|||||||
|
|
||||||
export default compose(
|
export default compose(
|
||||||
withDialogActions,
|
withDialogActions,
|
||||||
withItemCategories(({ itemCategoriesSelectedRows }) => ({
|
// withItemCategories(({ itemCategoriesSelectedRows }) => ({
|
||||||
itemCategoriesSelectedRows,
|
// itemCategoriesSelectedRows,
|
||||||
})),
|
// })),
|
||||||
withAlertActions,
|
withAlertActions,
|
||||||
)(ItemsCategoryActionsBar);
|
)(ItemsCategoryActionsBar);
|
||||||
|
|||||||
@@ -52,3 +52,44 @@ export function TableActionsCell(props) {
|
|||||||
</Popover>
|
</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 { connect } from 'react-redux';
|
||||||
import { getItemsCategoriesListFactory } from 'store/itemCategories/ItemsCategories.selectors';
|
import {
|
||||||
import { getResourceViews } from 'store/customViews/customViews.selectors';
|
getItemsCategoriesTableStateFactory,
|
||||||
|
} from 'store/itemCategories/itemsCategories.selectors';
|
||||||
|
|
||||||
export default (mapState) => {
|
export default (mapState) => {
|
||||||
const getItemsCategoriesList = getItemsCategoriesListFactory();
|
const getItemsCategoriesTableState = getItemsCategoriesTableStateFactory();
|
||||||
|
|
||||||
const mapStateToProps = (state, props) => {
|
const mapStateToProps = (state, props) => {
|
||||||
const mapped = {
|
const mapped = {
|
||||||
categoriesList: getItemsCategoriesList(state, props),
|
itemsCategoriesTableState: getItemsCategoriesTableState(state, props),
|
||||||
itemCategoriesViews: getResourceViews(state, props, 'items_categories'),
|
|
||||||
categoriesTableLoading: state.itemCategories.loading,
|
|
||||||
itemCategoriesSelectedRows: state.itemCategories.selectedRows,
|
|
||||||
};
|
};
|
||||||
return mapState ? mapState(mapped, state, props) : mapState;
|
return mapState ? mapState(mapped, state, props) : mapState;
|
||||||
};
|
};
|
||||||
|
|
||||||
return connect(mapStateToProps);
|
return connect(mapStateToProps);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,38 +1,9 @@
|
|||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import {
|
import { setItemsCategoriesTableState } from 'store/itemCategories/itemsCategory.actions';
|
||||||
fetchItemCategories,
|
|
||||||
submitItemCategory,
|
|
||||||
deleteItemCategory,
|
|
||||||
editItemCategory,
|
|
||||||
deleteBulkItemCategories,
|
|
||||||
} from 'store/itemCategories/itemsCategory.actions';
|
|
||||||
import t from 'store/types';
|
|
||||||
|
|
||||||
export const mapDispatchToProps = (dispatch) => ({
|
export const mapDispatchToProps = (dispatch) => ({
|
||||||
requestSubmitItemCategory: (form) => dispatch(submitItemCategory({ form })),
|
setItemsCategoriesTableState: (state) =>
|
||||||
requestFetchItemCategories: (query) =>
|
dispatch(setItemsCategoriesTableState(state)),
|
||||||
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 },
|
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(null, mapDispatchToProps);
|
export default connect(null, mapDispatchToProps);
|
||||||
|
|||||||
@@ -1,5 +1,14 @@
|
|||||||
import { useMutation, useQuery, useQueryClient } from 'react-query';
|
import { useMutation, useQuery, useQueryClient } from 'react-query';
|
||||||
|
import { defaultTo } from 'lodash';
|
||||||
import ApiService from 'services/ApiService';
|
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.
|
* Creates the inventory adjustment to the given item.
|
||||||
@@ -11,7 +20,7 @@ export function useCreateInventoryAdjustment(props) {
|
|||||||
(values) => ApiService.post('inventory_adjustments/quick', values),
|
(values) => ApiService.post('inventory_adjustments/quick', values),
|
||||||
{
|
{
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
queryClient.invalidateQueries('INVENTORY_ADJUSTMENTS');
|
invalidateQueries(queryClient)
|
||||||
},
|
},
|
||||||
...props,
|
...props,
|
||||||
},
|
},
|
||||||
@@ -28,7 +37,7 @@ export function useDeleteInventoryAdjustment(props) {
|
|||||||
(id) => ApiService.delete(`inventory_adjustments/${id}`),
|
(id) => ApiService.delete(`inventory_adjustments/${id}`),
|
||||||
{
|
{
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
queryClient.invalidateQueries('INVENTORY_ADJUSTMENTS');
|
invalidateQueries(queryClient)
|
||||||
},
|
},
|
||||||
...props
|
...props
|
||||||
},
|
},
|
||||||
@@ -38,7 +47,7 @@ export function useDeleteInventoryAdjustment(props) {
|
|||||||
const inventoryAdjustmentsTransformer = (response) => {
|
const inventoryAdjustmentsTransformer = (response) => {
|
||||||
return {
|
return {
|
||||||
transactions: response.data.inventoy_adjustments,
|
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.
|
* Retrieve inventory adjustment list with pagination meta.
|
||||||
*/
|
*/
|
||||||
export function useInventoryAdjustments(query, props) {
|
export function useInventoryAdjustments(query, props) {
|
||||||
return useQuery(
|
const states = useQuery(
|
||||||
['INVENTORY_ADJUSTMENTS', query],
|
['INVENTORY_ADJUSTMENTS', query],
|
||||||
() => ApiService.get('inventory_adjustments', { params: query })
|
() => ApiService.get('inventory_adjustments', { params: query })
|
||||||
.then(inventoryAdjustmentsTransformer),
|
.then(inventoryAdjustmentsTransformer),
|
||||||
{
|
props,
|
||||||
initialData: {
|
|
||||||
transactions: [],
|
|
||||||
pagination: {
|
|
||||||
page: 1,
|
|
||||||
page_size: 12,
|
|
||||||
total: 0
|
|
||||||
},
|
|
||||||
},
|
|
||||||
...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), {
|
return useMutation((values) => ApiService.post('items', values), {
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
queryClient.invalidateQueries('ITEMS');
|
queryClient.invalidateQueries('ITEMS');
|
||||||
|
queryClient.invalidateQueries('ITEMS_CATEGORIES');
|
||||||
},
|
},
|
||||||
...props,
|
...props,
|
||||||
});
|
});
|
||||||
@@ -33,6 +34,7 @@ export function useEditItem(props) {
|
|||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
queryClient.invalidateQueries('ITEMS');
|
queryClient.invalidateQueries('ITEMS');
|
||||||
queryClient.invalidateQueries('ITEM');
|
queryClient.invalidateQueries('ITEM');
|
||||||
|
queryClient.invalidateQueries('ITEMS_CATEGORIES');
|
||||||
},
|
},
|
||||||
...props,
|
...props,
|
||||||
});
|
});
|
||||||
@@ -48,6 +50,7 @@ export function useDeleteItem(props) {
|
|||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
queryClient.invalidateQueries('ITEMS');
|
queryClient.invalidateQueries('ITEMS');
|
||||||
queryClient.invalidateQueries('ITEM');
|
queryClient.invalidateQueries('ITEM');
|
||||||
|
queryClient.invalidateQueries('ITEMS_CATEGORIES');
|
||||||
},
|
},
|
||||||
...props,
|
...props,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { useQuery, useMutation, useQueryClient } from 'react-query';
|
import { useQuery, useMutation, useQueryClient } from 'react-query';
|
||||||
|
import { defaultTo } from 'lodash';
|
||||||
import ApiService from 'services/ApiService';
|
import ApiService from 'services/ApiService';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -7,15 +8,12 @@ import ApiService from 'services/ApiService';
|
|||||||
export function useCreateItemCategory(props) {
|
export function useCreateItemCategory(props) {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
return useMutation(
|
return useMutation((values) => ApiService.post('item_categories', values), {
|
||||||
(values) => ApiService.post('item_categories', values),
|
onSuccess: () => {
|
||||||
{
|
queryClient.invalidateQueries('ITEMS_CATEGORIES');
|
||||||
onSuccess: () => {
|
},
|
||||||
queryClient.invalidateQueries('ITEMS_CATEGORIES');
|
...props,
|
||||||
},
|
});
|
||||||
...props
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -29,9 +27,10 @@ export function useEditItemCategory(props) {
|
|||||||
{
|
{
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
queryClient.invalidateQueries('ITEMS_CATEGORIES');
|
queryClient.invalidateQueries('ITEMS_CATEGORIES');
|
||||||
|
queryClient.invalidateQueries('ITEMS');
|
||||||
},
|
},
|
||||||
...props
|
...props,
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,14 +40,13 @@ export function useEditItemCategory(props) {
|
|||||||
export function useDeleteItemCategory(props) {
|
export function useDeleteItemCategory(props) {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
return useMutation(
|
return useMutation((id) => ApiService.delete(`item_categories/${id}`), {
|
||||||
(id) => ApiService.delete(`item_categories/${id}`),
|
onSuccess: () => {
|
||||||
{
|
queryClient.invalidateQueries('ITEMS_CATEGORIES');
|
||||||
onSuccess: () => {
|
queryClient.invalidateQueries('ITEMS');
|
||||||
queryClient.invalidateQueries('ITEMS_CATEGORIES');
|
},
|
||||||
},
|
...props,
|
||||||
...props
|
});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transforms items categories.
|
// Transforms items categories.
|
||||||
@@ -63,18 +61,22 @@ const transformItemsCategories = (response) => {
|
|||||||
* Retrieve the items categories.
|
* Retrieve the items categories.
|
||||||
*/
|
*/
|
||||||
export function useItemsCategories(query, props) {
|
export function useItemsCategories(query, props) {
|
||||||
return useQuery(
|
const states = useQuery(
|
||||||
['ITEMS_CATEGORIES', query],
|
['ITEMS_CATEGORIES', query],
|
||||||
() => ApiService.get(`item_categories`, { params: query })
|
() =>
|
||||||
.then(transformItemsCategories),
|
ApiService.get(`item_categories`, { params: query }).then(
|
||||||
{
|
transformItemsCategories,
|
||||||
initialData: {
|
),
|
||||||
itemsCategories: [],
|
props,
|
||||||
pagination: {}
|
|
||||||
},
|
|
||||||
...props,
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
...states,
|
||||||
|
data: defaultTo(states.data, {
|
||||||
|
itemsCategories: [],
|
||||||
|
pagination: {},
|
||||||
|
}),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -82,13 +84,15 @@ export function useItemsCategories(query, props) {
|
|||||||
* @param {number} id - Item category.
|
* @param {number} id - Item category.
|
||||||
*/
|
*/
|
||||||
export function useItemCategory(id, props) {
|
export function useItemCategory(id, props) {
|
||||||
return useQuery(
|
const states = useQuery(
|
||||||
['ITEMS_CATEGORY', id],
|
['ITEMS_CATEGORY', id],
|
||||||
() => ApiService.get(`item_categories/${id}`)
|
() =>
|
||||||
.then(res => res.data.category),
|
ApiService.get(`item_categories/${id}`).then((res) => res.data.category),
|
||||||
{
|
props,
|
||||||
initialData: {},
|
|
||||||
...props,
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
return {
|
||||||
|
...states,
|
||||||
|
data: defaultTo(states.data, {}),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,87 +1,11 @@
|
|||||||
import ApiService from 'services/ApiService';
|
|
||||||
import t from 'store/types';
|
import t from 'store/types';
|
||||||
|
|
||||||
export const submitInventoryAdjustment = ({ form }) => {
|
/**
|
||||||
return (dispatch) =>
|
* Sets the inventory adjustments table state.
|
||||||
new Promise((resolve, reject) => {
|
*/
|
||||||
ApiService.post('inventory_adjustments/quick', form)
|
export const setInventoryAdjustmentsTableState = (queries) => {
|
||||||
.then((response) => {
|
return {
|
||||||
resolve(response);
|
type: t.INVENTORY_ADJUSTMENTS_TABLE_STATE_SET,
|
||||||
})
|
payload: { queries },
|
||||||
.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);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,73 +1,17 @@
|
|||||||
import { createReducer } from '@reduxjs/toolkit';
|
import { createReducer } from '@reduxjs/toolkit';
|
||||||
import {
|
import {
|
||||||
viewPaginationSetReducer,
|
createTableStateReducers,
|
||||||
createTableQueryReducers,
|
} from 'store/tableState.reducer';
|
||||||
} from 'store/journalNumber.reducer';
|
|
||||||
import t from 'store/types';
|
|
||||||
|
|
||||||
const initialState = {
|
const initialState = {
|
||||||
items: {},
|
tableState: {
|
||||||
views: {},
|
pageSize: 12,
|
||||||
loading: false,
|
pageIndex: 0,
|
||||||
currentViewId: -1,
|
sortBy: [],
|
||||||
tableQuery: {
|
|
||||||
page_size: 12,
|
|
||||||
page: 1,
|
|
||||||
},
|
},
|
||||||
selectedRows: [],
|
selectedRows: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
export default createReducer(initialState, {
|
export default createReducer(initialState, {
|
||||||
[t.INVENTORY_ADJUSTMENTS_LOADING]: (state, action) => {
|
...createTableStateReducers('INVENTORY_ADJUSTMENTS'),
|
||||||
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'),
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,36 +1,18 @@
|
|||||||
import { createSelector } from '@reduxjs/toolkit';
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
import {
|
import {
|
||||||
pickItemsFromIds,
|
|
||||||
paginationLocationQuery,
|
paginationLocationQuery,
|
||||||
defaultPaginationMeta,
|
|
||||||
} from 'store/selectors';
|
} from 'store/selectors';
|
||||||
|
|
||||||
const inventoryAdjustmentTableQuery = (state) =>
|
const inventoryAdjustmentTableState = (state) =>
|
||||||
state.inventoryAdjustments.tableQuery;
|
state.inventoryAdjustments.tableState;
|
||||||
|
|
||||||
const inventoryAdjustmentsPaginationSelector = (state, props) => {
|
/**
|
||||||
const viewId = state.inventoryAdjustments.currentViewId;
|
* Retrieve the inventory adjustments table state.
|
||||||
return state.inventoryAdjustments.views?.[viewId];
|
*/
|
||||||
};
|
export const getInventroyAdjsTableStateFactory = () =>
|
||||||
|
|
||||||
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 = () =>
|
|
||||||
createSelector(
|
createSelector(
|
||||||
paginationLocationQuery,
|
paginationLocationQuery,
|
||||||
inventoryAdjustmentTableQuery,
|
inventoryAdjustmentTableState,
|
||||||
(locationQuery, tableQuery) => {
|
(locationQuery, tableQuery) => {
|
||||||
return {
|
return {
|
||||||
...locationQuery,
|
...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 {
|
export default {
|
||||||
INVENTORY_ADJUSTMENT_ITEMS_SET: 'INVENTORY_ADJUSTMENT_ITEMS_SET',
|
INVENTORY_ADJUSTMENTS_TABLE_STATE_SET: 'INVENTORY_ADJUSTMENTS/TABLE_STATE_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',
|
|
||||||
};
|
|
||||||
@@ -1,18 +1,19 @@
|
|||||||
import { createSelector } from 'reselect';
|
import { paginationLocationQuery } from 'store/selectors';
|
||||||
import { getItemById } from 'store/selectors';
|
import { createDeepEqualSelector } from 'utils';
|
||||||
|
|
||||||
const itemsCateogoriesDataSelector = (state) => state.itemCategories.categories;
|
// Items categories table state.
|
||||||
const itemCategoryIdFromProps = (state, props) => props.itemCategoryId;
|
const itemsCategoriesTableStateSelector = (state) =>
|
||||||
|
state.itemsCategories.tableState;
|
||||||
|
|
||||||
export const getItemsCategoriesListFactory = () =>
|
// Get items categories table state marged with location query.
|
||||||
createSelector(itemsCateogoriesDataSelector, (itemsCategories) => {
|
export const getItemsCategoriesTableStateFactory = () =>
|
||||||
return Object.values(itemsCategories);
|
createDeepEqualSelector(
|
||||||
});
|
paginationLocationQuery,
|
||||||
|
itemsCategoriesTableStateSelector,
|
||||||
export const getItemCategoryByIdFactory = () => createSelector(
|
(locationQuery, tableState) => {
|
||||||
itemsCateogoriesDataSelector,
|
return {
|
||||||
itemCategoryIdFromProps,
|
...locationQuery,
|
||||||
(itemsCategories, itemCategoryid) => {
|
...tableState,
|
||||||
return getItemById(itemsCategories, itemCategoryid);
|
};
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,102 +1,11 @@
|
|||||||
import ApiService from 'services/ApiService';
|
|
||||||
import t from 'store/types';
|
import t from 'store/types';
|
||||||
|
|
||||||
export const submitItemCategory = ({ form }) => {
|
/**
|
||||||
return (dispatch) =>
|
* Sets the items categories table state.
|
||||||
new Promise((resolve, reject) => {
|
*/
|
||||||
ApiService.post('item_categories', form)
|
export const setItemsCategoriesTableState = (queries) => {
|
||||||
.then((response) => {
|
return {
|
||||||
resolve(response);
|
type: t.ITEMS_CATEGORIES_TABLE_STATE_SET,
|
||||||
})
|
payload: { queries },
|
||||||
.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);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,58 +1,13 @@
|
|||||||
import t from 'store/types';
|
|
||||||
import { createReducer } from '@reduxjs/toolkit';
|
import { createReducer } from '@reduxjs/toolkit';
|
||||||
|
import {
|
||||||
|
createTableStateReducers,
|
||||||
|
} from 'store/tableState.reducer';
|
||||||
|
|
||||||
|
// Initial state.
|
||||||
const initialState = {
|
const initialState = {
|
||||||
categories: {},
|
tableState: {},
|
||||||
loading: false,
|
|
||||||
selectedRows: [],
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default createReducer(initialState, {
|
export default createReducer(initialState, {
|
||||||
[t.ITEMS_CATEGORY_LIST_SET]: (state, action) => {
|
...createTableStateReducers('ITEMS_CATEGORIES'),
|
||||||
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;
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export const getCategoryId = (state, id) => {
|
|
||||||
return state.itemCategories.categories[id] || {};
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -1,10 +1,3 @@
|
|||||||
export default {
|
export default {
|
||||||
ITEMS_CATEGORY_LIST_SET: 'ITEMS_CATEGORY_LIST_SET',
|
ITEMS_CATEGORIES_TABLE_STATE_SET: 'ITEMS_CATEGORIES/TABLE_STATE_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',
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import expenses from './expenses/expenses.reducer';
|
|||||||
import currencies from './currencies/currencies.reducer';
|
import currencies from './currencies/currencies.reducer';
|
||||||
import resources from './resources/resources.reducer';
|
import resources from './resources/resources.reducer';
|
||||||
import financialStatements from './financialStatement/financialStatements.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 settings from './settings/settings.reducer';
|
||||||
import manualJournals from './manualJournals/manualJournals.reducers';
|
import manualJournals from './manualJournals/manualJournals.reducers';
|
||||||
import globalSearch from './search/search.reducer';
|
import globalSearch from './search/search.reducer';
|
||||||
@@ -45,7 +45,7 @@ export default combineReducers({
|
|||||||
resources,
|
resources,
|
||||||
financialStatements,
|
financialStatements,
|
||||||
items,
|
items,
|
||||||
itemCategories,
|
itemsCategories,
|
||||||
settings,
|
settings,
|
||||||
globalSearch,
|
globalSearch,
|
||||||
exchangeRates,
|
exchangeRates,
|
||||||
|
|||||||
@@ -531,8 +531,10 @@ export function globalTableStateToTable(globalState) {
|
|||||||
* Transformes the pagination meta repsonse.
|
* Transformes the pagination meta repsonse.
|
||||||
*/
|
*/
|
||||||
export function transformPagination(pagination) {
|
export function transformPagination(pagination) {
|
||||||
|
const transformed = transformResponse(pagination);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...pagination,
|
...transformed,
|
||||||
pagesCount: getPagesCountFromPaginationMeta(pagination),
|
pagesCount: getPagesCountFromPaginationMeta(transformed),
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Inject, Service } from 'typedi';
|
import { Inject, Service } from 'typedi';
|
||||||
import { Router, Request, Response, NextFunction } from 'express';
|
import { Router, Request, Response, NextFunction } from 'express';
|
||||||
import { check, param } from 'express-validator';
|
import { check, query, param } from 'express-validator';
|
||||||
import { ServiceError } from 'exceptions';
|
import { ServiceError } from 'exceptions';
|
||||||
import BaseController from '../BaseController';
|
import BaseController from '../BaseController';
|
||||||
import InventoryAdjustmentService from 'services/Inventory/InventoryAdjustmentService';
|
import InventoryAdjustmentService from 'services/Inventory/InventoryAdjustmentService';
|
||||||
@@ -39,12 +39,28 @@ export default class InventoryAdjustmentsController extends BaseController {
|
|||||||
);
|
);
|
||||||
router.get(
|
router.get(
|
||||||
'/',
|
'/',
|
||||||
|
[...this.validateListQuerySchema],
|
||||||
|
this.validationResult,
|
||||||
this.asyncMiddleware(this.getInventoryAdjustments.bind(this)),
|
this.asyncMiddleware(this.getInventoryAdjustments.bind(this)),
|
||||||
this.handleServiceErrors
|
this.handleServiceErrors
|
||||||
);
|
);
|
||||||
return router;
|
return router;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate list query schema
|
||||||
|
*/
|
||||||
|
get validateListQuerySchema() {
|
||||||
|
return [
|
||||||
|
query('column_sort_by').optional().trim().escape(),
|
||||||
|
query('sort_order').optional().isIn(['desc', 'asc']),
|
||||||
|
|
||||||
|
query('page').optional().isNumeric().toInt(),
|
||||||
|
query('page_size').optional().isNumeric().toInt(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Quick inventory adjustment validation schema.
|
* Quick inventory adjustment validation schema.
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user