Skip to content

Commit

Permalink
Create a Jaeger ui-kit package
Browse files Browse the repository at this point in the history
Create a packate to export componets.
Moved a minor component to this package to test the integration with jaeger-ui package.

Components.
  -  TimelineRow

Resolves: jaegertracing#248

Signed-off-by: Alberto Gutierrez <aljesusg@gmail.com>
  • Loading branch information
aljesusg committed Sep 24, 2018
1 parent d148dc5 commit d4f747f
Show file tree
Hide file tree
Showing 16 changed files with 368 additions and 3 deletions.
1 change: 1 addition & 0 deletions packages/jaeger-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"sinon": "^3.2.1"
},
"dependencies": {
"@jaegertracing/ui-kit": "0.0.1-dev.1",
"@jaegertracing/plexus": "0.0.1-dev.3",
"antd": "^3.0.3",
"chance": "^1.0.10",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@
// limitations under the License.

import * as React from 'react';
import { TimelineRow } from '@jaegertracing/ui-kit';

import IoAlert from 'react-icons/lib/io/alert';
import IoArrowRightA from 'react-icons/lib/io/arrow-right-a';

import TimelineRow from './TimelineRow';
import SpanTreeOffset from './SpanTreeOffset';
import SpanBar from './SpanBar';
import Ticks from './Ticks';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
// limitations under the License.

import React from 'react';
import { TimelineRow } from '@jaegertracing/ui-kit';

import SpanDetail from './SpanDetail';
import DetailState from './SpanDetail/DetailState';
import SpanTreeOffset from './SpanTreeOffset';
import TimelineRow from './TimelineRow';
import type { Log, Span, KeyValuePair, Link } from '../../../types/trace';

import './SpanDetailRow.css';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@
// limitations under the License.

import * as React from 'react';
import { TimelineRow } from '@jaegertracing/ui-kit';

import TimelineCollapser from './TimelineCollapser';
import TimelineColumnResizer from './TimelineColumnResizer';
import TimelineViewingLayer from './TimelineViewingLayer';
import Ticks from '../Ticks';
import TimelineRow from '../TimelineRow';
import type { ViewRangeTime, ViewRangeTimeUpdate } from '../../types';

import './TimelineHeaderRow.css';
Expand Down
12 changes: 12 additions & 0 deletions packages/ui-kit/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"presets": ["env", "react"],
"plugins": [
"transform-object-rest-spread",
"transform-react-jsx",
["import", {
"libraryName": "antd",
"style": true
}
]
]
}
47 changes: 47 additions & 0 deletions packages/ui-kit/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"name": "@jaegertracing/ui-kit",
"version": "0.0.1-dev.1",
"main": "build/index.js",
"license": "Apache-2.0",
"peerDependencies": {
"react": "^15.5.4"
},
"scripts": {
"test": "jest",
"start": "webpack --watch",
"build": "webpack"
},
"devDependencies": {
"babel-cli": "^6.24.1",
"babel-core": "^6.24.1",
"babel-loader": "^7.0.0",
"babel-plugin-import": "^1.6.3",
"babel-plugin-transform-object-rest-spread": "^6.23.0",
"babel-plugin-transform-react-jsx": "^6.24.1",
"babel-preset-env": "^1.5.1",
"css-loader": "^1.0.0",
"enzyme": "^3.2.0",
"enzyme-adapter-react-16": "^1.1.0",
"enzyme-to-json": "^3.3.0",
"identity-obj-proxy": "^3.0.0",
"style-loader": "^0.23.0"
},
"dependencies": {
"antd": "^3.0.3",
"deep-freeze": "^0.0.1",
"jest": "^21.2.1",
"lodash": "^4.17.4",
"moment": "^2.18.1",
"prop-types": "^15.5.10",
"react": "^16.3.2",
"react-router-dom": "^4.1.2",
"recompose": "^0.25.0"
},
"jest": {
"setupTestFrameworkScriptFile": "./src/setupTests.js",
"collectCoverageFrom": ["src/**/*.js"],
"moduleNameMapper": {
"\\.(css|less)$": "identity-obj-proxy"
}
}
}
1 change: 1 addition & 0 deletions packages/ui-kit/src/components/TimelineRow/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as TimelineRow } from './TimelineRow';
1 change: 1 addition & 0 deletions packages/ui-kit/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './components/TimelineRow';
27 changes: 27 additions & 0 deletions packages/ui-kit/src/setupTests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (c) 2017 Uber Technologies, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// NOTE: This must be above the enzyme related code below, and the enzyme
// related imports MUST use `require`
import { polyfill as rafPolyfill } from './utils/test/requestAnimationFrame';
// react requires requestAnimationFrame polyfill when using jsdom
rafPolyfill();

