mirror of
https://github.com/FoggedLens/iD.git
synced 2026-02-13 01:02:58 +00:00
Add basic title + description UI
This commit is contained in:
@@ -661,6 +661,18 @@ en:
|
||||
cannot_zoom: "Cannot zoom out further in current mode."
|
||||
full_screen: Toggle Full Screen
|
||||
QA:
|
||||
improveOSM:
|
||||
title: ImproveOSM Error
|
||||
error_types:
|
||||
ow:
|
||||
title: Missing One-way
|
||||
description: Aggregate data suggests {var1} may be missing a "oneway" tag. Please confirm via imagery or survey before mapping.
|
||||
mr:
|
||||
title: Missing Road
|
||||
description: Aggregate data suggests there may be an unmapped road here. Please confirm via imagery or survey before mapping.
|
||||
tr:
|
||||
title: Missing Turn Restriction
|
||||
description: Aggregate data suggests this junction may be missing a turn restriction. Please confirm via imagery or survey before mapping.
|
||||
keepRight:
|
||||
title: KeepRight Error
|
||||
detail_title: Error
|
||||
|
||||
17
dist/locales/en.json
vendored
17
dist/locales/en.json
vendored
@@ -803,6 +803,23 @@
|
||||
"cannot_zoom": "Cannot zoom out further in current mode.",
|
||||
"full_screen": "Toggle Full Screen",
|
||||
"QA": {
|
||||
"improveOSM": {
|
||||
"title": "ImproveOSM Error",
|
||||
"error_types": {
|
||||
"ow": {
|
||||
"title": "Missing One-way",
|
||||
"description": "Aggregate data suggests {var1} may be missing a \"oneway\" tag. Please confirm via imagery or survey before mapping."
|
||||
},
|
||||
"mr": {
|
||||
"title": "Missing Road",
|
||||
"description": "Aggregate data suggests there may be an unmapped road here. Please confirm via imagery or survey before mapping."
|
||||
},
|
||||
"tr": {
|
||||
"title": "Missing Turn Restriction",
|
||||
"description": "Aggregate data suggests this junction may be missing a turn restriction. Please confirm via imagery or survey before mapping."
|
||||
}
|
||||
}
|
||||
},
|
||||
"keepRight": {
|
||||
"title": "KeepRight Error",
|
||||
"detail_title": "Error",
|
||||
|
||||
@@ -5,7 +5,7 @@ import {
|
||||
select as d3_select
|
||||
} from 'd3-selection';
|
||||
|
||||
import { osmEntity, osmNote, krError } from '../osm';
|
||||
import { osmEntity, osmNote, krError, impOsmError } from '../osm';
|
||||
import { utilKeybinding, utilRebind } from '../util';
|
||||
|
||||
|
||||
@@ -112,6 +112,10 @@ export function behaviorHover(context) {
|
||||
entity = datum;
|
||||
selector = '.data' + datum.__featurehash__;
|
||||
|
||||
} else if (datum instanceof impOsmError) {
|
||||
entity = datum;
|
||||
selector = '.iOSM_error-' + datum.id;
|
||||
|
||||
} else if (datum instanceof krError) {
|
||||
entity = datum;
|
||||
selector = '.kr_error-' + datum.id;
|
||||
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
import {
|
||||
osmEntity,
|
||||
osmNote,
|
||||
impOsmError,
|
||||
krError
|
||||
} from '../osm';
|
||||
|
||||
@@ -170,10 +171,14 @@ export function behaviorSelect(context) {
|
||||
context
|
||||
.selectedNoteID(datum.id)
|
||||
.enter(modeSelectNote(context, datum.id));
|
||||
} else if (datum instanceof impOsmError & !isMultiselect) { // clicked an improveOSM error
|
||||
context
|
||||
.selectedErrorID(datum.id)
|
||||
.enter(modeSelectError(context, datum.id, 'ImproveOSM'));
|
||||
} else if (datum instanceof krError & !isMultiselect) { // clicked a krError error
|
||||
context
|
||||
.selectedErrorID(datum.id)
|
||||
.enter(modeSelectError(context, datum.id));
|
||||
.enter(modeSelectError(context, datum.id, 'KeepRight'));
|
||||
} else { // clicked nothing..
|
||||
context.selectedNoteID(null);
|
||||
context.selectedErrorID(null);
|
||||
|
||||
@@ -13,26 +13,44 @@ import {
|
||||
import { t } from '../util/locale';
|
||||
import { services } from '../services';
|
||||
import { modeBrowse, modeDragNode, modeDragNote } from '../modes';
|
||||
import { uiKeepRightEditor } from '../ui';
|
||||
import { uiImproveOsmEditor, uiKeepRightEditor } from '../ui';
|
||||
import { utilKeybinding } from '../util';
|
||||
|
||||
|
||||
export function modeSelectError(context, selectedErrorID) {
|
||||
export function modeSelectError(context, selectedErrorID, selectedErrorSource) {
|
||||
var mode = {
|
||||
id: 'select-error',
|
||||
button: 'browse'
|
||||
};
|
||||
|
||||
var keepRight = services.keepRight;
|
||||
var keybinding = utilKeybinding('select-error');
|
||||
var keepRightEditor = uiKeepRightEditor(context)
|
||||
.on('change', function() {
|
||||
context.map().pan([0,0]); // trigger a redraw
|
||||
var error = checkSelectedID();
|
||||
if (!error) return;
|
||||
context.ui().sidebar
|
||||
.show(keepRightEditor.error(error));
|
||||
});
|
||||
|
||||
var errorService, errorEditor;
|
||||
switch (selectedErrorSource) {
|
||||
case 'ImproveOSM':
|
||||
errorService = services.improveOSM;
|
||||
errorEditor = uiImproveOsmEditor(context)
|
||||
.on('change', function() {
|
||||
context.map().pan([0,0]); // trigger a redraw
|
||||
var error = checkSelectedID();
|
||||
if (!error) return;
|
||||
context.ui().sidebar
|
||||
.show(errorEditor.error(error));
|
||||
});
|
||||
break;
|
||||
case 'KeepRight':
|
||||
errorService = services.keepRight;
|
||||
errorEditor = uiKeepRightEditor(context)
|
||||
.on('change', function() {
|
||||
context.map().pan([0,0]); // trigger a redraw
|
||||
var error = checkSelectedID();
|
||||
if (!error) return;
|
||||
context.ui().sidebar
|
||||
.show(errorEditor.error(error));
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
var behaviors = [
|
||||
behaviorBreathe(context),
|
||||
@@ -45,8 +63,8 @@ export function modeSelectError(context, selectedErrorID) {
|
||||
|
||||
|
||||
function checkSelectedID() {
|
||||
if (!keepRight) return;
|
||||
var error = keepRight.getError(selectedErrorID);
|
||||
if (!errorService) return;
|
||||
var error = errorService.getError(selectedErrorID);
|
||||
if (!error) {
|
||||
context.enter(modeBrowse(context));
|
||||
}
|
||||
@@ -55,8 +73,8 @@ export function modeSelectError(context, selectedErrorID) {
|
||||
|
||||
|
||||
mode.zoomToSelected = function() {
|
||||
if (!keepRight) return;
|
||||
var error = keepRight.getError(selectedErrorID);
|
||||
if (!errorService) return;
|
||||
var error = errorService.getError(selectedErrorID);
|
||||
if (error) {
|
||||
context.map().centerZoomEase(error.loc, 20);
|
||||
}
|
||||
@@ -78,7 +96,7 @@ export function modeSelectError(context, selectedErrorID) {
|
||||
selectError();
|
||||
|
||||
var sidebar = context.ui().sidebar;
|
||||
sidebar.show(keepRightEditor.error(error));
|
||||
sidebar.show(errorEditor.error(error));
|
||||
|
||||
context.map()
|
||||
.on('drawn.select-error', selectError);
|
||||
|
||||
@@ -218,5 +218,27 @@ export default {
|
||||
return _erCache.rtree.search(bbox).map(function(d) {
|
||||
return d.data;
|
||||
});
|
||||
},
|
||||
|
||||
// get a single error from the cache
|
||||
getError: function(id) {
|
||||
return _erCache.data[id];
|
||||
},
|
||||
|
||||
// replace a single error in the cache
|
||||
replaceError: function(error) {
|
||||
if (!(error instanceof impOsmError) || !error.id) return;
|
||||
|
||||
_erCache.data[error.id] = error;
|
||||
updateRtree(encodeErrorRtree(error), true); // true = replace
|
||||
return error;
|
||||
},
|
||||
|
||||
// remove a single error from the cache
|
||||
removeError: function(error) {
|
||||
if (!(error instanceof impOsmError) || !error.id) return;
|
||||
|
||||
delete _erCache.data[error.id];
|
||||
updateRtree(encodeErrorRtree(error), false); // false = remove
|
||||
}
|
||||
};
|
||||
|
||||
127
modules/ui/improveOSM_details.js
Normal file
127
modules/ui/improveOSM_details.js
Normal file
@@ -0,0 +1,127 @@
|
||||
import {
|
||||
event as d3_event,
|
||||
select as d3_select
|
||||
} from 'd3-selection';
|
||||
|
||||
import { dataEn } from '../../data';
|
||||
import { modeSelect } from '../modes';
|
||||
import { t } from '../util/locale';
|
||||
import { utilDisplayName, utilEntityOrMemberSelector, utilEntityRoot } from '../util';
|
||||
|
||||
|
||||
export function uiImproveOsmDetails(context) {
|
||||
var _error;
|
||||
|
||||
|
||||
function errorDetail(d) {
|
||||
var unknown = t('inspector.unknown');
|
||||
|
||||
if (!d) return unknown;
|
||||
var errorType = d.parent_error_type;
|
||||
var et = dataEn.QA.improveOSM.error_types[errorType];
|
||||
|
||||
var detail;
|
||||
if (et && et.description) {
|
||||
detail = t('QA.improveOSM.error_types.' + errorType + '.description');
|
||||
} else {
|
||||
detail = unknown;
|
||||
}
|
||||
|
||||
return detail;
|
||||
}
|
||||
|
||||
|
||||
function improveOsmDetails(selection) {
|
||||
var details = selection.selectAll('.kr_error-details')
|
||||
.data(
|
||||
(_error ? [_error] : []),
|
||||
function(d) { return d.id + '-' + (d.status || 0); }
|
||||
);
|
||||
|
||||
details.exit()
|
||||
.remove();
|
||||
|
||||
var detailsEnter = details.enter()
|
||||
.append('div')
|
||||
.attr('class', 'kr_error-details kr_error-details-container');
|
||||
|
||||
|
||||
// description
|
||||
var descriptionEnter = detailsEnter
|
||||
.append('div')
|
||||
.attr('class', 'kr_error-details-description');
|
||||
|
||||
descriptionEnter
|
||||
.append('h4')
|
||||
.text(function() { return t('QA.keepRight.detail_description'); });
|
||||
|
||||
descriptionEnter
|
||||
.append('div')
|
||||
.attr('class', 'kr_error-details-description-text')
|
||||
.html(errorDetail);
|
||||
|
||||
// If there are entity links in the error message..
|
||||
descriptionEnter.selectAll('.kr_error_entity_link, .kr_error_object_link')
|
||||
.each(function() {
|
||||
var link = d3_select(this);
|
||||
var isObjectLink = link.classed('kr_error_object_link');
|
||||
var entityID = isObjectLink ?
|
||||
(utilEntityRoot(_error.object_type) + _error.object_id)
|
||||
: this.textContent;
|
||||
var entity = context.hasEntity(entityID);
|
||||
|
||||
// Add click handler
|
||||
link
|
||||
.on('mouseover', function() {
|
||||
context.surface().selectAll(utilEntityOrMemberSelector([entityID], context.graph()))
|
||||
.classed('hover', true);
|
||||
})
|
||||
.on('mouseout', 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);
|
||||
}
|
||||
|
||||
context.map().centerZoom(_error.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 && !isObjectLink) {
|
||||
var preset = context.presets().match(entity, context.graph());
|
||||
name = preset && !preset.isFallback() && preset.name(); // fallback to preset name
|
||||
}
|
||||
|
||||
if (name) {
|
||||
this.innerText = name;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
improveOsmDetails.error = function(val) {
|
||||
if (!arguments.length) return _error;
|
||||
_error = val;
|
||||
return improveOsmDetails;
|
||||
};
|
||||
|
||||
|
||||
return improveOsmDetails;
|
||||
}
|
||||
90
modules/ui/improveOSM_editor.js
Normal file
90
modules/ui/improveOSM_editor.js
Normal file
@@ -0,0 +1,90 @@
|
||||
import { dispatch as d3_dispatch } from 'd3-dispatch';
|
||||
import { select as d3_select } from 'd3-selection';
|
||||
|
||||
import { t } from '../util/locale';
|
||||
import { services } from '../services';
|
||||
import { modeBrowse } from '../modes';
|
||||
import { svgIcon } from '../svg';
|
||||
|
||||
import {
|
||||
uiImproveOsmDetails,
|
||||
uiImproveOsmHeader,
|
||||
uiQuickLinks,
|
||||
uiTooltipHtml
|
||||
} from './index';
|
||||
|
||||
import { utilNoAuto, utilRebind } from '../util';
|
||||
|
||||
|
||||
export function uiImproveOsmEditor(context) {
|
||||
var dispatch = d3_dispatch('change');
|
||||
var errorDetails = uiImproveOsmDetails(context);
|
||||
var errorHeader = uiImproveOsmHeader(context);
|
||||
var quickLinks = uiQuickLinks();
|
||||
|
||||
var _error;
|
||||
|
||||
|
||||
function improveOsmEditor(selection) {
|
||||
// quick links
|
||||
var choices = [{
|
||||
id: 'zoom_to',
|
||||
label: 'inspector.zoom_to.title',
|
||||
tooltip: function() {
|
||||
return uiTooltipHtml(t('inspector.zoom_to.tooltip_issue'), t('inspector.zoom_to.key'));
|
||||
},
|
||||
click: function zoomTo() {
|
||||
context.mode().zoomToSelected();
|
||||
}
|
||||
}];
|
||||
|
||||
|
||||
var header = selection.selectAll('.header')
|
||||
.data([0]);
|
||||
|
||||
var headerEnter = header.enter()
|
||||
.append('div')
|
||||
.attr('class', 'header fillL');
|
||||
|
||||
headerEnter
|
||||
.append('button')
|
||||
.attr('class', 'fr keepRight-editor-close')
|
||||
.on('click', function() {
|
||||
context.enter(modeBrowse(context));
|
||||
})
|
||||
.call(svgIcon('#iD-icon-close'));
|
||||
|
||||
headerEnter
|
||||
.append('h3')
|
||||
.text(t('QA.improveOSM.title'));
|
||||
|
||||
|
||||
var body = selection.selectAll('.body')
|
||||
.data([0]);
|
||||
|
||||
body = body.enter()
|
||||
.append('div')
|
||||
.attr('class', 'body')
|
||||
.merge(body);
|
||||
|
||||
var editor = body.selectAll('.keepRight-editor')
|
||||
.data([0]);
|
||||
|
||||
editor.enter()
|
||||
.append('div')
|
||||
.attr('class', 'modal-section keepRight-editor')
|
||||
.merge(editor)
|
||||
.call(errorHeader.error(_error))
|
||||
.call(quickLinks.choices(choices))
|
||||
.call(errorDetails.error(_error));
|
||||
}
|
||||
|
||||
improveOsmEditor.error = function(val) {
|
||||
if (!arguments.length) return _error;
|
||||
_error = val;
|
||||
return improveOsmEditor;
|
||||
};
|
||||
|
||||
|
||||
return utilRebind(improveOsmEditor, dispatch, 'on');
|
||||
}
|
||||
66
modules/ui/improveOSM_header.js
Normal file
66
modules/ui/improveOSM_header.js
Normal file
@@ -0,0 +1,66 @@
|
||||
import { dataEn } from '../../data';
|
||||
import { svgIcon } from '../svg';
|
||||
import { t } from '../util/locale';
|
||||
|
||||
|
||||
export function uiImproveOsmHeader() {
|
||||
var _error;
|
||||
|
||||
|
||||
function errorTitle(d) {
|
||||
var unknown = t('inspector.unknown');
|
||||
|
||||
if (!d) return unknown;
|
||||
var errorType = d.parent_error_type;
|
||||
var et = dataEn.QA.improveOSM.error_types[errorType];
|
||||
|
||||
if (et && et.title) {
|
||||
return t('QA.improveOSM.error_types.' + errorType + '.title');
|
||||
} else {
|
||||
return unknown;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function improveOsmHeader(selection) {
|
||||
var header = selection.selectAll('.kr_error-header')
|
||||
.data(
|
||||
(_error ? [_error] : []),
|
||||
function(d) { return d.id + '-' + (d.status || 0); }
|
||||
);
|
||||
|
||||
header.exit()
|
||||
.remove();
|
||||
|
||||
var headerEnter = header.enter()
|
||||
.append('div')
|
||||
.attr('class', 'kr_error-header');
|
||||
|
||||
var iconEnter = headerEnter
|
||||
.append('div')
|
||||
.attr('class', 'kr_error-header-icon')
|
||||
.classed('new', function(d) { return d.id < 0; });
|
||||
|
||||
iconEnter
|
||||
.append('div')
|
||||
.attr('class', function(d) {
|
||||
return 'preset-icon-28 iOSM_error iOSM_error-' + d.id + ' iOSM_error_type_' + d.parent_error_type;
|
||||
})
|
||||
.call(svgIcon('#iD-icon-bolt', 'iOSM_error-fill'));
|
||||
|
||||
headerEnter
|
||||
.append('div')
|
||||
.attr('class', 'kr_error-header-label')
|
||||
.text(errorTitle);
|
||||
}
|
||||
|
||||
|
||||
improveOsmHeader.error = function(val) {
|
||||
if (!arguments.length) return _error;
|
||||
_error = val;
|
||||
return improveOsmHeader;
|
||||
};
|
||||
|
||||
|
||||
return improveOsmHeader;
|
||||
}
|
||||
@@ -28,6 +28,9 @@ export { uiFormFields } from './form_fields';
|
||||
export { uiFullScreen } from './full_screen';
|
||||
export { uiGeolocate } from './geolocate';
|
||||
export { uiHelp } from './help';
|
||||
export { uiImproveOsmDetails } from './improveOSM_details';
|
||||
export { uiImproveOsmEditor } from './improveOSM_editor';
|
||||
export { uiImproveOsmHeader } from './improveOSM_header';
|
||||
export { uiInfo } from './info';
|
||||
export { uiInspector } from './inspector';
|
||||
export { uiKeepRightDetails } from './keepRight_details';
|
||||
|
||||
Reference in New Issue
Block a user