diff --git a/modules/ui/changeset_editor.js b/modules/ui/changeset_editor.js new file mode 100644 index 000000000..e3c6a4103 --- /dev/null +++ b/modules/ui/changeset_editor.js @@ -0,0 +1,165 @@ +import * as d3 from 'd3'; +import { d3combobox } from '../lib/d3.combobox.js'; +import { t } from '../util/locale'; +import { uiField } from './field'; +import { + utilGetSetValue, + utilNoAuto, + utilRebind +} from '../util'; + + +export function uiChangesetEditor(context) { + var dispatch = d3.dispatch('change'), + fieldsArr, + changeset, + tags; + + + function changesetEditor(selection) { + + if (!fieldsArr) { + var presets = context.presets(); + + fieldsArr = []; + +// FIXME: for testing + if (presets.field('brand')) { + fieldsArr.push( + uiField(context, presets.field('brand'), changeset) + ); + } + +// FIXME: for testing + presets.universal().forEach(function(field) { + fieldsArr.push( + uiField(context, field, changeset, { show: false }) + ); + }); + + fieldsArr.forEach(function(field) { + field + .on('change', function(t, onInput) { + dispatch.call('change', field, t, onInput); + }); + }); + } + + fieldsArr.forEach(function(field) { + field + .tags(tags); + }); + + var shown = fieldsArr.filter(function(field) { return field.isShown(); }), + notShown = fieldsArr.filter(function(field) { return !field.isShown(); }); + + + var form = selection.selectAll('.preset-form') + .data([0]); + + form = form.enter() + .append('div') + .attr('class', 'preset-form inspector-inner fillL3') + .merge(form); + + + var fields = form.selectAll('.wrap-form-field') + .data(shown, function(d) { return d.id; }); + + fields.exit() + .remove(); + + // Enter + var enter = fields.enter() + .append('div') + .attr('class', function(d) { return 'wrap-form-field wrap-form-field-' + d.id; }); + + // Update + fields = fields + .merge(enter); + + fields + .order() + .each(function(d) { + d3.select(this) + .call(d.render); + }); + + + notShown = notShown.map(function(field) { + return { + title: field.label(), + value: field.label(), + field: field + }; + }); + + + var more = selection.selectAll('.more-fields') + .data((notShown.length > 0) ? [0] : []); + + more.exit() + .remove(); + + more = more.enter() + .append('div') + .attr('class', 'more-fields') + .append('label') + .text(t('inspector.add_fields')) + .merge(more); + + + var input = more.selectAll('.value') + .data([0]); + + input.exit() + .remove(); + + input = input.enter() + .append('input') + .attr('class', 'value') + .attr('type', 'text') + .call(utilNoAuto) + .merge(input); + + input + .call(utilGetSetValue, '') + .attr('placeholder', function() { + var placeholder = []; + for (var field in notShown) { + placeholder.push(notShown[field].title); + } + return placeholder.slice(0,3).join(', ') + ((placeholder.length > 3) ? '…' : ''); + }) + .call(d3combobox() + .container(context.container()) + .data(notShown) + .minItems(1) + .on('accept', function (d) { + var field = d.field; + field.show = true; + changesetEditor(selection); + field.focus(); + }) + ); + } + + + changesetEditor.changeset = function(_) { + if (!arguments.length) return changeset; + changeset = _; + fieldsArr = null; + return changesetEditor; + }; + + + changesetEditor.tags = function(_) { + if (!arguments.length) return tags; + tags = _; + // Don't reset fieldsArr here. + return changesetEditor; + }; + + + return utilRebind(changesetEditor, dispatch, 'on'); +} diff --git a/modules/ui/commit.js b/modules/ui/commit.js index bfae8b19a..7b9b7d8a7 100644 --- a/modules/ui/commit.js +++ b/modules/ui/commit.js @@ -6,6 +6,7 @@ import { osmChangeset } from '../osm'; import { modeSelect } from '../modes'; import { svgIcon } from '../svg'; import { tooltip } from '../util/tooltip'; +import { uiChangesetEditor } from './changeset_editor'; import { uiRawTagEditor } from './raw_tag_editor'; import { utilDetect } from '../util/detect'; import { @@ -41,10 +42,13 @@ export function uiCommit(context) { changeset = new osmChangeset({ tags: tags }); } + var changesetEditor = uiChangesetEditor(context) + .on('change', changeTags); + var rawTagEditor = uiRawTagEditor(context) + .on('change', changeTags); var changes = context.history().changes(), summary = context.history().difference().summary(), - rawTagEditor = uiRawTagEditor(context).on('change', changeTags), comment = context.storage('comment') || '', commentDate = +context.storage('commentDate') || 0, currDate = Date.now(), @@ -65,6 +69,14 @@ export function uiCommit(context) { .append('div') .attr('class', 'body'); + body + .append('div') + .attr('class', 'modal-section changeset-editor') + .call(changesetEditor + .changeset(changeset) + .tags(tags) + ); + // Fields var fieldSection = body diff --git a/modules/ui/index.js b/modules/ui/index.js index 3abe1ebb2..874e0354d 100644 --- a/modules/ui/index.js +++ b/modules/ui/index.js @@ -2,6 +2,7 @@ export { uiInit } from './init'; export { uiAccount } from './account'; export { uiAttribution } from './attribution'; export { uiBackground } from './background'; +export { uiChangesetEditor } from './changeset_editor'; export { uiCmd } from './cmd'; export { uiCommit } from './commit'; export { uiConfirm } from './confirm';