organization and added a data service

This commit is contained in:
2020-03-02 16:08:08 -06:00
parent 0028156f74
commit eb19039ed7
11 changed files with 205 additions and 225 deletions

View File

@@ -1,6 +1,6 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { HomeComponent } from './home/home.component';
import { DashboardComponent } from './dashboard/dashboard.component';
import { AuthComponent } from './auth/auth.component';
import { SignInComponent } from './auth/sign-in/sign-in.component';
import { SignUpComponent } from './auth/sign-up/sign-up.component';
@@ -34,7 +34,7 @@ const routes: Routes = [
}
]},
{ path: 'configs', component: ConfigsComponent, canActivate: [AuthGuard]},
{ path: '', component: HomeComponent, canActivate: [AuthGuard] }];
{ path: '', component: DashboardComponent, canActivate: [AuthGuard] }];
@NgModule({
imports: [RouterModule.forRoot(routes)],

View File

@@ -6,11 +6,14 @@
mode="over"
class="sidenav">
<div class="content">
<mat-list>
<mat-list-item *ngFor="let route of nav">
<a mat-button routerLink="{{route.path}}" routerLinkActive="active" (click)="toggleMobileNav(lnav)">{{route.title}}</a>
</mat-list-item>
</mat-list>
<mat-accordion >
<mat-expansion-panel *ngFor="let location of this.dataservice.serverMessages">
<mat-expansion-panel-header>
<mat-panel-title>{{location.location}}</mat-panel-title>
</mat-expansion-panel-header>
<p *ngFor="let keys of location | keyvalue">{{keys.key}} {{keys.value}}</p>
</mat-expansion-panel>
</mat-accordion>
</div>
</mat-sidenav>
<mat-sidenav-content class="sidenav-content">
@@ -25,6 +28,9 @@
<mat-icon>menu</mat-icon>
</button>
{{title}}
<div *ngFor="let route of nav">
<a mat-button routerLink="{{route.path}}" routerLinkActive="active" (click)="toggleMobileNav(lnav)">{{route.title}}</a>
</div>
<div class="fill-space"></div>
<span whoami></span>
</mat-toolbar>
@@ -33,11 +39,14 @@
mode="side"
[opened]="!mobileQuery.matches">
<div class="content">
<mat-list>
<mat-list-item *ngFor="let route of nav">
<a mat-button routerLink="{{route.path}}" routerLinkActive="active" (click)="toggleMobileNav(lnav)">{{route.title}}</a>
</mat-list-item>
</mat-list>
<mat-accordion >
<mat-expansion-panel *ngFor="let location of this.dataservice.serverMessages">
<mat-expansion-panel-header>
<mat-panel-title>{{location.location}}</mat-panel-title>
</mat-expansion-panel-header>
<p *ngFor="let keys of location | keyvalue">{{keys.key}}: {{keys.value}}</p>
</mat-expansion-panel>
</mat-accordion>
</div>
</mat-drawer>
<mat-drawer-content>

View File

@@ -1,6 +1,8 @@
import { Component, ChangeDetectorRef, EventEmitter, Output } from '@angular/core';
import { MediaMatcher } from '@angular/cdk/layout';
import { MatSidenav } from '@angular/material/sidenav';
import { DataService } from './services/data.service';
@Component({
selector: 'app-root',
@@ -24,13 +26,17 @@ export class AppComponent {
path: '/configs'
}
];
private mobileQueryListener: () => void;
@Output() toggleSideNav = new EventEmitter();
constructor( changeDetectorRef: ChangeDetectorRef, media: MediaMatcher ) {
constructor( changeDetectorRef: ChangeDetectorRef, media: MediaMatcher , public dataservice: DataService) {
this.mobileQuery = media.matchMedia('(max-width: 600px)');
this.mobileQueryListener = () => changeDetectorRef.detectChanges();
this.mobileQuery.addListener(this.mobileQueryListener);
}
toggleMobileNav(nav: MatSidenav) {
if (this.mobileQuery.matches) {
nav.toggle();

View File

@@ -4,7 +4,7 @@ import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MaterialModule } from './material/material.module';
import { HomeComponent } from './home/home.component';
import { DashboardComponent } from './dashboard/dashboard.component';
import { ServiceWorkerModule } from '@angular/service-worker';
import { environment } from '../environments/environment';
import { ReactiveFormsModule, FormsModule } from '@angular/forms';
@@ -21,10 +21,11 @@ import { MatSortModule } from '@angular/material/sort';
import { MatTableModule } from '@angular/material/table';
import { ConfigsComponent } from './configs/configs.component';
import { HttpClientModule } from '@angular/common/http';
import { DataService } from './services/data.service';
@NgModule({
declarations: [
AppComponent,
HomeComponent,
DashboardComponent,
AuthComponent,
LoaderComponent,
CountryCodeSelectComponent,
@@ -48,7 +49,7 @@ import { HttpClientModule } from '@angular/common/http';
MatSortModule,
HttpClientModule
],
providers: [],
providers: [DataService],
bootstrap: [AppComponent],
entryComponents: [LoaderComponent, CountryCodeSelectComponent]
})

View File

@@ -1,20 +1,20 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { HomeComponent } from './home.component';
import { DashboardComponent } from './dashboard.component';
describe('HomeComponent', () => {
let component: HomeComponent;
let fixture: ComponentFixture<HomeComponent>;
describe('DashboardComponent', () => {
let component: DashboardComponent;
let fixture: ComponentFixture<DashboardComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ HomeComponent ]
declarations: [ DashboardComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(HomeComponent);
fixture = TestBed.createComponent(DashboardComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

View File

@@ -0,0 +1,58 @@
import { Component, OnInit } from '@angular/core';
import { Chart } from 'chart.js';
import { DataService, MyJSON } from '../services/data.service';
@Component({
selector: 'app-home',
templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.scss']
})
export class DashboardComponent implements OnInit {
constructor(private dataservice: DataService) { }
title = 'Bar Chart';
charts = new Array<Chart>();
messages: Array<MyJSON>;
charttypes = ['bar', 'line', 'radar', 'doughnut', 'pie', 'polarArea', 'bubble', 'scatter'];
ngOnInit() {
for (let i = 0; i < 8; i++) {
const chart = document.createElement('canvas');
chart.id = 'chart-' + i.toString();
chart.style.width = '100%';
chart.style.height = '500px';
document.getElementById('charts').appendChild(chart);
this.charts.push(new Chart(document.getElementById('chart-' + i.toString()), {
type: this.charttypes[i],
data: {
labels: [],
datasets: [{
label: '',
data: []
}]
}
}));
}
this.dataservice.message.subscribe((data) => {
this.messages = data;
this.populate();
});
}
populate() {
this.charts.forEach(element => {
element.data.labels = this.messages.map((d) => d.location);
element.data.datasets.forEach( dataset => {
dataset.label = 'Volume Flow';
dataset.data = this.messages.map( d => d.volumeflow);
dataset.backgroundColor = dataset.data.map((item, index) => 'rgba(' +
index * (255 / this.messages.length) + ',' +
0 + ',' +
(this.messages.length - index) * (255 / this.messages.length) + ',' + '0.8)');
});
element.update();
});
}
}

View File

@@ -1,203 +0,0 @@
import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core';
import { WebSocketSubject } from 'rxjs/webSocket';
import Auth from '@aws-amplify/auth';
import { MatTableDataSource } from '@angular/material/table';
import { MatSort } from '@angular/material/sort';
import { Chart } from 'chart.js';
export interface MyJSON {
location: string;
company: string;
volumeflow: number;
field: string;
intakepressure: number;
current: number;
frequency: number;
}
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit, OnDestroy {
constructor() {
Auth.currentAuthenticatedUser().then(data => {
// console.log(data);
this.roles = data.signInUserSession.idToken.payload['cognito:roles'];
this.groups = data.signInUserSession.idToken.payload['cognito:groups'];
this.groups.forEach( (element, index, array) => {
array[index] = element.replace(/_/g, ' ');
});
this.currentRole = data.signInUserSession.idToken.payload['cognito:roles'][0];
this.token = data.signInUserSession.accessToken.jwtToken;
this.connect();
});
}
public serverMessages: MyJSON[] = [];
private socket$: WebSocketSubject<any>;
private currentMessage = {location: '', company: '', volumeflow: '', field: ''};
totalFlowRate = 0;
private roles: string[];
private groups: string[];
private currentRole: string;
private token: string;
title = 'Bar Chart';
charts = new Array<Chart>();
@ViewChild(MatSort, {static: true}) sort: MatSort;
ngOnInit() {
const chart = document.createElement('CANVAS');
chart.id = 'myChart';
chart.style.width = '100%';
chart.style.height = '500px';
document.getElementById('charts').appendChild(chart);
const chart1 = document.createElement('canvas');
chart1.id = 'yourChart';
chart1.style.width = '100%';
chart1.style.height = '400px';
document.getElementById('charts').appendChild(chart1);
this.charts.push(new Chart(document.getElementById('myChart'), {
type: 'bar',
data: {
labels: [],
datasets: [{
label: '',
data: []
}]
}
}));
this.charts.push(new Chart(document.getElementById('yourChart'), {
type: 'line',
data: {
labels: [],
datasets: [{
label: '',
data: []
}]
}
}));
}
ngOnDestroy() {
this.socket$.complete();
}
connect() {
this.connectWS(this.token, this.currentRole);
this.subscribeWS();
this.socket$.next({action: 'getDashboardData', policy: this.currentRole});
}
connectWS(token: string, role: string) {
this.socket$ = new WebSocketSubject('wss://3fseaywb8b.execute-api.us-east-1.amazonaws.com/prototype?token=' + token +
'&role=' + role);
// console.log(this.socket$);
}
subscribeWS() {
this.socket$.subscribe((message) => {
// console.log(message);
if (message instanceof Array) {
message.forEach(element => {
this.updateList(element);
});
} else {
this.updateList(message);
}
this.totalFlowRate = this.totalFlowRates();
// console.log(this.serverMessages);
this.serverMessages.sort((a, b) => a.location.localeCompare(b.location));
this.charts.forEach(element => {
element.data.labels = this.serverMessages.map((d) => d.location);
element.data.datasets.forEach( dataset => {
dataset.label = 'Volume Flow';
dataset.data = this.serverMessages.map( d => d.volumeflow);
dataset.backgroundColor = dataset.data.map((item, index) => 'rgba(' +
index * (255 / this.serverMessages.length) + ',' +
0 + ',' +
(this.serverMessages.length - index) * (255 / this.serverMessages.length) + ',' + '0.8)');
});
element.update();
});
},
(err) => console.error(err),
() => console.warn('Complete: Websocket closed')
);
}
updateList(obj: MyJSON) {
// console.log(this.serverMessages);
// console.log(obj);
const index = this.serverMessages.findIndex((e) => e.location === obj.location);
try {
obj.volumeflow = Number(obj.volumeflow.toFixed(2));
} catch {
// console.log('can transform to fixed decimal data missing or not a number');
}
try {
obj.current = Number(obj.current.toFixed(2));
} catch {
// console.log('can transform to fixed decimal data missing or not a number');
}
try {
obj.intakepressure = Number(obj.intakepressure.toFixed(2));
} catch {
// console.log('can transform to fixed decimal data missing or not a number');
}
try {
obj.frequency = Number(obj.frequency.toFixed(2));
} catch {
// console.log('can transform to fixed decimal data missing or not a number');
}
if (index === -1) {
this.serverMessages.push(obj);
} else {
if (! obj.volumeflow) {
obj.volumeflow = this.serverMessages[index].volumeflow;
}
if (! obj.current) {
obj.current = this.serverMessages[index].current;
}
if (! obj.frequency) {
obj.frequency = this.serverMessages[index].frequency;
}
if (! obj.intakepressure) {
obj.intakepressure = this.serverMessages[index].intakepressure;
}
this.serverMessages[index] = obj;
}
}
totalFlowRates() {
let temp = 0;
this.serverMessages.forEach(element => {
if (element.volumeflow) {
temp += element.volumeflow;
}
});
return Number(temp.toFixed(2));
}
setRole(index: number) {
this.currentRole = this.roles[index];
this.socket$.complete();
this.serverMessages = [];
this.connect();
}
}

View File

@@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { DataService } from './data.service';
describe('DataService', () => {
let service: DataService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(DataService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});

View File

@@ -0,0 +1,93 @@
import { Injectable } from '@angular/core';
import Auth from '@aws-amplify/auth';
import { WebSocketSubject } from 'rxjs/webSocket';
import { Observable, Subject } from 'rxjs';
export interface MyJSON {
[key: string]: any;
}
@Injectable({
providedIn: 'root'
})
export class DataService {
public serverMessages: Array<MyJSON> = [];
public message = new Subject<MyJSON[]>();
private socket$: WebSocketSubject<any>;
totalFlowRate = 0;
private roles: string[];
private groups: string[];
private currentRole: string;
private token: string;
constructor() {
Auth.currentAuthenticatedUser().then(data => {
// console.log(data);
this.roles = data.signInUserSession.idToken.payload['cognito:roles'];
this.groups = data.signInUserSession.idToken.payload['cognito:groups'];
this.groups.forEach( (element, index, array) => {
array[index] = element.replace(/_/g, ' ');
});
this.currentRole = data.signInUserSession.idToken.payload['cognito:roles'][0];
this.token = data.signInUserSession.accessToken.jwtToken;
this.message.subscribe({
next: d => d
});
this.connect();
}); }
connect() {
this.connectWS(this.token, this.currentRole);
this.subscribeWS();
this.socket$.next({action: 'getDashboardData', policy: this.currentRole});
}
connectWS(token: string, role: string) {
this.socket$ = new WebSocketSubject('wss://3fseaywb8b.execute-api.us-east-1.amazonaws.com/prototype?token=' + token +
'&role=' + role);
// console.log(this.socket$);
}
subscribeWS() {
this.socket$.subscribe((message) => {
// console.log(message);
if (message instanceof Array) {
message.forEach(element => {
this.updateList(element);
});
} else {
this.updateList(message);
}
// console.log(this.serverMessages);
this.serverMessages.sort((a, b) => a.location.localeCompare(b.location));
this.message.next(this.serverMessages);
},
(err) => console.error(err),
() => console.warn('Complete: Websocket closed')
);
}
updateList(obj: MyJSON) {
// console.log(this.serverMessages);
// console.log(obj);
const index = this.serverMessages.findIndex((e) => e.location === obj.location);
if (index === -1) {
this.serverMessages.push(obj);
} else {
Object.keys(obj).forEach(element => {
this.serverMessages[index][element] = obj[element];
});
}
}
setRole(index: number) {
this.currentRole = this.roles[index];
this.socket$.complete();
this.serverMessages = [];
this.connect();
}
}