refactoring: expenses landing list.

refactoring: customers landing list.
refactoring: vendors landing list.
refactoring: manual journals landing list.
This commit is contained in:
a.bouhuolia
2021-02-10 18:35:19 +02:00
parent 6e10ed0721
commit c68b4ca9ba
170 changed files with 2835 additions and 4430 deletions

View File

@@ -13,18 +13,14 @@ import {
import classNames from 'classnames';
import { useHistory } from 'react-router-dom';
import { FormattedMessage as T } from 'react-intl';
import { connect } from 'react-redux';
import { useManualJournalsContext } from 'containers/Accounting/ManualJournalsListProvider';
import { useManualJournalsContext } from './ManualJournalsListProvider';
import DashboardActionsBar from 'components/Dashboard/DashboardActionsBar';
import withDialogActions from 'containers/Dialog/withDialogActions';
import { If, DashboardActionViewsList } from 'components';
import withResourceDetail from 'containers/Resources/withResourceDetails';
import withManualJournals from 'containers/Accounting/withManualJournals';
import withManualJournalsActions from 'containers/Accounting/withManualJournalsActions';
import withManualJournalsActions from './withManualJournalsActions';
import { compose } from 'utils';
/**
@@ -32,9 +28,12 @@ import { compose } from 'utils';
*/
function ManualJournalActionsBar({
// #withManualJournalsActions
addManualJournalsTableQueries,
setManualJournalsTableState,
}) {
// History context.
const history = useHistory();
// Manual journals context.
const { journalsViews } = useManualJournalsContext();
// Handle click a new manual journal.
@@ -44,13 +43,13 @@ function ManualJournalActionsBar({
// Handle delete button click.
const handleBulkDelete = () => {
};
// Handle tab change.
const handleTabChange = (viewId) => {
addManualJournalsTableQueries({
custom_view_id: viewId.id || null,
setManualJournalsTableState({
customViewid: viewId.id || null,
});
};
@@ -115,20 +114,7 @@ function ManualJournalActionsBar({
);
}
const mapStateToProps = (state, props) => ({
resourceName: 'manual_journals',
});
const withManualJournalsActionsBar = connect(mapStateToProps);
export default compose(
withManualJournalsActionsBar,
withDialogActions,
withResourceDetail(({ resourceFields }) => ({
resourceFields,
})),
withManualJournals(({ manualJournalsViews }) => ({
manualJournalsViews,
})),
withManualJournalsActions,
)(ManualJournalActionsBar);

View File

@@ -0,0 +1,118 @@
import React from 'react';
import classNames from 'classnames';
import { DataTable, Choose } from 'components';
import { CLASSES } from 'common/classes';
import ManualJournalsEmptyStatus from './ManualJournalsEmptyStatus';
import TableSkeletonRows from 'components/Datatable/TableSkeletonRows';
import TableSkeletonHeader from 'components/Datatable/TableHeaderSkeleton';
import withManualJournalsActions from './withManualJournalsActions';
import withAlertsActions from 'containers/Alert/withAlertActions';
import { useManualJournalsContext } from './ManualJournalsListProvider';
import { useManualJournalsColumns } from './utils';
import { ActionsMenu } from './components';
import { compose } from 'utils';
/**
* Manual journals data-table.
*/
function ManualJournalsDataTable({
// #withManualJournalsActions
setManualJournalsTableState,
// #withAlertsActions
openAlert,
// #ownProps
onSelectedRowsChange,
}) {
// Manual journals context.
const {
manualJournals,
pagination,
isManualJournalsLoading,
isManualJournalsFetching,
isEmptyStatus
} = useManualJournalsContext();
// Manual journals columns.
const columns = useManualJournalsColumns();
// Handles the journal publish action.
const handlePublishJournal = ({ id }) => {
openAlert('journal-publish', { manualJournalId: id })
};
// Handle the journal edit action.
const handleEditJournal = ({ id }) => {
};
// Handle the journal delete action.
const handleDeleteJournal = ({ id }) => {
openAlert('journal-delete', { manualJournalId: id });
};
// Handle fetch data once the page index, size or sort by of the table change.
const handleFetchData = React.useCallback(
({ pageSize, pageIndex, sortBy }) => {
setManualJournalsTableState({
pageIndex,
pageSize,
sortBy,
});
},
[setManualJournalsTableState],
);
return (
<div className={classNames(CLASSES.DASHBOARD_DATATABLE)}>
<Choose>
<Choose.When condition={isEmptyStatus}>
<ManualJournalsEmptyStatus />
</Choose.When>
<Choose.Otherwise>
<DataTable
noInitialFetch={true}
columns={columns}
data={manualJournals}
manualSortBy={true}
selectionColumn={true}
expandable={true}
sticky={true}
loading={isManualJournalsLoading}
headerLoading={isManualJournalsLoading}
progressBarLoading={isManualJournalsFetching}
pagesCount={pagination.pagesCount}
pagination={true}
autoResetSortBy={false}
autoResetPage={false}
TableLoadingRenderer={TableSkeletonRows}
TableHeaderSkeletonRenderer={TableSkeletonHeader}
ContextMenu={ActionsMenu}
onFetchData={handleFetchData}
payload={{
onDelete: handleDeleteJournal,
onPublish: handlePublishJournal
}}
/>
</Choose.Otherwise>
</Choose>
</div>
);
}
export default compose(
withManualJournalsActions,
withAlertsActions
)(ManualJournalsDataTable);

View File

@@ -0,0 +1,56 @@
import React, { useEffect } from 'react';
import { useIntl } from 'react-intl';
import DashboardPageContent from 'components/Dashboard/DashboardPageContent';
import { ManualJournalsListProvider } from './ManualJournalsListProvider';
import ManualJournalsAlerts from './ManualJournalsAlerts';
import ManualJournalsViewTabs from './ManualJournalsViewTabs';
import ManualJournalsDataTable from './ManualJournalsDataTable';
import ManualJournalsActionsBar from './ManualJournalActionsBar';
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
import withManualJournals from './withManualJournals';
import { transformTableStateToQuery, compose } from 'utils';
import 'style/pages/ManualJournal/List.scss';
/**
* Manual journals table.
*/
function ManualJournalsTable({
// #withDashboardActions
changePageTitle,
// #withManualJournals
journalsTableState,
}) {
const { formatMessage } = useIntl();
// Handle update the page title.
useEffect(() => {
changePageTitle(formatMessage({ id: 'manual_journals' }));
}, [changePageTitle, formatMessage]);
return (
<ManualJournalsListProvider
query={transformTableStateToQuery(journalsTableState)}
>
<ManualJournalsActionsBar />
<DashboardPageContent>
<ManualJournalsViewTabs />
<ManualJournalsDataTable />
<ManualJournalsAlerts />
</DashboardPageContent>
</ManualJournalsListProvider>
);
}
export default compose(
withDashboardActions,
withManualJournals(({ manualJournalsTableState }) => ({
journalsTableState: manualJournalsTableState,
})),
)(ManualJournalsTable);

View File

@@ -1,28 +1,39 @@
import React, { createContext } from 'react';
import DashboardInsider from 'components/Dashboard/DashboardInsider';
import { useResourceViews, useJournals } from 'hooks/query';
import { isTableEmptyStatus } from 'utils';
const ManualJournalsContext = createContext();
function ManualJournalsListProvider({ query, ...props }) {
// Fetches accounts resource views and fields.
const { data: journalsViews, isFetching: isViewsLoading } = useResourceViews(
const { data: journalsViews, isLoading: isViewsLoading } = useResourceViews(
'manual_journals',
);
// Fetches the manual journals transactions with pagination meta.
const {
data: { manualJournals },
isFetching: isManualJournalsLoading,
} = useJournals(query);
data: { manualJournals, pagination, filterMeta },
isLoading: isManualJournalsLoading,
isFetching: isManualJournalsFetching
} = useJournals(query, { keepPreviousData: true });
// Detarmines the datatable empty status.
const isEmptyStatus = isTableEmptyStatus({
data: manualJournals, pagination, filterMeta,
}) && !isManualJournalsFetching;
// Global state.
const state = {
manualJournals,
pagination,
journalsViews,
isManualJournalsLoading,
isManualJournalsFetching,
isViewsLoading,
isEmptyStatus
};
return (

View File

@@ -8,17 +8,21 @@ import { DashboardViewsTabs } from 'components';
import { useManualJournalsContext } from './ManualJournalsListProvider';
import withManualJournalsActions from './withManualJournalsActions';
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
import withManualJournals from './withManualJournals';
import { compose, saveInvoke } from 'utils';
import { compose } from 'utils';
/**
* Manual journal views tabs.
*/
function ManualJournalsViewTabs({
// #withManualJournalsActions
addManualJournalsTableQueries,
setManualJournalsTableState,
// #withManualJournals
journalsTableState
}) {
const { custom_view_id: customViewId } = useParams();
// Manual journals context.
const { journalsViews } = useManualJournalsContext();
const tabs = journalsViews.map((view) => ({
@@ -27,9 +31,10 @@ function ManualJournalsViewTabs({
const handleClickNewView = () => {};
// Handles the tab change.
const handleTabChange = (viewId) => {
addManualJournalsTableQueries({
custom_view_id: viewId || null,
setManualJournalsTableState({
customViewId: viewId || null,
});
};
@@ -38,7 +43,7 @@ function ManualJournalsViewTabs({
<NavbarGroup align={Alignment.LEFT}>
<DashboardViewsTabs
resourceName={'manual-journals'}
initialViewId={customViewId}
customViewId={journalsTableState.customViewId}
tabs={tabs}
onChange={handleTabChange}
onNewViewTabClick={handleClickNewView}
@@ -51,4 +56,7 @@ function ManualJournalsViewTabs({
export default compose(
withManualJournalsActions,
withDashboardActions,
withManualJournals(({ manualJournalsTableState }) => ({
journalsTableState: manualJournalsTableState,
})),
)(ManualJournalsViewTabs);

View File

@@ -6,16 +6,20 @@ import {
Position,
Tag,
Button,
MenuItem,
Menu,
MenuDivider,
Popover,
} from '@blueprintjs/core';
import { FormattedMessage as T } from 'react-intl';
import moment from 'moment';
import { Choose, Money, If, Icon, Hint } from 'components';
import { Choose, Money, If, Icon } from 'components';
import { safeCallback } from 'utils';
import { formatMessage } from 'services/intl';
import withAccountDetails from 'containers/Accounts/withAccountDetail';
import { compose } from 'utils';
// Amount accessor.
/**
* Amount accessor.
*/
export const AmountAccessor = (r) => (
<Tooltip
content={<AmountPopoverContent journalEntries={r.entries} />}
@@ -26,15 +30,13 @@ export const AmountAccessor = (r) => (
</Tooltip>
);
const AmountPopoverContentLineRender = ({
journalEntry,
accountId,
// #withAccountDetail
account,
}) => {
/**
* Amount popover content line.
*/
export const AmountPopoverContentLine = ({ journalEntry }) => {
const isCredit = !!journalEntry.credit;
const isDebit = !!journalEntry.debit;
const { account } = journalEntry;
return (
<Choose>
@@ -55,10 +57,9 @@ const AmountPopoverContentLineRender = ({
);
};
const AmountPopoverContentLine = compose(withAccountDetails)(
AmountPopoverContentLineRender,
);
/**
* Amount popover content.
*/
export function AmountPopoverContent({ journalEntries }) {
const journalLinesProps = journalEntries.map((journalEntry) => ({
journalEntry,
@@ -78,7 +79,7 @@ export function AmountPopoverContent({ journalEntries }) {
}
/**
* publish column accessor.
* Publish column accessor.
*/
export const StatusAccessor = (row) => {
return (
@@ -123,79 +124,52 @@ export function NoteAccessor(row) {
);
}
// Contact header cell.
export function ContactHeaderCell() {
/**
* Table actions cell.
*/
export const ActionsCell = (props) => {
return (
<>
<T id={'contact'} />
<Hint
content={<T id={'contact_column_hint'} />}
position={Position.LEFT_BOTTOM}
/>
</>
<Popover
content={<ActionsMenu {...props} />}
position={Position.RIGHT_BOTTOM}
>
<Button icon={<Icon icon="more-h-16" iconSize={16} />} />
</Popover>
);
}
};
// Actions cell renderer.
export const ActionsCellRenderer = ({
row: { index },
column: { id },
cell: { value: initialValue },
data,
payload,
/**
* Actions menu of the table.
*/
export const ActionsMenu = ({
payload: { onPublish, onEdit, onDelete },
row: { original },
}) => {
if (data.length <= index + 1) {
return '';
}
const onClickRemoveRole = () => {
payload.removeRow(index);
};
return (
<Tooltip content={<T id={'remove_the_line'} />} position={Position.LEFT}>
<Button
icon={<Icon icon="times-circle" iconSize={14} />}
iconSize={14}
className="ml2"
minimal={true}
intent={Intent.DANGER}
onClick={onClickRemoveRole}
<Menu>
<MenuItem
icon={<Icon icon="reader-18" />}
text={formatMessage({ id: 'view_details' })}
/>
</Tooltip>
<MenuDivider />
<If condition={!original.is_published}>
<MenuItem
icon={<Icon icon="arrow-to-top" />}
text={formatMessage({ id: 'publish_journal' })}
onClick={safeCallback(onPublish, original)}
/>
</If>
<MenuItem
icon={<Icon icon="pen-18" />}
text={formatMessage({ id: 'edit_journal' })}
onClick={safeCallback(onEdit, original)}
/>
<MenuItem
text={formatMessage({ id: 'delete_journal' })}
icon={<Icon icon="trash-16" iconSize={16} />}
intent={Intent.DANGER}
onClick={safeCallback(onDelete, original)}
/>
</Menu>
);
};
// Total text cell renderer.
export const TotalAccountCellRenderer = (chainedComponent) => (props) => {
if (props.data.length === props.row.index + 1) {
return <span>{'Total USD'}</span>;
}
return chainedComponent(props);
};
// Total credit/debit cell renderer.
export const TotalCreditDebitCellRenderer = (chainedComponent, type) => (
props,
) => {
if (props.data.length === props.row.index + 1) {
const total = props.data.reduce((total, entry) => {
const amount = parseInt(entry[type], 10);
const computed = amount ? total + amount : total;
return computed;
}, 0);
return (
<span>
<Money amount={total} currency={'USD'} />
</span>
);
}
return chainedComponent(props);
};
export const NoteCellRenderer = (chainedComponent) => (props) => {
if (props.data.length === props.row.index + 1) {
return '';
}
return chainedComponent(props);
};

View File

@@ -0,0 +1,79 @@
import React from 'react';
import { formatMessage } from 'services/intl';
import moment from 'moment';
import {
NoteAccessor,
StatusAccessor,
DateAccessor,
AmountAccessor,
ActionsCell,
} from './components';
/**
* Retrieve the manual journals columns.
*/
export const useManualJournalsColumns = () => {
return React.useMemo(
() => [
{
id: 'date',
Header: formatMessage({ id: 'date' }),
accessor: DateAccessor,
width: 115,
className: 'date',
},
{
id: 'amount',
Header: formatMessage({ id: 'amount' }),
accessor: AmountAccessor,
className: 'amount',
width: 115,
},
{
id: 'journal_number',
Header: formatMessage({ id: 'journal_no' }),
accessor: (row) => `#${row.journal_number}`,
className: 'journal_number',
width: 100,
},
{
id: 'journal_type',
Header: formatMessage({ id: 'journal_type' }),
accessor: 'journal_type',
width: 110,
className: 'journal_type',
},
{
id: 'publish',
Header: formatMessage({ id: 'publish' }),
accessor: (row) => StatusAccessor(row),
width: 95,
className: 'publish',
},
{
id: 'note',
Header: formatMessage({ id: 'note' }),
accessor: NoteAccessor,
disableSorting: true,
width: 85,
className: 'note',
},
{
id: 'created_at',
Header: formatMessage({ id: 'created_at' }),
accessor: (r) => moment(r.created_at).format('YYYY MMM DD'),
width: 125,
className: 'created_at',
},
{
id: 'actions',
Header: '',
Cell: ActionsCell,
className: 'actions',
width: 50,
disableResizing: true,
},
],
[],
);
};

View File

@@ -0,0 +1,16 @@
import { connect } from 'react-redux';
import {
getManualJournalsTableStateFactory
} from 'store/manualJournals/manualJournals.selectors';
export default (mapState) => {
const getJournalsTableQuery = getManualJournalsTableStateFactory();
const mapStateToProps = (state, props) => {
const mapped = {
manualJournalsTableState: getJournalsTableQuery(state, props),
};
return mapState ? mapState(mapped, state, props) : mapped;
};
return connect(mapStateToProps);
};

View File

@@ -0,0 +1,11 @@
import { connect } from 'react-redux';
import {
setManualJournalsTableState,
} from 'store/manualJournals/manualJournals.actions';
const mapActionsToProps = (dispatch) => ({
setManualJournalsTableState: (queries) =>
dispatch(setManualJournalsTableState(queries)),
});
export default connect(null, mapActionsToProps);

View File

@@ -1,4 +1,4 @@
import React, { useCallback } from 'react';
import React from 'react';
import {
InputGroup,
FormGroup,
@@ -26,6 +26,9 @@ import withDialogActions from 'containers/Dialog/withDialogActions';
import { compose, inputIntent, handleDateChange } from 'utils';
/**
* Make journal entries header.
*/
function MakeJournalEntriesHeader({
// #ownProps
onJournalNumberChanged,

View File

@@ -0,0 +1,91 @@
import React from 'react';
import { Position } from '@blueprintjs/core';
import { FormattedMessage as T } from 'react-intl';
import { Money, Hint } from 'components';
/**
* Contact header cell.
*/
export function ContactHeaderCell() {
return (
<>
<T id={'contact'} />
<Hint
content={<T id={'contact_column_hint'} />}
position={Position.LEFT_BOTTOM}
/>
</>
);
}
/**
* Total text cell renderer.
*/
export const TotalAccountCellRenderer = (chainedComponent) => (props) => {
if (props.data.length === props.row.index + 1) {
return <span>{'Total USD'}</span>;
}
return chainedComponent(props);
};
/**
* Total credit/debit cell renderer.
*/
export const TotalCreditDebitCellRenderer = (chainedComponent, type) => (
props,
) => {
if (props.data.length === props.row.index + 1) {
const total = props.data.reduce((total, entry) => {
const amount = parseInt(entry[type], 10);
const computed = amount ? total + amount : total;
return computed;
}, 0);
return (
<span>
<Money amount={total} currency={'USD'} />
</span>
);
}
return chainedComponent(props);
};
export const NoteCellRenderer = (chainedComponent) => (props) => {
if (props.data.length === props.row.index + 1) {
return '';
}
return chainedComponent(props);
};
/**
* Actions cell renderer.
*/
export const ActionsCellRenderer = ({
row: { index },
column: { id },
cell: { value: initialValue },
data,
payload,
}) => {
if (data.length <= index + 1) {
return '';
}
const onClickRemoveRole = () => {
payload.removeRow(index);
};
return (
<Tooltip content={<T id={'remove_the_line'} />} position={Position.LEFT}>
<Button
icon={<Icon icon="times-circle" iconSize={14} />}
iconSize={14}
className="ml2"
minimal={true}
intent={Intent.DANGER}
onClick={onClickRemoveRole}
/>
</Tooltip>
);
};

View File

@@ -1,9 +1,10 @@
import React from 'react';
import { Intent } from '@blueprintjs/core';
import { get, sumBy, setWith, toSafeInteger } from 'lodash';
import { sumBy, setWith, toSafeInteger, get } from 'lodash';
import { transformUpdatedRows } from 'utils';
import { AppToaster } from 'components';
import { formatMessage } from 'services/intl';
import { transformUpdatedRows } from 'utils';
const ERROR = {
JOURNAL_NUMBER_ALREADY_EXISTS: 'JOURNAL.NUMBER.ALREADY.EXISTS',
@@ -16,15 +17,17 @@ const ERROR = {
ENTRIES_SHOULD_ASSIGN_WITH_CONTACT: 'ENTRIES_SHOULD_ASSIGN_WITH_CONTACT',
};
/**
* Entries adjustment.
*/
function adjustmentEntries(entries) {
const credit = sumBy(entries, e => toSafeInteger(e.credit));
const debit = sumBy(entries, e => toSafeInteger(e.debit));
const credit = sumBy(entries, (e) => toSafeInteger(e.credit));
const debit = sumBy(entries, (e) => toSafeInteger(e.debit));
return {
debit: Math.max(credit - debit, 0),
credit: Math.max(debit - credit, 0),
}
};
}
export const updateDataReducer = (rows, rowIndex, columnId, value) => {

View File

@@ -1,249 +0,0 @@
import React, { useCallback, useMemo } from 'react';
import {
Intent,
Button,
Popover,
Menu,
MenuItem,
MenuDivider,
Position,
} from '@blueprintjs/core';
import { useIntl } from 'react-intl';
import moment from 'moment';
import classNames from 'classnames';
import {
DataTable,
If,
Choose,
Icon,
} from 'components';
import { CLASSES } from 'common/classes';
import ManualJournalsEmptyStatus from './ManualJournalsEmptyStatus';
import TableSkeletonRows from 'components/Datatable/TableSkeletonRows';
import TableSkeletonHeader from 'components/Datatable/TableHeaderSkeleton';
import {
NoteAccessor,
StatusAccessor,
DateAccessor,
AmountAccessor
} from './components';
import withManualJournalsActions from 'containers/Accounting/withManualJournalsActions';
import { compose, saveInvoke } from 'utils';
import { useManualJournalsContext } from './ManualJournalsListProvider';
/**
* Manual journals data-table.
*/
function ManualJournalsDataTable({
// #withManualJournalsActions
addManualJournalsTableQueries,
// #ownProps
onSelectedRowsChange,
}) {
const { formatMessage } = useIntl();
const { manualJournals, isManualJournalsLoading } = useManualJournalsContext();
const handlePublishJournal = useCallback(
(journal) => () => {
},
[],
);
const handleEditJournal = useCallback(
(journal) => () => {
},
[],
);
const handleDeleteJournal = useCallback(
(journal) => () => {
},
[],
);
const actionMenuList = useCallback(
(journal) => (
<Menu>
<MenuItem
icon={<Icon icon="reader-18" />}
text={formatMessage({ id: 'view_details' })}
/>
<MenuDivider />
<If condition={!journal.is_published}>
<MenuItem
icon={<Icon icon="arrow-to-top" />}
text={formatMessage({ id: 'publish_journal' })}
onClick={handlePublishJournal(journal)}
/>
</If>
<MenuItem
icon={<Icon icon="pen-18" />}
text={formatMessage({ id: 'edit_journal' })}
onClick={handleEditJournal(journal)}
/>
<MenuItem
text={formatMessage({ id: 'delete_journal' })}
icon={<Icon icon="trash-16" iconSize={16} />}
intent={Intent.DANGER}
onClick={handleDeleteJournal(journal)}
/>
</Menu>
),
[
handleEditJournal,
handleDeleteJournal,
handlePublishJournal,
formatMessage,
],
);
const onRowContextMenu = useCallback(
(cell) => actionMenuList(cell.row.original),
[actionMenuList],
);
const columns = useMemo(
() => [
{
id: 'date',
Header: formatMessage({ id: 'date' }),
accessor: DateAccessor,
width: 115,
className: 'date',
},
{
id: 'amount',
Header: formatMessage({ id: 'amount' }),
accessor: AmountAccessor,
className: 'amount',
width: 115,
},
{
id: 'journal_number',
Header: formatMessage({ id: 'journal_no' }),
accessor: (row) => `#${row.journal_number}`,
className: 'journal_number',
width: 100,
},
{
id: 'journal_type',
Header: formatMessage({ id: 'journal_type' }),
accessor: 'journal_type',
width: 110,
className: 'journal_type',
},
{
id: 'publish',
Header: formatMessage({ id: 'publish' }),
accessor: (row) => StatusAccessor(row),
width: 95,
className: 'publish',
},
{
id: 'note',
Header: formatMessage({ id: 'note' }),
accessor: NoteAccessor,
disableSorting: true,
width: 85,
className: 'note',
},
{
id: 'created_at',
Header: formatMessage({ id: 'created_at' }),
accessor: (r) => moment(r.created_at).format('YYYY MMM DD'),
width: 125,
className: 'created_at',
},
{
id: 'actions',
Header: '',
Cell: ({ cell }) => (
<Popover
content={actionMenuList(cell.row.original)}
position={Position.RIGHT_BOTTOM}
>
<Button icon={<Icon icon="more-h-16" iconSize={16} />} />
</Popover>
),
className: 'actions',
width: 50,
disableResizing: true,
},
],
[actionMenuList, formatMessage],
);
const handleDataTableFetchData = useCallback(
({ 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,
});
},
[addManualJournalsTableQueries],
);
const handleSelectedRowsChange = useCallback(
(selectedRows) => {
saveInvoke(
onSelectedRowsChange,
selectedRows.map((s) => s.original),
);
},
[onSelectedRowsChange],
);
return (
<div className={classNames(CLASSES.DASHBOARD_DATATABLE)}>
<Choose>
<Choose.When condition={false}>
<ManualJournalsEmptyStatus />
</Choose.When>
<Choose.Otherwise>
<DataTable
noInitialFetch={true}
columns={columns}
data={manualJournals}
onFetchData={handleDataTableFetchData}
manualSortBy={true}
selectionColumn={true}
expandable={true}
sticky={true}
loading={isManualJournalsLoading}
onSelectedRowsChange={handleSelectedRowsChange}
rowContextMenu={onRowContextMenu}
// pagesCount={manualJournalsPagination.pagesCount}
pagination={true}
// initialPageSize={manualJournalsTableQuery.page_size}
// initialPageIndex={manualJournalsTableQuery.page - 1}
autoResetSortBy={false}
autoResetPage={false}
TableLoadingRenderer={TableSkeletonRows}
TableHeaderSkeletonRenderer={TableSkeletonHeader}
/>
</Choose.Otherwise>
</Choose>
</div>
);
}
export default compose(
withManualJournalsActions,
)(ManualJournalsDataTable);

View File

@@ -1,80 +0,0 @@
import React, { useEffect, useCallback } from 'react';
import { Route, Switch, useHistory } from 'react-router-dom';
import {
FormattedMessage as T,
useIntl,
} from 'react-intl';
import DashboardPageContent from 'components/Dashboard/DashboardPageContent';
import { ManualJournalsListProvider } from './ManualJournalsListProvider';
import ManualJournalsAlerts from './ManualJournalsAlerts';
import ManualJournalsViewTabs from './ManualJournalsViewTabs';
import ManualJournalsDataTable from './ManualJournalsDataTable';
import ManualJournalsActionsBar from './ManualJournalActionsBar';
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
import withManualJournals from 'containers/Accounting/withManualJournals';
import { compose } from 'utils';
import 'style/pages/ManualJournal/List.scss';
/**
* Manual journals table.
*/
function ManualJournalsTable({
// #withDashboardActions
changePageTitle,
// #withManualJournals
manualJournalsTableQuery,
}) {
const history = useHistory();
const { formatMessage } = useIntl();
// Handle update the page title.
useEffect(() => {
changePageTitle(formatMessage({ id: 'manual_journals' }));
}, [changePageTitle, formatMessage]);
const handleEditJournal = useCallback(
(journal) => {
history.push(`/manual-journals/${journal.id}/edit`);
},
[history],
);
// Handle filter change to re-fetch data-table.
const handleFilterChanged = useCallback(() => {}, []);
return (
<ManualJournalsListProvider query={manualJournalsTableQuery}>
<ManualJournalsActionsBar />
<DashboardPageContent>
<Switch>
<Route
exact={true}
path={[
'/manual-journals/:custom_view_id/custom_view',
'/manual-journals',
]}
>
<ManualJournalsViewTabs />
<ManualJournalsDataTable />
<ManualJournalsAlerts />
</Route>
</Switch>
</DashboardPageContent>
</ManualJournalsListProvider>
);
}
export default compose(
withDashboardActions,
withManualJournals(({ manualJournalsTableQuery }) => ({
manualJournalsTableQuery,
})),
)(ManualJournalsTable);

View File

@@ -1,10 +0,0 @@
import {connect} from 'react-redux';
import {
getManualJournal,
} from 'store/manualJournals/manualJournals.reducers';
export const mapStateToProps = (state, props) => ({
manualJournal: getManualJournal(state, props.manualJournalId),
});
export default connect(mapStateToProps);

View File

@@ -1,14 +0,0 @@
import {connect} from 'react-redux';
import {
makeJournalEntries,
fetchManualJournal,
editManualJournal,
} from 'store/manualJournals/manualJournals.actions';
export const mapDispatchToProps = (dispatch) => ({
requestMakeJournalEntries: (form) => dispatch(makeJournalEntries({ form })),
requestFetchManualJournal: (id) => dispatch(fetchManualJournal({ id })),
requestEditManualJournal: (id, form) => dispatch(editManualJournal({ id, form }))
});
export default connect(null, mapDispatchToProps);

View File

@@ -1,11 +0,0 @@
import { connect } from 'react-redux';
import { getManualJournalByIdFactory } from 'store/manualJournals/manualJournals.selectors';
export default () => {
const getManualJournalById = getManualJournalByIdFactory();
const mapStateToProps = (state, props) => ({
manualJournal: getManualJournalById(state, props),
});
return connect(mapStateToProps);
};

View File

@@ -1,33 +0,0 @@
import { connect } from 'react-redux';
import { getResourceViews } from 'store/customViews/customViews.selectors';
import {
getManualJournalsItems,
getManualJournalsPagination,
getManualJournalsTableQuery,
getManualJournalsCurrentViewIdFactory
} from 'store/manualJournals/manualJournals.selectors';
export default (mapState) => {
const getManualJournalsCurrentViewId = getManualJournalsCurrentViewIdFactory();
const mapStateToProps = (state, props) => {
const query = getManualJournalsTableQuery(state, props);
const mapped = {
manualJournalsCurrentPage: getManualJournalsItems(state, props, query),
manualJournalsTableQuery: query,
manualJournalsViews: getResourceViews(state, props, 'manual_journals'),
manualJournalsItems: state.manualJournals.items,
manualJournalsPagination: getManualJournalsPagination(state, props, query),
manualJournalsLoading: state.manualJournals.loading,
journalNumberChanged: state.manualJournals.journalNumberChanged,
manualJournalsCurrentViewId: getManualJournalsCurrentViewId(state, props),
};
return mapState ? mapState(mapped, state, props) : mapped;
};
return connect(mapStateToProps);
};

View File

@@ -1,33 +0,0 @@
import { connect } from 'react-redux';
import t from 'store/types';
import {
deleteManualJournal,
fetchManualJournalsTable,
publishManualJournal,
deleteBulkManualJournals,
fetchManualJournal,
} from 'store/manualJournals/manualJournals.actions';
const mapActionsToProps = (dispatch) => ({
requestDeleteManualJournal: (id) => dispatch(deleteManualJournal({ id })),
requestFetchManualJournalsTable: (query = {}) => dispatch(fetchManualJournalsTable({ query })),
requestFetchManualJournal: (id) => dispatch(fetchManualJournal({ id })),
requestPublishManualJournal: (id) => dispatch(publishManualJournal({ id })),
requestDeleteBulkManualJournals: (ids) => dispatch(deleteBulkManualJournals({ ids })),
changeManualJournalCurrentView: (id) => dispatch({
type: t.MANUAL_JOURNALS_SET_CURRENT_VIEW,
payload: {
currentViewId: parseInt(id, 10),
}
}),
addManualJournalsTableQueries: (queries) => dispatch({
type: t.MANUAL_JOURNALS_TABLE_QUERIES_ADD,
payload: { queries },
}),
setJournalNumberChanged: (isChanged) => dispatch({
type: t.MANUAL_JOURNAL_NUMBER_CHANGED,
payload: { isChanged },
}),
});
export default connect(null, mapActionsToProps);