This is an automated email from the ASF dual-hosted git repository.
amitmiran pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git
The following commit(s) were added to refs/heads/master by this push:
new 2cb13e6 fix(native-filters): Fix native filters config modal (#15506)
2cb13e6 is described below
commit 2cb13e695e25c2fc07e6f58e8a8eab8e38a9defd
Author: simcha90 <[email protected]>
AuthorDate: Sun Jul 4 11:26:59 2021 +0300
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
---
.../components/gridComponents/ChartHolder.jsx | 2 +-
.../FilterBar/FilterControls/FilterValue.tsx | 10 +-
.../FiltersConfigForm/DefaultValue.tsx | 6 ++
.../FiltersConfigForm/FiltersConfigForm.tsx | 56 +++++------
.../components/GroupBy/GroupByFilterPlugin.tsx | 7 +-
.../filters/components/Range/RangeFilterPlugin.tsx | 7 +-
.../components/Select/SelectFilterPlugin.tsx | 102 +++++++++++----------
.../TimeColumn/TimeColumnFilterPlugin.tsx | 7 +-
.../components/TimeGrain/TimeGrainFilterPlugin.tsx | 7 +-
superset-frontend/src/filters/components/common.ts | 7 ++
10 files changed, 120 insertions(+), 91 deletions(-)
diff --git
a/superset-frontend/src/dashboard/components/gridComponents/ChartHolder.jsx
b/superset-frontend/src/dashboard/components/gridComponents/ChartHolder.jsx
index 23365b7..23f46f2 100644
--- a/superset-frontend/src/dashboard/components/gridComponents/ChartHolder.jsx
+++ b/superset-frontend/src/dashboard/components/gridComponents/ChartHolder.jsx
@@ -132,7 +132,7 @@ const FilterFocusHighlight = React.forwardRef(
if (focusedNativeFilterId) {
if (
- nativeFilters.filters[focusedNativeFilterId].chartsInScope?.includes(
+ nativeFilters.filters[focusedNativeFilterId]?.chartsInScope?.includes(
chartId,
)
) {
diff --git
a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/FilterValue.tsx
b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/FilterValue.tsx
index 1bd8cd4..f833e9e 100644
---
a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/FilterValue.tsx
+++
b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/FilterValue.tsx
@@ -44,6 +44,7 @@ import { FilterProps } from './types';
import { getFormData } from '../../utils';
import { useCascadingFilters } from './state';
import { usePreselectNativeFilter } from '../../state';
+import { checkIsMissingRequiredValue } from '../utils';
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) {
filterState.value = preselection;
}
diff --git
a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/DefaultValue.tsx
b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/DefaultValue.tsx
index 0b22dc7..85d5580 100644
---
a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/DefaultValue.tsx
+++
b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/DefaultValue.tsx
@@ -22,6 +22,7 @@ import {
SetDataMaskHook,
SuperChart,
AppSection,
+ t,
} from '@superset-ui/core';
import { FormInstance } from 'antd/lib/form';
import Loading from 'src/components/Loading';
@@ -56,6 +57,10 @@ const DefaultValue: FC<DefaultValueProps> = ({
setLoading(true);
}
}, [hasDataset, queriesData]);
+ const value = formFilter.defaultDataMask?.filterState.value;
+ const isMissingRequiredValue =
+ (value === null || value === undefined) &&
+ formFilter?.controlValues?.enableEmptyFilter;
return loading ? (
<Loading position="inline-centered" />
) : (
@@ -74,6 +79,7 @@ const DefaultValue: FC<DefaultValueProps> = ({
enableNoResults={enableNoResults}
filterState={{
...formFilter.defaultDataMask?.filterState,
+ validateMessage: isMissingRequiredValue && t('Value is required'),
}}
/>
);
diff --git
a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx
b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx
index 5e95d16..306f06b 100644
---
a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx
+++
b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx
@@ -345,13 +345,27 @@ const FiltersConfigForm = (
const hasDataset = !!nativeFilterItems[formFilter?.filterType]?.value
?.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] ?? {};
// @ts-ignore
const enableNoResults = !!nativeFilterItem.value?.enableNoResults;
const datasetId = formFilter?.dataset?.value;
useEffect(() => {
- if (datasetId && hasDataset) {
+ if (datasetId && hasColumn) {
cachedSupersetGet({
endpoint: `/api/v1/dataset/${datasetId}`,
})
@@ -367,7 +381,7 @@ const FiltersConfigForm = (
addDangerToast(response.message);
});
}
- }, [datasetId, hasDataset]);
+ }, [datasetId, hasColumn]);
useImperativeHandle(ref, () => ({
changeTab(tab: 'configuration' | 'scoping') {
@@ -375,10 +389,10 @@ const FiltersConfigForm = (
},
}));
- const hasMetrics = hasDataset && !!metrics.length;
+ const hasMetrics = hasColumn && !!metrics.length;
const hasFilledDataset =
- !hasDataset || (datasetId && (formFilter?.column || !hasDataset));
+ !hasDataset || (datasetId && (formFilter?.column || !hasColumn));
const hasAdditionalFilters = FILTERS_WITH_ADHOC_FILTERS.includes(
formFilter?.filterType,
@@ -477,7 +491,7 @@ const FiltersConfigForm = (
: undefined);
const newFormData = getFormData({
datasetId,
- groupby: hasDataset ? formFilter?.column : undefined,
+ groupby: hasColumn ? formFilter?.column : undefined,
...formFilter,
});
@@ -534,20 +548,10 @@ const FiltersConfigForm = (
const hasSorting =
typeof filterToEdit?.controlValues?.sortAscending === 'boolean';
- const showDefaultValue = !hasDataset || (!isDataDirty && hasFilledDataset);
-
- const { controlItems = {}, mainControlItems = {} } = formFilter
- ? getControlItemsMap({
- disabled: false,
- forceUpdate,
- form,
- filterId,
- filterType: formFilter.filterType,
- filterToEdit,
- formFilter,
- removed,
- })
- : {};
+ const showDefaultValue =
+ !hasDataset ||
+ (!isDataDirty && hasFilledDataset) ||
+ !mainControlItems.groupby;
const onSortChanged = (value: boolean | undefined) => {
const previous = form.getFieldValue('filters')?.[filterId].controlValues;
@@ -683,6 +687,7 @@ const FiltersConfigForm = (
setNativeFilterFieldValues(form, filterId, {
filterType: value,
defaultDataMask: null,
+ column: null,
});
forceUpdate();
}}
@@ -738,13 +743,6 @@ const FiltersConfigForm = (
header={FilterPanels.basic.name}
key={FilterPanels.basic.key}
>
- {hasFilledDataset && (
- <CleanFormItem
- name={['filters', filterId, 'defaultValueFormData']}
- hidden
- initialValue={newFormData}
- />
- )}
<CleanFormItem
name={['filters', filterId, 'defaultValueQueriesData']}
hidden
@@ -760,7 +758,11 @@ const FiltersConfigForm = (
>
<StyledRowSubFormItem
name={['filters', filterId, 'defaultDataMask']}
- initialValue={filterToEdit?.defaultDataMask}
+ initialValue={
+ formFilter.filterType === filterToEdit?.filterType
+ ? filterToEdit?.defaultDataMask
+ : null
+ }
data-test="default-input"
label={<StyledLabel>{t('Default Value')}</StyledLabel>}
required={hasDefaultValue}
diff --git
a/superset-frontend/src/filters/components/GroupBy/GroupByFilterPlugin.tsx
b/superset-frontend/src/filters/components/GroupBy/GroupByFilterPlugin.tsx
index 11739c8..981a928 100644
--- a/superset-frontend/src/filters/components/GroupBy/GroupByFilterPlugin.tsx
+++ b/superset-frontend/src/filters/components/GroupBy/GroupByFilterPlugin.tsx
@@ -19,9 +19,8 @@
import { ensureIsArray, ExtraFormData, styled, t, tn } from
'@superset-ui/core';
import React, { useEffect, useState } from 'react';
import { Select } from 'src/common/components';
-import { Styles, StyledSelect } from '../common';
+import { Styles, StyledSelect, StyledFormItem } from '../common';
import { PluginFilterGroupByProps } from './types';
-import FormItem from '../../../components/Form/FormItem';
const { Option } = Select;
@@ -87,7 +86,7 @@ export default function PluginFilterGroupBy(props:
PluginFilterGroupByProps) {
: tn('%s option', '%s options', columns.length, columns.length);
return (
<Styles height={height} width={width}>
- <FormItem
+ <StyledFormItem
validateStatus={filterState.validateMessage && 'error'}
extra={<Error>{filterState.validateMessage}</Error>}
>
@@ -116,7 +115,7 @@ export default function PluginFilterGroupBy(props:
PluginFilterGroupByProps) {
},
)}
</StyledSelect>
- </FormItem>
+ </StyledFormItem>
</Styles>
);
}
diff --git
a/superset-frontend/src/filters/components/Range/RangeFilterPlugin.tsx
b/superset-frontend/src/filters/components/Range/RangeFilterPlugin.tsx
index f510a62..f742b97 100644
--- a/superset-frontend/src/filters/components/Range/RangeFilterPlugin.tsx
+++ b/superset-frontend/src/filters/components/Range/RangeFilterPlugin.tsx
@@ -26,9 +26,8 @@ import React, { useEffect, useState } from 'react';
import { Slider } from 'src/common/components';
import { rgba } from 'emotion-rgba';
import { PluginFilterRangeProps } from './types';
-import { Styles } from '../common';
+import { StyledFormItem, Styles } from '../common';
import { getRangeExtraFormData } from '../../utils';
-import FormItem from '../../../components/Form/FormItem';
const Error = styled.div`
color: ${({ theme }) => theme.colors.error.base};
@@ -159,7 +158,7 @@ export default function RangeFilterPlugin(props:
PluginFilterRangeProps) {
{Number.isNaN(Number(min)) || Number.isNaN(Number(max)) ? (
<h4>{t('Chosen non-numeric column')}</h4>
) : (
- <FormItem
+ <StyledFormItem
validateStatus={filterState.validateMessage && 'error'}
extra={<Error>{filterState.validateMessage}</Error>}
>
@@ -183,7 +182,7 @@ export default function RangeFilterPlugin(props:
PluginFilterRangeProps) {
marks={marks}
/>
</Wrapper>
- </FormItem>
+ </StyledFormItem>
)}
</Styles>
);
diff --git
a/superset-frontend/src/filters/components/Select/SelectFilterPlugin.tsx
b/superset-frontend/src/filters/components/Select/SelectFilterPlugin.tsx
index 7e4ffaa..9957e5a 100644
--- a/superset-frontend/src/filters/components/Select/SelectFilterPlugin.tsx
+++ b/superset-frontend/src/filters/components/Select/SelectFilterPlugin.tsx
@@ -26,6 +26,7 @@ import {
GenericDataType,
JsonObject,
smartDateDetailedFormatter,
+ styled,
t,
tn,
} from '@superset-ui/core';
@@ -44,11 +45,15 @@ import { useImmerReducer } from 'use-immer';
import Icons from 'src/components/Icons';
import { usePrevious } from 'src/common/hooks/usePrevious';
import { PluginFilterSelectProps, SelectValue } from './types';
-import { StyledSelect, Styles } from '../common';
+import { StyledFormItem, StyledSelect, Styles } from '../common';
import { getDataRecordFormatter, getSelectExtraFormData } from '../../utils';
const { Option } = Select;
+const Error = styled.div`
+ color: ${({ theme }) => theme.colors.error.base};
+`;
+
type DataMaskAction =
| { type: 'ownState'; ownState: JsonObject }
| {
@@ -273,52 +278,57 @@ export default function PluginFilterSelect(props:
PluginFilterSelectProps) {
return (
<Styles height={height} width={width}>
- <StyledSelect
- allowClear
- // @ts-ignore
- 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" />}
+ <StyledFormItem
+ validateStatus={filterState.validateMessage && 'error'}
+ extra={<Error>{filterState.validateMessage}</Error>}
>
- {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>
+ <StyledSelect
+ allowClear
+ // @ts-ignore
+ 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 => {
+ 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>
);
}
diff --git
a/superset-frontend/src/filters/components/TimeColumn/TimeColumnFilterPlugin.tsx
b/superset-frontend/src/filters/components/TimeColumn/TimeColumnFilterPlugin.tsx
index 7ea97ed..48629da 100644
---
a/superset-frontend/src/filters/components/TimeColumn/TimeColumnFilterPlugin.tsx
+++
b/superset-frontend/src/filters/components/TimeColumn/TimeColumnFilterPlugin.tsx
@@ -26,9 +26,8 @@ import {
} from '@superset-ui/core';
import React, { useEffect, useState } from 'react';
import { Select } from 'src/common/components';
-import { Styles, StyledSelect } from '../common';
+import { Styles, StyledSelect, StyledFormItem } from '../common';
import { PluginFilterTimeColumnProps } from './types';
-import FormItem from '../../../components/Form/FormItem';
const { Option } = Select;
@@ -89,7 +88,7 @@ export default function PluginFilterTimeColumn(
: tn('%s option', '%s options', timeColumns.length, timeColumns.length);
return (
<Styles height={height} width={width}>
- <FormItem
+ <StyledFormItem
validateStatus={filterState.validateMessage && 'error'}
extra={<Error>{filterState.validateMessage}</Error>}
>
@@ -117,7 +116,7 @@ export default function PluginFilterTimeColumn(
},
)}
</StyledSelect>
- </FormItem>
+ </StyledFormItem>
</Styles>
);
}
diff --git
a/superset-frontend/src/filters/components/TimeGrain/TimeGrainFilterPlugin.tsx
b/superset-frontend/src/filters/components/TimeGrain/TimeGrainFilterPlugin.tsx
index a2c4a18..d02e7ac 100644
---
a/superset-frontend/src/filters/components/TimeGrain/TimeGrainFilterPlugin.tsx
+++
b/superset-frontend/src/filters/components/TimeGrain/TimeGrainFilterPlugin.tsx
@@ -26,9 +26,8 @@ import {
} from '@superset-ui/core';
import React, { useEffect, useMemo, useState } from 'react';
import { Select } from 'src/common/components';
-import { Styles, StyledSelect } from '../common';
+import { Styles, StyledSelect, StyledFormItem } from '../common';
import { PluginFilterTimeGrainProps } from './types';
-import FormItem from '../../../components/Form/FormItem';
const { Option } = Select;
@@ -99,7 +98,7 @@ export default function PluginFilterTimegrain(
: tn('%s option', '%s options', data.length, data.length);
return (
<Styles height={height} width={width}>
- <FormItem
+ <StyledFormItem
validateStatus={filterState.validateMessage && 'error'}
extra={<Error>{filterState.validateMessage}</Error>}
>
@@ -122,7 +121,7 @@ export default function PluginFilterTimegrain(
);
})}
</StyledSelect>
- </FormItem>
+ </StyledFormItem>
</Styles>
);
}
diff --git a/superset-frontend/src/filters/components/common.ts
b/superset-frontend/src/filters/components/common.ts
index 5d0046e..1efafac 100644
--- a/superset-frontend/src/filters/components/common.ts
+++ b/superset-frontend/src/filters/components/common.ts
@@ -19,6 +19,7 @@
import { styled } from '@superset-ui/core';
import { Select } from 'src/common/components';
import { PluginFilterStylesProps } from './types';
+import FormItem from '../../components/Form/FormItem';
export const Styles = styled.div<PluginFilterStylesProps>`
min-height: ${({ height }) => height}px;
@@ -28,3 +29,9 @@ export const Styles = styled.div<PluginFilterStylesProps>`
export const StyledSelect = styled(Select)`
width: 100%;
`;
+
+export const StyledFormItem = styled(FormItem)`
+ &.ant-row.ant-form-item {
+ margin: 0;
+ }
+`;