From 23355eb472c4591da4c44f369d6ecb61d4615b69 Mon Sep 17 00:00:00 2001 From: Antonin Delpeuch Date: Fri, 8 Sep 2017 17:18:22 +0100 Subject: [PATCH] Add reference support in Wikibase schema editor --- .../dialogs/schema-alignment-dialog.js | 108 +++++++++++++++++- .../dialogs/schema-alignment-dialog.less | 39 ++++++- .../exporters/QuickStatementsExporter.java | 7 ++ .../wikidata/schema/WbStatementExpr.java | 14 +++ 4 files changed, 158 insertions(+), 10 deletions(-) diff --git a/extensions/wikidata/module/scripts/dialogs/schema-alignment-dialog.js b/extensions/wikidata/module/scripts/dialogs/schema-alignment-dialog.js index dd4da1785..366aa2740 100644 --- a/extensions/wikidata/module/scripts/dialogs/schema-alignment-dialog.js +++ b/extensions/wikidata/module/scripts/dialogs/schema-alignment-dialog.js @@ -211,6 +211,10 @@ SchemaAlignmentDialog._createDialog = function() { this.preview(); }; +/**************/ +/*** ITEMS ****/ +/**************/ + SchemaAlignmentDialog._addItem = function(json) { var subject = null; var statementGroups = null; @@ -249,6 +253,10 @@ SchemaAlignmentDialog._itemToJSON = function (item) { statementGroups: lst}; }; +/******************** + * STATEMENT GROUPS * + ********************/ + SchemaAlignmentDialog._addStatementGroup = function(item, json) { var property = null; var statements = null; @@ -290,12 +298,17 @@ SchemaAlignmentDialog._statementGroupToJSON = function (statementGroup) { statements: lst}; }; +/************** + * STATEMENTS * + **************/ SchemaAlignmentDialog._addStatement = function(container, datatype, json) { var qualifiers = null; + var references = null; var value = null; if (json) { qualifiers = json.qualifiers; + references = json.references; value = json.value; } @@ -306,10 +319,12 @@ SchemaAlignmentDialog._addStatement = function(container, datatype, json) { }).appendTo(toolbar1); var inputContainer = $('
').addClass('wbs-target-input').appendTo(statement); SchemaAlignmentDialog._initField(inputContainer, datatype, value); - var right = $('
').addClass('wbs-right').appendTo(statement); - // If we are in a mainsnak, add qualifiers and references + // If we are in a mainsnak... if (container.parents('.wbs-statement').length == 0) { + + // add qualifiers... + var right = $('
').addClass('wbs-right').appendTo(statement); var qualifierContainer = $('
').addClass('wbs-qualifier-container').appendTo(right); var toolbar2 = $('
').addClass('wbs-toolbar').appendTo(right); $('').addClass('wbs-add-qualifier').text('add qualifier').click(function() { @@ -320,6 +335,27 @@ SchemaAlignmentDialog._addStatement = function(container, datatype, json) { SchemaAlignmentDialog._addQualifier(qualifierContainer, qualifiers[i]); } } + + // and references + var referencesToggleContainer = $('
').addClass('wbs-references-toggle').appendTo(statement); + var referencesToggle = $('').appendTo(referencesToggleContainer); + right = $('
').addClass('wbs-right').appendTo(statement); + var referenceContainer = $('
').addClass('wbs-reference-container').appendTo(right); + referencesToggle.click(function () { + referenceContainer.toggle(100); + }); + var right2 = $('
').addClass('wbs-right').appendTo(right); + var toolbar3 = $('
').addClass('wbs-toolbar').appendTo(right2); + $('').addClass('wbs-add-reference').text('add reference').click(function() { + SchemaAlignmentDialog._addReference(referenceContainer, null); + SchemaAlignmentDialog._updateReferencesNumber(referenceContainer); + }).appendTo(toolbar3); + if (references) { + for (var i = 0; i != references.length; i++) { + SchemaAlignmentDialog._addReference(referenceContainer, references[i]); + } + } + SchemaAlignmentDialog._updateReferencesNumber(referenceContainer); } container.append(statement); } @@ -327,16 +363,24 @@ SchemaAlignmentDialog._addStatement = function(container, datatype, json) { SchemaAlignmentDialog._statementToJSON = function (statement) { var inputContainer = statement.find(".wbs-target-input").first(); var qualifiersList = new Array(); - statement.find('.wbs-qualifier').each(function () { + var referencesList = new Array(); + statement.find('.wbs-qualifier-container').first().children().each(function () { qualifiersList.push(SchemaAlignmentDialog._qualifierToJSON($(this))); }); + statement.find('.wbs-reference-container').first().children().each(function () { + referencesList.push(SchemaAlignmentDialog._referenceToJSON($(this))); + }); return { value:SchemaAlignmentDialog._inputContainerToJSON(inputContainer), qualifiers: qualifiersList, - references:[], + references: referencesList, }; }; +/************** + * QUALIFIERS * + **************/ + SchemaAlignmentDialog._addQualifier = function(container, json) { var property = null; var value = null; @@ -351,7 +395,6 @@ SchemaAlignmentDialog._addQualifier = function(container, json) { var right = $('
').addClass('wbs-right').appendTo(qualifier); var statementContainer = $('
').addClass('wbs-statement-container').appendTo(right); SchemaAlignmentDialog._initPropertyField(inputContainer, statementContainer, property); - console.log(json); if (value && property) { SchemaAlignmentDialog._addStatement(statementContainer, property.datatype, {value:value}); } @@ -370,6 +413,61 @@ SchemaAlignmentDialog._qualifierToJSON = function(elem) { }; } +/************** + * REFERENCES * + **************/ + +SchemaAlignmentDialog._addReference = function(container, json) { + var snaks = null; + if (json) { + snaks = json.snaks; + } + + var reference = $('
').addClass('wbs-reference').appendTo(container); + var referenceHeader = $('
').addClass('wbs-reference-header').appendTo(reference); + var toolbarRef = $('
').addClass('wbs-toolbar').appendTo(referenceHeader); + $('').attr('alt', 'remove reference').click(function() { + reference.remove(); + SchemaAlignmentDialog._updateReferencesNumber(container); + }).appendTo(toolbarRef); + var right = $('
').addClass('wbs-right').appendTo(reference); + var qualifierContainer = $('
').addClass('wbs-qualifier-container').appendTo(right); + var toolbar2 = $('
').addClass('wbs-toolbar').appendTo(right); + $('').addClass('wbs-add-qualifier').text('add').click(function() { + SchemaAlignmentDialog._addQualifier(qualifierContainer, null); + }).appendTo(toolbar2); + + if (snaks) { + for (var i = 0; i != snaks.length; i++) { + SchemaAlignmentDialog._addQualifier(qualifierContainer, snaks[i]); + } + } else { + SchemaAlignmentDialog._addQualifier(qualifierContainer, null); + } +} + +SchemaAlignmentDialog._referenceToJSON = function(reference) { + var snaks = reference.find('.wbs-qualifier-container').first().children(); + var snaksList = new Array(); + snaks.each(function () { + snaksList.push(SchemaAlignmentDialog._qualifierToJSON($(this))); + }); + return {snaks:snaksList}; +} + +SchemaAlignmentDialog._updateReferencesNumber = function(container) { + var childrenCount = container.children().length; + var statement = container.parents('.wbs-statement'); + console.log(statement); + var a = statement.find('.wbs-references-toggle a').first(); + console.log(a); + a.html(childrenCount+' references'); +} + +/************************ + * FIELD INITIALIZATION * + ************************/ + SchemaAlignmentDialog._getPropertyType = function(pid, callback) { $.ajax({ url:'https://www.wikidata.org/w/api.php', diff --git a/extensions/wikidata/module/styles/dialogs/schema-alignment-dialog.less b/extensions/wikidata/module/styles/dialogs/schema-alignment-dialog.less index 9154afc36..8a0e7ae50 100644 --- a/extensions/wikidata/module/styles/dialogs/schema-alignment-dialog.less +++ b/extensions/wikidata/module/styles/dialogs/schema-alignment-dialog.less @@ -82,7 +82,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. width: 120px; } -.wbs-qualifier .wbs-prop-input, .wbs-reference .wbs-prop-input { +.wbs-qualifier .wbs-prop-input { width: 85px; } @@ -100,18 +100,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. padding: 2px; } -.wbs-add-item, .wbs-add-statement-group, .wbs-add-statement, .wbs-add-qualifier { +.wbs-add-item, .wbs-add-statement-group, .wbs-add-statement, .wbs-add-qualifier, .wbs-add-reference { color: #0645ad !important; font-size: 0.9em; } -.wbs-statement-group-container, .wbs-statement-container, .wbs-qualifier-container { +.wbs-statement-group-container, .wbs-statement-container, .wbs-qualifier-container, .wbs-reference-container { width: 100%; display: block; overflow: auto; } -.wbs-item, .wbs-statement-group, .wbs-statement, .wbs-qualifier { +.wbs-item, .wbs-statement-group, .wbs-statement, .wbs-qualifier, .wbs-reference { display: block; overflow: auto; } @@ -142,13 +142,26 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. position: relative; } -.wbs-qualifier .wbs-right, .wbs-reference .wbs-right { +.wbs-qualifier .wbs-right { width: 70%; position: absolute; top: 0px; margin-left: 100px; } +.wbs-reference > .wbs-right { + width: 100%; +} + +.wbs-references-toggle { + width: 12em; + margin: 5px; +} + +.wbs-references-toggle a { + color: #0645ad !important; +} + .wbs-qualifier .wbs-target-input { width: 90px; } @@ -157,6 +170,22 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. overflow: hidden; } +.wbs-reference-header { + height: 20px; + overflow: auto; + display: block; + background-color: #b6c8ec; +} + +.wbs-reference { + background-color: #eaf3ff; + margin-bottom: 5px; +} + +.wbs-reference .wbs-statement { + background-color: #eaf3ff; +} + .schema-alignment-columns-header { margin-bottom: 0.3em; } diff --git a/extensions/wikidata/src/org/openrefine/wikidata/exporters/QuickStatementsExporter.java b/extensions/wikidata/src/org/openrefine/wikidata/exporters/QuickStatementsExporter.java index ae67c9484..52f90c536 100644 --- a/extensions/wikidata/src/org/openrefine/wikidata/exporters/QuickStatementsExporter.java +++ b/extensions/wikidata/src/org/openrefine/wikidata/exporters/QuickStatementsExporter.java @@ -20,6 +20,7 @@ import org.wikidata.wdtk.datamodel.interfaces.ItemDocument; import org.wikidata.wdtk.datamodel.interfaces.ItemIdValue; import org.wikidata.wdtk.datamodel.interfaces.MonolingualTextValue; import org.wikidata.wdtk.datamodel.interfaces.QuantityValue; +import org.wikidata.wdtk.datamodel.interfaces.Reference; import org.wikidata.wdtk.datamodel.interfaces.Snak; import org.wikidata.wdtk.datamodel.interfaces.SnakGroup; import org.wikidata.wdtk.datamodel.interfaces.Statement; @@ -89,6 +90,12 @@ public class QuickStatementsExporter implements WriterExporter { for(SnakGroup q : claim.getQualifiers()) { translateSnakGroup(q, false, writer); } + for(Reference r : statement.getReferences()) { + for(SnakGroup g : r.getSnakGroups()) { + translateSnakGroup(g, true, writer); + } + break; // QS only supports one reference + } writer.write("\n"); } } diff --git a/extensions/wikidata/src/org/openrefine/wikidata/schema/WbStatementExpr.java b/extensions/wikidata/src/org/openrefine/wikidata/schema/WbStatementExpr.java index 8725e7159..7c9f1705e 100644 --- a/extensions/wikidata/src/org/openrefine/wikidata/schema/WbStatementExpr.java +++ b/extensions/wikidata/src/org/openrefine/wikidata/schema/WbStatementExpr.java @@ -50,6 +50,12 @@ public class WbStatementExpr extends BiJsonizable { expr.write(writer, options); } writer.endArray(); + writer.key("references"); + writer.array(); + for (WbReferenceExpr expr : referenceExprs) { + expr.write(writer, options); + } + writer.endArray(); } public static WbStatementExpr fromJSON(JSONObject obj) throws JSONException { @@ -95,13 +101,21 @@ public class WbStatementExpr extends BiJsonizable { public Statement evaluate(ExpressionContext ctxt, ItemIdValue subject, PropertyIdValue propertyId) throws SkipStatementException { Value mainSnakValue = mainSnakValueExpr.evaluate(ctxt); Snak mainSnak = Datamodel.makeValueSnak(propertyId, mainSnakValue); + + // evaluate qualifiers List qualifiers = new ArrayList(qualifierExprs.size()); for (WbSnakExpr qExpr : qualifierExprs) { qualifiers.add(qExpr.evaluate(ctxt)); } List groupedQualifiers = groupSnaks(qualifiers); Claim claim = Datamodel.makeClaim(subject, mainSnak, groupedQualifiers); + + // evaluate references List references = new ArrayList(); + for (WbReferenceExpr rExpr : referenceExprs) { + references.add(rExpr.evaluate(ctxt)); + } + StatementRank rank = StatementRank.NORMAL; return Datamodel.makeStatement(claim, references, rank, ""); }