2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
6 * Copyright © 2017-2018 Amdocs
7 * ================================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END=========================================================
21 import React, {Component} from 'react';
22 import { PropTypes } from 'prop-types';
23 import {connect} from 'react-redux';
24 import FontAwesome from 'react-fontawesome';
25 import {clearFilters} from 'filter-bar-utils';
26 import Button from 'react-bootstrap/lib/Button.js';
27 import Modal from 'react-bootstrap/lib/Modal.js';
28 import {postAnalyticsData, getStoreAnalyticsPayload} from 'app/analytics/AnalyticsActions.js';
29 import GlobalInlineMessageBar from 'app/globalInlineMessageBar/GlobalInlineMessageBar.jsx';
30 import {getClearGlobalMessageEvent} from 'app/globalInlineMessageBar/GlobalInlineMessageBarActions.js';
31 import {externalUrlRequest, externalMessageRequest, getSubscriptionPayload} from 'app/contextHandler/ContextHandlerActions.js';
32 import { getConfigurableViewConfigs } from 'app/configurableViews/ConfigurableViewActions.js';
33 import {GlobalExtConstants} from 'utils/GlobalExtConstants.js';
34 import axios from 'axios';
35 import {BASE_URL} from 'app/networking/NetworkConstants.js';
40 } from 'utils/GlobalConstants.js';
45 } from 'react-router-dom';
51 AAI_LOADTEMPLATE_MAX_COUNT
52 } from './MainScreenWrapperConstants.js';
56 clearExtensibleViewData,
58 } from './MainScreenWrapperActionHelper.js';
60 import {clearSuggestionsTextField} from 'app/globalAutoCompleteSearchBar/GlobalAutoCompleteSearchBarActions.js';
61 import {changeUrlAddress} from 'utils/Routes.js';
62 import defaultViews from 'resources/views/defaultViews.json';
63 import defaultViews_onap from 'resources/views/defaultViews_onap.json';
64 import {getPersonalizationDetails} from 'app/personlaization/PersonalizationActions.js';
65 import {isEmpty} from 'lodash';
67 let INVLIST = GlobalExtConstants.INVLIST;
69 const mapStateToProps = ({mainWrapper, configurableViews}) => {
72 toggleButtonActive = false,
73 externalRequestFound = {},
75 subscriptionPayload = {},
76 subscriptionEnabled = false,
77 aaiTopLeftPersonalizedHeader = AAI_TOP_LEFT_HEADER,
78 aaiPersonalizedHtmlDocumentTitle = AAI_HTML_TITLE,
79 aaiPersonalizedApertureService = AAI_APERTURE_SERVICE,
80 aaiPersonalizedLoadTemplateMaxCount = AAI_LOADTEMPLATE_MAX_COUNT
84 configurableViewsConfig
85 } = configurableViews;
94 configurableViewsConfig,
95 aaiTopLeftPersonalizedHeader,
96 aaiPersonalizedHtmlDocumentTitle,
97 aaiPersonalizedApertureService,
98 aaiPersonalizedLoadTemplateMaxCount
103 const mapActionsToProps = (dispatch) => {
105 onShowMenu: () => dispatch(showMainMenu(true)),
107 dispatch(showMainMenu(false));
109 dispatchAnalyticsData: () => dispatch(
110 postAnalyticsData(getStoreAnalyticsPayload())),
111 onRouteChange: () => {
112 dispatch(getClearGlobalMessageEvent());
113 dispatch(clearSuggestionsTextField());
114 dispatch(clearExtensibleViewData());
115 dispatch(clearFilters(filterBarActionTypes.CLEAR_FILTERS));
116 dispatch(setSecondaryTitle(undefined));
118 onExternalUrlRequest: (urlParamString) => {
119 dispatch(externalUrlRequest(urlParamString));
121 onExternalMessageRecieved: (messageJson) => {
122 dispatch(externalMessageRequest(messageJson));
124 onGetSubscriptionPayload: () => {
125 dispatch(getSubscriptionPayload());
127 onFetchCustomViews: () => {
128 dispatch(getConfigurableViewConfigs());
130 onGetPersonalizationValues: () => {
131 dispatch(getPersonalizationDetails());
136 class MainScreenHeader extends Component {
138 showMenu: PropTypes.bool,
139 toggleButtonActive: PropTypes.bool,
140 externalRequestFound: PropTypes.object,
141 secondaryTitle: PropTypes.string,
142 subscriptionPayload: PropTypes.object,
143 aaiTopLeftPersonalizedHeader: PropTypes.string,
144 aaiPersonalizedHtmlDocumentTitle: PropTypes.string,
145 aaiPersonalizedApertureService: PropTypes.bool,
146 aaiPersonalizedLoadTemplateMaxCount: PropTypes.string
149 navigationLinkAndCurrentPathMatch(location, to) {
150 let linkPathElements = to.split('/');
151 let locationElements = location.pathname.split('/');
153 // the element arrays above will have the route at index 1 ... need to
154 // verify if the routes match
155 return locationElements[1] === linkPathElements[1];
158 hasRouteChanged(currentPath, nextPath) {
159 let currentPathParts = currentPath.split('/');
160 let nextPathParts = nextPath.split('/');
162 if (currentPathParts[1] !== nextPathParts[1]) {
169 isValidExternalURL(url) {
170 if(decodeURIComponent(url).indexOf('&') > 0 ) {
177 componentWillMount() {
178 this.props.onGetPersonalizationValues();
179 this.props.onGetSubscriptionPayload();
180 if(this.props.match.params.externalUrl !== undefined &&
181 this.isValidExternalURL(this.props.match.params.externalUrl)) {
182 this.props.onExternalUrlRequest(this.props.match.params.externalUrl);
184 sessionStorage.setItem(ENVIRONMENT + 'ENABLE_ANALYSIS', !INVLIST.IS_ONAP);
185 var portalInfoPath = BASE_URL + '/portal/info';
186 //portalInfoPath = 'https://localhost:8000/portal/info';
187 axios.get(portalInfoPath).then(res => {
188 console.log('res:' + res.data);
190 if(res.status === 200){
191 if(res.data.status && (res.data.status !== '200')){
192 this.setDefaultCredentials(res.data);
194 sessionStorage.setItem(ENVIRONMENT + 'userId', res.data.attuid);
195 for(var i = 0; i < res.data.role.length; i++){
196 roles.push(res.data.role[i].name);
198 sessionStorage.setItem(ENVIRONMENT + 'roles', roles);
201 this.setDefaultCredentials(res.data);
204 this.setDefaultCredentials(error);
206 this.setDefaultCredentials(error);
210 setDefaultCredentials = (error) =>{
211 console.log('MainScreenHeader.jsx :: Issue retrieving portal info from sparky backend, setting default, details - ' + JSON.stringify(error));
212 sessionStorage.setItem(ENVIRONMENT + 'userId', 'default_uid');
213 var roles = ['ui_view'];
214 sessionStorage.setItem(ENVIRONMENT + 'roles', roles);
217 componentWillReceiveProps(nextProps) {
218 if(!isEmpty(nextProps.aaiPersonalizedHtmlDocumentTitle)) {
219 if(!sessionStorage.getItem(ENVIRONMENT + 'PAGE_TITLE') || sessionStorage.getItem(ENVIRONMENT + 'PAGE_TITLE') !== nextProps.aaiPersonalizedHtmlDocumentTitle) {
220 sessionStorage.setItem(ENVIRONMENT + 'PAGE_TITLE', nextProps.aaiPersonalizedHtmlDocumentTitle);
222 document.title = nextProps.aaiPersonalizedHtmlDocumentTitle;
224 document.title = AAI_HTML_TITLE;
226 //Added for APERTURE Service Enable/Disable
227 if(!sessionStorage.getItem(ENVIRONMENT + 'APERTURE_SERVICE') || JSON.parse(sessionStorage.getItem(ENVIRONMENT + 'APERTURE_SERVICE')) !== nextProps.aaiPersonalizedApertureService) {
228 if(JSON.parse(sessionStorage.getItem(ENVIRONMENT + 'APERTURE_SERVICE')) !== nextProps.aaiPersonalizedApertureService){
229 sessionStorage.setItem(ENVIRONMENT + 'APERTURE_SERVICE', Boolean(nextProps.aaiPersonalizedApertureService));
230 if(nextProps.aaiPersonalizedApertureService){
231 sessionStorage.setItem(ENVIRONMENT + 'ENABLE_ANALYSIS', true);
233 sessionStorage.setItem(ENVIRONMENT + 'ENABLE_ANALYSIS', false);
236 sessionStorage.setItem(ENVIRONMENT + 'APERTURE_SERVICE', Boolean(nextProps.aaiPersonalizedApertureService));
239 if(!sessionStorage.getItem(ENVIRONMENT + 'APERTURE_SERVICE')){
240 sessionStorage.setItem(ENVIRONMENT + 'ENABLE_ANALYSIS', false);
242 if(!sessionStorage.getItem(ENVIRONMENT + 'LOADTEMPLATE_MAX_COUNT') || sessionStorage.getItem(ENVIRONMENT + 'LOADTEMPLATE_MAX_COUNT') !== nextProps.aaiPersonalizedLoadTemplateMaxCount) {
243 sessionStorage.setItem(ENVIRONMENT + 'LOADTEMPLATE_MAX_COUNT', nextProps.aaiPersonalizedLoadTemplateMaxCount);
245 if (this.props.location &&
246 this.props.location.pathname !==
247 nextProps.location.pathname) {
249 this.props.dispatchAnalyticsData();
251 if (this.hasRouteChanged(this.props.location.pathname,
252 nextProps.location.pathname)) {
253 this.props.onRouteChange();
257 if(nextProps.match.params.externalUrl !== undefined &&
258 nextProps.match.params.externalUrl !== this.props.match.params.externalUrl &&
259 this.isValidExternalURL(nextProps.match.params.externalUrl)) {
260 this.props.onExternalUrlRequest(nextProps.match.params.externalUrl);
262 /* if the externalURL is not valid, we do not add any message as other proper
263 views will get that messages since the route will be this parameter.*/
265 if(this.props.externalRequestFound !== nextProps.externalRequestFound &&
266 nextProps.externalRequestFound !== undefined && nextProps.externalRequestFound.suggestion !== undefined) {
267 changeUrlAddress(nextProps.externalRequestFound.suggestion, nextProps.history);
270 if (nextProps.subscriptionEnabled) {
271 if (nextProps.subscriptionPayload !== this.props.subscriptionPayload &&
272 Object.keys(nextProps.subscriptionPayload).length > 0) {
273 var getWindowUrl = function (url) {
274 var split = url.split('/');
275 return split[0] + '//' + split[2];
277 window.parent.postMessage(
278 JSON.stringify(nextProps.subscriptionPayload),
279 getWindowUrl(document.referrer));
284 receiveMessage(event, $this) {
285 function isJson(str) {
293 if(isJson(event.data)) {
294 let messageData = JSON.parse(event.data);
295 if(isJson(messageData.message)) {
296 $this.props.onExternalMessageRecieved(messageData.message);
301 componentDidMount() {
302 //TODO Move this logic to the component will receive props.
303 //Check if the event lister is available and if the subscription is
304 // enabled before registering for it
305 if(document.referrer) {
307 window.addEventListener('message', function (e) {
308 $this.receiveMessage(e, $this);
312 // fetch custom views
313 this.props.onFetchCustomViews();
316 componentWillUnmount() {
317 if(this.props.subscriptionEnabled) {
319 window.removeEventListener('message', function (e) {
320 $this.receiveMessage(e, $this);
332 configurableViewsConfig,
333 aaiTopLeftPersonalizedHeader
336 let menuOptions = [];
338 const MenuItem = ({label, iconClass, to}) => (
339 <Route path={to} children={({location}) => (
340 <NavLink to={to} onClick={onHideMenu}>
341 <div className={this.navigationLinkAndCurrentPathMatch(location, to) ? 'main-menu-button-active' : 'main-menu-button'}>
342 <div className={iconClass}/>
343 <div className='button-icon'>{label}</div>
349 const ConfigurableMenuItem = ({label, to}) => (
350 <Route path={to} children={({location}) => (
351 <NavLink to={to} onClick={onHideMenu}>
352 <div className={this.navigationLinkAndCurrentPathMatch(location, to) ?
353 'main-menu-button-active' : 'main-menu-button'}>
354 <div className='button-icon configurable-view-button-icon'/>
355 <div className='button-icon'>{label}</div>
361 let dv = defaultViews;
363 dv = defaultViews_onap;
366 // add all default view menu options
367 for (let view in dv) {
368 let shouldDisplayIcon = false;
369 if(dv[view]['onlyRoute'] === undefined){
370 shouldDisplayIcon = true;
371 } else if(dv[view]['onlyRoute'] === false){
372 shouldDisplayIcon = true;
374 if(shouldDisplayIcon === true){
376 <MenuItem key={dv[view]['viewName'] + 'Menu'} to={'/' + dv[view]['viewName']}
377 label={dv[view]['displayName']}
378 iconClass={'button-icon font-awesome-icon fa ' + dv[view]['iconClass']}/>
383 if (configurableViewsConfig && configurableViewsConfig.layouts) {
384 for (let configurableView in configurableViewsConfig.layouts) {
386 <ConfigurableMenuItem key={configurableViewsConfig.layouts[configurableView]['id'] + 'Menu'} to={'/' + configurableViewsConfig.layouts[configurableView]['id']}
387 label={configurableViewsConfig.layouts[configurableView]['title']}/>
392 let secondaryTitleClass = 'secondary-header';
393 if (secondaryTitle === undefined || secondaryTitle === '') {
394 secondaryTitleClass = secondaryTitleClass + ' hidden';
398 <div className='header'>
401 bsClass={(toggleButtonActive)
402 ? 'toggle-view-button-active'
403 : 'toggle-view-button'}
404 onClick={onShowMenu}>
405 <FontAwesome name='bars'/>
407 <Modal show={showMenu} onHide={onHideMenu}
408 dialogClassName='modal-main-menu'>
413 <span className='application-title'>{aaiTopLeftPersonalizedHeader}</span>
415 <GlobalInlineMessageBar />
416 <div className={secondaryTitleClass}>
417 <span className='secondary-title'>{secondaryTitle}</span>
424 export default connect(mapStateToProps, mapActionsToProps)(MainScreenHeader);