in modules/ui/osmose_details.js [24:203]
function osmoseDetails(selection) {
const details = selection.selectAll('.error-details')
.data(
_qaItem ? [_qaItem] : [],
d => `${d.id}-${d.status || 0}`
);
details.exit()
.remove();
const detailsEnter = details.enter()
.append('div')
.attr('class', 'error-details qa-details-container');
// Description
if (issueString(_qaItem, 'detail')) {
const div = detailsEnter
.append('div')
.attr('class', 'qa-details-subsection');
div
.append('h4')
.html(t.html('QA.keepRight.detail_description'));
div
.append('p')
.attr('class', 'qa-details-description-text')
.html(d => issueString(d, 'detail'))
.selectAll('a')
.attr('rel', 'noopener')
.attr('target', '_blank');
}
// Elements (populated later as data is requested)
const detailsDiv = detailsEnter
.append('div')
.attr('class', 'qa-details-subsection');
const elemsDiv = detailsEnter
.append('div')
.attr('class', 'qa-details-subsection');
// Suggested Fix (mustn't exist for every issue type)
if (issueString(_qaItem, 'fix')) {
const div = detailsEnter
.append('div')
.attr('class', 'qa-details-subsection');
div
.append('h4')
.html(t.html('QA.osmose.fix_title'));
div
.append('p')
.html(d => issueString(d, 'fix'))
.selectAll('a')
.attr('rel', 'noopener')
.attr('target', '_blank');
}
// Common Pitfalls (mustn't exist for every issue type)
if (issueString(_qaItem, 'trap')) {
const div = detailsEnter
.append('div')
.attr('class', 'qa-details-subsection');
div
.append('h4')
.html(t.html('QA.osmose.trap_title'));
div
.append('p')
.html(d => issueString(d, 'trap'))
.selectAll('a')
.attr('rel', 'noopener')
.attr('target', '_blank');
}
// Save current item to check if UI changed by time request resolves
const thisItem = _qaItem;
services.osmose.loadIssueDetail(_qaItem)
.then(d => {
// No details to add if there are no associated issue elements
if (!d.elems || d.elems.length === 0) return;
// Do nothing if UI has moved on by the time this resolves
if (
context.selectedErrorID() !== thisItem.id
&& context.container().selectAll(`.qaItem.osmose.hover.itemId-${thisItem.id}`).empty()
) return;
// Things like keys and values are dynamically added to a subtitle string
if (d.detail) {
detailsDiv
.append('h4')
.html(t.html('QA.osmose.detail_title'));
detailsDiv
.append('p')
.html(d => d.detail)
.selectAll('a')
.attr('rel', 'noopener')
.attr('target', '_blank');
}
// Create list of linked issue elements
elemsDiv
.append('h4')
.html(t.html('QA.osmose.elems_title'));
elemsDiv
.append('ul').selectAll('li')
.data(d.elems)
.enter()
.append('li')
.append('a')
.attr('href', '#')
.attr('class', 'error_entity_link')
.html(d => d)
.each(function() {
const link = d3_select(this);
const entityID = this.textContent;
const entity = context.hasEntity(entityID);
// Add click handler
link
.on('mouseenter', () => {
utilHighlightEntities([entityID], true, context);
})
.on('mouseleave', () => {
utilHighlightEntities([entityID], false, context);
})
.on('click', (d3_event) => {
d3_event.preventDefault();
utilHighlightEntities([entityID], false, context);
const osmlayer = context.layers().layer('osm');
if (!osmlayer.enabled()) {
osmlayer.enabled(true);
}
context.map().centerZoom(d.loc, 20);
if (entity) {
context.enter(modeSelect(context, [entityID]));
} else {
context.loadEntity(entityID, (err, result) => {
if (err) return;
const entity = result.data.find(e => e.id === entityID);
if (entity) context.enter(modeSelect(context, [entityID]));
});
}
});
// Replace with friendly name if possible
// (The entity may not yet be loaded into the graph)
if (entity) {
let name = utilDisplayName(entity); // try to use common name
if (!name) {
const preset = presetManager.match(entity, context.graph());
name = preset && !preset.isFallback() && preset.name(); // fallback to preset name
}
if (name) {
this.innerText = name;
}
}
});
// Don't hide entities related to this issue - #5880
context.features().forceVisible(d.elems);
context.map().pan([0,0]); // trigger a redraw
})
.catch(err => {
console.log(err); // eslint-disable-line no-console
});
}