You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dlab.apache.org by dg...@apache.org on 2020/02/25 08:58:56 UTC

[incubator-dlab] 01/01: [DLAB-1551]: Added bucket dialog

This is an automated email from the ASF dual-hosted git repository.

dgnatyshyn pushed a commit to branch DLAB-1551
in repository https://gitbox.apache.org/repos/asf/incubator-dlab.git

commit bf11f35897d4fdf4d72505d7600881b420ed78cf
Author: Dmytro Gnatyshyn <di...@ukr.net>
AuthorDate: Tue Feb 25 10:58:23 2020 +0200

    [DLAB-1551]: Added bucket dialog
---
 .../bucket-dialog/bucket-dialog.component.html     | 55 +++++++++++++
 .../bucket-dialog/bucket-dialog.component.scss     | 32 ++++++++
 .../bucket-dialog/bucket-dialog.component.ts       | 94 ++++++++++++++++++++++
 .../resources/exploratory/bucket-dialog/index.ts   | 39 +++++++++
 .../detail-dialog/detail-dialog.component.html     | 14 ++++
 .../detail-dialog/detail-dialog.component.scss     |  3 +
 .../detail-dialog/detail-dialog.component.ts       | 14 +++-
 .../src/app/resources/resources-grid/index.ts      |  4 +-
 8 files changed, 252 insertions(+), 3 deletions(-)

diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/bucket-dialog/bucket-dialog.component.html b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/bucket-dialog/bucket-dialog.component.html
new file mode 100644
index 0000000..fee54c3
--- /dev/null
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/bucket-dialog/bucket-dialog.component.html
@@ -0,0 +1,55 @@
+<!--
+  ~ 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.
+  -->
+
+<div class="ami-dialog" id="dialog-box">
+  <header class="dialog-header">
+    <h4 class="modal-title">Bucket</h4>
+    <button type="button" class="close" (click)="dialogRef.close()">&times;</button>
+  </header>
+  <div class="dialog-content">
+    <div class="content-box" *ngIf="notebook">
+      <form [formGroup]="createAMIForm" novalidate>
+        <div class="control-group">
+          <label class="label">Upload file</label>
+          <div class="control">
+            <input type="text" formControlName="name" placeholder="Enter image name">
+            <span class="error" *ngIf="createAMIForm.controls['name'].hasError('duplication')">This
+              image name already exists in project.</span>
+            <span class="error"
+              *ngIf="!createAMIForm.valid && createAMIForm.controls['name'].dirty && !createAMIForm.controls['name'].hasError('duplication')">
+              image name
+              <span *ngIf="provider === 'azure'"> cannot be longer than 10 characters and</span>
+              can only contain letters, numbers, hyphens and '_'</span>
+          </div>
+        </div>
+        <div class="control-group">
+          <label class="label">Download file</label>
+          <div class="control">
+            <input type="text" formControlName="description" placeholder="Leave description">
+          </div>
+        </div>
+      </form>
+      <div class="text-center m-top-30 m-bott-10">
+        <button mat-raised-button type="button" class="butt action" (click)="dialogRef.close()">Cancel</button>
+        <button mat-raised-button type="button" [disabled]="!createAMIForm.valid"
+          (click)="assignChanges(createAMIForm.value)" class="butt butt-success action">Create</button>
+      </div>
+    </div>
+  </div>
+</div>
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/bucket-dialog/bucket-dialog.component.scss b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/bucket-dialog/bucket-dialog.component.scss
new file mode 100644
index 0000000..4ab43fd
--- /dev/null
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/bucket-dialog/bucket-dialog.component.scss
@@ -0,0 +1,32 @@
+/*!
+ * 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.
+ */
+
+form {
+  textarea {
+    height: 70px;
+    resize: none;
+    padding-top: 8px;
+    // font: 300 16px/26px 'Open Sans', sans-serif;
+    font-style: normal;
+    font-weight: 300;
+    font-size: 16px;
+    line-height: 26px;
+    font-family:'Open Sans', sans-serif;
+  }
+}
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/bucket-dialog/bucket-dialog.component.ts b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/bucket-dialog/bucket-dialog.component.ts
new file mode 100644
index 0000000..abb13d4
--- /dev/null
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/bucket-dialog/bucket-dialog.component.ts
@@ -0,0 +1,94 @@
+/*
+ * 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 } from '@angular/material/dialog';
+import { ToastrService } from 'ngx-toastr';
+
+import { UserResourceService } from '../../../core/services';
+import { HTTP_STATUS_CODES } from '../../../core/util';
+import { DICTIONARY } from '../../../../dictionary/global.dictionary';
+
+@Component({
+  selector: 'bucket-create-dialog',
+  templateUrl: './bucket-dialog.component.html',
+  styleUrls: ['./bucket-dialog.component.scss']
+})
+export class BucketDialogComponent implements OnInit {
+  readonly DICTIONARY = DICTIONARY;
+  public notebook: any;
+  public createAMIForm: FormGroup;
+  public provider: string;
+  namePattern = '[-_a-zA-Z0-9]+';
+  delimitersRegex = /[-_]?/g;
+  imagesList: any;
+
+  constructor(
+    @Inject(MAT_DIALOG_DATA) public data: any,
+    public toastr: ToastrService,
+    public dialogRef: MatDialogRef<BucketDialogComponent>,
+    private _userResource: UserResourceService,
+    private _fb: FormBuilder,
+  ) { }
+
+  ngOnInit() {
+    this.notebook = this.data;
+    this.provider = this.data.cloud_provider;
+
+    this.initFormModel();
+    this._userResource.getImagesList(this.data.project).subscribe(res => this.imagesList = res);
+  }
+
+  public assignChanges(data) {
+    this._userResource.createAMI(data).subscribe(
+      response => response.status === HTTP_STATUS_CODES.ACCEPTED && this.dialogRef.close(),
+      error => this.toastr.error(error.message || `Image creation failed!`, 'Oops!'));
+  }
+
+  private initFormModel(): void {
+    this.createAMIForm = this._fb.group({
+      name: ['', [Validators.required, Validators.pattern(this.namePattern), this.providerMaxLength, this.checkDuplication.bind(this)]],
+      description: [''],
+      exploratory_name: [this.notebook.name]
+    });
+  }
+
+  private providerMaxLength(control) {
+    if (control && control.value)
+      return control.value.length <= 10 ? null : { valid: false };
+  }
+
+  private checkDuplication(control) {
+    if (control.value)
+      return this.isDuplicate(control.value) ? { duplication: true } : null;
+  }
+
+  private isDuplicate(value: string) {
+    for (let index = 0; index < this.imagesList.length; index++) {
+      if (this.delimitersFiltering(value) === this.delimitersFiltering(this.imagesList[index].name))
+        return true;
+    }
+    return false;
+  }
+
+  private delimitersFiltering(resource): string {
+    return resource.replace(this.delimitersRegex, '').toString().toLowerCase();
+  }
+}
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/bucket-dialog/index.ts b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/bucket-dialog/index.ts
new file mode 100644
index 0000000..59b6136
--- /dev/null
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/bucket-dialog/index.ts
@@ -0,0 +1,39 @@
+/*
+ * 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 { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { FormsModule, ReactiveFormsModule } from '@angular/forms';
+import { MaterialModule } from '../../../shared/material.module';
+
+import { BucketDialogComponent } from './bucket-dialog.component';
+export * from './bucket-dialog.component';
+
+@NgModule({
+  imports: [
+    CommonModule,
+    MaterialModule,
+    FormsModule,
+    ReactiveFormsModule
+  ],
+  declarations: [BucketDialogComponent],
+  entryComponents: [BucketDialogComponent],
+  exports: [BucketDialogComponent]
+})
+export class BucketDialogModule {}
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/detail-dialog/detail-dialog.component.html b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/detail-dialog/detail-dialog.component.html
index 4977b22..b5b1491 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/detail-dialog/detail-dialog.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/detail-dialog/detail-dialog.component.html
@@ -61,17 +61,31 @@
 
             <p class="m-top-30">{{ DICTIONARY[PROVIDER].personal_storage }}: &nbsp;</p>
             <div class="links_block">
+              <div class="links">
+              <p >{{ DICTIONARY[PROVIDER].container }}
+                <span class="bucket-info"> notebook.shared_bucket_name</span></p>
               <p *ngIf="DICTIONARY[PROVIDER].cloud_provider === 'azure' && notebook.account_name">{{ DICTIONARY[PROVIDER].account }}
                 <span class="bucket-info">{{ notebook.account_name}}</span></p>
               <p *ngIf="notebook.bucket_name">{{ DICTIONARY[PROVIDER].container }} <span
                   class="bucket-info">{{ notebook.bucket_name }}</span></p>
+              </div>
+              <div class="action-block">
+                <button class="butt butt-tool mat-raised-button" (click)="openBucketDialog()">Bucket info</button>
+              </div>
             </div>
             <p>Shared endpoint bucket: &nbsp;</p>
             <div class="links_block">
+              <div class="links">
+              <p >{{ DICTIONARY[PROVIDER].container }}
+                <span class="bucket-info"> notebook.shared_bucket_name</span></p>
               <p *ngIf="DICTIONARY[PROVIDER].cloud_provider === 'azure' && notebook.shared_account_name">{{ DICTIONARY[PROVIDER].account }}
                 <span class="bucket-info">{{ notebook.shared_account_name}}</span></p>
               <p *ngIf="notebook.shared_bucket_name">{{ DICTIONARY[PROVIDER].container }}
                 <span class="bucket-info">{{ notebook.shared_bucket_name }}</span></p>
+              </div>
+              <div class="action-block">
+                <button class="butt butt-tool mat-raised-button" (click)="openBucketDialog()">Bucket info</button>
+              </div>
             </div>
             <br />
 
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/detail-dialog/detail-dialog.component.scss b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/detail-dialog/detail-dialog.component.scss
index 2849ce0..b692c0f 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/detail-dialog/detail-dialog.component.scss
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/detail-dialog/detail-dialog.component.scss
@@ -26,6 +26,9 @@
 }
 
 .links_block {
+  display: flex;
+  justify-content: space-between;
+  padding-right: 10px;
 
   >p {
     display: flex;
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/detail-dialog/detail-dialog.component.ts b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/detail-dialog/detail-dialog.component.ts
index 1fa43ca..9aa2bc7 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/detail-dialog/detail-dialog.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/detail-dialog/detail-dialog.component.ts
@@ -20,12 +20,14 @@
 import { Component, ViewChild, OnInit, Inject } from '@angular/core';
 import { FormGroup, FormBuilder } from '@angular/forms';
 import { ToastrService } from 'ngx-toastr';
-import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
+import {MatDialogRef, MAT_DIALOG_DATA, MatDialog} from '@angular/material/dialog';
 
 import { DateUtils, CheckUtils } from '../../../core/util';
 import { DICTIONARY } from '../../../../dictionary/global.dictionary';
 import { DataengineConfigurationService } from '../../../core/services';
 import { CLUSTER_CONFIGURATION } from '../../computational/computational-resource-create-dialog/cluster-configuration-templates';
+import {NotificationDialogComponent} from '../../../shared/modal-dialog/notification-dialog';
+import {BucketDialogComponent} from '../bucket-dialog';
 
 @Component({
   selector: 'detail-dialog',
@@ -51,7 +53,8 @@ export class DetailDialogComponent implements OnInit {
     private dataengineConfigurationService: DataengineConfigurationService,
     private _fb: FormBuilder,
     public dialogRef: MatDialogRef<DetailDialogComponent>,
-    public toastr: ToastrService
+    public toastr: ToastrService,
+    public dialog: MatDialog
   ) {
     this.notebook = data;
   }
@@ -120,4 +123,11 @@ export class DetailDialogComponent implements OnInit {
         ? (control.value && control.value !== null && CheckUtils.isJSON(control.value) ? null : { valid: false })
         : null;
   }
+
+  public openBucketDialog() {
+    this.dialog.open(BucketDialogComponent, { data: {  }, panelClass: 'modal-sm' })
+      .afterClosed().subscribe(result => {
+
+    });
+  }
 }
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/resources-grid/index.ts b/services/self-service/src/main/resources/webapp/src/app/resources/resources-grid/index.ts
index 39a9732..247b3d6 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/resources-grid/index.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/resources-grid/index.ts
@@ -32,6 +32,7 @@ import { InstallLibrariesModule } from '../exploratory/install-libraries';
 import { AmiCreateDialogModule } from '../exploratory/ami-create-dialog';
 import { SchedulerModule } from '../scheduler';
 import { UnderscorelessPipeModule } from '../../core/pipes/underscoreless-pipe';
+import {BucketDialogModule} from '../exploratory/bucket-dialog';
 
 @NgModule({
   imports: [
@@ -48,7 +49,8 @@ import { UnderscorelessPipeModule } from '../../core/pipes/underscoreless-pipe';
     SchedulerModule,
     AmiCreateDialogModule,
     UnderscorelessPipeModule,
-    MaterialModule
+    MaterialModule,
+    BucketDialogModule
   ],
   declarations: [ResourcesGridComponent],
   exports: [ResourcesGridComponent]


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@dlab.apache.org
For additional commands, e-mail: commits-help@dlab.apache.org