sparnatural
Version:
Visual client-side SPARQL query builder and knowledge graph exploration tool
152 lines (133 loc) • 4.55 kB
text/typescript
import { BlankTerm, IriTerm, LiteralTerm, Pattern } from "sparqljs";
import { SelectedVal } from "../SelectedVal";
import HTMLComponent from "../HtmlComponent";
import LoadingSpinner from "./LoadingSpinner";
import { DataFactory, Literal } from "rdf-data-factory";
import { Term } from "@rdfjs/types/data-model";
const factory = new DataFactory();
// The ValueType decides wheter a widget has the possibility to choose only one value or multiple values
// example for multiples: List of countries in ListWidget
// example for single: Search string in SearchWidget
export enum ValueRepetition {
SINGLE, // only one value can be chosen.
MULTIPLE, // multiple values can be selected like a list of values
}
export interface WidgetValue {
value: {
label: string; // that's the human readable string representation shown as a WidgetValue to the user
};
key: () => string; // a function that returns the value key as a string.
}
/**
* Generic RDFTerm value structure, either an IRI or a Literal with lang or datatype
*/
export class RDFTerm {
type: string;
value: string;
"xml:lang"?: string;
datatype?: string;
constructor(term: Term) {
switch (term.termType) {
case "Literal":
this.type = "literal";
break;
case "BlankNode":
this.type = "bnode";
break;
case "NamedNode":
this.type = "uri";
break;
default:
throw new Error("Unsupported termType here " + term.termType);
}
this.value = term.value;
this["xml:lang"] =
term instanceof Literal ? (term as Literal).language : undefined;
this.datatype =
term instanceof Literal ? (term as Literal).datatype.value : undefined;
}
}
export class RdfTermValue implements WidgetValue {
value: {
label: string;
rdfTerm: RDFTerm;
};
key(): string {
return this.value.rdfTerm.value;
}
constructor(v: RdfTermValue["value"]) {
this.value = v;
}
}
export abstract class AbstractWidget extends HTMLComponent {
public valueRepetition: ValueRepetition;
startClassVal: SelectedVal;
objectPropVal: SelectedVal;
endClassVal: SelectedVal;
protected blockStartTriple = false;
protected blockObjectPropTriple = false;
protected blockEndTriple = false;
protected spinner = new LoadingSpinner(this).render();
constructor(
baseCssClass: string,
parentComponent: HTMLComponent,
widgetHTML: JQuery<HTMLElement>,
startClassVal: SelectedVal,
objectPropVal: SelectedVal,
endClassVal: SelectedVal,
valueRepetition: ValueRepetition
) {
super(baseCssClass, parentComponent, widgetHTML);
this.startClassVal = startClassVal;
this.objectPropVal = objectPropVal;
this.endClassVal = endClassVal;
this.valueRepetition = valueRepetition;
}
render(): this {
super.render();
this.spinner.render();
return this;
}
// Is used to parse the inputs from the ISparnaturalJson e.g "preloaded" queries
abstract parseInput(value: WidgetValue["value"]): WidgetValue;
// fires the event to render the label of the WidgetValue on the UI
// can take either a single value or an array of values
triggerRenderWidgetVal(widgetValue: WidgetValue | WidgetValue[]) {
this.html[0].dispatchEvent(
new CustomEvent("renderWidgetVal", {
bubbles: true,
detail: widgetValue,
})
);
}
// Method to disable the widget
disableWidget() {
// Add a 'disabled-widget' class to visually indicate it's disabled
//this.html[0].classList.add("disabled-widget");
// Disable all input elements within the widget's HTML container
const inputs = this.html[0].querySelectorAll(
"input, button, select, textarea"
);
inputs.forEach((element) => {
element.setAttribute("disabled", "true");
});
}
// Method to enable the widget
enableWidget() {
// Remove the 'disabled-widget' class to restore normal appearance
//this.html[0].classList.remove("disabled-widget");
// Enable all input elements within the widget's HTML container
const inputs = this.html[0].querySelectorAll(
"input, button, select, textarea"
);
inputs.forEach((element) => {
element.removeAttribute("disabled");
});
}
// toggle spinner component when loading a datasource
toggleSpinner(message?: string) {
const elements = this.spinner.html[0].getElementsByClassName("load");
if (elements.length > 0) elements[0].classList.toggle("show");
if (message != null) this.spinner.renderMessage(message);
}
}