Skip to content

Commit

Permalink
feat(native-filters): enable filter indicator and make datasource opt…
Browse files Browse the repository at this point in the history
…ional (#13148)

* refactor: continue decouple native filters

* refactor(native-filters): decouple native filter parms from config modal

* lint: fix TS errors

* lint: fix TS errors

* refactor: update filter badge

* refactor: rename ant filters

* test: fix tests

* test: fix tests

* refactor: remove 18 from dataset
  • Loading branch information
simcha90 authored Feb 16, 2021
1 parent 5ab613d commit 5aa38ef
Show file tree
Hide file tree
Showing 28 changed files with 292 additions and 288 deletions.
11 changes: 10 additions & 1 deletion superset-frontend/spec/fixtures/mockDashboardInfo.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,16 @@
export default {
id: 1234,
slug: 'dashboardSlug',
metadata: {},
metadata: {
filter_configuration: [
{
id: 'DefaultsID',
filterType: 'filter_select',
targets: [{}],
cascadeParentIds: [],
},
],
},
userId: 'mock_user_id',
dash_edit_perm: true,
dash_save_perm: true,
Expand Down
11 changes: 8 additions & 3 deletions superset-frontend/spec/fixtures/mockNativeFilters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,14 @@
* specific language governing permissions and limitations
* under the License.
*/
import { FilterType } from 'src/dashboard/components/nativeFilters/types';
import { NativeFiltersState } from 'src/dashboard/reducers/types';

export const nativeFilters: NativeFiltersState = {
filters: {
'NATIVE_FILTER-e7Q8zKixx': {
id: 'NATIVE_FILTER-e7Q8zKixx',
name: 'region',
filterType: FilterType.filter_select,
filterType: 'filter_select',
targets: [
{
datasetId: 2,
Expand All @@ -49,7 +48,7 @@ export const nativeFilters: NativeFiltersState = {
'NATIVE_FILTER-x9QPw0so1': {
id: 'NATIVE_FILTER-x9QPw0so1',
name: 'country_code',
filterType: FilterType.filter_select,
filterType: 'filter_select',
targets: [
{
datasetId: 2,
Expand All @@ -75,6 +74,9 @@ export const nativeFilters: NativeFiltersState = {
filtersState: {
'NATIVE_FILTER-e7Q8zKixx': {
id: 'NATIVE_FILTER-e7Q8zKixx',
currentState: {
value: ['East Asia & Pacific'],
},
extraFormData: {
append_form_data: {
filters: [
Expand Down Expand Up @@ -128,6 +130,9 @@ export const singleNativeFiltersState = {
[NATIVE_FILTER_ID]: {
id: NATIVE_FILTER_ID,
extraFormData,
currentState: {
value: ['No, not an ethnic minority'],
},
},
},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,25 @@ Object.defineProperty(window, 'matchMedia', {
})),
});

jest.mock('@superset-ui/core', () => ({
// @ts-ignore
...jest.requireActual('@superset-ui/core'),
getChartMetadataRegistry: () => ({
items: {
filter_select: {
value: {
datasourceCount: 1,
behaviors: ['NATIVE_FILTER'],
},
},
},
}),
}));

describe('FiltersConfigModal', () => {
const mockedProps = {
isOpen: true,
initialFilterId: 'DefaultFilterId',
initialFilterId: 'DefaultsID',
createNewOnOpen: true,
onCancel: jest.fn(),
save: jest.fn(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@
*/
export const nativeFiltersInfo = {
filters: {
DefaultID1: {
id: 'DefaultID1',
DefaultsID: {
id: 'DefaultsID',
name: 'test',
type: 'text',
type: 'filter_select',
targets: [
{
datasetId: 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,9 @@
*/
import { TIME_FILTER_MAP } from 'src/explore/constants';
import { getChartIdsInFilterScope } from 'src/dashboard/util/activeDashboardFilters';
import {
NativeFiltersState,
NativeFilterState,
} from 'src/dashboard/reducers/types';
import { NativeFiltersState } from 'src/dashboard/reducers/types';
import { getTreeCheckedItems } from '../nativeFilters/FilterConfigModal/utils';
import { Layout } from '../../types';

export enum IndicatorStatus {
Unset = 'UNSET',
Expand Down Expand Up @@ -130,7 +129,7 @@ const getRejectedColumns = (chart: any): Set<string> =>
);

export type Indicator = {
column: string;
column?: string;
name: string;
value: string[];
status: IndicatorStatus;
Expand Down Expand Up @@ -172,50 +171,52 @@ export const selectIndicatorsForChart = (
return indicators;
};

const selectNativeIndicatorValue = (
filterState: NativeFilterState,
): string[] => {
const filters = filterState?.extraFormData?.append_form_data?.filters;
if (filters?.length) {
const filter = filters[0];
if ('val' in filter) {
const val = filter.val as string | string[];
if (Array.isArray(val)) {
return val;
}
return [val];
}
}
return [];
};

export const selectNativeIndicatorsForChart = (
nativeFilters: NativeFiltersState,
chartId: number,
charts: any,
dashboardLayout: Layout,
): Indicator[] => {
const chart = charts[chartId];

const appliedColumns = getAppliedColumns(chart);
const rejectedColumns = getRejectedColumns(chart);

const getStatus = (column: string, value: string[]): IndicatorStatus => {
if (rejectedColumns.has(column)) return IndicatorStatus.Incompatible;
if (appliedColumns.has(column) && value.length > 0) {
const getStatus = (
value: string[],
isAffectedByScope: boolean,
column?: string,
): IndicatorStatus => {
if (!column && isAffectedByScope) {
// Filter without datasource
return IndicatorStatus.Applied;
}
if (column && rejectedColumns.has(column))
return IndicatorStatus.Incompatible;
if (column && appliedColumns.has(column) && value.length > 0) {
return IndicatorStatus.Applied;
}
return IndicatorStatus.Unset;
};

const indicators = Object.values(nativeFilters.filters).map(nativeFilter => {
const column = nativeFilter.targets[0].column.name;
const isAffectedByScope = getTreeCheckedItems(
nativeFilter.scope,
dashboardLayout,
).some(
layoutItem => dashboardLayout[layoutItem]?.meta?.chartId === chartId,
);
const column = nativeFilter.targets[0]?.column?.name;
const filterState = nativeFilters.filtersState[nativeFilter.id];
const value = selectNativeIndicatorValue(filterState);
let value = filterState?.currentState?.value ?? [];
if (!Array.isArray(value)) {
value = [value];
}
return {
column,
name: nativeFilter.name,
path: [nativeFilter.id],
status: getStatus(column, value),
status: getStatus(value, isAffectedByScope, column),
value,
};
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,19 @@ const FilterValue: React.FC<FilterProps> = ({
const { id, targets, filterType } = filter;
const cascadingFilters = useCascadingFilters(id);
const filterState = useFilterState(id);
const [loading, setLoading] = useState<boolean>(true);
const [state, setState] = useState([]);
const [error, setError] = useState<boolean>(false);
const [formData, setFormData] = useState<Partial<QueryFormData>>({});
const inputRef = useRef<HTMLInputElement>(null);
const [target] = targets;
const { datasetId = 18, column } = target;
const {
datasetId,
column = {},
}: Partial<{ datasetId: number; column: { name?: string } }> = target;
const { name: groupby } = column;
const currentValue = filterState.currentState?.value;
const hasDataSource = !!(datasetId && groupby);
const [loading, setLoading] = useState<boolean>(hasDataSource);
useEffect(() => {
const newFormData = getFormData({
datasetId,
Expand All @@ -71,6 +75,9 @@ const FilterValue: React.FC<FilterProps> = ({
});
if (!areObjectsEqual(formData || {}, newFormData)) {
setFormData(newFormData);
if (!hasDataSource) {
return;
}
getChartDataRequest({
formData: newFormData,
force: false,
Expand Down Expand Up @@ -131,7 +138,8 @@ const FilterValue: React.FC<FilterProps> = ({
height={20}
width={220}
formData={formData}
queriesData={state}
// For charts that don't have datasource we need workaround for empty placeholder
queriesData={hasDataSource ? state : [{ data: [null] }]}
chartType={filterType}
// @ts-ignore (update superset-ui)
hooks={{ setExtraFormData }}
Expand Down
Loading

0 comments on commit 5aa38ef

Please sign in to comment.