Files
bigcapital/packages/webapp/src/components/Accounts/AccountsMultiSelect.tsx
2026-05-31 23:35:10 +02:00

114 lines
3.0 KiB
TypeScript

import React from 'react';
import { MenuItem } from '@blueprintjs/core';
import intl from 'react-intl-universal';
import { FMultiSelect } from '../Forms';
import { accountPredicate } from './_components';
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;
}
export interface AccountSelect extends Partial<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: string,
active: boolean,
handleClick: (event: React.MouseEvent<HTMLElement>) => void,
): React.ReactElement => {
return (
<MenuItem
icon="add"
text={intl.get('list.create', { value: `"${query}"` })}
active={active}
onClick={handleClick}
/>
);
};
// Create new item from the given query string.
const createNewItemFromQuery = (query: string): AccountSelect => ({
label: query,
value: query,
text: query,
id: 0,
name: query,
code: query,
});
/**
* Accounts multi-select field binded with Formik form.
* @returns {JSX.Element}
*/
export function AccountsMultiSelect({
items,
allowCreate,
filterByRootTypes,
filterByParentTypes,
filterByTypes,
filterByNormal,
...rest
}: AccountsMultiSelectProps): React.ReactElement {
const { openDialog } = useDialogActions();
// Filters accounts based on filter props.
const filteredAccounts = usePreprocessingAccounts(items, {
filterByParentTypes: filterByParentTypes || [],
filterByTypes: filterByTypes || [],
filterByNormal: filterByNormal || [],
filterByRootTypes: filterByRootTypes || [],
});
// Maybe inject new item props to select component.
const maybeCreateNewItemRenderer = allowCreate
? createNewItemRenderer
: undefined;
const maybeCreateNewItemFromQuery = allowCreate
? createNewItemFromQuery
: undefined;
// Handles the create item click.
const handleCreateItemClick = (): void => {
openDialog(DialogsName.AccountForm);
};
return (
<FMultiSelect
{...rest}
items={filteredAccounts}
valueAccessor={'id'}
textAccessor={'name'}
labelAccessor={'code'}
tagAccessor={'name'}
popoverProps={{ minimal: true }}
itemPredicate={accountPredicate}
createNewItemRenderer={maybeCreateNewItemRenderer}
createNewItemFromQuery={maybeCreateNewItemFromQuery}
onCreateItemSelect={handleCreateItemClick}
/>
);
}