Allow undeletions

This commit is contained in:
Bryan Housel
2015-01-13 16:28:06 -05:00
parent a3459714b8
commit 3fc99e1df5
3 changed files with 58 additions and 29 deletions
+6 -6
View File
@@ -314,23 +314,23 @@ en:
no_changes: No changes to save.
error: Errors occurred while trying to save
status_code: "Server returned status code {code}"
status_gone: '{type} "{id}" {name} has already been deleted.'
status_gone: '{name} has already been deleted.'
unknown_error_details: "Please ensure you are connected to the internet."
uploading: Uploading changes to OpenStreetMap.
unsaved_changes: You have unsaved changes
conflict:
header: Conflicting edits detected
message: 'Conflicting edits were made to {type} "{id}" {name}'
message: 'Conflicting edits were made to {name}'
keep_local: Keep Mine
keep_remote: Keep Theirs
restore: Restore
delete: Leave Deleted
annotation:
safe: Merged remote changes from server.
keep_local: 'Kept local version of "{id}".'
keep_remote: 'Kept remote version of "{id}".'
restore: 'Restored local version of "{id}".'
delete: 'Deleted local version of "{id}".'
keep_local: 'Kept local version of {id}.'
keep_remote: 'Kept remote version of {id}.'
restore: 'Restored local version of {id}.'
delete: 'Deleted local version of {id}.'
try_again: Try Again
download_changes: Download Changes
help: |
+6 -6
View File
@@ -388,23 +388,23 @@
"no_changes": "No changes to save.",
"error": "Errors occurred while trying to save",
"status_code": "Server returned status code {code}",
"status_gone": "{type} \"{id}\" {name} has already been deleted.",
"status_gone": "{name} has already been deleted.",
"unknown_error_details": "Please ensure you are connected to the internet.",
"uploading": "Uploading changes to OpenStreetMap.",
"unsaved_changes": "You have unsaved changes",
"conflict": {
"header": "Conflicting edits detected",
"message": "Conflicting edits were made to {type} \"{id}\" {name}",
"message": "Conflicting edits were made to {name}",
"keep_local": "Keep Mine",
"keep_remote": "Keep Theirs",
"restore": "Restore",
"delete": "Leave Deleted",
"annotation": {
"safe": "Merged remote changes from server.",
"keep_local": "Kept local version of \"{id}\".",
"keep_remote": "Kept remote version of \"{id}\".",
"restore": "Restored local version of \"{id}\".",
"delete": "Deleted local version of \"{id}\"."
"keep_local": "Kept local version of {id}.",
"keep_remote": "Kept remote version of {id}.",
"restore": "Restored local version of {id}.",
"delete": "Deleted local version of {id}."
},
"try_again": "Try Again",
"download_changes": "Download Changes",
+46 -17
View File
@@ -1,7 +1,17 @@
iD.modes.Save = function(context) {
var ui = iD.ui.Commit(context)
.on('cancel', cancel)
.on('save', save);
var undeletions = [],
ui = iD.ui.Commit(context)
.on('cancel', cancel)
.on('save', save);
function undelete(id) {
return function(graph) {
var entity = context.entity(id),
target = iD.Entity(entity, { version: +entity.version + 1 });
undeletions.push(id);
return graph.replace(target);
};
}
function choice(text, actions) {
return {
@@ -18,7 +28,8 @@ iD.modes.Save = function(context) {
var loading = iD.ui.Loading(context).message(t('save.uploading')).blocking(true),
history = context.history(),
altGraph = iD.Graph(history.base(), true),
toCheck = _.pluck(history.changes().modified, 'id'),
modified = _.pluck(history.changes().modified, 'id'),
toCheck = _.clone(modified),
didMerge = false,
conflicts = [],
errors = [],
@@ -39,23 +50,29 @@ iD.modes.Save = function(context) {
var graph = context.graph(),
local = graph.entity(id),
type = iD.util.displayType(id),
name = iD.util.displayName(local) || '';
name = iD.util.displayName(local) || (type + ' ' + id);
toCheck = _.without(toCheck, id);
if (err) {
if (err.status === 410) { // Status: Gone (contains no responseText)
conflicts.push({
id: id,
msg: t('save.status_gone', { id: id, type: type, name: name }),
details: [ t('save.status_code', { code: err.status }) ],
choices: [
choice(t('save.conflict.restore'),
[ iD.actions.Noop() /*FIXME*/, t('save.conflict.annotation.restore', {id: id}) ]),
choice(t('save.conflict.delete'),
[ iD.actions.DeleteMultiple([id]), t('save.conflict.annotation.delete', {id: id}) ])
]
});
if (undeletions.indexOf(id) === -1) { // skip if we have already undeleted it..
if (local.type === 'node') {
checkParents(local);
}
conflicts.push({
id: id,
msg: t('save.status_gone', { name: name }),
details: [ t('save.status_code', { code: err.status }) ],
choices: [
choice(t('save.conflict.restore'),
[ undelete(id), t('save.conflict.annotation.restore', {id: id}) ]),
choice(t('save.conflict.delete'),
[ iD.actions.DeleteMultiple([id]), t('save.conflict.annotation.delete', {id: id}) ])
]
});
}
} else {
errors.push({
id: id,
@@ -82,7 +99,7 @@ iD.modes.Save = function(context) {
conflicts.push({
id: id,
msg: t('save.conflict.message', { id: id, type: type, name: name }),
msg: t('save.conflict.message', { name: name }),
details: details,
choices: [
choice(t('save.conflict.keep_local'),
@@ -101,6 +118,18 @@ iD.modes.Save = function(context) {
});
}
function checkParents(entity) {
var ids = _.pluck(context.graph().parentWays(entity), 'id');
for (var i = 0; i < ids.length; i++) {
if (modified.indexOf(ids[i]) === -1) {
modified.push(ids[i]);
toCheck.push(ids[i]);
check(ids[i]);
}
}
}
function finalize() {
if (didMerge) { // set undo checkpoint..
context.perform(iD.actions.Noop(), t('save.conflict.annotation.safe'));