re-structure to monorepo.

This commit is contained in:
a.bouhuolia
2023-02-03 01:02:31 +02:00
parent 8242ec64ba
commit 7a0a13f9d5
10400 changed files with 46966 additions and 17223 deletions

View File

@@ -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);

View File

@@ -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 },
];

View File

@@ -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);

View File

@@ -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>
</>
}
/>
);
}

View File

@@ -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);

View File

@@ -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 };

View File

@@ -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);

View File

@@ -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>
);
};

View File

@@ -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,
},
],
[],
);
};

View File

@@ -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);
};

View File

@@ -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);

View File

@@ -0,0 +1,43 @@
// @ts-nocheck
import * as Yup from 'yup';
import intl from 'react-intl-universal';
import { DATATYPES_LENGTH } from '@/constants/dataTypes';
const Schema = Yup.object().shape({
journal_number: Yup.string()
.required()
.min(1)
.max(DATATYPES_LENGTH.STRING)
.label(intl.get('journal_number_')),
journal_type: Yup.string()
.required()
.min(1)
.max(DATATYPES_LENGTH.STRING)
.label(intl.get('journal_type')),
date: Yup.date().required().label(intl.get('date')),
currency_code: Yup.string().max(3),
publish: Yup.boolean(),
branch_id: Yup.string(),
reference: Yup.string().nullable().min(1).max(DATATYPES_LENGTH.STRING),
description: Yup.string().min(1).max(DATATYPES_LENGTH.STRING).nullable(),
exchange_rate: Yup.number(),
entries: Yup.array().of(
Yup.object().shape({
credit: Yup.number().nullable(),
debit: Yup.number().nullable(),
account_id: Yup.number()
.nullable()
.when(['credit', 'debit'], {
is: (credit, debit) => credit || debit,
then: Yup.number().required(),
}),
contact_id: Yup.number().nullable(),
contact_type: Yup.string().nullable(),
project_id: Yup.number().nullable(),
note: Yup.string().max(DATATYPES_LENGTH.TEXT).nullable(),
}),
),
});
export const CreateJournalSchema = Schema;
export const EditJournalSchema = Schema;

View File

@@ -0,0 +1,50 @@
// @ts-nocheck
import React from 'react';
import { FastField } from 'formik';
import classNames from 'classnames';
import { CLASSES } from '@/constants/classes';
import {
entriesFieldShouldUpdate,
defaultEntry,
MIN_LINES_NUMBER,
} from './utils';
import { useMakeJournalFormContext } from './MakeJournalProvider';
import MakeJournalEntriesTable from './MakeJournalEntriesTable';
/**
* Make journal entries field.
*/
export default function MakeJournalEntriesField() {
const { accounts, contacts, branches, projects } =
useMakeJournalFormContext();
return (
<div className={classNames(CLASSES.PAGE_FORM_BODY)}>
<FastField
name={'entries'}
contacts={contacts}
accounts={accounts}
branches={branches}
projects={projects}
shouldUpdate={entriesFieldShouldUpdate}
>
{({
form: { values, setFieldValue },
field: { value },
meta: { error, touched },
}) => (
<MakeJournalEntriesTable
onChange={(entries) => {
setFieldValue('entries', entries);
}}
entries={value}
defaultEntry={defaultEntry}
initialLinesNumber={MIN_LINES_NUMBER}
error={error}
currencyCode={values.currency_code}
/>
)}
</FastField>
</div>
);
}

View File

@@ -0,0 +1,193 @@
// @ts-nocheck
import React from 'react';
import {
Intent,
Button,
ButtonGroup,
Popover,
PopoverInteractionKind,
Position,
Menu,
MenuItem,
} from '@blueprintjs/core';
import classNames from 'classnames';
import { useFormikContext } from 'formik';
import { FormattedMessage as T, If, Icon } from '@/components';
import { CLASSES } from '@/constants/classes';
import { useMakeJournalFormContext } from './MakeJournalProvider';
import { useHistory } from 'react-router-dom';
/**
* Make Journal floating actions bar.
*/
export default function MakeJournalEntriesFooter() {
const history = useHistory();
// Formik context.
const { isSubmitting, submitForm } = useFormikContext();
// Make journal form context.
const {
manualJournalId,
setSubmitPayload,
manualJournalPublished = false,
} = useMakeJournalFormContext();
// Handle `submit & publish` button click.
const handleSubmitPublishBtnClick = (event) => {
setSubmitPayload({ redirect: true, publish: true });
submitForm();
};
// Handle `submit, publish & new` button click.
const handleSubmitPublishAndNewBtnClick = (event) => {
setSubmitPayload({ redirect: false, publish: true, resetForm: true });
submitForm();
};
// Handle `submit, publish & continue editing` button click.
const handleSubmitPublishContinueEditingBtnClick = (event) => {
setSubmitPayload({ redirect: false, publish: true });
submitForm();
};
// Handle `submit as draft` button click.
const handleSubmitDraftBtnClick = (event) => {
setSubmitPayload({ redirect: true, publish: false });
};
// Handle `submit as draft & new` button click.
const handleSubmitDraftAndNewBtnClick = (event) => {
setSubmitPayload({ redirect: false, publish: false, resetForm: true });
submitForm();
};
// Handles submit as draft & continue editing button click.
const handleSubmitDraftContinueEditingBtnClick = (event) => {
setSubmitPayload({ redirect: false, publish: false });
submitForm();
};
// Handle cancel button action click.
const handleCancelBtnClick = (event) => {
history.goBack();
};
const handleClearBtnClick = (event) => {};
return (
<div className={classNames(CLASSES.PAGE_FORM_FLOATING_ACTIONS)}>
{/* ----------- Save And Publish ----------- */}
<If condition={!manualJournalId || !manualJournalPublished}>
<ButtonGroup>
<Button
disabled={isSubmitting}
intent={Intent.PRIMARY}
type="submit"
onClick={handleSubmitPublishBtnClick}
text={<T id={'save_publish'} />}
/>
<Popover
content={
<Menu>
<MenuItem
text={<T id={'publish_and_new'} />}
onClick={handleSubmitPublishAndNewBtnClick}
/>
<MenuItem
text={<T id={'publish_continue_editing'} />}
onClick={handleSubmitPublishContinueEditingBtnClick}
/>
</Menu>
}
minimal={true}
interactionKind={PopoverInteractionKind.CLICK}
position={Position.BOTTOM_LEFT}
>
<Button
disabled={isSubmitting}
intent={Intent.PRIMARY}
rightIcon={<Icon icon="arrow-drop-up-16" iconSize={20} />}
/>
</Popover>
</ButtonGroup>
{/* ----------- Save As Draft ----------- */}
<ButtonGroup>
<Button
disabled={isSubmitting}
className={'ml1'}
type="submit"
onClick={handleSubmitDraftBtnClick}
text={<T id={'save_as_draft'} />}
/>
<Popover
content={
<Menu>
<MenuItem
text={<T id={'save_and_new'} />}
onClick={handleSubmitDraftAndNewBtnClick}
/>
<MenuItem
text={<T id={'save_continue_editing'} />}
onClick={handleSubmitDraftContinueEditingBtnClick}
/>
</Menu>
}
minimal={true}
interactionKind={PopoverInteractionKind.CLICK}
position={Position.BOTTOM_LEFT}
>
<Button
disabled={isSubmitting}
rightIcon={<Icon icon="arrow-drop-up-16" iconSize={20} />}
/>
</Popover>
</ButtonGroup>
</If>
{/* ----------- Save and New ----------- */}
<If condition={manualJournalId && manualJournalPublished}>
<ButtonGroup>
<Button
disabled={isSubmitting}
intent={Intent.PRIMARY}
type="submit"
onClick={handleSubmitPublishBtnClick}
text={<T id={'save'} />}
/>
<Popover
content={
<Menu>
<MenuItem
text={<T id={'save_and_new'} />}
onClick={handleSubmitPublishAndNewBtnClick}
/>
</Menu>
}
minimal={true}
interactionKind={PopoverInteractionKind.CLICK}
position={Position.BOTTOM_LEFT}
>
<Button
disabled={isSubmitting}
intent={Intent.PRIMARY}
rightIcon={<Icon icon="arrow-drop-up-16" iconSize={20} />}
/>
</Popover>
</ButtonGroup>
</If>
{/* ----------- Clear & Reset----------- */}
<Button
className={'ml1'}
disabled={isSubmitting}
onClick={handleClearBtnClick}
text={manualJournalId ? <T id={'reset'} /> : <T id={'clear'} />}
/>
{/* ----------- Cancel ----------- */}
<Button
className={'ml1'}
onClick={handleCancelBtnClick}
text={<T id={'cancel'} />}
/>
</div>
);
}

View File

@@ -0,0 +1,195 @@
// @ts-nocheck
import React, { useMemo } from 'react';
import { Formik, Form } from 'formik';
import { Intent } from '@blueprintjs/core';
import intl from 'react-intl-universal';
import * as R from 'ramda';
import { defaultTo, isEmpty, omit } from 'lodash';
import classNames from 'classnames';
import { useHistory } from 'react-router-dom';
import { CLASSES } from '@/constants/classes';
import {
CreateJournalSchema,
EditJournalSchema,
} from './MakeJournalEntries.schema';
import { useMakeJournalFormContext } from './MakeJournalProvider';
import MakeJournalEntriesHeader from './MakeJournalEntriesHeader';
import MakeJournalFormFloatingActions from './MakeJournalFormFloatingActions';
import MakeJournalEntriesField from './MakeJournalEntriesField';
import MakeJournalFormFooter from './MakeJournalFormFooter';
import MakeJournalFormDialogs from './MakeJournalFormDialogs';
import MakeJournalFormTopBar from './MakeJournalFormTopBar';
import withSettings from '@/containers/Settings/withSettings';
import withCurrentOrganization from '@/containers/Organization/withCurrentOrganization';
import { AppToaster } from '@/components';
import { compose, orderingLinesIndexes, transactionNumber } from '@/utils';
import {
transformErrors,
transformToEditForm,
defaultManualJournal,
} from './utils';
/**
* Journal entries form.
*/
function MakeJournalEntriesForm({
// #withSettings
journalNextNumber,
journalNumberPrefix,
journalAutoIncrement,
// #withCurrentOrganization
organization: { base_currency },
}) {
// Journal form context.
const {
createJournalMutate,
editJournalMutate,
isNewMode,
manualJournal,
submitPayload,
} = useMakeJournalFormContext();
const history = useHistory();
// New journal number.
const journalNumber = transactionNumber(
journalNumberPrefix,
journalNextNumber,
);
// Form initial values.
const initialValues = useMemo(
() => ({
...(!isEmpty(manualJournal)
? {
...transformToEditForm(manualJournal),
}
: {
...defaultManualJournal,
...(journalAutoIncrement && {
journal_number: journalNumber,
}),
currency_code: base_currency,
}),
}),
[manualJournal, base_currency, journalNumber, journalAutoIncrement],
);
// Handle the form submiting.
const handleSubmit = (values, { setErrors, setSubmitting, resetForm }) => {
setSubmitting(true);
const entries = values.entries.filter(
(entry) => entry.debit || entry.credit,
);
const getTotal = (type = 'credit') => {
return entries.reduce((total, item) => {
return item[type] ? item[type] + total : total;
}, 0);
};
const totalCredit = getTotal('credit');
const totalDebit = getTotal('debit');
// Validate the total credit should be eqials total debit.
if (totalCredit !== totalDebit) {
AppToaster.show({
message: intl.get('should_total_of_credit_and_debit_be_equal'),
intent: Intent.DANGER,
});
setSubmitting(false);
return;
} else if (totalCredit === 0 || totalDebit === 0) {
AppToaster.show({
message: intl.get('amount_cannot_be_zero_or_empty'),
intent: Intent.DANGER,
});
setSubmitting(false);
return;
}
const form = {
...omit(values, ['journal_number_manually']),
...(values.journal_number_manually && {
journal_number: values.journal_number,
}),
entries: R.compose(orderingLinesIndexes)(entries),
publish: submitPayload.publish,
};
// Handle the request error.
const handleError = ({
response: {
data: { errors },
},
}) => {
transformErrors(errors, { setErrors });
setSubmitting(false);
};
// Handle the request success.
const handleSuccess = (errors) => {
AppToaster.show({
message: intl.get(
isNewMode
? 'the_journal_has_been_created_successfully'
: 'the_journal_has_been_edited_successfully',
{ number: values.journal_number },
),
intent: Intent.SUCCESS,
});
setSubmitting(false);
if (submitPayload.redirect) {
history.push('/manual-journals');
}
if (submitPayload.resetForm) {
resetForm();
}
};
if (isNewMode) {
createJournalMutate(form).then(handleSuccess).catch(handleError);
} else {
editJournalMutate([manualJournal.id, form])
.then(handleSuccess)
.catch(handleError);
}
};
return (
<div
className={classNames(
CLASSES.PAGE_FORM,
CLASSES.PAGE_FORM_STRIP_STYLE,
CLASSES.PAGE_FORM_MAKE_JOURNAL,
)}
>
<Formik
initialValues={initialValues}
validationSchema={isNewMode ? CreateJournalSchema : EditJournalSchema}
onSubmit={handleSubmit}
>
<Form>
<MakeJournalFormTopBar />
<MakeJournalEntriesHeader />
<MakeJournalEntriesField />
<MakeJournalFormFooter />
<MakeJournalFormFloatingActions />
{/* --------- Dialogs --------- */}
<MakeJournalFormDialogs />
</Form>
</Formik>
</div>
);
}
export default compose(
withSettings(({ manualJournalsSettings }) => ({
journalNextNumber: manualJournalsSettings?.nextNumber,
journalNumberPrefix: manualJournalsSettings?.numberPrefix,
journalAutoIncrement: manualJournalsSettings?.autoIncrement,
})),
withCurrentOrganization(),
)(MakeJournalEntriesForm);

View File

@@ -0,0 +1,30 @@
// @ts-nocheck
import React from 'react';
import classNames from 'classnames';
import { useFormikContext } from 'formik';
import { CLASSES } from '@/constants/classes';
import { safeSumBy } from '@/utils';
import { PageFormBigNumber, FormattedMessage as T } from '@/components';
import MakeJournalEntriesHeaderFields from './MakeJournalEntriesHeaderFields';
export default function MakeJournalEntriesHeader() {
const {
values: { entries, currency_code },
} = useFormikContext();
const totalCredit = safeSumBy(entries, 'credit');
const totalDebit = safeSumBy(entries, 'debit');
const total = Math.max(totalCredit, totalDebit);
return (
<div className={classNames(CLASSES.PAGE_FORM_HEADER)}>
<MakeJournalEntriesHeaderFields />
<PageFormBigNumber
label={<T id={'amount'} />}
amount={total}
currencyCode={currency_code}
/>
</div>
);
}

View File

@@ -0,0 +1,230 @@
// @ts-nocheck
import React from 'react';
import {
InputGroup,
FormGroup,
Position,
ControlGroup,
} from '@blueprintjs/core';
import { FastField, ErrorMessage } from 'formik';
import { DateInput } from '@blueprintjs/datetime';
import classNames from 'classnames';
import { CLASSES } from '@/constants/classes';
import {
momentFormatter,
compose,
inputIntent,
handleDateChange,
tansformDateValue,
} from '@/utils';
import {
Hint,
FieldHint,
FieldRequiredHint,
Icon,
InputPrependButton,
CurrencySelectList,
FormattedMessage as T
} from '@/components';
import { useMakeJournalFormContext } from './MakeJournalProvider';
import { JournalExchangeRateInputField } from './components';
import withSettings from '@/containers/Settings/withSettings';
import withDialogActions from '@/containers/Dialog/withDialogActions';
import {
currenciesFieldShouldUpdate,
useObserveJournalNoSettings,
} from './utils';
/**
* Make journal entries header.
*/
function MakeJournalEntriesHeader({
// #ownProps
onJournalNumberChanged,
// #withDialog
openDialog,
// #withSettings
journalAutoIncrement,
journalNextNumber,
journalNumberPrefix,
}) {
const { currencies } = useMakeJournalFormContext();
// Handle journal number change.
const handleJournalNumberChange = () => {
openDialog('journal-number-form');
};
// Handle journal number blur.
const handleJournalNoBlur = (form, field) => (event) => {
const newValue = event.target.value;
if (field.value !== newValue && journalAutoIncrement) {
openDialog('journal-number-form', {
initialFormValues: {
manualTransactionNo: newValue,
incrementMode: 'manual-transaction',
},
});
}
};
useObserveJournalNoSettings(journalNumberPrefix, journalNextNumber);
return (
<div className={classNames(CLASSES.PAGE_FORM_HEADER_FIELDS)}>
{/*------------ Posting date -----------*/}
<FastField name={'date'}>
{({ form, field: { value }, meta: { error, touched } }) => (
<FormGroup
label={<T id={'posting_date'} />}
labelInfo={<FieldRequiredHint />}
intent={inputIntent({ error, touched })}
helperText={<ErrorMessage name="date" />}
minimal={true}
inline={true}
className={classNames(CLASSES.FILL)}
>
<DateInput
{...momentFormatter('YYYY/MM/DD')}
onChange={handleDateChange((formattedDate) => {
form.setFieldValue('date', formattedDate);
})}
value={tansformDateValue(value)}
popoverProps={{
position: Position.BOTTOM,
minimal: true,
}}
inputProps={{
leftIcon: <Icon icon={'date-range'} />,
}}
/>
</FormGroup>
)}
</FastField>
{/*------------ Journal number -----------*/}
<FastField name={'journal_number'}>
{({ form, field, meta: { error, touched } }) => (
<FormGroup
label={<T id={'journal_no'} />}
labelInfo={
<>
<FieldRequiredHint />
<FieldHint />
</>
}
className={'form-group--journal-number'}
intent={inputIntent({ error, touched })}
helperText={<ErrorMessage name="journal_number" />}
fill={true}
inline={true}
>
<ControlGroup fill={true}>
<InputGroup
fill={true}
value={field.value}
asyncControl={true}
onBlur={handleJournalNoBlur(form, field)}
/>
<InputPrependButton
buttonProps={{
onClick: handleJournalNumberChange,
icon: <Icon icon={'settings-18'} />,
}}
tooltip={true}
tooltipProps={{
content: (
<T id={'setting_your_auto_generated_journal_number'} />
),
position: Position.BOTTOM_LEFT,
}}
/>
</ControlGroup>
</FormGroup>
)}
</FastField>
{/*------------ Reference -----------*/}
<FastField name={'reference'}>
{({ form, field, meta: { error, touched } }) => (
<FormGroup
label={<T id={'reference'} />}
labelInfo={
<Hint
content={<T id={'journal_reference_hint'} />}
position={Position.RIGHT}
/>
}
className={'form-group--reference'}
intent={inputIntent({ error, touched })}
helperText={<ErrorMessage name="reference" />}
fill={true}
inline={true}
>
<InputGroup fill={true} {...field} />
</FormGroup>
)}
</FastField>
{/*------------ Journal type -----------*/}
<FastField name={'journal_type'}>
{({ form, field, meta: { error, touched } }) => (
<FormGroup
label={<T id={'journal_type'} />}
className={classNames('form-group--account-type', CLASSES.FILL)}
inline={true}
>
<InputGroup
intent={inputIntent({ error, touched })}
fill={true}
{...field}
/>
</FormGroup>
)}
</FastField>
{/*------------ Currency -----------*/}
<FastField
name={'currency_code'}
currencies={currencies}
shouldUpdate={currenciesFieldShouldUpdate}
>
{({ form, field: { value }, meta: { error, touched } }) => (
<FormGroup
label={<T id={'currency'} />}
className={classNames('form-group--currency', CLASSES.FILL)}
inline={true}
>
<CurrencySelectList
currenciesList={currencies}
selectedCurrencyCode={value}
onCurrencySelected={(currencyItem) => {
form.setFieldValue('currency_code', currencyItem.currency_code);
form.setFieldValue('exchange_rate', '');
}}
defaultSelectText={value}
/>
</FormGroup>
)}
</FastField>
{/* ----------- Exchange rate ----------- */}
<JournalExchangeRateInputField
name={'exchange_rate'}
formGroupProps={{ label: ' ', inline: true }}
/>
</div>
);
}
export default compose(
withDialogActions,
withSettings(({ manualJournalsSettings }) => ({
journalAutoIncrement: manualJournalsSettings?.autoIncrement,
journalNextNumber: manualJournalsSettings?.nextNumber,
journalNumberPrefix: manualJournalsSettings?.numberPrefix,
})),
)(MakeJournalEntriesHeader);

