From b17f71c8dfda2a264a2eea75d88adb4cedc1bd6f Mon Sep 17 00:00:00 2001 From: David Huynh Date: Sat, 13 Feb 2010 00:11:42 +0000 Subject: [PATCH] More work on schema alignment dialogs: schema data from Freebase is used to automatically fill in a lot of fields in the protograph. git-svn-id: http://google-refine.googlecode.com/svn/trunk@93 7d457c2a-affb-35e4-300a-418c747d4874 --- src/main/webapp/images/close.png | Bin 0 -> 392 bytes .../project/schema-alignment-ui-link.js | 78 ++++++++++++++++-- .../project/schema-alignment-ui-node.js | 55 ++++++++++-- .../scripts/project/schema-alignment.js | 2 +- 4 files changed, 119 insertions(+), 16 deletions(-) create mode 100644 src/main/webapp/images/close.png diff --git a/src/main/webapp/images/close.png b/src/main/webapp/images/close.png new file mode 100644 index 0000000000000000000000000000000000000000..7cfa7bad566b8e4b6ffd480efd6f045a13725ec4 GIT binary patch literal 392 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmSpUVoJlSq0=PBzpw; zGBD)MU|=ZjV_ZUM{U!lmtoF$*TD7O>x#EfAKvm|IHt#sS-iDv|4V z7=BC6QV{F0@1E|Ley=)n`DNGZrQFi5c9of!+0N0N=ey&oKxn9J_o9l188TZVnSF0O zubg+JP^b33ef7NM42G6j1#8%LJxGh3)|OZy').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({