feat: cashflow accounts.

This commit is contained in:
elforjani13
2021-10-13 19:54:36 +02:00
parent 4ba750fe11
commit b848553cf7
10 changed files with 454 additions and 3 deletions

View File

@@ -0,0 +1,113 @@
import React from 'react';
import classNames from 'classnames';
import { isEmpty } from 'lodash';
import {
Button,
NavbarGroup,
Classes,
NavbarDivider,
Alignment,
} from '@blueprintjs/core';
import {
Icon,
DashboardRowsHeightButton,
FormattedMessage as T,
} from 'components';
import DashboardActionsBar from 'components/Dashboard/DashboardActionsBar';
import { useCashFlowAccountsContext } from './CashFlowAccountsProvider';
import withDialogActions from 'containers/Dialog/withDialogActions';
import withSettings from '../../Settings/withSettings';
import withSettingsActions from '../../Settings/withSettingsActions';
import { compose } from 'utils';
/**
* Cash Flow accounts actions bar.
*/
function CashFlowAccountsActionsBar({
// #withDialogActions
openDialog,
// #withSettings
cashflowTableSize,
// #withSettingsActions
addSetting,
}) {
// Handle table row size change.
const handleTableRowSizeChange = (size) => {
addSetting('cashflowAccounts', 'tableSize', size);
};
// Handle click a refresh
const handleRefreshBtnClick = () => {};
// Handle add bank account.
const handleAddBankAccount = () => {
openDialog('account-form', {});
};
// Handle add cash account.
const handleAddCashAccount = () => {
openDialog('account-form', {});
};
return (
<DashboardActionsBar>
<NavbarGroup>
<Button
className={Classes.MINIMAL}
// className={classNames(Classes.MINIMAL, 'button--table-views')}
icon={<Icon icon={'plus-24'} iconSize={20} />}
text={<T id={'cash_flow.label.add_cash_account'} />}
onClick={handleAddBankAccount}
/>
<Button
className={Classes.MINIMAL}
icon={<Icon icon={'plus-24'} iconSize={20} />}
text={<T id={'cash_flow.label.add_bank_account'} />}
onClick={handleAddCashAccount}
/>
<NavbarDivider />
<Button
className={Classes.MINIMAL}
icon={<Icon icon="print-16" iconSize={16} />}
text={<T id={'print'} />}
/>
<Button
className={Classes.MINIMAL}
icon={<Icon icon="file-export-16" iconSize={16} />}
text={<T id={'export'} />}
/>
<Button
className={Classes.MINIMAL}
icon={<Icon icon="file-import-16" iconSize={16} />}
text={<T id={'import'} />}
/>
<NavbarDivider />
<DashboardRowsHeightButton
initialValue={cashflowTableSize}
onChange={handleTableRowSizeChange}
/>
<NavbarDivider />
</NavbarGroup>
<NavbarGroup align={Alignment.RIGHT}>
<Button
className={Classes.MINIMAL}
icon={<Icon icon="refresh-16" iconSize={14} />}
onClick={handleRefreshBtnClick}
/>
</NavbarGroup>
</DashboardActionsBar>
);
}
export default compose(
withDialogActions,
withSettingsActions,
withSettings(({ cashflowSettings }) => ({
cashflowTableSize: cashflowSettings?.tableSize,
})),
)(CashFlowAccountsActionsBar);

View File

@@ -0,0 +1,67 @@
import React from 'react';
import { DataTable, TableFastCell } from 'components';
import { TABLES } from 'common/tables';
import TableVirtualizedListRows from 'components/Datatable/TableVirtualizedRows';
import TableSkeletonRows from 'components/Datatable/TableSkeletonRows';
import TableSkeletonHeader from 'components/Datatable/TableHeaderSkeleton';
import withSettings from '../../Settings/withSettings';
import { useMemorizedColumnsWidths } from '../../../hooks';
import { useCashFlowAccountsContext } from './CashFlowAccountsProvider';
import { useCashFlowAccountsTableColumns } from './components';
import { compose } from 'utils';
/**
* Cash flow accounts data table.
*/
function CashFlowAccountsDataTable({
// #withSettings
cashflowTableSize,
}) {
// Retrieve list context.
const {
cashflowAccounts,
isCashFlowAccountsFetching,
isCashFlowAccountsLoading,
} = useCashFlowAccountsContext();
// Retrieve table columns.
const columns = useCashFlowAccountsTableColumns();
// Local storage memorizing columns widths.
const [initialColumnsWidths, , handleColumnResizing] =
useMemorizedColumnsWidths(TABLES.CASHFLOW_ACCOUNTS);
return (
<DataTable
noInitialFetch={true}
columns={columns}
data={cashflowAccounts}
selectionColumn={true}
sticky={true}
loading={isCashFlowAccountsLoading}
headerLoading={isCashFlowAccountsLoading}
progressBarLoading={isCashFlowAccountsFetching}
expandColumnSpace={1}
expandToggleColumn={2}
selectionColumnWidth={45}
TableCellRenderer={TableFastCell}
TableRowsRenderer={TableVirtualizedListRows}
TableLoadingRenderer={TableSkeletonRows}
// #TableVirtualizedListRows props.
vListrowHeight={cashflowTableSize == 'small' ? 40 : 42}
vListOverscanRowCount={0}
TableHeaderSkeletonRenderer={TableSkeletonHeader}
initialColumnsWidths={initialColumnsWidths}
onColumnResizing={handleColumnResizing}
size={cashflowTableSize}
/>
);
}
export default compose(
withSettings(({ cashflowSettings }) => ({
cashflowTableSize: cashflowSettings?.tableSize,
})),
)(CashFlowAccountsDataTable);

