mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-25 09:34:04 +02:00
added new note icon and completed sidebar
This commit is contained in:
+9
-1
@@ -21,6 +21,11 @@
|
||||
color: #ff3300;
|
||||
stroke: #333;
|
||||
}
|
||||
.note-header-icon.new .note-fill,
|
||||
.layer-notes .note.new .note-fill {
|
||||
color: #00bcdd;
|
||||
stroke: #333;
|
||||
}
|
||||
.note-header-icon.closed .note-fill,
|
||||
.layer-notes .note.closed .note-fill {
|
||||
color: #55dd00;
|
||||
@@ -99,7 +104,6 @@
|
||||
.comments-container {
|
||||
background: #ececec;
|
||||
padding: 1px 10px;
|
||||
margin: 10px 0;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
@@ -157,6 +161,10 @@
|
||||
min-height: 100px;
|
||||
}
|
||||
|
||||
.note-save-section {
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.note-report {
|
||||
float: right;
|
||||
}
|
||||
|
||||
@@ -635,6 +635,9 @@ en:
|
||||
close_comment: Close and Comment
|
||||
open_comment: Reopen and Comment
|
||||
report: Report
|
||||
new: New Note
|
||||
newDescription: "Describe the issue."
|
||||
newNote: Add Note
|
||||
help:
|
||||
title: Help
|
||||
key: H
|
||||
|
||||
Vendored
+4
-1
@@ -769,7 +769,10 @@
|
||||
"comment": "Comment",
|
||||
"close_comment": "Close and Comment",
|
||||
"open_comment": "Reopen and Comment",
|
||||
"report": "Report"
|
||||
"report": "Report",
|
||||
"new": "New Note",
|
||||
"newDescription": "Describe the issue.",
|
||||
"newNote": "Add Note"
|
||||
},
|
||||
"help": {
|
||||
"title": "Help",
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
import osm from '../services/osm';
|
||||
|
||||
export function actionAddNote(note) {
|
||||
osm.replaceNote(note);
|
||||
console.log('actionAddNote: ', note);
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
export { actionAddEntity } from './add_entity';
|
||||
export { actionAddMember } from './add_member';
|
||||
export { actionAddMidpoint } from './add_midpoint';
|
||||
export { actionAddNote } from './add_note';
|
||||
export { actionAddVertex } from './add_vertex';
|
||||
export { actionChangeMember } from './change_member';
|
||||
export { actionChangePreset } from './change_preset';
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
import { t } from '../util/locale';
|
||||
import { actionAddNote } from '../actions';
|
||||
import { behaviorDraw } from '../behavior';
|
||||
import { modeBrowse, modeSelectNote } from './index';
|
||||
import { osmNote } from '../osm';
|
||||
import { services } from '../services';
|
||||
import { dispatch as d3_dispatch } from 'd3-dispatch';
|
||||
|
||||
|
||||
|
||||
export function modeAddNote(context) {
|
||||
|
||||
var dispatch = d3_dispatch('change');
|
||||
|
||||
var mode = {
|
||||
id: 'add-note',
|
||||
button: 'note',
|
||||
@@ -24,13 +27,20 @@ export function modeAddNote(context) {
|
||||
|
||||
|
||||
function add(loc) {
|
||||
var note = osmNote({ loc: loc });
|
||||
var note = osmNote({
|
||||
loc: loc,
|
||||
status: 'open',
|
||||
comments: {},
|
||||
newFeature: true
|
||||
});
|
||||
|
||||
// actionAddNote(note);
|
||||
services.osm.replaceNote(note);
|
||||
dispatch.call('change');
|
||||
|
||||
context.enter(
|
||||
modeSelectNote(context, [note.id]).newFeature(true)
|
||||
);
|
||||
|
||||
context
|
||||
.selectedNoteID(note.id)
|
||||
.enter(modeSelectNote(context, [note.id]).newFeature(true));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@ export function modeSelectNote(context, selectedNoteID) {
|
||||
.call(keybinding);
|
||||
|
||||
context.ui().sidebar
|
||||
.show(noteEditor.note(note));
|
||||
.show(noteEditor.note(note, newFeature));
|
||||
|
||||
context.map()
|
||||
.on('drawn.select', selectNote);
|
||||
|
||||
+32
-7
@@ -159,6 +159,17 @@ function parseComments(comments) {
|
||||
}
|
||||
|
||||
|
||||
function encodeNoteRtree(note) {
|
||||
return {
|
||||
minX: note.loc[0],
|
||||
minY: note.loc[1],
|
||||
maxX: note.loc[0],
|
||||
maxY: note.loc[1],
|
||||
data: note
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
var parsers = {
|
||||
node: function nodeData(obj, uid) {
|
||||
var attrs = obj.attributes;
|
||||
@@ -239,9 +250,10 @@ var parsers = {
|
||||
}
|
||||
|
||||
var note = new osmNote(props);
|
||||
var item = { minX: note.loc[0], minY: note.loc[1], maxX: note.loc[0], maxY: note.loc[1], data: note };
|
||||
_noteCache.rtree.insert(item);
|
||||
var item = encodeNoteRtree(note);
|
||||
_noteCache.note[note.id] = note;
|
||||
_noteCache.rtree.insert(item);
|
||||
|
||||
return note;
|
||||
},
|
||||
|
||||
@@ -906,7 +918,7 @@ export default {
|
||||
if (err) { return callback(err); }
|
||||
|
||||
// we get the updated note back, remove from caches and reparse..
|
||||
var item = { minX: note.loc[0], minY: note.loc[1], maxX: note.loc[0], maxY: note.loc[1], data: note };
|
||||
var item = encodeNoteRtree(note);
|
||||
_noteCache.rtree.remove(item, function isEql(a, b) { return a.data.id === b.data.id; });
|
||||
delete _noteCache.note[note.id];
|
||||
|
||||
@@ -1052,11 +1064,24 @@ export default {
|
||||
|
||||
|
||||
// replace a single note in the cache
|
||||
replaceNote: function(n) {
|
||||
if (n instanceof osmNote) {
|
||||
_noteCache.note[n.id] = n;
|
||||
replaceNote: function(note) {
|
||||
if (!(note instanceof osmNote) || !note.id) return;
|
||||
|
||||
_noteCache.note[note.id] = note; // update (or insert) in _noteCache.note
|
||||
|
||||
function updateRtree(item) { // update (or insert) in _noteCache.rtree
|
||||
|
||||
// TODO: other checks needed? (e.g., if cache.data.children.length decrements ...)
|
||||
|
||||
// remove note
|
||||
_noteCache.rtree.remove(item, function isEql(a, b) { return a.data.id === b.data.id; });
|
||||
_noteCache.rtree.insert(item); // add note (updated)
|
||||
|
||||
}
|
||||
return n;
|
||||
|
||||
updateRtree(encodeNoteRtree(note));
|
||||
|
||||
return note;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
+27
-4
@@ -43,25 +43,35 @@ export function svgNotes(projection, context, dispatch) {
|
||||
|
||||
|
||||
function showLayer() {
|
||||
editOn();
|
||||
// editOn();
|
||||
|
||||
layer
|
||||
.classed('disabled', false)
|
||||
.style('opacity', 0)
|
||||
.transition()
|
||||
.duration(250)
|
||||
.style('opacity', 1)
|
||||
.on('end', function () { dispatch.call('change'); });
|
||||
.on('end interrupt', function () {
|
||||
dispatch.call('change');
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function hideLayer() {
|
||||
// editOff();
|
||||
|
||||
throttledRedraw.cancel();
|
||||
layer.interrupt();
|
||||
|
||||
layer
|
||||
.transition()
|
||||
.duration(250)
|
||||
.style('opacity', 0)
|
||||
.on('end', editOff);
|
||||
.on('end interrupt', function () {
|
||||
layer.classed('disabled', true);
|
||||
dispatch.call('change');
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -80,7 +90,8 @@ export function svgNotes(projection, context, dispatch) {
|
||||
// enter
|
||||
var notesEnter = notes.enter()
|
||||
.append('g')
|
||||
.attr('class', function(d) { return 'note note-' + d.id + ' ' + d.status; });
|
||||
.attr('class', function(d) { return 'note note-' + d.id + ' ' + d.status; })
|
||||
.classed('new', function(d){ return d.id < 0; });
|
||||
|
||||
notesEnter
|
||||
.append('use')
|
||||
@@ -103,6 +114,18 @@ export function svgNotes(projection, context, dispatch) {
|
||||
.attr('y', '-20px')
|
||||
.attr('xlink:href', '#iD-icon-more');
|
||||
|
||||
// add plus if this is a new note
|
||||
notesEnter.selectAll('.note-annotation')
|
||||
.data(function(d) { return d.id < 0 ? [0] : []; })
|
||||
.enter()
|
||||
.append('use')
|
||||
.attr('class', 'note-annotation thread')
|
||||
.attr('width', '14px')
|
||||
.attr('height', '14px')
|
||||
.attr('x', '-7px')
|
||||
.attr('y', '-20px')
|
||||
.attr('xlink:href', '#iD-icon-plus');
|
||||
|
||||
// update
|
||||
notes
|
||||
.merge(notesEnter)
|
||||
|
||||
+1
-1
@@ -101,7 +101,7 @@ export function uiInit(context) {
|
||||
|
||||
limiter
|
||||
.append('div')
|
||||
.attr('class', 'button-wrap joined col5')
|
||||
.attr('class', 'button-wrap joined col3')
|
||||
.call(uiModes(context), limiter);
|
||||
|
||||
limiter
|
||||
|
||||
+2
-7
@@ -48,10 +48,8 @@ export function uiModes(context) {
|
||||
.append('button')
|
||||
.attr('tabindex', -1)
|
||||
.attr('class', function(mode) { return mode.id + ' add-button col3'; })
|
||||
// .classed('disabled', function(mode) {
|
||||
// return mode.id === 'add-note' && !svgNotes.enabled; // disable notes button
|
||||
// })
|
||||
.on('click.mode-buttons', function(mode) {
|
||||
//TODO: prevent modeBrowse when in modeAddNote & osm layer is turned off
|
||||
// When drawing, ignore accidental clicks on mode buttons - #4042
|
||||
var currMode = context.mode().id;
|
||||
if (currMode.match(/^draw/) !== null) return;
|
||||
@@ -100,10 +98,7 @@ export function uiModes(context) {
|
||||
modes.forEach(function(mode) {
|
||||
keybinding.on(mode.key, function() {
|
||||
// TODO: allow zooming out beyond minZoom when adding new note. Currently prevented
|
||||
if (
|
||||
(editable() && mode.id !== 'add-note')
|
||||
|| (toggleNewNote() && mode.id === 'add-note')
|
||||
) {
|
||||
if ((editable() && mode.id !== 'add-note') || (toggleNewNote() && mode.id === 'add-note')) {
|
||||
if (mode.id === context.mode().id) {
|
||||
context.enter(modeBrowse(context));
|
||||
} else {
|
||||
|
||||
@@ -11,6 +11,8 @@ export function uiNoteComments() {
|
||||
|
||||
|
||||
function noteComments(selection) {
|
||||
if (_note.newFeature) { return; }
|
||||
|
||||
var comments = selection.selectAll('.comments-container')
|
||||
.data([0]);
|
||||
|
||||
|
||||
+39
-13
@@ -90,7 +90,9 @@ export function uiNoteEditor(context) {
|
||||
noteSaveEnter
|
||||
.append('h4')
|
||||
.attr('class', '.note-save-header')
|
||||
.text(t('note.newComment'));
|
||||
.text(function() {
|
||||
return _note.newFeature ? t('note.newDescription') : t('note.newComment');
|
||||
});
|
||||
|
||||
noteSaveEnter
|
||||
.append('textarea')
|
||||
@@ -140,18 +142,26 @@ export function uiNoteEditor(context) {
|
||||
.append('div')
|
||||
.attr('class', 'buttons');
|
||||
|
||||
buttonEnter
|
||||
.append('button')
|
||||
.attr('class', 'button status-button action')
|
||||
.append('span')
|
||||
.attr('class', 'label');
|
||||
if (_note.newFeature) {
|
||||
buttonEnter
|
||||
.append('button')
|
||||
.attr('class', 'button add-note-button action')
|
||||
.append('span')
|
||||
.attr('class', 'label');
|
||||
} else {
|
||||
buttonEnter
|
||||
.append('button')
|
||||
.attr('class', 'button status-button action')
|
||||
.append('span')
|
||||
.attr('class', 'label');
|
||||
|
||||
buttonEnter
|
||||
.append('button')
|
||||
.attr('class', 'button comment-button action')
|
||||
.append('span')
|
||||
.attr('class', 'label')
|
||||
.text(t('note.comment'));
|
||||
buttonEnter
|
||||
.append('button')
|
||||
.attr('class', 'button comment-button action')
|
||||
.append('span')
|
||||
.attr('class', 'label')
|
||||
.text(t('note.comment'));
|
||||
}
|
||||
|
||||
// update
|
||||
buttonSection = buttonSection
|
||||
@@ -187,12 +197,28 @@ export function uiNoteEditor(context) {
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
buttonSection.select('.add-note-button') // select and propagate data
|
||||
.text(t('note.newNote'))
|
||||
.attr('disabled', function(d) {
|
||||
return (d.status === 'open' && d.newComment) ? null : true;
|
||||
})
|
||||
.on('click.save', function(d) {
|
||||
this.blur(); // avoid keeping focus on the button - #4641
|
||||
var osm = services.osm;
|
||||
if (osm) {
|
||||
osm.postNoteAdd(d, d.status, function(err, note) {
|
||||
dispatch.call('change', note);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
noteEditor.note = function(_) {
|
||||
noteEditor.note = function(_, __) {
|
||||
if (!arguments.length) return _note;
|
||||
_note = _;
|
||||
_note.update({ newFeature: __ });
|
||||
return noteEditor;
|
||||
};
|
||||
|
||||
|
||||
@@ -22,7 +22,8 @@ export function uiNoteHeader() {
|
||||
|
||||
var iconEnter = headerEnter
|
||||
.append('div')
|
||||
.attr('class', function(d) { return 'note-header-icon ' + d.status; });
|
||||
.attr('class', function(d) { return 'note-header-icon ' + d.status; })
|
||||
.classed('new', function(d) { return d.id < 0; });
|
||||
|
||||
iconEnter
|
||||
.append('div')
|
||||
@@ -35,6 +36,11 @@ export function uiNoteHeader() {
|
||||
.append('div')
|
||||
.attr('class', 'note-icon-annotation')
|
||||
.call(svgIcon('#iD-icon-more', 'note-annotation'));
|
||||
} else if (_note.newFeature) {
|
||||
iconEnter
|
||||
.append('div')
|
||||
.attr('class', 'note-icon-annotation')
|
||||
.call(svgIcon('#iD-icon-plus', 'note-annotation'));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -42,13 +48,14 @@ export function uiNoteHeader() {
|
||||
.append('div')
|
||||
.attr('class', 'note-header-label')
|
||||
.text(function(d) {
|
||||
if (_note.newFeature) { return t('note.new'); }
|
||||
return t('note.note') + ' ' + d.id + ' ' +
|
||||
(d.status === 'closed' ? t('note.closed') : '');
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
noteHeader.note = function(_) {
|
||||
noteHeader.note = function(_, __) {
|
||||
if (!arguments.length) return _note;
|
||||
_note = _;
|
||||
return noteHeader;
|
||||
|
||||
Reference in New Issue
Block a user