To optimize the shared module and apply it into the page

Issue-ID: DCAEGEN2-1715
Signed-off-by: Ekko Chang <ekko.chang@qct.io>
Change-Id: I1a461ab6f2a5cc272dbdeacb9b5a480b269eed93
diff --git a/components/datalake-handler/admin/src/package.json b/components/datalake-handler/admin/src/package.json
index de89944..d4e0444 100644
--- a/components/datalake-handler/admin/src/package.json
+++ b/components/datalake-handler/admin/src/package.json
@@ -13,11 +13,13 @@
   },
   "private": true,
   "dependencies": {
-    "@angular/animations": "~7.2.0",
+    "@angular/animations": "^7.2.15",
+    "@angular/cdk": "^7.3.7",
     "@angular/common": "~7.2.0",
     "@angular/compiler": "~7.2.0",
     "@angular/core": "~7.2.0",
     "@angular/forms": "~7.2.0",
+    "@angular/material": "^7.3.7",
     "@angular/platform-browser": "~7.2.0",
     "@angular/platform-browser-dynamic": "~7.2.0",
     "@angular/router": "~7.2.0",
diff --git a/components/datalake-handler/admin/src/src/app/app-routing.module.ts b/components/datalake-handler/admin/src/src/app/app-routing.module.ts
index ae2f9b6..e0484a4 100644
--- a/components/datalake-handler/admin/src/src/app/app-routing.module.ts
+++ b/components/datalake-handler/admin/src/src/app/app-routing.module.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.
@@ -28,15 +28,15 @@
 import { Routes, RouterModule } from "@angular/router";
 
 //test components for module testing
-import { TestComponent } from './views/test/test.component';
+import { TestComponent } from "./views/test/test.component";
 
 import { FeederComponent } from "./views/feeder/feeder.component";
 import { KafkaComponent } from "./views/kafka/kafka.component";
 import { TopicsComponent } from "./views/topics/topics.component";
 import { DatabaseComponent } from "./views/database/database.component";
 import { AboutComponent } from "./views/about/about.component";
-import { TemplateComponent } from './views/dashboard-setting/template/template.component';
-import {ToolsComponent} from "./views/tools/tools.component";
+import { TemplateComponent } from "./views/dashboard-setting/template/template.component";
+import { ToolsComponent } from "./views/tools/tools.component";
 
 const routes: Routes = [
   { path: "", redirectTo: "/feeder", pathMatch: "full" },
@@ -46,8 +46,8 @@
   { path: "topics", component: TopicsComponent },
   { path: "database", component: DatabaseComponent },
   { path: "about", component: AboutComponent },
-  { path: 'tools', component: ToolsComponent },
-  { path: 'dashboard-setting/template', component: TemplateComponent },
+  { path: "tools", component: ToolsComponent },
+  { path: "dashboard-setting/template", component: TemplateComponent }
 ];
 
 @NgModule({
@@ -58,4 +58,4 @@
   ],
   exports: [RouterModule]
 })
-export class AppRoutingModule { }
+export class AppRoutingModule {}
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 2f968bf..ddc0c10 100644
--- a/components/datalake-handler/admin/src/src/app/app.module.ts
+++ b/components/datalake-handler/admin/src/src/app/app.module.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.
@@ -65,12 +65,12 @@
 import { DatabaseAddModalComponent } from "./views/database/database-list/database-add-modal/database-add-modal.component";
 import { ElasticsearchComponent } from "./views/database/database-list/dbs-modal/elasticsearch/elasticsearch.component";
 import { DruidComponent } from "./views/database/database-list/dbs-modal/druid/druid.component";
-import { KafkaListComponent } from './views/kafka/kafka-list/kafka-list.component';
-import { NewKafkaModalComponent } from './views/kafka/kafka-list/new-kafka-modal/new-kafka-modal.component';
-import { EditKafkaModalComponent } from './views/kafka/kafka-list/edit-kafka-modal/edit-kafka-modal.component';
-import { ToolsComponent } from './views/tools/tools.component';
-import { ModalToolsComponent } from './views/tools/modal-tools/modal-tools.component';
-import { ToolAddModalComponent } from './views/tools/tool-add-modal/tool-add-modal.component';
+import { KafkaListComponent } from "./views/kafka/kafka-list/kafka-list.component";
+import { NewKafkaModalComponent } from "./views/kafka/kafka-list/new-kafka-modal/new-kafka-modal.component";
+import { EditKafkaModalComponent } from "./views/kafka/kafka-list/edit-kafka-modal/edit-kafka-modal.component";
+import { ToolsComponent } from "./views/tools/tools.component";
+import { ModalToolsComponent } from "./views/tools/modal-tools/modal-tools.component";
+import { ToolAddModalComponent } from "./views/tools/tool-add-modal/tool-add-modal.component";
 
 // Modals
 import { TopicDetailModalComponent } from "./views/topics/topic-list/topic-detail-modal/topic-detail-modal.component";
@@ -97,10 +97,14 @@
 import { ButtonComponent } from "./shared/components/Button/button.component";
 import { ModalDirective } from "./shared/modules/modal/modal.directive";
 import { ModalDemoComponent } from "./views/test/modal-demo/modal-demo.component";
-import { KafkaComponent } from './views/kafka/kafka.component';
+import { KafkaComponent } from "./views/kafka/kafka.component";
 // Angular SVG Icon
 import { AngularSvgIconModule } from "angular-svg-icon";
-import { IconComponent } from './shared/components/icon/icon.component';
+import { IconComponent } from "./shared/components/icon/icon.component";
+
+import { MatTabsModule } from "@angular/material";
+import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
+import { TopicModalComponent } from "./views/topics/topic-list/topic-modal/topic-modal.component";
 
 @NgModule({
   declarations: [
@@ -146,7 +150,8 @@
     ToolsComponent,
     ModalToolsComponent,
     ToolAddModalComponent,
-    IconComponent
+    IconComponent,
+    TopicModalComponent
   ],
   imports: [
     BrowserModule,
@@ -163,7 +168,9 @@
     FormsModule,
     NgxDatatableModule,
     NgxSpinnerModule,
-    AngularSvgIconModule
+    AngularSvgIconModule,
+    MatTabsModule,
+    BrowserAnimationsModule
   ],
   providers: [AdminService, RestApiService, ToastrNotificationService],
   bootstrap: [AppComponent],
@@ -187,7 +194,8 @@
     NewKafkaModalComponent,
     EditKafkaModalComponent,
     ToolAddModalComponent,
-    ModalToolsComponent
+    ModalToolsComponent,
+    TopicModalComponent
   ]
 })
 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 ca7f379..3de8f21 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
@@ -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.
@@ -35,4 +35,6 @@
   login: string;
   pass: string;
   dbTypeId: string;
+  // for UI display
+  checkedToSave: boolean;
 }
diff --git a/components/datalake-handler/admin/src/src/app/core/models/kafka.model.ts b/components/datalake-handler/admin/src/src/app/core/models/kafka.model.ts
index 40a7e26..34f283f 100644
--- a/components/datalake-handler/admin/src/src/app/core/models/kafka.model.ts
+++ b/components/datalake-handler/admin/src/src/app/core/models/kafka.model.ts
@@ -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.
@@ -29,4 +29,6 @@
   excludedTopic: string;
   consumerCount: number;
   timeout: number;
+  // for UI display
+  checkedToSave: boolean;
 }
diff --git a/components/datalake-handler/admin/src/src/app/core/models/topic.model.ts b/components/datalake-handler/admin/src/src/app/core/models/topic.model.ts
index 18faa58..be225da 100644
--- a/components/datalake-handler/admin/src/src/app/core/models/topic.model.ts
+++ b/components/datalake-handler/admin/src/src/app/core/models/topic.model.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.
@@ -41,50 +41,21 @@
   public flattenArrayPath: string;
   public enbabledKafkas: Array<string>;
   public kafkas: Array<string>;
+  public countsDb: CountsDb;
+  public countsKafka: number;
   // properties only for UI
   public config: boolean; //true: Configure, otherwise false: Unconfiure
-  public kafkaName: string;
-  public countCouchbase: number;
-  public countDruid: number;
-  public countEs: number;
-  public countMongo: number;
-  public countHadoop: number;
+  public countsMONGO: number;
+  public countsDRUID: number;
+  public countsHDFS: number;
+  public countsES: number;
+  public countsCB: number;
+}
 
-  constructor(
-    id: number,
-    name: string,
-    login: string,
-    password: string,
-    enabledSinkdbs: Array<string>,
-    sinkdbs: Array<string>,
-    enabled: boolean,
-    saveRaw: boolean,
-    dataFormat: string,
-    ttl: number,
-    correlateClearedMessage: boolean,
-    messageIdPath: string,
-    aggregateArrayPath: string,
-    flattenArrayPath: string,
-    enbabledKafkas: Array<string>,
-    kafkas: Array<string>,
-    config: boolean
-  ) {
-    this.id = id;
-    this.name = name;
-    this.login = login;
-    this.password = password;
-    this.enabledSinkdbs = enabledSinkdbs;
-    this.sinkdbs = sinkdbs;
-    this.enabled = enabled;
-    this.saveRaw = saveRaw;
-    this.dataFormat = dataFormat;
-    this.ttl = ttl;
-    this.correlateClearedMessage = correlateClearedMessage;
-    this.messageIdPath = messageIdPath;
-    this.aggregateArrayPath = aggregateArrayPath;
-    this.flattenArrayPath = flattenArrayPath;
-    this.enbabledKafkas = enbabledKafkas;
-    this.kafkas = kafkas;
-    this.config = config;
-  }
+class CountsDb {
+  MONGO: number;
+  DRUID: number;
+  HDFS: number;
+  ES: number;
+  CB: number;
 }
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 0c52089..b3ed616 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
@@ -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.
@@ -77,7 +77,7 @@
   }
 
   /*
-    Topic default config
+    Topics
   */
   public getTopicDefault(): Observable<Topic> {
     return this.http
@@ -85,19 +85,6 @@
       .pipe(retry(1), catchError(this.handleError));
   }
 