View File

@@ -0,0 +1,21 @@
// @ts-nocheck
import React from 'react';
import { useParams } from 'react-router-dom';
import '@/style/pages/ManualJournal/MakeJournal.scss';
import MakeJournalEntriesForm from './MakeJournalEntriesForm';
import { MakeJournalProvider } from './MakeJournalProvider';
/**
* Make journal entries page.
*/
export default function MakeJournalEntriesPage() {
const { id: journalId } = useParams();
return (
<MakeJournalProvider journalId={journalId}>
<MakeJournalEntriesForm />
</MakeJournalProvider>
);
}

View File

@@ -0,0 +1,80 @@
// @ts-nocheck
import React from 'react';
import { DataTableEditable } from '@/components';
import {
compose,
saveInvoke,
updateMinEntriesLines,
updateRemoveLineByIndex,
updateAutoAddNewLine,
updateTableCell,
} from '@/utils';
import { useMakeJournalFormContext } from './MakeJournalProvider';
import { useJournalTableEntriesColumns } from './components';
import { updateAdjustEntries } from './utils';
/**
* Make journal entries table component.
*/
export default function MakeJournalEntriesTable({
// #ownPorps
onChange,
entries,
defaultEntry,
error,
initialLinesNumber = 1,
minLinesNumber = 1,
currencyCode,
}) {
const { accounts, contacts, branches, projects } =
useMakeJournalFormContext();
// Memorized data table columns.
const columns = useJournalTableEntriesColumns();
// Handles update datatable data.
const handleUpdateData = (rowIndex, columnId, value) => {
const newRows = compose(
// Auto-adding new lines.
updateAutoAddNewLine(defaultEntry, ['account_id', 'credit', 'debit']),
// Update items entries total.
updateAdjustEntries(rowIndex, columnId, value),
// Update entry of the given row index and column id.
updateTableCell(rowIndex, columnId, value),
)(entries);
saveInvoke(onChange, newRows);
};
// Handle remove datatable row.
const handleRemoveRow = (rowIndex) => {
const newRows = compose(
// Ensure minimum lines count.
updateMinEntriesLines(minLinesNumber, defaultEntry),
// Remove the line by the given index.
updateRemoveLineByIndex(rowIndex),
)(entries);
saveInvoke(onChange, newRows);
};
return (
<DataTableEditable
columns={columns}
data={entries}
sticky={true}
totalRow={true}
payload={{
accounts,
errors: error,
updateData: handleUpdateData,
removeRow: handleRemoveRow,
contacts,
branches,
projects,
autoFocus: ['account_id', 0],
currencyCode,
}}
/>
);
}

View File

@@ -0,0 +1,26 @@
// @ts-nocheck
import React from 'react';
import { useFormikContext } from 'formik';
import JournalNumberDialog from '@/containers/Dialogs/JournalNumberDialog';
/**
* Make journal form dialogs.
*/
export default function MakeJournalFormDialogs() {
const { setFieldValue } = useFormikContext();
// Update the form once the journal number form submit confirm.
const handleConfirm = ({ manually, incrementNumber }) => {
setFieldValue('journal_number', incrementNumber || '');
setFieldValue('journal_number_manually', manually);
};
return (
<>
<JournalNumberDialog
dialogName={'journal-number-form'}
onConfirm={handleConfirm}
/>
</>
);
}

View File

@@ -0,0 +1,193 @@
// @ts-nocheck
import React from 'react';
import {
Intent,
Button,
ButtonGroup,
Popover,
PopoverInteractionKind,
Position,
Menu,
MenuItem,
} from '@blueprintjs/core';
import { useHistory } from 'react-router-dom';
import { useFormikContext } from 'formik';
import classNames from 'classnames';
import { Icon, If, FormattedMessage as T } from '@/components';
import { CLASSES } from '@/constants/classes';
import { useMakeJournalFormContext } from './MakeJournalProvider';
/**
* Make Journal floating actions bar.
*/
export default function MakeJournalFloatingAction() {
const history = useHistory();
// Formik context.
const { submitForm, resetForm, isSubmitting } = useFormikContext();
// Make journal form context.
const { setSubmitPayload, manualJournal } = useMakeJournalFormContext();
// Handle submit & publish button click.
const handleSubmitPublishBtnClick = (event) => {
submitForm();
setSubmitPayload({ redirect: true, publish: true });
};
// Handle submit, publish & new button click.
const handleSubmitPublishAndNewBtnClick = (event) => {
submitForm();
setSubmitPayload({ redirect: false, publish: true, resetForm: true });
};
// Handle submit, publish & edit button click.
const handleSubmitPublishContinueEditingBtnClick = (event) => {
submitForm();
setSubmitPayload({ redirect: false, publish: true });
};
// Handle submit as draft button click.
const handleSubmitDraftBtnClick = (event) => {
submitForm();
setSubmitPayload({ redirect: true, publish: false });
};
// Handle submit as draft & new button click.
const handleSubmitDraftAndNewBtnClick = (event) => {
submitForm();
setSubmitPayload({ redirect: false, publish: false, resetForm: true });
};
// Handle submit as draft & continue editing button click.
const handleSubmitDraftContinueEditingBtnClick = (event) => {
submitForm();
setSubmitPayload({ redirect: false, publish: false });
};
// Handle cancel button click.
const handleCancelBtnClick = (event) => {
history.goBack();
};
// Handle clear button click.
const handleClearBtnClick = (event) => {
resetForm();
};
return (
<div className={classNames(CLASSES.PAGE_FORM_FLOATING_ACTIONS)}>
{/* ----------- Save And Publish ----------- */}
<If condition={!manualJournal || !manualJournal?.is_published}>
<ButtonGroup>
<Button
loading={isSubmitting}
disabled={isSubmitting}
intent={Intent.PRIMARY}
onClick={handleSubmitPublishBtnClick}
text={<T id={'save_publish'} />}
/>
<Popover
content={
<Menu>
<MenuItem
text={<T id={'publish_and_new'} />}
onClick={handleSubmitPublishAndNewBtnClick}
/>
<MenuItem
text={<T id={'publish_continue_editing'} />}
onClick={handleSubmitPublishContinueEditingBtnClick}
/>
</Menu>
}
minimal={true}
interactionKind={PopoverInteractionKind.CLICK}
position={Position.BOTTOM_LEFT}
>
<Button
intent={Intent.PRIMARY}
rightIcon={<Icon icon="arrow-drop-up-16" iconSize={20} />}
disabled={isSubmitting}
/>
</Popover>
</ButtonGroup>
{/* ----------- Save As Draft ----------- */}
<ButtonGroup>
<Button
disabled={isSubmitting}
className={'ml1'}
onClick={handleSubmitDraftBtnClick}
text={<T id={'save_as_draft'} />}
/>
<Popover
content={
<Menu>
<MenuItem
text={<T id={'save_and_new'} />}
onClick={handleSubmitDraftAndNewBtnClick}
/>
<MenuItem
text={<T id={'save_continue_editing'} />}
onClick={handleSubmitDraftContinueEditingBtnClick}
/>
</Menu>
}
minimal={true}
interactionKind={PopoverInteractionKind.CLICK}
position={Position.BOTTOM_LEFT}
>
<Button
rightIcon={<Icon icon="arrow-drop-up-16" iconSize={20} />}
disabled={isSubmitting}
/>
</Popover>
</ButtonGroup>
</If>
{/* ----------- Save and New ----------- */}
<If condition={manualJournal && manualJournal?.is_published}>
<ButtonGroup>
<Button
loading={isSubmitting}
disabled={isSubmitting}
intent={Intent.PRIMARY}
onClick={handleSubmitPublishBtnClick}
style={{ minWidth: '85px' }}
text={<T id={'save'} />}
/>
<Popover
content={
<Menu>
<MenuItem
text={<T id={'save_and_new'} />}
onClick={handleSubmitPublishAndNewBtnClick}
/>
</Menu>
}
minimal={true}
interactionKind={PopoverInteractionKind.CLICK}
position={Position.BOTTOM_LEFT}
>
<Button
intent={Intent.PRIMARY}
rightIcon={<Icon icon="arrow-drop-up-16" iconSize={20} />}
disabled={isSubmitting}
/>
</Popover>
</ButtonGroup>
</If>
{/* ----------- Clear & Reset----------- */}
<Button
className={'ml1'}
disabled={isSubmitting}
onClick={handleClearBtnClick}
text={manualJournal ? <T id={'reset'} /> : <T id={'clear'} />}
/>
{/* ----------- Cancel ----------- */}
<Button
className={'ml1'}
onClick={handleCancelBtnClick}
text={<T id={'cancel'} />}
/>
</div>
);
}

View File

@@ -0,0 +1,30 @@
// @ts-nocheck
import React from 'react';
import classNames from 'classnames';
import styled from 'styled-components';
import { CLASSES } from '@/constants/classes';
import { Row, Col, Paper } from '@/components';
import { MakeJournalFormFooterLeft } from './MakeJournalFormFooterLeft';
import { MakeJournalFormFooterRight } from './MakeJournalFormFooterRight';
export default function MakeJournalFormFooter() {
return (
<div className={classNames(CLASSES.PAGE_FORM_FOOTER)}>
<MakeJournalFooterPaper>
<Row>
<Col md={8}>
<MakeJournalFormFooterLeft />
</Col>
<Col md={4}>
<MakeJournalFormFooterRight />
</Col>
</Row>
</MakeJournalFooterPaper>
</div>
);
}
const MakeJournalFooterPaper = styled(Paper)`
padding: 20px;
`;

View File

@@ -0,0 +1,33 @@
// @ts-nocheck
import React from 'react';
import styled from 'styled-components';
import { FFormGroup, FEditableText, FormattedMessage as T } from '@/components';
export function MakeJournalFormFooterLeft() {
return (
<React.Fragment>
{/* --------- Description --------- */}
<DescriptionFormGroup
label={<T id={'description'} />}
name={'description'}
>
<FEditableText
name={'description'}
placeholder={<T id={'make_jorunal.decscrption.placeholder'} />}
/>
</DescriptionFormGroup>
</React.Fragment>
);
}
const DescriptionFormGroup = styled(FFormGroup)`
&.bp3-form-group {
.bp3-label {
font-size: 12px;
margin-bottom: 12px;
}
.bp3-form-content {
margin-left: 10px;
}
}
`;

View File

@@ -0,0 +1,35 @@
// @ts-nocheck
import React from 'react';
import styled from 'styled-components';
import {
T,
TotalLines,
TotalLine,
TotalLineBorderStyle,
TotalLineTextStyle,
} from '@/components';
import { useJournalTotals } from './utils';
export function MakeJournalFormFooterRight() {
const { formattedSubtotal, formattedTotal } = useJournalTotals();
return (
<MakeJouranlTotalLines>
<TotalLine
title={<T id={'make_journal.label.subtotal'} />}
value={formattedSubtotal}
borderStyle={TotalLineBorderStyle.None}
/>
<TotalLine
title={<T id={'make_journal.label.total'} />}
value={formattedTotal}
textStyle={TotalLineTextStyle.Bold}
/>
</MakeJouranlTotalLines>
);
}
const MakeJouranlTotalLines =styled(TotalLines)`
width: 100%;
color: #555555;
`;

View File

@@ -0,0 +1,68 @@
// @ts-nocheck
import React from 'react';
import intl from 'react-intl-universal';
import { Button, Alignment, NavbarGroup, Classes } from '@blueprintjs/core';
import { useSetPrimaryBranchToForm } from './utils';
import { Features } from '@/constants';
import { useFeatureCan } from '@/hooks/state';
import {
Icon,
BranchSelect,
FeatureCan,
FormTopbar,
DetailsBarSkeletonBase,
} from '@/components';
import { useMakeJournalFormContext } from './MakeJournalProvider';
/**
* Make journal form topbar.
* @returns
*/
export default function MakeJournalFormTopBar() {
// Features guard.
const { featureCan } = useFeatureCan();
// Sets the primary branch to form.
useSetPrimaryBranchToForm();
// Can't display the navigation bar if branches feature is not enabled.
if (!featureCan(Features.Branches)) {
return null;
}
return (
<FormTopbar>
<NavbarGroup align={Alignment.LEFT}>
<FeatureCan feature={Features.Branches}>
<MakeJournalFormSelectBranch />
</FeatureCan>
</NavbarGroup>
</FormTopbar>
);
}
function MakeJournalFormSelectBranch() {
// Invoice form context.
const { branches, isBranchesLoading } = useMakeJournalFormContext();
return isBranchesLoading ? (
<DetailsBarSkeletonBase className={Classes.SKELETON} />
) : (
<BranchSelect
name={'branch_id'}
branches={branches}
input={MakeJournalBranchSelectButton}
popoverProps={{ minimal: true }}
/>
);
}
function MakeJournalBranchSelectButton({ label }) {
return (
<Button
text={intl.get('make_journal.branch_button.label', { label })}
minimal={true}
small={true}
icon={<Icon icon={'branch-16'} iconSize={16} />}
/>
);
}

View File

@@ -0,0 +1,116 @@
// @ts-nocheck
import React, { createContext, useState } from 'react';
import { Features } from '@/constants';
import { useFeatureCan } from '@/hooks/state';
import { DashboardInsider } from '@/components';
import {
useAccounts,
useAutoCompleteContacts,
useCurrencies,
useJournal,
useCreateJournal,
useEditJournal,
useBranches,
useSettingsManualJournals,
} from '@/hooks/query';
import { useProjects } from '@/containers/Projects/hooks';
const MakeJournalFormContext = createContext();
/**
* Make journal form provider.
*/
function MakeJournalProvider({ journalId, query, ...props }) {
// Features guard.
const { featureCan } = useFeatureCan();
const isBranchFeatureCan = featureCan(Features.Branches);
const isProjectFeatureCan = featureCan(Features.Projects);
// Load the accounts list.
const { data: accounts, isLoading: isAccountsLoading } = useAccounts();
// Load the customers list.
const { data: contacts, isLoading: isContactsLoading } =
useAutoCompleteContacts();
// Load the currencies list.
const { data: currencies, isLoading: isCurrenciesLoading } = useCurrencies();
// Load the details of the given manual journal.
const { data: manualJournal, isLoading: isJournalLoading } = useJournal(
journalId,
{
enabled: !!journalId,
},
);
// Create and edit journal mutations.
const { mutateAsync: createJournalMutate } = useCreateJournal();
const { mutateAsync: editJournalMutate } = useEditJournal();
// Loading the journal settings.
const { isLoading: isSettingsLoading } = useSettingsManualJournals();
// Fetches the branches list.
const {
data: branches,
isLoading: isBranchesLoading,
isSuccess: isBranchesSuccess,
} = useBranches(query, { enabled: isBranchFeatureCan });
// Fetch the projects list.
const {
data: { projects },
isLoading: isProjectsLoading,
} = useProjects({}, { enabled: !!isProjectFeatureCan });
// Submit form payload.
const [submitPayload, setSubmitPayload] = useState({});
// Determines whether the warehouse and branches are loading.
const isFeatureLoading = isBranchesLoading;
const provider = {
accounts,
contacts,
currencies,
manualJournal,
projects,
branches,
createJournalMutate,
editJournalMutate,
isAccountsLoading,
isContactsLoading,
isCurrenciesLoading,
isJournalLoading,
isFeatureLoading,
isSettingsLoading,
isBranchesSuccess,
isNewMode: !journalId,
submitPayload,
setSubmitPayload,
};
return (
<DashboardInsider
loading={
isJournalLoading ||
isAccountsLoading ||
isCurrenciesLoading ||
isContactsLoading ||
isSettingsLoading ||
isProjectsLoading
}
name={'make-journal-page'}
>
<MakeJournalFormContext.Provider value={provider} {...props} />
</DashboardInsider>
);
}
const useMakeJournalFormContext = () =>
React.useContext(MakeJournalFormContext);
export { MakeJournalProvider, useMakeJournalFormContext };

View File

@@ -0,0 +1,201 @@
// @ts-nocheck
import React from 'react';
import intl from 'react-intl-universal';
import { Menu, MenuItem, Position, Button } from '@blueprintjs/core';
import { Popover2 } from '@blueprintjs/popover2';
import { useFormikContext } from 'formik';
import {
ExchangeRateInputGroup,
Icon,
Hint,
FormattedMessage as T,
} from '@/components';
import {
AccountsListFieldCell,
MoneyFieldCell,
InputGroupCell,
ContactsListFieldCell,
BranchesListFieldCell,
ProjectsListFieldCell,
} from '@/components/DataTableCells';
import { CellType, Features, Align } from '@/constants';
import { useCurrentOrganization, useFeatureCan } from '@/hooks/state';
import { useJournalIsForeign } from './utils';
/**
* Contact header cell.
*/
export function ContactHeaderCell() {
return (
<>
<T id={'contact'} />
<Hint
content={<T id={'contact_column_hint'} />}
position={Position.LEFT_BOTTOM}
/>
</>
);
}
/**
* Credit header cell.
*/
export function CreditHeaderCell({ payload: { currencyCode } }) {
return intl.get('credit_currency', { currency: currencyCode });
}
/**
* debit header cell.
*/
export function DebitHeaderCell({ payload: { currencyCode } }) {
return intl.get('debit_currency', { currency: currencyCode });
}
/**
* Actions cell renderer.
*/
export const ActionsCellRenderer = ({
row: { index },
column: { id },
cell: { value: initialValue },
data,
payload,
}) => {
const handleClickRemoveRole = () => {
payload.removeRow(index);
};
const exampleMenu = (
<Menu>
<MenuItem
onClick={handleClickRemoveRole}
text={intl.get('make_journal.entries.remove_row')}
/>
</Menu>
);
return (
<Popover2 content={exampleMenu} placement="left-start">
<Button
icon={<Icon icon={'more-13'} iconSize={13} />}
iconSize={14}
className="m12"
minimal={true}
/>
</Popover2>
);
};
ActionsCellRenderer.cellType = CellType.Button;
/**
* Retrieve columns of make journal entries table.
*/
export const useJournalTableEntriesColumns = () => {
const { featureCan } = useFeatureCan();
return React.useMemo(
() => [
{
Header: intl.get('account'),
id: 'account_id',
accessor: 'account_id',
Cell: AccountsListFieldCell,
disableSortBy: true,
width: 160,
fieldProps: { allowCreate: true },
},
{
Header: CreditHeaderCell,
accessor: 'credit',
Cell: MoneyFieldCell,
disableSortBy: true,
width: 100,
align: Align.Right,
},
{
Header: DebitHeaderCell,
accessor: 'debit',
Cell: MoneyFieldCell,
disableSortBy: true,
width: 100,
align: Align.Right,
},
{
Header: ContactHeaderCell,
id: 'contact_id',
accessor: 'contact_id',
Cell: ContactsListFieldCell,
disableSortBy: true,
width: 120,
},
...(featureCan(Features.Branches)
? [
{
Header: intl.get('project'),
id: 'project_id',
accessor: 'project_id',
Cell: ProjectsListFieldCell,
className: 'project_id',
disableSortBy: true,
width: 120,
},
]
: []),
...(featureCan(Features.Branches)
? [
{
Header: intl.get('branch'),
id: 'branch_id',
accessor: 'branch_id',
Cell: BranchesListFieldCell,
disableSortBy: true,
width: 120,
},
]
: []),
{
Header: intl.get('note'),
accessor: 'note',
Cell: InputGroupCell,
disableSortBy: true,
width: 200,
},
{
Header: '',
accessor: 'action',
Cell: ActionsCellRenderer,
disableSortBy: true,
disableResizing: true,
width: 45,
align: Align.Center,
},
],
[],
);
};
/**
* Journal exchange rate input field.
* @returns {JSX.Element}
*/
export function JournalExchangeRateInputField({ ...props }) {
const currentOrganization = useCurrentOrganization();
const { values } = useFormikContext();
const isForeignJouranl = useJournalIsForeign();
// Can't continue if the customer is not foreign.
if (!isForeignJouranl) {
return null;
}
return (
<ExchangeRateInputGroup
fromCurrency={values.currency_code}
toCurrency={currentOrganization.base_currency}
{...props}
/>
);
}

