Skip to content

Commit

Permalink
feat: Adds support for clearing the Select cache (#20397)
Browse files Browse the repository at this point in the history
* feat: Adds support for clearing the Select cache

* Fixes lint errors
  • Loading branch information
michael-s-molina committed Jun 21, 2022
1 parent 44c5e28 commit ca526e6
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 7 deletions.
25 changes: 23 additions & 2 deletions superset-frontend/src/components/Select/Select.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,15 @@
* specific language governing permissions and limitations
* under the License.
*/
import React, { ReactNode, useState, useCallback } from 'react';
import React, { ReactNode, useState, useCallback, useRef } from 'react';
import Button from 'src/components/Button';
import ControlHeader from 'src/explore/components/ControlHeader';
import Select, { SelectProps, OptionsTypePage, OptionsType } from './Select';
import Select, {
SelectProps,
OptionsTypePage,
OptionsType,
SelectRef,
} from './Select';

export default {
title: 'Select',
Expand Down Expand Up @@ -387,6 +393,7 @@ export const AsyncSelect = ({
responseTime: number;
}) => {
const [requests, setRequests] = useState<ReactNode[]>([]);
const ref = useRef<SelectRef>(null);

const getResults = (username?: string) => {
let results: { label: string; value: string }[] = [];
Expand Down Expand Up @@ -458,6 +465,7 @@ export const AsyncSelect = ({
>
<Select
{...rest}
ref={ref}
fetchOnlyOnSearch={fetchOnlyOnSearch}
options={withError ? fetchUserListError : fetchUserListPage}
placeholder={fetchOnlyOnSearch ? 'Type anything' : 'Select...'}
Expand All @@ -484,6 +492,19 @@ export const AsyncSelect = ({
<p key={`request-${index}`}>{request}</p>
))}
</div>
<Button
style={{
position: 'absolute',
top: 452,
left: DEFAULT_WIDTH + 580,
}}
onClick={() => {
ref.current?.clearCache();
setRequests([]);
}}
>
Clear cache
</Button>
</>
);
};
Expand Down
18 changes: 17 additions & 1 deletion superset-frontend/src/components/Select/Select.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@
* specific language governing permissions and limitations
* under the License.
*/
import React from 'react';
import React, { RefObject } from 'react';
import { render, screen, waitFor, within } from 'spec/helpers/testing-library';
import userEvent from '@testing-library/user-event';
import { Select } from 'src/components';
import { SelectRef } from './Select';

const ARIA_LABEL = 'Test';
const NEW_OPTION = 'Kyle';
Expand Down Expand Up @@ -813,6 +814,21 @@ test('async - fires a new request if all values have not been fetched', async ()
expect(mock).toHaveBeenCalledTimes(2);
});

test('async - requests the options again after clearing the cache', async () => {
const ref: RefObject<SelectRef> = { current: null };
const mock = jest.fn(loadOptions);
const pageSize = OPTIONS.length;
render(
<Select {...defaultProps} options={mock} pageSize={pageSize} ref={ref} />,
);
await open();
expect(mock).toHaveBeenCalledTimes(1);
ref.current?.clearCache();
await type('{esc}');
await open();
expect(mock).toHaveBeenCalledTimes(2);
});

/*
TODO: Add tests that require scroll interaction. Needs further investigation.
- Fetches more data when scrolling and more data is available
Expand Down
16 changes: 15 additions & 1 deletion superset-frontend/src/components/Select/Select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import React, {
useState,
useRef,
useCallback,
useImperativeHandle,
} from 'react';
import { ensureIsArray, styled, t } from '@superset-ui/core';
import AntdSelect, {
Expand Down Expand Up @@ -81,6 +82,8 @@ export type OptionsPagePromise = (
pageSize: number,
) => Promise<OptionsTypePage>;

export type SelectRef = HTMLInputElement & { clearCache: () => void };

export interface SelectProps extends PickedSelectProps {
/**
* It enables the user to create new options.
Expand Down Expand Up @@ -315,7 +318,7 @@ const Select = (
value,
...props
}: SelectProps,
ref: RefObject<HTMLInputElement>,
ref: RefObject<SelectRef>,
) => {
const isAsync = typeof options === 'function';
const isSingleMode = mode === 'single';
Expand Down Expand Up @@ -678,6 +681,17 @@ const Select = (
}
}, [isLoading, loading]);

const clearCache = () => fetchedQueries.current.clear();

useImperativeHandle(
ref,
() => ({
...(ref.current as HTMLInputElement),
clearCache,
}),
[ref],
);

return (
<StyledContainer>
{header}
Expand Down
3 changes: 2 additions & 1 deletion superset-frontend/src/filters/components/GroupBy/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
QueryFormData,
} from '@superset-ui/core';
import { RefObject } from 'react';
import { SelectRef } from 'src/components/Select/Select';
import { PluginFilterHooks, PluginFilterStylesProps } from '../types';

interface PluginFilterGroupByCustomizeProps {
Expand All @@ -40,7 +41,7 @@ export type PluginFilterGroupByProps = PluginFilterStylesProps & {
data: DataRecord[];
filterState: FilterState;
formData: PluginFilterGroupByQueryFormData;
inputRef: RefObject<HTMLInputElement>;
inputRef: RefObject<SelectRef>;
} & PluginFilterHooks;

export const DEFAULT_FORM_DATA: PluginFilterGroupByCustomizeProps = {
Expand Down
3 changes: 2 additions & 1 deletion superset-frontend/src/filters/components/TimeColumn/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
QueryFormData,
} from '@superset-ui/core';
import { RefObject } from 'react';
import { SelectRef } from 'src/components/Select/Select';
import { PluginFilterHooks, PluginFilterStylesProps } from '../types';

interface PluginFilterTimeColumnCustomizeProps {
Expand All @@ -39,7 +40,7 @@ export type PluginFilterTimeColumnProps = PluginFilterStylesProps & {
data: DataRecord[];
filterState: FilterState;
formData: PluginFilterTimeColumnQueryFormData;
inputRef: RefObject<HTMLInputElement>;
inputRef: RefObject<SelectRef>;
} & PluginFilterHooks;

export const DEFAULT_FORM_DATA: PluginFilterTimeColumnCustomizeProps = {
Expand Down
3 changes: 2 additions & 1 deletion superset-frontend/src/filters/components/TimeGrain/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*/
import { FilterState, QueryFormData, DataRecord } from '@superset-ui/core';
import { RefObject } from 'react';
import { SelectRef } from 'src/components/Select/Select';
import { PluginFilterHooks, PluginFilterStylesProps } from '../types';

interface PluginFilterTimeGrainCustomizeProps {
Expand All @@ -33,7 +34,7 @@ export type PluginFilterTimeGrainProps = PluginFilterStylesProps & {
data: DataRecord[];
filterState: FilterState;
formData: PluginFilterTimeGrainQueryFormData;
inputRef: RefObject<HTMLInputElement>;
inputRef: RefObject<SelectRef>;
} & PluginFilterHooks;

export const DEFAULT_FORM_DATA: PluginFilterTimeGrainCustomizeProps = {
Expand Down

0 comments on commit ca526e6

Please sign in to comment.