mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-17 21:30:31 +00:00
feat: migrate from CRA to Vite for speed
This commit is contained in:
@@ -1,13 +1,43 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import { MenuItem } from '@blueprintjs/core';
|
||||
import intl from 'react-intl-universal';
|
||||
import { FMultiSelect } from '../Forms';
|
||||
import { accountPredicate } from './_components';
|
||||
import { MenuItemNestedText } from '../Menu';
|
||||
import { usePreprocessingAccounts } from './_hooks';
|
||||
import { DialogsName } from '@/constants/dialogs';
|
||||
import { useDialogActions } from '@/hooks/state/dashboard';
|
||||
import { SelectOptionProps } from '@blueprintjs-formik/select';
|
||||
|
||||
interface Account {
|
||||
id: number;
|
||||
name: string;
|
||||
code: string;
|
||||
account_level: number;
|
||||
account_type?: string;
|
||||
account_parent_type?: string;
|
||||
account_root_type?: string;
|
||||
account_normal?: string;
|
||||
}
|
||||
|
||||
interface AccountSelect extends Account, SelectOptionProps { }
|
||||
|
||||
type MultiSelectProps = React.ComponentProps<typeof FMultiSelect>;
|
||||
|
||||
interface AccountsMultiSelectProps extends Omit<MultiSelectProps, 'items'> {
|
||||
items: AccountSelect[];
|
||||
allowCreate?: boolean;
|
||||
filterByRootTypes?: string[];
|
||||
filterByParentTypes?: string[];
|
||||
filterByTypes?: string[];
|
||||
filterByNormal?: string[];
|
||||
}
|
||||
|
||||
// Create new account renderer.
|
||||
const createNewItemRenderer = (query, active, handleClick) => {
|
||||
const createNewItemRenderer = (
|
||||
query: string,
|
||||
active: boolean,
|
||||
handleClick: (event: React.MouseEvent<HTMLElement>) => void,
|
||||
): React.ReactElement => {
|
||||
return (
|
||||
<MenuItem
|
||||
icon="add"
|
||||
@@ -18,32 +48,12 @@ const createNewItemRenderer = (query, active, handleClick) => {
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Default account item renderer of the list.
|
||||
* @returns {JSX.Element}
|
||||
*/
|
||||
const accountRenderer = (
|
||||
item,
|
||||
{ handleClick, modifiers, query },
|
||||
{ isSelected },
|
||||
) => {
|
||||
if (!modifiers.matchesPredicate) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<MenuItem
|
||||
active={modifiers.active}
|
||||
disabled={modifiers.disabled}
|
||||
text={<MenuItemNestedText level={item.account_level} text={item.name} />}
|
||||
key={item.id}
|
||||
onClick={handleClick}
|
||||
icon={isSelected ? 'tick' : 'blank'}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
// Create new item from the given query string.
|
||||
const createNewItemFromQuery = (name) => ({ name });
|
||||
const createNewItemFromQuery = (query: string): SelectOptionProps => ({
|
||||
label: query,
|
||||
value: query,
|
||||
id: 0,
|
||||
});
|
||||
|
||||
/**
|
||||
* Accounts multi-select field binded with Formik form.
|
||||
@@ -59,27 +69,32 @@ export function AccountsMultiSelect({
|
||||
filterByNormal,
|
||||
|
||||
...rest
|
||||
}) {
|
||||
}: AccountsMultiSelectProps): React.ReactElement {
|
||||
const { openDialog } = useDialogActions();
|
||||
|
||||
// Filters accounts based on filter props.
|
||||
const filteredAccounts = usePreprocessingAccounts(items, {
|
||||
filterByParentTypes,
|
||||
filterByTypes,
|
||||
filterByNormal,
|
||||
filterByRootTypes,
|
||||
filterByParentTypes: filterByParentTypes || [],
|
||||
filterByTypes: filterByTypes || [],
|
||||
filterByNormal: filterByNormal || [],
|
||||
filterByRootTypes: filterByRootTypes || [],
|
||||
});
|
||||
// Maybe inject new item props to select component.
|
||||
const maybeCreateNewItemRenderer = allowCreate ? createNewItemRenderer : null;
|
||||
const maybeCreateNewItemRenderer = allowCreate
|
||||
? createNewItemRenderer
|
||||
: undefined;
|
||||
const maybeCreateNewItemFromQuery = allowCreate
|
||||
? createNewItemFromQuery
|
||||
: null;
|
||||
: undefined;
|
||||
|
||||
// Handles the create item click.
|
||||
const handleCreateItemClick = () => {
|
||||
const handleCreateItemClick = (): void => {
|
||||
openDialog(DialogsName.AccountForm);
|
||||
};
|
||||
|
||||
return (
|
||||
<FMultiSelect
|
||||
<FMultiSelect<AccountSelect>
|
||||
{...rest}
|
||||
items={filteredAccounts}
|
||||
valueAccessor={'id'}
|
||||
textAccessor={'name'}
|
||||
@@ -87,11 +102,9 @@ export function AccountsMultiSelect({
|
||||
tagAccessor={'name'}
|
||||
popoverProps={{ minimal: true }}
|
||||
itemPredicate={accountPredicate}
|
||||
itemRenderer={accountRenderer}
|
||||
createNewItemRenderer={maybeCreateNewItemRenderer}
|
||||
createNewItemFromQuery={maybeCreateNewItemFromQuery}
|
||||
onCreateItemSelect={handleCreateItemClick}
|
||||
{...rest}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
// @ts-nocheck
|
||||
import React, { useState, useCallback, useEffect, useMemo } from 'react';
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
import * as R from 'ramda';
|
||||
import intl from 'react-intl-universal';
|
||||
import classNames from 'classnames';
|
||||
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 {
|
||||
FSuggest,
|
||||
MenuItemNestedText,
|
||||
FormattedMessage as T,
|
||||
} from '@/components';
|
||||
import { nestedArrayToflatten, filterAccountsByQuery } from '@/utils';
|
||||
|
||||
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
||||
@@ -33,14 +36,6 @@ const createNewItemFromQuery = (name) => {
|
||||
};
|
||||
};
|
||||
|
||||
// Handle input value renderer.
|
||||
const handleInputValueRenderer = (inputValue) => {
|
||||
if (inputValue) {
|
||||
return inputValue.name.toString();
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
// Filters accounts items.
|
||||
const filterAccountsPredicater = (query, account, _index, exactMatch) => {
|
||||
const normalizedTitle = account.name.toLowerCase();
|
||||
@@ -62,11 +57,7 @@ function AccountsSuggestFieldRoot({
|
||||
|
||||
// #ownProps
|
||||
accounts,
|
||||
initialAccountId,
|
||||
selectedAccountId,
|
||||
defaultSelectText = intl.formatMessage({ id: 'select_account' }),
|
||||
popoverFill = false,
|
||||
onAccountSelected,
|
||||
|
||||
filterByParentTypes = [],
|
||||
filterByTypes = [],
|
||||
@@ -81,67 +72,14 @@ function AccountsSuggestFieldRoot({
|
||||
() => nestedArrayToflatten(accounts),
|
||||
[accounts],
|
||||
);
|
||||
|
||||
// Filters accounts based on filter props.
|
||||
const filteredAccounts = useMemo(() => {
|
||||
let filteredAccounts = filterAccountsByQuery(flattenAccounts, {
|
||||
filterByRootTypes,
|
||||
filterByParentTypes,
|
||||
filterByTypes,
|
||||
filterByNormal,
|
||||
});
|
||||
return filteredAccounts;
|
||||
}, [
|
||||
flattenAccounts,
|
||||
filterByRootTypes,
|
||||
filterByParentTypes,
|
||||
filterByTypes,
|
||||
filterByNormal,
|
||||
]);
|
||||
|
||||
// Find initial account object to set it as default account in initial render.
|
||||
const initialAccount = useMemo(
|
||||
() => filteredAccounts.find((a) => a.id === initialAccountId),
|
||||
[initialAccountId, filteredAccounts],
|
||||
);
|
||||
|
||||
const [selectedAccount, setSelectedAccount] = useState(
|
||||
initialAccount || null,
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof selectedAccountId !== 'undefined') {
|
||||
const account = selectedAccountId
|
||||
? filteredAccounts.find((a) => a.id === selectedAccountId)
|
||||
: null;
|
||||
setSelectedAccount(account);
|
||||
}
|
||||
}, [selectedAccountId, filteredAccounts, setSelectedAccount]);
|
||||
|
||||
// Account item of select accounts field.
|
||||
const accountItem = useCallback((item, { handleClick, modifiers, query }) => {
|
||||
return (
|
||||
<MenuItem
|
||||
text={<MenuItemNestedText level={item.level} text={item.name} />}
|
||||
label={item.code}
|
||||
key={item.id}
|
||||
onClick={handleClick}
|
||||
/>
|
||||
);
|
||||
}, []);
|
||||
|
||||
const handleAccountSelect = useCallback(
|
||||
(account) => {
|
||||
if (account.id) {
|
||||
setSelectedAccount({ ...account });
|
||||
onAccountSelected && onAccountSelected(account);
|
||||
} else {
|
||||
const handleCreateItemSelect = useCallback(
|
||||
(item) => {
|
||||
if (!item.id) {
|
||||
openDialog(DialogsName.AccountForm);
|
||||
}
|
||||
},
|
||||
[setSelectedAccount, onAccountSelected, openDialog],
|
||||
[openDialog],
|
||||
);
|
||||
|
||||
// Maybe inject new item props to select component.
|
||||
const maybeCreateNewItemRenderer = allowCreate ? createNewItemRenderer : null;
|
||||
const maybeCreateNewItemFromQuery = allowCreate
|
||||
@@ -149,21 +87,15 @@ function AccountsSuggestFieldRoot({
|
||||
: null;
|
||||
|
||||
return (
|
||||
<Suggest
|
||||
<FSuggest
|
||||
items={filteredAccounts}
|
||||
noResults={<MenuItem disabled={true} text={<T id={'no_accounts'} />} />}
|
||||
itemRenderer={accountItem}
|
||||
itemPredicate={filterAccountsPredicater}
|
||||
onItemSelect={handleAccountSelect}
|
||||
selectedItem={selectedAccount}
|
||||
onCreateItemSelect={handleCreateItemSelect}
|
||||
valueAccessor="id"
|
||||
textAccessor="name"
|
||||
labelAccessor="code"
|
||||
inputProps={{ placeholder: defaultSelectText }}
|
||||
resetOnClose={true}
|
||||
fill={true}
|
||||
resetOnClose
|
||||
popoverProps={{ minimal: true, boundary: 'window' }}
|
||||
inputValueRenderer={handleInputValueRenderer}
|
||||
className={classNames(CLASSES.FORM_GROUP_LIST_SELECT, {
|
||||
[CLASSES.SELECT_LIST_FILL_POPOVER]: popoverFill,
|
||||
})}
|
||||
createNewItemRenderer={maybeCreateNewItemRenderer}
|
||||
createNewItemFromQuery={maybeCreateNewItemFromQuery}
|
||||
{...suggestProps}
|
||||
|
||||
@@ -36,15 +36,19 @@ function getCurrentLocal() {
|
||||
/**
|
||||
* Loads the localization data of the given locale.
|
||||
*/
|
||||
function loadLocales(currentLocale) {
|
||||
return import(`../lang/${currentLocale}/index.json`);
|
||||
async function loadLocales(currentLocale) {
|
||||
return await import(`../lang/${currentLocale}/index.json`).then(
|
||||
(module) => module.default,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the localization data of yup validation library.
|
||||
*/
|
||||
function loadYupLocales(currentLocale) {
|
||||
return import(`../lang/${currentLocale}/locale`);
|
||||
async function loadYupLocales(currentLocale) {
|
||||
return await import(`../lang/${currentLocale}/locale.tsx`).then(
|
||||
(module) => module.locale,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -109,11 +113,11 @@ function useAppYupLoadLocales(currentLocale) {
|
||||
|
||||
React.useEffect(() => {
|
||||
loadYupLocales(currentLocale)
|
||||
.then(({ locale }) => {
|
||||
setLocale(locale);
|
||||
.then((results) => {
|
||||
setLocale(results);
|
||||
setIsLoading(false);
|
||||
})
|
||||
.then(() => {});
|
||||
.then(() => { });
|
||||
}, [currentLocale, stopLoading]);
|
||||
|
||||
// Watches the valiue to start/stop splash screen.
|
||||
|
||||
@@ -6,10 +6,14 @@ import { Select } from '@blueprintjs/select';
|
||||
export function CurrenciesSelectList({ selectProps, onItemSelect, className }) {
|
||||
const currencies = [
|
||||
{
|
||||
id: 'USD',
|
||||
code: 'USD',
|
||||
name: 'USD US dollars',
|
||||
key: 'USD',
|
||||
},
|
||||
{
|
||||
id: 'CAD',
|
||||
code: 'CAD',
|
||||
name: 'CAD Canadian dollars',
|
||||
key: 'CAD',
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user