To apply the shared module into the database page

Issue-ID: DCAEGEN2-1716
Signed-off-by: Ekko Chang <ekko.chang@qct.io>
Change-Id: I2b89fe4fb81be10852c0fc813bbf5c81999bbc12
diff --git a/components/datalake-handler/admin/src/src/app/app.module.ts b/components/datalake-handler/admin/src/src/app/app.module.ts
index e15876a..eb7db26 100644
--- a/components/datalake-handler/admin/src/src/app/app.module.ts
+++ b/components/datalake-handler/admin/src/src/app/app.module.ts
@@ -105,7 +105,8 @@
 import { MatTabsModule } from "@angular/material";
 import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
 import { TopicModalComponent } from "./views/topics/topic-list/topic-modal/topic-modal.component";
-import { KafkaModalComponent } from './views/kafka/kafka-list/kafka-modal/kafka-modal.component';
+import { KafkaModalComponent } from "./views/kafka/kafka-list/kafka-modal/kafka-modal.component";
+import { DbModalComponent } from "./views/database/database-list/db-modal/db-modal.component";
 
 @NgModule({
   declarations: [
@@ -153,7 +154,8 @@
     ToolAddModalComponent,
     IconComponent,
     TopicModalComponent,
-    KafkaModalComponent
+    KafkaModalComponent,
+    DbModalComponent
   ],
   imports: [
     BrowserModule,
@@ -198,7 +200,8 @@
     ToolAddModalComponent,
     ModalToolsComponent,
     TopicModalComponent,
-    KafkaModalComponent
+    KafkaModalComponent,
+    DbModalComponent
   ]
 })
 export class AppModule {}
diff --git a/components/datalake-handler/admin/src/src/app/core/models/db.model.ts b/components/datalake-handler/admin/src/src/app/core/models/db.model.ts
index 3de8f21..eea91ad 100644
--- a/components/datalake-handler/admin/src/src/app/core/models/db.model.ts
+++ b/components/datalake-handler/admin/src/src/app/core/models/db.model.ts
@@ -25,16 +25,23 @@
  */
 
 export class Db {
-  id: number;
-  name: string;
-  enabled: boolean;
-  host: string;
-  port: number;
-  database: string;
-  encrypt: boolean;
-  login: string;
-  pass: string;
-  dbTypeId: string;
+  public id: number;
+  public name: string;
+  public enabled: boolean;
+  public host: string;
+  public port: number;
+  public database: string;
+  public encrypt: boolean;
+  public login: string;
+  public pass: string;
+  public dbTypeId: string;
   // for UI display
-  checkedToSave: boolean;
+  public checkedToSave: boolean;
+}
+
+export class DbType {
+  public id: string;
+  public name: string;
+  public defaultPort: number;
+  public tool: boolean;
 }
diff --git a/components/datalake-handler/admin/src/src/app/core/services/rest-api.service.ts b/components/datalake-handler/admin/src/src/app/core/services/rest-api.service.ts
index 83d814e..97421e4 100644
--- a/components/datalake-handler/admin/src/src/app/core/services/rest-api.service.ts
+++ b/components/datalake-handler/admin/src/src/app/core/services/rest-api.service.ts
@@ -32,7 +32,7 @@
 import { throwError } from "rxjs";
 
 import { Topic } from "src/app/core/models/topic.model";
-import { Db } from "src/app/core/models/db.model";
+import { Db, DbType } from "src/app/core/models/db.model";
 import { Template } from "src/app/core/models/template.model";
 import { Dashboard } from "src/app/core/models/dashboard.model";
 import { Kafka } from "../models/kafka.model";
@@ -150,6 +150,37 @@
       .pipe(retry(1), catchError(this.handleError));
   }
 
