summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/app/AppStore.js5
-rw-r--r--src/app/MainScreenHeader.jsx61
-rw-r--r--src/app/MainScreenWrapper.jsx67
-rw-r--r--src/app/MainScreenWrapperActionHelper.js1
-rw-r--r--src/app/configurableViews/ConfigurableViewActions.js48
-rw-r--r--src/app/configurableViews/ConfigurableViewConstants.js11
-rw-r--r--src/app/configurableViews/ConfigurableViewManager.js27
-rw-r--r--src/app/configurableViews/ConfigurableViewReducer.js26
-rw-r--r--src/app/configurableViews/index.js27
-rw-r--r--src/app/networking/NetworkCalls.js31
-rw-r--r--src/app/tierSupport/TierSupportActions.js121
-rw-r--r--src/generic-components/autoCompleteSearchBar/AutoCompleteSearchBar.jsx16
-rw-r--r--src/generic-components/componentManager/ComponentManagerContainer.jsx16
-rw-r--r--src/generic-components/graph/Link.jsx66
-rw-r--r--src/generic-components/graph/Node.jsx54
-rw-r--r--src/generic-components/graph/SVGShape.jsx66
-rw-r--r--src/generic-components/input/ToggleInput.jsx100
-rw-r--r--src/generic-components/input/inputOptions/InputOptions.jsx418
-rw-r--r--src/generic-components/map/TopographicMap.jsx2
-rw-r--r--src/generic-components/notifications/NotificationModal.jsx158
-rw-r--r--src/generic-components/panel/SlidePanel.jsx216
-rw-r--r--src/generic-components/titledContainer/TitledContainer.jsx2
-rw-r--r--src/generic-components/toggleButtonGroup/ToggleButtonGroup.jsx78
-rw-r--r--src/utils/Crypto.js13
-rw-r--r--src/utils/SpinnerContainer.jsx4
25 files changed, 871 insertions, 763 deletions
diff --git a/src/app/AppStore.js b/src/app/AppStore.js
index 9205937..842b683 100644
--- a/src/app/AppStore.js
+++ b/src/app/AppStore.js
@@ -27,7 +27,7 @@ import InventoryReducer from './inventory/InventoryReducer.js';
import VnfSearchReducer from './vnfSearch/VnfSearchReducer.js';
import GlobalInlineMessageBarReducer from 'app/globalInlineMessageBar/GlobalInlineMessageBarReducer.js';
import ExtensibilityReducer from 'app/extensibility/ExtensibilityReducer.js';
-
+import ConfigurableViewReducer from 'app/configurableViews/ConfigurableViewReducer.js';
function createCompose() {
@@ -45,7 +45,8 @@ export const storeCreator = (initialState) => createStore(
inventoryReducer: InventoryReducer,
vnfSearch: VnfSearchReducer,
globalInlineMessageBar: GlobalInlineMessageBarReducer,
- extensibility: ExtensibilityReducer
+ extensibility: ExtensibilityReducer,
+ configurableViews: ConfigurableViewReducer
}),
initialState,
createCompose()
diff --git a/src/app/MainScreenHeader.jsx b/src/app/MainScreenHeader.jsx
index e485161..8c5e13d 100644
--- a/src/app/MainScreenHeader.jsx
+++ b/src/app/MainScreenHeader.jsx
@@ -30,6 +30,7 @@ import {postAnalyticsData} from 'app/analytics/AnalyticsActions.js';
import GlobalInlineMessageBar from 'app/globalInlineMessageBar/GlobalInlineMessageBar.jsx';
import {getClearGlobalMessageEvent} from 'app/globalInlineMessageBar/GlobalInlineMessageBarActions.js';
import {externalUrlRequest, externalMessageRequest, getSubscriptionPayload} from 'app/contextHandler/ContextHandlerActions.js';
+import { getConfigurableViewConfigs } from 'app/configurableViews/ConfigurableViewActions.js';
import {
filterBarActionTypes
} from 'utils/GlobalConstants.js';
@@ -56,7 +57,7 @@ import {changeUrlAddress} from 'utils/Routes.js';
import extensibleViews from 'resources/views/extensibleViews.json';
-const mapStateToProps = ({mainWrapper}) => {
+const mapStateToProps = ({mainWrapper, configurableViews}) => {
let {
showMenu = false,
toggleButtonActive = false,
@@ -66,13 +67,18 @@ const mapStateToProps = ({mainWrapper}) => {
subscriptionEnabled = false
} = mainWrapper;
+ let {
+ configurableViewsConfig
+ } = configurableViews;
+
return {
showMenu,
toggleButtonActive,
externalRequestFound,
secondaryTitle,
subscriptionPayload,
- subscriptionEnabled
+ subscriptionEnabled,
+ configurableViewsConfig
};
};
@@ -100,6 +106,9 @@ const mapActionsToProps = (dispatch) => {
},
onGetSubscriptionPayload: () => {
dispatch(getSubscriptionPayload());
+ },
+ onFetchCustomViews: () => {
+ dispatch(getConfigurableViewConfigs());
}
};
};
@@ -132,7 +141,7 @@ class MainScreenHeader extends Component {
return false;
}
}
-
+
isValidExternalURL(url) {
if(decodeURIComponent(url).indexOf('&') > 0 ) {
return true;
@@ -168,7 +177,7 @@ class MainScreenHeader extends Component {
this.props.onExternalUrlRequest(nextProps.match.params.externalUrl);
}
/* if the externalURL is not valid, we do not add any message as other proper
- views will get that messages since the route will be this parameter.*/
+ views will get that messages since the route will be this parameter.*/
if(this.props.externalRequestFound !== nextProps.externalRequestFound &&
nextProps.externalRequestFound !== undefined && nextProps.externalRequestFound.suggestion !== undefined) {
@@ -216,13 +225,17 @@ class MainScreenHeader extends Component {
$this.receiveMessage(e, $this);
}, false);
}
+
+ // fetch custom views
+ this.props.onFetchCustomViews();
}
+
componentWillUnmount() {
if(this.props.subscriptionEnabled) {
var $this = this;
window.removeEventListener('message', function (e) {
- $this.receiveMessage(e, $this);
- }
+ $this.receiveMessage(e, $this);
+ }
);
}
}
@@ -233,7 +246,8 @@ class MainScreenHeader extends Component {
onShowMenu,
onHideMenu,
toggleButtonActive,
- secondaryTitle
+ secondaryTitle,
+ configurableViewsConfig
} = this.props;
let menuOptions = [];
@@ -249,6 +263,18 @@ class MainScreenHeader extends Component {
)}/>
);
+ const ConfigurableMenuItem = ({label, to}) => (
+ <Route path={to} children={({location}) => (
+ <NavLink to={to} onClick={onHideMenu}>
+ <div className={this.navigationLinkAndCurrentPathMatch(location, to) ?
+ 'main-menu-button-active' : 'main-menu-button'}>
+ <div className='button-icon configurable-view-button-icon'/>
+ <div className='button-icon'>{label}</div>
+ </div>
+ </NavLink>
+ )}/>
+ );
+
// add Tier Support view
menuOptions.push(
<MenuItem key='schemaMenu' to='/schema' label={MENU_ITEM_TIER_SUPPORT}
@@ -258,9 +284,9 @@ class MainScreenHeader extends Component {
// add VNF view
menuOptions.push(
<MenuItem key='vnfSearchMenu'
- to='/vnfSearch'
- label={MENU_ITEM_VNF_SEARCH}
- iconClass='button-icon vnf-search-button-icon'/>
+ to='/vnfSearch'
+ label={MENU_ITEM_VNF_SEARCH}
+ iconClass='button-icon vnf-search-button-icon'/>
);
// add all custom view menu options
@@ -277,7 +303,16 @@ class MainScreenHeader extends Component {
label={extensibleViews[view]['displayName']}
iconClass={'button-icon ' + extensibleViews[view]['iconClass']}/>
);
- }
+ }
+ }
+
+ if (configurableViewsConfig && configurableViewsConfig.layouts) {
+ for (let configurableView in configurableViewsConfig.layouts) {
+ menuOptions.push(
+ <ConfigurableMenuItem key={configurableViewsConfig.layouts[configurableView]['id'] + 'Menu'} to={'/' + configurableViewsConfig.layouts[configurableView]['id']}
+ label={configurableViewsConfig.layouts[configurableView]['title']}/>
+ );
+ }
}
let secondaryTitleClass = 'secondary-header';
@@ -290,8 +325,8 @@ class MainScreenHeader extends Component {
<div>
<Button
bsClass={(toggleButtonActive)
- ? 'toggle-view-button-active'
- : 'toggle-view-button'}
+ ? 'toggle-view-button-active'
+ : 'toggle-view-button'}
onClick={onShowMenu}>
<FontAwesome name='bars'/>
</Button>
diff --git a/src/app/MainScreenWrapper.jsx b/src/app/MainScreenWrapper.jsx
index 6689af9..730ac93 100644
--- a/src/app/MainScreenWrapper.jsx
+++ b/src/app/MainScreenWrapper.jsx
@@ -25,6 +25,10 @@ import TierSupport from './tierSupport/TierSupport.jsx';
import VnfSearch from './vnfSearch/VnfSearch.jsx';
import MainScreenHeader from './MainScreenHeader.jsx';
import {decryptParamsForView, changeUrlAddress} from 'utils/Routes.js';
+import {
+ getConfigurableViewConfigs,
+ setCustomRoutes
+} from 'app/configurableViews/ConfigurableViewActions.js';
import {isEmpty} from 'lodash';
import {genericRequest} from 'app/networking/NetworkCalls.js';
import {
@@ -42,18 +46,36 @@ import {
} from './MainScreenWrapperActionHelper.js';
import extensibleViews from 'resources/views/extensibleViews.json';
+import customComponentConfig from 'resources/views/customComponents.json';
+import { newCustomComponentsEvent } from 'app/configurableViews/ConfigurableViewActions.js';
+import {
+ getConfigurableRoutes
+} from 'app/configurableViews/ConfigurableViewManager.js';
+
+import {
+ getConfiguredComponentList
+} from 'app/configurableViews/index.js';
-const mapStateToProps = ({mainWrapper}) => {
+const mapStateToProps = ({mainWrapper, configurableViews}) => {
let {
showMenu = false,
toggleButtonActive = false,
extensibleViewNetworkCallbackData = {}
} = mainWrapper;
+ let {
+ configurableViewsConfig = {},
+ customComponents = {},
+ customRoutes = []
+ } = configurableViews;
+
return {
showMenu,
toggleButtonActive,
- extensibleViewNetworkCallbackData
+ extensibleViewNetworkCallbackData,
+ configurableViewsConfig,
+ customComponents,
+ customRoutes
};
};
@@ -68,6 +90,15 @@ const mapActionsToProps = (dispatch) => {
},
onOverlayNetworkCallback: (apiUrl, body, viewName, curViewData, responseEventKey) => {
dispatch(overlayNetworkCallback(apiUrl, body, viewName, curViewData, responseEventKey));
+ },
+ onConfigurableViewsInitialLoad: (components) => {
+ dispatch(newCustomComponentsEvent(components));
+ },
+ onFetchCustomViews: () => {
+ dispatch(getConfigurableViewConfigs());
+ },
+ onSetCustomRoutes: (routes) => {
+ dispatch(setCustomRoutes(routes));
}
};
};
@@ -82,6 +113,25 @@ class MainScreenWrapper extends Component {
}
+ componentDidMount() {
+ // fetch custom views
+ this.props.onFetchCustomViews();
+
+ // fetch custom components
+ let components = getConfiguredComponentList(customComponentConfig);
+ this.props.onConfigurableViewsInitialLoad(components);
+ }
+
+ componentDidUpdate(prevProps) {
+ if ((Object.keys(this.props.customComponents).length > 0 &&
+ Object.keys(this.props.configurableViewsConfig).length > 0) &&
+ ((JSON.stringify(prevProps.configurableViewsConfig) !== JSON.stringify(this.props.configurableViewsConfig)) ||
+ (JSON.stringify(prevProps.customComponents) !== JSON.stringify(this.props.customComponents)))) {
+ // we have both config and components populated and one was just set
+ let customRoutes = getConfigurableRoutes(this.props.configurableViewsConfig, this.props.customComponents);
+ this.props.onSetCustomRoutes(customRoutes);
+ }
+ }
render() {
@@ -89,14 +139,14 @@ class MainScreenWrapper extends Component {
onExtensibleViewNetworkCallback,
extensibleViewNetworkCallbackData,
onExtensibleViewMessageCallback,
- onOverlayNetworkCallback
+ onOverlayNetworkCallback,
+ customRoutes
} = this.props;
let customViewList = [];
extensibleViews.forEach(function(view,key) {
- let path = '',
- extKey = '';
+ let path = '', extKey = '';
if(isEmpty(extensibleViews[key]['viewParams'])){
path = '/' + view.viewName + '/:extensibleViewParams?';
extKey = view.viewName + 'Route';
@@ -140,13 +190,13 @@ class MainScreenWrapper extends Component {
if(isEmpty(extensibleViews[key]['isExact']) && !extensibleViews[key]['isExact']){
customViewList.push(
<Route key={extKey} path={path} render={renderComponent}/>
- );
+ );
} else {
customViewList.push(
<Route key={extKey} exact path={path} render={renderComponent}/>
- );
+ );
}
-
+
});
return (
@@ -159,6 +209,7 @@ class MainScreenWrapper extends Component {
<Route key='TierSupportRoue' path='/schema/:viParam?' component={TierSupport}/>
<Route key='VnfSearchRoute' path='/vnfSearch/:filters?' component={VnfSearch}/>
{customViewList}
+ {customRoutes}
</div>
</Router>
);
diff --git a/src/app/MainScreenWrapperActionHelper.js b/src/app/MainScreenWrapperActionHelper.js
index 371ea42..dd7450b 100644
--- a/src/app/MainScreenWrapperActionHelper.js
+++ b/src/app/MainScreenWrapperActionHelper.js
@@ -136,7 +136,6 @@ export function extensibleViewNetworkCallback(urlApi, postBody, paramName, curVi
() => fetchRequestObj(BASE_URL + urlApi, POST,
POST_HEADER, postBody);
-
return dispatch => {
dispatch(extensibleViewData(dataFetchRequest, paramName, curViewData));
};
diff --git a/src/app/configurableViews/ConfigurableViewActions.js b/src/app/configurableViews/ConfigurableViewActions.js
new file mode 100644
index 0000000..7cffacc
--- /dev/null
+++ b/src/app/configurableViews/ConfigurableViewActions.js
@@ -0,0 +1,48 @@
+import {
+ GET,
+ POST_HEADER
+} from 'app/networking/NetworkConstants.js';
+import {
+ GET_LAYOUTS_URL,
+ configurableViewsActionTypes
+} from './ConfigurableViewConstants.js';
+
+function createConfigReceivedEvent(config) {
+ return {
+ type: configurableViewsActionTypes.CONFIGURABLE_VIEWS_CONFIG_RECEIVED,
+ data: config
+ };
+}
+
+export function newCustomComponentsEvent(components) {
+ return {
+ type: configurableViewsActionTypes.CUSTOM_COMPONENTS_RECEIVED,
+ data: components
+ };
+}
+
+export function setCustomRoutes(routes) {
+ return {
+ type: configurableViewsActionTypes.CUSTOM_ROUTES,
+ data: routes
+ };
+}
+
+export function getConfigurableViewConfigs() {
+ return dispatch => {
+ return fetch(GET_LAYOUTS_URL, {
+ method: GET,
+ headers: POST_HEADER
+ }).then(
+ (response) => response.json()
+ ).then(
+ (responseJson) => {
+ dispatch(createConfigReceivedEvent(responseJson));
+ }
+ ).catch(
+ (err) => {
+ console.log(`problems fetching configurable view configs: ${err}`);
+ }
+ );
+ };
+}
diff --git a/src/app/configurableViews/ConfigurableViewConstants.js b/src/app/configurableViews/ConfigurableViewConstants.js
new file mode 100644
index 0000000..202dd18
--- /dev/null
+++ b/src/app/configurableViews/ConfigurableViewConstants.js
@@ -0,0 +1,11 @@
+import keyMirror from 'utils/KeyMirror.js';
+import {BASE_URL} from 'app/networking/NetworkConstants.js';
+
+export const configurableViewsActionTypes = keyMirror({
+ CONFIGURABLE_VIEWS_CONFIG_RECEIVED: null,
+ CONFIGURABLE_VIEWS_DATA_RECEIVED: null,
+ CUSTOM_ROUTES: null,
+ CUSTOM_COMPONENTS_RECEIVED: null
+});
+
+export const GET_LAYOUTS_URL = BASE_URL + '/layouts';
diff --git a/src/app/configurableViews/ConfigurableViewManager.js b/src/app/configurableViews/ConfigurableViewManager.js
new file mode 100644
index 0000000..71cc6cf
--- /dev/null
+++ b/src/app/configurableViews/ConfigurableViewManager.js
@@ -0,0 +1,27 @@
+import React from 'react';
+import {
+ Route
+} from 'react-router-dom';
+import { fetchConfigurableViewRequest } from 'app/networking/NetworkCalls';
+
+export function getConfigurableRoutes(config, components) {
+ let routes = [];
+ if (config && Object.keys(config).length > 0 && components && Object.keys(components).length > 0) {
+ config.layouts.forEach( (viewConfig) => {
+ let ConfigurableView = components[viewConfig.viewType];
+ if (ConfigurableView) {
+ routes.push(
+ <Route key={viewConfig.id} path={`/${viewConfig.id}`} render={ () => {
+ return (
+ <ConfigurableView
+ config={ viewConfig }
+ networkAPI={ fetchConfigurableViewRequest }/>
+ );
+ }}/>
+ );
+ }
+ });
+ }
+
+ return routes;
+}
diff --git a/src/app/configurableViews/ConfigurableViewReducer.js b/src/app/configurableViews/ConfigurableViewReducer.js
new file mode 100644
index 0000000..9a5eee0
--- /dev/null
+++ b/src/app/configurableViews/ConfigurableViewReducer.js
@@ -0,0 +1,26 @@
+import {
+ configurableViewsActionTypes
+} from './ConfigurableViewConstants.js';
+
+export default (state = {}, action) => {
+ let data = action.data;
+ switch (action.type) {
+ case configurableViewsActionTypes.CONFIGURABLE_VIEWS_CONFIG_RECEIVED:
+ return {
+ ...state,
+ configurableViewsConfig: data
+ };
+ case configurableViewsActionTypes.CUSTOM_COMPONENTS_RECEIVED:
+ return {
+ ...state,
+ customComponents: data
+ };
+ case configurableViewsActionTypes.CUSTOM_ROUTES:
+ return {
+ ...state,
+ customRoutes: data
+ };
+ }
+
+ return state;
+};
diff --git a/src/app/configurableViews/index.js b/src/app/configurableViews/index.js
new file mode 100644
index 0000000..3490fef
--- /dev/null
+++ b/src/app/configurableViews/index.js
@@ -0,0 +1,27 @@
+/*
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017-2018 Amdocs
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+// Import section (used as anchor to add extension imports)
+export function getConfiguredComponentList() {
+ let components = {};
+
+ // Components section (used as an anchor to add extension components)
+ return components;
+}
diff --git a/src/app/networking/NetworkCalls.js b/src/app/networking/NetworkCalls.js
index 63c08ed..e391391 100644
--- a/src/app/networking/NetworkCalls.js
+++ b/src/app/networking/NetworkCalls.js
@@ -32,6 +32,16 @@ function fetchRequest(URL, POST, POST_HEADER, BODY) {
);
}
+const fetchConfigurableViewRequest = (queryData) => {
+ const URL = `${BASE_URL}${queryData.api}`;
+ return fetch(URL, {
+ credentials: 'same-origin',
+ method: queryData.method,
+ headers: queryData.headers,
+ body: JSON.stringify(queryData.componentDataDescriptor)
+ });
+};
+
function fetchRequestObj(URL, POST, POST_HEADER, BODY) {
return fetch(URL, {
credentials: 'same-origin',
@@ -72,25 +82,6 @@ module.exports = {
fetchRequest: fetchRequest,
fetchRequestObj: fetchRequestObj,
getRequest: getRequest,
+ fetchConfigurableViewRequest: fetchConfigurableViewRequest,
genericRequest: genericRequest
};
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/app/tierSupport/TierSupportActions.js b/src/app/tierSupport/TierSupportActions.js
index 08e4e30..afb37be 100644
--- a/src/app/tierSupport/TierSupportActions.js
+++ b/src/app/tierSupport/TierSupportActions.js
@@ -18,24 +18,13 @@
* limitations under the License.
* ============LICENSE_END=========================================================
*/
-import {tierSupportActionTypes,
- TS_BACKEND_SEARCH_SELECTED_NODE_URL} from 'app/tierSupport/TierSupportConstants.js';
import {
- POST,
- POST_HEADER,
- ERROR_RETRIEVING_DATA,
- NO_RESULTS_FOUND
-} from 'app/networking/NetworkConstants.js';
-import networkCall from 'app/networking/NetworkCalls.js';
+ tierSupportActionTypes
+} from 'app/tierSupport/TierSupportConstants.js';
import {
getSetGlobalMessageEvent,
getClearGlobalMessageEvent
} from 'app/globalInlineMessageBar/GlobalInlineMessageBarActions.js';
-import {
- STATUS_CODE_204_NO_CONTENT,
- STATUS_CODE_3XX_REDIRECTION,
- STATUS_CODE_5XX_SERVER_ERROR
-} from 'utils/GlobalConstants.js';
function createOnNodeDetailsChangeEvent(newDetails) {
return {
@@ -76,118 +65,12 @@ export function onNodeMenuChange(selectedMenu) {
};
}
-function createNodeDetailsFoundEvent(nodeDetails) {
- return {
- type: tierSupportActionTypes.TS_NODE_SEARCH_RESULTS,
- data: nodeDetails
- };
-}
-
-function createSelectedNodeDetails(nodeDetails) {
- var selectedNodeDetail;
- for(let i = 0; i < nodeDetails.nodes.length; i++) {
- if(nodeDetails.nodes[i].nodeMeta.className === 'selectedSearchedNodeClass') {
- selectedNodeDetail = nodeDetails.nodes[i];
- break;
- }
- }
- return {
- type: tierSupportActionTypes.TS_GRAPH_NODE_SELECTED,
- data: selectedNodeDetail
- };
-}
-
-function noNodeDetailsFoundEvent(errorText) {
- return {
- type: tierSupportActionTypes.TS_NODE_SEARCH_NO_RESULTS,
- data: {errorMsg: errorText}
- };
-}
-
-function getInvalidSelectedNodeSearchEvent(errorText) {
- return {
- type: tierSupportActionTypes.TIER_SUPPORT_NETWORK_ERROR,
- data: {value: errorText, errorMsg: ERROR_RETRIEVING_DATA}
- };
-}
-
export function clearVIData() {
return {
type: tierSupportActionTypes.TIER_SUPPORT_CLEAR_DATA
};
}
-function setBusyFeedback(){
- return {
- type: tierSupportActionTypes.TIER_SUPPORT_ACTIVATE_BUSY_FEEDBACK
- };
-}
-
-function disableBusyFeedback(){
- return {
- type: tierSupportActionTypes.TIER_SUPPORT_DISABLE_BUSY_FEEDBACK
- };
-}
-
-export function fetchSelectedNodeElement(fetchRequestCallback) {
- return dispatch => {
- return fetchRequestCallback().then(
- (response) => {
- if (response.status === STATUS_CODE_204_NO_CONTENT || response.status >= STATUS_CODE_3XX_REDIRECTION) {
- return Promise.reject(new Error(response.status));
- } else {
- // assume 200 status
- return response.json();
- }
- }
- ).then(
- (responseJson) => {
- if (responseJson.nodes.length > 0) {
- dispatch(createNodeDetailsFoundEvent(responseJson));
- dispatch(createSelectedNodeDetails(responseJson));
- } else {
- dispatch(noNodeDetailsFoundEvent(NO_RESULTS_FOUND));
- }
- }
- ).then(
- () => {
- dispatch(disableBusyFeedback());
- }
- ).catch(
- (errorCode) => {
- dispatch(disableBusyFeedback());
- if (errorCode.message >= STATUS_CODE_5XX_SERVER_ERROR) {
- dispatch(getInvalidSelectedNodeSearchEvent(ERROR_RETRIEVING_DATA));
- } else {
- // TODO - assuming 204 status, but should include additional
- // statuses in the future with proper messaging in order to return
- // better messaging
- dispatch(noNodeDetailsFoundEvent(NO_RESULTS_FOUND));
- }
- }
- );
- };
-}
-
-export function querySelectedNodeElement(
- searchHashId, selectedNodeFetchRequest) {
- let payload = {
- hashId: searchHashId
- };
-
- if (selectedNodeFetchRequest === undefined) {
- let postBody = JSON.stringify(payload);
- selectedNodeFetchRequest =
- () => networkCall.fetchRequestObj(TS_BACKEND_SEARCH_SELECTED_NODE_URL, POST,
- POST_HEADER, postBody);
- }
-
- return dispatch => {
- dispatch(setBusyFeedback());
- dispatch(fetchSelectedNodeElement(selectedNodeFetchRequest));
- };
-}
-
export function setNotificationText(msgText, msgSeverity) {
if (msgText.length > 0) {
return dispatch => {
diff --git a/src/generic-components/autoCompleteSearchBar/AutoCompleteSearchBar.jsx b/src/generic-components/autoCompleteSearchBar/AutoCompleteSearchBar.jsx
index b7fca67..4f93125 100644
--- a/src/generic-components/autoCompleteSearchBar/AutoCompleteSearchBar.jsx
+++ b/src/generic-components/autoCompleteSearchBar/AutoCompleteSearchBar.jsx
@@ -94,13 +94,13 @@ export default class AutoCompleteSearchBar extends Component {
render() {
const {
- value, suggestions,
- suggestionName, cachedSuggestions,
- onInputChange, onInvalidSearch,
- onClearSuggestionsTextFieldRequested,
- onSuggestionsClearRequested,
- dispatchAnalytics
- } = this.props;
+ value, suggestions,
+ suggestionName, cachedSuggestions,
+ onInputChange, onInvalidSearch,
+ onClearSuggestionsTextFieldRequested,
+ onSuggestionsClearRequested,
+ dispatchAnalytics
+ } = this.props;
const inputProps = {
placeholder: SEARCH_PLACEHOLDER_TEXT,
value,
@@ -201,7 +201,7 @@ export default class AutoCompleteSearchBar extends Component {
rest.className = 'react-autosuggest__suggestions-containerCopy';
}
return (
- <div {...rest}>
+ <div {...rest.containerProps} {...rest}>
{children}
</div>
);
diff --git a/src/generic-components/componentManager/ComponentManagerContainer.jsx b/src/generic-components/componentManager/ComponentManagerContainer.jsx
index 02a3eba..cd51d37 100644
--- a/src/generic-components/componentManager/ComponentManagerContainer.jsx
+++ b/src/generic-components/componentManager/ComponentManagerContainer.jsx
@@ -18,7 +18,7 @@
* limitations under the License.
* ============LICENSE_END=========================================================
*/
-import React, {Component, PropTypes} from 'react';
+import React, {Component} from 'react';
import { PropTypes } from 'prop-types';
import ButtonGroup from 'react-bootstrap/lib/ButtonGroup';
import Button from 'react-bootstrap/lib/Button';
@@ -53,13 +53,13 @@ export default class ComponentManagerContainer extends Component {
render() {
let {
- title,
- actions,
- children,
- showHeader,
- showTitle,
- showBorder
- } = this.props;
+ title,
+ actions,
+ children,
+ showHeader,
+ showTitle,
+ showBorder
+ } = this.props;
let buttons = [];
actions.forEach((action) => {
switch (action.type) {
diff --git a/src/generic-components/graph/Link.jsx b/src/generic-components/graph/Link.jsx
index aec33b8..8c87ac5 100644
--- a/src/generic-components/graph/Link.jsx
+++ b/src/generic-components/graph/Link.jsx
@@ -24,39 +24,39 @@ import { PropTypes } from 'prop-types';
import TempCreateAttributes from './TempCreateAttributes.js';
class Link extends Component {
-
- static propTypes = {
- x1: PropTypes.number,
- y1: PropTypes.number,
- x2: PropTypes.number,
- y2: PropTypes.number,
- linkAttributes: PropTypes.object
- };
-
- static defaultProps = {
- x1: 0,
- y1: 0,
- x2: 0,
- y2: 0,
- linkAttributes: {}
- };
-
- render() {
- let {x1, y1, x2, y2, linkAttributes} = this.props;
-
- let combinedAttributes = {
- ...linkAttributes,
- x1: x1,
- y1: y1,
- x2: x2,
- y2: y2
- };
-
- return (
- <line {...combinedAttributes}
- style={TempCreateAttributes.createLineStyle()}/>
- );
- }
+
+ static propTypes = {
+ x1: PropTypes.number,
+ y1: PropTypes.number,
+ x2: PropTypes.number,
+ y2: PropTypes.number,
+ linkAttributes: PropTypes.object
+ };
+
+ static defaultProps = {
+ x1: 0,
+ y1: 0,
+ x2: 0,
+ y2: 0,
+ linkAttributes: {}
+ };
+
+ render() {
+ let {x1, y1, x2, y2, linkAttributes} = this.props;
+
+ let combinedAttributes = {
+ ...linkAttributes,
+ x1: x1,
+ y1: y1,
+ x2: x2,
+ y2: y2
+ };
+
+ return (
+ <line {...combinedAttributes}
+ style={TempCreateAttributes.createLineStyle()}/>
+ );
+ }
}
export default Link;
diff --git a/src/generic-components/graph/Node.jsx b/src/generic-components/graph/Node.jsx
index 6de4715..67d954c 100644
--- a/src/generic-components/graph/Node.jsx
+++ b/src/generic-components/graph/Node.jsx
@@ -22,33 +22,33 @@ import React, {Component} from 'react';
import { PropTypes } from 'prop-types';
class Node extends Component {
-
- static propTypes = {
- x: PropTypes.number,
- y: PropTypes.number,
- nodeClass: PropTypes.string,
- visualElements: PropTypes.array,
- meta: PropTypes.object
- };
-
- static defaultProps = {
- x: 0,
- y: 0,
- nodeClass: '',
- visualElements: [],
- meta: {}
- };
-
- render() {
- let {x, y, nodeClass, visualElements} = this.props;
- let translate = `translate(${x}, ${y})`;
-
- return (
- <g className={nodeClass} transform={translate}>
- {visualElements}
- </g>
- );
- }
+
+ static propTypes = {
+ x: PropTypes.number,
+ y: PropTypes.number,
+ nodeClass: PropTypes.string,
+ visualElements: PropTypes.array,
+ meta: PropTypes.object
+ };
+
+ static defaultProps = {
+ x: 0,
+ y: 0,
+ nodeClass: '',
+ visualElements: [],
+ meta: {}
+ };
+
+ render() {
+ let {x, y, nodeClass, visualElements} = this.props;
+ let translate = `translate(${x}, ${y})`;
+
+ return (
+ <g className={nodeClass} transform={translate}>
+ {visualElements}
+ </g>
+ );
+ }
}
export default Node;
diff --git a/src/generic-components/graph/SVGShape.jsx b/src/generic-components/graph/SVGShape.jsx
index b06c46f..8b33598 100644
--- a/src/generic-components/graph/SVGShape.jsx
+++ b/src/generic-components/graph/SVGShape.jsx
@@ -23,39 +23,39 @@ import { PropTypes } from 'prop-types';
import NodeVisualElementConstants from './NodeVisualElementConstants';
class SVGShape extends Component {
-
- static propTypes = {
- shapeType: PropTypes.string.isRequired,
- shapeAttributes: PropTypes.object.isRequired,
- shapeClass: PropTypes.object.isRequired,
- textValue: PropTypes.string
- };
-
- static defaultProps = {
- shapeType: '',
- shapeAttributes: {},
- shapeClass: {},
- textValue: ''
- };
-
- render() {
- let {shapeType, shapeAttributes, shapeClass, textValue} = this.props;
-
- switch (shapeType) {
- case NodeVisualElementConstants.SVG_CIRCLE:
- return <circle {...shapeAttributes} className={shapeClass}/>;
-
- case NodeVisualElementConstants.SVG_LINELINE:
- return <line {...shapeAttributes} className={shapeClass}/>;
-
- case NodeVisualElementConstants.TEXT:
- return <text {...shapeAttributes}
- className={shapeClass}>{textValue}</text>;
-
- default:
- return undefined;
- }
- }
+
+ static propTypes = {
+ shapeType: PropTypes.string.isRequired,
+ shapeAttributes: PropTypes.object.isRequired,
+ shapeClass: PropTypes.object.isRequired,
+ textValue: PropTypes.string
+ };
+
+ static defaultProps = {
+ shapeType: '',
+ shapeAttributes: {},
+ shapeClass: {},
+ textValue: ''
+ };
+
+ render() {
+ let {shapeType, shapeAttributes, shapeClass, textValue} = this.props;
+
+ switch (shapeType) {
+ case NodeVisualElementConstants.SVG_CIRCLE:
+ return <circle {...shapeAttributes} className={shapeClass}/>;
+
+ case NodeVisualElementConstants.SVG_LINELINE:
+ return <line {...shapeAttributes} className={shapeClass}/>;
+
+ case NodeVisualElementConstants.TEXT:
+ return <text {...shapeAttributes}
+ className={shapeClass}>{textValue}</text>;
+
+ default:
+ return undefined;
+ }
+ }
}
export default SVGShape;
diff --git a/src/generic-components/input/ToggleInput.jsx b/src/generic-components/input/ToggleInput.jsx
index 49b0376..f68758a 100644
--- a/src/generic-components/input/ToggleInput.jsx
+++ b/src/generic-components/input/ToggleInput.jsx
@@ -23,54 +23,54 @@ import { PropTypes } from 'prop-types';
export default
class ToggleInput extends React.Component {
-
- static propTypes = {
- label: PropTypes.node,
- value: PropTypes.bool,
- onChange: PropTypes.func,
- disabled: PropTypes.bool
- }
-
- static defaultProps = {
- value: false,
- label: ''
- }
-
- state = {
- value: this.props.value
- }
-
- status() {
- return this.state.value ? 'on' : 'off';
- }
-
- render() {
- let {label, disabled} = this.props;
- let checked = this.status() === 'on';
- return (
- <div className='toggle-input-wrapper form-group'
- onClick={!disabled && this.click}>
- <div className='toggle-input-label'>{label}</div>
- <div className='toggle-switch'>
- <input className='toggle toggle-round-flat' type='checkbox'
- checked={checked} readOnly/>
- <label></label>
- </div>
- </div>
- );
- }
-
- click = () => {
- let value = !this.state.value;
- this.setState({value});
-
- let onChange = this.props.onChange;
- if (onChange) {
- onChange(value);
- }
- }
-
- getValue() {
- return this.state.value;
- }
+
+ static propTypes = {
+ label: PropTypes.node,
+ value: PropTypes.bool,
+ onChange: PropTypes.func,
+ disabled: PropTypes.bool
+ }
+
+ static defaultProps = {
+ value: false,
+ label: ''
+ }
+
+ state = {
+ value: this.props.value
+ }
+
+ status() {
+ return this.state.value ? 'on' : 'off';
+ }
+
+ render() {
+ let {label, disabled} = this.props;
+ let checked = this.status() === 'on';
+ return (
+ <div className='toggle-input-wrapper form-group'
+ onClick={!disabled && this.click}>
+ <div className='toggle-input-label'>{label}</div>
+ <div className='toggle-switch'>
+ <input className='toggle toggle-round-flat' type='checkbox'
+ checked={checked} readOnly/>
+ <label></label>
+ </div>
+ </div>
+ );
+ }
+
+ click = () => {
+ let value = !this.state.value;
+ this.setState({value});
+
+ let onChange = this.props.onChange;
+ if (onChange) {
+ onChange(value);
+ }
+ }
+
+ getValue() {
+ return this.state.value;
+ }
}
diff --git a/src/generic-components/input/inputOptions/InputOptions.jsx b/src/generic-components/input/inputOptions/InputOptions.jsx
index bb9d777..bf17df1 100644
--- a/src/generic-components/input/inputOptions/InputOptions.jsx
+++ b/src/generic-components/input/inputOptions/InputOptions.jsx
@@ -27,215 +27,215 @@ import Select from 'generic-components/input/SelectInput.jsx';
export const other = {OTHER: 'Other'};
class InputOptions extends React.Component {
-
- static propTypes = {
- values: PropTypes.arrayOf(PropTypes.shape({
- enum: PropTypes.string,
- title: PropTypes.string
- })),
- isEnabledOther: PropTypes.bool,
- title: PropTypes.string,
- selectedValue: PropTypes.string,
- multiSelectedEnum: PropTypes.array,
- selectedEnum: PropTypes.string,
- otherValue: PropTypes.string,
- onEnumChange: PropTypes.func,
- onOtherChange: PropTypes.func,
- isRequired: PropTypes.bool,
- isMultiSelect: PropTypes.bool
- };
-
-
- static contextTypes = {
- isReadOnlyMode: PropTypes.bool
- };
-
- state = {
- otherInputDisabled: !this.props.otherValue
- };
-
- oldProps = {
- selectedEnum: '',
- otherValue: '',
- multiSelectedEnum: []
- };
-
- render() {
- let {label, isRequired, values, otherValue, onOtherChange, isMultiSelect, onBlur, multiSelectedEnum, selectedEnum, hasError, validations, children} = this.props;
-
- let currentMultiSelectedEnum = [];
- let currentSelectedEnum = '';
- let {otherInputDisabled} = this.state;
- if (isMultiSelect) {
- currentMultiSelectedEnum = multiSelectedEnum;
- if (!otherInputDisabled) {
- currentSelectedEnum =
- multiSelectedEnum ? multiSelectedEnum.toString() : undefined;
- }
- }
- else {
- currentSelectedEnum = selectedEnum;
- }
-
- let isReadOnlyMode = this.context.isReadOnlyMode;
-
- return (
- <div
- className={classNames('form-group', {'required' : validations.required , 'has-error' : hasError})}>
- <label className='control-label'>{label}</label>
- {isMultiSelect && otherInputDisabled ?
- <Select
- ref='_myInput'
- value={currentMultiSelectedEnum}
- className='options-input'
- clearable={false}
- required={isRequired}
- disabled={isReadOnlyMode || Boolean(this.props.disabled)}
- onBlur={() => onBlur()}
- onMultiSelectChanged={value => this.multiSelectEnumChanged(value)}
- options={this.renderMultiSelectOptions(values)}
- multi/> :
- <div className={classNames('input-options',{'has-error' : hasError})}>
- <select
- ref={'_myInput'}
- label={label}
- className='form-control input-options-select'
- value={currentSelectedEnum}
- style={{'width' : otherInputDisabled ? '100%' : '95px'}}
- onBlur={() => onBlur()}
- disabled={isReadOnlyMode || Boolean(this.props.disabled)}
- onChange={ value => this.enumChanged(value)}
- type='select'>
- {values &&
- values.length &&
- values.map(val => this.renderOptions(val))}
- {onOtherChange && <option key='other'
- value={other.OTHER}>{i18n(
- other.OTHER)}</option>}
- {children}
- </select>
-
- {!otherInputDisabled && <div className='input-options-separator'/>}
- <input
- className='form-control input-options-other'
- placeholder={i18n('other')}
- ref='_otherValue'
- style={{'display' : otherInputDisabled ? 'none' : 'block'}}
- disabled={isReadOnlyMode || Boolean(this.props.disabled)}
- value={otherValue || ''}
- onBlur={() => onBlur()}
- onChange={() => this.changedOtherInput()}/>
- </div>
- }
- </div>
- );
- }
-
- renderOptions(val) {
- return (
- <option key={val.enum} value={val.enum}>{val.title}</option>
- );
- }
-
-
- renderMultiSelectOptions(values) {
- let {onOtherChange} = this.props;
- let optionsList = [];
- if (onOtherChange) {
- optionsList = values.map(option => {
- return {
- label: option.title,
- value: option.enum,
- };
- }).concat([{
- label: i18n(other.OTHER),
- value: i18n(other.OTHER),
- }]);
- }
- else {
- optionsList = values.map(option => {
- return {
- label: option.title,
- value: option.enum,
- };
- });
- }
- if (optionsList.length > 0 && optionsList[0].value === '') {
- optionsList.shift();
- }
- return optionsList;
- }
-
- getValue() {
- let res = '';
- let {isMultiSelect} = this.props;
- let {otherInputDisabled} = this.state;
-
- if (otherInputDisabled) {
- res =
- isMultiSelect
- ? this.refs._myInput.getValue()
- : this.refs._myInput.value;
- } else {
- res = this.refs._otherValue.value;
- }
- return res;
- }
-
- enumChanged() {
- let enumValue = this.refs._myInput.value;
- let {onEnumChange, isMultiSelect, onChange} = this.props;
- this.setState({
- otherInputDisabled: enumValue !== other.OTHER
- });
- if (onEnumChange) {
- onEnumChange(isMultiSelect ? [enumValue] : enumValue);
- }
-
- if (onChange) {
- onChange(enumValue);
- }
-
- }
-
- multiSelectEnumChanged(enumValue) {
- let {onEnumChange} = this.props;
- let selectedValues = enumValue.map(enumVal => {
- return enumVal.value;
- });
-
- if (this.state.otherInputDisabled === false) {
- selectedValues.shift();
- }
- else if (selectedValues.includes(i18n(other.OTHER))) {
- selectedValues = [i18n(other.OTHER)];
- }
-
- this.setState({
- otherInputDisabled: !selectedValues.includes(i18n(other.OTHER))
- });
- onEnumChange(selectedValues);
- }
-
- changedOtherInput() {
- let {onOtherChange} = this.props;
- onOtherChange(this.refs._otherValue.value);
- }
-
- componentDidUpdate() {
- let {otherValue, selectedEnum, onInputChange, multiSelectedEnum} = this.props;
- if (this.oldProps.otherValue !== otherValue
- || this.oldProps.selectedEnum !== selectedEnum
- || this.oldProps.multiSelectedEnum !== multiSelectedEnum) {
- this.oldProps = {
- otherValue,
- selectedEnum,
- multiSelectedEnum
- };
- onInputChange();
- }
- }
-
+
+ static propTypes = {
+ values: PropTypes.arrayOf(PropTypes.shape({
+ enum: PropTypes.string,
+ title: PropTypes.string
+ })),
+ isEnabledOther: PropTypes.bool,
+ title: PropTypes.string,
+ selectedValue: PropTypes.string,
+ multiSelectedEnum: PropTypes.array,
+ selectedEnum: PropTypes.string,
+ otherValue: PropTypes.string,
+ onEnumChange: PropTypes.func,
+ onOtherChange: PropTypes.func,
+ isRequired: PropTypes.bool,
+ isMultiSelect: PropTypes.bool
+ };
+
+
+ static contextTypes = {
+ isReadOnlyMode: PropTypes.bool
+ };
+
+ state = {
+ otherInputDisabled: !this.props.otherValue
+ };
+
+ oldProps = {
+ selectedEnum: '',
+ otherValue: '',
+ multiSelectedEnum: []
+ };
+
+ render() {
+ let {label, isRequired, values, otherValue, onOtherChange, isMultiSelect, onBlur, multiSelectedEnum, selectedEnum, hasError, validations, children} = this.props;
+
+ let currentMultiSelectedEnum = [];
+ let currentSelectedEnum = '';
+ let {otherInputDisabled} = this.state;
+ if (isMultiSelect) {
+ currentMultiSelectedEnum = multiSelectedEnum;
+ if (!otherInputDisabled) {
+ currentSelectedEnum =
+ multiSelectedEnum ? multiSelectedEnum.toString() : undefined;
+ }
+ }
+ else {
+ currentSelectedEnum = selectedEnum;
+ }
+
+ let isReadOnlyMode = this.context.isReadOnlyMode;
+
+ return (
+ <div
+ className={classNames('form-group', {'required' : validations.required , 'has-error' : hasError})}>
+ <label className='control-label'>{label}</label>
+ {isMultiSelect && otherInputDisabled ?
+ <Select
+ ref='_myInput'
+ value={currentMultiSelectedEnum}
+ className='options-input'
+ clearable={false}
+ required={isRequired}
+ disabled={isReadOnlyMode || Boolean(this.props.disabled)}
+ onBlur={() => onBlur()}
+ onMultiSelectChanged={value => this.multiSelectEnumChanged(value)}
+ options={this.renderMultiSelectOptions(values)}
+ multi/> :
+ <div className={classNames('input-options',{'has-error' : hasError})}>
+ <select
+ ref={'_myInput'}
+ label={label}
+ className='form-control input-options-select'
+ value={currentSelectedEnum}
+ style={{'width' : otherInputDisabled ? '100%' : '95px'}}
+ onBlur={() => onBlur()}
+ disabled={isReadOnlyMode || Boolean(this.props.disabled)}
+ onChange={ value => this.enumChanged(value)}
+ type='select'>
+ {values &&
+ values.length &&
+ values.map(val => this.renderOptions(val))}
+ {onOtherChange && <option key='other'
+ value={other.OTHER}>{i18n(
+ other.OTHER)}</option>}
+ {children}
+ </select>
+
+ {!otherInputDisabled && <div className='input-options-separator'/>}
+ <input
+ className='form-control input-options-other'
+ placeholder={i18n('other')}
+ ref='_otherValue'
+ style={{'display' : otherInputDisabled ? 'none' : 'block'}}
+ disabled={isReadOnlyMode || Boolean(this.props.disabled)}
+ value={otherValue || ''}
+ onBlur={() => onBlur()}
+ onChange={() => this.changedOtherInput()}/>
+ </div>
+ }
+ </div>
+ );
+ }
+
+ renderOptions(val) {
+ return (
+ <option key={val.enum} value={val.enum}>{val.title}</option>
+ );
+ }
+
+
+ renderMultiSelectOptions(values) {
+ let {onOtherChange} = this.props;
+ let optionsList = [];
+ if (onOtherChange) {
+ optionsList = values.map(option => {
+ return {
+ label: option.title,
+ value: option.enum,
+ };
+ }).concat([{
+ label: i18n(other.OTHER),
+ value: i18n(other.OTHER),
+ }]);
+ }
+ else {
+ optionsList = values.map(option => {
+ return {
+ label: option.title,
+ value: option.enum,
+ };
+ });
+ }
+ if (optionsList.length > 0 && optionsList[0].value === '') {
+ optionsList.shift();
+ }
+ return optionsList;
+ }
+
+ getValue() {
+ let res = '';
+ let {isMultiSelect} = this.props;
+ let {otherInputDisabled} = this.state;
+
+ if (otherInputDisabled) {
+ res =
+ isMultiSelect
+ ? this.refs._myInput.getValue()
+ : this.refs._myInput.value;
+ } else {
+ res = this.refs._otherValue.value;
+ }
+ return res;
+ }
+
+ enumChanged() {
+ let enumValue = this.refs._myInput.value;
+ let {onEnumChange, isMultiSelect, onChange} = this.props;
+ this.setState({
+ otherInputDisabled: enumValue !== other.OTHER
+ });
+ if (onEnumChange) {
+ onEnumChange(isMultiSelect ? [enumValue] : enumValue);
+ }
+
+ if (onChange) {
+ onChange(enumValue);
+ }
+
+ }
+
+ multiSelectEnumChanged(enumValue) {
+ let {onEnumChange} = this.props;
+ let selectedValues = enumValue.map(enumVal => {
+ return enumVal.value;
+ });
+
+ if (this.state.otherInputDisabled === false) {
+ selectedValues.shift();
+ }
+ else if (selectedValues.includes(i18n(other.OTHER))) {
+ selectedValues = [i18n(other.OTHER)];
+ }
+
+ this.setState({
+ otherInputDisabled: !selectedValues.includes(i18n(other.OTHER))
+ });
+ onEnumChange(selectedValues);
+ }
+
+ changedOtherInput() {
+ let {onOtherChange} = this.props;
+ onOtherChange(this.refs._otherValue.value);
+ }
+
+ componentDidUpdate() {
+ let {otherValue, selectedEnum, onInputChange, multiSelectedEnum} = this.props;
+ if (this.oldProps.otherValue !== otherValue
+ || this.oldProps.selectedEnum !== selectedEnum
+ || this.oldProps.multiSelectedEnum !== multiSelectedEnum) {
+ this.oldProps = {
+ otherValue,
+ selectedEnum,
+ multiSelectedEnum
+ };
+ onInputChange();
+ }
+ }
+
}
export default InputOptions;
diff --git a/src/generic-components/map/TopographicMap.jsx b/src/generic-components/map/TopographicMap.jsx
index fc0fb64..6da9909 100644
--- a/src/generic-components/map/TopographicMap.jsx
+++ b/src/generic-components/map/TopographicMap.jsx
@@ -18,7 +18,7 @@
* limitations under the License.
* ============LICENSE_END=========================================================
*/
-import React, {Component, PropTypes} from 'react';
+import React, {Component} from 'react';
import { PropTypes } from 'prop-types';
import {geoAlbersUsa, geoEquirectangular, geoPath} from 'd3-geo';
import {feature, mesh} from 'topojson';
diff --git a/src/generic-components/notifications/NotificationModal.jsx b/src/generic-components/notifications/NotificationModal.jsx
index 1547da3..0e747d5 100644
--- a/src/generic-components/notifications/NotificationModal.jsx
+++ b/src/generic-components/notifications/NotificationModal.jsx
@@ -19,17 +19,17 @@
* ============LICENSE_END=========================================================
*/
/**
- * NotificationModal options:
- *
- * show: whether to show notification or not,
- * type: the type of the notification. valid values are: 'default', 'error',
- * 'warning', 'success' msg: the notification content. could be a string or
- * node (React component) title: the notification title timeout: timeout for
- * the notification to fade out. if timeout == 0 then the notification is
- * rendered until the user closes it
- *
- */
-import React, {Component, PropTypes} from 'react';
+ * NotificationModal options:
+ *
+ * show: whether to show notification or not,
+ * type: the type of the notification. valid values are: 'default', 'error',
+ * 'warning', 'success' msg: the notification content. could be a string or
+ * node (React component) title: the notification title timeout: timeout for
+ * the notification to fade out. if timeout == 0 then the notification is
+ * rendered until the user closes it
+ *
+ */
+import React, {Component} from 'react';
import { PropTypes } from 'prop-types';
import {connect} from 'react-redux';
import Button from 'react-bootstrap/lib/Button.js';
@@ -39,83 +39,83 @@ import Modal from 'generic-components/modal/Modal.jsx';
import NotificationConstants from './NotificationConstants.js';
let typeClass = {
- 'default': 'primary',
- error: 'danger',
- warning: 'warning',
- success: 'success'
+ 'default': 'primary',
+ error: 'danger',
+ warning: 'warning',
+ success: 'success'
};
const mapActionsToProps = (dispatch) => {
- return {
- onCloseClick: () => dispatch({type: NotificationConstants.NOTIFY_CLOSE})
- };
+ return {
+ onCloseClick: () => dispatch({type: NotificationConstants.NOTIFY_CLOSE})
+ };
};
const mapStateToProps = ({notification}) => {
-
- let show = notification !== null && notification.title !== 'Conflict';
- let mapResult = {show};
- if (show) {
- mapResult = {show, ...notification};
- }
-
- return mapResult;
+
+ let show = notification !== null && notification.title !== 'Conflict';
+ let mapResult = {show};
+ if (show) {
+ mapResult = {show, ...notification};
+ }
+
+ return mapResult;
};
class NotificationModal extends Component {
-
- static propTypes = {
- show: PropTypes.bool,
- type: PropTypes.oneOf(['default', 'error', 'warning', 'success']),
- msg: PropTypes.node,
- title: PropTypes.string,
- timeout: PropTypes.number
- };
-
- static defaultProps = {
- show: false,
- type: 'default',
- title: '',
- msg: '',
- timeout: 0
- };
-
- state = {type: undefined};
-
- componentWillReceiveProps(nextProps) {
- if (this.props.show !== nextProps.show && nextProps.show === false) {
- this.setState({type: this.props.type});
- }
- else {
- this.setState({type: undefined});
- }
- }
-
- componentDidUpdate() {
- if (this.props.timeout) {
- setTimeout(this.props.onCloseClick, this.props.timeout);
- }
- }
-
- render() {
- let {title, type, msg, show} = this.props;
- if (!show) {
- type = this.state.type;
- }
- return (
- <Modal show={this.props.show}
- className={`notification-modal ${typeClass[type]}`}>
- <Modal.Header>
- <Modal.Title>{title}</Modal.Title>
- </Modal.Header>
- <Modal.Body>{msg}</Modal.Body>
- <Modal.Footer>
- <Button bsStyle={typeClass[type]}
- onClick={this.props.onCloseClick}>{i18n('OK')}</Button>
- </Modal.Footer>
- </Modal>
- );
- }
+
+ static propTypes = {
+ show: PropTypes.bool,
+ type: PropTypes.oneOf(['default', 'error', 'warning', 'success']),
+ msg: PropTypes.node,
+ title: PropTypes.string,
+ timeout: PropTypes.number
+ };
+
+ static defaultProps = {
+ show: false,
+ type: 'default',
+ title: '',
+ msg: '',
+ timeout: 0
+ };
+
+ state = {type: undefined};
+
+ componentWillReceiveProps(nextProps) {
+ if (this.props.show !== nextProps.show && nextProps.show === false) {
+ this.setState({type: this.props.type});
+ }
+ else {
+ this.setState({type: undefined});
+ }
+ }
+
+ componentDidUpdate() {
+ if (this.props.timeout) {
+ setTimeout(this.props.onCloseClick, this.props.timeout);
+ }
+ }
+
+ render() {
+ let {title, type, msg, show} = this.props;
+ if (!show) {
+ type = this.state.type;
+ }
+ return (
+ <Modal show={this.props.show}
+ className={`notification-modal ${typeClass[type]}`}>
+ <Modal.Header>
+ <Modal.Title>{title}</Modal.Title>
+ </Modal.Header>
+ <Modal.Body>{msg}</Modal.Body>
+ <Modal.Footer>
+ <Button bsStyle={typeClass[type]}
+ onClick={this.props.onCloseClick}>{i18n('OK')}</Button>
+ </Modal.Footer>
+ </Modal>
+ );
+ }
}
export default connect(mapStateToProps, mapActionsToProps)(NotificationModal);
diff --git a/src/generic-components/panel/SlidePanel.jsx b/src/generic-components/panel/SlidePanel.jsx
index 9580837..1550cee 100644
--- a/src/generic-components/panel/SlidePanel.jsx
+++ b/src/generic-components/panel/SlidePanel.jsx
@@ -24,114 +24,114 @@ import FontAwesome from 'react-fontawesome';
import ReactDOM from 'react-dom';
class SlidePanel extends React.Component {
-
- static PropTypes = {
- direction: PropTypes.string.isRequired,
- className: PropTypes.string,
- title: PropTypes.string,
- isOpen: PropTypes.bool
- };
-
- static defaultProps = {
- title: '',
- className: '',
- isOpen: true
- };
-
- state = {
- isOpen: this.props.isOpen,
- direction: this.props.direction,
- width: 0,
- arrowWidth: 0
- };
-
- componentDidMount() {
- this.setSliderPosition();
- }
-
- componentDidUpdate() {
- this.setSliderPosition();
- }
-
- render() {
-
- let {children, className} = this.props;
- let {isOpen} = this.state;
-
- return (
- <div className={ `slide-panel ${className}`}>
- {this.renderHeader(isOpen)}
- <div
- className={'slide-panel-content ' + (isOpen ? 'opened' : 'closed')}>{children}</div>
- </div>
- );
- }
-
- renderHeader(isOpen) {
- let {direction: initialDirection, title} = this.props;
- let {direction: currentDirection} = this.state;
-
- let iconName = currentDirection ===
- 'right'
- ? 'angle-double-right collapse-double-icon'
- : 'angle-double-left collapse-double-icon';
-
- let awestyle = {padding: '5px'};
-
- if (!isOpen && initialDirection === 'right') {
- awestyle.marginLeft = '-1px';
- }
- return (
- <div className='slide-panel-header'>
- { initialDirection === 'left' &&
- <span className='slide-panel-header-title'>{title}</span>}
- <FontAwesome
- ref='arrowIcon'
- style={awestyle}
- onClick={this.handleClick}
- className='pull-right'
- name={iconName}
- size='2x'/>
- { initialDirection === 'right' &&
- <span className='slide-panel-header-title'>{title}</span>}
- </div>
- );
- }
-
- handleClick = () => {
- this.setState({
- isOpen: !this.state.isOpen,
- direction: this.state.direction === 'left' ? 'right' : 'left'
- });
- }
-
- setSliderPosition = () => {
-
- let el = ReactDOM.findDOMNode(this);
- let {style} = el;
-
- let {direction: initialDirection} = this.props;
- let arrowIconSize = Math.floor(ReactDOM.findDOMNode(this.refs.arrowIcon)
- .getBoundingClientRect().width) * 2;
- if (!this.state.isOpen) {
- if (this.props.direction === 'left') {
- style.left = arrowIconSize - el.getBoundingClientRect().width + 'px';
- }
- if (initialDirection === 'right') {
- style.right = arrowIconSize - el.getBoundingClientRect().width + 'px';
- }
- }
- else {
- if (initialDirection === 'left') {
- style.left = '0px';
- }
-
- if (this.props.direction === 'right') {
- style.right = '0px';
- }
- }
- }
-
+
+ static PropTypes = {
+ direction: PropTypes.string.isRequired,
+ className: PropTypes.string,
+ title: PropTypes.string,
+ isOpen: PropTypes.bool
+ };
+
+ static defaultProps = {
+ title: '',
+ className: '',
+ isOpen: true
+ };
+
+ state = {
+ isOpen: this.props.isOpen,
+ direction: this.props.direction,
+ width: 0,
+ arrowWidth: 0
+ };
+
+ componentDidMount() {
+ this.setSliderPosition();
+ }
+
+ componentDidUpdate() {
+ this.setSliderPosition();
+ }
+
+ render() {
+
+ let {children, className} = this.props;
+ let {isOpen} = this.state;
+
+ return (
+ <div className={ `slide-panel ${className}`}>
+ {this.renderHeader(isOpen)}
+ <div
+ className={'slide-panel-content ' + (isOpen ? 'opened' : 'closed')}>{children}</div>
+ </div>
+ );
+ }
+
+ renderHeader(isOpen) {
+ let {direction: initialDirection, title} = this.props;
+ let {direction: currentDirection} = this.state;
+
+ let iconName = currentDirection ===
+ 'right'
+ ? 'angle-double-right collapse-double-icon'
+ : 'angle-double-left collapse-double-icon';
+
+ let awestyle = {padding: '5px'};
+
+ if (!isOpen && initialDirection === 'right') {
+ awestyle.marginLeft = '-1px';
+ }
+ return (
+ <div className='slide-panel-header'>
+ { initialDirection === 'left' &&
+ <span className='slide-panel-header-title'>{title}</span>}
+ <FontAwesome
+ ref='arrowIcon'
+ style={awestyle}
+ onClick={this.handleClick}
+ className='pull-right'
+ name={iconName}
+ size='2x'/>
+ { initialDirection === 'right' &&
+ <span className='slide-panel-header-title'>{title}</span>}
+ </div>
+ );
+ }
+
+ handleClick = () => {
+ this.setState({
+ isOpen: !this.state.isOpen,
+ direction: this.state.direction === 'left' ? 'right' : 'left'
+ });
+ }
+
+ setSliderPosition = () => {
+
+ let el = ReactDOM.findDOMNode(this);
+ let {style} = el;
+
+ let {direction: initialDirection} = this.props;
+ let arrowIconSize = Math.floor(ReactDOM.findDOMNode(this.refs.arrowIcon)
+ .getBoundingClientRect().width) * 2;
+ if (!this.state.isOpen) {
+ if (this.props.direction === 'left') {
+ style.left = arrowIconSize - el.getBoundingClientRect().width + 'px';
+ }
+ if (initialDirection === 'right') {
+ style.right = arrowIconSize - el.getBoundingClientRect().width + 'px';
+ }
+ }
+ else {
+ if (initialDirection === 'left') {
+ style.left = '0px';
+ }
+
+ if (this.props.direction === 'right') {
+ style.right = '0px';
+ }
+ }
+ }
+
}
export default SlidePanel;
diff --git a/src/generic-components/titledContainer/TitledContainer.jsx b/src/generic-components/titledContainer/TitledContainer.jsx
index d3d606a..6aa626d 100644
--- a/src/generic-components/titledContainer/TitledContainer.jsx
+++ b/src/generic-components/titledContainer/TitledContainer.jsx
@@ -18,7 +18,7 @@
* limitations under the License.
* ============LICENSE_END=========================================================
*/
-import React, {Component, PropTypes} from 'react';
+import React, {Component} from 'react';
import { PropTypes } from 'prop-types';
import Button from 'react-bootstrap/lib/Button';
diff --git a/src/generic-components/toggleButtonGroup/ToggleButtonGroup.jsx b/src/generic-components/toggleButtonGroup/ToggleButtonGroup.jsx
index 6d57637..0fe8939 100644
--- a/src/generic-components/toggleButtonGroup/ToggleButtonGroup.jsx
+++ b/src/generic-components/toggleButtonGroup/ToggleButtonGroup.jsx
@@ -18,7 +18,7 @@
* limitations under the License.
* ============LICENSE_END=========================================================
*/
-import React, {Component, PropTypes} from 'react';
+import React, {Component} from 'react';
import { PropTypes } from 'prop-types';
import {connect} from 'react-redux';
@@ -28,49 +28,49 @@ import Button from 'react-bootstrap/lib/Button.js';
import ToggleButtonGroupActions from 'generic-components/toggleButtonGroup/ToggleButtonGroupActions.js';
let mapActionToProps = (dispatch) => {
- return {
- onButtonToggle: (buttonName) => {
- dispatch(ToggleButtonGroupActions.onToggle({button: buttonName}));
- }
- };
+ return {
+ onButtonToggle: (buttonName) => {
+ dispatch(ToggleButtonGroupActions.onToggle({button: buttonName}));
+ }
+ };
};
let mapStateToProps = ({toggleButtonGroupData}) => {
-
- let {selectedButton} = toggleButtonGroupData;
-
- return {
- selectedButton
- };
+
+ let {selectedButton} = toggleButtonGroupData;
+
+ return {
+ selectedButton
+ };
};
class ToggleButtonGroup extends Component {
-
- static propTypes = {
- buttonDefinitions: PropTypes.object.isRequired
- };
-
- onButtonSelect(buttonName) {
- this.props.onButtonToggle(buttonName);
- }
-
- render() {
- let {selectedButton, buttonDefinitions} = this.props;
- let buttonListElements = [];
- Object.keys(buttonDefinitions).map(function (item) {
- buttonListElements.push(
- <Button id={item} active={selectedButton === item ? true : false}
- onClick={() => this.onButtonSelect(item)}>
- <i className={buttonDefinitions[item]} aria-hidden='true'></i>
- </Button>
- );
- }.bind(this));
-
- return (
- <ButtonGroup bsClass='btn-group displayOptionButtons'>
- {buttonListElements}
- </ButtonGroup>
- );
- }
+
+ static propTypes = {
+ buttonDefinitions: PropTypes.object.isRequired
+ };
+
+ onButtonSelect(buttonName) {
+ this.props.onButtonToggle(buttonName);
+ }
+
+ render() {
+ let {selectedButton, buttonDefinitions} = this.props;
+ let buttonListElements = [];
+ Object.keys(buttonDefinitions).map(function (item) {
+ buttonListElements.push(
+ <Button id={item} active={selectedButton === item ? true : false}
+ onClick={() => this.onButtonSelect(item)}>
+ <i className={buttonDefinitions[item]} aria-hidden='true'></i>
+ </Button>
+ );
+ }.bind(this));
+
+ return (
+ <ButtonGroup bsClass='btn-group displayOptionButtons'>
+ {buttonListElements}
+ </ButtonGroup>
+ );
+ }
}
export default connect(mapStateToProps, mapActionToProps)(ToggleButtonGroup);
diff --git a/src/utils/Crypto.js b/src/utils/Crypto.js
index c84ca76..91b6799 100644
--- a/src/utils/Crypto.js
+++ b/src/utils/Crypto.js
@@ -23,7 +23,7 @@
*/
import CryptoJS from 'crypto-js';
-var key = 'key2017';
+const key = 'key2017';
function encrypt(text) {
var encrypted = CryptoJS.AES.encrypt(text, key);
@@ -35,8 +35,17 @@ function decrypt(text) {
return decrypted.toString(CryptoJS.enc.Utf8);
}
+function encode(phrase) {
+ return CryptoJS.enc.Utf16.parse(phrase);
+}
+
+function decode(encodedPhrase) {
+ return CryptoJS.enc.Utf16.stringify(encodedPhrase);
+}
module.exports = {
encrypt: encrypt,
- decrypt: decrypt
+ decrypt: decrypt,
+ encode: encode,
+ decode: decode
};
diff --git a/src/utils/SpinnerContainer.jsx b/src/utils/SpinnerContainer.jsx
index 9bcf769..17e6e58 100644
--- a/src/utils/SpinnerContainer.jsx
+++ b/src/utils/SpinnerContainer.jsx
@@ -26,9 +26,9 @@ import {COLOR_BLUE} from 'utils/GlobalConstants.js';
class SpinnerContainer extends Component {
render() {
// if loading, show content as busy (ex: grey out)
- const spinnerContentClass = this.props.loading ? 'spinner-content' : '';
+ const spinnerContentClass = this.props.loading ? 'spin-content' : '';
return (
- <div className='spinner-container'>
+ <div className='spin-container'>
<div className='spinner'>
<ClipLoader color={COLOR_BLUE} loading={this.props.loading} />
</div>