You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@datalab.apache.org by dg...@apache.org on 2020/11/19 13:07:15 UTC

[incubator-datalab] branch DATALAB-2156 created (now 913014b)

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

dgnatyshyn pushed a change to branch DATALAB-2156
in repository https://gitbox.apache.org/repos/asf/incubator-datalab.git.


      at 913014b  [DATALAB-2157]: Update main block on administrative page

This branch includes the following new commits:

     new 37fd894  [DATALAB-2138]: Implement administration page
     new 913014b  [DATALAB-2157]: Update main block on administrative page

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



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


[incubator-datalab] 01/02: [DATALAB-2138]: Implement administration page

Posted by dg...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

dgnatyshyn pushed a commit to branch DATALAB-2156
in repository https://gitbox.apache.org/repos/asf/incubator-datalab.git

commit 37fd894117fdb962f3f53beaa53551db701a1a2a
Author: Dmytro_Gnatyshyn <di...@ukr.net>
AuthorDate: Thu Nov 19 12:03:27 2020 +0200

    [DATALAB-2138]: Implement administration page
---
 .../src/main/resources/webapp/package-lock.json    |  19 ++
 .../src/main/resources/webapp/package.json         |   1 +
 .../app/administration/administration.module.ts    |   5 +-
 .../configuration/configuration.component.html     | 125 ++++++++++++
 .../configuration/configuration.component.scss     |  87 ++++++++
 .../configuration/configuration.component.ts       | 215 ++++++++++++++++++++
 .../index.ts}                                      |  27 ++-
 .../main/resources/webapp/src/app/app.module.ts    |   4 +-
 .../resources/webapp/src/app/app.routing.module.ts |   6 +
 .../resources/webapp/src/app/core/core.module.ts   |   3 +-
 .../app/core/services/configutration.service.ts    | 222 +++++++++++++++++++++
 .../multi-level-select-dropdown.component.scss     |   2 +
 .../src/app/shared/navbar/navbar.component.html    |   6 +
 .../webapp/src/assets/styles/_general.scss         |   1 +
 .../resources/webapp/src/assets/styles/_theme.scss |  22 ++
 .../src/main/resources/webapp/src/styles.scss      |   5 +-
 16 files changed, 737 insertions(+), 13 deletions(-)

diff --git a/services/self-service/src/main/resources/webapp/package-lock.json b/services/self-service/src/main/resources/webapp/package-lock.json
index a4d8a2f..89cca19 100644
--- a/services/self-service/src/main/resources/webapp/package-lock.json
+++ b/services/self-service/src/main/resources/webapp/package-lock.json
@@ -2002,6 +2002,11 @@
         "negotiator": "0.6.2"
       }
     },
+    "ace-builds": {
+      "version": "1.4.12",
+      "resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.4.12.tgz",
+      "integrity": "sha512-G+chJctFPiiLGvs3+/Mly3apXTcfgE45dT5yp12BcWZ1kUs+gm0qd3/fv4gsz6fVag4mM0moHVpjHDIgph6Psg=="
+    },
     "acorn": {
       "version": "6.4.2",
       "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz",
@@ -2602,6 +2607,11 @@
       "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=",
       "dev": true
     },
+    "brace": {
+      "version": "0.11.1",
+      "resolved": "https://registry.npmjs.org/brace/-/brace-0.11.1.tgz",
+      "integrity": "sha1-SJb8ydVE7vRfS7dmDbMg07N5/lg="
+    },
     "brace-expansion": {
       "version": "1.1.11",
       "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -7092,6 +7102,15 @@
         "date-fns": "^1.29.0"
       }
     },
