From 6eb04b1c4f5cc4a0ea8d9e72f7272d30a12392d9 Mon Sep 17 00:00:00 2001 From: Simcha Shats Date: Tue, 13 Apr 2021 16:04:01 +0300 Subject: [PATCH 1/4] fix:fix get permission function --- .../src/dashboard/util/getPermissions.ts | 37 +++++++++---------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/superset-frontend/src/dashboard/util/getPermissions.ts b/superset-frontend/src/dashboard/util/getPermissions.ts index 3e7cb19765dd..0208fd68fd65 100644 --- a/superset-frontend/src/dashboard/util/getPermissions.ts +++ b/superset-frontend/src/dashboard/util/getPermissions.ts @@ -18,25 +18,22 @@ */ import memoizeOne from 'memoize-one'; -export default function getPermissions( - perm: string, - view: string, - roles: object, -) { - return memoizeOne(() => { - const roleList = Object.entries(roles); - if (roleList.length === 0) return false; - let bool; +const findPermissions = (perm: string, view: string, roles: object) => { + const roleList = Object.entries(roles); + if (roleList.length === 0) return false; + let bool; - roleList.forEach(([role, permissions]) => { - bool = Boolean( - permissions.find( - (permission: Array) => - permission[0] === perm && permission[1] === view, - ), - ); - }); - console.log('bool', bool); - return bool; + roleList.forEach(([role, permissions]) => { + bool = Boolean( + permissions.find( + (permission: Array) => + permission[0] === perm && permission[1] === view, + ), + ); }); -} + return bool; +}; + +const getPermissions = memoizeOne(findPermissions); + +export default getPermissions; From 13741fc833380da71856ee2899fb553e15940f4e Mon Sep 17 00:00:00 2001 From: Simcha Shats Date: Mon, 21 Jun 2021 09:45:12 +0300 Subject: [PATCH 2/4] feat: show error status for required filters --- .../FilterBar/FilterControls/FilterValue.tsx | 3 +- .../GroupBy/GroupByFilterPlugin.tsx | 57 +++++++----- .../components/GroupBy/controlPanel.ts | 12 +++ .../components/Range/RangeFilterPlugin.tsx | 91 ++++++++++++++++--- .../filters/components/Range/controlPanel.ts | 18 ++++ .../components/Select/SelectFilterPlugin.tsx | 2 +- .../filters/components/Select/controlPanel.ts | 5 +- .../components/Time/TimeFilterPlugin.tsx | 32 ++++++- .../filters/components/Time/controlPanel.ts | 22 ++++- .../TimeColumn/TimeColumnFilterPlugin.tsx | 54 +++++++---- .../components/TimeColumn/controlPanel.ts | 22 ++++- .../TimeGrain/TimeGrainFilterPlugin.tsx | 47 ++++++---- .../components/TimeGrain/controlPanel.ts | 22 ++++- 13 files changed, 299 insertions(+), 88 deletions(-) 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 8c7485239210..20b18d453ac4 100644 --- a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/FilterValue.tsx +++ b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/FilterValue.tsx @@ -193,7 +193,7 @@ const FilterValue: React.FC = ({ ) : ( = ({ filterState={{ ...filter.dataMask?.filterState, validateMessage: isMissingRequiredValue && t('Value is required'), - validateStatus: isMissingRequiredValue && 'error', }} ownState={filter.dataMask?.ownState} enableNoResults={metadata?.enableNoResults} diff --git a/superset-frontend/src/filters/components/GroupBy/GroupByFilterPlugin.tsx b/superset-frontend/src/filters/components/GroupBy/GroupByFilterPlugin.tsx index ce67cdc72791..6e8a3bfb566c 100644 --- a/superset-frontend/src/filters/components/GroupBy/GroupByFilterPlugin.tsx +++ b/superset-frontend/src/filters/components/GroupBy/GroupByFilterPlugin.tsx @@ -16,14 +16,19 @@ * specific language governing permissions and limitations * under the License. */ -import { ensureIsArray, ExtraFormData, t, tn } from '@superset-ui/core'; +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 { PluginFilterGroupByProps } from './types'; +import FormItem from '../../../components/Form/FormItem'; const { Option } = Select; +const Error = styled.div` + color: ${({ theme }) => theme.colors.error.base}; +`; + export default function PluginFilterGroupBy(props: PluginFilterGroupByProps) { const { data, @@ -70,28 +75,36 @@ export default function PluginFilterGroupBy(props: PluginFilterGroupByProps) { : tn('%s option', '%s options', columns.length, columns.length); return ( - {filterState.validateMessage}} > - {columns.map( - (row: { column_name: string; verbose_name: string | null }) => { - const { column_name: columnName, verbose_name: verboseName } = row; - return ( - - ); - }, - )} - + + {columns.map( + (row: { column_name: string; verbose_name: string | null }) => { + const { + column_name: columnName, + verbose_name: verboseName, + } = row; + return ( + + ); + }, + )} + + ); } diff --git a/superset-frontend/src/filters/components/GroupBy/controlPanel.ts b/superset-frontend/src/filters/components/GroupBy/controlPanel.ts index 5b9b898e6487..970683ec803e 100644 --- a/superset-frontend/src/filters/components/GroupBy/controlPanel.ts +++ b/superset-frontend/src/filters/components/GroupBy/controlPanel.ts @@ -44,6 +44,18 @@ const config: ControlPanelConfig = { }, }, ], + [ + { + name: 'enableEmptyFilter', + config: { + type: 'CheckboxControl', + label: t('Required'), + default: false, + renderTrigger: true, + description: t('User must select a value for this filter.'), + }, + }, + ], ], }, ], diff --git a/superset-frontend/src/filters/components/Range/RangeFilterPlugin.tsx b/superset-frontend/src/filters/components/Range/RangeFilterPlugin.tsx index 8d88e516bc70..0feeb32154f4 100644 --- a/superset-frontend/src/filters/components/Range/RangeFilterPlugin.tsx +++ b/superset-frontend/src/filters/components/Range/RangeFilterPlugin.tsx @@ -16,12 +16,62 @@ * specific language governing permissions and limitations * under the License. */ -import { getNumberFormatter, NumberFormats, t } from '@superset-ui/core'; +import { + getNumberFormatter, + NumberFormats, + styled, + t, +} from '@superset-ui/core'; import React, { useEffect, useState } from 'react'; import { Slider } from 'src/common/components'; import { PluginFilterRangeProps } from './types'; import { Styles } from '../common'; import { getRangeExtraFormData } from '../../utils'; +import FormItem from '../../../components/Form/FormItem'; + +const Error = styled.div` + color: ${({ theme }) => theme.colors.error.base}; +`; + +const Wrapper = styled.div<{ validateStatus?: string }>` + border: 1px solid transparent; + &:focus { + border: 1px solid + ${({ theme, validateStatus }) => + validateStatus ? theme.colors.error.base : theme.colors.primary.base}; + outline: 0; + box-shadow: 0 0 0 5px + ${({ validateStatus }) => + validateStatus ? 'rgba(224, 67, 85, 12%)' : 'rgba(224, 67, 85, 12%)'}; + } + & .ant-slider { + & .ant-slider-track { + background-color: ${({ theme, validateStatus }) => + validateStatus && theme.colors.error.light1}; + } + & .ant-slider-handle { + border: ${({ theme, validateStatus }) => + validateStatus && `2px solid ${theme.colors.error.light1}`}; + &:focus { + box-shadow: 0 0 0 5px + ${({ validateStatus }) => + validateStatus + ? 'rgba(224, 67, 85, 12%)' + : 'rgba(32, 167, 201, 0.2)'}; + } + } + &:hover { + & .ant-slider-track { + background-color: ${({ theme, validateStatus }) => + validateStatus && theme.colors.error.base}; + } + & .ant-slider-handle { + border: ${({ theme, validateStatus }) => + validateStatus && `2px solid ${theme.colors.error.base}`}; + } + } + } +`; export default function RangeFilterPlugin(props: PluginFilterRangeProps) { const { @@ -32,7 +82,6 @@ export default function RangeFilterPlugin(props: PluginFilterRangeProps) { setDataMask, setFocusedFilter, unsetFocusedFilter, - inputRef, filterState, } = props; const numberFormatter = getNumberFormatter(NumberFormats.SMART_NUMBER); @@ -40,7 +89,7 @@ export default function RangeFilterPlugin(props: PluginFilterRangeProps) { const [row] = data; // @ts-ignore const { min, max }: { min: number; max: number } = row; - const { groupby, defaultValue } = formData; + const { groupby, defaultValue, inputRef } = formData; const [col = ''] = groupby || []; const [value, setValue] = useState<[number, number]>( defaultValue ?? [min, max], @@ -111,19 +160,31 @@ export default function RangeFilterPlugin(props: PluginFilterRangeProps) { {Number.isNaN(Number(min)) || Number.isNaN(Number(max)) ? (

{t('Chosen non-numeric column')}

) : ( -
- numberFormatter(value)} + {filterState.validateMessage}} + > + -
+ validateStatus={filterState.validateMessage} + onFocus={setFocusedFilter} + onBlur={unsetFocusedFilter} + onMouseEnter={setFocusedFilter} + onMouseLeave={unsetFocusedFilter} + > + numberFormatter(value)} + marks={marks} + /> + + )} ); diff --git a/superset-frontend/src/filters/components/Range/controlPanel.ts b/superset-frontend/src/filters/components/Range/controlPanel.ts index 8f9501d7a507..ad2ecfc4c4ae 100644 --- a/superset-frontend/src/filters/components/Range/controlPanel.ts +++ b/superset-frontend/src/filters/components/Range/controlPanel.ts @@ -43,6 +43,24 @@ const config: ControlPanelConfig = { ], ], }, + { + label: t('UI Configuration'), + expanded: true, + controlSetRows: [ + [ + { + name: 'enableEmptyFilter', + config: { + type: 'CheckboxControl', + label: t('Required'), + default: false, + renderTrigger: true, + description: t('User must select a value for this filter.'), + }, + }, + ], + ], + }, ], }; diff --git a/superset-frontend/src/filters/components/Select/SelectFilterPlugin.tsx b/superset-frontend/src/filters/components/Select/SelectFilterPlugin.tsx index 8b01d0faf7f4..8e4f96cafc03 100644 --- a/superset-frontend/src/filters/components/Select/SelectFilterPlugin.tsx +++ b/superset-frontend/src/filters/components/Select/SelectFilterPlugin.tsx @@ -280,7 +280,7 @@ export default function PluginFilterSelect(props: PluginFilterSelectProps) { return ( {filterState.validateMessage}} > ` + padding: 2px; + & > span { + border: 2px solid transparent; + display: inline-block; + border: ${({ theme, validateStatus }) => + validateStatus && `2px solid ${theme.colors.error.base}`}; + } + &:focus { + & > span { + border: 2px solid + ${({ theme, validateStatus }) => + validateStatus ? theme.colors.error.base : theme.colors.primary.base}; + outline: 0; + box-shadow: 0 0 0 2px + ${({ validateStatus }) => + validateStatus + ? 'rgba(224, 67, 85, 12%)' + : 'rgba(32, 167, 201, 0.2)'}; + } + } `; export default function TimeFilterPlugin(props: PluginFilterTimeProps) { @@ -37,7 +56,9 @@ export default function TimeFilterPlugin(props: PluginFilterTimeProps) { setFocusedFilter, unsetFocusedFilter, width, + height, filterState, + formData: { inputRef }, } = props; const handleTimeRangeChange = (timeRange?: string): void => { @@ -60,8 +81,13 @@ export default function TimeFilterPlugin(props: PluginFilterTimeProps) { return ( // @ts-ignore - + diff --git a/superset-frontend/src/filters/components/Time/controlPanel.ts b/superset-frontend/src/filters/components/Time/controlPanel.ts index 1b5f12b9a78c..466991f79b4e 100644 --- a/superset-frontend/src/filters/components/Time/controlPanel.ts +++ b/superset-frontend/src/filters/components/Time/controlPanel.ts @@ -17,10 +17,30 @@ * under the License. */ import { ControlPanelConfig } from '@superset-ui/chart-controls'; +import { t } from '@superset-ui/core'; const config: ControlPanelConfig = { // For control input types, see: superset-frontend/src/explore/components/controls/index.js - controlPanelSections: [], + controlPanelSections: [ + { + label: t('UI Configuration'), + expanded: true, + controlSetRows: [ + [ + { + name: 'enableEmptyFilter', + config: { + type: 'CheckboxControl', + label: t('Required'), + default: false, + renderTrigger: true, + description: t('User must select a value for this filter.'), + }, + }, + ], + ], + }, + ], }; export default config; diff --git a/superset-frontend/src/filters/components/TimeColumn/TimeColumnFilterPlugin.tsx b/superset-frontend/src/filters/components/TimeColumn/TimeColumnFilterPlugin.tsx index 08456baa85d3..7ea97edeb0d6 100644 --- a/superset-frontend/src/filters/components/TimeColumn/TimeColumnFilterPlugin.tsx +++ b/superset-frontend/src/filters/components/TimeColumn/TimeColumnFilterPlugin.tsx @@ -20,6 +20,7 @@ import { ensureIsArray, ExtraFormData, GenericDataType, + styled, t, tn, } from '@superset-ui/core'; @@ -27,9 +28,14 @@ import React, { useEffect, useState } from 'react'; import { Select } from 'src/common/components'; import { Styles, StyledSelect } from '../common'; import { PluginFilterTimeColumnProps } from './types'; +import FormItem from '../../../components/Form/FormItem'; const { Option } = Select; +const Error = styled.div` + color: ${({ theme }) => theme.colors.error.base}; +`; + export default function PluginFilterTimeColumn( props: PluginFilterTimeColumnProps, ) { @@ -83,27 +89,35 @@ export default function PluginFilterTimeColumn( : tn('%s option', '%s options', timeColumns.length, timeColumns.length); return ( - {filterState.validateMessage}} > - {timeColumns.map( - (row: { column_name: string; verbose_name: string | null }) => { - const { column_name: columnName, verbose_name: verboseName } = row; - return ( - - ); - }, - )} - + + {timeColumns.map( + (row: { column_name: string; verbose_name: string | null }) => { + const { + column_name: columnName, + verbose_name: verboseName, + } = row; + return ( + + ); + }, + )} + + ); } diff --git a/superset-frontend/src/filters/components/TimeColumn/controlPanel.ts b/superset-frontend/src/filters/components/TimeColumn/controlPanel.ts index 5b7bc3dc3bb3..448c0cea69ac 100644 --- a/superset-frontend/src/filters/components/TimeColumn/controlPanel.ts +++ b/superset-frontend/src/filters/components/TimeColumn/controlPanel.ts @@ -17,9 +17,29 @@ * under the License. */ import { ControlPanelConfig } from '@superset-ui/chart-controls'; +import { t } from '@superset-ui/core'; const config: ControlPanelConfig = { - controlPanelSections: [], + controlPanelSections: [ + { + label: t('UI Configuration'), + expanded: true, + controlSetRows: [ + [ + { + name: 'enableEmptyFilter', + config: { + type: 'CheckboxControl', + label: t('Required'), + default: false, + renderTrigger: true, + description: t('User must select a value for this filter.'), + }, + }, + ], + ], + }, + ], }; export default config; diff --git a/superset-frontend/src/filters/components/TimeGrain/TimeGrainFilterPlugin.tsx b/superset-frontend/src/filters/components/TimeGrain/TimeGrainFilterPlugin.tsx index aabc86786fda..1cde951a62e2 100644 --- a/superset-frontend/src/filters/components/TimeGrain/TimeGrainFilterPlugin.tsx +++ b/superset-frontend/src/filters/components/TimeGrain/TimeGrainFilterPlugin.tsx @@ -19,6 +19,7 @@ import { ensureIsArray, ExtraFormData, + styled, t, TimeGranularity, tn, @@ -27,9 +28,14 @@ import React, { useEffect, useState } from 'react'; import { Select } from 'src/common/components'; import { Styles, StyledSelect } from '../common'; import { PluginFilterTimeGrainProps } from './types'; +import FormItem from '../../../components/Form/FormItem'; const { Option } = Select; +const Error = styled.div` + color: ${({ theme }) => theme.colors.error.base}; +`; + export default function PluginFilterTimegrain( props: PluginFilterTimeGrainProps, ) { @@ -80,25 +86,30 @@ export default function PluginFilterTimegrain( : tn('%s option', '%s options', data.length, data.length); return ( - {filterState.validateMessage}} > - {(data || []).map((row: { name: string; duration: string }) => { - const { name, duration } = row; - return ( - - ); - })} - + + {(data || []).map((row: { name: string; duration: string }) => { + const { name, duration } = row; + return ( + + ); + })} + + ); } diff --git a/superset-frontend/src/filters/components/TimeGrain/controlPanel.ts b/superset-frontend/src/filters/components/TimeGrain/controlPanel.ts index 5b7bc3dc3bb3..448c0cea69ac 100644 --- a/superset-frontend/src/filters/components/TimeGrain/controlPanel.ts +++ b/superset-frontend/src/filters/components/TimeGrain/controlPanel.ts @@ -17,9 +17,29 @@ * under the License. */ import { ControlPanelConfig } from '@superset-ui/chart-controls'; +import { t } from '@superset-ui/core'; const config: ControlPanelConfig = { - controlPanelSections: [], + controlPanelSections: [ + { + label: t('UI Configuration'), + expanded: true, + controlSetRows: [ + [ + { + name: 'enableEmptyFilter', + config: { + type: 'CheckboxControl', + label: t('Required'), + default: false, + renderTrigger: true, + description: t('User must select a value for this filter.'), + }, + }, + ], + ], + }, + ], }; export default config; From 7ff5896b5c07ed90e0598aaad8fed90240a3177f Mon Sep 17 00:00:00 2001 From: Simcha Shats Date: Mon, 21 Jun 2021 10:34:50 +0300 Subject: [PATCH 3/4] test: fix tests --- .../FiltersConfigModal/FiltersConfigModal.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigModal.test.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigModal.test.tsx index 80729cb46a40..caba35a7d7d8 100644 --- a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigModal.test.tsx +++ b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigModal.test.tsx @@ -191,13 +191,13 @@ test('renders a numerical range filter type', () => { expect(screen.getByText(FILTER_NAME_REGEX)).toBeInTheDocument(); expect(screen.getByText(DATASET_REGEX)).toBeInTheDocument(); expect(screen.getByText(COLUMN_REGEX)).toBeInTheDocument(); + expect(screen.getByText(REQUIRED_REGEX)).toBeInTheDocument(); expect(getCheckbox(DEFAULT_VALUE_REGEX)).not.toBeChecked(); expect(getCheckbox(APPLY_INSTANTLY_REGEX)).not.toBeChecked(); expect(getCheckbox(PRE_FILTER_REGEX)).not.toBeChecked(); expect(queryCheckbox(MULTIPLE_REGEX)).not.toBeInTheDocument(); - expect(queryCheckbox(REQUIRED_REGEX)).not.toBeInTheDocument(); expect(queryCheckbox(HIERARCHICAL_REGEX)).not.toBeInTheDocument(); expect(queryCheckbox(FIRST_ITEM_REGEX)).not.toBeInTheDocument(); expect(queryCheckbox(INVERSE_SELECTION_REGEX)).not.toBeInTheDocument(); From 46ab39602b637fc7f68799fc79a42ac3cd495514 Mon Sep 17 00:00:00 2001 From: Simcha Shats Date: Tue, 22 Jun 2021 13:55:30 +0300 Subject: [PATCH 4/4] refactor: fix CR notes --- superset-frontend/package-lock.json | 11 +++++++++++ superset-frontend/package.json | 1 + .../FiltersConfigForm/DefaultValue.tsx | 11 +++++++++-- .../FiltersConfigForm/FiltersConfigForm.tsx | 4 +--- .../components/Range/RangeFilterPlugin.tsx | 17 ++++++++--------- 5 files changed, 30 insertions(+), 14 deletions(-) diff --git a/superset-frontend/package-lock.json b/superset-frontend/package-lock.json index 76cdea3b39df..748d37b13413 100644 --- a/superset-frontend/package-lock.json +++ b/superset-frontend/package-lock.json @@ -58,6 +58,7 @@ "d3-color": "^1.2.0", "d3-scale": "^2.1.2", "dom-to-image": "^2.6.0", + "emotion-rgba": "0.0.9", "fontsource-fira-code": "^3.0.5", "fontsource-inter": "^3.0.5", "geolib": "^2.0.24", @@ -25709,6 +25710,11 @@ "node": ">= 0.10" } }, + "node_modules/emotion-rgba": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/emotion-rgba/-/emotion-rgba-0.0.9.tgz", + "integrity": "sha512-fSt51Lh4a1fppXY3nQrMUC00p1jIYMSaRRkUhPiOJ3s9oumae1tY41AJytRK9d4YmJDP9njJBndgdDn9j7CbsA==" + }, "node_modules/emotion-theming": { "version": "10.0.27", "resolved": "https://registry.npmjs.org/emotion-theming/-/emotion-theming-10.0.27.tgz", @@ -76525,6 +76531,11 @@ "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", "dev": true }, + "emotion-rgba": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/emotion-rgba/-/emotion-rgba-0.0.9.tgz", + "integrity": "sha512-fSt51Lh4a1fppXY3nQrMUC00p1jIYMSaRRkUhPiOJ3s9oumae1tY41AJytRK9d4YmJDP9njJBndgdDn9j7CbsA==" + }, "emotion-theming": { "version": "10.0.27", "resolved": "https://registry.npmjs.org/emotion-theming/-/emotion-theming-10.0.27.tgz", diff --git a/superset-frontend/package.json b/superset-frontend/package.json index 772433968b71..ca806803d9c4 100644 --- a/superset-frontend/package.json +++ b/superset-frontend/package.json @@ -110,6 +110,7 @@ "d3-color": "^1.2.0", "d3-scale": "^2.1.2", "dom-to-image": "^2.6.0", + "emotion-rgba": "0.0.9", "fontsource-fira-code": "^3.0.5", "fontsource-inter": "^3.0.5", "geolib": "^2.0.24", 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 d4b0ed84c706..85d55807b267 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,7 +57,10 @@ const DefaultValue: FC = ({ setLoading(true); } }, [hasDataset, queriesData]); - + const value = formFilter.defaultDataMask?.filterState.value; + const isMissingRequiredValue = + (value === null || value === undefined) && + formFilter?.controlValues?.enableEmptyFilter; return loading ? ( ) : ( @@ -73,7 +77,10 @@ const DefaultValue: FC = ({ chartType={formFilter?.filterType} hooks={{ setDataMask }} enableNoResults={enableNoResults} - filterState={formFilter.defaultDataMask?.filterState} + 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 aa83b8bbb879..e8d46248dce6 100644 --- a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx +++ b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx @@ -735,9 +735,7 @@ const FiltersConfigForm = ( ) { return Promise.resolve(); } - return Promise.reject( - new Error(t('Default value is required')), - ); + return Promise.reject(); }, }, ]} diff --git a/superset-frontend/src/filters/components/Range/RangeFilterPlugin.tsx b/superset-frontend/src/filters/components/Range/RangeFilterPlugin.tsx index 0feeb32154f4..f510a6275f31 100644 --- a/superset-frontend/src/filters/components/Range/RangeFilterPlugin.tsx +++ b/superset-frontend/src/filters/components/Range/RangeFilterPlugin.tsx @@ -24,6 +24,7 @@ import { } from '@superset-ui/core'; 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 { getRangeExtraFormData } from '../../utils'; @@ -38,11 +39,11 @@ const Wrapper = styled.div<{ validateStatus?: string }>` &:focus { border: 1px solid ${({ theme, validateStatus }) => - validateStatus ? theme.colors.error.base : theme.colors.primary.base}; + theme.colors[validateStatus ? 'error' : 'primary'].base}; outline: 0; - box-shadow: 0 0 0 5px - ${({ validateStatus }) => - validateStatus ? 'rgba(224, 67, 85, 12%)' : 'rgba(224, 67, 85, 12%)'}; + box-shadow: 0 0 0 3px + ${({ theme, validateStatus }) => + rgba(theme.colors[validateStatus ? 'error' : 'primary'].base, 0.2)}; } & .ant-slider { & .ant-slider-track { @@ -53,11 +54,9 @@ const Wrapper = styled.div<{ validateStatus?: string }>` border: ${({ theme, validateStatus }) => validateStatus && `2px solid ${theme.colors.error.light1}`}; &:focus { - box-shadow: 0 0 0 5px - ${({ validateStatus }) => - validateStatus - ? 'rgba(224, 67, 85, 12%)' - : 'rgba(32, 167, 201, 0.2)'}; + box-shadow: 0 0 0 3px + ${({ theme, validateStatus }) => + rgba(theme.colors[validateStatus ? 'error' : 'primary'].base, 0.2)}; } } &:hover {