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" },
{ 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({
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
KafkaModalComponent,
DbModalComponent,
ToolModalComponent,
- TemplateModalComponent
+ TemplateModalComponent,
+ DataExposureComponent,
+ DeModalComponent
],
imports: [
BrowserModule,
KafkaModalComponent,
DbModalComponent,
ToolModalComponent,
- TemplateModalComponent
+ TemplateModalComponent,
+ DeModalComponent
]
})
export class AppModule {}
--- /dev/null
+/*
+ * ============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;
+}
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 = {
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)
+ );
+ }
}
<li class="nav-item ">
<a class="nav-link" [routerLinkActive]="['active']" [routerLinkActiveOptions]="{exact:true}"
- routerLink="/kafka">
+ routerLink="/kafka">
<i class="fas fa-cube"> </i>
{{"SIDEBAR.KAFKA" | translate}}
</a>
<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"> </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"> </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"> </i>
+ {{"SIDEBAR.DATAEXPOSURE" | translate}}
+ </a>
+ </li>
<li class="nav-item">
<a class="nav-link" [routerLinkActive]="['active']" [routerLinkActiveOptions]="{exact:true}"
--- /dev/null
+/*
+* ============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;
+}
--- /dev/null
+<!--
+============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>
--- /dev/null
+/*
+ * ============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();
+ });
+});
--- /dev/null
+/*
+ * ============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;
+ }
+ }
+}
--- /dev/null
+/*
+* ============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.
+*/
--- /dev/null
+<!--
+============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>
--- /dev/null
+/*
+ * ============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();
+ });
+});
--- /dev/null
+/*
+ * ============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;
+ }
+}
"DASHBOARD": "Portal Setting",
"DASHBOARDLIST": "Tools",
"TEMPLATE": "Design",
+ "DATAEXPOSURE": "Data Exposure Service",
"ABOUT": "About"
},
"NAME": "Name",
.menu .nav {
justify-content: center;
- min-width: 220px;
+ min-width: 250px;
}
.menu .nav-item {