View File

@@ -0,0 +1,266 @@
// @ts-nocheck
import React from 'react';
import * as R from 'ramda';
import moment from 'moment';
import intl from 'react-intl-universal';
import { Intent } from '@blueprintjs/core';
import { sumBy, setWith, toSafeInteger, get, first } from 'lodash';
import {
transactionNumber,
updateTableCell,
repeatValue,
transformToForm,
defaultFastFieldShouldUpdate,
ensureEntriesHasEmptyLine,
formattedAmount,
safeSumBy,
} from '@/utils';
import { AppToaster } from '@/components';
import { useFormikContext } from 'formik';
import { useMakeJournalFormContext } from './MakeJournalProvider';
import { useCurrentOrganization } from '@/hooks/state';
const ERROR = {
JOURNAL_NUMBER_ALREADY_EXISTS: 'JOURNAL.NUMBER.ALREADY.EXISTS',
CUSTOMERS_NOT_WITH_RECEVIABLE_ACC: 'CUSTOMERS.NOT.WITH.RECEIVABLE.ACCOUNT',
VENDORS_NOT_WITH_PAYABLE_ACCOUNT: 'VENDORS.NOT.WITH.PAYABLE.ACCOUNT',
PAYABLE_ENTRIES_HAS_NO_VENDORS: 'PAYABLE.ENTRIES.HAS.NO.VENDORS',
RECEIVABLE_ENTRIES_HAS_NO_CUSTOMERS: 'RECEIVABLE.ENTRIES.HAS.NO.CUSTOMERS',
CREDIT_DEBIT_SUMATION_SHOULD_NOT_EQUAL_ZERO:
'CREDIT.DEBIT.SUMATION.SHOULD.NOT.EQUAL.ZERO',
ENTRIES_SHOULD_ASSIGN_WITH_CONTACT: 'ENTRIES_SHOULD_ASSIGN_WITH_CONTACT',
};
export const MIN_LINES_NUMBER = 1;
export const DEFAULT_LINES_NUMBER = 1;
export const defaultEntry = {
account_id: '',
credit: '',
debit: '',
contact_id: '',
branch_id: '',
project_id: '',
note: '',
};
export const defaultManualJournal = {
journal_number: '',
journal_number_manually: false,
journal_type: 'Journal',
date: moment(new Date()).format('YYYY-MM-DD'),
description: '',
reference: '',
currency_code: '',
publish: '',
branch_id: '',
exchange_rate: 1,
entries: [...repeatValue(defaultEntry, DEFAULT_LINES_NUMBER)],
};
// Transform to edit form.
export function transformToEditForm(manualJournal) {
const defaultEntry = defaultManualJournal.entries[0];
const initialEntries = [
...manualJournal.entries.map((entry) => ({
...transformToForm(entry, defaultEntry),
})),
...repeatValue(
defaultEntry,
Math.max(MIN_LINES_NUMBER - manualJournal.entries.length, 0),
),
];
const entries = R.compose(
ensureEntriesHasEmptyLine(MIN_LINES_NUMBER, defaultEntry),
)(initialEntries);
return {
...transformToForm(manualJournal, defaultManualJournal),
entries,
};
}
/**
* Entries adjustment.
*/
function adjustmentEntries(entries) {
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),
};
}
/**
* Adjustment credit/debit entries.
* @param {number} rowIndex
* @param {number} columnId
* @param {string} value
* @return {array}
*/
export const updateAdjustEntries = (rowIndex, columnId, value) => (rows) => {
let newRows = [...rows];
const oldCredit = get(rows, `[${rowIndex}].credit`);
const oldDebit = get(rows, `[${rowIndex}].debit`);
if (columnId === 'account_id' && !oldCredit && !oldDebit) {
const adjustment = adjustmentEntries(rows);
if (adjustment.credit) {
newRows = updateTableCell(rowIndex, 'credit', adjustment.credit)(newRows);
}
if (adjustment.debit) {
newRows = updateTableCell(rowIndex, 'debit', adjustment.debit)(newRows);
}
}
return newRows;
};
/**
* Transform API errors in toasts messages.
*/
export const transformErrors = (resErrors, { setErrors, errors }) => {
const getError = (errorType) => resErrors.find((e) => e.type === errorType);
const toastMessages = [];
let error;
let newErrors = { ...errors, entries: [] };
const setEntriesErrors = (indexes, prop, message) =>
indexes.forEach((i) => {
const index = Math.max(i - 1, 0);
newErrors = setWith(newErrors, `entries.[${index}].${prop}`, message);
});
if ((error = getError(ERROR.RECEIVABLE_ENTRIES_HAS_NO_CUSTOMERS))) {
toastMessages.push(
intl.get('should_select_customers_with_entries_have_receivable_account'),
);
setEntriesErrors(error.indexes, 'contact_id', 'error');
}
if ((error = getError(ERROR.ENTRIES_SHOULD_ASSIGN_WITH_CONTACT))) {
if (error.meta.find((meta) => meta.contact_type === 'customer')) {
toastMessages.push(
intl.get('receivable_accounts_should_assign_with_customers'),
);
}
if (error.meta.find((meta) => meta.contact_type === 'vendor')) {
toastMessages.push(
intl.get('payable_accounts_should_assign_with_vendors'),
);
}
const indexes = error.meta.map((meta) => meta.indexes).flat();
setEntriesErrors(indexes, 'contact_id', 'error');
}
if ((error = getError(ERROR.JOURNAL_NUMBER_ALREADY_EXISTS))) {
newErrors = setWith(
newErrors,
'journal_number',
intl.get('journal_number_is_already_used'),
);
}
setErrors({ ...newErrors });
if (toastMessages.length > 0) {
AppToaster.show({
message: toastMessages.map((message) => {
return <div>{message}</div>;
}),
intent: Intent.DANGER,
});
}
};
export const useObserveJournalNoSettings = (prefix, nextNumber) => {
const { setFieldValue } = useFormikContext();
React.useEffect(() => {
const journalNo = transactionNumber(prefix, nextNumber);
setFieldValue('journal_number', journalNo);
}, [setFieldValue, prefix, nextNumber]);
};
/**
* Detarmines entries fast field should update.
*/
export const entriesFieldShouldUpdate = (newProps, oldProps) => {
return (
newProps.accounts !== oldProps.accounts ||
newProps.contacts !== oldProps.contacts ||
newProps.branches !== oldProps.branches ||
defaultFastFieldShouldUpdate(newProps, oldProps)
);
};
/**
* Detarmines currencies fast field should update.
*/
export const currenciesFieldShouldUpdate = (newProps, oldProps) => {
return (
newProps.currencies !== oldProps.currencies ||
defaultFastFieldShouldUpdate(newProps, oldProps)
);
};
export const useSetPrimaryBranchToForm = () => {
const { setFieldValue } = useFormikContext();
const { branches, isBranchesSuccess } = useMakeJournalFormContext();
React.useEffect(() => {
if (isBranchesSuccess) {
const primaryBranch = branches.find((b) => b.primary) || first(branches);
if (primaryBranch) {
setFieldValue('branch_id', primaryBranch.id);
}
}
}, [isBranchesSuccess, setFieldValue, branches]);
};
/**
* Retreives the Journal totals.
*/
export const useJournalTotals = () => {
const {
values: { entries, currency_code: currencyCode },
} = useFormikContext();
// Retrieves the invoice entries total.
const totalCredit = safeSumBy(entries, 'credit');
const totalDebit = safeSumBy(entries, 'debit');
const total = Math.max(totalCredit, totalDebit);
// Retrieves the formatted total money.
const formattedTotal = React.useMemo(
() => formattedAmount(total, currencyCode),
[total, currencyCode],
);
// Retrieves the formatted subtotal.
const formattedSubtotal = React.useMemo(
() => formattedAmount(total, currencyCode, { money: false }),
[total, currencyCode],
);
return {
formattedTotal,
formattedSubtotal,
};
};
/**
* Detarmines whether the expenses has foreign .
* @returns {boolean}
*/
export const useJournalIsForeign = () => {
const { values } = useFormikContext();
const currentOrganization = useCurrentOrganization();
const isForeignJournal = React.useMemo(
() => values.currency_code !== currentOrganization.base_currency,
[values.currency_code, currentOrganization.base_currency],
);
return isForeignJournal;
};

View File

@@ -0,0 +1,53 @@
// @ts-nocheck
import intl from 'react-intl-universal';
import { RESOURCES_TYPES } from '@/constants/resourcesTypes';
import { AbilitySubject, ManualJournalAction } from '@/constants/abilityOption';
import withDrawerActions from '@/containers/Drawer/withDrawerActions';
/**
* Universal search manual journal item select action.
*/
function JournalUniversalSearchSelectComponent({
// #ownProps
resourceType,
resourceId,
onAction,
// #withDrawerActions
openDrawer,
}) {
if (resourceType === RESOURCES_TYPES.MANUAL_JOURNAL) {
openDrawer('journal-drawer', { manualJournalId: resourceId });
onAction && onAction();
}
return null;
}
export const JournalUniversalSearchSelectAction = withDrawerActions(
JournalUniversalSearchSelectComponent,
);
/**
* Mappes the manual journal item to search item.
*/
const manualJournalsToSearch = (manualJournal) => ({
id: manualJournal.id,
text: manualJournal.journal_number,
subText: manualJournal.formatted_date,
label: manualJournal.formatted_amount,
reference: manualJournal,
});
/**
* Binds universal search invoice configure.
*/
export const universalSearchJournalBind = () => ({
resourceType: RESOURCES_TYPES.MANUAL_JOURNAL,
optionItemLabel: intl.get('manual_journals'),
selectItemAction: JournalUniversalSearchSelectAction,
itemSelect: manualJournalsToSearch,
permission: {
ability: ManualJournalAction.View,
subject: AbilitySubject.ManualJournal,
},
});

View File

@@ -0,0 +1,53 @@
// @ts-nocheck
import intl from 'react-intl-universal';
import withDrawerActions from '@/containers/Drawer/withDrawerActions';
import { AbilitySubject, AccountAction } from '@/constants/abilityOption';
import { RESOURCES_TYPES } from '@/constants/resourcesTypes';
function AccountUniversalSearchItemSelectComponent({
// #ownProps
resourceType,
resourceId,
onAction,
// #withDrawerActions
openDrawer,
}) {
if (resourceType === RESOURCES_TYPES.ACCOUNT) {
openDrawer('account-drawer', { accountId: resourceId });
onAction && onAction();
}
return null;
}
export const AccountUniversalSearchItemSelect = withDrawerActions(
AccountUniversalSearchItemSelectComponent,
);
/**
* Transformes account item to search item.
* @param {*} account
* @returns
*/
const accountToSearch = (account) => ({
id: account.id,
text: `${account.name} - ${account.code}`,
label: account.formatted_amount,
reference: account,
});
/**
* Binds universal search account configure.
*/
export const universalSearchAccountBind = () => ({
resourceType: RESOURCES_TYPES.ACCOUNT,
optionItemLabel: intl.get('accounts'),
selectItemAction: AccountUniversalSearchItemSelect,
itemSelect: accountToSearch,
permission: {
ability: AccountAction.View,
subject: AbilitySubject.Account,
},
});

View File

@@ -0,0 +1,225 @@
// @ts-nocheck
import React from 'react';
import { isEmpty } from 'lodash';
import {
Button,
NavbarGroup,
Classes,
NavbarDivider,
Intent,
Switch,
Alignment,
} from '@blueprintjs/core';
import {
AdvancedFilterPopover,
If,
Can,
Icon,
FormattedMessage as T,
DashboardActionViewsList,
DashboardFilterButton,
DashboardRowsHeightButton,
DashboardActionsBar
} from '@/components';
import { AccountAction, AbilitySubject } from '@/constants/abilityOption';
import { DialogsName } from '@/constants/dialogs';
import { useRefreshAccounts } from '@/hooks/query/accounts';
import { useAccountsChartContext } from './AccountsChartProvider';
import withAccounts from './withAccounts';
import withAccountsTableActions from './withAccountsTableActions';
import withDialogActions from '@/containers/Dialog/withDialogActions';
import withAlertActions from '@/containers/Alert/withAlertActions';
import withSettings from '@/containers/Settings/withSettings';
import withSettingsActions from '@/containers/Settings/withSettingsActions';
import { compose } from '@/utils';
/**
* Accounts actions bar.
*/
function AccountsActionsBar({
// #withDialogActions
openDialog,
// #withAccounts
accountsSelectedRows,
accountsInactiveMode,
accountsFilterConditions,
// #withAlertActions
openAlert,
// #withAccountsTableActions
setAccountsTableState,
// #ownProps
onFilterChanged,
// #withSettings
accountsTableSize,
// #withSettingsActions
addSetting,
}) {
const { resourceViews, fields } = useAccountsChartContext();
const onClickNewAccount = () => {
openDialog(DialogsName.AccountForm, {});
};
// Accounts refresh action.
const { refresh } = useRefreshAccounts();
// Handle bulk accounts delete.
const handleBulkDelete = () => {
openAlert('accounts-bulk-delete', { accountsIds: accountsSelectedRows });
};
// Handle bulk accounts activate.
const handelBulkActivate = () => {
openAlert('accounts-bulk-activate', { accountsIds: accountsSelectedRows });
};
// Handle bulk accounts inactivate.
const handelBulkInactive = () => {
openAlert('accounts-bulk-inactivate', {
accountsIds: accountsSelectedRows,
});
};
// Handle tab changing.
const handleTabChange = (view) => {
setAccountsTableState({ viewSlug: view ? view.slug : null });
};
// Handle inactive switch changing.
const handleInactiveSwitchChange = (event) => {
const checked = event.target.checked;
setAccountsTableState({ inactiveMode: checked });
};
// Handle click a refresh accounts
const handleRefreshBtnClick = () => {
refresh();
};
// Handle table row size change.
const handleTableRowSizeChange = (size) => {
addSetting('accounts', 'tableSize', size);
};
return (
<DashboardActionsBar>
<NavbarGroup>
<DashboardActionViewsList
resourceName={'accounts'}
allMenuItem={true}
allMenuItemText={<T id={'all_accounts'} />}
views={resourceViews}
onChange={handleTabChange}
/>
<NavbarDivider />
<Can I={AccountAction.Create} a={AbilitySubject.Account}>
<Button
className={Classes.MINIMAL}
icon={<Icon icon="plus" />}
text={<T id={'new_account'} />}
onClick={onClickNewAccount}
/>
</Can>
<AdvancedFilterPopover
advancedFilterProps={{
conditions: accountsFilterConditions,
defaultFieldKey: 'name',
fields: fields,
onFilterChange: (filterConditions) => {
setAccountsTableState({ filterRoles: filterConditions });
},
}}
>
<DashboardFilterButton
conditionsCount={accountsFilterConditions.length}
/>
</AdvancedFilterPopover>
<NavbarDivider />
<If condition={!isEmpty(accountsSelectedRows)}>
<Button
className={Classes.MINIMAL}
icon={<Icon icon="play-16" iconSize={16} />}
text={<T id={'activate'} />}
onClick={handelBulkActivate}
/>
<Button
className={Classes.MINIMAL}
icon={<Icon icon="pause-16" iconSize={16} />}
text={<T id={'inactivate'} />}
onClick={handelBulkInactive}
/>
<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-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={accountsTableSize}
onChange={handleTableRowSizeChange}
/>
<NavbarDivider />
<Can I={AccountAction.Edit} a={AbilitySubject.Account}>
<Switch
labelElement={<T id={'inactive'} />}
defaultChecked={accountsInactiveMode}
onChange={handleInactiveSwitchChange}
/>
</Can>
</NavbarGroup>
<NavbarGroup align={Alignment.RIGHT}>
<Button
className={Classes.MINIMAL}
icon={<Icon icon="refresh-16" iconSize={14} />}
onClick={handleRefreshBtnClick}
/>
</NavbarGroup>
</DashboardActionsBar>
);
}
export default compose(
withDialogActions,
withAlertActions,
withSettingsActions,
withAccounts(({ accountsSelectedRows, accountsTableState }) => ({
accountsSelectedRows,
accountsInactiveMode: accountsTableState.inactiveMode,
accountsFilterConditions: accountsTableState.filterRoles,
})),
withSettings(({ accountsSettings }) => ({
accountsTableSize: accountsSettings.tableSize,
})),
withAccountsTableActions,
)(AccountsActionsBar);

View File

@@ -0,0 +1,18 @@
// @ts-nocheck
import React from 'react';
const AccountDeleteAlert = React.lazy(
() => import('@/containers/Alerts/Accounts/AccountDeleteAlert'),
);
const AccountInactivateAlert = React.lazy(
() => import('@/containers/Alerts/Accounts/AccountInactivateAlert'),
);
const AccountActivateAlert = React.lazy(
() => import('@/containers/Alerts/Accounts/AccountDeleteAlert'),
);
export default [
{ name: 'account-delete', component: AccountDeleteAlert },
{ name: 'account-inactivate', component: AccountInactivateAlert },
{ name: 'account-activate', component: AccountActivateAlert },
];

View File

@@ -0,0 +1,60 @@
// @ts-nocheck
import React, { useEffect } from 'react';
import '@/style/pages/Accounts/List.scss';
import { DashboardPageContent, DashboardContentTable } from '@/components';
import { AccountsChartProvider } from './AccountsChartProvider';
import AccountsViewsTabs from './AccountsViewsTabs';
import AccountsActionsBar from './AccountsActionsBar';
import AccountsDataTable from './AccountsDataTable';
import withAccounts from '@/containers/Accounts/withAccounts';
import withAccountsTableActions from './withAccountsTableActions';
import { transformAccountsStateToQuery } from './utils';
import { compose } from '@/utils';
/**
* Accounts chart list.
*/
function AccountsChart({
// #withAccounts
accountsTableState,
accountsTableStateChanged,
// #withAccountsActions
resetAccountsTableState,
}) {
// Resets the accounts table state once the page unmount.
useEffect(
() => () => {
resetAccountsTableState();
},
[resetAccountsTableState],
);
return (
<AccountsChartProvider
query={transformAccountsStateToQuery(accountsTableState)}
tableStateChanged={accountsTableStateChanged}
>
<AccountsActionsBar />
<DashboardPageContent>
<AccountsViewsTabs />
<DashboardContentTable>
<AccountsDataTable />
</DashboardContentTable>
</DashboardPageContent>
</AccountsChartProvider>
);
}
export default compose(
withAccounts(({ accountsTableState, accountsTableStateChanged }) => ({
accountsTableState,
accountsTableStateChanged,
})),
withAccountsTableActions,
)(AccountsChart);

View File

