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/20 10:38:02 UTC

[incubator-dlab] 02/02: [DLAB-1476]: Added demo screenshots for links

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

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

commit 620ee0fc0c2c9fb95ff6a22d38244ae913885dbd
Author: Dmytro Gnatyshyn <di...@ukr.net>
AuthorDate: Thu Feb 20 12:35:20 2020 +0200

    [DLAB-1476]: Added demo screenshots for links
---
 .../cluster-details/cluster-details.component.html |   6 +-
 .../cluster-details/cluster-details.component.ts   |  23 ++++-
 .../demo-picture-dialog.component.html             |  28 ++++++
 .../demo-picture-dialog.component.scss             |  24 ++++++
 .../demo-picture-dialog.component.ts               |  94 +++++++++++++++++++++
 .../exploratory/demo-picture-dialog/index.ts       |  39 +++++++++
 .../detail-dialog/detail-dialog.component.html     |   8 +-
 .../detail-dialog/detail-dialog.component.ts       |  32 ++++++-
 .../src/app/resources/resources-grid/index.ts      |   2 +
 .../webapp/src/assets/img/demo/Jupyter.png         | Bin 0 -> 115150 bytes
 .../webapp/src/assets/img/demo/Rstudio.png         | Bin 0 -> 210897 bytes
 .../webapp/src/assets/img/demo/handoop_cluster.png | Bin 0 -> 105996 bytes
 .../webapp/src/assets/img/demo/spark_cluster.png   | Bin 0 -> 75258 bytes
 .../webapp/src/assets/img/demo/tensorboard.png     | Bin 0 -> 61639 bytes
 .../resources/webapp/src/assets/img/demo/ungit.png | Bin 0 -> 98113 bytes
 .../webapp/src/assets/img/demo/zeppeling.png       | Bin 0 -> 146524 bytes
 .../webapp/src/assets/styles/_dialogs.scss         |   8 ++
 17 files changed, 256 insertions(+), 8 deletions(-)

diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/computational/cluster-details/cluster-details.component.html b/services/self-service/src/main/resources/webapp/src/app/resources/computational/cluster-details/cluster-details.component.html
index 04ea086..8ce7fed 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/computational/cluster-details/cluster-details.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/computational/cluster-details/cluster-details.component.html
@@ -100,8 +100,10 @@
           <div class="m-top-10">
             <p *ngFor="let item of resource.computational_url" class="ellipsis flex">
               <span class="strong">{{ item.description }}:</span>&nbsp;
-              <a href="{{item.url}}" target="_blank" matTooltip="{{item.url}}"
-                matTooltipPosition="above">{{ item.url }}</a>
+              <a *ngIf="demoMode" href="{{item.url}}" target="_blank" matTooltip="{{item.url}}"
+                 matTooltipPosition="above">{{ item.url }}</a>
+              <span *ngIf="demoMode" class="fake-link" (click)="openDemoLink(item.description)" matTooltip="{{item.url}}"
+                    matTooltipPosition="above">{{ item.url }}</span>
             </p>
           </div>
         </div>
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/computational/cluster-details/cluster-details.component.ts b/services/self-service/src/main/resources/webapp/src/app/resources/computational/cluster-details/cluster-details.component.ts
index 75ea01e..d724f71 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/computational/cluster-details/cluster-details.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/computational/cluster-details/cluster-details.component.ts
@@ -18,7 +18,7 @@
  */
 
 import { Component, ViewChild, OnInit, Inject } from '@angular/core';
-import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
+import {MatDialogRef, MAT_DIALOG_DATA, MatDialog} from '@angular/material/dialog';
 import { FormGroup, FormBuilder } from '@angular/forms';
 import { ToastrService } from 'ngx-toastr';
 
@@ -26,6 +26,7 @@ import { DateUtils, CheckUtils } from '../../../core/util';
 import { DataengineConfigurationService } from '../../../core/services';
 import { DICTIONARY } from '../../../../dictionary/global.dictionary';
 import { CLUSTER_CONFIGURATION } from '../computational-resource-create-dialog/cluster-configuration-templates';
