-
Notifications
You must be signed in to change notification settings - Fork 761
/
client_page.ts
120 lines (98 loc) · 3.73 KB
/
client_page.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import {AfterViewInit, ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, OnDestroy, OnInit, ViewChild} from '@angular/core';
import {MatDrawer} from '@angular/material/sidenav';
import {Title} from '@angular/platform-browser';
import {ActivatedRoute, Router} from '@angular/router';
import {Subject} from 'rxjs';
import {filter, map, takeUntil} from 'rxjs/operators';
import {isNonNull} from '../../lib/preconditions';
import {ClientPageFacade} from '../../store/client_page_facade';
import {UserFacade} from '../../store/user_facade';
import {Approval} from '../approval/approval';
// Minimalistic polyfill for ResizeObserver typings. These typings represent a
// subset of the real interface, until TypeScript implements the real typings.
// See https://github.com/Microsoft/TypeScript/issues/28502.
declare class ResizeObserver {
constructor(callback: () => void);
observe: (target: Element) => void;
unobserve: (target: Element) => void;
disconnect: () => void;
}
declare global {
interface Window {
// tslint:disable-next-line:enforce-name-casing
ResizeObserver: typeof ResizeObserver;
}
}
/**
* Component displaying the details and actions for a single Client.
*/
@Component({
templateUrl: './client_page.ng.html',
styleUrls: ['./client_page.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ClientPage implements OnInit, AfterViewInit, OnDestroy {
static readonly CLIENT_DETAILS_ROUTE = 'details';
readonly id$ = this.route.paramMap.pipe(
map(params => params.get('id')),
filter(isNonNull),
);
readonly client$ = this.clientPageFacade.selectedClient$;
readonly currentUser$ = this.userFacade.currentUser$.pipe(
map(user => user.name),
);
private readonly unsubscribe$ = new Subject<void>();
@ViewChild('clientDetailsDrawer') clientDetailsDrawer!: MatDrawer;
@ViewChild(Approval, {read: ElementRef}) approvalViewContainer?: ElementRef;
approvalHeight: number = 0;
readonly showApprovalView$ = this.clientPageFacade.approvalsEnabled$;
private readonly resizeObserver = new ResizeObserver(() => {
this.approvalHeight =
this.approvalViewContainer?.nativeElement.offsetHeight ?? 0;
this.changeDetectorRef.markForCheck();
});
constructor(
private readonly route: ActivatedRoute,
private readonly clientPageFacade: ClientPageFacade,
private readonly userFacade: UserFacade,
private readonly title: Title,
private readonly changeDetectorRef: ChangeDetectorRef,
private readonly router: Router,
) {}
ngOnInit() {
this.id$.pipe(takeUntil(this.unsubscribe$)).subscribe(id => {
this.clientPageFacade.selectClient(id);
});
this.client$
.pipe(
takeUntil(this.unsubscribe$),
)
.subscribe(client => {
const fqdn = client.knowledgeBase.fqdn;
const info = fqdn ? `${fqdn} (${client.clientId})` : client.clientId;
this.title.setTitle(`GRR | ${info}`);
});
}
ngAfterViewInit() {
if (this.approvalViewContainer !== undefined) {
this.resizeObserver.observe(this.approvalViewContainer.nativeElement);
}
const urlTokens = this.router.routerState.snapshot.url.split('/');
if (urlTokens[urlTokens.length - 1] === ClientPage.CLIENT_DETAILS_ROUTE) {
this.clientDetailsDrawer.open();
}
this.clientDetailsDrawer.openedStart.subscribe(() => {
this.router.navigate(['details'], {relativeTo: this.route});
});
this.clientDetailsDrawer.closedStart.subscribe(() => {
this.router.navigate(['.'], {relativeTo: this.route});
});
}
onClientDetailsButtonClick() {
this.clientDetailsDrawer.toggle();
}
ngOnDestroy() {
this.unsubscribe$.next();
this.unsubscribe$.complete();
}
}