[dashboard] fix time granularity display values (#8806)

* [dashboard] fix time granularity display values

* fix review comments
This commit is contained in:
Grace Guo 2019-12-11 12:01:11 -08:00 committed by GitHub
parent 562aeab1aa
commit a96eae46af
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 62 additions and 17 deletions

View File

@ -26,6 +26,7 @@ import { FILTER_INDICATORS_DISPLAY_LENGTH } from '../util/constants';
import { getChartIdsInFilterScope } from '../util/activeDashboardFilters'; import { getChartIdsInFilterScope } from '../util/activeDashboardFilters';
import { getDashboardFilterKey } from '../util/getDashboardFilterKey'; import { getDashboardFilterKey } from '../util/getDashboardFilterKey';
import { getFilterColorMap } from '../util/dashboardFiltersColorMap'; import { getFilterColorMap } from '../util/dashboardFiltersColorMap';
import { TIME_FILTER_MAP } from '../../visualizations/FilterBox/FilterBox';
const propTypes = { const propTypes = {
// from props // from props
@ -34,6 +35,7 @@ const propTypes = {
chartStatus: PropTypes.string, chartStatus: PropTypes.string,
// from redux // from redux
datasources: PropTypes.object.isRequired,
setDirectPathToChild: PropTypes.func.isRequired, setDirectPathToChild: PropTypes.func.isRequired,
filterFieldOnFocus: PropTypes.object.isRequired, filterFieldOnFocus: PropTypes.object.isRequired,
}; };
@ -42,6 +44,11 @@ const defaultProps = {
chartStatus: 'loading', chartStatus: 'loading',
}; };
const TIME_GRANULARITY_FIELDS = [
TIME_FILTER_MAP.granularity,
TIME_FILTER_MAP.time_grain_sqla,
];
function sortByIndicatorLabel(indicator1, indicator2) { function sortByIndicatorLabel(indicator1, indicator2) {
const s1 = (indicator1.label || indicator1.name).toLowerCase(); const s1 = (indicator1.label || indicator1.name).toLowerCase();
const s2 = (indicator2.label || indicator2.name).toLowerCase(); const s2 = (indicator2.label || indicator2.name).toLowerCase();
@ -56,6 +63,7 @@ function sortByIndicatorLabel(indicator1, indicator2) {
export default class FilterIndicatorsContainer extends React.PureComponent { export default class FilterIndicatorsContainer extends React.PureComponent {
getFilterIndicators() { getFilterIndicators() {
const { const {
datasources = {},
dashboardFilters, dashboardFilters,
chartId: currentChartId, chartId: currentChartId,
filterFieldOnFocus, filterFieldOnFocus,
@ -66,12 +74,12 @@ export default class FilterIndicatorsContainer extends React.PureComponent {
} }
const dashboardFiltersColorMap = getFilterColorMap(); const dashboardFiltersColorMap = getFilterColorMap();
const sortIndicatorsByEmptiness = Object.values(dashboardFilters).reduce( const sortIndicatorsByEmptiness = Object.values(dashboardFilters).reduce(
(indicators, dashboardFilter) => { (indicators, dashboardFilter) => {
const { const {
chartId, chartId,
componentId, componentId,
datasourceId,
directPathToFilter, directPathToFilter,
isDateFilter, isDateFilter,
isInstantFilter, isInstantFilter,
@ -79,6 +87,7 @@ export default class FilterIndicatorsContainer extends React.PureComponent {
labels, labels,
scopes, scopes,
} = dashboardFilter; } = dashboardFilter;
const datasource = datasources[datasourceId] || {};
if (currentChartId !== chartId) { if (currentChartId !== chartId) {
Object.keys(columns) Object.keys(columns)
@ -111,6 +120,25 @@ export default class FilterIndicatorsContainer extends React.PureComponent {
name === filterFieldOnFocus.column, name === filterFieldOnFocus.column,
}; };
// map time granularity value to datasource configure
if (isDateFilter && TIME_GRANULARITY_FIELDS.includes(name)) {
const timeGranularityConfig =
(name === TIME_FILTER_MAP.time_grain_sqla
? datasource.time_grain_sqla
: datasource.granularity) || [];
const timeGranularityDisplayMapping = timeGranularityConfig.reduce(
(map, [key, value]) => ({
...map,
[key]: value,
}),
{},
);
indicator.values = indicator.values.map(
value => timeGranularityDisplayMapping[value] || value,
);
}
if (isEmpty(indicator.values)) { if (isEmpty(indicator.values)) {
indicators[1].push(indicator); indicators[1].push(indicator);
} else { } else {

View File

@ -23,13 +23,14 @@ import FilterIndicatorsContainer from '../components/FilterIndicatorsContainer';
import { setDirectPathToChild } from '../actions/dashboardState'; import { setDirectPathToChild } from '../actions/dashboardState';
function mapStateToProps( function mapStateToProps(
{ dashboardState, dashboardFilters, dashboardLayout, charts }, { datasources, dashboardState, dashboardFilters, dashboardLayout, charts },
ownProps, ownProps,
) { ) {
const chartId = ownProps.chartId; const chartId = ownProps.chartId;
const chartStatus = (charts[chartId] || {}).chartStatus; const chartStatus = (charts[chartId] || {}).chartStatus;
return { return {
datasources,
dashboardFilters, dashboardFilters,
chartId, chartId,
chartStatus, chartStatus,

View File

@ -41,6 +41,7 @@ export const dashboardFilter = {
chartId: null, chartId: null,
componentId: null, componentId: null,
filterName: null, filterName: null,
datasourceId: null,
directPathToFilter: [], directPathToFilter: [],
isDateFilter: false, isDateFilter: false,
isInstantFilter: true, isInstantFilter: true,
@ -71,6 +72,7 @@ export default function dashboardFiltersReducer(dashboardFilters = {}, action) {
...dashboardFilter, ...dashboardFilter,
chartId, chartId,
componentId: component.id, componentId: component.id,
datasourceId: form_data.datasource,
filterName: component.meta.sliceName, filterName: component.meta.sliceName,
directPathToFilter, directPathToFilter,
columns, columns,

View File

@ -223,6 +223,7 @@ export default function(bootstrapData) {
...dashboardFilter, ...dashboardFilter,
chartId: key, chartId: key,
componentId, componentId,
datasourceId: slice.form_data.datasource,
filterName: slice.slice_name, filterName: slice.slice_name,
directPathToFilter, directPathToFilter,
columns, columns,

View File

@ -17,11 +17,8 @@
* under the License. * under the License.
*/ */
/* eslint-disable camelcase */ /* eslint-disable camelcase */
import { import { TIME_FILTER_MAP } from '../../visualizations/FilterBox/FilterBox';
TIME_FILTER_MAP, import { TIME_FILTER_LABELS } from '../../explore/constants';
TIME_RANGE,
FILTER_LABELS,
} from '../../visualizations/FilterBox/FilterBox';
export default function getFilterConfigsFromFormdata(form_data = {}) { export default function getFilterConfigsFromFormdata(form_data = {}) {
const { const {
@ -58,7 +55,13 @@ export default function getFilterConfigsFromFormdata(form_data = {}) {
}; };
const updatedLabels = { const updatedLabels = {
...configs.labels, ...configs.labels,
[TIME_FILTER_MAP.time_range]: FILTER_LABELS[TIME_RANGE], ...Object.entries(TIME_FILTER_MAP).reduce(
(map, [key, value]) => ({
...map,
[value]: TIME_FILTER_LABELS[key],
}),
{},
),
}; };
if (show_sqla_time_granularity) { if (show_sqla_time_granularity) {

View File

@ -87,6 +87,7 @@ export const dashboardFilterPropShape = PropTypes.shape({
chartId: PropTypes.number.isRequired, chartId: PropTypes.number.isRequired,
componentId: PropTypes.string.isRequired, componentId: PropTypes.string.isRequired,
filterName: PropTypes.string.isRequired, filterName: PropTypes.string.isRequired,
datasourceId: PropTypes.string.isRequired,
directPathToFilter: PropTypes.arrayOf(PropTypes.string).isRequired, directPathToFilter: PropTypes.arrayOf(PropTypes.string).isRequired,
isDateFilter: PropTypes.bool.isRequired, isDateFilter: PropTypes.bool.isRequired,
isInstantFilter: PropTypes.bool.isRequired, isInstantFilter: PropTypes.bool.isRequired,

View File

@ -16,6 +16,8 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
import { t } from '@superset-ui/translation';
export const AGGREGATES = { export const AGGREGATES = {
AVG: 'AVG', AVG: 'AVG',
COUNT: 'COUNT ', COUNT: 'COUNT ',
@ -57,3 +59,11 @@ export const sqlaAutoGeneratedMetricRegex = /^(LONG|DOUBLE|FLOAT)?(SUM|AVG|MAX|M
export const druidAutoGeneratedMetricRegex = /^(LONG|DOUBLE|FLOAT)?(SUM|MAX|MIN|COUNT)\([A-Z0-9_."]*\)$/i; export const druidAutoGeneratedMetricRegex = /^(LONG|DOUBLE|FLOAT)?(SUM|MAX|MIN|COUNT)\([A-Z0-9_."]*\)$/i;
export const EXPLORE_ONLY_VIZ_TYPE = ['separator', 'markup']; export const EXPLORE_ONLY_VIZ_TYPE = ['separator', 'markup'];
export const TIME_FILTER_LABELS = {
time_range: t('Time Range'),
granularity_sqla: t('Time Column'),
time_grain_sqla: t('Time Grain'),
druid_time_origin: t('Origin'),
granularity: t('Time Granularity'),
};

View File

@ -72,6 +72,7 @@ import * as v from './validators';
import ColumnOption from '../components/ColumnOption'; import ColumnOption from '../components/ColumnOption';
import OptionDescription from '../components/OptionDescription'; import OptionDescription from '../components/OptionDescription';
import { DEFAULT_VIEWPORT } from '../explore/components/controls/ViewportControl'; import { DEFAULT_VIEWPORT } from '../explore/components/controls/ViewportControl';
import { TIME_FILTER_LABELS } from './constants';
const categoricalSchemeRegistry = getCategoricalSchemeRegistry(); const categoricalSchemeRegistry = getCategoricalSchemeRegistry();
const sequentialSchemeRegistry = getSequentialSchemeRegistry(); const sequentialSchemeRegistry = getSequentialSchemeRegistry();
@ -814,7 +815,7 @@ export const controls = {
druid_time_origin: { druid_time_origin: {
type: 'SelectControl', type: 'SelectControl',
freeForm: true, freeForm: true,
label: t('Origin'), label: TIME_FILTER_LABELS.druid_time_origin,
choices: [ choices: [
['', 'default'], ['', 'default'],
['now', 'now'], ['now', 'now'],
@ -865,7 +866,7 @@ export const controls = {
granularity: { granularity: {
type: 'SelectControl', type: 'SelectControl',
freeForm: true, freeForm: true,
label: t('Time Granularity'), label: TIME_FILTER_LABELS.granularity,
default: 'one day', default: 'one day',
choices: [ choices: [
[null, 'all'], [null, 'all'],
@ -953,7 +954,7 @@ export const controls = {
granularity_sqla: { granularity_sqla: {
type: 'SelectControl', type: 'SelectControl',
label: t('Time Column'), label: TIME_FILTER_LABELS.granularity_sqla,
description: t( description: t(
'The time column for the visualization. Note that you ' + 'The time column for the visualization. Note that you ' +
'can define arbitrary expression that return a DATETIME ' + 'can define arbitrary expression that return a DATETIME ' +
@ -983,7 +984,7 @@ export const controls = {
time_grain_sqla: { time_grain_sqla: {
type: 'SelectControl', type: 'SelectControl',
label: t('Time Grain'), label: TIME_FILTER_LABELS.time_grain_sqla,
default: 'P1D', default: 'P1D',
description: t( description: t(
'The time granularity for the visualization. This ' + 'The time granularity for the visualization. This ' +
@ -1025,7 +1026,7 @@ export const controls = {
time_range: { time_range: {
type: 'DateFilterControl', type: 'DateFilterControl',
freeForm: true, freeForm: true,
label: t('Time range'), label: TIME_FILTER_LABELS.time_range,
default: t('Last week'), default: t('Last week'),
description: t( description: t(
'The time range for the visualization. All relative times, e.g. "Last month", ' + 'The time range for the visualization. All relative times, e.g. "Last month", ' +

View File

@ -31,6 +31,7 @@ import OnPasteSelect from '../../components/OnPasteSelect';
import VirtualizedRendererWrap from '../../components/VirtualizedRendererWrap'; import VirtualizedRendererWrap from '../../components/VirtualizedRendererWrap';
import { getDashboardFilterKey } from '../../dashboard/util/getDashboardFilterKey'; import { getDashboardFilterKey } from '../../dashboard/util/getDashboardFilterKey';
import { getFilterColorMap } from '../../dashboard/util/dashboardFiltersColorMap'; import { getFilterColorMap } from '../../dashboard/util/dashboardFiltersColorMap';
import { TIME_FILTER_LABELS } from '../../explore/constants';
import FilterBadgeIcon from '../../components/FilterBadgeIcon'; import FilterBadgeIcon from '../../components/FilterBadgeIcon';
import './FilterBox.less'; import './FilterBox.less';
@ -46,9 +47,6 @@ export const TIME_FILTER_MAP = {
// a shortcut to a map key, used by many components // a shortcut to a map key, used by many components
export const TIME_RANGE = TIME_FILTER_MAP.time_range; export const TIME_RANGE = TIME_FILTER_MAP.time_range;
export const FILTER_LABELS = {
[TIME_RANGE]: 'Time range',
};
const propTypes = { const propTypes = {
chartId: PropTypes.number.isRequired, chartId: PropTypes.number.isRequired,
@ -165,7 +163,7 @@ class FilterBox extends React.Component {
renderDateFilter() { renderDateFilter() {
const { showDateFilter, chartId } = this.props; const { showDateFilter, chartId } = this.props;
const label = t(FILTER_LABELS[TIME_RANGE]); const label = TIME_FILTER_LABELS.time_range;
if (showDateFilter) { if (showDateFilter) {
return ( return (
<div className="row space-1"> <div className="row space-1">