Added dialog system.
Started to implement recon dialog. Added long-running recon process, which doesn't actually do reconciliation just yet. git-svn-id: http://google-refine.googlecode.com/svn/trunk@17 7d457c2a-affb-35e4-300a-418c747d4874
This commit is contained in:
parent
06b5373151
commit
17cbe6b62d
@ -23,6 +23,7 @@ import com.metaweb.gridlock.commands.GetHistoryCommand;
|
|||||||
import com.metaweb.gridlock.commands.GetProcessesCommand;
|
import com.metaweb.gridlock.commands.GetProcessesCommand;
|
||||||
import com.metaweb.gridlock.commands.GetProjectMetadataCommand;
|
import com.metaweb.gridlock.commands.GetProjectMetadataCommand;
|
||||||
import com.metaweb.gridlock.commands.GetRowsCommand;
|
import com.metaweb.gridlock.commands.GetRowsCommand;
|
||||||
|
import com.metaweb.gridlock.commands.ReconcileCommand;
|
||||||
import com.metaweb.gridlock.commands.UndoRedoCommand;
|
import com.metaweb.gridlock.commands.UndoRedoCommand;
|
||||||
|
|
||||||
public class GridlockServlet extends HttpServlet {
|
public class GridlockServlet extends HttpServlet {
|
||||||
@ -42,6 +43,7 @@ public class GridlockServlet extends HttpServlet {
|
|||||||
_commands.put("undo-redo", new UndoRedoCommand());
|
_commands.put("undo-redo", new UndoRedoCommand());
|
||||||
_commands.put("compute-facets", new ComputeFacetsCommand());
|
_commands.put("compute-facets", new ComputeFacetsCommand());
|
||||||
_commands.put("do-text-transform", new DoTextTransformCommand());
|
_commands.put("do-text-transform", new DoTextTransformCommand());
|
||||||
|
_commands.put("reconcile", new ReconcileCommand());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -10,6 +10,9 @@ import javax.servlet.http.HttpServletRequest;
|
|||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
|
||||||
|
import com.metaweb.gridlock.browsing.Engine;
|
||||||
|
import com.metaweb.gridlock.browsing.FilteredRows;
|
||||||
|
import com.metaweb.gridlock.browsing.RowVisitor;
|
||||||
import com.metaweb.gridlock.expr.Evaluable;
|
import com.metaweb.gridlock.expr.Evaluable;
|
||||||
import com.metaweb.gridlock.expr.Parser;
|
import com.metaweb.gridlock.expr.Parser;
|
||||||
import com.metaweb.gridlock.history.CellChange;
|
import com.metaweb.gridlock.history.CellChange;
|
||||||
@ -27,45 +30,60 @@ public class DoTextTransformCommand extends Command {
|
|||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
|
||||||
Project project = getProject(request);
|
|
||||||
int cellIndex = Integer.parseInt(request.getParameter("cell"));
|
|
||||||
|
|
||||||
Column column = project.columnModel.getColumnByCellIndex(cellIndex);
|
|
||||||
if (column == null) {
|
|
||||||
respond(response, "{ \"code\" : \"error\", \"message\" : \"No such column\" }");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String columnName = column.headerLabel;
|
|
||||||
String expression = request.getParameter("expression");
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
Project project = getProject(request);
|
||||||
|
Engine engine = getEngine(request, project);
|
||||||
|
|
||||||
|
int cellIndex = Integer.parseInt(request.getParameter("cell"));
|
||||||
|
Column column = project.columnModel.getColumnByCellIndex(cellIndex);
|
||||||
|
if (column == null) {
|
||||||
|
respond(response, "{ \"code\" : \"error\", \"message\" : \"No such column\" }");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String columnName = column.headerLabel;
|
||||||
|
String expression = request.getParameter("expression");
|
||||||
|
|
||||||
Evaluable eval = new Parser(expression).getExpression();
|
Evaluable eval = new Parser(expression).getExpression();
|
||||||
//System.out.println("--- " + eval.toString());
|
|
||||||
Properties bindings = new Properties();
|
Properties bindings = new Properties();
|
||||||
bindings.put("project", project);
|
bindings.put("project", project);
|
||||||
|
|
||||||
List<CellChange> cellChanges = new ArrayList<CellChange>(project.rows.size());
|
List<CellChange> cellChanges = new ArrayList<CellChange>(project.rows.size());
|
||||||
|
|
||||||
for (int r = 0; r < project.rows.size(); r++) {
|
FilteredRows filteredRows = engine.getAllFilteredRows();
|
||||||
Row row = project.rows.get(r);
|
filteredRows.accept(project, new RowVisitor() {
|
||||||
if (cellIndex < row.cells.size()) {
|
int cellIndex;
|
||||||
Cell cell = row.cells.get(cellIndex);
|
Properties bindings;
|
||||||
if (cell.value == null) {
|
List<CellChange> cellChanges;
|
||||||
continue;
|
Evaluable eval;
|
||||||
}
|
|
||||||
|
|
||||||
bindings.put("cell", cell);
|
public RowVisitor init(int cellIndex, Properties bindings, List<CellChange> cellChanges, Evaluable eval) {
|
||||||
bindings.put("value", cell.value);
|
this.cellIndex = cellIndex;
|
||||||
|
this.bindings = bindings;
|
||||||
Cell newCell = new Cell();
|
this.cellChanges = cellChanges;
|
||||||
newCell.value = eval.evaluate(bindings);
|
this.eval = eval;
|
||||||
newCell.recon = cell.recon;
|
return this;
|
||||||
|
|
||||||
CellChange cellChange = new CellChange(r, cellIndex, cell, newCell);
|
|
||||||
cellChanges.add(cellChange);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@Override
|
||||||
|
public boolean visit(Project project, int rowIndex, Row row) {
|
||||||
|
if (cellIndex < row.cells.size()) {
|
||||||
|
Cell cell = row.cells.get(cellIndex);
|
||||||
|
if (cell.value != null) {
|
||||||
|
bindings.put("cell", cell);
|
||||||
|
bindings.put("value", cell.value);
|
||||||
|
|
||||||
|
Cell newCell = new Cell();
|
||||||
|
newCell.value = eval.evaluate(bindings);
|
||||||
|
newCell.recon = cell.recon;
|
||||||
|
|
||||||
|
CellChange cellChange = new CellChange(rowIndex, cellIndex, cell, newCell);
|
||||||
|
cellChanges.add(cellChange);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}.init(cellIndex, bindings, cellChanges, eval));
|
||||||
|
|
||||||
MassCellChange massCellChange = new MassCellChange(cellChanges);
|
MassCellChange massCellChange = new MassCellChange(cellChanges);
|
||||||
HistoryEntry historyEntry = new HistoryEntry(
|
HistoryEntry historyEntry = new HistoryEntry(
|
||||||
|
@ -0,0 +1,82 @@
|
|||||||
|
package com.metaweb.gridlock.commands;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import com.metaweb.gridlock.browsing.Engine;
|
||||||
|
import com.metaweb.gridlock.browsing.FilteredRows;
|
||||||
|
import com.metaweb.gridlock.browsing.RowVisitor;
|
||||||
|
import com.metaweb.gridlock.model.Cell;
|
||||||
|
import com.metaweb.gridlock.model.Column;
|
||||||
|
import com.metaweb.gridlock.model.Project;
|
||||||
|
import com.metaweb.gridlock.model.Row;
|
||||||
|
import com.metaweb.gridlock.process.ReconProcess;
|
||||||
|
import com.metaweb.gridlock.process.ReconProcess.ReconEntry;
|
||||||
|
|
||||||
|
public class ReconcileCommand extends Command {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
|
throws ServletException, IOException {
|
||||||
|
|
||||||
|
try {
|
||||||
|
Project project = getProject(request);
|
||||||
|
Engine engine = getEngine(request, project);
|
||||||
|
|
||||||
|
int cellIndex = Integer.parseInt(request.getParameter("cell"));
|
||||||
|
Column column = project.columnModel.getColumnByCellIndex(cellIndex);
|
||||||
|
if (column == null) {
|
||||||
|
respond(response, "{ \"code\" : \"error\", \"message\" : \"No such column\" }");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String columnName = column.headerLabel;
|
||||||
|
String typeID = request.getParameter("type");
|
||||||
|
|
||||||
|
List<ReconEntry> entries = new ArrayList<ReconEntry>(project.rows.size());
|
||||||
|
|
||||||
|
FilteredRows filteredRows = engine.getAllFilteredRows();
|
||||||
|
filteredRows.accept(project, new RowVisitor() {
|
||||||
|
int cellIndex;
|
||||||
|
List<ReconEntry> entries;
|
||||||
|
|
||||||
|
public RowVisitor init(int cellIndex, List<ReconEntry> entries) {
|
||||||
|
this.cellIndex = cellIndex;
|
||||||
|
this.entries = entries;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean visit(Project project, int rowIndex, Row row) {
|
||||||
|
if (cellIndex < row.cells.size()) {
|
||||||
|
Cell cell = row.cells.get(cellIndex);
|
||||||
|
if (cell.value != null) {
|
||||||
|
entries.add(new ReconEntry(rowIndex, cell));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}.init(cellIndex, entries));
|
||||||
|
|
||||||
|
ReconProcess process = new ReconProcess(
|
||||||
|
project,
|
||||||
|
"Reconcile " + columnName + " to type " + typeID,
|
||||||
|
cellIndex,
|
||||||
|
entries,
|
||||||
|
typeID
|
||||||
|
);
|
||||||
|
|
||||||
|
boolean done = project.processManager.queueProcess(process);
|
||||||
|
|
||||||
|
respond(response, "{ \"code\" : " + (done ? "\"ok\"" : "\"pending\"") + " }");
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
respondException(response, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -25,7 +25,11 @@ public class History implements Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void addEntry(HistoryEntry entry) {
|
public void addEntry(HistoryEntry entry) {
|
||||||
|
for (HistoryEntry entry2 : _futureEntries) {
|
||||||
|
entry2.delete();
|
||||||
|
}
|
||||||
_futureEntries.clear();
|
_futureEntries.clear();
|
||||||
|
|
||||||
_pastEntries.add(entry);
|
_pastEntries.add(entry);
|
||||||
entry.apply(ProjectManager.singleton.getProject(_projectID));
|
entry.apply(ProjectManager.singleton.getProject(_projectID));
|
||||||
}
|
}
|
||||||
@ -54,6 +58,21 @@ public class History implements Serializable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected HistoryEntry getEntry(long entryID) {
|
||||||
|
for (int i = 0; i < _pastEntries.size(); i++) {
|
||||||
|
if (_pastEntries.get(i).id == entryID) {
|
||||||
|
return _pastEntries.get(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < _futureEntries.size(); i++) {
|
||||||
|
if (_futureEntries.get(i).id == entryID) {
|
||||||
|
return _futureEntries.get(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
protected void undo(int times) {
|
protected void undo(int times) {
|
||||||
Project project = ProjectManager.singleton.getProject(_projectID);
|
Project project = ProjectManager.singleton.getProject(_projectID);
|
||||||
|
|
||||||
|
@ -64,6 +64,13 @@ public class HistoryEntry implements Serializable {
|
|||||||
_change.revert(project);
|
_change.revert(project);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void delete() {
|
||||||
|
File file = getFile();
|
||||||
|
if (file.exists()) {
|
||||||
|
file.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void loadChange() {
|
protected void loadChange() {
|
||||||
File file = getFile();
|
File file = getFile();
|
||||||
|
|
||||||
|
@ -1,20 +1,35 @@
|
|||||||
package com.metaweb.gridlock.history;
|
package com.metaweb.gridlock.history;
|
||||||
|
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import com.metaweb.gridlock.model.Project;
|
import com.metaweb.gridlock.model.Project;
|
||||||
import com.metaweb.gridlock.process.Process;
|
import com.metaweb.gridlock.process.Process;
|
||||||
import com.metaweb.gridlock.process.ProcessManager;
|
import com.metaweb.gridlock.process.ProcessManager;
|
||||||
|
|
||||||
public class HistoryProcess extends Process {
|
public class HistoryProcess extends Process {
|
||||||
final protected Project _project;
|
final protected Project _project;
|
||||||
final protected long _lastDoneID;
|
final protected long _lastDoneID;
|
||||||
|
final protected String _description;
|
||||||
|
boolean _done = false;
|
||||||
|
|
||||||
public HistoryProcess(Project project, long lastDoneID) {
|
public HistoryProcess(Project project, long lastDoneID) {
|
||||||
_project = project;
|
_project = project;
|
||||||
_lastDoneID = lastDoneID;
|
_lastDoneID = lastDoneID;
|
||||||
|
|
||||||
|
if (_lastDoneID == 0) {
|
||||||
|
_description = "Undo all";
|
||||||
|
} else {
|
||||||
|
HistoryEntry entry = _project.history.getEntry(_lastDoneID);
|
||||||
|
_description = "Undo/redo until after " + entry.description;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cancel() {
|
public void cancel() {
|
||||||
|
throw new RuntimeException("Not a long-running process");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -25,9 +40,32 @@ public class HistoryProcess extends Process {
|
|||||||
@Override
|
@Override
|
||||||
public void performImmediate() {
|
public void performImmediate() {
|
||||||
_project.history.undoRedo(_lastDoneID);
|
_project.history.undoRedo(_lastDoneID);
|
||||||
|
_done = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void startPerforming(ProcessManager manager) {
|
public void startPerforming(ProcessManager manager) {
|
||||||
|
throw new RuntimeException("Not a long-running process");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSONObject getJSON(Properties options) throws JSONException {
|
||||||
|
JSONObject o = new JSONObject();
|
||||||
|
|
||||||
|
o.put("description", _description);
|
||||||
|
o.put("immediate", true);
|
||||||
|
o.put("status", _done ? "done" : "pending");
|
||||||
|
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDone() {
|
||||||
|
throw new RuntimeException("Not a long-running process");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isRunning() {
|
||||||
|
throw new RuntimeException("Not a long-running process");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,10 +6,11 @@ import org.json.JSONException;
|
|||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
abstract public class LongRunningProcess extends Process {
|
abstract public class LongRunningProcess extends Process {
|
||||||
final protected String _description;
|
final protected String _description;
|
||||||
protected ProcessManager _manager;
|
protected ProcessManager _manager;
|
||||||
protected Thread _thread;
|
protected Thread _thread;
|
||||||
protected int _progress; // out of 100
|
protected int _progress; // out of 100
|
||||||
|
protected boolean _canceled;
|
||||||
|
|
||||||
protected LongRunningProcess(String description) {
|
protected LongRunningProcess(String description) {
|
||||||
_description = description;
|
_description = description;
|
||||||
@ -17,11 +18,14 @@ abstract public class LongRunningProcess extends Process {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cancel() {
|
public void cancel() {
|
||||||
// TODO Auto-generated method stub
|
_canceled = true;
|
||||||
|
if (_thread != null && _thread.isAlive()) {
|
||||||
|
_thread.interrupt();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
public
|
||||||
JSONObject getJSON(Properties options) throws JSONException {
|
JSONObject getJSON(Properties options) throws JSONException {
|
||||||
JSONObject o = new JSONObject();
|
JSONObject o = new JSONObject();
|
||||||
|
|
||||||
@ -38,6 +42,16 @@ abstract public class LongRunningProcess extends Process {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isRunning() {
|
||||||
|
return _thread != null && _thread.isAlive();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDone() {
|
||||||
|
return _thread != null && !_thread.isAlive();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void performImmediate() {
|
public void performImmediate() {
|
||||||
throw new RuntimeException("Not an immediate process");
|
throw new RuntimeException("Not an immediate process");
|
||||||
|
@ -16,5 +16,5 @@ public abstract class Process {
|
|||||||
abstract public void startPerforming(ProcessManager manager);
|
abstract public void startPerforming(ProcessManager manager);
|
||||||
abstract public void cancel();
|
abstract public void cancel();
|
||||||
|
|
||||||
abstract JSONObject getJSON(Properties options) throws JSONException;
|
public abstract JSONObject getJSON(Properties options) throws JSONException;
|
||||||
}
|
}
|
||||||
|
@ -33,11 +33,15 @@ public class ProcessManager {
|
|||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
_processes.add(process);
|
_processes.add(process);
|
||||||
|
|
||||||
|
update();
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onDoneProcess(Process p) {
|
public void onDoneProcess(Process p) {
|
||||||
|
_processes.remove(p);
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,6 +45,7 @@ public class QuickHistoryEntryProcess extends Process {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
public
|
||||||
JSONObject getJSON(Properties options) throws JSONException {
|
JSONObject getJSON(Properties options) throws JSONException {
|
||||||
JSONObject o = new JSONObject();
|
JSONObject o = new JSONObject();
|
||||||
|
|
||||||
|
73
src/main/java/com/metaweb/gridlock/process/ReconProcess.java
Normal file
73
src/main/java/com/metaweb/gridlock/process/ReconProcess.java
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
package com.metaweb.gridlock.process;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.metaweb.gridlock.model.Cell;
|
||||||
|
import com.metaweb.gridlock.model.Project;
|
||||||
|
|
||||||
|
public class ReconProcess extends LongRunningProcess implements Runnable {
|
||||||
|
static public class ReconEntry {
|
||||||
|
final public int rowIndex;
|
||||||
|
final public Cell cell;
|
||||||
|
|
||||||
|
public ReconEntry(int rowIndex, Cell cell) {
|
||||||
|
this.rowIndex = rowIndex;
|
||||||
|
this.cell = cell;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final protected Project _project;
|
||||||
|
final protected int _cellIndex;
|
||||||
|
final protected List<ReconEntry> _entries;
|
||||||
|
final protected String _typeID;
|
||||||
|
|
||||||
|
public ReconProcess(Project project, String description, int cellIndex, List<ReconEntry> entries, String typeID) {
|
||||||
|
super(description);
|
||||||
|
_project = project;
|
||||||
|
_cellIndex = cellIndex;
|
||||||
|
_entries = entries;
|
||||||
|
_typeID = typeID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Runnable getRunnable() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
Map<String, List<ReconEntry>> valueToEntries = new HashMap<String, List<ReconEntry>>();
|
||||||
|
|
||||||
|
for (ReconEntry entry : _entries) {
|
||||||
|
Object value = entry.cell.value;
|
||||||
|
if (value != null && value instanceof String) {
|
||||||
|
List<ReconEntry> entries2;
|
||||||
|
if (valueToEntries.containsKey(value)) {
|
||||||
|
entries2 = valueToEntries.get(value);
|
||||||
|
} else {
|
||||||
|
entries2 = new LinkedList<ReconEntry>();
|
||||||
|
valueToEntries.put((String) value, entries2);
|
||||||
|
}
|
||||||
|
entries2.add(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> values = new ArrayList<String>(valueToEntries.keySet());
|
||||||
|
for (int i = 0; i < values.size(); i += 20) {
|
||||||
|
_progress = i * 100 / values.size();
|
||||||
|
try {
|
||||||
|
Thread.sleep(100);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
if (_canceled) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_project.processManager.onDoneProcess(this);
|
||||||
|
}
|
||||||
|
}
|
@ -1 +1 @@
|
|||||||
<html>
<head>
<title>Gridlock</title>
<link rel="stylesheet" href="/styles/common.css" />
<link rel="stylesheet" href="/styles/project.css" />
<link rel="stylesheet" href="/styles/history.css" />
<link rel="stylesheet" href="/styles/browsing.css" />
<link rel="stylesheet" href="/styles/process.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/misc.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/util/menu.js"></script>
<script type="text/javascript" src="scripts/project.js"></script>
<script type="text/javascript" src="scripts/project/list-facet.js"></script>
<script type="text/javascript" src="scripts/project/browsing-engine.js"></script>
<script type="text/javascript" src="scripts/project/data-table-view.js"></script>
<script type="text/javascript" src="scripts/project/history-widget.js"></script>
<script type="text/javascript" src="scripts/project/process-widget.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" />
<script type="text/javascript" src="scripts/util/url.js"></script>
<link rel="stylesheet" href="/styles/common.css" />
<link rel="stylesheet" href="/styles/project.css" />
<link rel="stylesheet" href="/styles/history.css" />
<link rel="stylesheet" href="/styles/browsing.css" />
<link rel="stylesheet" href="/styles/process.css" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
<script type="text/javascript" src="http://freebaselibs.com/static/suggest/1.0.3/suggest.min.js"></script>
<script type="text/javascript" src="scripts/util/misc.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/util/menu.js"></script>
<script type="text/javascript" src="scripts/util/dialog.js"></script>
<script type="text/javascript" src="scripts/project.js"></script>
<script type="text/javascript" src="scripts/project/list-facet.js"></script>
<script type="text/javascript" src="scripts/project/browsing-engine.js"></script>
<script type="text/javascript" src="scripts/project/data-table-view.js"></script>
<script type="text/javascript" src="scripts/project/history-widget.js"></script>
<script type="text/javascript" src="scripts/project/process-widget.js"></script>
<script type="text/javascript" src="scripts/project/recon-dialog.js"></script>
</head>
<body>
<div id="header">
<h1 id="title">Gridlock</h1>
</div>
<div id="body">
Loading ...
</div>
</body>
</html>
|
@ -45,6 +45,7 @@ DataTableView.prototype.render = function() {
|
|||||||
var trHead = table.insertRow(0);
|
var trHead = table.insertRow(0);
|
||||||
|
|
||||||
var td = trHead.insertCell(trHead.cells.length);
|
var td = trHead.insertCell(trHead.cells.length);
|
||||||
|
$(td).addClass("column-header");
|
||||||
$('<img src="/images/menu-dropdown.png" />').addClass("column-header-menu").appendTo(td).click(function() {
|
$('<img src="/images/menu-dropdown.png" />').addClass("column-header-menu").appendTo(td).click(function() {
|
||||||
self._createMenuForAllColumns(this);
|
self._createMenuForAllColumns(this);
|
||||||
});
|
});
|
||||||
@ -267,7 +268,9 @@ DataTableView.prototype._createMenuForColumnHeader = function(column, index, elm
|
|||||||
submenu: [
|
submenu: [
|
||||||
{
|
{
|
||||||
label: "Initiate on Filtered Rows...",
|
label: "Initiate on Filtered Rows...",
|
||||||
click: function() {}
|
click: function() {
|
||||||
|
new ReconDialog(index);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{},
|
{},
|
||||||
{
|
{
|
||||||
@ -283,7 +286,7 @@ DataTableView.prototype._doTextTransform = function(column, expression) {
|
|||||||
var self = this;
|
var self = this;
|
||||||
$.post(
|
$.post(
|
||||||
"/command/do-text-transform?" + $.param({ project: theProject.id, cell: column.cellIndex, expression: expression }),
|
"/command/do-text-transform?" + $.param({ project: theProject.id, cell: column.cellIndex, expression: expression }),
|
||||||
null,
|
{ engine: JSON.stringify(ui.browsingEngine.getJSON()) },
|
||||||
function(data) {
|
function(data) {
|
||||||
if (data.code == "ok") {
|
if (data.code == "ok") {
|
||||||
self.update();
|
self.update();
|
||||||
|
@ -24,9 +24,11 @@ ProcessWidget.prototype._render = function() {
|
|||||||
|
|
||||||
this._div.empty();
|
this._div.empty();
|
||||||
|
|
||||||
var bodyDiv = $('<div></div>').addClass("process-panel-inner").text("Testing").appendTo(this._div);
|
var bodyDiv = $('<div></div>').addClass("process-panel-inner").appendTo(this._div);
|
||||||
if (this._data.processes.length == 0) {
|
if (this._data.processes.length == 0) {
|
||||||
this._div.hide();
|
this._div.hide();
|
||||||
|
|
||||||
|
ui.historyWidget.update();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
48
src/main/webapp/scripts/project/recon-dialog.js
Normal file
48
src/main/webapp/scripts/project/recon-dialog.js
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
function ReconDialog(columnIndex) {
|
||||||
|
this._columnIndex = columnIndex;
|
||||||
|
this._column = theProject.columnModel.columns[columnIndex];
|
||||||
|
|
||||||
|
this._createDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
ReconDialog.prototype._createDialog = function() {
|
||||||
|
var self = this;
|
||||||
|
var frame = DialogSystem.createDialog();
|
||||||
|
frame.width("400px");
|
||||||
|
|
||||||
|
var header = $('<div></div>').addClass("dialog-header").text("Reconcile column " + this._column.headerLabel).appendTo(frame);
|
||||||
|
var body = $('<div></div>').addClass("dialog-body").appendTo(frame);
|
||||||
|
var footer = $('<div></div>').addClass("dialog-footer").appendTo(frame);
|
||||||
|
|
||||||
|
$('<p></p>').text("Reconcile cell values to topics of type:").appendTo(body);
|
||||||
|
|
||||||
|
var type = null;
|
||||||
|
var input = $('<input />').appendTo($('<p></p>').appendTo(body));
|
||||||
|
input.suggest({ type : '/type/type' }).bind("fb-select", function(e, data) {
|
||||||
|
type = data.id;
|
||||||
|
});
|
||||||
|
|
||||||
|
$('<button></button>').text("Start Reconciling").click(function() {
|
||||||
|
DialogSystem.dismissUntil(level - 1);
|
||||||
|
$.post(
|
||||||
|
"/command/reconcile?" + $.param({ project: theProject.id, cell: self._column.cellIndex, type: type }),
|
||||||
|
{ engine: JSON.stringify(ui.browsingEngine.getJSON()) },
|
||||||
|
function(data) {
|
||||||
|
if (data.code != "error") {
|
||||||
|
ui.processWidget.update();
|
||||||
|
} else {
|
||||||
|
alert(data.message);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"json"
|
||||||
|
);
|
||||||
|
}).appendTo(footer);
|
||||||
|
|
||||||
|
$('<button></button>').text("Cancel").click(function() {
|
||||||
|
DialogSystem.dismissUntil(level - 1);
|
||||||
|
}).appendTo(footer);
|
||||||
|
|
||||||
|
var level = DialogSystem.showDialog(frame);
|
||||||
|
|
||||||
|
input[0].focus();
|
||||||
|
};
|
70
src/main/webapp/scripts/util/dialog.js
Normal file
70
src/main/webapp/scripts/util/dialog.js
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
DialogSystem = {
|
||||||
|
_layers: [],
|
||||||
|
_bottomOverlay: null
|
||||||
|
};
|
||||||
|
|
||||||
|
DialogSystem.showDialog = function(elmt, onCancel) {
|
||||||
|
if (DialogSystem._bottomOverlay == null) {
|
||||||
|
DialogSystem._bottomOverlay = $('<div> </div>')
|
||||||
|
.addClass("dialog-overlay")
|
||||||
|
.css("z-index", 100)
|
||||||
|
.appendTo(document.body);
|
||||||
|
}
|
||||||
|
|
||||||
|
var overlay = $('<div> </div>')
|
||||||
|
.addClass("dialog-overlay2")
|
||||||
|
.css("z-index", 101 + DialogSystem._layers.length * 2)
|
||||||
|
.appendTo(document.body);
|
||||||
|
|
||||||
|
var container = $('<div></div>')
|
||||||
|
.addClass("dialog-container")
|
||||||
|
.css("z-index", 102 + DialogSystem._layers.length * 2)
|
||||||
|
.appendTo(document.body);
|
||||||
|
|
||||||
|
elmt.css("visibility", "hidden").appendTo(container);
|
||||||
|
container.css("top", Math.round((overlay.height() - elmt.height()) / 2) + "px");
|
||||||
|
elmt.css("visibility", "visible");
|
||||||
|
|
||||||
|
var layer = {
|
||||||
|
overlay: overlay,
|
||||||
|
container: container,
|
||||||
|
onCancel: onCancel
|
||||||
|
};
|
||||||
|
DialogSystem._layers.push(layer);
|
||||||
|
|
||||||
|
var level = DialogSystem._layers.length;
|
||||||
|
return level;
|
||||||
|
};
|
||||||
|
|
||||||
|
DialogSystem.dismissAll = function() {
|
||||||
|
DialogSystem.dismissUntil(0);
|
||||||
|
};
|
||||||
|
|
||||||
|
DialogSystem.dismissUntil = function(level) {
|
||||||
|
for (var i = DialogSystem._layers.length - 1; i >= level; i--) {
|
||||||
|
var layer = DialogSystem._layers[i];
|
||||||
|
layer.overlay.remove();
|
||||||
|
layer.container.remove();
|
||||||
|
|
||||||
|
if (layer.onCancel) {
|
||||||
|
try {
|
||||||
|
layer.onCancel();
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DialogSystem._layers = DialogSystem._layers.slice(0, level);
|
||||||
|
|
||||||
|
if (level == 0) {
|
||||||
|
if (DialogSystem._bottomOverlay != null) {
|
||||||
|
DialogSystem._bottomOverlay.remove();
|
||||||
|
DialogSystem._bottomOverlay = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
DialogSystem.createDialog = function() {
|
||||||
|
return $('<div></div>').addClass("dialog-frame");
|
||||||
|
};
|
||||||
|
|
@ -89,3 +89,64 @@ a.menu-item:hover {
|
|||||||
a.menu-item img {
|
a.menu-item img {
|
||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dialog-overlay {
|
||||||
|
background: black;
|
||||||
|
opacity: 0.3;
|
||||||
|
position: fixed;
|
||||||
|
padding: 0px;
|
||||||
|
margin: 0px;
|
||||||
|
top: 0px;
|
||||||
|
left: 0px;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-overlay2 {
|
||||||
|
position: fixed;
|
||||||
|
padding: 0px;
|
||||||
|
margin: 0px;
|
||||||
|
top: 0px;
|
||||||
|
left: 0px;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: black;
|
||||||
|
opacity: 0.01;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-container {
|
||||||
|
position: fixed;
|
||||||
|
padding: 0px;
|
||||||
|
margin: 0px;
|
||||||
|
left: 0px;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-frame {
|
||||||
|
margin: 0 auto;
|
||||||
|
text-align: left;
|
||||||
|
background: white;
|
||||||
|
border: 1px solid #aaa;
|
||||||
|
padding: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-header {
|
||||||
|
background: #ccc;
|
||||||
|
padding: 5px 10px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-body {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-footer {
|
||||||
|
background: #ddd;
|
||||||
|
padding: 5px 10px;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-footer button {
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
@ -13,3 +13,7 @@
|
|||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.fbs-pane, .fbs-flyout-pane {
|
||||||
|
z-index: 200;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user