From c9350c632e6a2d09301f1377c1608e0ec56f1496 Mon Sep 17 00:00:00 2001 From: Quincy Morgan Date: Fri, 21 Dec 2018 12:31:33 -0500 Subject: [PATCH] Add issue fixes UI Add two issue fixes for untagged feature --- css/80_app.css | 29 ++++++++---- data/core.yaml | 7 +++ dist/locales/en.json | 11 +++++ modules/ui/entity_issues.js | 60 ++++++++++++++++++++----- modules/ui/inspector.js | 13 +++--- modules/ui/sidebar.js | 9 ++-- modules/validations/missing_tag.js | 19 ++++++++ modules/validations/validation_issue.js | 7 +++ 8 files changed, 127 insertions(+), 28 deletions(-) diff --git a/css/80_app.css b/css/80_app.css index eeb7f744c..c4307fc2a 100644 --- a/css/80_app.css +++ b/css/80_app.css @@ -2838,11 +2838,9 @@ div.full-screen > button:hover { color: inherit; } -.issue.severity-warning, .issue.severity-warning button { background: #ffb; } -.issue.severity-warning:hover, .issue.severity-warning button:hover, .issue.severity-warning button:focus { background: #FFFF99; @@ -2851,11 +2849,9 @@ div.full-screen > button:hover { color: #FFB300 } -.issue.severity-error, .issue.severity-error button { background: #FFD5D4; } -.issue.severity-error:hover, .issue.severity-error button:hover, .issue.severity-error button:focus { background: #ffc9c7; @@ -2874,18 +2870,25 @@ div.full-screen > button:hover { border-radius: 4px; border-width: 1px; border-style: solid; + overflow: hidden; } -.entity-issues .issue .label { +.entity-issues .issue button { padding: 5px; - display: flex; height: auto; width: 100%; - text-align: inherit; + font-weight: inherit; + border-radius: 0; } -.entity-issues .issue.severity-warning { +.entity-issues .issue button.label { + text-align: inherit; + display: flex; +} +.entity-issues .issue.severity-warning, +.entity-issues .issue.severity-warning li { border-color: #FFDF5C; } -.entity-issues .issue.severity-error { +.entity-issues .issue.severity-error, +.entity-issues .issue.severity-error li { border-color: #f5b0ab; } .entity-issues .issue:first-of-type { @@ -2894,6 +2897,14 @@ div.full-screen > button:hover { .entity-issues .issue:not(:last-of-type) { margin-bottom: 10px; } +.entity-issues .issue ul.fixes li:first-child { + border-top-style: solid; + border-top-width: 3px; +} +.entity-issues .issue ul.fixes li:not(:last-of-type) { + border-bottom-style: solid; + border-bottom-width: 1px; +} /* Background - Display Options Sliders ------------------------------------------------------- */ diff --git a/data/core.yaml b/data/core.yaml index 44da62b61..fa52fbb34 100644 --- a/data/core.yaml +++ b/data/core.yaml @@ -900,6 +900,13 @@ en: crossing_ways: message: Crossing ways without connection tooltip: "Roads are crossing other roads, buildings, railroads, or waterways without connection nodes or a bridge tag." + fix: + delete_feature: + title: Delete this feature + select_preset: + title: Select a feature type + ignore_temporarily: + title: Ignore for now intro: done: done ok: OK diff --git a/dist/locales/en.json b/dist/locales/en.json index 8516d2696..5e1739736 100644 --- a/dist/locales/en.json +++ b/dist/locales/en.json @@ -1076,6 +1076,17 @@ "crossing_ways": { "message": "Crossing ways without connection", "tooltip": "Roads are crossing other roads, buildings, railroads, or waterways without connection nodes or a bridge tag." + }, + "fix": { + "delete_feature": { + "title": "Delete this feature" + }, + "select_preset": { + "title": "Select a feature type" + }, + "ignore_temporarily": { + "title": "Ignore for now" + } } }, "intro": { diff --git a/modules/ui/entity_issues.js b/modules/ui/entity_issues.js index e70ed8f59..24f5856d3 100644 --- a/modules/ui/entity_issues.js +++ b/modules/ui/entity_issues.js @@ -39,22 +39,19 @@ export function uiEntityIssues(context) { .append('div') .attr('class', function (d) { return 'issue severity-' + d.severity; - }) + }); + + var label = enter + .append('button') + .classed('label', true) .call(tooltip() .html(true) .title(function(d) { var tip = d.tooltip ? d.tooltip : ''; return uiTooltipHtml(tip); }) - .placement('bottom') - ) - .on('click', function(d) { - - }); - - var label = enter - .append('button') - .classed('label', true); + .placement('top') + ); label.each(function(d) { var iconSuffix = d.severity === 'warning' ? 'alert' : 'error'; @@ -70,6 +67,49 @@ export function uiEntityIssues(context) { .append('strong') .text(function(d) { return d.message; }); + enter.each(function(d) { + + var issue = d3_select(this); + + var list = issue + .selectAll('ul.fixes') + .data([0]); + + if (d.fixes && d.fixes.length > 0) { + list = list.enter() + .append('ul') + .attr('class', 'fixes') + .style('display', 'none') + .merge(list); + + issue.select('.label') + .on('click', function() { + if (list.style('display') === 'none') { + list.style('display', 'block'); + } else { + list.style('display', 'none'); + } + }); + + var fixItems = list + .selectAll('li') + .data(d.fixes); + + fixItems.exit() + .remove(); + + fixItems.enter() + .append('li') + .append('button') + .text(function(d) { + return d.title; + }) + .on('click', function(d){ + d.action() + }); + } + }) + // Update items = items .merge(enter); diff --git a/modules/ui/inspector.js b/modules/ui/inspector.js index ccb415077..c606abcb9 100644 --- a/modules/ui/inspector.js +++ b/modules/ui/inspector.js @@ -18,12 +18,12 @@ export function uiInspector(context) { presetList .entityID(_entityID) .autofocus(_newFeature) - .on('choose', setPreset); + .on('choose', inspector.setPreset); entityEditor .state(_state) .entityID(_entityID) - .on('choose', showList); + .on('choose', inspector.showList); var wrap = selection.selectAll('.panewrap') .data([0]); @@ -72,8 +72,7 @@ export function uiInspector(context) { .what(context.hasEntity(_entityID)) ); - - function showList(preset) { + inspector.showList = function(preset) { wrap.transition() .styleTween('right', function() { return d3_interpolate('0%', '-100%'); }); @@ -82,7 +81,7 @@ export function uiInspector(context) { } - function setPreset(preset) { + inspector.setPreset = function(preset) { wrap.transition() .styleTween('right', function() { return d3_interpolate('-100%', '0%'); }); @@ -91,7 +90,9 @@ export function uiInspector(context) { } } - + inspector.showList = function() {}; + inspector.setPreset = function() {}; + inspector.state = function(_) { if (!arguments.length) return _state; _state = _; diff --git a/modules/ui/sidebar.js b/modules/ui/sidebar.js index 9316a6695..31107290b 100644 --- a/modules/ui/sidebar.js +++ b/modules/ui/sidebar.js @@ -166,7 +166,6 @@ export function uiSidebar(context) { } } - sidebar.hover = _throttle(hover, 200); @@ -183,9 +182,9 @@ export function uiSidebar(context) { sidebar.hide(); if (id) { + var entity = context.entity(id); // uncollapse the sidebar if (selection.classed('collapsed')) { - var entity = context.entity(id); var extent = entity.extent(context.graph()); sidebar.expand(sidebar.intersects(extent)); } @@ -207,6 +206,10 @@ export function uiSidebar(context) { .call(inspector, newFeature); } + sidebar.showPresetList = function() { + inspector.showList(context.presets().match(entity, context.graph())); + }; + } else { inspector .state('hide'); @@ -310,7 +313,7 @@ export function uiSidebar(context) { resizer.on('dblclick', sidebar.toggle); } - + sidebar.showPresetList = function() {}; sidebar.hover = function() {}; sidebar.hover.cancel = function() {}; sidebar.intersects = function() {}; diff --git a/modules/validations/missing_tag.js b/modules/validations/missing_tag.js index 3b1d9f8bb..79964ff49 100644 --- a/modules/validations/missing_tag.js +++ b/modules/validations/missing_tag.js @@ -7,7 +7,12 @@ import { ValidationIssueType, ValidationIssueSeverity, validationIssue, + validationIssueFix } from './validation_issue'; +import { operationDelete } from '../operations/index'; +import { + select as d3_select +} from 'd3-selection'; export function validationMissingTag(context) { @@ -33,6 +38,20 @@ export function validationMissingTag(context) { message: t('issues.untagged_feature.message', {feature: entityLabel}), tooltip: t('issues.untagged_feature.tooltip'), entities: [change], + fixes: [ + new validationIssueFix({ + title: t('issues.fix.delete_feature.title'), + action: function() { + operationDelete([change.id], context)(); + } + }), + new validationIssueFix({ + title: t('issues.fix.select_preset.title'), + action: function() { + context.ui().sidebar.showPresetList(); + } + }) + ] })); } } diff --git a/modules/validations/validation_issue.js b/modules/validations/validation_issue.js index dd265309c..8e24ac06b 100644 --- a/modules/validations/validation_issue.js +++ b/modules/validations/validation_issue.js @@ -45,3 +45,10 @@ export function validationIssue(attrs) { this.coordinates = attrs.coordinates; // expect a [lon, lat] array this.fixes = attrs.fixes; // expect an array of functions for possible fixes } + +export function validationIssueFix(attrs) { + + this.title = attrs.title; + this.action = attrs.action; + +}