From a6d54b681bea0b7632ae643a43ba8c8c1ceaa2f7 Mon Sep 17 00:00:00 2001 From: "Michael S. Molina" <70410625+michael-s-molina@users.noreply.github.com> Date: Thu, 27 May 2021 07:37:36 -0300 Subject: [PATCH] chore: Improves the native filters UI/UX - iteration 4 (#14854) --- .../FiltersConfigForm/FiltersConfigForm.tsx | 119 ++++++++++++++++-- .../FiltersConfigModal/FiltersConfigModal.tsx | 39 ++++-- .../nativeFilters/FiltersConfigModal/utils.ts | 14 +-- 3 files changed, 135 insertions(+), 37 deletions(-) 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 f200ee1860..8672d0e09d 100644 --- a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx +++ b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx @@ -32,7 +32,14 @@ import { Metric, } from '@superset-ui/chart-controls'; import { FormInstance } from 'antd/lib/form'; -import React, { useCallback, useEffect, useState, useMemo } from 'react'; +import React, { + useCallback, + useEffect, + useState, + useMemo, + forwardRef, + useImperativeHandle, +} from 'react'; import { useSelector } from 'react-redux'; import { Checkbox, Form, Input } from 'src/common/components'; import { Select } from 'src/components/Select'; @@ -153,6 +160,12 @@ const StyledTabs = styled(Tabs)` } `; +const StyledAsterisk = styled.span` + color: ${({ theme }) => theme.colors.error.base}; + font-family: SimSun, sans-serif; + margin-right: ${({ theme }) => theme.gridUnit - 1}px; +`; + const FilterTabs = { configuration: { key: 'configuration', @@ -199,15 +212,19 @@ const BASIC_CONTROL_ITEMS = ['enableEmptyFilter', 'multiSelect']; * The configuration form for a specific filter. * Assigns field values to `filters[filterId]` in the form. */ -export const FiltersConfigForm: React.FC = ({ - filterId, - filterToEdit, - removed, - restoreFilter, - form, - parentFilters, -}) => { +const FiltersConfigForm = ( + { + filterId, + filterToEdit, + removed, + restoreFilter, + form, + parentFilters, + }: FiltersConfigFormProps, + ref: React.RefObject, +) => { const [metrics, setMetrics] = useState([]); + const [activeTabKey, setActiveTabKey] = useState(); const [hasDefaultValue, setHasDefaultValue] = useState( !!filterToEdit?.defaultDataMask?.filterState?.value, ); @@ -257,6 +274,12 @@ export const FiltersConfigForm: React.FC = ({ } }, [datasetId, hasColumn]); + useImperativeHandle(ref, () => ({ + changeTab(tab: 'configuration' | 'scoping') { + setActiveTabKey(tab); + }, + })); + const hasMetrics = hasColumn && !!metrics.length; const hasFilledDataset = @@ -374,7 +397,7 @@ export const FiltersConfigForm: React.FC = ({ const controlItems = formFilter ? getControlItemsMap({ - disabled: !showDefaultValue, + disabled: false, forceUpdate, form, filterId, @@ -396,7 +419,12 @@ export const FiltersConfigForm: React.FC = ({ return ( <> - + setActiveTabKey(activeKey)} + centered + > = ({ initialValue={filterToEdit?.defaultDataMask} data-test="default-input" label={{t('Default Value')}} + required + rules={[ + { + required: true, + }, + { + validator: (rule, value) => { + const hasValue = !!value.filterState?.value; + if (hasValue) { + return Promise.resolve(); + } + return Promise.reject( + new Error(t('Default value is required')), + ); + }, + }, + ]} > {showDefaultValue ? ( = ({ setNativeFilterFieldValues(form, filterId, { defaultDataMask: dataMask, }); + form.validateFields([ + ['filters', filterId, 'defaultDataMask'], + ]); forceUpdate(); }} filterId={filterId} @@ -565,12 +613,31 @@ export const FiltersConfigForm: React.FC = ({ { + if (checked) { + // execute after render + setTimeout( + () => + form.validateFields([ + ['filters', filterId, 'parentFilter'], + ]), + 0, + ); + } + }} > {t('Parent filter')}} initialValue={parentFilter} data-test="parent-filter-input" + required + rules={[ + { + required: true, + message: t('Parent filter is required'), + }, + ]} >