@@ -0,0 +1,59 @@
// @ts-nocheck
import React, { createContext } from 'react';
import { DashboardInsider } from '@/components';
import { useResourceViews, useResourceMeta, useAccounts } from '@/hooks/query';
import { getFieldsFromResourceMeta } from '@/utils';
const AccountsChartContext = createContext();
/**
* Accounts chart data provider.
*/
function AccountsChartProvider({ query, tableStateChanged, ...props }) {
// Fetch accounts resource views and fields.
const { data: resourceViews, isLoading: isViewsLoading } =
useResourceViews('accounts');
// Fetch the accounts resource fields.
const {
data: resourceMeta,
isLoading: isResourceMetaLoading,
isFetching: isResourceMetaFetching,
} = useResourceMeta('accounts');
// Fetch accounts list according to the given custom view id.
const {
data: accounts,
isFetching: isAccountsFetching,
isLoading: isAccountsLoading,
} = useAccounts(query, { keepPreviousData: true });
// Provider payload.
const provider = {
accounts,
resourceMeta,
resourceViews,
fields: getFieldsFromResourceMeta(resourceMeta.fields),
isAccountsLoading,
isAccountsFetching,
isResourceMetaFetching,
isResourceMetaLoading,
isViewsLoading,
};
return (
<DashboardInsider
loading={isViewsLoading || isResourceMetaLoading}
name={'accounts-chart'}
>
<AccountsChartContext.Provider value={provider} {...props} />
</DashboardInsider>
);
}
const useAccountsChartContext = () => React.useContext(AccountsChartContext);
export { AccountsChartProvider, useAccountsChartContext };

View File

@@ -0,0 +1,142 @@
// @ts-nocheck
import React from 'react';
import {
TableFastCell,
DataTable,
TableSkeletonRows,
TableSkeletonHeader,
TableVirtualizedListRows,
} from '@/components';
import { useAccountsTableColumns, rowClassNames } from './utils';
import { ActionsMenu } from './components';
import { AccountDialogAction } from '@/containers/Dialogs/AccountDialog/utils';
import { useAccountsChartContext } from './AccountsChartProvider';
import { useMemorizedColumnsWidths } from '@/hooks';
import { TABLES } from '@/constants/tables';
import { DialogsName } from '@/constants/dialogs';
import withSettings from '@/containers/Settings/withSettings';
import withAlertsActions from '@/containers/Alert/withAlertActions';
import withDialogActions from '@/containers/Dialog/withDialogActions';
import withDrawerActions from '@/containers/Drawer/withDrawerActions';
import { compose } from '@/utils';
/**
* Accounts data-table.
*/
function AccountsDataTable({
// #withAlertsDialog
openAlert,
// #withDial
openDialog,
// #withDrawerActions
openDrawer,
// #withSettings
accountsTableSize,
}) {
const { isAccountsLoading, isAccountsFetching, accounts } =
useAccountsChartContext();
// Retrieve accounts table columns.
const columns = useAccountsTableColumns();
// Handle delete action account.
const handleDeleteAccount = (account) => {
openAlert('account-delete', { accountId: account.id });
};
// Handle activate action account.
const handleActivateAccount = (account) => {
openAlert('account-activate', { accountId: account.id });
};
// Handle inactivate action account.
const handleInactivateAccount = (account) => {
openAlert('account-inactivate', { accountId: account.id });
};
// Handle edit account action.
const handleEditAccount = (account) => {
openDialog(DialogsName.AccountForm, {
action: AccountDialogAction.Edit,
accountId: account.id,
});
};
// Handle view detail account.
const handleViewDetailAccount = ({ id }) => {
openDrawer('account-drawer', { accountId: id });
};
// Handle new child button click.
const handleNewChildAccount = (account) => {
openDialog(DialogsName.AccountForm, {
action: AccountDialogAction.NewChild,
parentAccountId: account.id,
accountType: account.account_type,
});
};
// Handle cell click.
const handleCellClick = (cell, event) => {
openDrawer('account-drawer', { accountId: cell.row.original.id });
};
// Local storage memorizing columns widths.
const [initialColumnsWidths, , handleColumnResizing] =
useMemorizedColumnsWidths(TABLES.ACCOUNTS);
return (
<DataTable
noInitialFetch={true}
columns={columns}
data={accounts}
selectionColumn={true}
expandable={true}
sticky={true}
loading={isAccountsLoading}
headerLoading={isAccountsLoading}
progressBarLoading={isAccountsFetching}
rowClassNames={rowClassNames}
autoResetExpanded={false}
autoResetSortBy={false}
autoResetSelectedRows={false}
expandColumnSpace={1}
expandToggleColumn={2}
selectionColumnWidth={45}
TableCellRenderer={TableFastCell}
TableRowsRenderer={TableVirtualizedListRows}
TableLoadingRenderer={TableSkeletonRows}
TableHeaderSkeletonRenderer={TableSkeletonHeader}
ContextMenu={ActionsMenu}
// #TableVirtualizedListRows props.
vListrowHeight={accountsTableSize == 'small' ? 40 : 42}
vListOverscanRowCount={0}
onCellClick={handleCellClick}
initialColumnsWidths={initialColumnsWidths}
onColumnResizing={handleColumnResizing}
size={accountsTableSize}
payload={{
onEdit: handleEditAccount,
onDelete: handleDeleteAccount,
onActivate: handleActivateAccount,
onInactivate: handleInactivateAccount,
onNewChild: handleNewChildAccount,
onViewDetails: handleViewDetailAccount,
}}
/>
);
}
export default compose(
withAlertsActions,
withDrawerActions,
withDialogActions,
withSettings(({ accountsSettings }) => ({
accountsTableSize: accountsSettings.tableSize,
})),
)(AccountsDataTable);

View File

@@ -0,0 +1,60 @@
// @ts-nocheck
import React, { useCallback } from 'react';
import { Alignment, Navbar, NavbarGroup } from '@blueprintjs/core';
import intl from 'react-intl-universal';
import { DashboardViewsTabs } from '@/components';
import { useAccountsChartContext } from './AccountsChartProvider';
import withAccounts from './withAccounts';
import withAccountsTableActions from './withAccountsTableActions';
import { compose, transfromViewsToTabs } from '@/utils';
/**
* Accounts views tabs.
*/
function AccountsViewsTabs({
// #withAccountsTableActions
setAccountsTableState,
// #withAccounts
accountsCurrentView
}) {
// Accounts chart context.
const { resourceViews } = useAccountsChartContext();
// Handles the tab change.
const handleTabChange = useCallback(
(viewSlug) => {
setAccountsTableState({
viewSlug: viewSlug || null,
});
},
[setAccountsTableState],
);
// Transfromes the accounts views to tabs.
const tabs = transfromViewsToTabs(resourceViews);
return (
<Navbar className="navbar--dashboard-views">
<NavbarGroup align={Alignment.LEFT}>
<DashboardViewsTabs
defaultTabText={intl.get('all_accounts_')}
currentViewSlug={accountsCurrentView}
resourceName={'accounts'}
onChange={handleTabChange}
tabs={tabs}
/>
</NavbarGroup>
</Navbar>
);
}
export default compose(
withAccountsTableActions,
withAccounts(({ accountsTableState }) => ({
accountsCurrentView: accountsTableState.viewSlug
}))
)(AccountsViewsTabs);

View File

@@ -0,0 +1,118 @@
// @ts-nocheck
import React from 'react';
import intl from 'react-intl-universal';
import {
Position,
Classes,
Tooltip,
MenuItem,
Menu,
MenuDivider,
Intent,
} from '@blueprintjs/core';
import { Can, Icon, If } from '@/components';
import { safeCallback } from '@/utils';
import { AbilitySubject, AccountAction } from '@/constants/abilityOption';
/**
* Accounts table actions menu.
*/
export function ActionsMenu({
row: { original },
payload: {
onEdit,
onViewDetails,
onDelete,
onNewChild,
onActivate,
onInactivate,
// onDrawer,
},
}) {
return (
<Menu>
<MenuItem
icon={<Icon icon="reader-18" />}
text={intl.get('view_details')}
onClick={safeCallback(onViewDetails, original)}
/>
<Can I={AccountAction.Edit} a={AbilitySubject.Account}>
<MenuDivider />
<MenuItem
icon={<Icon icon="pen-18" />}
text={intl.get('edit_account')}
onClick={safeCallback(onEdit, original)}
/>
<MenuItem
icon={<Icon icon="plus" />}
text={intl.get('new_child_account')}
onClick={safeCallback(onNewChild, original)}
/>
<MenuDivider />
</Can>
<Can I={AccountAction.Edit} a={AbilitySubject.Account}>
<If condition={original.active}>
<MenuItem
text={intl.get('inactivate_account')}
icon={<Icon icon="pause-16" iconSize={16} />}
onClick={safeCallback(onInactivate, original)}
/>
</If>
<If condition={!original.active}>
<MenuItem
text={intl.get('activate_account')}
icon={<Icon icon="play-16" iconSize={16} />}
onClick={safeCallback(onActivate, original)}
/>
</If>
</Can>
<Can I={AccountAction.Edit} a={AbilitySubject.Account}>
<MenuItem
text={intl.get('delete_account')}
icon={<Icon icon="trash-16" iconSize={16} />}
intent={Intent.DANGER}
onClick={safeCallback(onDelete, original)}
/>
</Can>
</Menu>
);
}
/**
* Normal cell.
*/
export function NormalCell({ cell: { value } }) {
const arrowDirection = value === 'credit' ? 'down' : 'up';
// Can't continue if the value is not `credit` or `debit`.
if (['credit', 'debit'].indexOf(value) === -1) {
return '';
}
return (
<Tooltip
className={Classes.TOOLTIP_INDICATOR}
content={intl.get(value)}
position={Position.RIGHT}
hoverOpenDelay={100}
>
<Icon icon={`arrow-${arrowDirection}`} />
</Tooltip>
);
}
/**
* Balance cell.
*/
export function BalanceCell({ cell }) {
const account = cell.row.original;
return account.amount !== null ? (
<span>
{account.formatted_amount}
{/* <Money amount={account.amount} currency={account.currency_code} /> */}
</span>
) : (
<span class="placeholder"></span>
);
}

View File

@@ -0,0 +1,123 @@
// @ts-nocheck
import React from 'react';
import intl from 'react-intl-universal';
import { Intent, Tag } from '@blueprintjs/core';
import { If, AppToaster } from '@/components';
import { NormalCell, BalanceCell } from './components';
import { transformTableStateToQuery, isBlank } from '@/utils';
/**
* Account name accessor.
*/
export const accountNameAccessor = (account) => {
return (
<span>
<span class={'account-name'}>{account.name}</span>
<If condition={account.description}>
<span class={'account-desc'}>{account.description}</span>
</If>
</span>
);
};
/**
* Handle delete errors in bulk and singular.
*/
export const handleDeleteErrors = (errors) => {
if (errors.find((e) => e.type === 'ACCOUNT.PREDEFINED')) {
AppToaster.show({
message: intl.get('you_could_not_delete_predefined_accounts'),
intent: Intent.DANGER,
});
}
if (errors.find((e) => e.type === 'ACCOUNT.HAS.ASSOCIATED.TRANSACTIONS')) {
AppToaster.show({
message: intl.get('cannot_delete_account_has_associated_transactions'),
intent: Intent.DANGER,
});
}
};
export const AccountCodeAccessor = (row) =>
!isBlank(row.code) ? (
<Tag minimal={true} round={true} intent={Intent.NONE}>
{row.code}
</Tag>
) : null;
/**
* Accounts table columns.
*/
export const useAccountsTableColumns = () => {
return React.useMemo(
() => [
{
id: 'name',
Header: intl.get('account_name'),
accessor: 'name',
className: 'account_name',
width: 200,
clickable: true,
textOverview: true,
},
{
id: 'code',
Header: intl.get('code'),
accessor: AccountCodeAccessor,
className: 'code',
width: 80,
clickable: true,
},
{
id: 'type',
Header: intl.get('type'),
accessor: 'account_type_label',
className: 'type',
width: 140,
clickable: true,
textOverview: true,
},
{
id: 'normal',
Header: intl.get('account_normal'),
Cell: NormalCell,
accessor: 'account_normal',
className: 'normal',
width: 80,
clickable: true,
},
{
id: 'currency',
Header: intl.get('currency'),
accessor: 'currency_code',
width: 75,
clickable: true,
},
{
id: 'balance',
Header: intl.get('balance'),
accessor: 'amount',
Cell: BalanceCell,
width: 150,
clickable: true,
align: 'right',
},
],
[],
);
};
export const rowClassNames = (row) => ({
inactive: !row.original.active,
});
/**
* Transformes the table state to list query.
*/
export const transformAccountsStateToQuery = (tableState) => {
return {
...transformTableStateToQuery(tableState),
inactive_mode: tableState.inactiveMode,
}
}

View File

@@ -0,0 +1,21 @@
// @ts-nocheck
import { connect } from 'react-redux';
import {
getAccountsTableStateFactory,
accountsTableStateChangedFactory,
} from '@/store/accounts/accounts.selectors';
export default (mapState) => {
const getAccountsTableState = getAccountsTableStateFactory();
const accountsTableStateChanged = accountsTableStateChangedFactory();
const mapStateToProps = (state, props) => {
const mapped = {
accountsTableState: getAccountsTableState(state, props),
accountsTableStateChanged: accountsTableStateChanged(state, props),
};
return mapState ? mapState(mapped, state, props) : mapped;
};
return connect(mapStateToProps);
};

View File

@@ -0,0 +1,13 @@
// @ts-nocheck
import { connect } from 'react-redux';
import {
setAccountsTableState,
resetAccountsTableState,
} from '@/store/accounts/accounts.actions';
const mapActionsToProps = (dispatch) => ({
setAccountsTableState: (queries) => dispatch(setAccountsTableState(queries)),
resetAccountsTableState: () => dispatch(resetAccountsTableState()),
});
export default connect(null, mapActionsToProps);

View File

@@ -0,0 +1,14 @@
// @ts-nocheck
import { connect } from 'react-redux';
import t from '@/store/types';
export const mapStateToProps = (state, props) => {
return {};
};
export const mapDispatchToProps = (dispatch) => ({
openAlert: (name, payload) => dispatch({ type: t.OPEN_ALERT, name, payload }),
closeAlert: (name, payload) => dispatch({ type: t.CLOSE_ALERT, name, payload }),
});
export default connect(null, mapDispatchToProps);

View File

@@ -0,0 +1,20 @@
// @ts-nocheck
import { connect } from 'react-redux';
import {
isAlertOpenFactory,
getAlertPayloadFactory,
} from '@/store/dashboard/dashboard.selectors';
export default (mapState) => {
const isAlertOpen = isAlertOpenFactory();
const getAlertPayload = getAlertPayloadFactory();
const mapStateToProps = (state, props) => {
const mapped = {
isOpen: isAlertOpen(state, props),
payload: getAlertPayload(state, props),
};
return mapState ? mapState(mapped) : mapped;
};
return connect(mapStateToProps);
}

View File

@@ -0,0 +1,68 @@
// @ts-nocheck
import React from 'react';
import intl from 'react-intl-universal';
import { Intent, Alert } from '@blueprintjs/core';
import { AppToaster, FormattedMessage as T } from '@/components';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import withAlertActions from '@/containers/Alert/withAlertActions';
import { useActivateAccount } from '@/hooks/query';
import { compose } from '@/utils';
/**
* Account activate alert.
*/
function AccountActivateAlert({
name,
isOpen,
payload: { accountId },
// #withAlertActions
closeAlert,
}) {
const {
mutateAsync: activateAccount,
isLoading
} = useActivateAccount();
// Handle alert cancel.
const handleCancel = () => {
closeAlert('account-activate');
};
// Handle activate account confirm.
const handleConfirmAccountActivate = () => {
activateAccount(accountId).then(() => {
AppToaster.show({
message: intl.get('the_account_has_been_successfully_activated'),
intent: Intent.SUCCESS,
});
closeAlert('account-activate');
}).finally(() => {
closeAlert('account-activate');
});
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'activate'} />}
intent={Intent.WARNING}
isOpen={isOpen}
onCancel={handleCancel}
onConfirm={handleConfirmAccountActivate}
loading={isLoading}
>
<p>
<T id={'are_sure_to_activate_this_account'} />
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
)(AccountActivateAlert);

View File

@@ -0,0 +1,71 @@
// @ts-nocheck
import React, { useState } from 'react';
import intl from 'react-intl-universal';
import { Intent, Alert } from '@blueprintjs/core';
import { queryCache } from 'react-query';
import { FormattedMessage as T, AppToaster } from '@/components';
import withAccountsActions from '@/containers/Accounts/withAccountsActions';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import withAlertActions from '@/containers/Alert/withAlertActions';
import { compose } from '@/utils';
function AccountBulkActivateAlert({
name,
isOpen,
payload: { accountsIds },
// #withAlertActions
closeAlert,
requestBulkActivateAccounts,
}) {
const [isLoading, setLoading] = useState(false);
const selectedRowsCount = 0;
// Handle alert cancel.
const handleClose = () => {
closeAlert(name);
};
// Handle Bulk activate account confirm.
const handleConfirmBulkActivate = () => {
setLoading(true);
requestBulkActivateAccounts(accountsIds)
.then(() => {
AppToaster.show({
message: intl.get('the_accounts_has_been_successfully_activated'),
intent: Intent.SUCCESS,
});
queryCache.invalidateQueries('accounts-table');
})
.catch((errors) => {})
.finally(() => {
setLoading(false);
closeAlert(name);
});
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={`${intl.get('activate')} (${selectedRowsCount})`}
intent={Intent.WARNING}
isOpen={isOpen}
onCancel={handleClose}
onConfirm={handleConfirmBulkActivate}
loading={isLoading}
>
<p>
<T id={'are_sure_to_activate_this_accounts'} />
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
withAccountsActions,
)(AccountBulkActivateAlert);

View File

@@ -0,0 +1,84 @@
// @ts-nocheck
import React, { useState } from 'react';
import { FormattedMessage as T } from '@/components';
import intl from 'react-intl-universal';
import { Intent, Alert } from '@blueprintjs/core';
import { queryCache } from 'react-query';
import { AppToaster } from '@/components';
import { handleDeleteErrors } from '@/containers/Accounts/utils';
import withAccountsActions from '@/containers/Accounts/withAccountsActions';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import withAlertActions from '@/containers/Alert/withAlertActions';
import { compose } from '@/utils';
/**
* Account bulk delete alert.
*/
function AccountBulkDeleteAlert({
// #ownProps
name,
// #withAlertStoreConnect
isOpen,
payload: { accountsIds },
// #withAlertActions
closeAlert,
// #withAccountsActions
requestDeleteBulkAccounts,
}) {
const [isLoading, setLoading] = useState(false);
const selectedRowsCount = 0;
const handleCancel = () => {
closeAlert(name);
};
// Handle confirm accounts bulk delete.
const handleConfirmBulkDelete = () => {
setLoading(true);
requestDeleteBulkAccounts(accountsIds)
.then(() => {
AppToaster.show({
message: intl.get('the_accounts_has_been_successfully_deleted'),
intent: Intent.SUCCESS,
});
queryCache.invalidateQueries('accounts-table');
})
.catch((errors) => {
handleDeleteErrors(errors);
})
.finally(() => {
setLoading(false);
closeAlert(name);
});
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={`${intl.get('delete')} (${selectedRowsCount})`}
icon="trash"
intent={Intent.DANGER}
isOpen={isOpen}
onCancel={handleCancel}
onConfirm={handleConfirmBulkDelete}
loading={isLoading}
>
<p>
<T id={'once_delete_these_accounts_you_will_not_able_restore_them'} />
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
withAccountsActions,
)(AccountBulkDeleteAlert);

View File

@@ -0,0 +1,72 @@
// @ts-nocheck
import React, { useState } from 'react';
import { FormattedMessage as T } from '@/components';
import intl from 'react-intl-universal';
import { Intent, Alert } from '@blueprintjs/core';
import { queryCache } from 'react-query';
import { AppToaster } from '@/components';
import withAccountsActions from '@/containers/Accounts/withAccountsTableActions';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import withAlertActions from '@/containers/Alert/withAlertActions';
import { compose } from '@/utils';
function AccountBulkInactivateAlert({
name,
isOpen,
payload: { accountsIds },
// #withAccountsActions
requestBulkInactiveAccounts,
closeAlert,
}) {
const [isLoading, setLoading] = useState(false);
const selectedRowsCount = 0;
// Handle alert cancel.
const handleCancel = () => {
closeAlert(name);
};
// Handle Bulk Inactive accounts confirm.
const handleConfirmBulkInactive = () => {
setLoading(true);
requestBulkInactiveAccounts(accountsIds)
.then(() => {
AppToaster.show({
message: intl.get('the_accounts_have_been_successfully_inactivated'),
intent: Intent.SUCCESS,
});
queryCache.invalidateQueries('accounts-table');
})
.catch((errors) => {})
.finally(() => {
setLoading(false);
closeAlert(name);
});
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={`${intl.get('inactivate')} (${selectedRowsCount})`}
intent={Intent.WARNING}
isOpen={isOpen}
onCancel={handleCancel}
onConfirm={handleConfirmBulkInactive}
loading={isLoading}
>
<p>
<T id={'are_sure_to_inactive_this_accounts'} />
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
withAccountsActions,
)(AccountBulkInactivateAlert);

View File

@@ -0,0 +1,89 @@
// @ts-nocheck
import React from 'react';
import intl from 'react-intl-universal';
import { Intent, Alert } from '@blueprintjs/core';
import {
AppToaster,
FormattedMessage as T,
FormattedHTMLMessage,
} from '@/components';
import { handleDeleteErrors } from '@/containers/Accounts/utils';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import withAlertActions from '@/containers/Alert/withAlertActions';
import withDrawerActions from '@/containers/Drawer/withDrawerActions';
import { useDeleteAccount } from '@/hooks/query';
import { compose } from '@/utils';
/**
* Account delete alerts.
*/
function AccountDeleteAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: { accountId },
// #withAlertActions
closeAlert,
// #withDrawerActions
closeDrawer,
}) {
const { isLoading, mutateAsync: deleteAccount } = useDeleteAccount();
// handle cancel delete account alert.
const handleCancelAccountDelete = () => {
closeAlert(name);
};
// Handle confirm account delete.
const handleConfirmAccountDelete = () => {
deleteAccount(accountId)
.then(() => {
AppToaster.show({
message: intl.get('the_account_has_been_successfully_deleted'),
intent: Intent.SUCCESS,
});
closeAlert(name);
closeDrawer('account-drawer');
})
.catch(
({
response: {
data: { errors },
},
}) => {
handleDeleteErrors(errors);
closeAlert(name);
},
);
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'delete'} />}
icon="trash"
intent={Intent.DANGER}
isOpen={isOpen}
onCancel={handleCancelAccountDelete}
onConfirm={handleConfirmAccountDelete}
loading={isLoading}
>
<p>
<FormattedHTMLMessage
id={'once_delete_this_account_you_will_able_to_restore_it'}
/>
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
withDrawerActions,
)(AccountDeleteAlert);

