mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-19 22:30:31 +00:00
re-structure to monorepo.
This commit is contained in:
@@ -0,0 +1,167 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import {
|
||||
Button,
|
||||
NavbarGroup,
|
||||
Classes,
|
||||
NavbarDivider,
|
||||
Intent,
|
||||
Alignment,
|
||||
} from '@blueprintjs/core';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import {
|
||||
Icon,
|
||||
AdvancedFilterPopover,
|
||||
DashboardFilterButton,
|
||||
DashboardRowsHeightButton,
|
||||
FormattedMessage as T,
|
||||
Can,
|
||||
If,
|
||||
DashboardActionViewsList,
|
||||
DashboardActionsBar
|
||||
} from '@/components';
|
||||
import { useRefreshJournals } from '@/hooks/query/manualJournals';
|
||||
import { useManualJournalsContext } from './ManualJournalsListProvider';
|
||||
import { ManualJournalAction, AbilitySubject } from '@/constants/abilityOption';
|
||||
|
||||
import withManualJournals from './withManualJournals';
|
||||
import withManualJournalsActions from './withManualJournalsActions';
|
||||
import withSettings from '@/containers/Settings/withSettings';
|
||||
import withSettingsActions from '@/containers/Settings/withSettingsActions';
|
||||
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
||||
|
||||
import { compose } from '@/utils';
|
||||
|
||||
/**
|
||||
* Manual journal actions bar.
|
||||
*/
|
||||
function ManualJournalActionsBar({
|
||||
// #withManualJournalsActions
|
||||
setManualJournalsTableState,
|
||||
|
||||
// #withManualJournals
|
||||
manualJournalsFilterConditions,
|
||||
|
||||
// #withSettings
|
||||
manualJournalsTableSize,
|
||||
|
||||
// #withSettingsActions
|
||||
addSetting,
|
||||
}) {
|
||||
// History context.
|
||||
const history = useHistory();
|
||||
|
||||
// Manual journals context.
|
||||
const { journalsViews, fields } = useManualJournalsContext();
|
||||
|
||||
// Manual journals refresh action.
|
||||
const { refresh } = useRefreshJournals();
|
||||
|
||||
// Handle click a new manual journal.
|
||||
const onClickNewManualJournal = () => {
|
||||
history.push('/make-journal-entry');
|
||||
};
|
||||
// Handle delete button click.
|
||||
const handleBulkDelete = () => {};
|
||||
|
||||
// Handle tab change.
|
||||
const handleTabChange = (view) => {
|
||||
setManualJournalsTableState({ viewSlug: view ? view.slig : null });
|
||||
};
|
||||
// Handle click a refresh Journals
|
||||
const handleRefreshBtnClick = () => {
|
||||
refresh();
|
||||
};
|
||||
|
||||
// Handle table row size change.
|
||||
const handleTableRowSizeChange = (size) => {
|
||||
addSetting('manualJournals', 'tableSize', size);
|
||||
};
|
||||
|
||||
return (
|
||||
<DashboardActionsBar>
|
||||
<NavbarGroup>
|
||||
<DashboardActionViewsList
|
||||
resourceName={'manual-journals'}
|
||||
allMenuItem={true}
|
||||
views={journalsViews}
|
||||
onChange={handleTabChange}
|
||||
/>
|
||||
<NavbarDivider />
|
||||
<Can I={ManualJournalAction.Create} a={AbilitySubject.ManualJournal}>
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
icon={<Icon icon="plus" />}
|
||||
text={<T id={'journal_entry'} />}
|
||||
onClick={onClickNewManualJournal}
|
||||
/>
|
||||
</Can>
|
||||
<AdvancedFilterPopover
|
||||
advancedFilterProps={{
|
||||
conditions: manualJournalsFilterConditions,
|
||||
defaultFieldKey: 'journal_number',
|
||||
fields,
|
||||
onFilterChange: (filterConditions) => {
|
||||
setManualJournalsTableState({ filterRoles: filterConditions });
|
||||
},
|
||||
}}
|
||||
>
|
||||
<DashboardFilterButton
|
||||
conditionsCount={manualJournalsFilterConditions.length}
|
||||
/>
|
||||
</AdvancedFilterPopover>
|
||||
|
||||
<If condition={false}>
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
icon={<Icon icon="trash-16" iconSize={16} />}
|
||||
text={<T id={'delete'} />}
|
||||
intent={Intent.DANGER}
|
||||
onClick={handleBulkDelete}
|
||||
/>
|
||||
</If>
|
||||
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
icon={<Icon icon="print-16" iconSize={16} />}
|
||||
text={<T id={'print'} />}
|
||||
/>
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
icon={<Icon icon="file-import-16" iconSize={16} />}
|
||||
text={<T id={'import'} />}
|
||||
/>
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
icon={<Icon icon="file-export-16" iconSize={16} />}
|
||||
text={<T id={'export'} />}
|
||||
/>
|
||||
<NavbarDivider />
|
||||
<DashboardRowsHeightButton
|
||||
initialValue={manualJournalsTableSize}
|
||||
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,
|
||||
withManualJournalsActions,
|
||||
withSettingsActions,
|
||||
withManualJournals(({ manualJournalsTableState }) => ({
|
||||
manualJournalsFilterConditions: manualJournalsTableState.filterRoles,
|
||||
})),
|
||||
withSettings(({ manualJournalsSettings }) => ({
|
||||
manualJournalsTableSize: manualJournalsSettings?.tableSize,
|
||||
})),
|
||||
)(ManualJournalActionsBar);
|
||||
@@ -0,0 +1,18 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
|
||||
const JournalDeleteAlert = React.lazy(
|
||||
() => import('@/containers/Alerts/ManualJournals/JournalDeleteAlert'),
|
||||
);
|
||||
const JournalPublishAlert = React.lazy(
|
||||
() => import('@/containers/Alerts/ManualJournals/JournalPublishAlert'),
|
||||
);
|
||||
|
||||
/**
|
||||
* Manual journals alerts.
|
||||
*/
|
||||
|
||||
export default [
|
||||
{ name: 'journal-delete', component: JournalDeleteAlert },
|
||||
{ name: 'journal-publish', component: JournalPublishAlert },
|
||||
];
|
||||
@@ -0,0 +1,158 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
|
||||
import {
|
||||
DataTable,
|
||||
DashboardContentTable,
|
||||
TableSkeletonRows,
|
||||
TableSkeletonHeader,
|
||||
} from '@/components';
|
||||
import { TABLES } from '@/constants/tables';
|
||||
|
||||
import ManualJournalsEmptyStatus from './ManualJournalsEmptyStatus';
|
||||
|
||||
import { ActionsMenu } from './components';
|
||||
|
||||
import withManualJournals from './withManualJournals';
|
||||
import withManualJournalsActions from './withManualJournalsActions';
|
||||
import withAlertsActions from '@/containers/Alert/withAlertActions';
|
||||
import withDrawerActions from '@/containers/Drawer/withDrawerActions';
|
||||
import withSettings from '@/containers/Settings/withSettings';
|
||||
|
||||
import { useManualJournalsContext } from './ManualJournalsListProvider';
|
||||
import { useMemorizedColumnsWidths } from '@/hooks';
|
||||
import { useManualJournalsColumns } from './utils';
|
||||
|
||||
import { compose } from '@/utils';
|
||||
|
||||
/**
|
||||
* Manual journals data-table.
|
||||
*/
|
||||
function ManualJournalsDataTable({
|
||||
// #withManualJournalsActions
|
||||
setManualJournalsTableState,
|
||||
|
||||
// #withAlertsActions
|
||||
openAlert,
|
||||
|
||||
// #withDrawerActions
|
||||
openDrawer,
|
||||
|
||||
// #withManualJournals
|
||||
manualJournalsTableState,
|
||||
|
||||
// #ownProps
|
||||
onSelectedRowsChange,
|
||||
|
||||
// #withSettings
|
||||
manualJournalsTableSize,
|
||||
}) {
|
||||
// Manual journals context.
|
||||
const {
|
||||
manualJournals,
|
||||
pagination,
|
||||
isManualJournalsLoading,
|
||||
isManualJournalsFetching,
|
||||
isEmptyStatus,
|
||||
} = useManualJournalsContext();
|
||||
|
||||
const history = useHistory();
|
||||
|
||||
// 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 }) => {
|
||||
history.push(`/manual-journals/${id}/edit`);
|
||||
};
|
||||
|
||||
// Handle the journal delete action.
|
||||
const handleDeleteJournal = ({ id }) => {
|
||||
openAlert('journal-delete', { manualJournalId: id });
|
||||
};
|
||||
|
||||
// Handle view detail journal.
|
||||
const handleViewDetailJournal = ({ id }) => {
|
||||
openDrawer('journal-drawer', {
|
||||
manualJournalId: id,
|
||||
});
|
||||
};
|
||||
|
||||
// Handle cell click.
|
||||
const handleCellClick = (cell, event) => {
|
||||
openDrawer('journal-drawer', { manualJournalId: cell.row.original.id });
|
||||
};
|
||||
|
||||
// Local storage memorizing columns widths.
|
||||
const [initialColumnsWidths, , handleColumnResizing] =
|
||||
useMemorizedColumnsWidths(TABLES.MANUAL_JOURNALS);
|
||||
|
||||
// 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],
|
||||
);
|
||||
|
||||
// Display manual journal empty status instead of the table.
|
||||
if (isEmptyStatus) {
|
||||
return <ManualJournalsEmptyStatus />;
|
||||
}
|
||||
|
||||
return (
|
||||
<DashboardContentTable>
|
||||
<DataTable
|
||||
noInitialFetch={true}
|
||||
columns={columns}
|
||||
data={manualJournals}
|
||||
manualSortBy={true}
|
||||
selectionColumn={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}
|
||||
onCellClick={handleCellClick}
|
||||
initialColumnsWidths={initialColumnsWidths}
|
||||
onColumnResizing={handleColumnResizing}
|
||||
size={manualJournalsTableSize}
|
||||
payload={{
|
||||
onDelete: handleDeleteJournal,
|
||||
onPublish: handlePublishJournal,
|
||||
onEdit: handleEditJournal,
|
||||
onViewDetails: handleViewDetailJournal,
|
||||
}}
|
||||
/>
|
||||
</DashboardContentTable>
|
||||
);
|
||||
}
|
||||
|
||||
export default compose(
|
||||
withManualJournalsActions,
|
||||
withManualJournals(({ manualJournalsTableState }) => ({
|
||||
manualJournalsTableState,
|
||||
})),
|
||||
withAlertsActions,
|
||||
withDrawerActions,
|
||||
withSettings(({ manualJournalsSettings }) => ({
|
||||
manualJournalsTableSize: manualJournalsSettings?.tableSize,
|
||||
})),
|
||||
)(ManualJournalsDataTable);
|
||||
@@ -0,0 +1,43 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import { Button, Intent } from '@blueprintjs/core';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { Can, FormattedMessage as T, EmptyStatus } from '@/components';
|
||||
import {
|
||||
AbilitySubject,
|
||||
ManualJournalAction,
|
||||
} from '@/constants/abilityOption';
|
||||
|
||||
export default function ManualJournalsEmptyStatus() {
|
||||
const history = useHistory();
|
||||
|
||||
return (
|
||||
<EmptyStatus
|
||||
title={<T id={'manual_journals.empty_status.title'} />}
|
||||
description={
|
||||
<p>
|
||||
<T id={'manual_journals.empty_status.description'} />
|
||||
</p>
|
||||
}
|
||||
action={
|
||||
<>
|
||||
<Can I={ManualJournalAction.Create} a={AbilitySubject.ManualJournal}>
|
||||
<Button
|
||||
intent={Intent.PRIMARY}
|
||||
large={true}
|
||||
onClick={() => {
|
||||
history.push('/make-journal-entry');
|
||||
}}
|
||||
>
|
||||
<T id={'make_journal'} />
|
||||
</Button>
|
||||
|
||||
<Button intent={Intent.NONE} large={true}>
|
||||
<T id={'learn_more'} />
|
||||
</Button>
|
||||
</Can>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
|
||||
import '@/style/pages/ManualJournal/List.scss';
|
||||
|
||||
import { DashboardPageContent } from '@/components';
|
||||
import { transformTableStateToQuery, compose } from '@/utils';
|
||||
|
||||
import { ManualJournalsListProvider } from './ManualJournalsListProvider';
|
||||
import ManualJournalsViewTabs from './ManualJournalsViewTabs';
|
||||
import ManualJournalsDataTable from './ManualJournalsDataTable';
|
||||
import ManualJournalsActionsBar from './ManualJournalActionsBar';
|
||||
import withManualJournals from './withManualJournals';
|
||||
|
||||
|
||||
/**
|
||||
* Manual journals table.
|
||||
*/
|
||||
function ManualJournalsTable({
|
||||
// #withManualJournals
|
||||
journalsTableState,
|
||||
journalsTableStateChanged,
|
||||
}) {
|
||||
return (
|
||||
<ManualJournalsListProvider
|
||||
query={transformTableStateToQuery(journalsTableState)}
|
||||
tableStateChanged={journalsTableStateChanged}
|
||||
>
|
||||
<ManualJournalsActionsBar />
|
||||
|
||||
<DashboardPageContent>
|
||||
<ManualJournalsViewTabs />
|
||||
<ManualJournalsDataTable />
|
||||
</DashboardPageContent>
|
||||
</ManualJournalsListProvider>
|
||||
);
|
||||
}
|
||||
|
||||
export default compose(
|
||||
withManualJournals(
|
||||
({ manualJournalsTableState, manualJournalTableStateChanged }) => ({
|
||||
journalsTableState: manualJournalsTableState,
|
||||
journalsTableStateChanged: manualJournalTableStateChanged,
|
||||
}),
|
||||
),
|
||||
)(ManualJournalsTable);
|
||||
@@ -0,0 +1,61 @@
|
||||
// @ts-nocheck
|
||||
import React, { createContext } from 'react';
|
||||
import { isEmpty } from 'lodash';
|
||||
|
||||
import { DashboardInsider } from '@/components';
|
||||
import { useResourceViews, useResourceMeta, useJournals } from '@/hooks/query';
|
||||
import { getFieldsFromResourceMeta } from '@/utils';
|
||||
|
||||
const ManualJournalsContext = createContext();
|
||||
|
||||
function ManualJournalsListProvider({ query, tableStateChanged, ...props }) {
|
||||
// Fetches accounts resource views and fields.
|
||||
const { data: journalsViews, isLoading: isViewsLoading } =
|
||||
useResourceViews('manual_journals');
|
||||
|
||||
// Fetches the manual journals transactions with pagination meta.
|
||||
const {
|
||||
data: { manualJournals, pagination, filterMeta },
|
||||
isLoading: isManualJournalsLoading,
|
||||
isFetching: isManualJournalsFetching,
|
||||
} = useJournals(query, { keepPreviousData: true });
|
||||
|
||||
// Fetch the accounts resource fields.
|
||||
const {
|
||||
data: resourceMeta,
|
||||
isLoading: isResourceMetaLoading,
|
||||
isFetching: isResourceMetaFetching,
|
||||
} = useResourceMeta('manual_journals');
|
||||
|
||||
// Detarmines the datatable empty status.
|
||||
const isEmptyStatus =
|
||||
isEmpty(manualJournals) && !tableStateChanged && !isManualJournalsLoading;
|
||||
|
||||
// Global state.
|
||||
const state = {
|
||||
manualJournals,
|
||||
pagination,
|
||||
journalsViews,
|
||||
|
||||
resourceMeta,
|
||||
fields: getFieldsFromResourceMeta(resourceMeta.fields),
|
||||
|
||||
isManualJournalsLoading,
|
||||
isManualJournalsFetching,
|
||||
isViewsLoading,
|
||||
|
||||
isEmptyStatus,
|
||||
};
|
||||
|
||||
const isPageLoading = isViewsLoading || isResourceMetaLoading;
|
||||
|
||||
return (
|
||||
<DashboardInsider loading={isPageLoading} name={'manual-journals'}>
|
||||
<ManualJournalsContext.Provider value={state} {...props} />
|
||||
</DashboardInsider>
|
||||
);
|
||||
}
|
||||
|
||||
const useManualJournalsContext = () => React.useContext(ManualJournalsContext);
|
||||
|
||||
export { ManualJournalsListProvider, useManualJournalsContext };
|
||||
@@ -0,0 +1,61 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import { Alignment, Navbar, NavbarGroup } from '@blueprintjs/core';
|
||||
import { pick } from 'lodash';
|
||||
|
||||
import { DashboardViewsTabs } from '@/components';
|
||||
import { useManualJournalsContext } from './ManualJournalsListProvider';
|
||||
import withManualJournals from './withManualJournals';
|
||||
import withManualJournalsActions from './withManualJournalsActions';
|
||||
import withDashboardActions from '@/containers/Dashboard/withDashboardActions';
|
||||
|
||||
import { compose } from '@/utils';
|
||||
|
||||
/**
|
||||
* Manual journal views tabs.
|
||||
*/
|
||||
function ManualJournalsViewTabs({
|
||||
// #withManualJournalsActions
|
||||
setManualJournalsTableState,
|
||||
|
||||
// #withManualJournals
|
||||
journalsTableState
|
||||
}) {
|
||||
// Manual journals context.
|
||||
const { journalsViews } = useManualJournalsContext();
|
||||
|
||||
const tabs = journalsViews.map((view) => ({
|
||||
...pick(view, ['name', 'id']),
|
||||
}));
|
||||
|
||||
const handleClickNewView = () => {};
|
||||
|
||||
// Handles the tab change.
|
||||
const handleTabChange = (viewId) => {
|
||||
setManualJournalsTableState({
|
||||
customViewId: viewId || null,
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Navbar className="navbar--dashboard-views">
|
||||
<NavbarGroup align={Alignment.LEFT}>
|
||||
<DashboardViewsTabs
|
||||
resourceName={'manual-journals'}
|
||||
currentViewId={journalsTableState.customViewId}
|
||||
tabs={tabs}
|
||||
onChange={handleTabChange}
|
||||
onNewViewTabClick={handleClickNewView}
|
||||
/>
|
||||
</NavbarGroup>
|
||||
</Navbar>
|
||||
);
|
||||
}
|
||||
|
||||
export default compose(
|
||||
withManualJournalsActions,
|
||||
withDashboardActions,
|
||||
withManualJournals(({ manualJournalsTableState }) => ({
|
||||
journalsTableState: manualJournalsTableState,
|
||||
})),
|
||||
)(ManualJournalsViewTabs);
|
||||
@@ -0,0 +1,193 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import {
|
||||
Intent,
|
||||
Classes,
|
||||
Tooltip,
|
||||
Position,
|
||||
Tag,
|
||||
Button,
|
||||
MenuItem,
|
||||
Menu,
|
||||
MenuDivider,
|
||||
Popover,
|
||||
} from '@blueprintjs/core';
|
||||
import intl from 'react-intl-universal';
|
||||
|
||||
import {
|
||||
Can,
|
||||
FormattedMessage as T,
|
||||
Choose,
|
||||
Money,
|
||||
If,
|
||||
Icon,
|
||||
} from '@/components';
|
||||
import {
|
||||
ManualJournalAction,
|
||||
AbilitySubject,
|
||||
} from "@/constants/abilityOption";
|
||||
import { safeCallback } from '@/utils';
|
||||
|
||||
/**
|
||||
* Amount accessor.
|
||||
*/
|
||||
export const AmountAccessor = (r) => (
|
||||
<Tooltip
|
||||
content={
|
||||
<AmountPopoverContent
|
||||
journalEntries={r.entries}
|
||||
currencyCode={r.currency_code}
|
||||
/>
|
||||
}
|
||||
position={Position.RIGHT_TOP}
|
||||
boundary={'viewport'}
|
||||
>
|
||||
{r.amount_formatted}
|
||||
</Tooltip>
|
||||
);
|
||||
|
||||
/**
|
||||
* Amount popover content line.
|
||||
*/
|
||||
export const AmountPopoverContentLine = ({ journalEntry, currencyCode }) => {
|
||||
const isCredit = !!journalEntry.credit;
|
||||
const isDebit = !!journalEntry.debit;
|
||||
const { account } = journalEntry;
|
||||
|
||||
return (
|
||||
<Choose>
|
||||
<Choose.When condition={isDebit}>
|
||||
<div>
|
||||
C. <Money amount={journalEntry.debit} currency={currencyCode} /> -{' '}
|
||||
{account.name} <If condition={account.code}>({account.code})</If>
|
||||
</div>
|
||||
</Choose.When>
|
||||
|
||||
<Choose.When condition={isCredit}>
|
||||
<div>
|
||||
D. <Money amount={journalEntry.credit} currency={currencyCode} /> -{' '}
|
||||
{account.name} <If condition={account.code}>({account.code})</If>
|
||||
</div>
|
||||
</Choose.When>
|
||||
</Choose>
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Amount popover content.
|
||||
*/
|
||||
export function AmountPopoverContent({ journalEntries, currencyCode }) {
|
||||
const journalLinesProps = journalEntries.map((journalEntry) => ({
|
||||
journalEntry,
|
||||
accountId: journalEntry.account_id,
|
||||
}));
|
||||
|
||||
return (
|
||||
<div>
|
||||
{journalLinesProps.map(({ journalEntry, accountId }) => (
|
||||
<AmountPopoverContentLine
|
||||
journalEntry={journalEntry}
|
||||
accountId={accountId}
|
||||
currencyCode={currencyCode}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Publish column accessor.
|
||||
*/
|
||||
export const StatusAccessor = (row) => {
|
||||
return (
|
||||
<Choose>
|
||||
<Choose.When condition={!!row.is_published}>
|
||||
<Tag minimal={true} round={true}>
|
||||
<T id={'published'} />
|
||||
</Tag>
|
||||
</Choose.When>
|
||||
|
||||
<Choose.Otherwise>
|
||||
<Tag minimal={true} intent={Intent.WARNING} round={true}>
|
||||
<T id={'draft'} />
|
||||
</Tag>
|
||||
</Choose.Otherwise>
|
||||
</Choose>
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Note column accessor.
|
||||
*/
|
||||
export function NoteAccessor(row) {
|
||||
return (
|
||||
<If condition={row.description}>
|
||||
<Tooltip
|
||||
className={Classes.TOOLTIP_INDICATOR}
|
||||
content={row.description}
|
||||
position={Position.LEFT_TOP}
|
||||
hoverOpenDelay={50}
|
||||
>
|
||||
<Icon icon={'file-alt'} iconSize={16} />
|
||||
</Tooltip>
|
||||
</If>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Table actions cell.
|
||||
*/
|
||||
export const ActionsCell = (props) => {
|
||||
return (
|
||||
<Popover
|
||||
content={<ActionsMenu {...props} />}
|
||||
position={Position.RIGHT_BOTTOM}
|
||||
>
|
||||
<Button icon={<Icon icon="more-h-16" iconSize={16} />} />
|
||||
</Popover>
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Actions menu of the table.
|
||||
*/
|
||||
export const ActionsMenu = ({
|
||||
payload: { onPublish, onEdit, onDelete, onViewDetails },
|
||||
row: { original },
|
||||
}) => {
|
||||
return (
|
||||
<Menu>
|
||||
<MenuItem
|
||||
icon={<Icon icon="reader-18" />}
|
||||
text={intl.get('view_details')}
|
||||
onClick={safeCallback(onViewDetails, original)}
|
||||
/>
|
||||
<Can I={ManualJournalAction.Edit} a={AbilitySubject.ManualJournal}>
|
||||
<MenuDivider />
|
||||
<If condition={!original.is_published}>
|
||||
<MenuItem
|
||||
icon={<Icon icon="arrow-to-top" />}
|
||||
text={intl.get('publish_journal')}
|
||||
onClick={safeCallback(onPublish, original)}
|
||||
/>
|
||||
</If>
|
||||
</Can>
|
||||
<Can I={ManualJournalAction.Edit} a={AbilitySubject.ManualJournal}>
|
||||
<MenuItem
|
||||
icon={<Icon icon="pen-18" />}
|
||||
text={intl.get('edit_journal')}
|
||||
onClick={safeCallback(onEdit, original)}
|
||||
/>
|
||||
</Can>
|
||||
<Can I={ManualJournalAction.Delete} a={AbilitySubject.ManualJournal}>
|
||||
<MenuDivider />
|
||||
<MenuItem
|
||||
text={intl.get('delete_journal')}
|
||||
icon={<Icon icon="trash-16" iconSize={16} />}
|
||||
intent={Intent.DANGER}
|
||||
onClick={safeCallback(onDelete, original)}
|
||||
/>
|
||||
</Can>
|
||||
</Menu>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,77 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import intl from 'react-intl-universal';
|
||||
import clsx from 'classnames';
|
||||
|
||||
import { CLASSES } from '@/constants/classes';
|
||||
import { FormatDateCell } from '@/components';
|
||||
import { NoteAccessor, StatusAccessor } from './components';
|
||||
|
||||
/**
|
||||
* Retrieve the manual journals columns.
|
||||
*/
|
||||
export const useManualJournalsColumns = () => {
|
||||
return React.useMemo(
|
||||
() => [
|
||||
{
|
||||
id: 'date',
|
||||
Header: intl.get('date'),
|
||||
accessor: 'date',
|
||||
Cell: FormatDateCell,
|
||||
width: 115,
|
||||
className: 'date',
|
||||
clickable: true,
|
||||
},
|
||||
{
|
||||
id: 'amount',
|
||||
Header: intl.get('amount'),
|
||||
accessor: 'formatted_amount',
|
||||
width: 115,
|
||||
clickable: true,
|
||||
align: 'right',
|
||||
className: clsx(CLASSES.FONT_BOLD),
|
||||
},
|
||||
{
|
||||
id: 'journal_number',
|
||||
Header: intl.get('journal_no'),
|
||||
accessor: (row) => `${row.journal_number}`,
|
||||
className: 'journal_number',
|
||||
width: 100,
|
||||
clickable: true,
|
||||
textOverview: true,
|
||||
},
|
||||
{
|
||||
id: 'journal_type',
|
||||
Header: intl.get('journal_type'),
|
||||
accessor: 'journal_type',
|
||||
width: 110,
|
||||
clickable: true,
|
||||
textOverview: true,
|
||||
},
|
||||
{
|
||||
id: 'status',
|
||||
Header: intl.get('publish'),
|
||||
accessor: (row) => StatusAccessor(row),
|
||||
width: 95,
|
||||
clickable: true,
|
||||
},
|
||||
{
|
||||
id: 'note',
|
||||
Header: intl.get('note'),
|
||||
accessor: NoteAccessor,
|
||||
disableSortBy: true,
|
||||
width: 85,
|
||||
clickable: true,
|
||||
},
|
||||
{
|
||||
id: 'created_at',
|
||||
Header: intl.get('created_at'),
|
||||
accessor: 'created_at',
|
||||
Cell: FormatDateCell,
|
||||
width: 125,
|
||||
clickable: true,
|
||||
},
|
||||
],
|
||||
[],
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,24 @@
|
||||
// @ts-nocheck
|
||||
import { connect } from 'react-redux';
|
||||
import {
|
||||
getManualJournalsTableStateFactory,
|
||||
manualJournalTableStateChangedFactory,
|
||||
} from '@/store/manualJournals/manualJournals.selectors';
|
||||
|
||||
export default (mapState) => {
|
||||
const getJournalsTableQuery = getManualJournalsTableStateFactory();
|
||||
const manualJournalTableStateChanged =
|
||||
manualJournalTableStateChangedFactory();
|
||||
|
||||
const mapStateToProps = (state, props) => {
|
||||
const mapped = {
|
||||
manualJournalsTableState: getJournalsTableQuery(state, props),
|
||||
manualJournalTableStateChanged: manualJournalTableStateChanged(
|
||||
state,
|
||||
props,
|
||||
),
|
||||
};
|
||||
return mapState ? mapState(mapped, state, props) : mapped;
|
||||
};
|
||||
return connect(mapStateToProps);
|
||||
};
|
||||
@@ -0,0 +1,12 @@
|
||||
// @ts-nocheck
|
||||
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);
|
||||
Reference in New Issue
Block a user