DisplayProcessor: improve time field support (#20223)

This commit is contained in:
Ryan McKinley
2019-11-07 00:08:25 -08:00
committed by GitHub
parent a883350305
commit 8484b43001
3 changed files with 68 additions and 24 deletions

View File

@@ -1,7 +1,6 @@
import { TimeZone } from '../types/time'; import { TimeZone } from '../types/time';
/* tslint:disable:import-blacklist ban ban-types */ /* tslint:disable:import-blacklist ban ban-types */
import moment, { Moment, MomentInput, DurationInputArg1 } from 'moment'; import moment, { Moment, MomentInput, DurationInputArg1 } from 'moment';
import { DEFAULT_DATE_TIME_FORMAT } from './formats';
export interface DateTimeBuiltinFormat { export interface DateTimeBuiltinFormat {
__momentBuiltinFormatBrand: any; __momentBuiltinFormatBrand: any;
} }
@@ -38,7 +37,6 @@ export type DurationUnit =
| 'quarters' | 'quarters'
| 'Q'; | 'Q';
export type DateFormatter = (date: DateTimeInput, format?: string) => string;
export interface DateTimeLocale { export interface DateTimeLocale {
firstDayOfWeek: () => number; firstDayOfWeek: () => number;
} }
@@ -115,10 +113,3 @@ export const dateTimeForTimeZone = (
return dateTime(input, formatInput); return dateTime(input, formatInput);
}; };
export const getTimeZoneDateFormatter: (timezone?: TimeZone) => DateFormatter = timezone => (date, format) => {
date = isDateTime(date) ? date : dateTime(date);
format = format || DEFAULT_DATE_TIME_FORMAT;
return timezone === 'browser' ? dateTime(date).format(format) : toUtc(date).format(format);
};

View File

@@ -1,6 +1,7 @@
import { getDisplayProcessor, getColorFromThreshold } from './displayProcessor'; import { getDisplayProcessor, getColorFromThreshold } from './displayProcessor';
import { DisplayProcessor, DisplayValue } from '../types/displayValue'; import { DisplayProcessor, DisplayValue } from '../types/displayValue';
import { ValueMapping, MappingType } from '../types/valueMapping'; import { ValueMapping, MappingType } from '../types/valueMapping';
import { FieldType } from '../types';
function assertSame(input: any, processors: DisplayProcessor[], match: DisplayValue) { function assertSame(input: any, processors: DisplayProcessor[], match: DisplayValue) {
processors.forEach(processor => { processors.forEach(processor => {
@@ -192,3 +193,38 @@ describe('Format value', () => {
expect(instance(value).text).toEqual('1.000 Mil'); expect(instance(value).text).toEqual('1.000 Mil');
}); });
}); });
describe('Date display options', () => {
it('should format UTC dates', () => {
const processor = getDisplayProcessor({
type: FieldType.time,
isUtc: true,
config: {
unit: 'xyz', // ignore non-date formats
},
});
expect(processor(0).text).toEqual('1970-01-01 00:00:00');
});
it('should pick configured time format', () => {
const processor = getDisplayProcessor({
type: FieldType.time,
isUtc: true,
config: {
unit: 'dateTimeAsUS', // A configurable date format
},
});
expect(processor(0).text).toEqual('01/01/1970 12:00:00 am');
});
it('respect the configured date format', () => {
const processor = getDisplayProcessor({
type: FieldType.time,
isUtc: true,
config: {
dateDisplayFormat: 'YYYY',
},
});
expect(processor(0).text).toEqual('1970');
});
});

View File

@@ -11,8 +11,8 @@ import { DisplayProcessor, DisplayValue, DecimalCount, DecimalInfo } from '../ty
import { getValueFormat } from '../valueFormats/valueFormats'; import { getValueFormat } from '../valueFormats/valueFormats';
import { getMappedValue } from '../utils/valueMappings'; import { getMappedValue } from '../utils/valueMappings';
import { Threshold } from '../types/threshold'; import { Threshold } from '../types/threshold';
import { getTimeZoneDateFormatter } from '../datetime/moment_wrapper'; import { DateTime, DEFAULT_DATE_TIME_FORMAT, isDateTime, dateTime, toUtc } from '../datetime';
import { DEFAULT_DATE_TIME_FORMAT } from '../datetime'; import { KeyValue } from '../types';
interface DisplayProcessorOptions { interface DisplayProcessorOptions {
type?: FieldType; type?: FieldType;
@@ -23,22 +23,39 @@ interface DisplayProcessorOptions {
theme?: GrafanaTheme; // Will pick 'dark' if not defined theme?: GrafanaTheme; // Will pick 'dark' if not defined
} }
// Reasonable units for time
const timeFormats: KeyValue<boolean> = {
dateTimeAsIso: true,
dateTimeAsUS: true,
dateTimeFromNow: true,
};
export function getDisplayProcessor(options?: DisplayProcessorOptions): DisplayProcessor { export function getDisplayProcessor(options?: DisplayProcessorOptions): DisplayProcessor {
if (options && !_.isEmpty(options)) { if (options && !_.isEmpty(options)) {
if (options.type && options.type === FieldType.time) {
return (value: any) => {
let dateFormat = DEFAULT_DATE_TIME_FORMAT;
if (options.config && options.config.dateDisplayFormat) {
dateFormat = options.config.dateDisplayFormat;
}
const formatedDate = getTimeZoneDateFormatter(options.isUtc ? 'utc' : 'browser')(value, dateFormat);
return {
numeric: value,
text: formatedDate,
};
};
}
const field = options.config ? options.config : {}; const field = options.config ? options.config : {};
if (options.type === FieldType.time) {
if (field.unit && timeFormats[field.unit]) {
// Currently selected unit is valid for time fields
} else {
const dateFormat = field.dateDisplayFormat || DEFAULT_DATE_TIME_FORMAT;
// UTC or browser based timezone
let fmt = (date: DateTime) => date.format(dateFormat);
if (options.isUtc) {
fmt = (date: DateTime) => toUtc(date).format(dateFormat);
}
return (value: any) => {
const date: DateTime = isDateTime(value) ? value : dateTime(value);
return {
numeric: isNaN(value) ? date.valueOf() : value,
text: fmt(date),
};
};
}
}
const formatFunc = getValueFormat(field.unit || 'none'); const formatFunc = getValueFormat(field.unit || 'none');
return (value: any) => { return (value: any) => {