View File

@@ -0,0 +1,66 @@
// @ts-nocheck
import React from 'react';
import intl from 'react-intl-universal';
import { AppToaster, FormattedMessage as T } from '@/components';
import { Intent, Alert } from '@blueprintjs/core';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import withAlertActions from '@/containers/Alert/withAlertActions';
import { compose } from '@/utils';
import { useInactivateAccount } from '@/hooks/query';
/**
* Account inactivate alert.
*/
function AccountInactivateAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: { accountId },
// #withAlertActions
closeAlert,
}) {
const { mutateAsync: inactivateAccount, isLoading } = useInactivateAccount();
const handleCancelInactiveAccount = () => {
closeAlert('account-inactivate');
};
const handleConfirmAccountActive = () => {
inactivateAccount(accountId)
.then(() => {
AppToaster.show({
message: intl.get('the_account_has_been_successfully_inactivated'),
intent: Intent.SUCCESS,
});
})
.catch(() => {})
.finally(() => {
closeAlert('account-inactivate');
});
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'inactivate'} />}
intent={Intent.WARNING}
isOpen={isOpen}
onCancel={handleCancelInactiveAccount}
onConfirm={handleConfirmAccountActive}
loading={isLoading}
>
<p>
<T id={'are_sure_to_inactive_this_account'} />
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
)(AccountInactivateAlert);

View File

@@ -0,0 +1,6 @@
// @ts-nocheck
import AccountDeleteAlert from './AccountDeleteAlert';
export default {
AccountDeleteAlert,
};

View File

@@ -0,0 +1,85 @@
// @ts-nocheck
import React from 'react';
import intl from 'react-intl-universal';
import { AppToaster, FormattedMessage as T } from '@/components';
import { Intent, Alert } from '@blueprintjs/core';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import withAlertActions from '@/containers/Alert/withAlertActions';
import withDrawerActions from '@/containers/Drawer/withDrawerActions';
import { handleDeleteErrors } from '@/containers/Purchases/Bills/BillForm/utils';
import { useDeleteBill } from '@/hooks/query';
import { compose } from '@/utils';
/**
* Bill delete alert.
*/
function BillDeleteAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: { billId },
// #withAlertActions
closeAlert,
// #withDrawerActions
closeDrawer,
}) {
const { isLoading, mutateAsync: deleteBillMutate } = useDeleteBill();
// Handle cancel Bill
const handleCancel = () => {
closeAlert(name);
};
// Handle confirm delete invoice
const handleConfirmBillDelete = () => {
deleteBillMutate(billId)
.then(() => {
AppToaster.show({
message: intl.get('the_bill_has_been_deleted_successfully'),
intent: Intent.SUCCESS,
});
closeDrawer('bill-drawer');
})
.catch(
({
response: {
data: { errors },
},
}) => {
handleDeleteErrors(errors);
},
)
.finally(() => {
closeAlert(name);
});
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'delete'} />}
icon={'trash'}
intent={Intent.DANGER}
isOpen={isOpen}
onCancel={handleCancel}
onConfirm={handleConfirmBillDelete}
loading={isLoading}
>
<p>
<T id={'once_delete_this_bill_you_will_able_to_restore_it'} />
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
withDrawerActions,
)(BillDeleteAlert);

View File

@@ -0,0 +1,70 @@
// @ts-nocheck
import React from 'react';
import { Intent, Alert } from '@blueprintjs/core';
import { FormattedMessage as T } from '@/components';
import intl from 'react-intl-universal';
import { useDeleteLandedCost } from '@/hooks/query';
import { AppToaster } from '@/components';
import withAlertActions from '@/containers/Alert/withAlertActions';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import { compose } from '@/utils';
/**
* Bill transaction delete alert.
*/
function BillTransactionDeleteAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: { BillId },
// #withAlertActions
closeAlert,
}) {
const { mutateAsync: deleteLandedCostMutate, isLoading } =
useDeleteLandedCost();
// Handle cancel delete.
const handleCancelAlert = () => {
closeAlert(name);
};
// Handle confirm delete .
const handleConfirmLandedCostDelete = () => {
deleteLandedCostMutate(BillId)
.then(() => {
AppToaster.show({
message: intl.get('landed_cost.action.delete.success_message'),
intent: Intent.SUCCESS,
});
closeAlert(name);
})
.catch(() => {
closeAlert(name);
});
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'delete'} />}
icon="trash"
intent={Intent.DANGER}
isOpen={isOpen}
onCancel={handleCancelAlert}
onConfirm={handleConfirmLandedCostDelete}
loading={isLoading}
>
<p>
<T id={`landed_cost.once_your_delete_this_located_landed_cost`} />
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
)(BillTransactionDeleteAlert);

View File

@@ -0,0 +1,68 @@
// @ts-nocheck
import React from 'react';
import { AppToaster, FormattedMessage as T } from '@/components';
import intl from 'react-intl-universal';
import { Intent, Alert } from '@blueprintjs/core';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import withAlertActions from '@/containers/Alert/withAlertActions';
import { useOpenBill } from '@/hooks/query';
import { compose } from '@/utils';
/**
* Bill open alert.
*/
function BillOpenAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: { billId },
// #withAlertActions
closeAlert,
}) {
const { isLoading, mutateAsync: openBillMutate } = useOpenBill();
// Handle cancel open bill alert.
const handleCancelOpenBill = () => {
closeAlert(name);
};
// Handle confirm bill open.
const handleConfirmBillOpen = () => {
openBillMutate(billId)
.then(() => {
AppToaster.show({
message: intl.get('the_bill_has_been_opened_successfully'),
intent: Intent.SUCCESS,
});
closeAlert(name);
})
.catch((error) => {
closeAlert(name);
});
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'open'} />}
intent={Intent.WARNING}
isOpen={isOpen}
onCancel={handleCancelOpenBill}
onConfirm={handleConfirmBillOpen}
loading={isLoading}
>
<p>
<T id={'are_sure_to_open_this_bill'} />
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
)(BillOpenAlert);

View File

@@ -0,0 +1,83 @@
// @ts-nocheck
import React from 'react';
import intl from 'react-intl-universal';
import {
AppToaster,
FormattedMessage as T,
FormattedHTMLMessage,
} from '@/components';
import { Intent, Alert } from '@blueprintjs/core';
import { useDeleteBranch } from '@/hooks/query';
import { handleDeleteErrors } from '@/containers/Preferences/Branches/utils';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import withAlertActions from '@/containers/Alert/withAlertActions';
import { compose } from '@/utils';
/**
* Branch delete alert.
*/
function BranchDeleteAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: { branchId },
// #withAlertActions
closeAlert,
}) {
const { mutateAsync: deleteBranch, isLoading } = useDeleteBranch();
// Handle cancel delete alert.
const handleCancelDelete = () => {
closeAlert(name);
};
// Handle confirm delete branch.
const handleConfirmDeleteBranch = () => {
deleteBranch(branchId)
.then(() => {
AppToaster.show({
message: intl.get('branch.alert.delete_message'),
intent: Intent.SUCCESS,
});
})
.catch(
({
response: {
data: { errors },
},
}) => {
handleDeleteErrors(errors);
},
)
.finally(() => {
closeAlert(name);
});
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'delete'} />}
icon="trash"
intent={Intent.DANGER}
isOpen={isOpen}
onCancel={handleCancelDelete}
onConfirm={handleConfirmDeleteBranch}
loading={isLoading}
>
<p>
<FormattedHTMLMessage id={'branch.once_delete_this_branch'} />
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
)(BranchDeleteAlert);

View File

@@ -0,0 +1,70 @@
// @ts-nocheck
import React from 'react';
import intl from 'react-intl-universal';
import { Intent, Alert } from '@blueprintjs/core';
import { AppToaster, FormattedMessage as T } from '@/components';
import { useMarkBranchAsPrimary } from '@/hooks/query';
import withAlertActions from '@/containers/Alert/withAlertActions';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import { compose } from '@/utils';
/**
* branch mark primary alert.
*/
function BranchMarkPrimaryAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: { branchId },
// #withAlertActions
closeAlert,
}) {
const { mutateAsync: markPrimaryBranchMutate, isLoading } =
useMarkBranchAsPrimary();
// Handle cancel mark primary alert.
const handleCancelMarkPrimaryAlert = () => {
closeAlert(name);
};
// andle cancel mark primary confirm.
const handleConfirmMarkPrimaryBranch = () => {
markPrimaryBranchMutate(branchId)
.then(() => {
AppToaster.show({
message: intl.get('branch.alert.mark_primary_message'),
intent: Intent.SUCCESS,
});
closeAlert(name);
})
.catch((error) => {
closeAlert(name);
});
};
return (
<Alert
// cancelButtonText={<T id={'cancel'} />}
// confirmButtonText={<T id={'make_primary'} />}
intent={Intent.WARNING}
isOpen={isOpen}
onCancel={handleCancelMarkPrimaryAlert}
onConfirm={handleConfirmMarkPrimaryBranch}
loading={isLoading}
>
<p>
<T id={'branch.alert.are_you_sure_you_want_to_make'} />
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
)(BranchMarkPrimaryAlert);

View File

@@ -0,0 +1,91 @@
// @ts-nocheck
import React from 'react';
import intl from 'react-intl-universal';
import { Intent, Alert } from '@blueprintjs/core';
import {
AppToaster,
FormattedMessage as T,
FormattedHTMLMessage,
} from '@/components';
import { useDeleteCashflowTransaction } from '@/hooks/query';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import withAlertActions from '@/containers/Alert/withAlertActions';
import withDrawerActions from '@/containers/Drawer/withDrawerActions';
import { compose } from '@/utils';
/**
* Account delete transaction alert.
*/
function AccountDeleteTransactionAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: { referenceId },
// #withAlertActions
closeAlert,
// #withDrawerActions
closeDrawer,
}) {
const { mutateAsync: deleteTransactionMutate, isLoading } =
useDeleteCashflowTransaction();
// handle cancel delete alert
const handleCancelDeleteAlert = () => {
closeAlert(name);
};
// handleConfirm delete transaction.
const handleConfirmTransactioneDelete = () => {
deleteTransactionMutate(referenceId)
.then(() => {
AppToaster.show({
message: intl.get('cash_flow_transaction.delete.alert_message'),
intent: Intent.SUCCESS,
});
closeDrawer('cashflow-transaction-drawer');
})
.catch(
({
response: {
data: { errors },
},
}) => {},
)
.finally(() => {
closeAlert(name);
});
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'delete'} />}
icon="trash"
intent={Intent.DANGER}
isOpen={isOpen}
onCancel={handleCancelDeleteAlert}
onConfirm={handleConfirmTransactioneDelete}
loading={isLoading}
>
<p>
<FormattedHTMLMessage
id={
'cash_flow_transaction_once_delete_this_transaction_you_will_able_to_restore_it'
}
/>
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
withDrawerActions,
)(AccountDeleteTransactionAlert);

View File

@@ -0,0 +1,67 @@
// @ts-nocheck
import React from 'react';
import intl from 'react-intl-universal';
import { Intent, Alert } from '@blueprintjs/core';
import { AppToaster, FormattedMessage as T } from '@/components';
import { useActivateContact } from '@/hooks/query';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import withAlertActions from '@/containers/Alert/withAlertActions';
import { compose } from '@/utils';
/**
* Contact activate alert.
*/
function ContactActivateAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: { contactId, service },
// #withAlertActions
closeAlert,
}) {
const { mutateAsync: activateContact, isLoading } = useActivateContact();
// Handle activate contact alert cancel.
const handleCancelActivateContact = () => {
closeAlert(name);
};
// Handle confirm contact activated.
const handleConfirmContactActivate = () => {
activateContact(contactId)
.then(() => {
AppToaster.show({
message: intl.get('the_contact_has_been_activated_successfully'),
intent: Intent.SUCCESS,
});
})
.catch((error) => {})
.finally(() => {
closeAlert(name);
});
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'activate'} />}
intent={Intent.WARNING}
isOpen={isOpen}
onCancel={handleCancelActivateContact}
loading={isLoading}
onConfirm={handleConfirmContactActivate}
>
<p>{intl.get('are_sure_to_activate_this_contact')}</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
)(ContactActivateAlert);

View File

@@ -0,0 +1,70 @@
// @ts-nocheck
import React from 'react';
import intl from 'react-intl-universal';
import { AppToaster, FormattedMessage as T } from '@/components';
import { Intent, Alert } from '@blueprintjs/core';
import { useInactivateContact } from '@/hooks/query';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import withAlertActions from '@/containers/Alert/withAlertActions';
import { compose } from '@/utils';
/**
* Contact inactivate alert.
*/
function ContactInactivateAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: { contactId, service },
// #withAlertActions
closeAlert,
}) {
const { mutateAsync: inactivateContact, isLoading } = useInactivateContact();
// Handle cancel inactivate alert.
const handleCancelInactivateContact = () => {
closeAlert(name);
};
// Handle confirm contact Inactive.
const handleConfirmContactInactive = () => {
inactivateContact(contactId)
.then(() => {
AppToaster.show({
message: intl.get('the_contact_has_been_inactivated_successfully'),
intent: Intent.SUCCESS,
});
})
.catch((error) => {})
.finally(() => {
closeAlert(name);
});
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'inactivate'} />}
intent={Intent.WARNING}
isOpen={isOpen}
onCancel={handleCancelInactivateContact}
onConfirm={handleConfirmContactInactive}
loading={isLoading}
>
<p>
{intl.get('are_sure_to_inactive_this_contact', {
name: service,
})}
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
)(ContactInactivateAlert);

View File

@@ -0,0 +1,87 @@
// @ts-nocheck
import React from 'react';
import intl from 'react-intl-universal';
import { Intent, Alert } from '@blueprintjs/core';
import {
AppToaster,
FormattedMessage as T,
FormattedHTMLMessage,
} from '@/components';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import withAlertActions from '@/containers/Alert/withAlertActions';
import withDrawerActions from '@/containers/Drawer/withDrawerActions';
import { useDeleteCreditNote } from '@/hooks/query';
import { handleDeleteErrors } from '@/containers/Sales/CreditNotes/CreditNotesLanding/utils';
import { compose } from '@/utils';
/**
* Credit note delete alert.
*/
function CreditNoteDeleteAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: { creditNoteId },
// #withAlertActions
closeAlert,
// #withDrawerActions
closeDrawer,
}) {
const { isLoading, mutateAsync: deleteCreditNoteMutate } =
useDeleteCreditNote();
// handle cancel delete credit note alert.
const handleCancelDeleteAlert = () => {
closeAlert(name);
};
const handleConfirmCreditNoteDelete = () => {
deleteCreditNoteMutate(creditNoteId)
.then(() => {
AppToaster.show({
message: intl.get('credit_note.alert.delete_message'),
intent: Intent.SUCCESS,
});
closeDrawer('credit-note-detail-drawer');
})
.catch(
({
response: {
data: { errors },
},
}) => {
handleDeleteErrors(errors);
},
)
.finally(() => {
closeAlert(name);
});
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'delete'} />}
icon="trash"
intent={Intent.DANGER}
isOpen={isOpen}
onCancel={handleCancelDeleteAlert}
onConfirm={handleConfirmCreditNoteDelete}
loading={isLoading}
>
<p>
<FormattedHTMLMessage id={'credit_note.once_delete_this_credit_note'} />
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
withDrawerActions,
)(CreditNoteDeleteAlert);

View File

@@ -0,0 +1,68 @@
// @ts-nocheck
import React from 'react';
import intl from 'react-intl-universal';
import { Intent, Alert } from '@blueprintjs/core';
import { AppToaster, FormattedMessage as T } from '@/components';
import { useOpenCreditNote } from '@/hooks/query';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import withAlertActions from '@/containers/Alert/withAlertActions';
import { compose } from '@/utils';
/**
* Credit note opened alert.
*/
function CreditNoteOpenedAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: { creditNoteId },
// #withAlertActions
closeAlert,
}) {
const { mutateAsync: openCreditNoteMutate, isLoading } = useOpenCreditNote();
// Handle cancel opened credit note alert.
const handleAlertCancel = () => {
closeAlert(name);
};
// Handle confirm credit note opened.
const handleAlertConfirm = () => {
openCreditNoteMutate(creditNoteId)
.then(() => {
AppToaster.show({
message: intl.get('credit_note_opened.alert.success_message'),
intent: Intent.SUCCESS,
});
})
.catch((error) => {})
.finally(() => {
closeAlert(name);
});
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'open'} />}
intent={Intent.WARNING}
isOpen={isOpen}
onCancel={handleAlertCancel}
onConfirm={handleAlertConfirm}
loading={isLoading}
>
<p>
<T id={'credit_note_opened.are_sure_to_open_this_credit'} />
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
)(CreditNoteOpenedAlert);

View File

