Added target and terminal support in Dashboard
[src/xds/xds-agent.git] / webapp / src / app / pages / targets / target-add-modal / target-add-modal.component.ts
diff --git a/webapp/src/app/pages/targets/target-add-modal/target-add-modal.component.ts b/webapp/src/app/pages/targets/target-add-modal/target-add-modal.component.ts
new file mode 100644 (file)
index 0000000..fdcb048
--- /dev/null
@@ -0,0 +1,174 @@
+/**
+* @license
+* Copyright (C) 2018 "IoT.bzh"
+* Author Sebastien Douheret <sebastien@iot.bzh>
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*   http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+import { Component, ViewEncapsulation, Input, OnInit } from '@angular/core';
+import { Observable } from 'rxjs/Observable';
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import { FormControl, FormGroup, Validators, ValidationErrors, FormBuilder, ValidatorFn, AbstractControl } from '@angular/forms';
+
+// Import RxJs required methods
+import 'rxjs/add/operator/map';
+import 'rxjs/add/operator/filter';
+import 'rxjs/add/operator/debounceTime';
+
+import { AlertService, IAlert } from '../../../@core-xds/services/alert.service';
+import { TargetService, ITarget, TargetType, TargetTypes } from '../../../@core-xds/services/target.service';
+import { XDSConfigService } from '../../../@core-xds/services/xds-config.service';
+
+
+@Component({
+  selector: 'xds-target-add-modal',
+  templateUrl: 'target-add-modal.component.html',
+  encapsulation: ViewEncapsulation.None,
+  styles: [`
+    .modal-xxl .modal-lg {
+      width: 90%;
+      max-width:1200px;
+    }
+  `],
+})
+export class TargetAddModalComponent implements OnInit {
+  // @Input('server-id') serverID: string;
+  private serverID: string;
+
+  cancelAction = false;
+  userEditedName = false;
+  targetTypes = Object.assign([], TargetTypes);
+
+  addTargetForm: FormGroup;
+  typeCtrl: FormControl;
+  ipCtrl: FormControl;
+
+  constructor(
+    private alert: AlertService,
+    private targetSvr: TargetService,
+    private XdsConfigSvr: XDSConfigService,
+    private fb: FormBuilder,
+    private activeModal: NgbActiveModal,
+  ) {
+    // Define types (first one is special/placeholder)
+    this.targetTypes.unshift({ value: TargetType.UNSET, display: '--Select a type--' });
+
+    // Select first type item (Standard) by default
+    this.typeCtrl = new FormControl(this.targetTypes[1].value, this.validatorTgtType.bind(this));
+    this.ipCtrl = new FormControl('', this.validatorIP.bind(this));
+
+    this.addTargetForm = fb.group({
+      type: this.typeCtrl,
+      ip: this.ipCtrl,
+      name: ['', Validators.nullValidator],
+    });
+  }
+
+  ngOnInit() {
+    // Update server ID
+    this.serverID = this.XdsConfigSvr.getCurServer().id;
+    this.XdsConfigSvr.onCurServer().subscribe(svr => this.serverID = svr.id);
+
+    // Auto create target name
+    this.ipCtrl.valueChanges
+      .debounceTime(100)
+      .filter(n => n)
+      .map(n => {
+        if (this._isIPstart(n)) {
+          return 'Target_' + n;
+        }
+//        SEB PB
+        return n;
+      })
+      .subscribe(value => {
+        if (value && !this.userEditedName) {
+          this.addTargetForm.patchValue({ name: value });
+        }
+      });
+  }
+
+  closeModal() {
+    this.activeModal.close();
+  }
+
+  onKeyLabel(event: any) {
+    this.userEditedName = (this.addTargetForm.value.label !== '');
+  }
+
+  onChangeLocalTarget(e) {
+  }
+
+  onSubmit() {
+    if (this.cancelAction) {
+      return;
+    }
+
+    const formVal = this.addTargetForm.value;
+
+    this.targetSvr.add({
+      name: formVal['name'],
+      ip: formVal['ip'],
+      type: formVal['type'],
+    }).subscribe(
+      tgt => {
+        this.alert.info('Target ' + tgt.name + ' successfully created.');
+        this.closeModal();
+
+        // Reset Value for the next creation
+        this.addTargetForm.reset();
+        const selectedType = this.targetTypes[0].value;
+        this.addTargetForm.patchValue({ type: selectedType });
+
+      },
+      err => {
+        this.alert.error(err, 60);
+        this.closeModal();
+      },
+    );
+  }
+
+  private validatorTgtType(g: FormGroup): ValidationErrors | null {
+    return (g.value !== TargetType.UNSET) ? null : { validatorTgtType: { valid: false } };
+  }
+
+  private validatorIP(g: FormGroup): ValidationErrors | null {
+    const noValid = <ValidationErrors>{ validatorProjPath: { valid: false } };
+
+    if (g.value === '') {
+      return noValid;
+    }
+
+    if (this._isIPstart(g.value) && !this._isIPv4(g.value)) {
+      return noValid;
+    }
+
+    // Else accept any text / hostname
+    return null;
+  }
+
+  private _isIPstart(str) {
+    return /^(\d+)\./.test(str);
+  }
+
+  private _isIPv4(str) {
+    const ipv4Maybe = /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/
+    if (!ipv4Maybe.test(str)) {
+      return false;
+    }
+    const parts = str.split('.').sort(function (a, b) {
+      return a - b;
+    });
+    return (parts[3] <= 255);
+  }
+}