diff options
author | Sudarshan Kumar <sudarshan.kumar@att.com> | 2019-12-06 22:50:16 +0530 |
---|---|---|
committer | Sudarshan Kumar <sudarshan.kumar@att.com> | 2019-12-10 21:41:01 +0530 |
commit | f446cfb57f14004d6b34b137f8fa9802f6fdbdf6 (patch) | |
tree | 3470b3a5991cd5a5d281dbbca39e449fb3648f0a /portal-FE-common/src/app/layout | |
parent | ffd9af970318c1f5a0bad46d7aad5d4611414aae (diff) |
Added portal-FE-common - angular upgrade code
Added Layout Component- Footeter, global-search, header, header-menu, search-user, sidebar, tabbar, userbar and also added Account Onbaording changes
Issue-ID: PORTAL-795
Change-Id: I815add150ba12c868c1b0f80f3dfcdf4ea804d70
Signed-off-by: Sudarshan Kumar <sudarshan.kumar@att.com>
Diffstat (limited to 'portal-FE-common/src/app/layout')
39 files changed, 3300 insertions, 0 deletions
diff --git a/portal-FE-common/src/app/layout/components/footer/footer.component.html b/portal-FE-common/src/app/layout/components/footer/footer.component.html new file mode 100644 index 00000000..d9fc9903 --- /dev/null +++ b/portal-FE-common/src/app/layout/components/footer/footer.component.html @@ -0,0 +1,47 @@ +<!-- + ============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============================================ + + + --> +<footer> + <div id="footer-text" class="footerText"> + <p class="copyright-text"> + <a class="footer-link" href="//www.att.com/gen/privacy-policy?pid=2587" target="_blank"> + © 2018 AT&T Intellectual Property.</a> All rights reserved. AT&T, the AT&T Globe logo and all other AT&T marks + contained herein are trademarks of AT&T intellectual property and/or AT&T affiliated companies. + ECOMP Portal Version: {{buildVersion}} + <h2 style="color:white; text-align: center;" class="logo-title" id="at&t"> <img src="assets/images/global.logo"> AT&T</h2> + </div> +</footer>
\ No newline at end of file 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..acc7f1ba --- /dev/null +++ b/portal-FE-common/src/app/layout/components/footer/footer.component.scss @@ -0,0 +1,52 @@ +/* + * ============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============================================ + * + * + */ +$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..2ca6c454 --- /dev/null +++ b/portal-FE-common/src/app/layout/components/footer/footer.component.spec.ts @@ -0,0 +1,25 @@ +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..9b5cc8f6 --- /dev/null +++ b/portal-FE-common/src/app/layout/components/footer/footer.component.ts @@ -0,0 +1,27 @@ +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/global-search/global-search.component.html b/portal-FE-common/src/app/layout/components/global-search/global-search.component.html new file mode 100644 index 00000000..ff5473be --- /dev/null +++ b/portal-FE-common/src/app/layout/components/global-search/global-search.component.html @@ -0,0 +1,109 @@ +<!-- + ============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="search-div" (clickOutside)="clickOutSide($event)"> + <div class="notification-div"> + <div class="form-field form-field__small"> + <div class="search-input"> + <input id="mainSearchText" style="border-radius:0.25rem;" type="text" (keypress)="searchDialogToggle($event)" + placeholder="What are you looking for?" class="form-field form-field__small" /> + </div> + <span class="icon-search-span"> <i class="icon-search"> </i> + </span> + + </div> + </div> +</div> +<div *ngIf="searchResDialog" class="search-res-dialog"> + <div id="reg-header-snippet"> + + <div tabindex="0" id="reg-searchPop-id"> + <div id="contentVertical" att-scrollbar="y"> + <ul class="searchUl"> + <li><a class="icon-tiles"></a> <a id="search-app-title" (click)="goToUrl(item)" + class="searchLiHeader">Applications:</a> + </li> + <li *ngFor="let item of items?.application"><a + id="search-app-item-{{item.name.split(' ').join('-')}}-{{$index}}" (click)="goToUrl(item)" + class="searchLiItems">{{item.name}}</a> + </li> + </ul> + + <ul class="searchUl"> + <li><a class="icon-tiles-small"></a> <a id="seach-functional-menu-title" (click)="goToUrl(item)" + class="searchLiHeader">Functional Menus:</a></li> + <li *ngFor="let item of items?.menu"><a + id="search-functional-menu-item-{{item.name.split(' ').join('-')}}-{{$index}}" (click)="goToUrl(item)" + class="searchLiItems">{{item.name}}</a> + </li> + </ul> + + + <ul class="searchUl"> + <li><a class="full-linear-icon-person search-li"></a> <a id="search-user-title" (click)="goToUrl(item)" + class="searchLiHeader">Users:</a></li> + <li *ngFor="let item of items?.user"><a id="search-user-item-{{item.name.split(' ').join('-')}}-{{$index}}" + href="qto://talk/{{item.target}}" class="searchLiItems">{{item.name}}</a> + + </li> + </ul> + + <ul class="searchUl"> + <li><a class="full-linear-icon-person search-li"></a> <a id="search-widgets-title" (click)="goToUrl(item)" + class="searchLiHeader">Widgets:</a></li> + <li *ngFor="let item of items?.widget"><a + id="search-widgets-item-{{item.name.split(' ').join('-')}}-{{$index}}" href="widgetCatalog" + class="searchLiHeader">{{item.name}}</a></li> + </ul> + + <ul class="searchUl"> + <li><a class="full-linear-icon-internet search-li"></a> <a id="search-intranet" + (click)="goToUrl(item, 'intra')" class="searchLiHeader" style="cursor: pointer;">Click to search + Intranet <span class="icon-arrow-right"></span> + </a></li> + </ul> + + <ul class="searchUl"> + <li><a class="full-linear-icon-internet search-li"></a> <a id="search-extranet" + (click)="goToUrl(item, 'extra')" class="searchLiHeader" style="cursor: pointer;">Click to search + Extranet <span class="icon-arrow-right"></span></a></li> + </ul> + + </div> + </div> + </div> +</div>
\ No newline at end of file diff --git a/portal-FE-common/src/app/layout/components/global-search/global-search.component.scss b/portal-FE-common/src/app/layout/components/global-search/global-search.component.scss new file mode 100644 index 00000000..70f1b34c --- /dev/null +++ b/portal-FE-common/src/app/layout/components/global-search/global-search.component.scss @@ -0,0 +1,74 @@ +/*- + * ============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============================================ + * + * + */ + + .search-div { + margin-bottom: -14px; + } + + .search-res-dialog{ + position: fixed; + background: white; + box-shadow: rgba(0, 0, 0, 0.247059) 0px 5px 6px 0px; + top: 2.5em; + border-radius: 0.25rem; + padding: 20px; + opacity: 1; + z-index: 1; + } + .searchUl { + list-style: none; + border-bottom: 1px solid #bbb; + padding-bottom: 20px; + padding-left: 4px; + } + .searchLiHeader { + font-weight: bold; + color: #0574ac; + font-size: 16px; + padding-bottom: 10px; + line-height: 1.5; + font-family: Omnes-ECOMP-W02,Arial; + + } + .searchLiItems{ + cursor: pointer; + font-weight: normal; + font-size: 12px; + color: #444444; + font-family: Omnes-ECOMP-W02,Arial; + }
\ No newline at end of file diff --git a/portal-FE-common/src/app/layout/components/global-search/global-search.component.spec.ts b/portal-FE-common/src/app/layout/components/global-search/global-search.component.spec.ts new file mode 100644 index 00000000..c3771377 --- /dev/null +++ b/portal-FE-common/src/app/layout/components/global-search/global-search.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 { GlobalSearchComponent } from './global-search.component'; + +describe('GlobalSearchComponent', () => { + let component: GlobalSearchComponent; + let fixture: ComponentFixture<GlobalSearchComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ GlobalSearchComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(GlobalSearchComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/portal-FE-common/src/app/layout/components/global-search/global-search.component.ts b/portal-FE-common/src/app/layout/components/global-search/global-search.component.ts new file mode 100644 index 00000000..0f9a8930 --- /dev/null +++ b/portal-FE-common/src/app/layout/components/global-search/global-search.component.ts @@ -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============================================ + * + * + */ +import { Component, OnInit, Output, EventEmitter } from '@angular/core'; +import { GlobalSearchService } from 'src/app/shared/services/global-search/global-search.service'; +import { GlobalSearchItem } from 'src/app/shared/model/global-search-item.model'; +import * as $ from 'jquery'; +import { AddTabFunctionService } from 'src/app/shared/services/tab/add-tab-function.service'; +import { Router } from '@angular/router'; + +@Component({ + selector: 'app-global-search', + templateUrl: './global-search.component.html', + styleUrls: ['./global-search.component.scss'] +}) +export class GlobalSearchComponent implements OnInit { + searchResDialog: boolean = false; + items: any; + searchString: string; + constructor(private globalSearchService: GlobalSearchService, private addTabFuntionService: AddTabFunctionService, private router: Router) { } + + ngOnInit() { + } + + showHideSearchSnippet() { + setTimeout(() => { + $('#mainSearchSnippet').click(); + }, 1000); + setTimeout(() => { + $('mainSearchText').focus(); + }, 1000); + } + + mainSearchEvent = $('#mainSearchDiv').keyup((event) => { + if (event.keyCode == 13) { + + this.getSearchResult(<string><any>$('#mainSearchText').val()); + + // opens the popup + var popupDomObj = $("[content='searchSnippet.html']"); + if (popupDomObj.length == 0) { + this.showHideSearchSnippet(); + } else { + $('#mainSearchSnippet').click(); + this.showHideSearchSnippet(); + } + + + + } + }); + + clickOutSide(event: any) { + + this.searchResDialog = false; + + } + searchDialogToggle(event: any) { + if (event.keyCode == 13) { + this.searchResDialog = true; + this.searchString = <string><any>$('#mainSearchText').val(); + this.getSearchResult(<string><any>$('#mainSearchText').val()); + } + } + + getSearchResult(searchString: string) { + //console.log("getSearch Result"); + this.globalSearchService.getSearchResults(searchString).subscribe(data => { + //console.log("Response data" + data); + this.items = data.response; + //console.log("search result data" + JSON.stringify(data)); + + }, error => { + console.log('getSearchResult Error Object' + error); + }); + }; + goToUrl(item: any, type?: any) { + //console.log('check goto'); + //var a = { 'test1': 'value1', 'test2': 'value3', 'test3': 'value2' }; + if (type == 'intra') { + + var intraSearcLink = "http://insider.web.att.com/s/s.dll?spage=search%2FVeritySearchResult.htm&QueryText="; + var intraSpecSearcLink = intraSearcLink + encodeURIComponent(this.searchString); + window.open(intraSpecSearcLink, '_blank'); + + } else if (type == 'extra') { + var extraSearcLink = "https://www.att.com/global-search/search.jsp?q="; + var extraSpecSearcLink = extraSearcLink + encodeURIComponent(this.searchString); + window.open(extraSpecSearcLink, '_blank'); + } + let url = item.target; + let restrictedApp = item.uuid; + let getAccessState = "getAccess" + console.log("item.target " + item.target + "item.uuid " + item.uuid); + if (!url) { + this.router.navigate(['/' + getAccessState]); + //$log.info('No url found for this application, doing nothing..'); + return; + } + if (!restrictedApp) { + window.open(url, '_blank'); + } else { + if (item.url == "root.access") { + this.router.navigate(['/' + item.url]); + var tabContent = { id: new Date(), title: 'Home', url: url }; + // $cookies.putObject('addTab', tabContent ); + this.addTabFuntionService.filter(tabContent); + } else { + var tabContentCtrl = { id: new Date(), title: item.name, url: url }; + this.addTabFuntionService.filter(tabContentCtrl); + } + } + + } + +} 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..b1d4d835 --- /dev/null +++ b/portal-FE-common/src/app/layout/components/header-menu/header-menu.component.html @@ -0,0 +1,128 @@ +<!-- + ============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="container" style="width: 100%;" (clickOutside)="clickOutSide($event)"> + <!-- First Level menu --> + <div id="megaMenu-{{item.text.split(' ').join('-')}}" + *ngFor="let item of megaMenuDataObject;let megaMenuIndex = index" (mousedown)="loadFirstLevel(megaMenuIndex)" + role="presentation" class="header-menu-item-div"><a href="javascript:void(0);" id="parentmenu-tabs" role="menuitem" + class="header-menu-item-link">{{item.text}}<b class="caret"></b><span class="sr-only"></span></a> + + <div class="header-secondlevel-menu" *ngIf="item.active_yn=='Y' && hideMenus[megaMenuIndex]"> + <ul class="header-secondary" role="menu"> + <!-- Second Level menu --> + <li class="header-menu-item-li" id="subItem-{{i.text.split(' ').join('-')}}" + *ngFor="let i of item.children;let secondLevelIndex = index" + (mousemove)="hideThirdLevelMenu(megaMenuIndex,secondLevelIndex)" role="presentation"> + <!-- Favorites --> + + <div *ngIf="i.text=='Favorites'"> + <a href="javascript:void(0);" class="menu__item" role="menuitem">{{i.text}}</a> + <i id="favorite-star" data-size="large" class="icon-star favorites-icon-active"></i> + <div class="header-columns-div" *ngIf="hideSecondLevelMenus[megaMenuIndex][secondLevelIndex]"> + <div class="header-tertiary-wrapper" id="header-favorites"> + <ul class="header-tertiary" role="menu"> + <li role="presentation"> + <div *ngFor="let subItem of (favoritesMenuItems ? favoritesMenuItems : [])" + id="favoritesMenuItems-{{subItem.text.split(' ').join('-')}}"> + <div class="fav-links"> + <i id="favorite-selector-favorites-list" class="icon-star favorites-icon-active" + (click)="removeAsFavoriteItem($event, subItem.menuId)" + (mousedown)="removeAsFavoriteItem($event, subItem.menuId)"> + </i> <a id="favorites-list" (click)="goToUrl(subItem)">{{subItem.text}}</a> + </div> + </div> + + <div id="favorites-empty" class="favorites-window-empty" *ngIf="emptyFavorites"> + <p id="p-no-favs-icon" class="no-fav-icon"> + <span class="icon-star"></span> + </p> + <p id="p-no-favs" class="largeText">{{'No + Favorites'}}</p> + <p id="p-no-favs-desc" class="normal">{{'Add your + favorite items for quick access'}}.</p> + </div> + </li> + </ul> + </div> + </div> + </div> <!-- Support or Help --> + <div *ngIf="item.text=='Support' || item.text=='Help'" id="second-level-menus-help"> + <a id="second-level-menus-{{i.text.split(' ').join('-')}}-help" href="javascript:void(0);" + (click)="goToUrl(i);auditLog(i,'Support')" class="menu__item" role="menuitem">{{i.text}}</a> + </div> <!-- Others --> + <div *ngIf="i.text!='Favorites' && (item.text!='Support' && item.text!='Help')"> + <a href="javascript:void(0);" class="menu__item" role="menuitem">{{i.text}}</a> + <div class="header-thirdlevel-menu" *ngIf="hideSecondLevelMenus[megaMenuIndex][secondLevelIndex]"> + <ul class="third-level-menu" role="menu" id="third-level-menus"> + <!-- Third Level menu --> + + <li *ngFor="let link of i.children" role="presentation"><i id="level3-star-inactive-{{link.menuId}}" + class="icon-star favorites-icon-inactive" data-size="large" + (mousedown)="setAsFavoriteItem($event, link.menuId)" + *ngIf="link.url.length > 1 && isUrlFavorite(link.menuId)==false"> + </i> <i id="level3-star-active-{{link.menuId}}" + *ngIf="link.url.length > 1 && isUrlFavorite(link.menuId)" class="icon-star favorites-icon-active" + data-size="large" (mousedown)="removeAsFavoriteItem($event, link.menuId)"> + </i> <a class="third-level-title" + (mousedown)="goToUrl(link);auditLog(link,'application')">{{link.text}}</a> + <!-- Fourth Level menu --> + <div *ngFor="let title of link.children"> + <i id="level4-star-inactive-{{title.menuId}}" class="icon-star favorites-icon-inactive" + (mousedown)="setAsFavoriteItem($event, title.menuId)" + *ngIf="title.url.length > 1 && isUrlFavorite(title.menuId)==false"> + </i> <i id="level4-star-active-{{title.menuId}}" class="icon-star favorites-icon-active" + (mousedown)="removeAsFavoriteItem($event, title.menuId)" + *ngIf="title.url.length > 1 && isUrlFavorite(title.menuId)"> + </i> <a href="javascript:void(0);" class="header-tertiaryitem" + [ngClass]="{'disabled': title.disabled}" role="menuitem" + (mousedown)="goToUrl(title);auditLog(title,'functional')">{{title.text}}</a> + </div> + </li> + + + + + </ul> + </div> + </div> + + </li> + </ul> + </div> + </div> +</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..6329f3ae --- /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%"/> Ecomp 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="ecomp-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..c1ef2a34 --- /dev/null +++ b/portal-FE-common/src/app/layout/components/header/header.component.scss @@ -0,0 +1,84 @@ +/* + * ============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============================================ + * + * + */ +$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/search-users/search-users.component.html b/portal-FE-common/src/app/layout/components/search-users/search-users.component.html new file mode 100644 index 00000000..03624491 --- /dev/null +++ b/portal-FE-common/src/app/layout/components/search-users/search-users.component.html @@ -0,0 +1,70 @@ +<!-- + ============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============================================ + + + --> + +<form> + {{searchTitle}} + <div class="form-row"> + <div class="col-md-6 my-1"> + <label for="inputSearch" class="sr-only"></label> + <input id="inputSearch" pattern="[a-zA-Z0-9-'\s]{3,}" [(ngModel)]="searchString" (keyup)="passSystemUserInfo($event.srcElement.value)" maxlength="80" + required="true" name="searchString" #searchInput auto-focus tabindex="0" autocomplete="off" type="text" + class="form-control" value="searchString" placeholder="{{placeHolder}}"> + </div> + + <div class="col-auto my-1"> + <button id="button-search-users" *ngIf="!isSystemUser" [disabled]="!searchInput.validity.valid || isLoading " type="submit" + class="btn btn-primary mb-2" (click)="searchUsers()"> Search + </button> + </div> + </div> +</form> +<span class="ecomp-spinner" *ngIf="isLoading"></span> +<div class="search-user-container" *ngIf="showUserTable && !isSystemUser"> + <table mat-table [dataSource]="dataSourceMap"> + <!-- Search Result Column--> + <ng-container matColumnDef="firstName"> + <th id="rowheader-result" mat-header-cell *matHeaderCellDef> Showing {{searchUsersResults.length}} {{txtResults}} </th> + <td id="table-data-{{i}}" mat-cell *matCellDef="let element; let i = index;"> + {{element.firstName}} {{element.lastName}} <br> {{element.jobTitle}} + </td> + </ng-container> + <tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr> + <tr mat-row (click)="setSelectedUser(row)" id="table-row-{{i}}" [ngClass]="{ 'selected': row === selectedUser }" + *matRowDef="let row; columns: displayedColumns; let i = index;"></tr> + </table> +</div>
\ No newline at end of file diff --git a/portal-FE-common/src/app/layout/components/search-users/search-users.component.scss b/portal-FE-common/src/app/layout/components/search-users/search-users.component.scss new file mode 100644 index 00000000..95a2a5ec --- /dev/null +++ b/portal-FE-common/src/app/layout/components/search-users/search-users.component.scss @@ -0,0 +1,56 @@ +/*- + * ============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/pages.component"; + +.mat-row { + cursor: pointer; + background-color: #f2f2f2; +} +.selected { + background-color: #ffffff !important; +} + +.search-user-container { + overflow-y: auto; + height: 250px; +} + +.ecomp-spinner{ + opacity: 10; +} diff --git a/portal-FE-common/src/app/layout/components/search-users/search-users.component.spec.ts b/portal-FE-common/src/app/layout/components/search-users/search-users.component.spec.ts new file mode 100644 index 00000000..66a966cf --- /dev/null +++ b/portal-FE-common/src/app/layout/components/search-users/search-users.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 { SearchUsersComponent } from './search-users.component'; + +describe('SearchUsersComponent', () => { + let component: SearchUsersComponent; + let fixture: ComponentFixture<SearchUsersComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ SearchUsersComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(SearchUsersComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/portal-FE-common/src/app/layout/components/search-users/search-users.component.ts b/portal-FE-common/src/app/layout/components/search-users/search-users.component.ts new file mode 100644 index 00000000..b93ffd61 --- /dev/null +++ b/portal-FE-common/src/app/layout/components/search-users/search-users.component.ts @@ -0,0 +1,107 @@ +/*- + * ============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, ViewChild, Output, EventEmitter } from '@angular/core'; +import { UsersService } from 'src/app/shared/services'; +import { MatTableDataSource, MatPaginator, MatSort } from '@angular/material'; +import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; +import { ConfirmationModalComponent } from 'src/app/modals/confirmation-modal/confirmation-modal.component'; +import { PortalAdmin } from 'src/app/shared/model/PortalAdmin'; + +@Component({ + selector: 'app-search-users', + templateUrl: './search-users.component.html', + styleUrls: ['./search-users.component.scss'] +}) +export class SearchUsersComponent implements OnInit { + + constructor(private userService: UsersService, private ngModal: NgbModal) { } + @Input() searchTitle: string; + @Input() placeHolder: string; + @Input() isSystemUser: boolean; + @ViewChild(MatSort) sort: MatSort; + @ViewChild(MatPaginator) paginator: MatPaginator; + @Output() passBackSelectedUser: EventEmitter<any> = new EventEmitter(); + searchString: string; + txtResults = 'result'; + searchUsersResults: any; + selected: any; + isLoading: boolean; + showUserTable: boolean; + selectedUser: any; + displayedColumns: string[] = ['firstName']; + dataSourceMap = new MatTableDataSource(this.searchUsersResults); + + ngOnInit() { + this.searchString = ''; + this.showUserTable = false; + this.isSystemUser = false; + } + + passSystemUserInfo(systemUser: string) { + if (this.isSystemUser) + this.passBackSelectedUser.emit(systemUser); + } + + searchUsers() { + if (!this.isSystemUser) { + this.isLoading = true; + this.showUserTable = false; + this.passBackSelectedUser.emit(this.selectedUser = ''); + this.userService.searchUsers(this.searchString).subscribe((_data: PortalAdmin) => { + this.searchUsersResults = _data; + if (this.searchUsersResults == null || this.searchUsersResults.length == 0) { + const modelRef = this.ngModal.open(ConfirmationModalComponent) + modelRef.componentInstance.title = "Confirmation"; + modelRef.componentInstance.message = " No users found with your query. Please change your search and try again." + this.isLoading = false; + } else { + this.showUserTable = true; + this.isLoading = false; + this.dataSourceMap = new MatTableDataSource(this.searchUsersResults); + this.txtResults = (this.searchUsersResults && this.searchUsersResults.length > 1) ? 'results' : 'result'; + } + }); + } + } + + setSelectedUser(user: PortalAdmin) { + this.selectedUser = user; + this.passBackSelectedUser.emit(this.selectedUser); + } + +} 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> + </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> + <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> + <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> + <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> + <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..6330e3b2 --- /dev/null +++ b/portal-FE-common/src/app/layout/components/sidebar/sidebar.component.scss @@ -0,0 +1,228 @@ +/* + * ============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============================================ + * + * + */ +$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..0b941c6c --- /dev/null +++ b/portal-FE-common/src/app/layout/components/tabbar/tab.ts @@ -0,0 +1,12 @@ +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}} + <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..e9a8b822 --- /dev/null +++ b/portal-FE-common/src/app/layout/components/userbar/userbar.component.html @@ -0,0 +1,13 @@ +<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..b139d311 --- /dev/null +++ b/portal-FE-common/src/app/layout/components/userbar/userbar.component.scss @@ -0,0 +1,76 @@ +.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..db476dde --- /dev/null +++ b/portal-FE-common/src/app/layout/components/userbar/userbar.component.spec.ts @@ -0,0 +1,25 @@ +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..8f68018a --- /dev/null +++ b/portal-FE-common/src/app/layout/components/userbar/userbar.component.ts @@ -0,0 +1,96 @@ +import { Component, OnInit } from '@angular/core'; +import { UserbarService, UserProfileService } from 'src/app/shared/services'; +import { DomSanitizer } from '@angular/platform-browser'; + +@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; + 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.sanitizer.bypassSecurityTrustResourceUrl('qto://talk/' + _res[i]), + linkPic: 'https://tspace.web.att.com/profiles/photo.do?uid=' + _res[i] + } + 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..e3307a8b --- /dev/null +++ b/portal-FE-common/src/app/layout/layout-routing.module.ts @@ -0,0 +1,57 @@ +/* + * ============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============================================ + * + * + */ +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..7045da97 --- /dev/null +++ b/portal-FE-common/src/app/layout/layout.component.scss @@ -0,0 +1,68 @@ +/* + * ============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============================================ + * + * + */ +* { + -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..3da46662 --- /dev/null +++ b/portal-FE-common/src/app/layout/layout.component.ts @@ -0,0 +1,56 @@ +/* + * ============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============================================ + * + * + */ +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..e46448e9 --- /dev/null +++ b/portal-FE-common/src/app/layout/layout.module.ts @@ -0,0 +1,65 @@ +/* + * ============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============================================ + * + * + */ +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 {} |