mirror of
https://github.com/apache/superset.git
synced 2024-09-12 00:29:39 -04:00
fix(native-filters): Fix native filters config modal (#15506)
* fix:fix get permission function * fix: native filters * fix: remove unneccesary space fo filters / fix some crashes
This commit is contained in:
parent
dd16468d44
commit
2cb13e695e
@ -132,7 +132,7 @@ const FilterFocusHighlight = React.forwardRef(
|
|||||||
|
|
||||||
if (focusedNativeFilterId) {
|
if (focusedNativeFilterId) {
|
||||||
if (
|
if (
|
||||||
nativeFilters.filters[focusedNativeFilterId].chartsInScope?.includes(
|
nativeFilters.filters[focusedNativeFilterId]?.chartsInScope?.includes(
|
||||||
chartId,
|
chartId,
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
|
@ -44,6 +44,7 @@ import { FilterProps } from './types';
|
|||||||
import { getFormData } from '../../utils';
|
import { getFormData } from '../../utils';
|
||||||
import { useCascadingFilters } from './state';
|
import { useCascadingFilters } from './state';
|
||||||
import { usePreselectNativeFilter } from '../../state';
|
import { usePreselectNativeFilter } from '../../state';
|
||||||
|
import { checkIsMissingRequiredValue } from '../utils';
|
||||||
|
|
||||||
const HEIGHT = 32;
|
const HEIGHT = 32;
|
||||||
|
|
||||||
@ -197,7 +198,14 @@ const FilterValue: React.FC<FilterProps> = ({
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const filterState = { ...filter.dataMask?.filterState };
|
const isMissingRequiredValue = checkIsMissingRequiredValue(
|
||||||
|
filter,
|
||||||
|
filter.dataMask?.filterState,
|
||||||
|
);
|
||||||
|
const filterState = {
|
||||||
|
...filter.dataMask?.filterState,
|
||||||
|
validateMessage: isMissingRequiredValue && t('Value is required'),
|
||||||
|
};
|
||||||
if (filterState.value === undefined && preselection) {
|
if (filterState.value === undefined && preselection) {
|
||||||
filterState.value = preselection;
|
filterState.value = preselection;
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ import {
|
|||||||
SetDataMaskHook,
|
SetDataMaskHook,
|
||||||
SuperChart,
|
SuperChart,
|
||||||
AppSection,
|
AppSection,
|
||||||
|
t,
|
||||||
} from '@superset-ui/core';
|
} from '@superset-ui/core';
|
||||||
import { FormInstance } from 'antd/lib/form';
|
import { FormInstance } from 'antd/lib/form';
|
||||||
import Loading from 'src/components/Loading';
|
import Loading from 'src/components/Loading';
|
||||||
@ -56,6 +57,10 @@ const DefaultValue: FC<DefaultValueProps> = ({
|
|||||||
setLoading(true);
|
setLoading(true);
|
||||||
}
|
}
|
||||||
}, [hasDataset, queriesData]);
|
}, [hasDataset, queriesData]);
|
||||||
|
const value = formFilter.defaultDataMask?.filterState.value;
|
||||||
|
const isMissingRequiredValue =
|
||||||
|
(value === null || value === undefined) &&
|
||||||
|
formFilter?.controlValues?.enableEmptyFilter;
|
||||||
return loading ? (
|
return loading ? (
|
||||||
<Loading position="inline-centered" />
|
<Loading position="inline-centered" />
|
||||||
) : (
|
) : (
|
||||||
@ -74,6 +79,7 @@ const DefaultValue: FC<DefaultValueProps> = ({
|
|||||||
enableNoResults={enableNoResults}
|
enableNoResults={enableNoResults}
|
||||||
filterState={{
|
filterState={{
|
||||||
...formFilter.defaultDataMask?.filterState,
|
...formFilter.defaultDataMask?.filterState,
|
||||||
|
validateMessage: isMissingRequiredValue && t('Value is required'),
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -345,13 +345,27 @@ const FiltersConfigForm = (
|
|||||||
const hasDataset = !!nativeFilterItems[formFilter?.filterType]?.value
|
const hasDataset = !!nativeFilterItems[formFilter?.filterType]?.value
|
||||||
?.datasourceCount;
|
?.datasourceCount;
|
||||||
|
|
||||||
|
const { controlItems = {}, mainControlItems = {} } = formFilter
|
||||||
|
? getControlItemsMap({
|
||||||
|
disabled: false,
|
||||||
|
forceUpdate,
|
||||||
|
form,
|
||||||
|
filterId,
|
||||||
|
filterType: formFilter.filterType,
|
||||||
|
filterToEdit,
|
||||||
|
formFilter,
|
||||||
|
removed,
|
||||||
|
})
|
||||||
|
: {};
|
||||||
|
const hasColumn = !!mainControlItems.groupby;
|
||||||
|
|
||||||
const nativeFilterItem = nativeFilterItems[formFilter?.filterType] ?? {};
|
const nativeFilterItem = nativeFilterItems[formFilter?.filterType] ?? {};
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const enableNoResults = !!nativeFilterItem.value?.enableNoResults;
|
const enableNoResults = !!nativeFilterItem.value?.enableNoResults;
|
||||||
const datasetId = formFilter?.dataset?.value;
|
const datasetId = formFilter?.dataset?.value;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (datasetId && hasDataset) {
|
if (datasetId && hasColumn) {
|
||||||
cachedSupersetGet({
|
cachedSupersetGet({
|
||||||
endpoint: `/api/v1/dataset/${datasetId}`,
|
endpoint: `/api/v1/dataset/${datasetId}`,
|
||||||
})
|
})
|
||||||
@ -367,7 +381,7 @@ const FiltersConfigForm = (
|
|||||||
addDangerToast(response.message);
|
addDangerToast(response.message);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [datasetId, hasDataset]);
|
}, [datasetId, hasColumn]);
|
||||||
|
|
||||||
useImperativeHandle(ref, () => ({
|
useImperativeHandle(ref, () => ({
|
||||||
changeTab(tab: 'configuration' | 'scoping') {
|
changeTab(tab: 'configuration' | 'scoping') {
|
||||||
@ -375,10 +389,10 @@ const FiltersConfigForm = (
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const hasMetrics = hasDataset && !!metrics.length;
|
const hasMetrics = hasColumn && !!metrics.length;
|
||||||
|
|
||||||
const hasFilledDataset =
|
const hasFilledDataset =
|
||||||
!hasDataset || (datasetId && (formFilter?.column || !hasDataset));
|
!hasDataset || (datasetId && (formFilter?.column || !hasColumn));
|
||||||
|
|
||||||
const hasAdditionalFilters = FILTERS_WITH_ADHOC_FILTERS.includes(
|
const hasAdditionalFilters = FILTERS_WITH_ADHOC_FILTERS.includes(
|
||||||
formFilter?.filterType,
|
formFilter?.filterType,
|
||||||
@ -477,7 +491,7 @@ const FiltersConfigForm = (
|
|||||||
: undefined);
|
: undefined);
|
||||||
const newFormData = getFormData({
|
const newFormData = getFormData({
|
||||||
datasetId,
|
datasetId,
|
||||||
groupby: hasDataset ? formFilter?.column : undefined,
|
groupby: hasColumn ? formFilter?.column : undefined,
|
||||||
...formFilter,
|
...formFilter,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -534,20 +548,10 @@ const FiltersConfigForm = (
|
|||||||
const hasSorting =
|
const hasSorting =
|
||||||
typeof filterToEdit?.controlValues?.sortAscending === 'boolean';
|
typeof filterToEdit?.controlValues?.sortAscending === 'boolean';
|
||||||
|
|
||||||
const showDefaultValue = !hasDataset || (!isDataDirty && hasFilledDataset);
|
const showDefaultValue =
|
||||||
|
!hasDataset ||
|
||||||
const { controlItems = {}, mainControlItems = {} } = formFilter
|
(!isDataDirty && hasFilledDataset) ||
|
||||||
? getControlItemsMap({
|
!mainControlItems.groupby;
|
||||||
disabled: false,
|
|
||||||
forceUpdate,
|
|
||||||
form,
|
|
||||||
filterId,
|
|
||||||
filterType: formFilter.filterType,
|
|
||||||
filterToEdit,
|
|
||||||
formFilter,
|
|
||||||
removed,
|
|
||||||
})
|
|
||||||
: {};
|
|
||||||
|
|
||||||
const onSortChanged = (value: boolean | undefined) => {
|
const onSortChanged = (value: boolean | undefined) => {
|
||||||
const previous = form.getFieldValue('filters')?.[filterId].controlValues;
|
const previous = form.getFieldValue('filters')?.[filterId].controlValues;
|
||||||
@ -683,6 +687,7 @@ const FiltersConfigForm = (
|
|||||||
setNativeFilterFieldValues(form, filterId, {
|
setNativeFilterFieldValues(form, filterId, {
|
||||||
filterType: value,
|
filterType: value,
|
||||||
defaultDataMask: null,
|
defaultDataMask: null,
|
||||||
|
column: null,
|
||||||
});
|
});
|
||||||
forceUpdate();
|
forceUpdate();
|
||||||
}}
|
}}
|
||||||
@ -738,13 +743,6 @@ const FiltersConfigForm = (
|
|||||||
header={FilterPanels.basic.name}
|
header={FilterPanels.basic.name}
|
||||||
key={FilterPanels.basic.key}
|
key={FilterPanels.basic.key}
|
||||||
>
|
>
|
||||||
{hasFilledDataset && (
|
|
||||||
<CleanFormItem
|
|
||||||
name={['filters', filterId, 'defaultValueFormData']}
|
|
||||||
hidden
|
|
||||||
initialValue={newFormData}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
<CleanFormItem
|
<CleanFormItem
|
||||||
name={['filters', filterId, 'defaultValueQueriesData']}
|
name={['filters', filterId, 'defaultValueQueriesData']}
|
||||||
hidden
|
hidden
|
||||||
@ -760,7 +758,11 @@ const FiltersConfigForm = (
|
|||||||
>
|
>
|
||||||
<StyledRowSubFormItem
|
<StyledRowSubFormItem
|
||||||
name={['filters', filterId, 'defaultDataMask']}
|
name={['filters', filterId, 'defaultDataMask']}
|
||||||
initialValue={filterToEdit?.defaultDataMask}
|
initialValue={
|
||||||
|
formFilter.filterType === filterToEdit?.filterType
|
||||||
|
? filterToEdit?.defaultDataMask
|
||||||
|
: null
|
||||||
|
}
|
||||||
data-test="default-input"
|
data-test="default-input"
|
||||||
label={<StyledLabel>{t('Default Value')}</StyledLabel>}
|
label={<StyledLabel>{t('Default Value')}</StyledLabel>}
|
||||||
required={hasDefaultValue}
|
required={hasDefaultValue}
|
||||||
|
@ -19,9 +19,8 @@
|
|||||||
import { ensureIsArray, ExtraFormData, styled, t, tn } from '@superset-ui/core';
|
import { ensureIsArray, ExtraFormData, styled, t, tn } from '@superset-ui/core';
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { Select } from 'src/common/components';
|
import { Select } from 'src/common/components';
|
||||||
import { Styles, StyledSelect } from '../common';
|
import { Styles, StyledSelect, StyledFormItem } from '../common';
|
||||||
import { PluginFilterGroupByProps } from './types';
|
import { PluginFilterGroupByProps } from './types';
|
||||||
import FormItem from '../../../components/Form/FormItem';
|
|
||||||
|
|
||||||
const { Option } = Select;
|
const { Option } = Select;
|
||||||
|
|
||||||
@ -87,7 +86,7 @@ export default function PluginFilterGroupBy(props: PluginFilterGroupByProps) {
|
|||||||
: tn('%s option', '%s options', columns.length, columns.length);
|
: tn('%s option', '%s options', columns.length, columns.length);
|
||||||
return (
|
return (
|
||||||
<Styles height={height} width={width}>
|
<Styles height={height} width={width}>
|
||||||
<FormItem
|
<StyledFormItem
|
||||||
validateStatus={filterState.validateMessage && 'error'}
|
validateStatus={filterState.validateMessage && 'error'}
|
||||||
extra={<Error>{filterState.validateMessage}</Error>}
|
extra={<Error>{filterState.validateMessage}</Error>}
|
||||||
>
|
>
|
||||||
@ -116,7 +115,7 @@ export default function PluginFilterGroupBy(props: PluginFilterGroupByProps) {
|
|||||||
},
|
},
|
||||||
)}
|
)}
|
||||||
</StyledSelect>
|
</StyledSelect>
|
||||||
</FormItem>
|
</StyledFormItem>
|
||||||
</Styles>
|
</Styles>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -26,9 +26,8 @@ import React, { useEffect, useState } from 'react';
|
|||||||
import { Slider } from 'src/common/components';
|
import { Slider } from 'src/common/components';
|
||||||
import { rgba } from 'emotion-rgba';
|
import { rgba } from 'emotion-rgba';
|
||||||
import { PluginFilterRangeProps } from './types';
|
import { PluginFilterRangeProps } from './types';
|
||||||
import { Styles } from '../common';
|
import { StyledFormItem, Styles } from '../common';
|
||||||
import { getRangeExtraFormData } from '../../utils';
|
import { getRangeExtraFormData } from '../../utils';
|
||||||
import FormItem from '../../../components/Form/FormItem';
|
|
||||||
|
|
||||||
const Error = styled.div`
|
const Error = styled.div`
|
||||||
color: ${({ theme }) => theme.colors.error.base};
|
color: ${({ theme }) => theme.colors.error.base};
|
||||||
@ -159,7 +158,7 @@ export default function RangeFilterPlugin(props: PluginFilterRangeProps) {
|
|||||||
{Number.isNaN(Number(min)) || Number.isNaN(Number(max)) ? (
|
{Number.isNaN(Number(min)) || Number.isNaN(Number(max)) ? (
|
||||||
<h4>{t('Chosen non-numeric column')}</h4>
|
<h4>{t('Chosen non-numeric column')}</h4>
|
||||||
) : (
|
) : (
|
||||||
<FormItem
|
<StyledFormItem
|
||||||
validateStatus={filterState.validateMessage && 'error'}
|
validateStatus={filterState.validateMessage && 'error'}
|
||||||
extra={<Error>{filterState.validateMessage}</Error>}
|
extra={<Error>{filterState.validateMessage}</Error>}
|
||||||
>
|
>
|
||||||
@ -183,7 +182,7 @@ export default function RangeFilterPlugin(props: PluginFilterRangeProps) {
|
|||||||
marks={marks}
|
marks={marks}
|
||||||
/>
|
/>
|
||||||
</Wrapper>
|
</Wrapper>
|
||||||
</FormItem>
|
</StyledFormItem>
|
||||||
)}
|
)}
|
||||||
</Styles>
|
</Styles>
|
||||||
);
|
);
|
||||||
|
@ -26,6 +26,7 @@ import {
|
|||||||
GenericDataType,
|
GenericDataType,
|
||||||
JsonObject,
|
JsonObject,
|
||||||
smartDateDetailedFormatter,
|
smartDateDetailedFormatter,
|
||||||
|
styled,
|
||||||
t,
|
t,
|
||||||
tn,
|
tn,
|
||||||
} from '@superset-ui/core';
|
} from '@superset-ui/core';
|
||||||
@ -44,11 +45,15 @@ import { useImmerReducer } from 'use-immer';
|
|||||||
import Icons from 'src/components/Icons';
|
import Icons from 'src/components/Icons';
|
||||||
import { usePrevious } from 'src/common/hooks/usePrevious';
|
import { usePrevious } from 'src/common/hooks/usePrevious';
|
||||||
import { PluginFilterSelectProps, SelectValue } from './types';
|
import { PluginFilterSelectProps, SelectValue } from './types';
|
||||||
import { StyledSelect, Styles } from '../common';
|
import { StyledFormItem, StyledSelect, Styles } from '../common';
|
||||||
import { getDataRecordFormatter, getSelectExtraFormData } from '../../utils';
|
import { getDataRecordFormatter, getSelectExtraFormData } from '../../utils';
|
||||||
|
|
||||||
const { Option } = Select;
|
const { Option } = Select;
|
||||||
|
|
||||||
|
const Error = styled.div`
|
||||||
|
color: ${({ theme }) => theme.colors.error.base};
|
||||||
|
`;
|
||||||
|
|
||||||
type DataMaskAction =
|
type DataMaskAction =
|
||||||
| { type: 'ownState'; ownState: JsonObject }
|
| { type: 'ownState'; ownState: JsonObject }
|
||||||
| {
|
| {
|
||||||
@ -273,52 +278,57 @@ export default function PluginFilterSelect(props: PluginFilterSelectProps) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Styles height={height} width={width}>
|
<Styles height={height} width={width}>
|
||||||
<StyledSelect
|
<StyledFormItem
|
||||||
allowClear
|
validateStatus={filterState.validateMessage && 'error'}
|
||||||
// @ts-ignore
|
extra={<Error>{filterState.validateMessage}</Error>}
|
||||||
value={filterState.value || []}
|
|
||||||
disabled={isDisabled}
|
|
||||||
showSearch={showSearch}
|
|
||||||
mode={multiSelect ? 'multiple' : undefined}
|
|
||||||
placeholder={placeholderText}
|
|
||||||
onSearch={searchWrapper}
|
|
||||||
onSelect={clearSuggestionSearch}
|
|
||||||
onBlur={handleBlur}
|
|
||||||
onDropdownVisibleChange={setIsDropdownVisible}
|
|
||||||
dropdownRender={(
|
|
||||||
originNode: ReactElement & { ref?: RefObject<HTMLElement> },
|
|
||||||
) => {
|
|
||||||
if (isDropdownVisible && !wasDropdownVisible) {
|
|
||||||
originNode.ref?.current?.scrollTo({ top: 0 });
|
|
||||||
}
|
|
||||||
return originNode;
|
|
||||||
}}
|
|
||||||
onFocus={setFocusedFilter}
|
|
||||||
// @ts-ignore
|
|
||||||
onChange={handleChange}
|
|
||||||
ref={inputRef}
|
|
||||||
loading={isRefreshing}
|
|
||||||
maxTagCount={5}
|
|
||||||
menuItemSelectedIcon={<Icon iconSize="m" />}
|
|
||||||
>
|
>
|
||||||
{sortedData.map(row => {
|
<StyledSelect
|
||||||
const [value] = groupby.map(col => row[col]);
|
allowClear
|
||||||
return (
|
// @ts-ignore
|
||||||
// @ts-ignore
|
value={filterState.value || []}
|
||||||
<Option key={`${value}`} value={value}>
|
disabled={isDisabled}
|
||||||
{labelFormatter(value, datatype)}
|
showSearch={showSearch}
|
||||||
</Option>
|
mode={multiSelect ? 'multiple' : undefined}
|
||||||
);
|
placeholder={placeholderText}
|
||||||
})}
|
onSearch={searchWrapper}
|
||||||
{currentSuggestionSearch &&
|
onSelect={clearSuggestionSearch}
|
||||||
!ensureIsArray(filterState.value).some(
|
onBlur={handleBlur}
|
||||||
suggestion => suggestion === currentSuggestionSearch,
|
onDropdownVisibleChange={setIsDropdownVisible}
|
||||||
) && (
|
dropdownRender={(
|
||||||
<Option value={currentSuggestionSearch}>
|
originNode: ReactElement & { ref?: RefObject<HTMLElement> },
|
||||||
{`${t('Create "%s"', currentSuggestionSearch)}`}
|
) => {
|
||||||
</Option>
|
if (isDropdownVisible && !wasDropdownVisible) {
|
||||||
)}
|
originNode.ref?.current?.scrollTo({ top: 0 });
|
||||||
</StyledSelect>
|
}
|
||||||
|
return originNode;
|
||||||
|
}}
|
||||||
|
onFocus={setFocusedFilter}
|
||||||
|
// @ts-ignore
|
||||||
|
onChange={handleChange}
|
||||||
|
ref={inputRef}
|
||||||
|
loading={isRefreshing}
|
||||||
|
maxTagCount={5}
|
||||||
|
menuItemSelectedIcon={<Icon iconSize="m" />}
|
||||||
|
>
|
||||||
|
{sortedData.map(row => {
|
||||||
|
const [value] = groupby.map(col => row[col]);
|
||||||
|
return (
|
||||||
|
// @ts-ignore
|
||||||
|
<Option key={`${value}`} value={value}>
|
||||||
|
{labelFormatter(value, datatype)}
|
||||||
|
</Option>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
{currentSuggestionSearch &&
|
||||||
|
!ensureIsArray(filterState.value).some(
|
||||||
|
suggestion => suggestion === currentSuggestionSearch,
|
||||||
|
) && (
|
||||||
|
<Option value={currentSuggestionSearch}>
|
||||||
|
{`${t('Create "%s"', currentSuggestionSearch)}`}
|
||||||
|
</Option>
|
||||||
|
)}
|
||||||
|
</StyledSelect>
|
||||||
|
</StyledFormItem>
|
||||||
</Styles>
|
</Styles>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -26,9 +26,8 @@ import {
|
|||||||
} from '@superset-ui/core';
|
} from '@superset-ui/core';
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { Select } from 'src/common/components';
|
import { Select } from 'src/common/components';
|
||||||
import { Styles, StyledSelect } from '../common';
|
import { Styles, StyledSelect, StyledFormItem } from '../common';
|
||||||
import { PluginFilterTimeColumnProps } from './types';
|
import { PluginFilterTimeColumnProps } from './types';
|
||||||
import FormItem from '../../../components/Form/FormItem';
|
|
||||||
|
|
||||||
const { Option } = Select;
|
const { Option } = Select;
|
||||||
|
|
||||||
@ -89,7 +88,7 @@ export default function PluginFilterTimeColumn(
|
|||||||
: tn('%s option', '%s options', timeColumns.length, timeColumns.length);
|
: tn('%s option', '%s options', timeColumns.length, timeColumns.length);
|
||||||
return (
|
return (
|
||||||
<Styles height={height} width={width}>
|
<Styles height={height} width={width}>
|
||||||
<FormItem
|
<StyledFormItem
|
||||||
validateStatus={filterState.validateMessage && 'error'}
|
validateStatus={filterState.validateMessage && 'error'}
|
||||||
extra={<Error>{filterState.validateMessage}</Error>}
|
extra={<Error>{filterState.validateMessage}</Error>}
|
||||||
>
|
>
|
||||||
@ -117,7 +116,7 @@ export default function PluginFilterTimeColumn(
|
|||||||
},
|
},
|
||||||
)}
|
)}
|
||||||
</StyledSelect>
|
</StyledSelect>
|
||||||
</FormItem>
|
</StyledFormItem>
|
||||||
</Styles>
|
</Styles>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -26,9 +26,8 @@ import {
|
|||||||
} from '@superset-ui/core';
|
} from '@superset-ui/core';
|
||||||
import React, { useEffect, useMemo, useState } from 'react';
|
import React, { useEffect, useMemo, useState } from 'react';
|
||||||
import { Select } from 'src/common/components';
|
import { Select } from 'src/common/components';
|
||||||
import { Styles, StyledSelect } from '../common';
|
import { Styles, StyledSelect, StyledFormItem } from '../common';
|
||||||
import { PluginFilterTimeGrainProps } from './types';
|
import { PluginFilterTimeGrainProps } from './types';
|
||||||
import FormItem from '../../../components/Form/FormItem';
|
|
||||||
|
|
||||||
const { Option } = Select;
|
const { Option } = Select;
|
||||||
|
|
||||||
@ -99,7 +98,7 @@ export default function PluginFilterTimegrain(
|
|||||||
: tn('%s option', '%s options', data.length, data.length);
|
: tn('%s option', '%s options', data.length, data.length);
|
||||||
return (
|
return (
|
||||||
<Styles height={height} width={width}>
|
<Styles height={height} width={width}>
|
||||||
<FormItem
|
<StyledFormItem
|
||||||
validateStatus={filterState.validateMessage && 'error'}
|
validateStatus={filterState.validateMessage && 'error'}
|
||||||
extra={<Error>{filterState.validateMessage}</Error>}
|
extra={<Error>{filterState.validateMessage}</Error>}
|
||||||
>
|
>
|
||||||
@ -122,7 +121,7 @@ export default function PluginFilterTimegrain(
|
|||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</StyledSelect>
|
</StyledSelect>
|
||||||
</FormItem>
|
</StyledFormItem>
|
||||||
</Styles>
|
</Styles>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
import { styled } from '@superset-ui/core';
|
import { styled } from '@superset-ui/core';
|
||||||
import { Select } from 'src/common/components';
|
import { Select } from 'src/common/components';
|
||||||
import { PluginFilterStylesProps } from './types';
|
import { PluginFilterStylesProps } from './types';
|
||||||
|
import FormItem from '../../components/Form/FormItem';
|
||||||
|
|
||||||
export const Styles = styled.div<PluginFilterStylesProps>`
|
export const Styles = styled.div<PluginFilterStylesProps>`
|
||||||
min-height: ${({ height }) => height}px;
|
min-height: ${({ height }) => height}px;
|
||||||
@ -28,3 +29,9 @@ export const Styles = styled.div<PluginFilterStylesProps>`
|
|||||||
export const StyledSelect = styled(Select)`
|
export const StyledSelect = styled(Select)`
|
||||||
width: 100%;
|
width: 100%;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const StyledFormItem = styled(FormItem)`
|
||||||
|
&.ant-row.ant-form-item {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
Loading…
Reference in New Issue
Block a user