diff options
author | Shawn Severin <shawn.severin@amdocs.com> | 2017-12-07 15:19:25 -0500 |
---|---|---|
committer | Shawn Severin <shawn.severin@amdocs.com> | 2017-12-07 15:19:46 -0500 |
commit | a7b4b96afee33a2ff458f906742d88cd306ed961 (patch) | |
tree | dcf2b16fdc4f52368327d372112cebaf126a1ded /src/app/vnfSearch | |
parent | 6ac2e7c0bef5ee478b36181b8bb384119ad3d937 (diff) |
Adding filter bar
Issue-ID: AAI-543
Change-Id: I18ec69f4585a9f01feafd009fcd30493a039b064
Signed-off-by: Shawn Severin <shawn.severin@amdocs.com>
Diffstat (limited to 'src/app/vnfSearch')
-rw-r--r-- | src/app/vnfSearch/VnfSearch.jsx | 237 | ||||
-rw-r--r-- | src/app/vnfSearch/VnfSearchActions.js | 299 | ||||
-rw-r--r-- | src/app/vnfSearch/VnfSearchConstants.js | 65 | ||||
-rw-r--r-- | src/app/vnfSearch/VnfSearchNfRoleVisualization.jsx | 98 | ||||
-rw-r--r-- | src/app/vnfSearch/VnfSearchNfTypeVisualization.jsx | 96 | ||||
-rw-r--r-- | src/app/vnfSearch/VnfSearchOrchestratedStatusVisualization.jsx | 26 | ||||
-rw-r--r-- | src/app/vnfSearch/VnfSearchProvStatusVisualization.jsx | 28 | ||||
-rw-r--r-- | src/app/vnfSearch/VnfSearchReducer.js | 96 | ||||
-rw-r--r-- | src/app/vnfSearch/VnfSearchTotalCountVisualization.jsx | 25 |
9 files changed, 711 insertions, 259 deletions
diff --git a/src/app/vnfSearch/VnfSearch.jsx b/src/app/vnfSearch/VnfSearch.jsx index 5a35be3..d04bbd4 100644 --- a/src/app/vnfSearch/VnfSearch.jsx +++ b/src/app/vnfSearch/VnfSearch.jsx @@ -1,62 +1,142 @@ /* - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * ============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 + * 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========================================================= + * ============LICENSE_END===================================================== * - * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * ECOMP and OpenECOMP are trademarks + * and service marks of AT&T Intellectual Property. */ import React, {Component} from 'react'; import {connect} from 'react-redux'; import { + isEqual, + isEmpty +} from 'lodash'; +import {VerticalFilterBar} from 'vertical-filter-bar'; +import {CollapsibleSlidingPanel} from 'collapsible-sliding-panel'; + +import {setSecondaryTitle} from 'app/MainScreenWrapperActionHelper.js'; +import { + vnfActionTypes, VNF_TITLE, VNFS_ROUTE, - DEFAULT_VNFS_SEARCH_HASH + VNF_SEARCH_FILTER_NAME } from 'app/vnfSearch/VnfSearchConstants.js'; import { - processTotalVnfVisualizationOnSearchChange, - processOrchStatusVisualizationOnSearchChange, - processProvStatusVisualizationOnSearchChange, - setNotificationText + processVnfVisualizationsOnFilterChange, + processVnfFilterPanelCollapse, + setNotificationText, + clearVnfSearchData } from 'app/vnfSearch/VnfSearchActions.js'; import VnfSearchOrchStatusVisualizations from 'app/vnfSearch/VnfSearchOrchestratedStatusVisualization.jsx'; import VnfSearchProvStatusVisualizations from 'app/vnfSearch/VnfSearchProvStatusVisualization.jsx'; +import VnfSearchNfTypeVisualizations from 'app/vnfSearch/VnfSearchNfTypeVisualization.jsx'; +import VnfSearchNfRoleVisualizations from 'app/vnfSearch/VnfSearchNfRoleVisualization.jsx'; import VnfSearchTotalCountVisualization from 'app/vnfSearch/VnfSearchTotalCountVisualization.jsx'; import i18n from 'utils/i18n/i18n'; -import {changeUrlAddress, buildRouteObj} from 'utils/Routes.js'; +import {changeUrlAddress, buildRouteObjWithFilters} from 'utils/Routes.js'; +import { + getUnifiedFilters, + processFilterSelection, + setNonConvertedFilterValues, + convertNonConvertedValues, + buildFilterValueMap, + setFilterSelectionsToDefaults, + FILTER_BAR_TITLE +} from 'generic-components/filterBar/FilterBarUtils.js'; const mapStateToProps = ({vnfSearch}) => { let { feedbackMsgText = '', - feedbackMsgSeverity = '' + feedbackMsgSeverity = '', + vnfFilters = {}, + selectedFilterValues = {}, + vnfFilterValues = {}, + vnfVisualizationPanelClass = 'collapsible-panel-main-panel', + unifiedFilterValues = {}, + nonConvertedFilters = {} } = vnfSearch; return { feedbackMsgText, - feedbackMsgSeverity + feedbackMsgSeverity, + vnfFilters, + selectedFilterValues, + vnfFilterValues, + vnfVisualizationPanelClass, + unifiedFilterValues, + nonConvertedFilters }; }; let mapActionToProps = (dispatch) => { return { - onReceiveNewParams: (vnfParam) => { - dispatch(processTotalVnfVisualizationOnSearchChange(vnfParam)); - dispatch(processOrchStatusVisualizationOnSearchChange(vnfParam)); - dispatch(processProvStatusVisualizationOnSearchChange(vnfParam)); + onSetViewTitle: (title) => { + dispatch(setSecondaryTitle(title)); + }, + onInitializeVnfSearchFilters: () => { + // first time to the page, need to get the list of available filters + dispatch(getUnifiedFilters(VNF_SEARCH_FILTER_NAME, vnfActionTypes.VNF_SEARCH_FILTERS_RECEIVED)); + }, + onFilterPanelCollapse: (isOpen) => { + // expand/collapse the filter panel + dispatch(processVnfFilterPanelCollapse(isOpen)); + }, + onFilterSelection: (selectedFilters, allFilters) => { + // callback for filter bar whenever a selection is made... need to + // convert and save the selected value(s) + if (Object.keys(allFilters).length > 0) { + // only process the selection if allFilters has values (possible that + // filter bar is sending back the default filter selections before + // we have received the list of available filters i.e. allFilters) + dispatch(processFilterSelection(selectedFilters, allFilters)); + } + }, + onFilterValueChange: (convertedFilterValues) => { + // filter values have been converted, now update the VNF visualizations + dispatch(processVnfVisualizationsOnFilterChange(convertedFilterValues)); + }, + onReceiveNewFilterValueParams: (filterValueString) => { + // new filter values have been received as URL parameters, save the + // non-converted values (later to be converted and sent to filter bar) + // and update the VNF visualizations + let filterValueMap = buildFilterValueMap(filterValueString); + + dispatch(setNonConvertedFilterValues(filterValueMap)); + dispatch(processVnfVisualizationsOnFilterChange(filterValueMap)); + + // incase url param was changed manually, need to update vnfFilterValues + }, + onResetFilterBarToDefaults: (filters, filterValues) => { + dispatch(setFilterSelectionsToDefaults(filters, filterValues)); + }, + onPrepareToUnmount: () => { + // clean things up: + // 1- clear the VNF data + // 2- ensure filter bar is closed + dispatch(clearVnfSearchData()); + dispatch(processVnfFilterPanelCollapse(false)); + }, + onConvertFilterValues: (nonConvertedValues, allFilters, currentlySetFilterValues) => { + // we have saved non-converted filter values received from URL params, + // time to convert them so can update filter bar selections programatically + dispatch(convertNonConvertedValues(nonConvertedValues, allFilters, currentlySetFilterValues)); }, onMessageStateChange: (msgText, msgSeverity) => { dispatch(setNotificationText(msgText, msgSeverity)); @@ -65,16 +145,25 @@ let mapActionToProps = (dispatch) => { }; class vnfSearch extends Component { + static propTypes = { + feedbackMsgText: React.PropTypes.string, + feedbackSeverity: React.PropTypes.string, + vnfFilters: React.PropTypes.object, + selectedFilterValues: React.PropTypes.object, + vnfFilterValues: React.PropTypes.object, + vnfVisualizationPanelClass: React.PropTypes.string, + unifiedFilterValues: React.PropTypes.object, + nonConvertedFilters: React.PropTypes.object + }; + componentWillMount() { + this.props.onSetViewTitle(i18n(VNF_TITLE)); + this.props.onInitializeVnfSearchFilters(); + if (this.props.match && this.props.match.params && - this.props.match.params.vnfParam) { - this.props.onReceiveNewParams(this.props.match.params.vnfParam); - } else { - // render using default search params (hash for "VNFs") - this.props.onReceiveNewParams(DEFAULT_VNFS_SEARCH_HASH); - changeUrlAddress(buildRouteObj(VNFS_ROUTE, DEFAULT_VNFS_SEARCH_HASH), - this.props.history); + this.props.match.params.filters) { + this.props.onReceiveNewFilterValueParams(this.props.match.params.filters); } if (this.props.feedbackMsgText) { @@ -84,42 +173,90 @@ class vnfSearch extends Component { } componentWillReceiveProps(nextProps) { - if (nextProps.match.params.vnfParam) { - if (nextProps.match.params.vnfParam !== - this.props.match.params.vnfParam) { - this.props.onReceiveNewParams(nextProps.match.params.vnfParam); - } - } else if (this.props.match.params.vnfParam) { - // currently on VNF page and somebody has clicked the VNF NavLink - // want to reload the view with the default params (hash for "NFVs") - this.props.onReceiveNewParams(DEFAULT_VNFS_SEARCH_HASH); - changeUrlAddress(buildRouteObj(VNFS_ROUTE, DEFAULT_VNFS_SEARCH_HASH), - this.props.history); - } - if (nextProps.feedbackMsgText && nextProps.feedbackMsgText !== this.props.feedbackMsgText) { this.props.onMessageStateChange(nextProps.feedbackMsgText, nextProps.feedbackMsgSeverity); } + + if (nextProps.vnfFilterValues && + !isEqual(nextProps.vnfFilterValues, this.props.vnfFilterValues) && + this.props.vnfFilters) { + this.props.onFilterValueChange(nextProps.vnfFilterValues); + changeUrlAddress(buildRouteObjWithFilters(VNFS_ROUTE, nextProps.vnfFilterValues), + this.props.history); + } + + if (nextProps.match && + nextProps.match.params && + nextProps.match.params.filters && + !isEqual(nextProps.match.params.filters, this.props.match.params.filters)) { + // added line below to reload the filters if filter changes, this will load new filters + this.props.onInitializeVnfSearchFilters(); + this.props.onReceiveNewFilterValueParams(nextProps.match.params.filters); + } else if (Object.keys(nextProps.nonConvertedFilters).length > 0 && + !isEqual(this.props.nonConvertedFilters, nextProps.nonConvertedFilters)) { + if (Object.keys(this.props.vnfFilters).length > 0) { + this.props.onConvertFilterValues( + nextProps.nonConvertedFilters, this.props.vnfFilters, this.props.vnfFilterValues); + } + } else if ((!nextProps.match || !nextProps.match.params || !nextProps.match.params.filters) && + this.props.match.params.filters && this.props.vnfFilters && this.props.vnfFilterValues) { + // VNF Search navigation button was pressed while the view is still visible ... need to reset + // the filter bar selections to the default values + this.props.onResetFilterBarToDefaults(this.props.vnfFilters, this.props.vnfFilterValues); + } + + if (nextProps.vnfFilters && !isEqual(nextProps.vnfFilters, this.props.vnfFilters) && + Object.keys(this.props.nonConvertedFilters).length > 0) { + // just received list of available filters and there is are nonConvertedFilters (previously + // set from url params), need to convert those values and update the filter bar selections + this.props.onConvertFilterValues( + this.props.nonConvertedFilters, nextProps.vnfFilters, this.props.vnfFilterValues); + } else if (nextProps.vnfFilters && !isEqual(nextProps.vnfFilters, this.props.vnfFilters) && + isEmpty(this.props.vnfFilterValues)) { + // filter bar previously returned the default filter selections (but we didn't have the list + // of available filters at the time, so couldn't do anything. Now receiving the list of + // available filters, so triger the filter selection action in order to load the visualization data + this.props.onResetFilterBarToDefaults(nextProps.vnfFilters, this.props.vnfFilterValues); + } } componentWillUnmount() { - // resetting to default params so on relaunch there will be no - // visibility of old searches - this.props.onReceiveNewParams(DEFAULT_VNFS_SEARCH_HASH); + // set the data to 'NO DATA' so upon return, the view is rendered with + // no data until the request for new data is returned + this.props.onPrepareToUnmount(); + } + + getFilterBar() { + return ( + <VerticalFilterBar + filtersConfig={this.props.vnfFilters} + filterValues={this.props.unifiedFilterValues} + filterTitle={FILTER_BAR_TITLE} + onFilterChange={(selectedFilters) => + this.props.onFilterSelection(selectedFilters, this.props.vnfFilters)} /> ); } render() { + let filterBar = this.getFilterBar(); + return ( - <div> - <div className='secondary-header'> - <span className='secondary-title'>{i18n(VNF_TITLE)}</span> - </div> - <VnfSearchTotalCountVisualization /> - <VnfSearchProvStatusVisualizations /> - <VnfSearchOrchStatusVisualizations /> + <div className='view-container'> + <CollapsibleSlidingPanel + slidingPanelClassName='collapsible-sliding-panel' + slidingPanelClosedClassName='collapsible-sliding-panel-is-closed' + expanderHandleClassName='collapsible-sliding-panel-expander' + slidingPanelContent={filterBar}> + <div className={this.props.vnfVisualizationPanelClass}> + <VnfSearchTotalCountVisualization /> + <VnfSearchProvStatusVisualizations /> + <VnfSearchOrchStatusVisualizations /> + <VnfSearchNfTypeVisualizations /> + <VnfSearchNfRoleVisualizations /> + </div> + </CollapsibleSlidingPanel> </div> ); } diff --git a/src/app/vnfSearch/VnfSearchActions.js b/src/app/vnfSearch/VnfSearchActions.js index b28ab66..ce09b2a 100644 --- a/src/app/vnfSearch/VnfSearchActions.js +++ b/src/app/vnfSearch/VnfSearchActions.js @@ -1,35 +1,38 @@ /* - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * ============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 + * 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========================================================= + * ============LICENSE_END===================================================== * - * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * ECOMP and OpenECOMP are trademarks + * and service marks of AT&T Intellectual Property. */ + import { vnfActionTypes, - VNF_RESULT_URL + VNF_FILTER_AGGREGATION_URL, + CHART_PROV_STATUS, + CHART_ORCH_STATUS, + CHART_NF_TYPE, + CHART_NF_ROLE, + TOTAL_VNF_COUNT, + VNF_FILTER_EMPTY_RESULT } from 'app/vnfSearch/VnfSearchConstants.js'; - -import { - getVnfProvStatusQueryString, - getVnfOrchStatusQueryString, - getVnfCountQueryString -} from 'app/networking/NetworkUtil.js'; import { POST, POST_HEADER, @@ -38,7 +41,8 @@ import { import { getSetGlobalMessageEvent, getClearGlobalMessageEvent -} from 'app/GlobalInlineMessageBar/GlobalInlineMessageBarActions.js'; +} from 'app/globalInlineMessageBar/GlobalInlineMessageBarActions.js'; +import {MESSAGE_LEVEL_WARNING} from 'utils/GlobalConstants.js'; let fetch = require('node-fetch'); fetch.Promise = require('es6-promise').Promise; @@ -52,143 +56,174 @@ function getInvalidQueryEvent() { data: {errorMsg: ERROR_RETRIEVING_DATA} }; } -/*it is a vertical bar chart then y and x are switched */ -function getProvStatusEvent(responseJson) { - if (responseJson && responseJson.groupby_aggregation && - responseJson.groupby_aggregation.buckets && - responseJson.groupby_aggregation.buckets.length > 0) { - let groupByProvStatusBucket; - let dataPoints = []; - for (groupByProvStatusBucket of - responseJson.groupby_aggregation.buckets) { - dataPoints.push({ - 'x': groupByProvStatusBucket[itemKeyWord].split('=', 1)[0], - 'y': groupByProvStatusBucket[countKeyWord] - }); - } - let newProvStatusChartData = [ +function processProvData(provDataList) { + let dataPoints = []; + let newProvStatusChartData = CHART_PROV_STATUS.emptyData; + for (let provData of provDataList) { + dataPoints.push( { - 'values': dataPoints + 'x': provData[itemKeyWord], + 'y': provData[countKeyWord] } - ]; - - let provStatusCountChartData = { - chartData: newProvStatusChartData - }; - return { - type: vnfActionTypes.COUNT_BY_PROV_STATUS_RECEIVED, - data: {provStatusCountChartData} - }; + ); } - else { - return { - type: vnfActionTypes.ERROR_NO_DATA_FOR_PROV_STATUS_IN_SEARCH_RANGE_RECEIVED + + if (dataPoints.length > 0) { + newProvStatusChartData = { + 'values': dataPoints }; } -} -function getOrchStatusEvent(responseJson) { - if (responseJson && responseJson.groupby_aggregation && - responseJson.groupby_aggregation.buckets && - responseJson.groupby_aggregation.buckets.length > 0) { - let groupByOrchStatusBucket; - let dataPoints = []; - for (groupByOrchStatusBucket of - responseJson.groupby_aggregation.buckets) { - dataPoints.push({ - 'x': groupByOrchStatusBucket[itemKeyWord].split('=', 1)[0], - 'y': groupByOrchStatusBucket[countKeyWord] - }); - } + return newProvStatusChartData; +} - let newOrchStatusChartData = [ +function processOrchData(orchDataList) { + let dataPoints = []; + let newOrchStatusChartData = CHART_ORCH_STATUS.emptyData; + for (let orchData of orchDataList) { + dataPoints.push( { - 'values': dataPoints + 'x': orchData[itemKeyWord], + 'y': orchData[countKeyWord] } - ]; - - let orchStatusCountChartData = { - chartData: newOrchStatusChartData - }; - return { - type: vnfActionTypes.COUNT_BY_ORCH_STATUS_RECEIVED, - data: {orchStatusCountChartData} - }; + ); } - else { - return { - type: vnfActionTypes.ERROR_NO_DATA_FOR_ORCH_STATUS_IN_SEARCH_RANGE_RECEIVED + + if (dataPoints.length > 0) { + newOrchStatusChartData = { + 'values': dataPoints }; } + + return newOrchStatusChartData; } -function getTotalVnfEvent(responseJson) { - if (responseJson && responseJson.count && responseJson.count > 0) { - return { - type: vnfActionTypes.TOTAL_VNF_COUNT_RECEIVED, - data: {count: responseJson.count} - }; +function processNfTypeData(nfDataList) { + let dataPoints = []; + let newNfTypeChartData = CHART_NF_TYPE.emptyData; + for (let nfData of nfDataList) { + dataPoints.push( + { + 'x': nfData[itemKeyWord], + 'y': nfData[countKeyWord] + } + ); } - else { - return { - type: vnfActionTypes.ERROR_NO_COUNT_RECEIVED + + if (dataPoints.length > 0) { + newNfTypeChartData = { + 'values': dataPoints }; } + + return newNfTypeChartData; } -export function processProvStatusVisualizationOnSearchChange(requestObject) { - return dispatch => { - return fetch(VNF_RESULT_URL, { - method: POST, - headers: POST_HEADER, - body: JSON.stringify(getVnfProvStatusQueryString(requestObject)) - }).then( - (response) => response.json() - ).then( - (responseJson) => { - dispatch(getProvStatusEvent(responseJson)); - } - ).catch( - () => { - dispatch(getInvalidQueryEvent()); +function processNfRoleData(nfDataList) { + let dataPoints = []; + let newNfRoleChartData = CHART_NF_ROLE.emptyData; + for (let nfData of nfDataList) { + dataPoints.push( + { + 'x': nfData[itemKeyWord], + 'y': nfData[countKeyWord] } ); + } + + if (dataPoints.length > 0) { + newNfRoleChartData = { + 'values': dataPoints + }; + } + + return newNfRoleChartData; +} + +function getVnfFilterAggregationQueryString(filterValueMap) { + let filterList = []; + + for (let filter in filterValueMap) { + if (filterValueMap[filter] !== '') { + filterList.push( + { + 'filterId': filter, + 'filterValue': filterValueMap[filter] + } + ); + } else { + filterList.push( + { + 'filterId': filter + } + ); + } + } + + return { + 'filters': filterList }; } -export function processOrchStatusVisualizationOnSearchChange(requestObject) { - return dispatch => { - return fetch(VNF_RESULT_URL, { - method: POST, - headers: POST_HEADER, - body: JSON.stringify(getVnfOrchStatusQueryString(requestObject)) - }).then( - (response) => response.json() - ).then( - (responseJson) => { - dispatch(getOrchStatusEvent(responseJson)); - } - ).catch( - () => { - dispatch(getInvalidQueryEvent()); - } - ); +function getVnfVisualizationsResultsEvent(results) { + let count = TOTAL_VNF_COUNT.emptyData; + let provData = CHART_PROV_STATUS.emptyData; + let orchData = CHART_ORCH_STATUS.emptyData; + let netFuncTypeData = CHART_NF_TYPE.emptyData; + let netFuncRoleData = CHART_NF_ROLE.emptyData; + + if (results.total) { + count = results.total; + } + + if (results['aggregations'] && results['aggregations']['prov-status']) { + provData = processProvData(results['aggregations']['prov-status']); + } + + if (results['aggregations'] && + results['aggregations']['orchestration-status']) { + orchData = processOrchData(results['aggregations']['orchestration-status']); + } + + if (results['aggregations'] && + results['aggregations']['nf-type']) { + netFuncTypeData = processNfTypeData(results['aggregations']['nf-type']); + } + + if (results['aggregations'] && + results['aggregations']['nf-role']) { + netFuncRoleData = processNfRoleData(results['aggregations']['nf-role']); + } + + return { + type: vnfActionTypes.VNF_SEARCH_RESULTS_RECEIVED, + data: { + count: count, + provStatusData: provData, + orchStatusData: orchData, + nfTypeData: netFuncTypeData, + nfRoleData: netFuncRoleData + } }; } -export function processTotalVnfVisualizationOnSearchChange(requestObject) { +export function processVnfVisualizationsOnFilterChange(filterValueMap) { return dispatch => { - return fetch(VNF_RESULT_URL + '/count', { + return fetch(VNF_FILTER_AGGREGATION_URL, { method: POST, headers: POST_HEADER, - body: JSON.stringify( - getVnfCountQueryString(requestObject)) + body: JSON.stringify(getVnfFilterAggregationQueryString(filterValueMap)) }).then( (response) => response.json() ).then( (responseJson) => { - dispatch(getTotalVnfEvent(responseJson)); + if(responseJson.total === 0) { + dispatch(getSetGlobalMessageEvent(VNF_FILTER_EMPTY_RESULT, MESSAGE_LEVEL_WARNING)); + } else { + dispatch(getClearGlobalMessageEvent()); + } + dispatch(getVnfVisualizationsResultsEvent(responseJson)); } ).catch( () => { @@ -198,6 +233,21 @@ export function processTotalVnfVisualizationOnSearchChange(requestObject) { }; } +export function processVnfFilterPanelCollapse(isOpen) { + let vnfVisualizationPanelClass = 'collapsible-panel-main-panel'; + + if (isOpen) { + vnfVisualizationPanelClass += ' vertical-filter-panel-is-open'; + } + + return { + type: vnfActionTypes.VNF_FILTER_PANEL_TOGGLED, + data: { + vnfVisualizationPanelClass: vnfVisualizationPanelClass + } + }; +} + export function setNotificationText(msgText, msgSeverity) { if (msgText.length > 0) { return dispatch => { @@ -210,3 +260,16 @@ export function setNotificationText(msgText, msgSeverity) { }; } } + +export function clearVnfSearchData() { + return { + type: vnfActionTypes.VNF_SEARCH_RESULTS_RECEIVED, + data: { + count: '', + provStatusData: CHART_PROV_STATUS.emptyData, + orchStatusData: CHART_ORCH_STATUS.emptyData, + nfTypeData: CHART_NF_TYPE.emptyData, + nfRoleData: CHART_NF_ROLE.emptyData + } + }; +} diff --git a/src/app/vnfSearch/VnfSearchConstants.js b/src/app/vnfSearch/VnfSearchConstants.js index 5f920fd..604c96f 100644 --- a/src/app/vnfSearch/VnfSearchConstants.js +++ b/src/app/vnfSearch/VnfSearchConstants.js @@ -1,69 +1,92 @@ /* - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * ============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 + * 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========================================================= + * ============LICENSE_END===================================================== * - * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * ECOMP and OpenECOMP are trademarks + * and service marks of AT&T Intellectual Property. */ import keyMirror from 'utils/KeyMirror.js'; import {BASE_URL} from 'app/networking/NetworkConstants.js'; export const VNF_TITLE = 'VNFs'; +export const VNF_SEARCH_FILTER_NAME = 'vnfSearch'; export const vnfActionTypes = keyMirror({ - COUNT_BY_PROV_STATUS_RECEIVED: null, - ERROR_NO_DATA_FOR_PROV_STATUS_IN_SEARCH_RANGE_RECEIVED: null, - COUNT_BY_ORCH_STATUS_RECEIVED: null, - ERROR_NO_DATA_FOR_ORCH_STATUS_IN_SEARCH_RANGE_RECEIVED: null, - TOTAL_VNF_COUNT_RECEIVED: null, - ERROR_NO_COUNT_RECEIVED: null, - VNF_NETWORK_ERROR: null + VNF_NETWORK_ERROR: null, + VNF_SEARCH_RESULTS_RECEIVED: null, + VNF_SEARCH_FILTERS_RECEIVED: null, + VNF_FILTER_PANEL_TOGGLED: null }); export const CHART_PROV_STATUS = { title: 'VNFs By Provisioning Status', yAxisLabel: 'VNFs', xAxisLabel: 'VNFs', - emptyData: [{'values': [ + emptyData: {'values': [ { 'x': 'No data discovered for Provisioning Status', 'y': 0 } - ]}] + ]} }; export const CHART_ORCH_STATUS = { title: 'VNFs By Orchestration Status', yAxisLabel: 'VNFs', - emptyData: [{'values': [ + emptyData: {'values': [ { 'x': 'No data discovered for Orchestration Status', 'y': 0 } - ]}] + ]} +}; + +export const CHART_NF_TYPE = { + title: 'VNFs By Network Function Type', + yAxisLabel: 'VNFs', + emptyData: {'values': [ + { + 'x': 'No data discovered for Network Function Type', + 'y': 0 + } + ]} +}; + +export const CHART_NF_ROLE = { + title: 'VNFs By Network Function Role', + yAxisLabel: 'VNFs', + emptyData: {'values': [ + { + 'x': 'No data discovered for Network Function Role', + 'y': 0 + } + ]} }; export const TOTAL_VNF_COUNT = { title: 'Total VNFs', - emptyValue: 0 + emptyValue: '' }; -export const VNF_RESULT_URL = BASE_URL + '/search/summarybyentitytype'; +export const VNF_FILTER_AGGREGATION_URL = BASE_URL + '/rest/search/filterAggregation'; export const DEFAULT_VNFS_SEARCH_HASH = '2172a3c25ae56e4995038ffbc1f055692bfc76c0b8ceda1205bc745a9f7a805d'; export const VNFS_ROUTE = 'vnfSearch'; +export const VNF_FILTER_EMPTY_RESULT = 'No data for the specified filters'; diff --git a/src/app/vnfSearch/VnfSearchNfRoleVisualization.jsx b/src/app/vnfSearch/VnfSearchNfRoleVisualization.jsx new file mode 100644 index 0000000..ee8dd4f --- /dev/null +++ b/src/app/vnfSearch/VnfSearchNfRoleVisualization.jsx @@ -0,0 +1,98 @@ +/* eslint-disable max-len,max-len,max-len,max-len,max-len,max-len */ +/* + * ============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 React, {Component} from 'react'; +import {connect} from 'react-redux'; +import { + BarChart, + Bar, + XAxis, + YAxis, + CartesianGrid, + Tooltip, + ResponsiveContainer, +} from 'recharts'; + +import i18n from 'utils/i18n/i18n'; + +import {CHART_NF_ROLE} from 'app/vnfSearch/VnfSearchConstants.js'; +import {COLOR_BLUE} from 'utils/GlobalConstants.js'; + +let mapStateToProps = ({vnfSearch}) => { + let { + processedNfRoleCountChartData = CHART_NF_ROLE.emptyData + } = vnfSearch; + + return { + processedNfRoleCountChartData + }; +}; + +class VnfSearchNfRoleVisualization extends Component { + static propTypes = { + processedNfRoleCountChartData: React.PropTypes.object + }; + + render() { + let { + processedNfRoleCountChartData + } = this.props; + + let visualizationClass = 'visualizations'; + + if (processedNfRoleCountChartData.values === + null || + processedNfRoleCountChartData.values.size <= + 0) { + visualizationClass = 'visualizations hidden'; + } + + const xAxisAttrName = 'x'; + const yAxisAttrName = 'y'; + + return ( + <div id='audit-visualizations' className={visualizationClass}> + <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> + </div> + </div> + ); + } +} + +export default connect(mapStateToProps)(VnfSearchNfRoleVisualization); diff --git a/src/app/vnfSearch/VnfSearchNfTypeVisualization.jsx b/src/app/vnfSearch/VnfSearchNfTypeVisualization.jsx new file mode 100644 index 0000000..292a68a --- /dev/null +++ b/src/app/vnfSearch/VnfSearchNfTypeVisualization.jsx @@ -0,0 +1,96 @@ +/* eslint-disable max-len,max-len,max-len,max-len,max-len,max-len */ +/* + * ============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 React, {Component} from 'react'; +import {connect} from 'react-redux'; +import { + BarChart, + Bar, + XAxis, + YAxis, + CartesianGrid, + Tooltip, + ResponsiveContainer, +} from 'recharts'; + +import i18n from 'utils/i18n/i18n'; + +import {CHART_NF_TYPE} from 'app/vnfSearch/VnfSearchConstants.js'; +import {COLOR_BLUE} from 'utils/GlobalConstants.js'; + +let mapStateToProps = ({vnfSearch}) => { + let { + processedNfTypeCountChartData = CHART_NF_TYPE.emptyData + } = vnfSearch; + + return { + processedNfTypeCountChartData + }; +}; + +class VnfSearchNfTypeVisualization extends Component { + static propTypes = { + processedNfTypeCountChartData: React.PropTypes.object + }; + + render() { + let { + processedNfTypeCountChartData + } = this.props; + + let visualizationClass = 'visualizations'; + if (processedNfTypeCountChartData.values === + null || + processedNfTypeCountChartData.values.size <= + 0) { + visualizationClass = 'visualizations hidden'; + } + const xAxisAttrName = 'x'; + const yAxisAttrName = 'y'; + + return ( + <div id='audit-visualizations' className={visualizationClass}> + <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> + </div> + </div> + ); + } + +} +export default connect(mapStateToProps)(VnfSearchNfTypeVisualization); diff --git a/src/app/vnfSearch/VnfSearchOrchestratedStatusVisualization.jsx b/src/app/vnfSearch/VnfSearchOrchestratedStatusVisualization.jsx index 7e101b3..59f43eb 100644 --- a/src/app/vnfSearch/VnfSearchOrchestratedStatusVisualization.jsx +++ b/src/app/vnfSearch/VnfSearchOrchestratedStatusVisualization.jsx @@ -1,26 +1,28 @@ +/* eslint-disable max-len,max-len,max-len,max-len,max-len,max-len */ /* - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * ============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 + * 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========================================================= + * ============LICENSE_END===================================================== * - * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * ECOMP and OpenECOMP are trademarks + * and service marks of AT&T Intellectual Property. */ -/* eslint-disable max-len,max-len,max-len,max-len,max-len,max-len */ import React, {Component} from 'react'; import {connect} from 'react-redux'; @@ -58,9 +60,9 @@ class VnfSearchOrchStatusVisualizations extends Component { } = this.props; let visualizationClass = 'visualizations'; - if (processedOrchStatusCountChartData[0].values === + if (processedOrchStatusCountChartData.values === null || - processedOrchStatusCountChartData[0].values.size <= + processedOrchStatusCountChartData.values.size <= 0) { visualizationClass = 'visualizations hidden'; } @@ -73,7 +75,7 @@ class VnfSearchOrchStatusVisualizations extends Component { <div > <h3>{i18n(CHART_ORCH_STATUS.title)}</h3> <ResponsiveContainer width='100%' height={300}> - <BarChart data={processedOrchStatusCountChartData[0].values}> + <BarChart data={processedOrchStatusCountChartData.values}> <XAxis dataKey={xAxisAttrName}/> <YAxis /> <CartesianGrid strokeDasharray='3 3'/> diff --git a/src/app/vnfSearch/VnfSearchProvStatusVisualization.jsx b/src/app/vnfSearch/VnfSearchProvStatusVisualization.jsx index d889d20..5295e35 100644 --- a/src/app/vnfSearch/VnfSearchProvStatusVisualization.jsx +++ b/src/app/vnfSearch/VnfSearchProvStatusVisualization.jsx @@ -1,26 +1,28 @@ +/* eslint-disable max-len,max-len,max-len,max-len,max-len,max-len */ /* - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * ============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 + * 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========================================================= + * ============LICENSE_END===================================================== * - * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * ECOMP and OpenECOMP are trademarks + * and service marks of AT&T Intellectual Property. */ -/* eslint-disable max-len,max-len,max-len,max-len,max-len,max-len */ import React, {Component} from 'react'; import {connect} from 'react-redux'; @@ -51,7 +53,7 @@ let mapStateToProps = ({vnfSearch}) => { class VnfSearchProvStatusVisualization extends Component { static propTypes = { - processedProvStatusCountChartData: React.PropTypes.array + processedProvStatusCountChartData: React.PropTypes.object }; render() { @@ -60,9 +62,9 @@ class VnfSearchProvStatusVisualization extends Component { } = this.props; let visualizationClass = 'visualizations'; - if (processedProvStatusCountChartData[0].values === + if (processedProvStatusCountChartData.values === null || - processedProvStatusCountChartData[0].values.size <= + processedProvStatusCountChartData.values.size <= 0) { visualizationClass = 'visualizations hidden'; } @@ -76,7 +78,7 @@ class VnfSearchProvStatusVisualization extends Component { <h3>{i18n(CHART_PROV_STATUS.title)}</h3> <ResponsiveContainer width='100%' height={300}> <BarChart - data={processedProvStatusCountChartData[0].values}> + data={processedProvStatusCountChartData.values}> <XAxis dataKey={xAxisAttrName}/> <YAxis /> <CartesianGrid strokeDasharray='3 3'/> diff --git a/src/app/vnfSearch/VnfSearchReducer.js b/src/app/vnfSearch/VnfSearchReducer.js index 6dfc412..4c8337f 100644 --- a/src/app/vnfSearch/VnfSearchReducer.js +++ b/src/app/vnfSearch/VnfSearchReducer.js @@ -1,29 +1,33 @@ /* - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * ============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 + * 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========================================================= + * ============LICENSE_END===================================================== * - * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * ECOMP and OpenECOMP are trademarks + * and service marks of AT&T Intellectual Property. */ import {vnfActionTypes} from 'app/vnfSearch/VnfSearchConstants.js'; import { CHART_ORCH_STATUS, CHART_PROV_STATUS, + CHART_NF_ROLE, + CHART_NF_TYPE, TOTAL_VNF_COUNT } from 'app/vnfSearch/VnfSearchConstants.js'; import {ERROR_RETRIEVING_DATA} from 'app/networking/NetworkConstants.js'; @@ -31,63 +35,85 @@ import {MESSAGE_LEVEL_DANGER} from 'utils/GlobalConstants.js'; import { globalAutoCompleteSearchBarActionTypes } from 'app/globalAutoCompleteSearchBar/GlobalAutoCompleteSearchBarConstants.js'; +import { + filterBarActionTypes +} from 'generic-components/filterBar/FilterBarConstants.js'; export default (state = {}, action) => { let data = action.data; switch (action.type) { - - case vnfActionTypes.COUNT_BY_PROV_STATUS_RECEIVED: + case vnfActionTypes.VNF_NETWORK_ERROR: return { ...state, - processedProvStatusCountChartData: data.provStatusCountChartData.chartData, - feedbackMsgText: '', - feedbackMsgSeverity: '' + processedProvStatusCountChartData: CHART_PROV_STATUS.emptyData, + processedOrchStatusCountChartData: CHART_ORCH_STATUS.emptyData, + processedNfTypeCountChartData: CHART_NF_TYPE.emptyData, + processedNfRoleCountChartData: CHART_NF_ROLE.emptyData, + count: TOTAL_VNF_COUNT.emptyValue, + feedbackMsgText: ERROR_RETRIEVING_DATA, + feedbackMsgSeverity: MESSAGE_LEVEL_DANGER }; - - case vnfActionTypes.COUNT_BY_ORCH_STATUS_RECEIVED: + case globalAutoCompleteSearchBarActionTypes.SEARCH_WARNING_EVENT: return { ...state, - processedOrchStatusCountChartData: data.orchStatusCountChartData.chartData, - feedbackMsgText: '', - feedbackMsgSeverity: '' + processedProvStatusCountChartData: CHART_PROV_STATUS.emptyData, + processedOrchStatusCountChartData: CHART_ORCH_STATUS.emptyData, + processedNfTypeCountChartData: CHART_NF_TYPE.emptyData, + processedNfRoleCountChartData: CHART_NF_ROLE.emptyData, + count: TOTAL_VNF_COUNT.emptyValue + }; + case filterBarActionTypes.NEW_SELECTIONS: + return { + ...state, + vnfFilterValues: data.selectedValuesMap, + unifiedFilterValues: data.unifiedValues + }; + case filterBarActionTypes.SET_UNIFIED_VALUES: + return { + ...state, + unifiedFilterValues: data }; - case vnfActionTypes.TOTAL_VNF_COUNT_RECEIVED: + case vnfActionTypes.VNF_SEARCH_RESULTS_RECEIVED: return { ...state, count: data.count, + processedProvStatusCountChartData: data.provStatusData, + processedOrchStatusCountChartData: data.orchStatusData, + processedNfTypeCountChartData: data.nfTypeData, + processedNfRoleCountChartData: data.nfRoleData, feedbackMsgText: '', feedbackMsgSeverity: '' }; - case vnfActionTypes.ERROR_NO_DATA_FOR_PROV_STATUS_IN_SEARCH_RANGE_RECEIVED: + case vnfActionTypes.VNF_FILTER_PANEL_TOGGLED: return { ...state, - processedProvStatusCountChartData: CHART_PROV_STATUS.emptyData, + vnfVisualizationPanelClass: data.vnfVisualizationPanelClass }; - case vnfActionTypes.ERROR_NO_DATA_FOR_ORCH_STATUS_IN_SEARCH_RANGE_RECEIVED: + case vnfActionTypes.VNF_SEARCH_FILTERS_RECEIVED: return { ...state, - processedOrchStatusCountChartData: CHART_ORCH_STATUS.emptyData, + vnfFilters: data }; - case vnfActionTypes.ERROR_NO_COUNT_RECEIVED: + case filterBarActionTypes.SET_NON_CONVERTED_VALUES: return { ...state, - count: TOTAL_VNF_COUNT.emptyValue, + nonConvertedFilters: data }; - case vnfActionTypes.VNF_NETWORK_ERROR: + case filterBarActionTypes.SET_CONVERTED_VALUES: return { ...state, - processedProvStatusCountChartData: CHART_PROV_STATUS.emptyData, - processedOrchStatusCountChartData: CHART_ORCH_STATUS.emptyData, - count: TOTAL_VNF_COUNT.emptyValue, - feedbackMsgText: ERROR_RETRIEVING_DATA, - feedbackMsgSeverity: MESSAGE_LEVEL_DANGER + nonConvertedFilters: {}, + unifiedFilterValues: data.convertedValues, + vnfFilterValues: data.nonConvertedValues // launching DI view via menu button requires this + // to be set so visualizations and table will populate themselves }; - case globalAutoCompleteSearchBarActionTypes.SEARCH_WARNING_EVENT: + case filterBarActionTypes.CLEAR_FILTERS: return { ...state, - processedProvStatusCountChartData: CHART_PROV_STATUS.emptyData, - processedOrchStatusCountChartData: CHART_ORCH_STATUS.emptyData, - count: TOTAL_VNF_COUNT.emptyValue + vnfFilters: {}, + vnfFilterValues: {}, + nonConvertedFilters: {}, + unifiedFilterValues: {} }; } diff --git a/src/app/vnfSearch/VnfSearchTotalCountVisualization.jsx b/src/app/vnfSearch/VnfSearchTotalCountVisualization.jsx index 690b5ee..5d3f1f2 100644 --- a/src/app/vnfSearch/VnfSearchTotalCountVisualization.jsx +++ b/src/app/vnfSearch/VnfSearchTotalCountVisualization.jsx @@ -1,26 +1,28 @@ +/* eslint-disable max-len,max-len,max-len,max-len,max-len,max-len */ /* - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * ============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 + * 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========================================================= + * ============LICENSE_END===================================================== * - * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * ECOMP and OpenECOMP are trademarks + * and service marks of AT&T Intellectual Property. */ -/* eslint-disable max-len,max-len,max-len,max-len,max-len,max-len */ import React, {Component} from 'react'; import {connect} from 'react-redux'; @@ -41,7 +43,10 @@ let mapStateToProps = ({vnfSearch}) => { class VnfSearchTotalCountVisualization extends Component { static propTypes = { - count: React.PropTypes.number + count: React.PropTypes.oneOfType([ + React.PropTypes.string, + React.PropTypes.number + ]) }; render() { |