-  // updateTopicDefaultConfig(t: Topic): Observable<any> {
-  //   return this.http
-  //     .put(prefix + "topics/_DL_DEFAULT_", JSON.stringify(t), httpOptions)
-  //     .pipe(
-  //       retry(1),
-  //       tap(_ => this.extractData),
-  //       catchError(this.handleError)
-  //     );
-  // }
-
-  /*
-    Topics
-  */
   public getTopicList(): Observable<string[]> {
     return this.http
       .get<string[]>(prefix + "topics")
@@ -110,12 +97,43 @@
       .pipe(retry(1), catchError(this.handleError));
   }
 
-  public getTopic(id: string): Observable<Topic> {
+  // Get topic names for adding
+  public getTopicNames(): Observable<string[]> {
+    return this.http
+      .get<string[]>(prefix + "topicNames")
+      .pipe(retry(1), catchError(this.handleError));
+  }
+
+  public getTopic(id: string | number): Observable<Topic> {
     return this.http
       .get<Topic>(prefix + "topics/" + id)
       .pipe(retry(1), catchError(this.handleError));
   }
 
+  public updateTopic(t: Topic): Observable<Topic> {
+    return this.http.put<Topic>(prefix + "topics/" + t.id, t).pipe(
+      retry(1),
+      tap(_ => this.extractData),
+      catchError(this.handleError)
+    );
+  }
+
+  public addTopic(t: Topic): Observable<Topic> {
+    return this.http.post<Topic>(prefix + "topics", t).pipe(
+      retry(1),
+      tap(_ => console.log(`add topic name=${t.name}`)),
+      catchError(this.handleError)
+    );
+  }
+
+  public deleteTopic(id: number | string): Observable<Topic> {
+    return this.http.delete<Topic>(prefix + "topics/" + id).pipe(
+      retry(1),
+      tap(_ => console.log(`deleted topic name=${name}`)),
+      catchError(this.handleError)
+    );
+  }
+
   // TODO
   getTopicsFromFeeder(): Observable<any> {
     return this.http
@@ -123,41 +141,15 @@
       .pipe(retry(1), map(this.extractData), catchError(this.handleError));
   }
 
-  // addNewTopic(t: Topic): Observable<any> {
-  //   return this.http.post<any>(prefix + "topics", t).pipe(
-  //     retry(1),
-  //     tap(_ => console.log(`add topic name=${t.name}`)),
-  //     catchError(this.handleError)
-  //   );
-  // }
-
-  // addTopic(t: Topic): Observable<any> {
-  //   return this.http.post<any>(prefix + "topics", t).pipe(
-  //     retry(1),
-  //     tap(_ => console.log(`add topic name=${t.name}`)),
-  //     catchError(this.handleError)
-  //   );
-  // }
-
-  // upadteTopic(t: Topic): Observable<any> {
-  //   return this.http.put(prefix + "topics/" + t.name, t).pipe(
-  //     retry(1),
-  //     tap(_ => this.extractData),
-  //     catchError(this.handleError)
-  //   );
-  // }
-
-  // deleteTopic(name: string): Observable<any> {
-  //   return this.http.delete(prefix + "topics/" + name).pipe(
-  //     retry(1),
-  //     tap(_ => console.log(`deleted topic name=${name}`)),
-  //     catchError(this.handleError)
-  //   );
-  // }
-
   /*
     Database
   */
+  public getAllDbs(): Observable<Db[]> {
+    return this.http
+      .get<Db[]>(prefix + "dbs/list?isDb=true")
+      .pipe(retry(1), catchError(this.handleError));
+  }
+
   getDbEncryptList(flag): Observable<any> {
     return this.http
       .get(prefix + "dbs/list?tool=" + flag)
@@ -201,6 +193,7 @@
     );
   }
 