+    "ng2-ace-editor": {
+      "version": "0.3.9",
+      "resolved": "https://registry.npmjs.org/ng2-ace-editor/-/ng2-ace-editor-0.3.9.tgz",
+      "integrity": "sha512-e8Q4YCirlL/OEiekewmzupG+zV3prYsiYmQnRzQzd0wNgsPjOLOdb0it7cCbzFfIXKGyIIHKTW5584WxPr2LnQ==",
+      "requires": {
+        "ace-builds": "^1.4.2",
+        "brace": "^0.11.1"
+      }
+    },
     "ngx-toastr": {
       "version": "12.1.0",
       "resolved": "https://registry.npmjs.org/ngx-toastr/-/ngx-toastr-12.1.0.tgz",
diff --git a/services/self-service/src/main/resources/webapp/package.json b/services/self-service/src/main/resources/webapp/package.json
index 6baa7a2..bd320b3 100644
--- a/services/self-service/src/main/resources/webapp/package.json
+++ b/services/self-service/src/main/resources/webapp/package.json
@@ -33,6 +33,7 @@
     "moment": "^2.24.0",
     "moment-timezone": "^0.5.31",
     "ng-daterangepicker": "^1.1.0",
+    "ng2-ace-editor": "^0.3.9",
     "ngx-toastr": "^12.1.0",
     "rxjs": "^6.6.3",
     "rxjs-compat": "6.5.3",
diff --git a/services/self-service/src/main/resources/webapp/src/app/administration/administration.module.ts b/services/self-service/src/main/resources/webapp/src/app/administration/administration.module.ts
index e535bda..5315ff6 100644
--- a/services/self-service/src/main/resources/webapp/src/app/administration/administration.module.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/administration/administration.module.ts
@@ -23,10 +23,11 @@ import { CommonModule } from '@angular/common';
 import { ManagenementModule } from './management';
 import { ProjectModule } from './project';
 import { RolesModule } from './roles';
+import {ConfigurationModule} from './configuration';
 
 @NgModule({
-  imports: [CommonModule, ManagenementModule, ProjectModule, RolesModule],
+  imports: [CommonModule, ManagenementModule, ProjectModule, RolesModule, ConfigurationModule],
   declarations: [],
-  exports: [ManagenementModule, ProjectModule, RolesModule]
+  exports: [ManagenementModule, ProjectModule, RolesModule, ConfigurationModule]
 })
 export class AdministrationModule { }
diff --git a/services/self-service/src/main/resources/webapp/src/app/administration/configuration/configuration.component.html b/services/self-service/src/main/resources/webapp/src/app/administration/configuration/configuration.component.html
new file mode 100644
index 0000000..8877a6c
--- /dev/null
+++ b/services/self-service/src/main/resources/webapp/src/app/administration/configuration/configuration.component.html
@@ -0,0 +1,125 @@
+<!--
+  ~ 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="base-retreat">
+  <div class="sub-nav">
+    <button mat-raised-button class="butt"
+            (click)="action('save')"
+            [disabled]="provisioningSource === serverConfigs.provisioningSource
+               && serverConfigs.selvServiceSource === selvServiceSource
+               && serverConfigs.billingSource === billingSource
+               "
+    >
+      Save
+    </button>
+    <button mat-raised-button class="butt"
+            (click)="action('discard')"
+            [disabled]="provisioningSource === serverConfigs.provisioningSource
+               && serverConfigs.selvServiceSource === selvServiceSource
+               && serverConfigs.billingSource === billingSource"
+    >
+      Discard changes
+    </button>
+    <button mat-raised-button class="butt" (click)="refresh()">
+      <i class="material-icons refresh-icon">autorenew</i>Refresh
+    </button>
+  </div>
+  <mat-divider></mat-divider>
+  <div class="configuration-wrapper">
+    <mat-tab-group animationDuration="0.5ms" (selectedTabChange)="tabChanged($event)">
+      <mat-tab label="Main"
+               [disabled]="!(provisioningSource === serverConfigs.provisioningSource
+               && serverConfigs.selvServiceSource === selvServiceSource
+               && serverConfigs.billingSource === billingSource
+               ) && activeTab !== 0
+"
+      >
+        <h4>Main settings</h4>
+        <div class="main-wrapper">
+          <section class="section">
+            <p class="section-title">Restart services</p>
+            <div class="section-content">
+              <ul class="list-menu selection-list">
+                <li>
+                  <p class="list-item" role="menuitem">
+                    <span class="empty-checkbox" [ngClass]="{'checked': true}" (click)="toggleSetings($event);$event.stopPropagation()" >
+                    <span class="checked-checkbox" *ngIf="true"></span>
+                  </span>
+                    Provisioning
+                  </p>
+                </li>
+                <li>
+                  <p class="list-item" role="menuitem">
+                    <span class="empty-checkbox" [ngClass]="{'checked': true}" (click)="toggleSetings($event);$event.stopPropagation()" >
+                    <span class="checked-checkbox" *ngIf="true"></span>
+                  </span>
+                    Selv service
+                  </p>
+                </li>
+                <li>
+                  <p class="list-item" role="menuitem">
+                    <span class="empty-checkbox" [ngClass]="{'checked': true}" (click)="toggleSetings($event);$event.stopPropagation()" >
+                    <span class="checked-checkbox" *ngIf="true"></span>
+                  </span>
+                    Billing
+                  </p>
+                </li>
+              </ul>
+              <button mat-raised-button type="button" class="butt action" (click)="restartServices()">Restart</button>
+            </div>
+          </section>
+        </div>
+      </mat-tab>
+      <mat-tab label="Provisioning"
+               [disabled]="!(provisioningSource === serverConfigs.provisioningSource
+               && serverConfigs.selvServiceSource === selvServiceSource
+               && serverConfigs.billingSource === billingSource
+               ) && activeTab !== 1
+">
+        <h4>Edit provisioning.yml</h4>
+        <div class="editor-wrap">
+          <div ace-editor [(text)]="provisioningSource" ></div>
+        </div>
+      </mat-tab>
+      <mat-tab label="Self service"
+               [disabled]="!(provisioningSource === serverConfigs.provisioningSource
+               && serverConfigs.selvServiceSource === selvServiceSource
+               && serverConfigs.billingSource === billingSource
+               ) && activeTab !== 2
+"
+      >
+         <h4>Edit self-service.yml</h4>
+        <div class="editor-wrap">
+          <div ace-editor [(text)]="selvServiceSource" ></div>
+        </div>
+      </mat-tab>
+      <mat-tab label="Billing"
+               [disabled]="!(provisioningSource === serverConfigs.provisioningSource
+               && serverConfigs.selvServiceSource === selvServiceSource
+               && serverConfigs.billingSource === billingSource
+               ) && activeTab !== 3"
+      >
+        <h4>Edit billing.yml</h4>
+        <div class="editor-wrap">
+          <div ace-editor [(text)]="billingSource" ></div>
+        </div>
+      </mat-tab>
+    </mat-tab-group>
+  </div>
+</div>
diff --git a/services/self-service/src/main/resources/webapp/src/app/administration/configuration/configuration.component.scss b/services/self-service/src/main/resources/webapp/src/app/administration/configuration/configuration.component.scss
new file mode 100644
index 0000000..a6051b1
--- /dev/null
+++ b/services/self-service/src/main/resources/webapp/src/app/administration/configuration/configuration.component.scss
@@ -0,0 +1,87 @@
+/*!
+ * 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.
+ */
+
+.configuration-wrapper{
+  box-shadow: 0px 3px 5px -1px rgba(0, 0, 0, 0.2), 0px 6px 10px 0px rgba(0, 0, 0, 0.14), 0px 1px 18px 0px rgba(0, 0, 0, 0.12);
+  padding-top: 0;
+  height: calc(100vh - 130px);
+
+  .sub-nav{
+    justify-content: flex-end;
+    padding: 0 30px;
+  }
+
+  h4{
+    padding: 10px 30px;
+    color: rgba(0,0,0,.87);
+  }
+
+  .editor-wrap{
+    height: calc(100% - 60px);
+    box-shadow: 0 2px 24px 0 rgba(73,93,112,0.3);
+    margin: 0 30px;
+  }
+
+  .main-wrapper{
+    padding: 10px 30px;
+
+    .section{
+
+      &-title{
+        font-size: 17px;
+      }
+
+      &-content {
+
+        .list-menu {
+          width: 100%;
+          max-height: 450px;
+          left: 0;
+          padding: 10px 0;
+          margin: 0;
+          overflow-y: auto;
+          overflow-x: hidden;
+
+          li {
+            padding: 0;
+            margin: 0;
+          }
+
+          .list-item{
+            padding: 5px 10px;
+            display: flex;
+
+            .empty-checkbox{
+              display: block;
+              margin-right: 5px;
+            }
+          }
+        }
+      }
+    }
+  }
+}
+.sub-nav{
+  justify-content: flex-end;
+
+  .butt{
+    margin-left: 10px;
+  }
+
+}
diff --git a/services/self-service/src/main/resources/webapp/src/app/administration/configuration/configuration.component.ts b/services/self-service/src/main/resources/webapp/src/app/administration/configuration/configuration.component.ts
new file mode 100644
index 0000000..8d9830c
--- /dev/null
+++ b/services/self-service/src/main/resources/webapp/src/app/administration/configuration/configuration.component.ts
@@ -0,0 +1,215 @@
+/*
+ * 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, Output, EventEmitter, Inject, ViewChild, HostListener} from '@angular/core';
+import { ValidatorFn, FormControl } from '@angular/forms';
+import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
+import { ToastrService } from 'ngx-toastr';
+import {RolesGroupsService, HealthStatusService, ApplicationSecurityService, AppRoutingService} from '../../core/services';
+import {CheckUtils, SortUtils} from '../../core/util';
+import { DICTIONARY } from '../../../dictionary/global.dictionary';
+import {ProgressBarService} from '../../core/services/progress-bar.service';
+import {ConfirmationDialogComponent, ConfirmationDialogType} from '../../shared/modal-dialog/confirmation-dialog';
+import {MatTabChangeEvent} from '@angular/material/tabs';
+import {Router} from '@angular/router';
+import {ConfigurationService} from '../../core/services/configutration.service';
+import {NotificationDialogComponent} from '../../shared/modal-dialog/notification-dialog';
+import {logger} from 'codelyzer/util/logger';
+
+@Component({
+  selector: 'datalab-configuration',
+  templateUrl: './configuration.component.html',
+  styleUrls: ['./configuration.component.scss']
+})
+export class ConfigurationComponent implements OnInit {
+  private healthStatus: any;
+  editorOptions = {theme: 'vs-dark', language: 'javascript'};
+  code: string = 'function x() {console.log("Hello world!");}';
+  text: any;
+  public activeTab: number = 0;
+  selvServiceSource;
+  provisioningSource;
+  billingSource;
+  serverConfigs = {
+    selvServiceSource: {},
+    provisioningSource: {},
+    billingSource: {},
+  };
+  services: [
+    {label: 'Self service'},
+    {label: 'Provisioning'},
+    {label: 'Billing'},
+  ];
+
+  private confirmMessages = {
+    restartService: 'Restarting services will make DataLab unavailable for some time.',
+    discardChanges: 'Discard all unsaved changes.',
+    saveChanges: 'After you save changes you need to restart service.',
+  };
+
+  @HostListener('window:keydown', ['$event'])
+  onKeyDown(event: KeyboardEvent) {
+    if ((event.metaKey || event.ctrlKey) && event.key === 's' && this.activeTab !== 0 && this.router.url === '/configuration') {
+      this.action('save');
+      event.preventDefault();
+    }
+  }
+
+  constructor(
+    private healthStatusService: HealthStatusService,
+    private appRoutingService: AppRoutingService,
+    private configurationService: ConfigurationService,
+    private router: Router,
+    public dialog: MatDialog
+  ) { }
+
+  ngOnInit() {
+    this.getEnvironmentHealthStatus();
+    this.getSettings();
+  }
+  private getEnvironmentHealthStatus() {
+    this.healthStatusService.getEnvironmentHealthStatus()
+      .subscribe((result: any) => {
+          this.healthStatus = result;
+          if (!this.healthStatus.admin && !this.healthStatus.projectAdmin) {
+            this.appRoutingService.redirectToHomePage();
+          } else {
+
+          }
+        }
+      );
+  }
+
+  refresh() {
+    console.log('Refresh');
+  }
+
+  action(action) {
+    this.dialog.open(SettingsConfirmationDialogComponent, { data: {
+        action: action, message: action === 'discard' ? this.confirmMessages.discardChanges : this.confirmMessages.saveChanges
+      }, panelClass: 'modal-sm' })
+      .afterClosed().subscribe(result => {
+      console.log(action, this.activeTab);
+    });
+  }
+
+  getSettings() {
+    this.configurationService.getSelvServiceSettings().subscribe(v => {
+      console.log(v);
+      this.serverConfigs.billingSource = v;
+      this.serverConfigs.selvServiceSource = v;
+      this.serverConfigs.provisioningSource = v;
+      this.selvServiceSource = v;
+      this.provisioningSource = v;
+      this.billingSource = v;
+    }
+    );
+  }
+
+  public tabChanged(tabChangeEvent: MatTabChangeEvent): void {
+    this.activeTab = tabChangeEvent.index;
+    if (this.selvServiceSource !== this.serverConfigs.selvServiceSource) {
+      this.dialog.open(SettingsConfirmationDialogComponent, { data: {
+          action: 'Was changed'
+        }, panelClass: 'modal-sm' })
+        .afterClosed().subscribe(result => {
+        if (result) {
+          this.serverConfigs.selvServiceSource = this.selvServiceSource;
+        } else {
+          this.selvServiceSource = this.serverConfigs.selvServiceSource;
+        }
+        });
+    }
+  }
+
+  toggleSetings($event: MouseEvent) {
+
+  }
+
+  restartServices() {
+    this.dialog.open(SettingsConfirmationDialogComponent, { data: {
+        action: 'Restart services', message: this.confirmMessages.restartService
+      }, panelClass: 'modal-sm' })
+      .afterClosed().subscribe(result => {
+    });
+  }
+}
+
+@Component({
+  selector: 'confirm-dialog',
+  template: `
+  <div id="dialog-box">
+    <div class="dialog-header">
+      <h4 class="modal-title"><span class="capitalize">{{ data.action }}</span> <span *ngIf="data.action === 'save' || data.action === 'discard'"> changes</span></h4>
+      <button type="button" class="close" (click)="dialogRef.close()">&times;</button>
+    </div>
+
+    <div mat-dialog-content class="content">
+      {{data.message}}
+    </div>
+    <div class="text-center ">
+      <p class="strong">Do you want to proceed?</p>
+    </div>
+    <div class="text-center m-top-20 pb-25">
+      <button type="button" class="butt" mat-raised-button (click)="dialogRef.close()">No</button>
+      <button type="button" class="butt butt-success" mat-raised-button (click)="dialogRef.close(true)">Yes</button>
+    </div>
+  </div>
+  `,
+  styles: [
+    `
+      .content { color: #718ba6; padding: 20px 50px; font-size: 14px; font-weight: 400; margin: 0; }
+      .info { color: #35afd5; }
+      .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; }
+      .content{padding: 35px 30px 30px 30px;}
+      .plur { font-style: normal; }
+      .scrolling-content{overflow-y: auto; max-height: 200px; }
+      .cluster { width: 50%; text-align: left;}
+      .status { width: 50%;text-align: left;}
+      .label { font-size: 15px; font-weight: 500; font-family: "Open Sans",sans-serif;}
+      .node { font-weight: 300;}
+      .resource-name { width: 40%;text-align: left; padding: 10px 0;line-height: 26px;}
+      .clusters-list { width: 60%;text-align: left; padding: 10px 0;line-height: 26px;}
+      .clusters-list-item { width: 100%;text-align: left;display: flex}
+      .resource-list{max-width: 100%; margin: 0 auto;margin-top: 20px; }
+      .resource-list-header{display: flex; font-weight: 600; font-size: 16px;height: 48px; border-top: 1px solid #edf1f5; border-bottom: 1px solid #edf1f5; padding: 0 20px;}
+      .resource-list-row{display: flex; border-bottom: 1px solid #edf1f5;padding: 0 20px;}
+      .confirm-resource-terminating{text-align: left; padding: 10px 20px;}
+      .confirm-message{color: #ef5c4b;font-size: 13px;min-height: 18px; text-align: center; padding-top: 20px}
+      .checkbox{margin-right: 5px;vertical-align: middle; margin-bottom: 3px;}
+      label{cursor: pointer}
+      .bottom-message{padding-top: 15px;}
+      .table-header{padding-bottom: 10px;}`
+  ]
+})
+
+export class SettingsConfirmationDialogComponent {
+  constructor(
+    public dialogRef: MatDialogRef<SettingsConfirmationDialogComponent>,
+    @Inject(MAT_DIALOG_DATA) public data: any
+  ) {
+
+  }
+}
+
+
diff --git a/services/self-service/src/main/resources/webapp/src/app/administration/administration.module.ts b/services/self-service/src/main/resources/webapp/src/app/administration/configuration/index.ts
similarity index 53%
copy from services/self-service/src/main/resources/webapp/src/app/administration/administration.module.ts
copy to services/self-service/src/main/resources/webapp/src/app/administration/configuration/index.ts
index e535bda..d38f2c5 100644
--- a/services/self-service/src/main/resources/webapp/src/app/administration/administration.module.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/administration/configuration/index.ts
@@ -19,14 +19,25 @@
 
 import { NgModule } from '@angular/core';
 import { CommonModule } from '@angular/common';
-
-import { ManagenementModule } from './management';
-import { ProjectModule } from './project';
-import { RolesModule } from './roles';
+import { FormsModule, ReactiveFormsModule } from '@angular/forms';
+import { MaterialModule } from '../../shared/material.module';
+import { FormControlsModule } from '../../shared/form-controls';
+import {InformMessageModule} from '../../shared/inform-message';
+import {ConfigurationComponent, SettingsConfirmationDialogComponent} from './configuration.component';
+import {AceEditorModule} from 'ng2-ace-editor';
 
 @NgModule({
-  imports: [CommonModule, ManagenementModule, ProjectModule, RolesModule],
-  declarations: [],
-  exports: [ManagenementModule, ProjectModule, RolesModule]
+  imports: [
+    CommonModule,
+    FormsModule,
+    ReactiveFormsModule,
+    MaterialModule,
+    FormControlsModule,
+    InformMessageModule,
+    AceEditorModule
+  ],
+  declarations: [ConfigurationComponent, SettingsConfirmationDialogComponent],
+  entryComponents: [SettingsConfirmationDialogComponent],
+  exports: [ConfigurationComponent]
 })
-export class AdministrationModule { }
+export class ConfigurationModule { }
diff --git a/services/self-service/src/main/resources/webapp/src/app/app.module.ts b/services/self-service/src/main/resources/webapp/src/app/app.module.ts
index 9559cf1..e6e887c 100644
--- a/services/self-service/src/main/resources/webapp/src/app/app.module.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/app.module.ts
@@ -41,6 +41,7 @@ import { CoreModule } from './core/core.module';
 import { SwaggerAPIModule } from './swagger';
 import {ReportsModule} from './reports/reports.module';
 import {LocalizationService} from './core/services/localization.service';
+import {AceEditorModule} from 'ng2-ace-editor';
 
 LocalizationService.registerCulture(window.navigator.language);
 
@@ -66,7 +67,8 @@ LocalizationService.registerCulture(window.navigator.language);
     RouterModule,
     AppRoutingModule,
     CoreModule.forRoot(),
-    ToastrModule.forRoot({ timeOut: 10000 })
+    ToastrModule.forRoot({ timeOut: 10000 }),
+    AceEditorModule
   ],
   providers: [{
     provide: LocationStrategy,
diff --git a/services/self-service/src/main/resources/webapp/src/app/app.routing.module.ts b/services/self-service/src/main/resources/webapp/src/app/app.routing.module.ts
index 35c9df7..fe28bf8 100644
--- a/services/self-service/src/main/resources/webapp/src/app/app.routing.module.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/app.routing.module.ts
@@ -34,6 +34,7 @@ import { RolesComponent } from './administration/roles/roles.component';
 import { SwaggerComponent } from './swagger/swagger.component';
 import { AuthorizationGuard, CheckParamsGuard, CloudProviderGuard, AdminGuard, AuditGuard } from './core/services';
 import {AuditComponent} from './reports/audit/audit.component';
+import {ConfigurationComponent} from './administration/configuration/configuration.component';
 
 const routes: Routes = [{
   path: 'login',
@@ -68,6 +69,11 @@ const routes: Routes = [{
       component: ManagementComponent,
       canActivate: [AuthorizationGuard, AdminGuard]
     }, {
+      path: 'configuration',
+      component: ConfigurationComponent,
+      canActivate: [AuthorizationGuard, AdminGuard]
+    },
+    {
       path: 'swagger',
       component: SwaggerComponent,
       canActivate: [AuthorizationGuard]
diff --git a/services/self-service/src/main/resources/webapp/src/app/core/core.module.ts b/services/self-service/src/main/resources/webapp/src/app/core/core.module.ts
index 4b1c0f9..9b97b1f 100644
--- a/services/self-service/src/main/resources/webapp/src/app/core/core.module.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/core/core.module.ts
@@ -49,6 +49,7 @@ import { ErrorInterceptor } from './interceptors/error.interceptor';
 
 import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
 import {AuditGuard} from './services';
+import {ConfigurationService} from './services/configutration.service';
 
 @NgModule({
   imports: [CommonModule],
@@ -85,7 +86,7 @@ export class CoreModule {
         ProjectService,
         EndpointService,
         UserAccessKeyService,
-
+        ConfigurationService,
         { provide: MatDialogRef, useValue: {} },
         { provide: MAT_DIALOG_DATA, useValue: [] },
         {
diff --git a/services/self-service/src/main/resources/webapp/src/app/core/services/configutration.service.ts b/services/self-service/src/main/resources/webapp/src/app/core/services/configutration.service.ts
new file mode 100644
index 0000000..8cc8406
--- /dev/null
+++ b/services/self-service/src/main/resources/webapp/src/app/core/services/configutration.service.ts
@@ -0,0 +1,222 @@
+/*
+ * 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 { Injectable } from '@angular/core';
+import {Observable, of} from 'rxjs';
+import { map, catchError } from 'rxjs/operators';
+
+import { ApplicationServiceFacade } from './applicationServiceFacade.service';
+import { ErrorUtils } from '../util';
+
+@Injectable()
+export class ConfigurationService {
+  constructor(private applicationServiceFacade: ApplicationServiceFacade) { }
+
+  public getSelvServiceSettings(): Observable<{}> {
+    return of(`# *****************************************************************************
+    #
+    #  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.
+      #
+    # ******************************************************************************
+
+    <#include "/infrastructure-provisioning/src/ssn/templates/ssn.yml">
+
+    # Minimum and maximum number of slave EMR instances than could be created
+    minEmrInstanceCount: 2
+    maxEmrInstanceCount: 14
+    # Minimum and maximum percentage cost for slave EMR spot instances biding
+    minEmrSpotInstanceBidPct: 20
+    maxEmrSpotInstanceBidPct: 90
+
+    # Maximum length for gcp user name (due to gcp restrictions)
+    maxUserNameLength: 10
+    # Minimum and maximum number of slave Dataproc instances that could be created
+    minInstanceCount: 3
+    maxInstanceCount: 15
+    minDataprocPreemptibleCount: 0
+    gcpOuauth2AuthenticationEnabled: false
+
+    # Boundaries for Spark cluster creation
+    minSparkInstanceCount: 2
+    maxSparkInstanceCount: 14
+
+    # Timeout for check the status of environment via provisioning service
+    checkEnvStatusTimeout: 5m
+
+    # Restrict access to DataLab features using roles policy
+    rolePolicyEnabled: true
+    # Default access to DataLab features using roles policy
+    roleDefaultAccess: false
+
+    # Set to true to enable the scheduler of billing report.
+      billingSchedulerEnabled: true
+    billingPort: 8088
+    # Set to true to enable audit
+    auditEnabled: true
+    # Name of configuration file for billing report.
+    <#if DEV_MODE == "true">
+    billingConfFile: \${sys['user.dir']}/../billing/billing.yml
+    <#else>
+    billingConfFile: \${DATALAB_CONF_DIR}/billing.yml
+    </#if>
+
+    ssnInstanceSize: <SSN_INSTANCE_SIZE>
+
+      serviceBaseName: SERVICE_BASE_NAME
+    os: OPERATION_SYSTEM
+    server:
+      requestLog:
+        appenders:
+          - type: file
+    currentLogFilename: \${LOG_ROOT_DIR}/ssn/request-selfservice.log
+    archive: true
+    archivedLogFilenamePattern: \${LOG_ROOT_DIR}/ssn/request-selfservice-%d{yyyy-MM-dd}.log.gz
+    archivedFileCount: 10
+    rootPath: "/api"
+    applicationConnectors:
+      #    - type: http
+    #      port: 8080
+    - type: https
+    port: 8443
+    certAlias: ssn
+    validateCerts: false
+    keyStorePath: \${KEY_STORE_PATH}
+      keyStorePassword: \${KEY_STORE_PASSWORD}
+        trustStorePath: \${TRUST_STORE_PATH}
+          trustStorePassword: \${TRUST_STORE_PASSWORD}
+            adminConnectors:
+              #    - type: http
+    #      port: 8081
+    - type: https
+    port: 8444
+    certAlias: ssn
+    validateCerts: false
+    keyStorePath: \${KEY_STORE_PATH}
+      keyStorePassword: \${KEY_STORE_PASSWORD}
+        trustStorePath: \${TRUST_STORE_PATH}
+          trustStorePassword: \${TRUST_STORE_PASSWORD}
+
+            mongoMigrationEnabled: false
+
+    logging:
+      level: INFO
+    loggers:
+      com.epam: INFO
+    org.apache.guacamole: DEBUG
+    com.novemberain: ERROR
+    appenders:
+      <#if DEV_MODE == "true">
+    - type: console
+    </#if>
+    - type: file
+    currentLogFilename: \${LOG_ROOT_DIR}/ssn/selfservice.log
+    archive: true
+    archivedLogFilenamePattern: \${LOG_ROOT_DIR}/ssn/selfservice-%d{yyyy-MM-dd}.log.gz
+    archivedFileCount: 10
+
+    mavenSearchService:
+      protocol: http
+    host: search.maven.org
+    port: 80
+    jerseyClient:
+      timeout: 5s
+    connectionTimeout: 5s
+
+    schedulers:
+      inactivity:
+        enabled: false
+    cron: "0 0 0/2 ? * * *"
+    checkInfrastructureStatusScheduler:
+      enabled: true
+    cron: "0 0/15 * ? * *"
+    startComputationalScheduler:
+      enabled: true
+    cron: "*/20 * * ? * * *"
+    stopComputationalScheduler:
+      enabled: true
+    cron: "*/20 * * ? * * *"
+    startExploratoryScheduler:
+      enabled: true
+    cron: "*/20 * * ? * * *"
+    stopExploratoryScheduler:
+      enabled: true
+    cron: "*/20 * * ? * * *"
+    terminateComputationalScheduler:
+      enabled: true
+    cron: "*/20 * * ? * * *"
+    checkQuoteScheduler:
+      enabled: true
+    cron: "0 2/15 * ? * *"
+    checkUserQuoteScheduler:
+      enabled: false
+    cron: "0 0 * ? * * *"
+    checkProjectQuoteScheduler:
+      enabled: true
+    cron: "0 4/15 * ? * *"
+    checkEndpointStatusScheduler:
+      enabled: true
+    cron: "0 6/15 * ? * *"
+    billingScheduler:
+      enabled: true
+    cron: "0 0/15 * ? * *"
+
+
+    guacamole:
+      connectionProtocol: ssh
+    serverPort: 4822
+    port: 22
+    username: datalab-user
+
+    keycloakConfiguration:
+      redirectUri: http://localhost:4200/
+        realm: DLAB_bhliva
+    bearer-only: true
+    auth-server-url: http://52.11.45.11:8080/auth
+      ssl-required: none
+    register-node-at-startup: true
+    register-node-period: 600
+    resource: sss
+    credentials:
+      secret: cf5a484b-039b-4161-8707-ad65c0f25962
+
+    jerseyClient:
+      minThreads: 1
+    maxThreads: 128
+    workQueueSize: 8
+    gzipEnabled: true
+    gzipEnabledForRequests: false
+    chunkedEncodingEnabled: true
+    `)
+  }
+}
diff --git a/services/self-service/src/main/resources/webapp/src/app/shared/form-controls/multi-level-select-dropdown/multi-level-select-dropdown.component.scss b/services/self-service/src/main/resources/webapp/src/app/shared/form-controls/multi-level-select-dropdown/multi-level-select-dropdown.component.scss
index aab2b07..27e1e90 100644
--- a/services/self-service/src/main/resources/webapp/src/app/shared/form-controls/multi-level-select-dropdown/multi-level-select-dropdown.component.scss
+++ b/services/self-service/src/main/resources/webapp/src/app/shared/form-controls/multi-level-select-dropdown/multi-level-select-dropdown.component.scss
@@ -120,9 +120,11 @@
       padding: 0;
       margin: 0;
     }
+
     .role-item{
       padding-left: 30px;
     }
+
     .role-cloud-item{
       padding-left: 60px;
     }
diff --git a/services/self-service/src/main/resources/webapp/src/app/shared/navbar/navbar.component.html b/services/self-service/src/main/resources/webapp/src/app/shared/navbar/navbar.component.html
index 9e73f34..b662258 100644
--- a/services/self-service/src/main/resources/webapp/src/app/shared/navbar/navbar.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/shared/navbar/navbar.component.html
@@ -94,6 +94,12 @@
               <span *ngIf="isExpanded; else env">Environment Management</span>
               <ng-template #env><i class="material-icons">settings</i></ng-template>
             </a>
+            <a class="sub-nav-item" [style.margin-left.px]="isExpanded ? '30' : '0'"
+               [routerLink]="['/configuration']" [routerLinkActive]="['active']"
+               [routerLinkActiveOptions]="{exact:true}">
+              <span *ngIf="isExpanded; else env">Configuration</span>
+              <ng-template #env><i class="material-icons">settings</i></ng-template>
+            </a>
           </a>
           <a class="nav-item has-children" *ngIf="healthStatus?.billingEnabled || healthStatus?.auditEnabled">
             <span *ngIf="isExpanded">Reports</span>
diff --git a/services/self-service/src/main/resources/webapp/src/assets/styles/_general.scss b/services/self-service/src/main/resources/webapp/src/assets/styles/_general.scss
index 9234c6a..e27d33f 100644
--- a/services/self-service/src/main/resources/webapp/src/assets/styles/_general.scss
+++ b/services/self-service/src/main/resources/webapp/src/assets/styles/_general.scss
@@ -39,6 +39,7 @@ body.modal-open {
 .pr-3{padding-right: 3px}
 
 .pb-50 {padding-bottom: 50px;}
+.pb-25 {padding-bottom: 25px;}
 .pb-10 {padding-bottom: 10px;}
 
 .txt-r {text-align: right }
diff --git a/services/self-service/src/main/resources/webapp/src/assets/styles/_theme.scss b/services/self-service/src/main/resources/webapp/src/assets/styles/_theme.scss
index ec8fee0..6f9086c 100644
--- a/services/self-service/src/main/resources/webapp/src/assets/styles/_theme.scss
+++ b/services/self-service/src/main/resources/webapp/src/assets/styles/_theme.scss
@@ -1021,6 +1021,28 @@ mat-progress-bar {
     }
   }
 }
+.configuration-wrapper{
+  box-shadow: 0px 3px 5px -1px rgba(0, 0, 0, 0.2), 0px 6px 10px 0px rgba(0, 0, 0, 0.14), 0px 1px 18px 0px rgba(0, 0, 0, 0.12);
+  .mat-tab-header{
+    margin: 0 30px;
+  }
+  .mat-tab-label{
+    .mat-tab-label-content{
+      font-family: "Open Sans", sans-serif;
+      font-weight: 600;
+      font-size: 13px;
+    }
+  }
+
+  .ace-monokai{
+    height: calc(100%);
+  }
+
+  .ace_scrollbar{
+
+  }
+}
+
 
 
 
diff --git a/services/self-service/src/main/resources/webapp/src/styles.scss b/services/self-service/src/main/resources/webapp/src/styles.scss
index c09ccd9..3c5d948 100644
--- a/services/self-service/src/main/resources/webapp/src/styles.scss
+++ b/services/self-service/src/main/resources/webapp/src/styles.scss
@@ -382,12 +382,13 @@ input[type='number'] {
     text-align: center;
   }
 }
-#scrolling, .scrolling{
+#scrolling, .scrolling, ace_scrollbar{
   scrollbar-width: thin;
 }
 
 #scrolling::-webkit-scrollbar,
 .scrolling::-webkit-scrollbar,
+.ace_scrollbar::-webkit-scrollbar,
 .list-selected mat-chip-list .mat-chip-list-wrapper::-webkit-scrollbar {
   width: 5px;
   height: 5px;
@@ -395,6 +396,7 @@ input[type='number'] {
 
 #scrolling::-webkit-scrollbar-track,
 .scrolling::-webkit-scrollbar-track,
+.ace_scrollbar::-webkit-scrollbar-track,
 .list-selected mat-chip-list .mat-chip-list-wrapper::-webkit-scrollbar-track {
   box-shadow: none;
   -webkit-box-shadow: none;
@@ -403,6 +405,7 @@ input[type='number'] {
 
 #scrolling::-webkit-scrollbar-thumb,
 .scrolling::-webkit-scrollbar-thumb,
+.ace_scrollbar::-webkit-scrollbar-thumb,
 .list-selected mat-chip-list .mat-chip-list-wrapper::-webkit-scrollbar-thumb {
   background-color: #f6fafe;
   background-color: rgba(0, 0, 0, 0.4);


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


[incubator-datalab] 02/02: [DATALAB-2157]: Update main block on administrative page

Posted by dg...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

dgnatyshyn pushed a commit to branch DATALAB-2156
in repository https://gitbox.apache.org/repos/asf/incubator-datalab.git

commit 913014b8cc28054f8b9d192ae384d1c99fad83d6
Author: Dmytro_Gnatyshyn <di...@ukr.net>
AuthorDate: Thu Nov 19 15:06:38 2020 +0200

    [DATALAB-2157]: Update main block on administrative page
---
 .../configuration/configuration.component.html     | 31 ++++++----------------
 .../configuration/configuration.component.scss     |  5 ++++
 .../configuration/configuration.component.ts       | 13 +++++----
 3 files changed, 19 insertions(+), 30 deletions(-)

diff --git a/services/self-service/src/main/resources/webapp/src/app/administration/configuration/configuration.component.html b/services/self-service/src/main/resources/webapp/src/app/administration/configuration/configuration.component.html
index 8877a6c..f5c19bb 100644
--- a/services/self-service/src/main/resources/webapp/src/app/administration/configuration/configuration.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/administration/configuration/configuration.component.html
@@ -47,8 +47,7 @@
                [disabled]="!(provisioningSource === serverConfigs.provisioningSource
                && serverConfigs.selvServiceSource === selvServiceSource
                && serverConfigs.billingSource === billingSource
-               ) && activeTab !== 0
-"
+               ) && activeTab !== 0"
       >
         <h4>Main settings</h4>
         <div class="main-wrapper">
@@ -56,28 +55,14 @@
             <p class="section-title">Restart services</p>
             <div class="section-content">
               <ul class="list-menu selection-list">
-                <li>
-                  <p class="list-item" role="menuitem">
-                    <span class="empty-checkbox" [ngClass]="{'checked': true}" (click)="toggleSetings($event);$event.stopPropagation()" >
-                    <span class="checked-checkbox" *ngIf="true"></span>
-                  </span>
-                    Provisioning
-                  </p>
-                </li>
-                <li>
-                  <p class="list-item" role="menuitem">
-                    <span class="empty-checkbox" [ngClass]="{'checked': true}" (click)="toggleSetings($event);$event.stopPropagation()" >
-                    <span class="checked-checkbox" *ngIf="true"></span>
-                  </span>
-                    Selv service
-                  </p>
-                </li>
-                <li>
+                <li *ngFor="let service of services">
                   <p class="list-item" role="menuitem">
-                    <span class="empty-checkbox" [ngClass]="{'checked': true}" (click)="toggleSetings($event);$event.stopPropagation()" >
-                    <span class="checked-checkbox" *ngIf="true"></span>
-                  </span>
-                    Billing
+                    <span (click)="toggleSetings(service);$event.stopPropagation()" class="d-flex">
+                      <span class="empty-checkbox" [ngClass]="{'checked': service.selected}">
+                        <span class="checked-checkbox" *ngIf="service.selected"></span>
+                      </span>
+                      {{service.label}}
+                    </span>
                   </p>
                 </li>
               </ul>
diff --git a/services/self-service/src/main/resources/webapp/src/app/administration/configuration/configuration.component.scss b/services/self-service/src/main/resources/webapp/src/app/administration/configuration/configuration.component.scss
index a6051b1..40f533a 100644
--- a/services/self-service/src/main/resources/webapp/src/app/administration/configuration/configuration.component.scss
+++ b/services/self-service/src/main/resources/webapp/src/app/administration/configuration/configuration.component.scss
@@ -67,9 +67,14 @@
             padding: 5px 10px;
             display: flex;
 
+            span{
+              cursor: pointer;
+            }
+
             .empty-checkbox{
               display: block;
               margin-right: 5px;
+              margin-top: 0;
             }
           }
         }
diff --git a/services/self-service/src/main/resources/webapp/src/app/administration/configuration/configuration.component.ts b/services/self-service/src/main/resources/webapp/src/app/administration/configuration/configuration.component.ts
index 8d9830c..0d02230 100644
--- a/services/self-service/src/main/resources/webapp/src/app/administration/configuration/configuration.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/administration/configuration/configuration.component.ts
@@ -51,10 +51,10 @@ export class ConfigurationComponent implements OnInit {
     provisioningSource: {},
     billingSource: {},
   };
-  services: [
-    {label: 'Self service'},
-    {label: 'Provisioning'},
-    {label: 'Billing'},
+  public services = [
+    {label: 'Self service', selected: false},
+    {label: 'Provisioning', selected: false},
+    {label: 'Billing', selected: false},
   ];
 
   private confirmMessages = {
@@ -111,7 +111,6 @@ export class ConfigurationComponent implements OnInit {
 
   getSettings() {
     this.configurationService.getSelvServiceSettings().subscribe(v => {
-      console.log(v);
       this.serverConfigs.billingSource = v;
       this.serverConfigs.selvServiceSource = v;
       this.serverConfigs.provisioningSource = v;
@@ -138,8 +137,8 @@ export class ConfigurationComponent implements OnInit {
     }
   }
 
-  toggleSetings($event: MouseEvent) {
-
+  toggleSetings(service) {
+      service.selected = !service.selected
   }
 
   restartServices() {


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