diff options
author | Arul <arul.nambi@amdocs.com> | 2018-01-15 11:04:25 -0500 |
---|---|---|
committer | Arul <arul.nambi@amdocs.com> | 2018-01-15 11:09:58 -0500 |
commit | a38f3d6bb17a478d08016e49d6c2a667ac483d4a (patch) | |
tree | e125fd7d7b194fd3a902e34deb86bc7b8bf7b50f /src/app | |
parent | 9c0205dc5bfdac8931a4d8797240a4787d6af2dc (diff) |
Introduction of external URLs
Introduce external URLs to get AAI UI to show a specific graph
Change-Id: Ibc10dab32540f2c8347df1be535e48b88308b9ec
Signed-off-by: Arul <arul.nambi@amdocs.com>
Issue-ID: AAI-626
Diffstat (limited to 'src/app')
-rw-r--r-- | src/app/MainScreenHeader.jsx | 60 | ||||
-rw-r--r-- | src/app/MainScreenWrapperReducer.js | 13 | ||||
-rw-r--r-- | src/app/contextHandler/ContextHandlerActions.js | 78 | ||||
-rw-r--r-- | src/app/contextHandler/ContextHandlerConstants.js | 15 | ||||
-rw-r--r-- | src/app/networking/NetworkCalls.js | 27 | ||||
-rw-r--r-- | src/app/tierSupport/TierSupport.jsx | 3 | ||||
-rw-r--r-- | src/app/tierSupport/TierSupportReducer.js | 3 | ||||
-rw-r--r-- | src/app/tierSupport/launchExternalResource/LaunchExternalResource.jsx | 70 | ||||
-rw-r--r-- | src/app/tierSupport/launchExternalResource/LaunchExternalResourceReducer.js | 76 | ||||
-rw-r--r-- | src/app/tierSupport/selectedNodeDetails/SelectedNodeDetails.jsx | 4 | ||||
-rw-r--r-- | src/app/tierSupport/selectedNodeDetails/SelectedNodeDetailsReducer.js | 4 |
11 files changed, 327 insertions, 26 deletions
diff --git a/src/app/MainScreenHeader.jsx b/src/app/MainScreenHeader.jsx index 313adcd..49952f7 100644 --- a/src/app/MainScreenHeader.jsx +++ b/src/app/MainScreenHeader.jsx @@ -20,6 +20,7 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ + import React, {Component} from 'react'; import {connect} from 'react-redux'; import FontAwesome from 'react-fontawesome'; @@ -30,7 +31,7 @@ import GlobalAutoCompleteSearchBar from 'app/globalAutoCompleteSearchBar/GlobalA import {postAnalyticsData} from 'app/analytics/AnalyticsActions.js'; import GlobalInlineMessageBar from 'app/globalInlineMessageBar/GlobalInlineMessageBar.jsx'; import {getClearGlobalMessageEvent} from 'app/globalInlineMessageBar/GlobalInlineMessageBarActions.js'; -import {externalUrlRequest, externalMessageRequest} from 'app/contextHandler/ContextHandlerActions.js'; +import {externalUrlRequest, externalMessageRequest, getSubscriptionPayload} from 'app/contextHandler/ContextHandlerActions.js'; import { filterBarActionTypes @@ -63,14 +64,18 @@ const mapStateToProps = ({mainWrapper}) => { showMenu = false, toggleButtonActive = false, externalRequestFound = {}, - secondaryTitle = '' + secondaryTitle = '', + subscriptionPayload = {}, + subscriptionEnabled = false } = mainWrapper; return { showMenu, toggleButtonActive, externalRequestFound, - secondaryTitle + secondaryTitle, + subscriptionPayload, + subscriptionEnabled }; }; @@ -95,6 +100,9 @@ const mapActionsToProps = (dispatch) => { }, onExternalMessageRecieved: (messageJson) => { dispatch(externalMessageRequest(messageJson)); + }, + onGetSubscriptionPayload: () => { + dispatch(getSubscriptionPayload()); } }; }; @@ -104,7 +112,8 @@ class MainScreenHeader extends Component { showMenu: React.PropTypes.bool, toggleButtonActive: React.PropTypes.bool, externalRequestFound: React.PropTypes.object, - secondaryTitle: React.PropTypes.string + secondaryTitle: React.PropTypes.string, + subscriptionPayload: React.PropTypes.object }; navigationLinkAndCurrentPathMatch(location, to) { @@ -134,6 +143,7 @@ class MainScreenHeader extends Component { } } componentWillMount() { + this.props.onGetSubscriptionPayload(); if(this.props.match.params.externalUrl !== undefined && this.isValidExternalURL(this.props.match.params.externalUrl)) { this.props.onExternalUrlRequest(this.props.match.params.externalUrl); @@ -164,9 +174,22 @@ class MainScreenHeader extends Component { nextProps.externalRequestFound !== undefined && nextProps.externalRequestFound.suggestion !== undefined) { changeUrlAddress(nextProps.externalRequestFound.suggestion, nextProps.history); } + + if (nextProps.subscriptionEnabled) { + if (nextProps.subscriptionPayload !== this.props.subscriptionPayload && + Object.keys(nextProps.subscriptionPayload).length > 0) { + var getWindowUrl = function (url) { + var split = url.split('/'); + return split[0] + '//' + split[2]; + }; + window.parent.postMessage( + JSON.stringify(nextProps.subscriptionPayload), + getWindowUrl(document.referrer)); + } + } } - receiveMessage(event) { + receiveMessage(event, $this) { function isJson(str) { try { JSON.parse(str); @@ -175,16 +198,33 @@ class MainScreenHeader extends Component { } return true; } - let messageData = event.data.message; - if(isJson(messageData)) { - this.props.onExternalMessageRecieved(JSON.parse(messageData)); + if(isJson(event.data)) { + let messageData = JSON.parse(event.data); + if(isJson(messageData.message)) { + $this.props.onExternalMessageRecieved(messageData.message); + } } + } componentDidMount() { - window.addEventListener('message', this.receiveMessage, false); + //TODO Move this logic to the component will receive props. + //Check if the event lister is available and if the subscription is + // enabled before registering for it + if(document.referrer) { + var $this = this; + window.addEventListener('message', function (e) { + $this.receiveMessage(e, $this); + }, false); + } } componentWillUnmount() { - window.removeEventListener('message', this.receiveMessage); + if(this.props.subscriptionEnabled) { + var $this = this; + window.removeEventListener('message', function (e) { + $this.receiveMessage(e, $this); + } + ); + } } render() { diff --git a/src/app/MainScreenWrapperReducer.js b/src/app/MainScreenWrapperReducer.js index 8c60330..6dd7dbf 100644 --- a/src/app/MainScreenWrapperReducer.js +++ b/src/app/MainScreenWrapperReducer.js @@ -20,6 +20,7 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ + import {aaiActionTypes} from './MainScreenWrapperConstants.js'; import { globalAutoCompleteSearchBarActionTypes @@ -61,11 +62,23 @@ export default (state = {}, action) => { ...state, externalRequestFound: action.data }; + case aaiActionTypes.SET_SECONDARY_TITLE: return { ...state, secondaryTitle: action.data }; + case contextHandlerActionTypes.SUBSCRIPTION_PAYLOAD_FOUND: + return { + ...state, + subscriptionPayload: action.data, + subscriptionEnabled: true + }; + case contextHandlerActionTypes.SUBSCRIPTION_PAYLOAD_EMPTY: + return { + ...state, + subscriptionEnabled: false + }; } return state; }; diff --git a/src/app/contextHandler/ContextHandlerActions.js b/src/app/contextHandler/ContextHandlerActions.js index 5738f2a..889020a 100644 --- a/src/app/contextHandler/ContextHandlerActions.js +++ b/src/app/contextHandler/ContextHandlerActions.js @@ -20,14 +20,21 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ + import { POST, - POST_HEADER + POST_HEADER, + GET } from 'app/networking/NetworkConstants.js'; import networkCall from 'app/networking/NetworkCalls.js'; import {EXTERNAL_REQ_ENTITY_SEARCH_URL, WRONG_EXTERNAL_REQUEST_MESSAGE, - WRONG_RESULT + WRONG_RESULT, + ZERO_RESULT, + MULTIPLE_RESULT, + FAILED_REQUEST, + SUBSCRIPTION_FAILED_MESSAGE, + SUBSCRIPTION_PAYLOAD_URL } from 'app/contextHandler/ContextHandlerConstants'; import { getSetGlobalMessageEvent, @@ -36,7 +43,8 @@ import { import { STATUS_CODE_204_NO_CONTENT, STATUS_CODE_3XX_REDIRECTION, - MESSAGE_LEVEL_DANGER + MESSAGE_LEVEL_DANGER, + MESSAGE_LEVEL_WARNING } from 'utils/GlobalConstants.js'; @@ -56,6 +64,55 @@ function getExternalParamValues(urlParams) { } +function createSubscriptionPayloadEvent(payload) { + return { + type: contextHandlerActionTypes.SUBSCRIPTION_PAYLOAD_FOUND, + data: payload + }; +} + +function createSubscriptionIsEmptyEvent() { + return { + type: contextHandlerActionTypes.SUBSCRIPTION_PAYLOAD_EMPTY, + data: {} + }; +} + +function fetchSubscriptionPayload(fetchRequestCallback) { + return dispatch => { + return fetchRequestCallback().then( + (response) => { + if (response.status >= STATUS_CODE_3XX_REDIRECTION) { + return Promise.reject(new Error(response.status)); + } else { + // assume 200 status + return response; + } + } + ).then( + (results)=> { + dispatch(createSubscriptionPayloadEvent(results)); + + } + ).catch( + (e) => { + if(e.name === 'EmptyResponseException'){ + dispatch(getClearGlobalMessageEvent()); + dispatch(createSubscriptionIsEmptyEvent()); + } else{ + dispatch(getSetGlobalMessageEvent(SUBSCRIPTION_FAILED_MESSAGE , MESSAGE_LEVEL_WARNING)); + } + } + ); + }; +} +export function getSubscriptionPayload() { + let externalfetchRequest = + () => networkCall.getRequest(SUBSCRIPTION_PAYLOAD_URL, GET); + return dispatch => { + dispatch(fetchSubscriptionPayload(externalfetchRequest)); + }; +} function validateExternalParams(externalURLParams) { if(externalURLParams.view && externalURLParams.entityId && externalURLParams.entityType) { return true; @@ -86,16 +143,21 @@ function fetchDataForExternalRequest(fetchRequestCallback) { } ).then( (results)=> { - if (results.suggestions !== undefined && results.suggestions.length === 1) { - dispatch(getClearGlobalMessageEvent()); - dispatch(createSuggestionFoundEvent({suggestion: results.suggestions[0]})); + if (results.suggestions !== undefined) { + if( results.suggestions.length === 1) { + dispatch(getClearGlobalMessageEvent()); + dispatch(createSuggestionFoundEvent({suggestion: results.suggestions[0]})); + } else if(results.totalFound === 0 ) { + dispatch(getSetGlobalMessageEvent(ZERO_RESULT, MESSAGE_LEVEL_DANGER)); + } else { + dispatch(getSetGlobalMessageEvent(MULTIPLE_RESULT, MESSAGE_LEVEL_DANGER)); } } else { - dispatch(getSetGlobalMessageEvent(WRONG_RESULT , MESSAGE_LEVEL_DANGER)); + dispatch(getSetGlobalMessageEvent(WRONG_RESULT, MESSAGE_LEVEL_DANGER)); } } ).catch( () => { - dispatch(getSetGlobalMessageEvent(WRONG_RESULT , MESSAGE_LEVEL_DANGER)); + dispatch(getSetGlobalMessageEvent(FAILED_REQUEST , MESSAGE_LEVEL_DANGER)); } ); }; diff --git a/src/app/contextHandler/ContextHandlerConstants.js b/src/app/contextHandler/ContextHandlerConstants.js index 809d05c..6229968 100644 --- a/src/app/contextHandler/ContextHandlerConstants.js +++ b/src/app/contextHandler/ContextHandlerConstants.js @@ -21,17 +21,26 @@ * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ + import keyMirror from 'utils/KeyMirror.js'; import {BASE_URL} from 'app/networking/NetworkConstants.js'; export const contextHandlerActionTypes = keyMirror({ SINGLE_SUGGESTION_FOUND: null, - INVALID_SUGGESTION_FOUND: null + INVALID_SUGGESTION_FOUND: null, + SUBSCRIPTION_PAYLOAD_EMPTY: null, + SUBSCRIPTION_PAYLOAD_FOUND: null }); export const EXTERNAL_REQ_ENTITY_SEARCH_URL = BASE_URL + '/rest/search/externalRequestEntitySearch'; -export const WRONG_EXTERNAL_REQUEST_MESSAGE = 'External parameter request is incorrect'; -export const WRONG_RESULT = 'Invalid result for the requested external params.'; +export const WRONG_EXTERNAL_REQUEST_MESSAGE = 'A parameter in the request is incorrect'; +export const WRONG_RESULT = 'Invalid result for the request.'; +export const FAILED_REQUEST = 'Failed to pull result for the request.'; +export const ZERO_RESULT = 'No result has been found for this request.'; +export const MULTIPLE_RESULT = 'Multiple results were found for this request so none got selected.'; +export const SUBSCRIPTION_FAILED_MESSAGE = 'Failed to fetch subscription payload.'; +export const SUBSCRIPTION_PAYLOAD_URL = BASE_URL + '/subscription/getsubscription'; + diff --git a/src/app/networking/NetworkCalls.js b/src/app/networking/NetworkCalls.js index 98021f4..b6c96b7 100644 --- a/src/app/networking/NetworkCalls.js +++ b/src/app/networking/NetworkCalls.js @@ -21,6 +21,9 @@ * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ +function EmptyResponseException(){ + this.name = 'EmptyResponseException'; +} function fetchRequest(URL, POST, POST_HEADER, BODY) { return fetch(URL, { credentials: 'same-origin', @@ -41,9 +44,31 @@ function fetchRequestObj(URL, POST, POST_HEADER, BODY) { }); } +function processResponse(response){ + if(response.status === 204){ + throw new EmptyResponseException(); + } + return response.json(); +} +function getRequest(URL, GET) { + return fetch(URL, { + credentials: 'same-origin', + method: GET + }).then( + (response) => { + try{ + response.json(); + } catch (e){ + response.isValidJson = false; + } + return processResponse(response); + } + ); +} module.exports = { fetchRequest: fetchRequest, - fetchRequestObj: fetchRequestObj + fetchRequestObj: fetchRequestObj, + getRequest: getRequest }; diff --git a/src/app/tierSupport/TierSupport.jsx b/src/app/tierSupport/TierSupport.jsx index c2d1c57..315b6a0 100644 --- a/src/app/tierSupport/TierSupport.jsx +++ b/src/app/tierSupport/TierSupport.jsx @@ -20,6 +20,7 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ + import React, {Component} from 'react'; import {connect} from 'react-redux'; import SplitPane from 'react-split-pane'; @@ -131,7 +132,7 @@ class TierSupport extends Component { this.props.match.params.viParam) { this.props.onNewVIParam(nextProps.match.params.viParam); } - if(nextProps.match.params.viParam === undefined && nextProps.match.params.viParam !== + if(nextProps.match.params.viParam && nextProps.match.params.viParam !== this.props.match.params.viParam) { this.props.onRequestClearData(); } diff --git a/src/app/tierSupport/TierSupportReducer.js b/src/app/tierSupport/TierSupportReducer.js index 186c4f1..1560427 100644 --- a/src/app/tierSupport/TierSupportReducer.js +++ b/src/app/tierSupport/TierSupportReducer.js @@ -20,6 +20,7 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ + import {combineReducers} from 'redux'; import ForceDirectedGraph from 'generic-components/graph/ForceDirectedGraph.jsx'; import {aaiActionTypes} from 'app/MainScreenWrapperConstants.js'; @@ -28,6 +29,7 @@ import { } from 'app/tierSupport/TierSupportConstants.js'; import SelectedNodeDetailsReducer from 'app/tierSupport/selectedNodeDetails/SelectedNodeDetailsReducer.js'; import GlobalAutoCompleteSearchBarReducer from 'app/globalAutoCompleteSearchBar/GlobalAutoCompleteSearchBarReducer.js'; +import LaunchInContextReducer from 'app/tierSupport/launchExternalResource/LaunchExternalResourceReducer.js'; import { MESSAGE_LEVEL_DANGER, MESSAGE_LEVEL_WARNING } from 'utils/GlobalConstants.js'; @@ -37,6 +39,7 @@ import { export default combineReducers({ selectedNodeDetails: SelectedNodeDetailsReducer, + launchExternalResourceReducer: LaunchInContextReducer, globalAutoCompleteSearchBar: GlobalAutoCompleteSearchBarReducer, tierSupportReducer: (state = {}, action) => { switch (action.type) { diff --git a/src/app/tierSupport/launchExternalResource/LaunchExternalResource.jsx b/src/app/tierSupport/launchExternalResource/LaunchExternalResource.jsx new file mode 100644 index 0000000..095669b --- /dev/null +++ b/src/app/tierSupport/launchExternalResource/LaunchExternalResource.jsx @@ -0,0 +1,70 @@ +/* + * ============LICENSE_START=================================================== + * SPARKY (AAI UI service) + * ============================================================================ + * Copyright © 2017 AT&T Intellectual Property. + * Copyright © 2017 Amdocs + * All rights reserved. + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + * + * ECOMP and OpenECOMP are trademarks + * and service marks of AT&T Intellectual Property. + */ + +import {connect} from 'react-redux'; +import React, {Component} from 'react'; +import {isEmpty} from 'lodash'; +import Button from 'react-bootstrap/lib/Button.js'; + +let mapStateToProps = ({tierSupport: {launchExternalResourceReducer}}) => { + let {externalResourcePayload = {}} = launchExternalResourceReducer; + + return { + externalResourcePayload + }; +}; + +class LaunchExternalResource extends Component { + static propTypes = { + externalResourcePayload: React.PropTypes.object + }; + + render() { + const {externalResourcePayload} = this.props; + + let launchExternalResourceClass = 'hidden'; + if(!isEmpty(externalResourcePayload) && (externalResourcePayload.message.payload.params.objectName.length > 0)){ + launchExternalResourceClass = ''; + } + + return ( + <div className={launchExternalResourceClass}> + <Button + bsClass='launch-external-resource-button' + onClick={this.handleClick} /> + </div> + ); + } + handleClick = () => { + var getWindowUrl = function (url) { + var split = url.split('/'); + return split[0] + '//' + split[2]; + }; + if(document.referrer) { + window.parent.postMessage(JSON.stringify(this.props.externalResourcePayload), getWindowUrl(document.referrer)); + } + } +} +export default connect(mapStateToProps)(LaunchExternalResource); diff --git a/src/app/tierSupport/launchExternalResource/LaunchExternalResourceReducer.js b/src/app/tierSupport/launchExternalResource/LaunchExternalResourceReducer.js new file mode 100644 index 0000000..493afaa --- /dev/null +++ b/src/app/tierSupport/launchExternalResource/LaunchExternalResourceReducer.js @@ -0,0 +1,76 @@ +/* + * ============LICENSE_START=================================================== + * SPARKY (AAI UI service) + * ============================================================================ + * Copyright © 2017 AT&T Intellectual Property. + * Copyright © 2017 Amdocs + * All rights reserved. + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + * + * ECOMP and OpenECOMP are trademarks + * and service marks of AT&T Intellectual Property. + */ + +import {tierSupportActionTypes} from 'app/tierSupport/TierSupportConstants.js'; +import { + globalAutoCompleteSearchBarActionTypes +} from 'app/globalAutoCompleteSearchBar/GlobalAutoCompleteSearchBarConstants.js'; +import {isEmpty} from 'lodash'; + +export default (state = {}, action) => { + switch (action.type) { + case tierSupportActionTypes.TS_NODE_SEARCH_RESULTS: + if(!isEmpty(action.data.nodes)){ + for (const node of action.data.nodes) { + if (node.nodeMeta.searchTarget === true) { + let externalResourcePayload = {}; + if(!isEmpty(node.externalResourcePayload)){ + externalResourcePayload = node.externalResourcePayload; + } + return { + ...state, + externalResourcePayload: externalResourcePayload + }; + } + } + } + return { + ...state, + externalResourcePayload: {} + }; + + case tierSupportActionTypes.TS_GRAPH_NODE_SELECTED: + let externalResourcePayload; + if(action.data.externalResourcePayload){ + externalResourcePayload = action.data.externalResourcePayload; + } else { + externalResourcePayload = {}; + } + return { + ...state, + externalResourcePayload: externalResourcePayload + }; + + case globalAutoCompleteSearchBarActionTypes.SEARCH_WARNING_EVENT: + case tierSupportActionTypes.TIER_SUPPORT_NETWORK_ERROR: + case tierSupportActionTypes.TIER_SUPPORT_CLEAR_DATA: + case tierSupportActionTypes.TS_NODE_SEARCH_NO_RESULTS: + return { + ...state, + externalResourcePayload: {} + }; + } + return state; +}; diff --git a/src/app/tierSupport/selectedNodeDetails/SelectedNodeDetails.jsx b/src/app/tierSupport/selectedNodeDetails/SelectedNodeDetails.jsx index 5ff4104..1dbd71b 100644 --- a/src/app/tierSupport/selectedNodeDetails/SelectedNodeDetails.jsx +++ b/src/app/tierSupport/selectedNodeDetails/SelectedNodeDetails.jsx @@ -20,9 +20,11 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ + import {connect} from 'react-redux'; import React, {Component} from 'react'; import Table from 'react-bootstrap/lib/Table'; +import LaunchInContext from 'app/tierSupport/launchExternalResource/LaunchExternalResource.jsx'; import i18n from 'utils/i18n/i18n'; import { SELECTED_NODE_TITLE, @@ -82,7 +84,7 @@ class SelectedNodeDetails extends Component { <div className='ts-selected-node-details'> <h1>{i18n(SELECTED_NODE_TITLE)}</h1> <h2>{nodeType}</h2> - <span>{uid}</span> + <span>{uid} <LaunchInContext /></span> <Table bsClass={tableClass}> <thead> <tr> diff --git a/src/app/tierSupport/selectedNodeDetails/SelectedNodeDetailsReducer.js b/src/app/tierSupport/selectedNodeDetails/SelectedNodeDetailsReducer.js index d088e73..17eaed1 100644 --- a/src/app/tierSupport/selectedNodeDetails/SelectedNodeDetailsReducer.js +++ b/src/app/tierSupport/selectedNodeDetails/SelectedNodeDetailsReducer.js @@ -40,7 +40,7 @@ export default (state = {}, action) => { } return { ...state, - nodeData: [], + nodeData: {}, nodeType: '', uid: '' }; @@ -60,7 +60,7 @@ export default (state = {}, action) => { case tierSupportActionTypes.TS_NODE_SEARCH_NO_RESULTS: return { ...state, - nodeData: [], + nodeData: {}, nodeType: '', uid: '' }; |