mirror of
https://github.com/apache/superset.git
synced 2024-09-12 00:29:39 -04:00
feat: Adds support for clearing the Select cache (#20397)
* feat: Adds support for clearing the Select cache * Fixes lint errors
This commit is contained in:
parent
44c5e2879b
commit
ca526e63c8
@ -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',
|
||||
@ -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 }[] = [];
|
||||
@ -458,6 +465,7 @@ export const AsyncSelect = ({
|
||||
>
|
||||
<Select
|
||||
{...rest}
|
||||
ref={ref}
|
||||
fetchOnlyOnSearch={fetchOnlyOnSearch}
|
||||
options={withError ? fetchUserListError : fetchUserListPage}
|
||||
placeholder={fetchOnlyOnSearch ? 'Type anything' : 'Select...'}
|
||||
@ -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>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -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';
|
||||
@ -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
|
||||
|
@ -27,6 +27,7 @@ import React, {
|
||||
useState,
|
||||
useRef,
|
||||
useCallback,
|
||||
useImperativeHandle,
|
||||
} from 'react';
|
||||
import { ensureIsArray, styled, t } from '@superset-ui/core';
|
||||
import AntdSelect, {
|
||||
@ -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.
|
||||
@ -315,7 +318,7 @@ const Select = (
|
||||
value,
|
||||
...props
|
||||
}: SelectProps,
|
||||
ref: RefObject<HTMLInputElement>,
|
||||
ref: RefObject<SelectRef>,
|
||||
) => {
|
||||
const isAsync = typeof options === 'function';
|
||||
const isSingleMode = mode === 'single';
|
||||
@ -678,6 +681,17 @@ const Select = (
|
||||
}
|
||||
}, [isLoading, loading]);
|
||||
|
||||
const clearCache = () => fetchedQueries.current.clear();
|
||||
|
||||
useImperativeHandle(
|
||||
ref,
|
||||
() => ({
|
||||
...(ref.current as HTMLInputElement),
|
||||
clearCache,
|
||||
}),
|
||||
[ref],
|
||||
);
|
||||
|
||||
return (
|
||||
<StyledContainer>
|
||||
{header}
|
||||
|
@ -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 {
|
||||
@ -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 = {
|
||||
|
@ -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 {
|
||||
@ -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 = {
|
||||
|
@ -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 {
|
||||
@ -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 = {
|
||||
|
Loading…
Reference in New Issue
Block a user