/* eslint-disable import/no-extraneous-dependencies */
const Enzyme = require('enzyme');
const EnzymeAdapter = require('enzyme-adapter-react-16');
const createSerializer = require('enzyme-to-json').createSerializer;

Enzyme.configure({ adapter: new EnzymeAdapter() });
expect.addSnapshotSerializer(createSerializer({ mode: 'deep' }));
123 changes: 123 additions & 0 deletions packages/ui-kit/src/utils/date.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
// Copyright (c) 2017 Uber Technologies, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import moment from 'moment';
import _ from 'lodash';

import { toFloatPrecision } from './number';

const TODAY = 'Today';
const YESTERDAY = 'Yesterday';

export const STANDARD_DATE_FORMAT = 'YYYY-MM-DD';
export const STANDARD_TIME_FORMAT = 'HH:mm';
export const STANDARD_DATETIME_FORMAT = 'LLL';
export const ONE_MILLISECOND = 1000;
export const ONE_SECOND = 1000 * ONE_MILLISECOND;
export const DEFAULT_MS_PRECISION = Math.log10(ONE_MILLISECOND);

/**
* @param {number} timestamp
* @param {number} initialTimestamp
* @param {number} totalDuration
* @return {number} 0-100 percentage
*/
export function getPercentageOfDuration(duration, totalDuration) {
return duration / totalDuration * 100;
}

const quantizeDuration = (duration, floatPrecision, conversionFactor) =>
toFloatPrecision(duration / conversionFactor, floatPrecision) * conversionFactor;

/**
* @param {number} duration (in microseconds)
* @return {string} formatted, unit-labelled string with time in milliseconds
*/
export function formatDate(duration) {
return moment(duration / ONE_MILLISECOND).format(STANDARD_DATE_FORMAT);
}

/**
* @param {number} duration (in microseconds)
* @return {string} formatted, unit-labelled string with time in milliseconds
*/
export function formatTime(duration) {
return moment(duration / ONE_MILLISECOND).format(STANDARD_TIME_FORMAT);
}

/**
* @param {number} duration (in microseconds)
* @return {string} formatted, unit-labelled string with time in milliseconds
*/
export function formatDatetime(duration) {
return moment(duration / ONE_MILLISECOND).format(STANDARD_DATETIME_FORMAT);
}

/**
* @param {number} duration (in microseconds)
* @return {string} formatted, unit-labelled string with time in milliseconds
*/
export function formatMillisecondTime(duration) {
const targetDuration = quantizeDuration(duration, DEFAULT_MS_PRECISION, ONE_MILLISECOND);
return `${moment.duration(targetDuration / ONE_MILLISECOND).asMilliseconds()}ms`;
}

/**
* @param {number} duration (in microseconds)
* @return {string} formatted, unit-labelled string with time in seconds
*/
export function formatSecondTime(duration) {
const targetDuration = quantizeDuration(duration, DEFAULT_MS_PRECISION, ONE_SECOND);
return `${moment.duration(targetDuration / ONE_MILLISECOND).asSeconds()}s`;
}

/**
* Humanizes the duration based on the inputUnit
*
* Example:
* 5000ms => 5s
* 1000μs => 1ms
*/
export function formatDuration(duration, inputUnit = 'microseconds') {
let d = duration;
if (inputUnit === 'microseconds') {
d = duration / 1000;
}
let units = 'ms';
if (d >= 1000) {
units = 's';
d /= 1000;
}
return _.round(d, 2) + units;
}

