Skip to content
This repository has been archived by the owner on Dec 10, 2021. It is now read-only.

Commit

Permalink
Convert time-format to TypeScript (#78)
Browse files Browse the repository at this point in the history
* convert source to TS

* fix lint

* convert unit test to TS

* fix rebasing issue

* fix typings

* use ts-ignore
  • Loading branch information
kristw authored Jan 25, 2019
1 parent e0b2de1 commit 727618b
Show file tree
Hide file tree
Showing 26 changed files with 171 additions and 115 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
"build": "yarn run build:cjs && yarn run build:esm && yarn run type:dts",
"build:cjs": "NODE_ENV=production beemo babel --extensions=\".js,.jsx,.ts,.tsx\" ./src --out-dir lib/ --minify --workspaces=\"@superset-ui/!(demo|generator-superset)\"",
"build:esm": "NODE_ENV=production beemo babel --extensions=\".js,.jsx,.ts,.tsx\" ./src --out-dir esm/ --esm --minify --workspaces=\"@superset-ui/!(demo|generator-superset)\"",
"type": "NODE_ENV=production beemo typescript --workspaces=\"@superset-ui/(connection|core|color|chart|number-format|translation)\" --noEmit",
"type:dts": "NODE_ENV=production beemo typescript --workspaces=\"@superset-ui/(connection|core|color|chart|number-format|translation)\" --emitDeclarationOnly",
"type": "NODE_ENV=production beemo typescript --workspaces=\"@superset-ui/(connection|core|color|chart|number-format|time-format|translation)\" --noEmit",
"type:dts": "NODE_ENV=production beemo typescript --workspaces=\"@superset-ui/(connection|core|color|chart|number-format|time-format|translation)\" --emitDeclarationOnly",
"lint": "beemo create-config prettier && beemo eslint \"./packages/*/{src,test,storybook}/**/*.{js,jsx,ts,tsx}\"",
"lint:fix": "beemo create-config prettier && beemo eslint --fix \"./packages/*/{src,test,storybook}/**/*.{js,jsx,ts,tsx}\"",
"jest": "beemo jest --color --coverage --react",
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import createD3NumberFormatter from '../../src/factories/createD3NumberFormatter';

describe('createD3NumberFormatter(config)', () => {
it('requires config.formatString', () => {
// @ts-ignore -- intentionally pass invalid input
expect(() => createD3NumberFormatter({})).toThrow();
});
describe('config.formatString', () => {
it('creates a NumberFormatter with the formatString as id', () => {
const formatter = createD3NumberFormatter({ formatString: '.2f' });
Expand Down
2 changes: 2 additions & 0 deletions packages/superset-ui-time-format/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
"access": "public"
},
"dependencies": {
"@types/d3-time": "^1.0.9",
"@types/d3-time-format": "^2.1.0",
"@superset-ui/core": "^0.8.0",
"d3-time": "^1.0.10",
"d3-time-format": "^2.1.3"
Expand Down
35 changes: 0 additions & 35 deletions packages/superset-ui-time-format/src/TimeFormatter.js

This file was deleted.

50 changes: 50 additions & 0 deletions packages/superset-ui-time-format/src/TimeFormatter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/* eslint-disable no-magic-numbers */

import { ExtensibleFunction, isRequired } from '@superset-ui/core';
import { TimeFormatFunction } from './types';

export const PREVIEW_TIME = new Date(Date.UTC(2017, 1, 14, 11, 22, 33));

export default class TimeFormatter extends ExtensibleFunction {
id: string;
label: string;
description: string;
formatFunc: TimeFormatFunction;
useLocalTime: boolean;

constructor(config: {
id: string;
label?: string;
description?: string;
formatFunc: TimeFormatFunction;
useLocalTime?: boolean;
}) {
super((value: Date | null | undefined) => this.format(value));

const {
id = isRequired('config.id'),
label,
description = '',
formatFunc = isRequired('config.formatFunc'),
useLocalTime = false,
} = config;

this.id = id;
this.label = label || id;
this.description = description;
this.formatFunc = formatFunc;
this.useLocalTime = useLocalTime;
}

format(value: Date | null | undefined) {
if (value === null || value === undefined) {
return `${value}`;
}

return this.formatFunc(value);
}

preview(value: Date = PREVIEW_TIME) {
return `${value.toUTCString()} => ${this.format(value)}`;
}
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
import { RegistryWithDefaultKey } from '@superset-ui/core';
import TimeFormats, { LOCAL_PREFIX } from './TimeFormats';
import createD3TimeFormatter from './factories/createD3TimeFormatter';
import TimeFormatter from './TimeFormatter';

export default class TimeFormatterRegistry extends RegistryWithDefaultKey {
export default class TimeFormatterRegistry extends RegistryWithDefaultKey<
TimeFormatter,
TimeFormatter
> {
constructor() {
super({
initialDefaultKey: TimeFormats.DATABASE_DATETIME,
name: 'TimeFormatter',
});
}

get(format) {
const targetFormat = (format || this.defaultKey).trim();
get(format?: string) {
const targetFormat = `${format || this.defaultKey}`.trim();

if (this.has(targetFormat)) {
return super.get(targetFormat);
return super.get(targetFormat) as TimeFormatter;
}

// Create new formatter if does not exist
Expand All @@ -26,7 +30,7 @@ export default class TimeFormatterRegistry extends RegistryWithDefaultKey {
return formatter;
}

format(format, value) {
format(format: string, value: Date | null | undefined): string {
return this.get(format)(value);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ const getInstance = makeSingleton(TimeFormatterRegistry);

export default getInstance;

export function getTimeFormatter(formatId) {
export function getTimeFormatter(formatId: string) {
return getInstance().get(formatId);
}

export function formatTime(formatId, value) {
export function formatTime(formatId: string, value: Date | null | undefined) {
return getInstance().format(formatId, value);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,19 @@ import { isRequired } from '@superset-ui/core';
import TimeFormatter from '../TimeFormatter';
import { LOCAL_PREFIX } from '../TimeFormats';

export default function createD3TimeFormatter({
description,
formatString = isRequired('formatString'),
label,
useLocalTime = false,
export default function createD3TimeFormatter(config: {
description?: string;
formatString: string;
label?: string;
useLocalTime?: boolean;
}) {
const {
description,
formatString = isRequired('formatString'),
label,
useLocalTime = false,
} = config;

const id = useLocalTime ? `${LOCAL_PREFIX}${formatString}` : formatString;
const format = useLocalTime ? timeFormat : utcFormat;
const formatFunc = format(formatString);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,29 @@ import { utcFormat, timeFormat } from 'd3-time-format';
import { utcUtils, localTimeUtils } from '../utils';
import TimeFormatter from '../TimeFormatter';

type FormatsByStep = Partial<{
millisecond: string;
second: string;
minute: string;
hour: string;
day: string;
week: string;
month: string;
year: string;
}>;

export default function createMultiFormatter({
id,
label,
description,
formats = {},
useLocalTime = false,
}: {
id: string;
label?: string;
description?: string;
formats?: FormatsByStep;
useLocalTime?: boolean;
}) {
const {
millisecond = '.%L',
Expand Down Expand Up @@ -41,7 +58,7 @@ export default function createMultiFormatter({
isNotFirstMonth,
} = useLocalTime ? localTimeUtils : utcUtils;

function multiFormatFunc(date) {
function multiFormatFunc(date: Date) {
if (hasMillisecond(date)) {
return formatMillisecond;
} else if (hasSecond(date)) {
Expand All @@ -61,7 +78,7 @@ export default function createMultiFormatter({

return new TimeFormatter({
description,
formatFunc: date => multiFormatFunc(date)(date),
formatFunc: (date: Date) => multiFormatFunc(date)(date),
id,
label,
useLocalTime,
Expand Down
2 changes: 2 additions & 0 deletions packages/superset-ui-time-format/src/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/* eslint-disable import/prefer-default-export */
export type TimeFormatFunction = (value: Date) => string;
Original file line number Diff line number Diff line change
Expand Up @@ -29,23 +29,24 @@ import {
utcSaturday,
utcMonth,
utcYear,
CountableTimeInterval,
} from 'd3-time';

function createUtils(useLocalTime = false) {
let floorSecond;
let floorMinute;
let floorHour;
let floorDay;
let floorWeek;
let floorWeekStartOnSunday;
let floorWeekStartOnMonday;
let floorWeekStartOnTuesday;
let floorWeekStartOnWednesday;
let floorWeekStartOnThursday;
let floorWeekStartOnFriday;
let floorWeekStartOnSaturday;
let floorMonth;
let floorYear;
let floorSecond: CountableTimeInterval;
let floorMinute: CountableTimeInterval;
let floorHour: CountableTimeInterval;
let floorDay: CountableTimeInterval;
let floorWeek: CountableTimeInterval;
let floorWeekStartOnSunday: CountableTimeInterval;
let floorWeekStartOnMonday: CountableTimeInterval;
let floorWeekStartOnTuesday: CountableTimeInterval;
let floorWeekStartOnWednesday: CountableTimeInterval;
let floorWeekStartOnThursday: CountableTimeInterval;
let floorWeekStartOnFriday: CountableTimeInterval;
let floorWeekStartOnSaturday: CountableTimeInterval;
let floorMonth: CountableTimeInterval;
let floorYear: CountableTimeInterval;
if (useLocalTime) {
floorSecond = timeSecond;
floorMinute = timeMinute;
Expand Down Expand Up @@ -93,20 +94,20 @@ function createUtils(useLocalTime = false) {
floorWeekStartOnSaturday,
floorMonth,
floorYear,
hasMillisecond: date => floorSecond(date) < date,
hasSecond: date => floorMinute(date) < date,
hasMinute: date => floorHour(date) < date,
hasHour: date => floorDay(date) < date,
isNotFirstDayOfMonth: date => floorMonth(date) < date,
isNotFirstDayOfWeek: date => floorWeek(date) < date,
isNotFirstDayOfWeekStartOnSunday: date => floorWeekStartOnSunday(date) < date,
isNotFirstDayOfWeekStartOnMonday: date => floorWeekStartOnMonday(date) < date,
isNotFirstDayOfWeekStartOnTuesday: date => floorWeekStartOnTuesday(date) < date,
isNotFirstDayOfWeekStartOnWednesday: date => floorWeekStartOnWednesday(date) < date,
isNotFirstDayOfWeekStartOnThursday: date => floorWeekStartOnThursday(date) < date,
isNotFirstDayOfWeekStartOnFriday: date => floorWeekStartOnFriday(date) < date,
isNotFirstDayOfWeekStartOnSaturday: date => floorWeekStartOnSaturday(date) < date,
isNotFirstMonth: date => floorYear(date) < date,
hasMillisecond: (date: Date) => floorSecond(date) < date,
hasSecond: (date: Date) => floorMinute(date) < date,
hasMinute: (date: Date) => floorHour(date) < date,
hasHour: (date: Date) => floorDay(date) < date,
isNotFirstDayOfMonth: (date: Date) => floorMonth(date) < date,
isNotFirstDayOfWeek: (date: Date) => floorWeek(date) < date,
isNotFirstDayOfWeekStartOnSunday: (date: Date) => floorWeekStartOnSunday(date) < date,
isNotFirstDayOfWeekStartOnMonday: (date: Date) => floorWeekStartOnMonday(date) < date,
isNotFirstDayOfWeekStartOnTuesday: (date: Date) => floorWeekStartOnTuesday(date) < date,
isNotFirstDayOfWeekStartOnWednesday: (date: Date) => floorWeekStartOnWednesday(date) < date,
isNotFirstDayOfWeekStartOnThursday: (date: Date) => floorWeekStartOnThursday(date) < date,
isNotFirstDayOfWeekStartOnFriday: (date: Date) => floorWeekStartOnFriday(date) < date,
isNotFirstDayOfWeekStartOnSaturday: (date: Date) => floorWeekStartOnSaturday(date) < date,
isNotFirstMonth: (date: Date) => floorYear(date) < date,
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,18 @@ import TimeFormatter, { PREVIEW_TIME } from '../src/TimeFormatter';
describe('TimeFormatter', () => {
describe('new TimeFormatter(config)', () => {
it('requires config.id', () => {
expect(() => new TimeFormatter()).toThrow();
expect(
() =>
// @ts-ignore -- intentionally pass invalid input
new TimeFormatter({
formatFunc: () => 'test',
}),
).toThrow();
});
it('requires config.formatFunc', () => {
expect(
() =>
// @ts-ignore -- intentionally pass invalid input
new TimeFormatter({
id: 'my_format',
}),
Expand All @@ -17,7 +24,7 @@ describe('TimeFormatter', () => {
describe('formatter is also a format function itself', () => {
const formatter = new TimeFormatter({
id: 'year_only',
formatFunc: value => `${value.getFullYear()}`,
formatFunc: (value: Date) => `${value.getFullYear()}`,
});
it('returns formatted value', () => {
expect(formatter(PREVIEW_TIME)).toEqual('2017');
Expand All @@ -33,10 +40,10 @@ describe('TimeFormatter', () => {
formatFunc: value => `${value.getFullYear()}`,
});
it('handles null', () => {
expect(formatter.format(null)).toBeNull();
expect(formatter.format(null)).toEqual('null');
});
it('handles undefined', () => {
expect(formatter.format(undefined)).toBeUndefined();
expect(formatter.format(undefined)).toEqual('undefined');
});
it('otherwise returns formatted value', () => {
expect(formatter.format(PREVIEW_TIME)).toEqual('2017');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import TimeFormatterRegistry from '../src/TimeFormatterRegistry';
import { TimeFormats, TimeFormatter, PREVIEW_TIME } from '../src';

describe('TimeFormatterRegistry', () => {
let registry;
let registry: TimeFormatterRegistry;
beforeEach(() => {
registry = new TimeFormatterRegistry();
});
Expand Down
Loading

0 comments on commit 727618b

Please sign in to comment.