diff --git a/client/src/common/classes.js b/client/src/common/classes.js
index 79e07b132..396700ebb 100644
--- a/client/src/common/classes.js
+++ b/client/src/common/classes.js
@@ -33,7 +33,7 @@ const CLASSES = {
PAGE_FORM_PAYMENT_MADE: 'page-form--payment-made',
PAGE_FORM_PAYMENT_RECEIVE: 'page-form--payment-receive',
PAGE_FORM_CUSTOMER: 'page-form--customer',
- PAGE_FORM_VENDOR: 'page-form--customer',
+ PAGE_FORM_VENDOR: 'page-form--vendor',
PAGE_FORM_ITEM: 'page-form--item',
PAGE_FORM_MAKE_JOURNAL: 'page-form--make-journal-entries',
PAGE_FORM_EXPENSE: 'page-form--expense',
diff --git a/client/src/components/DialogsContainer.js b/client/src/components/DialogsContainer.js
index a84df5e5f..c7fb79fff 100644
--- a/client/src/components/DialogsContainer.js
+++ b/client/src/components/DialogsContainer.js
@@ -19,7 +19,7 @@ import PaymentViaVoucherDialog from 'containers/Dialogs/PaymentViaVoucherDialog'
export default function DialogsContainer() {
return (
-
+ {/*
*/}
diff --git a/client/src/containers/Accounting/ManualJournalActionsBar.js b/client/src/containers/Accounting/JournalsLanding/ManualJournalActionsBar.js
similarity index 77%
rename from client/src/containers/Accounting/ManualJournalActionsBar.js
rename to client/src/containers/Accounting/JournalsLanding/ManualJournalActionsBar.js
index 2fe0fd561..35f900df7 100644
--- a/client/src/containers/Accounting/ManualJournalActionsBar.js
+++ b/client/src/containers/Accounting/JournalsLanding/ManualJournalActionsBar.js
@@ -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);
diff --git a/client/src/containers/Accounting/ManualJournalsAlerts.js b/client/src/containers/Accounting/JournalsLanding/ManualJournalsAlerts.js
similarity index 100%
rename from client/src/containers/Accounting/ManualJournalsAlerts.js
rename to client/src/containers/Accounting/JournalsLanding/ManualJournalsAlerts.js
diff --git a/client/src/containers/Accounting/JournalsLanding/ManualJournalsDataTable.js b/client/src/containers/Accounting/JournalsLanding/ManualJournalsDataTable.js
new file mode 100644
index 000000000..d9f89d5e1
--- /dev/null
+++ b/client/src/containers/Accounting/JournalsLanding/ManualJournalsDataTable.js
@@ -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 (
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default compose(
+ withManualJournalsActions,
+ withAlertsActions
+)(ManualJournalsDataTable);
diff --git a/client/src/containers/Accounting/ManualJournalsEmptyStatus.js b/client/src/containers/Accounting/JournalsLanding/ManualJournalsEmptyStatus.js
similarity index 100%
rename from client/src/containers/Accounting/ManualJournalsEmptyStatus.js
rename to client/src/containers/Accounting/JournalsLanding/ManualJournalsEmptyStatus.js
diff --git a/client/src/containers/Accounting/JournalsLanding/ManualJournalsList.js b/client/src/containers/Accounting/JournalsLanding/ManualJournalsList.js
new file mode 100644
index 000000000..b04d2c786
--- /dev/null
+++ b/client/src/containers/Accounting/JournalsLanding/ManualJournalsList.js
@@ -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 (
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default compose(
+ withDashboardActions,
+ withManualJournals(({ manualJournalsTableState }) => ({
+ journalsTableState: manualJournalsTableState,
+ })),
+)(ManualJournalsTable);
diff --git a/client/src/containers/Accounting/ManualJournalsListProvider.js b/client/src/containers/Accounting/JournalsLanding/ManualJournalsListProvider.js
similarity index 62%
rename from client/src/containers/Accounting/ManualJournalsListProvider.js
rename to client/src/containers/Accounting/JournalsLanding/ManualJournalsListProvider.js
index 6a28387f4..d9f512714 100644
--- a/client/src/containers/Accounting/ManualJournalsListProvider.js
+++ b/client/src/containers/Accounting/JournalsLanding/ManualJournalsListProvider.js
@@ -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 (
diff --git a/client/src/containers/Accounting/ManualJournalsViewTabs.js b/client/src/containers/Accounting/JournalsLanding/ManualJournalsViewTabs.js
similarity index 72%
rename from client/src/containers/Accounting/ManualJournalsViewTabs.js
rename to client/src/containers/Accounting/JournalsLanding/ManualJournalsViewTabs.js
index 25cba1767..e4b06c652 100644
--- a/client/src/containers/Accounting/ManualJournalsViewTabs.js
+++ b/client/src/containers/Accounting/JournalsLanding/ManualJournalsViewTabs.js
@@ -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({
({
+ journalsTableState: manualJournalsTableState,
+ })),
)(ManualJournalsViewTabs);
diff --git a/client/src/containers/Accounting/components.js b/client/src/containers/Accounting/JournalsLanding/components.js
similarity index 54%
rename from client/src/containers/Accounting/components.js
rename to client/src/containers/Accounting/JournalsLanding/components.js
index e516dbc51..f0d5472ab 100644
--- a/client/src/containers/Accounting/components.js
+++ b/client/src/containers/Accounting/JournalsLanding/components.js
@@ -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) => (
}
@@ -26,15 +30,13 @@ export const AmountAccessor = (r) => (
);
-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 (
@@ -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 (
- <>
-
- }
- position={Position.LEFT_BOTTOM}
- />
- >
+ }
+ position={Position.RIGHT_BOTTOM}
+ >
+ } />
+
);
-}
+};
-// 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 (
- } position={Position.LEFT}>
- }
- iconSize={14}
- className="ml2"
- minimal={true}
- intent={Intent.DANGER}
- onClick={onClickRemoveRole}
+
);
};
-
-// Total text cell renderer.
-export const TotalAccountCellRenderer = (chainedComponent) => (props) => {
- if (props.data.length === props.row.index + 1) {
- return {'Total USD'};
- }
- 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 (
-
-
-
- );
- }
- return chainedComponent(props);
-};
-
-export const NoteCellRenderer = (chainedComponent) => (props) => {
- if (props.data.length === props.row.index + 1) {
- return '';
- }
- return chainedComponent(props);
-};
diff --git a/client/src/containers/Accounting/JournalsLanding/utils.js b/client/src/containers/Accounting/JournalsLanding/utils.js
new file mode 100644
index 000000000..9cd8be409
--- /dev/null
+++ b/client/src/containers/Accounting/JournalsLanding/utils.js
@@ -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,
+ },
+ ],
+ [],
+ );
+};
diff --git a/client/src/containers/Accounting/JournalsLanding/withManualJournals.js b/client/src/containers/Accounting/JournalsLanding/withManualJournals.js
new file mode 100644
index 000000000..551196582
--- /dev/null
+++ b/client/src/containers/Accounting/JournalsLanding/withManualJournals.js
@@ -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);
+};
diff --git a/client/src/containers/Accounting/JournalsLanding/withManualJournalsActions.js b/client/src/containers/Accounting/JournalsLanding/withManualJournalsActions.js
new file mode 100644
index 000000000..3b1123ec6
--- /dev/null
+++ b/client/src/containers/Accounting/JournalsLanding/withManualJournalsActions.js
@@ -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);
diff --git a/client/src/containers/Accounting/MakeJournalEntries.schema.js b/client/src/containers/Accounting/MakeJournal/MakeJournalEntries.schema.js
similarity index 100%
rename from client/src/containers/Accounting/MakeJournalEntries.schema.js
rename to client/src/containers/Accounting/MakeJournal/MakeJournalEntries.schema.js
diff --git a/client/src/containers/Accounting/MakeJournalEntriesField.js b/client/src/containers/Accounting/MakeJournal/MakeJournalEntriesField.js
similarity index 100%
rename from client/src/containers/Accounting/MakeJournalEntriesField.js
rename to client/src/containers/Accounting/MakeJournal/MakeJournalEntriesField.js
diff --git a/client/src/containers/Accounting/MakeJournalEntriesFooter.js b/client/src/containers/Accounting/MakeJournal/MakeJournalEntriesFooter.js
similarity index 100%
rename from client/src/containers/Accounting/MakeJournalEntriesFooter.js
rename to client/src/containers/Accounting/MakeJournal/MakeJournalEntriesFooter.js
diff --git a/client/src/containers/Accounting/MakeJournalEntriesForm.js b/client/src/containers/Accounting/MakeJournal/MakeJournalEntriesForm.js
similarity index 100%
rename from client/src/containers/Accounting/MakeJournalEntriesForm.js
rename to client/src/containers/Accounting/MakeJournal/MakeJournalEntriesForm.js
diff --git a/client/src/containers/Accounting/MakeJournalEntriesHeader.js b/client/src/containers/Accounting/MakeJournal/MakeJournalEntriesHeader.js
similarity index 100%
rename from client/src/containers/Accounting/MakeJournalEntriesHeader.js
rename to client/src/containers/Accounting/MakeJournal/MakeJournalEntriesHeader.js
diff --git a/client/src/containers/Accounting/MakeJournalEntriesHeaderFields.js b/client/src/containers/Accounting/MakeJournal/MakeJournalEntriesHeaderFields.js
similarity index 98%
rename from client/src/containers/Accounting/MakeJournalEntriesHeaderFields.js
rename to client/src/containers/Accounting/MakeJournal/MakeJournalEntriesHeaderFields.js
index 3600deaa3..d09615584 100644
--- a/client/src/containers/Accounting/MakeJournalEntriesHeaderFields.js
+++ b/client/src/containers/Accounting/MakeJournal/MakeJournalEntriesHeaderFields.js
@@ -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,
diff --git a/client/src/containers/Accounting/MakeJournalEntriesPage.js b/client/src/containers/Accounting/MakeJournal/MakeJournalEntriesPage.js
similarity index 100%
rename from client/src/containers/Accounting/MakeJournalEntriesPage.js
rename to client/src/containers/Accounting/MakeJournal/MakeJournalEntriesPage.js
diff --git a/client/src/containers/Accounting/MakeJournalEntriesTable.js b/client/src/containers/Accounting/MakeJournal/MakeJournalEntriesTable.js
similarity index 100%
rename from client/src/containers/Accounting/MakeJournalEntriesTable.js
rename to client/src/containers/Accounting/MakeJournal/MakeJournalEntriesTable.js
diff --git a/client/src/containers/Accounting/MakeJournalFormFloatingActions.js b/client/src/containers/Accounting/MakeJournal/MakeJournalFormFloatingActions.js
similarity index 100%
rename from client/src/containers/Accounting/MakeJournalFormFloatingActions.js
rename to client/src/containers/Accounting/MakeJournal/MakeJournalFormFloatingActions.js
diff --git a/client/src/containers/Accounting/MakeJournalFormFooter.js b/client/src/containers/Accounting/MakeJournal/MakeJournalFormFooter.js
similarity index 100%
rename from client/src/containers/Accounting/MakeJournalFormFooter.js
rename to client/src/containers/Accounting/MakeJournal/MakeJournalFormFooter.js
diff --git a/client/src/containers/Accounting/MakeJournalNumberWatcher.js b/client/src/containers/Accounting/MakeJournal/MakeJournalNumberWatcher.js
similarity index 100%
rename from client/src/containers/Accounting/MakeJournalNumberWatcher.js
rename to client/src/containers/Accounting/MakeJournal/MakeJournalNumberWatcher.js
diff --git a/client/src/containers/Accounting/MakeJournalProvider.js b/client/src/containers/Accounting/MakeJournal/MakeJournalProvider.js
similarity index 100%
rename from client/src/containers/Accounting/MakeJournalProvider.js
rename to client/src/containers/Accounting/MakeJournal/MakeJournalProvider.js
diff --git a/client/src/containers/Accounting/MakeJournal/components.js b/client/src/containers/Accounting/MakeJournal/components.js
new file mode 100644
index 000000000..51d73ad4c
--- /dev/null
+++ b/client/src/containers/Accounting/MakeJournal/components.js
@@ -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 (
+ <>
+
+ }
+ position={Position.LEFT_BOTTOM}
+ />
+ >
+ );
+}
+
+/**
+ * Total text cell renderer.
+ */
+export const TotalAccountCellRenderer = (chainedComponent) => (props) => {
+ if (props.data.length === props.row.index + 1) {
+ return {'Total USD'};
+ }
+ 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 (
+
+
+
+ );
+ }
+ 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 (
+ } position={Position.LEFT}>
+ }
+ iconSize={14}
+ className="ml2"
+ minimal={true}
+ intent={Intent.DANGER}
+ onClick={onClickRemoveRole}
+ />
+
+ );
+ };
+
\ No newline at end of file
diff --git a/client/src/containers/Accounting/utils.js b/client/src/containers/Accounting/MakeJournal/utils.js
similarity index 93%
rename from client/src/containers/Accounting/utils.js
rename to client/src/containers/Accounting/MakeJournal/utils.js
index 9024aabf0..7e9d27614 100644
--- a/client/src/containers/Accounting/utils.js
+++ b/client/src/containers/Accounting/MakeJournal/utils.js
@@ -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) => {
diff --git a/client/src/containers/Accounting/ManualJournalsDataTable.js b/client/src/containers/Accounting/ManualJournalsDataTable.js
deleted file mode 100644
index 1415b1112..000000000
--- a/client/src/containers/Accounting/ManualJournalsDataTable.js
+++ /dev/null
@@ -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) => (
-
- ),
- [
- 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 }) => (
-
- } />
-
- ),
- 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 (
-
-
-
-
-
-
-
-
-
-
-
- );
-}
-
-export default compose(
- withManualJournalsActions,
-)(ManualJournalsDataTable);
diff --git a/client/src/containers/Accounting/ManualJournalsList.js b/client/src/containers/Accounting/ManualJournalsList.js
deleted file mode 100644
index 12727f816..000000000
--- a/client/src/containers/Accounting/ManualJournalsList.js
+++ /dev/null
@@ -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 (
-
-
-
-
-
-
-
-
-
-
-
-
-
- );
-}
-
-export default compose(
- withDashboardActions,
- withManualJournals(({ manualJournalsTableQuery }) => ({
- manualJournalsTableQuery,
- })),
-)(ManualJournalsTable);
diff --git a/client/src/containers/Accounting/withJournalDetail.js b/client/src/containers/Accounting/withJournalDetail.js
deleted file mode 100644
index eaf32d843..000000000
--- a/client/src/containers/Accounting/withJournalDetail.js
+++ /dev/null
@@ -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);
\ No newline at end of file
diff --git a/client/src/containers/Accounting/withJournalsActions.js b/client/src/containers/Accounting/withJournalsActions.js
deleted file mode 100644
index b4b66c000..000000000
--- a/client/src/containers/Accounting/withJournalsActions.js
+++ /dev/null
@@ -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);
\ No newline at end of file
diff --git a/client/src/containers/Accounting/withManualJournalDetail.js b/client/src/containers/Accounting/withManualJournalDetail.js
deleted file mode 100644
index a51f1ef5a..000000000
--- a/client/src/containers/Accounting/withManualJournalDetail.js
+++ /dev/null
@@ -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);
-};
\ No newline at end of file
diff --git a/client/src/containers/Accounting/withManualJournals.js b/client/src/containers/Accounting/withManualJournals.js
deleted file mode 100644
index 02642aff9..000000000
--- a/client/src/containers/Accounting/withManualJournals.js
+++ /dev/null
@@ -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);
-};
diff --git a/client/src/containers/Accounting/withManualJournalsActions.js b/client/src/containers/Accounting/withManualJournalsActions.js
deleted file mode 100644
index 6ae041b59..000000000
--- a/client/src/containers/Accounting/withManualJournalsActions.js
+++ /dev/null
@@ -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);
diff --git a/client/src/containers/Accounts/AccountActionsMenu.js b/client/src/containers/Accounts/AccountActionsMenu.js
deleted file mode 100644
index a10d4f21a..000000000
--- a/client/src/containers/Accounts/AccountActionsMenu.js
+++ /dev/null
@@ -1,30 +0,0 @@
-import React from 'react';
-import { Menu, MenuItem, MenuDivider, Intent } from '@blueprintjs/core';
-import { Icon, If } from 'components';
-import { useIntl } from 'react-intl';
-
-import withDialogs from 'containers/Dialog/withDialogActions';
-import withAlertsActions from 'containers/Alert/withAlertActions';
-
-import { compose } from 'utils';
-import { formatMessage } from 'services/intl';
-
-/**
- * Account actions menu list.
- */
-export default function AccountActionsMenuList({
- account,
-
- // #withAlert
- openAlert,
- openDialog,
-}) {
- const { formatMessage } = useIntl();
-
-
- return (
-
- );
-}
-
-// export default compose(withDialogs, withAlertsActions)(AccountActionsMenuList);
diff --git a/client/src/containers/Accounts/AccountsActionsBar.js b/client/src/containers/Accounts/AccountsActionsBar.js
index ce9bcfdf5..e06eb7362 100644
--- a/client/src/containers/Accounts/AccountsActionsBar.js
+++ b/client/src/containers/Accounts/AccountsActionsBar.js
@@ -1,5 +1,6 @@
import React from 'react';
import Icon from 'components/Icon';
+import { isEmpty } from 'lodash';
import {
Button,
NavbarGroup,
@@ -21,6 +22,7 @@ import { useAccountsChartContext } from 'containers/Accounts/AccountsChartProvid
import withDialogActions from 'containers/Dialog/withDialogActions';
import withAccounts from 'containers/Accounts/withAccounts';
import withAlertActions from 'containers/Alert/withAlertActions';
+import withAccountsTableActions from './withAccountsTableActions';
import { compose } from 'utils';
@@ -37,6 +39,9 @@ function AccountsActionsBar({
// #withAlertActions
openAlert,
+ // #withAccountsTableActions
+ setAccountsTableState,
+
// #ownProps
onFilterChanged,
}) {
@@ -46,7 +51,7 @@ function AccountsActionsBar({
openDialog('account-form', {});
};
- // handle bulk accounts delete.
+ // Handle bulk accounts delete.
const handleBulkDelete = () => {
openAlert('accounts-bulk-delete', { accountsIds: accountsSelectedRows });
};
@@ -63,12 +68,18 @@ function AccountsActionsBar({
});
};
+ // Handle tab changing.
+ const handleTabChange = (viewId) => {
+ setAccountsTableState({ customViewId: viewId.id || null });
+ };
+
return (
@@ -100,7 +111,7 @@ function AccountsActionsBar({
/>
-
+
}
@@ -144,8 +155,9 @@ function AccountsActionsBar({
export default compose(
withDialogActions,
+ withAlertActions,
withAccounts(({ accountsSelectedRows }) => ({
accountsSelectedRows,
})),
- withAlertActions,
+ withAccountsTableActions
)(AccountsActionsBar);
diff --git a/client/src/containers/Accounts/AccountsAlerts.js b/client/src/containers/Accounts/AccountsAlerts.js
index eebe4480c..1fb967e42 100644
--- a/client/src/containers/Accounts/AccountsAlerts.js
+++ b/client/src/containers/Accounts/AccountsAlerts.js
@@ -2,9 +2,9 @@ import React from 'react';
import AccountDeleteAlert from 'containers/Alerts/AccountDeleteAlert';
import AccountInactivateAlert from 'containers/Alerts/AccountInactivateAlert';
import AccountActivateAlert from 'containers/Alerts/AccountActivateAlert';
-import AccountBulkDeleteAlert from 'containers/Alerts/AccountBulkDeleteAlert';
-import AccountBulkInactivateAlert from 'containers/Alerts/AccountBulkInactivateAlert';
-import AccountBulkActivateAlert from 'containers/Alerts/AccountBulkActivateAlert';
+// import AccountBulkDeleteAlert from 'containers/Alerts/AccountBulkDeleteAlert';
+// import AccountBulkInactivateAlert from 'containers/Alerts/AccountBulkInactivateAlert';
+// import AccountBulkActivateAlert from 'containers/Alerts/AccountBulkActivateAlert';
/**
* Accounts alert.
@@ -18,9 +18,9 @@ export default function AccountsAlerts({
-
+ {/*
-
+ */}
)
}
\ No newline at end of file
diff --git a/client/src/containers/Accounts/AccountsChart.js b/client/src/containers/Accounts/AccountsChart.js
index e4f9529b3..75daab70f 100644
--- a/client/src/containers/Accounts/AccountsChart.js
+++ b/client/src/containers/Accounts/AccountsChart.js
@@ -4,15 +4,17 @@ import { useIntl } from 'react-intl';
import 'style/pages/Accounts/List.scss';
import DashboardPageContent from 'components/Dashboard/DashboardPageContent';
-import { AccountsChartProvider } from 'containers/Accounts/AccountsChartProvider';
-import AccountsViewPage from 'containers/Accounts/AccountsViewPage';
+import { AccountsChartProvider } from './AccountsChartProvider';
+
+import AccountsViewsTabs from 'containers/Accounts/AccountsViewsTabs';
import AccountsActionsBar from 'containers/Accounts/AccountsActionsBar';
import AccountsAlerts from './AccountsAlerts';
+import AccountsDataTable from './AccountsDataTable';
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
import withAccounts from 'containers/Accounts/withAccounts';
-import { compose } from 'utils';
+import { transformTableStateToQuery, compose } from 'utils';
/**
* Accounts chart list.
@@ -22,7 +24,7 @@ function AccountsChart({
changePageTitle,
// #withAccounts
- accountsTableQuery
+ accountsTableState,
}) {
const { formatMessage } = useIntl();
@@ -31,11 +33,14 @@ function AccountsChart({
}, [changePageTitle, formatMessage]);
return (
-