mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-19 14:20:31 +00:00
feat: journal number setting dialog.
This commit is contained in:
@@ -7,13 +7,14 @@ import AccountFormDialog from 'containers/Dialogs/AccountFormDialog';
|
|||||||
// import CurrencyDialog from 'containers/Dialogs/CurrencyDialog';
|
// import CurrencyDialog from 'containers/Dialogs/CurrencyDialog';
|
||||||
// import InviteUserDialog from 'containers/Dialogs/InviteUserDialog';
|
// import InviteUserDialog from 'containers/Dialogs/InviteUserDialog';
|
||||||
// import ExchangeRateDialog from 'containers/Dialogs/ExchangeRateDialog';
|
// import ExchangeRateDialog from 'containers/Dialogs/ExchangeRateDialog';
|
||||||
// import JournalNumberDailog from 'containers/Dialogs/JournalNumberDailog';
|
import JournalNumberDialog from 'containers/Dialogs/JournalNumberDialog';
|
||||||
|
|
||||||
|
|
||||||
export default function DialogsContainer() {
|
export default function DialogsContainer() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<AccountFormDialog dialogName={'account-form'} />
|
<AccountFormDialog dialogName={'account-form'} />
|
||||||
|
<JournalNumberDialog dialogName={'journal-number-form'} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
27
client/src/components/Forms/InputPrependButton.js
Normal file
27
client/src/components/Forms/InputPrependButton.js
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import React, { useMemo } from 'react';
|
||||||
|
import classNames from 'classnames';
|
||||||
|
import { Button, Tooltip, Classes } from '@blueprintjs/core';
|
||||||
|
|
||||||
|
export default function InputPrependButton({
|
||||||
|
buttonProps = {},
|
||||||
|
tooltip = false,
|
||||||
|
tooltipProps = {},
|
||||||
|
}) {
|
||||||
|
const appendButton = useMemo(() => (
|
||||||
|
<Button
|
||||||
|
className={classNames('input-prepend__button', Classes.SMALL)}
|
||||||
|
{...buttonProps}
|
||||||
|
/>
|
||||||
|
), [buttonProps]);
|
||||||
|
|
||||||
|
const appendButtonWithTooltip = useMemo(
|
||||||
|
() => (<Tooltip {...tooltipProps}>{ appendButton }</Tooltip>),
|
||||||
|
[tooltipProps, appendButton],
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div class="input-prepend">
|
||||||
|
{ tooltip ? appendButtonWithTooltip : appendButton }
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -24,6 +24,7 @@ import DashboardActionViewsList from './Dashboard/DashboardActionViewsList';
|
|||||||
import Dialog from './Dialog/Dialog';
|
import Dialog from './Dialog/Dialog';
|
||||||
import DialogContent from './Dialog/DialogContent';
|
import DialogContent from './Dialog/DialogContent';
|
||||||
import DialogSuspense from './Dialog/DialogSuspense';
|
import DialogSuspense from './Dialog/DialogSuspense';
|
||||||
|
import InputPrependButton from './Forms/InputPrependButton';
|
||||||
const Hint = FieldHint;
|
const Hint = FieldHint;
|
||||||
|
|
||||||
export {
|
export {
|
||||||
@@ -53,5 +54,6 @@ export {
|
|||||||
AppToaster,
|
AppToaster,
|
||||||
Dialog,
|
Dialog,
|
||||||
DialogContent,
|
DialogContent,
|
||||||
DialogSuspense
|
DialogSuspense,
|
||||||
|
InputPrependButton
|
||||||
};
|
};
|
||||||
@@ -20,6 +20,8 @@ import withJournalsActions from 'containers/Accounting/withJournalsActions';
|
|||||||
import withManualJournalDetail from 'containers/Accounting/withManualJournalDetail';
|
import withManualJournalDetail from 'containers/Accounting/withManualJournalDetail';
|
||||||
import withAccountsActions from 'containers/Accounts/withAccountsActions';
|
import withAccountsActions from 'containers/Accounts/withAccountsActions';
|
||||||
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
|
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
|
||||||
|
import withSettings from 'containers/Settings/withSettings';
|
||||||
|
import withManualJournals from './withManualJournals';
|
||||||
|
|
||||||
import AppToaster from 'components/AppToaster';
|
import AppToaster from 'components/AppToaster';
|
||||||
import Dragzone from 'components/Dragzone';
|
import Dragzone from 'components/Dragzone';
|
||||||
@@ -27,6 +29,7 @@ import withMediaActions from 'containers/Media/withMediaActions';
|
|||||||
|
|
||||||
import useMedia from 'hooks/useMedia';
|
import useMedia from 'hooks/useMedia';
|
||||||
import { compose, repeatValue } from 'utils';
|
import { compose, repeatValue } from 'utils';
|
||||||
|
import withManualJournalsActions from './withManualJournalsActions';
|
||||||
|
|
||||||
const ERROR = {
|
const ERROR = {
|
||||||
JOURNAL_NUMBER_ALREADY_EXISTS: 'JOURNAL.NUMBER.ALREADY.EXISTS',
|
JOURNAL_NUMBER_ALREADY_EXISTS: 'JOURNAL.NUMBER.ALREADY.EXISTS',
|
||||||
@@ -54,6 +57,15 @@ function MakeJournalEntriesForm({
|
|||||||
changePageTitle,
|
changePageTitle,
|
||||||
changePageSubtitle,
|
changePageSubtitle,
|
||||||
|
|
||||||
|
// #withSettings
|
||||||
|
journalNextNumber,
|
||||||
|
journalNumberPrefix,
|
||||||
|
|
||||||
|
// #withManualJournals
|
||||||
|
nextJournalNumberChanged,
|
||||||
|
|
||||||
|
setJournalNumberChanged,
|
||||||
|
|
||||||
manualJournalId,
|
manualJournalId,
|
||||||
manualJournal,
|
manualJournal,
|
||||||
onFormSubmit,
|
onFormSubmit,
|
||||||
@@ -149,16 +161,19 @@ function MakeJournalEntriesForm({
|
|||||||
[],
|
[],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const journalNumber = (journalNumberPrefix) ?
|
||||||
|
`${journalNumberPrefix}-${journalNextNumber}` : journalNextNumber;
|
||||||
|
|
||||||
const defaultInitialValues = useMemo(
|
const defaultInitialValues = useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
journal_number: '',
|
journal_number: journalNumber,
|
||||||
journal_type: 'Journal',
|
journal_type: 'Journal',
|
||||||
date: moment(new Date()).format('YYYY-MM-DD'),
|
date: moment(new Date()).format('YYYY-MM-DD'),
|
||||||
description: '',
|
description: '',
|
||||||
reference: '',
|
reference: '',
|
||||||
entries: [...repeatValue(defaultEntry, 4)],
|
entries: [...repeatValue(defaultEntry, 4)],
|
||||||
}),
|
}),
|
||||||
[defaultEntry],
|
[defaultEntry, journalNumber],
|
||||||
);
|
);
|
||||||
|
|
||||||
const initialValues = useMemo(
|
const initialValues = useMemo(
|
||||||
@@ -255,7 +270,6 @@ function MakeJournalEntriesForm({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const formik = useFormik({
|
const formik = useFormik({
|
||||||
enableReinitialize: true,
|
|
||||||
validationSchema,
|
validationSchema,
|
||||||
initialValues: {
|
initialValues: {
|
||||||
...initialValues,
|
...initialValues,
|
||||||
@@ -354,6 +368,11 @@ function MakeJournalEntriesForm({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
formik.setFieldValue('journal_number', journalNumber);
|
||||||
|
setJournalNumberChanged(false);
|
||||||
|
}, [nextJournalNumberChanged, journalNumber]);
|
||||||
|
|
||||||
const handleSubmitClick = useCallback(
|
const handleSubmitClick = useCallback(
|
||||||
(payload) => {
|
(payload) => {
|
||||||
setPayload(payload);
|
setPayload(payload);
|
||||||
@@ -430,7 +449,15 @@ function MakeJournalEntriesForm({
|
|||||||
export default compose(
|
export default compose(
|
||||||
withJournalsActions,
|
withJournalsActions,
|
||||||
withManualJournalDetail,
|
withManualJournalDetail,
|
||||||
|
withManualJournals(({ nextJournalNumberChanged }) => ({
|
||||||
|
nextJournalNumberChanged,
|
||||||
|
})),
|
||||||
withAccountsActions,
|
withAccountsActions,
|
||||||
withDashboardActions,
|
withDashboardActions,
|
||||||
withMediaActions,
|
withMediaActions,
|
||||||
|
withSettings(({ manualJournalsSettings }) => ({
|
||||||
|
journalNextNumber: manualJournalsSettings.next_number,
|
||||||
|
journalNumberPrefix: manualJournalsSettings.number_prefix
|
||||||
|
})),
|
||||||
|
withManualJournalsActions,
|
||||||
)(MakeJournalEntriesForm);
|
)(MakeJournalEntriesForm);
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import {
|
|||||||
Intent,
|
Intent,
|
||||||
Position,
|
Position,
|
||||||
Classes,
|
Classes,
|
||||||
Button,
|
|
||||||
} from '@blueprintjs/core';
|
} from '@blueprintjs/core';
|
||||||
import { DateInput } from '@blueprintjs/datetime';
|
import { DateInput } from '@blueprintjs/datetime';
|
||||||
import { FormattedMessage as T } from 'react-intl';
|
import { FormattedMessage as T } from 'react-intl';
|
||||||
@@ -20,6 +19,7 @@ import {
|
|||||||
FieldHint,
|
FieldHint,
|
||||||
FieldRequiredHint,
|
FieldRequiredHint,
|
||||||
Icon,
|
Icon,
|
||||||
|
InputPrependButton
|
||||||
} from 'components';
|
} from 'components';
|
||||||
|
|
||||||
import withDialogActions from 'containers/Dialog/withDialogActions';
|
import withDialogActions from 'containers/Dialog/withDialogActions';
|
||||||
@@ -40,7 +40,7 @@ function MakeJournalEntriesHeader({
|
|||||||
[setFieldValue],
|
[setFieldValue],
|
||||||
);
|
);
|
||||||
const handleJournalNumberChange = useCallback(() => {
|
const handleJournalNumberChange = useCallback(() => {
|
||||||
openDialog('journalNumber-form', {});
|
openDialog('journal-number-form', {});
|
||||||
}, [openDialog]);
|
}, [openDialog]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -63,25 +63,29 @@ function MakeJournalEntriesHeader({
|
|||||||
<ErrorMessage name="journal_number" {...{ errors, touched }} />
|
<ErrorMessage name="journal_number" {...{ errors, touched }} />
|
||||||
}
|
}
|
||||||
fill={true}
|
fill={true}
|
||||||
|
|
||||||
>
|
>
|
||||||
<InputGroup
|
<InputGroup
|
||||||
intent={
|
intent={
|
||||||
errors.journal_number && touched.journal_number && Intent.DANGER
|
errors.journal_number && touched.journal_number && Intent.DANGER
|
||||||
}
|
}
|
||||||
fill={true}
|
fill={true}
|
||||||
|
rightElement={<InputPrependButton
|
||||||
|
buttonProps={{
|
||||||
|
onClick: handleJournalNumberChange,
|
||||||
|
icon: (<Icon icon={'settings-18'} />)
|
||||||
|
}}
|
||||||
|
tooltip={true}
|
||||||
|
tooltipProps={{
|
||||||
|
content: 'Setting your auto-generated journal number',
|
||||||
|
position: Position.BOTTOM_LEFT,
|
||||||
|
}}
|
||||||
|
/>}
|
||||||
{...getFieldProps('journal_number')}
|
{...getFieldProps('journal_number')}
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
</Col>
|
</Col>
|
||||||
<Col width={50}>
|
|
||||||
{/* <FormGroup> */}
|
|
||||||
<Button
|
|
||||||
className={classNames('btn', Classes.SMALL)}
|
|
||||||
icon={<Icon icon="setting" />}
|
|
||||||
onClick={handleJournalNumberChange}
|
|
||||||
/>
|
|
||||||
{/* </FormGroup> */}
|
|
||||||
</Col>
|
|
||||||
<Col width={220}>
|
<Col width={220}>
|
||||||
<FormGroup
|
<FormGroup
|
||||||
label={<T id={'date'} />}
|
label={<T id={'date'} />}
|
||||||
@@ -173,4 +177,6 @@ function MakeJournalEntriesHeader({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default compose(withDialogActions)(MakeJournalEntriesHeader);
|
export default compose(
|
||||||
|
withDialogActions,
|
||||||
|
)(MakeJournalEntriesHeader);
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import DashboardInsider from 'components/Dashboard/DashboardInsider';
|
|||||||
import withCustomersActions from 'containers/Customers/withCustomersActions';
|
import withCustomersActions from 'containers/Customers/withCustomersActions';
|
||||||
import withAccountsActions from 'containers/Accounts/withAccountsActions';
|
import withAccountsActions from 'containers/Accounts/withAccountsActions';
|
||||||
import withManualJournalsActions from 'containers/Accounting/withManualJournalsActions';
|
import withManualJournalsActions from 'containers/Accounting/withManualJournalsActions';
|
||||||
|
import withSettingsActions from 'containers/Settings/withSettingsActions';
|
||||||
|
|
||||||
import { compose } from 'utils';
|
import { compose } from 'utils';
|
||||||
|
|
||||||
@@ -20,6 +21,9 @@ function MakeJournalEntriesPage({
|
|||||||
|
|
||||||
// #withManualJournalActions
|
// #withManualJournalActions
|
||||||
requestFetchManualJournal,
|
requestFetchManualJournal,
|
||||||
|
|
||||||
|
// #withSettingsActions
|
||||||
|
requestFetchOptions,
|
||||||
}) {
|
}) {
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
@@ -32,6 +36,8 @@ function MakeJournalEntriesPage({
|
|||||||
requestFetchCustomers(),
|
requestFetchCustomers(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const fetchSettings = useQuery(['settings'], () => requestFetchOptions({}));
|
||||||
|
|
||||||
const fetchJournal = useQuery(
|
const fetchJournal = useQuery(
|
||||||
['manual-journal', id],
|
['manual-journal', id],
|
||||||
(key, journalId) => requestFetchManualJournal(journalId),
|
(key, journalId) => requestFetchManualJournal(journalId),
|
||||||
@@ -71,4 +77,5 @@ export default compose(
|
|||||||
withAccountsActions,
|
withAccountsActions,
|
||||||
withCustomersActions,
|
withCustomersActions,
|
||||||
withManualJournalsActions,
|
withManualJournalsActions,
|
||||||
|
withSettingsActions
|
||||||
)(MakeJournalEntriesPage);
|
)(MakeJournalEntriesPage);
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ export default (mapState) => {
|
|||||||
|
|
||||||
manualJournalsPagination: getManualJournalsPagination(state, props, query),
|
manualJournalsPagination: getManualJournalsPagination(state, props, query),
|
||||||
manualJournalsLoading: state.manualJournals.loading,
|
manualJournalsLoading: state.manualJournals.loading,
|
||||||
|
|
||||||
|
nextJournalNumberChanged: state.manualJournals.nextJournalNumberChanged,
|
||||||
};
|
};
|
||||||
return mapState ? mapState(mapped, state, props) : mapped;
|
return mapState ? mapState(mapped, state, props) : mapped;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -24,6 +24,10 @@ const mapActionsToProps = (dispatch) => ({
|
|||||||
type: t.MANUAL_JOURNALS_TABLE_QUERIES_ADD,
|
type: t.MANUAL_JOURNALS_TABLE_QUERIES_ADD,
|
||||||
queries,
|
queries,
|
||||||
}),
|
}),
|
||||||
|
setJournalNumberChanged: (isChanged) => dispatch({
|
||||||
|
type: t.MANUAL_JOURNAL_NUMBER_CHANGED,
|
||||||
|
payload: { isChanged },
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(null, mapActionsToProps);
|
export default connect(null, mapActionsToProps);
|
||||||
|
|||||||
@@ -1,71 +0,0 @@
|
|||||||
import React, { useEffect, useCallback, useMemo } from 'react';
|
|
||||||
import { FormattedMessage as T, useIntl } from 'react-intl';
|
|
||||||
import { useQuery, queryCache } from 'react-query';
|
|
||||||
import { Dialog } from 'components';
|
|
||||||
import withDialogActions from 'containers/Dialog/withDialogActions';
|
|
||||||
import withDialogRedux from 'components/DialogReduxConnect';
|
|
||||||
import withSettingsActions from 'containers/Settings/withSettingsActions';
|
|
||||||
import withSettings from 'containers/Settings/withSettings';
|
|
||||||
import ReferenceNumberForm from 'containers/JournalNumber/ReferenceNumberForm';
|
|
||||||
import classNames from 'classnames';
|
|
||||||
|
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import { compose, optionsMapToArray } from 'utils';
|
|
||||||
|
|
||||||
function JournalNumberDailog({
|
|
||||||
dialogName,
|
|
||||||
payload,
|
|
||||||
isOpen,
|
|
||||||
|
|
||||||
// #withSettingsActions
|
|
||||||
requestSubmitOptions,
|
|
||||||
|
|
||||||
// #withDialogActions
|
|
||||||
closeDialog,
|
|
||||||
}) {
|
|
||||||
// Handles dialog close.
|
|
||||||
const handleClose = useCallback(() => {
|
|
||||||
closeDialog(dialogName);
|
|
||||||
}, [closeDialog, dialogName]);
|
|
||||||
|
|
||||||
const handleSubmitForm = useCallback(() => {});
|
|
||||||
|
|
||||||
// Handle dialog on closed.
|
|
||||||
// const onDialogClosed = useCallback(() => {
|
|
||||||
// resetForm();
|
|
||||||
// }, [resetForm]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Dialog
|
|
||||||
name={dialogName}
|
|
||||||
// isLoading={}
|
|
||||||
title={<T id={'journal_number_settings'} />}
|
|
||||||
autoFocus={true}
|
|
||||||
canEscapeKeyClose={true}
|
|
||||||
isOpen={isOpen}
|
|
||||||
onClose={handleClose}
|
|
||||||
>
|
|
||||||
<ReferenceNumberForm
|
|
||||||
onSubmit={handleSubmitForm}
|
|
||||||
initialNumber={'1000'}
|
|
||||||
initialPrefix={'A'}
|
|
||||||
onClose={handleClose}
|
|
||||||
groupName={'manual_journals'}
|
|
||||||
/>
|
|
||||||
</Dialog>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const mapStateToProps = (state, props) => ({
|
|
||||||
dialogName: 'journalNumber-form',
|
|
||||||
journalNumberId: props?.payload?.id || null,
|
|
||||||
});
|
|
||||||
|
|
||||||
const withJournalNumberDailog = connect(mapStateToProps);
|
|
||||||
|
|
||||||
export default compose(
|
|
||||||
withDialogRedux(null, 'journalNumber-form'),
|
|
||||||
withJournalNumberDailog,
|
|
||||||
withDialogActions,
|
|
||||||
withSettingsActions,
|
|
||||||
)(JournalNumberDailog);
|
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { DialogContent } from 'components';
|
||||||
|
import { useQuery, queryCache } from 'react-query';
|
||||||
|
|
||||||
|
import ReferenceNumberForm from 'containers/JournalNumber/ReferenceNumberForm';
|
||||||
|
|
||||||
|
import withDialogActions from 'containers/Dialog/withDialogActions';
|
||||||
|
import withSettingsActions from 'containers/Settings/withSettingsActions';
|
||||||
|
import withSettings from 'containers/Settings/withSettings';
|
||||||
|
import withManualJournalsActions from 'containers/Accounting/withManualJournalsActions';
|
||||||
|
|
||||||
|
import { compose, optionsMapToArray } from 'utils';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Journal number dialog's content.
|
||||||
|
*/
|
||||||
|
function JournalNumberDialogContent({
|
||||||
|
// #withSettings
|
||||||
|
nextNumber,
|
||||||
|
numberPrefix,
|
||||||
|
|
||||||
|
// #withSettingsActions
|
||||||
|
requestFetchOptions,
|
||||||
|
requestSubmitOptions,
|
||||||
|
|
||||||
|
// #withDialogActions
|
||||||
|
closeDialog,
|
||||||
|
|
||||||
|
// #withManualJournalsActions
|
||||||
|
setJournalNumberChanged,
|
||||||
|
}) {
|
||||||
|
const fetchSettings = useQuery(['settings'], () => requestFetchOptions({}));
|
||||||
|
|
||||||
|
const handleSubmitForm = (values, { setSubmitting }) => {
|
||||||
|
const options = optionsMapToArray(values).map((option) => {
|
||||||
|
return { key: option.key, ...option, group: 'manual_journals' };
|
||||||
|
});
|
||||||
|
|
||||||
|
requestSubmitOptions({ options }).then(() => {
|
||||||
|
setSubmitting(false);
|
||||||
|
closeDialog('journal-number-form');
|
||||||
|
setJournalNumberChanged(true);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
queryCache.invalidateQueries('settings');
|
||||||
|
}, 250);
|
||||||
|
}).catch(() => {
|
||||||
|
setSubmitting(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
closeDialog('journal-number-form');
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DialogContent isLoading={fetchSettings.isFetching}>
|
||||||
|
<ReferenceNumberForm
|
||||||
|
initialNumber={nextNumber}
|
||||||
|
initialPrefix={numberPrefix}
|
||||||
|
onSubmit={handleSubmitForm}
|
||||||
|
onClose={handleClose}
|
||||||
|
/>
|
||||||
|
</DialogContent>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default compose(
|
||||||
|
withDialogActions,
|
||||||
|
withSettingsActions,
|
||||||
|
withSettings(({ manualJournalsSettings }) => ({
|
||||||
|
nextNumber: manualJournalsSettings?.next_number,
|
||||||
|
numberPrefix: manualJournalsSettings?.number_prefix,
|
||||||
|
})),
|
||||||
|
withManualJournalsActions,
|
||||||
|
)(JournalNumberDialogContent);
|
||||||
35
client/src/containers/Dialogs/JournalNumberDialog/index.js
Normal file
35
client/src/containers/Dialogs/JournalNumberDialog/index.js
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
import React, { lazy } from 'react';
|
||||||
|
import { FormattedMessage as T } from 'react-intl';
|
||||||
|
import { Dialog, DialogSuspense } from 'components';
|
||||||
|
import withDialogRedux from 'components/DialogReduxConnect';
|
||||||
|
import { compose } from 'utils';
|
||||||
|
|
||||||
|
const JournalNumberDialogContent = lazy(() => import('./JournalNumberDialogContent'));
|
||||||
|
|
||||||
|
function JournalNumberDialog({
|
||||||
|
dialogName,
|
||||||
|
payload = { id: null },
|
||||||
|
isOpen,
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<Dialog
|
||||||
|
name={dialogName}
|
||||||
|
title={<T id={'journal_number_settings'} />}
|
||||||
|
autoFocus={true}
|
||||||
|
canEscapeKeyClose={true}
|
||||||
|
isOpen={isOpen}
|
||||||
|
className={'dialog--journal-number-settings'}
|
||||||
|
>
|
||||||
|
<DialogSuspense>
|
||||||
|
<JournalNumberDialogContent
|
||||||
|
journalNumberId={payload.id}
|
||||||
|
/>
|
||||||
|
</DialogSuspense>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default compose(
|
||||||
|
withDialogRedux(),
|
||||||
|
)(JournalNumberDialog);
|
||||||
@@ -1,51 +1,43 @@
|
|||||||
import React, { useMemo, useCallback } from 'react';
|
import React, { useMemo } from 'react';
|
||||||
import * as Yup from 'yup';
|
import * as Yup from 'yup';
|
||||||
import { useFormik } from 'formik';
|
import { useFormik } from 'formik';
|
||||||
import { Row, Col } from 'react-grid-system';
|
import { Row, Col } from 'react-grid-system';
|
||||||
import { FormattedMessage as T, useIntl } from 'react-intl';
|
import { FormattedMessage as T } from 'react-intl';
|
||||||
import { ErrorMessage, AppToaster } from 'components';
|
import { ErrorMessage } from 'components';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
Classes,
|
Classes,
|
||||||
FormGroup,
|
FormGroup,
|
||||||
InputGroup,
|
InputGroup,
|
||||||
Intent,
|
Intent,
|
||||||
Position,
|
|
||||||
} from '@blueprintjs/core';
|
} from '@blueprintjs/core';
|
||||||
import { compose, optionsMapToArray } from 'utils';
|
|
||||||
import withSettingsActions from 'containers/Settings/withSettingsActions';
|
import withSettingsActions from 'containers/Settings/withSettingsActions';
|
||||||
import withSettings from 'containers/Settings/withSettings';
|
|
||||||
|
|
||||||
function ReferenceNumberForm({
|
import { compose } from 'utils';
|
||||||
|
|
||||||
|
|
||||||
|
export default function ReferenceNumberForm({
|
||||||
onSubmit,
|
onSubmit,
|
||||||
onClose,
|
onClose,
|
||||||
initialPrefix,
|
initialPrefix,
|
||||||
initialNumber,
|
initialNumber,
|
||||||
groupName,
|
|
||||||
requestSubmitOptions,
|
|
||||||
}) {
|
}) {
|
||||||
const { formatMessage } = useIntl();
|
|
||||||
|
|
||||||
const validationSchema = Yup.object().shape({
|
const validationSchema = Yup.object().shape({
|
||||||
prefix: Yup.string(),
|
number_prefix: Yup.string(),
|
||||||
next_number: Yup.number(),
|
next_number: Yup.number(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const initialValues = useMemo(
|
const initialValues = useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
prefix: initialPrefix || '',
|
number_prefix: initialPrefix || '',
|
||||||
next_number: initialNumber || '',
|
next_number: initialNumber || '',
|
||||||
}),
|
}),
|
||||||
[],
|
[initialPrefix, initialNumber],
|
||||||
);
|
);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
errors,
|
errors,
|
||||||
values,
|
|
||||||
touched,
|
touched,
|
||||||
setFieldValue,
|
|
||||||
resetForm,
|
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
isSubmitting,
|
isSubmitting,
|
||||||
getFieldProps,
|
getFieldProps,
|
||||||
@@ -56,33 +48,9 @@ function ReferenceNumberForm({
|
|||||||
},
|
},
|
||||||
validationSchema,
|
validationSchema,
|
||||||
onSubmit: (values, { setSubmitting, setErrors }) => {
|
onSubmit: (values, { setSubmitting, setErrors }) => {
|
||||||
const options = optionsMapToArray(values).map((option) => {
|
onSubmit(values, { setSubmitting, setErrors });
|
||||||
return { key: option.key, ...option, group: groupName };
|
|
||||||
});
|
|
||||||
|
|
||||||
onSubmit(
|
|
||||||
requestSubmitOptions({ options })
|
|
||||||
.then(() => {
|
|
||||||
setSubmitting(false);
|
|
||||||
})
|
|
||||||
|
|
||||||
.catch((erros) => {
|
|
||||||
setSubmitting(false);
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// Handles dialog close.
|
|
||||||
// const handleClose = useCallback(() => {
|
|
||||||
// closeDialog(dialogName);
|
|
||||||
// }, [closeDialog, dialogName]);
|
|
||||||
|
|
||||||
// Handle dialog on closed.
|
|
||||||
const onClosed = useCallback(() => {
|
|
||||||
resetForm();
|
|
||||||
}, [resetForm]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<form onSubmit={handleSubmit}>
|
<form onSubmit={handleSubmit}>
|
||||||
@@ -97,14 +65,14 @@ function ReferenceNumberForm({
|
|||||||
<FormGroup
|
<FormGroup
|
||||||
label={<T id={'prefix'} />}
|
label={<T id={'prefix'} />}
|
||||||
className={'form-group--'}
|
className={'form-group--'}
|
||||||
intent={errors.prefix && touched.prefix && Intent.DANGER}
|
intent={errors.number_prefix && touched.number_prefix && Intent.DANGER}
|
||||||
helperText={
|
helperText={
|
||||||
<ErrorMessage name={'prefix'} {...{ errors, touched }} />
|
<ErrorMessage name={'prefix'} {...{ errors, touched }} />
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<InputGroup
|
<InputGroup
|
||||||
intent={errors.prefix && touched.prefix && Intent.DANGER}
|
intent={errors.number_prefix && touched.number_prefix && Intent.DANGER}
|
||||||
{...getFieldProps('prefix')}
|
{...getFieldProps('number_prefix')}
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
</Col>
|
</Col>
|
||||||
@@ -147,6 +115,4 @@ function ReferenceNumberForm({
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default compose(withSettingsActions)(ReferenceNumberForm);
|
|
||||||
@@ -2,6 +2,7 @@ import React from 'react';
|
|||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import { Provider } from 'react-redux';
|
import { Provider } from 'react-redux';
|
||||||
import { BrowserRouter } from 'react-router-dom';
|
import { BrowserRouter } from 'react-router-dom';
|
||||||
|
import 'services/yup';
|
||||||
import App from 'components/App';
|
import App from 'components/App';
|
||||||
import * as serviceWorker from 'serviceWorker';
|
import * as serviceWorker from 'serviceWorker';
|
||||||
import createStore from 'store/createStore';
|
import createStore from 'store/createStore';
|
||||||
|
|||||||
@@ -774,5 +774,5 @@ export default {
|
|||||||
bigger_or_equals: 'Bigger or equals',
|
bigger_or_equals: 'Bigger or equals',
|
||||||
prefix: 'Prefix',
|
prefix: 'Prefix',
|
||||||
next_number: 'Next Number',
|
next_number: 'Next Number',
|
||||||
journal_number_settings: 'Journal Number Settings',
|
journal_number_settings: 'Journal number settings',
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import * as Yup from 'yup';
|
import * as Yup from 'yup';
|
||||||
|
|
||||||
|
|
||||||
Yup.addMethod(Yup.string, 'digits', function () {
|
Yup.addMethod(Yup.string, 'digits', function () {
|
||||||
return this.test(
|
return this.test(
|
||||||
'is-digits',
|
'is-digits',
|
||||||
|
|||||||
@@ -275,4 +275,10 @@ export default {
|
|||||||
],
|
],
|
||||||
viewBox: '0 0 16 16',
|
viewBox: '0 0 16 16',
|
||||||
},
|
},
|
||||||
|
'settings-18': {
|
||||||
|
path: [
|
||||||
|
'M19.43 12.98c.04-.32.07-.64.07-.98s-.03-.66-.07-.98l2.11-1.65c.19-.15.24-.42.12-.64l-2-3.46c-.12-.22-.39-.3-.61-.22l-2.49 1c-.52-.4-1.08-.73-1.69-.98l-.38-2.65C14.46 2.18 14.25 2 14 2h-4c-.25 0-.46.18-.49.42l-.38 2.65c-.61.25-1.17.59-1.69.98l-2.49-1c-.23-.09-.49 0-.61.22l-2 3.46c-.13.22-.07.49.12.64l2.11 1.65c-.04.32-.07.65-.07.98s.03.66.07.98l-2.11 1.65c-.19.15-.24.42-.12.64l2 3.46c.12.22.39.3.61.22l2.49-1c.52.4 1.08.73 1.69.98l.38 2.65c.03.24.24.42.49.42h4c.25 0 .46-.18.49-.42l.38-2.65c.61-.25 1.17-.59 1.69-.98l2.49 1c.23.09.49 0 .61-.22l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.65zM12 15.5c-1.93 0-3.5-1.57-3.5-3.5s1.57-3.5 3.5-3.5 3.5 1.57 3.5 3.5-1.57 3.5-3.5 3.5z',
|
||||||
|
],
|
||||||
|
viewBox: '0 0 24 24',
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -14,7 +14,8 @@ const initialState = {
|
|||||||
},
|
},
|
||||||
paginationMeta: {
|
paginationMeta: {
|
||||||
total: 0,
|
total: 0,
|
||||||
}
|
},
|
||||||
|
nextJournalNumberChanged: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
const defaultJournal = {
|
const defaultJournal = {
|
||||||
@@ -114,6 +115,11 @@ const reducer = createReducer(initialState, {
|
|||||||
paginationMeta,
|
paginationMeta,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
[t.MANUAL_JOURNAL_NUMBER_CHANGED]: (state, action) => {
|
||||||
|
const { isChanged } = action.payload;
|
||||||
|
state.nextJournalNumberChanged = isChanged;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -12,4 +12,6 @@ export default {
|
|||||||
MANUAL_JOURNAL_PUBLISH: 'MANUAL_JOURNAL_PUBLISH',
|
MANUAL_JOURNAL_PUBLISH: 'MANUAL_JOURNAL_PUBLISH',
|
||||||
MANUAL_JOURNALS_BULK_DELETE: 'MANUAL_JOURNALS_BULK_DELETE',
|
MANUAL_JOURNALS_BULK_DELETE: 'MANUAL_JOURNALS_BULK_DELETE',
|
||||||
MANUAL_JOURNALS_PAGINATION_SET: 'MANUAL_JOURNALS_PAGINATION_SET',
|
MANUAL_JOURNALS_PAGINATION_SET: 'MANUAL_JOURNALS_PAGINATION_SET',
|
||||||
|
|
||||||
|
MANUAL_JOURNAL_NUMBER_CHANGED: 'MANUAL_JOURNAL_NUMBER_CHANGED'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -12,7 +12,16 @@ const initialState = {
|
|||||||
export default createReducer(initialState, {
|
export default createReducer(initialState, {
|
||||||
[t.SETTING_SET]: (state, action) => {
|
[t.SETTING_SET]: (state, action) => {
|
||||||
const { options } = action;
|
const { options } = action;
|
||||||
|
const _data = {
|
||||||
state.data.organization = optionsArrayToMap(options);
|
...state.data,
|
||||||
|
};
|
||||||
|
options.forEach((option) => {
|
||||||
|
const { key, group, value } = option;
|
||||||
|
if (!_data[group]) {
|
||||||
|
_data[group] = {};
|
||||||
|
}
|
||||||
|
_data[group][key] = value;
|
||||||
|
});
|
||||||
|
state.data = _data;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -341,4 +341,42 @@ $form-check-input-indeterminate-bg-image: url("data:image/svg+xml,<svg xmlns='ht
|
|||||||
|
|
||||||
.bp3-menu-item::before, .bp3-menu-item > .bp3-icon{
|
.bp3-menu-item::before, .bp3-menu-item > .bp3-icon{
|
||||||
color: #4b5d6b;
|
color: #4b5d6b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bp3-input-group{
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
.bp3-input:not(:last-child) {
|
||||||
|
border-radius: 3px 0 0 3px;
|
||||||
|
border-right-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bp3-input-action{
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-prepend{
|
||||||
|
|
||||||
|
&__text,
|
||||||
|
&__button{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: .375rem .75rem;
|
||||||
|
margin: 0;
|
||||||
|
height: 32px;
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 1.5;
|
||||||
|
color: #495057;
|
||||||
|
text-align: center;
|
||||||
|
white-space: nowrap;
|
||||||
|
background-color: #e9ecef;
|
||||||
|
border: 1px solid #ced4da;
|
||||||
|
border-radius: 0 3px 3px 0;
|
||||||
|
|
||||||
|
.bp3-icon{
|
||||||
|
color: #848da0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -14,12 +14,6 @@
|
|||||||
color: #444;
|
color: #444;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.bp3-button:not([class*='bp3-intent-']):not(.bp3-minimal).bp3-small {
|
|
||||||
font-size: 13px;
|
|
||||||
min-height: 33px;
|
|
||||||
margin-top: 21px;
|
|
||||||
margin-left: -30px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&__table {
|
&__table {
|
||||||
@@ -186,3 +180,20 @@
|
|||||||
margin-right: 20px;
|
margin-right: 20px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.dialog--journal-number-settings{
|
||||||
|
|
||||||
|
.paragraph {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
.bp3-form-group{
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bp3-dialog-footer-actions{
|
||||||
|
.bp3-button{
|
||||||
|
min-width: 75px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -47,11 +47,11 @@ export default {
|
|||||||
],
|
],
|
||||||
manual_journals: [
|
manual_journals: [
|
||||||
{
|
{
|
||||||
key: 'journal_number_next',
|
key: 'next_number',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'journal_number_prefix',
|
key: 'number_prefix',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|||||||
Reference in New Issue
Block a user