+  public getDbTypes(): Observable<DbType[]> {
+    return this.http
+      .get<DbType[]>(prefix + "dbs/dbtypes")
+      .pipe(retry(1), catchError(this.handleError));
+  }
+
+  public deleteDb(id: string | number): Observable<Db> {
+    return this.http.delete<Db>(prefix + "dbs/" + id).pipe(
+      //online
+      retry(1),
+      tap(_ => console.log(`deleted db id=${id}`)),
+      catchError(this.handleError)
+    );
+  }
+
+  public updateDb(db: Db): Observable<Db> {
+    return this.http.put<Db>(prefix + "dbs/" + db.id, db).pipe(
+      retry(1),
+      tap(_ => this.extractData),
+      catchError(this.handleError)
+    );
+  }
+
+  public addDb(db: Db): Observable<Db> {
+    return this.http.post<Db>(prefix + "dbs", db).pipe(
+      retry(1),
+      tap(_ => console.log(`add db name=${db.name}`)),
+      catchError(this.handleError)
+    );
+  }
+
   getDbEncryptList(flag): Observable<any> {
     return this.http
       .get(prefix + "dbs/list?isDb=" + flag)
@@ -168,23 +199,6 @@
       .pipe(retry(1), map(this.extractData), catchError(this.handleError));
   }
 
