Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(dashboard): Add description to the native filter #17025

Merged
merged 11 commits into from
Oct 27, 2021
2 changes: 2 additions & 0 deletions superset-frontend/spec/fixtures/mockNativeFilters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export const nativeFilters: NativeFiltersState = {
inverseSelection: false,
},
type: NativeFilterType.NATIVE_FILTER,
description: '',
},
'NATIVE_FILTER-x9QPw0so1': {
id: 'NATIVE_FILTER-x9QPw0so1',
Expand Down Expand Up @@ -81,6 +82,7 @@ export const nativeFilters: NativeFiltersState = {
inverseSelection: false,
},
type: NativeFilterType.NATIVE_FILTER,
description: '2 letter code',
},
},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ export const nativeFiltersInfo: NativeFiltersState = {
isRequired: false,
},
type: NativeFilterType.NATIVE_FILTER,
description: 'test description',
},
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,21 @@ import { Provider } from 'react-redux';
import { nativeFiltersInfo } from 'spec/javascripts/dashboard/fixtures/mockNativeFilters';
import CascadeFilterControl, { CascadeFilterControlProps } from '.';

const mockedProps = {
const mockedProps = (defaultsId = nativeFiltersInfo.filters.DefaultsID) => ({
michael-s-molina marked this conversation as resolved.
Show resolved Hide resolved
filter: {
...nativeFiltersInfo.filters.DefaultsID,
...defaultsId,
cascadeChildren: [
{
...nativeFiltersInfo.filters.DefaultsID,
...defaultsId,
name: 'test child filter 1',
cascadeChildren: [],
},
{
...nativeFiltersInfo.filters.DefaultsID,
...defaultsId,
name: 'test child filter 2',
cascadeChildren: [
{
...nativeFiltersInfo.filters.DefaultsID,
...defaultsId,
name: 'test child of a child filter',
cascadeChildren: [],
},
Expand All @@ -46,7 +46,7 @@ const mockedProps = {
],
},
onFilterSelectionChange: jest.fn(),
};
});

const setup = (props: CascadeFilterControlProps) => (
<Provider store={mockStore}>
Expand All @@ -55,22 +55,38 @@ const setup = (props: CascadeFilterControlProps) => (
);

test('should render', () => {
const { container } = render(setup(mockedProps));
const { container } = render(setup(mockedProps()));
expect(container).toBeInTheDocument();
});

test('should render the filter name', () => {
render(setup(mockedProps));
render(setup(mockedProps()));
expect(screen.getByText('test')).toBeInTheDocument();
});

test('should render the children filter names', () => {
render(setup(mockedProps));
render(setup(mockedProps()));
expect(screen.getByText('test child filter 1')).toBeInTheDocument();
expect(screen.getByText('test child filter 2')).toBeInTheDocument();
});

test('should render the child of a child filter name', () => {
render(setup(mockedProps));
render(setup(mockedProps()));
expect(screen.getByText('test child of a child filter')).toBeInTheDocument();
});

test('should render tooltip if description is not empty', async () => {
render(setup(mockedProps()));
const toolTips = await screen.findAllByTestId('filter-description');
expect(toolTips).toHaveLength(4);
toolTips.map(item => expect(item).toBeInTheDocument());
});
test('should not render tooltip if description is empty', () => {
michael-s-molina marked this conversation as resolved.
Show resolved Hide resolved
render(
setup(
mockedProps({ ...nativeFiltersInfo.filters.DefaultsID, description: '' }),
),
);
const toolTips = screen.queryAllByTestId('filter-description');
toolTips.map(item => expect(item).not.toBeInTheDocument());
});
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@
* under the License.
*/
import React from 'react';
import { styled } from '@superset-ui/core';
import { InfoTooltipWithTrigger } from '@superset-ui/chart-controls';
import { styled, t } from '@superset-ui/core';
import { Form, FormItem } from 'src/components/Form';
import { checkIsMissingRequiredValue } from '../utils';
import FilterValue from './FilterValue';
import { FilterProps } from './types';
import { checkIsMissingRequiredValue } from '../utils';

const StyledIcon = styled.div`
position: absolute;
Expand Down Expand Up @@ -52,6 +53,12 @@ const StyledFilterControlContainer = styled(Form)`
}
`;

const ToolTipContainer = styled.div`
font-size: ${({ theme }) => theme.typography.sizes.m}px;
display: flex;
padding-left: ${({ theme }) => theme.gridUnit}px;
`;

const FilterControl: React.FC<FilterProps> = ({
dataMaskSelected,
filter,
Expand All @@ -74,7 +81,19 @@ const FilterControl: React.FC<FilterProps> = ({
<StyledFilterControlTitleBox>
<StyledFilterControlTitle data-test="filter-control-name">
{name}
</StyledFilterControlTitle>
</StyledFilterControlTitle>{' '}
{!!filter.description && (
<ToolTipContainer
data-test="filter-description"
michael-s-molina marked this conversation as resolved.
Show resolved Hide resolved
className="text-muted"
>
<InfoTooltipWithTrigger
label={t('description')}
tooltip={filter.description}
placement="top"
/>
</ToolTipContainer>
)}
<StyledIcon data-test="filter-icon">{icon}</StyledIcon>
</StyledFilterControlTitleBox>
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@
* specific language governing permissions and limitations
* under the License.
*/
import {
ColumnMeta,
InfoTooltipWithTrigger,
Metric,
} from '@superset-ui/chart-controls';
import {
AdhocFilter,
Behavior,
Expand All @@ -26,15 +31,11 @@ import {
JsonResponse,
styled,
SupersetApiError,
t,
SupersetClient,
t,
} from '@superset-ui/core';
import {
ColumnMeta,
InfoTooltipWithTrigger,
Metric,
} from '@superset-ui/chart-controls';
import { FormInstance } from 'antd/lib/form';
import { isEmpty, isEqual } from 'lodash';
import React, {
forwardRef,
useCallback,
Expand All @@ -44,53 +45,52 @@ import React, {
useState,
} from 'react';
import { useSelector } from 'react-redux';
import { isEqual, isEmpty } from 'lodash';
import { FormItem } from 'src/components/Form';
import { Input } from 'src/common/components';
import { getChartDataRequest } from 'src/chart/chartAction';
import { Input, TextArea } from 'src/common/components';
import { Select } from 'src/components';
import { cacheWrapper } from 'src/utils/cacheWrapper';
import AdhocFilterControl from 'src/explore/components/controls/FilterControl/AdhocFilterControl';
import DateFilterControl from 'src/explore/components/controls/DateFilterControl';
import { addDangerToast } from 'src/components/MessageToasts/actions';
import { ClientErrorObject } from 'src/utils/getClientErrorObject';
import Collapse from 'src/components/Collapse';
import { getChartDataRequest } from 'src/chart/chartAction';
import { FeatureFlag, isFeatureEnabled } from 'src/featureFlags';
import { waitForAsyncData } from 'src/middleware/asyncEvent';
import Tabs from 'src/components/Tabs';
import BasicErrorAlert from 'src/components/ErrorMessage/BasicErrorAlert';
import { FormItem } from 'src/components/Form';
import Icons from 'src/components/Icons';
import { Tooltip } from 'src/components/Tooltip';
import Loading from 'src/components/Loading';
import { addDangerToast } from 'src/components/MessageToasts/actions';
import { Radio } from 'src/components/Radio';
import BasicErrorAlert from 'src/components/ErrorMessage/BasicErrorAlert';
import Tabs from 'src/components/Tabs';
import { Tooltip } from 'src/components/Tooltip';
import {
Chart,
ChartsState,
DatasourcesState,
RootState,
} from 'src/dashboard/types';
import Loading from 'src/components/Loading';
import DateFilterControl from 'src/explore/components/controls/DateFilterControl';
import AdhocFilterControl from 'src/explore/components/controls/FilterControl/AdhocFilterControl';
import { FeatureFlag, isFeatureEnabled } from 'src/featureFlags';
import { waitForAsyncData } from 'src/middleware/asyncEvent';
import { cacheWrapper } from 'src/utils/cacheWrapper';
import { ClientErrorObject } from 'src/utils/getClientErrorObject';
import { Filter, NativeFilterType } from '../../types';
import { getFormData } from '../../utils';
michael-s-molina marked this conversation as resolved.
Show resolved Hide resolved
import {
CASCADING_FILTERS,
getFiltersConfigModalTestId,
} from '../FiltersConfigModal';
import { FilterRemoval, NativeFiltersForm } from '../types';
import { CollapsibleControl } from './CollapsibleControl';
import { ColumnSelect } from './ColumnSelect';
import { NativeFiltersForm, FilterRemoval } from '../types';
import DatasetSelect from './DatasetSelect';
import DefaultValue from './DefaultValue';
import FilterScope from './FilterScope/FilterScope';
import getControlItemsMap from './getControlItemsMap';
import RemovedFilter from './RemovedFilter';
import { useBackendFormUpdate, useDefaultValue } from './state';
import {
FILTER_SUPPORTED_TYPES,
hasTemporalColumns,
mostUsedDataset,
setNativeFilterFieldValues,
useForceUpdate,
mostUsedDataset,
} from './utils';
import { useBackendFormUpdate, useDefaultValue } from './state';
import { getFormData } from '../../utils';
import { Filter, NativeFilterType } from '../../types';
import getControlItemsMap from './getControlItemsMap';
import FilterScope from './FilterScope/FilterScope';
import RemovedFilter from './RemovedFilter';
import DefaultValue from './DefaultValue';
import { CollapsibleControl } from './CollapsibleControl';
import {
CASCADING_FILTERS,
getFiltersConfigModalTestId,
} from '../FiltersConfigModal';
import DatasetSelect from './DatasetSelect';

const { TabPane } = Tabs;

Expand Down Expand Up @@ -931,6 +931,13 @@ const FiltersConfigForm = (
{Object.keys(controlItems)
.filter(key => BASIC_CONTROL_ITEMS.includes(key))
.map(key => controlItems[key].element)}
<StyledFormItem
name={['filters', filterId, 'description']}
initialValue={filterToEdit?.description}
label={<StyledLabel>{t('Description')}</StyledLabel>}
>
<TextArea />
</StyledFormItem>
</Collapse.Panel>
{hasAdvancedSection && (
<Collapse.Panel
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ const filterMock: Filter = {
targets: [{}],
controlValues: {},
type: NativeFilterType.NATIVE_FILTER,
description: '',
};

const createProps: () => ControlItemsProps = () => ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export interface NativeFiltersFormItem {
time_range?: string;
granularity_sqla?: string;
type: NativeFilterType;
description: string;
}

export interface NativeFiltersForm {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ export const createHandleSave = (
scope: formInputs.scope,
sortMetric: formInputs.sortMetric,
type: formInputs.type,
description: formInputs.description || '',
};
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export interface Filter {
tabsInScope?: string[];
chartsInScope?: number[];
type: NativeFilterType;
description: string;
}

export type FilterConfiguration = Filter[];
Expand Down