Replace validator tooltip with reference function, add tag diff

This commit is contained in:
Bryan Housel
2019-04-16 16:56:50 -04:00
parent 8afd8887cf
commit 01d2e3eaf3
20 changed files with 255 additions and 54 deletions
+25 -1
View File
@@ -3360,12 +3360,36 @@ li.issue-fix-item:not(.actionable) .fix-icon {
width: 100%;
overflow: hidden;
display: none;
padding: 10px;
padding: 10px 0;
}
.issue-info.expanded {
display: inline-block;
}
.issue-info .issue-reference {
margin-bottom: 10px;
}
.issue-info .tagDiff-table {
min-width: 60%;
width: unset;
border: 1px solid #ccc;
}
.issue-info .tagDiff-row {
border: 1px solid #ccc;
}
.issue-info .tagDiff-cell {
padding: 2px 5px;
font-family: monospace;
font-size: 10px;
border: 1px solid #ccc;
}
.issue-info .tagDiff-cell-add {
background: #dfd;
}
.issue-info .tagDiff-cell-remove {
background: #fdd;
}
/* Background - Display Options Sliders
------------------------------------------------------- */
+1
View File
@@ -1269,6 +1269,7 @@ en:
title: "Where:"
visible: "In View"
all: "Everywhere"
suggested: "Suggested updates:"
almost_junction:
title: Almost Junctions
message: "{feature} is very close but not connected to {feature2}"
+1
View File
@@ -1548,6 +1548,7 @@
"all": "Everywhere"
}
},
"suggested": "Suggested updates:",
"almost_junction": {
"title": "Almost Junctions",
"message": "{feature} is very close but not connected to {feature2}",
+1 -1
View File
@@ -334,7 +334,7 @@ export function validationIssue(attrs) {
this.type = attrs.type; // required
this.severity = attrs.severity; // required - 'warning' or 'error'
this.message = attrs.message; // required - localized string
this.tooltip = attrs.tooltip; // required - localized string
this.reference = attrs.reference; // required - function(selection) to render reference info
this.entities = attrs.entities; // optional - array of entities
this.loc = attrs.loc; // optional - expect a [lon, lat] array
this.data = attrs.data; // optional - object containing extra data for the fixes
+4 -1
View File
@@ -159,7 +159,10 @@ export function uiEntityIssues(context) {
.attr('class', 'issue-info')
.style('max-height', '0')
.style('opacity', '0')
.html(function(d) { return d.tooltip; });
.each(function(d) {
d3_select(this)
.call(d.reference);
});
// Update
+3 -6
View File
@@ -93,11 +93,8 @@ export function uiIssues(context) {
.on('click', function(d) {
var extent = d.extent(context.graph());
if (extent) {
var extent = d.extent(context.graph());
if (extent) {
var setZoom = Math.max(context.map().zoom(), 19);
context.map().centerZoomEase(extent.center(), setZoom);
}
var setZoom = Math.max(context.map().zoom(), 19);
context.map().centerZoomEase(extent.center(), setZoom);
// select the first entity
if (d.entities && d.entities.length) {
@@ -134,7 +131,7 @@ export function uiIssues(context) {
var iconName = '#iD-icon-' + (d.severity === 'warning' ? 'alert' : 'error');
d3_select(this)
.call(svgIcon(iconName));
})
});
textEnter
.append('span')
+1 -1
View File
@@ -7,7 +7,7 @@ import { geoRawMercator, geoScaleToZoom, geoVecSubtract, geoVecScale, geoZoomToS
import { rendererTileLayer } from '../renderer';
import { svgDebug, svgData } from '../svg';
import { utilSetTransform } from '../util';
import { utilGetDimensions } from '../util/dimensions';
// import { utilGetDimensions } from '../util/dimensions';
export function uiMapInMap(context) {
+10 -1
View File
@@ -91,7 +91,7 @@ export function validationAlmostJunction() {
feature: utilDisplayLabel(entity, context),
feature2: utilDisplayLabel(edgeHighway, context)
}),
tooltip: t('issues.almost_junction.highway-highway.tip'),
reference: showReference,
entities: [entity, node, edgeHighway],
loc: extendableNodeInfo.node.loc,
data: {
@@ -105,6 +105,15 @@ export function validationAlmostJunction() {
return issues;
function showReference(selection) {
selection.selectAll('.issue-reference')
.data([0])
.enter()
.append('div')
.attr('class', 'issue-reference')
.text(t('issues.almost_junction.highway-highway.tip'));
}
function isExtendableCandidate(node, way) {
// can not accurately test vertices on tiles not downloaded from osm - #5938
+12 -2
View File
@@ -224,7 +224,6 @@ export function validationCrossingWays() {
function findCrossingsByWay(way1, graph, tree) {
var edgeCrossInfos = [];
if (way1.type !== 'way') return edgeCrossInfos;
@@ -467,6 +466,7 @@ export function validationCrossingWays() {
}
}));
}
var useFixIcon = 'iD-icon-layers';
var useFixID;
if (isCrossingIndoors) {
@@ -496,11 +496,12 @@ export function validationCrossingWays() {
icon: 'iD-operation-move',
title: t('issues.fix.reposition_features.title')
}));
return new validationIssue({
type: type,
severity: 'warning',
message: t('issues.crossing_ways.message', messageDict),
tooltip: t('issues.crossing_ways.' + crossingTypeID + '.tip'),
reference: showReference,
entities: entities,
data: {
edges: crossing.edges,
@@ -509,6 +510,15 @@ export function validationCrossingWays() {
loc: crossing.crossPoint,
fixes: fixes
});
function showReference(selection) {
selection.selectAll('.issue-reference')
.data([0])
.enter()
.append('div')
.attr('class', 'issue-reference')
.text(t('issues.crossing_ways.' + crossingTypeID + '.tip'));
}
}
function makeChangeLayerFix(higherOrLower, context) {
+11 -1
View File
@@ -77,12 +77,22 @@ export function validationDisconnectedWay() {
type: type,
severity: 'warning',
message: t('issues.disconnected_way.highway.message', { highway: entityLabel }),
tooltip: t('issues.disconnected_way.highway.tip'),
reference: showReference,
entities: [entity],
fixes: fixes
})];
function showReference(selection) {
selection.selectAll('.issue-reference')
.data([0])
.enter()
.append('div')
.attr('class', 'issue-reference')
.text(t('issues.disconnected_way.highway.tip'));
}
function vertexIsDisconnected(way, vertex, relation) {
// can not accurately test vertices on tiles not downloaded from osm - #5938
var osm = context.connection();
+11 -1
View File
@@ -58,7 +58,7 @@ export function validationGenericName() {
type: type,
severity: 'warning',
message: t('issues.generic_name.message', {feature: preset.name(), name: generic}),
tooltip: t('issues.generic_name.tip'),
reference: showReference,
entities: [entity],
fixes: [
new validationIssueFix({
@@ -76,6 +76,16 @@ export function validationGenericName() {
})
]
})];
function showReference(selection) {
selection.selectAll('.issue-reference')
.data([0])
.enter()
.append('div')
.attr('class', 'issue-reference')
.text(t('issues.generic_name.tip'));
}
};
validation.type = type;
+14 -1
View File
@@ -21,7 +21,7 @@ export function validationIncompatibleSource() {
message: t('issues.incompatible_source.' + invalidSource.id + '.feature.message', {
feature: utilDisplayLabel(entity, context),
}),
tooltip: t('issues.incompatible_source.' + invalidSource.id + '.tip'),
reference: getReference(invalidSource.id),
entities: [entity],
fixes: [
new validationIssueFix({
@@ -32,7 +32,20 @@ export function validationIncompatibleSource() {
}
});
}
return issues;
function getReference(id) {
return function showReference(selection) {
selection.selectAll('.issue-reference')
.data([0])
.enter()
.append('div')
.attr('class', 'issue-reference')
.text(t('issues.incompatible_source.' + id + '.tip'));
};
}
};
validation.type = type;
+12 -1
View File
@@ -43,14 +43,25 @@ export function validationManyDeletions() {
'issues.many_deletions.'+messageType+'.message',
{ n: totalFeatures, p: points, l: lines, a:areas, r: relations }
),
tooltip: t('issues.many_deletions.tip'),
reference: showReference,
hash: [points, lines, areas, relations].join()
})];
}
return [];
function showReference(selection) {
selection.selectAll('.issue-reference')
.data([0])
.enter()
.append('div')
.attr('class', 'issue-reference')
.text(t('issues.many_deletions.tip'));
}
};
validation.type = type;
validation.inputType = 'changes';
+13 -1
View File
@@ -35,6 +35,7 @@ export function validationMissingRole() {
return !member.role || !member.role.trim().length;
}
function makeIssue(way, relation, member, context) {
return new validationIssue({
type: type,
@@ -43,7 +44,7 @@ export function validationMissingRole() {
member: utilDisplayLabel(way, context),
relation: utilDisplayLabel(relation, context),
}),
tooltip: t('issues.missing_role.multipolygon.tip'),
reference: showReference,
entities: [relation, way],
data: {
member: member
@@ -63,8 +64,19 @@ export function validationMissingRole() {
})
]
});
function showReference(selection) {
selection.selectAll('.issue-reference')
.data([0])
.enter()
.append('div')
.attr('class', 'issue-reference')
.text(t('issues.missing_role.multipolygon.tip'));
}
}
function makeAddRoleFix(role, context) {
return new validationIssueFix({
title: t('issues.fix.set_as_' + role + '.title'),
+12 -1
View File
@@ -87,12 +87,23 @@ export function validationMissingTag() {
type: type,
severity: isError ? 'error' : 'warning',
message: t('issues.missing_tag.' + missingTagType + '.message', messageObj),
tooltip: t('issues.missing_tag.tip'),
reference: showReference,
entities: [entity],
fixes: fixes
})];
function showReference(selection) {
selection.selectAll('.issue-reference')
.data([0])
.enter()
.append('div')
.attr('class', 'issue-reference')
.text(t('issues.missing_tag.tip'));
}
};
validation.type = type;
return validation;
+13 -1
View File
@@ -24,12 +24,13 @@ export function validationOldMultipolygon() {
}
if (!multipolygon || !outerWay) return [];
var multipolygonLabel = utilDisplayLabel(multipolygon, context);
return [new validationIssue({
type: type,
severity: 'warning',
message: t('issues.old_multipolygon.message', { multipolygon: multipolygonLabel }),
tooltip: t('issues.old_multipolygon.tip'),
reference: showReference,
entities: [outerWay, multipolygon],
fixes: [
new validationIssueFix({
@@ -51,8 +52,19 @@ export function validationOldMultipolygon() {
})
]
})];
function showReference(selection) {
selection.selectAll('.issue-reference')
.data([0])
.enter()
.append('div')
.attr('class', 'issue-reference')
.text(t('issues.old_multipolygon.tip'));
}
};
validation.type = type;
return validation;
+32 -7
View File
@@ -57,19 +57,13 @@ export function validationOutdatedTags() {
if (!tagDiff.length) return [];
// debugging (sorta)
var tooltip = '<pre>\n' + tagDiff.join('\n') + '</pre>';
return [new validationIssue({
type: type,
severity: 'warning',
message: t('issues.outdated_tags.message', { feature: utilDisplayLabel(entity, context) }),
tooltip: tooltip, // t('issues.outdated_tags.tip'),
reference: showReference,
entities: [entity],
data: {
tagDiff: tagDiff,
newTags: newTags
},
fixes: [
@@ -87,6 +81,37 @@ export function validationOutdatedTags() {
})
]
})];
function showReference(selection) {
var enter = selection.selectAll('.issue-reference')
.data([0])
.enter();
enter
.append('div')
.attr('class', 'issue-reference')
.text(t('issues.outdated_tags.tip'));
enter
.append('strong')
.text(t('issues.suggested'));
enter
.append('table')
.attr('class', 'tagDiff-table')
.selectAll('.tagDiff-row')
.data(tagDiff)
.enter()
.append('tr')
.attr('class', 'tagDiff-row')
.append('td')
.attr('class', function(d) {
var klass = d.charAt(0) === '+' ? 'add' : 'remove';
return 'tagDiff-cell tagDiff-cell-' + klass;
})
.text(function(d) { return d; });
}
};
+57 -25
View File
@@ -18,7 +18,7 @@ export function validationPrivateData() {
};
// but they might be public if they have one of these other tags
var okayModifierKeys = {
var publicKeys = {
amenity: true,
craft: true,
historic: true,
@@ -39,55 +39,87 @@ export function validationPrivateData() {
website: true
};
function privateDataKeys(entity) {
var tags = entity.tags;
if (!tags.building || !privateBuildingValues[tags.building]) return [];
var privateKeys = [];
for (var key in tags) {
if (okayModifierKeys[key]) return [];
if (personalTags[key]) privateKeys.push(key);
}
return privateKeys;
}
var validation = function checkPrivateData(entity, context) {
var privateKeys = privateDataKeys(entity);
if (privateKeys.length === 0) return [];
var tags = entity.tags;
var keepTags = {};
var tagDiff = [];
if (!tags.building || !privateBuildingValues[tags.building]) return [];
for (var k in tags) {
if (publicKeys[k]) return []; // probably a public feature
if (personalTags[k]) {
tagDiff.push('- ' + k + '=' + tags[k]);
} else {
keepTags[k] = tags[k];
}
}
if (!tagDiff.length) return [];
var fixID = tagDiff.length === 1 ? 'remove_tag' : 'remove_tags';
var fixID = privateKeys.length === 1 ? 'remove_tag' : 'remove_tags';
return [new validationIssue({
type: type,
severity: 'warning',
message: t('issues.private_data.contact.message', {
feature: utilDisplayLabel(entity, context),
}),
tooltip: t('issues.private_data.tip'),
reference: showReference,
entities: [entity],
data: {
privateKeys: privateKeys
newTags: keepTags
},
fixes: [
new validationIssueFix({
auto: true,
icon: 'iD-operation-delete',
title: t('issues.fix.' + fixID + '.title'),
onClick: function() {
var entity = this.issue.entities[0];
var tags = Object.assign({}, entity.tags); // shallow copy
var privateKeys = this.issue.data.privateKeys;
for (var index in privateKeys) {
delete tags[privateKeys[index]];
}
var entityID = this.issue.entities[0].id;
var newTags = this.issue.data.newTags;
context.perform(
actionChangeTags(entity.id, tags),
t('issues.fix.remove_private_info.annotation')
actionChangeTags(entityID, newTags),
t('issues.fix.upgrade_tags.annotation')
);
}
})
]
})];
function showReference(selection) {
var enter = selection.selectAll('.issue-reference')
.data([0])
.enter();
enter
.append('div')
.attr('class', 'issue-reference')
.text(t('issues.private_data.tip'));
enter
.append('strong')
.text(t('issues.suggested'));
enter
.append('table')
.attr('class', 'tagDiff-table')
.selectAll('.tagDiff-row')
.data(tagDiff)
.enter()
.append('tr')
.attr('class', 'tagDiff-row')
.append('td')
.attr('class', function(d) {
var klass = d.charAt(0) === '+' ? 'add' : 'remove';
return 'tagDiff-cell tagDiff-cell-' + klass;
})
.text(function(d) { return d; });
}
};
validation.type = type;
return validation;
+11 -1
View File
@@ -95,10 +95,20 @@ export function validationTagSuggestsArea() {
type: type,
severity: 'warning',
message: t('issues.tag_suggests_area.message', { feature: featureLabel, tag: tagText }),
tooltip: t('issues.tag_suggests_area.tip'),
reference: showReference,
entities: [entity],
fixes: fixes
})];
function showReference(selection) {
selection.selectAll('.issue-reference')
.data([0])
.enter()
.append('div')
.attr('class', 'issue-reference')
.text(t('issues.tag_suggests_area.tip'));
}
};
validation.type = type;
+11 -1
View File
@@ -42,10 +42,20 @@ export function validationUnknownRoad() {
message: t('issues.unknown_road.message', {
feature: utilDisplayLabel(entity, context),
}),
tooltip: t('issues.unknown_road.tip'),
reference: showReference,
entities: [entity],
fixes: fixes
})];
function showReference(selection) {
selection.selectAll('.issue-reference')
.data([0])
.enter()
.append('div')
.attr('class', 'issue-reference')
.text(t('issues.unknown_road.tip'));
}
};
validation.type = type;