-  deleteDb(id): Observable<any> {
-    return this.http.delete(prefix + "dbs/" + id).pipe(
-      //online
-      retry(1),
-      map(this.extractData2),
-      catchError(this.handleError)
-    );
-  }
-
-  updateDb(d: Db): Observable<any> {
-    return this.http.put(prefix + "dbs", d).pipe(
-      retry(1),
-      tap(_ => this.extractData),
-      catchError(this.handleError)
-    );
-  }
-
   createDb(d: Db): Observable<any> {
     return this.http.post(prefix + "dbs", d).pipe(
       retry(1),
diff --git a/components/datalake-handler/admin/src/src/app/views/database/database-list/database-list.component.html b/components/datalake-handler/admin/src/src/app/views/database/database-list/database-list.component.html
index db75f71..9df9e56 100644
--- a/components/datalake-handler/admin/src/src/app/views/database/database-list/database-list.component.html
+++ b/components/datalake-handler/admin/src/src/app/views/database/database-list/database-list.component.html
@@ -1,5 +1,5 @@
 <!--
-    Copyright (C) 2019 CMCC, Inc. and others. All rights reserved.
+    Copyright (C) 2019 - 2020 CMCC, Inc. and others. All rights reserved.
 
     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -13,6 +13,7 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 -->
+
 <div class="topic-list-panel">
   <div class="row">
     <div class="col-md-12">
@@ -21,69 +22,22 @@
         <div class="p-1">
           <div class="input-group">
             <input #searchText type="text" class="form-control dl-input-text-search" placeholder="Search..."
-                   (keyup)="this.updateFilter($event.target.value)" />
-            <div class="input-group-append">
-              <button type="button" class="btn dl-btn-dark">
-                <i class="fa fa-search"></i>
-              </button>
-            </div>
+              (keyup)="this.updateFilter($event.target.value)" />
           </div>
         </div>
-
         <!-- button -->
         <div class="p-1">
-          <app-button [text]="'plus'" [style]="'inlineicon'" [color]="'dark'" (click)="newDbModal()"></app-button>
+          <app-button [text]="'plus'" [style]="'inlineicon'" [color]="'dark'" (click)="openModal('new')">
+          </app-button>
         </div>
       </div>
     </div>
   </div>
+
   <!-- datatable -->
   <div class="row">
     <div class="col-md-12">
-      <ngx-datatable #mytemlate class="bootstrap" [rows]="dbList" [columnMode]="'force'" [headerHeight]="40"
-                     [footerHeight]="40" [rowHeight]="50" [scrollbarV]="true" [scrollbarH]="true"
-                     [loadingIndicator]="loadingIndicator" [messages]="mesgNoData" [limit]="10" (activate)="onActivate($event)">
-        <ngx-datatable-column [width]="100" name="{{ 'STATUS' | translate }}" prop="enabled"
-                              headerClass="d-flex justify-content-center" cellClass="d-flex justify-content-center">
-          <ng-template let-row="row" ngx-datatable-cell-template>
-            <span *ngIf="row.enabled">
-              <i class="fas fa-circle dl-icon-enable fa-xs" aria-hidden="true"></i>
-            </span>
-            <span *ngIf="!row.enabled">
-              <i class="fas fa-circle dl-icon-disable fa-xs" aria-hidden="true"></i>
-            </span>
-          </ng-template>
-        </ngx-datatable-column>
-
-        <ngx-datatable-column name="{{ 'TEMPLATE_NAME' | translate }}" prop="name"
-                              headerClass="d-flex justify-content-center" cellClass="d-flex justify-content-center">
-          <ng-template let-row="row" ngx-datatable-cell-template>
-            <span>{{ row.name }}</span>
-          </ng-template>
-        </ngx-datatable-column>
-
-        <ngx-datatable-column name="{{ 'DB_TYPE' | translate }}" prop="topic">
-          <ng-template let-row="row" ngx-datatable-cell-template>
-            <span>{{ row.dbTypeId }}</span>
-          </ng-template>
-        </ngx-datatable-column>
-
-        <ngx-datatable-column name="" sortable="false" cellClass="d-flex justify-content-center">
-          <ng-template let-row="row" ngx-datatable-cell-template>
-            <span>
-              <button class="btn action-icon-setting" (click)="this.deleteDbModel(row.id);">
-                <i class="fas fa-trash-alt fa-xs"></i>
-              </button>
-            </span>
-            <span>
-              <button class="btn action-icon-setting" (click)="this.updateDbModel(row.id, row.dbTypeId);">
-                <i class="fas fa-cog fa-xs"></i>
-              </button>
-            </span>
-          </ng-template>
-        </ngx-datatable-column>
-
-      </ngx-datatable>
+      <app-table [data]="dbs" [columns]="columns" (btnTableAction)="btnTableAction($event)"></app-table>
     </div>
   </div>
 </div>
diff --git a/components/datalake-handler/admin/src/src/app/views/database/database-list/database-list.component.ts b/components/datalake-handler/admin/src/src/app/views/database/database-list/database-list.component.ts
index ed25a70..2eb41a8 100644
--- a/components/datalake-handler/admin/src/src/app/views/database/database-list/database-list.component.ts
+++ b/components/datalake-handler/admin/src/src/app/views/database/database-list/database-list.component.ts
@@ -2,7 +2,7 @@
  * ============LICENSE_START=======================================================
  * ONAP : DataLake
  * ================================================================================
- * Copyright 2019 QCT
+ * Copyright 2019 - 2020 QCT
  *=================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -29,24 +29,22 @@
 import { Component, OnInit, ViewChild, ElementRef } from "@angular/core";
 import { Db } from "src/app/core/models/db.model";
 import { NgbModal } from "@ng-bootstrap/ng-bootstrap";
-import { DatabaseAddModalComponent } from "src/app/views/database/database-list/database-add-modal/database-add-modal.component";
 
-// DB modal components
 import { RestApiService } from "src/app/core/services/rest-api.service";
 
 // Modal
 import { AlertComponent } from "src/app/shared/components/alert/alert.component";
+import { ModalComponent } from "src/app/shared/modules/modal/modal.component";
+import { ModalContentData } from "src/app/shared/modules/modal/modal.data";
+import { DbModalComponent } from "src/app/views/database/database-list/db-modal/db-modal.component";
 
 // Notify
 import { ToastrNotificationService } from "src/app/shared/components/toastr-notification/toastr-notification.service";
 
 // Loading spinner
 import { NgxSpinnerService } from "ngx-spinner";
-import {CouchbaseComponent} from "src/app/views/database/database-list/dbs-modal/couchbase/couchbase.component";
-import {DruidComponent} from "src/app/views/database/database-list/dbs-modal/druid/druid.component";
-import {ElasticsearchComponent} from "src/app/views/database/database-list/dbs-modal/elasticsearch/elasticsearch.component";
-import {MongodbComponent} from "src/app/views/database/database-list/dbs-modal/mongodb/mongodb.component";
-import {HdfsComponent} from "src/app/views/database/database-list/dbs-modal/hdfs/hdfs.component";
+import { map, mergeMap } from "rxjs/operators";
+import { forkJoin, from } from "rxjs";
 
 @Component({
   selector: "app-database-list",
@@ -54,230 +52,192 @@
   styleUrls: ["./database-list.component.css"]
 })
 export class DatabaseListComponent implements OnInit {
-  pageFinished: Boolean = false;
-
-  dbList: any = [];
-  dbs: Db[] = [];
-  dbNew: Db;
-  db_NewBody: Db;
-  loading: Boolean = true;
-  flag: Boolean = true;
-  loadingIndicator: boolean = true;
-
-  mesgNoData = {
-    emptyMessage: `
-      <div class="d-flex justify-content-center">
-        <div class="p-2">
-          <label class="dl-nodata">No Data</label>
-        </div>
-      </div>
-    `
-  };
+  dbs: Array<Db> = []; // data of table
+  t_temp: Array<Db> = []; // cache for dbs
+  columns: Array<any> = []; // column of table
 
   @ViewChild("searchText") searchText: ElementRef;
 
   constructor(
-      private dbApiService: RestApiService,
-      private notificationService: ToastrNotificationService,
-      private modalService: NgbModal,
-      private spinner: NgxSpinnerService
-  ) {
-    this.initData().then(data => {
-      this.initDbsList(this.dbList).then(data => {
-        this.dbs = data;
-      });
-    });
-  }
+    private restApiService: RestApiService,
+    private notificationService: ToastrNotificationService,
+    private modalService: NgbModal,
+    private spinner: NgxSpinnerService
+  ) {}
 
   ngOnInit() {
     this.spinner.show();
-  }
 
-  async initData() {
-      this.dbList = [];
-      this.dbList = await this.getDbList(this.flag);
+    let t_dbs: Array<Db> = [];
+
+    const get_dbs = this.restApiService.getAllDbs().pipe(
+      mergeMap(dbs => from(dbs)),
+      map(db => {
+        t_dbs.push(db);
+      })
+    );
+
+    forkJoin(get_dbs).subscribe(data => {
+      this.columns = this.initColumn();
+      this.dbs = t_dbs;
+      this.t_temp = [...this.dbs];
+      this.updateFilter(this.searchText.nativeElement.value);
       setTimeout(() => {
-          this.spinner.hide();
+        this.spinner.hide();
       }, 500);
-  }
-
-  getDbList(flag) {
-    return this.dbApiService.getDbEncryptList(flag).toPromise();
-
-  }
-
-  async initDbsList(dbList: []) {
-    var d: Db[] = [];
-
-    for (var i = 0; i < dbList.length; i++) {
-      let data = dbList[i];
-      let feed = {
-        id: data["id"],
-        name: data["name"],
-        enabled: data["enabled"],
-        host: data["host"],
-        port: data["port"],
-        database: data["database"],
-        encrypt: data["encrypt"],
-        login: data["login"],
-        pass: data["pass"],
-        dbTypeId: data["dbTypeId"],
-      };
-      d.push(feed);
-    }
-    return d;
-  }
-
-  // getDbDetail(name: string) {
-  //   return this.restApiService.getDbDetail(name).toPromise();
-  // }
-
-  openAddModal() {
-    const modalRef = this.modalService.open(DatabaseAddModalComponent, {
-      windowClass: "dl-md-modal",
-      centered: true
-    });
-
-    modalRef.componentInstance.passEntry.subscribe(receivedEntry => {
-      if (receivedEntry) {
-        modalRef.close();
-        //this.openDetailModal(receivedEntry);
-      }
     });
   }
 
-  updateFilter(searchValue) {
+  updateFilter(searchValue: string) {
     const val = searchValue.toLowerCase();
+
     // filter our data
-    const temps = this.dbList.filter(function (d) {
-      return d.name.toLowerCase().indexOf(val) != -1 || !val;
+    const temp = this.t_temp.filter(t => {
+      return t.name.toLowerCase().indexOf(val) !== -1 || !val;
     });
+
     // update the rows
-    this.dbList = temps;
+    this.dbs = temp;
   }
 
-  newDbModal() {
-    const modalRef = this.modalService.open(DatabaseAddModalComponent, {
-      windowClass: "dl-md-modal dbs",
-      centered: true
-    });
+  initColumn() {
+    let t_columns: Array<any> = [];
+
+    t_columns = [
+      {
+        headerName: "STATUS",
+        width: "15",
+        sortable: true,
+        dataIndex: "enabled",
+        icon: "status"
+      },
+      {
+        headerName: "NAME",
+        width: "420",
+        sortable: true,
+        dataIndex: "name"
+      },
+      {
+        headerName: "Type",
+        width: "50",
+        sortable: true,
+        dataIndex: "dbTypeId"
+      },
+      {
+        headerName: "Host",
+        width: "100",
+        sortable: true,
+        dataIndex: "host"
+      },
+      {
+        width: "2",
+        iconButton: "cog",
+        action: "edit"
+      },
+      {
+        width: "2",
+        iconButton: "trash",
+        action: "delete"
+      }
+    ];
+
+    return t_columns;
   }
 
-  deleteDbModel(id: number) {
+  btnTableAction(passValueArr: Array<any>) {
+    let action = passValueArr[0];
+    let id = passValueArr[1];
 
-    console.log("delete id", id);
-    const index = this.dbList.findIndex(t => t.id === id);
-    const modalRef = this.modalService.open(AlertComponent, {
-      size: "sm",
-      centered: true
-    });
-    modalRef.componentInstance.message = "ARE_YOU_SURE_DELETE";
-    modalRef.componentInstance.passEntry.subscribe(receivedEntry => {
-      // Delete db
-      this.dbApiService.deleteDb(id).subscribe(
-        res => {
-          console.log(res);
-          if (JSON.stringify(res).length <= 2) {
-            this.dbList.splice(index, 1);
-            this.dbList = [...this.dbList];
-            this.initData();
-            this.notificationService.success("SUCCESSFULLY_DELETED");
-
-          } else {
-            this.initData();
-            this.notificationService.error("FAILED_DELETED");
-          }
-
+    switch (action) {
+      case "edit":
+        this.openModal("edit", id);
+        break;
+      case "delete":
+        const modalRef = this.modalService.open(AlertComponent, {
+          size: "sm",
+          centered: true,
+          backdrop: "static"
+        });
+        modalRef.componentInstance.message = "ARE_YOU_SURE_DELETE";
+        modalRef.componentInstance.passEntry.subscribe(recevicedEntry => {
+          this.restApiService.deleteDb(id).subscribe(
+            res => {
+              this.ngOnInit();
+              setTimeout(() => {
+                this.notificationService.success("SUCCESSFULLY_DELETED");
+              }, 500);
+            },
+            err => {
+              this.notificationService.error(err);
+            }
+          );
           modalRef.close();
-        },
-        err => {
-          this.notificationService.error(err);
-          modalRef.close();
-        }
-      );
-    });
-  }
-
-  updateDbModel(id: number, dbType: string) {
-    var modalRef;
-    console.log(dbType, "dbType");
-    switch (dbType) {
-      case "CB": {
-        modalRef = this.modalService.open(CouchbaseComponent, {
-          size: "lg",
-          centered: true
         });
-        this.editDbModal(id, modalRef);
         break;
-      }
-      case "DRUID": {
-        modalRef = this.modalService.open(DruidComponent, {
-          size: "lg",
-          centered: true
-        });
-        this.editDbModal(id, modalRef);
-        break;
-      }
-      case "ES": {
-        modalRef = this.modalService.open(ElasticsearchComponent, {
-          size: "lg",
-          centered: true
-        });
-        this.editDbModal(id, modalRef);
-        break;
-      }
-      case "MONGO": {
-        modalRef = this.modalService.open(MongodbComponent, {
-          size: "lg",
-          centered: true
-        });
-        this.editDbModal(id, modalRef);
-        break;
-      }
-      case "HDFS": {
-        modalRef = this.modalService.open(HdfsComponent, {
-          size: "lg",
-          centered: true
-        });
-        this.editDbModal(id, modalRef);
-        break;
-      }
-      default: {
-        break;
-      }
     }
   }
 
-  editDbModal(id: number, modalRef) {
-    console.log("id", id);
-    const index = this.dbList.findIndex(t => t.id === id);
-    modalRef.componentInstance.editDb = this.dbList[index];
-    modalRef.componentInstance.passEntry.subscribe(receivedEntry => {
-      this.dbNew = receivedEntry;
-      this.dbApiService
-        .updateDb(this.dbNew)
-        .subscribe(
-          res => {
-            if (res.statusCode == 200) {
-              this.dbList[index] = this.dbNew;
-              this.dbList = [...this.dbList];
-              this.notificationService.success("SUCCESSFULLY_UPDATED");
-              this.initData();
-            } else {
-              this.notificationService.error("FAILED_UPDATED");
-              this.initData();
+  openModal(mode: string = "", id: number | string) {
+    const modalRef = this.modalService.open(ModalComponent, {
+      size: "lg",
+      centered: true,
+      backdrop: "static"
+    });
+
+    switch (mode) {
+      case "new":
+        let newDB: Db = new Db();
+        let componentNew = new ModalContentData(DbModalComponent, newDB);
+
+        modalRef.componentInstance.title = "NEW_DB";
+        modalRef.componentInstance.notice = "";
+        modalRef.componentInstance.mode = "new";
+        modalRef.componentInstance.component = componentNew;
+
+        modalRef.componentInstance.passEntry.subscribe((data: Db) => {
+          newDB = Object.assign({}, data);
+          console.log(newDB.dbTypeId);
+          console.log(newDB);
+          this.restApiService.addDb(newDB).subscribe(
+            res => {
+              this.ngOnInit();
+              setTimeout(() => {
+                this.notificationService.success("SUCCESSFULLY_CREARED");
+              }, 500);
+            },
+            err => {
+              this.notificationService.error(err);
             }
-            modalRef.close();
-          },
-          err => {
-            this.notificationService.error(err);
-            modalRef.close();
-          }
-        );
-    })
-  }
+          );
+          modalRef.close();
+        });
+        break;
+      case "edit":
+        let index: number = this.dbs.findIndex(db => db.id === id);
+        let editDb: Db = this.dbs[index];
+        let componentEdit = new ModalContentData(DbModalComponent, editDb);
 
-  onActivate(event) {
+        modalRef.componentInstance.title = editDb.name;
+        modalRef.componentInstance.notice = "";
+        modalRef.componentInstance.mode = "edit";
+        modalRef.componentInstance.component = componentEdit;
 
+        modalRef.componentInstance.passEntry.subscribe((data: Db) => {
+          editDb = Object.assign({}, data);
+          this.restApiService.updateDb(editDb).subscribe(
+            res => {
+              this.ngOnInit();
+              setTimeout(() => {
+                this.notificationService.success("SUCCESSFULLY_UPDATED");
+              }, 500);
+            },
+            err => {
+              this.notificationService.error(err);
+            }
+          );
+          modalRef.close();
+        });
+        break;
+    }
   }
 }
diff --git a/components/datalake-handler/admin/src/src/app/views/database/database-list/db-modal/db-modal.component.css b/components/datalake-handler/admin/src/src/app/views/database/database-list/db-modal/db-modal.component.css
new file mode 100644
index 0000000..0b713d5
--- /dev/null
+++ b/components/datalake-handler/admin/src/src/app/views/database/database-list/db-modal/db-modal.component.css
@@ -0,0 +1,25 @@
+/*
+* ============LICENSE_START=======================================================
+* ONAP : DataLake
+* ================================================================================
+* Copyright 2019 - 2020 QCT
+*=================================================================================
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+* ============LICENSE_END=========================================================
+*/
+
+/*
+ * For every Angular component you write, you may define not only an HTML template,
+ * but also the CSS styles that go with that template, specifying any selectors,
+ * rules, and media queries that you need.
+*/
diff --git a/components/datalake-handler/admin/src/src/app/views/database/database-list/db-modal/db-modal.component.html b/components/datalake-handler/admin/src/src/app/views/database/database-list/db-modal/db-modal.component.html
new file mode 100644
index 0000000..276b8fb
--- /dev/null
+++ b/components/datalake-handler/admin/src/src/app/views/database/database-list/db-modal/db-modal.component.html
@@ -0,0 +1,128 @@
+<!--
+============LICENSE_START=======================================================
+ONAP : DataLake
+================================================================================
+Copyright 2019 - 2020 QCT
+=================================================================================
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+============LICENSE_END=========================================================
+-->
+
+<div class="container p-4">
+
+  <div class="form-group">
+    <div class="row">
+      <div class="col-md-6">
+        <label class="dl-emphasis1">{{ 'STATUS' | translate }}</label>
+      </div>
+      <div class="col-md-6">
+
+      </div>
+    </div>
+    <div class="row">
+      <div class="col-md-6">
+        <label class="dl-switch">
+          <input id="switch" type="checkbox" [(ngModel)]="this.data.enabled" />
+          <span class="dl-slider round"></span>
+        </label>
+      </div>
+      <div class="col-md-6">
+
+      </div>
+    </div>
+  </div>
+
+  <div class="form-group">
+    <div class="row">
+      <div class="col-md-6">
+        <label class="dl-emphasis1">{{ "NAME" | translate }}</label>
+      </div>
+      <div class="col-md-6">
+        <label class="dl-emphasis1">{{ 'DB_TYPE' | translate }}</label>
+      </div>
+    </div>
+    <div class="row">
+      <div class="col-md-6">
+        <input [(ngModel)]="this.data.name" class="form-control dl-input-text" type="text" />
+      </div>
+      <div class="col-md-3">
+        <select [(ngModel)]="this.data.dbTypeId" class="custom-select dl-input-text">
+          <option *ngFor="let item of dbTypes" [value]="item.id" [selected]="item.id==this.data.dbTypeId">
+            {{ item.name }}
+          </option>
+        </select>
+      </div>
+    </div>
+  </div>
+
+  <div class="form-group">
+    <div class="row">
+      <div class="col-md-6">
+        <label class="dl-emphasis1">{{ 'HOST' | translate }}</label>
+      </div>
+      <div class="col-md-6">
+        <label class="dl-emphasis1">{{ 'Port' | translate }}</label>
+      </div>
+    </div>
+    <div class="row">
+      <div class="col-md-6">
+        <input [(ngModel)]="this.data.host" class="form-control dl-input-text" type="text" />
+      </div>
+      <div class="col-md-3">
+        <input [(ngModel)]="this.data.port" class="form-control dl-input-text" type="text"
+          (input)="this.adminService.onKeyPressNumber($event)" />
+      </div>
+    </div>
+  </div>
+
+  <div class="form-group">
+    <div class="row">
+      <div class="col-md-6">
+        <label class="dl-emphasis1">{{ 'Username' | translate }}</label>
+      </div>
+      <div class="col-md-6">
+        <label class="dl-emphasis1">{{ 'Password' | translate }}</label>
+      </div>
+    </div>
+    <div class="row">
+      <div class="col-md-6">
+        <input [(ngModel)]="this.data.login" class="form-control dl-input-text" type="text" />
+      </div>
+      <div class="col-md-6">
+        <input [(ngModel)]="this.data.pass" class="form-control dl-input-text" type="text" />
+      </div>
+    </div>
+  </div>
+
+  <div class="form-group">
+    <div class="row">
+      <div class="col-md-6">
+        <label class="dl-emphasis1">{{ 'DATABASE_NAME' | translate }}</label>
+      </div>
+      <div class="col-md-6">
+        <label class="dl-emphasis1">{{ 'SECURE_COMMUNICATION' | translate }}</label>
+      </div>
+    </div>
+    <div class="row">
+      <div class="col-md-6">
+        <input [(ngModel)]="this.data.database" class="form-control dl-input-text" type="text" />
+      </div>
+      <div class="col-md-6">
+        <label class="dl-switch">
+          <input id="switch" type="checkbox" [(ngModel)]="this.data.encrypt" />
+          <span class="dl-slider round"></span>
+        </label>
+      </div>
+    </div>
+  </div>
+</div>
diff --git a/components/datalake-handler/admin/src/src/app/views/database/database-list/db-modal/db-modal.component.spec.ts b/components/datalake-handler/admin/src/src/app/views/database/database-list/db-modal/db-modal.component.spec.ts
new file mode 100644
index 0000000..7e48dcb
--- /dev/null
+++ b/components/datalake-handler/admin/src/src/app/views/database/database-list/db-modal/db-modal.component.spec.ts
@@ -0,0 +1,44 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP : DataLake
+ * ================================================================================
+ * Copyright 2019 - 2020 QCT
+ *=================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import { async, ComponentFixture, TestBed } from "@angular/core/testing";
+
+import { DbModalComponent } from "./db-modal.component";
+
+describe("DbModalComponent", () => {
+  let component: DbModalComponent;
+  let fixture: ComponentFixture<DbModalComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [DbModalComponent]
+    }).compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(DbModalComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it("should create", () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/components/datalake-handler/admin/src/src/app/views/database/database-list/db-modal/db-modal.component.ts b/components/datalake-handler/admin/src/src/app/views/database/database-list/db-modal/db-modal.component.ts
new file mode 100644
index 0000000..b7ca5b1
--- /dev/null
+++ b/components/datalake-handler/admin/src/src/app/views/database/database-list/db-modal/db-modal.component.ts
@@ -0,0 +1,74 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP : DataLake
+ * ================================================================================
+ * Copyright 2019 - 2020 QCT
+ *=================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+/**
+ *
+ * @author Ekko Chang
+ *
+ */
+
+import { Component, OnInit, Input, ViewChild } from "@angular/core";
+import { NgxSpinnerService } from "ngx-spinner";
+import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap";
+import { RestApiService } from "src/app/core/services/rest-api.service";
+import { AdminService } from "src/app/core/services/admin.service";
+import { Db, DbType } from "src/app/core/models/db.model";
+import { from, forkJoin } from "rxjs";
+import { mergeMap, map } from "rxjs/operators";
+
+@Component({
+  selector: "app-db-modal",
+  templateUrl: "./db-modal.component.html",
+  styleUrls: ["./db-modal.component.css"]
+})
+export class DbModalComponent implements OnInit {
+  @Input() data: Db;
+  @Input() mode: string;
+
+  dbTypes: Array<DbType> = [];
+
+  constructor(
+    public activeModal: NgbActiveModal,
+    public adminService: AdminService,
+    private restApiService: RestApiService,
+    private spinner: NgxSpinnerService
+  ) {}
+
+  ngOnInit() {
+    // this.spinner.show();
+
+    // get database types
+    const get_dbTypes = this.restApiService.getDbTypes().pipe(
+      mergeMap(dbTypes => from(dbTypes)),
+      map(dbType => {
+        if (!dbType.tool) this.dbTypes.push(dbType);
+      })
+    );
+
+    forkJoin(get_dbTypes).subscribe(data => {
+      if (this.mode === "new") {
+        // default value
+        if (this.dbTypes.length > 0) {
+          this.data.dbTypeId = this.dbTypes[0].id;
+        }
+      }
+    });
+  }
+}
diff --git a/components/datalake-handler/admin/src/src/assets/i18n/en-us.json b/components/datalake-handler/admin/src/src/assets/i18n/en-us.json
index 2e0892f..b5e7d28 100644
--- a/components/datalake-handler/admin/src/src/assets/i18n/en-us.json
+++ b/components/datalake-handler/admin/src/src/assets/i18n/en-us.json
@@ -76,7 +76,7 @@
   "TIME_OUT": "Time out(sec)",
   "EDIT_KAFKA": "Edit Kafka",
   "NEW_DB": "New Database",
-  "DB_TYPE": "DbType",
+  "DB_TYPE": "Db Type",
   "NEW_DRUID": "New Druid",
   "NEW_ELASTICSEARCH": "New Elasticsearch",
   "NEW_COUCHBASE": "New Couchbase",
@@ -84,5 +84,11 @@
   "NEW_HDFS": "New Hdfs",
   "SECURE_COMMUNICATION": "Secure Communication",
   "NEW_TOOL": "New Tool",
-  "NEW_KIBANA": "New Kibana"
+  "NEW_KIBANA": "New Kibana",
+  "COUCHBASE": "Couchbase",
+  "DRUID": "Druid",
+  "ELASTICSEARCH": "Elasticsearch",
+  "MONGODB": "MongoDB",
+  "HDFS": "Hdfs",
+  "DATABASE_NAME": "Database Name"
 }