Data exposure service management pages 20/101220/1
authorEkko Chang <ekko.chang@qct.io>
Thu, 6 Feb 2020 08:53:39 +0000 (08:53 +0000)
committerEkko Chang <ekko.chang@qct.io>
Thu, 6 Feb 2020 08:53:39 +0000 (08:53 +0000)
Issue-ID: DCAEGEN2-1960
Signed-off-by: Ekko Chang <ekko.chang@qct.io>
Change-Id: I8f03f775210576cb3d8e9729b1154bc16149fae6

15 files changed:
components/datalake-handler/admin/src/src/app/app-routing.module.ts
components/datalake-handler/admin/src/src/app/app.module.ts
components/datalake-handler/admin/src/src/app/core/models/data-service.model.ts [new file with mode: 0644]
components/datalake-handler/admin/src/src/app/core/services/rest-api.service.ts
components/datalake-handler/admin/src/src/app/shared/layout/sidebar/sidebar.component.html
components/datalake-handler/admin/src/src/app/views/data-exposure/data-exposure.component.css [new file with mode: 0644]
components/datalake-handler/admin/src/src/app/views/data-exposure/data-exposure.component.html [new file with mode: 0644]
components/datalake-handler/admin/src/src/app/views/data-exposure/data-exposure.component.spec.ts [new file with mode: 0644]
components/datalake-handler/admin/src/src/app/views/data-exposure/data-exposure.component.ts [new file with mode: 0644]
components/datalake-handler/admin/src/src/app/views/data-exposure/de-modal/de-modal.component.css [new file with mode: 0644]
components/datalake-handler/admin/src/src/app/views/data-exposure/de-modal/de-modal.component.html [new file with mode: 0644]
components/datalake-handler/admin/src/src/app/views/data-exposure/de-modal/de-modal.component.spec.ts [new file with mode: 0644]
components/datalake-handler/admin/src/src/app/views/data-exposure/de-modal/de-modal.component.ts [new file with mode: 0644]
components/datalake-handler/admin/src/src/assets/i18n/en-us.json
components/datalake-handler/admin/src/src/styles.css

index e0484a4..01e1ff4 100644 (file)
@@ -37,6 +37,7 @@ 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 { DataExposureComponent } from "./views/data-exposure/data-exposure.component";
 
 const routes: Routes = [
   { path: "", redirectTo: "/feeder", pathMatch: "full" },
@@ -47,7 +48,8 @@ const routes: Routes = [
   { path: "database", component: DatabaseComponent },
   { path: "about", component: AboutComponent },
   { path: "tools", component: ToolsComponent },
-  { path: "dashboard-setting/template", component: TemplateComponent }
+  { path: "dashboard-setting/template", component: TemplateComponent },
+  { path: "data-exposure", component: DataExposureComponent }
 ];
 
 @NgModule({
index 94ce52e..39db98c 100644 (file)
@@ -86,6 +86,8 @@ import { ModalComponent } from "./shared/modules/modal/modal.component";
 import { ModalDirective } from "./shared/modules/modal/modal.directive";
 import { ToastrNotificationComponent } from "./shared/components/toastr-notification/toastr-notification.component";
 import { AlertComponent } from "./shared/components/alert/alert.component";
+import { DataExposureComponent } from "./views/data-exposure/data-exposure.component";
+import { DeModalComponent } from "./views/data-exposure/de-modal/de-modal.component";
 
 // Others
 
@@ -123,7 +125,9 @@ import { AlertComponent } from "./shared/components/alert/alert.component";
     KafkaModalComponent,
     DbModalComponent,
     ToolModalComponent,
-    TemplateModalComponent
+    TemplateModalComponent,
+    DataExposureComponent,
+    DeModalComponent
   ],
   imports: [
     BrowserModule,
@@ -156,7 +160,8 @@ import { AlertComponent } from "./shared/components/alert/alert.component";
     KafkaModalComponent,
     DbModalComponent,
     ToolModalComponent,
-    TemplateModalComponent
+    TemplateModalComponent,
+    DeModalComponent
   ]
 })
 export class AppModule {}
