summaryrefslogtreecommitdiffstats
path: root/portal-FE-common/src/app
diff options
context:
space:
mode:
Diffstat (limited to 'portal-FE-common/src/app')
-rw-r--r--portal-FE-common/src/app/layout/components/footer/footer.component.scss52
-rw-r--r--portal-FE-common/src/app/layout/components/footer/footer.component.spec.ts62
-rw-r--r--portal-FE-common/src/app/layout/components/footer/footer.component.ts65
-rw-r--r--portal-FE-common/src/app/layout/components/header-menu/header-menu.component.html130
-rw-r--r--portal-FE-common/src/app/layout/components/header-menu/header-menu.component.scss150
-rw-r--r--portal-FE-common/src/app/layout/components/header-menu/header-menu.component.spec.ts62
-rw-r--r--portal-FE-common/src/app/layout/components/header-menu/header-menu.component.ts231
-rw-r--r--portal-FE-common/src/app/layout/components/header/header.component.html130
-rw-r--r--portal-FE-common/src/app/layout/components/header/header.component.scss84
-rw-r--r--portal-FE-common/src/app/layout/components/header/header.component.spec.ts63
-rw-r--r--portal-FE-common/src/app/layout/components/header/header.component.ts181
-rw-r--r--portal-FE-common/src/app/layout/components/sidebar/sidebar.component.html72
-rw-r--r--portal-FE-common/src/app/layout/components/sidebar/sidebar.component.scss228
-rw-r--r--portal-FE-common/src/app/layout/components/sidebar/sidebar.component.spec.ts62
-rw-r--r--portal-FE-common/src/app/layout/components/sidebar/sidebar.component.ts158
-rw-r--r--portal-FE-common/src/app/layout/components/tabbar/tab.ts50
-rw-r--r--portal-FE-common/src/app/layout/components/tabbar/tabbar.component.html97
-rw-r--r--portal-FE-common/src/app/layout/components/tabbar/tabbar.component.scss80
-rw-r--r--portal-FE-common/src/app/layout/components/tabbar/tabbar.component.spec.ts63
-rw-r--r--portal-FE-common/src/app/layout/components/tabbar/tabbar.component.ts95
-rw-r--r--portal-FE-common/src/app/layout/components/userbar/userbar.component.html51
-rw-r--r--portal-FE-common/src/app/layout/components/userbar/userbar.component.scss114
-rw-r--r--portal-FE-common/src/app/layout/components/userbar/userbar.component.spec.ts63
-rw-r--r--portal-FE-common/src/app/layout/components/userbar/userbar.component.ts133
-rw-r--r--portal-FE-common/src/app/layout/layout-routing.module.ts57
-rw-r--r--portal-FE-common/src/app/layout/layout.component.html44
-rw-r--r--portal-FE-common/src/app/layout/layout.component.scss68
-rw-r--r--portal-FE-common/src/app/layout/layout.component.spec.ts62
-rw-r--r--portal-FE-common/src/app/layout/layout.component.ts56
-rw-r--r--portal-FE-common/src/app/layout/layout.module.ts65
-rw-r--r--portal-FE-common/src/app/pages/admins/admins.component.html92
-rw-r--r--portal-FE-common/src/app/pages/admins/admins.component.scss42
-rw-r--r--portal-FE-common/src/app/pages/admins/admins.component.spec.ts62
-rw-r--r--portal-FE-common/src/app/pages/admins/admins.component.ts133
-rw-r--r--portal-FE-common/src/app/pages/admins/new-admin/new-admin.component.html96
-rw-r--r--portal-FE-common/src/app/pages/admins/new-admin/new-admin.component.scss58
-rw-r--r--portal-FE-common/src/app/pages/admins/new-admin/new-admin.component.spec.ts62
-rw-r--r--portal-FE-common/src/app/pages/admins/new-admin/new-admin.component.ts228
-rw-r--r--portal-FE-common/src/app/pages/functional-menu/functional-menu-dialog/functional-menu-dialog.component.html100
-rw-r--r--portal-FE-common/src/app/pages/functional-menu/functional-menu-dialog/functional-menu-dialog.component.scss63
-rw-r--r--portal-FE-common/src/app/pages/functional-menu/functional-menu-dialog/functional-menu-dialog.component.spec.ts63
-rw-r--r--portal-FE-common/src/app/pages/functional-menu/functional-menu-dialog/functional-menu-dialog.component.ts446
-rw-r--r--portal-FE-common/src/app/pages/functional-menu/functional-menu.component.html52
-rw-r--r--portal-FE-common/src/app/pages/functional-menu/functional-menu.component.scss95
-rw-r--r--portal-FE-common/src/app/pages/functional-menu/functional-menu.component.spec.ts25
-rw-r--r--portal-FE-common/src/app/pages/functional-menu/functional-menu.component.ts192
-rw-r--r--portal-FE-common/src/app/pages/functional-menu/jqTreeContextMenu.js195
-rw-r--r--portal-FE-common/src/app/pages/portal-admins/new-portal-admin/new-portal-admin.component.html54
-rw-r--r--portal-FE-common/src/app/pages/portal-admins/new-portal-admin/new-portal-admin.component.scss37
-rw-r--r--portal-FE-common/src/app/pages/portal-admins/new-portal-admin/new-portal-admin.component.spec.ts62
-rw-r--r--portal-FE-common/src/app/pages/portal-admins/new-portal-admin/new-portal-admin.component.ts94
-rw-r--r--portal-FE-common/src/app/pages/portal-admins/portal-admins.component.html87
-rw-r--r--portal-FE-common/src/app/pages/portal-admins/portal-admins.component.scss43
-rw-r--r--portal-FE-common/src/app/pages/portal-admins/portal-admins.component.spec.ts62
-rw-r--r--portal-FE-common/src/app/pages/portal-admins/portal-admins.component.ts124
-rw-r--r--portal-FE-common/src/app/shared/helpers/must-match-validator.ts21
-rw-r--r--portal-FE-common/src/app/shared/model/Admins.ts49
-rw-r--r--portal-FE-common/src/app/shared/model/AllApps.ts44
-rw-r--r--portal-FE-common/src/app/shared/model/PortalAdmin.ts44
-rw-r--r--portal-FE-common/src/app/shared/model/Role.ts51
-rw-r--r--portal-FE-common/src/app/shared/model/RoleFunction.ts51
-rw-r--r--portal-FE-common/src/app/shared/model/UserAccessRoles.ts44
-rw-r--r--portal-FE-common/src/app/shared/model/UserAdminApps.ts42
-rw-r--r--portal-FE-common/src/app/shared/model/application-catalog.model.ts49
-rw-r--r--portal-FE-common/src/app/shared/model/applications-onboarding/applications.ts63
-rw-r--r--portal-FE-common/src/app/shared/model/dynamic-component-manifest/dynamic-component-manifest.ts43
-rw-r--r--portal-FE-common/src/app/shared/model/global-search-item.model.ts45
-rw-r--r--portal-FE-common/src/app/shared/model/index.ts44
-rw-r--r--portal-FE-common/src/app/shared/model/widget-catalog.model.ts44
-rw-r--r--portal-FE-common/src/app/shared/model/widget-onboarding/widget.ts54
-rw-r--r--portal-FE-common/src/app/shared/pipes/application-pipes.module.ts57
-rw-r--r--portal-FE-common/src/app/shared/pipes/elipsis/elipsis.pipe.spec.ts45
-rw-r--r--portal-FE-common/src/app/shared/pipes/elipsis/elipsis.pipe.ts61
-rw-r--r--portal-FE-common/src/app/shared/plugin/dynamic-widget/dynamic-widget.module.ts57
-rw-r--r--portal-FE-common/src/app/shared/plugin/dynamic-widget/list-widget/list-widget.component.html58
-rw-r--r--portal-FE-common/src/app/shared/plugin/dynamic-widget/list-widget/list-widget.component.scss37
-rw-r--r--portal-FE-common/src/app/shared/plugin/dynamic-widget/list-widget/list-widget.component.spec.ts63
-rw-r--r--portal-FE-common/src/app/shared/plugin/dynamic-widget/list-widget/list-widget.component.ts61
-rw-r--r--portal-FE-common/src/app/shared/plugin/plugin-loader/client-plugin-loader.service.ts86
-rw-r--r--portal-FE-common/src/app/shared/plugin/plugin-loader/plugin-externals.ts53
-rw-r--r--portal-FE-common/src/app/shared/plugin/plugin-loader/plugin-loader.service.ts49
-rw-r--r--portal-FE-common/src/app/shared/plugin/plugin.component.html48
-rw-r--r--portal-FE-common/src/app/shared/plugin/plugin.component.scss38
-rw-r--r--portal-FE-common/src/app/shared/plugin/plugin.component.spec.ts63
-rw-r--r--portal-FE-common/src/app/shared/plugin/plugin.component.ts75
-rw-r--r--portal-FE-common/src/app/shared/plugin/plugin.module.ts89
-rw-r--r--portal-FE-common/src/app/shared/plugin/plugins-config.provider.ts75
-rw-r--r--portal-FE-common/src/app/shared/plugin/transfer-state.service.ts85
88 files changed, 7183 insertions, 0 deletions
diff --git a/portal-FE-common/src/app/layout/components/footer/footer.component.scss b/portal-FE-common/src/app/layout/components/footer/footer.component.scss
new file mode 100644
index 00000000..82c81d7c
--- /dev/null
+++ b/portal-FE-common/src/app/layout/components/footer/footer.component.scss
@@ -0,0 +1,52 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal SDK
+ * ===================================================================
+ * Copyright � 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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============================================
+ *
+ *
+ */
+$topnav-background-color: #222;
+
+.footerText {
+ background-color: $topnav-background-color;
+}
+
+.copyright-text {
+ background-color: $topnav-background-color;
+ color: #fff;
+ font-size: 11px;
+ margin-bottom: 0;
+ line-height: 3rem;
+ margin-top: 20px;
+ text-align: center;
+}
diff --git a/portal-FE-common/src/app/layout/components/footer/footer.component.spec.ts b/portal-FE-common/src/app/layout/components/footer/footer.component.spec.ts
new file mode 100644
index 00000000..b8340222
--- /dev/null
+++ b/portal-FE-common/src/app/layout/components/footer/footer.component.spec.ts
@@ -0,0 +1,62 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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 { FooterComponent } from './footer.component';
+
+describe('FooterComponent', () => {
+ let component: FooterComponent;
+ let fixture: ComponentFixture<FooterComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ FooterComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(FooterComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/portal-FE-common/src/app/layout/components/footer/footer.component.ts b/portal-FE-common/src/app/layout/components/footer/footer.component.ts
new file mode 100644
index 00000000..2561a26a
--- /dev/null
+++ b/portal-FE-common/src/app/layout/components/footer/footer.component.ts
@@ -0,0 +1,65 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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 { Component, OnInit } from '@angular/core';
+import { ManifestService } from 'src/app/shared/services';
+
+
+@Component({
+ selector: 'app-footer',
+ templateUrl: './footer.component.html',
+ styleUrls: ['./footer.component.scss']
+})
+export class FooterComponent implements OnInit {
+
+ buildVersion: string;
+ constructor(private manifest: ManifestService) { }
+
+ ngOnInit() {
+ this.buildVersion = '';
+ this.manifestDetails();
+ }
+
+ manifestDetails() {
+ this.manifest.getManifest().subscribe((_res: any) => {
+ this.buildVersion = _res.manifest['Build-Number'];
+ }, (_err) => {
+
+ });
+ }
+}
diff --git a/portal-FE-common/src/app/layout/components/header-menu/header-menu.component.html b/portal-FE-common/src/app/layout/components/header-menu/header-menu.component.html
new file mode 100644
index 00000000..45b4e9f9
--- /dev/null
+++ b/portal-FE-common/src/app/layout/components/header-menu/header-menu.component.html
@@ -0,0 +1,130 @@
+<!--
+ ============LICENSE_START==========================================
+ ONAP Portal
+ ===================================================================
+ Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ ===================================================================
+
+ Unless otherwise specified, all software contained herein is licensed
+ under the Apache License, Version 2.0 (the "License");
+ you may not use this software 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.
+
+ Unless otherwise specified, all documentation contained herein is licensed
+ under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ you may not use this documentation except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://creativecommons.org/licenses/by/4.0/
+
+ Unless required by applicable law or agreed to in writing, documentation
+ 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 style="bottom: tabBottom; display: flex; height: 100%; overflow: hidden">
+ <nav class="navbar navbar-expand-lg fixed-top">
+ <a class="navbar-brand" href=""> <img src="assets/images/global.logo" style="width:14%"/> &nbsp; ONAP Portal</a>
+ <div class="header-menu-display">
+ <app-header-menu></app-header-menu>
+ </div>
+ <button class="navbar-toggler" type="button" (click)="toggleSidebar()">
+ <i class="icon ion-md-menu" style="color:white;"></i>
+ </button>
+ <div class="collapse navbar-collapse">
+ <ul class="navbar-nav ml-auto">
+ <app-global-search></app-global-search>
+ <li class="nav-item dropdown" ngbDropdown>
+ <a href="javascript:void(0)" class="nav-link" ngbDropdownToggle>
+ <i class="icon ion-md-bulb"></i> <b class="caret"></b><span class="sr-only"></span>
+ </a>
+ <div class="custom-dropdown-item" ngbDropdownMenu>
+
+ <li class="dropdown-divider"></li>
+ </div>
+ </li>
+ <li class="nav-item dropdown" ngbDropdown>
+ <a href="javascript:void(0)" class="nav-link" ngbDropdownToggle>
+ <i class="icon ion-md-flag"></i> <b class="caret"></b><span class="sr-only"></span>
+ </a>
+ <div class="dropdown-menu-right" ngbDropdownMenu>
+ <a style="margin-left: 8%;" id="application-role" [routerLink]="['/recentNotifications']"
+ href="javascript:void(0);">
+ {{ 'View All Recent Notifications' }} </a>
+ <li class="dropdown-divider"></li>
+</div>
+</li>
+<li class="nav-item dropdown" ngbDropdown>
+ <a href="javascript:void(0)" class="nav-link" ngbDropdownToggle>
+ <i class="icon ion-md-person"></i> {{firstName}} <b class="caret"></b>
+ </a>
+ <div class="dropdown-menu-right" ngbDropdownMenu>
+<li class="dropdown-item" style="font-weight: lighter">
+ {{firstName}}, {{lastName}}
+</li>
+<li class="dropdown-item">
+ <span class="dropdown-item-name"> {{ 'Email'}}: </span>
+ <div>
+ <span class="dropdown-item-value">
+ {{loginSnippetEmail}}
+ </span>
+ </div>
+</li>
+<li class="dropdown-item">
+ <span class="dropdown-item-name"> {{ 'User Id' }}: </span>
+ <div>
+ <span class="dropdown-item-value">
+ {{loginSnippetUserid}}
+ </span>
+ </div>
+</li>
+<li class="dropdown-item">
+ <span class="dropdown-item-name"> {{ 'Last login' }}: </span>
+ <div>
+ <span class="dropdown-item-value">
+ {{lastLogin | date:'medium'}}
+ </span>
+ </div>
+</li>
+<li class="custom-display-item">
+ <a (click)="getUserApplicationRoles()" href="javascript:void(0);"><span><i class="icon ion-md-add-circle-outline"
+ [ngClass]="{true: 'icon ion-md-add-circle-outline', false: 'icon ion-md-remove-circle-outline'}[ !displayUserAppRoles]"></i>
+ {{ 'Applications and Roles' }} </span></a>
+ <span class="onap-spinner" *ngIf="isLoading"></span>
+</li> <br>
+<div class="custom-display-item approles" [hidden]="!displayUserAppRoles">
+ <div *ngFor="let ua of userapproles ; index as i">
+ <div class="reg-userApp-value">
+ <span class="dropdown-item-name">{{ua.App}}:</span>
+ </div>
+ <div *ngFor="let role of ua.Roles ; index as i" class="reg-userAppRoles-value">
+ <span *ngIf="role.indexOf('global_')!=-1" id="required" style="color: Red;" visible="false">
+ *</span> <span class="dropdown-item-value">{{role}}</span>
+ </div>
+ <br>
+ </div>
+</div>
+<hr>
+<div id="reg-logout-div" >
+<button type="button" class="btn btn-primary" (click)="allAppsLogout()">
+ <i class="icon ion-md-log-out"></i> {{ 'Log Out' }} </button></div>
+</div>
+</li>
+</ul>
+</div>
+</nav>
+</div> \ No newline at end of file
diff --git a/portal-FE-common/src/app/layout/components/header-menu/header-menu.component.scss b/portal-FE-common/src/app/layout/components/header-menu/header-menu.component.scss
new file mode 100644
index 00000000..d69b8580
--- /dev/null
+++ b/portal-FE-common/src/app/layout/components/header-menu/header-menu.component.scss
@@ -0,0 +1,150 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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============================================
+ *
+ *
+ */
+ .header-menu-item-div
+ {
+ float: left;
+ margin-right: 5%;
+
+ }
+ .header-menu-item-li
+ {
+ float: left;
+ margin-right: 2%;
+
+
+ }
+ .header-menu-item-link
+ {
+ font-family:"Open Sans", Arial;
+ font-size:16px;
+ color:#999;
+ text-decoration:none;
+
+ }
+ #parentmenu-tabs:hover {
+ color: #fff;
+ }
+
+
+
+
+ .third-level-menu{
+ column-count: 4;
+ line-height: 12px;
+ overflow-x: hidden;
+ overflow-y: hidden;
+ column-gap: 13px;
+ column-rule: 1px outset #d2d2d2;
+ margin-left:20px;
+ }
+
+
+
+ .third-level-menu a{
+ color:black;
+ }
+
+ .third-level-menu li a {
+ color: #333;
+ display: inline-flex;
+ padding: 7px 15px;
+ font-family:"Omnes-ECOMP-W02", Arial;
+ margin-top:5px;
+ margin-bottom:5px;
+ }
+
+ .third-level-menu li{
+ width:100%;
+ border-bottom: 1px solid #d2d2d2;
+ }
+
+
+ .b2b-header-tabs .header-secondary .header-subitem a.menu__item{
+ font-size:16px;
+ }
+
+ .third-level-title{
+ font-size:15px;
+ font-weight: 700;
+ }
+ .header-secondlevel-menu
+ {
+ background-color: #fff;
+ position: fixed;
+ right:1%;
+ width: -webkit-fill-available;
+
+ }
+
+ .header-thirdlevel-menu
+ {
+ background-color: #fff;
+ position: fixed;
+ left:0;
+ height: 70%;
+ width: 100%;
+ }
+
+ a.menu__item{
+ font-size:16px;
+ font-family:"Open Sans", Arial;
+ color:#333;
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ \ No newline at end of file
diff --git a/portal-FE-common/src/app/layout/components/header-menu/header-menu.component.spec.ts b/portal-FE-common/src/app/layout/components/header-menu/header-menu.component.spec.ts
new file mode 100644
index 00000000..889f499a
--- /dev/null
+++ b/portal-FE-common/src/app/layout/components/header-menu/header-menu.component.spec.ts
@@ -0,0 +1,62 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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 { HeaderMenuComponent } from './header-menu.component';
+
+describe('HeaderMenuComponent', () => {
+ let component: HeaderMenuComponent;
+ let fixture: ComponentFixture<HeaderMenuComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ HeaderMenuComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(HeaderMenuComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/portal-FE-common/src/app/layout/components/header-menu/header-menu.component.ts b/portal-FE-common/src/app/layout/components/header-menu/header-menu.component.ts
new file mode 100644
index 00000000..eb8f747a
--- /dev/null
+++ b/portal-FE-common/src/app/layout/components/header-menu/header-menu.component.ts
@@ -0,0 +1,231 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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 * as _ from 'underscore';
+import { Component, OnInit } from '@angular/core';
+import { MenusService } from 'src/app/shared/services/menus/menus.service';
+import { AddTabFunctionService } from 'src/app/shared/services/tab/add-tab-function.service';
+import { Router } from '@angular/router';
+
+@Component({
+ selector: 'app-header-menu',
+ templateUrl: './header-menu.component.html',
+ styleUrls: ['./header-menu.component.scss']
+})
+export class HeaderMenuComponent implements OnInit {
+ hideMenus: boolean[] = [];
+ hideSecondLevelMenus: boolean[][] = [];
+ hideThirdLevelMenus: boolean[] = [];
+ megaMenuDataObject: any[];
+ favoritesMenuItems: any[];
+ favoritesWindow: boolean;
+ showFavorites: boolean;
+ emptyFavorites: boolean;
+ favoriteItemsCount: number;
+
+ constructor(public router: Router, private menusService: MenusService, private addTabFuntionService: AddTabFunctionService) { }
+
+ ngOnInit() {
+ //this.hideMenus[0] = false;
+ this.getFunctionalMenuForUser();
+
+ }
+
+ unflatten(array: any, parent?: any, tree?: any) {
+ tree = typeof tree !== 'undefined' ? tree : [];
+ parent = typeof parent !== 'undefined' ? parent : { menuId: null };
+ var children = _.filter(array, function (child: any) {
+ return child.parentMenuId == parent.menuId;
+ });
+ if (!_.isEmpty(children)) {
+ if (parent.menuId === null) {
+ tree = children;
+ } else {
+ parent['children'] = children
+ }
+ _.each(children, function (child: any) {
+ this.unflatten(array, child)
+ }, this);
+ }
+
+ return tree;
+ }
+ getFunctionalMenuForUser() {
+ this.menusService.getFunctionalMenuForUser().subscribe((jsonHeaderMenu: any) => {
+ this.megaMenuDataObject = this.unflatten(jsonHeaderMenu);
+ // for (let entry of this.megaMenuDataObject) {
+ // console.log('First level '+entry.text);
+ // for (let secondLevel of entry.children)
+ // {
+ // if(secondLevel)
+ // {
+ // console.log('Second level '+secondLevel.text);
+ // for (let thirdLevel of secondLevel.children)
+ // {
+ // console.log('Third level '+thirdLevel.text);
+ // }
+ // }
+
+ // }
+
+ // }
+
+
+ }, (err) => {
+ console.log('HeaderCtrl::GetFunctionalMenuForUser: HeaderCtrl json returned: ' + err);
+ });
+
+ }
+ getFavoriteItems() {
+ this.menusService.getFavoriteItems().toPromise().then((jsonFavourites: any) => {
+ this.favoritesMenuItems = jsonFavourites;
+ if (this.favoritesMenuItems) {
+ this.favoriteItemsCount = this.favoritesMenuItems.length;
+ }
+ }, (err) => {
+ console.log('HeaderCtrl::getFavoriteItems: HeaderCtrl json returned: ' + err);
+ });
+ }
+ loadFirstLevel(index: any) {
+ this.hideMenus = [];
+ this.hideSecondLevelMenus = [];
+ for (let firstLevelIndex = 0; firstLevelIndex < this.megaMenuDataObject.length; firstLevelIndex++) {
+ this.hideMenus.push(false);
+ this.hideSecondLevelMenus.push(new Array(this.megaMenuDataObject[firstLevelIndex].length).fill(false));
+ }
+ this.hideMenus[index] = true;
+ if (!this.favoritesMenuItems) {
+ this.getFavoriteItems();
+ }
+
+ }
+ isUrlFavorite(menuId: any) {
+ if (this.favoritesMenuItems) {
+ var jsonMenu = JSON.stringify(this.favoritesMenuItems);
+ var isMenuFavorite = jsonMenu.indexOf('menuId\":' + menuId);
+ if (isMenuFavorite == -1) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+ else {
+ return false;
+ }
+ }
+ submenuLevelAction(index: any, column: any) {
+ //console.log('index and column' + index + column);
+ if (index == 'Favorites' && this.favoriteItemsCount != 0) {
+ this.favoritesWindow = true;
+ this.showFavorites = true;
+ this.emptyFavorites = false;
+ }
+ if (index == 'Favorites' && this.favoriteItemsCount == 0) {
+ this.favoritesWindow = true;
+ this.showFavorites = false;
+ this.emptyFavorites = true;
+ }
+ if (index != 'Favorites') {
+ this.favoritesWindow = false;
+ this.showFavorites = false;
+ this.emptyFavorites = false;
+ }
+ }
+ hideFavoritesWindow() {
+ this.showFavorites = false;
+ this.emptyFavorites = false;
+ }
+ removeAsFavoriteItem(event: any, menuId: any) {
+ this.menusService.removeFavoriteItem(menuId).subscribe(() => {
+ //angular.element('#' + event.target.id).css('color', '#666666');
+ this.getFavoriteItems();
+ }, (err) => {
+ console.error('HeaderCtrl::removeAsFavoriteItem: API removeFavoriteItem error: ' + err);
+ });
+ }
+ hideThirdLevelMenu(firstLevelIndex: any, secondLevelIndex: any) {
+ this.hideSecondLevelMenus = [];
+ for (let firstLevelIndex = 0; firstLevelIndex < this.megaMenuDataObject.length; firstLevelIndex++) {
+ this.hideSecondLevelMenus.push(new Array(this.megaMenuDataObject[firstLevelIndex].length).fill(false));
+ }
+ this.hideSecondLevelMenus[firstLevelIndex][secondLevelIndex] = true;
+ }
+
+ clickOutSide(event: any) {
+ this.hideMenus = [];
+ this.hideSecondLevelMenus = [];
+ for (let firstLevelIndex = 0; firstLevelIndex < this.megaMenuDataObject.length; firstLevelIndex++) {
+ this.hideMenus.push(false);
+ this.hideSecondLevelMenus.push(new Array(this.megaMenuDataObject[firstLevelIndex].length).fill(false));
+ }
+
+ }
+ setAsFavoriteItem(event: any, menuId: any) {
+
+ }
+ goToUrl(item: any) {
+ //console.log('Get into URL function' + item.url);
+ let url = item.url;
+ let restrictedApp = item.restrictedApp;
+ if (!url) {
+ console.log('HeaderCtrl::goToUrl: No url found for this application, doing nothing..');
+ return;
+ }
+ if (restrictedApp) {
+ window.open(url, '_blank');
+ } else {
+ if (item.url == "getAccess" || item.url == "contactUs") {
+
+ this.router.navigate(['/' + item.url]);
+
+ } else {
+ var tabContent = {
+ id: new Date(),
+ title: item.text,
+ url: item.url,
+ appId: item.appid
+ };
+ this.addTabFuntionService.filter(tabContent);
+ }
+ }
+
+ }
+ auditLog(link: any, action: any) {
+
+ }
+
+}
diff --git a/portal-FE-common/src/app/layout/components/header/header.component.html b/portal-FE-common/src/app/layout/components/header/header.component.html
new file mode 100644
index 00000000..45b4e9f9
--- /dev/null
+++ b/portal-FE-common/src/app/layout/components/header/header.component.html
@@ -0,0 +1,130 @@
+<!--
+ ============LICENSE_START==========================================
+ ONAP Portal
+ ===================================================================
+ Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ ===================================================================
+
+ Unless otherwise specified, all software contained herein is licensed
+ under the Apache License, Version 2.0 (the "License");
+ you may not use this software 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.
+
+ Unless otherwise specified, all documentation contained herein is licensed
+ under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ you may not use this documentation except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://creativecommons.org/licenses/by/4.0/
+
+ Unless required by applicable law or agreed to in writing, documentation
+ 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 style="bottom: tabBottom; display: flex; height: 100%; overflow: hidden">
+ <nav class="navbar navbar-expand-lg fixed-top">
+ <a class="navbar-brand" href=""> <img src="assets/images/global.logo" style="width:14%"/> &nbsp; ONAP Portal</a>
+ <div class="header-menu-display">
+ <app-header-menu></app-header-menu>
+ </div>
+ <button class="navbar-toggler" type="button" (click)="toggleSidebar()">
+ <i class="icon ion-md-menu" style="color:white;"></i>
+ </button>
+ <div class="collapse navbar-collapse">
+ <ul class="navbar-nav ml-auto">
+ <app-global-search></app-global-search>
+ <li class="nav-item dropdown" ngbDropdown>
+ <a href="javascript:void(0)" class="nav-link" ngbDropdownToggle>
+ <i class="icon ion-md-bulb"></i> <b class="caret"></b><span class="sr-only"></span>
+ </a>
+ <div class="custom-dropdown-item" ngbDropdownMenu>
+
+ <li class="dropdown-divider"></li>
+ </div>
+ </li>
+ <li class="nav-item dropdown" ngbDropdown>
+ <a href="javascript:void(0)" class="nav-link" ngbDropdownToggle>
+ <i class="icon ion-md-flag"></i> <b class="caret"></b><span class="sr-only"></span>
+ </a>
+ <div class="dropdown-menu-right" ngbDropdownMenu>
+ <a style="margin-left: 8%;" id="application-role" [routerLink]="['/recentNotifications']"
+ href="javascript:void(0);">
+ {{ 'View All Recent Notifications' }} </a>
+ <li class="dropdown-divider"></li>
+</div>
+</li>
+<li class="nav-item dropdown" ngbDropdown>
+ <a href="javascript:void(0)" class="nav-link" ngbDropdownToggle>
+ <i class="icon ion-md-person"></i> {{firstName}} <b class="caret"></b>
+ </a>
+ <div class="dropdown-menu-right" ngbDropdownMenu>
+<li class="dropdown-item" style="font-weight: lighter">
+ {{firstName}}, {{lastName}}
+</li>
+<li class="dropdown-item">
+ <span class="dropdown-item-name"> {{ 'Email'}}: </span>
+ <div>
+ <span class="dropdown-item-value">
+ {{loginSnippetEmail}}
+ </span>
+ </div>
+</li>
+<li class="dropdown-item">
+ <span class="dropdown-item-name"> {{ 'User Id' }}: </span>
+ <div>
+ <span class="dropdown-item-value">
+ {{loginSnippetUserid}}
+ </span>
+ </div>
+</li>
+<li class="dropdown-item">
+ <span class="dropdown-item-name"> {{ 'Last login' }}: </span>
+ <div>
+ <span class="dropdown-item-value">
+ {{lastLogin | date:'medium'}}
+ </span>
+ </div>
+</li>
+<li class="custom-display-item">
+ <a (click)="getUserApplicationRoles()" href="javascript:void(0);"><span><i class="icon ion-md-add-circle-outline"
+ [ngClass]="{true: 'icon ion-md-add-circle-outline', false: 'icon ion-md-remove-circle-outline'}[ !displayUserAppRoles]"></i>
+ {{ 'Applications and Roles' }} </span></a>
+ <span class="onap-spinner" *ngIf="isLoading"></span>
+</li> <br>
+<div class="custom-display-item approles" [hidden]="!displayUserAppRoles">
+ <div *ngFor="let ua of userapproles ; index as i">
+ <div class="reg-userApp-value">
+ <span class="dropdown-item-name">{{ua.App}}:</span>
+ </div>
+ <div *ngFor="let role of ua.Roles ; index as i" class="reg-userAppRoles-value">
+ <span *ngIf="role.indexOf('global_')!=-1" id="required" style="color: Red;" visible="false">
+ *</span> <span class="dropdown-item-value">{{role}}</span>
+ </div>
+ <br>
+ </div>
+</div>
+<hr>
+<div id="reg-logout-div" >
+<button type="button" class="btn btn-primary" (click)="allAppsLogout()">
+ <i class="icon ion-md-log-out"></i> {{ 'Log Out' }} </button></div>
+</div>
+</li>
+</ul>
+</div>
+</nav>
+</div> \ No newline at end of file
diff --git a/portal-FE-common/src/app/layout/components/header/header.component.scss b/portal-FE-common/src/app/layout/components/header/header.component.scss
new file mode 100644
index 00000000..65a4be04
--- /dev/null
+++ b/portal-FE-common/src/app/layout/components/header/header.component.scss
@@ -0,0 +1,84 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal SDK
+ * ===================================================================
+ * Copyright � 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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============================================
+ *
+ *
+ */
+$topnav-background-color: #222;
+:host {
+ .navbar {
+ background-color: $topnav-background-color;
+ .navbar-brand {
+ color: #fff;
+ }
+ .nav-item > a {
+ color: #999;
+ &:hover {
+ color: #fff;
+ }
+ }
+ }
+
+ .dropdown-menu-right.dropdown-menu.show{
+ width: 250px;
+ }
+ .dropdown-item-name {
+ font-weight: bold;
+ }
+
+ .dropdown-item-value {
+ font-weight: lighter;
+ }
+
+ .custom-display-item {
+ display: block;
+ width: 100%;
+ padding: 0.25rem 1.5rem;
+ clear: both;
+ font-weight: 400;
+ color: #212529;
+ text-align: inherit;
+ white-space: nowrap;
+ background-color: transparent;
+ border: 0;
+ }
+
+ .custom-display-item.approles {
+ overflow-y: scroll;
+ height: 250px;
+ }
+ .header-menu-display {
+ width: 250px;
+ }
+}
diff --git a/portal-FE-common/src/app/layout/components/header/header.component.spec.ts b/portal-FE-common/src/app/layout/components/header/header.component.spec.ts
new file mode 100644
index 00000000..1bcd2ffb
--- /dev/null
+++ b/portal-FE-common/src/app/layout/components/header/header.component.spec.ts
@@ -0,0 +1,63 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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 { 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/portal-FE-common/src/app/layout/components/header/header.component.ts b/portal-FE-common/src/app/layout/components/header/header.component.ts
new file mode 100644
index 00000000..cb6bdd31
--- /dev/null
+++ b/portal-FE-common/src/app/layout/components/header/header.component.ts
@@ -0,0 +1,181 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal SDK
+ * ===================================================================
+ * Copyright � 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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 { Component, OnInit } from '@angular/core';
+import { Router, NavigationEnd } from '@angular/router';
+import { UserProfileService, MenusService } from 'src/app/shared/services';
+import { CookieService } from 'ngx-cookie-service';
+
+@Component({
+ selector: 'app-header',
+ templateUrl: './header.component.html',
+ styleUrls: ['./header.component.scss']
+})
+export class HeaderComponent implements OnInit {
+ public pushRightClass: string;
+ firstName: string;
+ lastName: string;
+ loginSnippetUserid: any;
+ lastLogin: number;
+ loginSnippetEmail: any;
+ userapproles: any[];
+ displayUserAppRoles: any;
+ isLoading: boolean;
+
+ constructor(public router: Router, private userProfileService: UserProfileService, private menusService: MenusService, private cookieService: CookieService) {
+
+ this.router.events.subscribe(val => {
+ if (
+ val instanceof NavigationEnd &&
+ window.innerWidth <= 992 &&
+ this.isToggled()
+ ) {
+ this.toggleSidebar();
+ }
+ });
+ }
+
+ ngOnInit() {
+ this.pushRightClass = 'push-right';
+ this.getUserInformation();
+ }
+
+ getUserInformation() {
+ this.userProfileService.getFunctionalMenuStaticInfo().toPromise().then((res: any) => {
+ if (res == null || res.firstName == null || res.firstName == '' || res.lastName == null || res.lastName == '') {
+ // $log.info('HeaderCtrl: failed to get all required data, trying user profile');
+ this.userProfileService.getUserProfile().toPromise().then((profile: any) => {
+ this.firstName = profile.firstName;
+ this.lastName = profile.lastName;
+ }, (err) => {
+ // $log.error('Header Controller:: getUserProfile() failed: ' + err);
+ });
+ } else {
+ this.firstName = res.firstName;
+ this.lastName = res.lastName;
+ this.loginSnippetEmail = res.email;
+ this.loginSnippetUserid = res.userId;
+ this.lastLogin = Date.parse(res.last_login);
+ }
+ sessionStorage.userId = res.userId;
+ this.menusService.getFunctionalMenuForUser().toPromise().then((jsonHeaderMenu: any) => {
+ // $scope.menuItems = unflatten(jsonHeaderMenu);
+ // $scope.megaMenuDataObject = $scope.menuItems;
+ }, (err) => {
+ // $log.error('HeaderCtrl::GetFunctionalMenuForUser: HeaderCtrl json returned: ' + err);
+ });
+
+ }, (err) => {
+ // $log.error('HeaderCtrl::getFunctionalMenuStaticInfo failed: ' + err);
+ })
+ }
+
+ // unflatten = function( array, parent, tree ){
+
+ // tree = typeof tree !== 'undefined' ? tree : [];
+ // parent = typeof parent !== 'undefined' ? parent : { menuId: null };
+ // var children = _.filter( array, function(child){ return child.parentMenuId == parent.menuId; });
+
+ // if( !_.isEmpty( children ) ){
+ // if( parent.menuId === null ){
+ // tree = children;
+ // }else{
+ // parent['children'] = children
+ // }
+ // _.each( children, function( child ){ unflatten( array, child ) } );
+ // }
+
+ // return tree;
+ // }
+
+ getUserApplicationRoles() {
+ this.userapproles = [];
+ if (this.displayUserAppRoles) {
+ this.displayUserAppRoles = false;
+ } else {
+ this.displayUserAppRoles = true;
+ this.isLoading = true;
+ this.userProfileService.getUserAppRoles(this.loginSnippetUserid)
+ .subscribe((res: any) => {
+ this.isLoading = false;
+ for (var i = 0; i < res.length; i++) {
+ var userapprole = {
+ App: res[i].appName,
+ Roles: res[i].roleNames,
+ };
+ this.userapproles.push(userapprole);
+ }
+ }, (err) => {
+ this.isLoading = false;
+ });
+ }
+ }
+
+ allAppsLogout() {
+ this.firstName="";
+ this.lastName="";
+ this.displayUserAppRoles=false;
+ var cookieTabs = this.cookieService.get("visInVisCookieTabs").toString;
+ if(cookieTabs!=null){
+ for(var t in cookieTabs){
+
+ var url = cookieTabs[t].content;
+ if(url != "") {
+ this.menusService.logout(url);
+ }
+ }
+ }
+ // wait for individual applications to log out before the portal logout
+ setTimeout(function() {
+ window.location.href = "logout.htm";
+ }, 2000);
+ }
+
+ isToggled(): boolean {
+ const dom: Element = document.querySelector('body');
+ return dom.classList.contains(this.pushRightClass);
+ }
+
+ toggleSidebar() {
+ const dom: any = document.querySelector('body');
+ dom.classList.toggle(this.pushRightClass);
+ }
+
+ onLoggedout() {
+ localStorage.removeItem('isLoggedin');
+ }
+}
diff --git a/portal-FE-common/src/app/layout/components/sidebar/sidebar.component.html b/portal-FE-common/src/app/layout/components/sidebar/sidebar.component.html
new file mode 100644
index 00000000..e2f4f3a0
--- /dev/null
+++ b/portal-FE-common/src/app/layout/components/sidebar/sidebar.component.html
@@ -0,0 +1,72 @@
+<!--
+ ============LICENSE_START==========================================
+ ONAP Portal
+ ===================================================================
+ Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ ===================================================================
+
+ Unless otherwise specified, all software contained herein is licensed
+ under the Apache License, Version 2.0 (the "License");
+ you may not use this software 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.
+
+ Unless otherwise specified, all documentation contained herein is licensed
+ under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ you may not use this documentation except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://creativecommons.org/licenses/by/4.0/
+
+ Unless required by applicable law or agreed to in writing, documentation
+ 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============================================
+
+
+ -->
+
+<nav class="sidebar" [ngClass]="{sidebarPushRight: isActive, collapsed: collapsed}">
+ <div class="toggle-button" [ngClass]="{collapsed: collapsed}" (click)="toggleCollapsed()">
+ <i class="icon ion-md-arrow-{{collapsed?'dropright':'dropleft'}}" style="float:right"></i> <i
+ class="icon ion-md-arrow-{{collapsed?'dropright':'dropleft'}}" style="float:right"></i>&nbsp;
+ </div>
+ <div class="list-group" *ngFor="let menu of menuData ; index as item">
+ <a href="{{menu.href}}" *ngIf="!showOnlyParentMenu" [routerLinkActive]="['router-link-active']"
+ class="list-group-item">
+ <i class="icon ion-md-{{menu.imageSrc}}"></i>&nbsp;
+ <span>{{menu.name}}</span>
+ </a>
+ <a [routerLink]="menu.state" *ngIf="showOnlyParentMenu" [routerLinkActive]="['router-link-active']"
+ class="list-group-item">
+ <i class="icon ion-md-{{menu.imageSrc}}"></i>&nbsp;
+ <span>{{menu.name}}</span>
+ </a>
+ <div class="nested-menu" *ngIf="menu.menuItems.length > 0">
+ <a href="javascript:void(0)" class="list-group-item" (click)="addExpandClass(menu.name)">
+ <i class="fa fa-plus"></i>&nbsp;
+ <span>{{menu.name}}</span>
+ </a>
+ <li class="nested" [class.expand]="showMenu === menu.name">
+ <ul class="submenu">
+ <li *ngFor="let menuItems of menu.menuItems">
+ <a href="{{menuItems.href}}">
+ <i class="fa fa-monument"></i>&nbsp;
+ <span>{{ menuItems.name }}</span>
+ </a>
+ </li>
+ </ul>
+ </li>
+ </div>
+ </div>
+</nav> \ No newline at end of file
diff --git a/portal-FE-common/src/app/layout/components/sidebar/sidebar.component.scss b/portal-FE-common/src/app/layout/components/sidebar/sidebar.component.scss
new file mode 100644
index 00000000..8d3c51fe
--- /dev/null
+++ b/portal-FE-common/src/app/layout/components/sidebar/sidebar.component.scss
@@ -0,0 +1,228 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal SDK
+ * ===================================================================
+ * Copyright � 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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============================================
+ *
+ *
+ */
+$topnav-background-color: #fff;
+.sidebar {
+ border-radius: 0;
+ position: relative;
+ z-index: 1000;
+ //top: 56px;
+ left: 270px;
+ width: 270px;
+ margin-left: -270px;
+ margin-bottom: 48px;
+ border: none;
+ border-radius: 0;
+ overflow-y: auto;
+ background-color: $topnav-background-color;
+ bottom: 0;
+ overflow-x: hidden;
+ padding-bottom: 40px;
+ white-space: nowrap;
+ -webkit-transition: all 0.2s ease-in-out;
+ -moz-transition: all 0.2s ease-in-out;
+ -ms-transition: all 0.2s ease-in-out;
+ -o-transition: all 0.2s ease-in-out;
+ transition: all 0.2s ease-in-out;
+ .list-group {
+ a.list-group-item {
+ background: $topnav-background-color;
+ border: 0;
+ border-top: 1px solid #999;
+ border-radius: 0;
+ color: #0568ae;
+ text-decoration: none;
+ .icon {
+ margin-right: 10px;
+ color: #000;
+ }
+ }
+ a:hover {
+ background: darken($topnav-background-color, 2%);
+ color: #000;
+ }
+ a.router-link-active {
+ background: darken($topnav-background-color, 5%);
+ color: #000;
+ }
+ .header-fields {
+ padding-top: 10px;
+
+ > .list-group-item:first-child {
+ border-top: 1px solid rgba(255, 255, 255, 0.2);
+ }
+ }
+ }
+ .sidebar-dropdown {
+ *:focus {
+ border-radius: none;
+ border: none;
+ }
+ .panel-title {
+ font-size: 1rem;
+ height: 50px;
+ margin-bottom: 0;
+ a {
+ color: #999;
+ text-decoration: none;
+ font-weight: 400;
+ background: $topnav-background-color;
+ span {
+ position: relative;
+ display: block;
+ padding: 0.75rem 1.5rem;
+ padding-top: 1rem;
+ }
+ }
+ a:hover,
+ a:focus {
+ color: #fff;
+ outline: none;
+ outline-offset: -2px;
+ }
+ }
+ .panel-title:hover {
+ background: darken($topnav-background-color, 5%);
+ }
+ .panel-collapse {
+ border-radious: 0;
+ border: none;
+ .panel-body {
+ .list-group-item {
+ border-radius: 0;
+ background-color: $topnav-background-color;
+ border: 0 solid transparent;
+ a {
+ color: #999;
+ }
+ a:hover {
+ color: #fff;
+ }
+ }
+ .list-group-item:hover {
+ background: darken($topnav-background-color, 5%);
+ }
+ }
+ }
+ }
+}
+
+.nested-menu {
+ .list-group-item {
+ cursor: pointer;
+ }
+ .nested {
+ list-style-type: none;
+ }
+ ul.submenu {
+ display: none;
+ height: 0;
+ }
+ & .expand {
+ ul.submenu {
+ display: block;
+ list-style-type: none;
+ height: auto;
+ li {
+ a {
+ color: #0568ae;
+ padding: 10px;
+ display: block;
+ }
+ }
+ }
+ }
+}
+@media screen and (max-width: 992px) {
+ .sidebar {
+ top: 54px;
+ left: 0px;
+ }
+}
+@media print {
+ .sidebar {
+ display: none !important;
+ }
+}
+@media (min-width: 992px) {
+ .header-fields {
+ display: none;
+ }
+}
+
+::-webkit-scrollbar {
+ width: 8px;
+}
+
+::-webkit-scrollbar-track {
+ -webkit-box-shadow: inset 0 0 0px rgba(255, 255, 255, 1);
+ border-radius: 3px;
+}
+
+::-webkit-scrollbar-thumb {
+ border-radius: 3px;
+ -webkit-box-shadow: inset 0 0 3px rgba(255, 255, 255, 1);
+}
+
+.toggle-button {
+ width: 270px;
+ cursor: pointer;
+ padding: 12px;
+ bottom: 0;
+ color: #0568ae;
+ background: #fff;
+ i {
+ font-size: 23px;
+ }
+ &:hover {
+ background: darken($topnav-background-color, 2%);
+ color: #000;
+ }
+ border-top: 1px solid #999;
+ -webkit-transition: all 0.2s ease-in-out;
+ -moz-transition: all 0.2s ease-in-out;
+ -ms-transition: all 0.2s ease-in-out;
+ -o-transition: all 0.2s ease-in-out;
+ transition: all 0.2s ease-in-out;
+}
+
+.collapsed {
+ width: 60px;
+ span {
+ display: none;
+ }
+}
diff --git a/portal-FE-common/src/app/layout/components/sidebar/sidebar.component.spec.ts b/portal-FE-common/src/app/layout/components/sidebar/sidebar.component.spec.ts
new file mode 100644
index 00000000..92caeb42
--- /dev/null
+++ b/portal-FE-common/src/app/layout/components/sidebar/sidebar.component.spec.ts
@@ -0,0 +1,62 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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 { 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/portal-FE-common/src/app/layout/components/sidebar/sidebar.component.ts b/portal-FE-common/src/app/layout/components/sidebar/sidebar.component.ts
new file mode 100644
index 00000000..1c689e16
--- /dev/null
+++ b/portal-FE-common/src/app/layout/components/sidebar/sidebar.component.ts
@@ -0,0 +1,158 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal SDK
+ * ===================================================================
+ * Copyright © 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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 { Component, Output, EventEmitter, OnInit, Input } from '@angular/core';
+import { Router, NavigationEnd } from '@angular/router';
+import { SidebarService } from '../../../shared/services/index'
+
+@Component({
+ selector: 'app-sidebar',
+ templateUrl: './sidebar.component.html',
+ styleUrls: ['./sidebar.component.scss']
+})
+export class SidebarComponent implements OnInit {
+ @Input() labelName: string;
+ isActive: boolean;
+ collapsed: boolean;
+ showMenu: string;
+ pushRightClass: string;
+ result: any;
+ showOnlyParentMenu: boolean;
+ leftParentData: any;
+ leftChildData: any;
+ menuData: Array<object> = [];
+ page: any;
+
+ @Output() collapsedEvent = new EventEmitter<boolean>();
+
+ constructor(public router: Router, public sidebarService: SidebarService) {
+ this.router.events.subscribe(val => {
+ if (
+ val instanceof NavigationEnd &&
+ window.innerWidth <= 992 &&
+ this.isToggled()
+ ) {
+ this.toggleSidebar();
+ }
+ });
+ }
+
+ ngOnInit() {
+ this.isActive = false;
+ this.collapsed = false;
+ this.showMenu = '';
+ this.pushRightClass = 'push-right';
+ this.sidebarService.getLeftMenu()
+ .subscribe(data => {
+ this.result = data;
+ if (this.result.data && this.result.data2) {
+ this.leftParentData = JSON.parse(this.result.data);
+ this.leftChildData = JSON.parse(this.result.data2);
+ } else {
+ this.labelName = this.result.label;
+ this.leftParentData = this.result.navItems;
+ this.showOnlyParentMenu = true;
+ }
+
+ for (var i = 0; i < this.leftParentData.length; i++) {
+ var parentItem = {
+ name: null,
+ imageSrc: null,
+ href: null,
+ menuItems: [],
+ state: null
+ }
+ if (this.showOnlyParentMenu) {
+ parentItem.name = this.leftParentData[i].name;
+ parentItem.imageSrc = this.leftParentData[i].imageSrc;
+ parentItem.state = '/'+this.leftParentData[i].state;
+ } else {
+ parentItem.name = this.leftParentData[i].label;
+ parentItem.imageSrc = this.leftParentData[i].imageSrc;
+ }
+ // Add link to items with no subitems
+ if (!this.showOnlyParentMenu) {
+ if (this.leftChildData[i].length == 0)
+ parentItem.href = this.leftParentData[i].action;
+
+ for (var j = 0; j < this.leftChildData[i].length; j++) {
+
+ var childItem = {
+ name: null,
+ href: null
+ };
+ if (this.leftChildData[i][j].label != null && this.leftChildData[i][j].label.length > 0) {
+
+ childItem.name = this.leftChildData[i][j].label;
+ childItem.href = this.leftChildData[i][j].action;
+ parentItem.menuItems.push(childItem);
+ }
+ }
+ }
+ this.menuData.push(parentItem);
+ }
+
+ });
+
+ }
+ eventCalled() {
+ this.isActive = !this.isActive;
+ }
+
+ addExpandClass(element: any) {
+ if (element === this.showMenu) {
+ this.showMenu = '0';
+ } else {
+ this.showMenu = element;
+ }
+ }
+
+ toggleCollapsed() {
+ this.collapsed = !this.collapsed;
+ this.collapsedEvent.emit(this.collapsed);
+ }
+
+ isToggled(): boolean {
+ const dom: Element = document.querySelector('body');
+ return dom.classList.contains(this.pushRightClass);
+ }
+
+ toggleSidebar() {
+ const dom: any = document.querySelector('body');
+ dom.classList.toggle(this.pushRightClass);
+ }
+}
diff --git a/portal-FE-common/src/app/layout/components/tabbar/tab.ts b/portal-FE-common/src/app/layout/components/tabbar/tab.ts
new file mode 100644
index 00000000..bdccdc18
--- /dev/null
+++ b/portal-FE-common/src/app/layout/components/tabbar/tab.ts
@@ -0,0 +1,50 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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 { SafeUrl } from '@angular/platform-browser';
+
+export class Tab {
+ label: string;
+ url: SafeUrl;
+ active: boolean;
+
+ constructor(label: string) {
+ this.label = label;
+ }
+
+}
diff --git a/portal-FE-common/src/app/layout/components/tabbar/tabbar.component.html b/portal-FE-common/src/app/layout/components/tabbar/tabbar.component.html
new file mode 100644
index 00000000..31bb197c
--- /dev/null
+++ b/portal-FE-common/src/app/layout/components/tabbar/tabbar.component.html
@@ -0,0 +1,97 @@
+<!--
+ ============LICENSE_START==========================================
+ ONAP Portal
+ ===================================================================
+ Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ ===================================================================
+
+ Unless otherwise specified, all software contained herein is licensed
+ under the Apache License, Version 2.0 (the "License");
+ you may not use this software 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.
+
+ Unless otherwise specified, all documentation contained herein is licensed
+ under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ you may not use this documentation except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://creativecommons.org/licenses/by/4.0/
+
+ Unless required by applicable law or agreed to in writing, documentation
+ 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 style="display: flex; flex-direction:column">
+
+ <mat-tab-group [selectedIndex]="selected.value" (selectedIndexChange)="selected.setValue($event)"
+ (selectedTabChange)="tabChanged($event)">
+ <mat-tab [label]="mainTab">
+ <!--
+ <mat-grid-list cols="5">
+ <mat-grid-tile [colspan]="1" [rowspan]="3">
+ <app-sidebar (collapsedEvent)="receiveCollapsed($event)"></app-sidebar>
+ <app-userbar></app-userbar>
+ </mat-grid-tile>
+ <mat-grid-tile [colspan]="4" style="height: calc(100vh - 24px);overflow-y: hidden">
+ <div class="container">
+ <router-outlet></router-outlet>
+ </div>
+ </mat-grid-tile>
+ </mat-grid-list>
+ -->
+
+
+ <div style="display: flex; flex-direction:column; overflow-y: scroll; height: calc(100vh - 100px)">
+ <div style="display: flex; flex-direction:row;">
+ <app-sidebar (collapsedEvent)="receiveCollapsed($event)"></app-sidebar>
+ <app-userbar></app-userbar>
+ <div class="container" style="margin-left: 370px;">
+ <router-outlet></router-outlet>
+ </div>
+ </div>
+ <app-footer></app-footer>
+ </div>
+
+ </mat-tab>
+
+ <mat-tab *ngFor="let tab of tabs; let index = index">
+ <ng-template mat-tab-label>
+ {{tab.label | elipsis: 13}} &nbsp;
+ <i class="icon ion-md-close-circle" (click)="removeTab(index)"></i>
+ </ng-template>
+
+
+ </mat-tab>
+
+ </mat-tab-group>
+
+
+
+
+
+ <div *ngFor="let tab of tabs; let index = index"
+ [style.display]='tab.active? "inline" : "none"'
+ [style.position]='tab.active? "static" : "absolute"'
+ [style.height]='tab.active? "calc(100vh)" : "calc(0vh)"'>
+
+ <iframe id="tabframe-{{tab.label.split(' ').join('-')}}" scrolling='yes' frameBorder='0' width='100%'
+ scrolling='yes' frameBorder='0' width='100%' height='90%' [src]='tab.url'></iframe>
+
+ </div>
+
+
+ </div>
diff --git a/portal-FE-common/src/app/layout/components/tabbar/tabbar.component.scss b/portal-FE-common/src/app/layout/components/tabbar/tabbar.component.scss
new file mode 100644
index 00000000..807e2d57
--- /dev/null
+++ b/portal-FE-common/src/app/layout/components/tabbar/tabbar.component.scss
@@ -0,0 +1,80 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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============================================
+ *
+ *
+ */
+
+ .input-label,
+ .add-tab-button,
+ .delete-tab-button {
+ margin: 8px;
+ }
+ .search-bar {
+ position: absolute;
+ right: 10%;
+ }
+
+ #mat-tab-label-0-1 {
+ position: fixed;
+ right: 1em;
+ }
+
+ .mat-tab-group{
+ margin-top: 55px;
+ }
+
+ ::ng-deep .mat-tab-label {
+ font-size: 13px !important;
+ line-height: 30px !important;
+ margin: 5px 0px 0 !important;
+ border-top-left-radius: 88px 205px !important;
+ border-top-right-radius: 88px 205px !important;
+ padding: 0 30px 0 25px !important;
+ height: 35px !important;
+ background: #d2d2d2 !important;
+ position: relative !important;
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.5) !important;
+ width: 180px !important;
+ max-width: 200px !important;
+ min-width: 20px !important;
+ border: 1px solid #aaa !important;
+ text-transform: capitalize !important;
+ text-align: left !important;
+ }
+
+
+ ::ng-deep .mat-tab-label.mat-ripple.ng-star-inserted.mat-tab-label-active {
+ opacity: 1;
+ } \ No newline at end of file
diff --git a/portal-FE-common/src/app/layout/components/tabbar/tabbar.component.spec.ts b/portal-FE-common/src/app/layout/components/tabbar/tabbar.component.spec.ts
new file mode 100644
index 00000000..94866e4e
--- /dev/null
+++ b/portal-FE-common/src/app/layout/components/tabbar/tabbar.component.spec.ts
@@ -0,0 +1,63 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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 { TabbarComponent } from './tabbar.component';
+
+describe('TabbarComponent', () => {
+ let component: TabbarComponent;
+ let fixture: ComponentFixture<TabbarComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ TabbarComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(TabbarComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/portal-FE-common/src/app/layout/components/tabbar/tabbar.component.ts b/portal-FE-common/src/app/layout/components/tabbar/tabbar.component.ts
new file mode 100644
index 00000000..7a10e39d
--- /dev/null
+++ b/portal-FE-common/src/app/layout/components/tabbar/tabbar.component.ts
@@ -0,0 +1,95 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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 { Component, OnInit } from '@angular/core';
+import { FormControl } from '@angular/forms';
+import { DomSanitizer } from '@angular/platform-browser';
+import { Tab } from './tab';
+import { AddTabFunctionService } from 'src/app/shared/services/tab/add-tab-function.service';
+
+@Component({
+ selector: 'app-tabbar',
+ templateUrl: './tabbar.component.html',
+ styleUrls: ['./tabbar.component.scss']
+})
+export class TabbarComponent implements OnInit {
+
+ tabs = [];
+ mainTab = 'Home';
+ selected = new FormControl(0);
+ collapedSideBar: boolean;
+
+ constructor(private sanitizer: DomSanitizer, private addTabFuntionService: AddTabFunctionService) {
+
+ }
+
+ ngOnInit(): void {
+
+ this.addTabFuntionService.listen().subscribe((m: any) => {
+ console.log(m);
+ this.addTab(true, m.title, m.url);
+ })
+ }
+
+ addTab(selectAfterAdding: boolean, label: string, url: string) {
+ const tab = new Tab(label);
+ tab.url = this.sanitizer.bypassSecurityTrustResourceUrl(url);
+ tab.active = true;
+ this.tabs.push(tab);
+
+ if (selectAfterAdding) {
+ this.selected.setValue(this.tabs.length);
+ }
+ }
+
+ removeTab(index: number) {
+ this.tabs.splice(index, 1);
+ }
+
+ receiveCollapsed($event) {
+ this.collapedSideBar = $event;
+ }
+
+ tabChanged($event) {
+
+ for (const ttab of this.tabs) {
+ ttab.active = false;
+ }
+ if(this.tabs.length != 0 && $event.index != 0)
+ this.tabs[$event.index - 1].active = true;
+ }
+}
diff --git a/portal-FE-common/src/app/layout/components/userbar/userbar.component.html b/portal-FE-common/src/app/layout/components/userbar/userbar.component.html
new file mode 100644
index 00000000..0ff5a554
--- /dev/null
+++ b/portal-FE-common/src/app/layout/components/userbar/userbar.component.html
@@ -0,0 +1,51 @@
+<!--
+ ============LICENSE_START==========================================
+ ONAP Portal
+ ===================================================================
+ Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ ===================================================================
+
+ Unless otherwise specified, all software contained herein is licensed
+ under the Apache License, Version 2.0 (the "License");
+ you may not use this software 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.
+
+ Unless otherwise specified, all documentation contained herein is licensed
+ under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ you may not use this documentation except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://creativecommons.org/licenses/by/4.0/
+
+ Unless required by applicable law or agreed to in writing, documentation
+ 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============================================
+
+
+ -->
+
+<button type="button" class="btn btn-primary" href="javascript:void(0)"
+[ngStyle]="{'right': isOpen ? '65px' : '-18px' }" (click)="toggleSidebar()">
+ <span id="user-chevron-down" class="icon-controls-down" [hidden]="!isOpen">Close</span>
+ <span id="user-chevron-up" class="icon-controls-upPRIMARY" [hidden]="isOpen"><span class="right-menu-button"><i
+ class="icon ion-md-arrow-dropup"></i> Users</span></span>
+</button>
+<nav [ngStyle]="{'right': isOpen ? '18px' : '-75px' }" class="usb-item usb-item-vertical usb-item-right" id="usb-item-s2">
+ <h3>Online Users</h3>
+ <div *ngFor="let user of userList" style="font-size: 10px;">
+ <a [href]="user.linkQ"><img class="activeUserIcon" [src]="user.linkPic" alt="User Link"></a>
+ <div class="userId-txt">{{user.userId}}</div>
+ </div>
+</nav> \ No newline at end of file
diff --git a/portal-FE-common/src/app/layout/components/userbar/userbar.component.scss b/portal-FE-common/src/app/layout/components/userbar/userbar.component.scss
new file mode 100644
index 00000000..81801104
--- /dev/null
+++ b/portal-FE-common/src/app/layout/components/userbar/userbar.component.scss
@@ -0,0 +1,114 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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============================================
+ *
+ *
+ */
+
+.usb-item {
+ background: #fff;
+ position: fixed;
+}
+
+.usb-item h3 {
+ color: #ef6f00;
+ font-size: 14px;
+ padding: 20px;
+ margin: 0;
+ text-align: center;
+ font-weight: 300;
+ background: #f8f9fa;
+}
+
+.usb-item a {
+ display: block;
+ color: #fff;
+ font-size: 1.1em;
+ font-weight: 300;
+ transition: all 0.2s ease-in-out;
+ -ms-transition: all 0.2s ease-in-out; /* IE 9 */
+ -webkit-transition: all 0.2s ease-in-out; /* Safari 3-8 */
+}
+
+.usb-item a:active {
+ background: #afdefa;
+ color: #47a3da;
+}
+
+.usb-item-right {
+ transition: all 0.5s ease-in-out;
+ -ms-transition: all 0.5s ease-in-out; /* IE 9 */
+ -webkit-transition: all 0.5s ease-in-out; /* Safari 3-8 */
+}
+
+.usb-item a:hover {
+ -ms-transform: scale(1.5); /* IE 9 */
+ -webkit-transform: scale(1.5); /* Safari 3-8 */
+ transform: scale(1.5);
+}
+
+.usb-item-vertical {
+ margin-top: 105px;
+ text-align: center;
+ width: 75px;
+ height: 79%;
+ top: 0;
+ z-index: 1000;
+ box-shadow: 0 4px 5px rgba(0, 0, 0, 0.2);
+}
+
+.usb-item-vertical a {
+ padding: 0.5em;
+}
+
+button {
+ transition: all 0.5s ease-in-out;
+ -ms-transition: all 0.5s ease-in-out; /* IE 9 */
+ -webkit-transition: all 0.5s ease-in-out; /* Safari 3-8 */
+ z-index: 9999;
+ top: 450px;
+ -ms-transform: rotate(-90deg); /* IE 9 */
+ -webkit-transform: rotate(-90deg); /* Safari 3-8 */
+ transform: rotate(-90deg);
+ position: fixed;
+}
+
+.activeUserIcon {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+ height: 55px;
+ width: 55px;
+ border-radius: 50%;
+}
diff --git a/portal-FE-common/src/app/layout/components/userbar/userbar.component.spec.ts b/portal-FE-common/src/app/layout/components/userbar/userbar.component.spec.ts
new file mode 100644
index 00000000..62b9c543
--- /dev/null
+++ b/portal-FE-common/src/app/layout/components/userbar/userbar.component.spec.ts
@@ -0,0 +1,63 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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 { UserbarComponent } from './userbar.component';
+
+describe('UserbarComponent', () => {
+ let component: UserbarComponent;
+ let fixture: ComponentFixture<UserbarComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ UserbarComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(UserbarComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/portal-FE-common/src/app/layout/components/userbar/userbar.component.ts b/portal-FE-common/src/app/layout/components/userbar/userbar.component.ts
new file mode 100644
index 00000000..661317bf
--- /dev/null
+++ b/portal-FE-common/src/app/layout/components/userbar/userbar.component.ts
@@ -0,0 +1,133 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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 { Component, OnInit } from '@angular/core';
+import { UserbarService, UserProfileService } from 'src/app/shared/services';
+import { DomSanitizer } from '@angular/platform-browser';
+import { environment } from 'src/environments/environment';
+
+@Component({
+ selector: 'app-userbar',
+ templateUrl: './userbar.component.html',
+ styleUrls: ['./userbar.component.scss']
+})
+export class UserbarComponent implements OnInit {
+
+ userList;
+ isOpen: boolean;
+ intervalPromise = null;
+ updateRate: number;
+ myservice: UserbarService;
+ api = environment.api;
+ constructor(private sanitizer: DomSanitizer, private userbarService: UserbarService, private userProfileService: UserProfileService) { }
+
+ ngOnInit() {
+ this.userList = [];
+ this.myservice = this.userbarService;
+ this.isOpen = true;
+ // this.userbarService.getOnlineUserUpdateRate().subscribe((_res: any) => {
+ // if (_res != null) {
+ // var rate = parseInt(_res.onlineUserUpdateRate);
+ // var duration = parseInt(_res.onlineUserUpdateDuration);
+ // this.userbarService.setMaxRefreshCount((duration / rate) + 1);
+ // this.userbarService.setRefreshCount(this.userbarService.maxCount);
+ // if (rate != NaN && duration != NaN) {
+ // // $log.debug('UserbarCtlr: scheduling function at interval ' + millis);
+ // this.updateRate = rate;
+ // this.start(this.updateRate);
+ // }
+ // }
+ // })
+ this.updateActiveUsers();
+ }
+
+ updateActiveUsers() {
+ // this.userbarService.decrementRefreshCount();
+ this.userProfileService.getActiveUser().subscribe((_res: any) => {
+ if (_res == null) {
+ // $log.error('UserbarCtrl::updateActiveUsers: failed to get active user');
+ this.stop();
+ } else {
+ var maxItems = 25;
+ if (_res.length < maxItems)
+ maxItems = _res.length;
+ for (var i = 0; i < maxItems; i++) {
+ var data = {
+ userId: _res[i],
+ linkQ: this.api.linkQ,
+ linkPic: this.api.linkPic
+ }
+ this.userList.push(data);
+ }
+ }
+
+ }, (err) => {
+ this.userList = [];
+ this.stop();
+ })
+
+ // .add(() => {
+ // var footerOff = $('#online-userbar').offset().top;
+ // var headOff = $('#footer').offset().top;
+ // var defaultOffSet = 45;
+ // $(".online-user-container").css({
+ // "height": headOff - footerOff - defaultOffSet
+ // });
+ // })
+
+ }
+
+ toggleSidebar() {
+ this.isOpen = !this.isOpen;
+ }
+
+ start(rate) {
+ // stops any running interval to avoid two intervals running at the same time
+ this.stop();
+ // store the interval promise
+ this.intervalPromise = setInterval(this.updateActiveUsers, rate);
+ }
+
+
+ stop() {
+ if (this.intervalPromise != null) {
+ clearInterval(this.intervalPromise);
+ this.intervalPromise = null;
+ }
+ }
+
+}
diff --git a/portal-FE-common/src/app/layout/layout-routing.module.ts b/portal-FE-common/src/app/layout/layout-routing.module.ts
new file mode 100644
index 00000000..5fa77e3a
--- /dev/null
+++ b/portal-FE-common/src/app/layout/layout-routing.module.ts
@@ -0,0 +1,57 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal SDK
+ * ===================================================================
+ * Copyright � 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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 { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+import { LayoutComponent } from './layout.component';
+
+const routes: Routes = [
+ {
+ path: '',
+ component: LayoutComponent,
+ children: [
+ //redirecting to pages module
+ { path: '', redirectTo: 'app', },
+ { path: 'app', loadChildren: () => import('../pages/pages.module').then(m => m.PagesModule) }, ]
+ }
+];
+
+@NgModule({
+ imports: [RouterModule.forChild(routes)],
+ exports: [RouterModule]
+})
+export class LayoutRoutingModule {}
diff --git a/portal-FE-common/src/app/layout/layout.component.html b/portal-FE-common/src/app/layout/layout.component.html
new file mode 100644
index 00000000..fa7ada03
--- /dev/null
+++ b/portal-FE-common/src/app/layout/layout.component.html
@@ -0,0 +1,44 @@
+<!--
+ ============LICENSE_START==========================================
+ ONAP Portal
+ ===================================================================
+ Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ ===================================================================
+
+ Unless otherwise specified, all software contained herein is licensed
+ under the Apache License, Version 2.0 (the "License");
+ you may not use this software 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.
+
+ Unless otherwise specified, all documentation contained herein is licensed
+ under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ you may not use this documentation except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://creativecommons.org/licenses/by/4.0/
+
+ Unless required by applicable law or agreed to in writing, documentation
+ 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============================================
+
+
+ -->
+
+ <app-header></app-header>
+ <app-tabbar></app-tabbar>
+
+
+
+
diff --git a/portal-FE-common/src/app/layout/layout.component.scss b/portal-FE-common/src/app/layout/layout.component.scss
new file mode 100644
index 00000000..a8adf264
--- /dev/null
+++ b/portal-FE-common/src/app/layout/layout.component.scss
@@ -0,0 +1,68 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal SDK
+ * ===================================================================
+ * Copyright � 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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============================================
+ *
+ *
+ */
+* {
+ -webkit-transition: margin-left 0.2s ease-in-out;
+ -moz-transition: margin-left 0.2s ease-in-out;
+ -ms-transition: margin-left 0.2s ease-in-out;
+ -o-transition: margin-left 0.2s ease-in-out;
+ transition: margin-left 0.2s ease-in-out;
+}
+.main-container {
+ margin-top: 56px;
+ margin-left: 270px;
+ padding: 15px;
+ -ms-overflow-x: hidden;
+ overflow-x: hidden;
+ overflow-y: scroll;
+ position: relative;
+ overflow: hidden;
+}
+.collapsed {
+ margin-left: 60px;
+}
+@media screen and (max-width: 992px) {
+ .main-container {
+ margin-left: 0px !important;
+ }
+}
+@media print {
+ .main-container {
+ margin-top: 0px !important;
+ margin-left: 0px !important;
+ }
+}
diff --git a/portal-FE-common/src/app/layout/layout.component.spec.ts b/portal-FE-common/src/app/layout/layout.component.spec.ts
new file mode 100644
index 00000000..5184fe43
--- /dev/null
+++ b/portal-FE-common/src/app/layout/layout.component.spec.ts
@@ -0,0 +1,62 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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 { LayoutComponent } from './layout.component';
+
+describe('LayoutComponent', () => {
+ let component: LayoutComponent;
+ let fixture: ComponentFixture<LayoutComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ LayoutComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(LayoutComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/portal-FE-common/src/app/layout/layout.component.ts b/portal-FE-common/src/app/layout/layout.component.ts
new file mode 100644
index 00000000..b512988d
--- /dev/null
+++ b/portal-FE-common/src/app/layout/layout.component.ts
@@ -0,0 +1,56 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal SDK
+ * ===================================================================
+ * Copyright © 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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 { Component, OnInit } from '@angular/core';
+
+@Component({
+ selector: 'app-layout',
+ templateUrl: './layout.component.html',
+ styleUrls: ['./layout.component.scss']
+})
+export class LayoutComponent implements OnInit {
+
+ collapedSideBar: boolean;
+
+ constructor() {}
+
+ ngOnInit() {}
+
+ receiveCollapsed($event) {
+ this.collapedSideBar = $event;
+ }
+}
diff --git a/portal-FE-common/src/app/layout/layout.module.ts b/portal-FE-common/src/app/layout/layout.module.ts
new file mode 100644
index 00000000..63a99d86
--- /dev/null
+++ b/portal-FE-common/src/app/layout/layout.module.ts
@@ -0,0 +1,65 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal SDK
+ * ===================================================================
+ * Copyright � 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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 { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap';
+import { NgMaterialModule } from '../ng-material-module';
+import { LayoutRoutingModule } from './layout-routing.module';
+import { LayoutComponent } from './layout.component';
+import { SidebarComponent } from './components/sidebar/sidebar.component';
+import { HeaderComponent } from './components/header/header.component';
+import { GlobalSearchComponent } from './components/global-search/global-search.component';
+import { ClickOutsideModule } from 'ng-click-outside';
+import { TabbarComponent } from './components/tabbar/tabbar.component';
+import { HeaderMenuComponent } from './components/header-menu/header-menu.component';
+import { UserbarComponent } from './components/userbar/userbar.component';
+import { FooterComponent } from './components/footer/footer.component';
+import { ApplicationPipesModule } from '../shared/pipes/application-pipes.module';
+
+@NgModule({
+ imports: [
+ CommonModule,
+ NgMaterialModule,
+ LayoutRoutingModule,
+ ApplicationPipesModule,
+ NgbDropdownModule,
+ ClickOutsideModule
+ ],
+ declarations: [LayoutComponent, SidebarComponent, HeaderComponent,GlobalSearchComponent, TabbarComponent, HeaderMenuComponent, UserbarComponent, FooterComponent]
+})
+export class LayoutModule {}
diff --git a/portal-FE-common/src/app/pages/admins/admins.component.html b/portal-FE-common/src/app/pages/admins/admins.component.html
new file mode 100644
index 00000000..a47a6207
--- /dev/null
+++ b/portal-FE-common/src/app/pages/admins/admins.component.html
@@ -0,0 +1,92 @@
+<!--
+ ============LICENSE_START==========================================
+ ONAP Portal
+ ===================================================================
+ Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ ===================================================================
+
+ Unless otherwise specified, all software contained herein is licensed
+ under the Apache License, Version 2.0 (the "License");
+ you may not use this software 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.
+
+ Unless otherwise specified, all documentation contained herein is licensed
+ under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ you may not use this documentation except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://creativecommons.org/licenses/by/4.0/
+
+ Unless required by applicable law or agreed to in writing, documentation
+ 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">
+ <div class="onap-main-view-title">
+ <h1 class="heading-page">Admins</h1>
+ </div>
+
+ <mat-form-field>
+ <mat-label>All Applications</mat-label>
+ <mat-select>
+ <mat-option>All Applications</mat-option>
+ <mat-option *ngFor="let app of availableApps" [value]="app.value" (click)="applyFilterByAppName(app.value)">{{app.title}}</mat-option>
+ </mat-select>
+ </mat-form-field>
+ &nbsp;
+ <mat-form-field>
+ <input matInput type="text" (keyup)="applyFilter($event.target.value)" placeholder="Search in entire table">
+ </mat-form-field>
+ <button type="button" class="btn btn-primary" (click)="openAddNewAdminModal()"><i class="icon ion-md-person-add"></i>
+ Add Admin</button>
+ <span class="onap-spinner" *ngIf="showSpinner"></span>
+ <table mat-table [dataSource]="adminsDataSource" matSort>
+ <!-- First Name Column -->
+ <ng-container matColumnDef="firstName">
+ <th id="col1" mat-header-cell *matHeaderCellDef mat-sort-header> First Name </th>
+ <td id="rowheader_t1_{{i}}-firstName" mat-cell *matCellDef="let element; let i = index;"> {{element.firstName}}
+ </td>
+ </ng-container>
+
+ <!-- Last Name Column -->
+ <ng-container matColumnDef="lastName">
+ <th id="col2" mat-header-cell *matHeaderCellDef mat-sort-header> Last Name </th>
+ <td id="rowheader_t1_{{i}}-lastName" mat-cell *matCellDef="let element; let i=index;"> {{element.lastName}}
+ </td>
+ </ng-container>
+
+ <!-- User ID Column -->
+ <ng-container matColumnDef="userId">
+ <th id="col3" mat-header-cell *matHeaderCellDef mat-sort-header> User ID </th>
+ <td id="rowheader_t1_{{i}}-userId" mat-cell *matCellDef="let element; let i=index;"> {{element.orgUserId}}
+ </td>
+ </ng-container>
+
+ <!-- Applications Column -->
+ <ng-container matColumnDef="appName">
+ <th id="col4" mat-header-cell *matHeaderCellDef> Applications </th>
+ <td id="rowheader_t1_{{i}}-applications" mat-cell *matCellDef="let element; let i=index;">
+ <div *ngFor="let element of element.apps; let i=index;"> {{element.appName}} </div>
+ </td>
+ </ng-container>
+
+ <tr [hidden]="adminsData.length === 0" mat-header-row *matHeaderRowDef="displayedColumns"></tr>
+ <tr mat-row *matRowDef="let row; columns: displayedColumns;" (click)="openExistingAdminModal(row)"></tr>
+ </table>
+ <mat-paginator [hidden]="adminsData.length === 0" [pageSizeOptions]="[10, 20]" showFirstLastButtons></mat-paginator>
+</div> \ No newline at end of file
diff --git a/portal-FE-common/src/app/pages/admins/admins.component.scss b/portal-FE-common/src/app/pages/admins/admins.component.scss
new file mode 100644
index 00000000..a7f4d385
--- /dev/null
+++ b/portal-FE-common/src/app/pages/admins/admins.component.scss
@@ -0,0 +1,42 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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 '../pages.component';
+
+.mat-row{
+ cursor: pointer;
+}
diff --git a/portal-FE-common/src/app/pages/admins/admins.component.spec.ts b/portal-FE-common/src/app/pages/admins/admins.component.spec.ts
new file mode 100644
index 00000000..563f80ff
--- /dev/null
+++ b/portal-FE-common/src/app/pages/admins/admins.component.spec.ts
@@ -0,0 +1,62 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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 { AdminsComponent } from './admins.component';
+
+describe('AdminsComponent', () => {
+ let component: AdminsComponent;
+ let fixture: ComponentFixture<AdminsComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ AdminsComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(AdminsComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/portal-FE-common/src/app/pages/admins/admins.component.ts b/portal-FE-common/src/app/pages/admins/admins.component.ts
new file mode 100644
index 00000000..d7a839b5
--- /dev/null
+++ b/portal-FE-common/src/app/pages/admins/admins.component.ts
@@ -0,0 +1,133 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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 { Component, OnInit, ViewChild } from '@angular/core';
+import { AdminsService, ApplicationsService } from 'src/app/shared/services';
+import { Admins, AllApps } from 'src/app/shared/model';
+import { MatTableDataSource, MatSort, MatPaginator } from '@angular/material';
+import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
+import { NewAdminComponent } from './new-admin/new-admin.component';
+
+@Component({
+ selector: 'app-admins',
+ templateUrl: './admins.component.html',
+ styleUrls: ['./admins.component.scss']
+})
+export class AdminsComponent implements OnInit {
+ availableApps: Array<{ index: number, title: string, value: string }> = [];
+
+ constructor(private adminsService: AdminsService, private applicationService: ApplicationsService,
+ public ngModal: NgbModal) { }
+
+ showSpinner = true;
+ displayedColumns: string[] = ['firstName', 'lastName', 'userId', 'appName'];
+ adminsData: Admins[] = [];
+ adminsDataSource = new MatTableDataSource(this.adminsData);
+ @ViewChild(MatSort) sort: MatSort;
+ @ViewChild(MatPaginator) paginator: MatPaginator;
+ ngOnInit() {
+ this.adminsData = [];
+ this.getAccoutAdminsData();
+ this.getAllApps();
+ }
+
+ openAddNewAdminModal() {
+ const modalRef = this.ngModal.open(NewAdminComponent);
+ modalRef.componentInstance.title = 'New Admin';
+ modalRef.componentInstance.dialogState = 1;
+ modalRef.componentInstance.disableBack = false;
+ modalRef.componentInstance.passBackNewAdminPopup.subscribe((_result: any) => {
+ modalRef.close();
+ this.showSpinner = true;
+ this.getAccoutAdminsData();
+ }, (_reason: any) => {
+ return;
+ });
+ }
+
+ openExistingAdminModal(_adminData: Admins) {
+ const modalRef = this.ngModal.open(NewAdminComponent);
+ modalRef.componentInstance.userTitle = `${_adminData.firstName}, ${_adminData.lastName} `+'('+`${_adminData.orgUserId}`+')';
+ modalRef.componentInstance.adminModalData = _adminData;
+ modalRef.componentInstance.dialogState = 2;
+ modalRef.componentInstance.disableBack = true;
+ modalRef.componentInstance.passBackNewAdminPopup.subscribe((_result: any) => {
+ modalRef.close();
+ this.showSpinner = true;
+ this.getAccoutAdminsData();
+ }, (_reason: any) => {
+ return;
+ });
+ }
+
+ applyFilterByAppName(filterValue: string) {
+
+ }
+
+ applyFilter(filterValue: string) {
+ this.adminsDataSource.filter = filterValue.trim().toLowerCase();
+ }
+
+
+ getAccoutAdminsData() {
+ this.adminsService.getAccountAdmins().subscribe((_res: Admins[]) => {
+ this.showSpinner = false;
+ this.adminsData = _res;
+ this.adminsDataSource = new MatTableDataSource(this.adminsData);
+ this.adminsDataSource.sort = this.sort;
+ this.adminsDataSource.paginator = this.paginator;
+ });
+ }
+
+ getAllApps() {
+ this.applicationService.getAvailableApps().subscribe((_res: AllApps[]) => {
+ var realAppIndex = 1;
+ for (let i = 1; i <= _res.length; i++) {
+ if (!_res[i - 1].restrictedApp) {
+ this.availableApps.push({
+ index: realAppIndex,
+ title: _res[i - 1].title,
+ value: _res[i - 1].value
+ });
+ realAppIndex = realAppIndex + 1;
+ } else {
+ }
+ }
+ });
+ }
+
+}
diff --git a/portal-FE-common/src/app/pages/admins/new-admin/new-admin.component.html b/portal-FE-common/src/app/pages/admins/new-admin/new-admin.component.html
new file mode 100644
index 00000000..c43e4ba1
--- /dev/null
+++ b/portal-FE-common/src/app/pages/admins/new-admin/new-admin.component.html
@@ -0,0 +1,96 @@
+<!--
+ ============LICENSE_START==========================================
+ ONAP Portal
+ ===================================================================
+ Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ ===================================================================
+
+ Unless otherwise specified, all software contained herein is licensed
+ under the Apache License, Version 2.0 (the "License");
+ you may not use this software 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.
+
+ Unless otherwise specified, all documentation contained herein is licensed
+ under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ you may not use this documentation except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://creativecommons.org/licenses/by/4.0/
+
+ Unless required by applicable law or agreed to in writing, documentation
+ 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" *ngIf="dialogState===1">
+ <div class="modal-header">
+ <h4 class="modal-title">{{title}}</h4>
+ <button type="button" class="close" aria-label="Close" (click)="activeModal.dismiss('Cross')">
+ <span aria-hidden="true">&times;</span>
+ </button>
+ </div>
+ <div class="modal-body">
+ <app-search-users [searchTitle]="searchTitleText" [placeHolder]="placeholderText" (passBackSelectedUser)='changeSelectedUser($event)'></app-search-users>
+ <span class="onap-spinner" *ngIf="isLoading"></span>
+ </div>
+ <div class="modal-footer">
+ <button type="submit" class="btn btn-primary" [disabled]='!changedSelectedUser'
+ (click)="getAdminAppsRoles()">Next</button> &nbsp;
+ <button type="button" class="btn btn-primary" (click)="activeModal.close('Close')">Close</button>
+ </div>
+</div>
+<div class="container" *ngIf="dialogState===2">
+ <div class="modal-header">
+ <h4 class="modal-title">{{userTitle}}</h4>
+ <button type="button" class="close" aria-label="Close" (click)="activeModal.dismiss('Cross')">
+ <span aria-hidden="true">&times;</span>
+ </button>
+ </div>
+ <div class="modal-body adminApps">
+ <div ngbDropdown class="d-inline-block">
+ <h4>Administrates:</h4>
+ <button class="btn btn-outline-primary" id="dropdownBasic1" ngbDropdownToggle>Select Application</button>
+ <div ngbDropdownMenu aria-labelledby="dropdownBasic1">
+ <button *ngFor="let app of adminDropdownApps" (click)="updateDropdown(app, true)"
+ ngbDropdownItem>{{app.appName}}</button>
+ </div>
+ </div>
+ <!-- User admins list -->
+ <div class="container adminApps" *ngIf="adminAppsRoles.length > 0">
+ <table mat-table [dataSource]="adminsAppsSource">
+ <!-- Search Result Column-->
+ <ng-container matColumnDef="applications">
+ <th id="rowheader-result" mat-header-cell *matHeaderCellDef> Applications <span id="i-delete-application"
+ class="span-remove-title"> Delete </span></th>
+ <td id="table-data-{{i}}" mat-cell *matCellDef="let element; let i = index;">
+ {{element.appName}} <span id="i-delete-application" class="span-remove-admin"
+ (click)="removeAdminApp(element)"><i class="icon ion-md-trash"></i></span>
+ </td>
+ </ng-container>
+ <tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr>
+ <tr mat-row id="table-row-{{i}}" *matRowDef="let row; columns: displayedColumns; let i = index;"></tr>
+ </table>
+ </div>
+ </div>
+ <div class="modal-footer">
+ <button [hidden]="disableBack" type="submit" class="btn btn-primary" [disabled]='!changedSelectedUser'
+ (click)="navigateBack()">Back</button> &nbsp;
+ <button type="submit" class="btn btn-primary" [disabled]='!newAppSelected'
+ (click)="updateAdminAppsRoles(adminAppsScreen)">Save</button> &nbsp;
+ <button type="button" class="btn btn-primary" (click)="activeModal.close('Close')">Close</button>
+ </div>
+</div> \ No newline at end of file
diff --git a/portal-FE-common/src/app/pages/admins/new-admin/new-admin.component.scss b/portal-FE-common/src/app/pages/admins/new-admin/new-admin.component.scss
new file mode 100644
index 00000000..eb6db14c
--- /dev/null
+++ b/portal-FE-common/src/app/pages/admins/new-admin/new-admin.component.scss
@@ -0,0 +1,58 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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============================================
+ *
+ *
+ */
+.container.adminApps {
+ overflow-y: auto;
+ height: 250px;
+}
+
+.dropdown-menu.show {
+ overflow-y: auto !important;
+ height: 250px !important;
+}
+.span-remove-title {
+ float: right;
+}
+.span-remove-admin {
+ float: right;
+ cursor: pointer;
+ font-size: 20px;
+}
+
+.onap-spinner{
+ z-index: 9999;
+} \ No newline at end of file
diff --git a/portal-FE-common/src/app/pages/admins/new-admin/new-admin.component.spec.ts b/portal-FE-common/src/app/pages/admins/new-admin/new-admin.component.spec.ts
new file mode 100644
index 00000000..4040b0d3
--- /dev/null
+++ b/portal-FE-common/src/app/pages/admins/new-admin/new-admin.component.spec.ts
@@ -0,0 +1,62 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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 { NewAdminComponent } from './new-admin.component';
+
+describe('NewAdminComponent', () => {
+ let component: NewAdminComponent;
+ let fixture: ComponentFixture<NewAdminComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ NewAdminComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(NewAdminComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/portal-FE-common/src/app/pages/admins/new-admin/new-admin.component.ts b/portal-FE-common/src/app/pages/admins/new-admin/new-admin.component.ts
new file mode 100644
index 00000000..8f80138e
--- /dev/null
+++ b/portal-FE-common/src/app/pages/admins/new-admin/new-admin.component.ts
@@ -0,0 +1,228 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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 { Component, OnInit, Output, EventEmitter, Input } from '@angular/core';
+import { AdminsService } from 'src/app/shared/services';
+import { HttpErrorResponse } from '@angular/common/http';
+import { ConfirmationModalComponent } from 'src/app/modals/confirmation-modal/confirmation-modal.component';
+import { NgbModal, NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import { PortalAdmin } from 'src/app/shared/model';
+import { MatTableDataSource } from '@angular/material';
+import { InformationModalComponent } from 'src/app/modals/information-modal/information-modal.component';
+import { Router } from '@angular/router';
+
+@Component({
+ selector: 'app-new-admin',
+ templateUrl: './new-admin.component.html',
+ styleUrls: ['./new-admin.component.scss']
+})
+export class NewAdminComponent implements OnInit {
+
+ @Input() dialogState: number;
+ @Input() userTitle: string;
+ @Input() disableBack: boolean;
+ @Input() adminModalData: any;
+ @Output() passBackNewAdminPopup: EventEmitter<any> = new EventEmitter();
+ searchTitleText = 'Enter First Name, Last Name or Org User Id';
+ placeholderText = 'Search';
+ changedSelectedUser: PortalAdmin;
+ adminAppsRoles: any;
+ adminDropdownApps: any;
+ isLoading: boolean;
+ newAppSelected: boolean;
+ adminAppSelectAndUnselectData: any;
+ displayedColumns: string[] = ['applications'];
+ adminsAppsSource = new MatTableDataSource(this.adminAppsRoles);
+ constructor(public router: Router, private adminsService: AdminsService, public ngModal: NgbModal, public activeModal: NgbActiveModal) { }
+
+ ngOnInit() {
+ this.adminAppsRoles = [];
+ this.changedSelectedUser = null;
+ if (this.disableBack){
+ this.changedSelectedUser = this.adminModalData;
+ this.getAdminAppsRoles();
+ }
+ this.adminDropdownApps = [];
+ this.adminAppSelectAndUnselectData = [];
+ }
+
+ changeSelectedUser(user: PortalAdmin) {
+ this.changedSelectedUser = user;
+ this.userTitle = `${this.changedSelectedUser.firstName}, ` + ` ${this.changedSelectedUser.lastName} ` + ` (${this.changedSelectedUser.orgUserId})`;
+ }
+
+ getAdminAppsRoles() {
+ this.isLoading = true;
+ this.adminsService.getAdminAppsRoles(this.changedSelectedUser.orgUserId).subscribe((_res: any) => {
+ JSON.stringify(_res);
+ if (!_res.appsRoles) {
+ return;
+ }
+ this.adminAppsRoles = [];
+ for (var i = 0; i < _res.appsRoles.length; i++) {
+ if (!_res.appsRoles[i].restrictedApp && _res.appsRoles[i].isAdmin) {
+ this.adminAppsRoles.push({
+ id: _res.appsRoles[i].id,
+ appName: _res.appsRoles[i].appName,
+ isAdmin: _res.appsRoles[i].isAdmin,
+ restrictedApp: _res.appsRoles[i].restrictedApp
+ });
+ } else if (!_res.appsRoles[i].restrictedApp) {
+ this.adminDropdownApps.push({
+ id: _res.appsRoles[i].id,
+ appName: _res.appsRoles[i].appName,
+ isAdmin: _res.appsRoles[i].isAdmin,
+ restrictedApp: _res.appsRoles[i].restrictedApp
+ });
+ }
+ }
+ this.isLoading = false;
+ this.newAppSelected = false;
+ this.dialogState = 2;
+ this.adminsAppsSource = new MatTableDataSource(this.adminAppsRoles);
+ });
+ }
+
+ navigateBack() {
+ this.dialogState = 1;
+ }
+
+ removeAdminApp(app: any) {
+ const modalRef = this.ngModal.open(InformationModalComponent);
+ modalRef.componentInstance.title = "Confirmation";
+ modalRef.componentInstance.message = `Are you sure you want to delete ${app.appName}?`;
+ modalRef.result.then((result) => {
+ if (result === 'Ok') {
+ this.adminAppsRoles.forEach((item: any, index: any) => {
+ if (item === app) this.adminAppsRoles.splice(index, 1);
+ });
+ //call from delete admin app
+ this.updateDropdown(app, false);
+ this.adminsAppsSource = new MatTableDataSource(this.adminAppsRoles);
+ }
+ }, (resut) => {
+ return;
+ })
+ }
+
+ updateDropdown(_newValue: any, isDropdownCall: boolean) {
+ // app is selected from dropdown
+ if (isDropdownCall) {
+ this.adminDropdownApps.forEach((item: any, index: any) => {
+ if (item === _newValue) this.adminDropdownApps.splice(index, 1);
+ });
+ this.getadminAppSelectAndUnselectedData(_newValue);
+ _newValue.isAdmin = true;
+ this.adminAppsRoles.push(_newValue);
+ this.adminsAppsSource = new MatTableDataSource(this.adminAppsRoles);
+ } else { // app is removed from the admin list
+ this.getadminAppSelectAndUnselectedData(_newValue);
+ _newValue.isAdmin = false;
+ this.adminDropdownApps.push(_newValue);
+ }
+
+ // disable save button if nothing new in the admin list
+ if (this.adminAppSelectAndUnselectData.length > 0)
+ this.newAppSelected = true;
+ else
+ this.newAppSelected = false;
+
+ }
+
+ private getadminAppSelectAndUnselectedData(_newValue: any) {
+ const index: number = this.adminAppSelectAndUnselectData.indexOf(_newValue);
+ if (index !== -1) {
+ this.adminAppSelectAndUnselectData.splice(index, 1); // if found, remove selected app from dropdown in the list
+ }
+ else {
+ this.adminAppSelectAndUnselectData.push(_newValue);
+ }
+ }
+
+ remindToAddUserIfNecessary() {
+ let adminAddedToNewApp = true;
+ if ((this.adminAppsRoles != null) && (this.adminAppsRoles.length > 0)) {
+ for (var i = 0; i < this.adminAppSelectAndUnselectData.length; i++) {
+ var foundApp = false;
+ for (var j = 0; j < this.adminAppsRoles.length; j++) {
+ if (this.adminAppsRoles[j] === this.adminAppSelectAndUnselectData[i]) {
+ foundApp = true;
+ }
+ }
+ if (foundApp === false) {
+ adminAddedToNewApp = true;
+ break;
+ }
+ }
+ } else {
+ adminAddedToNewApp = true;
+ }
+ if (adminAddedToNewApp === true) {
+ const modalRef = this.ngModal.open(InformationModalComponent);
+ modalRef.componentInstance.title = "Confirmation";
+ modalRef.componentInstance.message = 'Add this person as an application user? This allows them to access the application from ONAP Portal. Press OK to go to the Add Users page.';
+ modalRef.result.then((_res) => {
+ if (_res === 'Ok') {
+ this.router.navigate(['/users']);
+ }
+ });
+ }
+ }
+
+ updateAdminAppsRoles() {
+ const modalRef = this.ngModal.open(InformationModalComponent);
+ modalRef.componentInstance.title = "Admin Update";
+ modalRef.componentInstance.message = 'Are you sure you want to make these admin changes?';
+ modalRef.result.then((result) => {
+ if (result === 'Ok') {
+ this.adminsService.updateAdminAppsRoles({ orgUserId: this.changedSelectedUser.orgUserId, appsRoles: this.adminAppsRoles }).subscribe(_data => {
+ this.passBackNewAdminPopup.emit(_data);
+ this.remindToAddUserIfNecessary();
+ }, (_err: HttpErrorResponse) => {
+ this.passBackNewAdminPopup.emit(_err);
+ const modalErrorRef = this.ngModal.open(ConfirmationModalComponent);
+ modalErrorRef.componentInstance.title = "Error";
+ if (_err.status) {
+ modalErrorRef.componentInstance.message = "There was a unknown problem while adding admin to selected application(s)." + "Please try again later. Error Status: " + _err.status;
+ }
+ });
+ }
+ }, (reason) => {
+ return;
+ });
+ }
+}
diff --git a/portal-FE-common/src/app/pages/functional-menu/functional-menu-dialog/functional-menu-dialog.component.html b/portal-FE-common/src/app/pages/functional-menu/functional-menu-dialog/functional-menu-dialog.component.html
new file mode 100644
index 00000000..5e10b78f
--- /dev/null
+++ b/portal-FE-common/src/app/pages/functional-menu/functional-menu-dialog/functional-menu-dialog.component.html
@@ -0,0 +1,100 @@
+<!--
+ ============LICENSE_START==========================================
+ ONAP Portal
+ ===================================================================
+ Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ ===================================================================
+
+ Unless otherwise specified, all software contained herein is licensed
+ under the Apache License, Version 2.0 (the "License");
+ you may not use this software 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.
+
+ Unless otherwise specified, all documentation contained herein is licensed
+ under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ you may not use this documentation except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://creativecommons.org/licenses/by/4.0/
+
+ Unless required by applicable law or agreed to in writing, documentation
+ 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">
+ <div class="functionalMenu-details-modal">
+ <!--Modal Headers-->
+ <div class="modal-header">
+ <h4 class="modal-title">Functional Menu</h4>
+ <button type="button" class="close" aria-label="Close" (click)="activeModal.dismiss('Cross')">
+ <span aria-hidden="true">&times;</span>
+ </button>
+ </div>
+
+ <!--Modal Body goes here-->
+ <div class="modal-body">
+ <div class="parent">
+ <div class="item-label">Parent</div>
+ <input id="input-parent" class="functionalMenu-height"
+ [(ngModel)]="nodedetails.menuLocation" [disabled]="isParentDisable"
+ type="text" name="parent" readonly="readonly" />
+ </div>
+ <div class="title" >
+ <div class="item-label">Title</div>
+ <input id="input-title" placeholder="Enter text" class="functionalMenu-height"
+ [(ngModel)]="nodedetails.name" type="text" autocomplete="off" name="title" maxlength="100" [disabled]="isViewMode"/>
+ </div>
+ <div class="url" >
+ <div class="item-label">URL</div>
+ <input id="input-title" placeholder="http://" class="functionalMenu-height"
+ [(ngModel)]="nodedetails.url" type="text" autocomplete="off" name="url" maxlength="100" [disabled]="isViewMode"/>
+ </div>
+ <div class="application-select">
+ <mat-form-field>
+ <mat-label>App</mat-label>
+ <mat-select name="functional-menu-application-select" [disabled]="isViewMode"
+ [(ngModel)]="nodedetails.selectedAppIndex"
+ (ngModelChange)="updateSelectedApp(nodedetails.selectedAppIndex)"
+ [(value)]="selectedApp"
+ >
+ <mat-option *ngFor="let d of availableApps" [value]="d.index" >{{d.title}}</mat-option>
+ </mat-select>
+ </mat-form-field>
+ </div>
+ <div class="role-select" [hidden]="hideRoleField">
+ <mat-form-field>
+ <mat-label>Role</mat-label>
+ <mat-select name="functional-menu-role-select" [disabled]="isViewMode"
+ [(ngModel)]="nodedetails.selectedRole" [(value)]="selectedRole"
+ >
+ <mat-option *ngFor="let d of availableRoles" [value]="d.roleId" >{{d.rolename}}</mat-option>
+ </mat-select>
+ </mat-form-field>
+ </div>
+ </div>
+
+ <!--Modal Footer goes Here-->
+ <div class="modal-footer">
+ <button type="button" class="btn btn-primary" (click)="switchToAddMode()">Add</button> &nbsp;
+ <button type="button" class="btn btn-primary" (click)="switchToEditMode()">Edit</button> &nbsp;
+ <button type="button" class="btn btn-primary" *ngIf="(isEditMode)" (click)="saveChanges()">Save</button> &nbsp;
+ <button type="button" class="btn btn-primary" (click)="deleteMenuItem()">Delete</button> &nbsp;
+ <button type="button" class="btn btn-primary" (click)="activeModal.close('Close')">Cancel</button>
+ </div>
+ </div>
+</div> \ No newline at end of file
diff --git a/portal-FE-common/src/app/pages/functional-menu/functional-menu-dialog/functional-menu-dialog.component.scss b/portal-FE-common/src/app/pages/functional-menu/functional-menu-dialog/functional-menu-dialog.component.scss
new file mode 100644
index 00000000..ba9a1e37
--- /dev/null
+++ b/portal-FE-common/src/app/pages/functional-menu/functional-menu-dialog/functional-menu-dialog.component.scss
@@ -0,0 +1,63 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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============================================
+ *
+ *
+ */
+
+::ng-deep .modal-dialog {
+ max-width: 550px;
+ width: 550px;
+ overflow-x: auto;
+ overflow-y: auto;
+}
+
+::ng-deep .mat-form-field-infix {
+ display: block;
+ position: relative;
+ flex: auto;
+ min-width: 0;
+ width: 448px !important;
+}
+
+.container .functionalMenu-details-modal {
+ padding: 16px;
+ height: 537px;
+ overflow: auto;
+}
+
+.functionalMenu-details-modal input[type="text"] {
+ width: 28em;
+ margin-bottom: 10px;
+} \ No newline at end of file
diff --git a/portal-FE-common/src/app/pages/functional-menu/functional-menu-dialog/functional-menu-dialog.component.spec.ts b/portal-FE-common/src/app/pages/functional-menu/functional-menu-dialog/functional-menu-dialog.component.spec.ts
new file mode 100644
index 00000000..de79b9d8
--- /dev/null
+++ b/portal-FE-common/src/app/pages/functional-menu/functional-menu-dialog/functional-menu-dialog.component.spec.ts
@@ -0,0 +1,63 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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 { FunctionalMenuDialogComponent } from './functional-menu-dialog.component';
+
+describe('FunctionalMenuDialogComponent', () => {
+ let component: FunctionalMenuDialogComponent;
+ let fixture: ComponentFixture<FunctionalMenuDialogComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ FunctionalMenuDialogComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(FunctionalMenuDialogComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/portal-FE-common/src/app/pages/functional-menu/functional-menu-dialog/functional-menu-dialog.component.ts b/portal-FE-common/src/app/pages/functional-menu/functional-menu-dialog/functional-menu-dialog.component.ts
new file mode 100644
index 00000000..a1839732
--- /dev/null
+++ b/portal-FE-common/src/app/pages/functional-menu/functional-menu-dialog/functional-menu-dialog.component.ts
@@ -0,0 +1,446 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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 { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
+import { NgbActiveModal, NgbModal } from '@ng-bootstrap/ng-bootstrap';
+import { FunctionalMenuService } from 'src/app/shared/services';
+import { ConfirmationModalComponent } from 'src/app/modals/confirmation-modal/confirmation-modal.component';
+import { InformationModalComponent } from 'src/app/modals/information-modal/information-modal.component';
+
+@Component({
+ selector: 'app-functional-menu-dialog',
+ templateUrl: './functional-menu-dialog.component.html',
+ styleUrls: ['./functional-menu-dialog.component.scss']
+})
+export class FunctionalMenuDialogComponent implements OnInit {
+
+ @Input() nodedata: any;
+ @Input() operationName: string;
+ @Output() passEntry: EventEmitter<any> = new EventEmitter();
+ isEditMode: boolean = false;
+ isViewMode: boolean = false;
+ isAddItemMode: boolean = false;
+ selectedItem: any;
+ result: any;
+ availableRoles: any;
+ preSelectedRoles: any;
+ isAllApplications: boolean = false;
+ availableApps: any
+ selectedRole: any = [];
+ selectedApp={
+ index:null,
+ isDisabled: null
+ };
+ selectedAppIndex: any;
+ menutitle:string;
+ menuLocation:string;
+ nodedetails: any;
+ isParentDisable:boolean =true;
+ hideRoleField:boolean = true;
+ conflictMessages = {};
+ functionalMenuForm = {};
+
+ constructor(public functionalMenuService : FunctionalMenuService, public ngbModal: NgbModal, public activeModal: NgbActiveModal) { }
+
+ ngOnInit() {
+ //console.log("nodedata in dialog ",this.nodedata);
+ this.nodedetails = Object.assign({}, this.nodedata);
+ this.isViewMode = true;
+ this.selectedItem = this.nodedata;
+ this.selectedRole = [];
+ this.availableRoles = [];
+ if(this.nodedata && (this.isViewMode || this.isEditMode) && this.isLeafMenuItem(this.nodedetails)){
+ this.selectedApp.index = this.nodedetails.appid;
+ this.selectedAppIndex=this.nodedetails.appid;
+ this.getAvailableRoles(this.selectedAppIndex);
+ }
+
+ if(this.isViewMode || this.isEditMode){
+ this.nodedetails.menutitle = this.nodedetails.name;
+ this.nodedetails.menuLocation = this.isParentMenuItem(this.nodedata) ? this.nodedata.name : this.nodedata.parent.name;
+ }else{
+ this.nodedetails.menutitle = '';
+ this.nodedetails.menuLocation = this.nodedata.name;
+ }
+ this.nodedetails.selectedAppIndex = (this.selectedItem.appid) ? this.selectedItem.appid : 0;
+ this.getAvailableApps();
+ if(this.selectedItem.appid && this.selectedItem.appid >0){
+ this.getAvailableRoles(this.selectedItem.appid);
+ }
+ }
+
+ switchToEditMode(){
+ //console.log("switchToEditMode :: ",this.nodedata);
+ this.isViewMode = false;
+ this.isEditMode = true;
+ this.isParentDisable =true;
+ this.nodedetails.name = this.selectedItem.name;
+ this.nodedetails.url = this.selectedItem.url;
+ this.nodedetails.selectedAppIndex = (this.selectedItem.appid) ? this.selectedItem.appid : 0;
+ this.nodedetails.selectedRole = (this.selectedItem.roles) ? this.selectedItem.roles : 0;
+ }
+
+ switchToAddMode(){
+ //console.log("switchToAddMode :: ",this.nodedata);
+ if(this.selectedItem != null && this.selectedItem.getLevel() >= 4){
+ this.openConfirmationModal("","You are not allowed to have a menu item at a level greater than 4.");
+ return ;
+ }
+ //this.isViewMode = false;
+ this.isViewMode = false;
+ this.isEditMode = true;
+ this.isAddItemMode = true;
+ this.nodedetails.name = "";
+ this.nodedetails.url = "";
+ this.nodedetails.selectedAppIndex = 0;
+ this.nodedetails.selectedRole = 0;
+ }
+
+ /**
+ * deleteMenuItem
+ * @param selectedItem
+ */
+ deleteMenuItem(){
+ if(this.selectedItem.children!=null && this.selectedItem.children.length>0){
+ const modalRef = this.ngbModal.open(ConfirmationModalComponent);
+ modalRef.componentInstance.title = "";
+ modalRef.componentInstance.message = 'You are not allowed to delete a menu item that has children. You can only delete leaf menu items.';
+ modalRef.result.then((result) => { }, (resut) => {return;});
+ }else{
+ const modalRef = this.ngbModal.open(InformationModalComponent);
+ modalRef.componentInstance.title = "Confirmation";
+ modalRef.componentInstance.message = 'Are you sure you want to delete '+ this.selectedItem.name+' ?';
+ modalRef.result.then((result) => {
+ if (result === 'Ok') {
+ this.functionalMenuService.deleteMenuItem(this.selectedItem.menuId)
+ .subscribe(_data => {
+ this.result = _data
+ this.passEntry.emit(this.result);
+ let successMsg = "Item Deleted Successfully";
+ this.openConfirmationModal("Success",successMsg);
+ this.ngbModal.dismissAll();
+ }, error =>{
+ console.log(error);
+ let deleteErrorMsg = 'There was an error while deleting the item.'+error.message;
+ this.openConfirmationModal("Error",deleteErrorMsg);
+ return;
+ });
+ }
+ }, (resut) => {
+
+ })
+ }
+ }
+
+ updateSelectedApp(appid){
+ //console.log("updateSelectedApp called with appId :: ",appid);
+ if (!appid) {
+ return;
+ }
+ this.getAvailableRoles(appid);
+ }
+
+ getAvailableRoles(appid){
+ //console.log("getAvailableRoles called with appId :: ",appid);
+ if (appid != null && appid >0) {
+ this.functionalMenuService.getManagedRolesMenu(appid)
+ .subscribe(rolesObj => {
+ this.availableRoles = rolesObj;
+ if(this.availableRoles && this.availableRoles.length >0){
+ this.hideRoleField = false;
+ }
+ this.preSelectedRoles = {roles:[]};
+ this.preSelectedRoles = {roles:[]};
+
+ if((this.isEditMode) && this.isMidLevelMenuItem(this.nodedata)){
+ // in Edit flow , for Midlevel menu item no need to preSelect.
+ this.preSelectedRoles = {roles:[]};
+ }else if(this.nodedata && this.isEditMode && this.isLeafMenuItem(this.nodedata) && this.nodedata.appid!=appid) {
+ // in Edit flow , for LeafMenuItem, if appid changed then no need to preSelect.
+ this.preSelectedRoles = {roles:[]};
+ }else{
+ if(this.nodedata && this.nodedata.roles){
+ for(var i=0; i< this.nodedata.roles.length; i++){
+ var role = {"roleId": this.nodedata.roles[i]};
+ this.preSelectedRoles.roles.push(role);
+ }
+ }
+ }
+
+ if(this.nodedata.rolesObj){
+ for(var i=0; i< this.nodedata.rolesObj.length;i++){
+ //this.availableRoles[i].isApplied = false;
+ for(var j=0;j<this.preSelectedRoles.roles.length;j++){
+ if(this.preSelectedRoles.roles[j].roleId==this.availableRoles[i].roleId){
+ this.availableRoles[i].isApplied=true;
+ this.nodedetails.selectedRole = (this.preSelectedRoles.roles[j]) ? this.preSelectedRoles.roles[j] : 0;
+ break;
+ }
+ }
+ }
+ }
+ }, error =>{
+ console.log(error);
+ let errorMsg = 'There was an error while gettting available roles. ' + error.message;
+ this.openConfirmationModal("",errorMsg);
+ return;
+ });
+ //console.log("this.availableRoles >>>>>",this.availableRoles);
+ }else{
+ console.log("FunctionalMenuDialogComponent::getAvailableRoles: appid was null or -1");
+ }
+ }
+
+ getAvailableApps(){
+ this.isAllApplications = true;
+ this.functionalMenuService.getAvailableApplications()
+ .subscribe(apps => {
+ this.availableApps = apps;
+ if (this.nodedetails && this.nodedetails.index) {
+ for (var i = 0; i < this.availableApps.length; i++) {
+ if (apps[i].index === this.nodedetails.index) {
+ //console.log("MenuDetailsModalCtrl::getAvailableApps: found app with index: " + this.nodedetails.index);
+ //console.log("MenuDetailsModalCtrl::getAvailableApps: setting isDisabled to: " + !apps[i].enabled);
+ this.nodedetails.isDisabled = !apps[i].enabled;
+ break;
+ }
+ }
+ //console.log("didn't find index: " + this.nodedetails.index);
+ }
+ }, error =>{
+ console.log(error);
+ this.isAllApplications = false;
+ let errorMsg = 'There was a problem retrieving the Applications. '+error.message;
+ this.openConfirmationModal("Error",errorMsg);
+ });
+ }
+
+ isLeafMenuItem(menu: any){
+ return menu.children.length>0 ? false : true;
+ }
+
+ isMidLevelMenuItem(menu: any){
+ return menu.parentMenuId!=null && menu.children.length>0 ? true : false;
+ }
+
+ isParentMenuItem(menu: any){
+ return menu.parentMenuId!=null ? false : true;
+ };
+
+ isRoleSelected(){
+ var selectedRoleIds=[];
+ for(var i=0;i<this.availableRoles.length;i++){
+ if(this.availableRoles[i].isApplied){
+ selectedRoleIds.push(this.availableRoles[i].roleId);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ getDialogTitle = (source) => {
+ switch (source) {
+ case 'edit':
+ return "Functional Menu - Edit";
+ case 'view':
+ return "Functional Menu - View";
+ case 'add':
+ return "Functional Menu - Add";
+ default:
+ return "Functional Menu";
+ };
+ }
+
+ saveChanges(){
+ if(!this.nodedetails.menuLocation || !this.nodedetails.name
+ || !this.nodedetails.url || !this.nodedetails.selectedAppIndex
+ || !this.nodedetails.selectedAppIndex || !this.nodedetails.selectedRole){
+ this.openConfirmationModal("","All fields are mandatory, please provide inputs for all the fields.");
+ return;
+ }
+ /*
+ if(!!this.nodedetails.url && (!this.selectedApp || this.selectedAppIndex <=0)) {
+ this.openConfirmationModal("","Please select the appropriate app, or remove the url");
+ return;
+ }else if(!this.nodedetails.url && (this.selectedApp) && this.selectedApp.index>0){
+ this.openConfirmationModal("","Please enter url, or select No Application");
+ return;
+ }else if(!this.nodedetails.menutitle){
+ this.openConfirmationModal("","Please enter the Menu title");
+ return;
+ }
+ */
+
+ if(this.isAddItemMode){
+ if(this.selectedItem != null && this.selectedItem.getLevel() >= 4){
+ this.openConfirmationModal("","You are not allowed to have a menu item at a level greater than 4.");
+ return ;
+ }else{
+ let data = null;
+ let selectedMenuDetails = null;
+ this.functionalMenuService.getFunctionalMenu(this.selectedItem.menuId)
+ .subscribe(_data => {
+ selectedMenuDetails = _data
+ if((this.selectedItem.children===null || this.selectedItem.children.length == 0) && (!!selectedMenuDetails.url
+ || !!selectedMenuDetails.appid || !!selectedMenuDetails.roles)){
+ let warning_message = 'Warning: the child menu item "' +
+ this.selectedItem.name + '" is already configured with an application. You can create a new mid-level menu item.';
+ this.openConfirmationModal("",warning_message);
+ return;
+ }else{
+ if(this.selectedItem){
+ var selectedRoleIds=[];
+ //console.log("Selected Role ID ; ",this.nodedetails.selectedRole);
+ if(this.nodedetails.selectedRole){
+ selectedRoleIds.push(this.nodedetails.selectedRole);
+ }
+
+ let applicationid: any = null;
+ if(!this.nodedata){
+ applicationid = null;
+ }else{
+ applicationid = this.nodedata.appid;
+ }
+ var newMenuItem = {
+ menuId:null, // this is a new menu item
+ column:this.nodedata.column,
+ text:this.nodedetails.name,
+ // We are creating this new menu item under the menu item that was clicked on.
+ parentMenuId:this.nodedata.menuId,
+ url:(this.nodedetails.url) ? this.nodedetails.url : null,
+ appid:(this.nodedetails.selectedAppIndex) ? this.nodedetails.selectedAppIndex: null,
+ roles:selectedRoleIds
+ };
+ //console.log("Add menu Item newMenuItem :: ",newMenuItem)
+ this.functionalMenuService.saveMenuItem(newMenuItem)
+ .subscribe(_data => {
+ this.result = _data
+ //console.log("add menu item response :: ",_data);
+ this.passEntry.emit(this.result);
+ let successMsg = "Item added successfully";
+ this.openConfirmationModal("Success",successMsg);
+ }, error =>{
+ console.log(error);
+ if(error.status === 409){//Conflict
+ this.handleConflictErrors(error);
+ } else {
+ let errorMsg = "There was a problem saving your menu. Please try again later. Error Status: "+error.status
+ this.openConfirmationModal("",errorMsg);
+ return;
+ }
+ });
+ }
+ }
+ }, error =>{
+ //console.log(error);
+ let errorMsg = "There was a problem saving your menu. Please try again later. Error Status: "+error.status
+ this.openConfirmationModal("",errorMsg );
+ return;
+ });
+ }
+ }else{
+ //edit mode..
+ //console.log('MenuDetailsModalCtrl::saveChanges: Will be saving an edit menu item');
+ var selectedRoleIds=[];
+ //console.log("Selected Role ID ---->>>> ",this.nodedetails.selectedRole);
+ if(this.nodedetails.selectedRole){
+ selectedRoleIds.push(this.nodedetails.selectedRole);
+ }
+ let activeMenuItem = {
+ menuId:this.nodedata.menuId,
+ column:this.nodedata.column,
+ text:this.nodedetails.name,
+ parentMenuId:this.nodedata.parentMenuId,
+ url:(this.nodedetails.url) ? this.nodedetails.url : null,
+ appid: (this.nodedetails.selectedAppIndex) ? this.nodedetails.selectedAppIndex: null,
+ roles:selectedRoleIds
+ };
+ if ((activeMenuItem.appid==null && activeMenuItem.url=="") || (activeMenuItem.appid==null && activeMenuItem.url=="undefined")) {
+ activeMenuItem.roles = null;
+ }
+ //console.log("Update menu Item activeMenuItem :: ",activeMenuItem);
+ this.functionalMenuService.saveEditedMenuItem(activeMenuItem)
+ .subscribe(_data => {
+ this.result = _data
+ //console.log("Edit menu item response :: ",_data);
+ this.passEntry.emit(this.result);
+ let successMsg = "Item updated successfully";
+ this.openConfirmationModal("Success",successMsg);
+ //this.ngbModal.dismissAll();
+ }, error =>{
+ //console.log(error);
+ let errorMsg = "There was a problem updating your menu. Please try again later. Error Status: "+error.status;
+ this.openConfirmationModal("",errorMsg);
+ return;
+ });
+ }
+ }
+
+ //This part handles conflict errors (409)
+ handleConflictErrors(error){
+ if(!error.data){
+ return;
+ }
+ if(!error.data.length){ //support objects
+ error.data = [error.data]
+ }
+ //console.log('MenuDetailsModalCtrl::handleConflictErrors: err.data = ' + JSON.stringify(error.data));
+ if(error.data){
+ error.data.forEach(item => {
+ //set conflict message
+ this.conflictMessages[item.field.name] = item.errorCode;
+ //set field as invalid
+ //console.log('MenuDetailsModalCtrl::handleConflictErrors: fieldName = ' + item.field.name);
+ this.functionalMenuForm[item.field.name].$setValidity('conflict', false);
+ });
+ }
+ }
+
+ openConfirmationModal(_title: string, _message: string) {
+ const modalInfoRef = this.ngbModal.open(ConfirmationModalComponent);
+ modalInfoRef.componentInstance.title = _title;
+ modalInfoRef.componentInstance.message = _message;
+ }
+
+ openInformationModal(_title: string, _message: string){
+ const modalInfoRef = this.ngbModal.open(InformationModalComponent);
+ modalInfoRef.componentInstance.title = _title;
+ modalInfoRef.componentInstance.message = _message;
+ return modalInfoRef;
+ }
+}
diff --git a/portal-FE-common/src/app/pages/functional-menu/functional-menu.component.html b/portal-FE-common/src/app/pages/functional-menu/functional-menu.component.html
new file mode 100644
index 00000000..d898563b
--- /dev/null
+++ b/portal-FE-common/src/app/pages/functional-menu/functional-menu.component.html
@@ -0,0 +1,52 @@
+<!--
+ ============LICENSE_START==========================================
+ ONAP Portal
+ ===================================================================
+ Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ ===================================================================
+
+ Unless otherwise specified, all software contained herein is licensed
+ under the Apache License, Version 2.0 (the "License");
+ you may not use this software 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.
+
+ Unless otherwise specified, all documentation contained herein is licensed
+ under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ you may not use this documentation except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://creativecommons.org/licenses/by/4.0/
+
+ Unless required by applicable law or agreed to in writing, documentation
+ 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">
+ <div id="title" class="w-onap-main-view-title">
+ <h1 class="heading-page">Edit Functional Menu</h1>
+ </div>
+ <div id="jqTree"></div>
+ <div class="functional-admin-button-container">
+ <button id="regenrate-functionalmenu-btn"
+ class="btn btn-alt btn-small"
+ (click)="regenerateFunctionalMenuAncestors()">Regenerate Menu
+ </button>
+ <div class="regenerate-functionalmenu-btn-txt">
+ <span class="n16r">Click when you are done with your changes.</span>
+ </div>
+ </div>
+</div>
diff --git a/portal-FE-common/src/app/pages/functional-menu/functional-menu.component.scss b/portal-FE-common/src/app/pages/functional-menu/functional-menu.component.scss
new file mode 100644
index 00000000..c716252e
--- /dev/null
+++ b/portal-FE-common/src/app/pages/functional-menu/functional-menu.component.scss
@@ -0,0 +1,95 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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============================================
+ *
+ *
+ */
+
+.functional-menu-main {
+ background-color: #fff;
+ position: fixed;
+ top: 105px;
+ left: 0;
+ right: 0;
+ bottom: 75px;
+ padding-top: 10px;
+ overflow-y: scroll;
+ padding-left: 0;
+}
+
+.functional-menu-main .functional-menu-container {
+ position: relative;
+ padding-right: 0;
+ padding-left: 0;
+ padding-bottom: 32px;
+ background-color: #fff;
+}
+
+.w-ecomp-main-view-title {
+ color: #191919;
+ font-family: Omnes-ECOMP-W02-Medium,Arial;
+ font-size: 24px;
+ width: 1170px;
+ padding-bottom: 15px;
+ margin: auto;
+}
+
+.functional-menu-main .functional-menu-container .tree {
+ margin: auto;
+ width: 1170px;
+ font-size: 16px;
+}
+
+.functional-admin-button-container {
+ padding-top: 10px;
+ width: 1170px;
+ margin: auto;
+}
+
+.btn-small {
+ padding: 10px 19px 9px 18px;
+ font-size: 1.5rem;
+ border-radius: 8px;
+}
+
+.btn-alt {
+ border-color: #087ac2 transparent #0568ae;
+ background-color: #0568ae;
+ background: linear-gradient(to bottom, #087ac2 0%, #0568ae 100%);
+ color: #ffffff;
+}
+
+.functional-menu-main .regenerate-functionalmenu-btn-txt {
+ color: #000;
+}
diff --git a/portal-FE-common/src/app/pages/functional-menu/functional-menu.component.spec.ts b/portal-FE-common/src/app/pages/functional-menu/functional-menu.component.spec.ts
new file mode 100644
index 00000000..c5c562ed
--- /dev/null
+++ b/portal-FE-common/src/app/pages/functional-menu/functional-menu.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { FunctionalMenuComponent } from './functional-menu.component';
+
+describe('FunctionalMenuComponent', () => {
+ let component: FunctionalMenuComponent;
+ let fixture: ComponentFixture<FunctionalMenuComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ FunctionalMenuComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(FunctionalMenuComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/portal-FE-common/src/app/pages/functional-menu/functional-menu.component.ts b/portal-FE-common/src/app/pages/functional-menu/functional-menu.component.ts
new file mode 100644
index 00000000..655b4cb4
--- /dev/null
+++ b/portal-FE-common/src/app/pages/functional-menu/functional-menu.component.ts
@@ -0,0 +1,192 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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 { Component, OnInit } from '@angular/core';
+import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
+import { FunctionalMenuService } from 'src/app/shared/services';
+import { ConfirmationModalComponent } from 'src/app/modals/confirmation-modal/confirmation-modal.component';
+import { FunctionalMenuDialogComponent } from './functional-menu-dialog/functional-menu-dialog.component';
+
+
+@Component({
+ selector: 'app-functional-menu',
+ templateUrl: './functional-menu.component.html',
+ styleUrls: ['./functional-menu.component.scss']
+})
+export class FunctionalMenuComponent implements OnInit {
+
+ result: any;
+ functionalMenu: any = [];
+ treedata = [];
+ isEditMode: boolean;
+ operationName: string;
+ self: any;
+ constructor(public functionalMenuService : FunctionalMenuService, public ngbModal: NgbModal) { }
+
+ ngOnInit() {
+ this.self = this;
+ this.functionalMenu = [];
+ this.getFunctionalMenu();
+
+ }
+
+ /**
+ * regenerateFunctionalMenuAncestors
+ */
+ regenerateFunctionalMenuAncestors(){
+ this.functionalMenuService.regenerateFunctionalMenuAncestors()
+ .subscribe(_data => {
+ this.result = _data
+ if(this.result){
+ const modalRef = this.ngbModal.open(ConfirmationModalComponent);
+ modalRef.componentInstance.title = "";
+ modalRef.componentInstance.message = 'You have successfully regenerated the menu.';
+ modalRef.result.then((result) => { }, (resut) => {return;});
+ this.getFunctionalMenu();
+ }
+ }, error =>{
+ console.log(error);
+ const modalRef = this.ngbModal.open(ConfirmationModalComponent);
+ modalRef.componentInstance.title = "";
+ modalRef.componentInstance.message = 'There was an error while regenerating the menu.';
+ modalRef.result.then((result) => { }, (resut) => {return;});
+ });
+ }
+
+ /**
+ * getFunctionalMenu
+ */
+ getFunctionalMenu(){
+ let actualData=[];
+ this.functionalMenuService.getManagedFunctionalMenu()
+ .subscribe(_data => {
+ this.result = _data;
+ if(this.result){
+ for(let i = 0; i < this.result.length; i++){
+ this.result[i].children=[];
+ this.result[i].label= this.result[i].text;
+ this.result[i].id= this.result[i].text;
+ }
+ //Adding actual child items to children array in res objects
+ for(let i = 0; i < this.result.length; i++){
+ let parentId=this.result[i].menuId;
+ for(let j = 0; j < this.result.length; j++){
+ let childId=this.result[j].parentMenuId;
+ if(parentId===childId){
+ this.result[i].children.push(this.result[j]);
+ }
+ }
+ }
+ // Sort the top-level menu items in order based on the column
+ this.result.sort(function(a, b) {
+ return a.column-b.column;
+ });
+
+ // Sort all the children in order based on the column
+ for(let i = 0; i < this.result.length; i++){
+ this.result[i].children.sort(function(a, b){
+ return a.column-b.column;
+ });
+ }
+
+ //Forming actual parent items
+ for(let i = 0; i < this.result.length; i++){
+ let parentId= this.result[i].parentMenuId;
+ if(parentId===null){
+ actualData.push( this.result[i]);
+ }
+ }
+
+ this.treedata = actualData;
+ //console.log("this.treedata :: ",this.treedata);
+
+ if(this.treedata){
+ this.buildTree(this.treedata,this.ngbModal, this.self);
+ }
+
+ }
+ }, error =>{
+ console.log(error);
+ });
+
+ }
+
+ /**
+ * buildTree
+ * @param treedataarray
+ * @param ngbModal
+ */
+ buildTree(treedataarray,ngbModal: NgbModal , _self){
+ //console.log("treedataarray>>>>",treedataarray);
+ $(function() {
+ $('#jqTree').tree('loadData', treedataarray);
+ $('#jqTree').tree({
+ data: treedataarray,
+ autoOpen: false,
+ dragAndDrop: true,
+ onCreateLi: function(node, $li) {
+ ////console.log("node >>",node);
+ }
+ }).on(
+ 'tree.contextmenu',
+ function(event:any) {
+ // The clicked node is 'event.node'
+ var node = event.node;
+ openMenuDetailsModal(node, "view");
+ }
+ );
+
+ var openMenuDetailsModal = function(node: any, actionName: string ){
+ const modalRef = ngbModal.open(FunctionalMenuDialogComponent, { size: 'lg' });
+ modalRef.componentInstance.title = 'Functional Menu ',actionName;
+ if(node != 'undefined' && node){
+ modalRef.componentInstance.nodedata = node;
+ modalRef.componentInstance.operationName = actionName;
+ }else{
+ modalRef.componentInstance.nodedata = {};
+ }
+ modalRef.componentInstance.passEntry.subscribe((receivedEntry: any) => {
+ //console.log("receivedEntry>>>>",receivedEntry);
+ ngbModal.dismissAll();
+ if(receivedEntry.httpStatusCode===200){
+ _self.getFunctionalMenu();
+ }
+ });
+ }
+ });
+ }
+}
diff --git a/portal-FE-common/src/app/pages/functional-menu/jqTreeContextMenu.js b/portal-FE-common/src/app/pages/functional-menu/jqTreeContextMenu.js
new file mode 100644
index 00000000..fa240187
--- /dev/null
+++ b/portal-FE-common/src/app/pages/functional-menu/jqTreeContextMenu.js
@@ -0,0 +1,195 @@
+(function ($) {
+ if (!$.fn.tree) {
+ throw "Error jqTree is not loaded.";
+ }
+
+ $.fn.jqTreeContextMenu = function (menuElement, callbacks) {
+ //
+ // TODO:
+ // * Make sure the useContextMenu option is set in jqTree, either complain or set it automatically
+ // * Make menu fade in/out
+ //
+ var self = this;
+ var $el = this;
+
+ // The jQuery object of the menu div.
+ var $menuEl = menuElement;
+
+ // This hash holds all menu items that should be disabled for a specific node.
+ var nodeToDisabledMenuItems = {};
+
+ // Hide the menu div.
+ $menuEl.hide();
+
+ // Disable system context menu from beeing displayed.
+ $el.bind("contextmenu", function (e) {
+ e.preventDefault();
+ return false;
+ });
+
+ // Handle the contextmenu event sent from jqTree when user clicks right mouse button.
+ $el.bind('tree.contextmenu', function (event) {
+ var x = event.click_event.pageX;
+ var y = event.click_event.pageY;
+ var yPadding = 5;
+ var xPadding = 5;
+ var menuHeight = $menuEl.height();
+ var menuWidth = $menuEl.width();
+ var windowHeight = $(window).height();
+ var windowWidth = $(window).width();
+
+ if (menuHeight + y + yPadding > windowHeight) {
+ // Make sure the whole menu is rendered within the viewport.
+ y = y - menuHeight;
+ }
+ if (menuWidth + x + xPadding > windowWidth) {
+ // Make sure the whole menu is rendered within the viewport.
+ x = x - menuWidth;
+ }
+
+ // Handle disabling and enabling of menu items on specific nodes.
+ if (Object.keys(nodeToDisabledMenuItems).length > 0) {
+ if (event.node.name in nodeToDisabledMenuItems) {
+ var nodeName = event.node.name;
+ var items = nodeToDisabledMenuItems[nodeName];
+ if (items.length === 0) {
+ $menuEl.find('li').addClass('disabled');
+ $menuEl.find('li > a').unbind('click');
+ } else {
+ $menuEl.find('li > a').each(function () {
+ $(this).closest('li').removeClass('disabled');
+ var hrefValue = $(this).attr('href');
+ var value = hrefValue.slice(hrefValue.indexOf("#") + 1, hrefValue.length)
+ if ($.inArray(value, items) > -1) {
+ $(this).closest('li').addClass('disabled');
+ $(this).unbind('click');
+ }
+ });
+ }
+ } else {
+ $menuEl.find('li.disabled').removeClass('disabled');
+ }
+ }
+
+ // Must call show before we set the offset (offset can not be set on display: none elements).
+ $menuEl.show();
+
+ $menuEl.offset({ left: x, top: y });
+
+ var dismissContextMenu = function () {
+ $(document).unbind('click.jqtreecontextmenu');
+ $el.unbind('tree.click.jqtreecontextmenu');
+ $menuEl.hide();
+ }
+ // Make it possible to dismiss context menu by clicking somewhere in the document.
+ $(document).bind('click.jqtreecontextmenu', function () {
+ dismissContextMenu();
+ });
+
+ // Dismiss context menu if another node in the tree is clicked.
+ $el.bind('tree.click.jqtreecontextmenu', function (e) {
+ dismissContextMenu();
+ });
+
+ // Make selection follow the node that was right clicked on.
+ var selectedNode = $el.tree('getSelectedNode');
+ if (selectedNode !== event.node) {
+ $el.tree('selectNode', event.node);
+ }
+
+ // Handle click on menu items, if it's not disabled.
+ var menuItems = $menuEl.find('li:not(.disabled) a');
+ if (menuItems.length !== 0) {
+ menuItems.unbind('click');
+ menuItems.click(function (e) {
+ e.stopImmediatePropagation();
+ dismissContextMenu();
+ var hrefAnchor = e.currentTarget.attributes.href.nodeValue;
+ var funcKey = hrefAnchor.slice(hrefAnchor.indexOf("#") + 1, hrefAnchor.length)
+ var callbackFn = callbacks[funcKey];
+ if (callbackFn) {
+ callbackFn(event.node);
+ }
+ return false;
+ });
+ }
+ });
+
+ this.disable = function () {
+ if (arguments.length === 0) {
+ // Called as: api.disable()
+ $menuEl.find('li:not(.disabled)').addClass('disabled');
+ $menuEl.find('li a').unbind('click');
+ nodeToDisabledMenuItems = {};
+ } else if (arguments.length === 1) {
+ // Called as: api.disable(['edit','remove'])
+ var items = arguments[0];
+ if (typeof items !== 'object') {
+ return;
+ }
+ $menuEl.find('li > a').each(function () {
+ var hrefValue = $(this).attr('href');
+ var value = hrefValue.slice(hrefValue.indexOf("#") + 1, hrefValue.length)
+ if ($.inArray(value, items) > -1) {
+ $(this).closest('li').addClass('disabled');
+ $(this).unbind('click');
+ }
+ });
+ nodeToDisabledMenuItems = {};
+ } else if (arguments.length === 2) {
+ // Called as: api.disable(nodeName, ['edit','remove'])
+ var nodeName = arguments[0];
+ var items = arguments[1];
+ nodeToDisabledMenuItems[nodeName] = items;
+ }
+ };
+
+ this.enable = function () {
+ if (arguments.length === 0) {
+ // Called as: api.enable()
+ $menuEl.find('li.disabled').removeClass('disabled');
+ nodeToDisabledMenuItems = {};
+ } else if (arguments.length === 1) {
+ // Called as: api.enable(['edit','remove'])
+ var items = arguments[0];
+ if (typeof items !== 'object') {
+ return;
+ }
+
+ $menuEl.find('li > a').each(function () {
+ var hrefValue = $(this).attr('href');
+ var value = hrefValue.slice(hrefValue.indexOf("#") + 1, hrefValue.length)
+ if ($.inArray(value, items) > -1) {
+ $(this).closest('li').removeClass('disabled');
+ }
+ });
+
+ nodeToDisabledMenuItems = {};
+ } else if (arguments.length === 2) {
+ // Called as: api.enable(nodeName, ['edit','remove'])
+ var nodeName = arguments[0];
+ var items = arguments[1];
+ if (items.length === 0) {
+ delete nodeToDisabledMenuItems[nodeName];
+ } else {
+ var disabledItems = nodeToDisabledMenuItems[nodeName];
+ for (var i = 0; i < items.length; i++) {
+ var idx = disabledItems.indexOf(items[i]);
+ if (idx > -1) {
+ disabledItems.splice(idx, 1);
+ }
+ }
+ if (disabledItems.length === 0) {
+ delete nodeToDisabledMenuItems[nodeName];
+ } else {
+ nodeToDisabledMenuItems[nodeName] = disabledItems;
+ }
+ }
+ if (Object.keys(nodeToDisabledMenuItems).length === 0) {
+ $menuEl.find('li.disabled').removeClass('disabled');
+ }
+ }
+ };
+ return this;
+ };
+} (jQuery));
diff --git a/portal-FE-common/src/app/pages/portal-admins/new-portal-admin/new-portal-admin.component.html b/portal-FE-common/src/app/pages/portal-admins/new-portal-admin/new-portal-admin.component.html
new file mode 100644
index 00000000..bdd99730
--- /dev/null
+++ b/portal-FE-common/src/app/pages/portal-admins/new-portal-admin/new-portal-admin.component.html
@@ -0,0 +1,54 @@
+<!--
+ ============LICENSE_START==========================================
+ ONAP Portal
+ ===================================================================
+ Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ ===================================================================
+
+ Unless otherwise specified, all software contained herein is licensed
+ under the Apache License, Version 2.0 (the "License");
+ you may not use this software 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.
+
+ Unless otherwise specified, all documentation contained herein is licensed
+ under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ you may not use this documentation except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://creativecommons.org/licenses/by/4.0/
+
+ Unless required by applicable law or agreed to in writing, documentation
+ 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">
+ <div class="modal-header">
+ <h4 class="modal-title">{{title}}</h4>
+ <button type="button" class="close" aria-label="Close" (click)="activeModal.dismiss('Cross')">
+ <span aria-hidden="true">&times;</span>
+ </button>
+ </div>
+ <div class="modal-body">
+ <app-search-users [searchTitle]="searchTitleText" [placeHolder]="placeholderText" (passBackSelectedUser)='changeSelectedUser($event)'></app-search-users>
+ </div>
+ <div class="modal-footer">
+ <button type="submit" class="btn btn-primary" [disabled]='!changedSelectedUser'
+ (click)="addNewPortalAdmin(changedSelectedUser)">Save</button> &nbsp;
+ <button type="button" class="btn btn-primary" (click)="activeModal.close('Close')">Cancel</button>
+ </div>
+</div> \ No newline at end of file
diff --git a/portal-FE-common/src/app/pages/portal-admins/new-portal-admin/new-portal-admin.component.scss b/portal-FE-common/src/app/pages/portal-admins/new-portal-admin/new-portal-admin.component.scss
new file mode 100644
index 00000000..7a773398
--- /dev/null
+++ b/portal-FE-common/src/app/pages/portal-admins/new-portal-admin/new-portal-admin.component.scss
@@ -0,0 +1,37 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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============================================
+ *
+ *
+ */ \ No newline at end of file
diff --git a/portal-FE-common/src/app/pages/portal-admins/new-portal-admin/new-portal-admin.component.spec.ts b/portal-FE-common/src/app/pages/portal-admins/new-portal-admin/new-portal-admin.component.spec.ts
new file mode 100644
index 00000000..cd85fca1
--- /dev/null
+++ b/portal-FE-common/src/app/pages/portal-admins/new-portal-admin/new-portal-admin.component.spec.ts
@@ -0,0 +1,62 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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 { NewPortalAdminComponent } from './new-portal-admin.component';
+
+describe('NewPortalAdminComponent', () => {
+ let component: NewPortalAdminComponent;
+ let fixture: ComponentFixture<NewPortalAdminComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ NewPortalAdminComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(NewPortalAdminComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/portal-FE-common/src/app/pages/portal-admins/new-portal-admin/new-portal-admin.component.ts b/portal-FE-common/src/app/pages/portal-admins/new-portal-admin/new-portal-admin.component.ts
new file mode 100644
index 00000000..d5cde04b
--- /dev/null
+++ b/portal-FE-common/src/app/pages/portal-admins/new-portal-admin/new-portal-admin.component.ts
@@ -0,0 +1,94 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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 { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
+import { NgbActiveModal, NgbModal, ModalDismissReasons } from '@ng-bootstrap/ng-bootstrap';
+import { PortalAdmin } from 'src/app/shared/model/PortalAdmin';
+import { PortalAdminsService } from 'src/app/shared/services';
+import { HttpErrorResponse } from '@angular/common/http';
+import { ConfirmationModalComponent } from 'src/app/modals/confirmation-modal/confirmation-modal.component';
+import { InformationModalComponent } from 'src/app/modals/information-modal/information-modal.component';
+
+@Component({
+ selector: 'app-new-portal-admin',
+ templateUrl: './new-portal-admin.component.html',
+ styleUrls: ['./new-portal-admin.component.scss']
+})
+export class NewPortalAdminComponent implements OnInit {
+
+ constructor(public activeModal: NgbActiveModal, private portalAdminsService: PortalAdminsService,
+ public ngbModal: NgbModal) { }
+ @Input() title: string;
+ @Input() id: number;
+ changedSelectedUser: PortalAdmin;
+ closeResult: string;
+ searchTitleText = 'Enter First Name, Last Name or Org User Id';
+ placeholderText = 'Search';
+ @Output() passBackNewPortalAdmin: EventEmitter<any> = new EventEmitter();
+
+ ngOnInit() {
+ }
+
+ changeSelectedUser(user: PortalAdmin) {
+ this.changedSelectedUser = user;
+ }
+
+ addNewPortalAdmin(changedSelectedUser: PortalAdmin) {
+ const modalRef = this.ngbModal.open(InformationModalComponent);
+ modalRef.componentInstance.title = "Admin Update";
+ modalRef.componentInstance.message = `Are you sure you want to add ${changedSelectedUser.firstName} ${changedSelectedUser.lastName} as a Portal Admin?`;
+ modalRef.result.then((result) => {
+ if (result === 'Ok') {
+ this.portalAdminsService.addPortalAdmin(this.changedSelectedUser.orgUserId).subscribe(_data => {
+ this.passBackNewPortalAdmin.emit(_data);
+ }, (_err: HttpErrorResponse) => {
+ this.passBackNewPortalAdmin.emit(_err);
+ const modalErrorRef = this.ngbModal.open(ConfirmationModalComponent);
+ modalErrorRef.componentInstance.title = "Error";
+ if (_err.status === 409) { //Conflict
+ modalErrorRef.componentInstance.message = "This user already exists as a portal admin!";
+ } else {
+ modalErrorRef.componentInstance.message = "There was a unknown problem adding the portal admin." + "Please try again later. Error Status: " + _err.status;
+ }
+ });
+ }
+ }, (reason) => {
+ return;
+ });
+
+ }
+}
diff --git a/portal-FE-common/src/app/pages/portal-admins/portal-admins.component.html b/portal-FE-common/src/app/pages/portal-admins/portal-admins.component.html
new file mode 100644
index 00000000..26e59e45
--- /dev/null
+++ b/portal-FE-common/src/app/pages/portal-admins/portal-admins.component.html
@@ -0,0 +1,87 @@
+<!--
+ ============LICENSE_START==========================================
+ ONAP Portal
+ ===================================================================
+ Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ ===================================================================
+
+ Unless otherwise specified, all software contained herein is licensed
+ under the Apache License, Version 2.0 (the "License");
+ you may not use this software 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.
+
+ Unless otherwise specified, all documentation contained herein is licensed
+ under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ you may not use this documentation except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://creativecommons.org/licenses/by/4.0/
+
+ Unless required by applicable law or agreed to in writing, documentation
+ 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">
+ <div class="onap-main-view-title">
+ <h1 class="heading-page">Portal Admins</h1>
+ </div>
+ <mat-form-field>
+ <input matInput type="text" (keyup)="applyFilter($event.target.value)" placeholder="Search in entire table">
+ </mat-form-field>
+
+ <button type="button" class="btn btn-primary" (click)="addPortalAdminEntry()"><i class="icon ion-md-person-add"></i>
+ Add Portal Admin</button>
+
+ <span class="onap-spinner" *ngIf="showSpinner"></span>
+ <table mat-table [dataSource]="dataSource" matSort>
+ <!-- First Name Column -->
+ <ng-container matColumnDef="firstName">
+ <th id="col1" mat-header-cell *matHeaderCellDef mat-sort-header> First Name </th>
+ <td id="rowheader_t1_{{i}}-firstName" mat-cell *matCellDef="let element; let i = index;"> {{element.firstName}}
+ </td>
+ </ng-container>
+
+ <!-- Last Name Column -->
+ <ng-container matColumnDef="lastName">
+ <th id="col2" mat-header-cell *matHeaderCellDef mat-sort-header> Last Name </th>
+ <td id="rowheader_t1_{{i}}-lastName" mat-cell *matCellDef="let element; let i=index;"> {{element.lastName}}
+ </td>
+ </ng-container>
+
+ <!-- User ID Column -->
+ <ng-container matColumnDef="loginId">
+ <th id="col3" mat-header-cell *matHeaderCellDef mat-sort-header> User ID </th>
+ <td id="rowheader_t1_{{$index}}-loginId" mat-cell *matCellDef="let element; let i=index;"> {{element.loginId}}
+ </td>
+ </ng-container>
+
+ <!-- Delete Column -->
+ <ng-container matColumnDef="delete">
+ <th id="col4" mat-header-cell *matHeaderCellDef> Delete </th>
+ <td id="rowheader_t1_{{i}}" mat-cell *matCellDef="let element; let i=index;">
+ <span class="icon-trash" id="{{i}}-button-portal-admin-remove" (click)="removePortalAdmin(element)">
+ <i class="icon ion-md-trash"></i>
+ </span>
+ </td>
+ </ng-container>
+
+ <tr [hidden]="portalAdmins.length === 0" mat-header-row *matHeaderRowDef="displayedColumns"></tr>
+ <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
+ </table>
+ <mat-paginator [hidden]="portalAdmins.length === 0" [pageSizeOptions]="[10, 20]" showFirstLastButtons></mat-paginator>
+</div> \ No newline at end of file
diff --git a/portal-FE-common/src/app/pages/portal-admins/portal-admins.component.scss b/portal-FE-common/src/app/pages/portal-admins/portal-admins.component.scss
new file mode 100644
index 00000000..4c65595a
--- /dev/null
+++ b/portal-FE-common/src/app/pages/portal-admins/portal-admins.component.scss
@@ -0,0 +1,43 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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 '../pages.component';
+
+.icon-trash{
+ cursor: pointer;
+ font-size: 20px;
+}
diff --git a/portal-FE-common/src/app/pages/portal-admins/portal-admins.component.spec.ts b/portal-FE-common/src/app/pages/portal-admins/portal-admins.component.spec.ts
new file mode 100644
index 00000000..0e3c969f
--- /dev/null
+++ b/portal-FE-common/src/app/pages/portal-admins/portal-admins.component.spec.ts
@@ -0,0 +1,62 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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 { PortalAdminsComponent } from './portal-admins.component';
+
+describe('PortalAdminsComponent', () => {
+ let component: PortalAdminsComponent;
+ let fixture: ComponentFixture<PortalAdminsComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ PortalAdminsComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(PortalAdminsComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/portal-FE-common/src/app/pages/portal-admins/portal-admins.component.ts b/portal-FE-common/src/app/pages/portal-admins/portal-admins.component.ts
new file mode 100644
index 00000000..5dfe026d
--- /dev/null
+++ b/portal-FE-common/src/app/pages/portal-admins/portal-admins.component.ts
@@ -0,0 +1,124 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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 { OnInit, Component, ViewChild, NgModuleRef } from '@angular/core';
+import { MatSort, MatPaginator } from '@angular/material';
+import { MatTableDataSource } from '@angular/material';
+import { PortalAdminsService } from 'src/app/shared/services';
+import { NgbModal, ModalDismissReasons } from '@ng-bootstrap/ng-bootstrap';
+import { NewPortalAdminComponent } from './new-portal-admin/new-portal-admin.component';
+import { InformationModalComponent } from 'src/app/modals/information-modal/information-modal.component';
+import { PortalAdmin } from 'src/app/shared/model/PortalAdmin';
+import { HttpErrorResponse } from '@angular/common/http';
+import { ConfirmationModalComponent } from 'src/app/modals/confirmation-modal/confirmation-modal.component';
+
+@Component({
+ selector: 'app-portal-admins',
+ templateUrl: './portal-admins.component.html',
+ styleUrls: ['./portal-admins.component.scss']
+})
+export class PortalAdminsComponent implements OnInit {
+ portalAdmins: PortalAdmin[] = [];
+ showSpinner = true;
+ closeResult: string;
+ constructor(private portalAdminsService: PortalAdminsService, private ngbModal: NgbModal) { }
+ displayedColumns: string[] = ['firstName', 'lastName', 'loginId', 'delete'];
+ dataSource = new MatTableDataSource(this.portalAdmins);
+ @ViewChild(MatSort) sort: MatSort;
+ @ViewChild(MatPaginator) paginator: MatPaginator;
+ ngOnInit() {
+ this.getAllPortalAdmins();
+ }
+
+ getAllPortalAdmins() {
+ this.portalAdminsService.getPortalAdmins().subscribe((_data: PortalAdmin[]) => {
+ this.showSpinner = false;
+ // _data is the array of data that you getting from the db.
+ this.portalAdmins = _data;
+ this.dataSource = new MatTableDataSource(this.portalAdmins);
+ this.dataSource.sort = this.sort;
+ this.dataSource.paginator = this.paginator;
+ }, (_err: HttpErrorResponse) =>{
+ const modalErrorRef = this.ngbModal.open(ConfirmationModalComponent);
+ modalErrorRef.componentInstance.title = "Error";
+ if (_err.status) { //Conflict
+ modalErrorRef.componentInstance.message = 'Error Status: ' + _err.status + ' There was a unknown problem adding the portal admin.' + 'Please try again later.';
+ }
+ })
+ }
+
+ applyFilter(filterValue: string) {
+ this.dataSource.filter = filterValue.trim().toLowerCase();
+ }
+
+ addPortalAdminEntry() {
+ const modalRef = this.ngbModal.open(NewPortalAdminComponent);
+ modalRef.componentInstance.title = 'Add Portal Admin';
+ modalRef.componentInstance.id = 1;
+ modalRef.componentInstance.passBackNewPortalAdmin.subscribe((_result: any) => {
+ modalRef.close();
+ this.showSpinner = true;
+ this.getAllPortalAdmins();
+ })
+ }
+
+ removePortalAdmin(deletePortalAdmin: any) {
+ const modalRef = this.ngbModal.open(InformationModalComponent);
+ modalRef.componentInstance.title = 'Confirmation';
+ modalRef.componentInstance.message = `Are you sure you want to delete ${deletePortalAdmin.firstName} ${deletePortalAdmin.lastName} ?`;
+ modalRef.result.then((result) => {
+ if (result === 'Ok') {
+ this.portalAdminsService.removePortalAdmin(deletePortalAdmin.userId, deletePortalAdmin.loginId).subscribe(_data => {
+ this.showSpinner = true;
+ this.getAllPortalAdmins();
+ })
+ }
+ }, (reason) => {
+ this.closeResult = `Dismissed ${this.getDismissReason(reason)}`;
+ });
+ }
+
+ private getDismissReason(reason: any): string {
+ if (reason === ModalDismissReasons.ESC) {
+ return 'by pressing ESC';
+ } else if (reason === ModalDismissReasons.BACKDROP_CLICK) {
+ return 'by clicking on a backdrop';
+ } else {
+ return `with: ${reason}`;
+ }
+ }
+} \ No newline at end of file
diff --git a/portal-FE-common/src/app/shared/helpers/must-match-validator.ts b/portal-FE-common/src/app/shared/helpers/must-match-validator.ts
new file mode 100644
index 00000000..70e9e1a4
--- /dev/null
+++ b/portal-FE-common/src/app/shared/helpers/must-match-validator.ts
@@ -0,0 +1,21 @@
+import { FormGroup } from '@angular/forms';
+
+// custom validator to check that two fields match
+export function MustMatch(controlName: string, matchingControlName: string) {
+ return (formGroup: FormGroup) => {
+ const control = formGroup.controls[controlName];
+ const matchingControl = formGroup.controls[matchingControlName];
+
+ if (matchingControl.errors && !matchingControl.errors.mustMatch) {
+ // return if another validator has already found an error on the matchingControl
+ return;
+ }
+
+ // set error on matchingControl if validation fails
+ if (control.value !== matchingControl.value) {
+ matchingControl.setErrors({ mustMatch: true });
+ } else {
+ matchingControl.setErrors(null);
+ }
+ }
+} \ No newline at end of file
diff --git a/portal-FE-common/src/app/shared/model/Admins.ts b/portal-FE-common/src/app/shared/model/Admins.ts
new file mode 100644
index 00000000..258c42a5
--- /dev/null
+++ b/portal-FE-common/src/app/shared/model/Admins.ts
@@ -0,0 +1,49 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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============================================
+ *
+ *
+ */
+export class Admins {
+ firstName: string;
+ lastName: string;
+ user_Id: number;
+ orgUserId: string;
+ apps: Apps[];
+}
+
+export class Apps {
+ appId: number;
+ appName: string;
+} \ No newline at end of file
diff --git a/portal-FE-common/src/app/shared/model/AllApps.ts b/portal-FE-common/src/app/shared/model/AllApps.ts
new file mode 100644
index 00000000..fcf9f7b0
--- /dev/null
+++ b/portal-FE-common/src/app/shared/model/AllApps.ts
@@ -0,0 +1,44 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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============================================
+ *
+ *
+ */
+export class AllApps {
+ enabled: boolean;
+ index: number;
+ restrictedApp: boolean;
+ title: string;
+ value: string;
+} \ No newline at end of file
diff --git a/portal-FE-common/src/app/shared/model/PortalAdmin.ts b/portal-FE-common/src/app/shared/model/PortalAdmin.ts
new file mode 100644
index 00000000..f826d45c
--- /dev/null
+++ b/portal-FE-common/src/app/shared/model/PortalAdmin.ts
@@ -0,0 +1,44 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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============================================
+ *
+ *
+ */
+export class PortalAdmin {
+ firstName: string;
+ lastName: string;
+ userId: number;
+ loginId: string;
+ orgUserId: string;
+} \ No newline at end of file
diff --git a/portal-FE-common/src/app/shared/model/Role.ts b/portal-FE-common/src/app/shared/model/Role.ts
new file mode 100644
index 00000000..5badf9e9
--- /dev/null
+++ b/portal-FE-common/src/app/shared/model/Role.ts
@@ -0,0 +1,51 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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 { RoleFunction } from './RoleFunction';
+
+export class Role {
+ name: string;
+ priority: any;
+ childRoles: ChildRoles[];
+ roleFunctions: RoleFunction[];
+}
+
+export class ChildRoles {
+ name: string;
+ priority: any;
+}
+
diff --git a/portal-FE-common/src/app/shared/model/RoleFunction.ts b/portal-FE-common/src/app/shared/model/RoleFunction.ts
new file mode 100644
index 00000000..68f055c0
--- /dev/null
+++ b/portal-FE-common/src/app/shared/model/RoleFunction.ts
@@ -0,0 +1,51 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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============================================
+ *
+ *
+ */
+export class RoleFunction {
+ type: string;
+ code: string;
+ action: string;
+ name: string;
+
+ //constructor
+ constructor(type: string, code: string, action: string, name: string) {
+ this.type = type;
+ this.code = code;
+ this.action = action;
+ this.name = name;
+ }
+} \ No newline at end of file
diff --git a/portal-FE-common/src/app/shared/model/UserAccessRoles.ts b/portal-FE-common/src/app/shared/model/UserAccessRoles.ts
new file mode 100644
index 00000000..ed180883
--- /dev/null
+++ b/portal-FE-common/src/app/shared/model/UserAccessRoles.ts
@@ -0,0 +1,44 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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============================================
+ *
+ *
+ */
+export class UserAccessRoles {
+ isApplied: boolean;
+ roleId: number;
+ roleName: string;
+ appId: number;
+ appName: string;
+} \ No newline at end of file
diff --git a/portal-FE-common/src/app/shared/model/UserAdminApps.ts b/portal-FE-common/src/app/shared/model/UserAdminApps.ts
new file mode 100644
index 00000000..1617beaf
--- /dev/null
+++ b/portal-FE-common/src/app/shared/model/UserAdminApps.ts
@@ -0,0 +1,42 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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============================================
+ *
+ *
+ */
+export class UserAdminApps {
+ id: number;
+ name: string;
+ restrictedApp: string;
+} \ No newline at end of file
diff --git a/portal-FE-common/src/app/shared/model/application-catalog.model.ts b/portal-FE-common/src/app/shared/model/application-catalog.model.ts
new file mode 100644
index 00000000..a0f368c4
--- /dev/null
+++ b/portal-FE-common/src/app/shared/model/application-catalog.model.ts
@@ -0,0 +1,49 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright © 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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============================================
+ *
+ *
+ */
+export interface IApplicationCatalog {
+ id: number;
+ name: string;
+ mlAppName: string;
+ imageUrl: string;
+ url: string;
+ restricted: boolean;
+ open: boolean;
+ access: boolean;
+ select: boolean;
+ pending: boolean;
+} \ No newline at end of file
diff --git a/portal-FE-common/src/app/shared/model/applications-onboarding/applications.ts b/portal-FE-common/src/app/shared/model/applications-onboarding/applications.ts
new file mode 100644
index 00000000..a0a93a22
--- /dev/null
+++ b/portal-FE-common/src/app/shared/model/applications-onboarding/applications.ts
@@ -0,0 +1,63 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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============================================
+ *
+ *
+ */
+
+export interface IApplications {
+ id ?: any;
+ name ?: any;
+ imageUrl ?: any;
+ imageLink ?: any;
+ description ?: any;
+ notes ?: any;
+ url ?: any
+ alternateUrl ?: any;
+ restUrl ?: any;
+ isOpen ?: any;
+ isEnabled ?: any;
+ motsId ?: any;
+ myLoginsAppName ?: any;
+ myLoginsAppOwner ?: any;
+ username ?: any;
+ appPassword ?: any;
+ thumbnail ?: any;
+ uebTopicName ?: any;
+ uebKey ?: any;
+ uebSecret ?: any;
+ restrictedApp ?: any;
+ isCentralAuth ?: any;
+ nameSpace ?: any
+} \ No newline at end of file
diff --git a/portal-FE-common/src/app/shared/model/dynamic-component-manifest/dynamic-component-manifest.ts b/portal-FE-common/src/app/shared/model/dynamic-component-manifest/dynamic-component-manifest.ts
new file mode 100644
index 00000000..176e16eb
--- /dev/null
+++ b/portal-FE-common/src/app/shared/model/dynamic-component-manifest/dynamic-component-manifest.ts
@@ -0,0 +1,43 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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============================================
+ *
+ *
+ */
+
+export interface IDynamicComponentManifest {
+ componentId: string;
+ path: string;
+ loadChildren: string;
+} \ No newline at end of file
diff --git a/portal-FE-common/src/app/shared/model/global-search-item.model.ts b/portal-FE-common/src/app/shared/model/global-search-item.model.ts
new file mode 100644
index 00000000..626a8d2d
--- /dev/null
+++ b/portal-FE-common/src/app/shared/model/global-search-item.model.ts
@@ -0,0 +1,45 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright © 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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============================================
+ *
+ *
+ */
+export interface GlobalSearchItem {
+ rowId: number;
+ category: string;
+ name: string;
+ target: string;
+ uuid: boolean;
+
+}
diff --git a/portal-FE-common/src/app/shared/model/index.ts b/portal-FE-common/src/app/shared/model/index.ts
new file mode 100644
index 00000000..f8572b8c
--- /dev/null
+++ b/portal-FE-common/src/app/shared/model/index.ts
@@ -0,0 +1,44 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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============================================
+ *
+ *
+ */
+export * from './Admins';
+export * from './AllApps'
+export * from './PortalAdmin';
+export * from './UserAdminApps';
+export * from './UserAccessRoles';
+export * from './Role';
+export * from './RoleFunction'; \ No newline at end of file
diff --git a/portal-FE-common/src/app/shared/model/widget-catalog.model.ts b/portal-FE-common/src/app/shared/model/widget-catalog.model.ts
new file mode 100644
index 00000000..f30a4e3c
--- /dev/null
+++ b/portal-FE-common/src/app/shared/model/widget-catalog.model.ts
@@ -0,0 +1,44 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal SDK
+ * ===================================================================
+ * Copyright © 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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============================================
+ *
+ *
+ */
+export interface IWidgetCatalog {
+ widgetId: string;
+ widgetName: String;
+ widgetStatus: string;
+ imageLink: string;
+ select: boolean;
+} \ No newline at end of file
diff --git a/portal-FE-common/src/app/shared/model/widget-onboarding/widget.ts b/portal-FE-common/src/app/shared/model/widget-onboarding/widget.ts
new file mode 100644
index 00000000..ba1842f5
--- /dev/null
+++ b/portal-FE-common/src/app/shared/model/widget-onboarding/widget.ts
@@ -0,0 +1,54 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal SDK
+ * ===================================================================
+ * Copyright © 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified?: any; all software contained herein is licensed
+ * under the Apache License?: any; Version 2.0 (the "License");
+ * you may not use this software 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?: any; software
+ * distributed under the License is distributed on an "AS IS" BASIS?: any;
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND?: any; either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Unless otherwise specified?: any; all documentation contained herein is licensed
+ * under the Creative Commons License?: any; Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing?: any; documentation
+ * distributed under the License is distributed on an "AS IS" BASIS?: any;
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND?: any; either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END============================================
+ *
+ *
+ */
+export interface IWidget {
+ id ?: any;
+ name ?: any;
+ desc ?: any;
+ fileLocation ?: any;
+ allowAllUser ?: any;
+ serviceId ?: any;
+ serviceURL ?: any;
+ sortOrder ?: any;
+ statusCode ?: any;
+ widgetRoles ?: any;
+ appContent ?: any;
+ appName ?: any
+ file ?: any;
+ allUser ?: boolean;
+ saving ?: any
+} \ No newline at end of file
diff --git a/portal-FE-common/src/app/shared/pipes/application-pipes.module.ts b/portal-FE-common/src/app/shared/pipes/application-pipes.module.ts
new file mode 100644
index 00000000..3e19fa2b
--- /dev/null
+++ b/portal-FE-common/src/app/shared/pipes/application-pipes.module.ts
@@ -0,0 +1,57 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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 { ElipsisPipe } from "./elipsis/elipsis.pipe";
+import { NgModule } from "@angular/core";
+
+// application-pipes.module.ts
+// other imports
+
+
+@NgModule({
+ imports: [
+ // dep modules
+ ],
+ declarations: [
+ ElipsisPipe
+ ],
+ exports: [
+ ElipsisPipe
+ ]
+})
+export class ApplicationPipesModule {} \ No newline at end of file
diff --git a/portal-FE-common/src/app/shared/pipes/elipsis/elipsis.pipe.spec.ts b/portal-FE-common/src/app/shared/pipes/elipsis/elipsis.pipe.spec.ts
new file mode 100644
index 00000000..22a477d3
--- /dev/null
+++ b/portal-FE-common/src/app/shared/pipes/elipsis/elipsis.pipe.spec.ts
@@ -0,0 +1,45 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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 { ElipsisPipe } from './elipsis.pipe';
+
+describe('ElipsisPipe', () => {
+ it('create an instance', () => {
+ const pipe = new ElipsisPipe();
+ expect(pipe).toBeTruthy();
+ });
+});
diff --git a/portal-FE-common/src/app/shared/pipes/elipsis/elipsis.pipe.ts b/portal-FE-common/src/app/shared/pipes/elipsis/elipsis.pipe.ts
new file mode 100644
index 00000000..d749626a
--- /dev/null
+++ b/portal-FE-common/src/app/shared/pipes/elipsis/elipsis.pipe.ts
@@ -0,0 +1,61 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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 { Pipe, PipeTransform } from '@angular/core';
+
+@Pipe({
+ name: 'elipsis'
+})
+export class ElipsisPipe implements PipeTransform {
+
+ transform(value: any, args: string): any {
+ if (!value) {
+ return value;
+ }
+
+ var noOfChar = parseInt(args);
+
+ if (!noOfChar || value.length <= noOfChar) {
+ return value;
+ }
+
+ value = value.substr(0, noOfChar);
+
+ return value + '...';
+ }
+
+}
diff --git a/portal-FE-common/src/app/shared/plugin/dynamic-widget/dynamic-widget.module.ts b/portal-FE-common/src/app/shared/plugin/dynamic-widget/dynamic-widget.module.ts
new file mode 100644
index 00000000..baab502d
--- /dev/null
+++ b/portal-FE-common/src/app/shared/plugin/dynamic-widget/dynamic-widget.module.ts
@@ -0,0 +1,57 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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 { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { ListWidgetComponent } from './list-widget/list-widget.component';
+import { HttpClientModule } from '@angular/common/http';
+import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
+
+@NgModule({
+ declarations: [ListWidgetComponent],
+ imports: [
+ CommonModule,
+ HttpClientModule
+ ],
+ exports: [ListWidgetComponent],
+ providers: [HttpClient],
+ entryComponents: [ListWidgetComponent]
+})
+export class DynamicWidgetModule {
+ static entry = ListWidgetComponent;
+}
diff --git a/portal-FE-common/src/app/shared/plugin/dynamic-widget/list-widget/list-widget.component.html b/portal-FE-common/src/app/shared/plugin/dynamic-widget/list-widget/list-widget.component.html
new file mode 100644
index 00000000..82f4f35d
--- /dev/null
+++ b/portal-FE-common/src/app/shared/plugin/dynamic-widget/list-widget/list-widget.component.html
@@ -0,0 +1,58 @@
+<!--
+ ============LICENSE_START==========================================
+ ONAP Portal
+ ===================================================================
+ Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ ===================================================================
+
+ Unless otherwise specified, all software contained herein is licensed
+ under the Apache License, Version 2.0 (the "License");
+ you may not use this software 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.
+
+ Unless otherwise specified, all documentation contained herein is licensed
+ under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ you may not use this documentation except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://creativecommons.org/licenses/by/4.0/
+
+ Unless required by applicable law or agreed to in writing, documentation
+ 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 id="widget-news" class="widget-news-main">
+ <div onap-gridster-item-body class="information-section-gridsterContent">
+ <div class="resources">
+ <ul *ngIf="newsData && newsData.length!=0">
+ <li *ngFor="let item of newsData"><a href="{{item.href}}" target="_blank">{{item.title}}</a></li>
+ </ul>
+ <div *ngIf="newsData && newsData.length!=0">
+ <div class="activity-error-container"
+ style="background: rgb(255, 255, 255); overflow: hidden !important; width: 100%;">
+ <div class="activity-error-block">
+ <i class="icon-information full-linear-icon-information" style="margin-left: 125px; font-size: 90px"></i>
+ <br>
+ <div class="activity-error-msg1">There's currently no
+ news available.</div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
diff --git a/portal-FE-common/src/app/shared/plugin/dynamic-widget/list-widget/list-widget.component.scss b/portal-FE-common/src/app/shared/plugin/dynamic-widget/list-widget/list-widget.component.scss
new file mode 100644
index 00000000..7a773398
--- /dev/null
+++ b/portal-FE-common/src/app/shared/plugin/dynamic-widget/list-widget/list-widget.component.scss
@@ -0,0 +1,37 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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============================================
+ *
+ *
+ */ \ No newline at end of file
diff --git a/portal-FE-common/src/app/shared/plugin/dynamic-widget/list-widget/list-widget.component.spec.ts b/portal-FE-common/src/app/shared/plugin/dynamic-widget/list-widget/list-widget.component.spec.ts
new file mode 100644
index 00000000..d7991933
--- /dev/null
+++ b/portal-FE-common/src/app/shared/plugin/dynamic-widget/list-widget/list-widget.component.spec.ts
@@ -0,0 +1,63 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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 { ListWidgetComponent } from './list-widget.component';
+
+describe('ListWidgetComponent', () => {
+ let component: ListWidgetComponent;
+ let fixture: ComponentFixture<ListWidgetComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ ListWidgetComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(ListWidgetComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/portal-FE-common/src/app/shared/plugin/dynamic-widget/list-widget/list-widget.component.ts b/portal-FE-common/src/app/shared/plugin/dynamic-widget/list-widget/list-widget.component.ts
new file mode 100644
index 00000000..1d28026f
--- /dev/null
+++ b/portal-FE-common/src/app/shared/plugin/dynamic-widget/list-widget/list-widget.component.ts
@@ -0,0 +1,61 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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 { Component, OnInit } from '@angular/core';
+import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
+import { Observable } from 'rxjs';
+
+@Component({
+ selector: 'app-list-widget',
+ templateUrl: './list-widget.component.html',
+ styleUrls: ['./list-widget.component.scss']
+})
+export class ListWidgetComponent implements OnInit {
+ newsData: any[];
+
+ constructor(private api: HttpClient) { }
+
+ ngOnInit() {
+ this.getNewsWidgetCatalog();
+ }
+
+ getNewsWidgetCatalog() {
+ //console.log("getNewsWidgetCatalog called");
+ }
+
+}
diff --git a/portal-FE-common/src/app/shared/plugin/plugin-loader/client-plugin-loader.service.ts b/portal-FE-common/src/app/shared/plugin/plugin-loader/client-plugin-loader.service.ts
new file mode 100644
index 00000000..2666a523
--- /dev/null
+++ b/portal-FE-common/src/app/shared/plugin/plugin-loader/client-plugin-loader.service.ts
@@ -0,0 +1,86 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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 { Injectable, NgModuleFactory } from '@angular/core';
+import { PluginLoaderService } from './plugin-loader.service';
+import { PLUGIN_EXTERNALS_MAP } from './plugin-externals';
+import { PluginsConfigProvider } from '../plugins-config.provider';
+
+const SystemJs = window.System;
+
+@Injectable({
+ providedIn: 'root',
+})
+export class ClientPluginLoaderService extends PluginLoaderService {
+ constructor(private configProvider: PluginsConfigProvider) {
+ super();
+ configProvider.loadConfig()
+ .toPromise()
+ .then(config => {
+ configProvider.config = config;
+ console.log(config);
+ });
+ }
+
+ provideExternals() {
+ Object.keys(PLUGIN_EXTERNALS_MAP).forEach(externalKey =>
+ window.define(externalKey, [], () => PLUGIN_EXTERNALS_MAP[externalKey])
+ );
+ }
+
+ load<T>(pluginName): Promise<NgModuleFactory<T>> {
+
+ const { config } = this.configProvider;
+ if (!config[pluginName]) {
+ throw Error(`Can't find appropriate plugin`);
+ }
+
+ const depsPromises = (config[pluginName].deps || []).map(dep => {
+ return SystemJs.import(window['base'] + config[dep].path).then(m => {
+ window['define'](dep, [], () => m.default);
+ });
+ });
+
+ return Promise.all(depsPromises).then(() => {
+
+ return SystemJs.import(window['base'] + config[pluginName].path).then(
+ module => module.default.default
+ );
+ });
+ }
+}
diff --git a/portal-FE-common/src/app/shared/plugin/plugin-loader/plugin-externals.ts b/portal-FE-common/src/app/shared/plugin/plugin-loader/plugin-externals.ts
new file mode 100644
index 00000000..3bd5a133
--- /dev/null
+++ b/portal-FE-common/src/app/shared/plugin/plugin-loader/plugin-externals.ts
@@ -0,0 +1,53 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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 * as core from '@angular/core';
+import * as common from '@angular/common';
+import * as forms from '@angular/forms';
+import * as router from '@angular/router';
+import * as rxjs from 'rxjs';
+import * as tslib from 'tslib';
+
+export const PLUGIN_EXTERNALS_MAP = {
+ 'ng.core': core,
+ 'ng.common': common,
+ 'ng.forms': forms,
+ 'ng.router': router,
+ rxjs,
+ tslib
+};
diff --git a/portal-FE-common/src/app/shared/plugin/plugin-loader/plugin-loader.service.ts b/portal-FE-common/src/app/shared/plugin/plugin-loader/plugin-loader.service.ts
new file mode 100644
index 00000000..1d79b65f
--- /dev/null
+++ b/portal-FE-common/src/app/shared/plugin/plugin-loader/plugin-loader.service.ts
@@ -0,0 +1,49 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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 { NgModuleFactory } from '@angular/core';
+
+export abstract class PluginLoaderService {
+ protected constructor() {
+ this.provideExternals();
+ }
+
+ abstract provideExternals(): void;
+
+ abstract load<T>(pluginName): Promise<NgModuleFactory<T>>;
+}
diff --git a/portal-FE-common/src/app/shared/plugin/plugin.component.html b/portal-FE-common/src/app/shared/plugin/plugin.component.html
new file mode 100644
index 00000000..e2aeaf18
--- /dev/null
+++ b/portal-FE-common/src/app/shared/plugin/plugin.component.html
@@ -0,0 +1,48 @@
+<!--
+ ============LICENSE_START==========================================
+ ONAP Portal
+ ===================================================================
+ Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ ===================================================================
+
+ Unless otherwise specified, all software contained herein is licensed
+ under the Apache License, Version 2.0 (the "License");
+ you may not use this software 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.
+
+ Unless otherwise specified, all documentation contained herein is licensed
+ under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ you may not use this documentation except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://creativecommons.org/licenses/by/4.0/
+
+ Unless required by applicable law or agreed to in writing, documentation
+ 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============================================
+
+
+ -->
+
+<p> plugin works</p>
+<button (click)="loadPlugin('listWidgetPlugin')">Load News</button>
+<div>
+ <div class="plugins">
+ <ng-template #targetRef></ng-template>
+ </div>
+</div>
+<!--
+<app-list-widget></app-list-widget>
+-->
diff --git a/portal-FE-common/src/app/shared/plugin/plugin.component.scss b/portal-FE-common/src/app/shared/plugin/plugin.component.scss
new file mode 100644
index 00000000..fa57ecbf
--- /dev/null
+++ b/portal-FE-common/src/app/shared/plugin/plugin.component.scss
@@ -0,0 +1,38 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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============================================
+ *
+ *
+ */
+ \ No newline at end of file
diff --git a/portal-FE-common/src/app/shared/plugin/plugin.component.spec.ts b/portal-FE-common/src/app/shared/plugin/plugin.component.spec.ts
new file mode 100644
index 00000000..cc5810c1
--- /dev/null
+++ b/portal-FE-common/src/app/shared/plugin/plugin.component.spec.ts
@@ -0,0 +1,63 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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 { PluginComponent } from './plugin.component';
+
+describe('PluginComponent', () => {
+ let component: PluginComponent;
+ let fixture: ComponentFixture<PluginComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ PluginComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(PluginComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/portal-FE-common/src/app/shared/plugin/plugin.component.ts b/portal-FE-common/src/app/shared/plugin/plugin.component.ts
new file mode 100644
index 00000000..b64ea7c9
--- /dev/null
+++ b/portal-FE-common/src/app/shared/plugin/plugin.component.ts
@@ -0,0 +1,75 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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 {
+ Component,
+ Injector,
+ OnInit,
+ ViewChild,
+ ViewContainerRef
+} from '@angular/core';
+import { PluginLoaderService } from './plugin-loader/plugin-loader.service';
+
+@Component({
+ selector: 'app-plugin',
+ templateUrl: './plugin.component.html',
+ styleUrls: ['./plugin.component.scss']
+})
+export class PluginComponent implements OnInit {
+ @ViewChild('targetRef', { read: ViewContainerRef }) vcRef: ViewContainerRef;
+
+ constructor(
+ private injector: Injector,
+ private pluginLoader: PluginLoaderService
+ ) {}
+
+ ngOnInit() {
+ //this.loadPlugin('plugin1');
+ }
+
+ loadPlugin(pluginName: string) {
+ this.pluginLoader.load(pluginName).then(moduleFactory => {
+ const moduleRef = moduleFactory.create(this.injector);
+ const entryComponent = (moduleFactory.moduleType as any).entry;
+ const compFactory = moduleRef.componentFactoryResolver.resolveComponentFactory(
+ entryComponent
+ );
+ this.vcRef.createComponent(compFactory);
+ });
+ }
+}
diff --git a/portal-FE-common/src/app/shared/plugin/plugin.module.ts b/portal-FE-common/src/app/shared/plugin/plugin.module.ts
new file mode 100644
index 00000000..de366627
--- /dev/null
+++ b/portal-FE-common/src/app/shared/plugin/plugin.module.ts
@@ -0,0 +1,89 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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 {
+ BrowserModule,
+ BrowserTransferStateModule, TransferState
+} from '@angular/platform-browser';
+import { APP_INITIALIZER, NgModule, APP_BOOTSTRAP_LISTENER } from '@angular/core';
+import { HttpClientModule } from '@angular/common/http';
+import { DynamicWidgetModule } from './dynamic-widget/dynamic-widget.module';
+
+
+
+import { ClientPluginLoaderService } from './plugin-loader/client-plugin-loader.service';
+import { PluginsConfigProvider } from './plugins-config.provider';
+import { TransferStateService } from './transfer-state.service';
+import { PluginLoaderService } from './plugin-loader/plugin-loader.service';
+import { PluginComponent } from './plugin.component';
+import { ListWidgetComponent } from './dynamic-widget/list-widget/list-widget.component';
+
+import { config } from 'rxjs';
+
+@NgModule({
+ declarations: [PluginComponent],
+ imports: [
+ HttpClientModule,
+ //BrowserModule.withServerTransition({ appId: 'serverApp' }),
+ BrowserTransferStateModule
+ ],
+ providers: [
+ { provide: PluginLoaderService, useClass: ClientPluginLoaderService },
+ //PluginsConfigProvider,
+ TransferStateService,
+ {
+ provide: APP_BOOTSTRAP_LISTENER,
+ useFactory: (provider: PluginsConfigProvider) => () =>
+ provider
+ .loadConfig()
+ .toPromise()
+ .then(config => {
+ provider.config = config;
+ console.log(config);
+ }
+ ),
+ multi: true,
+ deps: [PluginsConfigProvider]
+ }
+ ],
+ bootstrap: [PluginComponent],
+ exports: [PluginComponent]
+})
+export class PluginModule {
+ constructor(transferStateService: TransferStateService) {}
+}
diff --git a/portal-FE-common/src/app/shared/plugin/plugins-config.provider.ts b/portal-FE-common/src/app/shared/plugin/plugins-config.provider.ts
new file mode 100644
index 00000000..8c2a2e7d
--- /dev/null
+++ b/portal-FE-common/src/app/shared/plugin/plugins-config.provider.ts
@@ -0,0 +1,75 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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 { Inject, Injectable, Optional, PLATFORM_ID } from '@angular/core';
+import { HttpClient } from '@angular/common/http';
+import { tap } from 'rxjs/operators';
+import { preserveServerState } from './transfer-state.service';
+import { isPlatformBrowser } from '@angular/common';
+
+interface PluginsConfig {
+ [key: string]: {
+ name: string;
+ path: string;
+ deps: string[];
+ };
+}
+
+@Injectable({
+ providedIn: 'root',
+})
+export class PluginsConfigProvider {
+ config: PluginsConfig;
+
+ constructor(
+ private http: HttpClient,
+ @Inject(PLATFORM_ID) private platformId: {},
+ @Inject('APP_BASE_URL') @Optional() private readonly baseUrl: string
+ ) {
+ if (isPlatformBrowser(platformId)) {
+ this.baseUrl = document.location.origin;
+ }
+ }
+
+ @preserveServerState('PLUGIN_CONFIGS')
+ loadConfig() {
+ return this.http.get<PluginsConfig>(
+ `assets/plugins-config.json`
+ );
+ }
+}
diff --git a/portal-FE-common/src/app/shared/plugin/transfer-state.service.ts b/portal-FE-common/src/app/shared/plugin/transfer-state.service.ts
new file mode 100644
index 00000000..e42abcb8
--- /dev/null
+++ b/portal-FE-common/src/app/shared/plugin/transfer-state.service.ts
@@ -0,0 +1,85 @@
+/*-
+ * ============LICENSE_START==========================================
+ * ONAP Portal
+ * ===================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * 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 { Inject, Injectable, PLATFORM_ID } from '@angular/core';
+import { makeStateKey, TransferState } from '@angular/platform-browser';
+import { isPlatformBrowser, isPlatformServer } from '@angular/common';
+import { of } from 'rxjs';
+import { tap } from 'rxjs/operators';
+
+let isBrowser: boolean;
+let isServer: boolean;
+let transferState: TransferState;
+
+@Injectable({
+ providedIn: 'root'
+})
+export class TransferStateService {
+ constructor(
+ private state: TransferState,
+ @Inject(PLATFORM_ID) private platformId: any
+ ) {
+ transferState = state;
+ isBrowser = isPlatformBrowser(this.platformId);
+ isServer = isPlatformServer(this.platformId);
+ }
+}
+
+export const preserveServerState = (
+ keyName: string,
+ emptyResult: any = null
+) => {
+ const key = makeStateKey(keyName);
+ return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {
+ const method = descriptor.value;
+ descriptor.value = function() {
+ if (isBrowser && transferState.hasKey(key)) {
+ const state = transferState.get(key, emptyResult);
+ return of(state);
+ }
+
+ return method.apply(this, arguments).pipe(
+ tap(res => {
+ // if (isServer) {
+ transferState.set(key, res);
+ // }
+ })
+ );
+ };
+ };
+};