UNPKG

sparnatural

Version:

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

208 lines (188 loc) 7.88 kB
/** * A single line/criteria **/ import ISparnaturalSpecification from "../../../../spec-providers/ISparnaturalSpecification"; import UnselectBtn from "../../../buttons/UnselectBtn"; import ObjectPropertyGroup from "./objectpropertygroup/ObjectPropertyGroup"; import EndClassGroup from "./startendclassgroup/EndClassGroup"; import StartClassGroup from "./startendclassgroup/StartClassGroup"; import GroupWrapper from "../GroupWrapper"; import { OptionsGroup, OptionTypes } from "./optionsgroup/OptionsGroup"; import HTMLComponent from "../../../HtmlComponent"; import { SelectedVal } from "../../../SelectedVal"; import { EndClassWidgetGroup, EndClassWidgetValue, } from "./startendclassgroup/EndClassWidgetGroup"; import ActionsGroup from "../../../buttons/actions/ActionsGroup"; import { triggerOption } from "../groupwrapperevents/events/TriggerOption"; import { I18n } from "../../../../settings/I18n"; class CriteriaGroup extends HTMLComponent { StartClassGroup: StartClassGroup; OptionsGroup: OptionsGroup; // optional or notexists ObjectPropertyGroup: ObjectPropertyGroup; EndClassGroup: EndClassGroup; endClassWidgetGroup: EndClassWidgetGroup; ActionsGroup: ActionsGroup; specProvider: ISparnaturalSpecification; ParentGroupWrapper: GroupWrapper; unselectBtn: UnselectBtn; constructor( parentComponent: GroupWrapper, specProvider: any, startClassVal?: SelectedVal, startClassEyeBtn?: boolean ) { super("CriteriaGroup", parentComponent, null); this.specProvider = specProvider; this.ParentGroupWrapper = parentComponent; this.StartClassGroup = new StartClassGroup( this, this.specProvider, I18n.labels.StartClassTemporaryLabel, startClassVal, // Decides if the selectviewvarBtn is rendered on the startClass. That is the case only for the first one startClassEyeBtn ); } render(): this { super.render(); this.#renderChildComponents(); this.unselectBtn = new UnselectBtn(this, () => { // caught in Parentcomponent this.html[0].dispatchEvent( new CustomEvent("onRemoveGrp", { bubbles: true }) ); }).render(); return this; } #renderChildComponents() { // create all the elements of the criteria this.StartClassGroup.render(); this.OptionsGroup = new OptionsGroup(this, this.specProvider).render(); this.ObjectPropertyGroup = new ObjectPropertyGroup( this, this.specProvider, I18n.labels.ObjectPropertyTemporaryLabel ).render(); this.EndClassGroup = new EndClassGroup(this, this.specProvider).render(); this.endClassWidgetGroup = new EndClassWidgetGroup(this, this.specProvider); this.ActionsGroup = new ActionsGroup(this, this.specProvider).render(); this.#assembleComponents(); } #assembleComponents = () => { // 1. User selects StartClassVal this.html[0].addEventListener( "StartClassGroupSelected", (e: CustomEvent) => { e.stopImmediatePropagation(); if (!this.#isSelectedVal(e.detail)) throw Error( "StartClassGroupSelected expects object of type SelectedVal" ); this.ObjectPropertyGroup.onStartClassGroupSelected(e.detail); this.EndClassGroup.onStartClassGroupSelected(e.detail); } ); // 2. User Selects EndClassVal this.html[0].addEventListener("EndClassGroupSelected", (e: CustomEvent) => { e.stopImmediatePropagation(); if (!this.#isSelectedVal(e.detail)) throw Error("EndClassGroupSelected expects object of type SelectedVal"); this.ObjectPropertyGroup.onEndClassGroupSelected(e.detail); }); // 3. Automatically selected or User selects ObjectPropertyGrpVal this.html[0].addEventListener( "onObjectPropertyGroupSelected", (e: CustomEvent) => { e.stopImmediatePropagation(); if (!this.#isSelectedVal(e.detail)) throw Error( "onObjectPropertyGroupSelected expects object of type SelectedVal" ); // if there is already a where connection or widget values selected, don't change anything if ( !this.ParentGroupWrapper.whereChild && this.endClassWidgetGroup?.widgetValues?.length === 0 ) { this.EndClassGroup.onObjectPropertyGroupSelected(e.detail); this.endClassWidgetGroup.render(); } this.OptionsGroup.onObjectPropertyGroupSelected( this.ParentGroupWrapper.optionState ); // if there is already a andSibling don't allow to rerender the ActionAnd again if (!this.ParentGroupWrapper.andSibling) this.ActionsGroup.onObjectPropertyGroupSelected(); // if property has a sparqlService, switch the state if (this.specProvider.getProperty(e.detail.type).getServiceEndpoint()) { triggerOption(this.ParentGroupWrapper, OptionTypes.SERVICE); } else { triggerOption( this.ParentGroupWrapper, this.ParentGroupWrapper.optionState ); } } ); // gets called by the widget. this.html[0].addEventListener("renderWidgetVal", (e: CustomEvent) => { e.stopImmediatePropagation(); if (e.detail == "" || !e.detail) throw Error( 'No widgetValue received. Widget Value needs to be provided for "renderWidgetVal"' ); if (Array.isArray(e.detail)) { // if there is an array with values provided, render all of them e.detail.forEach((v) => this.endClassWidgetGroup.renderWidgetVal(v)); } else { this.endClassWidgetGroup.renderWidgetVal(e.detail); } }); // when inputgot selected then we remove the where btn and EditComponents this.html[0].addEventListener("removeEditComponents", (e: CustomEvent) => { e.stopImmediatePropagation(); this.EndClassGroup.editComponents?.html?.empty()?.remove(); }); //gets called when a user removes a previously selected widgetValue //removes the widgetValue from the widgetvalues list in the widget this.html[0].addEventListener("updateWidgetList", (e: CustomEvent) => { if (!("unselectedVal" in e.detail)) throw Error( "updateWidgetList expects an object of type EndClassWidgetValue" ); e.stopImmediatePropagation(); this.html[0].dispatchEvent( new CustomEvent("generateQuery", { bubbles: true }) ); }); // gets called when the user adds widgetvalues or removes widgetvalues this.html[0].addEventListener("renderWidgetWrapper", (e: CustomEvent) => { if (!("selectedValues" in e.detail) && e.detail.selectedValues.isArray) throw Error("renderWidgetWrapper expects list of selected values."); e.stopImmediatePropagation(); // removeEditComponents: if add btn got clicked mutiple times or the old widgetwrapper is still rendered while the last selectedvalue got deleted this.html[0].dispatchEvent(new CustomEvent("removeEditComponents")); if ( e.detail.selectedValues.length === 0 && // if we are not in the case that we edit the last value in the list // note : editedValue contains the value being edited - it could be passed again to the widget, maybe, instead // of keeping the state in the widget !e.detail.editedValue ) { // Render WidgetsWrapper and ActionWhere this.EndClassGroup.editComponents.render(); this.html[0].dispatchEvent( new CustomEvent("onGrpInputNotCompleted", { bubbles: true }) ); } else { //we only need widgetswrapper this.EndClassGroup.editComponents.renderWidgetsWrapper(); } }); }; #isSelectedVal(payload: any): payload is SelectedVal { return "type" in payload && "variable" in payload; } } export default CriteriaGroup;