mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
DisplayProcessor: improve time field support (#20223)
This commit is contained in:
@@ -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);
|
|
||||||
};
|
|
||||||
|
@@ -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');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
@@ -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) => {
|
||||||
|
Reference in New Issue
Block a user