@@ -0,0 +1,90 @@
// @ts-nocheck
import React from 'react';
import intl from 'react-intl-universal';
import { Intent, Alert } from '@blueprintjs/core';
import {
AppToaster,
FormattedMessage as T,
FormattedHTMLMessage,
} from '@/components';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import withAlertActions from '@/containers/Alert/withAlertActions';
import withDrawerActions from '@/containers/Drawer/withDrawerActions';
import { useDeleteReconcileCredit } from '@/hooks/query';
import { compose } from '@/utils';
/**
* Reconcile credit note delete alert.
*/
function ReconcileCreditNoteDeleteAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: { creditNoteId },
// #withAlertActions
closeAlert,
// #withDrawerActions
closeDrawer,
}) {
const { isLoading, mutateAsync: deleteReconcileCreditMutate } =
useDeleteReconcileCredit();
// handle cancel delete credit note alert.
const handleCancelDeleteAlert = () => {
closeAlert(name);
};
const handleConfirmVendorCreditDelete = () => {
deleteReconcileCreditMutate(creditNoteId)
.then(() => {
AppToaster.show({
message: intl.get('reconcile_credit_note.alert.success_message'),
intent: Intent.SUCCESS,
});
})
.catch(
({
response: {
data: { errors },
},
}) => {
// handleDeleteErrors(errors);
},
)
.finally(() => {
closeAlert(name);
});
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'delete'} />}
icon="trash"
intent={Intent.DANGER}
isOpen={isOpen}
onCancel={handleCancelDeleteAlert}
onConfirm={handleConfirmVendorCreditDelete}
loading={isLoading}
>
<p>
<FormattedHTMLMessage
id={
'reconcile_credit_note.once_you_delete_this_reconcile_credit_note'
}
/>
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
withDrawerActions,
)(ReconcileCreditNoteDeleteAlert);

View File

@@ -0,0 +1,77 @@
// @ts-nocheck
import React from 'react';
import intl from 'react-intl-universal';
import { Intent, Alert } from '@blueprintjs/core';
import { FormattedMessage as T, AppToaster } from '@/components';
import { useDeleteRefundCreditNote } from '@/hooks/query';
import withAlertActions from '@/containers/Alert/withAlertActions';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import withDrawerActions from '@/containers/Drawer/withDrawerActions';
import { compose } from '@/utils';
/**
* Refund credit transactions delete alert
*/
function RefundCreditNoteDeleteAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: { creditNoteId },
// #withAlertActions
closeAlert,
// #withDrawerActions
closeDrawer,
}) {
const { mutateAsync: deleteRefundCreditMutate, isLoading } =
useDeleteRefundCreditNote();
// Handle cancel delete.
const handleCancelAlert = () => {
closeAlert(name);
};
// Handle confirm delete .
const handleConfirmRefundCreditDelete = () => {
deleteRefundCreditMutate(creditNoteId)
.then(() => {
AppToaster.show({
message: intl.get('refund_credit_transactions.alert.delete_message'),
intent: Intent.SUCCESS,
});
closeDrawer('refund-credit-detail-drawer');
})
.catch(() => {})
.finally(() => {
closeAlert(name);
});
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'delete'} />}
icon="trash"
intent={Intent.DANGER}
isOpen={isOpen}
onCancel={handleCancelAlert}
onConfirm={handleConfirmRefundCreditDelete}
loading={isLoading}
>
<p>
<T
id={`refund_credit_transactions.once_your_delete_this_refund_credit_note`}
/>
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
withDrawerActions,
)(RefundCreditNoteDeleteAlert);

View File

@@ -0,0 +1,85 @@
// @ts-nocheck
import React from 'react';
import intl from 'react-intl-universal';
import {
AppToaster,
FormattedMessage as T,
FormattedHTMLMessage,
} from '@/components';
import { Intent, Alert } from '@blueprintjs/core';
import { useDeleteCurrency } from '@/hooks/query';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import withAlertActions from '@/containers/Alert/withAlertActions';
import { compose } from '@/utils';
/**
* Currency delete alerts.
*/
function CurrencyDeleteAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: { currency_code },
// #withAlertActions
closeAlert,
}) {
const { mutateAsync: deleteCurrency, isLoading } = useDeleteCurrency();
// handle cancel delete currency alert.
const handleCancelCurrencyDelete = () => closeAlert(name);
// handle alert confirm delete currency.
const handleConfirmCurrencyDelete = () => {
deleteCurrency(currency_code)
.then((response) => {
AppToaster.show({
message: intl.get('the_currency_has_been_deleted_successfully'),
intent: Intent.SUCCESS,
});
closeAlert(name);
})
.catch(
({
response: {
data: { errors },
},
}) => {
if (errors.find((e) => e.type === 'CANNOT_DELETE_BASE_CURRENCY')) {
AppToaster.show({
intent: Intent.DANGER,
message: 'Cannot delete the base currency.',
});
}
closeAlert(name);
},
);
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'delete'} />}
intent={Intent.DANGER}
isOpen={isOpen}
onCancel={handleCancelCurrencyDelete}
onConfirm={handleConfirmCurrencyDelete}
loading={isLoading}
>
<p>
<FormattedHTMLMessage
id={'once_delete_this_currency_you_will_able_to_restore_it'}
/>
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
)(CurrencyDeleteAlert);

View File

@@ -0,0 +1,69 @@
// @ts-nocheck
import React from 'react';
import intl from 'react-intl-universal';
import { Intent, Alert } from '@blueprintjs/core';
import { AppToaster, FormattedMessage as T } from '@/components';
import { useActivateContact } from '@/hooks/query';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import withAlertActions from '@/containers/Alert/withAlertActions';
import { compose } from '@/utils';
/**
* Customer activate alert.
*/
function CustomerActivateAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: { customerId, service },
// #withAlertActions
closeAlert,
}) {
const { mutateAsync: activateContact, isLoading } = useActivateContact();
// Handle activate constomer alert cancel.
const handleCancelActivateCustomer = () => {
closeAlert(name);
};
// Handle confirm customer activated.
const handleConfirmCustomerActivate = () => {
activateContact(customerId)
.then(() => {
AppToaster.show({
message: intl.get('customer.alert.activated_message'),
intent: Intent.SUCCESS,
});
})
.catch((error) => {})
.finally(() => {
closeAlert(name);
});
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'activate'} />}
intent={Intent.WARNING}
isOpen={isOpen}
onCancel={handleCancelActivateCustomer}
loading={isLoading}
onConfirm={handleConfirmCustomerActivate}
>
<p>
{intl.get('customer.alert.are_you_sure_want_to_activate_this_customer')}
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
)(CustomerActivateAlert);

View File

@@ -0,0 +1,77 @@
// @ts-nocheck
import React, { useCallback, useState } from 'react';
import { FormattedMessage as T } from '@/components';
import intl from 'react-intl-universal';
import { Intent, Alert } from '@blueprintjs/core';
import { AppToaster } from '@/components';
import { transformErrors } from '@/containers/Customers/utils';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import withAlertActions from '@/containers/Alert/withAlertActions';
import { compose } from '@/utils';
/**
* Customer bulk delete alert.
*/
function CustomerBulkDeleteAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: { customersIds },
// #withAlertActions
closeAlert,
}) {
const [isLoading, setLoading] = useState(false);
// handle cancel delete alert.
const handleCancelDeleteAlert = () => {
closeAlert(name);
};
// Handle confirm customers bulk delete.
const handleConfirmBulkDelete = useCallback(() => {
setLoading(true);
requestDeleteBulkCustomers(customersIds)
.then(() => {
AppToaster.show({
message: intl.get('the_customers_has_been_deleted_successfully'),
intent: Intent.SUCCESS,
});
})
.catch((errors) => {
transformErrors(errors);
})
.finally(() => {
setLoading(false);
closeAlert(name);
});
}, [requestDeleteBulkCustomers, customersIds]);
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'delete'} />}
icon="trash"
intent={Intent.DANGER}
isOpen={isOpen}
onCancel={handleCancelDeleteAlert}
onConfirm={handleConfirmBulkDelete}
loading={isLoading}
>
<p>
<T id={'once_delete_these_customers_you_will_not_able_restore_them'} />
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
)(CustomerBulkDeleteAlert);

View File

@@ -0,0 +1,90 @@
// @ts-nocheck
import React, { useCallback } from 'react';
import intl from 'react-intl-universal';
import { Intent, Alert } from '@blueprintjs/core';
import {
AppToaster,
FormattedMessage as T,
FormattedHTMLMessage,
} from '@/components';
import { transformErrors } from '@/containers/Customers/utils';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import withAlertActions from '@/containers/Alert/withAlertActions';
import withDrawerActions from '@/containers/Drawer/withDrawerActions';
import { useDeleteCustomer } from '@/hooks/query';
import { compose } from '@/utils';
/**
* Customer delete alert.
*/
function CustomerDeleteAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: { contactId },
// #withAlertActions
closeAlert,
// #withDrawerActions
closeDrawer,
}) {
const { mutateAsync: deleteCustomerMutate, isLoading } = useDeleteCustomer();
// handle cancel delete alert.
const handleCancelDeleteAlert = () => {
closeAlert(name);
};
// handle confirm delete customer.
const handleConfirmDeleteCustomer = useCallback(() => {
deleteCustomerMutate(contactId)
.then(() => {
AppToaster.show({
message: intl.get('the_customer_has_been_deleted_successfully'),
intent: Intent.SUCCESS,
});
closeDrawer('customer-detail-drawer');
})
.catch(
({
response: {
data: { errors },
},
}) => {
transformErrors(errors);
},
)
.finally(() => {
closeAlert(name);
});
}, [deleteCustomerMutate, contactId, closeAlert, name]);
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'delete'} />}
icon="trash"
intent={Intent.DANGER}
isOpen={isOpen}
onCancel={handleCancelDeleteAlert}
onConfirm={handleConfirmDeleteCustomer}
loading={isLoading}
>
<p>
<FormattedHTMLMessage
id={'once_delete_this_customer_you_will_able_to_restore_it'}
/>
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
withDrawerActions,
)(CustomerDeleteAlert);

View File

@@ -0,0 +1,69 @@
// @ts-nocheck
import React from 'react';
import intl from 'react-intl-universal';
import { AppToaster, FormattedMessage as T } from '@/components';
import { Intent, Alert } from '@blueprintjs/core';
import { useInactivateContact } from '@/hooks/query';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import withAlertActions from '@/containers/Alert/withAlertActions';
import { compose } from '@/utils';
/**
* customer inactivate alert.
*/
function CustomerInactivateAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: { customerId, service },
// #withAlertActions
closeAlert,
}) {
const { mutateAsync: inactivateContact, isLoading } = useInactivateContact();
// Handle cancel inactivate alert.
const handleCancelInactivateCustomer = () => {
closeAlert(name);
};
// Handle confirm contact Inactive.
const handleConfirmCustomerInactive = () => {
inactivateContact(customerId)
.then(() => {
AppToaster.show({
message: intl.get('the_contact_has_been_inactivated_successfully'),
intent: Intent.SUCCESS,
});
})
.catch((error) => {})
.finally(() => {
closeAlert(name);
});
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'inactivate'} />}
intent={Intent.WARNING}
isOpen={isOpen}
onCancel={handleCancelInactivateCustomer}
onConfirm={handleConfirmCustomerInactive}
loading={isLoading}
>
<p>
{intl.get(
'customer.alert.are_you_sure_want_to_inactivate_this_customer',
)}
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
)(CustomerInactivateAlert);

View File

@@ -0,0 +1,71 @@
// @ts-nocheck
import React, { useCallback } from 'react';
import intl from 'react-intl-universal';
import { AppToaster, FormattedMessage as T } from '@/components';
import { Intent, Alert } from '@blueprintjs/core';
import { queryCache } from 'react-query';
import { useApproveEstimate } from '@/hooks/query';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import withAlertActions from '@/containers/Alert/withAlertActions';
import { compose } from '@/utils';
/**
* Estimate approve alert.
*/
function EstimateApproveAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: { estimateId },
// #withAlertActions
closeAlert,
}) {
const { mutateAsync: deliverEstimateMutate, isLoading } =
useApproveEstimate();
// handle cancel approve alert.
const handleCancelApproveEstimate = () => {
closeAlert(name);
};
// Handle confirm estimate approve.
const handleConfirmEstimateApprove = useCallback(() => {
deliverEstimateMutate(estimateId)
.then(() => {
AppToaster.show({
message: intl.get('the_estimate_has_been_approved_successfully'),
intent: Intent.SUCCESS,
});
queryCache.invalidateQueries('estimates-table');
})
.catch((error) => {})
.finally(() => {
closeAlert(name);
});
}, [estimateId, deliverEstimateMutate, closeAlert, name]);
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'approve'} />}
intent={Intent.WARNING}
isOpen={isOpen}
loading={isLoading}
onCancel={handleCancelApproveEstimate}
onConfirm={handleConfirmEstimateApprove}
>
<p>
<T id={'are_sure_to_approve_this_estimate'} />
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
)(EstimateApproveAlert);

View File

@@ -0,0 +1,99 @@
// @ts-nocheck
import React, { useCallback } from 'react';
import intl from 'react-intl-universal';
import { Intent, Alert } from '@blueprintjs/core';
import {
AppToaster,
FormattedMessage as T,
FormattedHTMLMessage,
} from '@/components';
import { useDeleteEstimate } from '@/hooks/query';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import withAlertActions from '@/containers/Alert/withAlertActions';
import withDrawerActions from '@/containers/Drawer/withDrawerActions';
import { compose } from '@/utils';
/**
* Estimate delete alert.
*/
function EstimateDeleteAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: { estimateId },
// #withAlertActions
closeAlert,
// #withDrawerActions
closeDrawer,
}) {
const { mutateAsync: deleteEstimateMutate, isLoading } = useDeleteEstimate();
// handle cancel delete alert.
const handleAlertCancel = () => {
closeAlert(name);
};
// handle confirm delete estimate
const handleAlertConfirm = () => {
deleteEstimateMutate(estimateId)
.then(() => {
AppToaster.show({
message: intl.get('the_estimate_has_been_deleted_successfully'),
intent: Intent.SUCCESS,
});
closeDrawer('estimate-detail-drawer');
})
.catch(
({
response: {
data: { errors },
},
}) => {
if (
errors.find((e) => e.type === 'SALE_ESTIMATE_CONVERTED_TO_INVOICE')
) {
AppToaster.show({
intent: Intent.DANGER,
message: intl.get(
'estimate.delete.error.estimate_converted_to_invoice',
),
});
}
},
)
.finally(() => {
closeAlert(name);
});
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'delete'} />}
icon="trash"
intent={Intent.DANGER}
isOpen={isOpen}
loading={isLoading}
onCancel={handleAlertCancel}
onConfirm={handleAlertConfirm}
>
<p>
<FormattedHTMLMessage
id={'once_delete_this_estimate_you_will_able_to_restore_it'}
/>
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
withDrawerActions,
)(EstimateDeleteAlert);

View File

@@ -0,0 +1,70 @@
// @ts-nocheck
import React from 'react';
import intl from 'react-intl-universal';
import { AppToaster, FormattedMessage as T } from '@/components';
import { Intent, Alert } from '@blueprintjs/core';
import { useDeliverEstimate } from '@/hooks/query';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import withAlertActions from '@/containers/Alert/withAlertActions';
import { compose } from '@/utils';
/**
* Estimate delivered alert.
*/
function EstimateDeliveredAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: { estimateId },
// #withAlertActions
closeAlert,
}) {
const { mutateAsync: deliverEstimateMutate, isLoading } =
useDeliverEstimate();
// Handle cancel delivered estimate alert.
const handleAlertCancel = () => {
closeAlert(name);
};
// Handle confirm estimate delivered.
const handleAlertConfirm = () => {
deliverEstimateMutate(estimateId)
.then(() => {
AppToaster.show({
message: intl.get('the_estimate_has_been_delivered_successfully'),
intent: Intent.SUCCESS,
});
})
.catch((error) => {})
.finally(() => {
closeAlert(name);
});
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'deliver'} />}
intent={Intent.WARNING}
isOpen={isOpen}
onCancel={handleAlertCancel}
onConfirm={handleAlertConfirm}
loading={isLoading}
>
<p>
<T id={'are_sure_to_deliver_this_estimate'} />
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
)(EstimateDeliveredAlert);

View File

@@ -0,0 +1,69 @@
// @ts-nocheck
import React from 'react';
import intl from 'react-intl-universal';
import { AppToaster, FormattedMessage as T } from '@/components';
import { Intent, Alert } from '@blueprintjs/core';
import { useRejectEstimate } from '@/hooks/query';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import withAlertActions from '@/containers/Alert/withAlertActions';
import { compose } from '@/utils';
/**
* Estimate reject delete alerts.
*/
function EstimateRejectAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: { estimateId },
// #withAlertActions
closeAlert,
}) {
const { mutateAsync: rejectEstimateMutate, isLoading } = useRejectEstimate();
// Handle cancel reject estimate alert.
const handleCancelRejectEstimate = () => {
closeAlert(name);
};
// Handle confirm estimate reject.
const handleConfirmEstimateReject = () => {
rejectEstimateMutate(estimateId)
.then(() => {
AppToaster.show({
message: intl.get('the_estimate_has_been_rejected_successfully'),
intent: Intent.SUCCESS,
});
})
.catch((error) => {})
.finally(() => {
closeAlert(name);
});
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'reject'} />}
intent={Intent.WARNING}
isOpen={isOpen}
onCancel={handleCancelRejectEstimate}
onConfirm={handleConfirmEstimateReject}
loading={isLoading}
>
<p>
<T id={'are_sure_to_reject_this_estimate'} />
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
)(EstimateRejectAlert);

View File

@@ -0,0 +1,73 @@
// @ts-nocheck
import React, { useState } from 'react';
import { FormattedMessage as T } from '@/components';
import intl from 'react-intl-universal';
import { Intent, Alert } from '@blueprintjs/core';
import { size } from 'lodash';
import { AppToaster } from '@/components';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import withAlertActions from '@/containers/Alert/withAlertActions';
import { compose } from '@/utils';
/**
* Exchange rate bulk delete alert.
*/
function ExchangeRateBulkDeleteAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: { exchangeRatesIds },
// #withAlertActions
closeAlert,
}) {
// handle cancel item bulk delete alert.
const handleCancelBulkDelete = () => {
closeAlert(name);
};
// handle confirm Exchange Rates bulk delete.
// const handleConfirmBulkDelete = () => {
// bulkDeleteExchangeRate(exchangeRatesIds)
// .then(() => {
// AppToaster.show({
// message: formatMessage({
// id: 'the_exchange_rates_has_been_successfully_deleted',
// }),
// intent: Intent.SUCCESS,
// });
// })
// .catch(({ errors }) => {
// handleDeleteErrors(errors);
// });
// };
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={
<T id={'delete_count'} values={{ count: size(exchangeRatesIds) }} />
}
icon="trash"
intent={Intent.DANGER}
isOpen={isOpen}
onCancel={handleCancelBulkDelete}
// onConfirm={}
// loading={isLoading}
>
<p>
<T
id={'once_delete_these_exchange_rates_you_will_not_able_restore_them'}
/>
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
)(ExchangeRateBulkDeleteAlert);

View File

@@ -0,0 +1,72 @@
// @ts-nocheck
import React from 'react';
import intl from 'react-intl-universal';
import {
AppToaster,
FormattedMessage as T,
FormattedHTMLMessage,
} from '@/components';
import { Intent, Alert } from '@blueprintjs/core';
import { useDeleteExchangeRate } from '@/hooks/query';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import withAlertActions from '@/containers/Alert/withAlertActions';
import { compose } from '@/utils';
/**
* exchange rate delete alerts.
*/
function ExchangeRateDeleteAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: { exchangeRateId },
// #withAlertActions
closeAlert,
}) {
const { mutateAsync: deleteExchangeRate, isLoading } =
useDeleteExchangeRate();
// Handle cancel delete exchange rate alert.
const handleCancelExchangeRateDelete = () => closeAlert(name);
const handelConfirmExchangeRateDelete = () => {
deleteExchangeRate(exchangeRateId)
.then((response) => {
AppToaster.show({
message: intl.get('the_exchange_rates_has_been_deleted_successfully'),
intent: Intent.SUCCESS,
});
closeAlert(name);
})
.catch(() => {
closeAlert(name);
});
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'delete'} />}
intent={Intent.DANGER}
isOpen={isOpen}
onCancel={handleCancelExchangeRateDelete}
onConfirm={handelConfirmExchangeRateDelete}
loading={isLoading}
>
<p>
<FormattedHTMLMessage
id={'once_delete_this_exchange_rate_you_will_able_to_restore_it'}
/>
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
)(ExchangeRateDeleteAlert);

