mirror of
https://github.com/FoggedLens/iD.git
synced 2026-03-22 11:03:28 +00:00
Change autofix to accept arguments to perform, implement "fix all"
This commit is contained in:
@@ -3126,9 +3126,8 @@ div.full-screen > button:hover {
|
||||
padding: 5px 0;
|
||||
}
|
||||
.issue-label .issue-autofix {
|
||||
width: 36px;
|
||||
flex: 0 0 auto;
|
||||
padding: 5px 7px;
|
||||
padding: 5px 8px;
|
||||
}
|
||||
.issue-label .issue-info-button {
|
||||
height: unset;
|
||||
@@ -3149,19 +3148,39 @@ div.full-screen > button:hover {
|
||||
border-radius: 4px 0 0 4px;
|
||||
}
|
||||
|
||||
.issue-autofix button.autofix.action {
|
||||
button.autofix.action {
|
||||
flex: 0 0 20px;
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
background: #7092ff;
|
||||
color: #fff;
|
||||
}
|
||||
.issue-label button.autofix.action:focus,
|
||||
.issue-label button.autofix.action:hover,
|
||||
.issue-label button.autofix.action.active {
|
||||
button.autofix.action:focus,
|
||||
button.autofix.action:hover,
|
||||
button.autofix.action.active {
|
||||
background: #597be7;
|
||||
}
|
||||
|
||||
/* fix all */
|
||||
.autofix-all {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
flex-direction: row-reverse;
|
||||
height: 30px;
|
||||
padding-top: 5px;
|
||||
}
|
||||
.autofix-all-link-text {
|
||||
padding: 0 5px;
|
||||
}
|
||||
.autofix-all-link-icon svg {
|
||||
margin: 0 9px;
|
||||
background: currentColor;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.autofix-all-link-icon svg use {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* warning styles */
|
||||
.warnings-list,
|
||||
.warnings-list *,
|
||||
@@ -3245,6 +3264,10 @@ div.full-screen > button:hover {
|
||||
color: #ff0c05;
|
||||
}
|
||||
|
||||
.layer-list.issues-list {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
|
||||
/* Issues Pane */
|
||||
.issues-options-container {
|
||||
|
||||
@@ -1270,6 +1270,11 @@ en:
|
||||
visible: "In View"
|
||||
all: "Everywhere"
|
||||
suggested: "Suggested updates:"
|
||||
fix_one:
|
||||
title: fix
|
||||
fix_all:
|
||||
title: Fix All
|
||||
annotation: Fixed several validation issues.
|
||||
almost_junction:
|
||||
title: Almost Junctions
|
||||
message: "{feature} is very close but not connected to {feature2}"
|
||||
|
||||
7
dist/locales/en.json
vendored
7
dist/locales/en.json
vendored
@@ -1549,6 +1549,13 @@
|
||||
}
|
||||
},
|
||||
"suggested": "Suggested updates:",
|
||||
"fix_one": {
|
||||
"title": "fix"
|
||||
},
|
||||
"fix_all": {
|
||||
"title": "Fix All",
|
||||
"annotation": "Fixed several validation issues."
|
||||
},
|
||||
"almost_junction": {
|
||||
"title": "Almost Junctions",
|
||||
"message": "{feature} is very close but not connected to {feature2}",
|
||||
|
||||
@@ -318,11 +318,13 @@ export function coreValidator(context) {
|
||||
// if (!difference) return;
|
||||
// validator.validate();
|
||||
// });
|
||||
context.history()
|
||||
.on('undone.validator', validator.validate)
|
||||
.on('redone.validator', validator.validate);
|
||||
|
||||
// re-run validation when the user switches editing modes (less frequent)
|
||||
context.on('exit.validator', function() {
|
||||
validator.validate();
|
||||
});
|
||||
context
|
||||
.on('exit.validator', validator.validate);
|
||||
|
||||
|
||||
return validator;
|
||||
@@ -342,7 +344,7 @@ export function validationIssue(attrs) {
|
||||
this.hash = attrs.hash; // optional - string to further differentiate the issue
|
||||
|
||||
this.id = generateID.apply(this); // generated - see below
|
||||
this.auto = null; // generated - if autofix exists, will be set below
|
||||
this.autoFix = null; // generated - if autofix exists, will be set below
|
||||
|
||||
// A unique, deterministic string hash.
|
||||
// Issues with identical id values are considered identical.
|
||||
@@ -389,8 +391,8 @@ export function validationIssue(attrs) {
|
||||
for (var i = 0; i < this.fixes.length; i++) {
|
||||
var fix = this.fixes[i];
|
||||
fix.issue = this;
|
||||
if (fix.auto) {
|
||||
this.auto = fix;
|
||||
if (fix.autoArgs) {
|
||||
this.autoFix = fix;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -398,11 +400,11 @@ export function validationIssue(attrs) {
|
||||
|
||||
|
||||
export function validationIssueFix(attrs) {
|
||||
this.title = attrs.title; // Required
|
||||
this.onClick = attrs.onClick; // Required
|
||||
this.icon = attrs.icon; // Optional - shows 'iD-icon-wrench' if not set
|
||||
this.entityIds = attrs.entityIds || []; // Optional - Used for hover-higlighting.
|
||||
this.auto = attrs.auto; // Optional - pass true if this fix can be an auto fix
|
||||
this.title = attrs.title; // Required
|
||||
this.onClick = attrs.onClick; // Required
|
||||
this.icon = attrs.icon; // Optional - shows 'iD-icon-wrench' if not set
|
||||
this.entityIds = attrs.entityIds || []; // Optional - Used for hover-higlighting.
|
||||
this.autoArgs = attrs.autoArgs; // Optional - pass [actions, annotation] arglist if this fix can automatically run
|
||||
|
||||
this.issue = null; // Generated link - added by ValidationIssue constructor
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ import { event as d3_event, select as d3_select } from 'd3-selection';
|
||||
|
||||
import { t, textDirection } from '../util/locale';
|
||||
import { tooltip } from '../util/tooltip';
|
||||
|
||||
import { actionNoop } from '../actions';
|
||||
import { geoSphericalDistance } from '../geo';
|
||||
import { modeSelect } from '../modes';
|
||||
import { svgIcon } from '../svg';
|
||||
@@ -17,8 +19,8 @@ import { utilCallWhenIdle, utilHighlightEntities } from '../util';
|
||||
|
||||
export function uiIssues(context) {
|
||||
var key = t('issues.key');
|
||||
var _errorsList = d3_select(null);
|
||||
var _warningsList = d3_select(null);
|
||||
var _errorsSelection = d3_select(null);
|
||||
var _warningsSelection = d3_select(null);
|
||||
var _rulesList = d3_select(null);
|
||||
var _pane = d3_select(null);
|
||||
var _toggleButton = d3_select(null);
|
||||
@@ -51,35 +53,30 @@ export function uiIssues(context) {
|
||||
.attr('fill', 'currentColor');
|
||||
}
|
||||
|
||||
|
||||
function renderErrorsList(selection) {
|
||||
_errorsList = selection.selectAll('.errors-list')
|
||||
.data([0]);
|
||||
|
||||
_errorsList = _errorsList.enter()
|
||||
.append('ul')
|
||||
.attr('class', 'layer-list errors-list issues-list')
|
||||
.merge(_errorsList);
|
||||
|
||||
_errorsList
|
||||
.call(drawIssuesList, _errors);
|
||||
_errorsSelection = selection
|
||||
.call(drawIssuesList, 'errors', _errors);
|
||||
}
|
||||
|
||||
|
||||
function renderWarningsList(selection) {
|
||||
_warningsList = selection.selectAll('.warnings-list')
|
||||
.data([0]);
|
||||
|
||||
_warningsList = _warningsList.enter()
|
||||
.append('ul')
|
||||
.attr('class', 'layer-list warnings-list issues-list')
|
||||
.merge(_warningsList);
|
||||
|
||||
_warningsList
|
||||
.call(drawIssuesList, _warnings);
|
||||
_warningsSelection = selection
|
||||
.call(drawIssuesList, 'warnings', _warnings);
|
||||
}
|
||||
|
||||
|
||||
function drawIssuesList(selection, issues) {
|
||||
var items = selection.selectAll('li')
|
||||
function drawIssuesList(selection, which, issues) {
|
||||
var list = selection.selectAll('.issues-list')
|
||||
.data([0]);
|
||||
|
||||
list = list.enter()
|
||||
.append('ul')
|
||||
.attr('class', 'layer-list issues-list ' + which + '-list')
|
||||
.merge(list);
|
||||
|
||||
|
||||
var items = list.selectAll('li')
|
||||
.data(issues, function(d) { return d.id; });
|
||||
|
||||
// Exit
|
||||
@@ -143,15 +140,16 @@ export function uiIssues(context) {
|
||||
.append('span')
|
||||
.attr('class', 'issue-autofix')
|
||||
.each(function(d) {
|
||||
if (!d.auto) return;
|
||||
if (!d.autoFix) return;
|
||||
|
||||
d3_select(this)
|
||||
.append('button')
|
||||
.datum(d.auto) // set button datum to the autofix
|
||||
.attr('title', t('issues.fix_one.title'))
|
||||
.datum(d.autoFix) // set button datum to the autofix
|
||||
.attr('class', 'autofix action')
|
||||
.on('click', function(d) {
|
||||
utilHighlightEntities(d.entityIds, false, context);
|
||||
d.onClick();
|
||||
context.perform.apply(context, d.autoArgs);
|
||||
context.validator().validate();
|
||||
})
|
||||
.call(svgIcon('#iD-icon-wrench'));
|
||||
@@ -162,6 +160,55 @@ export function uiIssues(context) {
|
||||
items = items
|
||||
.merge(itemsEnter)
|
||||
.order();
|
||||
|
||||
|
||||
// autofix
|
||||
var canAutoFix = issues.filter(function(issue) { return issue.autoFix; });
|
||||
|
||||
var autoFixAll = selection.selectAll('.autofix-all')
|
||||
.data(canAutoFix.length ? [0] : []);
|
||||
|
||||
// exit
|
||||
autoFixAll.exit()
|
||||
.remove();
|
||||
|
||||
// enter
|
||||
var autoFixAllEnter = autoFixAll.enter()
|
||||
.append('div')
|
||||
.attr('class', 'autofix-all');
|
||||
|
||||
var linkEnter = autoFixAllEnter
|
||||
.append('a')
|
||||
.attr('class', 'autofix-all-link')
|
||||
.attr('href', '#');
|
||||
|
||||
linkEnter
|
||||
.append('span')
|
||||
.attr('class', 'autofix-all-link-text')
|
||||
.text(t('issues.fix_all.title'));
|
||||
|
||||
linkEnter
|
||||
.append('span')
|
||||
.attr('class', 'autofix-all-link-icon')
|
||||
.call(svgIcon('#iD-icon-wrench'));
|
||||
|
||||
// update
|
||||
autoFixAll = autoFixAll
|
||||
.merge(autoFixAllEnter);
|
||||
|
||||
autoFixAll.selectAll('.autofix-all-link')
|
||||
.on('click', function() {
|
||||
context.perform(actionNoop());
|
||||
canAutoFix.forEach(function(issue) {
|
||||
var args = issue.autoFix.autoArgs.slice(); // copy
|
||||
if (typeof args[args.length - 1] !== 'function') {
|
||||
args.pop();
|
||||
}
|
||||
args.push(t('issues.fix_all.annotation'));
|
||||
context.replace.apply(context, args);
|
||||
});
|
||||
context.validator().validate();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -292,27 +339,28 @@ export function uiIssues(context) {
|
||||
.classed('warning', (_errors.length === 0 && _warnings.length > 0))
|
||||
.classed('hide', (_errors.length === 0 && _warnings.length === 0));
|
||||
|
||||
_pane.select('.issues-errors')
|
||||
|
||||
_pane.selectAll('.issues-errors')
|
||||
.classed('hide', _errors.length === 0);
|
||||
|
||||
if (_errors.length > 0) {
|
||||
_pane.select('.hide-toggle-issues_errors .hide-toggle-text')
|
||||
_pane.selectAll('.hide-toggle-issues_errors .hide-toggle-text')
|
||||
.text(t('issues.errors.list_title', { count: errorCount }));
|
||||
if (!_pane.select('.disclosure-wrap-issues_errors').classed('hide')) {
|
||||
_errorsList
|
||||
.call(drawIssuesList, _errors);
|
||||
_errorsSelection
|
||||
.call(drawIssuesList, 'errors', _errors);
|
||||
}
|
||||
}
|
||||
|
||||
_pane.select('.issues-warnings')
|
||||
_pane.selectAll('.issues-warnings')
|
||||
.classed('hide', _warnings.length === 0);
|
||||
|
||||
if (_warnings.length > 0) {
|
||||
_pane.select('.hide-toggle-issues_warnings .hide-toggle-text')
|
||||
_pane.selectAll('.hide-toggle-issues_warnings .hide-toggle-text')
|
||||
.text(t('issues.warnings.list_title', { count: warningCount }));
|
||||
if (!_pane.select('.disclosure-wrap-issues_warnings').classed('hide')) {
|
||||
_warningsList
|
||||
.call(drawIssuesList, _warnings);
|
||||
_warningsSelection
|
||||
.call(drawIssuesList, 'warnings', _warnings);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,26 +34,23 @@ export function validationOldMultipolygon() {
|
||||
entities: [outerWay, multipolygon],
|
||||
fixes: [
|
||||
new validationIssueFix({
|
||||
auto: true,
|
||||
autoArgs: [doUpgrade, t('issues.fix.move_tags.annotation')],
|
||||
title: t('issues.fix.move_tags.title'),
|
||||
onClick: function() {
|
||||
var outerWay = this.issue.entities[0];
|
||||
var multipolygon = this.issue.entities[1];
|
||||
context.perform(
|
||||
function(graph) {
|
||||
multipolygon = multipolygon.mergeTags(outerWay.tags);
|
||||
graph = graph.replace(multipolygon);
|
||||
graph = actionChangeTags(outerWay.id, {})(graph);
|
||||
return graph;
|
||||
},
|
||||
t('issues.fix.move_tags.annotation')
|
||||
);
|
||||
context.perform(doUpgrade, t('issues.fix.move_tags.annotation'));
|
||||
}
|
||||
})
|
||||
]
|
||||
})];
|
||||
|
||||
|
||||
function doUpgrade(graph) {
|
||||
multipolygon = multipolygon.mergeTags(outerWay.tags);
|
||||
graph = graph.replace(multipolygon);
|
||||
return actionChangeTags(outerWay.id, {})(graph);
|
||||
}
|
||||
|
||||
|
||||
function showReference(selection) {
|
||||
selection.selectAll('.issue-reference')
|
||||
.data([0])
|
||||
|
||||
@@ -63,26 +63,23 @@ export function validationOutdatedTags() {
|
||||
message: t('issues.outdated_tags.message', { feature: utilDisplayLabel(entity, context) }),
|
||||
reference: showReference,
|
||||
entities: [entity],
|
||||
data: {
|
||||
newTags: newTags
|
||||
},
|
||||
fixes: [
|
||||
new validationIssueFix({
|
||||
auto: true,
|
||||
autoArgs: [doUpgrade, t('issues.fix.upgrade_tags.annotation')],
|
||||
title: t('issues.fix.upgrade_tags.title'),
|
||||
onClick: function() {
|
||||
var entityID = this.issue.entities[0].id;
|
||||
var newTags = this.issue.data.newTags;
|
||||
context.perform(
|
||||
actionChangeTags(entityID, newTags),
|
||||
t('issues.fix.upgrade_tags.annotation')
|
||||
);
|
||||
context.perform(doUpgrade, t('issues.fix.upgrade_tags.annotation'));
|
||||
}
|
||||
})
|
||||
]
|
||||
})];
|
||||
|
||||
|
||||
function doUpgrade(graph) {
|
||||
return actionChangeTags(entity.id, newTags)(graph);
|
||||
}
|
||||
|
||||
|
||||
function showReference(selection) {
|
||||
var enter = selection.selectAll('.issue-reference')
|
||||
.data([0])
|
||||
|
||||
Reference in New Issue
Block a user