diff --git a/src/main/webapp/images/close.png b/src/main/webapp/images/close.png
new file mode 100644
index 000000000..7cfa7bad5
Binary files /dev/null and b/src/main/webapp/images/close.png differ
diff --git a/src/main/webapp/scripts/project/schema-alignment-ui-link.js b/src/main/webapp/scripts/project/schema-alignment-ui-link.js
index e9a82e940..81432255a 100644
--- a/src/main/webapp/scripts/project/schema-alignment-ui-link.js
+++ b/src/main/webapp/scripts/project/schema-alignment-ui-link.js
@@ -1,6 +1,7 @@
-SchemaAlignmentDialog.UILink = function(link, table, expanded) {
+SchemaAlignmentDialog.UILink = function(link, table, options, parentUINode) {
this._link = link;
- this._expanded = expanded;
+ this._options = options;
+ this._parentUINode = parentUINode;
this._tr = table.insertRow(table.rows.length);
this._tdMain = this._tr.insertCell(0);
@@ -15,7 +16,7 @@ SchemaAlignmentDialog.UILink = function(link, table, expanded) {
this._expandedDetailDiv = $('
').appendTo(this._tdDetails).addClass("schema-alignment-detail-container");
var self = this;
var show = function() {
- if (self._expanded) {
+ if (self._options.expanded) {
self._collapsedDetailDiv.hide();
self._expandedDetailDiv.show();
} else {
@@ -27,12 +28,12 @@ SchemaAlignmentDialog.UILink = function(link, table, expanded) {
$(this._tdToggle).html(" ");
$('
')
- .attr("src", this._expanded ? "images/expanded.png" : "images/collapsed.png")
+ .attr("src", this._options.expanded ? "images/expanded.png" : "images/collapsed.png")
.appendTo(this._tdToggle)
.click(function() {
- self._expanded = !self._expanded;
+ self._options.expanded = !self._options.expanded;
- $(this).attr("src", self._expanded ? "images/expanded.png" : "images/collapsed.png");
+ $(this).attr("src", self._options.expanded ? "images/expanded.png" : "images/collapsed.png");
show();
});
@@ -48,6 +49,18 @@ SchemaAlignmentDialog.UILink.prototype._renderMain = function() {
var self = this;
+ $('
')
+ .attr("title", "remove property")
+ .attr("src", "images/close.png")
+ .css("cursor", "pointer")
+ .prependTo(this._tdMain)
+ .click(function() {
+ window.setTimeout(function() {
+ self._parentUINode.removeLink(self);
+ self._tr.parentNode.removeChild(self._tr);
+ }, 100);
+ });
+
var a = $('')
.addClass("schema-alignment-link-tag")
.html(label)
@@ -81,12 +94,23 @@ SchemaAlignmentDialog.UILink.prototype._showPropertySuggestPopup = function(elmt
var level = MenuSystem.showMenu(fakeMenu, function(){});
MenuSystem.positionMenuAboveBelow(fakeMenu, $(elmt));
+
+ var options = {
+ type : '/type/property'
+ };
+ var expectedTypeID = this._parentUINode.getExpectedType();
+ if (expectedTypeID != null) {
+ options.mql_filter = [{
+ "/type/property/schema" : { "id" : expectedTypeID }
+ }];
+ }
- input.suggest({ type : '/type/property' }).bind("fb-select", function(e, data) {
+ input.suggest(options).bind("fb-select", function(e, data) {
self._link.property = {
id: data.id,
name: data.name
};
+ self._configureTarget();
window.setTimeout(function() {
MenuSystem.dismissAll();
@@ -110,3 +134,43 @@ SchemaAlignmentDialog.UILink.prototype.getJSON = function() {
}
return null;
};
+
+SchemaAlignmentDialog.UILink.prototype._configureTarget = function() {
+ var self = this;
+ $.getJSON(
+ "http://api.freebase.com/api/service/mqlread?query=" + JSON.stringify({
+ query: {
+ "id" : this._link.property.id,
+ "type" : "/type/property",
+ "expected_type" : {
+ "id" : null,
+ "name" : null,
+ "/freebase/type_hints/mediator" : null
+ }
+ }
+ }) + "&callback=?",
+ null,
+ function(o) {
+ if ("result" in o) {
+ var expected_type = o.result.expected_type;
+ self._link.target.type = {
+ id: expected_type.id,
+ name: expected_type.name
+ };
+ if (expected_type["/freebase/type_hints/mediator"] == true) {
+ self._link.target.nodeType = "anonymous";
+ } else if (expected_type.id == "/type/key") {
+ self._link.target.nodeType = "cell-as-key";
+ } else if (expected_type.id.match(/^\/type\//)) {
+ self._link.target.nodeType = "cell-as-value";
+ } else if (!("topic" in self._link.target)) {
+ self._link.target.nodeType = "cell-as-topic";
+ self._link.target.createForNoReconMatch = true;
+ }
+
+ self._targetUI.render();
+ }
+ },
+ "jsonp"
+ );
+};
diff --git a/src/main/webapp/scripts/project/schema-alignment-ui-node.js b/src/main/webapp/scripts/project/schema-alignment-ui-node.js
index 55bce8265..7cf04f012 100644
--- a/src/main/webapp/scripts/project/schema-alignment-ui-node.js
+++ b/src/main/webapp/scripts/project/schema-alignment-ui-node.js
@@ -22,12 +22,38 @@ SchemaAlignmentDialog.UINode = function(node, table, options) {
}
};
+SchemaAlignmentDialog.UINode.prototype.removeLink = function(linkUI) {
+ for (var i = this._linkUIs.length - 1; i >= 0; i--) {
+ if (this._linkUIs[i] === linkUI) {
+ this._linkUIs.splice(i, 1);
+ this._node.links.splice(i, 1);
+ break;
+ }
+ }
+};
+
SchemaAlignmentDialog.UINode.prototype._isExpandable = function() {
return this._node.nodeType == "cell-as-topic" ||
this._node.nodeType == "anonymous" ||
this._node.nodeType == "topic";
};
+SchemaAlignmentDialog.UINode.prototype.render = function() {
+ this._renderMain();
+ if (this._isExpandable()) {
+ this._showExpandable();
+ } else {
+ this._hideExpandable();
+ }
+};
+
+SchemaAlignmentDialog.UINode.prototype.getExpectedType = function() {
+ if ("type" in this._node) {
+ return this._node.type.id;
+ }
+ return null;
+};
+
SchemaAlignmentDialog.UINode.prototype._renderMain = function() {
$(this._tdMain).empty();
@@ -123,7 +149,7 @@ SchemaAlignmentDialog.UINode.prototype._renderDetails = function() {
if ("links" in this._node && this._node.links != null) {
for (var i = 0; i < this._node.links.length; i++) {
- this._linkUIs.push(new SchemaAlignmentDialog.UILink(this._node.links[i], this._tableLinks, true));
+ this._linkUIs.push(new SchemaAlignmentDialog.UILink(this._node.links[i], this._tableLinks, { expanded: true }, this));
}
}
@@ -146,7 +172,8 @@ SchemaAlignmentDialog.UINode.prototype._renderDetails = function() {
{
expanded: true,
mustBeCellTopic: false
- }
+ },
+ self
));
});
};
@@ -369,6 +396,22 @@ SchemaAlignmentDialog.UINode.prototype._showNodeConfigDialog = function() {
.appendTo(tr.insertCell(0))
.click(function() {
elmts.radioNodeTypeCellAs[0].checked = true;
+
+ if ("reconConfig" in column) {
+ var typeID = column.reconConfig.type;
+ $.getJSON(
+ "http://api.freebase.com/api/service/mqlread?query=" + JSON.stringify({ query: { "id" : typeID, "name" : null } }) + "&callback=?",
+ null,
+ function(o) {
+ if ("result" in o) {
+ elmts.cellAsTopicNodeTypeInput[0].value = o.result.name;
+ elmts.cellAsTopicNodeTypeInput.data("data.suggest", { "id" : typeID, "name" : o.result.name });
+ elmts.radioNodeTypeCellAsTopicCreate[0].checked = true;
+ }
+ },
+ "jsonp"
+ );
+ }
});
if ((!("columnName" in self._node) || self._node.columnName == null) && columnIndex == 0) {
@@ -431,6 +474,7 @@ SchemaAlignmentDialog.UINode.prototype._showNodeConfigDialog = function() {
})
.suggest({ type: "/type/namespace" });
+ elmts.radioNodeTypeCellAsTopic[0].checked = true; // just make sure some subtype is selected
if (this._node.nodeType.match(/^cell-as-/)) {
elmts.radioNodeTypeCellAs[0].checked = true;
if (this._node.nodeType == "cell-as-topic") {
@@ -564,12 +608,7 @@ SchemaAlignmentDialog.UINode.prototype._showNodeConfigDialog = function() {
DialogSystem.dismissUntil(level - 1);
self._node = node;
- if (self._isExpandable()) {
- self._showExpandable();
- } else {
- self._hideExpandable();
- }
- self._renderMain();
+ self.render();
}
}).appendTo(footer);
diff --git a/src/main/webapp/scripts/project/schema-alignment.js b/src/main/webapp/scripts/project/schema-alignment.js
index 30a8c2d31..49b138cd3 100644
--- a/src/main/webapp/scripts/project/schema-alignment.js
+++ b/src/main/webapp/scripts/project/schema-alignment.js
@@ -93,7 +93,7 @@ SchemaAlignment._cleanName = function(s) {
function SchemaAlignmentDialog(protograph, onDone) {
this._onDone = onDone;
this._originalProtograph = protograph || { rootNodes: [] };
- this._protograph = cloneDeep(protograph); // this is what can be munched on
+ this._protograph = cloneDeep(this._originalProtograph); // this is what can be munched on
if (this._protograph.rootNodes.length == 0) {
this._protograph.rootNodes.push({