View File

@@ -0,0 +1,67 @@
// @ts-nocheck
import React from 'react';
import { FormattedMessage as T } from '@/components';
import intl from 'react-intl-universal';
import { Intent, Alert } from '@blueprintjs/core';
import { AppToaster } from '@/components';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import withAlertActions from '@/containers/Alert/withAlertActions';
import { compose } from '@/utils';
/**
* Expense bulk delete alert.
*/
function ExpenseBulkDeleteAlert({
closeAlert,
// #withAlertStoreConnect
name,
payload: { expenseId, selectedCount },
isOpen,
}) {
// Handle confirm journals bulk delete.
const handleConfirmBulkDelete = () => {
// requestDeleteBulkExpenses(bulkDelete)
// .then(() => {
// AppToaster.show({
// message: formatMessage(
// { id: 'the_expenses_have_been_deleted_successfully' },
// { count: selectedRowsCount },
// ),
// intent: Intent.SUCCESS,
// });
// })
// .catch((error) => {
// });
};
// Handle cancel bulk delete alert.
const handleCancelBulkDelete = () => {
closeAlert(name);
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={
<T id={'delete_count'} values={{ count: selectedCount }} />
}
icon="trash"
intent={Intent.DANGER}
isOpen={isOpen}
onCancel={handleCancelBulkDelete}
onConfirm={handleConfirmBulkDelete}
>
<p>
<T id={'once_delete_these_expenses_you_will_not_able_restore_them'} />
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
)(ExpenseBulkDeleteAlert);

View File

@@ -0,0 +1,92 @@
// @ts-nocheck
import React from 'react';
import intl from 'react-intl-universal';
import { AppToaster, FormattedMessage as T } from '@/components';
import { Intent, Alert } from '@blueprintjs/core';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import withAlertActions from '@/containers/Alert/withAlertActions';
import withDrawerActions from '@/containers/Drawer/withDrawerActions';
import { useDeleteExpense } from '@/hooks/query';
import { compose } from '@/utils';
/**
* Expense delete alert.
*/
function ExpenseDeleteAlert({
// #withAlertActions
closeAlert,
// #withAlertStoreConnect
isOpen,
payload: { expenseId },
// #withDrawerActions
closeDrawer,
}) {
const { mutateAsync: deleteExpenseMutate, isLoading } = useDeleteExpense();
// Handle cancel expense journal.
const handleCancelExpenseDelete = () => {
closeAlert('expense-delete');
};
// Handle confirm delete expense.
const handleConfirmExpenseDelete = () => {
deleteExpenseMutate(expenseId)
.then(() => {
AppToaster.show({
message: intl.get('the_expense_has_been_deleted_successfully', {
number: expenseId,
}),
intent: Intent.SUCCESS,
});
closeDrawer('expense-drawer');
})
.catch(
({
response: {
data: { errors },
},
}) => {
if (
errors.find((e) => e.type === 'EXPENSE_HAS_ASSOCIATED_LANDED_COST')
) {
AppToaster.show({
intent: Intent.DANGER,
message: intl.get(
'couldn_t_delete_expense_transaction_has_associated_located_landed_cost_transaction',
),
});
}
},
)
.finally(() => {
closeAlert('expense-delete');
});
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'delete'} />}
icon="trash"
intent={Intent.DANGER}
isOpen={isOpen}
onCancel={handleCancelExpenseDelete}
onConfirm={handleConfirmExpenseDelete}
loading={isLoading}
>
<p>
<T id={'once_delete_this_expense_you_will_able_to_restore_it'} />
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
withDrawerActions,
)(ExpenseDeleteAlert);

View File

@@ -0,0 +1,56 @@
// @ts-nocheck
import React from 'react';
import { Intent, Alert } from '@blueprintjs/core';
import { FormattedMessage as T } from '@/components';
import withAlertActions from '@/containers/Alert/withAlertActions';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import { compose, saveInvoke } from '@/utils';
/**
* Alert description.
*/
function ExpenseDeleteEntriesAlert({
name,
onConfirm,
// #withAlertStoreConnect
isOpen,
payload: { },
// #withAlertActions
closeAlert,
}) {
// Handle the alert cancel.
const handleCancel = () => {
closeAlert(name);
};
// Handle confirm the alert.
const handleConfirm = (event) => {
closeAlert(name);
saveInvoke(onConfirm, event)
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'clear_all_lines'} />}
intent={Intent.DANGER}
isOpen={isOpen}
onCancel={handleCancel}
onConfirm={handleConfirm}
loading={false}
>
<p>
Clearing the table lines will delete all expense amounts were applied, Is this okay?
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
)(ExpenseDeleteEntriesAlert);

View File

@@ -0,0 +1,65 @@
// @ts-nocheck
import React from 'react';
import intl from 'react-intl-universal';
import { Intent, Alert } from '@blueprintjs/core';
import { AppToaster, FormattedMessage as T } from '@/components';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import withAlertActions from '@/containers/Alert/withAlertActions';
import { usePublishExpense } from '@/hooks/query';
import { compose } from '@/utils';
/**
* Expense publish alert.
*/
function ExpensePublishAlert({
closeAlert,
// #withAlertStoreConnect
name,
payload: { expenseId },
isOpen,
}) {
const { mutateAsync: publishExpenseMutate, isLoading } = usePublishExpense();
const handleCancelPublishExpense = () => {
closeAlert('expense-publish');
};
// Handle publish expense confirm.
const handleConfirmPublishExpense = () => {
publishExpenseMutate(expenseId)
.then(() => {
AppToaster.show({
message: intl.get('the_expense_has_been_published'),
intent: Intent.SUCCESS,
});
closeAlert(name);
})
.catch((error) => {
closeAlert(name);
});
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'publish'} />}
intent={Intent.WARNING}
isOpen={isOpen}
onCancel={handleCancelPublishExpense}
onConfirm={handleConfirmPublishExpense}
loading={isLoading}
>
<p>
<T id={'are_sure_to_publish_this_expense'} />
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
)(ExpensePublishAlert);

View File

@@ -0,0 +1,68 @@
// @ts-nocheck
import React from 'react';
import intl from 'react-intl-universal';
import { AppToaster, FormattedMessage as T } from '@/components';
import { Intent, Alert } from '@blueprintjs/core';
import { useCancelBadDebt } from '@/hooks/query';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import withAlertActions from '@/containers/Alert/withAlertActions';
import { compose } from '@/utils';
/**
* Cancel bad debt alert.
*/
function CancelBadDebtAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: { invoiceId },
// #withAlertActions
closeAlert,
}) {
// handle cancel alert.
const handleCancel = () => {
closeAlert(name);
};
const { mutateAsync: cancelBadDebtMutate, isLoading } = useCancelBadDebt();
// handleConfirm alert.
const handleConfirm = () => {
cancelBadDebtMutate(invoiceId)
.then(() => {
AppToaster.show({
message: intl.get('bad_debt.cancel_alert.success_message'),
intent: Intent.SUCCESS,
});
})
.catch(() => {})
.finally(() => {
closeAlert(name);
});
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'save'} />}
intent={Intent.WARNING}
isOpen={isOpen}
onCancel={handleCancel}
onConfirm={handleConfirm}
loading={isLoading}
>
<p>
<T id={'bad_debt.cancel_alert.message'} />
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
)(CancelBadDebtAlert);

View File

@@ -0,0 +1,91 @@
// @ts-nocheck
import React from 'react';
import intl from 'react-intl-universal';
import { Intent, Alert } from '@blueprintjs/core';
import {
AppToaster,
FormattedMessage as T,
FormattedHTMLMessage,
} from '@/components';
import { useDeleteInvoice } from '@/hooks/query';
import { handleDeleteErrors } from '@/containers/Sales/Invoices/InvoicesLanding/components';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import withAlertActions from '@/containers/Alert/withAlertActions';
import withDrawerActions from '@/containers/Drawer/withDrawerActions';
import { compose } from '@/utils';
/**
* Invoice delete alert.
*/
function InvoiceDeleteAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: { invoiceId },
// #withAlertActions
closeAlert,
// #withDrawerActions
closeDrawer,
}) {
const { mutateAsync: deleteInvoiceMutate, isLoading } = useDeleteInvoice();
// handle cancel delete invoice alert.
const handleCancelDeleteAlert = () => {
closeAlert(name);
};
// handleConfirm delete invoice
const handleConfirmInvoiceDelete = () => {
deleteInvoiceMutate(invoiceId)
.then(() => {
AppToaster.show({
message: intl.get('the_invoice_has_been_deleted_successfully'),
intent: Intent.SUCCESS,
});
closeDrawer('invoice-detail-drawer');
})
.catch(
({
response: {
data: { errors },
},
}) => {
handleDeleteErrors(errors);
},
)
.finally(() => {
closeAlert(name);
});
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'delete'} />}
icon="trash"
intent={Intent.DANGER}
isOpen={isOpen}
onCancel={handleCancelDeleteAlert}
onConfirm={handleConfirmInvoiceDelete}
loading={isLoading}
>
<p>
<FormattedHTMLMessage
id={'once_delete_this_invoice_you_will_able_to_restore_it'}
/>
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
withDrawerActions,
)(InvoiceDeleteAlert);

View File

@@ -0,0 +1,69 @@
// @ts-nocheck
import React from 'react';
import intl from 'react-intl-universal';
import { AppToaster, FormattedMessage as T } from '@/components';
import { Intent, Alert } from '@blueprintjs/core';
import { useDeliverInvoice } from '@/hooks/query';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import withAlertActions from '@/containers/Alert/withAlertActions';
import { compose } from '@/utils';
/**
* Sale invoice alert.
*/
function InvoiceDeliverAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: { invoiceId },
// #withAlertActions
closeAlert,
}) {
const { mutateAsync: deliverInvoiceMutate, isLoading } = useDeliverInvoice();
// handle cancel delete deliver alert.
const handleCancelDeleteAlert = () => {
closeAlert(name);
};
// Handle confirm invoice deliver.
const handleConfirmInvoiceDeliver = () => {
deliverInvoiceMutate(invoiceId)
.then(() => {
AppToaster.show({
message: intl.get('the_invoice_has_been_delivered_successfully'),
intent: Intent.SUCCESS,
});
})
.catch((error) => {})
.finally(() => {
closeAlert(name);
});
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'deliver'} />}
intent={Intent.WARNING}
isOpen={isOpen}
onCancel={handleCancelDeleteAlert}
onConfirm={handleConfirmInvoiceDeliver}
loading={isLoading}
>
<p>
<T id={'are_sure_to_deliver_this_invoice'} />
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
)(InvoiceDeliverAlert);

View File

@@ -0,0 +1,86 @@
// @ts-nocheck
import React from 'react';
import intl from 'react-intl-universal';
import { Intent, Alert } from '@blueprintjs/core';
import {
AppToaster,
FormattedMessage as T,
FormattedHTMLMessage,
} from '@/components';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import withAlertActions from '@/containers/Alert/withAlertActions';
import withDrawerActions from '@/containers/Drawer/withDrawerActions';
import { useDeleteInventoryAdjustment } from '@/hooks/query';
import { compose } from '@/utils';
/**
* Inventory Adjustment delete alerts.
*/
function InventoryAdjustmentDeleteAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: { inventoryId },
// #withAlertActions
closeAlert,
// #withDrawerActions
closeDrawer,
}) {
const { mutateAsync: deleteInventoryAdjMutate, isLoading } =
useDeleteInventoryAdjustment();
// handle cancel delete alert.
const handleCancelInventoryAdjustmentDelete = () => {
closeAlert(name);
};
// Handle the confirm delete of the inventory adjustment transaction.
const handleConfirmInventoryAdjustmentDelete = () => {
deleteInventoryAdjMutate(inventoryId)
.then(() => {
AppToaster.show({
message: intl.get(
'the_adjustment_transaction_has_been_deleted_successfully',
),
intent: Intent.SUCCESS,
});
closeDrawer('inventory-adjustment-drawer');
})
.catch((errors) => {})
.finally(() => {
closeAlert(name);
});
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'delete'} />}
icon="trash"
intent={Intent.DANGER}
isOpen={isOpen}
onCancel={handleCancelInventoryAdjustmentDelete}
onConfirm={handleConfirmInventoryAdjustmentDelete}
loading={isLoading}
>
<p>
<FormattedHTMLMessage
id={
'once_delete_this_inventory_a_adjustment_you_will_able_to_restore_it'
}
/>
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
withDrawerActions,
)(InventoryAdjustmentDeleteAlert);

View File

@@ -0,0 +1,70 @@
// @ts-nocheck
import React from 'react';
import intl from 'react-intl-universal';
import { Intent, Alert } from '@blueprintjs/core';
import { AppToaster, FormattedMessage as T } from '@/components';
import { usePublishInventoryAdjustment } from '@/hooks/query';
import withAlertActions from '@/containers/Alert/withAlertActions';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import { compose } from '@/utils';
/**
* Inventory Adjustment publish alert.
*/
function InventoryAdjustmentPublishAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: { inventoryId },
// #withAlertActions
closeAlert,
}) {
const { mutateAsync: publishInventoryAdjustmentMutate, isLoading } =
usePublishInventoryAdjustment();
// Handle cancel inventory adjustment alert.
const handleCancelPublish = () => {
closeAlert(name);
};
// Handle publish inventory adjustment confirm.
const handleConfirmPublish = () => {
publishInventoryAdjustmentMutate(inventoryId)
.then(() => {
AppToaster.show({
message: intl.get('inventory_adjustment.publish.success_message'),
intent: Intent.SUCCESS,
});
closeAlert(name);
})
.catch((error) => {
closeAlert(name);
});
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'publish'} />}
intent={Intent.WARNING}
isOpen={isOpen}
onCancel={handleCancelPublish}
onConfirm={handleConfirmPublish}
loading={isLoading}
>
<p>
<T id={'inventory_adjustment.publish.alert_message'} />
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
)(InventoryAdjustmentPublishAlert);

View File

@@ -0,0 +1,69 @@
// @ts-nocheck
import React from 'react';
import intl from 'react-intl-universal';
import { AppToaster, FormattedMessage as T } from '@/components';
import { Intent, Alert } from '@blueprintjs/core';
import { useActivateItem } from '@/hooks/query';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import withAlertActions from '@/containers/Alert/withAlertActions';
import { compose } from '@/utils';
/**
* Item activate alert.
*/
function ItemActivateAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: { itemId },
// #withAlertActions
closeAlert,
}) {
const { mutateAsync: activateItem, isLoading } = useActivateItem();
// Handle activate item alert cancel.
const handleCancelActivateItem = () => {
closeAlert(name);
};
// Handle confirm item activated.
const handleConfirmItemActivate = () => {
activateItem(itemId)
.then(() => {
AppToaster.show({
message: intl.get('the_item_has_been_activated_successfully'),
intent: Intent.SUCCESS,
});
})
.catch((error) => {})
.finally(() => {
closeAlert(name);
});
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'activate'} />}
intent={Intent.WARNING}
isOpen={isOpen}
onCancel={handleCancelActivateItem}
loading={isLoading}
onConfirm={handleConfirmItemActivate}
>
<p>
<T id={'are_sure_to_activate_this_item'} />
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
)(ItemActivateAlert);

View File

@@ -0,0 +1,77 @@
// @ts-nocheck
import React, { useState } from 'react';
import {AppToaster, FormattedMessage as T } from '@/components';
import intl from 'react-intl-universal';
import { Intent, Alert } from '@blueprintjs/core';
import { size } from 'lodash';
import withItemsActions from '@/containers/Items/withItemsActions';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import withAlertActions from '@/containers/Alert/withAlertActions';
import { compose } from '@/utils';
/**
* Item bulk delete alert.
*/
function ItemBulkDeleteAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: { itemsIds },
// #withItemsActions
requestDeleteBulkItems,
// #withAlertActions
closeAlert,
}) {
const [isLoading, setLoading] = useState(false);
// handle cancel item bulk delete alert.
const handleCancelBulkDelete = () => {
closeAlert(name);
};
// Handle confirm items bulk delete.
const handleConfirmBulkDelete = () => {
setLoading(true);
requestDeleteBulkItems(itemsIds)
.then(() => {
AppToaster.show({
message: intl.get('the_items_has_been_deleted_successfully'),
intent: Intent.SUCCESS,
});
})
.catch((errors) => {})
.finally(() => {
setLoading(false);
closeAlert(name);
});
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={
<T id={'delete_count'} values={{ count: size(itemsIds) }} />
}
icon="trash"
intent={Intent.DANGER}
isOpen={isOpen}
onCancel={handleCancelBulkDelete}
onConfirm={handleConfirmBulkDelete}
loading={isLoading}
>
<p>
<T id={'once_delete_these_items_you_will_not_able_restore_them'} />
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
withItemsActions,
)(ItemBulkDeleteAlert);

View File

@@ -0,0 +1,83 @@
// @ts-nocheck
import React, { useState } from 'react';
import intl from 'react-intl-universal';
import { FormattedMessage as T, FormattedHTMLMessage } from '@/components';
import { Intent, Alert } from '@blueprintjs/core';
import { size } from 'lodash';
import { AppToaster } from '@/components';
import withItemCategoriesActions from '@/containers/ItemsCategories/withItemCategoriesActions';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import withAlertActions from '@/containers/Alert/withAlertActions';
import { compose } from '@/utils';
/**
* Item category bulk delete alerts.
*/
function ItemCategoryBulkDeleteAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: { itemCategoriesIds },
// #withItemCategoriesActions
requestDeleteBulkItemCategories,
// #withAlertActions
closeAlert,
}) {
const [isLoading, setLoading] = useState(false);
// handle cancel bulk delete alert.
const handleCancelBulkDelete = () => {
closeAlert(name);
};
// handle confirm itemCategories bulk delete.
const handleConfirmBulkDelete = () => {
setLoading(true);
requestDeleteBulkItemCategories(itemCategoriesIds)
.then(() => {
AppToaster.show({
message: intl.get('the_item_categories_has_been_deleted_successfully'),
intent: Intent.SUCCESS,
});
})
.catch((errors) => {})
.finally(() => {
closeAlert(name);
setLoading(false);
});
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={
<T id={'delete_count'} values={{ count: size(itemCategoriesIds) }} />
}
icon="trash"
intent={Intent.DANGER}
isOpen={isOpen}
onCancel={handleCancelBulkDelete}
onConfirm={handleConfirmBulkDelete}
loading={isLoading}
>
<p>
<FormattedHTMLMessage
id={
'once_delete_these_item_categories_you_will_not_able_restore_them'
}
/>
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
withItemCategoriesActions,
)(ItemCategoryBulkDeleteAlert);

View File

@@ -0,0 +1,77 @@
// @ts-nocheck
import React from 'react';
import intl from 'react-intl-universal';
import { Intent, Alert } from '@blueprintjs/core';
import {
AppToaster,
FormattedMessage as T,
FormattedHTMLMessage,
} from '@/components';
import { useDeleteItemCategory } from '@/hooks/query';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import withAlertActions from '@/containers/Alert/withAlertActions';
import { compose } from '@/utils';
/**
* Item Category delete alerts.
*/
function ItemCategoryDeleteAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: { itemCategoryId },
// #withAlertActions
closeAlert,
}) {
const { mutateAsync: deleteItemCategory, isLoading } =
useDeleteItemCategory();
// handle cancel delete item category alert.
const handleCancelItemCategoryDelete = () => {
closeAlert(name);
};
// Handle alert confirm delete item category.
const handleConfirmItemDelete = () => {
deleteItemCategory(itemCategoryId)
.then(() => {
AppToaster.show({
message: intl.get('the_item_category_has_been_deleted_successfully'),
intent: Intent.SUCCESS,
});
})
.catch(() => {})
.finally(() => {
closeAlert(name);
});
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'delete'} />}
icon="trash"
intent={Intent.DANGER}
isOpen={isOpen}
onCancel={handleCancelItemCategoryDelete}
onConfirm={handleConfirmItemDelete}
loading={isLoading}
>
<p>
<FormattedHTMLMessage
id={'once_delete_this_item_category_you_will_able_to_restore_it'}
/>
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
)(ItemCategoryDeleteAlert);