+import {DemoPictureDialogComponent} from '../../exploratory/demo-picture-dialog';
 
 @Component({
   selector: 'dlab-cluster-details',
@@ -46,13 +47,15 @@ export class DetailComputationalResourcesComponent implements OnInit {
   tooltip: boolean = false;
   config: Array<{}> = [];
   public configurationForm: FormGroup;
+  private demoMode: boolean = true;
 
   constructor(
     @Inject(MAT_DIALOG_DATA) public data: any,
     public toastr: ToastrService,
     public dialogRef: MatDialogRef<DetailComputationalResourcesComponent>,
     private dataengineConfigurationService: DataengineConfigurationService,
-    private _fb: FormBuilder
+    private _fb: FormBuilder,
+    private dialog: MatDialog
   ) { }
 
   ngOnInit() {
@@ -117,4 +120,20 @@ export class DetailComputationalResourcesComponent implements OnInit {
         ? (control.value && control.value !== null && CheckUtils.isJSON(control.value) ? null : { valid: false })
         : null;
   }
+
+  private openDemoLink(template) {
+    const demoData = {
+      title: template.slice(0, -3),
+      url: ''
+    };
+
+    if (this.data.resource.image === 'docker.dlab-dataengine') {
+      demoData.url = 'assets/img/demo/spark_cluster.png';
+    } else {
+      demoData.url = 'assets/img/demo/handoop_cluster.png';
+    }
+    this.dialog.open(DemoPictureDialogComponent, { data: demoData, panelClass: 'modal-fullscreen' })
+      .afterClosed().subscribe(() => console.log('done'));
+  }
+
 }
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/demo-picture-dialog/demo-picture-dialog.component.html b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/demo-picture-dialog/demo-picture-dialog.component.html
new file mode 100644
index 0000000..a45900a
--- /dev/null
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/demo-picture-dialog/demo-picture-dialog.component.html
@@ -0,0 +1,28 @@
+<!--
+  ~ 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">Demo {{data.title}}</h4>
+    <button type="button" class="close" (click)="dialogRef.close()">&times;</button>
+  </header>
+  <div class="dialog-content">
+    <img class="demo-picture" src="{{data.url}}" alt="">
+  </div>
+</div>
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/demo-picture-dialog/demo-picture-dialog.component.scss b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/demo-picture-dialog/demo-picture-dialog.component.scss
new file mode 100644
index 0000000..1668e5f
--- /dev/null
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/demo-picture-dialog/demo-picture-dialog.component.scss
@@ -0,0 +1,24 @@
+/*!
+ * 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.
+ */
+
+
+
+.demo-picture{
+  width: 100%;
+}
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/demo-picture-dialog/demo-picture-dialog.component.ts b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/demo-picture-dialog/demo-picture-dialog.component.ts
new file mode 100644
index 0000000..dd13006
--- /dev/null
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/demo-picture-dialog/demo-picture-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: 'demo-picture-dialog',
+  templateUrl: './demo-picture-dialog.component.html',
+  styleUrls: ['./demo-picture-dialog.component.scss']
+})
+export class DemoPictureDialogComponent 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<DemoPictureDialogComponent>,
+    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/demo-picture-dialog/index.ts b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/demo-picture-dialog/index.ts
new file mode 100644
index 0000000..dd32784
--- /dev/null
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/demo-picture-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 { DemoPictureDialogComponent } from './demo-picture-dialog.component';
+export * from './demo-picture-dialog.component';
+
+@NgModule({
+  imports: [
+    CommonModule,
+    MaterialModule,
+    FormsModule,
+    ReactiveFormsModule
+  ],
+  declarations: [DemoPictureDialogComponent],
+  entryComponents: [DemoPictureDialogComponent],
+  exports: [DemoPictureDialogComponent]
+})
+export class DemoPictureDialogModule {}
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..1950044 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
@@ -48,14 +48,18 @@
             <div class="links_block">
               <p *ngFor="let item of notebook.url">
                 <span class="description">{{item.description}}: &nbsp;</span>
-                <a class="ellipsis" matTooltip="{{item.url}}" matTooltipPosition="above" href="{{item.url}}"
+                <a *ngIf="!demoMode" class="ellipsis" matTooltip="{{item.url}}" matTooltipPosition="above" href="{{item.url}}"
                   target="_blank">
                   &nbsp;{{item.url}}
                 </a>
+                <span *ngIf="demoMode" (click)="openDemoLink(item.description)" class="ellipsis fake-link" matTooltip="{{item.url}}" matTooltipPosition="above">
+                  &nbsp;{{item.url}}
+                </span>
               </p>
+
             </div>
             <p class="flex" *ngIf="notebook.username">Node User: &nbsp;<span
-                class="strong">{{ notebook.username }}</span></p>
+                class="strong" >{{ notebook.username }}</span></p>
             <p class="flex" *ngIf="notebook.password">Password: &nbsp;<span
                 class="strong">{{ notebook.password }}</span></p>
 
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..6aae7ca 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 {AmiCreateDialogComponent} from '../ami-create-dialog';
+import {DemoPictureDialogComponent} from '../demo-picture-dialog';
 
 @Component({
   selector: 'detail-dialog',
@@ -41,17 +43,20 @@ export class DetailDialogComponent implements OnInit {
   upTimeSince: string = '';
   tooltip: boolean = false;
   config: Array<{}> = [];
+  demoMode: boolean = true;
 
   public configurationForm: FormGroup;
 
   @ViewChild('configurationNode', { static: false }) configuration;
 
+
   constructor(
     @Inject(MAT_DIALOG_DATA) public data: any,
     private dataengineConfigurationService: DataengineConfigurationService,
     private _fb: FormBuilder,
     public dialogRef: MatDialogRef<DetailDialogComponent>,
-    public toastr: ToastrService
+    public toastr: ToastrService,
+    private dialog: MatDialog
   ) {
     this.notebook = data;
   }
@@ -120,4 +125,27 @@ export class DetailDialogComponent implements OnInit {
         ? (control.value && control.value !== null && CheckUtils.isJSON(control.value) ? null : { valid: false })
         : null;
   }
+
+  private openDemoLink(template) {
+    const demoData = {
+      title: template,
+      url: ''
+    };
+
+     if (template === 'Jupyter') {
+      demoData.url = 'assets/img/demo/Jupyter.png';
+    } else if (template === 'Ungit') {
+       demoData.url = 'assets/img/demo/ungit.png';
+    } else if (template === 'TensorBoard') {
+       demoData.url = 'assets/img/demo/tensorboard.png';
+    } else if (template === 'RStudio') {
+      demoData.url = 'assets/img/demo/Rstudio.png';
+    } else if (template === 'Apache Zeppelin') {
+       demoData.url = 'assets/img/demo/zeppeling.png';
+    } else {
+      demoData.url = 'assets/img/demo/Jupyter.png';
+    }
+    this.dialog.open(DemoPictureDialogComponent, { data: demoData, panelClass: 'modal-fullscreen' })
+      .afterClosed().subscribe(() => console.log('done'));
+  }
 }
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..e5ab331 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 {DemoPictureDialogModule} from '../exploratory/demo-picture-dialog';
 
 @NgModule({
   imports: [
@@ -47,6 +48,7 @@ import { UnderscorelessPipeModule } from '../../core/pipes/underscoreless-pipe';
     InstallLibrariesModule,
     SchedulerModule,
     AmiCreateDialogModule,
+    DemoPictureDialogModule,
     UnderscorelessPipeModule,
     MaterialModule
   ],
diff --git a/services/self-service/src/main/resources/webapp/src/assets/img/demo/Jupyter.png b/services/self-service/src/main/resources/webapp/src/assets/img/demo/Jupyter.png
new file mode 100644
index 0000000..6fea12e
Binary files /dev/null and b/services/self-service/src/main/resources/webapp/src/assets/img/demo/Jupyter.png differ
diff --git a/services/self-service/src/main/resources/webapp/src/assets/img/demo/Rstudio.png b/services/self-service/src/main/resources/webapp/src/assets/img/demo/Rstudio.png
new file mode 100644
index 0000000..45f7367
Binary files /dev/null and b/services/self-service/src/main/resources/webapp/src/assets/img/demo/Rstudio.png differ
diff --git a/services/self-service/src/main/resources/webapp/src/assets/img/demo/handoop_cluster.png b/services/self-service/src/main/resources/webapp/src/assets/img/demo/handoop_cluster.png
new file mode 100644
index 0000000..741f9b1
Binary files /dev/null and b/services/self-service/src/main/resources/webapp/src/assets/img/demo/handoop_cluster.png differ
diff --git a/services/self-service/src/main/resources/webapp/src/assets/img/demo/spark_cluster.png b/services/self-service/src/main/resources/webapp/src/assets/img/demo/spark_cluster.png
new file mode 100644
index 0000000..79999b9
Binary files /dev/null and b/services/self-service/src/main/resources/webapp/src/assets/img/demo/spark_cluster.png differ
diff --git a/services/self-service/src/main/resources/webapp/src/assets/img/demo/tensorboard.png b/services/self-service/src/main/resources/webapp/src/assets/img/demo/tensorboard.png
new file mode 100644
index 0000000..5387534
Binary files /dev/null and b/services/self-service/src/main/resources/webapp/src/assets/img/demo/tensorboard.png differ
diff --git a/services/self-service/src/main/resources/webapp/src/assets/img/demo/ungit.png b/services/self-service/src/main/resources/webapp/src/assets/img/demo/ungit.png
new file mode 100644
index 0000000..aa7fa9f
Binary files /dev/null and b/services/self-service/src/main/resources/webapp/src/assets/img/demo/ungit.png differ
diff --git a/services/self-service/src/main/resources/webapp/src/assets/img/demo/zeppeling.png b/services/self-service/src/main/resources/webapp/src/assets/img/demo/zeppeling.png
new file mode 100644
index 0000000..ed71f56
Binary files /dev/null and b/services/self-service/src/main/resources/webapp/src/assets/img/demo/zeppeling.png differ
diff --git a/services/self-service/src/main/resources/webapp/src/assets/styles/_dialogs.scss b/services/self-service/src/main/resources/webapp/src/assets/styles/_dialogs.scss
index f1fa89f..6acdc96 100644
--- a/services/self-service/src/main/resources/webapp/src/assets/styles/_dialogs.scss
+++ b/services/self-service/src/main/resources/webapp/src/assets/styles/_dialogs.scss
@@ -335,6 +335,14 @@ mat-dialog-container {
   top: 49%;
 }
 
+.fake-link{
+  color: #35afd5;
+  text-decoration: none;
+  transition: all 0.45s ease-in-out;
+  line-height: 19px;
+  cursor: pointer;
+}
+
 @media screen and (max-width: 1280px) {
   .modal-fullscreen {
     max-width: 100vw !important;


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