From 16df2f595fab0f9c5e104a0f631a869761289824 Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Mon, 13 Mar 2017 17:32:50 -0400 Subject: [PATCH] Change raw tag editor to embed it on commit pane --- css/80_app.css | 6 +-- modules/modes/save.js | 51 +++++++++++---------- modules/ui/commit.js | 89 ++++++++++++++++++++++++++++++------ modules/ui/raw_tag_editor.js | 36 ++++++++++++--- 4 files changed, 135 insertions(+), 47 deletions(-) diff --git a/css/80_app.css b/css/80_app.css index 694c81947..6be523066 100644 --- a/css/80_app.css +++ b/css/80_app.css @@ -1673,7 +1673,7 @@ div.combobox { /* Adding form fields to tag editor */ -.inspector-inner .add-tag { +.raw-tag-editor .add-tag { width: 40%; height: 30px; border-top: 0; @@ -1681,11 +1681,11 @@ div.combobox { border-radius: 0 0 4px 4px; } -.inspector-inner .add-tag:hover { +.raw-tag-editor .add-tag:hover { background: rgba(0,0,0,.8); } -.inspector-inner .add-tag .label { +.raw-tag-editor .add-tag .label { display: none; } diff --git a/modules/modes/save.js b/modules/modes/save.js index 74743d846..a2174c56b 100644 --- a/modules/modes/save.js +++ b/modules/modes/save.js @@ -43,23 +43,7 @@ export function modeSave(context) { } - function save(e, tryAgain) { - function withChildNodes(ids, graph) { - return _.uniq(_.reduce(ids, function(result, id) { - var e = graph.entity(id); - if (e.type === 'way') { - try { - var cn = graph.childNodes(e); - result.push.apply(result, _.map(_.filter(cn, 'version'), 'id')); - } catch (err) { - /* eslint-disable no-console */ - if (typeof console !== 'undefined') console.error(err); - /* eslint-enable no-console */ - } - } - return result; - }, _.clone(ids))); - } + function save(changeset, tryAgain) { var loading = uiLoading(context).message(t('save.uploading')).blocking(true), history = context.history(), @@ -72,7 +56,10 @@ export function modeSave(context) { conflicts = [], errors = []; - if (!tryAgain) history.perform(actionNoop()); // checkpoint + if (!tryAgain) { + history.perform(actionNoop()); // checkpoint + } + context.container().call(loading); if (toCheck.length) { @@ -82,6 +69,24 @@ export function modeSave(context) { } + function withChildNodes(ids, graph) { + return _.uniq(_.reduce(ids, function(result, id) { + var entity = graph.entity(id); + if (entity.type === 'way') { + try { + var cn = graph.childNodes(entity); + result.push.apply(result, _.map(_.filter(cn, 'version'), 'id')); + } catch (err) { + /* eslint-disable no-console */ + if (typeof console !== 'undefined') console.error(err); + /* eslint-enable no-console */ + } + } + return result; + }, _.clone(ids))); + } + + // Reload modified entities into an alternate graph and check for conflicts.. function loaded(err, result) { if (errors.length) return; @@ -198,7 +203,7 @@ export function modeSave(context) { context.connection().putChangeset( changes, context.version, - e.comment, + changeset.tags.comment, history.imageryUsed(), function(err, changeset_id) { if (err) { @@ -209,7 +214,7 @@ export function modeSave(context) { showErrors(); } else { history.clearSaved(); - success(e, changeset_id); + success(changeset, changeset_id); // Add delay to allow for postgres replication #1646 #2678 window.setTimeout(function() { d3.select('.inspector-wrap *').remove(); @@ -262,7 +267,7 @@ export function modeSave(context) { } selection.remove(); - save(e, true); + save(changeset, true); }) ); } @@ -335,12 +340,12 @@ export function modeSave(context) { } - function success(e, changeset_id) { + function success(changeset, changeset_id) { context.enter(modeBrowse(context) .sidebar(uiSuccess(context) .changeset({ id: changeset_id, - comment: e.comment + comment: changeset.tags.comment }) .on('cancel', function() { context.ui().sidebar.hide(); diff --git a/modules/ui/commit.js b/modules/ui/commit.js index 210ff8eea..39f3b60ef 100644 --- a/modules/ui/commit.js +++ b/modules/ui/commit.js @@ -2,16 +2,22 @@ import * as d3 from 'd3'; import _ from 'lodash'; import { t } from '../util/locale'; import { d3combobox } from '../lib/d3.combobox.js'; -import { modeSelect } from '../modes/index'; -import { svgIcon } from '../svg/index'; +import { osmChangeset } from '../osm'; +import { modeSelect } from '../modes'; +import { svgIcon } from '../svg'; import { tooltip } from '../util/tooltip'; +import { uiRawTagEditor } from './raw_tag_editor'; +import { utilDetect } from '../util/detect'; import { utilDisplayName, utilDisplayType, - utilEntityOrMemberSelector -} from '../util/index'; -import { utilRebind } from '../util/rebind'; -import { utilTriggerEvent } from '../util/trigger_event'; + utilEntityOrMemberSelector, + utilRebind, + utilTriggerEvent +} from '../util'; + + +var changeset; export function uiCommit(context) { @@ -19,8 +25,22 @@ export function uiCommit(context) { function commit(selection) { + if (!changeset) { + var detected = utilDetect(), + tags = { + created_by: ('iD ' + context.version).substr(0, 255), + imagery_used: context.history().imageryUsed().join(';').substr(0, 255), + host: detected.host.substr(0, 255), + locale: detected.locale.substr(0, 255) + }; + + changeset = new osmChangeset({ tags: tags }); + } + + var changes = context.history().changes(), - summary = context.history().difference().summary(); + summary = context.history().difference().summary(), + rawTagEditor = uiRawTagEditor(context).on('change', changeTags); selection .append('div') @@ -43,6 +63,7 @@ export function uiCommit(context) { var commentField = commentSection .append('textarea') + .attr('class', 'commit-form-comment') .attr('placeholder', t('commit.description_placeholder')) .attr('maxlength', 255) .property('value', context.storage('comment') || '') @@ -169,12 +190,14 @@ export function uiCommit(context) { // Buttons var buttonSection = saveSection .append('div') - .attr('class','buttons fillL cf'); + .attr('class', 'buttons fillL cf'); var cancelButton = buttonSection .append('button') .attr('class', 'secondary-action col5 button cancel-button') - .on('click.cancel', function() { dispatch.call('cancel'); }); + .on('click.cancel', function() { + dispatch.call('cancel'); + }); cancelButton .append('span') @@ -189,9 +212,8 @@ export function uiCommit(context) { return (n && n.value.length) ? null : true; }) .on('click.save', function() { - dispatch.call('save', this, { - comment: commentField.node().value - }); + dispatch.call('save', this, changeset); + changeset = null; }); saveButton @@ -200,6 +222,16 @@ export function uiCommit(context) { .text(t('commit.save')); + // Raw Tag Editor + var tagSection = body + .append('div') + .attr('class', 'modal-section tag-section raw-tag-editor') + .call(rawTagEditor + .expanded(false) + .tags(_.clone(changeset.tags)) + ); + + // Changes var changeSection = body .append('div') @@ -291,13 +323,15 @@ export function uiCommit(context) { function checkComment() { + var comment = this.value; + d3.selectAll('.save-section .save-button') - .attr('disabled', (this.value.length ? null : true)); + .attr('disabled', (comment.length ? null : true)); var googleWarning = clippyArea .html('') .selectAll('a') - .data(this.value.match(/google/i) ? [true] : []); + .data(comment.match(/google/i) ? [true] : []); googleWarning.exit() .remove(); @@ -310,7 +344,34 @@ export function uiCommit(context) { .attr('href', t('commit.google_warning_link')) .append('span') .text(t('commit.google_warning')); + + updateChangeset({ comment: comment }); } + + + function changeTags(changed) { + if (changed.hasOwnProperty('comment')) { + selection.selectAll('.commit-form-comment') + .property('value', changed.comment); + } + updateChangeset(changed); + } + + + function updateChangeset(changed) { + var tags = _.clone(changeset.tags); + + _.forEach(changed, function(v, k) { + if (v !== undefined || tags.hasOwnProperty(k)) { + tags[k] = v; + } + }); + + if (!_.isEqual(changeset.tags, tags)) { + changeset = changeset.update({ tags: tags }); + } + } + } return utilRebind(commit, dispatch, 'on'); diff --git a/modules/ui/raw_tag_editor.js b/modules/ui/raw_tag_editor.js index 168ec4f66..ab1d1c0df 100644 --- a/modules/ui/raw_tag_editor.js +++ b/modules/ui/raw_tag_editor.js @@ -15,6 +15,8 @@ import { export function uiRawTagEditor(context) { var taginfo = services.taginfo, dispatch = d3.dispatch('change'), + expanded = context.storage('raw_tag_editor.expanded') === 'true', + updatePreference = true, showBlank = false, state, preset, @@ -27,12 +29,15 @@ export function uiRawTagEditor(context) { selection.call(uiDisclosure() .title(t('inspector.all_tags') + ' (' + count + ')') - .expanded(context.storage('raw_tag_editor.expanded') === 'true' || preset.isFallback()) + .expanded(expanded) .on('toggled', toggled) - .content(content)); + .content(content) + ); function toggled(expanded) { - context.storage('raw_tag_editor.expanded', expanded); + if (updatePreference) { + context.storage('raw_tag_editor.expanded', expanded); + } if (expanded) { selection.node().parentNode.scrollTop += 200; } @@ -125,11 +130,11 @@ export function uiRawTagEditor(context) { key = row.select('input.key'), // propagate bound data to child value = row.select('input.value'); // propagate bound data to child - if (taginfo) { + if (id && taginfo) { bindTypeahead(key, value); } - var isRelation = (context.entity(id).type === 'relation'), + var isRelation = (id && context.entity(id).type === 'relation'), reference; if (isRelation && tag.key === 'type') { @@ -182,11 +187,13 @@ export function uiRawTagEditor(context) { return sameletter.concat(other); } + var geometry = context.geometry(id); + key.call(d3combobox() .fetcher(function(value, callback) { taginfo.keys({ debounce: true, - geometry: context.geometry(id), + geometry: geometry, query: value }, function(err, data) { if (!err) callback(sort(value, data)); @@ -198,7 +205,7 @@ export function uiRawTagEditor(context) { taginfo.values({ debounce: true, key: utilGetSetValue(key), - geometry: context.geometry(id), + geometry: geometry, query: value }, function(err, data) { if (!err) callback(sort(value, data)); @@ -277,6 +284,13 @@ export function uiRawTagEditor(context) { rawTagEditor.preset = function(_) { if (!arguments.length) return preset; preset = _; + if (preset.isFallback()) { + expanded = true; + updatePreference = false; + } else { + expanded = context.storage('raw_tag_editor.expanded') === 'true'; + updatePreference = true; + } return rawTagEditor; }; @@ -295,5 +309,13 @@ export function uiRawTagEditor(context) { }; + rawTagEditor.expanded = function(_) { + if (!arguments.length) return expanded; + expanded = _; + updatePreference = false; + return rawTagEditor; + }; + + return utilRebind(rawTagEditor, dispatch, 'on'); }