| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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, OnInit, Inject } from '@angular/core'; |
| import { FormGroup, FormBuilder, Validators } from '@angular/forms'; |
| import { MatDialogRef, MAT_DIALOG_DATA, MatDialog } from '@angular/material/dialog'; |
| import { ToastrService } from 'ngx-toastr'; |
| import { map } from 'rxjs/operators'; |
| |
| import { EndpointService } from '../../../core/services'; |
| import { NotificationDialogComponent } from '../../../shared/modal-dialog/notification-dialog'; |
| import { PATTERNS } from '../../../core/util'; |
| |
| export interface Endpoint { |
| name: string; |
| url: string; |
| account: string; |
| } |
| |
| @Component({ |
| selector: 'endpoints', |
| templateUrl: './endpoints.component.html', |
| styleUrls: ['./endpoints.component.scss'] |
| }) |
| export class EndpointsComponent implements OnInit { |
| public createEndpointForm: FormGroup; |
| public maxEndpointNameLength: number = 6; |
| endpoints: Endpoint[] = []; |
| displayedColumns: string[] = ['name', 'url', 'account', 'endpoint_tag', 'actions']; |
| |
| constructor( |
| @Inject(MAT_DIALOG_DATA) public data: any, |
| public toastr: ToastrService, |
| public dialogRef: MatDialogRef<EndpointsComponent>, |
| public dialog: MatDialog, |
| private endpointService: EndpointService, |
| private _fb: FormBuilder, |
| ) { } |
| |
| ngOnInit() { |
| this.initFormModel(); |
| this.getEndpointList(); |
| } |
| |
| public generateEndpointTag($event) { |
| this.createEndpointForm.controls.endpoint_tag.setValue($event.target.value.toLowerCase()); |
| } |
| |
| public assignChanges(data) { |
| this.endpointService.createEndpoint(data).subscribe(() => { |
| this.toastr.success('Endpoint connected successfully!', 'Success!'); |
| this.dialogRef.close(true); |
| }, error => this.toastr.error(error.message || 'Endpoint connection failed!', 'Oops!')); |
| } |
| |
| public deleteEndpoint(data): void { |
| this.endpointService.getEndpointsResource(data.name) |
| .pipe( |
| map(resource => |
| resource.projects |
| .map(project => |
| EndpointsComponent.createResourceList( |
| project.name, |
| resource.exploratories.filter(notebook => notebook.project === project.name), |
| project.endpoints.filter(endpoint => endpoint.name === data.name)[0].status) |
| ) |
| .filter(project => project.nodeStatus !== 'TERMINATED' |
| && project.nodeStatus !== 'TERMINATING' |
| && project.nodeStatus !== 'FAILED' |
| ) |
| ) |
| ) |
| .subscribe((resource: any) => { |
| this.dialog.open(NotificationDialogComponent, { |
| data: { |
| type: 'confirmation', item: data, list: resource |
| }, panelClass: 'modal-sm' |
| }) |
| .afterClosed().subscribe(result => { |
| result && this.deleteEndpointOption(data); |
| }); |
| }); |
| } |
| |
| public getEndpoinConnectionStatus(url) { |
| const getStatus = this.endpointService.getEndpoinConnectionStatus(encodeURIComponent(url)); |
| this.dialog.open(EndpointTestResultDialogComponent, { data: { url: url, getStatus }, panelClass: 'modal-sm' }); |
| } |
| |
| private static createResourceList(name: string, resource: Array<any>, nodeStatus: string): Object { |
| return { name, resource, nodeStatus }; |
| } |
| |
| private initFormModel(): void { |
| this.createEndpointForm = this._fb.group({ |
| name: ['', Validators.compose([ |
| Validators.required, |
| Validators.pattern(PATTERNS.namePattern), |
| this.validateName.bind(this), |
| this.providerMaxLength.bind(this) |
| ])], |
| url: ['', Validators.compose([ |
| Validators.required, |
| Validators.pattern(PATTERNS.fullUrl), |
| this.validateUrl.bind(this) |
| ])], |
| account: ['', Validators.compose([ |
| Validators.required, |
| Validators.pattern(PATTERNS.namePattern) |
| ])], |
| endpoint_tag: ['', Validators.compose([ |
| Validators.required, |
| Validators.pattern(PATTERNS.namePattern) |
| ])] |
| }); |
| } |
| |
| private deleteEndpointOption(data): void { |
| this.endpointService.deleteEndpoint(`${data.name}`) |
| .subscribe( |
| () => { |
| this.toastr.success('Endpoint successfully disconnected. All related resources are terminating!', 'Success!'); |
| this.getEndpointList(); |
| }, |
| error => this.toastr.error(error.message || 'Endpoint creation failed!', 'Oops!') |
| ); |
| } |
| |
| private getEndpointList(): void { |
| this.endpointService.getEndpointsData().subscribe((endpoints: any) => this.endpoints = endpoints); |
| } |
| |
| private validateUrl(control) { |
| if (control && control.value) { |
| const isDublicat = this.endpoints.some(endpoint => endpoint['url'].toLocaleLowerCase() === control.value.toLowerCase()); |
| return isDublicat ? { isDuplicate: true } : null; |
| } |
| } |
| |
| private validateName(control) { |
| if (control && control.value) { |
| const isDublicat = this.endpoints.some(endpoint => endpoint['name'].toLocaleLowerCase() === control.value.toLowerCase()); |
| return isDublicat ? { isDuplicate: true } : null; |
| } |
| } |
| |
| private providerMaxLength(control) { |
| return control.value.length <= this.maxEndpointNameLength ? null : { limit: true }; |
| } |
| } |
| |
| @Component({ |
| selector: 'endpoint-test-result-dialog', |
| template: ` |
| <div id="dialog-box"> |
| <div class="dialog-header"> |
| <h4 class="modal-title">Endpoint test</h4> |
| <button type="button" class="close" (click)="dialogRef.close()">×</button> |
| </div> |
| <div class="progress-bar" > |
| <mat-progress-bar *ngIf="!response" mode="indeterminate"></mat-progress-bar> |
| </div> |
| <div class="content-box"> |
| <div mat-dialog-content class="content message"> |
| <p |
| class="dialog-message ellipsis" |
| *ngIf="!response"> |
| Connecting to url |
| <span class="strong" |
| matTooltip="{{data.url}}" |
| [matTooltipPosition]="'above'" |
| > |
| {{cutToLongUrl(data.url)}} |
| </span> |
| </p> |
| <p |
| class="dialog-message ellipsis" |
| *ngIf="isConnected && response"> |
| <i class="material-icons icons-possition active">check_circle</i> |
| Connected to url |
| <span matTooltip="{{data.url}}" |
| [matTooltipPosition]="'above'" |
| class="strong" |
| > |
| {{cutToLongUrl(data.url)}} |
| </span> |
| </p> |
| <p class="dialog-message ellipsis" |
| *ngIf="!isConnected && response" |
| > |
| <i class="material-icons icons-possition failed">cancel</i> |
| Failed to connect to url |
| <span matTooltip="{{data.url}}" |
| [matTooltipPosition]="'above'" |
| class="strong" |
| > |
| {{cutToLongUrl(data.url)}} |
| </span> |
| </p> |
| </div> |
| <div class="text-center m-top-20 m-bott-10"> |
| <button type="button" class="butt" mat-raised-button (click)="dialogRef.close()">Close</button> |
| </div> |
| </div> |
| </div> |
| `, |
| styles: [ |
| `#dialog-box {overflow: hidden} |
| .icons-possition {line-height: 25px; vertical-align: middle; padding-right: 7px } |
| .content { color: #718ba6; padding: 15px 50px; font-size: 14px; font-weight: 400; margin: 0; } |
| .info .confirm-dialog { color: #607D8B; } |
| header { display: flex; justify-content: space-between; color: #607D8B; } |
| header h4 i { vertical-align: bottom; } |
| header a i { font-size: 20px; } |
| header a:hover i { color: #35afd5; cursor: pointer; } |
| label { font-size: 15px; font-weight: 500; font-family: "Open Sans",sans-serif; cursor: pointer; display: flex; align-items: center;} |
| .progress-bar{ height: 4px;} |
| .dialog-message{min-height: 25px; overflow: hidden;} |
| ` |
| ] |
| }) |
| export class EndpointTestResultDialogComponent { |
| public isConnected = false; |
| public response = false; |
| constructor( |
| public dialogRef: MatDialogRef<EndpointTestResultDialogComponent>, |
| @Inject(MAT_DIALOG_DATA) public data: any |
| ) { |
| this.data.getStatus |
| .subscribe( |
| () => { |
| this.isConnected = true; |
| this.response = true; |
| return; |
| }, |
| () => { |
| this.isConnected = false; |
| this.response = true; |
| return; |
| }); |
| } |
| public cutToLongUrl(url) { |
| return url.length > 25 ? url.slice(0, 25) + '...' : url; |
| } |
| } |