Added dynamic forms

This commit is contained in:
2020-02-07 17:08:31 -06:00
parent 6a0e8e70dd
commit e8d9651db0
5 changed files with 158 additions and 134 deletions

136
package-lock.json generated
View File

@@ -26,23 +26,23 @@
}
},
"@angular-devkit/build-angular": {
"version": "0.803.24",
"resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-0.803.24.tgz",
"integrity": "sha512-uA789spMVghXehwAhl5zK0loY/wfxblUiL+y21T24LMCJc15a9QX5dwbXH72ioHz7qdzb/agXk7AK+foc2/0Hw==",
"version": "0.803.25",
"resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-0.803.25.tgz",
"integrity": "sha512-WY0E7NgXuog3phhz5ZdutZPWQ9nbOr+omGN5KI1e8MZs1sJO4xkyaGRT8zOulkogkqJ2NboTBq3j9uSbZkcYeg==",
"dev": true,
"requires": {
"@angular-devkit/architect": "0.803.24",
"@angular-devkit/build-optimizer": "0.803.24",
"@angular-devkit/build-webpack": "0.803.24",
"@angular-devkit/core": "8.3.24",
"@angular-devkit/architect": "0.803.25",
"@angular-devkit/build-optimizer": "0.803.25",
"@angular-devkit/build-webpack": "0.803.25",
"@angular-devkit/core": "8.3.25",
"@babel/core": "7.8.3",
"@babel/preset-env": "7.8.3",
"@ngtools/webpack": "8.3.24",
"@ngtools/webpack": "8.3.25",
"ajv": "6.10.2",
"autoprefixer": "9.6.1",
"browserslist": "4.8.3",
"browserslist": "4.8.6",
"cacache": "12.0.2",
"caniuse-lite": "1.0.30001019",
"caniuse-lite": "1.0.30001024",
"circular-dependency-plugin": "5.2.0",
"clean-css": "4.2.1",
"copy-webpack-plugin": "5.1.1",
@@ -90,19 +90,19 @@
},
"dependencies": {
"@angular-devkit/architect": {
"version": "0.803.24",
"resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.803.24.tgz",
"integrity": "sha512-ONY/Ppzyvtb0tqgwnzQvlGlexb5nTyy58ljgL1aQLTO3cNTkpl4IQYUCTdvn61gGA+FWPAXMCCbNqOPZMsOZCQ==",
"version": "0.803.25",
"resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.803.25.tgz",
"integrity": "sha512-usV/zEncKCKQuF6AD3pRU6N5i5fbaAux/qZb+nbOz9/2G5jrXwe5sH+y3vxbgqB83e3LqusEQCTu7/tfg6LwZg==",
"dev": true,
"requires": {
"@angular-devkit/core": "8.3.24",
"@angular-devkit/core": "8.3.25",
"rxjs": "6.4.0"
}
},
"@angular-devkit/core": {
"version": "8.3.24",
"resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-8.3.24.tgz",
"integrity": "sha512-xpT5yg+ddGDnifryBv2sRSYtq5F3iZIS+lN/K2AhhEa50B7Z+QaCVlEzoV/IfrGd6sLArdnKYwjLHFZ0LElUuw==",
"version": "8.3.25",
"resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-8.3.25.tgz",
"integrity": "sha512-l7Gqy1tMrTpRmPVlovcFX8UA3mtXRlgO8kcSsbJ9MKRKNTCcxlfsWEYY5igyDBUVh6ADkgSIu0nuk31ZGTe0lw==",
"dev": true,
"requires": {
"ajv": "6.10.2",
@@ -142,9 +142,9 @@
}
},
"@angular-devkit/build-optimizer": {
"version": "0.803.24",
"resolved": "https://registry.npmjs.org/@angular-devkit/build-optimizer/-/build-optimizer-0.803.24.tgz",
"integrity": "sha512-Z+d7M+WpBq7AWWRwbxzb1l9O9qkylxnDRKxXvq3Tzjn43g+2WyspE91dMyrg1ISc+p8jgX6xKSblRLvtWqpA8w==",
"version": "0.803.25",
"resolved": "https://registry.npmjs.org/@angular-devkit/build-optimizer/-/build-optimizer-0.803.25.tgz",
"integrity": "sha512-MiQimuEs8QeM3xo7bR3Yk1OWHHlp2pGCc2GLUMIcWhKqM+QjoRky0HoGoBazbznx292l+xjFjANvPEKbqJ2v7Q==",
"dev": true,
"requires": {
"loader-utils": "1.2.3",
@@ -155,30 +155,30 @@
}
},
"@angular-devkit/build-webpack": {
"version": "0.803.24",
"resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.803.24.tgz",
"integrity": "sha512-Bbd5KUGaE+edN0sp8K3azuqS/JTBmeWXIumdBEtqWyL6VsohX7fL+toJlSvRkj8lg02LVyozAFetXKnyaBkfCQ==",
"version": "0.803.25",
"resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.803.25.tgz",
"integrity": "sha512-WR7HWJIWL6TB3WHG7ZFn8s0z3WlojeQlod75UIKl5i+f4OU90kp8kxcoH5G6OCXu56x5w40oIi1ve5ljjWSJkw==",
"dev": true,
"requires": {
"@angular-devkit/architect": "0.803.24",
"@angular-devkit/core": "8.3.24",
"@angular-devkit/architect": "0.803.25",
"@angular-devkit/core": "8.3.25",
"rxjs": "6.4.0"
},
"dependencies": {
"@angular-devkit/architect": {
"version": "0.803.24",
"resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.803.24.tgz",
"integrity": "sha512-ONY/Ppzyvtb0tqgwnzQvlGlexb5nTyy58ljgL1aQLTO3cNTkpl4IQYUCTdvn61gGA+FWPAXMCCbNqOPZMsOZCQ==",
"version": "0.803.25",
"resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.803.25.tgz",
"integrity": "sha512-usV/zEncKCKQuF6AD3pRU6N5i5fbaAux/qZb+nbOz9/2G5jrXwe5sH+y3vxbgqB83e3LqusEQCTu7/tfg6LwZg==",
"dev": true,
"requires": {
"@angular-devkit/core": "8.3.24",
"@angular-devkit/core": "8.3.25",
"rxjs": "6.4.0"
}
},
"@angular-devkit/core": {
"version": "8.3.24",
"resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-8.3.24.tgz",
"integrity": "sha512-xpT5yg+ddGDnifryBv2sRSYtq5F3iZIS+lN/K2AhhEa50B7Z+QaCVlEzoV/IfrGd6sLArdnKYwjLHFZ0LElUuw==",
"version": "8.3.25",
"resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-8.3.25.tgz",
"integrity": "sha512-l7Gqy1tMrTpRmPVlovcFX8UA3mtXRlgO8kcSsbJ9MKRKNTCcxlfsWEYY5igyDBUVh6ADkgSIu0nuk31ZGTe0lw==",
"dev": true,
"requires": {
"ajv": "6.10.2",
@@ -1453,23 +1453,6 @@
"semver": "^5.5.0"
},
"dependencies": {
"browserslist": {
"version": "4.8.6",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.8.6.tgz",
"integrity": "sha512-ZHao85gf0eZ0ESxLfCp73GG9O/VTytYDIkIiZDlURppLTI9wErSM/5yAKEq6rcUdxBLjMELmrYUJGg5sxGKMHg==",
"dev": true,
"requires": {
"caniuse-lite": "^1.0.30001023",
"electron-to-chromium": "^1.3.341",
"node-releases": "^1.1.47"
}
},
"caniuse-lite": {
"version": "1.0.30001025",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001025.tgz",
"integrity": "sha512-SKyFdHYfXUZf5V85+PJgLYyit27q4wgvZuf8QTOk1osbypcROihMBlx9GRar2/pIcKH2r4OehdlBr9x6PXetAQ==",
"dev": true
},
"semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
@@ -1881,23 +1864,6 @@
"semver": "^5.5.0"
},
"dependencies": {
"browserslist": {
"version": "4.8.6",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.8.6.tgz",
"integrity": "sha512-ZHao85gf0eZ0ESxLfCp73GG9O/VTytYDIkIiZDlURppLTI9wErSM/5yAKEq6rcUdxBLjMELmrYUJGg5sxGKMHg==",
"dev": true,
"requires": {
"caniuse-lite": "^1.0.30001023",
"electron-to-chromium": "^1.3.341",
"node-releases": "^1.1.47"
}
},
"caniuse-lite": {
"version": "1.0.30001025",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001025.tgz",
"integrity": "sha512-SKyFdHYfXUZf5V85+PJgLYyit27q4wgvZuf8QTOk1osbypcROihMBlx9GRar2/pIcKH2r4OehdlBr9x6PXetAQ==",
"dev": true
},
"semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
@@ -3879,12 +3845,12 @@
"dev": true
},
"@ngtools/webpack": {
"version": "8.3.24",
"resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-8.3.24.tgz",
"integrity": "sha512-OpR7t/99qNOpADayCuM67agBVdYkdbFyEEcOLaDFYh3LsefHOSSxtAGv8M77e7dguvtaljHTiVkMxgcXFsZM0Q==",
"version": "8.3.25",
"resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-8.3.25.tgz",
"integrity": "sha512-yHvgxXUXlgdWijtzcRjTaUqzK+6TVK/8p7PreBR00GsLxhl4U1jQSC6yDaZUCjOaEkiczFWl4hEuC4wTU/hLdg==",
"dev": true,
"requires": {
"@angular-devkit/core": "8.3.24",
"@angular-devkit/core": "8.3.25",
"enhanced-resolve": "4.1.0",
"rxjs": "6.4.0",
"tree-kill": "1.2.2",
@@ -3892,9 +3858,9 @@
},
"dependencies": {
"@angular-devkit/core": {
"version": "8.3.24",
"resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-8.3.24.tgz",
"integrity": "sha512-xpT5yg+ddGDnifryBv2sRSYtq5F3iZIS+lN/K2AhhEa50B7Z+QaCVlEzoV/IfrGd6sLArdnKYwjLHFZ0LElUuw==",
"version": "8.3.25",
"resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-8.3.25.tgz",
"integrity": "sha512-l7Gqy1tMrTpRmPVlovcFX8UA3mtXRlgO8kcSsbJ9MKRKNTCcxlfsWEYY5igyDBUVh6ADkgSIu0nuk31ZGTe0lw==",
"dev": true,
"requires": {
"ajv": "6.10.2",
@@ -5067,14 +5033,14 @@
}
},
"browserslist": {
"version": "4.8.3",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.8.3.tgz",
"integrity": "sha512-iU43cMMknxG1ClEZ2MDKeonKE1CCrFVkQK2AqO2YWFmvIrx4JWrvQ4w4hQez6EpVI8rHTtqh/ruHHDHSOKxvUg==",
"version": "4.8.6",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.8.6.tgz",
"integrity": "sha512-ZHao85gf0eZ0ESxLfCp73GG9O/VTytYDIkIiZDlURppLTI9wErSM/5yAKEq6rcUdxBLjMELmrYUJGg5sxGKMHg==",
"dev": true,
"requires": {
"caniuse-lite": "^1.0.30001017",
"electron-to-chromium": "^1.3.322",
"node-releases": "^1.1.44"
"caniuse-lite": "^1.0.30001023",
"electron-to-chromium": "^1.3.341",
"node-releases": "^1.1.47"
}
},
"browserstack": {
@@ -5237,9 +5203,9 @@
"dev": true
},
"caniuse-lite": {
"version": "1.0.30001019",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001019.tgz",
"integrity": "sha512-6ljkLtF1KM5fQ+5ZN0wuyVvvebJxgJPTmScOMaFuQN2QuOzvRJnWSKfzQskQU5IOU4Gap3zasYPIinzwUjoj/g==",
"version": "1.0.30001024",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001024.tgz",
"integrity": "sha512-LubRSEPpOlKlhZw9wGlLHo8ZVj6ugGU3xGUfLPneNBledSd9lIM5cCGZ9Mz/mMCJUhEt4jZpYteZNVRdJw5FRA==",
"dev": true
},
"canonical-path": {
@@ -10069,9 +10035,9 @@
}
},
"node-releases": {
"version": "1.1.47",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.47.tgz",
"integrity": "sha512-k4xjVPx5FpwBUj0Gw7uvFOTF4Ep8Hok1I6qjwL3pLfwe7Y0REQSAqOwwv9TWBCUtMHxcXfY4PgRLRozcChvTcA==",
"version": "1.1.48",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.48.tgz",
"integrity": "sha512-Hr8BbmUl1ujAST0K0snItzEA5zkJTQup8VNTKNfT6Zw8vTJkIiagUPNfxHmgDOyfFYNfKAul40sD0UEYTvwebw==",
"dev": true,
"requires": {
"semver": "^6.3.0"

View File

@@ -32,7 +32,7 @@
"zone.js": "~0.9.1"
},
"devDependencies": {
"@angular-devkit/build-angular": "^0.803.24",
"@angular-devkit/build-angular": "^0.803.25",
"@angular/cli": "~8.3.23",
"@angular/compiler-cli": "~8.2.14",
"@angular/language-service": "~8.2.14",

View File

@@ -21,6 +21,7 @@ import { AvatarComponent } from './auth/profile/avatar/avatar.component';
import { NgxGaugeModule} from 'ngx-gauge';
import { MatSortModule, MatTableModule } from '@angular/material';
import { ConfigsComponent } from './configs/configs.component';
import { HttpClientModule } from '@angular/common/http';
@NgModule({
declarations: [
AppComponent,
@@ -47,7 +48,8 @@ import { ConfigsComponent } from './configs/configs.component';
NgxGaugeModule,
FlexLayoutModule,
MatTableModule,
MatSortModule
MatSortModule,
HttpClientModule
],
providers: [],
bootstrap: [AppComponent],

View File

@@ -2,33 +2,62 @@
<h2>Configuration</h2>
<form [formGroup]="configForm">
<mat-form-field>
<input matInput placeholder="Certificate ID" type="text" formControlName="certificateID" required>
<mat-hint *ngIf="!certificateIDInput.value">Certificate ID</mat-hint>
</mat-form-field>
<h2>Device 1</h2>
<mat-form-field>
<input matInput placeholder="Application Name" type="text" formControlName="d1appname" required>
<mat-hint *ngIf="!d1appnameInput.value">Application Name</mat-hint>
</mat-form-field>
<mat-form-field>
<input matInput placeholder="Certificate ID" type="text" formControlName="d1certificateID" required>
<mat-hint *ngIf="!certificateIDInput.value">Certificate ID</mat-hint>
</mat-form-field>
<mat-form-field>
<input matInput placeholder="Company" type="text" formControlName="d1company" required>
<mat-hint *ngIf="!d1companyInput.value">Company</mat-hint>
</mat-form-field>
<mat-form-field>
<input matInput placeholder="Location" type="text" formControlName="d1location" required>
<mat-hint *ngIf="!d1locationInput.value">Location</mat-hint>
</mat-form-field>
<mat-form-field>
<input matInput placeholder="Field" type="text" formControlName="d1field" required>
<mat-hint *ngIf="!d1fieldInput.value">Field</mat-hint>
</mat-form-field>
<mat-form-field>
<input matInput placeholder="Device Type" type="text" formControlName="d1devicetype" required>
<mat-hint *ngIf="!d1devicetypeInput.value">Device Type</mat-hint>
<input matInput placeholder="Certificate ID" type="text" [formControl]="certificateIDInput" [matAutocomplete]="auto" (change)="onCertificateChange($event)"required>
<mat-autocomplete #auto="matAutocomplete">
<mat-option *ngFor="let option of filteredOptions | async" [value]="option">
{{option}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
<div *ngFor="let device of devicesArray.controls; let i = index">
<h2>Device {{i + 1}}</h2>
<div [formGroup]="device">
<mat-form-field>
<input matInput placeholder="Application Name" type="text" formControlName="appname" required>
</mat-form-field>
<mat-form-field>
<input matInput placeholder="Certificate ID" type="text" formControlName="certificateID" required>
</mat-form-field>
<mat-form-field>
<input matInput placeholder="Company" type="text" formControlName="company" required>
</mat-form-field>
<mat-form-field>
<input matInput placeholder="Location" type="text" formControlName="location" required>
</mat-form-field>
<mat-form-field>
<input matInput placeholder="Field" type="text" formControlName="field" required>
</mat-form-field>
<mat-form-field>
<input matInput placeholder="Device Type" type="text" formControlName="devicetype" required>
</mat-form-field>
<div *ngFor="let tag of plcarray(i).controls; let j = index">
<h3>Tag {{j+1}}</h3>
<div [formGroup]="tag">
<mat-form-field>
<input matInput placeholder="PLC IP" type="text" formControlName="plcip" required>
</mat-form-field>
<mat-form-field>
<input matInput placeholder="PLC Tag" type="text" formControlName="plctag" required>
</mat-form-field>
<mat-form-field>
<input matInput placeholder="Tag Display Name" type="text" formControlName="plcname" required>
</mat-form-field>
<mat-form-field>
<input matInput placeholder="Tag Change Threshold" type="number" formControlName="plcchangethres" value=0 required>
</mat-form-field>
<mat-form-field>
<input matInput placeholder="Tag Guaranteed Timer" type="number" formControlName="plcguaranteed" value=3600 required>
</mat-form-field>
<mat-form-field>
<input matInput placeholder="PLC Type" type="text" formControlName="plctype" [matAutocomplete]="auto" required>
<mat-autocomplete #auto="matAutocomplete">
<mat-option value="CLX">CLX</mat-option>
<mat-option value="Micro800">Micro800</mat-option>
</mat-autocomplete>
</mat-form-field>
</div>
</div>
</div>
</div>
</form>
</div>

View File

@@ -1,6 +1,8 @@
import { Component, OnInit } from '@angular/core';
import { FormBuilder } from '@angular/forms';
import { Certificate } from 'crypto';
import { FormBuilder, FormControl, FormGroup, FormArray } from '@angular/forms';
import { Observable } from 'rxjs';
import {map, startWith} from 'rxjs/operators';
import { HttpClient } from '@angular/common/http';
@Component({
selector: 'app-configs',
templateUrl: './configs.component.html',
@@ -8,26 +10,51 @@ import { Certificate } from 'crypto';
})
export class ConfigsComponent implements OnInit {
constructor(private builder: FormBuilder) { }
constructor(private builder: FormBuilder, private http: HttpClient) { }
get certificateIDInput() { return this.configForm.get('certificateID'); }
get devicesArray() { return this.configForm.get('devices') as FormArray; }
ngOnInit() { }
configForm = this.builder.group({
certificateID: '',
d1appname: 'hpiot',
d1certificateID: '',
d1company: '',
d1location: '',
d1field: '',
d1devicetype: ''
devices: new FormArray([])
});
get certificateIDInput() {return this.configForm.get('certificateID')}
get d1appnameInput() {return this.configForm.get('d1appname')}
get d1certificateIDInput() {return this.configForm.get('certificateID')}
get d1companyInput() {return this.configForm.get('d1company')}
get d1locationInput() {return this.configForm.get('d1location')}
get d1fieldInput() {return this.configForm.get('d1field')}
get d1devicetypeInput() {return this.configForm.get('d1devicetype')}
// Setup an API call to get the list of certificate IDs from DDB to store in options
options: string[] = ['1217f08d31bbc1e9f70aabb700fb33878ccc1ec6caa38c5efb8c9f2709c7a444',
'1370cf88050a5d9bc5aeef22f2b9756224c080c89f703eefeee8c9081dc6424e', '1e1f59fb7ac397487ceddbd65ff3ecb39e021997c1926317d076b2fe1f8a9614'];
filteredOptions: Observable<string[]>;
ngOnInit() {
this.filteredOptions = this.certificateIDInput.valueChanges.pipe(
startWith(''),
map(value => this._filter(value))
);
}
plcarray(i) { return this.configForm.get('devices.' + i + '.plcdata') as FormArray; }
private _filter(value: string): string[] {
const filterValue = value.toLowerCase();
return this.options.filter(option => option.toLowerCase().includes(filterValue));
}
// Setup a function for onChangeCertificateID to get said config and load the form dynamically
onCertificateChange(e) {
console.log(e.target.value);
const config = this.http.get('https://4ax24ru9ra.execute-api.us-east-1.amazonaws.com/Gamma/HPIoTgetConfig/?certificateID=' + e.target.value);
console.log(config);
const numberOfDevices = 3;
if (this.devicesArray.length < numberOfDevices) {
for (let i = this.devicesArray.length; i < numberOfDevices; i++) {
this.devicesArray.push(this.builder.group({
appname: 'hpiot',
certificateID: '',
company: '',
location: i,
field: '',
devicetype: '',
plcdata: new FormArray([]),
modbusdata: new FormArray([]),
currentdata: new FormArray([]),
voltagedata: new FormArray([])
}));
}
}
}
}