Skip to content

Commit 5abad38

Browse files
authored
Merge branch 'main' into cartesian_drilldown
2 parents 3a1b067 + 2ea76f4 commit 5abad38

File tree

159 files changed

+6261
-4303
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

159 files changed

+6261
-4303
lines changed

package-lock.json

Lines changed: 3515 additions & 3073 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,14 @@
3636
"@angular/platform-browser": "^12.2.1",
3737
"@angular/platform-browser-dynamic": "^12.2.1",
3838
"@angular/router": "^12.2.1",
39-
"@apollo/client": "^3.5.5",
40-
"@fullstory/browser": "^1.4.9",
39+
"@apollo/client": "^3.5.6",
40+
"@fullstory/browser": "^1.4.10",
4141
"@hypertrace/hyperdash": "^1.2.1",
4242
"@hypertrace/hyperdash-angular": "^2.6.0",
4343
"@types/d3-hierarchy": "^2.0.2",
4444
"@types/d3-transition": "1.1.5",
4545
"apollo-angular": "^2.6.0",
46-
"core-js": "^3.19.3",
46+
"core-js": "^3.20.2",
4747
"d3-array": "^2.12.0",
4848
"d3-axis": "^2.1.0",
4949
"d3-brush": "^1.1.6",
@@ -59,11 +59,12 @@
5959
"d3-shape": "^1.3.5",
6060
"d3-transition": "^1.2.0",
6161
"d3-zoom": "^1.8.3",
62-
"graphql": "^15.7.2",
62+
"graphql": "^15.8.0",
6363
"graphql-tag": "^2.12.6",
6464
"iso8601-duration": "^1.3.0",
6565
"lodash-es": "^4.17.21",
66-
"mixpanel-browser": "^2.42.0",
66+
"mixpanel-browser": "^2.43.0",
67+
"ngx-color": "7.0.0",
6768
"rxjs": "~6.6.7",
6869
"tslib": "^2.3.1",
6970
"uuid": "^8.3.2",
@@ -75,41 +76,41 @@
7576
"@angular/cli": "12.2.1",
7677
"@angular/compiler-cli": "~12.2.1",
7778
"@angular/language-service": "~12.2.1",
78-
"@commitlint/cli": "^15.0.0",
79-
"@commitlint/config-conventional": "^15.0.0",
80-
"@compodoc/compodoc": "^1.1.15",
81-
"@ngneat/spectator": "^8.3.1",
79+
"@commitlint/cli": "^16.0.1",
80+
"@commitlint/config-conventional": "^16.0.0",
81+
"@compodoc/compodoc": "^1.1.18",
82+
"@ngneat/spectator": "^8.3.2",
8283
"@types/d3-array": "^2.9.0",
8384
"@types/d3-axis": "^2.0.0",
8485
"@types/d3-brush": "^2.1.0",
8586
"@types/d3-drag": "^1.2.3",
8687
"@types/d3-force": "^2.1.0",
8788
"@types/d3-path": "^2.0.0",
8889
"@types/d3-quadtree": "^1.0.7",
89-
"@types/d3-scale": "^2.1.1",
90+
"@types/d3-scale": "^2.2.6",
9091
"@types/d3-selection": "^1.4.2",
9192
"@types/d3-shape": "^2.1.0",
9293
"@types/d3-zoom": "^1.7.5",
93-
"@types/jest": "^26.0.24",
94+
"@types/jest": "^27.4.0",
9495
"@types/lodash-es": "^4.17.5",
95-
"@types/mixpanel-browser": "^2.35.7",
96-
"@types/node": "^16.11.10",
97-
"@types/uuid": "^8.3.1",
96+
"@types/mixpanel-browser": "^2.36.0",
97+
"@types/node": "^17.0.5",
98+
"@types/uuid": "^8.3.4",
9899
"@types/webpack-env": "^1.16.3",
99100
"codelyzer": "^6.0.2",
100101
"commitizen": "^4.2.4",
101102
"cz-conventional-changelog": "^3.3.0",
102103
"husky": "^7.0.4",
103104
"jest": "^26.6.3",
104-
"jest-config": "^27.4.3",
105-
"jest-html-reporter": "^3.4.1",
105+
"jest-config": "^27.4.7",
106+
"jest-html-reporter": "^3.4.2",
106107
"jest-junit": "^13.0.0",
107108
"jest-preset-angular": "^8.4.0",
108109
"lodash": "^4.17.21",
109-
"ng-mocks": "^12.5.0",
110+
"ng-mocks": "^12.5.1",
110111
"ng-packagr": "^12.2.5",
111112
"prettier": "^2.2.1",
112-
"pretty-quick": "^3.1.1",
113+
"pretty-quick": "^3.1.3",
113114
"ts-node": "~10.4.0",
114115
"tslint": "~6.1.3",
115116
"tslint-config-prettier": "^1.18.0",