diff --git a/components/datalake-handler/admin/src/src/app/core/models/data-service.model.ts b/components/datalake-handler/admin/src/src/app/core/models/data-service.model.ts
new file mode 100644 (file)
index 0000000..106a422
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP : DataLake
+ * ================================================================================
+ * Copyright 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
+ *
+ */
+
+export class DataService {
+  public id: string;
+  public note: string;
+  public sqlTemplate: string;
+  public dbId: number;
+}
index d1dcd63..6548c07 100644 (file)
@@ -36,6 +36,7 @@ import { Db, DbType } from "src/app/core/models/db.model";
 import { Template } from "src/app/core/models/template.model";
 import { Dashboard } from "src/app/core/models/dashboard.model";
 import { Kafka } from "../models/kafka.model";
+import { DataService } from "src/app/core/models/data-service.model";
 
 const prefix = "/datalake/v1/";
 const httpOptions = {
@@ -366,4 +367,45 @@ export class RestApiService {
       catchError(this.handleError)
     );
   }
+
+  /*
+    Dataexposure service
+  */
+  public getAllDataService(): Observable<DataService[]> {
+    return this.http
+      .get<DataService[]>(prefix + "exposure")
+      .pipe(retry(1), catchError(this.handleError));
+  }
+
+  public getDataService(id: string): Observable<DataService> {
+    return this.http
+      .get<DataService>(prefix + "exposure/" + id)
+      .pipe(retry(1), catchError(this.handleError));
+  }
+
+  public updateDataService(ds: DataService): Observable<DataService> {
+    return this.http
+      .put<DataService>(prefix + "exposure/" + ds.id, ds)
+      .pipe(
+        retry(1),
+        tap(_ => this.extractData),
+        catchError(this.handleError)
+      );
+  }
+
+  public addDataService(ds: DataService): Observable<DataService> {
+    return this.http.post<DataService>(prefix + "exposure", ds).pipe(
+      retry(1),
+      tap(_ => console.log(`add service =${ds.id}`)),
+      catchError(this.handleError)
+    );
+  }
+
+  public deleteDataService(id: string): Observable<DataService> {
+    return this.http.delete<DataService>(prefix + "exposure/" + id).pipe(
+      retry(1),
+      tap(_ => console.log(`deleted service=${id}`)),
+      catchError(this.handleError)
+    );
+  }
 }
index a0ed00c..e4cf962 100644 (file)
@@ -36,7 +36,7 @@ limitations under the License.
 
       <li class="nav-item ">
         <a class="nav-link" [routerLinkActive]="['active']" [routerLinkActiveOptions]="{exact:true}"
-           routerLink="/kafka">
+          routerLink="/kafka">
           <i class="fas fa-cube">&nbsp;</i>
           {{"SIDEBAR.KAFKA" | translate}}
         </a>
@@ -59,20 +59,26 @@ limitations under the License.
 
       <li class="nav-item">
         <a class="nav-link" [routerLinkActive]="['active']" [routerLinkActiveOptions]="{exact:true}"
-           routerLink="/tools">
+          routerLink="/tools">
           <i class="fas fa-external-link-alt" aria-hidden="true">&nbsp;</i>
           {{"SIDEBAR.DASHBOARDLIST" | translate}}
         </a>
       </li>
       <li class="nav-item">
         <a class="nav-link" [routerLinkActive]="['active']" [routerLinkActiveOptions]="{exact:true}"
-           routerLink="dashboard-setting/template"
-        >
+          routerLink="dashboard-setting/template">
           <i class="far fa-file-image" aria-hidden="true">&nbsp;</i>
           {{"SIDEBAR.TEMPLATE" | translate}}
         </a>
       </li>
 
