Skip to content

Commit 8f0b07e

Browse files
authored
Merge branch 'main' into clear-selected-in-select
2 parents 610b0ea + 379ff4e commit 8f0b07e

File tree

13 files changed

+170
-6
lines changed

13 files changed

+170
-6
lines changed

projects/common/src/preference/preference.service.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,16 @@ import { Injectable } from '@angular/core';
22
import { Observable, of, throwError } from 'rxjs';
33
import { map, switchMap } from 'rxjs/operators';
44
import { AbstractStorage } from '../utilities/browser/storage/abstract-storage';
5+
import { InMemoryStorage } from '../utilities/browser/storage/in-memory-storage';
56
import { LocalStorage } from '../utilities/browser/storage/local-storage';
67
import { SessionStorage } from '../utilities/browser/storage/session-storage';
78
import { BooleanCoercer } from '../utilities/coercers/boolean-coercer';
89
import { NumberCoercer } from '../utilities/coercers/number-coercer';
910

1011
export const enum StorageType {
1112
Local = 'local',
12-
Session = 'session'
13+
Session = 'session',
14+
InMemory = 'in-memory'
1315
}
1416

1517
@Injectable({
@@ -24,7 +26,11 @@ export class PreferenceService {
2426
private readonly numberCoercer: NumberCoercer = new NumberCoercer();
2527
private readonly booleanCoercer: BooleanCoercer = new BooleanCoercer();
2628

27-
public constructor(private readonly localStorage: LocalStorage, private readonly sessionStorage: SessionStorage) {}
29+
public constructor(
30+
private readonly localStorage: LocalStorage,
31+
private readonly sessionStorage: SessionStorage,
32+
private readonly inMemoryStorage: InMemoryStorage
33+
) {}
2834

2935
/**
3036
* Returns the current storage value if defined, else the default value. The observable
@@ -94,6 +100,8 @@ export class PreferenceService {
94100
switch (type) {
95101
case StorageType.Session:
96102
return this.sessionStorage;
103+
case StorageType.InMemory:
104+
return this.inMemoryStorage;
97105
case StorageType.Local:
98106
default:
99107
return this.localStorage;
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { Injectable } from '@angular/core';
2+
import { AbstractStorage } from './abstract-storage';
3+
4+
@Injectable({ providedIn: 'root' })
5+
export class InMemoryStorage extends AbstractStorage {
6+
public constructor() {
7+
super(
8+
new (class {
9+
private readonly data: Map<string, string> = new Map();
10+
11+
public get length(): number {
12+
return this.data.size;
13+
}
14+
15+
public clear(): void {
16+
this.data.clear();
17+
}
18+
19+
public getItem(key: string): string | null {
20+
// tslint:disable-next-line: no-null-keyword
21+
return this.data.get(key) ?? null;
22+
}
23+
24+
public key(index: number): string | null {
25+
// tslint:disable-next-line: no-null-keyword
26+
return Array.from(this.data.keys())[index] ?? null;
27+
}
28+
29+
public removeItem(key: string): void {
30+
this.data.delete(key);
31+
}
32+
33+
public setItem(key: string, value: string): void {
34+
this.data.set(key, value);
35+
}
36+
})()
37+
);
38+
}
39+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
2+
import { ContentHolder, CONTENT_HOLDER_TEMPLATE } from '../../public-api';
3+
4+
@Component({
5+
selector: 'ht-draggable-item',
6+
changeDetection: ChangeDetectionStrategy.OnPush,
7+
template: CONTENT_HOLDER_TEMPLATE
8+
})
9+
export class DraggableItemComponent<T> extends ContentHolder {
10+
@Input()
11+
public disabled: boolean = false;
12+
13+
@Input()
14+
public data?: T;
15+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
@import 'color-palette';
2+
3+
.draggable-list .draggable-item {
4+
cursor: move;
5+
6+
&.disabled {
7+
background-color: $gray-2;
8+
color: $gray-5;
9+
cursor: not-allowed;
10+
}
11+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
2+
import {
3+
AfterContentInit,
4+
ChangeDetectionStrategy,
5+
Component,
6+
ContentChildren,
7+
EventEmitter,
8+
Input,
9+
Output,
10+
QueryList
11+
} from '@angular/core';
12+
import { DraggableItemComponent } from './draggable-item/draggable-item.component';
13+
14+
@Component({
15+
selector: 'ht-draggable-list',
16+
changeDetection: ChangeDetectionStrategy.OnPush,
17+
styleUrls: ['./draggable-list.component.scss'],
18+
template: `
19+
<div cdkDropList class="draggable-list" (cdkDropListDropped)="this.dropList($event)">
20+
<div
21+
*ngFor="let draggableItem of this.draggableItems"
22+
cdkDrag
23+
class="draggable-item"
24+
[ngClass]="{ disabled: disabled || draggableItem.disabled }"
25+
[cdkDragDisabled]="disabled || draggableItem.disabled"
26+
>
27+
<ng-container *ngTemplateOutlet="draggableItem.content"></ng-container>
28+
</div>
29+
</div>
30+
`
31+
})
32+
export class DraggableListComponent<T> implements AfterContentInit {
33+
@Input()
34+
public disabled: boolean = false;
35+
36+
@Output()
37+
public readonly draggableListChange: EventEmitter<T[]> = new EventEmitter();
38+
39+
@ContentChildren(DraggableItemComponent)
40+
public draggableItemsRef!: QueryList<DraggableItemComponent<T>>;
41+
42+
public draggableItems: DraggableItemComponent<T>[] = [];
43+
44+
public ngAfterContentInit(): void {
45+
this.draggableItems = this.draggableItemsRef.toArray();
46+
}
47+
48+
public dropList(event: CdkDragDrop<DraggableItemComponent<unknown>[]>): void {
49+
moveItemInArray(this.draggableItems, event.previousIndex, event.currentIndex);
50+
this.draggableListChange.emit(this.draggableItems.map(dragabbleItem => dragabbleItem.data!));
51+
}
52+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { DragDropModule } from '@angular/cdk/drag-drop';
2+
import { CommonModule } from '@angular/common';
3+
import { NgModule } from '@angular/core';
4+
import { DraggableItemComponent } from './draggable-item/draggable-item.component';
5+
import { DraggableListComponent } from './draggable-list.component';
6+
7+
@NgModule({
8+
declarations: [DraggableListComponent, DraggableItemComponent],
9+
imports: [CommonModule, DragDropModule],
10+
exports: [DraggableListComponent, DraggableItemComponent]
11+
})
12+
export class DraggableListModule {}

projects/components/src/load-async/wrapper/load-async-wrapper.component.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { ChangeDetectionStrategy, Component, Inject, InjectionToken, TemplateRef
22
import { IconType } from '@hypertrace/assets-library';
33
import { Observable } from 'rxjs';
44
import { switchMap, tap } from 'rxjs/operators';
5+
import { NotificationMode } from '../../notification/notification.component';
56
import { LoadAsyncStateType } from '../load-async-state.type';
67
import { AsyncState, LoadAsyncConfig, LoadAsyncContext, LoaderType } from '../load-async.service';
78

@@ -21,6 +22,13 @@ export const ASYNC_WRAPPER_PARAMETERS$ = new InjectionToken<Observable<LoadAsync
2122
</ng-container>
2223
<ng-container *ngSwitchDefault>
2324
<ht-message-display
25+
aria-live="polite"
26+
role="alert"
27+
[attr.data-alert-type]="
28+
state.type === '${LoadAsyncStateType.GenericError}'
29+
? '${NotificationMode.Failure}'
30+
: '${NotificationMode.Info}'
31+
"
2432
[icon]="this.icon"
2533
[title]="this.title"
2634
[description]="this.description"

projects/components/src/not-found/not-found.component.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,20 @@ import { ChangeDetectionStrategy, Component } from '@angular/core';
22
import { ImagesAssetPath } from '@hypertrace/assets-library';
33
import { NavigationService } from '@hypertrace/common';
44
import { ButtonRole, ButtonStyle } from '../button/button';
5+
import { NotificationMode } from '../notification/notification.component';
56

67
@Component({
78
selector: 'ht-not-found',
89
changeDetection: ChangeDetectionStrategy.OnPush,
910
styleUrls: ['./not-found.component.scss'],
1011
template: `
1112
<div class="not-found-container fill-container">
12-
<div class="not-found-content">
13+
<div
14+
class="not-found-content"
15+
role="alert"
16+
aria-live="assertive"
17+
[attr.data-alert-type]="'${NotificationMode.Failure}'"
18+
>
1319
<img class="not-found-image" src="${ImagesAssetPath.ErrorPage}" loading="lazy" alt="not found page" />
1420
<div class="not-found-message-wrapper">
1521
<div class="not-found-text-wrapper">
@@ -30,6 +36,7 @@ import { ButtonRole, ButtonStyle } from '../button/button';
3036
})
3137
export class NotFoundComponent {
3238
public constructor(private readonly navService: NavigationService) {}
39+
3340
public goHome(): void {
3441
this.navService.navigateToHome();
3542
}

projects/components/src/notification/notification.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { IconSize } from '../icon/icon-size';
1010
styleUrls: ['./notification.component.scss'],
1111
changeDetection: ChangeDetectionStrategy.OnPush,
1212
template: `
13-
<div class="notification-container">
13+
<div class="notification-container" role="alert" aria-live="polite" [attr.data-alert-type]="this.data.mode">
1414
<ht-icon
1515
[ngClass]="this.data.mode"
1616
class="status-icon"

projects/components/src/public-api.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@ export * from './description/description.module';
6565
export * from './divider/divider.component';
6666
export * from './divider/divider.module';
6767

68+
// Draggable list
69+
export { DraggableListComponent } from './draggable-list/draggable-list.component';
70+
export { DraggableItemComponent } from './draggable-list/draggable-item/draggable-item.component';
71+
export { DraggableListModule } from './draggable-list/draggable-list.module';
72+
6873
// Dropdown menu
6974
export { MenuDropdownComponent } from './menu-dropdown/menu-dropdown.component';
7075
export { MenuItemComponent } from './menu-dropdown/menu-item/menu-item.component';

0 commit comments

Comments
 (0)