diff --git a/corehq/apps/geospatial/static/geospatial/js/case_management.js b/corehq/apps/geospatial/static/geospatial/js/case_management.js index f0c2bfb13728..fdef307a1a5c 100644 --- a/corehq/apps/geospatial/static/geospatial/js/case_management.js +++ b/corehq/apps/geospatial/static/geospatial/js/case_management.js @@ -65,17 +65,16 @@ hqDefine("geospatial/js/case_management", [ self.handleDisbursementResults = function (result) { // Clean stale disbursement results - mapModel.removeDisbursementLayers(); + mapModel.removeDisbursementLayer(); let groupId = 0; + mapModel.caseGroupsIndex = {}; Object.keys(result).forEach((userId) => { const user = mapModel.userMapItems().find((userModel) => {return userModel.itemId === userId;}); mapModel.caseGroupsIndex[userId] = {groupId: groupId, item: user}; - let cases = []; mapModel.caseMapItems().forEach((caseModel) => { if (result[userId].includes(caseModel.itemId)) { - cases.push(caseModel); mapModel.caseGroupsIndex[caseModel.itemId] = { groupId: groupId, item: caseModel, @@ -83,25 +82,16 @@ hqDefine("geospatial/js/case_management", [ }; } }); - self.connectUserWithCasesOnMap(user, cases); groupId += 1; }); + self.connectUserWithCasesOnMap(); self.setBusy(false); }; - self.clearConnectionLines = function (cases) { - let mapInstance = mapModel.mapInstance; + self.getCasesForDisbursement = function (cases) { let caseData = []; const hasSelectedCases = mapModel.hasSelectedCases(); cases.forEach(function (c) { - const layerId = mapModel.getLineFeatureId(c.itemId); - if (mapInstance.getLayer(layerId)) { - mapInstance.removeLayer(layerId); - } - if (mapInstance.getSource(layerId)) { - mapInstance.removeSource(layerId); - } - // Either select all if none selected, or only pick selected cases if (!hasSelectedCases || c.isSelected()) { caseData.push({ @@ -111,13 +101,13 @@ hqDefine("geospatial/js/case_management", [ }); } }); - return caseData; }; self.runCaseDisbursementAlgorithm = function (cases, users) { self.setBusy(true); - const caseData = self.clearConnectionLines(cases); + mapModel.removeDisbursementLayer(); + const caseData = self.getCasesForDisbursement(cases); self.setDisbursementParameters = function (parameters) { var parametersList = [ @@ -181,38 +171,35 @@ hqDefine("geospatial/js/case_management", [ }); }; - self.connectUserWithCasesOnMap = function (user, cases) { - cases.forEach((caseModel) => { - const lineCoordinates = [ - [user.itemData.coordinates.lng, user.itemData.coordinates.lat], - [caseModel.itemData.coordinates.lng, caseModel.itemData.coordinates.lat], - ]; - let mapInstance = mapModel.mapInstance; - mapInstance.addLayer({ - id: mapModel.getLineFeatureId(caseModel.itemId), - type: 'line', - source: { - type: 'geojson', - data: { + self.connectUserWithCasesOnMap = function () { + let disbursementLinesSource = generateDisbursementLinesSource(); + mapModel.addDisbursementLinesLayer(disbursementLinesSource); + }; + + function generateDisbursementLinesSource() { + let disbursementLinesSource = { + 'type': 'FeatureCollection', + 'features': [], + }; + for (const itemId of Object.keys(mapModel.caseGroupsIndex)) { + let element = mapModel.caseGroupsIndex[itemId]; + if ('assignedUserId' in element) { + let user = mapModel.caseGroupsIndex[element.assignedUserId].item; + const lineCoordinates = [ + [user.itemData.coordinates.lng, user.itemData.coordinates.lat], + [element.item.itemData.coordinates.lng, element.item.itemData.coordinates.lat], + ]; + disbursementLinesSource.features.push( + { type: 'Feature', properties: {}, - geometry: { - type: 'LineString', - coordinates: lineCoordinates, - }, - }, - }, - layout: { - 'line-join': 'round', - 'line-cap': 'round', - }, - paint: { - 'line-color': '#808080', - 'line-width': 1, - }, - }); - }); - }; + geometry: { type: 'LineString', coordinates: lineCoordinates }, + } + ); + } + } + return disbursementLinesSource; + } return self; }; @@ -520,8 +507,8 @@ hqDefine("geospatial/js/case_management", [ if (polygonFilterModel) { selectMapItemsInPolygons(); } - if (mapModel.hasDisbursementLayers()) { - mapModel.removeDisbursementLayers(); + if (mapModel.hasDisbursementLayer()) { + mapModel.removeDisbursementLayer(); } } }); diff --git a/corehq/apps/geospatial/static/geospatial/js/models.js b/corehq/apps/geospatial/static/geospatial/js/models.js index 2b261f96e2d1..7139d8d166e8 100644 --- a/corehq/apps/geospatial/static/geospatial/js/models.js +++ b/corehq/apps/geospatial/static/geospatial/js/models.js @@ -131,6 +131,8 @@ hqDefine('geospatial/js/models', [ self.caseGroupsIndex = {}; + self.DISBURSEMENT_LINES_LAYER_ID = 'disbursement-lines'; + self.initMap = function (mapDivId, centerCoordinates) { mapboxgl.accessToken = initialPageData.get('mapbox_access_token'); // eslint-disable-line no-undef if (!centerCoordinates) { @@ -513,24 +515,38 @@ hqDefine('geospatial/js/models', [ }); }; - self.hasDisbursementLayers = function () { - const mapLayers = self.mapInstance.getStyle().layers; - return _.any( - mapLayers, - function (layer) { return layer.id.includes(DISBURSEMENT_LAYER_PREFIX); } - ); + self.hasDisbursementLayer = function () { + return self.mapInstance.getLayer(self.DISBURSEMENT_LINES_LAYER_ID); }; - self.removeDisbursementLayers = function () { - const mapLayers = self.mapInstance.getStyle().layers; - let layerRemoved = false; - mapLayers.forEach(function (layer) { - if (layer.id.includes(DISBURSEMENT_LAYER_PREFIX)) { - self.mapInstance.removeLayer(layer.id); - layerRemoved = true; - } + self.addDisbursementLinesLayer = function (source) { + let layerId = self.DISBURSEMENT_LINES_LAYER_ID; + self.mapInstance.addSource(layerId, { + 'type': 'geojson', + 'data': source, }); - return layerRemoved; + self.mapInstance.addLayer({ + id: layerId, + type: 'line', + source: layerId, + layout: { + 'line-join': 'round', + 'line-cap': 'round', + }, + paint: { + 'line-color': '#808080', + 'line-width': 1, + }, + }); + }; + + self.removeDisbursementLayer = function () { + if (self.mapInstance.getLayer(self.DISBURSEMENT_LINES_LAYER_ID)) { + self.mapInstance.removeLayer(self.DISBURSEMENT_LINES_LAYER_ID); + } + if (self.mapInstance.getSource(self.DISBURSEMENT_LINES_LAYER_ID)) { + self.mapInstance.removeSource(self.DISBURSEMENT_LINES_LAYER_ID); + } }; self.hasSelectedUsers = function () { @@ -685,11 +701,11 @@ hqDefine('geospatial/js/models', [ function clearDisbursementBeforeProceeding() { let proceedFurther = true; - if (self.mapObj.hasDisbursementLayers()) { + if (self.mapObj.hasDisbursementLayer()) { // hide it by default and show it only if necessary $('#disbursement-clear-message').hide(); if (confirmForClearingDisbursement()) { - self.mapObj.removeDisbursementLayers(); + self.mapObj.removeDisbursementLayer(); $('#disbursement-clear-message').show(); $('#disbursement-params').hide(); } else { @@ -1002,29 +1018,15 @@ hqDefine('geospatial/js/models', [ }; self.finishAssignment = function () { - let userCasesToConnect = {}; - let casesToClear = []; for (const caseItem of self.caseData) { const userItem = self.mapModel.caseGroupsIndex[caseItem.assignedUserId]; const groupId = (userItem) ? userItem.groupId : null; self.mapModel.caseGroupsIndex[caseItem.caseId].assignedUserId = caseItem.assignedUserId; self.mapModel.caseGroupsIndex[caseItem.caseId].groupId = groupId; - - casesToClear.push(caseItem.mapItem); - if (caseItem.assignedUserId) { - if (!userCasesToConnect[caseItem.assignedUserId]) { - userCasesToConnect[caseItem.assignedUserId] = []; - } - userCasesToConnect[caseItem.assignedUserId].push(caseItem.mapItem); - } } - self.disbursementModel.clearConnectionLines(casesToClear); - for (const userId in userCasesToConnect) { - const user = self.mapModel.caseGroupsIndex[userId].item; - const cases = userCasesToConnect[userId]; - self.disbursementModel.connectUserWithCasesOnMap(user, cases); - } + self.mapModel.removeDisbursementLayer(); + self.disbursementModel.connectUserWithCasesOnMap(); }; self.exportAssignments = function () {