diff --git a/src/components/Accounts/AccountsSelectList.tsx b/src/components/Accounts/AccountsSelectList.tsx index e8eb37a4a..8ec02d8e4 100644 --- a/src/components/Accounts/AccountsSelectList.tsx +++ b/src/components/Accounts/AccountsSelectList.tsx @@ -8,7 +8,9 @@ import * as R from 'ramda'; import { MenuItemNestedText, FormattedMessage as T } from '@/components'; import { nestedArrayToflatten, filterAccountsByQuery } from '@/utils'; + import { CLASSES } from '@/constants/classes'; +import { DialogsName } from '@/constants/dialogs'; import withDialogActions from '@/containers/Dialog/withDialogActions'; @@ -129,7 +131,7 @@ function AccountsSelectListRoot({ setSelectedAccount({ ...account }); onAccountSelected && onAccountSelected(account); } else { - openDialog('account-form'); + openDialog(DialogsName.AccountForm); } }, [setSelectedAccount, onAccountSelected, openDialog], diff --git a/src/components/Accounts/AccountsSuggestField.tsx b/src/components/Accounts/AccountsSuggestField.tsx index 4afac2784..4680d150a 100644 --- a/src/components/Accounts/AccountsSuggestField.tsx +++ b/src/components/Accounts/AccountsSuggestField.tsx @@ -7,6 +7,8 @@ import { MenuItem } from '@blueprintjs/core'; import { Suggest } from '@blueprintjs/select'; import { CLASSES } from '@/constants/classes'; +import { DialogsName } from '@/constants/dialogs'; + import { MenuItemNestedText, FormattedMessage as T } from '@/components'; import { nestedArrayToflatten, filterAccountsByQuery } from '@/utils'; @@ -134,7 +136,7 @@ function AccountsSuggestFieldRoot({ setSelectedAccount({ ...account }); onAccountSelected && onAccountSelected(account); } else { - openDialog('account-form'); + openDialog(DialogsName.AccountForm); } }, [setSelectedAccount, onAccountSelected, openDialog], diff --git a/src/containers/Accounts/AccountsActionsBar.tsx b/src/containers/Accounts/AccountsActionsBar.tsx index 435e64935..38d7a8214 100644 --- a/src/containers/Accounts/AccountsActionsBar.tsx +++ b/src/containers/Accounts/AccountsActionsBar.tsx @@ -24,8 +24,11 @@ import { } 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'; @@ -65,7 +68,7 @@ function AccountsActionsBar({ const { resourceViews, fields } = useAccountsChartContext(); const onClickNewAccount = () => { - openDialog('account-form', {}); + openDialog(DialogsName.AccountForm, {}); }; // Accounts refresh action. diff --git a/src/containers/Accounts/AccountsDataTable.tsx b/src/containers/Accounts/AccountsDataTable.tsx index 440b2c6de..2c5270c34 100644 --- a/src/containers/Accounts/AccountsDataTable.tsx +++ b/src/containers/Accounts/AccountsDataTable.tsx @@ -8,13 +8,15 @@ import { TableSkeletonHeader, TableVirtualizedListRows, } from '@/components'; -import { TABLES } from '@/constants/tables'; 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 { AccountDialogAction } from '@/containers/Dialogs/AccountDialog/utils'; + +import { TABLES } from '@/constants/tables'; +import { DialogsName } from '@/constants/dialogs'; import withSettings from '@/containers/Settings/withSettings'; import withAlertsActions from '@/containers/Alert/withAlertActions'; @@ -61,9 +63,9 @@ function AccountsDataTable({ // Handle edit account action. const handleEditAccount = (account) => { - openDialog('account-form', { + openDialog(DialogsName.AccountForm, { action: AccountDialogAction.Edit, - id: account.id, + accountId: account.id, }); }; @@ -74,7 +76,7 @@ function AccountsDataTable({ // Handle new child button click. const handleNewChildAccount = (account) => { - openDialog('account-form', { + openDialog(DialogsName.AccountForm, { action: AccountDialogAction.NewChild, parentAccountId: account.id, accountType: account.account_type, diff --git a/src/containers/CashFlow/CashFlowAccounts/CashFlowAccountsActionsBar.tsx b/src/containers/CashFlow/CashFlowAccounts/CashFlowAccountsActionsBar.tsx index faa61dfbc..4c5c2d4c8 100644 --- a/src/containers/CashFlow/CashFlowAccounts/CashFlowAccountsActionsBar.tsx +++ b/src/containers/CashFlow/CashFlowAccounts/CashFlowAccountsActionsBar.tsx @@ -21,7 +21,9 @@ import withDialogActions from '@/containers/Dialog/withDialogActions'; import withCashflowAccountsTableActions from '../AccountTransactions/withCashflowAccountsTableActions'; import { AccountDialogAction } from '@/containers/Dialogs/AccountDialog/utils'; + import { ACCOUNT_TYPE } from '@/constants'; +import { DialogsName } from '@/constants/dialogs'; import { compose } from '@/utils'; @@ -43,14 +45,14 @@ function CashFlowAccountsActionsBar({ }; // Handle add bank account. const handleAddBankAccount = () => { - openDialog('account-form', { + openDialog(DialogsName.AccountForm, { action: AccountDialogAction.NewDefinedType, accountType: ACCOUNT_TYPE.CASH, }); }; // Handle add cash account. const handleAddCashAccount = () => { - openDialog('account-form', { + openDialog(DialogsName.AccountForm, { action: AccountDialogAction.NewDefinedType, accountType: ACCOUNT_TYPE.BANK, }); diff --git a/src/containers/CashFlow/CashFlowAccounts/CashflowAccountsGrid.tsx b/src/containers/CashFlow/CashFlowAccounts/CashflowAccountsGrid.tsx index 65f121df8..18f7cbd4e 100644 --- a/src/containers/CashFlow/CashFlowAccounts/CashflowAccountsGrid.tsx +++ b/src/containers/CashFlow/CashFlowAccounts/CashflowAccountsGrid.tsx @@ -8,24 +8,26 @@ import { Link } from 'react-router-dom'; import { ContextMenu2 } from '@blueprintjs/popover2'; import { Menu, MenuItem, MenuDivider, Intent } from '@blueprintjs/core'; -import { BankAccountsList, BankAccount, If, Icon, T, Can } from '@/components'; import { AccountAction, CashflowAction, AbilitySubject, } from '@/constants/abilityOption'; +import { DialogsName } from '@/constants/dialogs'; +import { + getAddMoneyInOptions, + getAddMoneyOutOptions, +} from '@/constants/cashflowOptions'; +import { BankAccountsList, BankAccount, If, Icon, T, Can } from '@/components'; import { useCashFlowAccountsContext } from './CashFlowAccountsProvider'; import withDrawerActions from '@/containers/Drawer/withDrawerActions'; import withAlertsActions from '@/containers/Alert/withAlertActions'; import withDialogActions from '@/containers/Dialog/withDialogActions'; +import { AccountDialogAction } from '@/containers/Dialogs/AccountDialog/utils'; import { safeCallback } from '@/utils'; -import { - getAddMoneyInOptions, - getAddMoneyOutOptions, -} from '@/constants/cashflowOptions'; const CASHFLOW_SKELETON_N = 4; @@ -77,7 +79,10 @@ function CashflowBankAccount({ }; // Handle edit account action. const handleEditAccount = () => { - openDialog('account-form', { action: 'edit', id: account.id }); + openDialog(DialogsName.AccountForm, { + action: AccountDialogAction.Edit, + id: account.id, + }); }; // Handle money in menu item actions. const handleMoneyInClick = (transactionType) => { diff --git a/src/containers/Drawers/AccountDrawer/AccountDrawerActionBar.tsx b/src/containers/Drawers/AccountDrawer/AccountDrawerActionBar.tsx index b0e702cb8..fe2e67644 100644 --- a/src/containers/Drawers/AccountDrawer/AccountDrawerActionBar.tsx +++ b/src/containers/Drawers/AccountDrawer/AccountDrawerActionBar.tsx @@ -13,7 +13,9 @@ import { Can, FormattedMessage as T, } from '@/components'; + import { AccountAction, AbilitySubject } from '@/constants/abilityOption'; +import { DialogsName } from '@/constants/dialogs'; import withDialogActions from '@/containers/Dialog/withDialogActions'; import withAlertsActions from '@/containers/Alert/withAlertActions'; @@ -37,7 +39,7 @@ function AccountDrawerActionBar({ // Handle new child button click. const onNewChildAccount = () => { - openDialog('account-form', { + openDialog(DialogsName.AccountForm, { action: AccountDialogAction.NewChild, parentAccountId: account.id, accountType: account.account_type, @@ -45,9 +47,9 @@ function AccountDrawerActionBar({ }; // Handle edit account action. const onEditAccount = () => { - openDialog('account-form', { + openDialog(DialogsName.AccountForm, { action: AccountDialogAction.Edit, - id: account.id, + accountId: account.id, }); }; // Handle delete action account. diff --git a/src/containers/Drawers/AccountDrawer/AccountDrawerHeader.tsx b/src/containers/Drawers/AccountDrawer/AccountDrawerHeader.tsx index 17ae69a0e..f86440d69 100644 --- a/src/containers/Drawers/AccountDrawer/AccountDrawerHeader.tsx +++ b/src/containers/Drawers/AccountDrawer/AccountDrawerHeader.tsx @@ -1,6 +1,6 @@ // @ts-nocheck import React from 'react'; -import { defaultTo } from 'lodash'; +import { isEmpty } from 'lodash'; import { Icon, @@ -15,6 +15,7 @@ import { useAccountDrawerContext } from './AccountDrawerProvider'; */ export default function AccountDrawerHeader() { const { account } = useAccountDrawerContext(); + return (
@@ -50,7 +51,7 @@ export default function AccountDrawerHeader() { }> - {defaultTo(account.description, '--')} + {!isEmpty(account.description) ? account.description : '--'}
diff --git a/src/containers/Entries/components.tsx b/src/containers/Entries/components.tsx index 337e9d355..66ee92cdc 100644 --- a/src/containers/Entries/components.tsx +++ b/src/containers/Entries/components.tsx @@ -4,7 +4,7 @@ import intl from 'react-intl-universal'; import { MenuItem, Menu, Button, Position } from '@blueprintjs/core'; import { Popover2 } from '@blueprintjs/popover2'; -import { Align, CellType } from '@/constants'; +import { Align, CellType, Features } from '@/constants'; import { Hint, Icon, FormattedMessage as T } from '@/components'; import { formattedAmount } from '@/utils'; import { @@ -16,6 +16,7 @@ import { CheckBoxFieldCell, ProjectBillableEntriesCell, } from '@/components/DataTableCells'; +import { useFeatureCan } from '@/hooks/state'; /** * Item header cell. @@ -88,6 +89,9 @@ const LandedCostHeaderCell = () => { * Retrieve editable items entries columns. */ export function useEditableItemsEntriesColumns({ landedCost }) { + const { featureCan } = useFeatureCan(); + const isProjectsFeatureEnabled = featureCan(Features.Projects); + return React.useMemo( () => [ { @@ -154,15 +158,19 @@ export function useEditableItemsEntriesColumns({ landedCost }) { }, ] : []), - { - Header: '', - accessor: 'invoicing', - Cell: ProjectBillableEntriesCell, - disableSortBy: true, - disableResizing: true, - width: 45, - align: Align.Center, - }, + ...(isProjectsFeatureEnabled + ? [ + { + Header: '', + accessor: 'invoicing', + Cell: ProjectBillableEntriesCell, + disableSortBy: true, + disableResizing: true, + width: 45, + align: Align.Center, + }, + ] + : []), { Header: '', accessor: 'action', diff --git a/src/containers/FinancialStatements/FinancialStatementDateRange.tsx b/src/containers/FinancialStatements/FinancialStatementDateRange.tsx index 592a98cf0..fdb09cf35 100644 --- a/src/containers/FinancialStatements/FinancialStatementDateRange.tsx +++ b/src/containers/FinancialStatements/FinancialStatementDateRange.tsx @@ -1,14 +1,16 @@ // @ts-nocheck -import React from 'react'; +import React, { useMemo } from 'react'; import intl from 'react-intl-universal'; import moment from 'moment'; import { FastField, ErrorMessage } from 'formik'; import { HTMLSelect, FormGroup, Intent, Position } from '@blueprintjs/core'; +import { DateInput } from '@blueprintjs/datetime'; + import { Row, Col, Hint } from '@/components'; import { momentFormatter, parseDateRangeQuery } from '@/utils'; -import { DateInput } from '@blueprintjs/datetime'; import { dateRangeOptions } from './constants'; +const FINANCIAL_REPORT_MAX_DATE = moment().add(5, 'years').toDate(); /** * Financial statement - Date range select. @@ -19,10 +21,7 @@ export default function FinancialStatementDateRange() { - {({ - form: { setFieldValue }, - field: { value }, - }) => ( + {({ form: { setFieldValue }, field: { value } }) => ( } @@ -40,8 +39,14 @@ export default function FinancialStatementDateRange() { const dateRange = parseDateRangeQuery(newValue); if (dateRange) { - setFieldValue('fromDate', moment(dateRange.fromDate).toDate()); - setFieldValue('toDate', moment(dateRange.toDate).toDate()); + setFieldValue( + 'fromDate', + moment(dateRange.fromDate).toDate(), + ); + setFieldValue( + 'toDate', + moment(dateRange.toDate).toDate(), + ); } } setFieldValue('dateRange', newValue); @@ -78,6 +83,7 @@ export default function FinancialStatementDateRange() { canClearSelection={false} minimal={true} fill={true} + maxDate={FINANCIAL_REPORT_MAX_DATE} /> )} @@ -109,6 +115,7 @@ export default function FinancialStatementDateRange() { fill={true} minimal={true} intent={error && Intent.DANGER} + maxDate={FINANCIAL_REPORT_MAX_DATE} /> )} diff --git a/src/containers/Purchases/Bills/BillForm/BillFormHeaderFields.tsx b/src/containers/Purchases/Bills/BillForm/BillFormHeaderFields.tsx index 4234067cd..7e051cb8b 100644 --- a/src/containers/Purchases/Bills/BillForm/BillFormHeaderFields.tsx +++ b/src/containers/Purchases/Bills/BillForm/BillFormHeaderFields.tsx @@ -5,7 +5,7 @@ import classNames from 'classnames'; import { FormGroup, InputGroup, Classes, Position } from '@blueprintjs/core'; import { FastField, ErrorMessage } from 'formik'; import { DateInput } from '@blueprintjs/datetime'; -import { FormattedMessage as T } from '@/components'; +import { FeatureCan, FormattedMessage as T } from '@/components'; import { CLASSES } from '@/constants/classes'; import { @@ -31,6 +31,7 @@ import { handleDateChange, inputIntent, } from '@/utils'; +import { Features } from '@/constants'; /** * Fill form header. @@ -170,19 +171,21 @@ function BillFormHeader() { {/*------------ Project name -----------*/} - } - inline={true} - className={classNames('form-group--select-list', Classes.FILL)} - > - + - + label={} + inline={true} + className={classNames('form-group--select-list', Classes.FILL)} + > + + + ); } diff --git a/src/containers/Sales/Estimates/EstimateForm/EstimateFormHeaderFields.tsx b/src/containers/Sales/Estimates/EstimateForm/EstimateFormHeaderFields.tsx index f07ece73f..823b3ba14 100644 --- a/src/containers/Sales/Estimates/EstimateForm/EstimateFormHeaderFields.tsx +++ b/src/containers/Sales/Estimates/EstimateForm/EstimateFormHeaderFields.tsx @@ -10,7 +10,7 @@ import { ControlGroup, } from '@blueprintjs/core'; import { DateInput } from '@blueprintjs/datetime'; -import { FFormGroup, FormattedMessage as T } from '@/components'; +import { FeatureCan, FFormGroup, FormattedMessage as T } from '@/components'; import { FastField, Field, ErrorMessage } from 'formik'; import { @@ -22,6 +22,7 @@ import { } from '@/utils'; import { customersFieldShouldUpdate } from './utils'; import { CLASSES } from '@/constants/classes'; +import { Features } from '@/constants'; import { CustomerSelectField, FieldRequiredHint, @@ -58,7 +59,6 @@ function EstimateFormHeader({ const handleEstimateNumberBtnClick = () => { openDialog('estimate-number-form', {}); }; - const handleEstimateNoBlur = (form, field) => (event) => { const newValue = event.target.value; @@ -71,7 +71,6 @@ function EstimateFormHeader({ }); } }; - // Syncs estimate number settings with the form. useObserveEstimateNoSettings(estimateNumberPrefix, estimateNextNumber); @@ -228,19 +227,21 @@ function EstimateFormHeader({ {/*------------ Project name -----------*/} - } - inline={true} - className={classNames('form-group--select-list', Classes.FILL)} - > - + - + label={} + inline={true} + className={classNames('form-group--select-list', Classes.FILL)} + > + + + ); } diff --git a/src/containers/Sales/Invoices/InvoiceForm/InvoiceFormHeaderFields.tsx b/src/containers/Sales/Invoices/InvoiceForm/InvoiceFormHeaderFields.tsx index f3c722dff..efcaf08a2 100644 --- a/src/containers/Sales/Invoices/InvoiceForm/InvoiceFormHeaderFields.tsx +++ b/src/containers/Sales/Invoices/InvoiceForm/InvoiceFormHeaderFields.tsx @@ -22,6 +22,7 @@ import { FieldRequiredHint, Icon, InputPrependButton, + FeatureCan, } from '@/components'; import { momentFormatter, compose, tansformDateValue } from '@/utils'; import { CLASSES } from '@/constants/classes'; @@ -40,6 +41,7 @@ import { ProjectsSelect, ProjectBillableEntriesLink, } from '@/containers/Projects/components'; +import { Features } from '@/constants'; import withSettings from '@/containers/Settings/withSettings'; import withDialogActions from '@/containers/Dialog/withDialogActions'; @@ -238,24 +240,26 @@ function InvoiceFormHeaderFields({ {/*------------ Project name -----------*/} - } - inline={true} - className={classNames('form-group--select-list', Classes.FILL)} - > - + - {values?.project_id && ( - - - - )} - + label={} + inline={true} + className={classNames('form-group--select-list', Classes.FILL)} + > + + {values?.project_id && ( + + + + )} + + ); } diff --git a/src/containers/Sales/PaymentReceives/PaymentReceiveForm/PaymentReceiveHeaderFields.tsx b/src/containers/Sales/PaymentReceives/PaymentReceiveForm/PaymentReceiveHeaderFields.tsx index c777f6854..85e9205ff 100644 --- a/src/containers/Sales/PaymentReceives/PaymentReceiveForm/PaymentReceiveHeaderFields.tsx +++ b/src/containers/Sales/PaymentReceives/PaymentReceiveForm/PaymentReceiveHeaderFields.tsx @@ -11,7 +11,8 @@ import { Button, } from '@blueprintjs/core'; import { DateInput } from '@blueprintjs/datetime'; -import { FormattedMessage as T } from '@/components'; +import { toSafeInteger } from 'lodash'; +import { FeatureCan, FormattedMessage as T } from '@/components'; import { FastField, Field, useFormikContext, ErrorMessage } from 'formik'; import { useAutofocus } from '@/hooks'; @@ -56,8 +57,7 @@ import { customersFieldShouldUpdate, accountsFieldShouldUpdate, } from './utils'; - -import { toSafeInteger } from 'lodash'; +import { Features } from '@/constants'; /** * Payment receive header fields. @@ -341,19 +341,21 @@ function PaymentReceiveHeaderFields({ {/*------------ Project name -----------*/} - } - inline={true} - className={classNames('form-group--select-list', Classes.FILL)} - > - + - + label={} + inline={true} + className={classNames('form-group--select-list', Classes.FILL)} + > + + + ); } diff --git a/src/containers/Sales/Receipts/ReceiptForm/ReceiptFormHeaderFields.tsx b/src/containers/Sales/Receipts/ReceiptForm/ReceiptFormHeaderFields.tsx index ce0247fd2..76435a890 100644 --- a/src/containers/Sales/Receipts/ReceiptForm/ReceiptFormHeaderFields.tsx +++ b/src/containers/Sales/Receipts/ReceiptForm/ReceiptFormHeaderFields.tsx @@ -22,6 +22,7 @@ import { InputPrependButton, CustomerDrawerLink, FormattedMessage as T, + FeatureCan, } from '@/components'; import withSettings from '@/containers/Settings/withSettings'; import withDialogActions from '@/containers/Dialog/withDialogActions'; @@ -44,6 +45,7 @@ import { ReceiptExchangeRateInputField, ReceiptProjectSelectButton, } from './components'; +import { Features } from '@/constants'; /** * Receipt form header fields. @@ -238,19 +240,21 @@ function ReceiptFormHeader({ {/*------------ Project name -----------*/} - } - inline={true} - className={classNames('form-group--select-list', Classes.FILL)} - > - + - + label={} + inline={true} + className={classNames('form-group--select-list', Classes.FILL)} + > + + + ); }