More scaffolding.
git-svn-id: http://google-refine.googlecode.com/svn/trunk@4 7d457c2a-affb-35e4-300a-418c747d4874
This commit is contained in:
parent
e1fa9279eb
commit
9f436ad717
@ -17,6 +17,7 @@ import org.json.JSONTokener;
|
|||||||
import com.metaweb.gridlock.commands.Command;
|
import com.metaweb.gridlock.commands.Command;
|
||||||
import com.metaweb.gridlock.commands.CreateProjectFromUploadCommand;
|
import com.metaweb.gridlock.commands.CreateProjectFromUploadCommand;
|
||||||
import com.metaweb.gridlock.commands.GetColumnModelCommand;
|
import com.metaweb.gridlock.commands.GetColumnModelCommand;
|
||||||
|
import com.metaweb.gridlock.commands.GetProjectMetadataCommand;
|
||||||
import com.metaweb.gridlock.commands.GetRowsCommand;
|
import com.metaweb.gridlock.commands.GetRowsCommand;
|
||||||
|
|
||||||
public class GridlockServlet extends HttpServlet {
|
public class GridlockServlet extends HttpServlet {
|
||||||
@ -26,6 +27,7 @@ public class GridlockServlet extends HttpServlet {
|
|||||||
|
|
||||||
static {
|
static {
|
||||||
_commands.put("create-project-from-upload", new CreateProjectFromUploadCommand());
|
_commands.put("create-project-from-upload", new CreateProjectFromUploadCommand());
|
||||||
|
_commands.put("get-project-metadata", new GetProjectMetadataCommand());
|
||||||
_commands.put("get-column-model", new GetColumnModelCommand());
|
_commands.put("get-column-model", new GetColumnModelCommand());
|
||||||
_commands.put("get-rows", new GetRowsCommand());
|
_commands.put("get-rows", new GetRowsCommand());
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ public class ProjectManager implements Serializable {
|
|||||||
private static final long serialVersionUID = -2967415873336723962L;
|
private static final long serialVersionUID = -2967415873336723962L;
|
||||||
|
|
||||||
protected File _dir;
|
protected File _dir;
|
||||||
protected Map<Long, ProjectMetadata> _projectsMetadata = new HashMap<Long, ProjectMetadata>();
|
protected Map<Long, ProjectMetadata> _projectsMetadata;
|
||||||
|
|
||||||
transient protected Map<Long, Project> _projects;
|
transient protected Map<Long, Project> _projects;
|
||||||
|
|
||||||
@ -67,6 +67,9 @@ public class ProjectManager implements Serializable {
|
|||||||
private ProjectManager(File dir) {
|
private ProjectManager(File dir) {
|
||||||
_dir = dir;
|
_dir = dir;
|
||||||
_dir.mkdirs();
|
_dir.mkdirs();
|
||||||
|
|
||||||
|
_projectsMetadata = new HashMap<Long, ProjectMetadata>();
|
||||||
|
|
||||||
internalInitialize();
|
internalInitialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,6 +91,10 @@ public class ProjectManager implements Serializable {
|
|||||||
return project;
|
return project;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ProjectMetadata getProjectMetadata(long id) {
|
||||||
|
return _projectsMetadata.get(id);
|
||||||
|
}
|
||||||
|
|
||||||
public Project getProject(long id) {
|
public Project getProject(long id) {
|
||||||
if (_projects.containsKey(id)) {
|
if (_projects.containsKey(id)) {
|
||||||
return _projects.get(id);
|
return _projects.get(id);
|
||||||
|
@ -2,9 +2,20 @@ package com.metaweb.gridlock;
|
|||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
public class ProjectMetadata implements Serializable {
|
public class ProjectMetadata implements Serializable {
|
||||||
private static final long serialVersionUID = 7959027046468240844L;
|
private static final long serialVersionUID = 7959027046468240844L;
|
||||||
|
|
||||||
public String name;
|
public String name;
|
||||||
public String password;
|
public String password;
|
||||||
|
|
||||||
|
public JSONObject getJSON() throws JSONException {
|
||||||
|
JSONObject o = new JSONObject();
|
||||||
|
|
||||||
|
o.put("name", name);
|
||||||
|
|
||||||
|
return o;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,8 +23,8 @@ public class CreateProjectFromUploadCommand extends Command {
|
|||||||
String content = readFileUpload(request, properties);
|
String content = readFileUpload(request, properties);
|
||||||
|
|
||||||
ProjectMetadata pm = new ProjectMetadata();
|
ProjectMetadata pm = new ProjectMetadata();
|
||||||
pm.name = properties.getProperty("name");
|
pm.name = properties.getProperty("project-name");
|
||||||
pm.password = properties.getProperty("password");
|
pm.password = properties.getProperty("project-password");
|
||||||
|
|
||||||
Project project = ProjectManager.singleton.createProject(pm);
|
Project project = ProjectManager.singleton.createProject(pm);
|
||||||
|
|
||||||
@ -49,14 +49,14 @@ public class CreateProjectFromUploadCommand extends Command {
|
|||||||
if (tab >= 0) {
|
if (tab >= 0) {
|
||||||
sep = "\t";
|
sep = "\t";
|
||||||
} else {
|
} else {
|
||||||
sep = "\\,";
|
sep = ",";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] cells = line.split(sep);
|
|
||||||
if (first) {
|
if (first) {
|
||||||
first = false;
|
String[] cells = line.split(sep);
|
||||||
|
|
||||||
|
first = false;
|
||||||
for (int c = 0; c < cells.length; c++) {
|
for (int c = 0; c < cells.length; c++) {
|
||||||
String cell = cells[c];
|
String cell = cells[c];
|
||||||
if (cell.startsWith("\"") && cell.endsWith("\"")) {
|
if (cell.startsWith("\"") && cell.endsWith("\"")) {
|
||||||
@ -74,13 +74,10 @@ public class CreateProjectFromUploadCommand extends Command {
|
|||||||
} else {
|
} else {
|
||||||
Row row = new Row(cellCount);
|
Row row = new Row(cellCount);
|
||||||
|
|
||||||
for (int c = 0; c < cells.length; c++) {
|
if (sep.charAt(0) == ',') {
|
||||||
String text = cells[c];
|
parseCSVIntoRow(row, line);
|
||||||
|
} else {
|
||||||
Cell cell = new Cell();
|
parseTSVIntoRow(row, line);
|
||||||
cell.value = parseCellValue(text);
|
|
||||||
|
|
||||||
row.cells.add(cell);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
project.rows.add(row);
|
project.rows.add(row);
|
||||||
@ -90,21 +87,66 @@ public class CreateProjectFromUploadCommand extends Command {
|
|||||||
redirect(response, "/project.html?project=" + project.id);
|
redirect(response, "/project.html?project=" + project.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
static public Object parseCellValue(String text) {
|
static protected void parseTSVIntoRow(Row row, String line) {
|
||||||
if (text.startsWith("\"") && text.endsWith("\"")) {
|
String[] cells = line.split("\t");
|
||||||
return text.substring(1, text.length() - 1);
|
for (int c = 0; c < cells.length; c++) {
|
||||||
}
|
String text = cells[c];
|
||||||
|
|
||||||
try {
|
Cell cell = new Cell();
|
||||||
return Long.parseLong(text);
|
cell.value = parseCellValue(text);
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
|
row.cells.add(cell);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
static protected void parseCSVIntoRow(Row row, String line) {
|
||||||
return Double.parseDouble(text);
|
int start = 0;
|
||||||
} catch (NumberFormatException e) {
|
while (start < line.length()) {
|
||||||
|
String text = null;
|
||||||
|
|
||||||
|
if (line.charAt(start) == '"') {
|
||||||
|
int next = line.indexOf('"', start + 1);
|
||||||
|
if (next < 0) {
|
||||||
|
text = line.substring(start);
|
||||||
|
start = line.length();
|
||||||
|
} else {
|
||||||
|
text = line.substring(start, next + 1);
|
||||||
|
start = next + 2;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int next = line.indexOf(',', start);
|
||||||
|
if (next < 0) {
|
||||||
|
text = line.substring(start);
|
||||||
|
start = line.length();
|
||||||
|
} else {
|
||||||
|
text = line.substring(start, next);
|
||||||
|
start = next + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Cell cell = new Cell();
|
||||||
|
cell.value = parseCellValue(text);
|
||||||
|
|
||||||
|
row.cells.add(cell);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static public Object parseCellValue(String text) {
|
||||||
|
if (text.length() > 0) {
|
||||||
|
if (text.length() > 1 && text.startsWith("\"") && text.endsWith("\"")) {
|
||||||
|
return text.substring(1, text.length() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return Long.parseLong(text);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return Double.parseDouble(text);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
package com.metaweb.gridlock.commands;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
|
||||||
|
import com.metaweb.gridlock.ProjectManager;
|
||||||
|
import com.metaweb.gridlock.model.Project;
|
||||||
|
|
||||||
|
public class GetProjectMetadataCommand extends Command {
|
||||||
|
@Override
|
||||||
|
public void doGet(HttpServletRequest request, HttpServletResponse response)
|
||||||
|
throws ServletException, IOException {
|
||||||
|
|
||||||
|
Project project = getProject(request);
|
||||||
|
|
||||||
|
try {
|
||||||
|
respondJSON(response, ProjectManager.singleton.getProjectMetadata(project.id).getJSON());
|
||||||
|
} catch (JSONException e) {
|
||||||
|
respondException(response, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -40,6 +40,7 @@ public class GetRowsCommand extends Command {
|
|||||||
o.put("start", start);
|
o.put("start", start);
|
||||||
o.put("limit", limit);
|
o.put("limit", limit);
|
||||||
o.put("rows", a);
|
o.put("rows", a);
|
||||||
|
o.put("total", project.rows.size());
|
||||||
|
|
||||||
respondJSON(response, o);
|
respondJSON(response, o);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
|
@ -1 +1 @@
|
|||||||
<html>
<head>
<title>Gridlock</title>
<link rel="stylesheet" href="/styles/common.css" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript" src="scripts/util/string.js"></script>
<script type="text/javascript" src="scripts/index.js"></script>
</head>
<body>
<div id="header">
<h1>Gridlock</h1>
</div>
<div id="body">
<h2>New Project</h2>
<p>Create a new project by uploading a tab-separated value or comma-separated value file.</p>
<form id="file-upload-form" method="post" enctype="multipart/form-data" action="/command/create-project-from-upload">
<table cellspacing="10">
<tr><td>Project Name:</td><td><input type="text" size="30" id="project-name-input" name="project-name" /></td></tr>
<tr><td>Project Password:</td><td><input type="password" size="30" id="project-password-input" name="project-password" /><br/>optional, not protected, so use some password you don't care to reveal</td></tr>
<tr><td>Upload File:</td><td>
<input type="file" id="project-file-input" name="project-file" size="50" />
</td></tr>
<tr><td></td><td>
<input type="submit" value="Create Project" id="upload-file-button" />
</td></tr>
</table>
</form>
</div>
</body>
</html>
|
<html>
<head>
<title>Gridlock</title>
<link rel="stylesheet" href="/styles/common.css" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
<script type="text/javascript" src="scripts/util/string.js"></script>
<script type="text/javascript" src="scripts/index.js"></script>
</head>
<body>
<div id="header">
<h1>Gridlock</h1>
</div>
<div id="body">
<h2>New Project</h2>
<p>Create a new project by uploading a tab-separated value or comma-separated value file.</p>
<form id="file-upload-form" method="post" enctype="multipart/form-data" action="/command/create-project-from-upload">
<table cellspacing="10">
<tr><td>Project Name:</td><td><input type="text" size="30" id="project-name-input" name="project-name" /></td></tr>
<tr><td>Project Password:</td><td><input type="password" size="30" id="project-password-input" name="project-password" /><br/>optional, not protected, so use some password you don't care to reveal</td></tr>
<tr><td>Upload File:</td><td>
<input type="file" id="project-file-input" name="project-file" size="50" />
</td></tr>
<tr><td></td><td>
<input type="submit" value="Create Project" id="upload-file-button" />
</td></tr>
</table>
</form>
</div>
</body>
</html>
|
@ -1 +1 @@
|
|||||||
<html>
<head>
<title>Gridlock</title>
<link rel="stylesheet" href="/styles/common.css" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript" src="scripts/util/string.js"></script>
<script type="text/javascript" src="scripts/project.js"></script>
</head>
<body>
<div id="header">
<h1 id="title">Gridlock</h1>
</div>
<div id="body">
Loading ...
</div>
</body>
</html>
|
<html>
<head>
<title>Gridlock</title>
<link rel="stylesheet" href="/styles/common.css" />
<link rel="stylesheet" href="/styles/project.css" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
<script type="text/javascript" src="scripts/util/url.js"></script>
<script type="text/javascript" src="scripts/util/string.js"></script>
<script type="text/javascript" src="scripts/util/ajax.js"></script>
<script type="text/javascript" src="scripts/project.js"></script>
</head>
<body>
<div id="header">
<h1 id="title">Gridlock</h1>
</div>
<div id="body">
Loading ...
</div>
</body>
</html>
|
@ -1,4 +1,153 @@
|
|||||||
|
var theProject;
|
||||||
|
var ui = {};
|
||||||
|
|
||||||
function onLoad() {
|
function onLoad() {
|
||||||
|
var params = URL.getParameters();
|
||||||
|
if ("project" in params) {
|
||||||
|
theProject = {
|
||||||
|
id: parseInt(params.project),
|
||||||
|
view: {
|
||||||
|
pageSize: 25
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Ajax.chainGetJSON(
|
||||||
|
"/command/get-project-metadata?" + $.param({ project: theProject.id }), null,
|
||||||
|
function(data) {
|
||||||
|
theProject.metadata = data;
|
||||||
|
},
|
||||||
|
"/command/get-column-model?" + $.param({ project: theProject.id }), null,
|
||||||
|
function(data) {
|
||||||
|
theProject.columnModel = data;
|
||||||
|
},
|
||||||
|
"/command/get-rows?" + $.param({ project: theProject.id, start: 0, limit: 25 }), null,
|
||||||
|
function(data) {
|
||||||
|
theProject.rowModel = data;
|
||||||
|
},
|
||||||
|
function() {
|
||||||
|
initializeUI();
|
||||||
|
renderView();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$(onLoad);
|
$(onLoad);
|
||||||
|
|
||||||
|
function initializeUI() {
|
||||||
|
document.title = theProject.metadata.name + " - Gridlock";
|
||||||
|
$("#title").html(document.title);
|
||||||
|
|
||||||
|
var body = $("#body").empty();
|
||||||
|
|
||||||
|
var table = document.createElement("table");
|
||||||
|
$(table).attr("cellspacing", 20).css("width", "100%");
|
||||||
|
body.append(table);
|
||||||
|
|
||||||
|
var tr = table.insertRow(0);
|
||||||
|
|
||||||
|
var tdLeft = tr.insertCell(0);
|
||||||
|
var tdRight = tr.insertCell(1);
|
||||||
|
tdLeft.setAttribute("width", "75%");
|
||||||
|
tdRight.setAttribute("width", "25%");
|
||||||
|
|
||||||
|
ui.viewPanel = $('<div></div>').appendTo(tdLeft).css("width", tdLeft.offsetWidth + "px").css("overflow-x", "auto");
|
||||||
|
ui.facetPanel = $('<div></div>').appendTo(tdRight);
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderView() {
|
||||||
|
ui.viewPanel.empty();
|
||||||
|
|
||||||
|
var divSummary = $('<div></div>').addClass("viewPanel-summary").appendTo(ui.viewPanel);
|
||||||
|
$('<span>' +
|
||||||
|
(theProject.rowModel.start + 1) + " to " +
|
||||||
|
(theProject.rowModel.start + theProject.rowModel.limit) + " of " +
|
||||||
|
(theProject.rowModel.total) +
|
||||||
|
" rows total" +
|
||||||
|
'</span>'
|
||||||
|
).appendTo(divSummary);
|
||||||
|
|
||||||
|
var pagingControls = $('<div></div>').addClass("viewPanel-pagingControls").appendTo(ui.viewPanel);
|
||||||
|
var firstPage = $('<a href="javascript:{}">« first</a>').appendTo(pagingControls);
|
||||||
|
var previousPage = $('<a href="javascript:{}">« previous</a>').appendTo(pagingControls);
|
||||||
|
if (theProject.rowModel.start > 0) {
|
||||||
|
firstPage.addClass("action").click(onClickFirstPage);
|
||||||
|
previousPage.addClass("action").click(onClickPreviousPage);
|
||||||
|
} else {
|
||||||
|
firstPage.addClass("inaction");
|
||||||
|
previousPage.addClass("inaction");
|
||||||
|
}
|
||||||
|
$('<span> • </span>').appendTo(pagingControls);
|
||||||
|
var nextPage = $('<a href="javascript:{}">next page »</a>').appendTo(pagingControls);
|
||||||
|
var lastPage = $('<a href="javascript:{}">last »</a>').appendTo(pagingControls);
|
||||||
|
if (theProject.rowModel.start + theProject.rowModel.limit < theProject.rowModel.total) {
|
||||||
|
nextPage.addClass("action").click(onClickNextPage);
|
||||||
|
lastPage.addClass("action").click(onClickLastPage);
|
||||||
|
} else {
|
||||||
|
nextPage.addClass("inaction");
|
||||||
|
lastPage.addClass("inaction");
|
||||||
|
}
|
||||||
|
|
||||||
|
var table = document.createElement("table");
|
||||||
|
table.className = "data-table";
|
||||||
|
ui.viewPanel.append(table);
|
||||||
|
|
||||||
|
var trHead = table.insertRow(0);
|
||||||
|
var td = trHead.insertCell(trHead.cells.length);
|
||||||
|
|
||||||
|
var columns = theProject.columnModel.columns;
|
||||||
|
for (var i = 0; i < columns.length; i++) {
|
||||||
|
var column = columns[i];
|
||||||
|
var td = trHead.insertCell(trHead.cells.length);
|
||||||
|
$(td).html(column.headerLabel);
|
||||||
|
}
|
||||||
|
|
||||||
|
var rows = theProject.rowModel.rows;
|
||||||
|
for (var r = 0; r < rows.length; r++) {
|
||||||
|
var row = rows[r];
|
||||||
|
var cells = row.cells;
|
||||||
|
|
||||||
|
var tr = table.insertRow(table.rows.length);
|
||||||
|
tr.className = (r % 2) == 1 ? "odd" : "even";
|
||||||
|
|
||||||
|
var td = tr.insertCell(tr.cells.length);
|
||||||
|
$(td).html((theProject.rowModel.start + r + 1) + ".");
|
||||||
|
|
||||||
|
for (var i = 0; i < columns.length; i++) {
|
||||||
|
var column = columns[i];
|
||||||
|
var td = tr.insertCell(tr.cells.length);
|
||||||
|
|
||||||
|
if (column.cellIndex < cells.length) {
|
||||||
|
var cell = cells[column.cellIndex];
|
||||||
|
if (cell.v != null) {
|
||||||
|
$(td).html(cell.v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function showRows(start, onDone) {
|
||||||
|
Ajax.chainGetJSON(
|
||||||
|
"/command/get-rows?" + $.param({ project: theProject.id, start: start, limit: theProject.view.pageSize }), null,
|
||||||
|
function(data) {
|
||||||
|
theProject.rowModel = data;
|
||||||
|
renderView();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onClickPreviousPage() {
|
||||||
|
showRows(theProject.rowModel.start - theProject.view.pageSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onClickNextPage() {
|
||||||
|
showRows(theProject.rowModel.start + theProject.view.pageSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onClickFirstPage() {
|
||||||
|
showRows(0, theProject.view.pageSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onClickLastPage() {
|
||||||
|
showRows(Math.floor(theProject.rowModel.total / theProject.view.pageSize) * theProject.view.pageSize);
|
||||||
|
}
|
||||||
|
22
src/main/webapp/scripts/util/ajax.js
Normal file
22
src/main/webapp/scripts/util/ajax.js
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
Ajax = {};
|
||||||
|
|
||||||
|
Ajax.chainGetJSON = function() {
|
||||||
|
var a = arguments;
|
||||||
|
var i = 0;
|
||||||
|
var next = function() {
|
||||||
|
if (i <= a.length - 3) {
|
||||||
|
var url = a[i++];
|
||||||
|
var data = a[i++];
|
||||||
|
var callback = a[i++];
|
||||||
|
|
||||||
|
$.getJSON(url, data, function(o) {
|
||||||
|
callback(o);
|
||||||
|
next();
|
||||||
|
}, "json");
|
||||||
|
} else if (i < a.length) {
|
||||||
|
var finalCallback = a[i++];
|
||||||
|
finalCallback();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
next();
|
||||||
|
};
|
16
src/main/webapp/scripts/util/url.js
Normal file
16
src/main/webapp/scripts/util/url.js
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
URL = {};
|
||||||
|
|
||||||
|
URL.getParameters = function() {
|
||||||
|
var r = {};
|
||||||
|
|
||||||
|
var params = window.location.search;
|
||||||
|
if (params.length > 1) {
|
||||||
|
params = params.substr(1).split("&");
|
||||||
|
$.each(params, function() {
|
||||||
|
pair = this.split("=");
|
||||||
|
r[pair[0]] = unescape(pair[1]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
};
|
@ -30,3 +30,17 @@ tr, td {
|
|||||||
padding: 20px;
|
padding: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a.action {
|
||||||
|
margin: 0 3px;
|
||||||
|
text-decoration: none;
|
||||||
|
color: #448;
|
||||||
|
}
|
||||||
|
a.action:hover {
|
||||||
|
color: #88f;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.inaction {
|
||||||
|
margin: 0 3px;
|
||||||
|
text-decoration: none;
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
|
17
src/main/webapp/styles/project.css
Normal file
17
src/main/webapp/styles/project.css
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
table.data-table td {
|
||||||
|
padding: 2px 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.data-table tr.odd {
|
||||||
|
}
|
||||||
|
|
||||||
|
table.data-table tr.even {
|
||||||
|
background: #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.viewPanel-summary {
|
||||||
|
}
|
||||||
|
.viewPanel-pagingControls {
|
||||||
|
text-align: center;
|
||||||
|
margin: 1em 0;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user