blob: f508c1bfe3868bd23a0915ce525ff87cbede541b [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/* eslint-disable camelcase */
import {
ADD_FILTER,
REMOVE_FILTER,
CHANGE_FILTER,
UPDATE_DIRECT_PATH_TO_FILTER,
UPDATE_LAYOUT_COMPONENTS,
UPDATE_DASHBOARD_FILTERS_SCOPE,
} from '../actions/dashboardFilters';
import { TIME_RANGE } from '../../visualizations/FilterBox/FilterBox';
import { DASHBOARD_ROOT_ID } from '../util/constants';
import getFilterConfigsFromFormdata from '../util/getFilterConfigsFromFormdata';
import { buildActiveFilters } from '../util/activeDashboardFilters';
import { getChartIdAndColumnFromFilterKey } from '../util/getDashboardFilterKey';
export const DASHBOARD_FILTER_SCOPE_GLOBAL = {
scope: [DASHBOARD_ROOT_ID],
immune: [],
};
export const dashboardFilter = {
chartId: null,
componentId: null,
filterName: null,
datasourceId: null,
directPathToFilter: [],
isDateFilter: false,
isInstantFilter: true,
columns: {},
labels: {},
scopes: {},
};
const CHANGE_FILTER_VALUE_ACTIONS = [ADD_FILTER, REMOVE_FILTER, CHANGE_FILTER];
export default function dashboardFiltersReducer(dashboardFilters = {}, action) {
const actionHandlers = {
[ADD_FILTER]() {
const { chartId, component, form_data } = action;
const { columns, labels } = getFilterConfigsFromFormdata(form_data);
const scopes = Object.keys(columns).reduce(
(map, column) => ({
...map,
[column]: DASHBOARD_FILTER_SCOPE_GLOBAL,
}),
{},
);
const directPathToFilter = component
? (component.parents || []).slice().concat(component.id)
: [];
const newFilter = {
...dashboardFilter,
chartId,
componentId: component.id,
datasourceId: form_data.datasource,
filterName: component.meta.sliceName,
directPathToFilter,
columns,
labels,
scopes,
isInstantFilter: !!form_data.instant_filtering,
isDateFilter: Object.keys(columns).includes(TIME_RANGE),
};
return newFilter;
},
[CHANGE_FILTER](state) {
const { newSelectedValues, merge } = action;
const updatedColumns = Object.keys(newSelectedValues).reduce(
(columns, name) => {
// override existed column value, or add new column name
if (!merge || !(name in columns)) {
return {
...columns,
[name]: newSelectedValues[name],
};
}
return {
...columns,
[name]: [...columns[name], ...newSelectedValues[name]],
};
},
{ ...state.columns },
);
return {
...state,
columns: updatedColumns,
};
},
[UPDATE_DIRECT_PATH_TO_FILTER](state) {
const { path } = action;
return {
...state,
directPathToFilter: path,
};
},
};
if (action.type === UPDATE_LAYOUT_COMPONENTS) {
buildActiveFilters({
dashboardFilters,
components: action.components,
});
return dashboardFilters;
}
if (action.type === UPDATE_DASHBOARD_FILTERS_SCOPE) {
const allDashboardFiltersScope = action.scopes;
// update filter scope for each filter field
const updatedFilters = Object.entries(allDashboardFiltersScope).reduce(
(map, entry) => {
const [filterKey, { scope, immune }] = entry;
const { chartId, column } = getChartIdAndColumnFromFilterKey(filterKey);
const scopes = {
...map[chartId].scopes,
[column]: {
scope,
immune,
},
};
return {
...map,
[chartId]: {
...map[chartId],
scopes,
},
};
},
dashboardFilters,
);
buildActiveFilters({ dashboardFilters: updatedFilters });
return updatedFilters;
}
if (action.type === REMOVE_FILTER) {
const { chartId } = action;
const { [chartId]: deletedFilter, ...updatedFilters } = dashboardFilters;
buildActiveFilters({ dashboardFilters: updatedFilters });
return updatedFilters;
}
if (action.type in actionHandlers) {
const updatedFilters = {
...dashboardFilters,
[action.chartId]: actionHandlers[action.type](
dashboardFilters[action.chartId],
),
};
if (CHANGE_FILTER_VALUE_ACTIONS.includes(action.type)) {
buildActiveFilters({ dashboardFilters: updatedFilters });
}
return updatedFilters;
}
return dashboardFilters;
}