Skip to content

Commit

Permalink
feat: Property filter token groups (#2626)
Browse files Browse the repository at this point in the history
  • Loading branch information
pan-kot authored Sep 17, 2024
1 parent faf9a6d commit fdad04b
Show file tree
Hide file tree
Showing 17 changed files with 257 additions and 233 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
62 changes: 58 additions & 4 deletions src/__tests__/__snapshots__/documenter.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -12216,6 +12216,14 @@ in order to prevent the user from changing the filtering query.",
"optional": true,
"type": "boolean",
},
{
"defaultValue": "false",
"description": "Activates token grouping mechanism to support tokens nesting (up to one level).
When \`true\`, the \`query.tokens\` property is ignored and \`query.tokenGroups\` is used instead.",
"name": "enableTokenGroups",
"optional": true,
"type": "boolean",
},
{
"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 @@ -12341,6 +12349,7 @@ Use the \`onLoadItems\` event to perform a recovery action (for example, retryin
"type": "PropertyFilterProps.FreeTextFiltering",
},
{
"defaultValue": "false",
"description": "If hideOperations it set, the indicator of the operation (that is, \`and\` or \`or\`) and the selection of operations
(applied to the property and value token) are hidden from the user. Only use when you have a custom
filtering logic which combines tokens in different way than the default one. When used, ensure that
Expand Down Expand Up @@ -12410,6 +12419,11 @@ operations are communicated to the user in another way.",
"optional": true,
"type": "(token: PropertyFilterProps.FormattedToken) => string",
},
{
"name": "groupEditAriaLabel",
"optional": true,
"type": "(group: PropertyFilterProps.FormattedTokenGroup) => string",
},
{
"name": "groupPropertiesText",
"optional": true,
Expand Down Expand Up @@ -12500,6 +12514,46 @@ operations are communicated to the user in another way.",
"optional": true,
"type": "(token: PropertyFilterProps.FormattedToken) => string",
},
{
"name": "tokenEditorAddExistingTokenAriaLabel",
"optional": true,
"type": "(token: PropertyFilterProps.FormattedToken) => string",
},
{
"name": "tokenEditorAddExistingTokenLabel",
"optional": true,
"type": "(token: PropertyFilterProps.FormattedToken) => string",
},
{
"name": "tokenEditorAddNewTokenLabel",
"optional": true,
"type": "string",
},
{
"name": "tokenEditorAddTokenActionsAriaLabel",
"optional": true,
"type": "string",
},
{
"name": "tokenEditorTokenActionsAriaLabel",
"optional": true,
"type": "(token: PropertyFilterProps.FormattedToken) => string",
},
{
"name": "tokenEditorTokenRemoveAriaLabel",
"optional": true,
"type": "(token: PropertyFilterProps.FormattedToken) => string",
},
{
"name": "tokenEditorTokenRemoveFromGroupLabel",
"optional": true,
"type": "string",
},
{
"name": "tokenEditorTokenRemoveLabel",
"optional": true,
"type": "string",
},
{
"name": "tokenLimitShowFewer",
"optional": true,
Expand Down Expand Up @@ -12537,14 +12591,14 @@ use the \`id\` attribute, consider setting it on a parent element instead.",
"type": "string",
},
{
"description": "An object representing the current query displayed in the property filter. Has two properties: \`tokens\` and \`operation\`.
\`tokens\` is an array of objects that will be displayed to the user beneath the filtering input.
"description": "An object representing the current query displayed in the property filter. Has three properties: \`operation\`, \`tokens\`, and \`tokenGroups\`.
The \`operation\` property has two valid values: "and", "or", and controls the join operation to be applied between tokens when filtering the items.
The \`tokens\` property is an array of objects that will be displayed to the user beneath the filtering input. When \`enableTokenGroups=true\`, the
\`tokenGroups\` property is used instead, which supports nested tokens.
Each token has the following properties:
* value [string]: The string value of the token to be used as a filter.
* propertyKey [string]: The key of the corresponding property in filteringProperties.
* operator ['<' | '<=' | '>' | '>=' | ':' | '!:' | '=' | '!=' | '^' | '!^']: The operator which indicates how to filter the dataset using this token.

\`operation\` has two valid values [and, or] and controls the join operation to be applied between tokens when filtering the items.
",
"inlineType": {
"name": "PropertyFilterProps.Query",
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 @@ -51,9 +43,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 @@ -144,8 +134,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 @@ -280,7 +278,7 @@ describe('i18n', () => {
},
}}
>
<InternalPropertyFilter
<PropertyFilter
{...defaultProps}
i18nStrings={{}}
query={{
Expand All @@ -306,7 +304,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} i18nStrings={{}} i18nStringsTokenGroups={{}} />
<PropertyFilter {...defaultProps} {...props} i18nStrings={{}} />
</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 @@ -450,12 +446,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
Loading

0 comments on commit fdad04b

Please sign in to comment.