Skip to content

Commit

Permalink
feat: Property filter token groups
Browse files Browse the repository at this point in the history
  • Loading branch information
pan-kot committed Sep 9, 2024
1 parent 5324945 commit f3a4b50
Show file tree
Hide file tree
Showing 14 changed files with 173 additions and 216 deletions.
3 changes: 0 additions & 3 deletions pages/property-filter/common-props.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import { PropertyFilterProps } from '~components/property-filter';
import { I18nStringsTokenGroups } from '~components/property-filter/interfaces';

import {
DateForm,
Expand Down Expand Up @@ -184,9 +183,7 @@ export const i18nStrings: PropertyFilterProps.I18nStrings = {

formatToken,
removeTokenButtonAriaLabel: token => `Remove token, ${formatToken(token)}`,
};

export const i18nStringsTokenGroups: I18nStringsTokenGroups = {
groupEditAriaLabel: group => `Edit group with ${group.tokens.length} tokens`,
tokenEditorTokenActionsAriaLabel: token => `Filter remove actions for ${formatToken(token)}`,
tokenEditorTokenRemoveAriaLabel: token => `Remove filter, ${formatToken(token)}`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Button from '~components/button';
import Header from '~components/header';
import I18nProvider from '~components/i18n';
import messages from '~components/i18n/messages/all.en';
import PropertyFilter from '~components/property-filter/internal';
import PropertyFilter from '~components/property-filter';
import SplitPanel from '~components/split-panel';
import Table from '~components/table';

Expand Down
5 changes: 1 addition & 4 deletions pages/property-filter/token-editor.page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,12 @@ import React from 'react';

import PropertyFilter from '~components/property-filter';
import { PropertyFilterProps } from '~components/property-filter/interfaces';
import PropertyFilterInternal from '~components/property-filter/internal';

import ScreenshotArea from '../utils/screenshot-area';
import {
columnDefinitions,
filteringProperties as commonFilteringProperties,
i18nStrings,
i18nStringsTokenGroups,
labels,
} from './common-props';

Expand All @@ -28,7 +26,6 @@ const commonProps = {
filteringProperties,
filteringOptions: [],
i18nStrings,
i18nStringsTokenGroups,
countText: '5 matches',
disableFreeTextFiltering: false,
virtualScroll: true,
Expand Down Expand Up @@ -102,7 +99,7 @@ export default function () {
{...commonProps}
freeTextFiltering={{ operators: [':', '!:', '=', '!=', '^', '!^'] }}
/>
<PropertyFilterInternal
<PropertyFilter
className="property-filter-group-editor"
query={{
tokens: [
Expand Down
51 changes: 51 additions & 0 deletions src/__tests__/__snapshots__/documenter.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -12216,6 +12216,12 @@ in order to prevent the user from changing the filtering query.",
"optional": true,
"type": "boolean",
},
Object {
"defaultValue": "false",
"name": "enableTokenGroups",
"optional": true,
"type": "boolean",
},
Object {
"description": "By default, the dropdown height is constrained to fit inside the height of its next scrollable container element.
Enabling this property will allow the dropdown to extend beyond that container by using fixed positioning and
Expand Down Expand Up @@ -12410,6 +12416,11 @@ operations are communicated to the user in another way.",
"optional": true,
"type": "(token: PropertyFilterProps.FormattedToken) => string",
},
Object {
"name": "groupEditAriaLabel",
"optional": true,
"type": "(group: PropertyFilterProps.FormattedTokenGroup) => string",
},
Object {
"name": "groupPropertiesText",
"optional": true,
Expand Down Expand Up @@ -12500,6 +12511,46 @@ operations are communicated to the user in another way.",
"optional": true,
"type": "(token: PropertyFilterProps.FormattedToken) => string",
},
Object {
"name": "tokenEditorAddExistingTokenAriaLabel",
"optional": true,
"type": "(token: PropertyFilterProps.FormattedToken) => string",
},
Object {
"name": "tokenEditorAddExistingTokenLabel",
"optional": true,
"type": "(token: PropertyFilterProps.FormattedToken) => string",
},
Object {
"name": "tokenEditorAddNewTokenLabel",
"optional": true,
"type": "string",
},
Object {
"name": "tokenEditorAddTokenActionsAriaLabel",
"optional": true,
"type": "string",
},
Object {
"name": "tokenEditorTokenActionsAriaLabel",
"optional": true,
"type": "(token: PropertyFilterProps.FormattedToken) => string",
},
Object {
"name": "tokenEditorTokenRemoveAriaLabel",
"optional": true,
"type": "(token: PropertyFilterProps.FormattedToken) => string",
},
Object {
"name": "tokenEditorTokenRemoveFromGroupLabel",
"optional": true,
"type": "string",
},
Object {
"name": "tokenEditorTokenRemoveLabel",
"optional": true,
"type": "string",
},
Object {
"name": "tokenLimitShowFewer",
"optional": true,
Expand Down
17 changes: 1 addition & 16 deletions src/property-filter/__tests__/common.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,7 @@
import React, { useState } from 'react';

import PropertyFilter from '../../../lib/components/property-filter';
import PropertyFilterInternal, { PropertyFilterInternalProps } from '../../../lib/components/property-filter/internal';
import {
FilteringProperty,
I18nStrings,
I18nStringsTokenGroups,
InternalFilteringProperty,
PropertyFilterProps,
Token,
} from '../interfaces';
import { FilteringProperty, I18nStrings, InternalFilteringProperty, PropertyFilterProps, Token } from '../interfaces';

export const i18nStrings: I18nStrings = {
dismissAriaLabel: 'Dismiss',
Expand Down Expand Up @@ -50,9 +42,7 @@ export const i18nStrings: I18nStrings = {
formatToken: token => `${token.propertyLabel} ${formatOperator(token.operator)} ${token.value}`,
removeTokenButtonAriaLabel: (token: Token) =>
'Remove token ' + token.propertyKey + ' ' + formatOperator(token.operator) + ' ' + token.value,
};

export const i18nStringsTokenGroups: I18nStringsTokenGroups = {
groupEditAriaLabel: group =>
'Edit filter, ' +
group.tokens
Expand Down Expand Up @@ -137,8 +127,3 @@ export function StatefulPropertyFilter(props: Omit<PropertyFilterProps, 'onChang
const [query, setQuery] = useState<PropertyFilterProps.Query>(props.query);
return <PropertyFilter {...props} query={query} onChange={e => setQuery(e.detail)} />;
}

export function StatefulInternalPropertyFilter(props: Omit<PropertyFilterInternalProps, 'onChange'>) {
const [query, setQuery] = useState<PropertyFilterInternalProps['query']>(props.query);
return <PropertyFilterInternal {...props} query={query} onChange={e => setQuery(e.detail)} />;
}
6 changes: 2 additions & 4 deletions src/property-filter/__tests__/property-filter-i18n.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@ import { act, render } from '@testing-library/react';

import TestI18nProvider from '../../../lib/components/i18n/testing';
import PropertyFilter from '../../../lib/components/property-filter';
import InternalPropertyFilter from '../../../lib/components/property-filter/internal';
import createWrapper, { ElementWrapper, PropertyFilterWrapper } from '../../../lib/components/test-utils/dom';
import { PropertyFilterWrapperInternal } from '../../../lib/components/test-utils/dom/property-filter/index.js';
import { createDefaultProps } from './common';

import styles from '../../../lib/components/property-filter/styles.selectors.js';
Expand Down Expand Up @@ -274,7 +272,7 @@ describe('i18n', () => {
},
}}
>
<InternalPropertyFilter
<PropertyFilter
{...defaultProps}
i18nStrings={{}}
query={{
Expand All @@ -300,7 +298,7 @@ describe('i18n', () => {
/>
</TestI18nProvider>
);
const wrapper = new PropertyFilterWrapperInternal(createWrapper(container).findPropertyFilter()!.getElement());
const wrapper = createWrapper(container).findPropertyFilter()!;
const token = (index: number) => wrapper.findTokens()[index];
const groupToken = (index: number, inGroupIndex: number) => token(index).findGroupTokens()[inGroupIndex];

Expand Down
36 changes: 16 additions & 20 deletions src/property-filter/__tests__/property-filter-token-editor.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,14 @@ import { act, fireEvent, render as reactRender } from '@testing-library/react';

import TestI18nProvider from '../../../lib/components/i18n/testing';
import { useMobile } from '../../../lib/components/internal/hooks/use-mobile';
import { FilteringOption, FilteringProperty } from '../../../lib/components/property-filter/interfaces';
import PropertyFilterInternal, { PropertyFilterInternalProps } from '../../../lib/components/property-filter/internal';
import createWrapper from '../../../lib/components/test-utils/dom';
import { PropertyFilterWrapperInternal } from '../../../lib/components/test-utils/dom/property-filter';
import PropertyFilter from '../../../lib/components/property-filter';
import {
createDefaultProps,
i18nStrings,
i18nStringsTokenGroups,
providedI18nStrings,
StatefulInternalPropertyFilter,
} from './common';
FilteringOption,
FilteringProperty,
PropertyFilterProps,
} from '../../../lib/components/property-filter/interfaces';
import createWrapper from '../../../lib/components/test-utils/dom';
import { createDefaultProps, i18nStrings, providedI18nStrings, StatefulPropertyFilter } from './common';

jest.mock('../../../lib/components/internal/hooks/use-mobile', () => ({
...jest.requireActual('../../../lib/components/internal/hooks/use-mobile'),
Expand Down Expand Up @@ -71,26 +68,25 @@ const filteringOptions: readonly FilteringOption[] = [
{ propertyKey: 'default-operator', value: 'value' },
];

const defaultProps: PropertyFilterInternalProps = {
const defaultProps: PropertyFilterProps = {
filteringOptions: [],
customGroupsText: [],
disableFreeTextFiltering: false,
i18nStringsTokenGroups,
...createDefaultProps(filteringProperties, filteringOptions),
};

function renderComponent(props?: Partial<PropertyFilterInternalProps>, withI18nProvider = false) {
function renderComponent(props?: Partial<PropertyFilterProps>, withI18nProvider = false) {
return withI18nProvider
? reactRender(
<TestI18nProvider messages={providedI18nStrings}>
<PropertyFilterInternal {...defaultProps} {...props} />
<PropertyFilter {...defaultProps} {...props} />
</TestI18nProvider>
)
: reactRender(<PropertyFilterInternal {...defaultProps} {...props} />);
: reactRender(<PropertyFilter {...defaultProps} {...props} />);
}

function openEditor(tokenIndex: number, options: { expandToViewport?: boolean; isMobile?: boolean }) {
const propertyFilter = new PropertyFilterWrapperInternal(createWrapper().findPropertyFilter()!.getElement());
const propertyFilter = createWrapper().findPropertyFilter()!;
const token = propertyFilter.findTokens()[tokenIndex];
if (token.findEditButton()) {
token.findEditButton()!.click();
Expand All @@ -104,7 +100,7 @@ function findEditor(
tokenIndex: number,
{ expandToViewport = false, isMobile = false }: { expandToViewport?: boolean; isMobile?: boolean }
) {
const propertyFilter = new PropertyFilterWrapperInternal(createWrapper().findPropertyFilter()!.getElement());
const propertyFilter = createWrapper().findPropertyFilter()!;
const editor = propertyFilter.findTokens()[tokenIndex].findEditorDropdown({ expandToViewport })!;
return editor
? {
Expand Down Expand Up @@ -436,12 +432,12 @@ describe('token editor with groups', () => {
jest.mocked(useMobile).mockReturnValue(false);
});

function render(props: Partial<PropertyFilterInternalProps>) {
function render(props: Partial<PropertyFilterProps>) {
return renderComponent({ enableTokenGroups: true, ...props });
}

function renderStateful(props?: Partial<PropertyFilterInternalProps>) {
return reactRender(<StatefulInternalPropertyFilter {...defaultProps} {...props} enableTokenGroups={true} />);
function renderStateful(props?: Partial<PropertyFilterProps>) {
return reactRender(<StatefulPropertyFilter {...defaultProps} {...props} enableTokenGroups={true} />);
}

test('changes filter property', () => {
Expand Down
50 changes: 11 additions & 39 deletions src/property-filter/__tests__/property-filter-token-list.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,8 @@ import { act, render } from '@testing-library/react';

import PropertyFilter from '../../../lib/components/property-filter';
import { PropertyFilterProps, Ref } from '../../../lib/components/property-filter/interfaces';
import PropertyFilterInternal, { PropertyFilterInternalProps } from '../../../lib/components/property-filter/internal';
import createWrapper, { PropertyFilterWrapper } from '../../../lib/components/test-utils/dom';
import { PropertyFilterWrapperInternal } from '../../../lib/components/test-utils/dom/property-filter';
import {
createDefaultProps,
i18nStrings,
i18nStringsTokenGroups,
StatefulInternalPropertyFilter,
StatefulPropertyFilter,
} from './common';
import { createDefaultProps, i18nStrings, StatefulPropertyFilter } from './common';

const defaultProps = createDefaultProps(
[
Expand Down Expand Up @@ -51,34 +43,14 @@ const renderStatefulComponent = (props?: Partial<PropertyFilterProps>) => {
return { container, propertyFilterWrapper: createWrapper(container).findPropertyFilter()! };
};

function renderInternalComponent(props: Partial<PropertyFilterInternalProps>) {
const { container } = render(
<PropertyFilterInternal
{...defaultProps}
enableTokenGroups={true}
i18nStringsTokenGroups={i18nStringsTokenGroups}
filteringOptions={[]}
customGroupsText={[]}
disableFreeTextFiltering={false}
{...props}
/>
);
return new PropertyFilterWrapperInternal(container);
function renderWithGroups(props: Partial<PropertyFilterProps>) {
const { container } = render(<PropertyFilter {...defaultProps} enableTokenGroups={true} {...props} />);
return createWrapper(container).findPropertyFilter()!;
}

const renderStatefulInternalComponent = (props?: Partial<PropertyFilterInternalProps>) => {
const { container } = render(
<StatefulInternalPropertyFilter
{...defaultProps}
enableTokenGroups={true}
i18nStringsTokenGroups={i18nStringsTokenGroups}
filteringOptions={[]}
customGroupsText={[]}
disableFreeTextFiltering={false}
{...props}
/>
);
return new PropertyFilterWrapperInternal(container);
const renderWithGroupsStateful = (props?: Partial<PropertyFilterProps>) => {
const { container } = render(<StatefulPropertyFilter {...defaultProps} enableTokenGroups={true} {...props} />);
return createWrapper(container).findPropertyFilter()!;
};

describe('filtering tokens', () => {
Expand Down Expand Up @@ -213,7 +185,7 @@ describe('filtering tokens', () => {
});

test('moves focus to the adjacent grouped token and to the single remaining token', () => {
const wrapper = renderStatefulInternalComponent({
const wrapper = renderWithGroupsStateful({
query: {
operation: 'and',
tokenGroups: [
Expand Down Expand Up @@ -372,7 +344,7 @@ describe('grouped token', () => {
const tokenJack = { propertyKey: 'string', operator: '=', value: 'Jack' };

test('token group has correct ARIA label and edit button ARIA label', () => {
const wrapper = renderInternalComponent({
const wrapper = renderWithGroups({
query: { operation: 'and', tokenGroups: [{ operation: 'or', tokens: [tokenJohn, tokenJane] }], tokens: [] },
});

Expand All @@ -384,7 +356,7 @@ describe('grouped token', () => {

test('changes group operation', () => {
const onChange = jest.fn();
const wrapper = renderInternalComponent({
const wrapper = renderWithGroups({
query: { operation: 'and', tokenGroups: [{ operation: 'and', tokens: [tokenJohn, tokenJane] }], tokens: [] },
onChange,
});
Expand All @@ -406,7 +378,7 @@ describe('grouped token', () => {

test('removes token from group', () => {
const onChange = jest.fn();
const wrapper = renderInternalComponent({
const wrapper = renderWithGroups({
query: {
operation: 'and',
tokenGroups: [{ operation: 'and', tokens: [tokenJohn, tokenJane, tokenJack] }],
Expand Down
Loading

0 comments on commit f3a4b50

Please sign in to comment.