From a2f4307bc34dee6cff0e137b1910961fb196bc55 Mon Sep 17 00:00:00 2001 From: Emmanuel Robert Ssebaggala Date: Sat, 5 Oct 2019 13:37:52 +0300 Subject: [PATCH 1/3] Update version to v0.3.0-beta.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e2079873..66d5b550 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "Boda-Lite", - "version": "0.3.0", + "version": "0.3.0-beta.3", "description": "Boda-Lite is a telecommunication network management application", "private": true, "homepage": "./", From 3fd718187db3b2442cfdcd59fd032f147aa8f7da Mon Sep 17 00:00:00 2001 From: Emmanuel Robert Ssebaggala Date: Sun, 6 Oct 2019 03:22:38 +0300 Subject: [PATCH 2/3] Update carrier colors on GIS map --- background/baseline.js | 11 ++-- src/modules/gis/GISMap.js | 92 ++++++++++++++++++++++++---------- src/modules/gis/gis-actions.js | 44 ++++++++++++++++ src/modules/gis/gis-reducer.js | 43 +++++++++++++++- 4 files changed, 158 insertions(+), 32 deletions(-) diff --git a/background/baseline.js b/background/baseline.js index bf52d979..1b07e995 100644 --- a/background/baseline.js +++ b/background/baseline.js @@ -226,6 +226,7 @@ FROM ericsson_cm."${mo}" t1 WHERE t1.data->>'BSC_NAME' IS NOT NULL + AND TRIM(t1.data->>'BSC_NAME') != '' GROUP BY t1.data->>'BSC_NAME', t1.data->>'${parameter}' @@ -249,6 +250,7 @@ FROM ericsson_cm."${mo}" t1 WHERE t1.data->>'SubNetwork_2_id' IS NOT NULL + AND TRIM(t1.data->>'SubNetwork_2_id') != '' GROUP BY t1.data->>'SubNetwork_2_id', t1.data->>'${parameter}' @@ -292,7 +294,7 @@ async function computeZTEBaselineScore(tech, mo, parameter){ INSERT INTO baseline.scores (vendor, technology, cluster, mo, parameter, value, score) SELECT - 'ERICSSON' as vendor, + 'ZTE' as vendor, '${tech}' as technology, t1.data->>'SubNetwork_2_id' AS "cluster", '${mo}' AS "mo", @@ -300,9 +302,10 @@ SELECT t1.data->>'${parameter}' as "value", COUNT(1) AS "score" FROM -ericsson_cm."${mo}" t1 +zte_cm."${mo}" t1 WHERE t1.data->>'SubNetwork_2_id' IS NOT NULL + AND TRIM(t1.data->>'SubNetwork_2_id') != '' GROUP BY t1.data->>'SubNetwork_2_id', t1.data->>'${parameter}' @@ -317,7 +320,7 @@ ON CONFLICT ON CONSTRAINT unq_scores DO UPDATE SET INSERT INTO baseline.scores (vendor, technology, cluster, mo, parameter, value, score) SELECT - 'ERICSSON' as vendor, + 'ZTE' as vendor, '${tech}' as technology, t1.data->>'meContext_id' AS "cluster", '${mo}' AS "mo", @@ -325,7 +328,7 @@ SELECT t1.data->>'${parameter}' as "value", COUNT(1) AS "score" FROM -ericsson_cm."${mo}" t1 +zte_cm."${mo}" t1 WHERE TRIM(t1.data->>'meContext_id') IS NOT NULL AND TRIM(t1.data->>'meContext_id') != '' diff --git a/src/modules/gis/GISMap.js b/src/modules/gis/GISMap.js index 9a288277..b0d2502b 100644 --- a/src/modules/gis/GISMap.js +++ b/src/modules/gis/GISMap.js @@ -26,7 +26,16 @@ import { ProgressBar, Switch } from "@blueprintjs/core"; -import { gisGetCells, gisGetNbrs, gisHideCellNbrs, gisHideRelation, gisClear } from './gis-actions'; +import { + gisGetCells, + gisGetNbrs, + gisHideCellNbrs, + gisHideRelation, + gisClear, + gisFetchPlanFrequencies, + gisUpdateCarrierColor, + gisUpdateSectorRadius +} from './gis-actions'; import { SemiCircle, SemiCircleMarker } from 'react-leaflet-semicircle'; import 'react-leaflet-fullscreen-control' import { FaRss } from "react-icons/fa"; @@ -151,8 +160,6 @@ class GISMap extends React.Component{ const target = event.target; const value = target.type === 'checkbox' ? target.checked : target.value; const name = target.name; - - console.log("handleEnabledChange:", value, name); this.setState({ [name]: value @@ -198,6 +205,9 @@ class GISMap extends React.Component{ componentDidMount () { this.map = this.refs.map.leafletElement; const map = this.refs.map.leafletElement; + + //Update carrier colors + this.props.dispatch(gisFetchPlanFrequencies()); //By the time the GIS tab is shown, the GIS component has already //been mounted. As a result, leaflet does not display correctly because @@ -265,6 +275,9 @@ class GISMap extends React.Component{ }); } + updateCarrierColor = (e) => { + this.props.dispatch(gisUpdateCarrierColor(e.target.name, e.target.value)); + } importMapData = () => { //Show error notice if user tries to upload empty file. @@ -341,27 +354,17 @@ class GISMap extends React.Component{ this.setState({clearBeforeLoading: !this.state.clearBeforeLoading}); } - handleGSMRadiusChange = (e) => { - if(isNaN(e.target.value) || e.target.value <= 0 ) return; - this.techRadii['gsm'] = e.target.value; - this.setState({gsmRadius: e.target.value}); - } - - handleUMTSRadiusChange = (e) => { - if(isNaN(e.target.value) || e.target.value <= 0 ) return; - this.techRadii['umts'] = e.target.value; - this.setState({umtsRadius: e.target.value}); - } - - handleLTERadiusChange = (e) => { - if(isNaN(e.target.value) || e.target.value <= 0 ) return; - this.techRadii['lte'] = e.target.value; - this.setState({lteRadius: e.target.value}); + handleRadiusChange = (e) => { + const tech = e.target.name.replace("Radius", ""); + const radius = e.target.value; + this.props.dispatch(gisUpdateSectorRadius(tech, radius)); } render(){ + console.log('Rendering....'); + const position = [this.state.lat, this.state.lng] const height = this.state.height; let center = [this.state.lat, this.state.lng] @@ -403,10 +406,18 @@ class GISMap extends React.Component{ const cell = this.props.cells[cellid]; const beamWidth = parseInt(cell.antenna_beam) > 0 && parseInt(cell.antenna_beam) !== NaN ? cell.antenna_beam : 30; const lcTech = cell.technology.toLowerCase(); - const radius = this.techRadii[lcTech] || 500; + + //Radius. Adjust by twice the last digit in the ci + const lastDigit = cell.ci.toString()[cell.ci.toString().length-1] || 0; + + let radius = this.props.sectorRadius[lcTech] || 500 ; + radius = parseInt(radius) + (lastDigit-1)*4; + + const color = this.props.carrierColors[cell.frequency] || null; return ( @@ -672,8 +684,9 @@ class GISMap extends React.Component{ > @@ -687,11 +700,36 @@ class GISMap extends React.Component{ inline={true} className="mb-1" > - + + + +
+
+ Carrier Colors +
+
+ {Object.keys(this.props.carrierColors).map((v, i) => ( +
+
{v}
+
+ +
+
+ ))} + +
@@ -713,7 +751,9 @@ function mapStateToProps(state){ cells: state.gis.cells || {}, relations: state.gis.relations || {}, redraw: state.gis.redraw, - hiddenRelations: state.gis.hiddenRelations || {} + hiddenRelations: state.gis.hiddenRelations || {}, + carrierColors: state.gis.carrierColorMap, + sectorRadius: state.gis.sectorRadius }; } diff --git a/src/modules/gis/gis-actions.js b/src/modules/gis/gis-actions.js index b63f24ea..b5016c51 100644 --- a/src/modules/gis/gis-actions.js +++ b/src/modules/gis/gis-actions.js @@ -17,10 +17,41 @@ export const GIS_CONFIRM_NBRS_RECEIVED = 'GIS_CONFIRM_NBRS_RECEIVED'; export const GIS_HIDE_CELL_NBRS = 'GIS_HIDE_CELL_NBRS'; export const GIS_HIDE_RELATION = 'GIS_HIDE_RELATION'; + export const GIS_SHOW_RELATION = 'GIS_SHOW_RELATION'; export const GIS_CLEAR = 'GIS_CLEAR'; +export const GIS_UPDATE_PLAN_CARRIERS = 'GIS_UPDATE_PLAN_CARRIERS'; + +export const GIS_UPDATE_CARRIER_COLOR = 'GIS_UPDATE_CARRIER_COLOR'; + +export const GIS_UPDATE_SECTOR_RADIUS = 'GIS_UPDATE_SECTOR_RADIUS'; + +export function gisUpdateSectorRadius(tech, radius){ + return { + type: GIS_UPDATE_SECTOR_RADIUS, + tech: tech, + radius: radius + } +} + +export function gisUpdateCarrierColor(carrier, color){ + return{ + type: GIS_UPDATE_CARRIER_COLOR, + carrier: carrier, + color: color + } +} + +export function gisUpdatePlanCarriers(frequencies){ + return{ + type: GIS_UPDATE_PLAN_CARRIERS, + frequencies: frequencies + } +} + + //Convert array to object const arrayToObject = (array, id) => array.reduce((obj, item) => { @@ -137,6 +168,19 @@ export function gisGetNbrs(svrCI){ } } +export function gisFetchPlanFrequencies(){ + return async (dispatch, getState) => { + + const results = await runQuery(`SELECT DISTINCT frequency FROM plan_network.vw_cells`); + if(typeof results.error !== 'undefined'){ + log.error(results.error); + return dispatch(gisShowError("Failed to retreive neighbours")); + } + + dispatch(gisUpdatePlanCarriers(results.rows.map(f => f.frequency))); + } +} + /* * Hide nbrs for a cell * diff --git a/src/modules/gis/gis-reducer.js b/src/modules/gis/gis-reducer.js index 4c62f960..9a38264d 100644 --- a/src/modules/gis/gis-reducer.js +++ b/src/modules/gis/gis-reducer.js @@ -5,7 +5,10 @@ import { GIS_CONFIRM_CELLS_RECEIVED, GIS_CONFIRM_NBRS_RECEIVED, GIS_SHOW_INFO, GIS_HIDE_CELL_NBRS, GIS_HIDE_RELATION, - GIS_CLEAR} from './gis-actions'; + GIS_CLEAR, + GIS_UPDATE_PLAN_CARRIERS, + GIS_UPDATE_CARRIER_COLOR, + GIS_UPDATE_SECTOR_RADIUS} from './gis-actions'; const initialState = { cells: [], @@ -14,7 +17,18 @@ const initialState = { //List of relations to hide hiddenRelations: {}, - carrierLayer: {} + carrierLayer: {}, + + //Colors to use for each carrier + carrierColors: ["#0251a6", "#498354", "#66aebd", "#4a8bae", "#2f4285", "#edb1ff", "#a960ed", "#007bff", "#432ab7", "#427ff5", "#88075f", "#cc5d96", "#fb0998", "#fa1bfc", "#9a789e", "#20c997", "#76480d", "#b1e632", "#19a71f", "#20f53d"], + carrierColorMap: {}, + + //Radius of the sectors + sectorRadius: { + 'gsm': 700, + 'umts':500, + 'lte': 250, + } }; function gis(state = initialState, action) { @@ -60,8 +74,33 @@ function gis(state = initialState, action) { [action.svr_ci + "-" + action.nbr_ci]: {} } } + case GIS_UPDATE_PLAN_CARRIERS: + var colorMap = {}; + action.frequencies.forEach((f, i) => { + colorMap[f] = state.carrierColors[i]; + }); + return { + ...state, + carrierColorMap: colorMap + } case GIS_CLEAR: return initialState; + case GIS_UPDATE_CARRIER_COLOR: + return { + ...state, + carrierColorMap: { + ...state.carrierColorMap, + [action.carrier]: action.color + } + } + case GIS_UPDATE_SECTOR_RADIUS: + return { + ...state, + sectorRadius: { + ...state.sectorRadius, + [action.tech]: action.radius || initialState.sectorRadius[action.tech] + } + } default: return state; } From 5e2f57ec1b5a11919cc7acb8574e52dfe15700e5 Mon Sep 17 00:00:00 2001 From: Emmanuel Robert Ssebaggala Date: Sun, 6 Oct 2019 05:25:57 +0300 Subject: [PATCH 3/3] Add button to clear entire baseline reference --- background/background-process.html | 14 +++++++- background/background-utils.js | 11 ++++++ package.json | 2 +- src/modules/baseline/Baseline.jsx | 56 ++++++++++++++++++++++++++++-- src/version.js | 2 +- 5 files changed, 79 insertions(+), 6 deletions(-) diff --git a/background/background-process.html b/background/background-process.html index a2937d58..a125f893 100644 --- a/background/background-process.html +++ b/background/background-process.html @@ -851,9 +851,21 @@

Background process

}catch(err){ log.error(err) sendLogToUI(task,'error', "Error occured while importing file. Check logs for details."); - } + } + + // clear_baseline_reference + try{ + if(task === 'clear_baseline_reference'){ + const result = await utils.clearBaselineReference(); + sendLogToUI(task, result.status, result.message); + } + }catch(err){ + log.error(err) + sendLogToUI(task,'error', "Error occured while clearing the baseline reference. Check logs for details."); + } } + ipcRenderer.on('parse-cm-job', (event, task, args) => { log.info(`Backgroup process: task: ${task} args: ${args}`); const obj = JSON.parse(args) diff --git a/background/background-utils.js b/background/background-utils.js index a252e235..152a4c11 100644 --- a/background/background-utils.js +++ b/background/background-utils.js @@ -1565,6 +1565,17 @@ async function importGISFile(fileName, format, truncateTable){ } } +async function clearBaselineReference(){ + try{ + await queryHelper.runQuery("TRUNCATE TABLE baseline.configuration RESTART IDENTITY"); + return {status: 'success', message: `Successfully cleared baseline reference` }; + }catch(e){ + log.error(e); + return {status: 'error', message: `Error occured while importing ${format} file. Check logs for details.`}; + } +} + +exports.clearBaselineReference = clearBaselineReference; exports.importGISFile = importGISFile; exports.addParamToBaselineRef = addParamToBaselineRef; exports.runBaseline = runBaseline; diff --git a/package.json b/package.json index 66d5b550..1c810a71 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "Boda-Lite", - "version": "0.3.0-beta.3", + "version": "0.3.0-beta.4", "description": "Boda-Lite is a telecommunication network management application", "private": true, "homepage": "./", diff --git a/src/modules/baseline/Baseline.jsx b/src/modules/baseline/Baseline.jsx index ec88811a..b0a93341 100644 --- a/src/modules/baseline/Baseline.jsx +++ b/src/modules/baseline/Baseline.jsx @@ -117,6 +117,7 @@ export default class Baseline extends React.Component { this.baselineRefDownloadListener = null; this.addToBaselineRefListener = null; this.deleteBaselineListener = null; + this.clearBaselineRefListener = null; } @@ -220,7 +221,7 @@ export default class Baseline extends React.Component { } /** - * Delete parameter + * Delete parameter's baseline reference */ deleteParameter = (vendor, technology, mo, parameter) => { let payload = { @@ -271,6 +272,54 @@ export default class Baseline extends React.Component { } + /** + * Clear all parameters in the baseline reference + */ + clearBaselineReference = () => { + let payload = { + }; + + //Set processing to true + this.setState({processing: true }); + + ipcRenderer.send('parse-cm-request', 'clear_baseline_reference', JSON.stringify(payload)); + + this.clearBaselineRefListener = (event, task, args) => { + const obj = JSON.parse(args) + if(task !== 'clear_baseline_reference') return; + + //error + if(obj.status === 'error' && task === 'clear_baseline_reference' ){ + this.setState({ + notice: {type: 'danger', message: obj.message}, + processing: false + }); + ipcRenderer.removeListener("parse-cm-request", this.clearBaselineRefListener); + } + + //info + if(obj.status === 'info' && task === 'clear_baseline_reference' ){ + this.setNotice('info', obj.message) + } + + if(obj.status === "success" && task === 'clear_baseline_reference' ){ + this.setState({ + notice: { + type: 'success', + message: obj.message + }, + processing: false + }); + + ipcRenderer.removeListener("parse-cm-request", this.clearBaselineRefListener); + this.refreshData(); + } + + } + ipcRenderer.on('parse-cm-request', this.clearBaselineRefListener); + + } + /* * Update the cluster state variable @@ -576,7 +625,8 @@ export default class Baseline extends React.Component { - |   +
diff --git a/src/version.js b/src/version.js index a1cf9a68..58fce8bc 100644 --- a/src/version.js +++ b/src/version.js @@ -1,3 +1,3 @@ -export const VERSION = "0.3.0-beta.3"; +export const VERSION = "0.3.0-beta.4"; export default VERSION;