Add uiDataEditor for inspecting custom map data

This commit is contained in:
Bryan Housel
2018-08-25 10:10:04 -04:00
parent 7241e07344
commit 0a82ab125e
7 changed files with 237 additions and 44 deletions
+57
View File
@@ -717,6 +717,7 @@ button.add-note svg.icon {
}
.field-help-title button.close,
.sidebar-component .header button.data-editor-close,
.sidebar-component .header button.note-editor-close,
.entity-editor-pane .header button.preset-close,
.preset-list-pane .header button.preset-choose {
@@ -725,6 +726,7 @@ button.add-note svg.icon {
top: 0;
}
[dir='rtl'] .field-help-title button.close,
[dir='rtl'] .sidebar-component .header button.data-editor-close,
[dir='rtl'] .sidebar-component .header button.note-editor-close,
[dir='rtl'] .entity-editor-pane .header button.preset-close,
[dir='rtl'] .preset-list-pane .header button.preset-choose {
@@ -1392,6 +1394,10 @@ a.hide-toggle {
.inspector-hover .tag-row .form-field.input-wrap-position {
width: 50%;
}
.inspector-hover .tag-row .key-wrap,
.inspector-hover .tag-row .input-wrap-position {
height: 31px;
}
.inspector-hover .tag-row:first-child input.value {
border-top-right-radius: 4px;
@@ -2541,6 +2547,57 @@ input.key-trap {
}
/* Map Data Inspector */
.data-header {
background-color: #f6f6f6;
border-radius: 5px;
border: 1px solid #ccc;
display: flex;
flex-flow: row nowrap;
align-items: center;
}
.data-header-icon {
background-color: #fff;
padding: 10px;
flex: 0 0 62px;
position: relative;
width: 60px;
height: 60px;
border-right: 1px solid #ccc;
border-radius: 5px 0 0 5px;
}
[dir='rtl'] .data-header-icon {
border-right: unset;
border-left: 1px solid #ccc;
border-radius: 0 5px 5px 0;
}
.data-header-icon .icon-wrap {
position: absolute;
top: 0px;
}
.data-header-label {
background-color: #f6f6f6;
padding: 0 15px;
flex: 1 1 100%;
font-size: 14px;
font-weight: bold;
border-radius: 0 5px 5px 0;
}
[dir='rtl'] .data-header-label {
border-radius: 5px 0 0 5px;
}
/* tag editor - no buttons */
.data-editor.raw-tag-editor button {
display: none;
}
.data-editor.raw-tag-editor .tag-row .input-wrap-position {
width: 50%;
}
/* Fullscreen button */
div.full-screen {
+1 -5
View File
@@ -6,10 +6,7 @@ import {
} from 'd3-selection';
import { d3keybinding as d3_keybinding } from '../lib/d3.keybinding.js';
import {
osmEntity,
osmNote
} from '../osm';
import { osmEntity, osmNote } from '../osm';
import { utilRebind } from '../util/rebind';
@@ -154,7 +151,6 @@ export function behaviorHover(context) {
dispatch.call('hover', this, null);
}
}
};
+79
View File
@@ -0,0 +1,79 @@
import { t } from '../util/locale';
import { modeBrowse } from '../modes';
import { svgIcon } from '../svg';
import {
uiDataHeader,
uiRawTagEditor
} from './index';
export function uiDataEditor(context) {
var dataHeader = uiDataHeader();
var rawTagEditor = uiRawTagEditor(context);
var _datum;
function dataEditor(selection) {
var header = selection.selectAll('.header')
.data([0]);
var headerEnter = header.enter()
.append('div')
.attr('class', 'header fillL');
headerEnter
.append('button')
.attr('class', 'fr data-editor-close')
.on('click', function() {
context.enter(modeBrowse(context));
})
.call(svgIcon('#iD-icon-close'));
headerEnter
.append('h3')
.text(t('map_data.title'));
var body = selection.selectAll('.body')
.data([0]);
body = body.enter()
.append('div')
.attr('class', 'body')
.merge(body);
var editor = body.selectAll('.data-editor')
.data([0]);
editor = editor.enter()
.append('div')
.attr('class', 'modal-section data-editor')
.merge(editor)
.call(dataHeader.datum(_datum));
var rte = body.selectAll('.raw-tag-editor')
.data([0]);
rte.enter()
.append('div')
.attr('class', 'inspector-border raw-tag-editor inspector-inner data-editor')
.merge(rte)
.call(rawTagEditor
.expanded(true)
.readOnlyTags([/./])
.tags((_datum && _datum.properties) || {})
.state('hover')
);
}
dataEditor.datum = function(val) {
if (!arguments.length) return _datum;
_datum = val;
return this;
};
return dataEditor;
}
+47
View File
@@ -0,0 +1,47 @@
import { t } from '../util/locale';
import { svgIcon } from '../svg';
export function uiDataHeader() {
var _datum;
function dataHeader(selection) {
var header = selection.selectAll('.data-header')
.data(
(_datum ? [_datum] : []),
function(d) { return d.__featurehash__; }
);
header.exit()
.remove();
var headerEnter = header.enter()
.append('div')
.attr('class', 'data-header');
var iconEnter = headerEnter
.append('div')
.attr('class', 'data-header-icon');
iconEnter
.append('div')
.attr('class', 'preset-icon-28')
.call(svgIcon('#iD-icon-data', 'note-fill'));
headerEnter
.append('div')
.attr('class', 'data-header-label')
.text(t('map_data.layers.custom.title'));
}
dataHeader.datum = function(val) {
if (!arguments.length) return _datum;
_datum = val;
return this;
};
return dataHeader;
}
+2
View File
@@ -13,6 +13,8 @@ export { uiConfirm } from './confirm';
export { uiConflicts } from './conflicts';
export { uiContributors } from './contributors';
export { uiCurtain } from './curtain';
export { uiDataEditor } from './data_editor';
export { uiDataHeader } from './data_header';
export { uiDisclosure } from './disclosure';
export { uiEditMenu } from './edit_menu';
export { uiEntityEditor } from './entity_editor';
+29 -30
View File
@@ -24,17 +24,17 @@ import {
export function uiRawTagEditor(context) {
var taginfo = services.taginfo,
dispatch = d3_dispatch('change'),
_readOnlyTags = [],
_showBlank = false,
_updatePreference = true,
_expanded = false,
_newRow,
_state,
_preset,
_tags,
_entityID;
var taginfo = services.taginfo;
var dispatch = d3_dispatch('change');
var _readOnlyTags = [];
var _showBlank = false;
var _updatePreference = true;
var _expanded = false;
var _newRow;
var _state;
var _preset;
var _tags;
var _entityID;
function rawTagEditor(selection) {
@@ -148,16 +148,16 @@ export function uiRawTagEditor(context) {
items
.each(function(tag) {
var row = d3_select(this),
key = row.select('input.key'), // propagate bound data to child
value = row.select('input.value'); // propagate bound data to child
var row = d3_select(this);
var key = row.select('input.key'); // propagate bound data to child
var value = row.select('input.value'); // propagate bound data to child
if (_entityID && taginfo) {
bindTypeahead(key, value);
}
var isRelation = (_entityID && context.entity(_entityID).type === 'relation'),
reference;
var isRelation = (_entityID && context.entity(_entityID).type === 'relation');
var reference;
if (isRelation && tag.key === 'type') {
reference = uiTagReference({ rtype: tag.value }, context);
@@ -239,8 +239,8 @@ export function uiRawTagEditor(context) {
function sort(value, data) {
var sameletter = [],
other = [];
var sameletter = [];
var other = [];
for (var i = 0; i < data.length; i++) {
if (data[i].value.substring(0, value.length) === value) {
sameletter.push(data[i]);
@@ -265,10 +265,9 @@ export function uiRawTagEditor(context) {
function keyChange(d) {
var kOld = d.key,
kNew = this.value.trim(),
tag = {};
var kOld = d.key;
var kNew = this.value.trim();
var tag = {};
if (isReadOnly({ key: kNew })) {
this.value = kOld;
@@ -276,17 +275,17 @@ export function uiRawTagEditor(context) {
}
if (kNew && kNew !== kOld) {
var match = kNew.match(/^(.*?)(?:_(\d+))?$/),
base = match[1],
suffix = +(match[2] || 1);
var match = kNew.match(/^(.*?)(?:_(\d+))?$/);
var base = match[1];
var suffix = +(match[2] || 1);
while (_tags[kNew]) { // rename key if already in use
kNew = base + '_' + suffix++;
}
if (_includes(kNew, '=')) {
var splitStr = kNew.split('=').map(function(str) { return str.trim(); }),
key = splitStr[0],
value = splitStr[1];
var splitStr = kNew.split('=').map(function(str) { return str.trim(); });
var key = splitStr[0];
var value = splitStr[1];
kNew = key;
d.value = value;
@@ -295,9 +294,9 @@ export function uiRawTagEditor(context) {
tag[kOld] = undefined;
tag[kNew] = d.value;
d.key = kNew; // Maintain DOM identity through the subsequent update.
d.key = kNew; // Maintain DOM identity through the subsequent update.
if (_newRow === kOld) { // see if this row is still a new row
if (_newRow === kOld) { // see if this row is still a new row
_newRow = ((d.value === '' || kNew === '') ? kNew : undefined);
}
+22 -9
View File
@@ -2,16 +2,25 @@ import _throttle from 'lodash-es/throttle';
import { selectAll as d3_selectAll } from 'd3-selection';
import { osmEntity, osmNote } from '../osm';
import { uiFeatureList } from './feature_list';
import { uiInspector } from './inspector';
import { uiNoteEditor } from './note_editor';
import {
osmEntity,
osmNote
} from '../osm';
import {
uiDataEditor,
uiFeatureList,
uiInspector,
uiNoteEditor
} from './index';
export function uiSidebar(context) {
var inspector = uiInspector(context);
var dataEditor = uiDataEditor(context);
var noteEditor = uiNoteEditor(context);
var _current;
var _wasData = false;
var _wasNote = false;
@@ -28,8 +37,12 @@ export function uiSidebar(context) {
function hover(datum) {
if (datum && datum.__featurehash__) { // hovering on data
console.log ('hover on data ' + datum.__featurehash__);
// show something
_wasData = true;
sidebar
.show(dataEditor.datum(datum));
selection.selectAll('.sidebar-component')
.classed('inspector-hover', true);
} else if (datum instanceof osmNote) {
if (context.mode().id === 'drag-note') return;
@@ -66,10 +79,10 @@ export function uiSidebar(context) {
inspector
.state('hide');
} else if (_wasNote) {
} else if (_wasData || _wasNote) {
_wasNote = false;
d3_selectAll('.note')
.classed('hover', false);
_wasData = false;
d3_selectAll('.note').classed('hover', false);
sidebar.hide();
}
}