diff --git a/client/package.json b/client/package.json
index 38b23dc02..c4dcc5020 100644
--- a/client/package.json
+++ b/client/package.json
@@ -16,6 +16,7 @@
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.4.0",
"@testing-library/user-event": "^7.2.1",
+ "@types/lodash": "^4.14.172",
"@typescript-eslint/eslint-plugin": "^2.10.0",
"@typescript-eslint/parser": "^2.10.0",
"accounting": "^0.4.1",
diff --git a/client/src/components/AdvancedFilter/AdvancedFilter.schema.ts b/client/src/components/AdvancedFilter/AdvancedFilter.schema.ts
new file mode 100644
index 000000000..6efa7d699
--- /dev/null
+++ b/client/src/components/AdvancedFilter/AdvancedFilter.schema.ts
@@ -0,0 +1,13 @@
+import * as Yup from 'yup';
+import { DATATYPES_LENGTH } from 'common/dataTypes';
+
+export const getFilterDropdownSchema = () => Yup.object().shape({
+ conditions: Yup.array().of(
+ Yup.object().shape({
+ fieldKey: Yup.string().max(DATATYPES_LENGTH.TEXT),
+ value: Yup.string().nullable().max(DATATYPES_LENGTH.TEXT),
+ condition: Yup.string().nullable().max(DATATYPES_LENGTH.TEXT),
+ comparator: Yup.string().nullable().max(DATATYPES_LENGTH.TEXT),
+ }),
+ ),
+});
diff --git a/client/src/components/DynamicFilter/DynamicFilterCompatatorField.js b/client/src/components/AdvancedFilter/AdvancedFilterCompatatorField.tsx
similarity index 78%
rename from client/src/components/DynamicFilter/DynamicFilterCompatatorField.js
rename to client/src/components/AdvancedFilter/AdvancedFilterCompatatorField.tsx
index b1cb3278e..7dffe6f0e 100644
--- a/client/src/components/DynamicFilter/DynamicFilterCompatatorField.js
+++ b/client/src/components/AdvancedFilter/AdvancedFilterCompatatorField.tsx
@@ -1,7 +1,7 @@
import React, { useMemo } from 'react';
import { HTMLSelect, Classes } from '@blueprintjs/core';
import intl from 'react-intl-universal';
-import { getConditionTypeCompatators } from './DynamicFilterCompatators';
+import { getConditionTypeCompatators } from './utils';
export default function DynamicFilterCompatatorField({
dataType,
@@ -9,7 +9,7 @@ export default function DynamicFilterCompatatorField({
}) {
const options = useMemo(
() => getConditionTypeCompatators(dataType).map(comp => ({
- value: comp.value, label: intl.get(comp.label_id),
+ value: comp.value, label: intl.get(comp.label),
})),
[dataType]
);
diff --git a/client/src/components/AdvancedFilter/AdvancedFilterDropdown.tsx b/client/src/components/AdvancedFilter/AdvancedFilterDropdown.tsx
new file mode 100644
index 000000000..d18d23958
--- /dev/null
+++ b/client/src/components/AdvancedFilter/AdvancedFilterDropdown.tsx
@@ -0,0 +1,306 @@
+import React from 'react';
+import { Formik, Field, FieldArray, useFormikContext } from 'formik';
+import {
+ Button,
+ Intent,
+ FormGroup,
+ Classes,
+ HTMLSelect,
+} from '@blueprintjs/core';
+import { get, defaultTo, isEqual } from 'lodash';
+import { Icon, FormattedMessage as T } from 'components';
+import {
+ AdvancedFilterDropdownProvider,
+ FilterConditionProvider,
+ useFilterCondition,
+ useAdvancedFilterContext,
+} from './AdvancedFilterDropdownContext';
+import AdvancedFilterCompatatorField from './AdvancedFilterCompatatorField';
+import AdvancedFilterValueField from './AdvancedFilterValueField2';
+import {
+ filterConditionRoles,
+ getConditionalsOptions,
+ transformFieldsToOptions,
+} from './utils';
+import { getFilterDropdownSchema } from './AdvancedFilter.schema';
+import {
+ IAdvancedFilterDropdown,
+ IAdvancedFilterDropdownFooter,
+ IFilterDropdownFormikValues,
+ IAdvancedFilterDropdownConditionsProps,
+ IAdvancedFilterDropdownCondition,
+ IFilterRole,
+} from './interfaces';
+import { useAdvancedFilterAutoSubmit } from './components';
+
+/**
+ * Filter condition field.
+ */
+function FilterConditionField() {
+ const conditionalsOptions = getConditionalsOptions();
+ const { conditionIndex } = useFilterCondition();
+
+ return (
+
+ {({ field }) => (
+
+
+
+ )}
+
+ );
+}
+
+/**
+ * Compatator field.
+ */
+function FilterCompatatorFilter() {
+ const { conditionIndex } = useFilterCondition();
+
+ return (
+
+ {({ field }) => (
+
+
+
+ )}
+
+ );
+}
+
+/**
+ * Resource fields field.
+ */
+function FilterFieldsField() {
+ const { conditionIndex } = useFilterCondition();
+ const { fields } = useAdvancedFilterContext();
+
+ return (
+
+ {({ field }) => (
+
+
+
+ )}
+
+ );
+}
+
+/**
+ * Advanced filter value field.
+ */
+function FilterValueField(): JSX.Element | null {
+ const { values } = useFormikContext();
+ const { conditionIndex } = useFilterCondition();
+ const { fieldsByKey } = useAdvancedFilterContext();
+
+ // Current condition field key.
+ const conditionFieldKey = get(
+ values.conditions,
+ `[${conditionIndex}].fieldKey`,
+ );
+ // Field meta.
+ const fieldMeta = fieldsByKey[conditionFieldKey];
+
+ // Can't continue if the given field key is not selected yet.
+ if (!conditionFieldKey || !fieldMeta) {
+ return null;
+ }
+ // Field meta type, name and options.
+ const fieldType = get(fieldMeta, 'fieldType');
+ const fieldName = get(fieldMeta, 'name');
+ const options = get(fieldMeta, 'options');
+
+ const valueFieldPath = `conditions[${conditionIndex}].value`;
+
+ return (
+
+ {({ form: { setFieldValue } }) => (
+
+ {
+ setFieldValue(valueFieldPath, value);
+ }}
+ />
+
+ )}
+
+ );
+}
+
+/**
+ * Advanced filter condition line.
+ */
+function AdvancedFilterDropdownCondition({
+ conditionIndex,
+ onRemoveClick,
+}: IAdvancedFilterDropdownCondition) {
+ // Handle click remove condition.
+ const handleClickRemoveCondition = () => {
+ onRemoveClick && onRemoveClick(conditionIndex);
+ };
+
+ return (
+
+
+
+
+
+
+
+ }
+ minimal={true}
+ onClick={handleClickRemoveCondition}
+ />
+
+
+ );
+}
+
+/**
+ * Advanced filter dropdown condition.
+ */
+function AdvancedFilterDropdownConditions({
+ push,
+ remove,
+ form,
+}: IAdvancedFilterDropdownConditionsProps) {
+ const { initialCondition } = useAdvancedFilterContext();
+
+ // Handle remove condition.
+ const handleClickRemoveCondition = (conditionIndex: number) => {
+ remove(conditionIndex);
+ };
+ // Handle new condition button click.
+ const handleNewConditionBtnClick = (index: number) => {
+ push({ ...initialCondition });
+ };
+
+ return (
+
+
+ {form.values.conditions.map((condition: IFilterRole, index: number) => (
+
+ ))}
+
+
+
+ );
+}
+
+/**
+ * Advanced filter dropdown form.
+ */
+function AdvancedFilterDropdownForm() {
+ //
+ useAdvancedFilterAutoSubmit();
+
+ return (
+
+ );
+}
+
+/**
+ * Advanced filter dropdown footer.
+ */
+function AdvancedFilterDropdownFooter({
+ onClick,
+}: IAdvancedFilterDropdownFooter) {
+ // Handle new filter condition button click.
+ const onClickNewFilter = (event) => {
+ onClick && onClick(event);
+ };
+
+ return (
+
+
+
+ );
+}
+
+/**
+ * Advanced filter dropdown.
+ */
+export default function AdvancedFilterDropdown({
+ fields,
+ defaultFieldKey,
+ defaultComparator,
+ defaultValue,
+ onFilterChange,
+}: IAdvancedFilterDropdown) {
+ const [prevConditions, setPrevConditions] = React.useState({});
+
+ // Handle the filter dropdown form submit.
+ const handleFitlerDropdownSubmit = (values: IFilterDropdownFormikValues) => {
+ const conditions = filterConditionRoles(values.conditions);
+
+ // Campare the current conditions with previous conditions, if they were equal
+ // there is no need to execute `onFilterChange` function.
+ if (!isEqual(prevConditions, conditions) && conditions.length > 0) {
+ onFilterChange && onFilterChange(conditions);
+
+ setPrevConditions(conditions);
+ }
+ };
+
+ // Filter dropdown validation schema.
+ const validationSchema = getFilterDropdownSchema();
+
+ // Initial condition.
+ const initialCondition = {
+ fieldKey: defaultFieldKey,
+ comparator: defaultTo(defaultComparator, 'equals'),
+ condition: '',
+ value: defaultTo(defaultValue, ''),
+ };
+ // Initial values.
+ const initialValues: IFilterDropdownFormikValues = {
+ conditions: [initialCondition],
+ };
+
+ return (
+
+ );
+}
diff --git a/client/src/components/AdvancedFilter/AdvancedFilterDropdownContext.tsx b/client/src/components/AdvancedFilter/AdvancedFilterDropdownContext.tsx
new file mode 100644
index 000000000..e6e53654a
--- /dev/null
+++ b/client/src/components/AdvancedFilter/AdvancedFilterDropdownContext.tsx
@@ -0,0 +1,47 @@
+import React, { createContext, useContext } from 'react';
+import { keyBy } from 'lodash';
+import {
+ IAdvancedFilterContextProps,
+ IFilterConditionContextProps,
+ IAdvancedFilterProviderProps,
+ IFilterConditionProviderProps,
+} from './interfaces';
+
+const AdvancedFilterContext = createContext({});
+const FilterConditionContext = createContext({});
+
+/**
+ * Advanced filter dropdown context provider.
+ */
+function AdvancedFilterDropdownProvider({
+ initialCondition,
+ fields,
+ ...props
+}: IAdvancedFilterProviderProps) {
+ const fieldsByKey = keyBy(fields, 'key');
+ // Provider payload.
+ const provider = { initialCondition, fields, fieldsByKey };
+ return ;
+}
+
+/**
+ * Filter condition row context provider.
+ */
+function FilterConditionProvider({
+ conditionIndex,
+ ...props
+}: IFilterConditionProviderProps) {
+ // Provider payload.
+ const provider = { conditionIndex };
+ return ;
+}
+
+const useFilterCondition = () => useContext(FilterConditionContext);
+const useAdvancedFilterContext = () => useContext(AdvancedFilterContext);
+
+export {
+ AdvancedFilterDropdownProvider,
+ FilterConditionProvider,
+ useAdvancedFilterContext,
+ useFilterCondition,
+};
diff --git a/client/src/components/DynamicFilter/DynamicFilterValueField.js b/client/src/components/AdvancedFilter/AdvancedFilterValueField.tsx
similarity index 100%
rename from client/src/components/DynamicFilter/DynamicFilterValueField.js
rename to client/src/components/AdvancedFilter/AdvancedFilterValueField.tsx
diff --git a/client/src/components/AdvancedFilter/AdvancedFilterValueField2.tsx b/client/src/components/AdvancedFilter/AdvancedFilterValueField2.tsx
new file mode 100644
index 000000000..c30a07e8a
--- /dev/null
+++ b/client/src/components/AdvancedFilter/AdvancedFilterValueField2.tsx
@@ -0,0 +1,104 @@
+import React from 'react';
+import { Position, Checkbox, InputGroup, FormGroup } from '@blueprintjs/core';
+import { DateInput } from '@blueprintjs/datetime';
+import moment from 'moment';
+import intl from 'react-intl-universal';
+import { Choose, ListSelect } from 'components';
+import { momentFormatter, tansformDateValue } from 'utils';
+import { IFieldType, IAdvancedFilterValueField } from './interfaces';
+
+function AdvancedFilterEnumerationField({ options, value, ...rest }) {
+ return (
+
+ );
+}
+
+/**
+ * Advanced filter value field detarminer.
+ */
+export default function AdvancedFilterValueField2({
+ fieldType,
+ options,
+ onChange,
+}: IAdvancedFilterValueField) {
+ const [localValue, setLocalValue] = React.useState('');
+
+ const triggerOnChange = (value: string) => onChange && onChange(value);
+
+ // Handle input change.
+ const handleInputChange = (e) => {
+ if (e.currentTarget.type === 'checkbox') {
+ setLocalValue(e.currentTarget.checked);
+ triggerOnChange(e.currentTarget.checked);
+ } else {
+ setLocalValue(e.currentTarget.value);
+ triggerOnChange(e.currentTarget.value);
+ }
+ };
+
+ // Handle enumeration field type change.
+ const handleEnumerationChange = (option) => {
+ setLocalValue(option.key);
+ triggerOnChange(option.key);
+ };
+
+ // Handle date field change.
+ const handleDateChange = (date: Date) => {
+ const formattedDate: string = moment(date).format('YYYY/MM/DD');
+
+ setLocalValue(formattedDate);
+ triggerOnChange(formattedDate);
+ };
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/client/src/components/AdvancedFilter/components.tsx b/client/src/components/AdvancedFilter/components.tsx
new file mode 100644
index 000000000..57b78fd3c
--- /dev/null
+++ b/client/src/components/AdvancedFilter/components.tsx
@@ -0,0 +1,22 @@
+import React from 'react';
+import { useFormikContext } from 'formik';
+import { debounce } from 'lodash';
+
+const DEBOUNCE_MS = 100;
+
+/**
+ * Advanced filter auto-save.
+ */
+export function useAdvancedFilterAutoSubmit() {
+ const { submitForm, values } = useFormikContext();
+ const [isSubmit, setIsSubmit] = React.useState(false);
+
+ const debouncedSubmit = React.useCallback(
+ debounce(() => {
+ return submitForm().then(() => setIsSubmit(true));
+ }, DEBOUNCE_MS),
+ [submitForm],
+ );
+
+ React.useEffect(() => debouncedSubmit, [debouncedSubmit, values]);
+}
diff --git a/client/src/components/AdvancedFilter/interfaces.ts b/client/src/components/AdvancedFilter/interfaces.ts
new file mode 100644
index 000000000..6ee8b0a7b
--- /dev/null
+++ b/client/src/components/AdvancedFilter/interfaces.ts
@@ -0,0 +1,84 @@
+import { ArrayHelpers } from 'formik';
+
+export type IResourceFieldType = 'text' | 'number' | 'enumeration' | 'boolean';
+
+export interface IResourceField {
+ name: string;
+ key: string;
+ fieldType: IResourceFieldType;
+}
+
+export interface IAdvancedFilterDropdown {
+ fields: IResourceField[];
+ defaultFieldKey: string;
+ defaultComparator?: string;
+ defaultValue?: string;
+}
+
+export interface IAdvancedFilterDropdownFooter {
+ onClick?: Function;
+}
+
+export interface IFilterFieldsField {
+ fields: IResourceField[];
+}
+
+export interface IFilterRole {
+ fieldKey: string;
+ comparator: string;
+ condition: string;
+ value: string;
+}
+
+export interface IAdvancedFilterContextProps {
+ initialCondition: IFilterRole;
+ fields: IResourceField[];
+ fieldsByKey: { [fieldKey: string]: IResourceField };
+}
+
+export interface IFilterConditionContextProps {
+ conditionIndex: number;
+}
+
+export interface IAdvancedFilterProviderProps {
+ initialCondition: IFilterRole;
+ fields: IResourceField[];
+ children: JSX.Element | JSX.Element[];
+}
+
+export interface IFilterConditionProviderProps {
+ conditionIndex: number;
+ children: JSX.Element | JSX.Element[];
+}
+
+export interface IFilterDropdownFormikValues {
+ conditions: IFilterRole[];
+}
+
+export type IAdvancedFilterDropdownConditionsProps = ArrayHelpers;
+
+export interface IAdvancedFilterDropdownCondition {
+ conditionIndex: number;
+ onRemoveClick: Function;
+}
+
+export interface IFilterOption {
+ key: string;
+ label: string;
+}
+
+export interface IAdvancedFilterValueField {
+ fieldType: string;
+ key: string;
+ label: string;
+ options?: IFilterOption[];
+ onChange: Function;
+}
+
+export enum IFieldType {
+ TEXT = 'text',
+ NUMBER = 'number',
+ DATE = 'date',
+ ENUMERATION = 'enumeration',
+ BOOLEAN = 'boolean',
+}
diff --git a/client/src/components/AdvancedFilter/utils.ts b/client/src/components/AdvancedFilter/utils.ts
new file mode 100644
index 000000000..a01044726
--- /dev/null
+++ b/client/src/components/AdvancedFilter/utils.ts
@@ -0,0 +1,98 @@
+import intl from 'react-intl-universal';
+import { IResourceField, IFilterRole } from './interfaces';
+import { uniqueMultiProps, checkRequiredProperties } from 'utils';
+
+interface IConditionOption {
+ label: string;
+ value: string;
+}
+
+// Conditions options.
+export const getConditionalsOptions = (): IConditionOption[] => [
+ { value: 'and', label: intl.get('and') },
+ { value: 'or', label: intl.get('or') },
+];
+
+interface IConditionTypeOption {
+ value: string;
+ label: string;
+}
+
+export const getBooleanCompatators = (): IConditionTypeOption[] => [
+ { value: 'is', label: 'is' },
+ { value: 'is_not', label: 'is_not' },
+];
+
+export const getTextCompatators = (): IConditionTypeOption[] => [
+ { value: 'contain', label: 'contain' },
+ { value: 'not_contain', label: 'not_contain' },
+ { value: 'equals', label: 'equals' },
+ { value: 'not_equal', label: 'not_equals' },
+];
+
+export const getDateCompatators = (): IConditionTypeOption[] => [
+ { value: 'in', label: 'in' },
+ { value: 'after', label: 'after' },
+ { value: 'before', label: 'before' },
+];
+
+export const getOptionsCompatators = (): IConditionTypeOption[] => [
+ { value: 'is', label: 'is' },
+ { value: 'is_not', label: 'is_not' },
+];
+
+export const getNumberCampatators = (): IConditionTypeOption[] => [
+ { value: 'equals', label: 'equals' },
+ { value: 'not_equal', label: 'not_equal' },
+ { value: 'bigger_than', label: 'bigger_than' },
+ { value: 'bigger_or_equals', label: 'bigger_or_equals' },
+ { value: 'smaller_than', label: 'smaller_than' },
+ { value: 'smaller_or_equals', label: 'smaller_or_equals' },
+];
+
+export const getConditionTypeCompatators = (
+ dataType: string,
+): IConditionTypeOption[] => {
+ return [
+ ...(dataType === 'options'
+ ? [...getOptionsCompatators()]
+ : dataType === 'date'
+ ? [...getDateCompatators()]
+ : dataType === 'boolean'
+ ? [...getBooleanCompatators()]
+ : dataType === 'number'
+ ? [...getNumberCampatators()]
+ : [...getTextCompatators()]),
+ ];
+};
+
+export const getConditionDefaultCompatator = (
+ dataType: string,
+): IConditionTypeOption => {
+ const compatators = getConditionTypeCompatators(dataType);
+ return compatators[0];
+};
+
+export const transformFieldsToOptions = (fields: IResourceField[]) =>
+ fields.map((field) => ({
+ value: field.key,
+ label: field.name,
+ }));
+
+/**
+ * Filtered conditions that don't contain atleast on required fields or
+ * fileds keys that not exists.
+ * @param {IFilterRole[]} conditions
+ * @returns
+ */
+export const filterConditionRoles = (
+ conditions: IFilterRole[],
+): IFilterRole[] => {
+ const requiredProps = ['fieldKey', 'condition', 'comparator', 'value'];
+
+ const filteredConditions = conditions.filter(
+ (condition: IFilterRole) =>
+ !checkRequiredProperties(condition, requiredProps),
+ );
+ return uniqueMultiProps(filteredConditions, requiredProps);
+};
diff --git a/client/src/components/DynamicFilter/DynamicFilterCompatators.js b/client/src/components/DynamicFilter/DynamicFilterCompatators.js
deleted file mode 100644
index 9eb5573ea..000000000
--- a/client/src/components/DynamicFilter/DynamicFilterCompatators.js
+++ /dev/null
@@ -1,50 +0,0 @@
-export const BooleanCompatators = [
- { value: 'is', label_id: 'is' },
- { value: 'is_not', label_id: 'is_not' },
-];
-
-export const TextCompatators = [
- { value: 'contain', label_id: 'contain' },
- { value: 'not_contain', label_id: 'not_contain' },
- { value: 'equals', label_id: 'equals' },
- { value: 'not_equal', label_id: 'not_equals' },
-];
-
-export const DateCompatators = [
- { value: 'in', label_id: 'in' },
- { value: 'after', label_id: 'after' },
- { value: 'before', label_id: 'before' },
-];
-
-export const OptionsCompatators = [
- { value: 'is', label_id: 'is' },
- { value: 'is_not', label_id: 'is_not' },
-];
-
-export const NumberCampatators = [
- { value: 'equals', label_id: 'equals' },
- { value: 'not_equal', label_id: 'not_equal' },
- { value: 'bigger_than', label_id: 'bigger_than' },
- { value: 'bigger_or_equals', label_id: 'bigger_or_equals' },
- { value: 'smaller_than', label_id: 'smaller_than' },
- { value: 'smaller_or_equals', label_id: 'smaller_or_equals' },
-]
-
-export const getConditionTypeCompatators = (dataType) => {
- return [
- ...(dataType === 'options'
- ? [...OptionsCompatators]
- : dataType === 'date'
- ? [...DateCompatators]
- : dataType === 'boolean'
- ? [...BooleanCompatators]
- : dataType === 'number'
- ? [...NumberCampatators]
- : [...TextCompatators]),
- ];
-};
-
-export const getConditionDefaultCompatator = (dataType) => {
- const compatators = getConditionTypeCompatators(dataType);
- return compatators[0];
-};
diff --git a/client/src/components/FilterDropdown.js b/client/src/components/FilterDropdown2.js
similarity index 100%
rename from client/src/components/FilterDropdown.js
rename to client/src/components/FilterDropdown2.js
diff --git a/client/src/components/index.js b/client/src/components/index.js
index ae78a3382..b6aa9dd50 100644
--- a/client/src/components/index.js
+++ b/client/src/components/index.js
@@ -6,8 +6,8 @@ import For from './Utils/For';
import { FormattedMessage, FormattedHTMLMessage } from './FormattedMessage';
import ListSelect from './ListSelect';
import FinancialStatement from './FinancialStatement';
-import DynamicFilterValueField from './DynamicFilter/DynamicFilterValueField';
-import DynamicFilterCompatatorField from './DynamicFilter/DynamicFilterCompatatorField';
+// import DynamicFilterValueField from './DynamicFilter/DynamicFilterValueField';
+// import DynamicFilterCompatatorField from './DynamicFilter/DynamicFilterCompatatorField';
import ErrorMessage from './ErrorMessage';
import MODIFIER from './modifiers';
import FieldHint from './FieldHint';
@@ -78,8 +78,8 @@ export {
Money,
ListSelect,
FinancialStatement,
- DynamicFilterValueField,
- DynamicFilterCompatatorField,
+ // DynamicFilterValueField,
+ // DynamicFilterCompatatorField,
MODIFIER,
ErrorMessage,
FieldHint,
diff --git a/client/src/containers/Accounts/AccountsActionsBar.js b/client/src/containers/Accounts/AccountsActionsBar.js
index 944f872f6..8204c9436 100644
--- a/client/src/containers/Accounts/AccountsActionsBar.js
+++ b/client/src/containers/Accounts/AccountsActionsBar.js
@@ -19,7 +19,7 @@ import intl from 'react-intl-universal';
import { If, DashboardActionViewsList } from 'components';
import DashboardActionsBar from 'components/Dashboard/DashboardActionsBar';
-import FilterDropdown from 'components/FilterDropdown';
+import AdvancedFilterDropdown from 'components/AdvancedFilter/AdvancedFilterDropdown.tsx';
import { useRefreshAccounts } from 'hooks/query/accounts';
import { useAccountsChartContext } from 'containers/Accounts/AccountsChartProvider';
@@ -30,6 +30,46 @@ import withAccountsTableActions from './withAccountsTableActions';
import { compose } from 'utils';
+const FIELDS = [
+ {
+ name: 'Name',
+ key: 'name',
+ fieldType: 'text',
+ },
+ {
+ name: 'Account code',
+ key: 'code',
+ fieldType: 'text',
+ },
+ {
+ name: 'Balance',
+ key: 'balance',
+ fieldType: 'number'
+ },
+ {
+ name: 'Active',
+ key: 'active',
+ fieldType: 'boolean'
+ },
+ {
+ name: 'Created at',
+ key: 'created_at',
+ fieldType: 'date'
+ },
+ {
+ name: 'Root type',
+ key: 'root_type',
+ fieldType: 'enumeration',
+ options: [
+ { key: 'asset', label: 'Asset' },
+ { key: 'liability', label: 'Liability' },
+ { key: 'equity', label: 'Equity' },
+ { key: 'Income', label: 'Income' },
+ { key: 'expense', label: 'Expense' },
+ ],
+ }
+];
+
/**
* Accounts actions bar.
*/
@@ -110,7 +150,14 @@ function AccountsActionsBar({
/>
{
+ console.log(filterConditions, 'XXX');
+ }} />
+ }
interactionKind={PopoverInteractionKind.CLICK}
position={Position.BOTTOM_LEFT}
canOutsideClickClose={true}
diff --git a/client/src/containers/ExchangeRates/ExchangeRateActionsBar.js b/client/src/containers/ExchangeRates/ExchangeRateActionsBar.js
index c54d414be..23908651e 100644
--- a/client/src/containers/ExchangeRates/ExchangeRateActionsBar.js
+++ b/client/src/containers/ExchangeRates/ExchangeRateActionsBar.js
@@ -18,7 +18,6 @@ import { connect } from 'react-redux';
import { If } from 'components';
import DashboardActionsBar from 'components/Dashboard/DashboardActionsBar';
import Icon from 'components/Icon';
-import FilterDropdown from 'components/FilterDropdown';
import { useRefreshExchangeRate } from 'hooks/query/exchangeRates';
import withDialogActions from 'containers/Dialog/withDialogActions';