Fix invalid linter conf and fix reported lint errors
[src/xds/xds-agent.git] / webapp / src / app / pages / targets / target-add-modal / target-add-modal.component.ts
1 /**
2 * @license
3 * Copyright (C) 2018 "IoT.bzh"
4 * Author Sebastien Douheret <sebastien@iot.bzh>
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 *   http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19 import { Component, ViewEncapsulation, Input, OnInit } from '@angular/core';
20 import { Observable } from 'rxjs/Observable';
21 import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
22 import { FormControl, FormGroup, Validators, ValidationErrors, FormBuilder, ValidatorFn, AbstractControl } from '@angular/forms';
23
24 // Import RxJs required methods
25 import 'rxjs/add/operator/map';
26 import 'rxjs/add/operator/filter';
27 import 'rxjs/add/operator/debounceTime';
28
29 import { AlertService, IAlert } from '../../../@core-xds/services/alert.service';
30 import { TargetService, ITarget, TargetType, TargetTypes } from '../../../@core-xds/services/target.service';
31 import { XDSConfigService } from '../../../@core-xds/services/xds-config.service';
32
33
34 @Component({
35   selector: 'xds-target-add-modal',
36   templateUrl: 'target-add-modal.component.html',
37   encapsulation: ViewEncapsulation.None,
38   styles: [`
39     .modal-xxl .modal-lg {
40       width: 90%;
41       max-width:1200px;
42     }
43   `],
44 })
45 export class TargetAddModalComponent implements OnInit {
46   // @Input('server-id') serverID: string;
47   private serverID: string;
48
49   cancelAction = false;
50   userEditedName = false;
51   targetTypes = Object.assign([], TargetTypes);
52
53   addTargetForm: FormGroup;
54   typeCtrl: FormControl;
55   ipCtrl: FormControl;
56
57   constructor(
58     private alert: AlertService,
59     private targetSvr: TargetService,
60     private XdsConfigSvr: XDSConfigService,
61     private fb: FormBuilder,
62     private activeModal: NgbActiveModal,
63   ) {
64     // Define types (first one is special/placeholder)
65     this.targetTypes.unshift({ value: TargetType.UNSET, display: '--Select a type--' });
66
67     // Select first type item (Standard) by default
68     this.typeCtrl = new FormControl(this.targetTypes[1].value, this.validatorTgtType.bind(this));
69     this.ipCtrl = new FormControl('', this.validatorIP.bind(this));
70
71     this.addTargetForm = fb.group({
72       type: this.typeCtrl,
73       ip: this.ipCtrl,
74       name: ['', Validators.nullValidator],
75     });
76   }
77
78   ngOnInit() {
79     // Update server ID
80     this.serverID = this.XdsConfigSvr.getCurServer().id;
81     this.XdsConfigSvr.onCurServer().subscribe(svr => this.serverID = svr.id);
82
83     // Auto create target name
84     this.ipCtrl.valueChanges
85       .debounceTime(100)
86       .filter(n => n)
87       .map(n => {
88         if (this._isIPstart(n)) {
89           return 'Target_' + n;
90         }
91         return n;
92       })
93       .subscribe(value => {
94         if (value && !this.userEditedName) {
95           this.addTargetForm.patchValue({ name: value });
96         }
97       });
98   }
99
100   closeModal() {
101     this.activeModal.close();
102   }
103
104   onKeyLabel(event: any) {
105     this.userEditedName = (this.addTargetForm.value.label !== '');
106   }
107
108   onChangeLocalTarget(e) {
109   }
110
111   onSubmit() {
112     if (this.cancelAction) {
113       return;
114     }
115
116     const formVal = this.addTargetForm.value;
117
118     this.targetSvr.add({
119       name: formVal['name'],
120       ip: formVal['ip'],
121       type: formVal['type'],
122     }).subscribe(
123       tgt => {
124         this.alert.info('Target ' + tgt.name + ' successfully created.');
125         this.closeModal();
126
127         // Reset Value for the next creation
128         this.addTargetForm.reset();
129         const selectedType = this.targetTypes[0].value;
130         this.addTargetForm.patchValue({ type: selectedType });
131
132       },
133       err => {
134         this.alert.error(err, 60);
135         this.closeModal();
136       },
137     );
138   }
139
140   private validatorTgtType(g: FormGroup): ValidationErrors | null {
141     return (g.value !== TargetType.UNSET) ? null : { validatorTgtType: { valid: false } };
142   }
143
144   private validatorIP(g: FormGroup): ValidationErrors | null {
145     const noValid = <ValidationErrors>{ validatorProjPath: { valid: false } };
146
147     if (g.value === '') {
148       return noValid;
149     }
150
151     if (this._isIPstart(g.value) && !this._isIPv4(g.value)) {
152       return noValid;
153     }
154
155     // Else accept any text / hostname
156     return null;
157   }
158
159   private _isIPstart(str) {
160     return /^(\d+)\./.test(str);
161   }
162
163   private _isIPv4(str) {
164     const ipv4Maybe = /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/;
165     if (!ipv4Maybe.test(str)) {
166       return false;
167     }
168     const parts = str.split('.').sort(function (a, b) {
169       return a - b;
170     });
171     return (parts[3] <= 255);
172   }
173 }