mirror of https://github.com/apache/superset.git
feat(native-filters): Highlight charts affected by focused native filter (#14693)
* Highlight charts affected by focused native filter * Remove tabs animation on dashboard * Remove a test that checks for "animated={true}" prop on tabs * Move hooks types to a separate interface
This commit is contained in:
parent
29828f8552
commit
c831655913
|
@ -128,12 +128,6 @@ describe('DashboardBuilder', () => {
|
|||
expect(parentSize.find(Tabs.TabPane)).toHaveLength(2);
|
||||
});
|
||||
|
||||
it('should have default animated=true on Tabs for perf', () => {
|
||||
const wrapper = setup({ dashboardLayout: undoableDashboardLayoutWithTabs });
|
||||
const tabProps = wrapper.find(ParentSize).find(Tabs).props();
|
||||
expect(tabProps.animated).toEqual(true);
|
||||
});
|
||||
|
||||
it('should render a TabPane and DashboardGrid for first Tab', () => {
|
||||
const wrapper = setup({ dashboardLayout: undoableDashboardLayoutWithTabs });
|
||||
const parentSize = wrapper.find(ParentSize);
|
||||
|
|
|
@ -116,7 +116,7 @@ type BootstrapData = {
|
|||
};
|
||||
};
|
||||
|
||||
export interface SetBooststapData {
|
||||
export interface SetBootstrapData {
|
||||
type: typeof HYDRATE_DASHBOARD;
|
||||
data: BootstrapData;
|
||||
}
|
||||
|
@ -182,6 +182,28 @@ export function saveFilterSets(
|
|||
};
|
||||
}
|
||||
|
||||
export const SET_FOCUSED_NATIVE_FILTER = 'SET_FOCUSED_NATIVE_FILTER';
|
||||
export interface SetFocusedNativeFilter {
|
||||
type: typeof SET_FOCUSED_NATIVE_FILTER;
|
||||
id: string;
|
||||
}
|
||||
export const UNSET_FOCUSED_NATIVE_FILTER = 'UNSET_FOCUSED_NATIVE_FILTER';
|
||||
export interface UnsetFocusedNativeFilter {
|
||||
type: typeof UNSET_FOCUSED_NATIVE_FILTER;
|
||||
}
|
||||
|
||||
export function setFocusedNativeFilter(id: string): SetFocusedNativeFilter {
|
||||
return {
|
||||
type: SET_FOCUSED_NATIVE_FILTER,
|
||||
id,
|
||||
};
|
||||
}
|
||||
export function unsetFocusedNativeFilter(): UnsetFocusedNativeFilter {
|
||||
return {
|
||||
type: UNSET_FOCUSED_NATIVE_FILTER,
|
||||
};
|
||||
}
|
||||
|
||||
export type AnyFilterAction =
|
||||
| SetFilterConfigBegin
|
||||
| SetFilterConfigComplete
|
||||
|
@ -190,4 +212,6 @@ export type AnyFilterAction =
|
|||
| SetFilterSetsConfigComplete
|
||||
| SetFilterSetsConfigFail
|
||||
| SaveFilterSets
|
||||
| SetBooststapData;
|
||||
| SetBootstrapData
|
||||
| SetFocusedNativeFilter
|
||||
| UnsetFocusedNativeFilter;
|
||||
|
|
|
@ -72,7 +72,7 @@ const DashboardContainer: FC<DashboardContainerProps> = ({ topLevelTabs }) => {
|
|||
activeKey={activeKey}
|
||||
renderTabBar={() => <></>}
|
||||
fullWidth={false}
|
||||
animated
|
||||
animated={false}
|
||||
allowOverflow
|
||||
>
|
||||
{childIds.map((id, index) => (
|
||||
|
|
|
@ -107,7 +107,7 @@ const FilterFocusHighlight = React.forwardRef(
|
|||
styles = {
|
||||
borderColor: theme.colors.primary.light2,
|
||||
opacity: 1,
|
||||
boxShadow: `0px 0px ${({ theme }) => theme.gridUnit * 2}px ${
|
||||
boxShadow: `0px 0px ${theme.gridUnit * 2}px ${
|
||||
theme.colors.primary.light2
|
||||
}`,
|
||||
pointerEvents: 'auto',
|
||||
|
|
|
@ -26,12 +26,17 @@ import {
|
|||
Behavior,
|
||||
ChartDataResponseResult,
|
||||
} from '@superset-ui/core';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { areObjectsEqual } from 'src/reduxUtils';
|
||||
import { getChartDataRequest } from 'src/chart/chartAction';
|
||||
import Loading from 'src/components/Loading';
|
||||
import BasicErrorAlert from 'src/components/ErrorMessage/BasicErrorAlert';
|
||||
import { FeatureFlag, isFeatureEnabled } from 'src/featureFlags';
|
||||
import { waitForAsyncData } from 'src/middleware/asyncEvent';
|
||||
import {
|
||||
setFocusedNativeFilter,
|
||||
unsetFocusedNativeFilter,
|
||||
} from 'src/dashboard/actions/nativeFilters';
|
||||
import { ClientErrorObject } from 'src/utils/getClientErrorObject';
|
||||
import { FilterProps } from './types';
|
||||
import { getFormData } from '../../utils';
|
||||
|
@ -61,6 +66,7 @@ const FilterValue: React.FC<FilterProps> = ({
|
|||
const { name: groupby } = column;
|
||||
const hasDataSource = !!datasetId;
|
||||
const [loading, setLoading] = useState<boolean>(hasDataSource);
|
||||
const dispatch = useDispatch();
|
||||
useEffect(() => {
|
||||
const newFormData = getFormData({
|
||||
...filter,
|
||||
|
@ -130,6 +136,9 @@ const FilterValue: React.FC<FilterProps> = ({
|
|||
const setDataMask = (dataMask: DataMask) =>
|
||||
onFilterSelectionChange(filter, dataMask);
|
||||
|
||||
const setFocusedFilter = () => dispatch(setFocusedNativeFilter(id));
|
||||
const unsetFocusedFilter = () => dispatch(unsetFocusedNativeFilter());
|
||||
|
||||
if (error) {
|
||||
return (
|
||||
<BasicErrorAlert
|
||||
|
@ -155,7 +164,7 @@ const FilterValue: React.FC<FilterProps> = ({
|
|||
behaviors={[Behavior.NATIVE_FILTER]}
|
||||
filterState={filter.dataMask?.filterState}
|
||||
ownState={filter.dataMask?.ownState}
|
||||
hooks={{ setDataMask }}
|
||||
hooks={{ setDataMask, setFocusedFilter, unsetFocusedFilter }}
|
||||
/>
|
||||
)}
|
||||
</FilterItem>
|
||||
|
|
|
@ -22,7 +22,7 @@ import { DataMask, HandlerFunction, styled, t } from '@superset-ui/core';
|
|||
import { useDispatch } from 'react-redux';
|
||||
import { DataMaskState, DataMaskWithId } from 'src/dataMask/types';
|
||||
import { setFilterSetsConfiguration } from 'src/dashboard/actions/nativeFilters';
|
||||
import { Filters, FilterSet, FilterSets } from 'src/dashboard/reducers/types';
|
||||
import { Filters, FilterSet } from 'src/dashboard/reducers/types';
|
||||
import { areObjectsEqual } from 'src/reduxUtils';
|
||||
import { findExistingFilterSet, generateFiltersSetId } from './utils';
|
||||
import { Filter } from '../../types';
|
||||
|
|
|
@ -79,12 +79,26 @@ function selectFocusedFilterScope(dashboardState, dashboardFilters) {
|
|||
};
|
||||
}
|
||||
|
||||
function selectFocusedNativeFilterScope(nativeFilters) {
|
||||
if (!nativeFilters.focusedFilterId) return null;
|
||||
const id = nativeFilters.focusedFilterId;
|
||||
const focusedFilterScope = nativeFilters.filters[id].scope;
|
||||
return {
|
||||
chartId: id,
|
||||
scope: {
|
||||
scope: focusedFilterScope.rootPath,
|
||||
immune: focusedFilterScope.excluded,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function mapStateToProps(
|
||||
{
|
||||
dashboardLayout: undoableLayout,
|
||||
dashboardState,
|
||||
dashboardInfo,
|
||||
dashboardFilters,
|
||||
nativeFilters,
|
||||
},
|
||||
ownProps,
|
||||
) {
|
||||
|
@ -101,10 +115,9 @@ function mapStateToProps(
|
|||
directPathToChild: dashboardState.directPathToChild,
|
||||
directPathLastUpdated: dashboardState.directPathLastUpdated,
|
||||
dashboardId: dashboardInfo.id,
|
||||
focusedFilterScope: selectFocusedFilterScope(
|
||||
dashboardState,
|
||||
dashboardFilters,
|
||||
),
|
||||
focusedFilterScope:
|
||||
selectFocusedFilterScope(dashboardState, dashboardFilters) ||
|
||||
selectFocusedNativeFilterScope(nativeFilters),
|
||||
};
|
||||
|
||||
// rows and columns need more data about their child dimensions
|
||||
|
|
|
@ -21,6 +21,8 @@ import {
|
|||
SAVE_FILTER_SETS,
|
||||
SET_FILTER_CONFIG_COMPLETE,
|
||||
SET_FILTER_SETS_CONFIG_COMPLETE,
|
||||
SET_FOCUSED_NATIVE_FILTER,
|
||||
UNSET_FOCUSED_NATIVE_FILTER,
|
||||
} from 'src/dashboard/actions/nativeFilters';
|
||||
import { FilterSet, NativeFiltersState } from './types';
|
||||
import { FilterConfiguration } from '../components/nativeFilters/types';
|
||||
|
@ -58,6 +60,7 @@ export function getInitialState({
|
|||
} else {
|
||||
state.filterSets = prevState?.filterSets ?? {};
|
||||
}
|
||||
state.focusedFilterId = undefined;
|
||||
return state as NativeFiltersState;
|
||||
}
|
||||
|
||||
|
@ -97,6 +100,17 @@ export default function nativeFilterReducer(
|
|||
state,
|
||||
});
|
||||
|
||||
case SET_FOCUSED_NATIVE_FILTER:
|
||||
return {
|
||||
...state,
|
||||
focusedFilterId: action.id,
|
||||
};
|
||||
|
||||
case UNSET_FOCUSED_NATIVE_FILTER:
|
||||
return {
|
||||
...state,
|
||||
focusedFilterId: undefined,
|
||||
};
|
||||
// TODO handle SET_FILTER_CONFIG_FAIL action
|
||||
default:
|
||||
return state;
|
||||
|
|
|
@ -99,4 +99,5 @@ export type Filters = {
|
|||
export type NativeFiltersState = {
|
||||
filters: Filters;
|
||||
filterSets: FilterSets;
|
||||
focusedFilterId?: string;
|
||||
};
|
||||
|
|
|
@ -47,13 +47,15 @@
|
|||
border-radius: @border-radius-large;
|
||||
box-shadow: inset 0 0 0 2px @shadow-highlight,
|
||||
0 0 0 3px fade(@shadow-highlight, @opacity-light);
|
||||
transition: box-shadow 1s ease-in-out;
|
||||
transition: box-shadow 0.2s ease-in-out, opacity 0.2s ease-in-out,
|
||||
border-color 0.2s ease-in-out, box-shadow 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
&.fade-out {
|
||||
border-radius: @border-radius-large;
|
||||
box-shadow: none;
|
||||
transition: box-shadow 1s ease-in-out;
|
||||
transition: box-shadow 0.2s ease-in-out, opacity 0.2s ease-in-out,
|
||||
border-color 0.2s ease-in-out, box-shadow 0.2s ease-in-out;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,16 @@ import { PluginFilterGroupByProps } from './types';
|
|||
const { Option } = Select;
|
||||
|
||||
export default function PluginFilterGroupBy(props: PluginFilterGroupByProps) {
|
||||
const { data, formData, height, width, setDataMask, filterState } = props;
|
||||
const {
|
||||
data,
|
||||
formData,
|
||||
height,
|
||||
width,
|
||||
setDataMask,
|
||||
setFocusedFilter,
|
||||
unsetFocusedFilter,
|
||||
filterState,
|
||||
} = props;
|
||||
const { defaultValue, inputRef, multiSelect } = formData;
|
||||
|
||||
const [value, setValue] = useState<string[]>(defaultValue ?? []);
|
||||
|
@ -68,6 +77,8 @@ export default function PluginFilterGroupBy(props: PluginFilterGroupByProps) {
|
|||
mode={multiSelect ? 'multiple' : undefined}
|
||||
// @ts-ignore
|
||||
onChange={handleChange}
|
||||
onBlur={unsetFocusedFilter}
|
||||
onFocus={setFocusedFilter}
|
||||
ref={inputRef}
|
||||
>
|
||||
{columns.map(
|
||||
|
|
|
@ -29,7 +29,11 @@ export default function transformProps(chartProps: ChartProps) {
|
|||
width,
|
||||
filterState,
|
||||
} = chartProps;
|
||||
const { setDataMask = () => {} } = hooks;
|
||||
const {
|
||||
setDataMask = () => {},
|
||||
setFocusedFilter = () => {},
|
||||
unsetFocusedFilter = () => {},
|
||||
} = hooks;
|
||||
|
||||
const { data } = queriesData[0];
|
||||
|
||||
|
@ -41,5 +45,7 @@ export default function transformProps(chartProps: ChartProps) {
|
|||
data,
|
||||
formData: { ...DEFAULT_FORM_DATA, ...formData },
|
||||
setDataMask,
|
||||
setFocusedFilter,
|
||||
unsetFocusedFilter,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -21,10 +21,9 @@ import {
|
|||
DataRecord,
|
||||
FilterState,
|
||||
QueryFormData,
|
||||
SetDataMaskHook,
|
||||
} from '@superset-ui/core';
|
||||
import { RefObject } from 'react';
|
||||
import { PluginFilterStylesProps } from '../types';
|
||||
import { PluginFilterHooks, PluginFilterStylesProps } from '../types';
|
||||
|
||||
interface PluginFilterGroupByCustomizeProps {
|
||||
defaultValue?: string[] | null;
|
||||
|
@ -39,10 +38,9 @@ export type PluginFilterGroupByQueryFormData = QueryFormData &
|
|||
export type PluginFilterGroupByProps = PluginFilterStylesProps & {
|
||||
behaviors: Behavior[];
|
||||
data: DataRecord[];
|
||||
setDataMask: SetDataMaskHook;
|
||||
filterState: FilterState;
|
||||
formData: PluginFilterGroupByQueryFormData;
|
||||
};
|
||||
} & PluginFilterHooks;
|
||||
|
||||
export const DEFAULT_FORM_DATA: PluginFilterGroupByCustomizeProps = {
|
||||
defaultValue: null,
|
||||
|
|
|
@ -30,6 +30,8 @@ export default function RangeFilterPlugin(props: PluginFilterRangeProps) {
|
|||
height,
|
||||
width,
|
||||
setDataMask,
|
||||
setFocusedFilter,
|
||||
unsetFocusedFilter,
|
||||
inputRef,
|
||||
filterState,
|
||||
} = props;
|
||||
|
@ -73,15 +75,17 @@ export default function RangeFilterPlugin(props: PluginFilterRangeProps) {
|
|||
{Number.isNaN(Number(min)) || Number.isNaN(Number(max)) ? (
|
||||
<h4>{t('Chosen non-numeric column')}</h4>
|
||||
) : (
|
||||
<Slider
|
||||
range
|
||||
min={min}
|
||||
max={max}
|
||||
value={value}
|
||||
onAfterChange={handleAfterChange}
|
||||
onChange={handleChange}
|
||||
ref={inputRef}
|
||||
/>
|
||||
<div onMouseEnter={setFocusedFilter} onMouseLeave={unsetFocusedFilter}>
|
||||
<Slider
|
||||
range
|
||||
min={min}
|
||||
max={max}
|
||||
value={value}
|
||||
onAfterChange={handleAfterChange}
|
||||
onChange={handleChange}
|
||||
ref={inputRef}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</Styles>
|
||||
);
|
||||
|
|
|
@ -28,7 +28,11 @@ export default function transformProps(chartProps: ChartProps) {
|
|||
behaviors,
|
||||
filterState,
|
||||
} = chartProps;
|
||||
const { setDataMask } = hooks;
|
||||
const {
|
||||
setDataMask = () => {},
|
||||
setFocusedFilter = () => {},
|
||||
unsetFocusedFilter = () => {},
|
||||
} = hooks;
|
||||
const { data } = queriesData[0];
|
||||
|
||||
return {
|
||||
|
@ -39,5 +43,7 @@ export default function transformProps(chartProps: ChartProps) {
|
|||
setDataMask,
|
||||
filterState,
|
||||
width,
|
||||
setFocusedFilter,
|
||||
unsetFocusedFilter,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -21,10 +21,9 @@ import {
|
|||
DataRecord,
|
||||
FilterState,
|
||||
QueryFormData,
|
||||
SetDataMaskHook,
|
||||
} from '@superset-ui/core';
|
||||
import { RefObject } from 'react';
|
||||
import { PluginFilterStylesProps } from '../types';
|
||||
import { PluginFilterHooks, PluginFilterStylesProps } from '../types';
|
||||
|
||||
interface PluginFilterSelectCustomizeProps {
|
||||
max?: number;
|
||||
|
@ -38,8 +37,7 @@ export type PluginFilterRangeQueryFormData = QueryFormData &
|
|||
export type PluginFilterRangeProps = PluginFilterStylesProps & {
|
||||
data: DataRecord[];
|
||||
formData: PluginFilterRangeQueryFormData;
|
||||
setDataMask: SetDataMaskHook;
|
||||
filterState: FilterState;
|
||||
behaviors: Behavior[];
|
||||
inputRef: RefObject<any>;
|
||||
};
|
||||
} & PluginFilterHooks;
|
||||
|
|
|
@ -40,6 +40,8 @@ export default function PluginFilterSelect(props: PluginFilterSelectProps) {
|
|||
height,
|
||||
width,
|
||||
setDataMask,
|
||||
setFocusedFilter,
|
||||
unsetFocusedFilter,
|
||||
filterState,
|
||||
appSection,
|
||||
} = props;
|
||||
|
@ -78,6 +80,11 @@ export default function PluginFilterSelect(props: PluginFilterSelectProps) {
|
|||
setCurrentSuggestionSearch('');
|
||||
};
|
||||
|
||||
const handleBlur = () => {
|
||||
clearSuggestionSearch();
|
||||
unsetFocusedFilter();
|
||||
};
|
||||
|
||||
const [col] = groupby;
|
||||
const datatype: GenericDataType = coltypeMap[col];
|
||||
const labelFormatter = getDataRecordFormatter({
|
||||
|
@ -157,7 +164,8 @@ export default function PluginFilterSelect(props: PluginFilterSelectProps) {
|
|||
placeholder={placeholderText}
|
||||
onSearch={setCurrentSuggestionSearch}
|
||||
onSelect={clearSuggestionSearch}
|
||||
onBlur={clearSuggestionSearch}
|
||||
onBlur={handleBlur}
|
||||
onFocus={setFocusedFilter}
|
||||
// @ts-ignore
|
||||
onChange={handleChange}
|
||||
ref={inputRef}
|
||||
|
|
|
@ -33,7 +33,11 @@ export default function transformProps(
|
|||
filterState,
|
||||
} = chartProps;
|
||||
const newFormData = { ...DEFAULT_FORM_DATA, ...formData };
|
||||
const { setDataMask = () => {} } = hooks;
|
||||
const {
|
||||
setDataMask = () => {},
|
||||
setFocusedFilter = () => {},
|
||||
unsetFocusedFilter = () => {},
|
||||
} = hooks;
|
||||
const [queryData] = queriesData;
|
||||
const { colnames = [], coltypes = [], data = [] } = queryData || {};
|
||||
const coltypeMap: Record<string, GenericDataType> = colnames.reduce(
|
||||
|
@ -51,5 +55,7 @@ export default function transformProps(
|
|||
data,
|
||||
formData: newFormData,
|
||||
setDataMask,
|
||||
setFocusedFilter,
|
||||
unsetFocusedFilter,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -24,11 +24,10 @@ import {
|
|||
FilterState,
|
||||
GenericDataType,
|
||||
QueryFormData,
|
||||
SetDataMaskHook,
|
||||
ChartDataResponseResult,
|
||||
} from '@superset-ui/core';
|
||||
import { RefObject } from 'react';
|
||||
import { PluginFilterStylesProps } from '../types';
|
||||
import { PluginFilterHooks, PluginFilterStylesProps } from '../types';
|
||||
|
||||
export const FIRST_VALUE = '__FIRST_VALUE__';
|
||||
export type SelectValue = (number | string)[] | null;
|
||||
|
@ -55,12 +54,11 @@ export interface PluginFilterSelectChartProps extends ChartProps {
|
|||
export type PluginFilterSelectProps = PluginFilterStylesProps & {
|
||||
coltypeMap: Record<string, GenericDataType>;
|
||||
data: DataRecord[];
|
||||
setDataMask: SetDataMaskHook;
|
||||
behaviors: Behavior[];
|
||||
appSection: AppSection;
|
||||
formData: PluginFilterSelectQueryFormData;
|
||||
filterState: FilterState;
|
||||
};
|
||||
} & PluginFilterHooks;
|
||||
|
||||
export const DEFAULT_FORM_DATA: PluginFilterSelectCustomizeProps = {
|
||||
defaultValue: null,
|
||||
|
|
|
@ -28,8 +28,19 @@ const TimeFilterStyles = styled(Styles)`
|
|||
overflow-x: scroll;
|
||||
`;
|
||||
|
||||
const ControlContainer = styled.div`
|
||||
display: inline-block;
|
||||
`;
|
||||
|
||||
export default function TimeFilterPlugin(props: PluginFilterTimeProps) {
|
||||
const { formData, setDataMask, width, filterState } = props;
|
||||
const {
|
||||
formData,
|
||||
setDataMask,
|
||||
setFocusedFilter,
|
||||
unsetFocusedFilter,
|
||||
width,
|
||||
filterState,
|
||||
} = props;
|
||||
const { defaultValue } = formData;
|
||||
|
||||
const [value, setValue] = useState<string>(defaultValue ?? DEFAULT_VALUE);
|
||||
|
@ -56,11 +67,16 @@ export default function TimeFilterPlugin(props: PluginFilterTimeProps) {
|
|||
return (
|
||||
// @ts-ignore
|
||||
<TimeFilterStyles width={width}>
|
||||
<DateFilterControl
|
||||
value={value}
|
||||
name="time_range"
|
||||
onChange={handleTimeRangeChange}
|
||||
/>
|
||||
<ControlContainer
|
||||
onMouseEnter={setFocusedFilter}
|
||||
onMouseLeave={unsetFocusedFilter}
|
||||
>
|
||||
<DateFilterControl
|
||||
value={value}
|
||||
name="time_range"
|
||||
onChange={handleTimeRangeChange}
|
||||
/>
|
||||
</ControlContainer>
|
||||
</TimeFilterStyles>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -29,7 +29,11 @@ export default function transformProps(chartProps: ChartProps) {
|
|||
behaviors,
|
||||
filterState,
|
||||
} = chartProps;
|
||||
const { setDataMask = () => {} } = hooks;
|
||||
const {
|
||||
setDataMask = () => {},
|
||||
setFocusedFilter = () => {},
|
||||
unsetFocusedFilter = () => {},
|
||||
} = hooks;
|
||||
const { data } = queriesData[0];
|
||||
|
||||
return {
|
||||
|
@ -42,6 +46,8 @@ export default function transformProps(chartProps: ChartProps) {
|
|||
height,
|
||||
behaviors,
|
||||
setDataMask,
|
||||
setFocusedFilter,
|
||||
unsetFocusedFilter,
|
||||
width,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -21,9 +21,8 @@ import {
|
|||
DataRecord,
|
||||
FilterState,
|
||||
QueryFormData,
|
||||
SetDataMaskHook,
|
||||
} from '@superset-ui/core';
|
||||
import { PluginFilterStylesProps } from '../types';
|
||||
import { PluginFilterHooks, PluginFilterStylesProps } from '../types';
|
||||
|
||||
interface PluginFilterTimeCustomizeProps {
|
||||
defaultValue?: string | null;
|
||||
|
@ -36,10 +35,9 @@ export type PluginFilterSelectQueryFormData = QueryFormData &
|
|||
export type PluginFilterTimeProps = PluginFilterStylesProps & {
|
||||
behaviors: Behavior[];
|
||||
data: DataRecord[];
|
||||
setDataMask: SetDataMaskHook;
|
||||
formData: PluginFilterSelectQueryFormData;
|
||||
filterState: FilterState;
|
||||
};
|
||||
} & PluginFilterHooks;
|
||||
|
||||
export const DEFAULT_FORM_DATA: PluginFilterTimeCustomizeProps = {
|
||||
defaultValue: null,
|
||||
|
|
|
@ -33,7 +33,16 @@ const { Option } = Select;
|
|||
export default function PluginFilterTimeColumn(
|
||||
props: PluginFilterTimeColumnProps,
|
||||
) {
|
||||
const { data, formData, height, width, setDataMask, filterState } = props;
|
||||
const {
|
||||
data,
|
||||
formData,
|
||||
height,
|
||||
width,
|
||||
setDataMask,
|
||||
setFocusedFilter,
|
||||
unsetFocusedFilter,
|
||||
filterState,
|
||||
} = props;
|
||||
const { defaultValue, inputRef } = formData;
|
||||
|
||||
const [value, setValue] = useState<string[]>(defaultValue ?? []);
|
||||
|
@ -80,6 +89,8 @@ export default function PluginFilterTimeColumn(
|
|||
placeholder={placeholderText}
|
||||
// @ts-ignore
|
||||
onChange={handleChange}
|
||||
onBlur={unsetFocusedFilter}
|
||||
onFocus={setFocusedFilter}
|
||||
ref={inputRef}
|
||||
>
|
||||
{timeColumns.map(
|
||||
|
|
|
@ -29,7 +29,11 @@ export default function transformProps(chartProps: ChartProps) {
|
|||
width,
|
||||
filterState,
|
||||
} = chartProps;
|
||||
const { setDataMask = () => {} } = hooks;
|
||||
const {
|
||||
setDataMask = () => {},
|
||||
setFocusedFilter = () => {},
|
||||
unsetFocusedFilter = () => {},
|
||||
} = hooks;
|
||||
|
||||
const { data } = queriesData[0];
|
||||
|
||||
|
@ -41,5 +45,7 @@ export default function transformProps(chartProps: ChartProps) {
|
|||
data,
|
||||
formData: { ...DEFAULT_FORM_DATA, ...formData },
|
||||
setDataMask,
|
||||
setFocusedFilter,
|
||||
unsetFocusedFilter,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -21,10 +21,9 @@ import {
|
|||
DataRecord,
|
||||
FilterState,
|
||||
QueryFormData,
|
||||
SetDataMaskHook,
|
||||
} from '@superset-ui/core';
|
||||
import { RefObject } from 'react';
|
||||
import { PluginFilterStylesProps } from '../types';
|
||||
import { PluginFilterHooks, PluginFilterStylesProps } from '../types';
|
||||
|
||||
interface PluginFilterTimeColumnCustomizeProps {
|
||||
defaultValue?: string[] | null;
|
||||
|
@ -38,10 +37,9 @@ export type PluginFilterTimeColumnQueryFormData = QueryFormData &
|
|||
export type PluginFilterTimeColumnProps = PluginFilterStylesProps & {
|
||||
behaviors: Behavior[];
|
||||
data: DataRecord[];
|
||||
setDataMask: SetDataMaskHook;
|
||||
filterState: FilterState;
|
||||
formData: PluginFilterTimeColumnQueryFormData;
|
||||
};
|
||||
} & PluginFilterHooks;
|
||||
|
||||
export const DEFAULT_FORM_DATA: PluginFilterTimeColumnCustomizeProps = {
|
||||
defaultValue: null,
|
||||
|
|
|
@ -33,7 +33,16 @@ const { Option } = Select;
|
|||
export default function PluginFilterTimegrain(
|
||||
props: PluginFilterTimeGrainProps,
|
||||
) {
|
||||
const { data, formData, height, width, setDataMask, filterState } = props;
|
||||
const {
|
||||
data,
|
||||
formData,
|
||||
height,
|
||||
width,
|
||||
setDataMask,
|
||||
setFocusedFilter,
|
||||
unsetFocusedFilter,
|
||||
filterState,
|
||||
} = props;
|
||||
const { defaultValue, inputRef } = formData;
|
||||
|
||||
const [value, setValue] = useState<string[]>(defaultValue ?? []);
|
||||
|
@ -77,6 +86,8 @@ export default function PluginFilterTimegrain(
|
|||
placeholder={placeholderText}
|
||||
// @ts-ignore
|
||||
onChange={handleChange}
|
||||
onBlur={unsetFocusedFilter}
|
||||
onFocus={setFocusedFilter}
|
||||
ref={inputRef}
|
||||
>
|
||||
{(data || []).map((row: { name: string; duration: string }) => {
|
||||
|
|
|
@ -28,7 +28,11 @@ export default function transformProps(chartProps: ChartProps) {
|
|||
width,
|
||||
filterState,
|
||||
} = chartProps;
|
||||
const { setDataMask = () => {} } = hooks;
|
||||
const {
|
||||
setDataMask = () => {},
|
||||
setFocusedFilter = () => {},
|
||||
unsetFocusedFilter = () => {},
|
||||
} = hooks;
|
||||
|
||||
const { data } = queriesData[0];
|
||||
|
||||
|
@ -39,5 +43,7 @@ export default function transformProps(chartProps: ChartProps) {
|
|||
data,
|
||||
formData: { ...DEFAULT_FORM_DATA, ...formData },
|
||||
setDataMask,
|
||||
setFocusedFilter,
|
||||
unsetFocusedFilter,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -16,14 +16,9 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import {
|
||||
FilterState,
|
||||
QueryFormData,
|
||||
DataRecord,
|
||||
SetDataMaskHook,
|
||||
} from '@superset-ui/core';
|
||||
import { FilterState, QueryFormData, DataRecord } from '@superset-ui/core';
|
||||
import { RefObject } from 'react';
|
||||
import { PluginFilterStylesProps } from '../types';
|
||||
import { PluginFilterHooks, PluginFilterStylesProps } from '../types';
|
||||
|
||||
interface PluginFilterTimeGrainCustomizeProps {
|
||||
defaultValue?: string[] | null;
|
||||
|
@ -36,10 +31,9 @@ export type PluginFilterTimeGrainQueryFormData = QueryFormData &
|
|||
|
||||
export type PluginFilterTimeGrainProps = PluginFilterStylesProps & {
|
||||
data: DataRecord[];
|
||||
setDataMask: SetDataMaskHook;
|
||||
filterState: FilterState;
|
||||
formData: PluginFilterTimeGrainQueryFormData;
|
||||
};
|
||||
} & PluginFilterHooks;
|
||||
|
||||
export const DEFAULT_FORM_DATA: PluginFilterTimeGrainCustomizeProps = {
|
||||
defaultValue: null,
|
||||
|
|
|
@ -21,8 +21,8 @@ import { Select } from 'src/common/components';
|
|||
import { PluginFilterStylesProps } from './types';
|
||||
|
||||
export const Styles = styled.div<PluginFilterStylesProps>`
|
||||
height: ${({ height }) => height};
|
||||
width: ${({ width }) => width};
|
||||
height: ${({ height }) => height}px;
|
||||
width: ${({ width }) => width}px;
|
||||
`;
|
||||
|
||||
export const StyledSelect = styled(Select)`
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { SetDataMaskHook } from '@superset-ui/core';
|
||||
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
|
@ -20,3 +22,9 @@ export interface PluginFilterStylesProps {
|
|||
height: number;
|
||||
width: number;
|
||||
}
|
||||
|
||||
export interface PluginFilterHooks {
|
||||
setDataMask: SetDataMaskHook;
|
||||
setFocusedFilter: () => void;
|
||||
unsetFocusedFilter: () => void;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue