Skip to content

Commit

Permalink
Use antd select
Browse files Browse the repository at this point in the history
  • Loading branch information
kgabryje committed Apr 21, 2024
1 parent cf21aef commit d110cd2
Show file tree
Hide file tree
Showing 10 changed files with 74 additions and 292 deletions.
115 changes: 19 additions & 96 deletions superset-frontend/src/components/Select/AsyncSelect.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -151,99 +151,37 @@ const USERS = [
'Claire',
'Benedetta',
'Ilenia',
]
.sort()
.map(u => ({ label: u, value: u }));

const GROUPED_USERS = [
{
label: 'Male',
title: 'Male',
options: [
'John',
'Liam',
'Noah',
'Oliver',
'Elijah',
'Diego',
'Evan',
'Michael',
'Giovanni',
'Luca',
'Paolo',
'Mario',
'Marco',
'Luigi',
'Quarto',
'Quinto',
'Sesto',
'Franco',
'Sandro',
'Alehandro',
'Johnny',
'Igor',
'Thami',
'Munei',
'Guilherme',
'Umair',
'Ashfaq',
'Irfan',
'George',
'Naseer',
'Mohammad',
'Rick',
],
},
{
label: 'Female',
title: 'Female',
options: [
'Olivia',
'Emma',
'Ava',
'Charlotte',
'Francesca',
'Chiara',
'Sara',
'Valentina',
'Jessica',
'Angelica',
'Nikole',
'Amna',
'Saliya',
'Claire',
'Benedetta',
'Ilenia',
],
},
].map(group => ({
...group,
options: group.options.sort().map(u => ({ label: u, value: u })),
}));

type AsyncSelectStoryProps = AsyncSelectProps & {
withError: boolean;
withInitialValue: boolean;
responseTime: number;
data: { label: string; value: string }[];
};
].sort();

