summaryrefslogtreecommitdiffstats
path: root/components/datalake-handler/admin/src/app
diff options
context:
space:
mode:
authorEkko Chang <ekko.chang@qct.io>2019-04-29 14:14:58 +0800
committerEkko Chang <ekko.chang@qct.io>2019-04-29 14:14:58 +0800
commitc4c381d400abc54a0deb14ee828c51aed6d16873 (patch)
tree043bb32228ab78b11eb16e70fcc89ed368d72b94 /components/datalake-handler/admin/src/app
parentc0cc89e2acb5f702f03e932dcd6a75ba8aba4618 (diff)
First commit of front-end admin UI
1. framework of front-end Issue-ID: DCAEGEN2-1188 Change-Id: Ib42e20f87f3f4fa5f0aee65c88b1efbfe1523b93 Signed-off-by: Ekko Chang <ekko.chang@qct.io>
Diffstat (limited to 'components/datalake-handler/admin/src/app')
-rw-r--r--components/datalake-handler/admin/src/app/app-routing.module.ts23
-rw-r--r--components/datalake-handler/admin/src/app/app.component.css0
-rw-r--r--components/datalake-handler/admin/src/app/app.component.html23
-rw-r--r--components/datalake-handler/admin/src/app/app.component.spec.ts35
-rw-r--r--components/datalake-handler/admin/src/app/app.component.ts9
-rw-r--r--components/datalake-handler/admin/src/app/app.module.ts82
-rw-r--r--components/datalake-handler/admin/src/app/core/models/DB/db.model.ts8
-rw-r--r--components/datalake-handler/admin/src/app/core/models/Topic/topic.model.ts14
-rw-r--r--components/datalake-handler/admin/src/app/core/services/header.service.spec.ts12
-rw-r--r--components/datalake-handler/admin/src/app/core/services/header.service.ts13
-rw-r--r--components/datalake-handler/admin/src/app/core/services/rest-api.service.spec.ts12
-rw-r--r--components/datalake-handler/admin/src/app/core/services/rest-api.service.ts52
-rw-r--r--components/datalake-handler/admin/src/app/database/database-list/database-add-modal/database-add-modal.component.css1
-rw-r--r--components/datalake-handler/admin/src/app/database/database-list/database-add-modal/database-add-modal.component.html59
-rw-r--r--components/datalake-handler/admin/src/app/database/database-list/database-add-modal/database-add-modal.component.spec.ts25
-rw-r--r--components/datalake-handler/admin/src/app/database/database-list/database-add-modal/database-add-modal.component.ts73
-rw-r--r--components/datalake-handler/admin/src/app/database/database-list/database-list.component.css14
-rw-r--r--components/datalake-handler/admin/src/app/database/database-list/database-list.component.html22
-rw-r--r--components/datalake-handler/admin/src/app/database/database-list/database-list.component.spec.ts25
-rw-r--r--components/datalake-handler/admin/src/app/database/database-list/database-list.component.ts118
-rw-r--r--components/datalake-handler/admin/src/app/database/database-list/dbs-modal/couchbase/couchbase.component.css0
-rw-r--r--components/datalake-handler/admin/src/app/database/database-list/dbs-modal/couchbase/couchbase.component.html80
-rw-r--r--components/datalake-handler/admin/src/app/database/database-list/dbs-modal/couchbase/couchbase.component.spec.ts25
-rw-r--r--components/datalake-handler/admin/src/app/database/database-list/dbs-modal/couchbase/couchbase.component.ts13
-rw-r--r--components/datalake-handler/admin/src/app/database/database-list/dbs-modal/druid/druid.component.css0
-rw-r--r--components/datalake-handler/admin/src/app/database/database-list/dbs-modal/druid/druid.component.html78
-rw-r--r--components/datalake-handler/admin/src/app/database/database-list/dbs-modal/druid/druid.component.spec.ts25
-rw-r--r--components/datalake-handler/admin/src/app/database/database-list/dbs-modal/druid/druid.component.ts13
-rw-r--r--components/datalake-handler/admin/src/app/database/database-list/dbs-modal/elasticsearch/elasticsearch.component.css0
-rw-r--r--components/datalake-handler/admin/src/app/database/database-list/dbs-modal/elasticsearch/elasticsearch.component.html69
-rw-r--r--components/datalake-handler/admin/src/app/database/database-list/dbs-modal/elasticsearch/elasticsearch.component.spec.ts25
-rw-r--r--components/datalake-handler/admin/src/app/database/database-list/dbs-modal/elasticsearch/elasticsearch.component.ts13
-rw-r--r--components/datalake-handler/admin/src/app/database/database-list/dbs-modal/mongodb/mongodb.component.css0
-rw-r--r--components/datalake-handler/admin/src/app/database/database-list/dbs-modal/mongodb/mongodb.component.html78
-rw-r--r--components/datalake-handler/admin/src/app/database/database-list/dbs-modal/mongodb/mongodb.component.spec.ts25
-rw-r--r--components/datalake-handler/admin/src/app/database/database-list/dbs-modal/mongodb/mongodb.component.ts15
-rw-r--r--components/datalake-handler/admin/src/app/database/database.component.css0
-rw-r--r--components/datalake-handler/admin/src/app/database/database.component.html7
-rw-r--r--components/datalake-handler/admin/src/app/database/database.component.spec.ts25
-rw-r--r--components/datalake-handler/admin/src/app/database/database.component.ts15
-rw-r--r--components/datalake-handler/admin/src/app/feeder/feeder.component.css27
-rw-r--r--components/datalake-handler/admin/src/app/feeder/feeder.component.html59
-rw-r--r--components/datalake-handler/admin/src/app/feeder/feeder.component.spec.ts25
-rw-r--r--components/datalake-handler/admin/src/app/feeder/feeder.component.ts20
-rw-r--r--components/datalake-handler/admin/src/app/header/header.component.css1
-rw-r--r--components/datalake-handler/admin/src/app/header/header.component.html10
-rw-r--r--components/datalake-handler/admin/src/app/header/header.component.spec.ts25
-rw-r--r--components/datalake-handler/admin/src/app/header/header.component.ts38
-rw-r--r--components/datalake-handler/admin/src/app/sidebar/sidebar.component.css0
-rw-r--r--components/datalake-handler/admin/src/app/sidebar/sidebar.component.html34
-rw-r--r--components/datalake-handler/admin/src/app/sidebar/sidebar.component.spec.ts25
-rw-r--r--components/datalake-handler/admin/src/app/sidebar/sidebar.component.ts12
-rw-r--r--components/datalake-handler/admin/src/app/topics/topic-list/topic-list.component.css5
-rw-r--r--components/datalake-handler/admin/src/app/topics/topic-list/topic-list.component.html421
-rw-r--r--components/datalake-handler/admin/src/app/topics/topic-list/topic-list.component.spec.ts24
-rw-r--r--components/datalake-handler/admin/src/app/topics/topic-list/topic-list.component.ts189
-rw-r--r--components/datalake-handler/admin/src/app/topics/topics.component.css0
-rw-r--r--components/datalake-handler/admin/src/app/topics/topics.component.html27
-rw-r--r--components/datalake-handler/admin/src/app/topics/topics.component.spec.ts25
-rw-r--r--components/datalake-handler/admin/src/app/topics/topics.component.ts16
60 files changed, 2109 insertions, 0 deletions
diff --git a/components/datalake-handler/admin/src/app/app-routing.module.ts b/components/datalake-handler/admin/src/app/app-routing.module.ts
new file mode 100644
index 00000000..50802a6b
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/app-routing.module.ts
@@ -0,0 +1,23 @@
+import { NgModule } from "@angular/core";
+import { Routes, RouterModule } from "@angular/router";
+
+import { FeederComponent } from "./feeder/feeder.component";
+import { TopicsComponent } from "./topics/topics.component";
+import { DatabaseComponent } from "./database/database.component";
+
+const routes: Routes = [
+ { path: "", redirectTo: "/feeder", pathMatch: "full" },
+ { path: "feeder", component: FeederComponent },
+ { path: "topics", component: TopicsComponent },
+ { path: "database", component: DatabaseComponent }
+];
+
+@NgModule({
+ imports: [
+ RouterModule.forRoot(routes, {
+ useHash: true
+ })
+ ],
+ exports: [RouterModule]
+})
+export class AppRoutingModule {}
diff --git a/components/datalake-handler/admin/src/app/app.component.css b/components/datalake-handler/admin/src/app/app.component.css
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/app.component.css
diff --git a/components/datalake-handler/admin/src/app/app.component.html b/components/datalake-handler/admin/src/app/app.component.html
new file mode 100644
index 00000000..68a6dfc6
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/app.component.html
@@ -0,0 +1,23 @@
+<div id="container">
+ <div class="container-fluid">
+ <div class="row">
+ <div class="col-md-2 sidebar-header p-0"></div>
+ <div class="col-md-10 header pl-3 pr-3">
+ <app-header></app-header>
+ </div>
+ </div>
+ </div>
+
+ <div class="container-fluid">
+ <div class="row">
+ <div class="col-md-2 sidebar p-0">
+ <app-sidebar></app-sidebar>
+ </div>
+
+ <div class="col-md-10 content pl-3 pr-3">
+ <hr>
+ <router-outlet></router-outlet>
+ </div>
+ </div>
+ </div>
+</div>
diff --git a/components/datalake-handler/admin/src/app/app.component.spec.ts b/components/datalake-handler/admin/src/app/app.component.spec.ts
new file mode 100644
index 00000000..631c2c55
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/app.component.spec.ts
@@ -0,0 +1,35 @@
+import { TestBed, async } from '@angular/core/testing';
+import { RouterTestingModule } from '@angular/router/testing';
+import { AppComponent } from './app.component';
+
+describe('AppComponent', () => {
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ imports: [
+ RouterTestingModule
+ ],
+ declarations: [
+ AppComponent
+ ],
+ }).compileComponents();
+ }));
+
+ it('should create the app', () => {
+ const fixture = TestBed.createComponent(AppComponent);
+ const app = fixture.debugElement.componentInstance;
+ expect(app).toBeTruthy();
+ });
+
+ it(`should have as title 'admin'`, () => {
+ const fixture = TestBed.createComponent(AppComponent);
+ const app = fixture.debugElement.componentInstance;
+ expect(app.title).toEqual('admin');
+ });
+
+ it('should render title in a h1 tag', () => {
+ const fixture = TestBed.createComponent(AppComponent);
+ fixture.detectChanges();
+ const compiled = fixture.debugElement.nativeElement;
+ expect(compiled.querySelector('h1').textContent).toContain('Welcome to admin!');
+ });
+});
diff --git a/components/datalake-handler/admin/src/app/app.component.ts b/components/datalake-handler/admin/src/app/app.component.ts
new file mode 100644
index 00000000..01be458c
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/app.component.ts
@@ -0,0 +1,9 @@
+import { Component } from "@angular/core";
+@Component({
+ selector: "app-root",
+ templateUrl: "./app.component.html",
+ styleUrls: ["./app.component.css"]
+})
+export class AppComponent {
+ title = "app";
+}
diff --git a/components/datalake-handler/admin/src/app/app.module.ts b/components/datalake-handler/admin/src/app/app.module.ts
new file mode 100644
index 00000000..07045363
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/app.module.ts
@@ -0,0 +1,82 @@
+import { BrowserModule } from "@angular/platform-browser";
+import { NgModule } from "@angular/core";
+import { FormsModule } from "@angular/forms";
+import { NgbModule } from "@ng-bootstrap/ng-bootstrap";
+
+import { AppRoutingModule } from "./app-routing.module";
+import { AppComponent } from "./app.component";
+
+import { HeaderComponent } from "./header/header.component";
+import { SidebarComponent } from "./sidebar/sidebar.component";
+
+import { FeederComponent } from "./feeder/feeder.component";
+import { TopicsComponent } from "./topics/topics.component";
+import { DatabaseComponent } from "./database/database.component";
+import { TopicListComponent } from "./topics/topic-list/topic-list.component";
+
+// Service
+import { HeaderService } from "./core/services/header.service";
+import { RestApiService } from "./core/services/rest-api.service";
+
+// i18n
+import { TranslateModule, TranslateLoader } from "@ngx-translate/core";
+import { TranslateHttpLoader } from "@ngx-translate/http-loader";
+
+export function createLoader(http: HttpClient) {
+ return new TranslateHttpLoader(http);
+}
+
+// REST API
+import { HttpClientModule } from "@angular/common/http";
+import { HttpClient } from "@angular/common/http";
+
+import { DatabaseListComponent } from "./database/database-list/database-list.component";
+import { NgxDatatableModule } from "@swimlane/ngx-datatable";
+import { CouchbaseComponent } from "./database/database-list/dbs-modal/couchbase/couchbase.component";
+import { MongodbComponent } from "./database/database-list/dbs-modal/mongodb/mongodb.component";
+import { DatabaseAddModalComponent } from "./database/database-list/database-add-modal/database-add-modal.component";
+import { ElasticsearchComponent } from "./database/database-list/dbs-modal/elasticsearch/elasticsearch.component";
+import { DruidComponent } from "./database/database-list/dbs-modal/druid/druid.component";
+
+@NgModule({
+ declarations: [
+ AppComponent,
+ HeaderComponent,
+ SidebarComponent,
+ FeederComponent,
+ TopicsComponent,
+ DatabaseComponent,
+ TopicListComponent,
+ DatabaseListComponent,
+ CouchbaseComponent,
+ MongodbComponent,
+ DatabaseAddModalComponent,
+ ElasticsearchComponent,
+ DruidComponent
+ ],
+ imports: [
+ BrowserModule,
+ AppRoutingModule,
+ NgbModule,
+ HttpClientModule,
+ TranslateModule.forRoot({
+ loader: {
+ provide: TranslateLoader,
+ useFactory: createLoader,
+ deps: [HttpClient]
+ }
+ }),
+ FormsModule,
+ NgxDatatableModule
+ ],
+ providers: [HeaderService, RestApiService],
+ bootstrap: [AppComponent],
+ entryComponents: [
+ DatabaseAddModalComponent,
+ CouchbaseComponent,
+ DruidComponent,
+ ElasticsearchComponent,
+ MongodbComponent
+ ]
+})
+export class AppModule {}
diff --git a/components/datalake-handler/admin/src/app/core/models/DB/db.model.ts b/components/datalake-handler/admin/src/app/core/models/DB/db.model.ts
new file mode 100644
index 00000000..473c32c0
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/core/models/DB/db.model.ts
@@ -0,0 +1,8 @@
+export class Db {
+ name: string;
+ host: string;
+ port: number;
+ login: string;
+ pass: string;
+ ssl: boolean;
+}
diff --git a/components/datalake-handler/admin/src/app/core/models/Topic/topic.model.ts b/components/datalake-handler/admin/src/app/core/models/Topic/topic.model.ts
new file mode 100644
index 00000000..f3eb8f15
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/core/models/Topic/topic.model.ts
@@ -0,0 +1,14 @@
+export class Topic {
+ name: string;
+ login: string;
+ pass: string;
+ dbs: any;
+ enable: boolean;
+ save_raw: boolean;
+ data_format: string;
+ ttl: number;
+ correlate_cleared_message: boolean;
+ message_id_path: string;
+ // for UI display
+ type: string;
+}
diff --git a/components/datalake-handler/admin/src/app/core/services/header.service.spec.ts b/components/datalake-handler/admin/src/app/core/services/header.service.spec.ts
new file mode 100644
index 00000000..f6eccf8f
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/core/services/header.service.spec.ts
@@ -0,0 +1,12 @@
+import { TestBed } from "@angular/core/testing";
+
+import { HeaderService } from "./header.service";
+
+describe("HeaderService", () => {
+ beforeEach(() => TestBed.configureTestingModule({}));
+
+ it("should be created", () => {
+ const service: HeaderService = TestBed.get(HeaderService);
+ expect(service).toBeTruthy();
+ });
+});
diff --git a/components/datalake-handler/admin/src/app/core/services/header.service.ts b/components/datalake-handler/admin/src/app/core/services/header.service.ts
new file mode 100644
index 00000000..f0e16d79
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/core/services/header.service.ts
@@ -0,0 +1,13 @@
+import { Injectable } from "@angular/core";
+import { BehaviorSubject } from "rxjs";
+
+@Injectable()
+export class HeaderService {
+ public title = new BehaviorSubject("Title");
+
+ constructor() {}
+
+ setTitle(title: string) {
+ this.title.next(title);
+ }
+}
diff --git a/components/datalake-handler/admin/src/app/core/services/rest-api.service.spec.ts b/components/datalake-handler/admin/src/app/core/services/rest-api.service.spec.ts
new file mode 100644
index 00000000..32e8d79a
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/core/services/rest-api.service.spec.ts
@@ -0,0 +1,12 @@
+import { TestBed } from "@angular/core/testing";
+
+import { RestApiService } from "./rest-api.service";
+
+describe("RestApiService", () => {
+ beforeEach(() => TestBed.configureTestingModule({}));
+
+ it("should be created", () => {
+ const service: RestApiService = TestBed.get(RestApiService);
+ expect(service).toBeTruthy();
+ });
+});
diff --git a/components/datalake-handler/admin/src/app/core/services/rest-api.service.ts b/components/datalake-handler/admin/src/app/core/services/rest-api.service.ts
new file mode 100644
index 00000000..efb3ad3e
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/core/services/rest-api.service.ts
@@ -0,0 +1,52 @@
+import { Injectable } from "@angular/core";
+import {
+ HttpClient,
+ HttpHeaders,
+ HttpErrorResponse
+} from "@angular/common/http";
+import { Observable, of } from "rxjs";
+import { map, catchError, tap } from "rxjs/operators";
+
+const httpOptions = {
+ headers: new HttpHeaders({
+ "Content-Type": "application/json"
+ })
+};
+
+@Injectable({
+ providedIn: "root"
+})
+export class RestApiService {
+ constructor(private http: HttpClient) {}
+
+ private extractData(res: Response) {
+ let body = res;
+ return body || {};
+ }
+
+ private handleError<T>(operation = "operation", result?: T) {
+ return (error: any): Observable<T> => {
+ // TODO: send the error to remote logging infrastructure
+ console.error(error); // log to console instead
+
+ // TODO: better job of transforming error for user consumption
+ console.log(`${operation} failed: ${error.message}`);
+
+ // Let the app keep running by returning an empty result.
+ return of(result as T);
+ };
+ }
+
+ getTopics(): Observable<any> {
+ return this.http.get("/topics/dmaap/").pipe(map(this.extractData));
+ }
+
+ /*
+ updateProduct (id, product): Observable<any> {
+ return this.http.put(endpoint + 'products/' + id, JSON.stringify(product), httpOptions).pipe(
+ tap(_ => console.log(`updated product id=${id}`)),
+ catchError(this.handleError<any>('updateProduct'))
+ );
+ }
+ */
+}
diff --git a/components/datalake-handler/admin/src/app/database/database-list/database-add-modal/database-add-modal.component.css b/components/datalake-handler/admin/src/app/database/database-list/database-add-modal/database-add-modal.component.css
new file mode 100644
index 00000000..8b137891
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/database/database-list/database-add-modal/database-add-modal.component.css
@@ -0,0 +1 @@
+
diff --git a/components/datalake-handler/admin/src/app/database/database-list/database-add-modal/database-add-modal.component.html b/components/datalake-handler/admin/src/app/database/database-list/database-add-modal/database-add-modal.component.html
new file mode 100644
index 00000000..4a8e8774
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/database/database-list/database-add-modal/database-add-modal.component.html
@@ -0,0 +1,59 @@
+<div class="modal-header border-0">
+
+</div>
+<div class="modal-body">
+ <div class="container-fluid">
+
+ <div class="row">
+ <div class="col-md-3 border-right">
+ <div class="row">
+
+
+
+ <ul class="nav nav-tabs flex-column">
+ <li class="nav-item">
+ <a class="nav-link active" id="all-tab" data-toggle="tab" href="#all" role="tab" aria-controls="all"
+ aria-selected="true">All</a>
+ </li>
+ <li class="nav-item">
+ <a class="nav-link" id="tsdb-tab" data-toggle="tab" href="#tsdb" role="tab" aria-controls="tsdb"
+ aria-selected="false">TSDB</a>
+ </li>
+ <li class="nav-item">
+ <a class="nav-link" id="olap-tab" data-toggle="tab" href="#olap" role="tab" aria-controls="olap"
+ aria-selected="false">OLAP</a>
+ </li>
+ </ul>
+
+
+ </div>
+ </div>
+ <div class="col-md-9">
+ <div class="tab-content" id="dbTabContent">
+ <div class="tab-pane fade show active" id="all" role="tabpanel" aria-labelledby="all-tab">
+
+ <div class="list-group">
+ <a class="list-group-item list-group-item-action" [ngClass]="{'active': seletedDb == 'Couchbase'}"
+ (click)="clickDb('Couchbase')">Couchbase</a>
+ <a class="list-group-item list-group-item-action" [ngClass]="{'active': seletedDb == 'Druid'}"
+ (click)="clickDb('Druid')">Druid</a>
+ <a class="list-group-item list-group-item-action" [ngClass]="{'active': seletedDb == 'Elasticsearch'}"
+ (click)="clickDb('Elasticsearch')">Elasticsearch</a>
+ <a class="list-group-item list-group-item-action" [ngClass]="{'active': seletedDb == 'MongoDB'}"
+ (click)="clickDb('MongoDB')">MongoDB</a>
+ </div>
+
+ </div>
+
+ <div class="tab-pane fade" id="tsdb" role="tabpanel" aria-labelledby="tsdb-tab">tsdb dbs</div>
+ <div class="tab-pane fade" id="olap" role="tabpanel" aria-labelledby="olap-tab">olap dbs</div>
+ </div>
+ </div>
+ </div>
+
+ </div>
+</div>
+<div class="modal-footer border-0">
+ <button type="submit" class="btn btn-primary" (click)="openDbDetailModal()">OK</button>
+ <button type="button" class="btn btn-outline-dark" (click)="activeModal.close('Close click')">Cancel</button>
+</div>
diff --git a/components/datalake-handler/admin/src/app/database/database-list/database-add-modal/database-add-modal.component.spec.ts b/components/datalake-handler/admin/src/app/database/database-list/database-add-modal/database-add-modal.component.spec.ts
new file mode 100644
index 00000000..fec2d097
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/database/database-list/database-add-modal/database-add-modal.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { DatabaseAddModalComponent } from './database-add-modal.component';
+
+describe('DatabaseAddModalComponent', () => {
+ let component: DatabaseAddModalComponent;
+ let fixture: ComponentFixture<DatabaseAddModalComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ DatabaseAddModalComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(DatabaseAddModalComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/components/datalake-handler/admin/src/app/database/database-list/database-add-modal/database-add-modal.component.ts b/components/datalake-handler/admin/src/app/database/database-list/database-add-modal/database-add-modal.component.ts
new file mode 100644
index 00000000..022220ce
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/database/database-list/database-add-modal/database-add-modal.component.ts
@@ -0,0 +1,73 @@
+import { Component, OnInit, Input, ViewChild } from "@angular/core";
+import { NgbModal, NgbActiveModal } from "@ng-bootstrap/ng-bootstrap";
+
+// DB modal components
+import { CouchbaseComponent } from "../dbs-modal/couchbase/couchbase.component";
+import { DruidComponent } from "../dbs-modal/druid/druid.component";
+import { ElasticsearchComponent } from "../dbs-modal/elasticsearch/elasticsearch.component";
+import { MongodbComponent } from "../dbs-modal/mongodb/mongodb.component";
+
+@Component({
+ selector: "app-database-add-modal",
+ templateUrl: "./database-add-modal.component.html",
+ styleUrls: ["./database-add-modal.component.css"]
+})
+export class DatabaseAddModalComponent implements OnInit {
+ seletedDb: string;
+
+ constructor(
+ private modalService: NgbModal,
+ public activeModal: NgbActiveModal
+ ) {}
+
+ ngOnInit() {}
+
+ clickDb(name: any) {
+ console.log("seleted: " + name);
+ if (name != null) {
+ this.seletedDb = name;
+ }
+ }
+
+ openDbDetailModal() {
+ this.activeModal.close();
+
+ switch (this.seletedDb) {
+ case "Couchbase": {
+ const modalRef = this.modalService.open(CouchbaseComponent, {
+ size: "lg",
+ centered: true
+ });
+ modalRef.componentInstance.name = "World";
+ break;
+ }
+ case "Druid": {
+ const modalRef = this.modalService.open(DruidComponent, {
+ size: "lg",
+ centered: true
+ });
+ modalRef.componentInstance.name = "World";
+ break;
+ }
+ case "Elasticsearch": {
+ const modalRef = this.modalService.open(ElasticsearchComponent, {
+ size: "lg",
+ centered: true
+ });
+ modalRef.componentInstance.name = "World";
+ break;
+ }
+ case "MongoDB": {
+ const modalRef = this.modalService.open(MongodbComponent, {
+ size: "lg",
+ centered: true
+ });
+ modalRef.componentInstance.name = "World";
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ }
+}
diff --git a/components/datalake-handler/admin/src/app/database/database-list/database-list.component.css b/components/datalake-handler/admin/src/app/database/database-list/database-list.component.css
new file mode 100644
index 00000000..ef7724a1
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/database/database-list/database-list.component.css
@@ -0,0 +1,14 @@
+.db-panel {
+ background: #FFFFFF;
+ box-shadow: 3px 3px 11px 0 #D2D3D5;
+ border-radius: 20px;
+ position: relative;
+ /*width: 100%;
+ padding-top: 75%;*/
+ /* 4:3 Aspect Ratio */
+ font-family: "Open Sans", sans-serif;
+ font-size: 18px;
+ color: #313032;
+ /*vertical-align: middle;*/
+ text-align: center;
+}
diff --git a/components/datalake-handler/admin/src/app/database/database-list/database-list.component.html b/components/datalake-handler/admin/src/app/database/database-list/database-list.component.html
new file mode 100644
index 00000000..2f560350
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/database/database-list/database-list.component.html
@@ -0,0 +1,22 @@
+<div class="d-flex flex-wrap">
+ <div *ngFor="let db of dbs; let i = index; let lastRecord = last" class="col-3 p-2">
+ <div class="db-panel w-100 mh-100">
+ <div class="row">
+ <div class="col-12">
+ <button type="button" class="btn" (click)="openDbDetailModal(db)">
+ icon
+ </button>
+ </div>
+ <div class="col-12">{{ db.name }}</div>
+ </div>
+ </div>
+ </div>
+ <div class="col-3 p-2">
+ <div class="db-panel w-100 mh-100">
+ <button type="button" class="btn btn-dl-dark-plus" (click)="openDbAddModal()">
+ <i class="fas fa-plus fa-2x"></i>
+ </button>
+ </div>
+
+ </div>
+</div>
diff --git a/components/datalake-handler/admin/src/app/database/database-list/database-list.component.spec.ts b/components/datalake-handler/admin/src/app/database/database-list/database-list.component.spec.ts
new file mode 100644
index 00000000..c65f8266
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/database/database-list/database-list.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { DatabaseListComponent } from './database-list.component';
+
+describe('DatabaseListComponent', () => {
+ let component: DatabaseListComponent;
+ let fixture: ComponentFixture<DatabaseListComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ DatabaseListComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(DatabaseListComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/components/datalake-handler/admin/src/app/database/database-list/database-list.component.ts b/components/datalake-handler/admin/src/app/database/database-list/database-list.component.ts
new file mode 100644
index 00000000..5fb941b9
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/database/database-list/database-list.component.ts
@@ -0,0 +1,118 @@
+import { Component, OnInit, ViewChild, ElementRef } from "@angular/core";
+import { Db } from "../../core/models/DB/db.model";
+import { NgbModal, ModalDismissReasons } from "@ng-bootstrap/ng-bootstrap";
+import { DatabaseAddModalComponent } from "./database-add-modal/database-add-modal.component";
+
+// DB modal components
+import { CouchbaseComponent } from "./dbs-modal/couchbase/couchbase.component";
+import { DruidComponent } from "./dbs-modal/druid/druid.component";
+import { ElasticsearchComponent } from "./dbs-modal/elasticsearch/elasticsearch.component";
+import { MongodbComponent } from "./dbs-modal/mongodb/mongodb.component";
+
+@Component({
+ selector: "app-database-list",
+ templateUrl: "./database-list.component.html",
+ styleUrls: ["./database-list.component.css"]
+})
+export class DatabaseListComponent implements OnInit {
+ constructor(private modalService: NgbModal) {}
+
+ @ViewChild("addDbModal") private addDBModal: ElementRef;
+
+ dbs: Db[] = [];
+
+ dbSupports: any[];
+
+ ngOnInit() {
+ // TODO: rest api
+ this.dbs.push(
+ {
+ name: "Couchbase",
+ host: "host1",
+ login: "login1",
+ pass: "pass1",
+ port: 111,
+ ssl: true
+ },
+ {
+ name: "Druid",
+ host: "host2",
+ login: "login2",
+ pass: "pass2",
+ port: 222,
+ ssl: true
+ },
+ {
+ name: "Elasticsearch",
+ host: "host3",
+ login: "login3",
+ pass: "pass3",
+ port: 333,
+ ssl: false
+ },
+ {
+ name: "MongoDB",
+ host: "host4",
+ login: "login4",
+ pass: "pass4",
+ port: 444,
+ ssl: false
+ }
+ );
+ }
+
+ openDbAddModal() {
+ this.modalService.open(DatabaseAddModalComponent, {
+ size: "lg",
+ centered: true
+ });
+ }
+
+ openDbDetailModal(db: Db) {
+ console.log("db name: " + db.name);
+
+ switch (db.name) {
+ case "Couchbase": {
+ const modalRef = this.modalService.open(CouchbaseComponent, {
+ size: "lg",
+ centered: true
+ });
+ modalRef.componentInstance.dbname = "Couchbase";
+ modalRef.componentInstance.name = db.name;
+ modalRef.componentInstance.host = db.host;
+ modalRef.componentInstance.port = db.port;
+ modalRef.componentInstance.login = db.login;
+ modalRef.componentInstance.pass = db.pass;
+ modalRef.componentInstance.ssl = db.ssl;
+ break;
+ }
+ case "Druid": {
+ const modalRef = this.modalService.open(DruidComponent, {
+ size: "lg",
+ centered: true
+ });
+ modalRef.componentInstance.name = "World";
+ break;
+ }
+ case "Elasticsearch": {
+ const modalRef = this.modalService.open(ElasticsearchComponent, {
+ size: "lg",
+ centered: true
+ });
+ modalRef.componentInstance.name = "World";
+ break;
+ }
+ case "MongoDB": {
+ const modalRef = this.modalService.open(MongodbComponent, {
+ size: "lg",
+ centered: true
+ });
+ modalRef.componentInstance.name = "World";
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ }
+}
diff --git a/components/datalake-handler/admin/src/app/database/database-list/dbs-modal/couchbase/couchbase.component.css b/components/datalake-handler/admin/src/app/database/database-list/dbs-modal/couchbase/couchbase.component.css
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/database/database-list/dbs-modal/couchbase/couchbase.component.css
diff --git a/components/datalake-handler/admin/src/app/database/database-list/dbs-modal/couchbase/couchbase.component.html b/components/datalake-handler/admin/src/app/database/database-list/dbs-modal/couchbase/couchbase.component.html
new file mode 100644
index 00000000..523d6dbb
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/database/database-list/dbs-modal/couchbase/couchbase.component.html
@@ -0,0 +1,80 @@
+<div class="modal-header border border-bottom">
+ <h1><label>Document store | {{ dbname }}</label></h1>
+ <hr>
+</div>
+<div class="modal-body border-0">
+
+ <div class="form-group">
+ <div class="row">
+ <div class="col-md-4"><label for="inputBucket">Bucket</label></div>
+ <div class="col-md-8">
+ <input class="form-control input-dl-field" id="inputBucket" type="text" placeholder="" value="{{ name }}">
+ </div>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <div class="row">
+ <div class="col-md-4"><label for="inputHost">Host</label></div>
+ <div class="col-md-8">
+ <input class="form-control input-dl-field" id="inputHost" type="text" placeholder="" value="{{ host }}">
+ </div>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <div class="row">
+ <div class="col-md-4"><label for="inputPort">Port</label></div>
+ <div class="col-md-8">
+ <input class="form-control input-dl-field" id="inputPort" type="text" placeholder="" value="{{ port }}">
+ </div>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <div class="row">
+ <div class="col-md-4"><label for="inputUserName">Authentication</label></div>
+ <div class="col-md-8">
+ <div class="row">
+ <div class="col-md-6">
+ <input class="form-control input-dl-field" id="inputUserName" type="text" placeholder="Username"
+ value="{{ login }}">
+ </div>
+ <div class="col-md-6">
+ <input class="form-control input-dl-field" id="inputPass" type="text" placeholder="Password"
+ value="{{ pass }}">
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <div class="row">
+ <div class="col-md-4"><label for="inputSsl">SSL</label></div>
+ <div class="col-md-8">
+ <div class="custom-control custom-checkbox">
+ <input type="checkbox" id="inputSsl" name="customRadio" class="custom-control-input" checked="ssl">
+ <label class="custom-control-label" for="inputSsl">Enable</label>
+ </div>
+ </div>
+ </div>
+ </div>
+
+</div>
+<div class="modal-footer border-0">
+
+ <div class="d-flex align-items-start">
+ <div class="p-2 mr-auto">
+ <button type="button" class="btn btn-outline-dark">Verify</button>
+ </div>
+ <div class="p-2">
+ <button type="button" class="btn btn-outline-dark">Save</button>
+ </div>
+ <div class="p-2">
+ <button type="button" class="btn btn-outline-dark" (click)="activeModal.close('Close click')">Close</button>
+ </div>
+
+ </div>
+
+</div>
diff --git a/components/datalake-handler/admin/src/app/database/database-list/dbs-modal/couchbase/couchbase.component.spec.ts b/components/datalake-handler/admin/src/app/database/database-list/dbs-modal/couchbase/couchbase.component.spec.ts
new file mode 100644
index 00000000..3f9ca6d0
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/database/database-list/dbs-modal/couchbase/couchbase.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { CouchbaseComponent } from './couchbase.component';
+
+describe('CouchbaseComponent', () => {
+ let component: CouchbaseComponent;
+ let fixture: ComponentFixture<CouchbaseComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ CouchbaseComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(CouchbaseComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/components/datalake-handler/admin/src/app/database/database-list/dbs-modal/couchbase/couchbase.component.ts b/components/datalake-handler/admin/src/app/database/database-list/dbs-modal/couchbase/couchbase.component.ts
new file mode 100644
index 00000000..9632174c
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/database/database-list/dbs-modal/couchbase/couchbase.component.ts
@@ -0,0 +1,13 @@
+import { Component, OnInit, Input } from "@angular/core";
+import { NgbModal, NgbActiveModal } from "@ng-bootstrap/ng-bootstrap";
+
+@Component({
+ selector: "app-couchbase",
+ templateUrl: "./couchbase.component.html",
+ styleUrls: ["./couchbase.component.css"]
+})
+export class CouchbaseComponent implements OnInit {
+ constructor(public activeModal: NgbActiveModal) {}
+
+ ngOnInit() {}
+}
diff --git a/components/datalake-handler/admin/src/app/database/database-list/dbs-modal/druid/druid.component.css b/components/datalake-handler/admin/src/app/database/database-list/dbs-modal/druid/druid.component.css
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/database/database-list/dbs-modal/druid/druid.component.css
diff --git a/components/datalake-handler/admin/src/app/database/database-list/dbs-modal/druid/druid.component.html b/components/datalake-handler/admin/src/app/database/database-list/dbs-modal/druid/druid.component.html
new file mode 100644
index 00000000..29639f97
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/database/database-list/dbs-modal/druid/druid.component.html
@@ -0,0 +1,78 @@
+<div class="modal-header border border-bottom">
+ <h1><label>OLAP store | Druid</label></h1>
+ <hr>
+</div>
+<div class="modal-body border-0">
+
+ <div class="form-group">
+ <div class="row">
+ <div class="col-md-4"><label for="inputBucket">Database</label></div>
+ <div class="col-md-8">
+ <input class="form-control input-dl-field" id="inputBucket" type="text" placeholder="">
+ </div>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <div class="row">
+ <div class="col-md-4"><label for="inputHost">Host</label></div>
+ <div class="col-md-8">
+ <input class="form-control input-dl-field" id="inputHost" type="text" placeholder="">
+ </div>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <div class="row">
+ <div class="col-md-4"><label for="inputPort">Port</label></div>
+ <div class="col-md-8">
+ <input class="form-control input-dl-field" id="inputPort" type="text" placeholder="">
+ </div>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <div class="row">
+ <div class="col-md-4"><label for="inputUserName">Authentication</label></div>
+ <div class="col-md-8">
+ <div class="row">
+ <div class="col-md-6">
+ <input class="form-control input-dl-field" id="inputUserName" type="text" placeholder="Username">
+ </div>
+ <div class="col-md-6">
+ <input class="form-control input-dl-field" id="inputPass" type="text" placeholder="Password">
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <div class="row">
+ <div class="col-md-4"><label for="inputSsl">SSL</label></div>
+ <div class="col-md-8">
+ <div class="custom-control custom-checkbox">
+ <input type="checkbox" id="inputSsl" name="customRadio" class="custom-control-input">
+ <label class="custom-control-label" for="inputSsl">Enable</label>
+ </div>
+ </div>
+ </div>
+ </div>
+
+</div>
+<div class="modal-footer border-0">
+
+ <div class="d-flex align-items-start">
+ <div class="p-2 mr-auto">
+ <button type="button" class="btn btn-outline-dark">Verify</button>
+ </div>
+ <div class="p-2">
+ <button type="button" class="btn btn-outline-dark">Save</button>
+ </div>
+ <div class="p-2">
+ <button type="button" class="btn btn-outline-dark" (click)="activeModal.close('Close click')">Close</button>
+ </div>
+
+ </div>
+
+</div>
diff --git a/components/datalake-handler/admin/src/app/database/database-list/dbs-modal/druid/druid.component.spec.ts b/components/datalake-handler/admin/src/app/database/database-list/dbs-modal/druid/druid.component.spec.ts
new file mode 100644
index 00000000..4418b99b
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/database/database-list/dbs-modal/druid/druid.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { DruidComponent } from './druid.component';
+
+describe('DruidComponent', () => {
+ let component: DruidComponent;
+ let fixture: ComponentFixture<DruidComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ DruidComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(DruidComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/components/datalake-handler/admin/src/app/database/database-list/dbs-modal/druid/druid.component.ts b/components/datalake-handler/admin/src/app/database/database-list/dbs-modal/druid/druid.component.ts
new file mode 100644
index 00000000..e2688a8e
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/database/database-list/dbs-modal/druid/druid.component.ts
@@ -0,0 +1,13 @@
+import { Component, OnInit } from "@angular/core";
+import { NgbModal, NgbActiveModal } from "@ng-bootstrap/ng-bootstrap";
+
+@Component({
+ selector: "app-druid",
+ templateUrl: "./druid.component.html",
+ styleUrls: ["./druid.component.css"]
+})
+export class DruidComponent implements OnInit {
+ constructor(public activeModal: NgbActiveModal) {}
+
+ ngOnInit() {}
+}
diff --git a/components/datalake-handler/admin/src/app/database/database-list/dbs-modal/elasticsearch/elasticsearch.component.css b/components/datalake-handler/admin/src/app/database/database-list/dbs-modal/elasticsearch/elasticsearch.component.css
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/database/database-list/dbs-modal/elasticsearch/elasticsearch.component.css
diff --git a/components/datalake-handler/admin/src/app/database/database-list/dbs-modal/elasticsearch/elasticsearch.component.html b/components/datalake-handler/admin/src/app/database/database-list/dbs-modal/elasticsearch/elasticsearch.component.html
new file mode 100644
index 00000000..65d8525b
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/database/database-list/dbs-modal/elasticsearch/elasticsearch.component.html
@@ -0,0 +1,69 @@
+<div class="modal-header border border-bottom">
+ <h1><label>Search Engine | Elasticsearch</label></h1>
+ <hr>
+</div>
+<div class="modal-body border-0">
+
+ <div class="form-group">
+ <div class="row">
+ <div class="col-md-4"><label for="inputHost">Host</label></div>
+ <div class="col-md-8">
+ <input class="form-control input-dl-field" id="inputHost" type="text" placeholder="">
+ </div>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <div class="row">
+ <div class="col-md-4"><label for="inputPort">Port</label></div>
+ <div class="col-md-8">
+ <input class="form-control input-dl-field" id="inputPort" type="text" placeholder="">
+ </div>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <div class="row">
+ <div class="col-md-4"><label for="inputUserName">Authentication</label></div>
+ <div class="col-md-8">
+ <div class="row">
+ <div class="col-md-6">
+ <input class="form-control input-dl-field" id="inputUserName" type="text" placeholder="Username">
+ </div>
+ <div class="col-md-6">
+ <input class="form-control input-dl-field" id="inputPass" type="text" placeholder="Password">
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <div class="row">
+ <div class="col-md-4"><label for="inputSsl">SSL</label></div>
+ <div class="col-md-8">
+ <div class="custom-control custom-checkbox">
+ <input type="checkbox" id="inputSsl" name="customRadio" class="custom-control-input">
+ <label class="custom-control-label" for="inputSsl">Enable</label>
+ </div>
+ </div>
+ </div>
+ </div>
+
+</div>
+<div class="modal-footer border-0">
+
+ <div class="d-flex align-items-start">
+ <div class="p-2 mr-auto">
+ <button type="button" class="btn btn-outline-dark">Verify</button>
+ </div>
+ <div class="p-2">
+ <button type="button" class="btn btn-outline-dark">Save</button>
+ </div>
+ <div class="p-2">
+ <button type="button" class="btn btn-outline-dark" (click)="activeModal.close('Close click')">Close</button>
+ </div>
+
+ </div>
+
+</div>
diff --git a/components/datalake-handler/admin/src/app/database/database-list/dbs-modal/elasticsearch/elasticsearch.component.spec.ts b/components/datalake-handler/admin/src/app/database/database-list/dbs-modal/elasticsearch/elasticsearch.component.spec.ts
new file mode 100644
index 00000000..96b18a8a
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/database/database-list/dbs-modal/elasticsearch/elasticsearch.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { ElasticsearchComponent } from './elasticsearch.component';
+
+describe('ElasticsearchComponent', () => {
+ let component: ElasticsearchComponent;
+ let fixture: ComponentFixture<ElasticsearchComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ ElasticsearchComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(ElasticsearchComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/components/datalake-handler/admin/src/app/database/database-list/dbs-modal/elasticsearch/elasticsearch.component.ts b/components/datalake-handler/admin/src/app/database/database-list/dbs-modal/elasticsearch/elasticsearch.component.ts
new file mode 100644
index 00000000..37add661
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/database/database-list/dbs-modal/elasticsearch/elasticsearch.component.ts
@@ -0,0 +1,13 @@
+import { Component, OnInit } from "@angular/core";
+import { NgbModal, NgbActiveModal } from "@ng-bootstrap/ng-bootstrap";
+
+@Component({
+ selector: "app-elasticsearch",
+ templateUrl: "./elasticsearch.component.html",
+ styleUrls: ["./elasticsearch.component.css"]
+})
+export class ElasticsearchComponent implements OnInit {
+ constructor(public activeModal: NgbActiveModal) {}
+
+ ngOnInit() {}
+}
diff --git a/components/datalake-handler/admin/src/app/database/database-list/dbs-modal/mongodb/mongodb.component.css b/components/datalake-handler/admin/src/app/database/database-list/dbs-modal/mongodb/mongodb.component.css
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/database/database-list/dbs-modal/mongodb/mongodb.component.css
diff --git a/components/datalake-handler/admin/src/app/database/database-list/dbs-modal/mongodb/mongodb.component.html b/components/datalake-handler/admin/src/app/database/database-list/dbs-modal/mongodb/mongodb.component.html
new file mode 100644
index 00000000..508ee515
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/database/database-list/dbs-modal/mongodb/mongodb.component.html
@@ -0,0 +1,78 @@
+<div class="modal-header border border-bottom">
+ <h1><label>Document store | MongoDB</label></h1>
+ <hr>
+</div>
+<div class="modal-body border-0">
+
+ <div class="form-group">
+ <div class="row">
+ <div class="col-md-4"><label for="inputBucket">Bucket</label></div>
+ <div class="col-md-8">
+ <input class="form-control input-dl-field" id="inputBucket" type="text" placeholder="">
+ </div>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <div class="row">
+ <div class="col-md-4"><label for="inputHost">Host</label></div>
+ <div class="col-md-8">
+ <input class="form-control input-dl-field" id="inputHost" type="text" placeholder="">
+ </div>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <div class="row">
+ <div class="col-md-4"><label for="inputPort">Port</label></div>
+ <div class="col-md-8">
+ <input class="form-control input-dl-field" id="inputPort" type="text" placeholder="">
+ </div>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <div class="row">
+ <div class="col-md-4"><label for="inputUserName">Authentication</label></div>
+ <div class="col-md-8">
+ <div class="row">
+ <div class="col-md-6">
+ <input class="form-control input-dl-field" id="inputUserName" type="text" placeholder="Username">
+ </div>
+ <div class="col-md-6">
+ <input class="form-control input-dl-field" id="inputPass" type="text" placeholder="Password">
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <div class="row">
+ <div class="col-md-4"><label for="inputSsl">SSL</label></div>
+ <div class="col-md-8">
+ <div class="custom-control custom-checkbox">
+ <input type="checkbox" id="inputSsl" name="customRadio" class="custom-control-input">
+ <label class="custom-control-label" for="inputSsl">Enable</label>
+ </div>
+ </div>
+ </div>
+ </div>
+
+</div>
+<div class="modal-footer border-0">
+
+ <div class="d-flex align-items-start">
+ <div class="p-2 mr-auto">
+ <button type="button" class="btn btn-outline-dark">Verify</button>
+ </div>
+ <div class="p-2">
+ <button type="button" class="btn btn-outline-dark">Save</button>
+ </div>
+ <div class="p-2">
+ <button type="button" class="btn btn-outline-dark" (click)="activeModal.close('Close click')">Close</button>
+ </div>
+
+ </div>
+
+</div>
diff --git a/components/datalake-handler/admin/src/app/database/database-list/dbs-modal/mongodb/mongodb.component.spec.ts b/components/datalake-handler/admin/src/app/database/database-list/dbs-modal/mongodb/mongodb.component.spec.ts
new file mode 100644
index 00000000..3d7fc234
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/database/database-list/dbs-modal/mongodb/mongodb.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { MongodbComponent } from './mongodb.component';
+
+describe('MongodbComponent', () => {
+ let component: MongodbComponent;
+ let fixture: ComponentFixture<MongodbComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ MongodbComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(MongodbComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/components/datalake-handler/admin/src/app/database/database-list/dbs-modal/mongodb/mongodb.component.ts b/components/datalake-handler/admin/src/app/database/database-list/dbs-modal/mongodb/mongodb.component.ts
new file mode 100644
index 00000000..399600ff
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/database/database-list/dbs-modal/mongodb/mongodb.component.ts
@@ -0,0 +1,15 @@
+import { Component, OnInit, Input } from "@angular/core";
+import { NgbModal, NgbActiveModal } from "@ng-bootstrap/ng-bootstrap";
+
+@Component({
+ selector: "app-mongodb",
+ templateUrl: "./mongodb.component.html",
+ styleUrls: ["./mongodb.component.css"]
+})
+export class MongodbComponent implements OnInit {
+ @Input() title = "1234";
+
+ constructor(public activeModal: NgbActiveModal) {}
+
+ ngOnInit() {}
+}
diff --git a/components/datalake-handler/admin/src/app/database/database.component.css b/components/datalake-handler/admin/src/app/database/database.component.css
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/database/database.component.css
diff --git a/components/datalake-handler/admin/src/app/database/database.component.html b/components/datalake-handler/admin/src/app/database/database.component.html
new file mode 100644
index 00000000..7ce4bc3e
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/database/database.component.html
@@ -0,0 +1,7 @@
+<div class="row">
+ <div class="col-md-12 path">
+ Home > Database Connections
+ </div>
+</div>
+
+<app-database-list></app-database-list>
diff --git a/components/datalake-handler/admin/src/app/database/database.component.spec.ts b/components/datalake-handler/admin/src/app/database/database.component.spec.ts
new file mode 100644
index 00000000..f0621e27
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/database/database.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { DatabaseComponent } from './database.component';
+
+describe('DatabaseComponent', () => {
+ let component: DatabaseComponent;
+ let fixture: ComponentFixture<DatabaseComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ DatabaseComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(DatabaseComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/components/datalake-handler/admin/src/app/database/database.component.ts b/components/datalake-handler/admin/src/app/database/database.component.ts
new file mode 100644
index 00000000..ef0ee0cb
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/database/database.component.ts
@@ -0,0 +1,15 @@
+import { Component, OnInit } from "@angular/core";
+import { HeaderService } from "../core/services/header.service";
+
+@Component({
+ selector: "app-database",
+ templateUrl: "./database.component.html",
+ styleUrls: ["./database.component.css"]
+})
+export class DatabaseComponent implements OnInit {
+ constructor(private headerService: HeaderService) {}
+
+ ngOnInit() {
+ this.headerService.setTitle("SIDEBAR.DATABASE");
+ }
+}
diff --git a/components/datalake-handler/admin/src/app/feeder/feeder.component.css b/components/datalake-handler/admin/src/app/feeder/feeder.component.css
new file mode 100644
index 00000000..efaa42c3
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/feeder/feeder.component.css
@@ -0,0 +1,27 @@
+.dashboard-panel {
+ background: #FFFFFF;
+ box-shadow: 3px 3px 11px 0 #D2D3D5;
+ border-radius: 20px;
+ position: relative;
+ width: 100%;
+ height: 100%;
+}
+
+.dashboard-panel .title {
+ font-family: 'Open Sans', sans-serif;
+ font-weight: 600;
+ font-size: 25px;
+ color: #5DBEBB;
+ letter-spacing: 1.79px;
+ text-align: left;
+ margin: 20px 0 -10px 20px;
+}
+
+.dashboard-panel .number {
+ font-family: 'Open Sans', sans-serif;
+ font-weight: 300;
+ font-size: 120px;
+ color: #313032;
+ letter-spacing: 5px;
+ text-align: center;
+}
diff --git a/components/datalake-handler/admin/src/app/feeder/feeder.component.html b/components/datalake-handler/admin/src/app/feeder/feeder.component.html
new file mode 100644
index 00000000..729e1e30
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/feeder/feeder.component.html
@@ -0,0 +1,59 @@
+<div class="row">
+ <div class="col-md-12 path">
+ Home > DataLake Feeder > Dashboard
+ </div>
+</div>
+
+<div class="row">
+ <div class="col-md-3 p-2">
+ <div class="dashboard-panel">
+ <div class="row">
+ <div class="col-md-12 title">
+ Topics
+ </div>
+ <div class="col-md-12 number">
+ {{ topicNumber }}
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div class="col-md-3 p-2">
+ <div class="dashboard-panel">
+ <div class="row">
+ <div class="col-md-12 title">
+ Success
+ </div>
+ <div class="col-md-12 number">
+ {{ topicSuccess }}
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div class="col-md-3 p-2">
+ <div class="dashboard-panel">
+ <div class="row">
+ <div class="col-md-12 title">
+ Fail
+ </div>
+ <div class="col-md-12 number">
+ {{ topicFail }}
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div class="col-md-3 p-2">
+ <div class="dashboard-panel">
+ <div class="row">
+ <div class="col-md-12 title">
+ Event
+ </div>
+ <div class="col-md-12 number">
+ {{ topicEvents }}
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
diff --git a/components/datalake-handler/admin/src/app/feeder/feeder.component.spec.ts b/components/datalake-handler/admin/src/app/feeder/feeder.component.spec.ts
new file mode 100644
index 00000000..e371f352
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/feeder/feeder.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { FeederComponent } from './feeder.component';
+
+describe('FeederComponent', () => {
+ let component: FeederComponent;
+ let fixture: ComponentFixture<FeederComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ FeederComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(FeederComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/components/datalake-handler/admin/src/app/feeder/feeder.component.ts b/components/datalake-handler/admin/src/app/feeder/feeder.component.ts
new file mode 100644
index 00000000..b738b2ee
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/feeder/feeder.component.ts
@@ -0,0 +1,20 @@
+import { Component, OnInit } from "@angular/core";
+import { HeaderService } from "../core/services/header.service";
+
+@Component({
+ selector: "app-feeder",
+ templateUrl: "./feeder.component.html",
+ styleUrls: ["./feeder.component.css"]
+})
+export class FeederComponent implements OnInit {
+ constructor(private headerService: HeaderService) {}
+
+ topicNumber: number = 11;
+ topicSuccess: number = 9;
+ topicFail: number = 1;
+ topicEvents: number = 50;
+
+ ngOnInit() {
+ this.headerService.setTitle("SIDEBAR.FEDDFER");
+ }
+}
diff --git a/components/datalake-handler/admin/src/app/header/header.component.css b/components/datalake-handler/admin/src/app/header/header.component.css
new file mode 100644
index 00000000..8b137891
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/header/header.component.css
@@ -0,0 +1 @@
+
diff --git a/components/datalake-handler/admin/src/app/header/header.component.html b/components/datalake-handler/admin/src/app/header/header.component.html
new file mode 100644
index 00000000..7aa35e2c
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/header/header.component.html
@@ -0,0 +1,10 @@
+<div class="d-flex">
+ <div class="mr-auto title">
+ {{ title | translate }}
+ </div>
+ <div class="ml-auto">
+ <select class="form-control lang-select" [(ngModel)]="selectedLang" (ngModelChange)="changeLanguage(selectedLang)">
+ <option class="lang" *ngFor="let lang of langs" [value]=lang.value>{{ lang.name }}</option>
+ </select>
+ </div>
+</div>
diff --git a/components/datalake-handler/admin/src/app/header/header.component.spec.ts b/components/datalake-handler/admin/src/app/header/header.component.spec.ts
new file mode 100644
index 00000000..2d0479d7
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/header/header.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { HeaderComponent } from './header.component';
+
+describe('HeaderComponent', () => {
+ let component: HeaderComponent;
+ let fixture: ComponentFixture<HeaderComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ HeaderComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(HeaderComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/components/datalake-handler/admin/src/app/header/header.component.ts b/components/datalake-handler/admin/src/app/header/header.component.ts
new file mode 100644
index 00000000..21ed700c
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/header/header.component.ts
@@ -0,0 +1,38 @@
+import { Component } from "@angular/core";
+import { HeaderService } from "../core/services/header.service";
+import { TranslateService } from "@ngx-translate/core";
+
+@Component({
+ selector: "app-header",
+ templateUrl: "./header.component.html",
+ styleUrls: ["./header.component.css"]
+})
+export class HeaderComponent {
+ title = "PageTitle";
+
+ selectedLang: String;
+ langs: Array<any> = [
+ { value: "en-us", name: "EN" },
+ { value: "zh-hans", name: "中文(简)" },
+ { value: "zh-hant", name: "中文(繁)" }
+ ];
+
+ constructor(
+ private headerService: HeaderService,
+ private translateService: TranslateService
+ ) {
+ this.translateService.setDefaultLang("en-us");
+ }
+
+ ngOnInit() {
+ this.headerService.title.subscribe(title => {
+ this.title = title;
+ });
+ this.selectedLang = "en-us";
+ }
+
+ changeLanguage(lang: string) {
+ console.log("Selected:" + lang);
+ this.translateService.use(lang);
+ }
+}
diff --git a/components/datalake-handler/admin/src/app/sidebar/sidebar.component.css b/components/datalake-handler/admin/src/app/sidebar/sidebar.component.css
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/sidebar/sidebar.component.css
diff --git a/components/datalake-handler/admin/src/app/sidebar/sidebar.component.html b/components/datalake-handler/admin/src/app/sidebar/sidebar.component.html
new file mode 100644
index 00000000..42d10a2d
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/sidebar/sidebar.component.html
@@ -0,0 +1,34 @@
+<nav class="navbar navbar-expand-md">
+ <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent"
+ aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
+ <span class="fas fa-align-justify"></span>
+ </button>
+ <div class="collapse navbar-collapse nav" id="navbarSupportedContent">
+ <ul class="navbar-nav flex-column" routerLinkActive="active">
+
+ <li class="nav-item">
+ <a class="nav-link" [routerLinkActive]="['active']" [routerLinkActiveOptions]="{exact:true}"
+ routerLink="/feeder">
+ <i class="fas fa-tachometer-alt"></i>
+ {{"SIDEBAR.FEDDFER" | translate}}
+ </a>
+ </li>
+
+ <li class="nav-item">
+ <a class="nav-link" [routerLinkActive]="['active']" [routerLinkActiveOptions]="{exact:true}"
+ routerLink="/topics">
+ <i class="fas fa-cube"></i>
+ {{"SIDEBAR.TOPICS" | translate}}
+ </a>
+ </li>
+
+ <li class="nav-item">
+ <a class="nav-link" [routerLinkActive]="['active']" [routerLinkActiveOptions]="{exact:true}"
+ routerLink="/database">
+ <i class="fas fa-database" aria-hidden="true"></i>
+ {{"SIDEBAR.DATABASE" | translate}}
+ </a>
+ </li>
+ </ul>
+ </div>
+</nav>
diff --git a/components/datalake-handler/admin/src/app/sidebar/sidebar.component.spec.ts b/components/datalake-handler/admin/src/app/sidebar/sidebar.component.spec.ts
new file mode 100644
index 00000000..f29709fd
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/sidebar/sidebar.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { SidebarComponent } from './sidebar.component';
+
+describe('SidebarComponent', () => {
+ let component: SidebarComponent;
+ let fixture: ComponentFixture<SidebarComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ SidebarComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(SidebarComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/components/datalake-handler/admin/src/app/sidebar/sidebar.component.ts b/components/datalake-handler/admin/src/app/sidebar/sidebar.component.ts
new file mode 100644
index 00000000..05c2f06a
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/sidebar/sidebar.component.ts
@@ -0,0 +1,12 @@
+import { Component, OnInit } from "@angular/core";
+
+@Component({
+ selector: "app-sidebar",
+ templateUrl: "./sidebar.component.html",
+ styleUrls: ["./sidebar.component.css"]
+})
+export class SidebarComponent implements OnInit {
+ constructor() {}
+
+ ngOnInit() {}
+}
diff --git a/components/datalake-handler/admin/src/app/topics/topic-list/topic-list.component.css b/components/datalake-handler/admin/src/app/topics/topic-list/topic-list.component.css
new file mode 100644
index 00000000..bb3e0e80
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/topics/topic-list/topic-list.component.css
@@ -0,0 +1,5 @@
+.topic-list-panel {
+ background: #FFFFFF;
+ box-shadow: 3px 3px 11px 0 #D2D3D5;
+ border-radius: 20px;
+}
diff --git a/components/datalake-handler/admin/src/app/topics/topic-list/topic-list.component.html b/components/datalake-handler/admin/src/app/topics/topic-list/topic-list.component.html
new file mode 100644
index 00000000..969a80e8
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/topics/topic-list/topic-list.component.html
@@ -0,0 +1,421 @@
+<div class="topic-list-panel">
+ <div class="row">
+ <div class="col-md-12">
+ <div class="d-flex justify-content-end p-2">
+
+ <!-- Search bar -->
+ <div class="p-1">
+ <div class="input-group">
+ <input type="text" class="form-control input-dl-field-search" placeholder="Search..."
+ (keyup)='this.updateFilter($event)'>
+ <div class="input-group-append">
+ <button type="button" class="btn btn-dl-dark">
+ <i class="fa fa-search"></i>
+ </button>
+ </div>
+ </div>
+ </div>
+
+ <!-- button -->
+ <div class="p-1">
+ <button class="btn btn-dl-dark" data-toggle="modal" data-target="#topicDefaultModal"
+ (click)="updateDetail()">Default
+ configuration</button>
+ </div>
+
+ </div>
+ </div>
+ </div>
+
+ <!-- datatable -->
+ <div class="row">
+ <div class="col-md-12">
+ <ngx-datatable #mydatatable class="bootstrap" [rows]="topics" [columnMode]="'force'" [headerHeight]="40"
+ [footerHeight]="40" [rowHeight]="50" [scrollbarV]="true" [scrollbarH]="true"
+ [loadingIndicator]="loadingIndicator">
+
+ <ngx-datatable-column [width]="50" name="Status" prop="enable">
+ <ng-template let-row="row" ngx-datatable-cell-template>
+ <span *ngIf="row.enable == true">
+ <i class="fas fa-circle icon-enable" aria-hidden="true"></i>
+ </span>
+ <span *ngIf="row.enable == false">
+ <i class="fas fa-circle icon-disable" aria-hidden="true"></i>
+ </span>
+ </ng-template>
+ </ngx-datatable-column>
+
+ <ngx-datatable-column [width]="300" name="Name" prop="name">
+ <ng-template let-row="row" ngx-datatable-cell-template>
+ <span>{{ row.name }}</span>
+ </ng-template>
+ </ngx-datatable-column>
+
+ <ngx-datatable-column [width]="150" name="Sink">
+ <ng-template let-row="row" ngx-datatable-cell-template>
+ <!-- couchbasedb -->
+ <span class="pr-1">
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
+ y="0px" width="20" height="20" viewBox="-408 285.3 25 25"
+ style="enable-background:new -408 285.3 25 25;" xml:space="preserve">
+ <path [ngStyle]="{'fill': row.dbs.includes('couchbasedb') ? '#5DBEBB':'D2D3D5'}"
+ d="M-395.5,285.3c-6.9,0-12.5,5.6-12.5,12.5s5.6,12.5,12.5,12.5s12.5-5.6,12.5-12.5S-388.6,285.3-395.5,285.3z
+ M-387.1,300c0,0.8-0.4,1.4-1.3,1.6c-1.5,0.3-4.6,0.4-7.2,0.4s-5.7-0.2-7.2-0.4c-0.8-0.2-1.3-0.8-1.3-1.6v-4.9
+ c0-0.8,0.6-1.5,1.3-1.6c0.4-0.1,1.5-0.2,2.2-0.2c0.3,0,0.5,0.2,0.5,0.6v3.4l4.4-0.1l4.4,0.1v-3.4c0-0.4,0.2-0.6,0.5-0.6
+ c0.8,0,1.8,0.1,2.2,0.2c0.7,0.1,1.3,0.8,1.3,1.6C-387.1,296.7-387.1,298.3-387.1,300L-387.1,300z" />
+ </svg>
+ </span>
+
+ <!-- druid -->
+ <span class="pr-1">
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
+ y="0px" width="20" height="20" viewBox="-403 285.3 34 25"
+ style="enable-background:new -403 285.3 34 25;" xml:space="preserve">
+ <g>
+ <path [ngStyle]="{'fill': row.dbs.includes('druid') ? '#5DBEBB':'D2D3D5'}"
+ d="M-385.5,285.3c2.2,0,4.3,0,6.5,0c4.2,0,8,2.7,9.4,6.6c0.6,1.7,0.8,3.4,0.6,5.2c-0.3,2.6-1,5-2.5,7.2
+ c-2.3,3.4-5.5,5.2-9.5,5.8c-1.4,0.2-2.7,0.2-4.1,0.2c-0.6,0-0.9-0.3-0.9-0.7c0-0.5,0.3-0.9,0.8-0.9c0.6,0,1.2,0,1.9,0
+ c3.7-0.1,7-1.4,9.6-4.2c1.8-1.9,2.7-4.3,3-6.9c0.2-1.8,0.2-3.6-0.5-5.3c-1.1-2.6-3.1-4.2-5.8-5c-1.1-0.3-2.1-0.3-3.2-0.4
+ c-4,0-8.1,0-12.1,0c-0.2,0-0.3,0-0.5,0c-0.4,0-0.7-0.4-0.7-0.8s0.3-0.7,0.6-0.8c0.2,0,0.4,0,0.6,0L-385.5,285.3L-385.5,285.3z" />
+ <path [ngStyle]="{'fill': row.dbs.includes('druid') ? '#5DBEBB':'D2D3D5'}" d="M-389.7,304.6h-7.2c-0.2,0-0.3,0-0.5,0c-0.4-0.1-0.7-0.3-0.7-0.7c0-0.4,0.2-0.7,0.6-0.9
+ c0.2-0.1,0.5-0.1,0.8-0.1c4.7,0,9.5,0,14.2,0c1.7,0,3.1-0.6,4.2-1.8c1-1,1.5-2.3,1.6-3.7c0.1-1.1,0-2.1-0.7-3.1
+ c-0.8-1-1.8-1.5-3.1-1.5c-4.5,0-9,0-13.5,0c-0.5,0-1,0-1.4-0.1c-0.4,0-0.6-0.3-0.7-0.7c0-0.5,0.2-0.8,0.6-0.9c0.1,0,0.3,0,0.4,0
+ h14.4c2.4,0,4.5,1.5,5.3,3.8c0.5,1.6,0.4,3.3-0.3,4.8c-1.2,3-3.9,4.9-7.2,4.9C-385,304.6-387.3,304.6-389.7,304.6L-389.7,304.6z
+ M-400.4,292.6c-0.6,0-1.1,0-1.7,0c-0.5,0-0.8-0.3-0.9-0.7s0.2-0.8,0.7-0.9c0.3,0,0.5-0.1,0.8-0.1c0.8,0,1.5,0,2.3,0
+ c0.2,0,0.5,0,0.7,0.1c0.4,0.1,0.6,0.5,0.6,0.9s-0.3,0.7-0.7,0.7C-399.2,292.7-399.8,292.6-400.4,292.6L-400.4,292.6z M-390.3,310.3
+ c-0.5,0-1,0-1.6,0c-0.5,0-0.8-0.3-0.9-0.7c0-0.5,0.3-0.9,0.7-0.9c1.1-0.1,2.2-0.1,3.4,0c0.4,0,0.8,0.4,0.7,0.8l0,0
+ c0,0.5-0.4,0.7-0.9,0.8L-390.3,310.3L-390.3,310.3z" />
+ </g>
+ </svg>
+ </span>
+
+ <!-- elasticsearch -->
+ <span class="pr-1">
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
+ y="0px" width="20" height="20" viewBox="2066.4 284.8 25.1 25"
+ style="enable-background:new 2066.4 284.8 25.1 25;" xml:space="preserve">
+ <g>
+ <path style="fill: #FFFFFF" d="M2091.6,297.9c0-2.1-1.3-3.9-3.3-4.7c0.1-0.4,0.1-0.9,0.1-1.4c0-3.9-3.2-7.1-7.1-7.1c-2.3,0-4.4,1.1-5.7,3
+ c-0.7-0.5-1.5-0.8-2.3-0.8c-2.1,0-3.8,1.7-3.8,3.8c0,0.5,0.1,0.9,0.2,1.3c-2,0.7-3.3,2.6-3.3,4.7c0,2.1,1.3,4,3.3,4.7
+ c-0.1,0.4-0.1,0.9-0.1,1.4c0,3.9,3.2,7.1,7.1,7.1c2.3,0,4.4-1.1,5.7-3c0.7,0.5,1.5,0.8,2.3,0.8c2.1,0,3.8-1.7,3.8-3.8
+ c0-0.5-0.1-0.9-0.2-1.3C2090.2,301.8,2091.6,300,2091.6,297.9L2091.6,297.9z" />
+ <path [ngStyle]="{'fill': row.dbs.includes('elasticsearch') ? '#5DBEBB':'#D2D3D5'}" d="M2076.3,295.5l5.6,2.6l5.7-5c0.1-0.4,0.1-0.8,0.1-1.3c0-3.5-2.8-6.3-6.3-6.3c-2.1,0-4,1-5.2,2.7l-0.9,4.9
+ L2076.3,295.5L2076.3,295.5z" />
+ <path [ngStyle]="{'fill': row.dbs.includes('elasticsearch') ? '#5DBEBB':'#D2D3D5'}" d="M2070.5,301.4c-0.1,0.4-0.1,0.8-0.1,1.3c0,3.5,2.8,6.3,6.3,6.3c2.1,0,4.1-1,5.2-2.8l0.9-4.9l-1.3-2.4l-5.6-2.6
+ L2070.5,301.4L2070.5,301.4z" />
+ <path [ngStyle]="{'fill': row.dbs.includes('elasticsearch') ? '#5DBEBB':'#D2D3D5'}" d="M2070.4,291.7l3.8,0.9l0.9-4.4c-0.5-0.4-1.2-0.6-1.8-0.6c-1.7,0-3,1.4-3,3
+ C2070.2,291.1,2070.3,291.4,2070.4,291.7L2070.4,291.7z" />
+ <path [ngStyle]="{'fill': row.dbs.includes('elasticsearch') ? '#5DBEBB':'#D2D3D5'}"
+ d="M2070.1,292.7c-1.7,0.6-2.9,2.2-2.9,4c0,1.8,1.1,3.3,2.7,4l5.4-4.9l-1-2.1L2070.1,292.7L2070.1,292.7z" />
+ <path [ngStyle]="{'fill': row.dbs.includes('elasticsearch') ? '#5DBEBB':'D2D3D5'}" d="M2082.9,306.3c0.5,0.4,1.2,0.6,1.8,0.6c1.7,0,3-1.4,3-3c0-0.4-0.1-0.7-0.2-1l-3.8-0.9L2082.9,306.3
+ L2082.9,306.3z" />
+ <path [ngStyle]="{'fill': row.dbs.includes('elasticsearch') ? '#5DBEBB':'#D2D3D5'}"
+ d="M2083.7,300.9l4.2,1c1.7-0.6,2.9-2.2,2.9-4c0-1.8-1.1-3.3-2.7-4l-5.5,4.8L2083.7,300.9L2083.7,300.9z" />
+ </g>
+ </svg>
+ </span>
+
+ <!-- mongodb -->
+ <span class="pr-1">
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
+ y="0px" width="20" height="20" viewBox="-397.2 285.8 11.2 25"
+ style="enable-background:new -397.2 285.8 11.2 25;" xml:space="preserve">
+ <g transform="matrix(1.2754196 0 0 1.2754196 -16.030009 -21.83192)">
+ <path [ngStyle]="{'fill': row.dbs.includes('mongodb') ? '#19A2A2':'#C4C6C8'}"
+ d="M-294.5,241.2c0.2,0.3,0.4,0.7,0.5,1c0.1,0.2,0.2,0.4,0.4,0.5c0.4,0.4,0.9,0.9,1.2,1.4
+ c0.9,1.2,1.5,2.5,1.9,3.9c0.3,0.9,0.4,1.7,0.4,2.6c0,2.7-0.9,4.9-2.7,6.8c-0.3,0.3-0.6,0.6-1,0.8c-0.2,0-0.3-0.2-0.4-0.3
+ c-0.2-0.2-0.2-0.5-0.3-0.8c-0.1-0.3-0.1-0.6-0.1-1c0,0,0-0.1,0-0.2C-294.4,256.1-294.6,241.3-294.5,241.2z" />
+ <path [ngStyle]="{'fill': row.dbs.includes('mongodb') ? '#5DBEBB':'#D2D3D5'}"
+ d="M-294.5,241.2C-294.5,241.2-294.5,241.2-294.5,241.2c-0.1,0.2-0.2,0.4-0.3,0.6c-0.1,0.2-0.3,0.3-0.5,0.5
+ c-0.9,0.8-1.7,1.8-2.3,2.9c-0.8,1.5-1.2,3.1-1.3,4.8c0,0.6,0.2,2.8,0.4,3.4c0.5,1.6,1.4,3,2.7,4.2c0.3,0.3,0.6,0.5,0.9,0.8
+ c0.1,0,0.1-0.1,0.1-0.2c0-0.2,0.1-0.3,0.1-0.4c0.1-0.5,0.2-1.1,0.2-1.6C-294.4,256.2-294.4,241.3-294.5,241.2L-294.5,241.2z" />
+ <path [ngStyle]="{'fill': row.dbs.includes('mongodb') ? '#CEEBEA':'#C2BFBF'}" d="M-294,258.9c0-0.2,0.2-0.4,0.3-0.7c-0.1,0-0.2-0.2-0.3-0.3c-0.1-0.1-0.1-0.2-0.2-0.4c-0.2-0.4-0.2-0.9-0.2-1.4
+ c0,0,0-0.1,0-0.2s0-0.1,0-0.2c0,0-0.1,0.4-0.1,0.5c0,0.5-0.1,1-0.2,1.4c0,0.2,0,0.4-0.2,0.5c0,0,0,0,0,0.1c0.2,0.5,0.2,1.1,0.3,1.7
+ v0.2c0,0.3,0,0.2,0.2,0.3c0.1,0,0.2,0,0.3,0.1c0.1,0,0.1,0,0.1-0.1c0-0.1,0-0.2,0-0.4c0-0.3,0-0.7,0-1
+ C-294,259.3-294,259.1-294,258.9z" />
+ </g>
+ </svg>
+ </span>
+
+ </ng-template>
+ </ngx-datatable-column>
+
+ <ngx-datatable-column [width]="100" name="TTL" prop="ttl">
+ <ng-template let-row="row" ngx-datatable-cell-template>
+ <span>{{ row.ttl }}</span>
+ </ng-template>
+ </ngx-datatable-column>
+
+ <ngx-datatable-column [width]="100" name="Authentication">
+ <ng-template let-row="row" ngx-datatable-cell-template>
+ <span *ngIf="row.login != '' && row.pass != ''">
+ <i class="fas fa-unlock-alt icon-enable" aria-hidden="true"></i> ​
+ </span>
+ <span *ngIf="row.login === '' && row.pass === ''">
+ <i class="fa fa-unlock-alt icon-disable" aria-hidden="true"></i> ​
+ </span>
+ </ng-template>
+ </ngx-datatable-column>
+
+ <ngx-datatable-column [width]="100" name="Save raw data" prop="save_raw">
+ <ng-template let-row="row" ngx-datatable-cell-template>
+ <span *ngIf="row.save_raw == true">
+ <i class="fas fa-check icon-enable" aria-hidden="true"></i>
+ </span>
+ <span *ngIf="row.save_raw == false">
+ <i class="fas fa-check icon-disable" aria-hidden="true"></i>
+ </span>
+ </ng-template>
+ </ngx-datatable-column>
+
+ <ngx-datatable-column [width]="150" name="Setting">
+ <ng-template let-row="row" ngx-datatable-cell-template>
+ <span class="icon-unconfig"
+ *ngIf="row.dbs.includes('_DL_DEFAULT_')">&nbsp;&nbsp;Unconfigured&nbsp;&nbsp;</span>
+ <span class="icon-config"
+ *ngIf="!row.dbs.includes('_DL_DEFAULT_')">&nbsp;&nbsp;Configured&nbsp;&nbsp;</span>
+ </ng-template>
+ </ngx-datatable-column>
+
+ <ngx-datatable-column [width]="100" name="" sortable="false">
+ <ng-template let-row="row" ngx-datatable-cell-template>
+ <span>
+ <button md-icon-button class="btn action-icon-setting" data-toggle="modal" data-target="#topicDetailModal"
+ (click)="this.updateDetail(row.name)">
+ <i class="fas fa-cog fa-xs"></i>
+ </button>
+ </span>
+ </ng-template>
+ </ngx-datatable-column>
+
+ </ngx-datatable>
+ </div>
+ </div>
+</div>
+
+<!-- Detail Modal -->
+<div class="modal fade" id="topicDetailModal" tabindex="-1" role="dialog" aria-hidden="true">
+ <div class="modal-dialog modal-dialog-centered modal-lg" role="document">
+ <div class="modal-content">
+ <div class="modal-title">
+ <div class="container-fluid pt-3">
+ <h4>{{ topicDetail.name }}</h4>
+ <hr>
+ </div>
+ </div>
+
+ <div class="modal-body">
+ <div class="container-fluid">
+
+ <div class="form-group">
+ <div class="row">
+ <div class="col-md-4"><label>Status</label></div>
+ <div class="col-md-8"><input type="checkbox" [(ngModel)]="topicDetail.enable"
+ [checked]="topicDetail.enable"></div>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <div class="row">
+ <div class="col-md-4"><label for="inputUserName">Authentication</label></div>
+ <div class="col-md-8">
+ <div class="row">
+ <div class="col-md-6">
+ <input class="form-control" id="inputUserName" type="text" placeholder="Username"
+ value="{{ topicDetail.login }}" [(ngModel)]="topicDetail.login">
+ </div>
+ <div class="col-md-6">
+ <input class="form-control" id="inputPass" type="text" placeholder="Password"
+ value="{{ topicDetail.pass }}" [(ngModel)]="topicDetail.pass">
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <div class="row">
+ <div class="col-md-4"><label>Database</label></div>
+ <div class="col-md-8">
+ {{ topicDetail.dbs }}
+ </div>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <div class="row">
+ <div class="col-md-4"><label>Data format</label></div>
+ <div class="col-md-4">
+ <select class="custom-select" id="selDataFormat" [(ngModel)]="topicDetail.data_format">
+ <option *ngFor="let dataFormat of dataFormats" [value]="dataFormat"
+ [selected]="dataFormat == topicDetail.data_format">
+ {{ dataFormat }}</option>
+ </select>
+ </div>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <div class="row">
+ <div class="col-md-4"><label>TTL (days)</label></div>
+ <div class="col-md-4">
+ <input class="form-control" id="inputTtl" type="text" placeholder="3650" [(ngModel)]="topicDetail.ttl"
+ value="{{ topicDetail.ttl }}">
+ </div>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <div class="row">
+ <div class="col-md-4">
+ <label>Save raw data</label>
+ </div>
+ <div class="col-md-4">
+ <input type="checkbox" [checked]="topicDetail.save_raw" [(ngModel)]="topicDetail.save_raw">
+ </div>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <div class="row">
+ <div class="col-md-4">
+ <label>Correlate cleard message</label>
+ </div>
+ <div class="col-md-4">
+ <input type="checkbox" [checked]="topicDetail.correlate_cleared_message"
+ [(ngModel)]="topicDetail.correlate_cleared_message">
+ </div>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <div class="row">
+ <div class="col-md-4"><label>ID extraction</label></div>
+ <div class="col-md-8">
+ <div class="d-flex" *ngFor="let field of idExFields; let i = index">
+ <div class="order-1">
+ <input class="form-control" placeholder="/event-header/id" type="text" [(ngModel)]="field.item"
+ [value]="field.item">
+ </div>
+ <div class="order-2">
+ <button type="button" class="btn" (click)="addIdField(i)"><i class="fa fa-plus fa-xs"
+ aria-hidden="true"></i>
+ </button>
+ </div>
+ <div class="order-3">
+ <button type="button" class="btn" (click)="deleteIdField(i)"><i class="fa fa-trash fa-xs"
+ aria-hidden="true"></i>
+ </button>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ </div>
+ </div>
+
+ <div class="modal-footer">
+ <button type="submit" class="btn btn-primary" (click)="saveTopic()">OK</button>
+ <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
+ </div>
+ </div>
+
+ </div>
+</div>
+
+<!-- config Modal -->
+<div class="modal fade" id="topicDefaultModal" tabindex="-1" role="dialog" aria-hidden="true">
+ <div class="modal-dialog modal-dialog-centered modal-lg" role="document">
+ <div class="modal-content">
+ <div class="modal-title">
+ <div class="container-fluid pt-3">
+ <h4>Topics Default Configurations</h4>
+ <hr>
+ </div>
+ </div>
+
+ <div class="modal-body">
+ <div class="container-fluid">
+
+ <div class="form-group">
+ <div class="row">
+ <div class="col-md-4"><label>Status</label></div>
+ <div class="col-md-8"><input type="checkbox" [(ngModel)]="topicDetail.enable"
+ [checked]="topicDetail.enable"></div>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <div class="row">
+ <div class="col-md-4"><label for="inputUserName">Authentication</label></div>
+ <div class="col-md-8">
+ <div class="row">
+ <div class="col-md-6">
+ <input class="form-control" id="inputUserName" type="text" placeholder="Username"
+ value="{{ topicDetail.login }}" [(ngModel)]="topicDetail.login">
+ </div>
+ <div class="col-md-6">
+ <input class="form-control" id="inputPass" type="text" placeholder="Password"
+ value="{{ topicDetail.pass }}" [(ngModel)]="topicDetail.pass">
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <div class="row">
+ <div class="col-md-4"><label>Data format</label></div>
+ <div class="col-md-4">
+ <select class="custom-select" id="selDataFormat" [(ngModel)]="topicDetail.data_format">
+ <option *ngFor="let dataFormat of dataFormats" [value]="dataFormat"
+ [selected]="dataFormat == topicDetail.data_format">
+ {{ dataFormat }}</option>
+ </select>
+ </div>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <div class="row">
+ <div class="col-md-4"><label>TTL (days)</label></div>
+ <div class="col-md-4">
+ <input class="form-control" id="inputTtl" type="text" placeholder="3650" [(ngModel)]="topicDetail.ttl"
+ value="{{ topicDetail.ttl }}">
+ </div>
+ </div>
+ </div>
+
+
+ <div class="form-group">
+ <div class="row">
+ <div class="col-md-4"><label>Database</label></div>
+ <div class="col-md-8">
+ Database list
+ </div>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <div class="row">
+ <div class="col-md-4">
+ <label>Save raw data</label>
+ </div>
+ <div class="col-md-4">
+ <input type="checkbox" [checked]="topicDetail.save_raw" [(ngModel)]="topicDetail.save_raw">
+ </div>
+ </div>
+ </div>
+
+ </div>
+ </div>
+
+ <div class="modal-footer">
+ <button type="submit" class="btn btn-primary" (click)="saveTopic()">OK</button>
+ <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
+ </div>
+ </div>
+
+ </div>
+</div>
diff --git a/components/datalake-handler/admin/src/app/topics/topic-list/topic-list.component.spec.ts b/components/datalake-handler/admin/src/app/topics/topic-list/topic-list.component.spec.ts
new file mode 100644
index 00000000..531afbb7
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/topics/topic-list/topic-list.component.spec.ts
@@ -0,0 +1,24 @@
+import { async, ComponentFixture, TestBed } from "@angular/core/testing";
+
+import { TopicListComponent } from "./topic-list.component";
+
+describe("TopicListComponent", () => {
+ let component: TopicListComponent;
+ let fixture: ComponentFixture<TopicListComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [TopicListComponent]
+ }).compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(TopicListComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it("should create", () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/components/datalake-handler/admin/src/app/topics/topic-list/topic-list.component.ts b/components/datalake-handler/admin/src/app/topics/topic-list/topic-list.component.ts
new file mode 100644
index 00000000..1cdd7634
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/topics/topic-list/topic-list.component.ts
@@ -0,0 +1,189 @@
+import { Component, ViewChild } from "@angular/core";
+import { RestApiService } from "../../core/services/rest-api.service";
+import { Topic } from "../../core/models/Topic/topic.model";
+import { NgbModal, ModalDismissReasons } from "@ng-bootstrap/ng-bootstrap";
+
+@Component({
+ selector: "app-topic-list",
+ templateUrl: "./topic-list.component.html",
+ styleUrls: ["./topic-list.component.css"]
+})
+export class TopicListComponent {
+ // fake data
+ topicList: Array<string> = [
+ "AAI-EVENT1",
+ "AAI-EVENT2",
+ "AAI-EVENT3",
+ "AAI-EVENT4",
+ "AAI-EVENT5",
+ "AAI-EVENT6",
+ "AAI-EVENT7",
+ "AAI-EVENT8",
+ "AAI-EVENT9",
+ "AAI-EVENT10",
+ "AAI-EVENT11",
+ "AAI-EVENT12",
+ "AAI-EVENT13",
+ "AAI-EVENT14",
+ "AAI-EVENT15",
+ "AAI-EVENT16",
+ "AAI-EVENT17",
+ "AAI-EVENT18",
+ "AAI-EVENT19",
+ "AAI-EVENT21",
+ "AAI-EVENT22",
+ "AAI-EVENT23",
+ "AAI-EVENT24",
+ "AAI-EVENT25",
+ "AAI-EVENT26",
+ "AAI-EVENT27",
+ "AAI-EVENT28",
+ "AAI-EVENT29",
+ "__consumer_offsets",
+ "msgrtr.apinode.metrics.dmaap",
+ "unauthenticated.DCAE_CL_OUTPUT",
+ "unauthenticated.SEC_FAULT_OUTPUT"
+ ];
+ topics: Topic[] = [];
+ temp: Topic[] = []; // cache for topics
+ topicDetail: Topic = new Topic();
+ closeResult: string;
+ dataFormats: Array<string> = ["JSON", "XML"];
+ idExFields: Array<any> = [];
+ idExNewField: any = {};
+
+ loadingIndicator: boolean = true;
+
+ constructor(
+ private restApiService: RestApiService,
+ private modalService: NgbModal
+ ) {
+ setTimeout(() => {
+ this.loadingIndicator = false;
+ }, 5000);
+ }
+
+ ngOnInit() {
+ // fake data
+ var topicCount: number = this.topicList.length;
+ console.log("topic length:" + topicCount);
+ for (var i = 0; i < topicCount; i++) {
+ if (i % 2 == 0) {
+ var feed = {
+ name: this.topicList[i],
+ login: "logintest" + i,
+ pass: "passtest" + i,
+ dbs: ["_DL_DEFAULT_", "couchbasedb", "druid", "mongodb"],
+ enable: true,
+ save_raw: true,
+ data_format: "XML",
+ ttl: 100 + i,
+ correlate_cleared_message: true,
+ message_id_path: "/event_id/id,/event_id/name",
+ type: ""
+ };
+ } else {
+ var feed = {
+ name: this.topicList[i],
+ login: "",
+ pass: "",
+ dbs: ["druid", "elasticsearch"],
+ enable: false,
+ save_raw: false,
+ data_format: "XML",
+ ttl: 100 + i,
+ correlate_cleared_message: false,
+ message_id_path: "/event_id/id,/event_id/name/event_id/ekko_name",
+ type: ""
+ };
+ }
+
+ if (feed.dbs.toString().search("_DL_DEFAULT")) {
+ feed.type = "Unconfigured";
+ } else {
+ feed.type = "Configured";
+ }
+ this.topics.push(feed);
+ }
+
+ // for cache of datatable
+ this.temp = this.topics;
+ }
+
+ updateDetail(name: string) {
+ // clean
+ this.topicDetail = null;
+ this.idExFields = [];
+
+ const index = this.topics.findIndex(topic => topic.name === name);
+
+ this.topicDetail = {
+ name: this.topics[index].name,
+ login: this.topics[index].login,
+ pass: this.topics[index].pass,
+ dbs: this.topics[index].dbs,
+ enable: this.topics[index].enable,
+ save_raw: this.topics[index].save_raw,
+ data_format: this.topics[index].data_format,
+ ttl: this.topics[index].ttl,
+ correlate_cleared_message: this.topics[index].correlate_cleared_message,
+ message_id_path: this.topics[index].message_id_path,
+ type: this.topics[index].type
+ };
+
+ var feed = this.topicDetail.message_id_path.split(",");
+ for (var i = 0; i < feed.length; i++) {
+ var data = { item: feed[i] };
+ this.idExFields.push(data);
+ }
+ }
+
+ addIdField() {
+ this.idExFields.push(this.idExNewField);
+ this.idExNewField = {};
+ }
+
+ deleteIdField(index: number) {
+ if (this.idExFields.length > 1) {
+ this.idExFields.splice(index, 1);
+ }
+ }
+
+ saveTopic() {
+ console.log("save topic");
+ console.log("name: " + this.topicDetail.name);
+ console.log("login: " + this.topicDetail.login);
+ console.log("pass: " + this.topicDetail.pass);
+ console.log("dbs: ");
+ console.log("enable: " + this.topicDetail.enable);
+ console.log("save_raw: " + this.topicDetail.save_raw);
+ console.log("data_format: " + this.topicDetail.data_format);
+ console.log("ttl: " + this.topicDetail.ttl);
+ console.log(
+ "correlate_cleared_message: " + this.topicDetail.correlate_cleared_message
+ );
+
+ this.topicDetail.message_id_path = "";
+ for (var i = 0; i < this.idExFields.length; i++) {
+ if (i == 0) {
+ this.topicDetail.message_id_path = this.idExFields[i].item;
+ } else {
+ this.topicDetail.message_id_path =
+ this.topicDetail.message_id_path + "," + this.idExFields[i].item;
+ }
+ }
+ console.log("message_id_path: ", this.topicDetail.message_id_path);
+ }
+
+ updateFilter(event) {
+ const val = event.target.value.toLowerCase();
+ console.log("filter val: " + val);
+ // filter data
+ const temp = this.temp.filter(function(d) {
+ return d.name.toLowerCase().indexOf(val) !== -1 || !val;
+ });
+
+ // update the rows
+ this.topics = temp;
+ }
+}
diff --git a/components/datalake-handler/admin/src/app/topics/topics.component.css b/components/datalake-handler/admin/src/app/topics/topics.component.css
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/topics/topics.component.css
diff --git a/components/datalake-handler/admin/src/app/topics/topics.component.html b/components/datalake-handler/admin/src/app/topics/topics.component.html
new file mode 100644
index 00000000..ced38d3d
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/topics/topics.component.html
@@ -0,0 +1,27 @@
+<div class="row">
+ <div class="col-md-12 path">
+ Home > Topics
+ </div>
+
+ <!--
+ <div class="col-md-2">
+
+ <div class="row">
+ <div class="col-md-12 text-center">
+ Topics Category
+ </div>
+ </div>
+
+ <div class="row">
+ <div class="col-md-12">
+ <app-topic-cate></app-topic-cate>
+ </div>
+ </div>
+
+ </div>
+ -->
+
+ <div class="col-md-12">
+ <app-topic-list></app-topic-list>
+ </div>
+</div>
diff --git a/components/datalake-handler/admin/src/app/topics/topics.component.spec.ts b/components/datalake-handler/admin/src/app/topics/topics.component.spec.ts
new file mode 100644
index 00000000..f38f85e6
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/topics/topics.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { TopicsComponent } from './topics.component';
+
+describe('TopicsComponent', () => {
+ let component: TopicsComponent;
+ let fixture: ComponentFixture<TopicsComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ TopicsComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(TopicsComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/components/datalake-handler/admin/src/app/topics/topics.component.ts b/components/datalake-handler/admin/src/app/topics/topics.component.ts
new file mode 100644
index 00000000..ef171437
--- /dev/null
+++ b/components/datalake-handler/admin/src/app/topics/topics.component.ts
@@ -0,0 +1,16 @@
+import { Component, OnInit } from "@angular/core";
+import { HeaderService } from "../core/services/header.service";
+
+@Component({
+ selector: "app-topics",
+ templateUrl: "./topics.component.html",
+ styleUrls: ["./topics.component.css"]
+})
+export class TopicsComponent implements OnInit {
+ constructor(private headerService: HeaderService) {}
+
+ ngOnInit() {
+ // Set page title
+ this.headerService.setTitle("SIDEBAR.TOPICS");
+ }
+}