Fixed issue 15: Ability to rename projects - added rename command in both index.html and project.html (main menu bar)

Updated CHANGES.txt with other fixes committed previously.
Made sure releases.js doesn't hold up the initialization code of project.html.
Some polishing on the rendering of projects' last modified dates in index.html.

git-svn-id: http://google-refine.googlecode.com/svn/trunk@799 7d457c2a-affb-35e4-300a-418c747d4874
This commit is contained in:
David Huynh 2010-05-17 19:22:58 +00:00
parent 2cf360b723
commit 4cf476630e
9 changed files with 156 additions and 21 deletions

View File

@ -5,6 +5,9 @@ Fixes:
Regex was not compiled with case insensitivity flag. Regex was not compiled with case insensitivity flag.
- Issue 4: "Match All bug with ZIP code". Numeric values in cells were not stringified first - Issue 4: "Match All bug with ZIP code". Numeric values in cells were not stringified first
before comparison. before comparison.
- Issue 41: "Envelope quotation marks are removed by CSV importer"
- Issue 19: "CSV import is too basic"
- Issue 15: "Ability to rename projects"
1.0.1 Release (May 12, 2010) 1.0.1 Release (May 12, 2010)

View File

@ -57,6 +57,7 @@ import com.metaweb.gridworks.commands.project.ExportRowsCommand;
import com.metaweb.gridworks.commands.project.GetModelsCommand; import com.metaweb.gridworks.commands.project.GetModelsCommand;
import com.metaweb.gridworks.commands.project.GetProjectMetadataCommand; import com.metaweb.gridworks.commands.project.GetProjectMetadataCommand;
import com.metaweb.gridworks.commands.project.ImportProjectCommand; import com.metaweb.gridworks.commands.project.ImportProjectCommand;
import com.metaweb.gridworks.commands.project.RenameProjectCommand;
import com.metaweb.gridworks.commands.recon.ReconDiscardJudgmentsCommand; import com.metaweb.gridworks.commands.recon.ReconDiscardJudgmentsCommand;
import com.metaweb.gridworks.commands.recon.ReconJudgeOneCellCommand; import com.metaweb.gridworks.commands.recon.ReconJudgeOneCellCommand;
import com.metaweb.gridworks.commands.recon.ReconJudgeSimilarCellsCommand; import com.metaweb.gridworks.commands.recon.ReconJudgeSimilarCellsCommand;
@ -92,6 +93,7 @@ public class GridworksServlet extends HttpServlet {
_commands.put("get-all-project-metadata", new GetAllProjectMetadataCommand()); _commands.put("get-all-project-metadata", new GetAllProjectMetadataCommand());
_commands.put("delete-project", new DeleteProjectCommand()); _commands.put("delete-project", new DeleteProjectCommand());
_commands.put("rename-project", new RenameProjectCommand());
_commands.put("get-models", new GetModelsCommand()); _commands.put("get-models", new GetModelsCommand());
_commands.put("get-rows", new GetRowsCommand()); _commands.put("get-rows", new GetRowsCommand());

View File

@ -18,6 +18,7 @@ import org.slf4j.LoggerFactory;
import com.metaweb.gridworks.Jsonizable; import com.metaweb.gridworks.Jsonizable;
import com.metaweb.gridworks.ProjectManager; import com.metaweb.gridworks.ProjectManager;
import com.metaweb.gridworks.ProjectMetadata;
import com.metaweb.gridworks.browsing.Engine; import com.metaweb.gridworks.browsing.Engine;
import com.metaweb.gridworks.history.HistoryEntry; import com.metaweb.gridworks.history.HistoryEntry;
import com.metaweb.gridworks.model.Project; import com.metaweb.gridworks.model.Project;
@ -107,6 +108,27 @@ public abstract class Command {
throw new ServletException("Can't find project: missing or bad URL parameter"); throw new ServletException("Can't find project: missing or bad URL parameter");
} }
/**
* Utility method for retrieving the ProjectMetadata object having the ID specified
* in the "project" URL parameter.
*
* @param request
* @return
* @throws ServletException
*/
protected ProjectMetadata getProjectMetadata(HttpServletRequest request) throws ServletException {
if (request == null) throw new IllegalArgumentException("parameter 'request' should not be null");
try {
ProjectMetadata pm = ProjectManager.singleton.getProjectMetadata(Long.parseLong(request.getParameter("project")));
if (pm != null) {
return pm;
}
} catch (Exception e) {
// ignore
}
throw new ServletException("Can't find project metadata: missing or bad URL parameter");
}
static protected int getIntegerParameter(HttpServletRequest request, String name, int def) { static protected int getIntegerParameter(HttpServletRequest request, String name, int def) {
if (request == null) throw new IllegalArgumentException("parameter 'request' should not be null"); if (request == null) throw new IllegalArgumentException("parameter 'request' should not be null");
try { try {

View File

@ -0,0 +1,28 @@
package com.metaweb.gridworks.commands.project;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.metaweb.gridworks.ProjectMetadata;
import com.metaweb.gridworks.commands.Command;
public class RenameProjectCommand extends Command {
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
String name = request.getParameter("name");
ProjectMetadata pm = getProjectMetadata(request);
pm.setName(name);
respond(response, "{ \"code\" : \"ok\" }");
} catch (Exception e) {
respondException(response, e);
}
}
}

View File

@ -129,8 +129,5 @@
</tr> </tr>
</table></div> </table></div>
</div> </div>
<script type="text/javascript" src="http://freebase-gridworks.googlecode.com/svn/support/releases.js"></script>
</body> </body>
</html> </html>

View File

@ -34,10 +34,10 @@ function formatDate(d) {
var tomorrow = Date.today().add({ days: 1 }); var tomorrow = Date.today().add({ days: 1 });
if (d.between(today, tomorrow)) { if (d.between(today, tomorrow)) {
return "today"; return "today " + d.toString("h:mm tt");
} else if (d.between(last_week, today)) { } else if (d.between(last_week, today)) {
var diff = Math.floor(today.getDayOfYear() - d.getDayOfYear()); var diff = Math.floor(today.getDayOfYear() - d.getDayOfYear());
return (diff == 1) ? "yesterday" : diff + " days ago"; return (diff <= 1) ? ("yesterday " + d.toString("h:mm tt")) : (diff + " days ago");
} else if (d.between(last_month, today)) { } else if (d.between(last_month, today)) {
var diff = Math.floor((today.getDayOfYear() - d.getDayOfYear()) / 7); var diff = Math.floor((today.getDayOfYear() - d.getDayOfYear()) / 7);
return (diff == 1) ? "a week ago" : diff.toFixed(0) + " weeks ago" ; return (diff == 1) ? "a week ago" : diff.toFixed(0) + " weeks ago" ;
@ -100,6 +100,7 @@ function renderProjects(data) {
var table = $( var table = $(
'<table><tr>' + '<table><tr>' +
'<th>Name</th>' + '<th>Name</th>' +
'<th></th>' +
'<th align="right">Last Modified</th>' + '<th align="right">Last Modified</th>' +
'<th></th>' + '<th></th>' +
'</tr></table>' '</tr></table>'
@ -108,15 +109,46 @@ function renderProjects(data) {
var renderProject = function(project) { var renderProject = function(project) {
var tr = table.insertRow(table.rows.length); var tr = table.insertRow(table.rows.length);
tr.className = "project"; tr.className = "project";
$('<a></a>') var nameLink = $('<a></a>')
.text(project.name) .text(project.name)
.attr("href", "/project.html?project=" + project.id) .attr("href", "/project.html?project=" + project.id)
.appendTo(tr.insertCell(tr.cells.length)); .appendTo(tr.insertCell(tr.cells.length));
var renameLink = $('<a></a>')
.text("rename")
.attr("href", "javascript:{}")
.css("visibility", "hidden")
.click(function() {
var name = window.prompt("Rename Project", project.name);
if (name == null) {
return;
}
name = $.trim(name);
if (project.name == name || name.length == 0) {
return;
}
$.ajax({
type: "POST",
url: "/command/rename-project",
data: { "project" : project.id, "name" : name },
dataType: "json",
success: function (data) {
if (data && typeof data.code != 'undefined' && data.code == "ok") {
nameLink.text(name);
} else {
alert("Failed to rename project: " + data.message)
}
}
});
}).appendTo(tr.insertCell(tr.cells.length));
$('<div></div>') $('<div></div>')
.html(formatDate(project.date)) .html(formatDate(project.date))
.addClass("last-modified") .addClass("last-modified")
.attr("title", project.date.toString())
.appendTo(tr.insertCell(tr.cells.length)); .appendTo(tr.insertCell(tr.cells.length));
$('<a></a>') $('<a></a>')
@ -141,6 +173,11 @@ function renderProjects(data) {
return false; return false;
}).appendTo(tr.insertCell(tr.cells.length)); }).appendTo(tr.insertCell(tr.cells.length));
$(tr).mouseenter(function() {
renameLink.css("visibility", "visible");
}).mouseleave(function() {
renameLink.css("visibility", "hidden");
});
}; };
for (var i = 0; i < projects.length; i++) { for (var i = 0; i < projects.length; i++) {
@ -166,11 +203,24 @@ function onLoad() {
$("#gridworks-version").text( $("#gridworks-version").text(
"Version " + GridworksVersion.version + "-" + GridworksVersion.revision "Version " + GridworksVersion.version + "-" + GridworksVersion.revision
); );
if (isThereNewRelease()) {
$('<div id="version-message">' + var script = $('<script></script>')
'New version "' + GridworksReleases.releases[0].description + '" <a href="' + GridworksReleases.homepage + '">available for download here</a>.' + .attr("src", "http://freebase-gridworks.googlecode.com/svn/support/releases.js")
'</div>').appendTo(document.body); .attr("type", "text/javascript")
} .appendTo(document.body);
var poll = function() {
if ("GridworksReleases" in window) {
if (isThereNewRelease()) {
$('<div id="version-message">' +
'New version "' + GridworksReleases.releases[0].description + '" <a href="' + GridworksReleases.homepage + '">available for download here</a>.' +
'</div>').appendTo(document.body);
}
} else {
window.setTimeout(poll, 1000);
}
};
window.setTimeout(poll, 1000);
} }
$(onLoad); $(onLoad);

View File

@ -67,19 +67,15 @@ function resizeAll() {
} }
function initializeUI(uiState) { function initializeUI(uiState) {
Gridworks.setTitle();
var path = $("#path"); var path = $("#path");
$('<span class="app-path-section" id="project-name-in-path"></span>').appendTo(path);
$('<span class="app-path-section">' +
'project: <a href="#">' + theProject.metadata.name + '</a>' +
'</span>').appendTo(path);
$('<a href="javascript:{}" class="permalink">permalink</a>') $('<a href="javascript:{}" class="permalink">permalink</a>')
.mouseenter(function() { .mouseenter(function() {
this.href = Gridworks.getPermanentLink(); this.href = Gridworks.getPermanentLink();
}).appendTo(path); }).appendTo(path);
Gridworks.setTitle();
var body = $("#body").empty().html( var body = $("#body").empty().html(
'<div bind="viewPanel" class="view-panel"></div>' + '<div bind="viewPanel" class="view-panel"></div>' +
'<div bind="processPanel" class="process-panel"></div>' + '<div bind="processPanel" class="process-panel"></div>' +
@ -130,6 +126,11 @@ Gridworks.setTitle = function(status) {
title = status + " - " + title; title = status + " - " + title;
} }
document.title = title; document.title = title;
var name = $("#project-name-in-path");
name.empty();
name.text('project: ');
$('<a href="#">' + theProject.metadata.name + '</a>').appendTo(name);
}; };
Gridworks.reinitializeProjectData = function(f) { Gridworks.reinitializeProjectData = function(f) {

View File

@ -28,6 +28,11 @@ MenuBar.prototype._initializeUI = function() {
}, },
{}, {},
*/ */
{
"label": "Rename...",
"click": function() { self._renameProject(); }
},
{},
{ {
"label": "Export Filtered Rows", "label": "Export Filtered Rows",
"submenu": [ "submenu": [
@ -231,6 +236,33 @@ MenuBar.prototype._exportProject = function() {
document.body.removeChild(form); document.body.removeChild(form);
}; };
MenuBar.prototype._renameProject = function() {
var name = window.prompt("Rename Project", theProject.metadata.name);
if (name == null) {
return;
}
name = $.trim(name);
if (theProject.metadata.name == name || name.length == 0) {
return;
}
$.ajax({
type: "POST",
url: "/command/rename-project",
data: { "project" : theProject.id, "name" : name },
dataType: "json",
success: function (data) {
if (data && typeof data.code != 'undefined' && data.code == "ok") {
theProject.metadata.name = name;
Gridworks.setTitle();
} else {
alert("Failed to rename project: " + data.message);
}
}
});
};
MenuBar.prototype._doAutoSchemaAlignment = function() { MenuBar.prototype._doAutoSchemaAlignment = function() {
//SchemaAlignment.autoAlign(); //SchemaAlignment.autoAlign();
}; };

View File

@ -43,8 +43,8 @@ div.round-corners {
} }
#projects-panel { #projects-panel {
width: 270px; width: 320px;
min-width: 270px !important; min-width: 320px !important;
} }
#projects { #projects {
background: white; background: white;