diff options
Diffstat (limited to 'webapp/src/app/pages/targets/target-add-modal')
-rw-r--r-- | webapp/src/app/pages/targets/target-add-modal/target-add-modal.component.html | 46 | ||||
-rw-r--r-- | webapp/src/app/pages/targets/target-add-modal/target-add-modal.component.ts | 174 |
2 files changed, 220 insertions, 0 deletions
diff --git a/webapp/src/app/pages/targets/target-add-modal/target-add-modal.component.html b/webapp/src/app/pages/targets/target-add-modal/target-add-modal.component.html new file mode 100644 index 0000000..84424b4 --- /dev/null +++ b/webapp/src/app/pages/targets/target-add-modal/target-add-modal.component.html @@ -0,0 +1,46 @@ +<div class="modal-header"> + <span>Add a new target</span> + <button class="close" aria-label="Close" (click)="closeModal()"> + <span aria-hidden="true">×</span> + </button> +</div> + +<div class="modal-body row"> + <div class="col-12"> + <form [formGroup]="addTargetForm" (ngSubmit)="onSubmit()"> + + <div class="form-group row"> + <label for="sharing-type" class="col-sm-3 col-form-label">Target Type</label> + <div class="col-sm-9"> + <select id="select-sharing-type" class="form-control" formControlName="type"> + <option *ngFor="let t of targetTypes" [value]="t.value">{{t.display}} + </option> + </select> + </div> + </div> + + <div class="form-group row"> + <label for="select-ip" class="col-sm-3 col-form-ip">IP or Name</label> + <div class="col-sm-9"> + <input type="text" id="inputLabel" class="form-control" formControlName="ip" (keyup)="onKeyLabel($event)"> + </div> + </div> + + <div class="form-group row"> + <label for="select-name" class="col-sm-3 col-form-name">Name</label> + <div class="col-sm-9"> + <input type="text" id="inputLabel" class="form-control" formControlName="name" (keyup)="onKeyLabel($event)"> + </div> + </div> + + </form> + </div> +</div> +<div class="modal-footer form-group"> + <div class="col-12"> + <div class="offset-sm-4 col-sm-6"> + <button class="btn btn-md btn-secondary" (click)="cancelAction=true; closeModal()"> Cancel </button> + <button class="btn btn-md btn-primary" (click)="onSubmit()" [disabled]="!addTargetForm.valid">Add Folder</button> + </div> + </div> +</div> 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 index 0000000..fdcb048 --- /dev/null +++ b/webapp/src/app/pages/targets/target-add-modal/target-add-modal.component.ts @@ -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); + } +} |