diff options
author | arul.nambi <arul.nambi@amdocs.com> | 2018-01-30 12:34:34 -0500 |
---|---|---|
committer | arul.nambi <arul.nambi@amdocs.com> | 2018-01-30 14:00:30 -0500 |
commit | f42261a2cd0582e0209018c23816681e146ea97d (patch) | |
tree | 078eb4fee79f5cb0740615042afc31a48b429d69 | |
parent | 89cfd8bfafeb71ea89030b062a467631988f15f0 (diff) |
Implementing user feed back
Change-Id: I66196a4a5a319bb9c78c503244c0e78824ac855a
Signed-off-by: arul.nambi <arul.nambi@amdocs.com>
Issue-ID: AAI-696
-rw-r--r-- | package.json | 1 | ||||
-rw-r--r-- | resources/scss/common/_layout.scss | 19 | ||||
-rw-r--r-- | src/app/tierSupport/TierSupport.jsx | 78 | ||||
-rw-r--r-- | src/app/tierSupport/TierSupportActions.js | 18 | ||||
-rw-r--r-- | src/app/tierSupport/TierSupportConstants.js | 4 | ||||
-rw-r--r-- | src/app/tierSupport/TierSupportReducer.js | 10 | ||||
-rw-r--r-- | src/app/vnfSearch/VnfSearchActions.js | 18 | ||||
-rw-r--r-- | src/app/vnfSearch/VnfSearchConstants.js | 4 | ||||
-rw-r--r-- | src/app/vnfSearch/VnfSearchNfRoleVisualization.jsx | 43 | ||||
-rw-r--r-- | src/app/vnfSearch/VnfSearchNfTypeVisualization.jsx | 43 | ||||
-rw-r--r-- | src/app/vnfSearch/VnfSearchOrchestratedStatusVisualization.jsx | 45 | ||||
-rw-r--r-- | src/app/vnfSearch/VnfSearchProvStatusVisualization.jsx | 46 | ||||
-rw-r--r-- | src/app/vnfSearch/VnfSearchReducer.js | 10 | ||||
-rw-r--r-- | src/app/vnfSearch/VnfSearchTotalCountVisualization.jsx | 28 |
14 files changed, 265 insertions, 102 deletions
diff --git a/package.json b/package.json index 325c418..ddbc889 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ "react-redux": "^4.4.1", "react-router-dom": "^4.1.1", "react-select": "^1.0.0-beta13", + "react-spinners": "^0.2.5", "react-split-pane": "^0.1.51", "redux": "^3.3.1", "redux-form": "^6.2.1", diff --git a/resources/scss/common/_layout.scss b/resources/scss/common/_layout.scss index 1c3bf66..07b5b4c 100644 --- a/resources/scss/common/_layout.scss +++ b/resources/scss/common/_layout.scss @@ -33,3 +33,22 @@ .view-container { } + +.hideContainer { + visibility: hidden +} + +.showContainer { +} + +.spinner { + position: fixed; + z-index: 999; + height: 2em; + width: 2em; + margin: auto; + top: 0; + left: 0; + bottom: 0; + right: 0; +}
\ No newline at end of file diff --git a/src/app/tierSupport/TierSupport.jsx b/src/app/tierSupport/TierSupport.jsx index 315b6a0..943943f 100644 --- a/src/app/tierSupport/TierSupport.jsx +++ b/src/app/tierSupport/TierSupport.jsx @@ -24,6 +24,8 @@ import React, {Component} from 'react'; import {connect} from 'react-redux'; import SplitPane from 'react-split-pane'; +import { ClipLoader } from 'react-spinners'; +import {COLOR_BLUE} from 'utils/GlobalConstants.js'; import {setSecondaryTitle} from 'app/MainScreenWrapperActionHelper.js'; import ForceDirectedGraph from 'generic-components/graph/ForceDirectedGraph.jsx'; @@ -69,7 +71,8 @@ let mapStateToProps = ( graphNodeSelectedMenu = TSUI_GRAPH_MENU_NODE_DETAILS, feedbackMsgText = '', feedbackMsgSeverity = '', - nodeData = {} + nodeData = {}, + enableBusyFeedback = false } = tierSupportReducer; let { @@ -85,7 +88,8 @@ let mapStateToProps = ( selectedSuggestion, feedbackMsgText, feedbackMsgSeverity, - nodeData + nodeData, + enableBusyFeedback }; }; @@ -123,7 +127,8 @@ class TierSupport extends Component { graphNodeSelectedMenu: React.PropTypes.string, feedbackMsgText: React.PropTypes.string, feedbackMsgSeverity: React.PropTypes.string, - nodeData: React.PropTypes.object + nodeData: React.PropTypes.object, + enableBusyFeedback: React.PropTypes.bool }; componentWillReceiveProps(nextProps) { @@ -169,10 +174,14 @@ class TierSupport extends Component { windowWidth, windowHeight, onSplitPaneResize, - onNodeMenuSelect + onNodeMenuSelect, + enableBusyFeedback } = this.props; - + let componentVisibitliyClassName = 'showContainer'; + if(enableBusyFeedback){ + componentVisibitliyClassName = 'hideContainer'; + } let availableOverlay; let overlayComponent; // Currently only ONE overlay can be added to each view. @@ -200,35 +209,40 @@ class TierSupport extends Component { let currentSelectedMenu = this.getCurrentSelectedMenu(overlayComponent); return ( <div className='tier-support-ui'> - <SplitPane - split='vertical' - enableResizing='true' - onDragFinished={ () => { - onSplitPaneResize(false); - } } - defaultSize={TSUI_NODE_DETAILS_INITIAL_WIDTH} - minSize={TSUI_NODE_DETAILS_MIN_WIDTH} - maxSize={-200} - primary='second'> - <div> - <ForceDirectedGraph - viewWidth={windowWidth} - viewHeight={windowHeight} - graphData={forceDirectedGraphRawData} - nodeSelectedCallback={(nodeData) => { - onNodeSelected(nodeData); - }} - nodeButtonSelectedCallback={(selectedMenuId) => { - onNodeMenuSelect(selectedMenuId); - }} - dataOverlayButtons={dataOverlayButtons} - currentlySelectedNodeView={currentNodeButton}/> + <div className='spinner'> + <ClipLoader color={COLOR_BLUE} loading={enableBusyFeedback} /> + </div> + <div className={componentVisibitliyClassName}> + <SplitPane + split='vertical' + enableResizing='true' + onDragFinished={ () => { + onSplitPaneResize(false); + } } + defaultSize={TSUI_NODE_DETAILS_INITIAL_WIDTH} + minSize={TSUI_NODE_DETAILS_MIN_WIDTH} + maxSize={-200} + primary='second'> + <div> + <ForceDirectedGraph + viewWidth={windowWidth} + viewHeight={windowHeight} + graphData={forceDirectedGraphRawData} + nodeSelectedCallback={(nodeData) => { + onNodeSelected(nodeData); + }} + nodeButtonSelectedCallback={(selectedMenuId) => { + onNodeMenuSelect(selectedMenuId); + }} + dataOverlayButtons={dataOverlayButtons} + currentlySelectedNodeView={currentNodeButton}/> + </div> + <div> + {currentSelectedMenu} + </div> + </SplitPane> </div> - <div> - {currentSelectedMenu} - </div> - </SplitPane> </div> ); } diff --git a/src/app/tierSupport/TierSupportActions.js b/src/app/tierSupport/TierSupportActions.js index ead321e..fc4bcad 100644 --- a/src/app/tierSupport/TierSupportActions.js +++ b/src/app/tierSupport/TierSupportActions.js @@ -120,6 +120,18 @@ export function clearVIData() { }; } +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( @@ -140,8 +152,13 @@ export function fetchSelectedNodeElement(fetchRequestCallback) { 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 { @@ -169,6 +186,7 @@ export function querySelectedNodeElement( } return dispatch => { + dispatch(setBusyFeedback()); dispatch(fetchSelectedNodeElement(selectedNodeFetchRequest)); }; } diff --git a/src/app/tierSupport/TierSupportConstants.js b/src/app/tierSupport/TierSupportConstants.js index d20325f..d66816e 100644 --- a/src/app/tierSupport/TierSupportConstants.js +++ b/src/app/tierSupport/TierSupportConstants.js @@ -32,7 +32,9 @@ export const tierSupportActionTypes = keyMirror({ TS_GRAPH_NODE_SELECTED: null, TS_GRAPH_NODE_MENU_SELECTED: null, SPLIT_PANE_RESIZE: null, - TIER_SUPPORT_CLEAR_DATA: null + TIER_SUPPORT_CLEAR_DATA: null, + TIER_SUPPORT_ACTIVATE_BUSY_FEEDBACK: null, + TIER_SUPPORT_DISABLE_BUSY_FEEDBACK: null }); export const TSUI_NODE_DETAILS_INITIAL_WIDTH = 300; diff --git a/src/app/tierSupport/TierSupportReducer.js b/src/app/tierSupport/TierSupportReducer.js index 1560427..c9a4faf 100644 --- a/src/app/tierSupport/TierSupportReducer.js +++ b/src/app/tierSupport/TierSupportReducer.js @@ -89,6 +89,16 @@ export default combineReducers({ ...state, nodeData: action.data }; + case tierSupportActionTypes.TIER_SUPPORT_ACTIVATE_BUSY_FEEDBACK: + return { + ...state, + enableBusyFeedback: true + }; + case tierSupportActionTypes.TIER_SUPPORT_DISABLE_BUSY_FEEDBACK: + return { + ...state, + enableBusyFeedback: false + }; case globalAutoCompleteSearchBarActionTypes.SEARCH_WARNING_EVENT: let emptyNodesAndLinksWarningEvent = ForceDirectedGraph.generateNewProps([], [], {}); return { diff --git a/src/app/vnfSearch/VnfSearchActions.js b/src/app/vnfSearch/VnfSearchActions.js index 0167962..156f541 100644 --- a/src/app/vnfSearch/VnfSearchActions.js +++ b/src/app/vnfSearch/VnfSearchActions.js @@ -205,8 +205,21 @@ function getVnfVisualizationsResultsEvent(results) { }; } +function setBusyFeedback(){ + return { + type: vnfActionTypes.VNF_ACTIVATE_BUSY_FEEDBACK + }; +} + +function disableBusyFeedback(){ + return { + type: vnfActionTypes.VNF_DISABLE_BUSY_FEEDBACK + }; +} + export function processVnfVisualizationsOnFilterChange(filterValueMap) { return dispatch => { + dispatch(setBusyFeedback()); return fetch(VNF_FILTER_AGGREGATION_URL, { method: POST, headers: POST_HEADER, @@ -222,8 +235,13 @@ export function processVnfVisualizationsOnFilterChange(filterValueMap) { } dispatch(getVnfVisualizationsResultsEvent(responseJson)); } + ).then( + () => { + dispatch(disableBusyFeedback()); + } ).catch( () => { + dispatch(disableBusyFeedback()); dispatch(getInvalidQueryEvent()); } ); diff --git a/src/app/vnfSearch/VnfSearchConstants.js b/src/app/vnfSearch/VnfSearchConstants.js index 97d7159..200d01f 100644 --- a/src/app/vnfSearch/VnfSearchConstants.js +++ b/src/app/vnfSearch/VnfSearchConstants.js @@ -30,7 +30,9 @@ export const vnfActionTypes = keyMirror({ VNF_NETWORK_ERROR: null, VNF_SEARCH_RESULTS_RECEIVED: null, VNF_SEARCH_FILTERS_RECEIVED: null, - VNF_FILTER_PANEL_TOGGLED: null + VNF_FILTER_PANEL_TOGGLED: null, + VNF_ACTIVATE_BUSY_FEEDBACK: null, + VNF_DISABLE_BUSY_FEEDBACK: null }); export const CHART_PROV_STATUS = { diff --git a/src/app/vnfSearch/VnfSearchNfRoleVisualization.jsx b/src/app/vnfSearch/VnfSearchNfRoleVisualization.jsx index ca6f269..806ab3a 100644 --- a/src/app/vnfSearch/VnfSearchNfRoleVisualization.jsx +++ b/src/app/vnfSearch/VnfSearchNfRoleVisualization.jsx @@ -36,27 +36,35 @@ import i18n from 'utils/i18n/i18n'; import {CHART_NF_ROLE} from 'app/vnfSearch/VnfSearchConstants.js'; import {COLOR_BLUE} from 'utils/GlobalConstants.js'; +import { ClipLoader } from 'react-spinners'; let mapStateToProps = ({vnfSearch}) => { let { - processedNfRoleCountChartData = CHART_NF_ROLE.emptyData + processedNfRoleCountChartData = CHART_NF_ROLE.emptyData, + enableBusyFeedback = false } = vnfSearch; return { - processedNfRoleCountChartData + processedNfRoleCountChartData, + enableBusyFeedback }; }; class VnfSearchNfRoleVisualization extends Component { static propTypes = { - processedNfRoleCountChartData: React.PropTypes.object + processedNfRoleCountChartData: React.PropTypes.object, + enableBusyFeedback: React.PropTypes.bool }; render() { let { - processedNfRoleCountChartData + processedNfRoleCountChartData, + enableBusyFeedback } = this.props; - + let componentVisibitliyClassName = 'showContainer'; + if(enableBusyFeedback){ + componentVisibitliyClassName = 'hideContainer'; + } let visualizationClass = 'visualizations'; if (processedNfRoleCountChartData.values === @@ -74,16 +82,21 @@ class VnfSearchNfRoleVisualization extends Component { <div className='visualization-charts'> <div> <h3>{i18n(CHART_NF_ROLE.title)}</h3> - <ResponsiveContainer width='100%' height={300}> - <BarChart data={processedNfRoleCountChartData.values}> - <XAxis dataKey={xAxisAttrName}/> - <YAxis/> - <CartesianGrid strokeDasharray='3 3'/> - <Tooltip/> - <Bar name={i18n(CHART_NF_ROLE.yAxisLabel)} - dataKey={yAxisAttrName} fill={COLOR_BLUE}/> - </BarChart> - </ResponsiveContainer> + <div className='spinner'> + <ClipLoader color={COLOR_BLUE} loading={enableBusyFeedback} /> + </div> + <div className={componentVisibitliyClassName}> + <ResponsiveContainer width='100%' height={300}> + <BarChart data={processedNfRoleCountChartData.values}> + <XAxis dataKey={xAxisAttrName}/> + <YAxis/> + <CartesianGrid strokeDasharray='3 3'/> + <Tooltip/> + <Bar name={i18n(CHART_NF_ROLE.yAxisLabel)} + dataKey={yAxisAttrName} fill={COLOR_BLUE}/> + </BarChart> + </ResponsiveContainer> + </div> </div> </div> </div> diff --git a/src/app/vnfSearch/VnfSearchNfTypeVisualization.jsx b/src/app/vnfSearch/VnfSearchNfTypeVisualization.jsx index 30c6cdc..3f4acf0 100644 --- a/src/app/vnfSearch/VnfSearchNfTypeVisualization.jsx +++ b/src/app/vnfSearch/VnfSearchNfTypeVisualization.jsx @@ -36,27 +36,35 @@ import i18n from 'utils/i18n/i18n'; import {CHART_NF_TYPE} from 'app/vnfSearch/VnfSearchConstants.js'; import {COLOR_BLUE} from 'utils/GlobalConstants.js'; +import { ClipLoader } from 'react-spinners'; let mapStateToProps = ({vnfSearch}) => { let { - processedNfTypeCountChartData = CHART_NF_TYPE.emptyData + processedNfTypeCountChartData = CHART_NF_TYPE.emptyData, + enableBusyFeedback = false } = vnfSearch; return { - processedNfTypeCountChartData + processedNfTypeCountChartData, + enableBusyFeedback }; }; class VnfSearchNfTypeVisualization extends Component { static propTypes = { - processedNfTypeCountChartData: React.PropTypes.object + processedNfTypeCountChartData: React.PropTypes.object, + enableBusyFeedback: React.PropTypes.bool }; render() { let { - processedNfTypeCountChartData + processedNfTypeCountChartData, + enableBusyFeedback } = this.props; - + let componentVisibitliyClassName = 'showContainer'; + if(enableBusyFeedback){ + componentVisibitliyClassName = 'hideContainer'; + } let visualizationClass = 'visualizations'; if (processedNfTypeCountChartData.values === null || @@ -72,16 +80,21 @@ class VnfSearchNfTypeVisualization extends Component { <div className='visualization-charts'> <div > <h3>{i18n(CHART_NF_TYPE.title)}</h3> - <ResponsiveContainer width='100%' height={300}> - <BarChart data={processedNfTypeCountChartData.values}> - <XAxis dataKey={xAxisAttrName}/> - <YAxis /> - <CartesianGrid strokeDasharray='3 3'/> - <Tooltip/> - <Bar name={i18n(CHART_NF_TYPE.yAxisLabel)} - dataKey={yAxisAttrName} fill={COLOR_BLUE}/> - </BarChart> - </ResponsiveContainer> + <div className='spinner'> + <ClipLoader color={COLOR_BLUE} loading={enableBusyFeedback} /> + </div> + <div className={componentVisibitliyClassName}> + <ResponsiveContainer width='100%' height={300}> + <BarChart data={processedNfTypeCountChartData.values}> + <XAxis dataKey={xAxisAttrName}/> + <YAxis /> + <CartesianGrid strokeDasharray='3 3'/> + <Tooltip/> + <Bar name={i18n(CHART_NF_TYPE.yAxisLabel)} + dataKey={yAxisAttrName} fill={COLOR_BLUE}/> + </BarChart> + </ResponsiveContainer> + </div> </div> </div> </div> diff --git a/src/app/vnfSearch/VnfSearchOrchestratedStatusVisualization.jsx b/src/app/vnfSearch/VnfSearchOrchestratedStatusVisualization.jsx index 1855db7..7cc29d8 100644 --- a/src/app/vnfSearch/VnfSearchOrchestratedStatusVisualization.jsx +++ b/src/app/vnfSearch/VnfSearchOrchestratedStatusVisualization.jsx @@ -36,25 +36,35 @@ import i18n from 'utils/i18n/i18n'; import {CHART_ORCH_STATUS} from 'app/vnfSearch/VnfSearchConstants.js'; import {COLOR_BLUE} from 'utils/GlobalConstants.js'; - +import { ClipLoader } from 'react-spinners'; let mapStateToProps = ({vnfSearch}) => { let { - processedOrchStatusCountChartData = CHART_ORCH_STATUS.emptyData + processedOrchStatusCountChartData = CHART_ORCH_STATUS.emptyData, + enableBusyFeedback = false } = vnfSearch; return { - processedOrchStatusCountChartData + processedOrchStatusCountChartData, + enableBusyFeedback }; }; class VnfSearchOrchStatusVisualizations extends Component { + static propTypes = { + processedOrchStatusCountChartData: React.PropTypes.object, + enableBusyFeedback: React.PropTypes.bool + }; render() { let { - processedOrchStatusCountChartData + processedOrchStatusCountChartData, + enableBusyFeedback } = this.props; - + let componentVisibitliyClassName = 'showContainer'; + if(enableBusyFeedback){ + componentVisibitliyClassName = 'hideContainer'; + } let visualizationClass = 'visualizations'; if (processedOrchStatusCountChartData.values === null || @@ -70,16 +80,21 @@ class VnfSearchOrchStatusVisualizations extends Component { <div className='visualization-charts'> <div > <h3>{i18n(CHART_ORCH_STATUS.title)}</h3> - <ResponsiveContainer width='100%' height={300}> - <BarChart data={processedOrchStatusCountChartData.values}> - <XAxis dataKey={xAxisAttrName}/> - <YAxis /> - <CartesianGrid strokeDasharray='3 3'/> - <Tooltip/> - <Bar name={i18n(CHART_ORCH_STATUS.yAxisLabel)} - dataKey={yAxisAttrName} fill={COLOR_BLUE}/> - </BarChart> - </ResponsiveContainer> + <div className='spinner'> + <ClipLoader color={COLOR_BLUE} loading={enableBusyFeedback} /> + </div> + <div className={componentVisibitliyClassName}> + <ResponsiveContainer width='100%' height={300}> + <BarChart data={processedOrchStatusCountChartData.values}> + <XAxis dataKey={xAxisAttrName}/> + <YAxis /> + <CartesianGrid strokeDasharray='3 3'/> + <Tooltip/> + <Bar name={i18n(CHART_ORCH_STATUS.yAxisLabel)} + dataKey={yAxisAttrName} fill={COLOR_BLUE}/> + </BarChart> + </ResponsiveContainer> + </div> </div> </div> </div> diff --git a/src/app/vnfSearch/VnfSearchProvStatusVisualization.jsx b/src/app/vnfSearch/VnfSearchProvStatusVisualization.jsx index cdf6872..7ef6e9e 100644 --- a/src/app/vnfSearch/VnfSearchProvStatusVisualization.jsx +++ b/src/app/vnfSearch/VnfSearchProvStatusVisualization.jsx @@ -36,27 +36,36 @@ import i18n from 'utils/i18n/i18n'; import {CHART_PROV_STATUS} from 'app/vnfSearch/VnfSearchConstants.js'; import {COLOR_BLUE} from 'utils/GlobalConstants.js'; +import { ClipLoader } from 'react-spinners'; let mapStateToProps = ({vnfSearch}) => { let { - processedProvStatusCountChartData = CHART_PROV_STATUS.emptyData + processedProvStatusCountChartData = CHART_PROV_STATUS.emptyData, + enableBusyFeedback = false } = vnfSearch; return { - processedProvStatusCountChartData + processedProvStatusCountChartData, + enableBusyFeedback }; }; class VnfSearchProvStatusVisualization extends Component { static propTypes = { - processedProvStatusCountChartData: React.PropTypes.object + processedProvStatusCountChartData: React.PropTypes.object, + enableBusyFeedback: React.PropTypes.bool }; render() { let { - processedProvStatusCountChartData + processedProvStatusCountChartData, + enableBusyFeedback } = this.props; + let componentVisibitliyClassName = 'showContainer'; + if(enableBusyFeedback){ + componentVisibitliyClassName = 'hideContainer'; + } let visualizationClass = 'visualizations'; if (processedProvStatusCountChartData.values === null || @@ -72,17 +81,22 @@ class VnfSearchProvStatusVisualization extends Component { <div className='visualization-charts'> <div className='visualization-side-by-side-70'> <h3>{i18n(CHART_PROV_STATUS.title)}</h3> - <ResponsiveContainer width='100%' height={300}> - <BarChart - data={processedProvStatusCountChartData.values}> - <XAxis dataKey={xAxisAttrName}/> - <YAxis /> - <CartesianGrid strokeDasharray='3 3'/> - <Tooltip/> - <Bar name={i18n(CHART_PROV_STATUS.xAxisLabel)} - dataKey={yAxisAttrName} fill={COLOR_BLUE}/> - </BarChart> - </ResponsiveContainer> + <div className='spinner'> + <ClipLoader color={COLOR_BLUE} loading={enableBusyFeedback} /> + </div> + <div className={componentVisibitliyClassName}> + <ResponsiveContainer width='100%' height={345} > + <BarChart + data={processedProvStatusCountChartData.values}> + <XAxis dataKey={xAxisAttrName}/> + <YAxis /> + <CartesianGrid strokeDasharray='3 3'/> + <Tooltip/> + <Bar name={i18n(CHART_PROV_STATUS.xAxisLabel)} + dataKey={yAxisAttrName} fill={COLOR_BLUE}/> + </BarChart> + </ResponsiveContainer> + </div> </div> </div> </div> @@ -90,4 +104,4 @@ class VnfSearchProvStatusVisualization extends Component { } } -export default connect(mapStateToProps)(VnfSearchProvStatusVisualization); +export default connect(mapStateToProps)(VnfSearchProvStatusVisualization);
\ No newline at end of file diff --git a/src/app/vnfSearch/VnfSearchReducer.js b/src/app/vnfSearch/VnfSearchReducer.js index 1394f97..afd822c 100644 --- a/src/app/vnfSearch/VnfSearchReducer.js +++ b/src/app/vnfSearch/VnfSearchReducer.js @@ -105,6 +105,16 @@ export default (state = {}, action) => { vnfFilterValues: data.nonConvertedValues // launching DI view via menu button requires this // to be set so visualizations and table will populate themselves }; + case vnfActionTypes.VNF_ACTIVATE_BUSY_FEEDBACK: + return { + ...state, + enableBusyFeedback: true + }; + case vnfActionTypes.VNF_DISABLE_BUSY_FEEDBACK: + return { + ...state, + enableBusyFeedback: false + }; case filterBarActionTypes.CLEAR_FILTERS: return { ...state, diff --git a/src/app/vnfSearch/VnfSearchTotalCountVisualization.jsx b/src/app/vnfSearch/VnfSearchTotalCountVisualization.jsx index a2abd7c..553de42 100644 --- a/src/app/vnfSearch/VnfSearchTotalCountVisualization.jsx +++ b/src/app/vnfSearch/VnfSearchTotalCountVisualization.jsx @@ -26,14 +26,18 @@ import {connect} from 'react-redux'; import i18n from 'utils/i18n/i18n'; import {TOTAL_VNF_COUNT} from 'app/vnfSearch/VnfSearchConstants.js'; +import {COLOR_BLUE} from 'utils/GlobalConstants.js'; +import { ClipLoader } from 'react-spinners'; let mapStateToProps = ({vnfSearch}) => { let { - count = TOTAL_VNF_COUNT.emptyValue + count = TOTAL_VNF_COUNT.emptyValue, + enableBusyFeedback = false } = vnfSearch; return { - count + count, + enableBusyFeedback }; }; @@ -42,14 +46,19 @@ class VnfSearchTotalCountVisualization extends Component { count: React.PropTypes.oneOfType([ React.PropTypes.string, React.PropTypes.number - ]) + ]), + enableBusyFeedback: React.PropTypes.bool }; render() { let { - count + count, + enableBusyFeedback } = this.props; - + let componentVisibitliyClassName = 'showContainer'; + if(enableBusyFeedback){ + componentVisibitliyClassName = 'hideContainer'; + } let visualizationClass = 'visualizations'; if (count === null) { visualizationClass = 'visualizations hidden'; @@ -61,8 +70,13 @@ class VnfSearchTotalCountVisualization extends Component { <div className='visualization-side-by-side-30'> <span> </span> <h3>{i18n(TOTAL_VNF_COUNT.title)}</h3> - <div className='total-box-entity-count'> - <span>{count}</span> + <div className='spinner'> + <ClipLoader color={COLOR_BLUE} loading={enableBusyFeedback} /> + </div> + <div className={componentVisibitliyClassName}> + <div className='total-box-entity-count'> + <span>{count}</span> + </div> </div> </div> </div> |