mirror of
https://github.com/apache/superset.git
synced 2024-09-19 12:09:42 -04:00
feat: support locale in number and time format (#182)
* feat: support locale in number and time format * test: improve coverage * test: merge js and ts test
This commit is contained in:
parent
9b82cd203f
commit
3fc8551014
@ -1,4 +1,4 @@
|
||||
import { format as d3Format } from 'd3-format';
|
||||
import { format as d3Format, formatLocale, FormatLocaleDefinition } from 'd3-format';
|
||||
import { isRequired } from '@superset-ui/core';
|
||||
import NumberFormatter from '../NumberFormatter';
|
||||
import { NumberFormatFunction } from '../types';
|
||||
@ -7,14 +7,18 @@ export default function createD3NumberFormatter(config: {
|
||||
description?: string;
|
||||
formatString: string;
|
||||
label?: string;
|
||||
locale?: FormatLocaleDefinition;
|
||||
}) {
|
||||
const { description, formatString = isRequired('config.formatString'), label } = config;
|
||||
const { description, formatString = isRequired('config.formatString'), label, locale } = config;
|
||||
|
||||
let formatFunc: NumberFormatFunction;
|
||||
let isInvalid = false;
|
||||
|
||||
try {
|
||||
formatFunc = d3Format(formatString);
|
||||
formatFunc =
|
||||
typeof locale === 'undefined'
|
||||
? d3Format(formatString)
|
||||
: formatLocale(locale).format(formatString);
|
||||
} catch (e) {
|
||||
formatFunc = value => `${value} (Invalid format: ${formatString})`;
|
||||
isInvalid = true;
|
||||
|
@ -45,4 +45,19 @@ describe('createD3NumberFormatter(config)', () => {
|
||||
expect(formatter.description).toEqual('lorem ipsum');
|
||||
});
|
||||
});
|
||||
describe('config.locale', () => {
|
||||
it('supports locale customization such as currency', () => {
|
||||
const formatter = createD3NumberFormatter({
|
||||
description: 'lorem ipsum',
|
||||
formatString: '$.2f',
|
||||
locale: {
|
||||
decimal: '.',
|
||||
thousands: ',',
|
||||
grouping: [3],
|
||||
currency: ['€', ''],
|
||||
},
|
||||
});
|
||||
expect(formatter(200)).toEqual('€200.00');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { utcFormat, timeFormat } from 'd3-time-format';
|
||||
import { utcFormat, timeFormat, timeFormatLocale, TimeLocaleDefinition } from 'd3-time-format';
|
||||
import { isRequired } from '@superset-ui/core';
|
||||
import TimeFormatter from '../TimeFormatter';
|
||||
import { LOCAL_PREFIX } from '../TimeFormats';
|
||||
@ -7,18 +7,29 @@ export default function createD3TimeFormatter(config: {
|
||||
description?: string;
|
||||
formatString: string;
|
||||
label?: string;
|
||||
locale?: TimeLocaleDefinition;
|
||||
useLocalTime?: boolean;
|
||||
}) {
|
||||
const {
|
||||
description,
|
||||
formatString = isRequired('formatString'),
|
||||
label,
|
||||
locale,
|
||||
useLocalTime = false,
|
||||
} = config;
|
||||
|
||||
const id = useLocalTime ? `${LOCAL_PREFIX}${formatString}` : formatString;
|
||||
const format = useLocalTime ? timeFormat : utcFormat;
|
||||
const formatFunc = format(formatString);
|
||||
let formatFunc;
|
||||
|
||||
if (typeof locale === 'undefined') {
|
||||
const format = useLocalTime ? timeFormat : utcFormat;
|
||||
formatFunc = format(formatString);
|
||||
} else {
|
||||
const localeObject = timeFormatLocale(locale);
|
||||
formatFunc = useLocalTime
|
||||
? localeObject.format(formatString)
|
||||
: localeObject.utcFormat(formatString);
|
||||
}
|
||||
|
||||
return new TimeFormatter({
|
||||
description,
|
||||
|
@ -1,8 +0,0 @@
|
||||
import createD3TimeFormatter from '../../src/factories/createD3TimeFormatter';
|
||||
|
||||
describe('createD3TimeFormatter(config)', () => {
|
||||
it('requires config.formatString', () => {
|
||||
expect(() => createD3TimeFormatter()).toThrow();
|
||||
expect(() => createD3TimeFormatter({})).toThrow();
|
||||
});
|
||||
});
|
@ -1,10 +1,60 @@
|
||||
import { TimeLocaleDefinition } from 'd3-time-format';
|
||||
import createD3TimeFormatter from '../../src/factories/createD3TimeFormatter';
|
||||
import { PREVIEW_TIME } from '../../src/TimeFormatter';
|
||||
import { TimeFormats } from '../../src';
|
||||
|
||||
const thLocale: TimeLocaleDefinition = {
|
||||
dateTime: '%a %e %b %Y %X',
|
||||
date: '%d/%m/%Y',
|
||||
time: '%H:%M:%S',
|
||||
periods: ['AM', 'PM'],
|
||||
days: ['วันอาทิตย์', 'วันจันทร์', 'วันอังคาร', 'วันพุธ', 'วันพฤหัส', 'วันศุกร์', 'วันเสาร์'],
|
||||
shortDays: ['อา.', 'จ.', 'อ.', 'พ.', 'พฤ', 'ศ.', 'ส.'],
|
||||
months: [
|
||||
'มกราคม',
|
||||
'กุมภาพันธ์',
|
||||
'มีนาคม',
|
||||
'เมษายน',
|
||||
'พฤษภาคม',
|
||||
'มิถุนายน',
|
||||
'กรกฎาคม',
|
||||
'สิงหาคม',
|
||||
'กันยายน',
|
||||
'ตุลาคม',
|
||||
'พฤศจิกายน',
|
||||
'ธันวาคม',
|
||||
],
|
||||
shortMonths: [
|
||||
'ม.ค.',
|
||||
'ก.พ.',
|
||||
'มี.ค.',
|
||||
'เม.ย.',
|
||||
'พ.ค.',
|
||||
'มิ.ย.',
|
||||
'ก.ค.',
|
||||
'ส.ค.',
|
||||
'ก.ย.',
|
||||
'ต.ค.',
|
||||
'พ.ย.',
|
||||
'ธ.ค.',
|
||||
],
|
||||
};
|
||||
|
||||
describe('createD3TimeFormatter(config)', () => {
|
||||
describe('if config.useLocalTime is true', () => {
|
||||
it('formats in local time', () => {
|
||||
it('requires config.formatString', () => {
|
||||
// @ts-ignore
|
||||
expect(() => createD3TimeFormatter()).toThrow();
|
||||
// @ts-ignore
|
||||
expect(() => createD3TimeFormatter({})).toThrow();
|
||||
});
|
||||
describe('config.useLocalTime', () => {
|
||||
it('if falsy, formats in UTC time', () => {
|
||||
const formatter = createD3TimeFormatter({
|
||||
formatString: TimeFormats.DATABASE_DATETIME,
|
||||
});
|
||||
expect(formatter.format(PREVIEW_TIME)).toEqual('2017-02-14 11:22:33');
|
||||
});
|
||||
it('if true, formats in local time', () => {
|
||||
const formatter = createD3TimeFormatter({
|
||||
formatString: TimeFormats.DATABASE_DATETIME,
|
||||
useLocalTime: true,
|
||||
@ -17,12 +67,28 @@ describe('createD3TimeFormatter(config)', () => {
|
||||
}
|
||||
});
|
||||
});
|
||||
describe('if config.useLocalTime is false', () => {
|
||||
it('formats in UTC time', () => {
|
||||
|
||||
describe('config.locale', () => {
|
||||
const TEST_TIME = new Date(Date.UTC(2015, 11, 20));
|
||||
it('supports locale customization (utc time)', () => {
|
||||
const formatter = createD3TimeFormatter({
|
||||
formatString: TimeFormats.DATABASE_DATETIME,
|
||||
formatString: '%c',
|
||||
locale: thLocale,
|
||||
});
|
||||
expect(formatter.format(PREVIEW_TIME)).toEqual('2017-02-14 11:22:33');
|
||||
expect(formatter(TEST_TIME)).toEqual('อา. 20 ธ.ค. 2015 00:00:00');
|
||||
});
|
||||
it('supports locale customization (local time)', () => {
|
||||
const formatter = createD3TimeFormatter({
|
||||
formatString: '%c',
|
||||
locale: thLocale,
|
||||
useLocalTime: true,
|
||||
});
|
||||
const offset = new Date().getTimezoneOffset();
|
||||
if (offset === 0) {
|
||||
expect(formatter(TEST_TIME)).toEqual('อา. 20 ธ.ค. 2015 00:00:00');
|
||||
} else {
|
||||
expect(formatter(TEST_TIME)).not.toEqual('อา. 20 ธ.ค. 2015 00:00:00');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user