export const AsynchronousSelect = ({
fetchOnlyOnSearch,
withError,
withInitialValue,
responseTime,
data,
...rest
}: AsyncSelectStoryProps) => {
}: AsyncSelectProps & {
withError: boolean;
withInitialValue: boolean;
responseTime: number;
}) => {
const [requests, setRequests] = useState<ReactNode[]>([]);
const ref = useRef<AsyncSelectRef>(null);

const getResults = (username?: string) => {
let results = [...data];
let results: { label: string; value: string }[] = [];

if (username) {
results = data.filter(u => u.value.toLowerCase().includes(username));
if (!username) {
results = USERS.map(u => ({
label: u,
value: u,
}));
} else {
const foundUsers = USERS.filter(u => u.toLowerCase().includes(username));
if (foundUsers) {
results = foundUsers.map(u => ({ label: u, value: u }));
} else {
results = [];
}
}
return results;
};
Expand Down Expand Up @@ -352,7 +290,6 @@ AsynchronousSelect.args = {
withError: false,
withInitialValue: false,
tokenSeparators: ['\n', '\t', ';'],
data: USERS,
};

AsynchronousSelect.argTypes = {
Expand Down Expand Up @@ -387,17 +324,3 @@ AsynchronousSelect.argTypes = {
},
},
};

export const AsyncSelectWithGroups = (props: AsyncSelectStoryProps) => (
<AsynchronousSelect {...props} />
);

AsyncSelectWithGroups.args = {
allowClear: true,
allowNewOptions: true,
mode: 'multiple',
pageSize: 5,
tokenSeparators: ['\n', '\t', ';'],
data: GROUPED_USERS,
};
AsyncSelectWithGroups.argTypes = AsynchronousSelect.argTypes;
68 changes: 11 additions & 57 deletions superset-frontend/src/components/Select/AsyncSelect.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import {
} from 'spec/helpers/testing-library';
import userEvent from '@testing-library/user-event';
import { AsyncSelect } from 'src/components';
import { OptionData, OptionGroup } from './types';

const ARIA_LABEL = 'Test';
const NEW_OPTION = 'Kyle';
Expand Down Expand Up @@ -63,31 +62,24 @@ const NULL_OPTION = { label: '<NULL>', value: null } as unknown as {
value: number;
};

const loadOptions = async (
search: string,
page: number,
pageSize: number,
options: OptionData | OptionGroup[] = OPTIONS,
) => {
const totalCount = options.length;
const loadOptions = async (search: string, page: number, pageSize: number) => {
const totalCount = OPTIONS.length;
const start = page * pageSize;
const deleteCount =
start + pageSize < totalCount ? pageSize : totalCount - start;
const searchValue = search.trim().toLowerCase();
const optionFilterProps = ['label', 'value', 'gender'];
const data = options
.filter((option: (typeof OPTIONS)[0]) =>
optionFilterProps.some(prop => {
const optionProp = option?.[prop]
? String(option[prop]).trim().toLowerCase()
: '';
return optionProp.includes(searchValue);
}),
)
.splice(start, deleteCount);
const data = OPTIONS.filter(option =>
optionFilterProps.some(prop => {
const optionProp = option?.[prop]
? String(option[prop]).trim().toLowerCase()
: '';
return optionProp.includes(searchValue);
}),
).splice(start, deleteCount);
return {
data,
totalCount: options.length,
totalCount: OPTIONS.length,
};
};

Expand Down Expand Up @@ -1009,44 +1001,6 @@ test('does not fire onChange if the same value is selected in single mode', asyn
expect(onChange).toHaveBeenCalledTimes(1);
});

test('correctly renders options group', async () => {
const groupedOptions = Object.values(
OPTIONS.slice(0, 10).reduce((acc, opt) => {
if (Array.isArray(acc[opt.gender]?.options)) {
acc[opt.gender].options.push(opt);
} else {
acc[opt.gender] = {
options: [opt],
title: opt.gender,
label: opt.gender,
};
}
return acc;
}, {}),
) as OptionGroup[];

render(
<AsyncSelect
{...defaultProps}
options={(search, page, pageSize) =>
loadOptions(search, page, pageSize, groupedOptions)
}
/>,
);
await open();

expect(
getElementsByClassName('.ant-select-item-option-grouped'),
).toHaveLength(10);
expect(getElementsByClassName('.ant-select-item-group')).toHaveLength(2);
expect(getElementsByClassName('.ant-select-item-group')[0]).toHaveTextContent(
'Female',
);
expect(getElementsByClassName('.ant-select-item-group')[1]).toHaveTextContent(
'Male',
);
});

/*
TODO: Add tests that require scroll interaction. Needs further investigation.
- Fetches more data when scrolling and more data is available
Expand Down
15 changes: 1 addition & 14 deletions superset-frontend/src/components/Select/AsyncSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ import {
getOption,
isObject,
isEqual as utilsIsEqual,
isOptGroup,
} from './utils';
import {
AsyncSelectProps,
Expand Down Expand Up @@ -225,17 +224,6 @@ const AsyncSelect = forwardRef(
: selectOptions;
}, [selectOptions, selectValue]);

const flattenedOptions = useMemo(
() =>
fullSelectOptions.reduce((acc, option) => {
if (isOptGroup(option)) {
return [...acc, ...option.options];
}
return [...acc, option];
}, []),
[fullSelectOptions],
);

const handleOnSelect: SelectProps['onSelect'] = (selectedItem, option) => {
if (isSingleMode) {
// on select is fired in single value mode if the same value is selected
Expand Down Expand Up @@ -342,7 +330,6 @@ const AsyncSelect = forwardRef(
const fetchOptions = options as SelectOptionsPagePromise;
fetchOptions(search, page, pageSize)
.then(({ data, totalCount }: SelectOptionsTypePage) => {
console.log(data);
const mergedData = mergeData(data);
fetchedQueries.current.set(key, totalCount);
setTotalCount(totalCount);
Expand Down Expand Up @@ -461,7 +448,7 @@ const AsyncSelect = forwardRef(
originNode,
isDropdownVisible,
isLoading,
flattenedOptions.length,
fullSelectOptions.length,
helperText,
error ? <Error error={error} /> : undefined,
);
Expand Down
38 changes: 0 additions & 38 deletions superset-frontend/src/components/Select/Select.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,30 +55,6 @@ const options: SelectOptionsType = [
{ label: 'I', value: 'I' },
];

const groupedOptions = [
{
title: 'Group 1',
label: <b>Group 1</b>,
options: [
{ label: 'A', value: 'A' },
{ label: 'B', value: 'B' },
{ label: 'C', value: 'C' },
{ label: 'D', value: 'D' },
],
},
{
title: 'Group 2',
label: <i>Group 2</i>,
options: [
{ label: 'E', value: 'E' },
{ label: 'F', value: 'F' },
{ label: 'G', value: 'G' },
{ label: 'H', value: 'H' },
{ label: 'I', value: 'I' },
],
},
];

const selectPositions = [
{
id: 'topLeft',
Expand Down Expand Up @@ -269,20 +245,6 @@ export const InteractiveSelect: StoryObj = {
},
};

export const InteractiveSelectWithGroups: StoryObj = {
render: ({ header, ...args }: SelectProps & { header: string }) => (
<div
style={{
width: DEFAULT_WIDTH,
}}
>
<Select {...args} header={mountHeader(header)} />
</div>
),
args: { ...InteractiveSelect.args, options: groupedOptions },
argTypes: InteractiveSelect.argTypes,
};

export const AtEveryCorner = () => (
<>
{selectPositions.map(position => (
Expand Down
32 changes: 0 additions & 32 deletions superset-frontend/src/components/Select/Select.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import {
import userEvent from '@testing-library/user-event';
import Select from 'src/components/Select/Select';
import { SELECT_ALL_VALUE } from './utils';
import { SelectOptionsType } from './types';

type Option = {
label: string;
Expand Down Expand Up @@ -1080,37 +1079,6 @@ test('does not fire onChange if the same value is selected in single mode', asyn
expect(onChange).toHaveBeenCalledTimes(1);
});

test('correctly renders options group', async () => {
const groupedOptions = Object.values(
OPTIONS.slice(0, 10).reduce((acc, opt) => {
if (Array.isArray(acc[opt.gender]?.options)) {
acc[opt.gender].options.push(opt);
} else {
acc[opt.gender] = {
options: [opt],
title: opt.gender,
label: opt.gender,
};
}
return acc;
}, {}),
) as SelectOptionsType;

render(<Select {...defaultProps} options={groupedOptions} />);
await open();

expect(
getElementsByClassName('.ant-select-item-option-grouped'),
).toHaveLength(10);
expect(getElementsByClassName('.ant-select-item-group')).toHaveLength(2);
expect(getElementsByClassName('.ant-select-item-group')[0]).toHaveTextContent(
'Male',
);
expect(getElementsByClassName('.ant-select-item-group')[1]).toHaveTextContent(
'Female',
);
});

/*
TODO: Add tests that require scroll interaction. Needs further investigation.
- Fetches more data when scrolling and more data is available
Expand Down
Loading

0 comments on commit d110cd2

Please sign in to comment.