export function formatRelativeDate(value, fullMonthName = false) {
const m = !(value instanceof moment) ? moment(value) : value;
const monthFormat = fullMonthName ? 'MMMM' : 'MMM';
const dt = new Date();
if (dt.getFullYear() !== m.year()) {
return m.format(`${monthFormat} D, YYYY`);
}
const mMonth = m.month();
const mDate = m.date();
const date = dt.getDate();
if (mMonth === dt.getMonth() && mDate === date) {
return TODAY;
}
dt.setDate(date - 1);
if (mMonth === dt.getMonth() && mDate === dt.getDate()) {
return YESTERDAY;
}
return m.format(`${monthFormat} D`);
}
39 changes: 39 additions & 0 deletions packages/ui-kit/src/utils/number.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright (c) 2017 Uber Technologies, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
* given a number and a desired precision for the floating
* side, return the number at the new precision.
*
* toFloatPrecision(3.55, 1) // 3.5
* toFloatPrecision(0.04422, 2) // 0.04
* toFloatPrecision(6.24e6, 2) // 6240000.00
*
* does not support numbers that use "e" notation on toString.
*
* @param {number} number
* @param {number} precision
* @return {number} number at new floating precision
*/
// eslint-disable-next-line import/prefer-default-export
export function toFloatPrecision(number, precision) {
const log10Length = Math.floor(Math.log10(Math.abs(number))) + 1;
const targetPrecision = precision + log10Length;

if (targetPrecision <= 0) {
return Math.trunc(number);
}

return Number(number.toPrecision(targetPrecision));
}
38 changes: 38 additions & 0 deletions packages/ui-kit/src/utils/number.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright (c) 2017 Uber Technologies, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import * as numberUtils from './number';

it('toFloatPrecision() should work for greater-than-0 numbers', () => {
expect(numberUtils.toFloatPrecision(3.52, 1)).toBe(3.5);
expect(numberUtils.toFloatPrecision(-30.52, 1)).toBe(-30.5);
expect(numberUtils.toFloatPrecision(301.24, 0)).toBe(301);
expect(numberUtils.toFloatPrecision(-3.14, 0)).toBe(-3);
expect(numberUtils.toFloatPrecision(3.551, 1)).toBe(3.6);
expect(numberUtils.toFloatPrecision(-30.55, 1)).toBe(-30.6);
expect(numberUtils.toFloatPrecision(301.55, 0)).toBe(302);
expect(numberUtils.toFloatPrecision(-3.55, 0)).toBe(-4);
});

it('toFloatPrecision() should work for less-than-0 numbers', () => {
expect(numberUtils.toFloatPrecision(0.24, 1)).toBe(0.2);
expect(numberUtils.toFloatPrecision(-0.026, 1)).toBe(0);
expect(numberUtils.toFloatPrecision(0.51, 1)).toBe(0.5);
expect(numberUtils.toFloatPrecision(-0.307, 2)).toBe(-0.31);
});

it('toFloatPrecision() should work for e-notation numbers', () => {
expect(numberUtils.toFloatPrecision(6.24e6, 1)).toBe(6240000);
expect(numberUtils.toFloatPrecision(-5.5e4, 1)).toBe(-55000);
});
40 changes: 40 additions & 0 deletions packages/ui-kit/src/utils/test/requestAnimationFrame.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright (c) 2017 Uber Technologies, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

const DEFAULT_ELAPSE = 0;

export default function requestAnimationFrame(callback) {
return setTimeout(callback, DEFAULT_ELAPSE);
}

export function cancelAnimationFrame(id) {
return clearTimeout(id);
}

export function polyfill(target, msElapse = DEFAULT_ELAPSE) {
const _target = target || global;
if (!_target.requestAnimationFrame) {
if (msElapse === DEFAULT_ELAPSE) {
// eslint-disable-next-line no-param-reassign
_target.requestAnimationFrame = requestAnimationFrame;
} else {
// eslint-disable-next-line no-param-reassign, no-shadow
_target.requestAnimationFrame = callback => setTimeout(callback, msElapse);
}
}
if (!_target.cancelAnimationFrame) {
// eslint-disable-next-line no-param-reassign
_target.cancelAnimationFrame = cancelAnimationFrame;
}
}
Loading

0 comments on commit d4f747f

Please sign in to comment.