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.GetProjectMetadataCommand;
|
||||
import com.metaweb.gridlock.commands.GetRowsCommand;
|
||||
import com.metaweb.gridlock.commands.ReconcileCommand;
|
||||
import com.metaweb.gridlock.commands.UndoRedoCommand;
|
||||
|
||||
public class GridlockServlet extends HttpServlet {
|
||||
@ -42,6 +43,7 @@ public class GridlockServlet extends HttpServlet {
|
||||
_commands.put("undo-redo", new UndoRedoCommand());
|
||||
_commands.put("compute-facets", new ComputeFacetsCommand());
|
||||
_commands.put("do-text-transform", new DoTextTransformCommand());
|
||||
_commands.put("reconcile", new ReconcileCommand());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -10,6 +10,9 @@ 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.expr.Evaluable;
|
||||
import com.metaweb.gridlock.expr.Parser;
|
||||
import com.metaweb.gridlock.history.CellChange;
|
||||
@ -27,45 +30,60 @@ public class DoTextTransformCommand extends Command {
|
||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||
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 {
|
||||
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();
|
||||
//System.out.println("--- " + eval.toString());
|
||||
Properties bindings = new Properties();
|
||||
bindings.put("project", project);
|
||||
|
||||
List<CellChange> cellChanges = new ArrayList<CellChange>(project.rows.size());
|
||||
|
||||
for (int r = 0; r < project.rows.size(); r++) {
|
||||
Row row = project.rows.get(r);
|
||||
if (cellIndex < row.cells.size()) {
|
||||
Cell cell = row.cells.get(cellIndex);
|
||||
if (cell.value == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
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(r, cellIndex, cell, newCell);
|
||||
cellChanges.add(cellChange);
|
||||
FilteredRows filteredRows = engine.getAllFilteredRows();
|
||||
filteredRows.accept(project, new RowVisitor() {
|
||||
int cellIndex;
|
||||
Properties bindings;
|
||||
List<CellChange> cellChanges;
|
||||
Evaluable eval;
|
||||
|
||||
public RowVisitor init(int cellIndex, Properties bindings, List<CellChange> cellChanges, Evaluable eval) {
|
||||
this.cellIndex = cellIndex;
|
||||
this.bindings = bindings;
|
||||
this.cellChanges = cellChanges;
|
||||
this.eval = eval;
|
||||
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) {
|
||||
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);
|
||||
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) {
|
||||
for (HistoryEntry entry2 : _futureEntries) {
|
||||
entry2.delete();
|
||||
}
|
||||
_futureEntries.clear();
|
||||
|
||||
_pastEntries.add(entry);
|
||||
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) {
|
||||
Project project = ProjectManager.singleton.getProject(_projectID);
|
||||
|
||||
|
@ -64,6 +64,13 @@ public class HistoryEntry implements Serializable {
|
||||
_change.revert(project);
|
||||
}
|
||||
|
||||
public void delete() {
|
||||
File file = getFile();
|
||||
if (file.exists()) {
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
|
||||
protected void loadChange() {
|
||||
File file = getFile();
|
||||
|
||||
|
@ -1,20 +1,35 @@
|
||||
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.process.Process;
|
||||
import com.metaweb.gridlock.process.ProcessManager;
|
||||
|
||||
public class HistoryProcess extends Process {
|
||||
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) {
|
||||
_project = project;
|
||||
_lastDoneID = lastDoneID;
|
||||
|
||||
if (_lastDoneID == 0) {
|
||||
_description = "Undo all";
|
||||
} else {
|
||||
HistoryEntry entry = _project.history.getEntry(_lastDoneID);
|
||||
_description = "Undo/redo until after " + entry.description;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
throw new RuntimeException("Not a long-running process");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -25,9 +40,32 @@ public class HistoryProcess extends Process {
|
||||
@Override
|
||||
public void performImmediate() {
|
||||
_project.history.undoRedo(_lastDoneID);
|
||||
_done = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
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;
|
||||
|
||||
abstract public class LongRunningProcess extends Process {
|
||||
final protected String _description;
|
||||
final protected String _description;
|
||||
protected ProcessManager _manager;
|
||||
protected Thread _thread;
|
||||
protected int _progress; // out of 100
|
||||
protected boolean _canceled;
|
||||
|
||||
protected LongRunningProcess(String description) {
|
||||
_description = description;
|
||||
@ -17,11 +18,14 @@ abstract public class LongRunningProcess extends Process {
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
_canceled = true;
|
||||
if (_thread != null && _thread.isAlive()) {
|
||||
_thread.interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public
|
||||
JSONObject getJSON(Properties options) throws JSONException {
|
||||
JSONObject o = new JSONObject();
|
||||
|
||||
@ -37,6 +41,16 @@ abstract public class LongRunningProcess extends Process {
|
||||
public boolean isImmediate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRunning() {
|
||||
return _thread != null && _thread.isAlive();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDone() {
|
||||
return _thread != null && !_thread.isAlive();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performImmediate() {
|
||||
|
@ -16,5 +16,5 @@ public abstract class Process {
|
||||
abstract public void startPerforming(ProcessManager manager);
|
||||
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;
|
||||
} else {
|
||||
_processes.add(process);
|
||||
|
||||
update();
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void onDoneProcess(Process p) {
|
||||
_processes.remove(p);
|
||||
update();
|
||||
}
|
||||
|
||||
|
@ -45,6 +45,7 @@ public class QuickHistoryEntryProcess extends Process {
|
||||
}
|
||||
|
||||
@Override
|
||||
public
|
||||
JSONObject getJSON(Properties options) throws JSONException {
|
||||
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 td = trHead.insertCell(trHead.cells.length);
|
||||
$(td).addClass("column-header");
|
||||
$('<img src="/images/menu-dropdown.png" />').addClass("column-header-menu").appendTo(td).click(function() {
|
||||
self._createMenuForAllColumns(this);
|
||||
});
|
||||
@ -267,7 +268,9 @@ DataTableView.prototype._createMenuForColumnHeader = function(column, index, elm
|
||||
submenu: [
|
||||
{
|
||||
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;
|
||||
$.post(
|
||||
"/command/do-text-transform?" + $.param({ project: theProject.id, cell: column.cellIndex, expression: expression }),
|
||||
null,
|
||||
{ engine: JSON.stringify(ui.browsingEngine.getJSON()) },
|
||||
function(data) {
|
||||
if (data.code == "ok") {
|
||||
self.update();
|
||||
|
@ -24,9 +24,11 @@ ProcessWidget.prototype._render = function() {
|
||||
|
||||
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) {
|
||||
this._div.hide();
|
||||
|
||||
ui.historyWidget.update();
|
||||
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 {
|
||||
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;
|
||||
}
|
@ -12,4 +12,8 @@
|
||||
background: #fffee0;
|
||||
margin: 0 auto;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.fbs-pane, .fbs-flyout-pane {
|
||||
z-index: 200;
|
||||
}
|
Loading…
Reference in New Issue
Block a user