View File

@@ -0,0 +1,98 @@
// @ts-nocheck
import React from 'react';
import intl from 'react-intl-universal';
import { Intent, Alert } from '@blueprintjs/core';
import {
AppToaster,
FormattedMessage as T,
FormattedHTMLMessage,
} from '@/components';
import { handleDeleteErrors } from '@/containers/Items/utils';
import { useDeleteItem } from '@/hooks/query';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import withAlertActions from '@/containers/Alert/withAlertActions';
import withItemsActions from '@/containers/Items/withItemsActions';
import withDrawerActions from '@/containers/Drawer/withDrawerActions';
import { compose } from '@/utils';
/**
* Item delete alerts.
*/
function ItemDeleteAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: { itemId },
// #withAlertActions
closeAlert,
// #withItemsActions
setItemsTableState,
// #withDrawerActions
closeDrawer,
}) {
const { mutateAsync: deleteItem, isLoading } = useDeleteItem();
// Handle cancel delete item alert.
const handleCancelItemDelete = () => {
closeAlert(name);
};
// Handle confirm delete item.
const handleConfirmDeleteItem = () => {
deleteItem(itemId)
.then(() => {
AppToaster.show({
message: intl.get('the_item_has_been_deleted_successfully'),
intent: Intent.SUCCESS,
});
// Reset to page number one.
setItemsTableState({ page: 1 });
closeDrawer('item-detail-drawer');
})
.catch(
({
response: {
data: { errors },
},
}) => {
handleDeleteErrors(errors);
},
)
.finally(() => {
closeAlert(name);
});
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'delete'} />}
icon="trash"
intent={Intent.DANGER}
isOpen={isOpen}
onCancel={handleCancelItemDelete}
onConfirm={handleConfirmDeleteItem}
loading={isLoading}
>
<p>
<FormattedHTMLMessage
id={'once_delete_this_item_you_will_able_to_restore_it'}
/>
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
withItemsActions,
withDrawerActions,
)(ItemDeleteAlert);

View File

@@ -0,0 +1,69 @@
// @ts-nocheck
import React from 'react';
import intl from 'react-intl-universal';
import { AppToaster, FormattedMessage as T } from '@/components';
import { Intent, Alert } from '@blueprintjs/core';
import { useInactivateItem } from '@/hooks/query';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import withAlertActions from '@/containers/Alert/withAlertActions';
import { compose } from '@/utils';
/**
* Item inactivate alert.
*/
function ItemInactivateAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: { itemId },
// #withAlertActions
closeAlert,
}) {
const { mutateAsync: inactivateItem, isLoading } = useInactivateItem();
// Handle cancel inactivate alert.
const handleCancelInactivateItem = () => {
closeAlert(name);
};
// Handle confirm item Inactive.
const handleConfirmItemInactive = () => {
inactivateItem(itemId)
.then(() => {
AppToaster.show({
message: intl.get('the_item_has_been_inactivated_successfully'),
intent: Intent.SUCCESS,
});
})
.catch((error) => {})
.finally(() => {
closeAlert(name);
});
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'inactivate'} />}
intent={Intent.WARNING}
isOpen={isOpen}
onCancel={handleCancelInactivateItem}
onConfirm={handleConfirmItemInactive}
loading={isLoading}
>
<p>
<T id={'are_sure_to_inactive_this_item'} />
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
)(ItemInactivateAlert);

View File

@@ -0,0 +1,56 @@
// @ts-nocheck
import React from 'react';
import { Intent, Alert } from '@blueprintjs/core';
import { FormattedMessage as T } from '@/components';
import withAlertActions from '@/containers/Alert/withAlertActions';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import { compose, saveInvoke } from '@/utils';
/**
* Items entries table clear all lines alert.
*/
function ItemsEntriesDeleteAlert({
name,
onConfirm,
// #withAlertStoreConnect
isOpen,
payload: { },
// #withAlertActions
closeAlert,
}) {
// Handle the alert cancel.
const handleCancel = () => {
closeAlert(name);
};
// Handle confirm the alert.
const handleConfirm = (event) => {
closeAlert(name);
saveInvoke(onConfirm, event)
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'clear_all_lines'} />}
intent={Intent.DANGER}
isOpen={isOpen}
onCancel={handleCancel}
onConfirm={handleConfirm}
loading={false}
>
<p>
Clearing the table lines will delete all quantities and rate were applied to the items, Is this okay?
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
)(ItemsEntriesDeleteAlert);

View File

@@ -0,0 +1,47 @@
// @ts-nocheck
function JournalBulkDeleteAlert({}) {
// Handle confirm journals bulk delete.
const handleConfirmBulkDelete = useCallback(() => {
requestDeleteBulkManualJournals(bulkDelete)
.then(() => {
setBulkDelete(false);
AppToaster.show({
message: formatMessage(
{ id: 'the_journals_has_been_deleted_successfully' },
{ count: selectedRowsCount },
),
intent: Intent.SUCCESS,
});
})
.catch((error) => {
setBulkDelete(false);
});
}, [
requestDeleteBulkManualJournals,
bulkDelete,
formatMessage,
selectedRowsCount,
]);
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={
<T id={'delete_count'} values={{ count: selectedRowsCount }} />
}
icon="trash"
intent={Intent.DANGER}
isOpen={bulkDelete}
onCancel={handleCancelBulkDelete}
onConfirm={handleConfirmBulkDelete}
>
<p>
<T id={'once_delete_these_journals_you_will_not_able_restore_them'} />
</p>
</Alert>
);
}

View File

@@ -0,0 +1,77 @@
// @ts-nocheck
import React from 'react';
import intl from 'react-intl-universal';
import { Intent, Alert } from '@blueprintjs/core';
import { AppToaster, FormattedMessage as T } from '@/components';
import { useDeleteJournal } from '@/hooks/query';
import withAlertActions from '@/containers/Alert/withAlertActions';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import withDrawerActions from '@/containers/Drawer/withDrawerActions';
import { compose } from '@/utils';
/**
* Journal delete alert.
*/
function JournalDeleteAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: { manualJournalId, journalNumber },
// #withAlertActions
closeAlert,
// #withDrawerActions
closeDrawer,
}) {
const { mutateAsync: deleteJournalMutate, isLoading } = useDeleteJournal();
// Handle cancel delete manual journal.
const handleCancelAlert = () => {
closeAlert(name);
};
// Handle confirm delete manual journal.
const handleConfirmManualJournalDelete = () => {
deleteJournalMutate(manualJournalId)
.then(() => {
AppToaster.show({
message: intl.get('the_journal_has_been_deleted_successfully', {
number: journalNumber,
}),
intent: Intent.SUCCESS,
});
closeAlert(name);
closeDrawer('journal-drawer');
})
.catch(() => {
closeAlert(name);
});
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'delete'} />}
icon="trash"
intent={Intent.DANGER}
isOpen={isOpen}
onCancel={handleCancelAlert}
onConfirm={handleConfirmManualJournalDelete}
loading={isLoading}
>
<p>
<T id={'once_delete_this_journal_you_will_able_to_restore_it'} />
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
withDrawerActions,
)(JournalDeleteAlert);

View File

@@ -0,0 +1,57 @@
// @ts-nocheck
import React from 'react';
import { Intent, Alert } from '@blueprintjs/core';
import { FormattedMessage as T } from '@/components';
import withAlertActions from '@/containers/Alert/withAlertActions';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import { compose, saveInvoke } from '@/utils';
/**
* Make journal delete entries alert.
*/
function JournalDeleteEntriesAlert({
// #ownProps
name,
onConfirm,
// #withAlertStoreConnect
isOpen,
payload: { },
// #withAlertActions
closeAlert,
}) {
// Handle the alert cancel.
const handleCancel = () => {
closeAlert(name);
};
// Handle confirm delete manual journal.
const handleConfirm = (event) => {
closeAlert(name);
saveInvoke(onConfirm, event);
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'clear_all_lines'} />}
intent={Intent.DANGER}
isOpen={isOpen}
onCancel={handleCancel}
onConfirm={handleConfirm}
loading={false}
>
<p>
Clearing the table lines will delete all credits and debits were applied, Is this okay?
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
)(JournalDeleteEntriesAlert);

View File

@@ -0,0 +1,71 @@
// @ts-nocheck
import React from 'react';
import intl from 'react-intl-universal';
import { Intent, Alert } from '@blueprintjs/core';
import { AppToaster,FormattedMessage as T } from '@/components';
import { usePublishJournal } from '@/hooks/query';
import withAlertActions from '@/containers/Alert/withAlertActions';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import { compose } from '@/utils';
/**
* Journal publish alert.
*/
function JournalPublishAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: { manualJournalId, journalNumber },
// #withAlertActions
closeAlert,
}) {
const { mutateAsync: publishJournalMutate, isLoading } = usePublishJournal();
// Handle cancel manual journal alert.
const handleCancel = () => {
closeAlert(name);
};
// Handle publish manual journal confirm.
const handleConfirm = () => {
publishJournalMutate(manualJournalId)
.then(() => {
AppToaster.show({
message: intl.get('the_manual_journal_has_been_published'),
intent: Intent.SUCCESS,
});
})
.catch((error) => {
})
.finally(() => {
closeAlert(name);
});
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'publish'} />}
intent={Intent.WARNING}
isOpen={isOpen}
onCancel={handleCancel}
onConfirm={handleConfirm}
loading={isLoading}
>
<p>
<T id={'are_sure_to_publish_this_manual_journal'} />
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
)(JournalPublishAlert)

View File

@@ -0,0 +1,55 @@
// @ts-nocheck
import React from 'react';
import { Intent, Alert } from '@blueprintjs/core';
import withAlertActions from '@/containers/Alert/withAlertActions';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import { compose, saveInvoke } from '@/utils';
/**
* Changing full-amount alert in payment made form.
*/
function ChangingFullAmountAlert({
name,
onConfirm,
// #withAlertStoreConnect
isOpen,
payload: {},
// #withAlertActions
closeAlert,
}) {
// Handle the alert cancel.
const handleCancel = () => {
closeAlert(name);
};
// Handle confirm delete manual journal.
const handleConfirm = (event) => {
closeAlert(name);
saveInvoke(onConfirm, event);
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'ok'} />}
intent={Intent.DANGER}
isOpen={isOpen}
onCancel={handleCancel}
onConfirm={handleConfirm}
>
<p>
Changing full amount will change all credit and payment were applied, Is
this okay?
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
)(ChangingFullAmountAlert);

View File

@@ -0,0 +1,55 @@
// @ts-nocheck
import React from 'react';
import { Intent, Alert } from '@blueprintjs/core';
import { FormattedMessage as T } from '@/components';
import withAlertActions from '@/containers/Alert/withAlertActions';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import { compose } from '@/utils';
/**
* Alert description.
*/
function ClearPaymentTransactionAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: { },
// #withAlertActions
closeAlert,
}) {
// Handle the alert cancel.
const handleCancel = () => {
closeAlert(name);
};
// Handle confirm delete manual journal.
const handleConfirm = () => {
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'action'} />}
icon="trash"
intent={Intent.DANGER}
isOpen={isOpen}
onCancel={handleCancel}
onConfirm={handleConfirm}
loading={false}
>
<p>
<T id={'are_you_sure_you_want_to_clear_this_transaction'} />
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
)(ClearPaymentTransactionAlert);

View File

@@ -0,0 +1,55 @@
// @ts-nocheck
import React from 'react';
import { Intent, Alert } from '@blueprintjs/core';
import { FormattedMessage as T } from '@/components';
import withAlertActions from '@/containers/Alert/withAlertActions';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import { compose } from '@/utils';
/**
* Clearning all lines alert.
*/
function ClearAllLinesAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: {},
// #withAlertActions
closeAlert,
}) {
// Handle the alert cancel.
const handleCancel = () => {
closeAlert(name);
};
// Handle confirm delete manual journal.
const handleConfirm = () => {};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'action'} />}
icon="trash"
intent={Intent.DANGER}
isOpen={isOpen}
onCancel={handleCancel}
onConfirm={handleConfirm}
loading={false}
>
<p>
Clearing the table lines will delete all credits and payments were
applied. Is this okay?
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
)(ClearAllLinesAlert);

View File

@@ -0,0 +1,76 @@
// @ts-nocheck
import React from 'react';
import intl from 'react-intl-universal';
import { AppToaster, FormattedMessage as T } from '@/components';
import { Intent, Alert } from '@blueprintjs/core';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import withAlertActions from '@/containers/Alert/withAlertActions';
import withDrawerActions from '@/containers/Drawer/withDrawerActions';
import { useDeletePaymentMade } from '@/hooks/query';
import { compose } from '@/utils';
/**
* Payment made delete alert.
*/
function PaymentMadeDeleteAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: { paymentMadeId },
// #withAlertActions
closeAlert,
// #withDrawerActions
closeDrawer,
}) {
const { mutateAsync: deletePaymentMadeMutate, isLoading } =
useDeletePaymentMade();
// Handle cancel payment made.
const handleCancelPaymentMadeDelete = () => {
closeAlert(name);
};
// Handle confirm delete payment made
const handleConfirmPaymentMadeDelete = () => {
deletePaymentMadeMutate(paymentMadeId)
.then(() => {
AppToaster.show({
message: intl.get('the_payment_made_has_been_deleted_successfully'),
intent: Intent.SUCCESS,
});
closeDrawer('payment-made-detail-drawer');
})
.finally(() => {
closeAlert(name);
});
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'delete'} />}
icon={'trash'}
intent={Intent.DANGER}
isOpen={isOpen}
onCancel={handleCancelPaymentMadeDelete}
onConfirm={handleConfirmPaymentMadeDelete}
loading={isLoading}
>
<p>
<T id={'once_delete_this_payment_made_you_will_able_to_restore_it'} />
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
withDrawerActions,
)(PaymentMadeDeleteAlert);

View File

@@ -0,0 +1,55 @@
// @ts-nocheck
import React from 'react';
import { Intent, Alert } from '@blueprintjs/core';
import { FormattedMessage as T } from '@/components';
import withAlertActions from '@/containers/Alert/withAlertActions';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import { saveInvoke, compose } from '@/utils';
/**
* Clearning all lines alert.
*/
function ClearningAllLinesAlert({
name,
onConfirm,
// #withAlertStoreConnect
isOpen,
payload: {},
// #withAlertActions
closeAlert,
}) {
// Handle the alert cancel.
const handleCancel = () => {
closeAlert(name);
};
// Handle confirm delete manual journal.
const handleConfirm = (event) => {
closeAlert(name);
saveInvoke(onConfirm, event)
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'action'} />}
intent={Intent.DANGER}
isOpen={isOpen}
onCancel={handleCancel}
onConfirm={handleConfirm}
>
<p>
<T id={'clearing_the_table_lines_will_delete_all_credits'} />
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
)(ClearningAllLinesAlert);

View File

@@ -0,0 +1,85 @@
// @ts-nocheck
import React from 'react';
import intl from 'react-intl-universal';
import {
AppToaster,
FormattedMessage as T,
FormattedHTMLMessage,
} from '@/components';
import { Intent, Alert } from '@blueprintjs/core';
import { useDeletePaymentReceive } from '@/hooks/query';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import withAlertActions from '@/containers/Alert/withAlertActions';
import withDrawerActions from '@/containers/Drawer/withDrawerActions';
import { compose } from '@/utils';
/**
* Payment receive delete alert.
*/
function PaymentReceiveDeleteAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: { paymentReceiveId },
// #withAlertActions
closeAlert,
// #withDrawerActions
closeDrawer,
}) {
const { mutateAsync: deletePaymentReceiveMutate, isLoading } =
useDeletePaymentReceive();
// Handle cancel payment Receive.
const handleCancelDeleteAlert = () => {
closeAlert(name);
};
// Handle confirm delete payment receive.
const handleConfirmPaymentReceiveDelete = () => {
deletePaymentReceiveMutate(paymentReceiveId)
.then(() => {
AppToaster.show({
message: intl.get(
'the_payment_receive_has_been_deleted_successfully',
),
intent: Intent.SUCCESS,
});
closeDrawer('payment-receive-detail-drawer');
})
.catch(() => {})
.finally(() => {
closeAlert(name);
});
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'delete'} />}
icon="trash"
intent={Intent.DANGER}
isOpen={isOpen}
onCancel={handleCancelDeleteAlert}
onConfirm={handleConfirmPaymentReceiveDelete}
loading={isLoading}
>
<p>
<FormattedHTMLMessage
id={'once_delete_this_payment_receive_you_will_able_to_restore_it'}
/>
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
withDrawerActions,
)(PaymentReceiveDeleteAlert);

View File

@@ -0,0 +1,69 @@
// @ts-nocheck
import React from 'react';
import intl from 'react-intl-universal';
import { AppToaster, FormattedMessage as T } from '@/components';
import { Intent, Alert } from '@blueprintjs/core';
import { useCloseReceipt } from '@/hooks/query';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import withAlertActions from '@/containers/Alert/withAlertActions';
import { compose } from '@/utils';
/**
* Receipt close alert.
*/
function ReceiptCloseAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: { receiptId },
// #withAlertActions
closeAlert,
}) {
const { mutateAsync: closeReceiptMutate, isLoading } = useCloseReceipt();
// handle cancel delete alert.
const handleCancelDeleteAlert = () => {
closeAlert(name);
};
// Handle confirm receipt close.
const handleConfirmReceiptClose = () => {
closeReceiptMutate(receiptId)
.then(() => {
AppToaster.show({
message: intl.get('the_receipt_has_been_closed_successfully'),
intent: Intent.SUCCESS,
});
})
.catch((error) => {})
.finally(() => {
closeAlert(name);
});
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'close'} />}
intent={Intent.WARNING}
isOpen={isOpen}
onCancel={handleCancelDeleteAlert}
onConfirm={handleConfirmReceiptClose}
loading={isLoading}
>
<p>
<T id={'are_sure_to_close_this_receipt'} />
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
)(ReceiptCloseAlert);

View File

@@ -0,0 +1,82 @@
// @ts-nocheck
import React from 'react';
import intl from 'react-intl-universal';
import {
AppToaster,
FormattedMessage as T,
FormattedHTMLMessage,
} from '@/components';
import { Intent, Alert } from '@blueprintjs/core';
import { useDeleteReceipt } from '@/hooks/query';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import withAlertActions from '@/containers/Alert/withAlertActions';
import withDrawerActions from '@/containers/Drawer/withDrawerActions';
import { compose } from '@/utils';
/**
* Invoice alert.
*/
function NameDeleteAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: { receiptId },
// #withAlertActions
closeAlert,
// #withDrawerActions
closeDrawer,
}) {
const { mutateAsync: deleteReceiptMutate, isLoading } = useDeleteReceipt();
// Handle cancel delete alert.
const handleCancelDeleteAlert = () => {
closeAlert(name);
};
// Handle confirm delete receipt
const handleConfirmReceiptDelete = () => {
deleteReceiptMutate(receiptId)
.then(() => {
AppToaster.show({
message: intl.get('the_receipt_has_been_deleted_successfully'),
intent: Intent.SUCCESS,
});
closeDrawer('receipt-detail-drawer');
})
.catch(() => {})
.finally(() => {
closeAlert(name);
});
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'delete'} />}
icon="trash"
intent={Intent.DANGER}
isOpen={isOpen}
onCancel={handleCancelDeleteAlert}
onConfirm={handleConfirmReceiptDelete}
loading={isLoading}
>
<p>
<FormattedHTMLMessage
id={'once_delete_this_receipt_you_will_able_to_restore_it'}
/>
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
withDrawerActions,
)(NameDeleteAlert);

Some files were not shown because too many files have changed in this diff Show More