+      <li class="nav-item ">
+        <a class="nav-link" [routerLinkActive]="['active']" [routerLinkActiveOptions]="{exact:true}"
+          routerLink="/data-exposure">
+          <i class="fas fa-cube">&nbsp;</i>
+          {{"SIDEBAR.DATAEXPOSURE" | translate}}
+        </a>
+      </li>
 
       <li class="nav-item">
         <a class="nav-link" [routerLinkActive]="['active']" [routerLinkActiveOptions]="{exact:true}"
diff --git a/components/datalake-handler/admin/src/src/app/views/data-exposure/data-exposure.component.css b/components/datalake-handler/admin/src/src/app/views/data-exposure/data-exposure.component.css
new file mode 100644 (file)
index 0000000..fcd3670
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+* ============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
+ *
+ */
+
+.list-panel {
+  background: #FFFFFF;
+  box-shadow: 3px 3px 11px 0 #D2D3D5;
+  border-radius: 20px;
+}
diff --git a/components/datalake-handler/admin/src/src/app/views/data-exposure/data-exposure.component.html b/components/datalake-handler/admin/src/src/app/views/data-exposure/data-exposure.component.html
new file mode 100644 (file)
index 0000000..52bbf5d
--- /dev/null
@@ -0,0 +1,58 @@
+<!--
+============LICENSE_START=======================================================
+ONAP : DataLake
+================================================================================
+Copyright 2019 - 2020 QCT
+=================================================================================
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+============LICENSE_END=========================================================
+-->
+
+
+<div class="row">
+  <div class="col-md-12 pb-2 path">
+    Home > DataExposure Service
+  </div>
+
+  <div class="col-md-12">
+
+    <div class="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 #searchText type="text" class="form-control dl-input-text-search" placeholder="Search..."
+                  (keyup)="this.updateFilter($event.target.value)" />
+              </div>
+            </div>
+            <!-- button -->
+            <div class="p-1">
+              <app-button [text]="'plus'" [style]="'inlineicon'" [color]="'dark'" (click)="openModal('new')">
+              </app-button>
+            </div>
+          </div>
+        </div>
+      </div>
+      <!-- datatable -->
+      <div class="row">
+        <div class="col-md-12">
+          <app-table [data]="datas" [columns]="columns" (btnTableAction)="btnTableAction($event)"></app-table>
+        </div>
+      </div>
+    </div>
+
+  </div>
+
+</div>
diff --git a/components/datalake-handler/admin/src/src/app/views/data-exposure/data-exposure.component.spec.ts b/components/datalake-handler/admin/src/src/app/views/data-exposure/data-exposure.component.spec.ts
new file mode 100644 (file)
index 0000000..03edd24
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP : DataLake
+ * ================================================================================
+ * Copyright 2020 QCT
+ *=================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import { async, ComponentFixture, TestBed } from "@angular/core/testing";
+
+import { DataExposureComponent } from "./data-exposure.component";
+
+describe("DataExposureComponent", () => {
+  let component: DataExposureComponent;
+  let fixture: ComponentFixture<DataExposureComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [DataExposureComponent]
+    }).compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(DataExposureComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it("should create", () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/components/datalake-handler/admin/src/src/app/views/data-exposure/data-exposure.component.ts b/components/datalake-handler/admin/src/src/app/views/data-exposure/data-exposure.component.ts
new file mode 100644 (file)
index 0000000..348c791
--- /dev/null
@@ -0,0 +1,229 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP : DataLake
+ * ================================================================================
+ * Copyright 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, ViewChild, ElementRef, OnInit } from "@angular/core";
+import { RestApiService } from "src/app/core/services/rest-api.service";
+import { AdminService } from "src/app/core/services/admin.service";
+import { DataService } from "src/app/core/models/data-service.model";
+import { NgbModal } from "@ng-bootstrap/ng-bootstrap";
+
+// Notify
+import { ToastrNotificationService } from "src/app/shared/components/toastr-notification/toastr-notification.service";
+
+// Loading spinner
+import { NgxSpinnerService } from "ngx-spinner";
+
+import { AlertComponent } from "src/app/shared/components/alert/alert.component";
+import { map, mergeMap } from "rxjs/operators";
+import { forkJoin, from } from "rxjs";
+
+// Modal
+import { ModalComponent } from "src/app/shared/modules/modal/modal.component";
+import { ModalContentData } from "src/app/shared/modules/modal/modal.data";
+import { DeModalComponent } from "src/app/views/data-exposure/de-modal/de-modal.component";
+
+@Component({
+  selector: "app-data-exposure",
+  templateUrl: "./data-exposure.component.html",
+  styleUrls: ["./data-exposure.component.css"]
+})
+export class DataExposureComponent implements OnInit {
+  datas: Array<DataService> = [];
+  t_temp: Array<DataService> = [];
+  columns: Array<any> = []; // column of table
+
+  @ViewChild("searchText") searchText: ElementRef;
+  constructor(
+    private restApiService: RestApiService,
+    private modalService: NgbModal,
+    private notificationService: ToastrNotificationService,
+    private spinner: NgxSpinnerService,
+    private adminService: AdminService
+  ) {
+    // Set page title
+    this.adminService.setTitle("SIDEBAR.DATAEXPOSURE");
+  }
+
+  ngOnInit() {
+    this.spinner.show();
+    let t_data: Array<DataService> = [];
+
+    const get_ds = this.restApiService.getAllDataService().pipe(
+      mergeMap(dss => from(dss)),
+      map(data => {
+        t_data.push(data);
+      })
+    );
+
+    forkJoin(get_ds).subscribe(data => {
+      this.columns = this.initColumn();
+      this.datas = t_data;
+      this.t_temp = [...this.datas];
+      this.updateFilter(this.searchText.nativeElement.value);
+      setTimeout(() => {
+        this.spinner.hide();
+      }, 500);
+    });
+  }
+
+  initColumn() {
+    let t_columns: Array<any> = [];
+
+    t_columns = [
+      {
+        headerName: "NAME",
+        width: "420",
+        sortable: true,
+        dataIndex: "id"
+      },
+      {
+        headerName: "DESCRIPTION",
+        width: "420",
+        sortable: true,
+        dataIndex: "note"
+      },
+      {
+        width: "2",
+        iconButton: "cog",
+        action: "edit"
+      },
+      {
+        width: "2",
+        iconButton: "trash",
+        action: "delete"
+      }
+    ];
+
+    return t_columns;
+  }
+
+  updateFilter(searchValue: string) {
+    const val = searchValue.toLowerCase();
+
+    // filter our data
+    const temp = this.t_temp.filter(data => {
+      return data.id.toLowerCase().indexOf(val) !== -1 || !val;
+    });
+
+    // update the rows
+    this.datas = temp;
+  }
+
+  btnTableAction(passValueArr: Array<any>) {
+    let action = passValueArr[0];
+    let id = passValueArr[1];
+
+    switch (action) {
+      case "edit":
+        this.openModal("edit", id);
+        break;
+      case "delete":
+        const modalRef = this.modalService.open(AlertComponent, {
+          size: "sm",
+          centered: true,
+          backdrop: "static"
+        });
+        modalRef.componentInstance.message = "ARE_YOU_SURE_DELETE";
+        modalRef.componentInstance.passEntry.subscribe(recevicedEntry => {
+          this.restApiService.deleteDataService(id).subscribe(
+            res => {
+              this.ngOnInit();
+              setTimeout(() => {
+                this.notificationService.success("SUCCESSFULLY_DELETED");
+              }, 500);
+            },
+            err => {
+              this.notificationService.error(err);
+            }
+          );
+          modalRef.close();
+        });
+        break;
+    }
+  }
+
+  openModal(mode: string = "", id: number | string) {
+    const modalRef = this.modalService.open(ModalComponent, {
+      size: "lg",
+      centered: true,
+      backdrop: "static"
+    });
+
+    switch (mode) {
+      case "new":
+        let newDS: DataService;
+        let componentNew = new ModalContentData(DeModalComponent, newDS);
+
+        modalRef.componentInstance.title = "NEW_DATASERVICE";
+        modalRef.componentInstance.notice = "";
+        modalRef.componentInstance.mode = "new";
+        modalRef.componentInstance.component = componentNew;
+
+        modalRef.componentInstance.passEntry.subscribe((data: DataService) => {
+          newDS = Object.assign({}, data);
+          this.restApiService.addDataService(newDS).subscribe(
+            res => {
+              this.ngOnInit();
+              setTimeout(() => {
+                this.notificationService.success("SUCCESSFULLY_CREARED");
+              }, 500);
+            },
+            err => {
+              this.notificationService.error(err);
+            }
+          );
+          modalRef.close();
+        });
+        break;
+      case "edit":
+        let index: number = this.datas.findIndex(data => data.id === id);
+        let editDS: DataService = this.datas[index];
+        let componentEdit = new ModalContentData(DeModalComponent, editDS);
+
+        modalRef.componentInstance.title = editDS.id;
+        modalRef.componentInstance.notice = "";
+        modalRef.componentInstance.mode = "edit";
+        modalRef.componentInstance.component = componentEdit;
+
+        modalRef.componentInstance.passEntry.subscribe((data: DataService) => {
+          editDS = Object.assign({}, data);
+          this.restApiService.updateDataService(editDS).subscribe(
+            res => {
+              this.ngOnInit();
+              setTimeout(() => {
+                this.notificationService.success("SUCCESSFULLY_UPDATED");
+              }, 500);
+            },
+            err => {
+              this.notificationService.error(err);
+            }
+          );
+          modalRef.close();
+        });
+        break;
+    }
+  }
+}
diff --git a/components/datalake-handler/admin/src/src/app/views/data-exposure/de-modal/de-modal.component.css b/components/datalake-handler/admin/src/src/app/views/data-exposure/de-modal/de-modal.component.css
new file mode 100644 (file)
index 0000000..0b713d5
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+* ============LICENSE_START=======================================================
+* ONAP : DataLake
+* ================================================================================
+* Copyright 2019 - 2020 QCT
+*=================================================================================
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+* ============LICENSE_END=========================================================
+*/
+
+/*
+ * For every Angular component you write, you may define not only an HTML template,
+ * but also the CSS styles that go with that template, specifying any selectors,
+ * rules, and media queries that you need.
+*/
diff --git a/components/datalake-handler/admin/src/src/app/views/data-exposure/de-modal/de-modal.component.html b/components/datalake-handler/admin/src/src/app/views/data-exposure/de-modal/de-modal.component.html
new file mode 100644 (file)
index 0000000..9b7747b
--- /dev/null
@@ -0,0 +1,84 @@
+<!--
+============LICENSE_START=======================================================
+ONAP : DataLake
+================================================================================
+Copyright 2020 QCT
+=================================================================================
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+============LICENSE_END=========================================================
+-->
+
+
+<div class="container p-4">
+  <div class="form-group">
+    <div class="row">
+      <div class="col-md-12">
+        <label class="dl-emphasis1">{{ "NAME" | translate }}</label>
+      </div>
+    </div>
+    <div class="row">
+      <div class="col-md-12">
+        <input [(ngModel)]="this.data.id" [disabled]="!isAddingMode()" class="form-control dl-input-text" type="text"
+          placeholder="totalBandwidth" />
+      </div>
+    </div>
+  </div>
+
+  <div class="form-group">
+    <div class="row">
+      <div class="col-md-12">
+        <label class="dl-emphasis1">{{ "DESCRIPTION" | translate }}</label>
+      </div>
+    </div>
+    <div class="row">
+      <div class="col-md-12">
+        <input [(ngModel)]="this.data.note" class="form-control dl-input-text" type="text" />
+      </div>
+    </div>
+  </div>
+
+  <div class="form-group">
+    <div class="row">
+      <div class="col-md-12">
+        <label class="dl-emphasis1">{{ "SINK" | translate }}</label>
+      </div>
+    </div>
+    <div class="row">
+      <div class="col-md-6">
+        <select [(ngModel)]="this.data.dbId" class="custom-select dl-input-text">
+          <option *ngFor="let db of dbs" [value]="db.id" [text]="db.name">
+            {{ item }}
+          </option>
+        </select>
+      </div>
+    </div>
+  </div>
+
+  <div class="form-group">
+    <div class="row">
+      <div class="col-md-12">
+        <label class="dl-emphasis1">{{ "SQL_TEMPLATE" | translate }}</label>
+      </div>
+    </div>
+
+    <div class="row">
+      <div class="col-md-12">
+        <textarea [(ngModel)]="this.data.sqlTemplate" class="form-control dl-input-text" rows="8" type="text"
+          length="10000">
+        </textarea>
+      </div>
+    </div>
+
+  </div>
+
+</div>
diff --git a/components/datalake-handler/admin/src/src/app/views/data-exposure/de-modal/de-modal.component.spec.ts b/components/datalake-handler/admin/src/src/app/views/data-exposure/de-modal/de-modal.component.spec.ts
new file mode 100644 (file)
index 0000000..6bda972
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP : DataLake
+ * ================================================================================
+ * Copyright 2020 QCT
+ *=================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import { async, ComponentFixture, TestBed } from "@angular/core/testing";
+
+import { DeModalComponent } from "./de-modal.component";
+
+describe("DeModalComponent", () => {
+  let component: DeModalComponent;
+  let fixture: ComponentFixture<DeModalComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [DeModalComponent]
+    }).compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(DeModalComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it("should create", () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/components/datalake-handler/admin/src/src/app/views/data-exposure/de-modal/de-modal.component.ts b/components/datalake-handler/admin/src/src/app/views/data-exposure/de-modal/de-modal.component.ts
new file mode 100644 (file)
index 0000000..de10e2e
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP : DataLake
+ * ================================================================================
+ * Copyright 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 } from "@angular/core";
+
+import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap";
+import { RestApiService } from "src/app/core/services/rest-api.service";
+import { AdminService } from "src/app/core/services/admin.service";
+import { map, mergeMap } from "rxjs/operators";
+import { from } from "rxjs";
+import { Db } from "src/app/core/models/db.model";
+import { DataService } from "src/app/core/models/data-service.model";
+
+@Component({
+  selector: "app-de-modal",
+  templateUrl: "./de-modal.component.html",
+  styleUrls: ["./de-modal.component.css"]
+})
+export class DeModalComponent implements OnInit {
+  @Input() data: DataService;
+  @Input() mode: string;
+  @Input() selectedIndex: number;
+
+  dbs: Array<Db> = [];
+  dbTypeIds: Array<string> = [];
+
+  constructor(
+    public activeModal: NgbActiveModal,
+    public adminService: AdminService,
+    private restApiService: RestApiService
+  ) {}
+
+  ngOnInit() {
+    // Init data
+    this.initData();
+  }
+
+  initData() {
+    this.getDbs();
+  }
+
+  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.dbId &&
+          this.data.dbId.toString().includes(db.id.toString())
+        ) {
+          db.checkedToSave = true;
+        } else {
+          db.checkedToSave = false;
+        }
+        this.dbs.push(db);
+      })
+    );
+
+    get_dbs.subscribe();
+  }
+
+  onClickMatTab(index: number) {
+    this.selectedIndex = index;
+  }
+
+  isAddingMode() {
+    let flag: boolean = false;
+
+    if (this.mode === "new") flag = true;
+
+    return flag;
+  }
+}
index 3f4959b..138042a 100644 (file)
@@ -7,6 +7,7 @@
     "DASHBOARD": "Portal Setting",
     "DASHBOARDLIST": "Tools",
     "TEMPLATE": "Design",
+    "DATAEXPOSURE": "Data Exposure Service",
     "ABOUT": "About"
   },
   "NAME": "Name",
index 958bb66..7adea34 100644 (file)
@@ -74,7 +74,7 @@ body {
 
 .menu .nav {
   justify-content: center;
-  min-width: 220px;
+  min-width: 250px;
 }
 
 .menu .nav-item {