diff --git a/CHANGES.txt b/CHANGES.txt index c5add9122..4a0118003 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -5,6 +5,9 @@ Fixes: Regex was not compiled with case insensitivity flag. - Issue 4: "Match All bug with ZIP code". Numeric values in cells were not stringified first 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) diff --git a/src/main/java/com/metaweb/gridworks/GridworksServlet.java b/src/main/java/com/metaweb/gridworks/GridworksServlet.java index b4880b3d8..cae8882f8 100644 --- a/src/main/java/com/metaweb/gridworks/GridworksServlet.java +++ b/src/main/java/com/metaweb/gridworks/GridworksServlet.java @@ -57,6 +57,7 @@ import com.metaweb.gridworks.commands.project.ExportRowsCommand; import com.metaweb.gridworks.commands.project.GetModelsCommand; import com.metaweb.gridworks.commands.project.GetProjectMetadataCommand; 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.ReconJudgeOneCellCommand; 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("delete-project", new DeleteProjectCommand()); + _commands.put("rename-project", new RenameProjectCommand()); _commands.put("get-models", new GetModelsCommand()); _commands.put("get-rows", new GetRowsCommand()); diff --git a/src/main/java/com/metaweb/gridworks/commands/Command.java b/src/main/java/com/metaweb/gridworks/commands/Command.java index b9f9b6fd2..349eea62c 100644 --- a/src/main/java/com/metaweb/gridworks/commands/Command.java +++ b/src/main/java/com/metaweb/gridworks/commands/Command.java @@ -18,6 +18,7 @@ import org.slf4j.LoggerFactory; import com.metaweb.gridworks.Jsonizable; import com.metaweb.gridworks.ProjectManager; +import com.metaweb.gridworks.ProjectMetadata; import com.metaweb.gridworks.browsing.Engine; import com.metaweb.gridworks.history.HistoryEntry; 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"); } + /** + * 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) { if (request == null) throw new IllegalArgumentException("parameter 'request' should not be null"); try { diff --git a/src/main/java/com/metaweb/gridworks/commands/project/RenameProjectCommand.java b/src/main/java/com/metaweb/gridworks/commands/project/RenameProjectCommand.java new file mode 100644 index 000000000..eaedbb492 --- /dev/null +++ b/src/main/java/com/metaweb/gridworks/commands/project/RenameProjectCommand.java @@ -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); + } + } +} diff --git a/src/main/webapp/index.html b/src/main/webapp/index.html index 4dc7133ec..6b85f4950 100644 --- a/src/main/webapp/index.html +++ b/src/main/webapp/index.html @@ -129,8 +129,5 @@ - - - diff --git a/src/main/webapp/scripts/index.js b/src/main/webapp/scripts/index.js index b627e58c3..a67a4c1e4 100644 --- a/src/main/webapp/scripts/index.js +++ b/src/main/webapp/scripts/index.js @@ -34,10 +34,10 @@ function formatDate(d) { var tomorrow = Date.today().add({ days: 1 }); if (d.between(today, tomorrow)) { - return "today"; + return "today " + d.toString("h:mm tt"); } else if (d.between(last_week, today)) { 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)) { var diff = Math.floor((today.getDayOfYear() - d.getDayOfYear()) / 7); return (diff == 1) ? "a week ago" : diff.toFixed(0) + " weeks ago" ; @@ -100,6 +100,7 @@ function renderProjects(data) { var table = $( '' + '' + + '' + '' + '' + '
NameLast Modified
' @@ -108,15 +109,46 @@ function renderProjects(data) { var renderProject = function(project) { var tr = table.insertRow(table.rows.length); tr.className = "project"; - - $('') + + var nameLink = $('') .text(project.name) .attr("href", "/project.html?project=" + project.id) .appendTo(tr.insertCell(tr.cells.length)); + var renameLink = $('') + .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)); + $('
') .html(formatDate(project.date)) .addClass("last-modified") + .attr("title", project.date.toString()) .appendTo(tr.insertCell(tr.cells.length)); $('') @@ -141,6 +173,11 @@ function renderProjects(data) { return false; }).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++) { @@ -166,11 +203,24 @@ function onLoad() { $("#gridworks-version").text( "Version " + GridworksVersion.version + "-" + GridworksVersion.revision ); - if (isThereNewRelease()) { - $('
' + - 'New version "' + GridworksReleases.releases[0].description + '" available for download here.' + - '
').appendTo(document.body); - } + + var script = $('') + .attr("src", "http://freebase-gridworks.googlecode.com/svn/support/releases.js") + .attr("type", "text/javascript") + .appendTo(document.body); + + var poll = function() { + if ("GridworksReleases" in window) { + if (isThereNewRelease()) { + $('
' + + 'New version "' + GridworksReleases.releases[0].description + '" available for download here.' + + '
').appendTo(document.body); + } + } else { + window.setTimeout(poll, 1000); + } + }; + window.setTimeout(poll, 1000); } $(onLoad); diff --git a/src/main/webapp/scripts/project.js b/src/main/webapp/scripts/project.js index 15ec85bd5..66780562b 100644 --- a/src/main/webapp/scripts/project.js +++ b/src/main/webapp/scripts/project.js @@ -67,19 +67,15 @@ function resizeAll() { } function initializeUI(uiState) { - Gridworks.setTitle(); - var path = $("#path"); - - $('' + - 'project: ' + theProject.metadata.name + '' + - '').appendTo(path); - + $('').appendTo(path); $('') .mouseenter(function() { this.href = Gridworks.getPermanentLink(); }).appendTo(path); + Gridworks.setTitle(); + var body = $("#body").empty().html( '
' + '
' + @@ -130,6 +126,11 @@ Gridworks.setTitle = function(status) { title = status + " - " + title; } document.title = title; + + var name = $("#project-name-in-path"); + name.empty(); + name.text('project: '); + $('' + theProject.metadata.name + '').appendTo(name); }; Gridworks.reinitializeProjectData = function(f) { diff --git a/src/main/webapp/scripts/project/menu-bar.js b/src/main/webapp/scripts/project/menu-bar.js index f92cd358f..7b1f48200 100644 --- a/src/main/webapp/scripts/project/menu-bar.js +++ b/src/main/webapp/scripts/project/menu-bar.js @@ -28,6 +28,11 @@ MenuBar.prototype._initializeUI = function() { }, {}, */ + { + "label": "Rename...", + "click": function() { self._renameProject(); } + }, + {}, { "label": "Export Filtered Rows", "submenu": [ @@ -231,6 +236,33 @@ MenuBar.prototype._exportProject = function() { 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() { //SchemaAlignment.autoAlign(); }; diff --git a/src/main/webapp/styles/index.css b/src/main/webapp/styles/index.css index c30b9ef20..0af2709c7 100644 --- a/src/main/webapp/styles/index.css +++ b/src/main/webapp/styles/index.css @@ -43,8 +43,8 @@ div.round-corners { } #projects-panel { - width: 270px; - min-width: 270px !important; + width: 320px; + min-width: 320px !important; } #projects { background: white;