diff --git a/superset-frontend/src/components/Form/FormItem.tsx b/superset-frontend/src/components/Form/FormItem.tsx index ab301a883e543..9b529dbd5d141 100644 --- a/superset-frontend/src/components/Form/FormItem.tsx +++ b/superset-frontend/src/components/Form/FormItem.tsx @@ -35,7 +35,7 @@ const StyledItem = styled(Form.Item)` &::after { display: inline-block; color: ${theme.colors.error.base}; - font-size: ${theme.typography.sizes.m}px; + font-size: ${theme.typography.sizes.s}px; content: '*'; } } diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterBar.test.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterBar.test.tsx index 3cfb259a99ecc..d666c975fa5e5 100644 --- a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterBar.test.tsx +++ b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterBar.test.tsx @@ -76,8 +76,8 @@ const addFilterFlow = async () => { userEvent.click(screen.getByTestId(getTestId('collapsable'))); userEvent.click(screen.getByTestId(getTestId('create-filter'))); // select filter - userEvent.click(screen.getByText('Select filter')); - userEvent.click(screen.getByText('Time filter')); + userEvent.click(screen.getByText('Value')); + userEvent.click(screen.getByText('Time range')); userEvent.type(screen.getByTestId(getModalTestId('name-input')), FILTER_NAME); userEvent.click(screen.getByText('Save')); await screen.findByText('All Filters (1)'); diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FilterTabs.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FilterTabs.tsx index 5020b564396e1..ccb0e009fb081 100644 --- a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FilterTabs.tsx +++ b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FilterTabs.tsx @@ -42,11 +42,9 @@ export const StyledFilterTitle = styled.span` export const StyledAddFilterBox = styled.div` color: ${({ theme }) => theme.colors.primary.dark1}; - text-align: left; - padding: ${({ theme }) => theme.gridUnit * 2}px 0; - margin: ${({ theme }) => theme.gridUnit * 3}px 0 0 - ${({ theme }) => -theme.gridUnit * 2}px; - border-top: 1px solid ${({ theme }) => theme.colors.grayscale.light1}; + padding: ${({ theme }) => theme.gridUnit * 2}px; + border-top: 1px solid ${({ theme }) => theme.colors.grayscale.light2}; + cursor: pointer; &:hover { color: ${({ theme }) => theme.colors.primary.base}; @@ -89,12 +87,19 @@ const FilterTabsContainer = styled(LineEditableTabs)` & > .ant-tabs-content-holder { border-left: 1px solid ${theme.colors.grayscale.light2}; - margin-right: ${theme.gridUnit * 4}px; + padding-right: ${theme.gridUnit * 4}px; + overflow-x: hidden; + overflow-y: auto; } + & > .ant-tabs-content-holder ~ .ant-tabs-content-holder { border: none; } + &.ant-tabs-card > .ant-tabs-nav .ant-tabs-ink-bar { + visibility: hidden; + } + &.ant-tabs-left > .ant-tabs-content-holder > .ant-tabs-content @@ -104,9 +109,11 @@ const FilterTabsContainer = styled(LineEditableTabs)` } .ant-tabs-nav-list { - padding-top: ${theme.gridUnit * 4}px; - padding-right: ${theme.gridUnit * 2}px; - padding-bottom: ${theme.gridUnit * 4}px; + overflow-x: hidden; + overflow-y: auto; + padding-top: ${theme.gridUnit * 2}px; + padding-right: ${theme.gridUnit}px; + padding-bottom: ${theme.gridUnit * 3}px; padding-left: ${theme.gridUnit * 3}px; } @@ -135,6 +142,24 @@ const FilterTabsContainer = styled(LineEditableTabs)` justify-content: space-between; text-transform: unset; } + + .ant-tabs-nav-more { + display: none; + } + + .ant-tabs-extra-content { + width: 100%; + } + `} +`; + +const StyledHeader = styled.div` + ${({ theme }) => ` + color: ${theme.colors.grayscale.dark1}; + font-size: ${theme.typography.sizes.l}px; + padding-top: ${theme.gridUnit * 4}px; + padding-right: ${theme.gridUnit * 4}px; + padding-left: ${theme.gridUnit * 4}px; `} `; @@ -164,14 +189,18 @@ const FilterTabs: FC = ({ onChange={onChange} activeKey={currentFilterId} onEdit={onEdit} - addIcon={ - - {' '} - - {t('Add filter')} - - - } + hideAdd + tabBarExtraContent={{ + left: {t('Filters')}, + right: ( + onEdit('', 'add')}> + {' '} + + {t('Add filter')} + + + ), + }} > {filterIds.map(id => ( theme.gridUnit * 4}px; + & .ant-form-item-label { + padding-bottom: 0px; + } + & .ant-form-item-control-input { min-height: ${({ theme }) => theme.gridUnit * 10}px; } `; -export const StyledRowFormItem = styled(Form.Item)` +export const StyledRowFormItem = styled(FormItem)` margin-bottom: 0px; + padding-bottom: 0px; min-width: 50%; + & .ant-form-item-label { + padding-bottom: 0px; + } + .ant-form-item-control-input-content > div > div { height: auto; } + & .ant-form-item-control-input { min-height: ${({ theme }) => theme.gridUnit * 10}px; } @@ -118,7 +129,7 @@ export const StyledLabel = styled.span` text-transform: uppercase; `; -const CleanFormItem = styled(Form.Item)` +const CleanFormItem = styled(FormItem)` margin-bottom: 0; `; @@ -151,6 +162,13 @@ const StyledCollapse = styled(Collapse)` `; const StyledTabs = styled(Tabs)` + .ant-tabs-nav { + position: sticky; + top: 0px; + background: white; + z-index: 1; + } + .ant-tabs-nav-list { padding: 0px; } @@ -164,6 +182,9 @@ const StyledAsterisk = styled.span` color: ${({ theme }) => theme.colors.error.base}; font-family: SimSun, sans-serif; margin-right: ${({ theme }) => theme.gridUnit - 1}px; + &:before { + content: '*'; + } `; const FilterTabs = { @@ -208,6 +229,15 @@ const FILTERS_WITH_ADHOC_FILTERS = ['filter_select', 'filter_range']; const BASIC_CONTROL_ITEMS = ['enableEmptyFilter', 'multiSelect']; +const FILTER_TYPE_NAME_MAPPING = { + [t('Select filter')]: t('Value'), + [t('Range filter')]: t('Numerical range'), + [t('Time filter')]: t('Time range'), + [t('Time column')]: t('Time column'), + [t('Time grain')]: t('Time grain'), + [t('Group By')]: t('Group by'), +}; + /** * The configuration form for a specific filter. * Assigns field values to `filters[filterId]` in the form. @@ -418,396 +448,402 @@ const FiltersConfigForm = ( }; return ( - <> - setActiveTabKey(activeKey)} - centered + setActiveTabKey(activeKey)} + centered + > + - - - {t('Filter name')}} - initialValue={filterToEdit?.name} - rules={[{ required: !removed, message: t('Name is required') }]} - > - - + + {t('Filter name')}} + initialValue={filterToEdit?.name} + rules={[{ required: !removed, message: t('Name is required') }]} + > + + + {t('Filter Type')}} + {...getFiltersConfigModalTestId('filter-type')} + > + ({ - value: filterType, - // @ts-ignore - label: nativeFilterItems[filterType]?.value.name, - }))} - onChange={({ value }: { value: string }) => { - setNativeFilterFieldValues(form, filterId, { - filterType: value, - defaultDataMask: null, - }); + { + // We need reset column when dataset changed + if (datasetId && e?.value !== datasetId) { + setNativeFilterFieldValues(form, filterId, { + defaultDataMask: null, + column: null, + }); + } forceUpdate(); }} /> - - {hasDataset && ( - + {hasColumn && ( {t('Dataset')}} + // don't show the column select unless we have a dataset + // style={{ display: datasetId == null ? undefined : 'none' }} + name={['filters', filterId, 'column']} + initialValue={initColumn} + label={{t('Column')}} rules={[ - { required: !removed, message: t('Dataset is required') }, + { required: !removed, message: t('Field is required') }, ]} - {...getFiltersConfigModalTestId('datasource-input')} + data-test="field-input" > - { - // We need reset column when dataset changed - if (datasetId && e?.value !== datasetId) { - setNativeFilterFieldValues(form, filterId, { - defaultDataMask: null, - column: null, - }); - } + { + // We need reset default value when when column changed + setNativeFilterFieldValues(form, filterId, { + defaultDataMask: null, + }); forceUpdate(); }} /> - {hasColumn && ( - {t('Column')}} - rules={[ - { required: !removed, message: t('Field is required') }, - ]} - data-test="field-input" - > - { - // We need reset default value when when column changed + )} + + )} + + + {hasFilledDataset && ( + + {((hasDataset && hasAdditionalFilters) || hasMetrics) && ( - {hasFilledDataset && ( - - )} - - - - - setNativeFilterFieldValues(form, filterId, values) - } - pathToFormValue={['filters', filterId]} - forceUpdate={forceUpdate} - scope={filterToEdit?.scope} - formScope={formFilter?.scope} - formScoping={formFilter?.scoping} - /> - - - + )} + + + + )} + + + + + setNativeFilterFieldValues(form, filterId, values) + } + pathToFormValue={['filters', filterId]} + forceUpdate={forceUpdate} + scope={filterToEdit?.scope} + formScope={formFilter?.scope} + formScoping={formFilter?.scoping} + /> + + ); }; diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigModal.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigModal.tsx index a7a4acdd222c6..1a4bd3814965d 100644 --- a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigModal.tsx +++ b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigModal.tsx @@ -231,7 +231,7 @@ export function FiltersConfigModal({