UNPKG

sparnatural

Version:

Visual client-side SPARQL query builder and knowledge graph exploration tool

113 lines 5.82 kB
import { AbstractWidget, ValueRepetition } from "./AbstractWidget"; import { DataFactory } from 'rdf-data-factory'; import "select2"; import "select2/dist/css/select2.css"; import { I18n } from "../../settings/I18n"; import { NoOpListDataProvider } from "../datasources/NoOpDataProviders"; import { mergeDatasourceResults } from "../datasources/SparqlDataProviders"; const factory = new DataFactory(); export class ListWidget extends AbstractWidget { constructor(parentComponent, config, startClassVal, objectPropVal, endClassVal) { super("list-widget", parentComponent, null, startClassVal, objectPropVal, endClassVal, ValueRepetition.MULTIPLE); this.configuration = config; this.startClassVal = startClassVal; this.objectPropVal = objectPropVal; this.endClassVal = endClassVal; } render() { super.render(); this.selectHtml = $(`<select style="width:100%; min-width:200px;"></select>`); this.html.append(this.selectHtml); let noItemsHtml = $(`<div class="no-items" style="display: none; font-style:italic;"> ${I18n.labels.ListWidgetNoItem} </div>`); let errorHtml = $(`<div class="no-items" style="display: none; font-style:italic;"> ${I18n.labels.ListWidgetNoItem} </div>`); let callback = (items) => { if (items.length > 0) { this.selectHtml.append($("<option value=''>" + I18n.labels.ListWidgetSelectValue + "</option>")); // find distinct values of the 'group' binding const groups = [...new Set(items.map(item => item.group))]; if (groups.length == 1 && groups[0] == undefined) { // no groups were defined at all items.forEach(item => { // select item label : either displayed label, or itemLabel if provided let itemLabel = item.itemLabel ? item.itemLabel : item.label; this.selectHtml.append($("<option value='" + JSON.stringify(item.term) + "' data-itemLabel='" + itemLabel + "'>" + item.label + "</option>")); }); } else { // we found some groups, organise the list content with optgroup let mergedResult = mergeDatasourceResults(items); const groupsAfterMerge = [...new Set(mergedResult.map(item => item.group))]; groupsAfterMerge.forEach(group => { let html = "<optgroup label=\"" + group + "\">"; mergedResult.filter(item => (item.group == group)).forEach(item => { // select item label : either displayed label, or itemLabel if provided let itemLabel = item.itemLabel ? item.itemLabel : item.label; html += "<option value='" + JSON.stringify(item.term) + "' data-itemLabel='" + itemLabel + "'>" + item.label + "</option>"; }); html += "</optgroup>"; this.selectHtml.append($(html)); }); } this.selectHtml = this.selectHtml.select2({ // use the minimumResultsForSearch parameter to avoid using a search box when only a few items are present minimumResultsForSearch: 20, // pass a JQUery object so that HTML markup is preserved // TODO : this does not work ATM // templateResult: function formatLabel(label:any) {return $(label)}, width: "style" }); // set a listener for when a value is selected this.selectHtml.on("select2:close", (e) => { let option = e.currentTarget.selectedOptions; if (option.length > 1) throw Error("List widget should allow only for one el to be selected!"); // this is the placeholder if (option[0].value == "") return; let itemLabel = option[0].getAttribute("data-itemLabel"); let listWidgetValue = this.buildValue(option[0].value, itemLabel); this.triggerRenderWidgetVal(listWidgetValue); }); } else { this.html.append(noItemsHtml); } // switch off spinner this.toggleSpinner(''); }; // TODO : this is not working for now let errorCallback = (payload) => { this.html.append(errorHtml); }; // toggle spinner before loading this.toggleSpinner(I18n.labels.AutocompleteSpinner_Searching); // if there are some provided values like in sh:in... if (this.configuration.values?.length > 0) { this.configuration.dataProvider.getListContent(this.configuration.values, callback, errorCallback); } else { this.configuration.dataProvider.getListContent(this.startClassVal.type, this.objectPropVal.type, this.endClassVal.type, callback, errorCallback); } return this; } // separate the creation of the value from the widget code itself // so that it can be overriden by LiteralListWidget buildValue(termString, label) { let term = JSON.parse(termString); return { label: label, criteria: { rdfTerm: term } }; } parseInput(input) { return input; } } // The default implementation of ListConfiguration ListWidget.defaultConfiguration = { dataProvider: new NoOpListDataProvider(), values: undefined }; //# sourceMappingURL=ListWidget.js.map