From b24b041335dc1e5ccd5a9dd50313e4bc04812fcd Mon Sep 17 00:00:00 2001 From: SilentSpike Date: Sat, 28 Dec 2019 21:45:45 +0000 Subject: [PATCH] Add Osmose issue detail fetching for UI Must fetch details per-issue to get the associated OSM elements for highlighting and use in the error description. Also fixes URL for error closure. --- data/core.yaml | 3 - data/qa_errors.json | 1 + dist/locales/en.json | 4 -- modules/services/osmose.js | 41 +++++++++++--- modules/ui/osmose_details.js | 105 ++++++++++++++++++----------------- 5 files changed, 89 insertions(+), 65 deletions(-) diff --git a/data/core.yaml b/data/core.yaml index 24507a75a..a10db48cc 100644 --- a/data/core.yaml +++ b/data/core.yaml @@ -857,9 +857,6 @@ en: title: 'Highway intersecting highway' 1070-10: title: 'Waterway intersecting waterway' - 1080-1: - title: 'Orphan Nodes Cluster' - description: 'A culster of nodes with no tags is present.' 1150: title: 'Overlapping Similar Areas' description: '{0} and {1} overlap.' diff --git a/data/qa_errors.json b/data/qa_errors.json index 77364cf8c..5fe329ff8 100644 --- a/data/qa_errors.json +++ b/data/qa_errors.json @@ -34,6 +34,7 @@ } }, "osmose": { + "items": ["0", "1040", "1050", "1070", "1150", "1280"], "errorTypes": { "0-1": { "icon": "maki-home" diff --git a/dist/locales/en.json b/dist/locales/en.json index df3cdc818..d2204cd95 100644 --- a/dist/locales/en.json +++ b/dist/locales/en.json @@ -1075,10 +1075,6 @@ "1070-10": { "title": "Waterway intersecting waterway" }, - "1080-1": { - "title": "Orphan Nodes Cluster", - "description": "A culster of nodes with no tags is present." - }, "1280-1": { "title": "Incorrect Speed Camera", "description": "Speed camera should be on the highway or part of an \"enforcement\" relation." diff --git a/modules/services/osmose.js b/modules/services/osmose.js index 12060cbe9..7408480eb 100644 --- a/modules/services/osmose.js +++ b/modules/services/osmose.js @@ -92,7 +92,8 @@ export default { loadErrors: function(projection) { var params = { - level: '1,2,3' + level: '1,2,3', + item: services.osmose.items.join() // only interested in certain errors }; // determine the needed tiles to cover the view @@ -140,11 +141,6 @@ export default { item: props.item // category of the issue for styling }); - // Variables used in the description - // d.replacements = elems.map(function(i) { - // return linkEntity(i); - // }); - _erCache.data[d.id] = d; _erCache.rtree.insert(encodeErrorRtree(d)); } @@ -160,7 +156,36 @@ export default { }); }, - // todo: need to fetch specific error details upon UI loading for element IDs + loadErrorDetail: function(d, callback) { + // Error details only need to be fetched once + if (d.elems !== undefined) { + if (callback) callback(null, d); + return; + } + + var url = _osmoseUrlRoot + 'en/api/0.3beta/issue/' + d.identifier; + + var that = this; + d3_json(url) + .then(function(data) { + // Associated elements used for highlighting + // Assign directly for immediate use in the callback + d.elems = data.elems.map(function(e) { + return e.type.substring(0,1) + e.id; + }); + + // Element links used in the error description + d.replacements = d.elems.map(function(i) { + return linkEntity(i); + }); + + that.replaceError(d); + if (callback) callback(null, d); + }) + .catch(function(err) { + if (callback) callback(err.message); + }); + }, postUpdate: function(d, callback) { if (_erCache.inflightPost[d.id]) { @@ -170,7 +195,7 @@ export default { var that = this; // UI sets the status to either '/done' or '/false' - var url = _osmoseUrlRoot + 'issue/' + d.identifier + d.newStatus; + var url = _osmoseUrlRoot + 'en/api/0.3beta/issue/' + d.identifier + d.newStatus; var controller = new AbortController(); _erCache.inflightPost[d.id] = controller; diff --git a/modules/ui/osmose_details.js b/modules/ui/osmose_details.js index 0d968e7f4..756a5dd5a 100644 --- a/modules/ui/osmose_details.js +++ b/modules/ui/osmose_details.js @@ -6,6 +6,7 @@ import { import { dataEn } from '../../data'; import { modeSelect } from '../modes/select'; import { t } from '../util/locale'; +import { services } from '../services'; import { utilDisplayName, utilEntityOrMemberSelector } from '../util'; @@ -57,65 +58,69 @@ export function uiOsmoseDetails(context) { .append('h4') .text(function() { return t('QA.keepRight.detail_description'); }); - descriptionEnter - .append('div') - .attr('class', 'error-details-description-text') - .html(errorDetail); + services.osmose.loadErrorDetail(_error, function(err, d) { + if (d.elems === undefined) { return; } - // If there are entity links in the error message.. - descriptionEnter.selectAll('.error_entity_link, .error_object_link') - .each(function() { - var link = d3_select(this); - var entityID = this.textContent; - var entity = context.hasEntity(entityID); + descriptionEnter + .append('div') + .attr('class', 'error-details-description-text') + .html(errorDetail); - // Add click handler - link - .on('mouseenter', function() { - context.surface().selectAll(utilEntityOrMemberSelector([entityID], context.graph())) - .classed('hover', true); - }) - .on('mouseleave', function() { - context.surface().selectAll('.hover') - .classed('hover', false); - }) - .on('click', function() { - d3_event.preventDefault(); - var osmlayer = context.layers().layer('osm'); - if (!osmlayer.enabled()) { - osmlayer.enabled(true); - } + // If there are entity links in the error message.. + descriptionEnter.selectAll('.error_entity_link, .error_object_link') + .each(function() { + var link = d3_select(this); + var entityID = this.textContent; + var entity = context.hasEntity(entityID); - context.map().centerZoom(_error.loc, 20); + // Add click handler + link + .on('mouseenter', function() { + context.surface().selectAll(utilEntityOrMemberSelector([entityID], context.graph())) + .classed('hover', true); + }) + .on('mouseleave', function() { + context.surface().selectAll('.hover') + .classed('hover', false); + }) + .on('click', function() { + d3_event.preventDefault(); + var osmlayer = context.layers().layer('osm'); + if (!osmlayer.enabled()) { + osmlayer.enabled(true); + } - if (entity) { - context.enter(modeSelect(context, [entityID])); - } else { - context.loadEntity(entityID, function() { + context.map().centerZoom(d.loc, 20); + + if (entity) { context.enter(modeSelect(context, [entityID])); - }); + } else { + context.loadEntity(entityID, function() { + context.enter(modeSelect(context, [entityID])); + }); + } + }); + + // Replace with friendly name if possible + // (The entity may not yet be loaded into the graph) + if (entity) { + var name = utilDisplayName(entity); // try to use common name + + if (!name) { + var preset = context.presets().match(entity, context.graph()); + name = preset && !preset.isFallback() && preset.name(); // fallback to preset name } - }); - // Replace with friendly name if possible - // (The entity may not yet be loaded into the graph) - if (entity) { - var name = utilDisplayName(entity); // try to use common name - - if (!name) { - var preset = context.presets().match(entity, context.graph()); - name = preset && !preset.isFallback() && preset.name(); // fallback to preset name + if (name) { + this.innerText = name; + } } + }); - if (name) { - this.innerText = name; - } - } - }); - - // Don't hide entities related to this error - #5880 - // context.features().forceVisible(_error.elems); - context.map().pan([0,0]); // trigger a redraw + // Don't hide entities related to this error - #5880 + context.features().forceVisible(d.elems); + context.map().pan([0,0]); // trigger a redraw + }); }