+  // Deprecated
   getDbTypeList(): Observable<any> {
     return this.http
       .get(prefix + "db_type")
@@ -233,8 +226,8 @@
   }
 
   /*
-Dashboard
-*/
+  Dashboard
+  */
   getDashboardList(): Observable<any> {
     let url = prefix + "portals"; //onilne
     return this.http
@@ -263,7 +256,7 @@
 
   /*
   Template
-*/
+  */
   getTemplateAll(): Observable<any> {
     return this.http.get(prefix + "designs/").pipe(
       //onlin
@@ -332,11 +325,11 @@
   }
 
   /*
-  Kafka
-*/
-  public getAllKafkaList(): Observable<string[]> {
+    Kafka
+  */
+  public getAllKafka(): Observable<Kafka[]> {
     return this.http
-      .get<string[]>(prefix + "kafkas")
+      .get<Kafka[]>(prefix + "kafkas")
       .pipe(retry(1), catchError(this.handleError));
   }
 
@@ -346,6 +339,12 @@
       .pipe(retry(1), catchError(this.handleError));
   }
 
+  getAllKafkaList(): Observable<any> {
+    return this.http
+      .get<any>(prefix + "kafkas")
+      .pipe(retry(1), catchError(this.handleError));
+  }
+
   deleteKafka(id): Observable<any> {
     return this.http.delete(prefix + "kafkas/" + id).pipe(
       //online
diff --git a/components/datalake-handler/admin/src/src/app/shared/components/Button/button.component.html b/components/datalake-handler/admin/src/src/app/shared/components/Button/button.component.html
index 7986886..9a6f9f4 100644
--- a/components/datalake-handler/admin/src/src/app/shared/components/Button/button.component.html
+++ b/components/datalake-handler/admin/src/src/app/shared/components/Button/button.component.html
@@ -1,17 +1,37 @@
+<!--
+============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=========================================================
+-->
+
 <!-- block type buttons -->
 <button type="button" *ngIf="this.buttonstyle===1"
   [class]="this.buttoncolor===1? 'btn dl-btn-light btn-block':'btn dl-btn-dark btn-block'">
-  <span> {{this.text | translate}}</span>
+  <span class="p-0"> {{this.text | translate}}</span>
 </button>
 
 <!-- inline type buttons -->
 <button type="button" *ngIf="this.buttonstyle===2" [class]="this.buttoncolor===1? 'btn dl-btn-light':'btn dl-btn-dark'">
-  <span> {{this.text | translate}}</span>
+  <span class="p-0"> {{this.text | translate}}</span>
 </button>
 
 <!-- inline icon buttons -->
 <button *ngIf="this.buttonstyle===4" [class]="this.buttoncolor===1? 'btn dl-btn-light':'btn dl-btn-dark'">
-  <span>
+  <span class="p-0">
     <i *ngIf="this.text==='search'" class="fa fa-search"></i>
     <i *ngIf="this.text==='plus'" class="fa fa-plus fa-xs" aria-hidden="true"></i>
     <i *ngIf="this.text==='trash'" class="fa fa-trash fa-xs" aria-hidden="true"></i>
@@ -20,7 +40,7 @@
 </button>
 
 <!-- icon type buttons -->
-<button type="button" *ngIf="this.buttonstyle===3" class="btn dl-icon-enable p-2" (click)="buttonClick(this.text)">
+<button type="button" *ngIf="this.buttonstyle===3" class="btn dl-icon-enable p-1" (click)="buttonClick(this.text)">
   <i *ngIf="this.text==='search'" class="fa fa-search"></i>
   <i *ngIf="this.text==='plus'" class="fa fa-plus fa-xs" aria-hidden="true"></i>
   <i *ngIf="this.text==='trash'" class="fa fa-trash fa-xs" aria-hidden="true"></i>
diff --git a/components/datalake-handler/admin/src/src/app/shared/modules/modal/modal.component.html b/components/datalake-handler/admin/src/src/app/shared/modules/modal/modal.component.html
index 38654bc..137e14d 100644
--- a/components/datalake-handler/admin/src/src/app/shared/modules/modal/modal.component.html
+++ b/components/datalake-handler/admin/src/src/app/shared/modules/modal/modal.component.html
@@ -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.
@@ -25,27 +25,20 @@
     <div class="container-fluid">
 
       <!-- Page Title -->
-      <div class="row">
-        <div class="col-md-12">
-          <label *ngIf="this.contentComponent.data.state == 'edit'" class="dl-h3">Edit&nbsp;</label>
-          <label class="dl-h3">{{ this.contentComponent.data.title | translate }}</label>
-        </div>
-      </div>
+      <label class="modal-title dl-h3">{{ this.title | translate }}</label>
       <!-- Page Title End -->
 
       <div class="row">
         <div class="col-md-12">
           <hr />
         </div>
-
         <!-- Notice -->
-        <div *ngIf="this.contentComponent.data.notice" class="col-md-12">
+        <div *ngIf="this.notice" class="col-md-12">
           <div class="dl-notice">
-            {{ this.contentComponent.data.notice | translate}}
+            {{ this.notice | translate }}
           </div>
         </div>
         <!-- Notice End -->
-
       </div>
 
     </div>
@@ -63,7 +56,6 @@
         </div>
       </div>
       <!-- Modal Content End -->
-
     </div>
   </div>
   <!-- Modal Body End -->
@@ -75,19 +67,15 @@
         <div class="col-md-12">
           <div class="d-flex justify-content-end">
             <div class="p-1">
-              <span>
-                <app-button *ngIf="this.contentComponent.data.state == 'new'" [text]="'Next'" [style]="'inline'"
-                  [color]="'dark'" (click)="this.nextPage()"></app-button>
-                <app-button *ngIf="this.contentComponent.data.state == 'edit'" [text]="'Save'" [style]="'inline'"
-                  [color]="'dark'" (click)="this.passBack()"></app-button>
-              </span>
+              <!-- <app-button *ngIf="this.mode == 'new'" [text]="'Next'" [style]="'inline'" [color]="'dark'"
+                (click)="this.nextPage()"></app-button> -->
+              <!-- <app-button *ngIf="this.mode == 'edit'" [text]="'Save'" [style]="'inline'" [color]="'dark'"
+                (click)="this.passBack()"></app-button> -->
+              <app-button [text]="'Save'" [style]="'inline'" [color]="'dark'" (click)="this.passBack()"></app-button>
             </div>
-
             <div class="p-1">
-              <span>
-                <app-button [text]="'Cancel'" [style]="'inline'" [color]="'light'"
-                  (click)="activeModal.close('Close click')"></app-button>
-              </span>
+              <app-button [text]="'Cancel'" [style]="'inline'" [color]="'light'"
+                (click)="activeModal.close('Close click')"></app-button>
             </div>
           </div>
         </div>
diff --git a/components/datalake-handler/admin/src/src/app/shared/modules/modal/modal.component.ts b/components/datalake-handler/admin/src/src/app/shared/modules/modal/modal.component.ts
index 0eade62..da757be 100644
--- a/components/datalake-handler/admin/src/src/app/shared/modules/modal/modal.component.ts
+++ b/components/datalake-handler/admin/src/src/app/shared/modules/modal/modal.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.
@@ -45,10 +45,19 @@
   styleUrls: ["./modal.component.css"]
 })
 export class ModalComponent implements OnInit {
-  @Input() contentComponent: ModalContentData;
+  @Input() title: string;
+  @Input() notice: string;
+  @Input() mode: string;
+  @Input() component: ModalContentData;
   @Output() passEntry: EventEmitter<any> = new EventEmitter();
   @ViewChild(ModalDirective) modalContent: ModalDirective;
 
+  emitData: any; // temp data for two way binding
+  selectedIndex: number = 0; // number to switch tab
+  componentFactory: any;
+  viewContainerRef: any;
+  componentRef: any;
+
   constructor(
     public activeModal: NgbActiveModal,
     private componentFactoryResolver: ComponentFactoryResolver
@@ -59,26 +68,31 @@
   }
 
   loadComponent() {
-    const componentFactory = this.componentFactoryResolver.resolveComponentFactory(
-      this.contentComponent.component
+    this.componentFactory = this.componentFactoryResolver.resolveComponentFactory(
+      this.component.modalComponent
     );
 
-    const viewContainerRef = this.modalContent.viewContainerRef;
-    viewContainerRef.clear();
+    this.viewContainerRef = this.modalContent.viewContainerRef;
+    this.viewContainerRef.clear();
 
-    const componentRef = viewContainerRef.createComponent(componentFactory);
-    (<ModalInterface>componentRef.instance).data = this.contentComponent.data;
+    this.componentRef = this.viewContainerRef.createComponent(
+      this.componentFactory
+    );
+
+    this.emitData = Object.assign({}, this.component.data);
+    (<ModalInterface>this.componentRef.instance).data = this.emitData;
+    (<ModalInterface>this.componentRef.instance).mode = this.mode;
+    (<ModalInterface>(
+      this.componentRef.instance
+    )).selectedIndex = this.selectedIndex;
   }
 
   nextPage() {
-    console.log("nextpage");
-    //TODO: Switch the pages
+    (<ModalInterface>this.componentRef.instance).selectedIndex++;
   }
 
   passBack() {
-    console.log("passback");
-    //TODO: Save the data
-
-    this.passEntry.emit("save....");
+    this.component.data = this.emitData;
+    this.passEntry.emit(this.component.data);
   }
 }
diff --git a/components/datalake-handler/admin/src/src/app/shared/modules/modal/modal.data.ts b/components/datalake-handler/admin/src/src/app/shared/modules/modal/modal.data.ts
index ff2f015..c5cb89b 100644
--- a/components/datalake-handler/admin/src/src/app/shared/modules/modal/modal.data.ts
+++ b/components/datalake-handler/admin/src/src/app/shared/modules/modal/modal.data.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.
@@ -27,5 +27,11 @@
 import { Type } from "@angular/core";
 
 export class ModalContentData {
-  constructor(public component: Type<any>, public data: any) {}
+  public modalComponent: Type<any>;
+  public data: any;
+
+  constructor(modalComponent: Type<any>, data: any) {
+    this.modalComponent = modalComponent;
+    this.data = data;
+  }
 }
diff --git a/components/datalake-handler/admin/src/src/app/shared/modules/modal/modal.interface.ts b/components/datalake-handler/admin/src/src/app/shared/modules/modal/modal.interface.ts
index a3b4728..556d4c6 100644
--- a/components/datalake-handler/admin/src/src/app/shared/modules/modal/modal.interface.ts
+++ b/components/datalake-handler/admin/src/src/app/shared/modules/modal/modal.interface.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.
@@ -23,6 +23,9 @@
  * @author Ekko Chang
  *
  */
+
 export interface ModalInterface {
   data: any;
+  mode: string;
+  selectedIndex: number;
 }
diff --git a/components/datalake-handler/admin/src/src/app/shared/modules/table/table.component.html b/components/datalake-handler/admin/src/src/app/shared/modules/table/table.component.html
index c0e0971..d4162ee 100644
--- a/components/datalake-handler/admin/src/src/app/shared/modules/table/table.component.html
+++ b/components/datalake-handler/admin/src/src/app/shared/modules/table/table.component.html
@@ -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.
@@ -20,7 +20,6 @@
 
 <div class="row">
   <div class="col-md-12">
-
     <ngx-datatable #mytemlate class="bootstrap" [rows]="data" [columnMode]="'force'" [headerHeight]="40"
       [footerHeight]="40" [rowHeight]="50" [scrollbarV]="true" [scrollbarH]="true" [loadingIndicator]="loadingIndicator"
       [messages]="mesgNoData" [limit]="10" (activate)="rowOnActivate($event)">
@@ -29,39 +28,43 @@
         headerClass="d-flex justify-content-center justify-content-start" cellClass="d-flex justify-content-center">
         <!-- template of header -->
         <ng-template ngx-datatable-header-template>
-
           <!-- display string -->
-          <span *ngIf="column.headerName&&column.headerName.length!==0">{{ column.headerName | translate}}</span>
+          <span *ngIf="column.headerName && column.headerName.length !== 0">{{
+            column.headerName | translate
+          }}</span>
 
           <!-- display icon -->
-          <span *ngIf="column.headerIcon&&column.headerIcon.length!==0">
-            <svg-icon [src]="column.headerIcon" [svgStyle]="{ 'height.px':20 }"></svg-icon>
+          <span *ngIf="column.headerIcon && column.headerIcon.length !== 0" placement="bottom" container="body"
+            ngbTooltip="{{column.headerIconInfo}}" tooltipClass="dl-db-icon-hover-enable" [openDelay]="300"
+            [closeDelay]="300">
+            <svg-icon [src]="column.headerIcon" [svgStyle]="{ 'height.px': 20 }">
+            </svg-icon>
           </span>
         </ng-template>
 
         <!-- template of cell -->
         <ng-template let-row="row" ngx-datatable-cell-template>
           <!-- display data -->
-          <span *ngIf="column.dataIndex&&column.dataIndex.length!==0&&!column.icon">{{row[column.dataIndex]}}</span>
+          <span *ngIf="
+              column.dataIndex && column.dataIndex.length !== 0 && !column.icon
+            ">{{ row[column.dataIndex] }}</span>
 
           <!-- display button with text -->
-          <span *ngIf="column.textButton&&column.textButton.length!==0">
+          <span *ngIf="column.textButton && column.textButton.length !== 0">
             <app-button [text]="column.textButton" [style]="'inline'" [color]="'dark'"></app-button>
           </span>
 
           <!-- display button with icon -->
-          <span *ngIf="column.iconButton&&column.iconButton.length!==0">
+          <span *ngIf="column.iconButton && column.iconButton.length !== 0">
             <app-button [text]="column.iconButton" [style]="'icon'" [color]="'dark'"
-              (btnAction)="tableAction($event, row.id)"></app-button>
+              (click)="tableAction(column.action, row.id)"></app-button>
           </span>
 
           <!-- display pure icon -->
-          <span *ngIf="column.icon&&column.icon.length!==0">
+          <span *ngIf="column.icon && column.icon.length !== 0">
             <app-icon [type]="column.icon" [enabled]="row[column.dataIndex]"></app-icon>
           </span>
-
         </ng-template>
-
       </ngx-datatable-column>
     </ngx-datatable>
   </div>
diff --git a/components/datalake-handler/admin/src/src/app/shared/modules/table/table.component.ts b/components/datalake-handler/admin/src/src/app/shared/modules/table/table.component.ts
index 8adb837..9452697 100644
--- a/components/datalake-handler/admin/src/src/app/shared/modules/table/table.component.ts
+++ b/components/datalake-handler/admin/src/src/app/shared/modules/table/table.component.ts
@@ -1,9 +1,31 @@
-import { Component, OnInit, Input, Output, EventEmitter } from "@angular/core";
+/*
+ * ============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=========================================================
+ */
 
 /**
+ *
  * @contributor Chunmeng Guo
+ *
  */
 
+import { Component, OnInit, Input, Output, EventEmitter } from "@angular/core";
+
 @Component({
   selector: "app-table",
   templateUrl: "./table.component.html",
@@ -34,22 +56,28 @@
     }, 500);
   }
 
-  tableAction(event: any, actionId: number) {
-    console.log("action id: " + actionId);
-    console.log("edit: " + event.row.id);
+  tableAction(action: string, id: number | string) {
     let passValueArr: Array<any> = [];
-    passValueArr.push(event);
-    passValueArr.push(actionId);
+    passValueArr.push(action);
+    passValueArr.push(id);
+
+    // array[0] for action
+    // array[1] for value
+    console.log("tableAction");
     this.btnTableAction.emit(passValueArr);
   }
 
   rowOnActivate(event: any) {
     const emitType = event.type;
+
     if (emitType == "dblclick") {
-      console.log("Activate Event", event);
-      let name = event.row.id;
-      // this.openTopicModal(name);
-      console.log("row name: " + name);
+      let passValueArr: Array<any> = [];
+      passValueArr.push("edit");
+      passValueArr.push(event.row.id);
+
+      // // array[0] for action
+      // // array[1] for value
+      this.btnTableAction.emit(passValueArr);
     }
   }
 }
diff --git a/components/datalake-handler/admin/src/src/app/views/topics/topic-list/topic-list.component.html b/components/datalake-handler/admin/src/src/app/views/topics/topic-list/topic-list.component.html
index 3fbbc42..17d77f9 100644
--- a/components/datalake-handler/admin/src/src/app/views/topics/topic-list/topic-list.component.html
+++ b/components/datalake-handler/admin/src/src/app/views/topics/topic-list/topic-list.component.html
@@ -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.
@@ -32,10 +32,12 @@
 
         <!-- button -->
         <div class="p-1">
-          <app-button [text]="'DEFAULT_CONFIGURATIONS'" [style]="'inline'" [color]="'dark'" (click)="buttonAction('default')"></app-button>
+          <app-button [text]="'DEFAULT_CONFIGURATIONS'" [style]="'inline'" [color]="'dark'"
+            (click)="openModal('default')"></app-button>
         </div>
         <div class="p-1">
-          <app-button [text]="'plus'" [style]="'inlineicon'" [color]="'dark'" (click)="buttonAction('new')"></app-button>
+          <app-button [text]="'plus'" [style]="'inlineicon'" [color]="'dark'" (click)="openModal('new')">
+          </app-button>
         </div>
       </div>
     </div>
@@ -44,7 +46,7 @@
   <!-- datatable -->
   <div class="row">
     <div class="col-md-12">
-      <app-table [data]="topics" [columns]="columns"></app-table>
+      <app-table [data]="topics" [columns]="columns" (btnTableAction)="btnTableAction($event)"></app-table>
     </div>
   </div>
 </div>
diff --git a/components/datalake-handler/admin/src/src/app/views/topics/topic-list/topic-list.component.ts b/components/datalake-handler/admin/src/src/app/views/topics/topic-list/topic-list.component.ts
index d2d983f..2c6fe3e 100644
--- a/components/datalake-handler/admin/src/src/app/views/topics/topic-list/topic-list.component.ts
+++ b/components/datalake-handler/admin/src/src/app/views/topics/topic-list/topic-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,12 +29,7 @@
 import { Topic } from "src/app/core/models/topic.model";
 import { NgbModal } from "@ng-bootstrap/ng-bootstrap";
 
-// modal
-import { TopicDetailModalComponent } from "./topic-detail-modal/topic-detail-modal.component";
-import { TopicConfigModalComponent } from "./topic-config-modal/topic-config-modal.component";
-import { NewTopicModelComponent } from "./new-topic-model/new-topic-model.component";
-
-// notify
+// Notify
 import { ToastrNotificationService } from "src/app/shared/components/toastr-notification/toastr-notification.service";
 
 // Loading spinner
@@ -43,7 +38,11 @@
 import { AlertComponent } from "src/app/shared/components/alert/alert.component";
 import { map, mergeMap } from "rxjs/operators";
 import { forkJoin, from } from "rxjs";
-import { HttpClient } from "@angular/common/http";
+
+// Modal
+import { ModalComponent } from "src/app/shared/modules/modal/modal.component";
+import { ModalContentData } from "src/app/shared/modules/modal/modal.data";
+import { TopicModalComponent } from "src/app/views/topics/topic-list/topic-modal/topic-modal.component";
 
 @Component({
   selector: "app-topic-list",
@@ -52,8 +51,12 @@
 })
 export class TopicListComponent {
   topics: Array<Topic> = []; // data of table
-  columns: Array<any> = []; // column of table
   t_temp: Array<Topic> = []; // cache for topics
+  t_default: Topic = new Topic();
+
+  columns: Array<any> = []; // column of table
+
+  @ViewChild("searchText") searchText: ElementRef;
 
   //TODO
   //tempTopicDetail: Topic; // temp for a topic
@@ -63,43 +66,44 @@
     private restApiService: RestApiService,
     private modalService: NgbModal,
     private notificationService: ToastrNotificationService,
-    private spinner: NgxSpinnerService,
-    public http: HttpClient
+    private spinner: NgxSpinnerService
   ) {}
 
   ngOnInit() {
-    //this.spinner.show();
+    this.spinner.show();
     let t_feeder: Array<Topic> = [];
-    let t_kafka: Object = {};
 
     const get_t_feeder = this.restApiService.getTopicList().pipe(
       mergeMap(ids => from(ids)),
       mergeMap(id => this.restApiService.getTopic(id)),
       map(t => {
         t.config = true;
+        t.countsDb.MONGO > 0
+          ? (t.countsMONGO = t.countsDb.MONGO)
+          : (t.countsMONGO = 0);
+        t.countsDb.DRUID > 0
+          ? (t.countsDRUID = t.countsDb.DRUID)
+          : (t.countsDRUID = 0);
+        t.countsDb.HDFS > 0
+          ? (t.countsHDFS = t.countsDb.HDFS)
+          : (t.countsHDFS = 0);
+        t.countsDb.ES > 0 ? (t.countsES = t.countsDb.ES) : (t.countsES = 0);
+        t.countsDb.CB > 0 ? (t.countsCB = t.countsDb.CB) : (t.countsCB = 0);
         t_feeder.push(t);
       })
     );
 
-    const get_t_kafka = this.restApiService.getAllKafkaList().pipe(
-      mergeMap(ids => from(ids)),
-      mergeMap(id =>
-        this.restApiService
-          .getTopicListFromKafka(id)
-          .pipe(map(t => (t_kafka[id] = t)))
-      )
-    );
-
     const get_t_default = this.restApiService.getTopicDefault();
 
-    forkJoin(get_t_feeder, get_t_kafka, get_t_default).subscribe(data => {
+    forkJoin(get_t_feeder, get_t_default).subscribe(data => {
       this.columns = this.initColumn();
-      this.topics = this.initRow(t_feeder, t_kafka, data[2]);
+      this.t_default = data[1];
+      this.topics = t_feeder;
       this.t_temp = [...this.topics];
-      // setTimeout(() => {
-      //   //this.spinner.hide();
-      //   this.loadingIndicator = false;
-      // }, 500);
+      this.updateFilter(this.searchText.nativeElement.value);
+      setTimeout(() => {
+        this.spinner.hide();
+      }, 500);
     });
   }
 
@@ -115,53 +119,58 @@
         icon: "status"
       },
       {
+        headerName: "ID",
+        width: "15",
+        sortable: true,
+        dataIndex: "id"
+      },
+      {
         headerName: "NAME",
         width: "420",
         sortable: true,
         dataIndex: "name"
       },
       {
-        headerName: "SETTING",
-        width: "30",
-        sortable: true,
-        dataIndex: "config",
-        icon: "check"
-      },
-      {
-        headerIcon: "assets/icons/kibana_able.svg",
+        headerIcon: "assets/icons/kafka_able.svg",
+        headerIconInfo: "Kafka",
         width: "10",
         sortable: true,
-        dataIndex: "kafkas"
+        dataIndex: "countsKafka"
       },
       {
         headerIcon: "assets/icons/couchbase_able.svg",
+        headerIconInfo: "Couchbase",
         width: "10",
         sortable: true,
-        dataIndex: "sinkdbs"
+        dataIndex: "countsCB"
       },
       {
         headerIcon: "assets/icons/druid_able.svg",
+        headerIconInfo: "Druid",
         width: "10",
         sortable: true,
-        dataIndex: "sinkdbs"
+        dataIndex: "countsDRUID"
       },
       {
         headerIcon: "assets/icons/elasticsearch_able.svg",
+        headerIconInfo: "Elasticsearch",
         width: "10",
         sortable: true,
-        dataIndex: "sinkdbs"
+        dataIndex: "countsES"
       },
       {
         headerIcon: "assets/icons/mongoDB_able.svg",
+        headerIconInfo: "MongoDB",
         width: "10",
         sortable: true,
-        dataIndex: "sinkdbs"
+        dataIndex: "countsMONGO"
       },
       {
         headerIcon: "assets/icons/hadoop_able.svg",
+        headerIconInfo: "Hadoop",
         width: "10",
         sortable: true,
-        dataIndex: "sinkdbs"
+        dataIndex: "countsHDFS"
       },
       {
         headerName: "TTL",
@@ -177,65 +186,150 @@
         icon: "check"
       },
       {
-        width: "20",
-        iconButton: "cog"
+        width: "2",
+        iconButton: "cog",
+        action: "edit"
+      },
+      {
+        width: "2",
+        iconButton: "trash",
+        action: "delete"
       }
     ];
 
     return t_columns;
   }
 
-  initRow(t_feeder: Array<Topic>, t_kafka: Object, t_default: Topic) {
-    let t_topics: Array<Topic> = [];
+  btnTableAction(passValueArr: Array<any>) {
+    let action = passValueArr[0];
+    let id = passValueArr[1];
 
-    // Save topics which are already configured.
-    t_topics = t_feeder;
-
-    // Save the topic which is unconfigured yet.
-    Object.keys(t_kafka).forEach(k_id => {
-      Object.values(t_kafka[k_id]).forEach((k_t_name: string) => {
-        let found: Topic = t_feeder.find(
-          t =>
-            t.name == k_t_name &&
-            t.kafkas.map(ids => ids.toString()).includes(k_id)
-        );
-        if (!found) {
-          let seed: Topic;
-          seed = JSON.parse(JSON.stringify(t_default));
-          seed.id = null;
-          seed.name = k_t_name;
-          seed.kafkas = [];
-          seed.kafkas.push(k_id);
-          seed.config = false;
-          t_topics.push(seed);
-        }
-      });
-    });
-
-    return t_topics;
-  }
-
-  buttonAction(string: string = "") {
-    switch (string) {
-      case "new":
-        // Open new topic modal
-        console.log("new modal");
-        break;
+    switch (action) {
       case "edit":
-        // Open edit of topic modal
-        console.log("edit modal");
+        this.openModal("edit", id);
         break;
-      case "default":
-        // Open default config of topic modal
-        console.log("default modal");
-        break;
-      default:
-        this.notificationService.success(string + " action successful!");
+      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.deleteTopic(id).subscribe(
+            res => {
+              this.ngOnInit();
+              setTimeout(() => {
+                this.notificationService.success("SUCCESSFULLY_DELETED");
+              }, 500);
+            },
+            err => {
+              this.notificationService.error(err);
+            }
+          );
+          modalRef.close();
+        });
         break;
     }
   }
 
-  updateFilter(searchValue) {
+  openModal(mode: string = "", t_id: number | string) {
+    const modalRef = this.modalService.open(ModalComponent, {
+      size: "lg",
+      centered: true,
+      backdrop: "static"
+    });
+
+    switch (mode) {
+      case "new":
+        // Open new modal for topic
+        let newTopic: Topic;
+        newTopic = Object.assign({}, this.t_default);
+        newTopic.id = null;
+        newTopic.name = "";
+        let componentNew = new ModalContentData(TopicModalComponent, newTopic);
+
+        modalRef.componentInstance.title = "NEW_TOPIC";
+        modalRef.componentInstance.notice = "TOPIC_NEW_NOTICE";
+        modalRef.componentInstance.mode = "new";
+        modalRef.componentInstance.component = componentNew;
+
+        modalRef.componentInstance.passEntry.subscribe((data: Topic) => {
+          newTopic = Object.assign({}, data);
+          this.restApiService.addTopic(newTopic).subscribe(
+            res => {
+              this.ngOnInit();
+              setTimeout(() => {
+                this.notificationService.success("SUCCESSFULLY_CREARED");
+              }, 500);
+            },
+            err => {
+              this.notificationService.error(err);
+            }
+          );
+          modalRef.close();
+        });
+        break;
+      case "edit":
+        // Open edit modal for topic
+        let index: number = this.topics.findIndex(t => t.id === t_id);
+        let editTopic: Topic = this.topics[index];
+        let componentEdit = new ModalContentData(
+          TopicModalComponent,
+          editTopic
+        );
+
+        modalRef.componentInstance.title = editTopic.name;
+        modalRef.componentInstance.notice = "";
+        modalRef.componentInstance.mode = "edit";
+        modalRef.componentInstance.component = componentEdit;
+
+        modalRef.componentInstance.passEntry.subscribe((data: Topic) => {
+          editTopic = Object.assign({}, data);
+          this.restApiService.updateTopic(editTopic).subscribe(
+            res => {
+              // this.topics[index] = editTopic;
+              this.ngOnInit();
+              setTimeout(() => {
+                this.notificationService.success("SUCCESSFULLY_UPDATED");
+              }, 500);
+            },
+            err => {
+              this.notificationService.error(err);
+            }
+          );
+          modalRef.close();
+        });
+        break;
+      case "default":
+        // Open default config modal for topic
+        let componentDefault = new ModalContentData(
+          TopicModalComponent,
+          this.t_default
+        );
+
+        modalRef.componentInstance.title = "DEFAULT_CONFIGURATIONS";
+        modalRef.componentInstance.notice = "TOPIC_DEFAULT_CONF_NOTICE";
+        modalRef.componentInstance.mode = "edit";
+        modalRef.componentInstance.component = componentDefault;
+
+        modalRef.componentInstance.passEntry.subscribe((data: Topic) => {
+          this.t_default = Object.assign({}, data);
+          this.restApiService.updateTopic(this.t_default).subscribe(
+            res => {
+              this.notificationService.success("SUCCESSFULLY_UPDATED");
+            },
+            err => {
+              this.notificationService.error("FAILED_UPDATED");
+            }
+          );
+          modalRef.close();
+        });
+        break;
+    }
+  }
+
+  updateFilter(searchValue: string) {
     const val = searchValue.toLowerCase();
 
     // filter our data
@@ -246,266 +340,4 @@
     // update the rows
     this.topics = temp;
   }
-
-  // async initData() {
-  //   this.topicListFeeder = [];
-  //   this.topicListFeeder = await this.getTopicList("feeder");
-
-  //   //this.topicDefaultConfig = new Topic();
-  //   this.topicDefaultConfig = await this.getTopicDefaultConfig();
-
-  //   return true;
-  // }
-
-  // getTopicList(type: string) {
-  //   var data: any;
-
-  //   switch (type) {
-  //     case "feeder": {
-  //       data = this.restApiService.getTopicsFromFeeder().toPromise();
-  //       break;
-  //     }
-  //   }
-  //   return data;
-  // }
-
-  // getTopicDefaultConfig() {
-  //   return this.restApiService.getTopicDefaultConfig().toPromise();
-  // }
-
-  // async initTopicList(dmaapList: [], feederList: []) {
-  //   // var t: Topic[] = [];
-  //   // // dmaap has no topics, only show topic in db
-  //   // for (var i = 0; i < feederList.length; i++) {
-  //   //   let data = await this.getTopicDetail(feederList[i]);
-  //   //   let dbinfo = [];
-  //   //   var totalCB = 0;
-  //   //   var totalDRUID = 0;
-  //   //   var totalES = 0;
-  //   //   var totalHDFS = 0;
-  //   //   var totalMONGO = 0;
-  //   //   for (var x = 0; x < data.enabledSinkdbs.length; x++) {
-  //   //     let dbdata = await this.getDbDetail(data.enabledSinkdbs[x]);
-  //   //     dbinfo.push(dbdata);
-  //   //     if (dbinfo != undefined && dbinfo[x].type == "CB") {
-  //   //       totalCB = totalCB + 1;
-  //   //     } if (dbinfo != undefined && dbinfo[x].type == "DRUID") {
-  //   //       totalDRUID = totalDRUID + 1;
-  //   //     } if (dbinfo != undefined && dbinfo[x].type == "ES") {
-  //   //       totalES = totalES + 1;
-  //   //     } if (dbinfo != undefined && dbinfo[x].type == "HDFS") {
-  //   //       totalHDFS = totalHDFS + 1;
-  //   //     } if (dbinfo != undefined && dbinfo[x].type == "MONGO") {
-  //   //       totalMONGO = totalMONGO + 1;
-  //   //     }
-  //   //   }
-  //   //   let feed = {
-  //   //     name: data.name,
-  //   //     login: data.login,
-  //   //     password: data.password,
-  //   //     enabledSinkdbs: data.enabledSinkdbs,
-  //   //     sinkdbs: data.sinkdbs,
-  //   //     enabled: data.enabled,
-  //   //     saveRaw: data.saveRaw,
-  //   //     dataFormat: data.dataFormat,
-  //   //     ttl: data.ttl,
-  //   //     correlateClearedMessage: data.correlateClearedMessage,
-  //   //     messageIdPath: data.messageIdPath,
-  //   //     kafkas: data.kafkas.length,
-  //   //     type: data.type,
-  //   //     CB: totalCB,
-  //   //     DRUID: totalDRUID,
-  //   //     ES: totalES,
-  //   //     HDFS: totalHDFS,
-  //   //     MONGO: totalMONGO
-  //   //   };
-  //   //   t.push(feed);
-  //   // }
-  //   // return t;
-  // }
-
-  // onActivate(event) {
-  //   const emitType = event.type;
-  //   if (emitType == "dblclick") {
-  //     console.log("Activate Event", event);
-  //     let name = event.row.name;
-  //     this.openTopicModal(name);
-  //   }
-  // }
-
-  // openNewTopicModal() {
-  //   const modalRef = this.modalService.open(NewTopicModelComponent, {
-  //     size: "lg",
-  //     centered: true
-  //   });
-  //   modalRef.componentInstance.newTopic = this.tempNewTopic;
-  //   modalRef.componentInstance.passEntry.subscribe(receivedEntry => {
-  //     console.log(receivedEntry, "newtopic receivedEntry");
-  //     this.tempNewTopic = receivedEntry;
-  //     this.restApiService.addNewTopic(this.tempNewTopic).subscribe(
-  //       res => {
-  //         this.init();
-  //         this.notificationService.success("SUCCESSFULLY_CREARED");
-  //         modalRef.close();
-  //         this.updateFilter(this.searchText.nativeElement.value);
-  //       },
-  //       err => {
-  //         this.notificationService.error(err);
-  //         modalRef.close();
-  //         this.updateFilter(this.searchText.nativeElement.value);
-  //       }
-  //     );
-  //   });
-  // }
-
-  // openTopicModal(name: string) {
-  //   if (name == "config") {
-  //     const modalRef = this.modalService.open(TopicConfigModalComponent, {
-  //       windowClass: "dl-md-modal",
-  //       centered: true
-  //     });
-  //     modalRef.componentInstance.title = "Topics Default Configurations";
-  //     modalRef.componentInstance.topic = this.topicDefaultConfig;
-  //     modalRef.componentInstance.passEntry.subscribe(receivedEntry => {
-  //       this.restApiService
-  //         .updateTopicDefaultConfig(this.topicDefaultConfig)
-  //         .subscribe(
-  //           res => {
-  //             this.topicDefaultConfig = receivedEntry;
-  //             this.topics.forEach(t => {
-  //               if (!t.type) {
-  //                 // Unconfigure topics
-  //                 t.login = this.topicDefaultConfig.login;
-  //                 t.password = this.topicDefaultConfig.password;
-  //                 t.enabledSinkdbs = this.topicDefaultConfig.enabledSinkdbs;
-  //                 // t.sinkdbs = this.topicDefaultConfig.sinkdbs; //todo
-  //                 t.enabled = this.topicDefaultConfig.enabled;
-  //                 t.saveRaw = this.topicDefaultConfig.saveRaw;
-  //                 t.dataFormat = this.topicDefaultConfig.dataFormat;
-  //                 t.ttl = this.topicDefaultConfig.ttl;
-  //                 t.correlateClearedMessage = this.topicDefaultConfig.correlateClearedMessage;
-  //                 t.messageIdPath = this.topicDefaultConfig.messageIdPath;
-  //               }
-  //             });
-  //             this.notificationService.success("Success updated.");
-  //             modalRef.close();
-  //           },
-  //           err => {
-  //             this.notificationService.error(err);
-  //             modalRef.close();
-  //           }
-  //         );
-  //     });
-  //   } else {
-  //     const index = this.temp.findIndex(t => t.name === name);
-  //     const modalRef = this.modalService.open(TopicDetailModalComponent, {
-  //       size: "lg",
-  //       centered: true
-  //     });
-  //     modalRef.componentInstance.topic = this.temp[index];
-  //     modalRef.componentInstance.passEntry.subscribe(receivedEntry => {
-  //       this.tempTopicDetail = receivedEntry;
-  //       // Configured topic
-  //       if (this.tempTopicDetail.type) {
-  //         this.restApiService.getTopicsFromFeeder().subscribe(
-  //           res => {
-  //             if (res.find(name => name === this.tempTopicDetail.name)) {
-  //               // Update topic from db
-  //               this.restApiService.upadteTopic(this.tempTopicDetail).subscribe(
-  //                 res => {
-  //                   this.temp[index] = this.tempTopicDetail;
-  //                   this.topics = this.temp;
-  //                   this.notificationService.success("SUCCESSFULLY_UPDATED");
-  //                   modalRef.close();
-  //                   this.updateFilter(this.searchText.nativeElement.value);
-  //                 },
-  //                 err => {
-  //                   this.notificationService.error(err);
-  //                   modalRef.close();
-  //                   this.updateFilter(this.searchText.nativeElement.value);
-  //                 }
-  //               );
-  //             } else {
-  //               // Insert topic from db
-  //               this.restApiService.addTopic(this.tempTopicDetail).subscribe(
-  //                 res => {
-  //                   this.init();
-  //                   this.notificationService.success("SUCCESSFULLY_CREARED");
-  //                   modalRef.close();
-  //                   this.updateFilter(this.searchText.nativeElement.value);
-  //                 },
-  //                 err => {
-  //                   this.notificationService.error(err);
-  //                   modalRef.close();
-  //                   this.updateFilter(this.searchText.nativeElement.value);
-  //                 }
-  //               );
-  //             }
-  //           },
-  //           err => {
-  //             this.notificationService.error(err);
-  //             modalRef.close();
-  //           }
-  //         );
-  //       } else {
-  //         // Reset to default and delete topic from db
-  //         this.restApiService.deleteTopic(this.tempTopicDetail.name).subscribe(
-  //           res => {
-  //             this.init();
-  //             this.notificationService.success("SUCCESSFULLY_DELETED");
-  //             modalRef.close();
-  //             this.updateFilter(this.searchText.nativeElement.value);
-  //           },
-  //           err => {
-  //             this.notificationService.error(err);
-  //             modalRef.close();
-  //             this.updateFilter(this.searchText.nativeElement.value);
-  //           }
-  //         );
-  //       }
-  //     });
-  //   }
-  // }
-
-  // deleteTopicModal(name: string) {
-  //   const index = this.temp.findIndex(t => t.name === name);
-  //   const modalRef = this.modalService.open(AlertComponent, {
-  //     size: "sm",
-  //     centered: true
-  //   });
-  //   modalRef.componentInstance.message = "ARE_YOU_SURE_DELETE";
-  //   console.log(this.temp[index]);
-  //   modalRef.componentInstance.passEntry.subscribe(receivedEntry => {
-  //     this.restApiService.deleteTopic(this.temp[index].name).subscribe(
-  //       res => {
-  //         this.init();
-  //         this.notificationService.success("SUCCESSFULLY_DELETED");
-  //         modalRef.close();
-  //         this.updateFilter(this.searchText.nativeElement.value);
-  //       },
-  //       err => {
-  //         this.notificationService.error(err);
-  //         modalRef.close();
-  //         this.updateFilter(this.searchText.nativeElement.value);
-  //       }
-  //     );
-  //   });
-  // }
-
-  // getTopicDetail(id) {
-  //   return this.restApiService.getTopicDetail(id).toPromise();
-  // }
-
-  // getDbDetail(id) {
-  //   return this.restApiService.getDbDetail(id).toPromise();
-  // }
-
-  // GroupByDbType = (array, key) => {
-  //   return array.reduce((result, currentValue) => {
-  //     (result[currentValue.type] = result[currentValue.type] || []).push(
-  //       currentValue
-  //     );
-  //     return result;
-  //   }, {});
-  // };
 }
diff --git a/components/datalake-handler/admin/src/src/app/views/topics/topic-list/topic-modal/topic-modal.component.css b/components/datalake-handler/admin/src/src/app/views/topics/topic-list/topic-modal/topic-modal.component.css
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/components/datalake-handler/admin/src/src/app/views/topics/topic-list/topic-modal/topic-modal.component.css
@@ -0,0 +1 @@
+
diff --git a/components/datalake-handler/admin/src/src/app/views/topics/topic-list/topic-modal/topic-modal.component.html b/components/datalake-handler/admin/src/src/app/views/topics/topic-list/topic-modal/topic-modal.component.html
new file mode 100644
index 0000000..f5f3a7e
--- /dev/null
+++ b/components/datalake-handler/admin/src/src/app/views/topics/topic-list/topic-modal/topic-modal.component.html
@@ -0,0 +1,213 @@
+<!--
+============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=========================================================
+-->
+
+<mat-tab-group #tabRef [selectedIndex]="this.selectedIndex" (click)="this.onClickMatTab(tabRef.selectedIndex)"
+  mat-align-tabs="center">
+  <mat-tab label="Information">
+    <div class="container p-4">
+      <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">{{ "STATUS" | translate }}</label>
+          </div>
+        </div>
+        <div class="row">
+          <div class="col-md-6">
+            <!-- For new topic -->
+            <div *ngIf="isAddingMode()">
+              <input id="tname" type="text" class="form-control dl-input-text" [(ngModel)]="this.data.name"
+                [ngbTypeahead]="search" (focus)="focus$.next($event.target.value)"
+                (click)="click$.next($event.target.value)" #instance="ngbTypeahead" />
+            </div>
+            <!-- For modified topic -->
+            <div *ngIf="!isAddingMode()">
+              <input [(ngModel)]="this.data.name" [disabled]="true" class="form-control dl-input-text" type="text" />
+            </div>
+          </div>
+
+          <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>
+      </div>
+
+      <div class="form-group">
+        <div class="row">
+          <div class="col-md-6">
+            <label class="dl-emphasis1">{{ "DATA_FORMAT" | translate }}</label>
+          </div>
+          <div class="col-md-6">
+            <label class="dl-emphasis1">{{ "TTL" | translate }} (days)</label>
+          </div>
+        </div>
+        <div class="row">
+          <div class="col-md-6">
+            <select [(ngModel)]="this.data.dataFormat" class="custom-select dl-input-text">
+              <option *ngFor="let item of dataFormats" [selected]="item == this.data.dataFormat">
+                {{ item }}
+              </option>
+            </select>
+          </div>
+          <div class="col-md-6">
+            <input [(ngModel)]="this.data.ttl" class="form-control dl-input-text" type="text" placeholder="3650"
+              (input)="this.adminService.onKeyPressNumber($event)" />
+          </div>
+        </div>
+      </div>
+
+      <div class="form-group">
+        <div class="row">
+          <div class="col-md-6">
+            <label class="dl-emphasis1">{{
+              "SAVE_RAW_DATA" | translate
+            }}</label>
+          </div>
+          <div class="col-md-6">
+            <label class="dl-emphasis1">{{
+              "CORRELATE_CLEARED_MESSAGE" | translate
+            }}</label>
+          </div>
+        </div>
+        <div class="row">
+          <div class="col-md-6">
+            <div class="input-group">
+              <div class="input-group-prepend">
+                <label class="input-group-text dl-input-chk-label">
+                  <input [(ngModel)]="this.data.saveRaw" id="chkSaveRaw" type="checkbox" />
+                  <span class="dl-input-checkmark"></span>
+                </label>
+              </div>
+              <label class="form-control dl-input-chk" for="chkSaveRaw">
+                Save
+              </label>
+            </div>
+          </div>
+          <div class="col-md-6">
+            <div class="input-group">
+              <div class="input-group-prepend">
+                <label class="input-group-text dl-input-chk-label">
+                  <input [(ngModel)]="this.data.correlateClearedMessage" id="chkMsg" type="checkbox" />
+                  <span class="dl-input-checkmark"></span>
+                </label>
+              </div>
+              <label class="form-control dl-input-chk" for="chkMsg">
+                Correlate
+              </label>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <div class="form-group">
+        <div class="row">
+          <div class="col-md-6">
+            <label class="dl-emphasis1">{{
+              "ID_EXTRACTION" | translate
+            }}</label>
+          </div>
+        </div>
+        <div class="row">
+          <div class="col-md-9">
+            <div class="d-flex row align-items-center" *ngFor="let field of idExFields; let i = index">
+              <div class="col-md-8 order-1">
+                <input [(ngModel)]="field.item" class="form-control dl-input-text" placeholder="/event-header/id"
+                  type="text" [value]="field.item" (change)="onChangeSaveIdField()" />
+              </div>
+              <div class="order-2">
+                <button type="button" class="btn dl-icon-enable p-2" (click)="onClickAddIdField(i)">
+                  <i class="fa fa-plus fa-xs" aria-hidden="true"></i>
+                </button>
+              </div>
+              <div class="order-3">
+                <button type="button" class="btn dl-icon-enable p-2" (click)="onClickDelIdField(i)">
+                  <i class="fa fa-trash fa-xs" aria-hidden="true"></i>
+                </button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </mat-tab>
+
+  <mat-tab label="Kafka">
+    <div class="container p-4">
+      <div class="form-group" *ngFor="let item of this.kafkas; let i = index">
+        <div class="row">
+          <div class="col-md-6">
+            <div class="input-group">
+              <div class="input-group">
+                <div class="input-group-prepend">
+                  <label class="input-group-text dl-input-chk-label">
+                    <input id="chkSaveRaw{{ i }}" [(ngModel)]="item.checkedToSave" type="checkbox" (change)="
+                        this.onChabgeSelKafka($event.target.checked, item.id)
+                      " />
+                    <span class="dl-input-checkmark"></span>
+                  </label>
+                </div>
+                <label class="form-control dl-input-chk" for="chkSaveRaw{{ i }}">
+                  {{ item.name }}
+                </label>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </mat-tab>
+
+  <mat-tab label="Sink">
+    <div class="container p-4">
+      <div class="form-group" *ngFor="let dbType of this.dbTypeIds">
+        <div class="row">
+          <div class="col-md-6">
+            <label class="dl-emphasis1">{{ dbType }}</label>
+          </div>
+        </div>
+
+        <div class="row" *ngFor="let db of this.dbs; let i = index">
+          <div class="col-md-6 p-1" *ngIf="db.dbTypeId == dbType">
+            <div class="input-group">
+              <div class="input-group">
+                <div class="input-group-prepend">
+                  <label class="input-group-text dl-input-chk-label">
+                    <input id="chkSaveRaw{{ i }}" [(ngModel)]="db.checkedToSave" type="checkbox" (change)="
+                        this.onChabgeSelDb($event.target.checked, db.id)
+                      " />
+                    <span class="dl-input-checkmark"></span>
+                  </label>
+                </div>
+                <label class="form-control dl-input-chk" for="chkSaveRaw{{ i }}">
+                  {{ db.name }}
+                </label>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </mat-tab>
+</mat-tab-group>
diff --git a/components/datalake-handler/admin/src/src/app/views/topics/topic-list/topic-modal/topic-modal.component.spec.ts b/components/datalake-handler/admin/src/src/app/views/topics/topic-list/topic-modal/topic-modal.component.spec.ts
new file mode 100644
index 0000000..a856a75
--- /dev/null
+++ b/components/datalake-handler/admin/src/src/app/views/topics/topic-list/topic-modal/topic-modal.component.spec.ts
@@ -0,0 +1,50 @@
+/*
+ * ============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 { async, ComponentFixture, TestBed } from "@angular/core/testing";
+
+import { TopicModalComponent } from "./topic-modal.component";
+
+describe("TopicModalComponent", () => {
+  let component: TopicModalComponent;
+  let fixture: ComponentFixture<TopicModalComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [TopicModalComponent]
+    }).compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(TopicModalComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it("should create", () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/components/datalake-handler/admin/src/src/app/views/topics/topic-list/topic-modal/topic-modal.component.ts b/components/datalake-handler/admin/src/src/app/views/topics/topic-list/topic-modal/topic-modal.component.ts
new file mode 100644
index 0000000..3f0223e
--- /dev/null
+++ b/components/datalake-handler/admin/src/src/app/views/topics/topic-list/topic-modal/topic-modal.component.ts
@@ -0,0 +1,262 @@
+/*
+ * ============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 { NgbActiveModal, NgbTypeahead } 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 { Topic } from "src/app/core/models/topic.model";
+import {
+  debounceTime,
+  distinctUntilChanged,
+  filter,
+  map,
+  mergeMap
+} from "rxjs/operators";
+import { from, Subject, Observable, merge } from "rxjs";
+import { Kafka } from "src/app/core/models/kafka.model";
+import { Db } from "src/app/core/models/db.model";
+
+@Component({
+  selector: "app-topic-modal",
+  templateUrl: "./topic-modal.component.html",
+  styleUrls: ["./topic-modal.component.css"]
+})
+export class TopicModalComponent implements OnInit {
+  @Input() data: Topic;
+  @Input() mode: string;
+  @Input() selectedIndex: number;
+
+  dataFormats: Array<string> = ["JSON", "XML"];
+  idExFields: Array<any> = [];
+  idExNewField: any = {};
+
+  kafkas: Array<Kafka> = [];
+  dbs: Array<Db> = [];
+  dbTypeIds: Array<string> = [];
+
+  // Autocomplete input
+  @ViewChild("instance") instance: NgbTypeahead;
+  focus$ = new Subject<string>();
+  click$ = new Subject<string>();
+  newTopicList: Array<string>;
+
+  search = (text$: Observable<string>) => {
+    const debouncedText$ = text$.pipe(
+      debounceTime(200),
+      distinctUntilChanged()
+    );
+    const clicksWithClosedPopup$ = this.click$.pipe(
+      filter(() => !this.instance.isPopupOpen())
+    );
+    const inputFocus$ = this.focus$;
+
+    return merge(debouncedText$, inputFocus$, clicksWithClosedPopup$).pipe(
+      map(term =>
+        (term === ""
+          ? this.newTopicList
+          : this.newTopicList.filter(
+              v => v.toLowerCase().indexOf(term.toLowerCase()) > -1
+            )
+        ).slice(0, 10)
+      )
+    );
+  };
+
+  constructor(
+    public activeModal: NgbActiveModal,
+    public adminService: AdminService,
+    private restApiService: RestApiService
+  ) {}
+
+  ngOnInit() {
+    // Get ID extration field
+    this.idExFields = [];
+    if (this.data.messageIdPath != null) {
+      let feed = this.data.messageIdPath.split(",");
+      for (let i = 0; i < feed.length; i++) {
+        let data = { item: feed[i] };
+        this.idExFields.push(data);
+      }
+    } else {
+      this.idExFields.push([]);
+    }
+
+    // Init data
+    this.initData();
+  }
+
+  initData() {
+    this.getKafkas();
+    this.getDbs();
+
+    if (this.mode === "new") {
+      this.getNewTopicList();
+    }
+  }
+
+  getKafkas() {
+    const get_kafkas = this.restApiService.getAllKafka().pipe(
+      mergeMap(ks => from(ks)),
+      map(k => {
+        if (
+          this.data.kafkas &&
+          this.data.kafkas.toString().includes(k.id.toString())
+        ) {
+          k.checkedToSave = true;
+        } else {
+          k.checkedToSave = false;
+        }
+        this.kafkas.push(k);
+      })
+    );
+
+    get_kafkas.subscribe();
+  }
+
+  getDbs() {
+    const get_dbs = this.restApiService.getAllDbs().pipe(
+      mergeMap(dbs => from(dbs)),
+      map(db => {
+        if (!this.dbTypeIds.includes(db.dbTypeId)) {
+          this.dbTypeIds.push(db.dbTypeId);
+        }
+        if (
+          this.data.sinkdbs &&
+          this.data.sinkdbs.toString().includes(db.id.toString())
+        ) {
+          db.checkedToSave = true;
+        } else {
+          db.checkedToSave = false;
+        }
+        this.dbs.push(db);
+      })
+    );
+
+    get_dbs.subscribe();
+  }
+
+  getNewTopicList() {
+    const get_topicName = this.restApiService.getTopicNames().pipe(
+      map(names => {
+        this.newTopicList = names;
+      })
+    );
+
+    get_topicName.subscribe();
+  }
+
+  onChabgeSelKafka(checked: boolean, id: string | number) {
+    // Array initialize
+    if (!this.data.kafkas) this.data.kafkas = [];
+
+    if (checked) {
+      // Add kafka_id into topic.kafkas
+      if (
+        this.data.kafkas &&
+        !this.data.kafkas.toString().includes(id.toString())
+      ) {
+        this.data.kafkas.push(id.toString());
+      }
+    } else {
+      // Remove kafka_id from topic.kafkas
+      if (
+        this.data.kafkas &&
+        this.data.kafkas.toString().includes(id.toString())
+      ) {
+        this.data.kafkas.forEach((k_id, index) => {
+          if (k_id.toString() === id.toString()) {
+            this.data.kafkas.splice(index, 1);
+            return;
+          }
+        });
+      }
+    }
+  }
+
+  onChabgeSelDb(checked: boolean, id: string | number) {
+    // Array initialize
+    if (!this.data.sinkdbs) this.data.sinkdbs = [];
+
+    if (checked) {
+      // Add db_id into topic.sinkdbs
+      if (
+        this.data.sinkdbs &&
+        !this.data.sinkdbs.toString().includes(id.toString())
+      ) {
+        this.data.sinkdbs.push(id.toString());
+      }
+    } else {
+      // Remove db_id from "topic.sinkdbs"
+      if (
+        this.data.sinkdbs &&
+        this.data.sinkdbs.toString().includes(id.toString())
+      ) {
+        this.data.sinkdbs.forEach((db_id, index) => {
+          if (db_id.toString() === id.toString()) {
+            this.data.sinkdbs.splice(index, 1);
+            return;
+          }
+        });
+      }
+    }
+  }
+
+  onClickAddIdField() {
+    this.idExFields.push(this.idExNewField);
+    this.idExNewField = {};
+  }
+
+  onClickDelIdField(index: number) {
+    if (this.idExFields.length > 1) {
+      this.idExFields.splice(index, 1);
+    }
+  }
+
+  onChangeSaveIdField() {
+    this.data.messageIdPath = "";
+    for (let i = 0; i < this.idExFields.length; i++) {
+      if (i == 0) {
+        this.data.messageIdPath = this.idExFields[i].item;
+      } else {
+        this.data.messageIdPath += "," + this.idExFields[i].item;
+      }
+    }
+  }
+
+  onClickMatTab(index: number) {
+    this.selectedIndex = index;
+  }
+
+  isAddingMode() {
+    let flag: boolean = false;
+
+    if (this.mode === "new") flag = true;
+
+    return flag;
+  }
+}
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 13872a4..1165461 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
@@ -1,6 +1,6 @@
 {
   "SIDEBAR": {
-    "FEEDER": "DataLake Feeder",
+    "FEEDFER": "DataLake Feeder",
     "KAFKA": "Kafka",
     "TOPICS": "Topics",
     "DATABASE": "Database",
@@ -11,7 +11,7 @@
   },
   "NAME": "Name",
   "STATUS": "Status",
-  "SINK": "Target",
+  "SINK": "Sink",
   "AUTHENTICATION": "Authentication",
   "DATA_FORMAT": "Data format",
   "TTL": "TTL",
@@ -35,6 +35,7 @@
   "ERROR_CODE": "Error Code",
   "SUCCESS_UPDATED": "Success updated",
   "TOPIC_DEFAULT_CONF_NOTICE": "Notice: This topic uses the default topics settings.",
+  "TOPIC_NEW_NOTICE": "Notice: A new topic will be created.",
   "HOME": "Home",
   "ConfigDashboard": "Config Portal",
   "EDIT": "Edit",
@@ -56,7 +57,7 @@
   "NODATA": "No Data",
   "NEW_TEMPLATE": "New design",
   "TEMPLATE_BODY": "Body",
-  "FIELUPLOAD": "Select File ...",
+  "FIELUPLOAD": "Import",
   "SUCCESSFULLY_CREARED": "Successfully created.",
   "FAILED_CREARED": "Failed updated.",
   "SUCCESSFULLY_UPDATED": "Successfully updated.",
@@ -83,6 +84,5 @@
   "NEW_HDFS": "New Hdfs",
   "SECURE_COMMUNICATION": "Secure Communication",
   "NEW_TOOL": "New Tool",
-  "NEW_KIBANA": "New Kibana",
-  "DATABASE": "Database"
+  "NEW_KIBANA": "New Kibana"
 }
diff --git a/components/datalake-handler/admin/src/src/assets/i18n/zh-hans.json b/components/datalake-handler/admin/src/src/assets/i18n/zh-hans.json
index 0ba8503..cce513b 100644
--- a/components/datalake-handler/admin/src/src/assets/i18n/zh-hans.json
+++ b/components/datalake-handler/admin/src/src/assets/i18n/zh-hans.json
@@ -1,40 +1,41 @@
 {
   "SIDEBAR": {
-    "FEEDER": "DataLake Feeder",
+    "FEEDFER": "DataLake Feeder",
     "TOPICS": "Topics",
-    "KAFKA":"Kafka",
+    "KAFKA": "卡夫卡",
     "DATABASE": "Database",
-    "DASHBOARD": "工具设置",
-    "DASHBOARDLIST": "工具",
+    "DASHBOARD": "仪表板设置",
+    "DASHBOARDLIST": "仪表板",
     "TEMPLATE": "模板",
     "ABOUT": "About"
   },
   "NAME": "名称",
   "STATUS": "状态",
   "SINK": "数据库",
-  "AUTHENTICATION": "身份验证​",
+  "AUTHENTICATION": "身份验证",
   "DATA_FORMAT": "数据格式",
   "TTL": "失效时间(天)",
   "SAVE_RAW_DATA": "保存原始数据",
-  "CORRELATE_CLEARED_MESSAGE": "关联已清除的消息​",
-  "DEFAULT_CONFIGURATIONS": "默认配置​",
-  "ID_EXTRACTION": "ID提取​",
+  "CORRELATE_CLEARED_MESSAGE": "关联已清除的消息",
+  "DEFAULT_CONFIGURATIONS": "默认配置",
+  "ID_EXTRACTION": "ID提取",
   "CONFIGURED": "已配置",
-  "UNCONFIGURED": "未配置​",
+  "UNCONFIGURED": "未配置",
   "NEW_TOPIC": "新建主题",
-  "DATABASE_CONNECTIONS": "数据库连接​",
+  "DATABASE_CONNECTIONS": "数据库连接",
   "BUCKET": "Bucket",
-  "HOST": "主机​",
-  "PORT": "端口​",
-  "ENABLE_SSL": "加密通信​",
-  "VERIFY": "验证​",
+  "HOST": "主机",
+  "PORT": "端口",
+  "ENABLE_SSL": "加密通信",
+  "VERIFY": "验证",
   "SETTING": "设置",
   "DOCUMENT_STORE": "文档存储",
   "SEARCH_ENGINE": "搜索引擎",
   "DELETE": "删除",
-  "ERROR_CODE": "错误代码​",
-  "SUCCESS_UPDATED": "更新成功​",
-  "TOPIC_DEFAULT_CONF_NOTICE": "注意: 本Topic使用默认Topic设置。​",
+  "ERROR_CODE": "错误代码",
+  "SUCCESS_UPDATED": "更新成功",
+  "TOPIC_DEFAULT_CONF_NOTICE": "注意: 本Topic使用默认Topic设置",
+  "TOPIC_NEW_NOTICE": "注意: 一个新Topic将会被创建",
   "HOME": "首页",
   "ConfigDashboard": "配置仪表板",
   "EDIT": "编辑",
@@ -65,5 +66,5 @@
   "FAILED_DELETED": "删除失败",
   "Deploy_SUCCESSFULLY": "部署成功",
   "Deploy_FAILED": "部署失败",
-  "ARE_YOU_SURE_DELETE": "您确定您要删除吗?"
-}
\ No newline at end of file
+  "ARE_YOU_SURE_DELETE": "您确定您要删除吗?"
+}
diff --git a/components/datalake-handler/admin/src/src/assets/i18n/zh-hant.json b/components/datalake-handler/admin/src/src/assets/i18n/zh-hant.json
index a3649be..88c2c8f 100644
--- a/components/datalake-handler/admin/src/src/assets/i18n/zh-hant.json
+++ b/components/datalake-handler/admin/src/src/assets/i18n/zh-hant.json
@@ -1,40 +1,41 @@
 {
   "SIDEBAR": {
-    "FEEDER": "DataLake Feeder",
-    "KAFKA":"Kafka",
+    "FEEDFER": "DataLake Feeder",
+    "KAFKA": "卡夫卡",
     "TOPICS": "Topics",
     "DATABASE": "Database",
-    "DASHBOARD": "工具設置",
-    "DASHBOARDLIST": "工具",
+    "DASHBOARD": "儀表板設置",
+    "DASHBOARDLIST": "儀表板",
     "TEMPLATE": "模板",
     "ABOUT": "About"
   },
   "NAME": "名稱",
-  "STATUS": "狀態​",
+  "STATUS": "狀態",
   "SINK": "資料庫",
-  "AUTHENTICATION": "身份驗證​",
-  "DATA_FORMAT": "檔案格式​",
-  "TTL": "存活時間​(天)",
-  "SAVE_RAW_DATA": "保存原始資料​",
-  "CORRELATE_CLEARED_MESSAGE": "關聯已清除的訊息​",
-  "DEFAULT_CONFIGURATIONS": "預設配置​",
-  "ID_EXTRACTION": "ID提取​",
+  "AUTHENTICATION": "身份驗證",
+  "DATA_FORMAT": "檔案格式",
+  "TTL": "存活時間(天)",
+  "SAVE_RAW_DATA": "保存原始資料",
+  "CORRELATE_CLEARED_MESSAGE": "關聯已清除的訊息",
+  "DEFAULT_CONFIGURATIONS": "預設配置",
+  "ID_EXTRACTION": "ID提取",
   "CONFIGURED": "已配置",
-  "UNCONFIGURED": "未配置​",
+  "UNCONFIGURED": "未配置",
   "NEW_TOPIC": "新建主題",
-  "DATABASE_CONNECTIONS": "資料庫連線​",
+  "DATABASE_CONNECTIONS": "資料庫連線",
   "BUCKET": "Bucket",
   "HOST": "主機",
   "PORT": "埠",
-  "ENABLE_SSL": "加密通信​",
-  "VERIFY": "驗證​",
+  "ENABLE_SSL": "加密通信",
+  "VERIFY": "驗證",
   "SETTING": "設定",
   "DOCUMENT_STORE": "文檔儲存",
   "SEARCH_ENGINE": "搜尋引擎",
   "DELETE": "刪除",
   "ERROR_CODE": "錯誤代碼",
-  "SUCCESS_UPDATED": "更新成功​",
-  "TOPIC_DEFAULT_CONF_NOTICE": "注意:此Topic目前使用預設配置。​",
+  "SUCCESS_UPDATED": "更新成功",
+  "TOPIC_DEFAULT_CONF_NOTICE": "注意: 此Topic目前使用預設配置",
+  "TOPIC_NEW_NOTICE": "注意: 一個新Topic將會被新增",
   "HOME": "首頁",
   "ConfigDashboard": "配置儀表板",
   "EDIT": "編輯",
@@ -65,5 +66,5 @@
   "FAILED_DELETED": "删除失败",
   "Deploy_SUCCESSFULLY": "部署成功",
   "Deploy_FAILED": "部署失败",
-  "ARE_YOU_SURE_DELETE": "您確定您要刪除嗎?"
-}
\ No newline at end of file
+  "ARE_YOU_SURE_DELETE": "您確定您要刪除嗎?"
+}
diff --git a/components/datalake-handler/admin/src/src/styles.css b/components/datalake-handler/admin/src/src/styles.css
index 096bd22..64cc8ea 100644
--- a/components/datalake-handler/admin/src/src/styles.css
+++ b/components/datalake-handler/admin/src/src/styles.css
@@ -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.
@@ -25,6 +25,8 @@
  *
  */
 
+@import "~@angular/material/prebuilt-themes/indigo-pink.css";
+
 html {
   height: 100%;
 }
@@ -235,6 +237,16 @@
   line-height: 27px;
 }
 
+/* override mat-tab active color*/
+.mat-tab-label-active {
+  color: #5dbebb;
+}
+
+.mat-tab-group.mat-primary .mat-ink-bar,
+.mat-tab-nav-bar.mat-primary .mat-ink-bar {
+  background: #5dbebb;
+}
+
 .dl-icon-enable {
   color: #5dbebb;
 }
@@ -642,18 +654,30 @@
   color: #BDBEC0
 }
 
+/* placeholder */
 input::-webkit-input-placeholder {
-  color: #313032 !important;
+  color: #c1bdc5 !important;
+  opacity: 1;
 }
 
 :-moz-placeholder {
-  color: #313032 !important;
+  color: #c1bdc5 !important;
+  opacity: 1;
 }
 
 ::-moz-placeholder {
-  color: #313032 !important;
+  color: #c1bdc5 !important;
+  opacity: 1;
 }
 
 :-ms-input-placeholder {
-  color: #313032 !important;
+  color: #c1bdc5 !important;
+  opacity: 1;
+}
+
+::placeholder {
+  /* Chrome, Firefox, Opera, Safari 10.1+ */
+  color: #c1bdc5;
+  opacity: 1;
+  /* Firefox */
 }