Skip to content

Commit

Permalink
AutoComplete clean-up (#2349)
Browse files Browse the repository at this point in the history
* AutoComplete clean-up

* notes

* lint fix

* fix tests

* review fix

* type
  • Loading branch information
carkom authored Feb 21, 2024
1 parent 0d1e6f2 commit 0609f47
Show file tree
Hide file tree
Showing 9 changed files with 95 additions and 146 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { type CSSProperties, theme } from '../../style';
import { View } from '../common/View';

import { Autocomplete } from './Autocomplete';
import { ItemHeader, type ItemHeaderProps } from './ItemHeader';

function AccountList({
items,
Expand Down Expand Up @@ -71,9 +72,7 @@ function AccountList({
type AccountAutoCompleteProps = {
embedded?: boolean;
includeClosedAccounts: boolean;
renderAccountItemGroupHeader?: (
props: AccountItemGroupHeaderProps,
) => ReactNode;
renderAccountItemGroupHeader?: (props: ItemHeaderProps) => ReactNode;
renderAccountItem?: (props: AccountItemProps) => ReactNode;
closeOnBlur?: boolean;
} & ComponentProps<typeof Autocomplete>;
Expand Down Expand Up @@ -124,35 +123,10 @@ export function AccountAutocomplete({
);
}

type AccountItemGroupHeaderProps = {
title: string;
style?: CSSProperties;
};

export function AccountItemGroupHeader({
title,
style,
...props
}: AccountItemGroupHeaderProps) {
return (
<div
style={{
color: theme.menuAutoCompleteTextHeader,
padding: '4px 9px',
...style,
}}
data-testid={`${title}-account-item-group`}
{...props}
>
{title}
</div>
);
}

function defaultRenderAccountItemGroupHeader(
props: AccountItemGroupHeaderProps,
props: ItemHeaderProps,
): ReactNode {
return <AccountItemGroupHeader {...props} />;
return <ItemHeader {...props} type="account" />;
}

type AccountItemProps = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { Text } from '../common/Text';
import { View } from '../common/View';

import { Autocomplete, defaultFilterSuggestion } from './Autocomplete';
import { ItemHeader, type ItemHeaderProps } from './ItemHeader';

export type CategoryListProps = {
items: Array<CategoryEntity & { group?: CategoryGroupEntity }>;
Expand All @@ -33,9 +34,7 @@ export type CategoryListProps = {
renderSplitTransactionButton?: (
props: SplitTransactionButtonProps,
) => ReactNode;
renderCategoryItemGroupHeader?: (
props: CategoryItemGroupHeaderProps,
) => ReactNode;
renderCategoryItemGroupHeader?: (props: ItemHeaderProps) => ReactNode;
renderCategoryItem?: (props: CategoryItemProps) => ReactNode;
};
function CategoryList({
Expand Down Expand Up @@ -103,9 +102,7 @@ type CategoryAutocompleteProps = ComponentProps<typeof Autocomplete> & {
renderSplitTransactionButton?: (
props: SplitTransactionButtonProps,
) => ReactNode;
renderCategoryItemGroupHeader?: (
props: CategoryItemGroupHeaderProps,
) => ReactNode;
renderCategoryItemGroupHeader?: (props: ItemHeaderProps) => ReactNode;
renderCategoryItem?: (props: CategoryItemProps) => ReactNode;
};

Expand Down Expand Up @@ -177,35 +174,8 @@ export function CategoryAutocomplete({
);
}

type CategoryItemGroupHeaderProps = {
title: string;
style?: CSSProperties;
};

export function CategoryItemGroupHeader({
title,
style,
...props
}: CategoryItemGroupHeaderProps) {
return (
<div
style={{
color: theme.menuAutoCompleteTextHeader,
padding: '4px 9px',
...style,
}}
data-testid={`${title}-category-item-group`}
{...props}
>
{title}
</div>
);
}

function defaultRenderCategoryItemGroupHeader(
props: CategoryItemGroupHeaderProps,
) {
return <CategoryItemGroupHeader {...props} />;
function defaultRenderCategoryItemGroupHeader(props: ItemHeaderProps) {
return <ItemHeader {...props} type="category" />;
}

type SplitTransactionButtonProps = {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React, { type ComponentProps } from 'react';

import { useFilters } from 'loot-core/src/client/data-hooks/filters';
import { type TransactionFilterEntity } from 'loot-core/types/models/transaction-filter';

import { Autocomplete } from './Autocomplete';
import { FilterList } from './FilterList';

export function FilterAutocomplete({
embedded,
...props
}: {
embedded?: boolean;
} & ComponentProps<typeof Autocomplete<TransactionFilterEntity>>) {
const filters = useFilters() || [];

return (
<Autocomplete
strict={true}
highlightFirst={true}
embedded={embedded}
suggestions={filters}
renderItems={(items, getItemProps, highlightedIndex) => (
<FilterList
items={items}
getItemProps={getItemProps}
highlightedIndex={highlightedIndex}
embedded={embedded}
/>
)}
{...props}
/>
);
}
Original file line number Diff line number Diff line change
@@ -1,26 +1,21 @@
import React, { type ComponentProps } from 'react';

import { useFilters } from 'loot-core/src/client/data-hooks/filters';
import { type TransactionFilterEntity } from 'loot-core/src/types/models';

import { theme } from '../../style';
import { theme } from '../../style/theme';
import { View } from '../common/View';

import { Autocomplete } from './Autocomplete';
import { ItemHeader } from './ItemHeader';

type FilterListProps<T> = {
items: T[];
getItemProps: (arg: { item: T }) => ComponentProps<typeof View>;
highlightedIndex: number;
embedded?: boolean;
};

function FilterList<T extends { id: string; name: string }>({
export function FilterList<T extends { id: string; name: string }>({
items,
getItemProps,
highlightedIndex,
embedded,
}: FilterListProps<T>) {
}: {
items: T[];
getItemProps: (arg: { item: T }) => ComponentProps<typeof View>;
highlightedIndex: number;
embedded?: boolean;
}) {
return (
<View>
<View
Expand All @@ -30,6 +25,7 @@ function FilterList<T extends { id: string; name: string }>({
...(!embedded && { maxHeight: 175 }),
}}
>
<ItemHeader title="Saved Filters" type="filter" />
{items.map((item, idx) => {
return [
<div
Expand All @@ -55,32 +51,3 @@ function FilterList<T extends { id: string; name: string }>({
</View>
);
}

type SavedFilterAutocompleteProps = {
embedded?: boolean;
} & ComponentProps<typeof Autocomplete<TransactionFilterEntity>>;

export function SavedFilterAutocomplete({
embedded,
...props
}: SavedFilterAutocompleteProps) {
const filters = useFilters() || [];

return (
<Autocomplete
strict={true}
highlightFirst={true}
embedded={embedded}
suggestions={filters}
renderItems={(items, getItemProps, highlightedIndex) => (
<FilterList
items={items}
getItemProps={getItemProps}
highlightedIndex={highlightedIndex}
embedded={embedded}
/>
)}
{...props}
/>
);
}
26 changes: 26 additions & 0 deletions packages/desktop-client/src/components/autocomplete/ItemHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from 'react';

import { theme } from '../../style/theme';
import { type CSSProperties } from '../../style/types';

export type ItemHeaderProps = {
title: string;
style?: CSSProperties;
type?: string;
};

export function ItemHeader({ title, style, type, ...props }: ItemHeaderProps) {
return (
<div
style={{
color: theme.menuAutoCompleteTextHeader,
padding: '4px 9px',
...style,
}}
data-testid={`${title}-${type}-item-group`}
{...props}
>
{title}
</div>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
defaultFilterSuggestion,
AutocompleteFooter,
} from './Autocomplete';
import { ItemHeader, type ItemHeaderProps } from './ItemHeader';

function getPayeeSuggestions(payees, focusTransferPayees, accounts) {
let activePayees = accounts ? getActivePayees(payees, accounts) : payees;
Expand Down Expand Up @@ -163,7 +164,7 @@ type PayeeAutocompleteProps = {
onSelect?: (value: string) => void;
onManagePayees: () => void;
renderCreatePayeeButton?: (props: CreatePayeeButtonProps) => ReactNode;
renderPayeeItemGroupHeader?: (props: PayeeItemGroupHeaderProps) => ReactNode;
renderPayeeItemGroupHeader?: (props: ItemHeaderProps) => ReactNode;
renderPayeeItem?: (props: PayeeItemProps) => ReactNode;
accounts?: AccountEntity[];
payees?: PayeeEntity[];
Expand Down Expand Up @@ -422,35 +423,8 @@ function defaultRenderCreatePayeeButton(
return <CreatePayeeButton {...props} />;
}

type PayeeItemGroupHeaderProps = {
title: string;
style?: CSSProperties;
};

export function PayeeItemGroupHeader({
title,
style,
...props
}: PayeeItemGroupHeaderProps) {
return (
<div
style={{
color: theme.menuAutoCompleteTextHeader,
padding: '4px 9px',
...style,
}}
data-testid={`${title}-payee-item-group`}
{...props}
>
{title}
</div>
);
}

function defaultRenderPayeeItemGroupHeader(
props: PayeeItemGroupHeaderProps,
): ReactNode {
return <PayeeItemGroupHeader {...props} />;
function defaultRenderPayeeItemGroupHeader(props: ItemHeaderProps): ReactNode {
return <ItemHeader {...props} type="payee" />;
}

type PayeeItemProps = {
Expand Down
10 changes: 4 additions & 6 deletions packages/desktop-client/src/components/modals/EditField.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,16 @@ import { useResponsive } from '../../ResponsiveProvider';
import { styles, theme } from '../../style';
import {
AccountAutocomplete,
AccountItemGroupHeader,
AccountItem,
} from '../autocomplete/AccountAutocomplete';
import {
CategoryAutocomplete,
CategoryItemGroupHeader,
CategoryItem,
} from '../autocomplete/CategoryAutocomplete';
import { ItemHeader } from '../autocomplete/ItemHeader';
import {
PayeeAutocomplete,
CreatePayeeButton,
PayeeItemGroupHeader,
PayeeItem,
} from '../autocomplete/PayeeAutocomplete';
import { Input } from '../common/Input';
Expand Down Expand Up @@ -118,7 +116,7 @@ export function EditField({ modalProps, name, onSubmit, onClose }) {
}}
{...(isNarrowWidth && {
renderAccountItemGroupHeader: props => (
<AccountItemGroupHeader
<ItemHeader
{...props}
style={{
...styles.largeText,
Expand Down Expand Up @@ -174,7 +172,7 @@ export function EditField({ modalProps, name, onSubmit, onClose }) {
/>
),
renderPayeeItemGroupHeader: props => (
<PayeeItemGroupHeader
<ItemHeader
{...props}
style={{
...styles.largeText,
Expand Down Expand Up @@ -228,7 +226,7 @@ export function EditField({ modalProps, name, onSubmit, onClose }) {
}}
{...(isNarrowWidth && {
renderCategoryItemGroupHeader: props => (
<CategoryItemGroupHeader
<ItemHeader
{...props}
style={{
...styles.largeText,
Expand Down
4 changes: 2 additions & 2 deletions packages/desktop-client/src/components/util/GenericInput.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import { useDateFormat } from '../../hooks/useDateFormat';
import { AccountAutocomplete } from '../autocomplete/AccountAutocomplete';
import { Autocomplete } from '../autocomplete/Autocomplete';
import { CategoryAutocomplete } from '../autocomplete/CategoryAutocomplete';
import { FilterAutocomplete } from '../autocomplete/FilterAutocomplete';
import { PayeeAutocomplete } from '../autocomplete/PayeeAutocomplete';
import { SavedFilterAutocomplete } from '../autocomplete/SavedFilterAutocomplete';
import { Input } from '../common/Input';
import { View } from '../common/View';
import { Checkbox } from '../forms';
Expand Down Expand Up @@ -98,7 +98,7 @@ export function GenericInput({
switch (field) {
case 'saved':
content = (
<SavedFilterAutocomplete
<FilterAutocomplete
saved={saved}
value={value}
multi={multi}
Expand Down
6 changes: 6 additions & 0 deletions upcoming-release-notes/2349.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
category: Maintenance
authors: [carkom]
---

Organizing and splitting filters Autocomplete. Splitting out headers function that was duplicated in all autocomplete elements.

0 comments on commit 0609f47

Please sign in to comment.