This commit is contained in:
elforjani3
2020-11-16 18:24:28 +02:00
76 changed files with 1160 additions and 1315 deletions

View File

@@ -29,6 +29,9 @@ const CLASSES = {
CLOUD_SPINNER: 'cloud-spinner',
IS_LOADING: 'is-loading',
DATATABLE_EMPTY_STATE: 'datatable-empty-state',
DATATABLE_EMPTY_STATE_TITLE: 'datatable-empty-state__title',
...Classes,
};

View File

@@ -1,4 +1,4 @@
import React, { useEffect, useRef, useCallback } from 'react';
import React, { useEffect, useRef, useCallback, useMemo } from 'react';
import {
useTable,
useExpanded,
@@ -7,20 +7,18 @@ import {
useResizeColumns,
useSortBy,
useFlexLayout,
useAsyncDebounce,
} from 'react-table';
import {
Checkbox,
Spinner,
ContextMenu,
} from '@blueprintjs/core';
import { Checkbox, Spinner, ContextMenu } from '@blueprintjs/core';
import classnames from 'classnames';
import { FixedSizeList } from 'react-window';
import { useSticky } from 'react-table-sticky';
import { ScrollSync, ScrollSyncPane } from 'react-scroll-sync';
import { ConditionalWrapper } from 'utils';
import { useUpdateEffect } from 'hooks';
import { If, Pagination } from 'components';
import { If, Pagination, Choose } from 'components';
import { ConditionalWrapper, saveInvoke } from 'utils';
const IndeterminateCheckbox = React.forwardRef(
({ indeterminate, ...rest }, ref) => {
@@ -31,10 +29,13 @@ const IndeterminateCheckbox = React.forwardRef(
export default function DataTable({
columns,
data,
loading,
onFetchData,
onSelectedRowsChange,
manualSortBy = false,
manualPagination = true,
selectionColumn = false,
expandSubRows = true,
className,
@@ -53,11 +54,24 @@ export default function DataTable({
pagination = false,
pagesCount: controlledPageCount,
initialPageIndex,
initialPageSize,
// Pagination props.
initialPageIndex = 0,
initialPageSize = 10,
rowContextMenu,
expandColumnSpace = 1.5,
updateDebounceTime = 200,
// Read this document to know why! https://bit.ly/2Uw9SEc
autoResetPage = true,
autoResetExpanded = true,
autoResetGroupBy = true,
autoResetSelectedRows = true,
autoResetSortBy = true,
autoResetFilters = true,
autoResetRowState = true,
}) {
const {
getTableProps,
@@ -85,18 +99,25 @@ export default function DataTable({
} = useTable(
{
columns,
data: data,
data,
initialState: {
pageIndex: initialPageIndex,
pageSize: initialPageSize,
expanded,
}, // Pass our hoisted table state
manualPagination: true,
},
manualPagination,
pageCount: controlledPageCount,
getSubRows: (row) => row.children,
manualSortBy,
expandSubRows,
payload,
autoResetPage,
autoResetExpanded,
autoResetGroupBy,
autoResetSelectedRows,
autoResetSortBy,
autoResetFilters,
autoResetRowState,
},
useSortBy,
useExpanded,
@@ -145,18 +166,23 @@ export default function DataTable({
);
const isInitialMount = useRef(noInitialFetch);
const onFetchDataDebounced = useAsyncDebounce(
(...args) => {
saveInvoke(onFetchData, ...args);
},
updateDebounceTime,
);
// When these table states change, fetch new data!
useEffect(() => {
if (isInitialMount.current) {
isInitialMount.current = false;
} else {
onFetchData && onFetchData({ pageIndex, pageSize, sortBy });
onFetchDataDebounced({ pageIndex, pageSize, sortBy });
}
}, [pageIndex, pageSize, manualSortBy ? sortBy : null, onFetchData]);
}, [pageIndex, pageSize, sortBy, onFetchDataDebounced]);
useUpdateEffect(() => {
onSelectedRowsChange && onSelectedRowsChange(selectedFlatRows);
saveInvoke(onSelectedRowsChange, selectedFlatRows);
}, [selectedRowIds, onSelectedRowsChange]);
// Renders table cell.
@@ -177,40 +203,50 @@ export default function DataTable({
{
// Use the row.canExpand and row.getToggleRowExpandedProps prop getter
// to build the toggle for expanding a row
row.canExpand && expandable && index === expandToggleColumn && (
<span
{...row.getToggleRowExpandedProps({
className: 'expand-toggle',
})}
>
<span
className={classnames({
'arrow-down': row.isExpanded,
'arrow-right': !row.isExpanded,
})}
/>
</span>
)
}
<If
condition={
row.canExpand && expandable && index === expandToggleColumn
}
>
<span
{...row.getToggleRowExpandedProps({ className: 'expand-toggle' })}
>
<span
className={classnames({
'arrow-down': row.isExpanded,
'arrow-right': !row.isExpanded,
})}
/>
</span>
</If>
{cell.render('Cell')}
</ConditionalWrapper>
),
[expandable, expandToggleColumn],
[expandable, expandToggleColumn, expandColumnSpace],
);
const handleRowContextMenu = (cell, row) => (e) => {
if (typeof rowContextMenu === 'function') {
e.preventDefault();
const tr = e.currentTarget.closest('.tr');
tr.classList.add('is-context-menu-active');
// Handle rendering row context menu.
const handleRowContextMenu = useMemo(
() => (cell, row) => (e) => {
if (typeof rowContextMenu === 'function') {
e.preventDefault();
const tr = e.currentTarget.closest('.tr');
tr.classList.add('is-context-menu-active');
const DropdownEl = rowContextMenu(cell, row);
const DropdownEl = rowContextMenu(cell, row);
ContextMenu.show(DropdownEl, { left: e.clientX, top: e.clientY }, () => {
tr.classList.remove('is-context-menu-active');
});
}
};
ContextMenu.show(
DropdownEl,
{ left: e.clientX, top: e.clientY },
() => {
tr.classList.remove('is-context-menu-active');
},
);
}
},
[rowContextMenu],
);
// Renders table row.
const RenderRow = useCallback(
@@ -221,9 +257,13 @@ export default function DataTable({
return (
<div
{...row.getRowProps({
className: classnames('tr', {
'is-expanded': row.isExpanded && row.canExpand,
}, rowClasses),
className: classnames(
'tr',
{
'is-expanded': row.isExpanded && row.canExpand,
},
rowClasses,
),
style,
})}
>
@@ -243,7 +283,7 @@ export default function DataTable({
</div>
);
},
[prepareRow, rowClassNames, expandable, RenderCell, expandToggleColumn],
[prepareRow, rowClassNames, RenderCell, handleRowContextMenu],
);
// Renders virtualize circle table rows.
@@ -254,7 +294,7 @@ export default function DataTable({
},
[RenderRow, rows],
);
// Renders page with multi-rows.
const RenderPage = useCallback(
({ style, index } = {}) => {
return page.map((row, index) => RenderRow({ row }));
@@ -284,6 +324,21 @@ export default function DataTable({
RenderPage,
]);
const handlePageChange = useCallback(
(currentPage) => {
gotoPage(currentPage - 1);
},
[gotoPage],
);
const handlePageSizeChange = useCallback(
(pageSize, currentPage) => {
gotoPage(0);
setPageSize(pageSize);
},
[gotoPage, setPageSize],
);
return (
<div
className={classnames('bigcapital-datatable', className, {
@@ -308,7 +363,11 @@ export default function DataTable({
className: classnames(column.className || '', 'th'),
})}
>
{expandable && index + 1 === expandToggleColumn && (
<If
condition={
expandable && index + 1 === expandToggleColumn
}
>
<span
{...getToggleAllRowsExpandedProps()}
className="expand-toggle"
@@ -320,12 +379,12 @@ export default function DataTable({
})}
/>
</span>
)}
</If>
<div {...column.getSortByToggleProps()}>
{column.render('Header')}
{column.isSorted && (
<If condition={column.isSorted}>
<span
className={classnames(
{
@@ -335,7 +394,7 @@ export default function DataTable({
'sort-icon',
)}
></span>
)}
</If>
</div>
{column.canResize && (
@@ -358,37 +417,36 @@ export default function DataTable({
<ScrollSyncPane>
<div {...getTableBodyProps()} className="tbody">
<div class="tbody-inner" style={{ minWidth: totalColumnsWidth }}>
<If condition={!loading}>{RenderTBody()}</If>
<Choose>
<Choose.When condition={loading}>
<div class="loading">
<Spinner {...spinnerProps} />
</div>
</Choose.When>
<If condition={!loading && page.length === 0}>
<div className={'tr no-results'}>
<div class="td">{noResults}</div>
</div>
</If>
<Choose.Otherwise>
{RenderTBody()}
<If condition={page.length === 0}>
<div className={'tr no-results'}>
<div class="td">{noResults}</div>
</div>
</If>
</Choose.Otherwise>
</Choose>
</div>
<If condition={loading}>
<div class="loading">
<Spinner size={spinnerProps.size} />
</div>
</If>
</div>
</ScrollSyncPane>
</div>
</ScrollSync>
<If condition={pagination && pageCount && !loading}>
<If condition={pagination && !loading}>
<Pagination
initialPage={pageIndex + 1}
total={pageSize * pageCount}
size={pageSize}
onPageChange={(currentPage) => {
gotoPage(currentPage - 1);
}}
onPageSizeChange={(pageSize, currentPage) => {
gotoPage(currentPage - 1);
setPageSize(pageSize);
}}
onPageChange={handlePageChange}
onPageSizeChange={handlePageSizeChange}
/>
</If>
</div>

View File

@@ -15,13 +15,22 @@ import { withRouter, useParams } from 'react-router-dom';
import { FormattedMessage as T, useIntl } from 'react-intl';
import moment from 'moment';
import { DataTable, If, Money, Choose, Icon } from 'components';
import { compose } from 'utils';
import {
DataTable,
If,
Money,
Choose,
Icon,
LoadingIndicator,
} from 'components';
import { useIsValuePassed } from 'hooks';
import withDialogActions from 'containers/Dialog/withDialogActions';
import withManualJournals from 'containers/Accounting/withManualJournals';
import withManualJournalsActions from 'containers/Accounting/withManualJournalsActions';
import { compose, saveInvoke } from 'utils';
/**
* Status column accessor.
*/
@@ -68,44 +77,36 @@ function ManualJournalsDataTable({
manualJournalsPagination,
manualJournalsTableQuery,
onFetchData,
// #withManualJournalsActions
addManualJournalsTableQueries,
// #ownProps
onEditJournal,
onDeleteJournal,
onPublishJournal,
onSelectedRowsChange,
}) {
const [isMounted, setIsMounted] = useState(false);
const { custom_view_id: customViewId } = useParams();
const { formatMessage } = useIntl();
useEffect(() => {
setIsMounted(false);
}, [customViewId]);
useEffect(() => {
if (!manualJournalsLoading) {
setIsMounted(true);
}
}, [manualJournalsLoading, setIsMounted]);
const isLoadedBefore = useIsValuePassed(manualJournalsLoading, false);
const handlePublishJournal = useCallback(
(journal) => () => {
onPublishJournal && onPublishJournal(journal);
saveInvoke(onPublishJournal, journal);
},
[onPublishJournal],
);
const handleEditJournal = useCallback(
(journal) => () => {
onEditJournal && onEditJournal(journal);
saveInvoke(onEditJournal, journal);
},
[onEditJournal],
);
const handleDeleteJournal = useCallback(
(journal) => () => {
onDeleteJournal && onDeleteJournal(journal);
saveInvoke(onDeleteJournal, journal);
},
[onDeleteJournal],
);
@@ -115,7 +116,8 @@ function ManualJournalsDataTable({
<Menu>
<MenuItem
icon={<Icon icon="reader-18" />}
text={formatMessage({ id: 'view_details' })} />
text={formatMessage({ id: 'view_details' })}
/>
<MenuDivider />
<If condition={!journal.status}>
<MenuItem
@@ -182,7 +184,7 @@ function ManualJournalsDataTable({
{
id: 'status',
Header: formatMessage({ id: 'status' }),
accessor: row => StatusAccessor(row),
accessor: (row) => StatusAccessor(row),
width: 95,
className: 'status',
},
@@ -221,46 +223,52 @@ function ManualJournalsDataTable({
);
const handleDataTableFetchData = useCallback(
(...args) => {
onFetchData && onFetchData(...args);
({ pageIndex, pageSize, sortBy }) => {
addManualJournalsTableQueries({
...(sortBy.length > 0
? {
column_sort_by: sortBy[0].id,
sort_order: sortBy[0].desc ? 'desc' : 'asc',
}
: {}),
page_size: pageSize,
page: pageIndex + 1,
});
},
[onFetchData],
[addManualJournalsTableQueries],
);
const handleSelectedRowsChange = useCallback(
(selectedRows) => {
onSelectedRowsChange &&
onSelectedRowsChange(selectedRows.map((s) => s.original));
saveInvoke(
onSelectedRowsChange,
selectedRows.map((s) => s.original),
);
},
[onSelectedRowsChange],
);
const selectionColumn = useMemo(
() => ({
minWidth: 40,
width: 40,
maxWidth: 40,
}),
[],
);
return (
<DataTable
noInitialFetch={true}
columns={columns}
data={manualJournalsCurrentPage}
onFetchData={handleDataTableFetchData}
manualSortBy={true}
selectionColumn={selectionColumn}
expandable={true}
sticky={true}
onSelectedRowsChange={handleSelectedRowsChange}
loading={manualJournalsLoading && !isMounted}
rowContextMenu={onRowContextMenu}
pagination={true}
pagesCount={manualJournalsPagination.pagesCount}
initialPageSize={manualJournalsTableQuery.page_size}
initialPageIndex={manualJournalsTableQuery.page - 1}
/>
<LoadingIndicator loading={manualJournalsLoading && !isLoadedBefore}>
<DataTable
noInitialFetch={true}
columns={columns}
data={manualJournalsCurrentPage}
onFetchData={handleDataTableFetchData}
manualSortBy={true}
selectionColumn={true}
expandable={true}
sticky={true}
onSelectedRowsChange={handleSelectedRowsChange}
rowContextMenu={onRowContextMenu}
pagesCount={manualJournalsPagination.pagesCount}
pagination={true}
initialPageSize={manualJournalsTableQuery.page_size}
initialPageIndex={manualJournalsTableQuery.page - 1}
autoResetSortBy={false}
autoResetPage={false}
/>
</LoadingIndicator>
);
}

View File

@@ -161,8 +161,6 @@ function ManualJournalsTable({
const handleFetchData = useCallback(
({ pageIndex, pageSize, sortBy }) => {
const page = pageIndex + 1;
// addQuery('page_size', pageSize);
// addQuery('page', page);
addManualJournalsTableQueries({
...(sortBy.length > 0
@@ -224,7 +222,6 @@ function ManualJournalsTable({
<ManualJournalsDataTable
onDeleteJournal={handleDeleteJournal}
onFetchData={handleFetchData}
onEditJournal={handleEditJournal}
onPublishJournal={handlePublishJournal}
onSelectedRowsChange={handleSelectedRowsChange}

View File

@@ -22,7 +22,7 @@ const mapActionsToProps = (dispatch) => ({
}),
addManualJournalsTableQueries: (queries) => dispatch({
type: t.MANUAL_JOURNALS_TABLE_QUERIES_ADD,
queries,
payload: { queries },
}),
setJournalNumberChanged: (isChanged) => dispatch({
type: t.MANUAL_JOURNAL_NUMBER_CHANGED,

View File

@@ -1,4 +1,4 @@
import React, { useState, useCallback, useMemo } from 'react';
import React, { useRef, useEffect, useCallback, useMemo } from 'react';
import {
Button,
Popover,
@@ -8,14 +8,15 @@ import {
Position,
Intent,
} from '@blueprintjs/core';
import { FormattedMessage as T, useIntl } from 'react-intl';
import { useUpdateEffect } from 'hooks';
import { useIsValuePassed } from 'hooks';
import LoadingIndicator from 'components/LoadingIndicator';
import { DataTable, Icon, Money } from 'components';
import withCustomers from './withCustomers';
import withCustomersActions from './withCustomersActions';
import { compose, firstLettersArgs, saveInvoke } from 'utils';
const AvatarCell = (row) => {
@@ -27,6 +28,10 @@ const CustomerTable = ({
customers,
customersLoading,
customerPagination,
customersTableQuery,
// #withCustomersActions
addCustomersTableQueries,
//#OwnProps
loading,
@@ -36,13 +41,7 @@ const CustomerTable = ({
onSelectedRowsChange,
}) => {
const { formatMessage } = useIntl();
const [initialMount, setInitialMount] = useState(false);
useUpdateEffect(() => {
if (!customersLoading) {
setInitialMount(true);
}
}, [customersLoading, setInitialMount]);
const isLoadedBefore = useIsValuePassed(loading, false);
// Customers actions list.
const renderContextMenu = useMemo(
@@ -94,6 +93,7 @@ const CustomerTable = ({
[onDeleteCustomer, onEditCustomer, renderContextMenu],
);
// Table columns.
const columns = useMemo(
() => [
{
@@ -150,19 +150,23 @@ const CustomerTable = ({
[formatMessage, renderActionsCell],
);
const selectionColumn = useMemo(
() => ({
minWidth: 42,
width: 42,
maxWidth: 42,
}),
[],
// Handle fetch data table.
const handleFetchData = useCallback(
({ pageIndex, pageSize, sortBy }) => {
addCustomersTableQueries({
page: pageIndex + 1,
page_size: pageSize,
...(sortBy.length > 0
? {
column_sort_order: sortBy[0].id,
sort_order: sortBy[0].desc ? 'desc' : 'asc',
}
: {}),
});
},
[addCustomersTableQueries],
);
const handleFetchDate = useCallback((...args) => {
onFetchData && onFetchData(...args);
});
const handleSelectedRowsChange = useCallback(
(selectedRows) => {
onSelectedRowsChange &&
@@ -179,32 +183,47 @@ const CustomerTable = ({
});
return (
<LoadingIndicator loading={loading} mount={false}>
<LoadingIndicator
loading={customersLoading && !isLoadedBefore}
mount={false}
>
<DataTable
noInitialFetch={true}
columns={columns}
data={customers}
selectionColumn={selectionColumn}
onFetchData={handleFetchDate}
// loading={customersLoading}
onFetchData={handleFetchData}
selectionColumn={true}
expandable={false}
treeGraph={false}
sticky={true}
onSelectedRowsChange={handleSelectedRowsChange}
loading={customersLoading && !initialMount}
spinnerProps={{ size: 30 }}
rowContextMenu={rowContextMenu}
pagination={true}
manualSortBy={true}
pagesCount={customerPagination.pagesCount}
initialPageSize={customerPagination.pageSize}
initialPageIndex={customerPagination.page - 1}
autoResetSortBy={false}
autoResetPage={false}
initialPageSize={customersTableQuery.page_size}
initialPageIndex={customersTableQuery.page - 1}
/>
</LoadingIndicator>
);
};
export default compose(
withCustomers(({ customers, customersLoading, customerPagination }) => ({
customers,
customersLoading,
customerPagination,
})),
withCustomers(
({
customers,
customersLoading,
customerPagination,
customersTableQuery,
}) => ({
customers,
customersLoading,
customerPagination,
customersTableQuery,
}),
),
withCustomersActions,
)(CustomerTable);

View File

@@ -52,15 +52,12 @@ function CustomersList({
useEffect(() => {
changePageTitle(formatMessage({ id: 'customers_list' }));
}, [changePageTitle]);
}, [changePageTitle, formatMessage]);
// Fetch customers resource views and fields.
// const fetchHook = useQuery('resource-customers', () => {
// return Promise.all([
// requestFetchResourceViews('customers'),
// requestFetchResourceFields('customers'),
// ]);
// });
// const fetchResourceViews = useQuery(['resource-views', 'customers'],
// () => requestFetchResourceViews('customers')
// );
const fetchCustomers = useQuery(
['customers-table', customersTableQuery],
@@ -116,22 +113,6 @@ function CustomersList({
});
}, [requestDeleteCustomer, deleteCustomer, formatMessage]);
// Handle fetch data table.
const handleFetchData = useCallback(
({ pageIndex, pageSize, sortBy }) => {
addCustomersTableQueries({
...(sortBy.length > 0
? {
column_sort_order: sortBy[0].id,
sort_order: sortBy[0].desc ? 'desc' : 'asc',
}
: {}),
});
fetchCustomers.refetch();
},
[fetchCustomers, addCustomersTableQueries],
);
// Handle selected rows change.
const handleSelectedRowsChange = useCallback(
(customer) => {
@@ -154,9 +135,9 @@ function CustomersList({
// Handle filter change to re-fetch the items.
const handleFilterChanged = useCallback(
(filterConditions) => {
addCustomersTableQueries({
filter_roles: filterConditions || '',
});
// addCustomersTableQueries({
// filter_roles: filterConditions || '',
// });
},
[addCustomersTableQueries],
);
@@ -210,7 +191,6 @@ function CustomersList({
loading={fetchCustomers.isFetching}
onDeleteCustomer={handleDeleteCustomer}
onEditCustomer={handleEditCustomer}
onfetchData={handleFetchData}
onSelectedRowsChange={handleSelectedRowsChange}
/>
</Route>
@@ -258,5 +238,6 @@ export default compose(
withResourceActions,
withCustomersActions,
withDashboardActions,
withViewsActions,
withCustomers(({ customersTableQuery }) => ({ customersTableQuery })),
)(CustomersList);

View File

@@ -39,9 +39,9 @@ function CustomersViewsTabs({
useEffect(() => {
setTopbarEditView(customViewId);
changePageSubtitle(customViewId && viewItem ? viewItem.name : '');
addCustomersTableQueries({
custom_view_id: customViewId,
});
// addCustomersTableQueries({
// custom_view_id: customViewId,
// });
return () => {
setTopbarEditView(null);
changePageSubtitle('');

View File

@@ -19,7 +19,7 @@ export const mapDispatchToProps = (dispatch) => ({
addCustomersTableQueries: (queries) =>
dispatch({
type: t.CUSTOMERS_TABLE_QUERIES_ADD,
queries,
payload: { queries }
}),
});

View File

@@ -17,8 +17,8 @@ import { FormattedMessage as T, useIntl } from 'react-intl';
import moment from 'moment';
import Icon from 'components/Icon';
import { compose } from 'utils';
import { useUpdateEffect } from 'hooks';
import { compose, saveInvoke } from 'utils';
import { useIsValuePassed } from 'hooks';
import LoadingIndicator from 'components/LoadingIndicator';
import { If, Money } from 'components';
@@ -32,11 +32,15 @@ import withExpensesActions from 'containers/Expenses/withExpensesActions';
import withCurrentView from 'containers/Views/withCurrentView';
function ExpensesDataTable({
//#withExpenes
// #withExpenes
expensesCurrentPage,
expensesLoading,
expensesPagination,
expensesTableQuery,
// #withExpensesActions
addExpensesTableQueries,
// #withDashboardActions
changeCurrentView,
changePageSubtitle,
@@ -46,27 +50,16 @@ function ExpensesDataTable({
viewMeta,
// #ownProps
loading,
onFetchData,
onEditExpense,
onDeleteExpense,
onPublishExpense,
onSelectedRowsChange,
}) {
const { custom_view_id: customViewId } = useParams();
const [initialMount, setInitialMount] = useState(false);
const isLoadedBefore = useIsValuePassed(expensesLoading, false);
const { formatMessage } = useIntl();
useEffect(()=>{
setInitialMount(false)
},[customViewId])
useUpdateEffect(() => {
if (!expensesLoading) {
setInitialMount(true);
}
}, [expensesLoading, setInitialMount]);
useEffect(() => {
if (customViewId) {
changeCurrentView(customViewId);
@@ -81,23 +74,40 @@ function ExpensesDataTable({
viewMeta,
]);
// Handle fetch data of manual jouranls datatable.
const handleFetchData = useCallback(
({ pageIndex, pageSize, sortBy }) => {
addExpensesTableQueries({
...(sortBy.length > 0
? {
column_sort_by: sortBy[0].id,
sort_order: sortBy[0].desc ? 'desc' : 'asc',
}
: {}),
page_size: pageSize,
page: pageIndex + 1,
});
},
[addExpensesTableQueries],
);
const handlePublishExpense = useCallback(
(expense) => () => {
onPublishExpense && onPublishExpense(expense);
saveInvoke(onPublishExpense, expense);
},
[onPublishExpense],
);
const handleEditExpense = useCallback(
(expense) => () => {
onEditExpense && onEditExpense(expense);
saveInvoke(onEditExpense, expense);
},
[onEditExpense],
);
const handleDeleteExpense = useCallback(
(expense) => () => {
onDeleteExpense && onDeleteExpense(expense);
saveInvoke(onDeleteExpense, expense);
},
[onDeleteExpense],
);
@@ -107,7 +117,8 @@ function ExpensesDataTable({
<Menu>
<MenuItem
icon={<Icon icon="reader-18" />}
text={formatMessage({ id: 'view_details' })} />
text={formatMessage({ id: 'view_details' })}
/>
<MenuDivider />
<If condition={!expense.published}>
<MenuItem
@@ -244,42 +255,39 @@ function ExpensesDataTable({
[actionMenuList, formatMessage],
);
const handleDataTableFetchData = useCallback(
(...args) => {
onFetchData && onFetchData(...args);
},
[onFetchData],
);
const handleSelectedRowsChange = useCallback(
(selectedRows) => {
onSelectedRowsChange &&
onSelectedRowsChange(selectedRows.map((s) => s.original));
saveInvoke(
onSelectedRowsChange,
selectedRows.map((s) => s.original),
);
},
[onSelectedRowsChange],
);
return (
<div>
<LoadingIndicator loading={loading} mount={false}>
<DataTable
columns={columns}
data={expensesCurrentPage}
onFetchData={handleDataTableFetchData}
manualSortBy={true}
selectionColumn={true}
noInitialFetch={true}
sticky={true}
loading={expensesLoading && !initialMount}
onSelectedRowsChange={handleSelectedRowsChange}
rowContextMenu={onRowContextMenu}
pagination={true}
pagesCount={expensesPagination.pagesCount}
initialPageSize={expensesPagination.pageSize}
initialPageIndex={expensesPagination.page - 1}
/>
</LoadingIndicator>
</div>
<LoadingIndicator
loading={expensesLoading && !isLoadedBefore}
mount={false}
>
<DataTable
columns={columns}
data={expensesCurrentPage}
manualSortBy={true}
selectionColumn={true}
noInitialFetch={true}
sticky={true}
onSelectedRowsChange={handleSelectedRowsChange}
onFetchData={handleFetchData}
rowContextMenu={onRowContextMenu}
pagination={true}
pagesCount={expensesPagination.pagesCount}
autoResetSortBy={false}
autoResetPage={false}
initialPageSize={expensesTableQuery.page_size}
initialPageIndex={expensesTableQuery.page - 1}
/>
</LoadingIndicator>
);
}
@@ -289,10 +297,18 @@ export default compose(
withDialogActions,
withDashboardActions,
withExpensesActions,
withExpenses(({ expensesCurrentPage, expensesLoading, expensesPagination }) => ({
expensesCurrentPage,
expensesLoading,
expensesPagination,
})),
withExpenses(
({
expensesCurrentPage,
expensesLoading,
expensesPagination,
expensesTableQuery,
}) => ({
expensesCurrentPage,
expensesLoading,
expensesPagination,
expensesTableQuery,
}),
),
withViewDetails(),
)(ExpensesDataTable);

View File

@@ -137,25 +137,6 @@ function ExpensesList({
// Handle filter change to re-fetch data-table.
const handleFilterChanged = useCallback(() => {}, []);
// Handle fetch data of manual jouranls datatable.
const handleFetchData = useCallback(
({ pageIndex, pageSize, sortBy }) => {
const page = pageIndex + 1;
addExpensesTableQueries({
...(sortBy.length > 0
? {
column_sort_by: sortBy[0].id,
sort_order: sortBy[0].desc ? 'desc' : 'asc',
}
: {}),
page_size: pageSize,
page,
});
},
[addExpensesTableQueries],
);
// const fetchExpenses = useQuery(['expenses-table', expensesTableQuery], () =>
// requestFetchExpensesTable(),
// );
@@ -217,9 +198,7 @@ function ExpensesList({
<ExpenseViewTabs />
<ExpenseDataTable
loading={fetchExpenses.isFetching}
onDeleteExpense={handleDeleteExpense}
onFetchData={handleFetchData}
onEditExpense={handleEidtExpense}
onPublishExpense={handlePublishExpense}
onSelectedRowsChange={handleSelectedRowsChange}

View File

@@ -29,7 +29,7 @@ const mapDispatchToProps = (dispatch) => ({
addExpensesTableQueries: (queries) =>
dispatch({
type: t.EXPENSES_TABLE_QUERIES_ADD,
queries,
payload: { queries },
}),
});

View File

@@ -101,7 +101,7 @@ function ItemFormBody({ accountsList }) {
<Col xs={6}>
{/*------------- Sellable checkbox ------------- */}
<FastField name={'purchasable'}>
{({ field, field: { value }, meta: { error, touched } }) => (
{({ form, field: { value, onChange }, meta: { error, touched } }) => (
<FormGroup inline={true} className={'form-group--purchasable'}>
<Checkbox
inline={true}
@@ -111,7 +111,7 @@ function ItemFormBody({ accountsList }) {
</h3>
}
checked={value}
{...field}
onChange={onChange}
/>
</FormGroup>
)}

View File

@@ -10,34 +10,46 @@ import {
Tag,
} from '@blueprintjs/core';
import { FormattedMessage as T, useIntl } from 'react-intl';
import { Icon, DataTable, Money, If, Choose } from 'components';
import { Icon, DataTable, Money } from 'components';
import { useIsValuePassed } from 'hooks';
import LoadingIndicator from 'components/LoadingIndicator';
import withItems from 'containers/Items/withItems';
import { compose } from 'utils';
const ItemsDataTable = ({
loading,
import withItemsActions from 'containers/Items/withItemsActions';
import { compose, saveInvoke } from 'utils';
function ItemsDataTable({
// #withItems
itemsTableLoading,
itemsCurrentPage,
itemsTableQuery,
// #withItemsActions
addItemsTableQueries,
// props
onEditItem,
onDeleteItem,
onFetchData,
onSelectedRowsChange,
}) => {
}) {
const { formatMessage } = useIntl();
const [initialMount, setInitialMount] = useState(false);
const isLoadedBefore = useIsValuePassed(itemsTableLoading, false);
useEffect(() => {
if (!itemsTableLoading) {
setInitialMount(true);
}
}, [itemsTableLoading, setInitialMount]);
const handleFetchData = useCallback(
({ pageIndex, pageSize, sortBy }) => {
addItemsTableQueries({
page_size: pageSize,
page: pageIndex + 1,
...(sortBy.length > 0
? {
column_sort_by: sortBy[0].id,
sort_order: sortBy[0].desc ? 'desc' : 'asc',
}
: {}),
});
},
[addItemsTableQueries],
);
const handleEditItem = useCallback(
(item) => () => {
@@ -46,7 +58,6 @@ const ItemsDataTable = ({
[onEditItem],
);
// const handleDeleteItem = (item) => () => { onDeleteItem(item); };
const handleDeleteItem = useCallback(
(item) => () => {
onDeleteItem(item);
@@ -158,48 +169,49 @@ const ItemsDataTable = ({
[actionMenuList, formatMessage],
);
const selectionColumn = useMemo(
() => ({
minWidth: 42,
width: 42,
maxWidth: 42,
}),
[],
);
const handleFetchData = useCallback((...args) => {
onFetchData && onFetchData(...args);
}, []);
// Handle selected row change.
const handleSelectedRowsChange = useCallback(
(selectedRows) => {
onSelectedRowsChange &&
onSelectedRowsChange(selectedRows.map((s) => s.original));
saveInvoke(
onSelectedRowsChange,
selectedRows.map((s) => s.original),
);
},
[onSelectedRowsChange],
);
return (
<LoadingIndicator loading={loading} mount={false}>
<LoadingIndicator
loading={itemsTableLoading && !isLoadedBefore}
mount={false}
>
<DataTable
columns={columns}
data={itemsCurrentPage}
selectionColumn={selectionColumn}
onFetchData={handleFetchData}
loading={itemsTableLoading && !initialMount}
noInitialFetch={true}
expandable={true}
treeGraph={true}
selectionColumn={true}
spinnerProps={{ size: 30 }}
onSelectedRowsChange={handleSelectedRowsChange}
rowContextMenu={handleRowContextMenu}
sticky={true}
pagination={true}
pagesCount={2}
autoResetSortBy={false}
autoResetPage={false}
initialPageSize={itemsTableQuery.page_size}
initialPageIndex={itemsTableQuery.page - 1}
/>
</LoadingIndicator>
);
};
export default compose(
withItems(({ itemsCurrentPage, itemsTableLoading }) => ({
withItems(({ itemsCurrentPage, itemsTableLoading, itemsTableQuery }) => ({
itemsCurrentPage,
itemsTableLoading,
itemsTableQuery,
})),
withItemsActions,
)(ItemsDataTable);

View File

@@ -43,7 +43,6 @@ function ItemsList({
}) {
const [deleteItem, setDeleteItem] = useState(false);
const [selectedRows, setSelectedRows] = useState([]);
const [tableLoading, setTableLoading] = useState(false);
const [bulkDelete, setBulkDelete] = useState(false);
const { formatMessage } = useIntl();
@@ -53,16 +52,19 @@ function ItemsList({
changePageTitle(formatMessage({ id: 'items_list' }));
}, [changePageTitle]);
// Handle fetching the resource views.
const fetchResourceViews = useQuery(
['resource-views', 'items'],
(key, resourceName) => requestFetchResourceViews(resourceName),
);
// Handle fetching the resource fields.
const fetchResourceFields = useQuery(
['resource-fields', 'items'],
(key, resourceName) => requestFetchResourceFields(resourceName),
);
// Handle fetching the items table based on the given query.
const fetchItems = useQuery(['items-table', itemsTableQuery], () =>
requestFetchItems({}),
);
@@ -112,18 +114,7 @@ function ItemsList({
const handleFetchData = useCallback(
({ pageIndex, pageSize, sortBy }) => {
const page = pageIndex + 1;
addItemsTableQueries({
...(sortBy.length > 0
? {
column_sort_by: sortBy[0].id,
sort_order: sortBy[0].desc ? 'desc' : 'asc',
}
: {}),
page_size: pageSize,
page,
});
},
[addItemsTableQueries],
);
@@ -135,23 +126,9 @@ function ItemsList({
filter_roles: filterConditions || '',
});
},
[fetchItems],
[addItemsTableQueries],
);
// Handle custom view change to re-fetch the items.
const handleCustomViewChanged = useCallback(
(customViewId) => {
setTableLoading(true);
},
[fetchItems],
);
useEffect(() => {
if (tableLoading && !fetchItems.isFetching) {
setTableLoading(false);
}
}, [tableLoading, fetchItems.isFetching]);
// Handle selected rows change.
const handleSelectedRowsChange = useCallback(
(accounts) => {
@@ -213,16 +190,13 @@ function ItemsList({
exact={true}
path={['/items/:custom_view_id/custom_view', '/items']}
>
<ItemsViewsTabs onViewChanged={handleCustomViewChanged} />
<ItemsViewsTabs />
<ItemsDataTable
loading={fetchItems.isFetching}
onDeleteItem={handleDeleteItem}
onEditItem={handleEditItem}
onFetchData={handleFetchData}
onSelectedRowsChange={handleSelectedRowsChange}
/>
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'delete'} />}

View File

@@ -10,6 +10,7 @@ import {
export default (mapState) => {
const mapStateToProps = (state, props) => {
const viewPages = getViewPages(state.items.views, state.items.currentViewId);
const mapped = {
itemsViews: getResourceViews(state, props, 'items'),
itemsCurrentPage: getCurrentPageResults(

View File

@@ -1,11 +1,11 @@
import {connect} from 'react-redux';
import { connect } from 'react-redux';
import {
fetchItems,
fetchItem,
deleteItem,
submitItem,
editItem,
deleteBulkItems
deleteBulkItems,
} from 'store/items/items.actions';
import t from 'store/types';
@@ -13,26 +13,36 @@ export const mapDispatchToProps = (dispatch) => ({
requestFetchItems: (query) => dispatch(fetchItems({ query })),
requestFetchItem: (id) => dispatch(fetchItem({ id })),
requestDeleteItem: (id) => dispatch(deleteItem({ id })),
requestDeleteBulkItems:(ids)=>dispatch(deleteBulkItems({ids})),
requestDeleteBulkItems: (ids) => dispatch(deleteBulkItems({ ids })),
requestSubmitItem: (form) => dispatch(submitItem({ form })),
requestEditItem:(id,form) => dispatch(editItem({id,form})),
addBulkActionItem: (id) => dispatch({
type: t.ITEM_BULK_ACTION_ADD, itemId: id
}),
removeBulkActionItem: (id) => dispatch({
type: t.ITEM_BULK_ACTION_REMOVE, itemId: id,
}),
setItemsTableQuery: (key, value) => dispatch({
type: t.ITEMS_TABLE_QUERY_SET, key, value,
}),
addItemsTableQueries: (queries) => dispatch({
type: t.ITEMS_TABLE_QUERIES_ADD, queries,
}),
requestEditItem: (id, form) => dispatch(editItem({ id, form })),
addBulkActionItem: (id) =>
dispatch({
type: t.ITEM_BULK_ACTION_ADD,
itemId: id,
}),
removeBulkActionItem: (id) =>
dispatch({
type: t.ITEM_BULK_ACTION_REMOVE,
itemId: id,
}),
setItemsTableQuery: (key, value) =>
dispatch({
type: t.ITEMS_TABLE_QUERY_SET,
key,
value,
}),
addItemsTableQueries: (queries) =>
dispatch({
type: t.ITEMS_TABLE_QUERIES_ADD,
payload: { queries },
}),
changeItemsCurrentView: (id) => dispatch({
type: t.ITEMS_SET_CURRENT_VIEW,
currentViewId: parseInt(id, 10),
}),
changeItemsCurrentView: (id) =>
dispatch({
type: t.ITEMS_SET_CURRENT_VIEW,
currentViewId: parseInt(id, 10),
}),
});
export default connect(null, mapDispatchToProps);

View File

@@ -90,23 +90,7 @@ function BillList({
history.push(`/bills/${bill.id}/edit`);
});
const handleFetchData = useCallback(
({ pageIndex, pageSize, sortBy }) => {
const page = pageIndex + 1;
addBillsTableQueries({
...(sortBy.length > 0
? {
column_sort_by: sortBy[0].id,
sort_order: sortBy[0].desc ? 'desc' : 'asc',
}
: {}),
page_size: pageSize,
page,
});
},
[addBillsTableQueries],
);
// Handle selected rows change.
const handleSelectedRowsChange = useCallback(
@@ -141,9 +125,7 @@ function BillList({
<Route exact={true}>
<BillViewTabs />
<BillsDataTable
loading={fetchBills.isFetching}
onDeleteBill={handleDeleteBill}
onFetchData={handleFetchData}
onEditBill={handleEditBill}
onSelectedRowsChange={handleSelectedRowsChange}
/>

View File

@@ -16,8 +16,8 @@ import { FormattedMessage as T, useIntl } from 'react-intl';
import moment from 'moment';
import Icon from 'components/Icon';
import { compose } from 'utils';
import { useUpdateEffect } from 'hooks';
import { compose, saveInvoke } from 'utils';
import { useIsValuePassed } from 'hooks';
import LoadingIndicator from 'components/LoadingIndicator';
import DataTable from 'components/DataTable';
@@ -41,29 +41,22 @@ function BillsDataTable({
changePageSubtitle,
setTopbarEditView,
// #withBillsActions
addBillsTableQueries,
// #withView
viewMeta,
//#OwnProps
// #ownProps
loading,
onFetchData,
onEditBill,
onDeleteBill,
onSelectedRowsChange,
}) {
const [initialMount, setInitialMount] = useState(false);
const { custom_view_id: customViewId } = useParams();
const { formatMessage } = useIntl();
useEffect(() => {
setInitialMount(false);
}, [customViewId]);
useUpdateEffect(() => {
if (!billsLoading) {
setInitialMount(true);
}
}, [billsLoading, setInitialMount]);
const isLoadedBefore = useIsValuePassed(billsLoading, false);
useEffect(() => {
if (customViewId) {
@@ -79,16 +72,34 @@ function BillsDataTable({
viewMeta,
]);
const handleFetchData = useCallback(
({ pageIndex, pageSize, sortBy }) => {
const page = pageIndex + 1;
addBillsTableQueries({
...(sortBy.length > 0
? {
column_sort_by: sortBy[0].id,
sort_order: sortBy[0].desc ? 'desc' : 'asc',
}
: {}),
page_size: pageSize,
page,
});
},
[addBillsTableQueries],
);
const handleEditBill = useCallback(
(_bill) => () => {
onEditBill && onEditBill(_bill);
saveInvoke(onEditBill, _bill);
},
[onEditBill],
);
const handleDeleteBill = useCallback(
(_bill) => () => {
onDeleteBill && onDeleteBill(_bill);
saveInvoke(onDeleteBill, _bill);
},
[onDeleteBill],
);
@@ -147,7 +158,6 @@ function BillsDataTable({
width: 140,
className: 'bill_number',
},
{
id: 'due_date',
Header: formatMessage({ id: 'due_date' }),
@@ -195,41 +205,34 @@ function BillsDataTable({
[actionMenuList, formatMessage],
);
const handleDataTableFetchData = useCallback(
(...args) => {
onFetchData && onFetchData(...args);
},
[onFetchData],
);
const handleSelectedRowsChange = useCallback(
(selectedRows) => {
onSelectedRowsChange &&
onSelectedRowsChange(selectedRows.map((s) => s.original));
saveInvoke(
onSelectedRowsChange,
selectedRows.map((s) => s.original),
);
},
[onSelectedRowsChange],
);
return (
<div>
<LoadingIndicator loading={loading} mount={false}>
<DataTable
columns={columns}
data={billsCurrentPage}
onFetchData={handleDataTableFetchData}
manualSortBy={true}
selectionColumn={true}
noInitialFetch={true}
sticky={true}
loading={billsLoading && !initialMount}
onSelectedRowsChange={handleSelectedRowsChange}
rowContextMenu={onRowContextMenu}
pagination={true}
pagesCount={billsPageination.pagesCount}
initialPageSize={billsPageination.pageSize}
initialPageIndex={billsPageination.page - 1}
/>
</LoadingIndicator>
</div>
<LoadingIndicator loading={billsLoading && !isLoadedBefore} mount={false}>
<DataTable
columns={columns}
data={billsCurrentPage}
onFetchData={handleFetchData}
manualSortBy={true}
selectionColumn={true}
noInitialFetch={true}
sticky={true}
onSelectedRowsChange={handleSelectedRowsChange}
rowContextMenu={onRowContextMenu}
pagination={true}
pagesCount={billsPageination.pagesCount}
initialPageSize={billsPageination.pageSize}
initialPageIndex={billsPageination.page - 1}
/>
</LoadingIndicator>
);
}
@@ -239,10 +242,18 @@ export default compose(
withDialogActions,
withDashboardActions,
withBillActions,
withBills(({ billsCurrentPage, billsLoading, billsPageination }) => ({
billsCurrentPage,
billsLoading,
billsPageination,
})),
withBills(
({
billsCurrentPage,
billsLoading,
billsPageination,
billsTableQuery,
}) => ({
billsCurrentPage,
billsLoading,
billsPageination,
billsTableQuery,
}),
),
withViewDetails(),
)(BillsDataTable);

View File

@@ -27,7 +27,7 @@ const mapDispatchToProps = (dispatch) => ({
addBillsTableQueries: (queries) =>
dispatch({
type: t.BILLS_TABLE_QUERIES_ADD,
queries,
payload: { queries }
}),
setBillNumberChanged: (isChanged) =>
dispatch({

View File

@@ -1,81 +1,58 @@
import React, { useEffect, useCallback, useState, useMemo } from 'react';
import React, { useCallback, useMemo } from 'react';
import {
Intent,
Button,
Classes,
Popover,
Menu,
MenuItem,
MenuDivider,
Position,
} from '@blueprintjs/core';
import { useParams } from 'react-router-dom';
import { withRouter } from 'react-router';
import { FormattedMessage as T, useIntl } from 'react-intl';
import moment from 'moment';
import { compose } from 'utils';
import { useUpdateEffect } from 'hooks';
import { compose, saveInvoke } from 'utils';
import { useIsValuePassed } from 'hooks';
import LoadingIndicator from 'components/LoadingIndicator';
import { DataTable, Money, Icon } from 'components';
import withDialogActions from 'containers/Dialog/withDialogActions';
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
import withViewDetails from 'containers/Views/withViewDetails';
import withPaymentMade from './withPaymentMade';
import withPaymentMadeActions from './withPaymentMadeActions';
import withCurrentView from 'containers/Views/withCurrentView';
/**
* Payment made datatable transactions.
*/
function PaymentMadeDataTable({
//#withPaymentMades
// #withPaymentMades
paymentMadeCurrentPage,
paymentMadePageination,
paymentMadeLoading,
paymentMadeItems,
paymentMadesLoading,
paymentMadeTableQuery,
// #withDashboardActions
changeCurrentView,
changePageSubtitle,
setTopbarEditView,
// #withPaymentMadeActions
addPaymentMadesTableQueries,
// #withView
viewMeta,
//#OwnProps
loading,
onFetchData,
// #ownProps
onEditPaymentMade,
onDeletePaymentMade,
onSelectedRowsChange,
}) {
const [initialMount, setInitialMount] = useState(false);
const { custom_view_id: customViewId } = useParams();
const isLoaded = useIsValuePassed(paymentMadesLoading, false);
const { formatMessage } = useIntl();
useEffect(() => {
setInitialMount(false);
}, [customViewId]);
useUpdateEffect(() => {
if (!paymentMadeLoading) {
setInitialMount(true);
}
}, [paymentMadeLoading, setInitialMount]);
const handleEditPaymentMade = useCallback(
(paymentMade) => () => {
onEditPaymentMade && onEditPaymentMade(paymentMade);
saveInvoke(onEditPaymentMade, paymentMade);
},
[onEditPaymentMade],
);
const handleDeletePaymentMade = useCallback(
(paymentMade) => () => {
onDeletePaymentMade && onDeletePaymentMade(paymentMade);
saveInvoke(onDeletePaymentMade, paymentMade);
},
[onDeletePaymentMade],
);
@@ -89,7 +66,7 @@ function PaymentMadeDataTable({
/>
<MenuDivider />
<MenuItem
icon={<Icon icon="pen-18" />}
icon={<Icon icon="pen-18" />}
text={formatMessage({ id: 'edit_payment_made' })}
onClick={handleEditPaymentMade(paymentMade)}
/>
@@ -176,59 +153,69 @@ function PaymentMadeDataTable({
);
const handleDataTableFetchData = useCallback(
(...args) => {
onFetchData && onFetchData(...args);
({ pageIndex, pageSize, sortBy }) => {
addPaymentMadesTableQueries({
...(sortBy.length > 0
? {
column_sort_by: sortBy[0].id,
sort_order: sortBy[0].desc ? 'desc' : 'asc',
}
: {}),
page_size: pageSize,
page: pageIndex + 1,
});
},
[onFetchData],
[addPaymentMadesTableQueries],
);
const handleSelectedRowsChange = useCallback(
(selectedRows) => {
onSelectedRowsChange &&
onSelectedRowsChange(selectedRows.map((s) => s.original));
saveInvoke(
onSelectedRowsChange,
selectedRows.map((s) => s.original),
);
},
[onSelectedRowsChange],
);
return (
<div>
<LoadingIndicator loading={loading} mount={false}>
<DataTable
columns={columns}
data={paymentMadeCurrentPage}
onFetchData={handleDataTableFetchData}
manualSortBy={true}
selectionColumn={true}
noInitialFetch={true}
sticky={true}
loading={paymentMadeLoading && !initialMount}
onSelectedRowsChange={handleSelectedRowsChange}
rowContextMenu={onRowContextMenu}
pagination={true}
pagesCount={paymentMadePageination.pagesCount}
initialPageSize={paymentMadePageination.pageSize}
initialPageIndex={paymentMadePageination.page - 1}
/>
</LoadingIndicator>
</div>
<LoadingIndicator loading={paymentMadesLoading && !isLoaded} mount={false}>
<DataTable
columns={columns}
data={paymentMadeCurrentPage}
onFetchData={handleDataTableFetchData}
manualSortBy={true}
selectionColumn={true}
noInitialFetch={true}
sticky={true}
onSelectedRowsChange={handleSelectedRowsChange}
rowContextMenu={onRowContextMenu}
pagination={true}
pagesCount={paymentMadePageination.pagesCount}
initialPageSize={paymentMadeTableQuery.page_size}
initialPageIndex={paymentMadeTableQuery.page - 1}
autoResetSortBy={false}
autoResetPage={false}
/>
</LoadingIndicator>
);
}
export default compose(
withRouter,
withCurrentView,
withDialogActions,
withDashboardActions,
withPaymentMadeActions,
withPaymentMade(
({
paymentMadeCurrentPage,
paymentMadeLoading,
paymentMadesLoading,
paymentMadePageination,
paymentMadeTableQuery,
}) => ({
paymentMadeCurrentPage,
paymentMadeLoading,
paymentMadesLoading,
paymentMadePageination,
paymentMadeTableQuery,
}),
),
withViewDetails(),
)(PaymentMadeDataTable);

View File

@@ -95,24 +95,6 @@ function PaymentMadeList({
selectedRows,
]);
const handleFetchData = useCallback(
({ pageIndex, pageSize, sortBy }) => {
const page = pageIndex + 1;
addPaymentMadesTableQueries({
...(sortBy.length > 0
? {
column_sort_by: sortBy[0].id,
sort_order: sortBy[0].desc ? 'desc' : 'asc',
}
: {}),
page_size: pageSize,
page,
});
},
[addPaymentMadesTableQueries],
);
// Handle filter change to re-fetch data-table.
const handleFilterChanged = useCallback(() => {}, [fetchPaymentMades]);
@@ -145,14 +127,13 @@ function PaymentMadeList({
>
<PaymentMadeViewTabs />
<PaymentMadeDataTable
loading={fetchPaymentMades.isFetching}
onDeletePaymentMade={handleDeletePaymentMade}
onFetchData={handleFetchData}
onEditPaymentMade={handleEditPaymentMade}
onSelectedRowsChange={handleSelectedRowsChange}
/>
</Route>
</Switch>
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'delete'} />}

View File

@@ -27,8 +27,8 @@ const mapDispatchToProps = (dispatch) => ({
addPaymentMadesTableQueries: (queries) =>
dispatch({
type: t.PAYMENT_MADE_TABLE_QUERIES_ADD,
queries,
type: t.PAYMENT_MADES_TABLE_QUERIES_ADD,
payload: { queries },
}),
setPaymentNumberChange: (isChanged) =>
dispatch({

View File

@@ -29,7 +29,7 @@ function EstimateList({
requestFetchResourceFields,
// #withEstimate
estimateTableQuery,
estimatesTableQuery,
estimateViews,
//#withEistimateActions
@@ -52,7 +52,7 @@ function EstimateList({
// (key, resourceName) => requestFetchResourceFields(resourceName),
// );
const fetchEstimate = useQuery(['estimates-table', estimateTableQuery], () =>
const fetchEstimate = useQuery(['estimates-table', estimatesTableQuery], () =>
requestFetchEstimatesTable(),
);
@@ -100,23 +100,6 @@ function EstimateList({
},
[history],
);
const handleFetchData = useCallback(
({ pageIndex, pageSize, sortBy }) => {
const page = pageIndex + 1;
addEstimatesTableQueries({
...(sortBy.length > 0
? {
column_sort_by: sortBy[0].id,
sort_order: sortBy[0].desc ? 'desc' : 'asc',
}
: {}),
page_size: pageSize,
page,
});
},
[addEstimatesTableQueries],
);
const handleSelectedRowsChange = useCallback(
(estimate) => {
@@ -142,14 +125,13 @@ function EstimateList({
>
<EstimateViewTabs />
<EstimatesDataTable
loading={fetchEstimate.isFetching}
onDeleteEstimate={handleDeleteEstimate}
onFetchData={handleFetchData}
onEditEstimate={handleEditEstimate}
onSelectedRowsChange={handleSelectedRowsChange}
/>
</Route>
</Switch>
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'delete'} />}
@@ -173,8 +155,8 @@ export default compose(
withEstimateActions,
withDashboardActions,
withViewsActions,
withEstimates(({ estimateTableQuery, estimateViews }) => ({
estimateTableQuery,
withEstimates(({ estimatesTableQuery, estimateViews }) => ({
estimatesTableQuery,
estimateViews,
})),
)(EstimateList);

View File

@@ -8,85 +8,48 @@ import {
MenuDivider,
Position,
} from '@blueprintjs/core';
import { useParams } from 'react-router-dom';
import { withRouter } from 'react-router';
import { FormattedMessage as T, useIntl } from 'react-intl';
import moment from 'moment';
import { compose } from 'utils';
import { useUpdateEffect } from 'hooks';
import { compose, saveInvoke } from 'utils';
import { useIsValuePassed } from 'hooks';
import LoadingIndicator from 'components/LoadingIndicator';
import { DataTable, Money, Icon } from 'components';
import withDialogActions from 'containers/Dialog/withDialogActions';
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
import withViewDetails from 'containers/Views/withViewDetails';
import withEstimates from './withEstimates';
import withEstimateActions from './withEstimateActions';
import withCurrentView from 'containers/Views/withCurrentView';
// Estimates transactions datatable.
function EstimatesDataTable({
//#withEitimates
// #withEstimates
estimatesCurrentPage,
estimatesLoading,
estimatesPageination,
estimateItems,
estimatesTableQuery,
// #withDashboardActions
changeCurrentView,
changePageSubtitle,
setTopbarEditView,
// #withEstimatesActions
addEstimatesTableQueries,
// #withView
viewMeta,
//#OwnProps
loading,
onFetchData,
// #ownProps
onEditEstimate,
onDeleteEstimate,
onSelectedRowsChange,
}) {
const [initialMount, setInitialMount] = useState(false);
const { custom_view_id: customViewId } = useParams();
const { formatMessage } = useIntl();
useEffect(() => {
setInitialMount(false);
}, []);
useUpdateEffect(() => {
if (!estimatesLoading) {
setInitialMount(true);
}
}, [estimatesLoading, setInitialMount]);
useEffect(() => {
if (customViewId) {
changeCurrentView(customViewId);
setTopbarEditView(customViewId);
}
changePageSubtitle(customViewId && viewMeta ? viewMeta.name : '');
}, [
customViewId,
changeCurrentView,
changePageSubtitle,
setTopbarEditView,
viewMeta,
]);
const isLoaded = useIsValuePassed(estimatesLoading, false);
const handleEditEstimate = useCallback(
(estimate) => () => {
onEditEstimate && onEditEstimate(estimate);
saveInvoke(onEditEstimate, estimate);
},
[onEditEstimate],
);
const handleDeleteEstimate = useCallback(
(estimate) => () => {
onDeleteEstimate && onDeleteEstimate(estimate);
saveInvoke(onDeleteEstimate, estimate);
},
[onDeleteEstimate],
);
@@ -185,74 +148,64 @@ function EstimatesDataTable({
],
[actionMenuList, formatMessage],
);
const selectionColumn = useMemo(
() => ({
minWidth: 40,
width: 40,
maxWidth: 40,
}),
[],
);
const handleDataTableFetchData = useCallback(
(...args) => {
onFetchData && onFetchData(...args);
const handleFetchData = useCallback(
({ pageIndex, pageSize, sortBy }) => {
const page = pageIndex + 1;
addEstimatesTableQueries({
...(sortBy.length > 0
? {
column_sort_by: sortBy[0].id,
sort_order: sortBy[0].desc ? 'desc' : 'asc',
}
: {}),
page_size: pageSize,
page,
});
},
[onFetchData],
[addEstimatesTableQueries],
);
const handleSelectedRowsChange = useCallback(
(selectedRows) => {
onSelectedRowsChange &&
onSelectedRowsChange(selectedRows.map((s) => s.original));
saveInvoke(
onSelectedRowsChange,
selectedRows.map((s) => s.original),
);
},
[onSelectedRowsChange],
);
console.log(estimatesCurrentPage, 'estimatesCurrentPage');
console.log(estimateItems, 'estimateItems');
return (
<div>
<LoadingIndicator loading={loading} mount={false}>
<DataTable
columns={columns}
data={estimatesCurrentPage}
onFetchData={handleDataTableFetchData}
manualSortBy={true}
selectionColumn={true}
noInitialFetch={true}
sticky={true}
loading={estimatesLoading && !initialMount}
onSelectedRowsChange={handleSelectedRowsChange}
rowContextMenu={onRowContextMenu}
pagination={true}
pagesCount={estimatesPageination.pagesCount}
initialPageSize={estimatesPageination.pageSize}
initialPageIndex={estimatesPageination.page - 1}
/>
</LoadingIndicator>
</div>
<LoadingIndicator loading={estimatesLoading && !isLoaded} mount={false}>
<DataTable
columns={columns}
data={estimatesCurrentPage}
onFetchData={handleFetchData}
manualSortBy={true}
selectionColumn={true}
noInitialFetch={true}
sticky={true}
onSelectedRowsChange={handleSelectedRowsChange}
rowContextMenu={onRowContextMenu}
pagination={true}
pagesCount={estimatesPageination.pagesCount}
initialPageSize={estimatesTableQuery.page_size}
initialPageIndex={estimatesTableQuery.page - 1}
/>
</LoadingIndicator>
);
}
export default compose(
withRouter,
withCurrentView,
withDialogActions,
withDashboardActions,
withEstimateActions,
withEstimates(
({
({ estimatesCurrentPage, estimatesLoading, estimatesPageination, estimatesTableQuery }) => ({
estimatesCurrentPage,
estimatesLoading,
estimatesPageination,
estimateItems,
}) => ({
estimatesCurrentPage,
estimatesLoading,
estimatesPageination,
estimateItems,
estimatesTableQuery
}),
),
withViewDetails(),
)(EstimatesDataTable);

View File

@@ -25,7 +25,7 @@ const mapDipatchToProps = (dispatch) => ({
addEstimatesTableQueries: (queries) =>
dispatch({
type: t.ESTIMATES_TABLE_QUERIES_ADD,
queries,
payload: { queries },
}),
setEstimateNumberChanged: (isChanged) =>
dispatch({

View File

@@ -18,8 +18,8 @@ export default (mapState) => {
estimatesCurrentPage: getEstimatesItems(state, props, query),
estimateViews: getResourceViews(state, props, 'sales_estimates'),
estimateItems: state.salesEstimates.items,
estimateTableQuery: query,
estimatesTableQuery: query,
estimatesPageination: getEstimatesPaginationMeta(state, props, query),
estimatesLoading: state.salesEstimates.loading,

View File

@@ -20,6 +20,9 @@ import withViewsActions from 'containers/Views/withViewsActions';
import { compose } from 'utils';
/**
* Invoices list.
*/
function InvoiceList({
// #withDashboardActions
changePageTitle,
@@ -94,26 +97,8 @@ function InvoiceList({
selectedRows,
]);
const handleFetchData = useCallback(
({ pageIndex, pageSize, sortBy }) => {
const page = pageIndex + 1;
addInvoiceTableQueries({
...(sortBy.length > 0
? {
column_sort_by: sortBy[0].id,
sort_order: sortBy[0].desc ? 'desc' : 'asc',
}
: {}),
page_size: pageSize,
page,
});
},
[addInvoiceTableQueries],
);
// Handle filter change to re-fetch data-table.
const handleFilterChanged = useCallback(() => {}, [fetchInvoices]);
const handleFilterChanged = useCallback(() => {}, []);
// Handle selected rows change.
const handleSelectedRowsChange = useCallback(
@@ -140,14 +125,13 @@ function InvoiceList({
>
<InvoiceViewTabs />
<InvoicesDataTable
loading={fetchInvoices.isFetching}
onDeleteInvoice={handleDeleteInvoice}
onFetchData={handleFetchData}
onEditInvoice={handleEditInvoice}
onSelectedRowsChange={handleSelectedRowsChange}
/>
</Route>
</Switch>
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'delete'} />}

View File

@@ -1,4 +1,4 @@
import React, { useEffect, useCallback, useState, useMemo } from 'react';
import React, { useCallback, useMemo } from 'react';
import {
Intent,
Button,
@@ -8,13 +8,12 @@ import {
MenuDivider,
Position,
} from '@blueprintjs/core';
import { useParams } from 'react-router-dom';
import { withRouter } from 'react-router';
import { FormattedMessage as T, useIntl } from 'react-intl';
import moment from 'moment';
import { compose } from 'utils';
import { useUpdateEffect } from 'hooks';
import { compose, saveInvoke } from 'utils';
import { useIsValuePassed } from 'hooks';
import LoadingIndicator from 'components/LoadingIndicator';
import { DataTable, Money, Icon } from 'components';
@@ -27,66 +26,34 @@ import withInvoices from './withInvoices';
import withInvoiceActions from './withInvoiceActions';
import withCurrentView from 'containers/Views/withCurrentView';
// Invoices datatable.
function InvoicesDataTable({
//#withInvoices
// #withInvoices
invoicesCurrentPage,
invoicesLoading,
invoicesPageination,
invoicesItems,
// #withDashboardActions
changeCurrentView,
changePageSubtitle,
setTopbarEditView,
// #withInvoicesActions
addInvoiceTableQueries,
// #withView
viewMeta,
//#OwnProps
loading,
onFetchData,
// #OwnProps
onEditInvoice,
onDeleteInvoice,
onSelectedRowsChange,
}) {
const [initialMount, setInitialMount] = useState(false);
const { custom_view_id: customViewId } = useParams();
const { formatMessage } = useIntl();
useEffect(() => {
setInitialMount(false);
}, [customViewId]);
useUpdateEffect(() => {
if (!invoicesLoading) {
setInitialMount(true);
}
}, [invoicesLoading, setInitialMount]);
// useEffect(() => {
// if (customViewId) {
// changeCurrentView(customViewId);
// setTopbarEditView(customViewId);
// }
// changePageSubtitle(customViewId && viewMeta ? viewMeta.name : '');
// }, [
// customViewId,
// changeCurrentView,
// changePageSubtitle,
// setTopbarEditView,
// viewMeta,
// ]);
const isLoadedBefore = useIsValuePassed(invoicesLoading, false);
const handleEditInvoice = useCallback(
(_invoice) => () => {
onEditInvoice && onEditInvoice(_invoice);
saveInvoke(onEditInvoice, _invoice);
},
[onEditInvoice],
);
const handleDeleteInvoice = useCallback(
(_invoice) => () => {
onDeleteInvoice && onDeleteInvoice(_invoice);
saveInvoke(onDeleteInvoice, _invoice);
},
[onDeleteInvoice],
);
@@ -194,49 +161,54 @@ function InvoicesDataTable({
);
const handleDataTableFetchData = useCallback(
(...args) => {
onFetchData && onFetchData(...args);
({ pageSize, pageIndex, sortBy }) => {
addInvoiceTableQueries({
...(sortBy.length > 0
? {
column_sort_by: sortBy[0].id,
sort_order: sortBy[0].desc ? 'desc' : 'asc',
}
: {}),
page_size: pageSize,
page: pageIndex + 1,
});
},
[onFetchData],
[addInvoiceTableQueries],
);
const handleSelectedRowsChange = useCallback(
(selectedRows) => {
onSelectedRowsChange &&
onSelectedRowsChange(selectedRows.map((s) => s.original));
saveInvoke(
onSelectedRowsChange,
selectedRows.map((s) => s.original),
);
},
[onSelectedRowsChange],
);
const selectionColumn = useMemo(
() => ({
minWidth: 40,
width: 40,
maxWidth: 40,
}),
[],
);
return (
<div>
<LoadingIndicator loading={loading} mount={false}>
<DataTable
columns={columns}
data={invoicesCurrentPage}
onFetchData={handleDataTableFetchData}
manualSortBy={true}
selectionColumn={true}
noInitialFetch={true}
sticky={true}
loading={invoicesLoading && !initialMount}
onSelectedRowsChange={handleSelectedRowsChange}
rowContextMenu={onRowContextMenu}
pagination={true}
pagesCount={invoicesPageination.pagesCount}
initialPageSize={invoicesPageination.pageSize}
initialPageIndex={invoicesPageination.page - 1}
/>
</LoadingIndicator>
</div>
<LoadingIndicator
loading={invoicesLoading && !isLoadedBefore}
mount={false}
>
<DataTable
columns={columns}
data={invoicesCurrentPage}
onFetchData={handleDataTableFetchData}
manualSortBy={true}
selectionColumn={true}
noInitialFetch={true}
sticky={true}
onSelectedRowsChange={handleSelectedRowsChange}
rowContextMenu={onRowContextMenu}
pagination={true}
autoResetSortBy={false}
autoResetPage={false}
pagesCount={invoicesPageination.pagesCount}
initialPageSize={invoicesPageination.pageSize}
initialPageIndex={invoicesPageination.page - 1}
/>
</LoadingIndicator>
);
}
@@ -247,10 +219,16 @@ export default compose(
withDashboardActions,
withInvoiceActions,
withInvoices(
({ invoicesCurrentPage, invoicesLoading, invoicesPageination }) => ({
({
invoicesCurrentPage,
invoicesLoading,
invoicesPageination,
invoicesTableQuery,
}) => ({
invoicesCurrentPage,
invoicesLoading,
invoicesPageination,
invoicesTableQuery,
}),
),
withViewDetails(),

View File

@@ -16,19 +16,20 @@ const mapDipatchToProps = (dispatch) => ({
requestFetchInvoiceTable: (query = {}) =>
dispatch(fetchInvoicesTable({ query: { ...query } })),
requestDeleteInvoice: (id) => dispatch(deleteInvoice({ id })),
requestFetchDueInvoices: (customerId) => dispatch(fetchDueInvoices({ customerId })),
requestFetchDueInvoices: (customerId) =>
dispatch(fetchDueInvoices({ customerId })),
changeInvoiceView: (id) =>
dispatch({
type: t.INVOICES_SET_CURRENT_VIEW,
currentViewId: parseInt(id, 10),
}),
addInvoiceTableQueries: (_queries) =>
addInvoiceTableQueries: (queries) =>
dispatch({
type: t.INVOICES_TABLE_QUERIES_ADD,
_queries,
payload: { queries },
}),
setInvoiceNumberChanged: (isChanged) => dispatch({
setInvoiceNumberChanged: (isChanged) =>
dispatch({
type: t.INVOICE_NUMBER_CHANGED,
payload: { isChanged },
}),

View File

@@ -29,7 +29,6 @@ export default (mapState) => {
state,
props,
),
invoiceNumberChanged: state.salesInvoices.journalNumberChanged,
};
return mapState ? mapState(mapped, state, props) : mapped;

View File

@@ -60,7 +60,7 @@ function PaymentReceiveList({
() => requestFetchPaymentReceiveTable(),
);
//handle dalete Payment Receive
// Handle dalete Payment Receive
const handleDeletePaymentReceive = useCallback(
(paymentReceive) => {
setDeletePaymentReceive(paymentReceive);
@@ -68,12 +68,12 @@ function PaymentReceiveList({
[setDeletePaymentReceive],
);
// handle cancel Payment Receive
// Handle cancel payment Receive.
const handleCancelPaymentReceiveDelete = useCallback(() => {
setDeletePaymentReceive(false);
}, [setDeletePaymentReceive]);
// handleConfirm delete payment receive
// Handle confirm delete payment receive.
const handleConfirmPaymentReceiveDelete = useCallback(() => {
requestDeletePaymentReceive(deletePaymentReceive.id).then(() => {
AppToaster.show({
@@ -95,24 +95,6 @@ function PaymentReceiveList({
selectedRows,
]);
const handleFetchData = useCallback(
({ pageIndex, pageSize, sortBy }) => {
const page = pageIndex + 1;
addPaymentReceivesTableQueries({
...(sortBy.length > 0
? {
column_sort_by: sortBy[0].id,
sort_order: sortBy[0].desc ? 'desc' : 'asc',
}
: {}),
page_size: pageSize,
page,
});
},
[addPaymentReceivesTableQueries],
);
// Handle filter change to re-fetch data-table.
const handleFilterChanged = useCallback(() => {}, [fetchPaymentReceives]);
@@ -145,9 +127,7 @@ function PaymentReceiveList({
>
<PaymentReceiveViewTabs />
<PaymentReceivesDataTable
loading={fetchPaymentReceives.isFetching}
onDeletePaymentReceive={handleDeletePaymentReceive}
onFetchData={handleFetchData}
onEditPaymentReceive={handleEditPaymentReceive}
onSelectedRowsChange={handleSelectedRowsChange}
/>

View File

@@ -1,21 +1,19 @@
import React, { useEffect, useCallback, useState, useMemo } from 'react';
import React, { useCallback, useMemo } from 'react';
import {
Intent,
Button,
Classes,
Popover,
Menu,
MenuItem,
MenuDivider,
Position,
} from '@blueprintjs/core';
import { useParams } from 'react-router-dom';
import { withRouter } from 'react-router';
import { FormattedMessage as T, useIntl } from 'react-intl';
import moment from 'moment';
import { compose } from 'utils';
import { useUpdateEffect } from 'hooks';
import { compose, saveInvoke } from 'utils';
import { useIsValuePassed } from 'hooks';
import LoadingIndicator from 'components/LoadingIndicator';
import { DataTable, Money, Icon } from 'components';
@@ -29,58 +27,26 @@ import withPaymentReceivesActions from './withPaymentReceivesActions';
import withCurrentView from 'containers/Views/withCurrentView';
function PaymentReceivesDataTable({
//#withPaymentReceives
// #withPaymentReceives
PaymentReceivesCurrentPage,
paymentReceivesPageination,
paymentReceivesLoading,
paymentReceivesItems,
paymentReceivesTableQuery,
// #withDashboardActions
changeCurrentView,
changePageSubtitle,
setTopbarEditView,
// #withPaymentReceivesActions
addPaymentReceivesTableQueries,
// #withView
viewMeta,
//#OwnProps
loading,
onFetchData,
// #OwnProps
onEditPaymentReceive,
onDeletePaymentReceive,
onSelectedRowsChange,
}) {
const [initialMount, setInitialMount] = useState(false);
const { custom_view_id: customViewId } = useParams();
const isLoaded = useIsValuePassed(paymentReceivesLoading, false);
const { formatMessage } = useIntl();
useEffect(() => {
setInitialMount(false);
}, [customViewId]);
useUpdateEffect(() => {
if (!paymentReceivesLoading) {
setInitialMount(true);
}
}, [paymentReceivesLoading, setInitialMount]);
// useEffect(() => {
// if (customViewId) {
// changeCurrentView(customViewId);
// setTopbarEditView(customViewId);
// }
// changePageSubtitle(customViewId && viewMeta ? viewMeta.name : '');
// }, [
// customViewId,
// changeCurrentView,
// changePageSubtitle,
// setTopbarEditView,
// viewMeta,
// ]);
const handleEditPaymentReceive = useCallback(
(paymentReceive) => () => {
onEditPaymentReceive && onEditPaymentReceive(paymentReceive);
saveInvoke(onEditPaymentReceive, paymentReceive);
},
[onEditPaymentReceive],
);
@@ -92,6 +58,32 @@ function PaymentReceivesDataTable({
[onDeletePaymentReceive],
);
const handleDataTableFetchData = useCallback(
({ pageIndex, pageSize, sortBy }) => {
addPaymentReceivesTableQueries({
...(sortBy.length > 0
? {
column_sort_by: sortBy[0].id,
sort_order: sortBy[0].desc ? 'desc' : 'asc',
}
: {}),
page_size: pageSize,
page: pageIndex + 1,
});
},
[addPaymentReceivesTableQueries],
);
const handleSelectedRowsChange = useCallback(
(selectedRows) => {
saveInvoke(
onSelectedRowsChange,
selectedRows.map((s) => s.original),
);
},
[onSelectedRowsChange],
);
const actionMenuList = useCallback(
(paymentReceive) => (
<Menu>
@@ -142,7 +134,8 @@ function PaymentReceivesDataTable({
{
id: 'payment_receive_no',
Header: formatMessage({ id: 'payment_receive_no' }),
accessor: (row) => (row.payment_receive_no ? `#${row.payment_receive_no}` : null),
accessor: (row) =>
row.payment_receive_no ? `#${row.payment_receive_no}` : null,
width: 140,
className: 'payment_receive_no',
},
@@ -186,41 +179,29 @@ function PaymentReceivesDataTable({
[actionMenuList, formatMessage],
);
const handleDataTableFetchData = useCallback(
(...args) => {
onFetchData && onFetchData(...args);
},
[onFetchData],
);
const handleSelectedRowsChange = useCallback(
(selectedRows) => {
onSelectedRowsChange &&
onSelectedRowsChange(selectedRows.map((s) => s.original));
},
[onSelectedRowsChange],
);
return (
<div>
<LoadingIndicator loading={loading} mount={false}>
<DataTable
columns={columns}
data={PaymentReceivesCurrentPage}
onFetchData={handleDataTableFetchData}
manualSortBy={true}
selectionColumn={true}
noInitialFetch={true}
sticky={true}
loading={paymentReceivesLoading && !initialMount}
onSelectedRowsChange={handleSelectedRowsChange}
rowContextMenu={onRowContextMenu}
pagination={true}
pagesCount={paymentReceivesPageination.pagesCount}
initialPageSize={paymentReceivesPageination.pageSize}
initialPageIndex={paymentReceivesPageination.page - 1}
/>
</LoadingIndicator>
</div>
<LoadingIndicator
loading={paymentReceivesLoading && !isLoaded}
mount={false}
>
<DataTable
columns={columns}
data={PaymentReceivesCurrentPage}
onFetchData={handleDataTableFetchData}
manualSortBy={true}
selectionColumn={true}
noInitialFetch={true}
sticky={true}
onSelectedRowsChange={handleSelectedRowsChange}
rowContextMenu={onRowContextMenu}
pagination={true}
autoResetSortBy={false}
autoResetPage={false}
pagesCount={paymentReceivesPageination.pagesCount}
initialPageSize={paymentReceivesTableQuery.page_size}
initialPageIndex={paymentReceivesTableQuery.page - 1}
/>
</LoadingIndicator>
);
}
@@ -235,10 +216,12 @@ export default compose(
PaymentReceivesCurrentPage,
paymentReceivesLoading,
paymentReceivesPageination,
paymentReceivesTableQuery
}) => ({
PaymentReceivesCurrentPage,
paymentReceivesLoading,
paymentReceivesPageination,
paymentReceivesTableQuery
}),
),
withViewDetails(),

View File

@@ -22,7 +22,6 @@ export default (mapState) => {
query,
),
paymentReceivesLoading: state.paymentReceives.loading,
paymentReceiveNumberChanged: state.paymentReceives.journalNumberChanged,
};
return mapState ? mapState(mapped, state, props) : mapped;

View File

@@ -20,16 +20,17 @@ const mapDispatchToProps = (dispatch) => ({
changePaymentReceiveView: (id) =>
dispatch({
type: t.PAYMENT_RECEIVE_SET_CURRENT_VIEW,
type: t.PAYMENT_RECEIVES_SET_CURRENT_VIEW,
currentViewId: parseInt(id, 10),
}),
addPaymentReceivesTableQueries: (queries) =>
dispatch({
type: t.PAYMENT_RECEIVE_TABLE_QUERIES_ADD,
queries,
type: t.PAYMENT_RECEIVES_TABLE_QUERIES_ADD,
payload: { queries }
}),
setPaymentReceiveNumberChanged: (isChanged) =>
setPaymentReceiveNumberChanged: (isChanged) =>
dispatch({
type: t.PAYMENT_RECEIVE_NUMBER_CHANGED,
payload: { isChanged },

View File

@@ -30,7 +30,6 @@ function ReceiptList({
//#withReceipts
receiptTableQuery,
receiptview,
//#withReceiptActions
requestFetchReceiptsTable,
@@ -96,10 +95,8 @@ function ReceiptList({
// [fetchReceipt],
// );
// Handle filter change to re-fetch data-table.
const handleFilterChanged = useCallback(() => {}, [fetchReceipts]);
// Handle filter change to re-fetch data-table.
const handleFilterChanged = useCallback(() => {}, [fetchReceipts]);
// Calculates the selected rows
const selectedRowsCount = useMemo(() => Object.values(selectedRows).length, [
@@ -112,23 +109,6 @@ function ReceiptList({
},
[history],
);
const handleFetchData = useCallback(
({ pageIndex, pageSize, sortBy }) => {
const page = pageIndex + 1;
addReceiptsTableQueries({
...(sortBy.length > 0
? {
column_sort_by: sortBy[0].id,
sort_order: sortBy[0].desc ? 'desc' : 'asc',
}
: {}),
page_size: pageSize,
page,
});
},
[addReceiptsTableQueries],
);
const handleSelectedRowsChange = useCallback(
(estimate) => {
@@ -154,14 +134,13 @@ function ReceiptList({
>
<ReceiptViewTabs />
<ReceiptsDataTable
loading={fetchReceipts.isLoading}
onDeleteReceipt={handleDeleteReceipt}
onFetchData={handleFetchData}
onEditReceipt={handleEditReceipt}
onSelectedRowsChange={handleSelectedRowsChange}
/>
</Route>
</Switch>
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'delete'} />}

View File

@@ -1,4 +1,4 @@
import React, { useEffect, useCallback, useState, useMemo } from 'react';
import React, { useCallback, useMemo } from 'react';
import {
Intent,
Button,
@@ -8,85 +8,50 @@ import {
MenuDivider,
Position,
} from '@blueprintjs/core';
import { useParams } from 'react-router-dom';
import { withRouter } from 'react-router';
import { FormattedMessage as T, useIntl } from 'react-intl';
import moment from 'moment';
import { compose } from 'utils';
import { useUpdateEffect } from 'hooks';
import { compose, saveInvoke } from 'utils';
import { useIsValuePassed } from 'hooks';
import LoadingIndicator from 'components/LoadingIndicator';
import { DataTable, Money, Icon } from 'components';
import { LoadingIndicator, DataTable, Money, Icon } from 'components';
import withDialogActions from 'containers/Dialog/withDialogActions';
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
import withViewDetails from 'containers/Views/withViewDetails';
import withReceipts from './withReceipts';
import withReceiptActions from './withReceiptActions';
import withCurrentView from 'containers/Views/withCurrentView';
function ReceiptsDataTable({
//#withReceipts
receiptsCurrentPage,
receiptsLoading,
receiptsPagination,
receiptItems,
// #withDashboardActions
changeCurrentView,
changePageSubtitle,
setTopbarEditView,
receiptTableQuery,
// #withView
viewMeta,
// #withReceiptsActions
addReceiptsTableQueries,
// #Own Props
loading,
onFetchData,
onEditReceipt,
onDeleteReceipt,
onSelectedRowsChange,
}) {
const [initialMount, setInitialMount] = useState(false);
const { custom_view_id: customViewId } = useParams();
const { formatMessage } = useIntl();
useUpdateEffect(() => {
if (!receiptsLoading) {
setInitialMount(true);
}
}, [receiptsLoading, setInitialMount]);
useEffect(() => {
setInitialMount(false);
}, []);
useEffect(() => {
if (customViewId) {
changeCurrentView(customViewId);
setTopbarEditView(customViewId);
}
changePageSubtitle(customViewId && viewMeta ? viewMeta.name : '');
}, [
customViewId,
changeCurrentView,
changePageSubtitle,
setTopbarEditView,
viewMeta,
]);
const isLoadedBefore = useIsValuePassed(receiptsLoading, false);
const handleEditReceipt = useCallback(
(receipt) => () => {
onEditReceipt && onEditReceipt(receipt);
saveInvoke(onEditReceipt, receipt);
},
[onEditReceipt],
);
const handleDeleteReceipt = useCallback(
(receipt) => () => {
onDeleteReceipt && onDeleteReceipt(receipt);
saveInvoke(onDeleteReceipt, receipt);
},
[onDeleteReceipt],
);
@@ -194,50 +159,61 @@ function ReceiptsDataTable({
);
const handleDataTableFetchData = useCallback(
(...args) => {
onFetchData && onFetchData(...args);
({ sortBy, pageIndex, pageSize }) => {
const page = pageIndex + 1;
addReceiptsTableQueries({
...(sortBy.length > 0
? {
column_sort_by: sortBy[0].id,
sort_order: sortBy[0].desc ? 'desc' : 'asc',
}
: {}),
page_size: pageSize,
page,
});
},
[onFetchData],
[addReceiptsTableQueries],
);
const handleSelectedRowsChange = useCallback(
(selectedRows) => {
onSelectedRowsChange &&
onSelectedRowsChange(selectedRows.map((s) => s.original));
saveInvoke(
onSelectedRowsChange,
selectedRows.map((s) => s.original),
);
},
[onSelectedRowsChange],
);
console.log(receiptsCurrentPage, 'receiptCurrnetPage');
console.log(receiptItems, 'receiptItems');
return (
<div>
<LoadingIndicator loading={loading} mount={false}>
<DataTable
columns={columns}
data={receiptsCurrentPage}
loading={receiptsLoading && !initialMount}
onFetchData={handleDataTableFetchData}
manualSortBy={true}
selectionColumn={true}
noInitialFetch={true}
sticky={true}
onSelectedRowsChange={handleSelectedRowsChange}
rowContextMenu={onRowContextMenu}
pagination={true}
pagesCount={receiptsPagination.pagesCount}
initialPageSize={receiptsPagination.pageSize}
initialPageIndex={receiptsPagination.page - 1}
/>
</LoadingIndicator>
</div>
<LoadingIndicator
loading={receiptsLoading && !isLoadedBefore}
mount={false}
>
<DataTable
columns={columns}
data={receiptsCurrentPage}
onFetchData={handleDataTableFetchData}
manualSortBy={true}
selectionColumn={true}
noInitialFetch={true}
sticky={true}
onSelectedRowsChange={handleSelectedRowsChange}
rowContextMenu={onRowContextMenu}
pagination={true}
pagesCount={receiptsPagination.pagesCount}
autoResetSortBy={false}
autoResetPage={false}
initialPageSize={receiptTableQuery.page_size}
initialPageIndex={receiptTableQuery.page - 1}
/>
</LoadingIndicator>
);
}
export default compose(
withRouter,
withCurrentView,
withDialogActions,
withDashboardActions,
withReceiptActions,
@@ -246,13 +222,12 @@ export default compose(
receiptsCurrentPage,
receiptsLoading,
receiptsPagination,
receiptItems,
receiptTableQuery,
}) => ({
receiptsCurrentPage,
receiptsLoading,
receiptsPagination,
receiptItems,
receiptTableQuery,
}),
),
withViewDetails(),
)(ReceiptsDataTable);

View File

@@ -26,7 +26,7 @@ const mapDispatchToProps = (dispatch) => ({
addReceiptsTableQueries: (queries) =>
dispatch({
type: t.RECEIPTS_TABLE_QUERIES_ADD,
queries,
payload: { queries },
}),
setReceiptNumberChanged:(isChanged) => dispatch({
type: t.RECEIPT_NUMBER_CHANGED,

View File

@@ -22,7 +22,6 @@ export default (mapState) => {
receiptsPagination: getReceiptPaginationMeta(state, props, tableQuery),
receiptsLoading: state.salesReceipts.loading,
receiptNumberChanged: state.salesReceipts.journalNumberChanged,
};

View File

@@ -21,6 +21,20 @@ export function useUpdateEffect(effect, dependencies = []) {
}, dependencies);
}
export function useIsValuePassed(value, compatatorValue) {
const cache = useRef([value]);
useEffect(() => {
if (cache.current.indexOf(value) === -1) {
cache.current.push(value);
}
}, [value]);
return cache.current.indexOf(compatatorValue) !== -1;
}
export default {
useAsync,
useUpdateEffect,

View File

@@ -1,5 +1,8 @@
import { createReducer } from '@reduxjs/toolkit';
import { createTableQueryReducers } from 'store/queryReducers';
import {
createTableQueryReducers,
viewPaginationSetReducer,
} from 'store/journalNumber.reducer';
import t from 'store/types';
@@ -9,7 +12,7 @@ const initialState = {
loading: false,
currentViewId: -1,
tableQuery: {
page_size: 5,
page_size: 12,
page: 1,
},
nextBillNumberChanged: false,
@@ -24,7 +27,8 @@ const defaultBill = {
entries: [],
};
const reducer = createReducer(initialState, {
export default createReducer(initialState, {
[t.BILL_SET]: (state, action) => {
const { id, bill } = action.payload;
const _bill = state.items[id] || {};
@@ -83,27 +87,6 @@ const reducer = createReducer(initialState, {
};
},
[t.BILLS_PAGINATION_SET]: (state, action) => {
const { pagination, customViewId } = action.payload;
const mapped = {
pageSize: parseInt(pagination.page_size, 10),
page: parseInt(pagination.page, 10),
total: parseInt(pagination.total, 10),
};
const paginationMeta = {
...mapped,
pagesCount: Math.ceil(mapped.total / mapped.pageSize),
pageIndex: Math.max(mapped.page - 1, 0),
};
state.views = {
...state.views,
[customViewId]: {
...(state.views?.[customViewId] || {}),
paginationMeta,
},
};
},
[t.BILL_NUMBER_CHANGED]: (state, action) => {
const { isChanged } = action.payload;
state.nextBillNumberChanged = isChanged;
@@ -141,7 +124,8 @@ const reducer = createReducer(initialState, {
const billsIds = bills.map((bill) => bill.id);
state.byBillPayamentId[billPaymentId] = billsIds;
}
});
},
export default createTableQueryReducers('bills', reducer);
...viewPaginationSetReducer(t.BILLS_PAGINATION_SET),
...createTableQueryReducers('BILLS'),
});

View File

@@ -1,12 +1,20 @@
import { createSelector } from '@reduxjs/toolkit';
import { pickItemsFromIds, paginationLocationQuery } from 'store/selectors';
import {
pickItemsFromIds,
paginationLocationQuery,
defaultPaginationMeta,
getCurrentPageResults,
} from 'store/selectors';
// Retreive bills table query.
const billTableQuery = (state) => state.bills.tableQuery;
const billPageSelector = (state, props, query) => {
const viewId = state.bills.currentViewId;
return state.bills.views?.[viewId]?.pages?.[query.page];
const currentView = state.bills.views?.[viewId];
const currentPageId = currentView?.paginationMeta?.page;
return currentView?.pages?.[currentPageId];
};
// Retreive bills items.
const billItemsSelector = (state) => state.bills.items;
@@ -15,7 +23,8 @@ const billItemsSelector = (state) => state.bills.items;
const billByIdSelector = (state, props) => state.bills.items[props.billId];
// Retrieve vendor due bills ids.
const billsPayableVendorSelector = (state, props) => state.bills.payable.byVendorId[props.vendorId];
const billsPayableVendorSelector = (state, props) =>
state.bills.payable.byVendorId[props.vendorId];
const billPaginationSelector = (state, props) => {
const viewId = state.bills.currentViewId;
@@ -58,13 +67,16 @@ export const getBillByIdFactory = () =>
*/
export const getBillPaginationMetaFactory = () =>
createSelector(billPaginationSelector, (billPage) => {
return billPage?.paginationMeta || {};
return {
...defaultPaginationMeta(),
...(billPage?.paginationMeta || {}),
};
});
/**
* Retrieve vendor payable bills.
*/
export const getVendorPayableBillsFactory = () =>
export const getVendorPayableBillsFactory = () =>
createSelector(
billItemsSelector,
billsPayableVendorSelector,
@@ -78,7 +90,7 @@ export const getVendorPayableBillsFactory = () =>
/**
* Retrieve vendor payable bills entries.
*/
export const getVendorPayableBillsEntriesFactory = () =>
export const getVendorPayableBillsEntriesFactory = () =>
createSelector(
billItemsSelector,
billsPayableVendorSelector,
@@ -94,5 +106,5 @@ export const getVendorPayableBillsEntriesFactory = () =>
id: null,
payment_amount: null,
}));
}
);
},
);

View File

@@ -4,7 +4,7 @@ export default {
BILLS_LIST_SET: 'BILLS_LIST_SET',
BILL_SET: 'BILL_SET',
BILLS_SET_CURRENT_VIEW: 'BILLS_SET_CURRENT_VIEW',
BILLS_TABLE_QUERIES_ADD: 'BILLS_TABLE_QUERIES_ADD',
BILLS_TABLE_QUERIES_ADD: 'BILLS/TABLE_QUERIES_ADD',
BILLS_TABLE_LOADING: 'BILLS_TABLE_LOADING',
BILLS_PAGINATION_SET: 'BILLS_PAGINATION_SET',
BILLS_PAGE_SET: 'BILLS_PAGE_SET',

View File

@@ -1,6 +1,8 @@
import { createReducer } from '@reduxjs/toolkit';
import { createTableQueryReducers } from 'store/queryReducers';
import { journalNumberChangedReducer } from 'store/journalNumber.reducer';
import {
journalNumberChangedReducer,
createTableQueryReducers,
} from 'store/journalNumber.reducer';
import t from 'store/types';
@@ -9,18 +11,17 @@ const initialState = {
views: {},
loading: false,
tableQuery: {
page_size: 5,
page_size: 12,
page: 1,
},
currentViewId: -1,
};
const defaultEstimate = {
entries: [],
};
const reducer = createReducer(initialState, {
export default createReducer(initialState, {
[t.ESTIMATE_SET]: (state, action) => {
const { id, estimate } = action.payload;
const _estimate = state.items[id] || {};
@@ -102,10 +103,9 @@ const reducer = createReducer(initialState, {
},
...journalNumberChangedReducer(t.ESTIMATE_NUMBER_CHANGED),
...createTableQueryReducers('ESTIMATES'),
});
export default createTableQueryReducers('sales_estimates', reducer);
export const getEstimateById = (state, id) => {
return state.sales_estimates.items[id];
};

View File

@@ -1,5 +1,5 @@
import { createSelector } from '@reduxjs/toolkit';
import { pickItemsFromIds, paginationLocationQuery } from 'store/selectors';
import { pickItemsFromIds, paginationLocationQuery, defaultPaginationMeta } from 'store/selectors';
const estimateTableQuery = (state) => state.salesEstimates.tableQuery;
@@ -14,9 +14,12 @@ const estimateItemsSelector = (state) => state.salesEstimates.items;
const estimatesPageSelector = (state, props, query) => {
const viewId = state.salesEstimates.currentViewId;
return state.salesEstimates.views?.[viewId]?.pages?.[query.page];
const currentPageId = state.salesEstimates.views?.[viewId]?.paginationMeta?.page;
return state.salesEstimates.views?.[viewId]?.pages?.[currentPageId];
};
// Retrieve estimates table query.
export const getEstimatesTableQueryFactory = () =>
createSelector(
paginationLocationQuery,
@@ -29,6 +32,7 @@ export const getEstimatesTableQueryFactory = () =>
},
);
// Retreive estimate results of the current page.
export const getEstimateCurrentPageFactory = () =>
createSelector(
estimatesPageSelector,
@@ -40,12 +44,17 @@ export const getEstimateCurrentPageFactory = () =>
},
);
// Retrieve specific estimate by the passed estimate id.
export const getEstimateByIdFactory = () =>
createSelector(estimateByIdSelector, (estimate) => {
return estimate;
});
// Retrieve estimates pagination meta.
export const getEstimatesPaginationMetaFactory = () =>
createSelector(estimatesCurrentViewSelector, (estimateView) => {
return estimateView?.paginationMeta || {};
return {
...defaultPaginationMeta(),
...(estimateView?.paginationMeta || {}),
};
});

View File

@@ -3,8 +3,8 @@ export default {
ESTIMATE_SET: 'ESTIMATE_SET',
ESTIMATE_DELETE: 'ESTIMATE_DELETE',
ESTIMATES_BULK_DELETE: 'ESTIMATES_BULK_DELETE',
ESTIMATES_SET_CURRENT_VIEW: 'ESTIMATES_SET_CURRENT_VIEW',
ESTIMATES_TABLE_QUERIES_ADD: 'ESTIMATES_TABLE_QUERIES_ADD',
ESTIMATES_SET_CURRENT_VIEW: 'ESTIMATES/SET_CURRENT_VIEW',
ESTIMATES_TABLE_QUERIES_ADD: 'ESTIMATES/TABLE_QUERIES_ADD',
ESTIMATES_TABLE_LOADING: 'ESTIMATES_TABLE_LOADING',
ESTIMATES_PAGINATION_SET: 'ESTIMATES_PAGINATION_SET',
ESTIMATES_PAGE_SET: 'ESTIMATES_PAGE_SET',

View File

@@ -1,7 +1,9 @@
import { createReducer } from '@reduxjs/toolkit';
import { createTableQueryReducers } from 'store/queryReducers';
import { journalNumberChangedReducer } from 'store/journalNumber.reducer';
import {
journalNumberChangedReducer,
viewPaginationSetReducer,
createTableQueryReducers,
} from 'store/journalNumber.reducer';
import t from 'store/types';
const initialState = {
@@ -10,7 +12,7 @@ const initialState = {
loading: false,
currentViewId: -1,
tableQuery: {
page_size: 5,
page_size: 12,
page: 1,
},
dueInvoices: {},
@@ -25,7 +27,7 @@ const defaultInvoice = {
entries: [],
};
const reducer = createReducer(initialState, {
export default createReducer(initialState, {
[t.INVOICE_SET]: (state, action) => {
const { id, sale_invoice } = action.payload;
const _invoice = state.items[id] || {};
@@ -82,28 +84,6 @@ const reducer = createReducer(initialState, {
};
},
[t.INVOICES_PAGINATION_SET]: (state, action) => {
const { pagination, customViewId } = action.payload;
const mapped = {
pageSize: parseInt(pagination.page_size, 10),
page: parseInt(pagination.page, 10),
total: parseInt(pagination.total, 10),
};
const paginationMeta = {
...mapped,
pagesCount: Math.ceil(mapped.total / mapped.pageSize),
pageIndex: Math.max(mapped.page - 1, 0),
};
state.views = {
...state.views,
[customViewId]: {
...(state.views?.[customViewId] || {}),
paginationMeta,
},
};
},
[t.INVOICES_RECEIVABLE_BY_PAYMENT_ID]: (state, action) => {
const { paymentReceiveId, saleInvoices } = action.payload;
const saleInvoicesIds = saleInvoices.map((saleInvoice) => saleInvoice.id);
@@ -126,10 +106,10 @@ const reducer = createReducer(initialState, {
},
...journalNumberChangedReducer(t.INVOICE_NUMBER_CHANGED),
...viewPaginationSetReducer(t.INVOICES_PAGINATION_SET),
...createTableQueryReducers('INVOICES'),
});
export default createTableQueryReducers('sales_invoices', reducer);
export const getInvoiceById = (state, id) => {
return state.sales_invoices.items[id];
};

View File

@@ -2,7 +2,7 @@ import { createSelector } from '@reduxjs/toolkit';
import {
pickItemsFromIds,
paginationLocationQuery,
getItemById,
defaultPaginationMeta,
} from 'store/selectors';
const invoiceTableQuery = (state) => state.salesInvoices.tableQuery;
@@ -17,10 +17,15 @@ const invoicesPaginationSelector = (state, props) => {
const invoicesPageSelector = (state, props, query) => {
const viewId = state.salesInvoices.currentViewId;
return state.salesInvoices.views?.[viewId]?.pages?.[query.page];
const currentView = state.salesInvoices.views?.[viewId];
const currentPageId = currentView?.paginationMeta?.page;
return currentView?.pages?.[currentPageId];
};
const invoicesItemsSelector = (state) => state.salesInvoices.items;
const invoicesReceiableCustomerSelector = (state, props) => state.salesInvoices.receivable.byCustomerId[props.customerId];
const invoicesReceiableCustomerSelector = (state, props) =>
state.salesInvoices.receivable.byCustomerId[props.customerId];
export const getInvoiceTableQueryFactory = () =>
createSelector(
@@ -34,6 +39,7 @@ export const getInvoiceTableQueryFactory = () =>
},
);
// Retrieve invoices of the current view and view.
export const getInvoiceCurrentPageFactory = () =>
createSelector(
invoicesPageSelector,
@@ -45,24 +51,27 @@ export const getInvoiceCurrentPageFactory = () =>
},
);
// Retrieve specific invoice by the passed invoice id.
export const getInvoiecsByIdFactory = () =>
createSelector(invoicesByIdSelector, (invoice) => {
return invoice;
});
// Retrieve invoices pagination meta.
export const getInvoicePaginationMetaFactory = () =>
createSelector(invoicesPaginationSelector, (invoicePage) => {
return invoicePage?.paginationMeta || {};
return {
...defaultPaginationMeta(),
...(invoicePage?.paginationMeta || {}),
};
});
export const getCustomerReceivableInvoicesEntriesFactory = () =>
export const getCustomerReceivableInvoicesEntriesFactory = () =>
createSelector(
invoicesItemsSelector,
invoicesReceiableCustomerSelector,
(invoicesItems, customerInvoicesIds) => {
const invoicesIds = [
...(customerInvoicesIds || []),
];
const invoicesIds = [...(customerInvoicesIds || [])];
const invoices = pickItemsFromIds(invoicesItems, invoicesIds);
return invoices.map((invoice) => ({
@@ -73,4 +82,4 @@ export const getCustomerReceivableInvoicesEntriesFactory = () =>
payment_amount: 0,
}));
},
)
);

View File

@@ -4,7 +4,7 @@ export default {
INVOICES_LIST_SET: 'INVOICES_LIST_SET',
INVOICE_SET: 'INVOICE_SET',
INVOICES_SET_CURRENT_VIEW: 'INVOICES_SET_CURRENT_VIEW',
INVOICES_TABLE_QUERIES_ADD: 'INVOICES_TABLE_QUERIES_ADD',
INVOICES_TABLE_QUERIES_ADD: 'INVOICES/TABLE_QUERIES_ADD',
INVOICES_TABLE_LOADING: 'INVOICES_TABLE_LOADING',
INVOICES_PAGINATION_SET: 'INVOICES_PAGINATION_SET',
INVOICES_PAGE_SET: 'INVOICES_PAGE_SET',

View File

@@ -1,6 +1,8 @@
import { createReducer } from '@reduxjs/toolkit';
import { createTableQueryReducers } from 'store/queryReducers';
import { omit } from 'lodash';
import {
createTableQueryReducers,
viewPaginationSetReducer,
} from 'store/journalNumber.reducer';
import t from 'store/types';
const initialState = {
@@ -9,7 +11,7 @@ const initialState = {
loading: false,
currentViewId: -1,
tableQuery: {
page_size: 5,
page_size: 12,
page: 1,
},
nextPaymentNumberChanged: false,
@@ -19,11 +21,12 @@ const defaultPaymentMade = {
entries: [],
};
const reducer = createReducer(initialState, {
export default createReducer(initialState, {
[t.PAYMENT_MADES_TABLE_LOADING]: (state, action) => {
const { loading } = action.payload;
state.loading = loading;
},
[t.PAYMENT_MADES_ITEMS_SET]: (state, action) => {
const { bill_payments } = action.payload;
const _bill_payments = {};
@@ -41,7 +44,7 @@ const reducer = createReducer(initialState, {
[t.PAYMENT_MADE_SET]: (state, action) => {
const { id, paymentMade } = action.payload;
const _oldPaymentMade = (state.items[id] || {});
const _oldPaymentMade = state.items[id] || {};
state.items[id] = {
...defaultPaymentMade,
@@ -58,28 +61,6 @@ const reducer = createReducer(initialState, {
}
},
[t.PAYMENT_MADES_PAGINATION_SET]: (state, action) => {
const { pagination, customViewId } = action.payload;
const mapped = {
pageSize: parseInt(pagination.pageSize, 10),
page: parseInt(pagination.page, 10),
total: parseInt(pagination.total, 10),
};
const paginationMeta = {
...mapped,
pagesCount: Math.ceil(mapped.total / mapped.pageSize),
pageIndex: Math.max(mapped.page - 1, 0),
};
state.views = {
...state.views,
[customViewId]: {
...(state.views?.[customViewId] || {}),
paginationMeta,
},
};
},
[t.PAYMENT_MADES_PAGE_SET]: (state, action) => {
const { customViewId, bill_payments, pagination } = action.payload;
@@ -97,10 +78,11 @@ const reducer = createReducer(initialState, {
};
},
[t.PAYMENT_MADES_NUMBER_CHANGED]:(state,action)=>{
[t.PAYMENT_MADES_NUMBER_CHANGED]: (state, action) => {
const { isChanged } = action.payload;
state.nextPaymentNumberChanged = isChanged
state.nextPaymentNumberChanged = isChanged;
},
}
...viewPaginationSetReducer(t.PAYMENT_MADES_PAGINATION_SET),
...createTableQueryReducers('PAYMENT_MADES'),
});
export default createTableQueryReducers('bill_payments', reducer);

View File

@@ -1,12 +1,19 @@
import { createSelector } from '@reduxjs/toolkit';
import { pickItemsFromIds, paginationLocationQuery } from 'store/selectors';
import {
pickItemsFromIds,
paginationLocationQuery,
defaultPaginationMeta,
} from 'store/selectors';
import { transformToObject } from 'utils';
const paymentMadeTableQuery = (state) => state.paymentMades.tableQuery;
const paymentMadesPageSelector = (state, props, query) => {
const paymentMadesPageSelector = (state) => {
const viewId = state.paymentMades.currentViewId;
return state.paymentMades.views?.[viewId]?.pages?.[query.page];
const currentView = state.paymentMades.views?.[viewId];
const currentPageId = currentView?.paginationMeta?.page;
return currentView?.pages?.[currentPageId];
};
const paymentMadesItemsSelector = (state) => state.paymentMades.items;
@@ -16,12 +23,15 @@ const PaymentMadePaginationSelector = (state, props) => {
return state.paymentMades.views?.[viewId];
};
const paymentMadeById = (state, props) => state.paymentMades.items[props.paymentMadeId];
const paymentMadeById = (state, props) =>
state.paymentMades.items[props.paymentMadeId];
const paymentMadeEntries = (state, props) => props.paymentMadeEntries;
const billsItemsSelector = (state, props) => state.bills.items;
const billsPayableByPaymentMadeSelector = (state, props) => state.bills.payable.byBillPayamentId[props.paymentMadeId];
const paymentMadeBillsSelector = (state, props) => state.bills.byBillPayamentId[props.paymentMadeId];
const billsPayableByPaymentMadeSelector = (state, props) =>
state.bills.payable.byBillPayamentId[props.paymentMadeId];
const paymentMadeBillsSelector = (state, props) =>
state.bills.byBillPayamentId[props.paymentMadeId];
export const getPaymentMadeCurrentPageFactory = () =>
createSelector(
@@ -46,8 +56,11 @@ export const getPaymentMadeTableQuery = createSelector(
);
export const getPaymentMadePaginationMetaFactory = () =>
createSelector(PaymentMadePaginationSelector, (Page) => {
return Page?.paginationMeta || {};
createSelector(PaymentMadePaginationSelector, (page) => {
return {
...defaultPaginationMeta(),
...(page?.paginationMeta || {}),
};
});
export const getPaymentMadeByIdFactory = () =>
@@ -55,39 +68,40 @@ export const getPaymentMadeByIdFactory = () =>
return payment_Made;
});
export const getPaymentMadeEntriesDataFactory = () =>
export const getPaymentMadeEntriesDataFactory = () =>
createSelector(
billsItemsSelector,
paymentMadeEntries,
(billsItems, paymentEntries) => {
return Array.isArray(paymentEntries) ?
paymentEntries.map((entry) => ({
...entry, ...(billsItems[entry.bill_id] || {}),
})) : [];
}
return Array.isArray(paymentEntries)
? paymentEntries.map((entry) => ({
...entry,
...(billsItems[entry.bill_id] || {}),
}))
: [];
},
);
export const getPaymentMadeEntriesFactory = () =>
// Retrieve payment made entries.
export const getPaymentMadeEntriesFactory = () =>
createSelector(
billsItemsSelector,
billsPayableByPaymentMadeSelector,
paymentMadeBillsSelector,
paymentMadeById,
(
billsItems,
paymentPayableBillsIds,
paymentMadeBillsIds,
paymentMade,
) => {
(billsItems, paymentPayableBillsIds, paymentMadeBillsIds, paymentMade) => {
const billsIds = [
...(paymentPayableBillsIds || []),
...(paymentMadeBillsIds || []),
];
const bills = pickItemsFromIds(billsItems, billsIds);
const billEntries = transformToObject((paymentMade?.entries || []), 'bill_id');
const billEntries = transformToObject(
paymentMade?.entries || [],
'bill_id',
);
return bills.map((bill) => {
const paymentMadeEntry = (billEntries?.[bill.id] || {});
const paymentMadeEntry = billEntries?.[bill.id] || {};
return {
...bill,
@@ -98,4 +112,4 @@ export const getPaymentMadeEntriesFactory = () =>
};
});
},
);
);

View File

@@ -3,7 +3,7 @@ export default {
PAYMENT_MADE_DELETE: 'PAYMENT_MADE_DELETE',
PAYMENT_MADE_SET: 'PAYMENT_MADE_SET',
PAYMENT_MADE_SET_CURRENT_VIEW: 'PAYMENT_MADE_SET_CURRENT_VIEW',
PAYMENT_MADE_TABLE_QUERIES_ADD: 'PAYMENT_MADE_TABLE_QUERIES_ADD',
PAYMENT_MADES_TABLE_QUERIES_ADD: 'PAYMENT_MADES/TABLE_QUERIES_ADD',
PAYMENT_MADES_TABLE_LOADING: 'PAYMENT_MADES_TABLE_LOADING',
PAYMENT_MADES_PAGE_SET: 'PAYMENT_MADES_PAGE_SET',
PAYMENT_MADES_ITEMS_SET: 'PAYMENT_MADES_ITEMS_SET',

View File

@@ -1,8 +1,10 @@
import { createReducer } from '@reduxjs/toolkit';
import { createTableQueryReducers } from 'store/queryReducers';
import { omit } from 'lodash';
import { journalNumberChangedReducer } from 'store/journalNumber.reducer';
import {
journalNumberChangedReducer,
viewPaginationSetReducer,
createTableQueryReducers,
} from 'store/journalNumber.reducer';
import t from 'store/types';
const initialState = {
@@ -11,7 +13,7 @@ const initialState = {
loading: false,
currentViewId: -1,
tableQuery: {
page_size: 5,
page_size: 12,
page: 1,
},
};
@@ -20,7 +22,7 @@ const defaultPaymentReceive = {
entries: [],
};
const reducer = createReducer(initialState, {
export default createReducer(initialState, {
[t.PAYMENT_RECEIVE_SET]: (state, action) => {
const { id, paymentReceive } = action.payload;
@@ -71,27 +73,6 @@ const reducer = createReducer(initialState, {
}
},
[t.PAYMENT_RECEIVES_PAGINATION_SET]: (state, action) => {
const { pagination, customViewId } = action.payload;
const mapped = {
pageSize: parseInt(pagination.page_size, 10),
page: parseInt(pagination.page, 10),
total: parseInt(pagination.total, 10),
};
const paginationMeta = {
...mapped,
pagesCount: Math.ceil(mapped.total / mapped.pageSize),
pageIndex: Math.max(mapped.page - 1, 0),
};
state.views = {
...state.views,
[customViewId]: {
...(state.views?.[customViewId] || {}),
paginationMeta,
},
};
},
[t.PAYMENT_RECEIVES_PAGE_SET]: (state, action) => {
const { customViewId, payment_receives, pagination } = action.payload;
@@ -109,5 +90,6 @@ const reducer = createReducer(initialState, {
},
...journalNumberChangedReducer(t.PAYMENT_RECEIVE_NUMBER_CHANGED),
...viewPaginationSetReducer(t.PAYMENT_RECEIVES_PAGINATION_SET),
...createTableQueryReducers('PAYMENT_RECEIVES'),
});
export default createTableQueryReducers('payment_receives', reducer);

View File

@@ -1,10 +1,17 @@
import { createSelector } from '@reduxjs/toolkit';
import { pickItemsFromIds, paginationLocationQuery } from 'store/selectors';
import {
pickItemsFromIds,
paginationLocationQuery,
defaultPaginationMeta,
} from 'store/selectors';
import { transformToObject } from 'utils';
const paymentReceivesPageSelector = (state, props, query) => {
const paymentReceivesPageSelector = (state) => {
const viewId = state.paymentReceives.currentViewId;
return state.paymentReceives.views?.[viewId]?.pages?.[query.page];
const viewMeta = state.paymentReceives.views?.[viewId];
const currentPageId = viewMeta?.paginationMeta?.page;
return viewMeta?.pages?.[currentPageId];
};
const paymentReceivesItemsSelector = (state) => state.paymentReceives.items;
@@ -28,17 +35,19 @@ const paymentReceiveInvoicesSelector = (state, props) =>
const paymentReceiveByIdSelector = (state, props) =>
state.paymentReceives.items[props.paymentReceiveId];
// Retrieve payment receive current page results.
export const getPaymentReceiveCurrentPageFactory = () =>
createSelector(
paymentReceivesPageSelector,
paymentReceivesItemsSelector,
(Page, Items) => {
return typeof Page === 'object'
? pickItemsFromIds(Items, Page.ids) || []
(expensesPage, expensesItems) => {
return typeof expensesPage === 'object'
? pickItemsFromIds(expensesItems, expensesPage.ids) || []
: [];
},
);
// Retrieve payment receives table fetch query.
export const getPaymentReceiveTableQuery = createSelector(
paginationLocationQuery,
paymentReceiveTableQuery,
@@ -50,16 +59,22 @@ export const getPaymentReceiveTableQuery = createSelector(
},
);
// Retrieve payment receive pagination meta.
export const getPaymentReceivePaginationMetaFactory = () =>
createSelector(PaymentReceivePaginationSelector, (Page) => {
return Page?.paginationMeta || {};
createSelector(PaymentReceivePaginationSelector, (page) => {
return {
...defaultPaginationMeta(),
...(page?.paginationMeta || {}),
};
});
// Retrieve payment receive based on the passed payment receive id.
export const getPaymentReceiveByIdFactory = () =>
createSelector(payemntReceiveById, (payment_receive) => {
return payment_receive;
});
// Retrieve the payment receive associated invoices.
export const getPaymentReceiveInvoices = createSelector(
payemntReceiveById,
invoicesItemsSelector,
@@ -73,9 +88,7 @@ export const getPaymentReceiveInvoices = createSelector(
},
);
/**
* Retrieve payment receive invoices entries.
*/
// Retrieve payment receive invoices entries.
export const getPaymentReceiveEntriesFactory = () =>
createSelector(
invoicesItemsSelector,

View File

@@ -2,12 +2,11 @@ export default {
PAYMENT_RECEIVE_LIST_SET: 'PAYMENT_RECEIVE_LIST_SET',
PAYMENT_RECEIVE_DELETE: 'PAYMENT_RECEIVE_DELETE',
PAYMENT_RECEIVE_SET: 'PAYMENT_RECEIVE_SET',
PAYMENT_RECEIVE_SET_CURRENT_VIEW: 'PAYMENT_RECEIVE_SET_CURRENT_VIEW',
PAYMENT_RECEIVE_TABLE_QUERIES_ADD: 'PAYMENT_RECEIVE_TABLE_QUERIES_ADD',
PAYMENT_RECEIVES_SET_CURRENT_VIEW: 'PAYMENT_RECEIVES_SET_CURRENT_VIEW',
PAYMENT_RECEIVES_TABLE_QUERIES_ADD: 'PAYMENT_RECEIVES/TABLE_QUERIES_ADD',
PAYMENT_RECEIVES_TABLE_LOADING: 'PAYMENT_RECEIVES_TABLE_LOADING',
PAYMENT_RECEIVES_PAGE_SET: 'PAYMENT_RECEIVES_PAGE_SET',
PAYMENT_RECEIVES_ITEMS_SET: 'PAYMENT_RECEIVES_ITEMS_SET',
PAYMENT_RECEIVES_PAGINATION_SET: 'PAYMENT_RECEIVES_PAGINATION_SET',
PAYMENT_RECEIVE_NUMBER_CHANGED: 'PAYMENT_RECEIVE_NUMBER_CHANGED',
};

View File

@@ -1,21 +1,25 @@
import t from 'store/types';
import { snakeCase } from 'lodash';
import { createReducer } from '@reduxjs/toolkit';
import { createTableQueryReducers } from 'store/queryReducers';
import {
viewPaginationSetReducer,
createTableQueryReducers,
} from 'store/journalNumber.reducer';
const initialState = {
items: {},
views: {},
loading: false,
currentViewId: -1,
// Responsible for data fetch query based on this query.
tableQuery: {
page_size: 5,
page_size: 12,
page: 1,
},
errors: [],
};
const customersReducer = createReducer(initialState, {
export default createReducer(initialState, {
[t.CUSTOMER_SET]: (state, action) => {
const { id, customer } = action.payload;
const _customers = state.items[id] || {};
@@ -65,28 +69,6 @@ const customersReducer = createReducer(initialState, {
state.loading = loading;
},
[t.CUSTOMERS_PAGINATION_SET]: (state, action) => {
const { pagination, customViewId } = action.payload;
const mapped = {
pageSize: parseInt(pagination.page_size, 10),
page: parseInt(pagination.page, 10),
total: parseInt(pagination.total, 10),
};
const paginationMeta = {
...mapped,
pagesCount: Math.ceil(mapped.total / mapped.pageSize),
pageIndex: Math.max(mapped.page - 1, 0),
};
state.views = {
...state.views,
[customViewId]: {
...(state.views?.[customViewId] || {}),
paginationMeta,
},
};
},
[t.CUSTOMERS_BULK_DELETE]: (state, action) => {
const { ids } = action.payload;
const items = { ...state.items };
@@ -98,9 +80,10 @@ const customersReducer = createReducer(initialState, {
});
state.items = items;
},
});
export default createTableQueryReducers('customers', customersReducer);
...viewPaginationSetReducer(t.CUSTOMERS_PAGINATION_SET),
...createTableQueryReducers('CUSTOMERS'),
});
export const getCustomerById = (state, id) => {
return state.customers.items[id];

View File

@@ -1,5 +1,9 @@
import { createSelector } from 'reselect';
import { pickItemsFromIds, paginationLocationQuery } from 'store/selectors';
import {
pickItemsFromIds,
paginationLocationQuery,
defaultPaginationMeta,
} from 'store/selectors';
const customerTableQuery = (state) => state.customers.tableQuery;
@@ -12,9 +16,12 @@ const customersPaginationSelector = (state, props) => {
return state.customers.views?.[viewId];
};
const customerPageSelector = (state, props, query) => {
const customerPageSelector = (state, props) => {
const viewId = state.customers.currentViewId;
return state.customers.views?.[viewId]?.pages?.[query.page];
const currentView = state.customers.views?.[viewId];
const currentPageId = currentView?.paginationMeta?.page;
return currentView?.pages?.[currentPageId];
};
const customersItemsSelector = (state) => state.customers.items;
@@ -49,6 +56,8 @@ export const getCustomersByIdFactory = () =>
export const getCustomerPaginationMetaFactory = () =>
createSelector(customersPaginationSelector, (customerPage) => {
return customerPage?.paginationMeta || {};
return {
...defaultPaginationMeta(),
...(customerPage?.paginationMeta || {}),
};
});

View File

@@ -3,7 +3,7 @@ export default {
CUSTOMER_SET: 'CUSTOMER_SET',
CUSTOMERS_PAGE_SET: 'CUSTOMERS_PAGE_SET',
CUSTOMERS_TABLE_LOADING: 'CUSTOMERS_TABLE_LOADING',
CUSTOMERS_TABLE_QUERIES_ADD: 'CUSTOMERS_TABLE_QUERIES_ADD',
CUSTOMERS_TABLE_QUERIES_ADD: 'CUSTOMERS/TABLE_QUERIES_ADD',
CUSTOMER_DELETE: 'CUSTOMER_DELETE',
CUSTOMERS_BULK_DELETE: 'CUSTOMERS_BULK_DELETE',
CUSTOMERS_PAGINATION_SET: 'CUSTOMERS_PAGINATION_SET',

View File

@@ -1,5 +1,8 @@
import { createReducer } from '@reduxjs/toolkit';
import { createTableQueryReducers } from 'store/queryReducers';
import {
viewPaginationSetReducer,
createTableQueryReducers,
} from 'store/journalNumber.reducer';
import t from 'store/types';
@@ -7,6 +10,7 @@ const initialState = {
items: {},
views: {},
loading: false,
//
tableQuery: {
page_size: 12,
page: 1,
@@ -18,7 +22,7 @@ const defaultExpense = {
categories: [],
};
const reducer = createReducer(initialState, {
export default createReducer(initialState, {
[t.EXPENSE_SET]: (state, action) => {
const { id, expense } = action.payload;
const oldExpense = state.items[id] || {};
@@ -66,29 +70,6 @@ const reducer = createReducer(initialState, {
};
},
[t.EXPENSES_PAGINATION_SET]: (state, action) => {
const { pagination, customViewId } = action.payload;
const mapped = {
pageSize: parseInt(pagination.pageSize, 10),
page: parseInt(pagination.page, 10),
total: parseInt(pagination.total, 10),
};
const paginationMeta = {
...mapped,
pagesCount: Math.ceil(mapped.total / mapped.pageSize),
pageIndex: Math.max(mapped.page - 1, 0),
};
state.views = {
...state.views,
[customViewId]: {
...(state.views?.[customViewId] || {}),
paginationMeta,
},
};
},
[t.EXPENSES_TABLE_LOADING]: (state, action) => {
const { loading } = action.payload;
state.loading = loading;
@@ -117,9 +98,10 @@ const reducer = createReducer(initialState, {
});
state.items = items;
},
});
export default createTableQueryReducers('expenses', reducer);
...viewPaginationSetReducer(t.EXPENSES_PAGINATION_SET),
...createTableQueryReducers('EXPENSES'),
});
export const getExpenseById = (state, id) => {
return state.expenses.items[id];

View File

@@ -1,8 +1,29 @@
import { createSelector } from '@reduxjs/toolkit';
import { pickItemsFromIds, paginationLocationQuery } from 'store/selectors';
const expensesTableQuery = state => state.expenses.tableQuery;
const expensesTableQuery = (state) => state.expenses.tableQuery;
const getPageExpensesQuery = (state, props) => {
const currentPageId = state.expenses.views?.[props.viewId]?.paginationMeta?.page;
return currentPageId || 0;
};
const expensesPageSelector = (state, props, query) => {
const viewId = state.expenses.currentViewId;
const currentPageId = getPageExpensesQuery(state, { viewId });
return state.expenses.views?.[viewId]?.pages?.[currentPageId];
};
const expensesItemsSelector = (state) => state.expenses.items;
const expenseByIdSelector = (state, props) => state.expenses.items[props.expenseId];
const manualJournalsPaginationSelector = (state, props) => {
const viewId = state.expenses.currentViewId;
return state.expenses.views?.[viewId];
};
// Retrive expenses table query.
export const getExpensesTableQuery = createSelector(
paginationLocationQuery,
expensesTableQuery,
@@ -14,13 +35,7 @@ export const getExpensesTableQuery = createSelector(
},
);
const expensesPageSelector = (state, props, query) => {
const viewId = state.expenses.currentViewId;
return state.expenses.views?.[viewId]?.pages?.[query.page];
};
const expensesItemsSelector = (state) => state.expenses.items;
// Retrieve expenses results of the current page.
export const getExpensesCurrentPageFactory = () => createSelector(
expensesPageSelector,
expensesItemsSelector,
@@ -31,8 +46,7 @@ export const getExpensesCurrentPageFactory = () => createSelector(
},
);
const expenseByIdSelector = (state, props) => state.expenses.items[props.expenseId];
// Retrieve specific expense by the passed expense id.
export const getExpenseByIdFactory = () => createSelector(
expenseByIdSelector,
(expense) => {
@@ -40,11 +54,7 @@ export const getExpenseByIdFactory = () => createSelector(
}
);
const manualJournalsPaginationSelector = (state, props) => {
const viewId = state.expenses.currentViewId;
return state.expenses.views?.[viewId];
};
// Retrieve expenses pagination meta.
export const getExpensesPaginationMetaFactory = () => createSelector(
manualJournalsPaginationSelector,
(expensesPage) => {

View File

@@ -4,7 +4,7 @@ export default {
EXPENSE_DELETE: 'EXPENSE_DELETE',
EXPENSES_BULK_DELETE: 'EXPENSES_BULK_DELETE',
EXPENSES_SET_CURRENT_VIEW: 'EXPENSES_SET_CURRENT_VIEW',
EXPENSES_TABLE_QUERIES_ADD:'EXPENSES_TABLE_QUERIES_ADD',
EXPENSES_TABLE_QUERIES_ADD:'EXPENSES/TABLE_QUERIES_ADD',
EXPENSE_PUBLISH: 'EXPENSE_PUBLISH',
EXPENSES_TABLE_LOADING: 'EXPENSES_TABLE_LOADING',
EXPENSES_PAGE_SET: 'EXPENSES_PAGE_SET',

View File

@@ -30,13 +30,17 @@ export const fetchItems = ({ query }) => {
customViewId: response.data?.filter_meta?.view?.custom_view_id,
paginationMeta: response.data.pagination,
});
dispatch({
type: t.ITEMS_PAGINATION_SET,
payload: {
pagination: response.data.pagination,
customViewId: response.data.customViewId || -1,
}
})
dispatch({
type: t.ITEMS_TABLE_LOADING,
payload: { loading: false },
});
dispatch({
type: t.SET_DASHBOARD_REQUEST_COMPLETED,
});
resolve(response);
})
.catch((error) => {

View File

@@ -1,7 +1,10 @@
import t from 'store/types';
import { createReducer } from '@reduxjs/toolkit';
import { getItemsViewPages } from 'store/items/items.selectors';
import { createTableQueryReducers } from 'store/queryReducers';
import {
viewPaginationSetReducer,
createTableQueryReducers,
} from 'store/journalNumber.reducer';
const initialState = {
items: {},
@@ -9,12 +12,15 @@ const initialState = {
itemsRelation: {},
currentPage: 1,
currentViewId: -1,
tableQuery: {},
bulkActions: {},
loading: false,
tableQuery: {
page_size: 12,
page: 1,
},
};
const itemsReducer = createReducer(initialState, {
export default createReducer(initialState, {
[t.ITEMS_SET]: (state, action) => {
const _items = {};
@@ -111,9 +117,10 @@ const itemsReducer = createReducer(initialState, {
});
state.items = items;
},
});
export default createTableQueryReducers('items', itemsReducer);
...viewPaginationSetReducer(t.ITEMS_PAGINATION_SET),
...createTableQueryReducers('ITEMS'),
});
export const getItemById = (state, id) => {
return state.items.items[id];

View File

@@ -2,12 +2,13 @@ export default {
ITEMS_SET: 'ITEMS_SET',
ITEM_SET: 'ITEM_SET',
ITEMS_PAGE_SET: 'ITEMS_PAGE_SET',
ITEMS_PAGINATION_SET: 'ITEMS_PAGINATION_SET',
ITEM_DELETE: 'ITEM_DELETE',
ITEM_BULK_ACTION_ADD: 'ITEM_BULK_ACTION_ADD',
ITEM_BULK_ACTION_REMOVE: 'ITEM_BULK_ACTION_REMOVE',
ITEMS_TABLE_QUERY_SET: 'ITEMS_TABLE_QUERY_SET',
ITEMS_TABLE_QUERIES_ADD: 'ITEMS_TABLE_QUERIES_ADD',
ITEMS_TABLE_QUERY_SET: 'ITEMS/TABLE_QUERY_SET',
ITEMS_TABLE_QUERIES_ADD: 'ITEMS/TABLE_QUERIES_ADD',
ITEMS_TABLE_LOADING: 'ITEMS_TABLE_LOADING',
ITEMS_SET_CURRENT_VIEW: 'ITEMS_SET_CURRENT_VIEW',

View File

@@ -4,4 +4,44 @@ export const journalNumberChangedReducer = (type) => ({
const { isChanged } = action.payload;
state.journalNumberChanged = isChanged;
},
});
export const viewPaginationSetReducer = (type) => ({
[type]: (state, action) => {
const { pagination, customViewId } = action.payload;
const mapped = {
pageSize: parseInt(pagination.page_size, 10),
page: parseInt(pagination.page, 10),
total: parseInt(pagination.total, 10),
};
const paginationMeta = {
...mapped,
pagesCount: Math.ceil(mapped.total / mapped.pageSize),
pageIndex: Math.max(mapped.page - 1, 0),
};
state.views = {
...state.views,
[customViewId]: {
...(state.views?.[customViewId] || {}),
paginationMeta,
},
};
},
});
export const createTableQueryReducers = (RESOURCE_NAME) => ({
[`${RESOURCE_NAME}/TABLE_QUERY_SET`]: (state, action) => {
state.tableQuery = {
...state.tableQuery,
[state.key]: action.payload.value,
};
},
[`${RESOURCE_NAME}/TABLE_QUERIES_ADD`]: (state, action) => {
state.tableQuery = {
...state.tableQuery,
...action.payload.queries,
};
},
});

View File

@@ -138,7 +138,7 @@ export const fetchManualJournalsTable = ({ query } = {}) => {
manual_journals: response.data.manual_journals,
});
dispatch({
type: 'MANUAL_JOURNALS_PAGINATION_SET',
type: t.MANUAL_JOURNALS_PAGINATION_SET,
payload: {
pagination: response.data.pagination,
customViewId:

View File

@@ -1,8 +1,11 @@
import t from 'store/types';
import { createReducer } from '@reduxjs/toolkit';
import { createTableQueryReducers } from 'store/queryReducers';
import { omit } from 'lodash';
import { journalNumberChangedReducer } from 'store/journalNumber.reducer';
import {
journalNumberChangedReducer,
viewPaginationSetReducer,
createTableQueryReducers,
} from 'store/journalNumber.reducer';
const initialState = {
items: {},
@@ -10,7 +13,7 @@ const initialState = {
loading: false,
currentViewId: -1,
tableQuery: {
page_size: 6,
page_size: 12,
page: 1,
},
paginationMeta: {
@@ -23,8 +26,7 @@ const defaultJournal = {
entries: [],
};
const reducer = createReducer(initialState, {
export default createReducer(initialState, {
[t.MANUAL_JOURNAL_SET]: (state, action) => {
const { id, manualJournal } = action.payload;
state.items[id] = { ...defaultJournal, ...manualJournal };
@@ -32,7 +34,7 @@ const reducer = createReducer(initialState, {
[t.MANUAL_JOURNAL_PUBLISH]: (state, action) => {
const { id } = action.payload;
const item = state.items[id] || {}
const item = state.items[id] || {};
state.items[id] = { ...item, status: 1 };
},
@@ -57,15 +59,15 @@ const reducer = createReducer(initialState, {
const viewId = customViewId || -1;
const view = state.views[viewId] || {};
state.views[viewId] = {
...view,
pages: {
...(state.views?.[viewId]?.pages || {}),
[pagination.page]: {
ids: (manualJournals.map((i) => i.id)),
ids: manualJournals.map((i) => i.id),
},
}
},
};
},
@@ -95,34 +97,11 @@ const reducer = createReducer(initialState, {
state.items = items;
},
[t.MANUAL_JOURNALS_PAGINATION_SET]: (state, action) => {
const { pagination, customViewId } = action.payload;
const mapped = {
pageSize: parseInt(pagination.pageSize, 10),
page: parseInt(pagination.page, 10),
total: parseInt(pagination.total, 10),
};
const paginationMeta = {
...mapped,
pagesCount: Math.ceil(mapped.total / mapped.pageSize),
pageIndex: Math.max(mapped.page - 1, 0),
};
state.views = {
...state.views,
[customViewId]: {
...(state.views?.[customViewId] || {}),
paginationMeta,
},
};
},
...viewPaginationSetReducer(t.MANUAL_JOURNALS_PAGINATION_SET),
...journalNumberChangedReducer(t.MANUAL_JOURNAL_NUMBER_CHANGED),
...createTableQueryReducers('MANUAL_JOURNALS'),
});
export default createTableQueryReducers('manual_journals', reducer);
export const getManualJournal = (state, id) => {
return state.manualJournals.items[id];
}
};

View File

@@ -1,9 +1,12 @@
import { createSelector } from 'reselect';
import { pickItemsFromIds, paginationLocationQuery } from 'store/selectors';
import { pickItemsFromIds, paginationLocationQuery, defaultPaginationMeta } from 'store/selectors';
const manualJournalsPageSelector = (state, props, query) => {
const manualJournalsPageSelector = (state) => {
const viewId = state.manualJournals.currentViewId;
return state.manualJournals.views?.[viewId]?.pages?.[query.page];
const currentView = state.manualJournals.views?.[viewId];
const currentPageId = currentView?.paginationMeta?.page;
return currentView?.pages?.[currentPageId];
};
const manualJournalsPaginationSelector = (state, props) => {
@@ -15,6 +18,7 @@ const manualJournalsTableQuery = (state) => state.manualJournals.tableQuery;
const manualJournalsDataSelector = (state) => state.manualJournals.items;
// Retrieve manual jounral current page results.
export const getManualJournalsItems = createSelector(
manualJournalsPageSelector,
manualJournalsDataSelector,
@@ -25,13 +29,18 @@ export const getManualJournalsItems = createSelector(
},
);
// Retrieve manual journals pagination meta.
export const getManualJournalsPagination = createSelector(
manualJournalsPaginationSelector,
(manualJournalsPage) => {
return manualJournalsPage?.paginationMeta || {};
return {
...defaultPaginationMeta(),
...(manualJournalsPage?.paginationMeta || {}),
};
},
);
// Retrieve manual jouranls table query.
export const getManualJournalsTableQuery = createSelector(
paginationLocationQuery,
manualJournalsTableQuery,

View File

@@ -6,7 +6,7 @@ export default {
MANUAL_JOURNALS_PAGE_SET: 'MANUAL_JOURNALS_PAGE_SET',
MANUAL_JOURNALS_ITEMS_SET: 'MANUAL_JOURNALS_ITEMS_SET',
MANUAL_JOURNALS_SET_CURRENT_VIEW: 'MANUAL_JOURNALS_SET_CURRENT_VIEW',
MANUAL_JOURNALS_TABLE_QUERIES_ADD: 'MANUAL_JOURNALS_TABLE_QUERIES_ADD',
MANUAL_JOURNALS_TABLE_QUERIES_ADD: 'MANUAL_JOURNALS/TABLE_QUERIES_ADD',
MANUAL_JOURNAL_REMOVE: 'MANUAL_JOURNAL_REMOVE',
MANUAL_JOURNAL_PUBLISH: 'MANUAL_JOURNAL_PUBLISH',

View File

@@ -1,27 +0,0 @@
const pages = (pages, action) => {
const { type, items, meta } = action;
switch(type) {
case REQUEST_PAGE:
return {
...pages,
[meta.currentPage]: {
...pages[meta.currentPage],
ids: [],
fetching: true,
},
};
case RECEIVE_PAGE:
return {
...pages,
[meta.currentPage]: {
...pages[meta.currentPage],
ids: items.map(i => i.id),
fetching: false,
},
};
}
};

View File

@@ -6,7 +6,7 @@ export const createTableQueryReducers =
const RESOURCE_NAME = resourceName.toUpperCase();
switch (action.type) {
case `${RESOURCE_NAME}_TABLE_QUERY_SET`:
case `${RESOURCE_NAME}/TABLE_QUERY_SET`:
return {
...state,
tableQuery: {
@@ -14,15 +14,11 @@ export const createTableQueryReducers =
[state.key]: state.value,
}
};
case `${RESOURCE_NAME}_TABLE_QUERIES_ADD`:
case `${RESOURCE_NAME}/TABLE_QUERIES_ADD`:
return {
...state,
tableQuery: {
...state.tableQuery,
...action.queries
},
};
default:
return reducer(state, action);
}
}
}

View File

@@ -1,14 +1,13 @@
import { createReducer } from '@reduxjs/toolkit';
import { createTableQueryReducers } from 'store/queryReducers';
import t from 'store/types';
import { journalNumberChangedReducer } from 'store/journalNumber.reducer';
import { journalNumberChangedReducer, createTableQueryReducers } from 'store/journalNumber.reducer';
const initialState = {
items: {},
views: {},
loading: false,
tableQuery: {
page_size: 5,
page_size: 12,
page: 1,
},
currentViewId: -1,
@@ -18,7 +17,7 @@ const defaultReceipt = {
entries: [],
};
const reducer = createReducer(initialState, {
export default createReducer(initialState, {
[t.RECEIPT_SET]: (state, action) => {
const { id, sale_receipt } = action.payload;
const _receipt = state.items[id] || {};
@@ -94,10 +93,9 @@ const reducer = createReducer(initialState, {
};
},
...journalNumberChangedReducer(t.RECEIPT_NUMBER_CHANGED),
...createTableQueryReducers('RECEIPTS'),
});
export default createTableQueryReducers('sales_receipts', reducer);
export const getReceiptById = (state, id) => {
return state.receipts.items[id];
};

View File

@@ -1,9 +1,12 @@
import { createSelector } from '@reduxjs/toolkit';
import { pickItemsFromIds, paginationLocationQuery } from 'store/selectors';
const receiptsPageSelector = (state, props, query) => {
const receiptsPageSelector = (state) => {
const viewId = state.salesReceipts.currentViewId;
return state.salesReceipts.views?.[viewId]?.pages?.[query.page];
const currentView = state.salesReceipts.views?.[viewId];
const currentPageId = currentView?.paginationMeta?.page;
return currentView?.pages?.[currentPageId];
};
const receiptsPaginationSelector = (state, props) => {
@@ -17,7 +20,7 @@ const receiptTableQuery = (state) => state.salesReceipts.tableQuery;
const receiptByIdSelector = (state, props) => state.salesReceipts.items[props.receiptId];
// Retrieve current page sale receipts results.
export const getReceiptCurrentPageFactory = () =>
createSelector(
receiptsPageSelector,
@@ -29,6 +32,7 @@ export const getReceiptCurrentPageFactory = () =>
},
);
// Retrieve receipts table query.
export const getReceiptsTableQueryFactory = () =>
createSelector(
paginationLocationQuery,
@@ -41,11 +45,13 @@ export const getReceiptsTableQueryFactory = () =>
},
);
// Retrieve specific receipts by the passed receipt id.
export const getReceiptByIdFactory = () =>
createSelector(receiptByIdSelector, (receipt) => {
return receipt;
});
// Retrieve receipts pagination meta.
export const getReceiptsPaginationMetaFactory = () =>
createSelector(receiptsPaginationSelector, (receiptPage) => {
return receiptPage?.paginationMeta || {};

View File

@@ -4,7 +4,7 @@ export default {
RECEIPTS_LIST_SET: 'RECEIPTS_LIST_SET',
RECEIPT_SET: 'RECEIPT_SET',
RECEIPTS_SET_CURRENT_VIEW: 'RECEIPTS_SET_CURRENT_VIEW',
RECEIPTS_TABLE_QUERIES_ADD: 'RECEIPTS_TABLE_QUERIES_ADD',
RECEIPTS_TABLE_QUERIES_ADD: 'RECEIPTS/TABLE_QUERIES_ADD',
RECEIPTS_TABLE_LOADING: 'RECEIPTS_TABLE_LOADING',
RECEIPTS_PAGINATION_SET: 'RECEIPTS_PAGINATION_SET',
RECEIPTS_PAGE_SET: 'RECEIPTS_PAGE_SET',

View File

@@ -47,4 +47,12 @@ export const paginationLocationQuery = (state, props) => {
parseInt(v, 10),
)
: null;
}
}
export const defaultPaginationMeta = () => ({
pageSize: 0,
page: 1,
total: 0,
pagesCount: 0,
pageIndex: 0,
})

View File

@@ -84,9 +84,19 @@
font-size: 13px;
border-radius: 3px;
color: #666;
padding-right: 8px;
padding-right: 14px;
padding-left: 8px;
}
&::after{
border-left-width: 3px;
border-right-width: 3px;
border-top-width: 4px;
margin-right: 6px;
}
}
}
&__goto-control{