diff --git a/client/src/containers/Dialogs/ItemCategoryDialog/ItemCategoryForm.js b/client/src/containers/Dialogs/ItemCategoryDialog/ItemCategoryForm.js
index bcb8981be..df4561014 100644
--- a/client/src/containers/Dialogs/ItemCategoryDialog/ItemCategoryForm.js
+++ b/client/src/containers/Dialogs/ItemCategoryDialog/ItemCategoryForm.js
@@ -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);
};
diff --git a/client/src/containers/InventoryAdjustments/InventoryAdjustmentDataTable.js b/client/src/containers/InventoryAdjustments/InventoryAdjustmentDataTable.js
deleted file mode 100644
index 4a2ce1330..000000000
--- a/client/src/containers/InventoryAdjustments/InventoryAdjustmentDataTable.js
+++ /dev/null
@@ -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) => (
-
- ),
- [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 }) => (
-
- } />
-
- ),
- 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 (
-
-
-
- );
-}
-
-export default compose(
- withRouter,
- withDialogActions,
- withInventoryAdjustmentActions,
-)(InventoryAdjustmentDataTable);
diff --git a/client/src/containers/InventoryAdjustments/InventoryAdjustmentList.js b/client/src/containers/InventoryAdjustments/InventoryAdjustmentList.js
index 5d0956af7..b64c8bd69 100644
--- a/client/src/containers/InventoryAdjustments/InventoryAdjustmentList.js
+++ b/client/src/containers/InventoryAdjustments/InventoryAdjustmentList.js
@@ -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 (
-
+
-
+
@@ -41,7 +44,7 @@ function InventoryAdjustmentList({
export default compose(
withDashboardActions,
- withInventoryAdjustments(({ inventoryAdjustmentTableQuery }) => ({
- inventoryAdjustmentTableQuery,
+ withInventoryAdjustments(({ inventoryAdjustmentTableState }) => ({
+ inventoryAdjustmentTableState,
})),
)(InventoryAdjustmentList);
diff --git a/client/src/containers/InventoryAdjustments/InventoryAdjustmentTable.js b/client/src/containers/InventoryAdjustments/InventoryAdjustmentTable.js
new file mode 100644
index 000000000..f195f6167
--- /dev/null
+++ b/client/src/containers/InventoryAdjustments/InventoryAdjustmentTable.js
@@ -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 (
+
+
+
+ );
+}
+
+export default compose(
+ withAlertsActions,
+ withInventoryAdjustmentActions,
+ withInventoryAdjustments(({ inventoryAdjustmentTableState }) => ({
+ inventoryAdjustmentTableState,
+ })),
+)(InventoryAdjustmentDataTable);
diff --git a/client/src/containers/InventoryAdjustments/InventoryAdjustmentView.js b/client/src/containers/InventoryAdjustments/InventoryAdjustmentView.js
index 8509ca145..0f698d6f5 100644
--- a/client/src/containers/InventoryAdjustments/InventoryAdjustmentView.js
+++ b/client/src/containers/InventoryAdjustments/InventoryAdjustmentView.js
@@ -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 (
+
);
diff --git a/client/src/containers/InventoryAdjustments/InventoryAdjustmentsProvider.js b/client/src/containers/InventoryAdjustments/InventoryAdjustmentsProvider.js
index 553b92200..ef560fbb0 100644
--- a/client/src/containers/InventoryAdjustments/InventoryAdjustmentsProvider.js
+++ b/client/src/containers/InventoryAdjustments/InventoryAdjustmentsProvider.js
@@ -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 (
diff --git a/client/src/containers/InventoryAdjustments/components.js b/client/src/containers/InventoryAdjustments/components.js
index 74e56ecd9..0f0bbc3e5 100644
--- a/client/src/containers/InventoryAdjustments/components.js
+++ b/client/src/containers/InventoryAdjustments/components.js
@@ -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 ? (
@@ -40,6 +44,9 @@ export const TypeAccessor = (row) => {
);
};
+/**
+ * Item type accessor.
+ */
export const ItemCodeAccessor = (row) =>
row.type ? (
@@ -49,20 +56,32 @@ export const ItemCodeAccessor = (row) =>
''
);
+/**
+ * Quantity on hand cell.
+ */
export const QuantityOnHandCell = ({ cell: { value } }) => {
return isNumber(value) ? (
{value}
) : null;
};
+/**
+ * Cost price cell.
+ */
export const CostPriceCell = ({ cell: { value } }) => {
return !isBlank(value) ? : null;
};
+/**
+ * Sell price cell.
+ */
export const SellPriceCell = ({ cell: { value } }) => {
return !isBlank(value) ? : null;
};
+/**
+ * Item type accessor.
+ */
export const ItemTypeAccessor = (row) => {
return row.type ? (
@@ -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 (
);
};
-export const ItemsActionsTableCell = (props) => {
- return (
- }
- >
- } />
-
+export const ActionsCell = (props) => {
+ return (}
+ position={Position.RIGHT_BOTTOM}
+ >
+ } />
+
+ );
+};
+
+/**
+ * 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],
);
};
diff --git a/client/src/containers/InventoryAdjustments/withInventoryAdjustmentActions.js b/client/src/containers/InventoryAdjustments/withInventoryAdjustmentActions.js
index f596e2b0f..6890cf166 100644
--- a/client/src/containers/InventoryAdjustments/withInventoryAdjustmentActions.js
+++ b/client/src/containers/InventoryAdjustments/withInventoryAdjustmentActions.js
@@ -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);
diff --git a/client/src/containers/InventoryAdjustments/withInventoryAdjustments.js b/client/src/containers/InventoryAdjustments/withInventoryAdjustments.js
index cbd3077e3..f95184530 100644
--- a/client/src/containers/InventoryAdjustments/withInventoryAdjustments.js
+++ b/client/src/containers/InventoryAdjustments/withInventoryAdjustments.js
@@ -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;
diff --git a/client/src/containers/ItemsCategories/ItemCategoriesList.js b/client/src/containers/ItemsCategories/ItemCategoriesList.js
index ca3f9e637..8cd428810 100644
--- a/client/src/containers/ItemsCategories/ItemCategoriesList.js
+++ b/client/src/containers/ItemsCategories/ItemCategoriesList.js
@@ -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 = ({
-
+
diff --git a/client/src/containers/ItemsCategories/ItemCategoriesTable.js b/client/src/containers/ItemsCategories/ItemCategoriesTable.js
index 176ccd293..3f5367e7d 100644
--- a/client/src/containers/ItemsCategories/ItemCategoriesTable.js
+++ b/client/src/containers/ItemsCategories/ItemCategoriesTable.js
@@ -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 (
@@ -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}
/>
);
}
+
+export default compose(
+ withDialogActions,
+ withAlertActions,
+)(ItemsCategoryTable);
\ No newline at end of file
diff --git a/client/src/containers/ItemsCategories/ItemCategoriesViewPage.js b/client/src/containers/ItemsCategories/ItemCategoriesViewPage.js
deleted file mode 100644
index 908d4ae0d..000000000
--- a/client/src/containers/ItemsCategories/ItemCategoriesViewPage.js
+++ /dev/null
@@ -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 (
-
- );
-}
-
-export default compose(
- withDialogActions,
- withAlertActions,
-)(ItemsCategoriesViewPage);
diff --git a/client/src/containers/ItemsCategories/ItemsCategoriesProvider.js b/client/src/containers/ItemsCategories/ItemsCategoriesProvider.js
index d79ba396f..aeb558a4d 100644
--- a/client/src/containers/ItemsCategories/ItemsCategoriesProvider.js
+++ b/client/src/containers/ItemsCategories/ItemsCategoriesProvider.js
@@ -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 (
diff --git a/client/src/containers/ItemsCategories/ItemsCategoryActionsBar.js b/client/src/containers/ItemsCategories/ItemsCategoryActionsBar.js
index 3b50ebd91..4acb452c1 100644
--- a/client/src/containers/ItemsCategories/ItemsCategoryActionsBar.js
+++ b/client/src/containers/ItemsCategories/ItemsCategoryActionsBar.js
@@ -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);
diff --git a/client/src/containers/ItemsCategories/components.js b/client/src/containers/ItemsCategories/components.js
index ae2ba0d20..b7d9a6137 100644
--- a/client/src/containers/ItemsCategories/components.js
+++ b/client/src/containers/ItemsCategories/components.js
@@ -52,3 +52,44 @@ export function TableActionsCell(props) {
);
}
+
+/**
+ * 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],
+ );
+}
\ No newline at end of file
diff --git a/client/src/containers/ItemsCategories/withItemCategories.js b/client/src/containers/ItemsCategories/withItemCategories.js
index 6b3fcb7e7..8b33e841d 100644
--- a/client/src/containers/ItemsCategories/withItemCategories.js
+++ b/client/src/containers/ItemsCategories/withItemCategories.js
@@ -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);
};
diff --git a/client/src/containers/ItemsCategories/withItemCategoriesActions.js b/client/src/containers/ItemsCategories/withItemCategoriesActions.js
index 81caaa114..ee571bd1b 100644
--- a/client/src/containers/ItemsCategories/withItemCategoriesActions.js
+++ b/client/src/containers/ItemsCategories/withItemCategoriesActions.js
@@ -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);
diff --git a/client/src/hooks/query/inventoryAdjustments.js b/client/src/hooks/query/inventoryAdjustments.js
index e398694d7..079ee9ae8 100644
--- a/client/src/hooks/query/inventoryAdjustments.js
+++ b/client/src/hooks/query/inventoryAdjustments.js
@@ -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,
+ }
+ })
+ }
}
\ No newline at end of file
diff --git a/client/src/hooks/query/items.js b/client/src/hooks/query/items.js
index 47fbeba03..90786a7df 100644
--- a/client/src/hooks/query/items.js
+++ b/client/src/hooks/query/items.js
@@ -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,
});
diff --git a/client/src/hooks/query/itemsCategories.js b/client/src/hooks/query/itemsCategories.js
index ee2f7daae..3453ef4c7 100644
--- a/client/src/hooks/query/itemsCategories.js
+++ b/client/src/hooks/query/itemsCategories.js
@@ -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,
);
-}
\ No newline at end of file
+
+ return {
+ ...states,
+ data: defaultTo(states.data, {}),
+ };
+}
diff --git a/client/src/store/inventoryAdjustments/inventoryAdjustment.actions.js b/client/src/store/inventoryAdjustments/inventoryAdjustment.actions.js
index 89fd1f50a..fc1f6ad41 100644
--- a/client/src/store/inventoryAdjustments/inventoryAdjustment.actions.js
+++ b/client/src/store/inventoryAdjustments/inventoryAdjustment.actions.js
@@ -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 },
+ };
};
diff --git a/client/src/store/inventoryAdjustments/inventoryAdjustment.reducer.js b/client/src/store/inventoryAdjustments/inventoryAdjustment.reducer.js
index 5c36769ff..71a1cb803 100644
--- a/client/src/store/inventoryAdjustments/inventoryAdjustment.reducer.js
+++ b/client/src/store/inventoryAdjustments/inventoryAdjustment.reducer.js
@@ -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'),
});
diff --git a/client/src/store/inventoryAdjustments/inventoryAdjustment.selector.js b/client/src/store/inventoryAdjustments/inventoryAdjustment.selector.js
index 1625e57f3..1b9e3345a 100644
--- a/client/src/store/inventoryAdjustments/inventoryAdjustment.selector.js
+++ b/client/src/store/inventoryAdjustments/inventoryAdjustment.selector.js
@@ -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 || {}),
- };
- });
diff --git a/client/src/store/inventoryAdjustments/inventoryAdjustment.type.js b/client/src/store/inventoryAdjustments/inventoryAdjustment.type.js
index 0ffd5b4c0..a8fbdc5dd 100644
--- a/client/src/store/inventoryAdjustments/inventoryAdjustment.type.js
+++ b/client/src/store/inventoryAdjustments/inventoryAdjustment.type.js
@@ -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',
+};
\ No newline at end of file
diff --git a/client/src/store/itemCategories/ItemsCategories.selectors.js b/client/src/store/itemCategories/ItemsCategories.selectors.js
index 86bdcfb46..9f9afc637 100644
--- a/client/src/store/itemCategories/ItemsCategories.selectors.js
+++ b/client/src/store/itemCategories/ItemsCategories.selectors.js
@@ -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,
+ };
+ },
+ );
diff --git a/client/src/store/itemCategories/itemsCategory.actions.js b/client/src/store/itemCategories/itemsCategory.actions.js
index 8487faaac..e14e1fcdb 100644
--- a/client/src/store/itemCategories/itemsCategory.actions.js
+++ b/client/src/store/itemCategories/itemsCategory.actions.js
@@ -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 },
+ };
};
diff --git a/client/src/store/itemCategories/itemsCategory.reducer.js b/client/src/store/itemCategories/itemsCategory.reducer.js
index 187b6e88c..b510439a2 100644
--- a/client/src/store/itemCategories/itemsCategory.reducer.js
+++ b/client/src/store/itemCategories/itemsCategory.reducer.js
@@ -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] || {};
-};
diff --git a/client/src/store/itemCategories/itemsCategory.type.js b/client/src/store/itemCategories/itemsCategory.type.js
index 0b4935420..9e04a9d65 100644
--- a/client/src/store/itemCategories/itemsCategory.type.js
+++ b/client/src/store/itemCategories/itemsCategory.type.js
@@ -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',
};
diff --git a/client/src/store/reducers.js b/client/src/store/reducers.js
index d74669c5f..a425bceff 100644
--- a/client/src/store/reducers.js
+++ b/client/src/store/reducers.js
@@ -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,
diff --git a/client/src/utils.js b/client/src/utils.js
index 402e17384..55124fdbc 100644
--- a/client/src/utils.js
+++ b/client/src/utils.js
@@ -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),
+ };
}
\ No newline at end of file
diff --git a/server/src/api/controllers/Inventory/InventoryAdjustments.ts b/server/src/api/controllers/Inventory/InventoryAdjustments.ts
index 8889a556e..99147ceb2 100644
--- a/server/src/api/controllers/Inventory/InventoryAdjustments.ts
+++ b/server/src/api/controllers/Inventory/InventoryAdjustments.ts
@@ -1,6 +1,6 @@
import { Inject, Service } from 'typedi';
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 BaseController from '../BaseController';
import InventoryAdjustmentService from 'services/Inventory/InventoryAdjustmentService';
@@ -39,12 +39,28 @@ export default class InventoryAdjustmentsController extends BaseController {
);
router.get(
'/',
+ [...this.validateListQuerySchema],
+ this.validationResult,
this.asyncMiddleware(this.getInventoryAdjustments.bind(this)),
this.handleServiceErrors
);
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.
*/