Add duplicate action.

This commit is contained in:
Paulo Gustavo Veiga 2012-04-07 20:05:50 -03:00
parent 3da0eec842
commit 748ecf7608
4 changed files with 224 additions and 99 deletions

View File

@ -98,14 +98,6 @@ public class MindmapController {
return view; return view;
} }
@RequestMapping(value = "delete")
public ModelAndView delete(@RequestParam(required = true) long mapId, @NotNull HttpServletRequest request) throws WiseMappingException {
final User user = Utils.getUser();
final MindMap mindmap = findMindmap(mapId);
mindmapService.removeCollaboratorFromMindmap(mindmap, user.getId());
return list(request);
}
@RequestMapping(value = "updateMindmap") @RequestMapping(value = "updateMindmap")
public ModelAndView updateMindmap(@RequestParam(required = true) long mapId, @RequestParam(required = true) String title, @RequestParam(required = true) String description, @NotNull HttpServletRequest request) throws WiseMappingException { public ModelAndView updateMindmap(@RequestParam(required = true) long mapId, @RequestParam(required = true) String title, @RequestParam(required = true) String description, @NotNull HttpServletRequest request) throws WiseMappingException {
final MindMap mindmap = findMindmap(mapId); final MindMap mindmap = findMindmap(mapId);

View File

@ -187,23 +187,15 @@ public class MindmapController extends BaseController {
@RequestMapping(method = RequestMethod.POST, value = "/maps/{id}", consumes = {"application/xml", "application/json"}) @RequestMapping(method = RequestMethod.POST, value = "/maps/{id}", consumes = {"application/xml", "application/json"})
@ResponseStatus(value = HttpStatus.CREATED) @ResponseStatus(value = HttpStatus.CREATED)
public void copyMap(@RequestBody RestMindmapInfo restMindmap, @PathVariable int id, @NotNull HttpServletResponse response) throws IOException, WiseMappingException { public void copyMap(@RequestBody RestMindmapInfo restMindmap, @PathVariable int id, @NotNull HttpServletResponse response) throws IOException, WiseMappingException {
// Validate ...
final String title = restMindmap.getTitle(); final BindingResult result = new BeanPropertyBindingResult(restMindmap, "");
if (title == null || title.isEmpty()) { new MapInfoValidator(mindmapService).validate(restMindmap.getDelegated(), result);
throw new IllegalArgumentException("Map title can not be null"); if (result.hasErrors()) {
} throw new ValidationException(result);
final String description = restMindmap.getDescription();
if (description == null || description.isEmpty()) {
throw new IllegalArgumentException("Map details can not be null");
} }
// Some basic validations ... // Some basic validations ...
final User user = Utils.getUser(); final User user = Utils.getUser();
final MindMap searchByMap = mindmapService.getMindmapByTitle(title, user);
if (searchByMap != null) {
throw new IllegalArgumentException("Map already exists with title '" + title + "'");
}
// Create a shallowCopy of the map ... // Create a shallowCopy of the map ...
final MindMap mindMap = mindmapService.getMindmapById(id); final MindMap mindMap = mindmapService.getMindmapById(id);

View File

@ -43,20 +43,95 @@ jQuery.fn.dataTableExt.getSelectedMapsIds = function() {
return ids; return ids;
}; };
jQuery.fn.dataTableExt.getSelectedRows = function() {
return $('.select input:checked[id!="selectAll"]').parent().parent();
};
jQuery.fn.dataTableExt.removeSelectedRows = function() { jQuery.fn.dataTableExt.removeSelectedRows = function() {
var mapIds = this.getSelectedMapsIds(); var mapIds = this.getSelectedMapsIds();
var trs = this.getSelectedRows();
jQuery.ajax({ jQuery.ajax({
async:false, async:false,
url: "../service/maps/batch?ids=" + mapIds.join(","), url: "../service/maps/batch?ids=" + mapIds.join(","),
type:"DELETE", type:"DELETE",
success : function(data, textStatus, jqXHR) { success : function(data, textStatus, jqXHR) {
var trs = $('.select input:checked[id!="selectAll"]').parent().parent();
trs.each(function() { trs.each(function() {
$('#mindmapListTable').dataTable().fnDeleteRow(this); $('#mindmapListTable').dataTable().fnDeleteRow(this);
}); });
}, },
error: function(){ error: function() {
alert("Unexpected error removing maps. Refresh before continue."); alert("Unexpected error removing maps. Refresh before continue.");
} }
}); });
}; };
jQuery.fn.dialogForm = function(options) {
var containerId = this[0].id;
var url = options.url;
var acceptButtonLabel = options.acceptButtonLabel;
// Clean previous dialog content ...
$("#" + containerId + " div[id='errorMessage']").text("").removeClass("ui-state-highlight");
options.buttons = {};
options.buttons[acceptButtonLabel] = function() {
var formData = {};
$('#' + containerId + ' input').each(function(index, elem) {
formData[elem.name] = elem.value;
});
jQuery.ajax(url, {
async:false,
dataType: 'json',
data: JSON.stringify(formData),
type: options.type ? options.type : 'POST',
contentType:"application/json; charset=utf-8",
success : function(data, textStatus, jqXHR) {
if (options.redirect) {
var mapId = jqXHR.getResponseHeader("ResourceId");
window.location = options.redirect + "&mapId=" + mapId;
} else if (options.postUpdate) {
options.postUpdate(formData);
}
$(this).dialog("close");
},
error: function(jqXHR, textStatus, errorThrown) {
if (jqXHR.status == 400) {
var errors = JSON.parse(jqXHR.responseText);
// Clean previous marks ....
$("#" + containerId + ' input').each(function(index, elem) {
$(elem).removeClass("ui-state-error");
});
// Mark fields with errors ...
var fieldErrors = errors.fieldErrors;
if (fieldErrors) {
for (var fieldName in fieldErrors) {
// Mark the field ...
var message = fieldErrors[fieldName];
var inputField = $("#" + containerId + " input[name='" + fieldName + "']");
$(inputField).addClass("ui-state-error");
$("#" + containerId + " div[id='errorMessage']").text(message).addClass("ui-state-highlight");
}
}
} else {
alert("Unexpected error removing maps. Refresh before continue.");
}
}
});
};
var cancelButtonLabel = options.cancelButtonLabel;
options.buttons[cancelButtonLabel] = function() {
$(this).dialog("close");
};
// Open the modal dialog ...
this.dialog(options);
};

View File

@ -41,7 +41,11 @@
sClass : "columName", sClass : "columName",
sTitle : "Name", sTitle : "Name",
bUseRendered : false, bUseRendered : false,
mDataProp: "title" mDataProp: "title",
fnRender : function(obj) {
return '<a href="c/editor.htm?action=open&mapId=' + obj.aData.id + '">' + obj.aData.title + '</a>';
}
}, },
{ {
sTitle : "Description", sTitle : "Description",
@ -157,77 +161,82 @@
} }
}); });
$("#buttons .newMap").button({ $("#buttons .newMap").button({
icons: { primary: "ui-icon-circle-plus" } icons: { primary: "ui-icon-circle-plus" }
}).click(function() { }).click(function() {
// Clean previous dialog content ... $("#new-dialog-modal").dialogForm({
$("#new-dialog-modal div[id='errorMessage']").text("").removeClass("ui-state-highlight");
$("#new-dialog-modal").dialog({
modal: true, modal: true,
buttons: { acceptButtonLabel : "Create",
"Create": function() { cancelButtonLabel : "Cancel",
redirect: "c/editor.htm?action=open",
var formData = {}; url : "../service/maps"
$('#new-dialog-modal input').each(function(index, elem) { });
formData[elem.name] = elem.value;
}); });
jQuery.ajax("../service/maps", {
async:false, $("#buttons .duplicateMap").button({
dataType: 'json', icons: { primary: "ui-icon-copy" }
data: JSON.stringify(formData), }).click(function() {
type: 'POST', // Map to be cloned ...
contentType:"application/json; charset=utf-8", var tableElem = $('#mindmapListTable');
success : function(data, textStatus, jqXHR) { var rows = tableElem.dataTableExt.getSelectedRows();
var mapId = jqXHR.getResponseHeader("ResourceId"); if (rows.length > 0) {
window.location = "c/editor.htm?action=open&mapId=" + mapId;
// Obtain map name ...
var rowData = tableElem.dataTable().fnGetData(rows[0]);
$('#duplicateMessage').text("Duplicate '" + rowData.title + "'");
// Obtains map id ...
var mapId = rowData.id;
// Initialize dialog ...
$("#duplicate-dialog-modal").dialogForm({
modal: true,
acceptButtonLabel : "Duplicated",
cancelButtonLabel : "Cancel",
redirect: "c/editor.htm?action=open",
url : "../service/maps/" + mapId
});
}
});
$("#buttons .renameMap").button({
icons: { primary: "ui-icon-gear" }
}).click(function() {
// Map to be cloned ...
var tableElem = $('#mindmapListTable');
var rows = tableElem.dataTableExt.getSelectedRows();
if (rows.length > 0) {
// Obtain map name ...
var dataTable = tableElem.dataTable();
var rowData = dataTable.fnGetData(rows[0]);
// Fill dialog with default values ...
var mapId = rowData.id;
$("#rename-dialog-modal input[name='title']").attr('value', rowData.title);
$("#rename-dialog-modal input[name='description']").attr('value', rowData.description);
// Initialize dialog ...
$("#rename-dialog-modal").dialogForm({
modal: true,
type: 'PUT',
acceptButtonLabel : "Rename",
cancelButtonLabel : "Cancel",
postUpdate: function(reqBodyData) {
// Remove old entry ...
dataTable.fnDeleteRow(rowData);
// Add a new one...
rowData.title = reqBodyData.title;
rowData.description = reqBodyData.description;
dataTable.fnAddData(rowData);
}, },
error: function(jqXHR, textStatus, errorThrown) { url : "../service/maps/" + mapId
if (jqXHR.status == 400) {
var errors = JSON.parse(jqXHR.responseText);
// Clean previous marks ....
$('#new-dialog-modal input').each(function(index, elem) {
$(elem).removeClass("ui-state-error");
}); });
// Mark fields with errors ...
var fieldErrors = errors.fieldErrors;
if (fieldErrors) {
for (var fieldName in fieldErrors) {
// Mark the field ...
var message = fieldErrors[fieldName];
var inputField = $("#new-dialog-modal input[name='" + fieldName + "']");
$(inputField).addClass("ui-state-error");
$("#new-dialog-modal div[id='errorMessage']").text(message).addClass("ui-state-highlight");
}
}
} else {
alert("Unexpected error removing maps. Refresh before continue.");
}
} }
}); });
},
Cancel:function() {
$(this).dialog("close");
}
}
});
});
$("#buttons .importMap").button({
icons: { primary: "ui-icon-trash" }
});
$("#buttons .moreActions").button({
icons: { primary: "ui-icon-triangle-1-s" }
});
$("#buttons .delete").button({ $("#buttons .delete").button({
icons: { primary: "ui-icon-trash" } icons: { primary: "ui-icon-trash" }
@ -250,8 +259,16 @@
}); });
} }
}); });
})
; $("#buttons .importMap").button({
icons: { primary: "ui-icon-trash" }
});
$("#buttons .moreActions").button({
icons: { primary: "ui-icon-triangle-1-s" }
});
});
</script> </script>
</head> </head>
<body> <body>
@ -271,9 +288,37 @@
<div id="delete-dialog-modal" title="Delete maps" style="display: none"> <div id="delete-dialog-modal" title="Delete maps" style="display: none">
<p>Are you sure you want to delete maps <span></span> ?</p> <p>Are you sure you want to delete maps <span></span> ?</p>
</div> </div>
<!-- New map dialog -->
<div id="new-dialog-modal" title="Add new map" style="display: none"> <div id="new-dialog-modal" title="Add new map" style="display: none">
<div id="errorMessage"></div> <div id="errorMessage"></div>
<table>
<tr>
<td class="formLabel">
<span class="fieldRequired">*</span>
<label for="newTitle"><spring:message code="NAME"/>:</label>
</td>
<td>
<input name="title" id="newTitle" type="text" required="true"
placeholder="Name used to identify your map"/>
</td>
</tr>
<tr>
<td class="formLabel">
<label for="newDec"><spring:message code="DESCRIPTION"/>:</label>
</td>
<td>
<input name="description" id="newDec" type="text"
placeholder="Some description for your map"/>
</td>
</tr>
</table>
</div>
<!-- Duplicate map dialog -->
<div id="duplicate-dialog-modal" title="Copy Map" style="display: none">
<div id="duplicateMessage"></div>
<div id="errorMessage"></div>
<table> <table>
<tr> <tr>
<td class="formLabel"> <td class="formLabel">
@ -281,7 +326,7 @@
<label for="title"><spring:message code="NAME"/>:</label> <label for="title"><spring:message code="NAME"/>:</label>
</td> </td>
<td> <td>
<input name="title" id="title" tabindex="1" type="text" required="true"/> <input name="title" id="title" type="text" required="true"/>
</td> </td>
</tr> </tr>
<tr> <tr>
@ -289,29 +334,50 @@
<label for="description"><spring:message code="DESCRIPTION"/>:</label> <label for="description"><spring:message code="DESCRIPTION"/>:</label>
</td> </td>
<td> <td>
<input name="description" id="description" tabindex="2"/> <input name="description" id="description" type="text"
placeholder="Some description for your map"/>
</td> </td>
</tr> </tr>
</table> </table>
</div> </div>
<!-- Duplicate map dialog -->
<div id="rename-dialog-modal" title="Rename" style="display: none">
<div id="errorMessage"></div>
<table>
<tr>
<td class="formLabel">
<span class="fieldRequired">*</span>
<label for="renTitle"><spring:message code="NAME"/>:</label>
</td>
<td>
<input name="title" id="renTitle" required="true"/>
</td>
</tr>
<tr>
<td class="formLabel">
<label for="renDescription"><spring:message code="DESCRIPTION"/>:</label>
</td>
<td>
<input name="description" id="renDescription"/>
</td>
</tr>
</table>
</div>
<div id="share-dialog-modal" title="Share maps" style="display: none"> <div id="share-dialog-modal" title="Share maps" style="display: none">
<p>Are you sure you want to share maps <span></span> ?</p> <p>Are you sure you want to share maps <span></span> ?</p>
</div> </div>
<button class="newMap">New</button> <button class="newMap">New</button>
<button class="duplicateMap">Duplicate</button>
<button class="delete">Delete</button> <button class="delete">Delete</button>
<button class="renameMap">Rename</button>
<button class="importMap">Import</button> <button class="importMap">Import</button>
<button class="moreActions">More</button> <button class="moreActions">More</button>
</div> </div>
<div> <div>
<div id="tags">
<h2>Mes dossiers:</h2>
<div id="tags-list"></div>
<div id="tags-actions">
<button>Nouveau Dossier</button>
</div>
</div>
<div id="map-table"> <div id="map-table">
<table class="display" id="mindmapListTable"> <table class="display" id="mindmapListTable">