View File

@@ -0,0 +1,28 @@
import React from 'react';
import 'style/pages/CashFlow/CashFlowAccounts/List.scss';
import { DashboardPageContent, DashboardContentTable } from 'components';
import { CashFlowAccountsProvider } from './CashFlowAccountsProvider';
import CashFlowAccountsActionsBar from './CashFlowAccountsActionsBar';
import CashFlowAccountsDataTable from './CashFlowAccountsDataTable';
/**
* Cash flow accounts list.
*/
function CashFlowAccountsList({}) {
return (
<CashFlowAccountsProvider>
<CashFlowAccountsActionsBar />
<DashboardPageContent>
<DashboardContentTable>
<CashFlowAccountsDataTable />
</DashboardContentTable>
</DashboardPageContent>
</CashFlowAccountsProvider>
);
}
export default CashFlowAccountsList;

View File

@@ -0,0 +1,35 @@
import React from 'react';
import DashboardInsider from 'components/Dashboard/DashboardInsider';
import { useCashflowAccounts } from 'hooks/query';
const CashFlowAccountsContext = React.createContext();
/**
* Cash Flow data provider.
*/
function CashFlowAccountsProvider({ query, tableStateChanged, ...props }) {
// Fetch cash flow list .
const {
data: cashflowAccounts,
isFetching: isCashFlowAccountsFetching,
isLoading: isCashFlowAccountsLoading,
} = useCashflowAccounts(query, { keepPreviousData: true });
// Provider payload.
const provider = {
cashflowAccounts,
isCashFlowAccountsFetching,
isCashFlowAccountsLoading,
};
return (
<DashboardInsider name={'cashflow-accounts'}>
<CashFlowAccountsContext.Provider value={provider} {...props} />
</DashboardInsider>
);
}
const useCashFlowAccountsContext = () =>
React.useContext(CashFlowAccountsContext);
export { CashFlowAccountsProvider, useCashFlowAccountsContext };

View File

@@ -0,0 +1,89 @@
import React from 'react';
import intl from 'react-intl-universal';
import { Intent, Tag } from '@blueprintjs/core';
import { isBlank } from 'utils';
import { Link } from 'react-router-dom';
/**
* Account code accessor.
*/
export const AccountCodeAccessor = (row) =>
!isBlank(row.code) ? (
<Tag minimal={true} round={true} intent={Intent.NONE}>
{row.code}
</Tag>
) : null;
/**
* Balance cell.
*/
export const BalanceCell = ({ cell }) => {
const account = cell.row.original;
return account.amount !== null ? (
<span>{account.formatted_amount}</span>
) : (
<span class="placeholder"></span>
);
};
/**
* Account cell.
*/
const AccountCell = ({ row }) => {
const account = row.original;
return <Link to={`/account/${account.id}/transactions`}>{account.name}</Link>;
};
/**
* Retrieve Cash flow table columns.
*/
export function useCashFlowAccountsTableColumns() {
return React.useMemo(
() => [
{
id: 'name',
Header: intl.get('account_name'),
accessor: 'name',
Cell: AccountCell,
className: 'account_name',
width: 200,
textOverview: true,
},
{
id: 'code',
Header: intl.get('code'),
accessor: 'code',
className: 'code',
width: 80,
},
{
id: 'type',
Header: intl.get('type'),
accessor: 'account_type_label',
className: 'type',
width: 140,
textOverview: true,
},
{
id: 'currency',
Header: intl.get('currency'),
accessor: 'currency_code',
width: 75,
},
{
id: 'balance',
Header: intl.get('balance'),
accessor: 'amount',
className: 'balance',
Cell: BalanceCell,
width: 150,
align: 'right',
},
],
[],
);
}