projects/common/src/color/color.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ export const enum Color {
22
Blue2 = '#b8d3ff',
33
Blue3 = '#70a7ff',
44
Blue4 = '#2478ff',
5+
Blue6 = '#0043ad',
56
Blue5 = '#0053d7',
67
Blue7 = '#003385',
78
BlueGray1 = '#70a7ff',
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { Time } from './time';
2+
3+
describe('Time', () => {
4+
const mockedTime = new Time(8, 30);
5+
6+
test('can get label', () => {
7+
expect(mockedTime.label).toBe('8:30 AM');
8+
});
9+
10+
test('can get date', () => {
11+
expect(mockedTime.date).toEqual(new Date(`${new Date().toDateString()} 08:30Z`));
12+
});
13+
14+
test('can get ISO String from time', () => {
15+
expect(mockedTime.toISOString()).toBe('08:30:00.000Z');
16+
});
17+
18+
test('can compare two times', () => {
19+
expect(mockedTime.equals(new Time(8, 30))).toBeTruthy();
20+
expect(mockedTime.equals(new Time(9, 30))).toBeFalsy();
21+
});
22+
});

projects/common/src/time/time.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,12 @@ export class Time {
3131
public get date(): Date {
3232
return this._date;
3333
}
34+
35+
public toISOString(): string {
36+
return this.date.toISOString().substring(11);
37+
}
38+
39+
public equals(other?: Time): boolean {
40+
return this.toISOString() === other?.toISOString();
41+
}
3442
}

projects/common/src/utilities/types/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ export type DistributiveOmit<T, K extends UnionKeys<T>> = T extends any ? Omit<T
77

88
export type PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
99
export type RequireBy<T, K extends keyof T> = T & Required<Pick<T, K>>;
10+
export type KeysWithType<T, V> = { [K in keyof T]-?: T[K] extends V ? K : never }[keyof T];
11+
1012
export interface Dictionary<T> {
1113
[key: string]: T;
1214
}

projects/components/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@
2727
"d3-axis": "^2.1.0",
2828
"d3-scale": "^3.3.0",
2929
"d3-selection": "^1.4.2",
30-
"d3-shape": "^1.3.5"
30+
"d3-shape": "^1.3.5",
31+
"ngx-color": "7.0.0"
3132
},
3233
"devDependencies": {
3334
"@hypertrace/test-utils": "^0.0.0"
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
@import 'color-palette';
2+
@import 'mixins';
3+
4+
.color-picker {
5+
display: flex;
6+
flex-flow: row wrap;
7+
align-items: center;
8+
9+
.color {
10+
width: 24px;
11+
height: 24px;
12+
border-radius: 50%;
13+
margin-right: 6px;
14+
cursor: pointer;
15+
16+
&.selected {
17+
border: 2px solid $blue-4;
18+
}
19+
}
20+
21+
.add-icon {
22+
cursor: pointer;
23+
}
24+
}
25+
26+
.container {
27+
width: 200px;
28+
height: 200px;
29+
cursor: pointer;
30+
}
31+
32+
.color-sketch {
33+
width: 200px;
34+
height: 200px;
35+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import { CommonModule } from '@angular/common';
2+
import { fakeAsync } from '@angular/core/testing';
3+
import { IconType } from '@hypertrace/assets-library';
4+
import { Color, NavigationService } from '@hypertrace/common';
5+
import { IconComponent } from '@hypertrace/components';
6+
import { createHostFactory, mockProvider, Spectator } from '@ngneat/spectator/jest';
7+
import { MockComponent } from 'ng-mocks';
8+
import { SketchComponent } from 'ngx-color/sketch';
9+
import { NEVER, Observable } from 'rxjs';
10+
import { NotificationService } from '../notification/notification.service';
11+
import { PopoverModule } from '../popover/popover.module';
12+
import { ColorPickerComponent } from './color-picker.component';
13+
14+
describe('Color Picker component', () => {
15+
let spectator: Spectator<ColorPickerComponent>;
16+
17+
const createHost = createHostFactory({
18+
component: ColorPickerComponent,
19+
imports: [CommonModule, PopoverModule],
20+
providers: [
21+
mockProvider(NotificationService, { withNotification: (x: Observable<unknown>) => x }),
22+
mockProvider(NavigationService, {
23+
navigation$: NEVER
24+
})
25+
],
26+
declarations: [MockComponent(SketchComponent), MockComponent(IconComponent)]
27+
});
28+
29+
test('should render color picker with default colors', fakeAsync(() => {
30+
const onSelectionChangeSpy = jest.fn();
31+
spectator = createHost(
32+
`<ht-color-picker (selectedChange)="onSelectionChange($event)">
33+
</ht-color-picker>`,
34+
{
35+
hostProps: {
36+
onSelectionChange: onSelectionChangeSpy
37+
}
38+
}
39+
);
40+
41+
const colors = spectator.queryAll('.color-picker .color');
42+
expect(colors.length).toBe(7);
43+
expect(spectator.query(IconComponent)?.icon).toBe(IconType.Add);
44+
45+
spectator.click(colors[1]);
46+
expect(spectator.component.selected).toEqual(Color.Blue3);
47+
expect(onSelectionChangeSpy).toHaveBeenCalledWith(Color.Blue3);
48+
49+
spectator.click('.add-icon');
50+
spectator.tick();
51+
52+
expect(spectator.query('.color-sketch', { root: true })).toExist();
53+
}));
54+
});
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
2+
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
3+
import { IconType } from '@hypertrace/assets-library';
4+
import { Color } from '@hypertrace/common';
5+
import { IconSize } from '../icon/icon-size';
6+
7+
@Component({
8+
selector: 'ht-color-picker',
9+
styleUrls: ['./color-picker.component.scss'],
10+
changeDetection: ChangeDetectionStrategy.OnPush,
11+
providers: [
12+
{
13+
provide: NG_VALUE_ACCESSOR,
14+
multi: true,
15+
useExisting: ColorPickerComponent
16+
}
17+
],
18+
template: `
19+
<div class="color-picker">
20+
<div
21+
class="color"
22+
*ngFor="let color of this.paletteColors"
23+
[ngClass]="{ selected: color === this.selected }"
24+
[style.backgroundColor]="color"
25+
(click)="this.selectColor(color)"
26+
></div>
27+
<ht-popover>
28+
<ht-popover-trigger>
29+
<ht-icon class="add-icon" icon="${IconType.Add}" size="${IconSize.Small}"></ht-icon>
30+
</ht-popover-trigger>
31+
<ht-popover-content>
32+
<div class="container">
33+
<color-sketch class="color-sketch" (onChange)="this.onAddColorToPalette($event.color.hex)"></color-sketch>
34+
</div>
35+
</ht-popover-content>
36+
</ht-popover>
37+
</div>
38+
`
39+
})
40+
export class ColorPickerComponent implements ControlValueAccessor {
41+
@Input()
42+
public selected?: string;
43+
44+
@Output()
45+
private readonly selectedChange: EventEmitter<string> = new EventEmitter<string>();
46+
47+
private readonly paletteSet: Set<string> = new Set<string>([
48+
Color.Brown1,
49+
Color.Blue3,
50+
Color.Green3,
51+
Color.Orange3,
52+
Color.Purple3,
53+
Color.Red3,
54+
Color.Yellow3
55+
]);
56+
public paletteColors: string[] = Array.from(this.paletteSet);
57+
58+
private propagateControlValueChange?: (value: string | undefined) => void;
59+
private propagateControlValueChangeOnTouch?: (value: string | undefined) => void;
60+
61+
public onAddColorToPalette(color: string): void {
62+
this.paletteSet.add(color);
63+
this.paletteColors = Array.from(this.paletteSet);
64+
this.selectColor(color);
65+
}
66+
67+
public selectColor(color: string): void {
68+
this.selected = color;
69+
this.selectedChange.emit(color);
70+
this.propagateValueChangeToFormControl(color);
71+
}
72+
73+
private propagateValueChangeToFormControl(value?: string): void {
74+
this.propagateControlValueChange?.(value);
75+
this.propagateControlValueChangeOnTouch?.(value);
76+
}
77+
78+
public writeValue(color?: string): void {
79+
this.selected = color;
80+
}
81+
82+
public registerOnChange(onChange: (value?: string) => void): void {
83+
this.propagateControlValueChange = onChange;
84+
}
85+
86+
public registerOnTouched(onTouch: (value?: string) => void): void {
87+
this.propagateControlValueChangeOnTouch = onTouch;
88+
}
89+
}

0 commit comments

Comments
 (0)