Skip to content

Commit

Permalink
Merge pull request #4876 from inception-project/feature/4875-Add-know…
Browse files Browse the repository at this point in the history
…ledge-base-browser-to-multi-value-concept-feature-editor

#4875 - Add knowledge-base browser to multi-value concept feature editor
  • Loading branch information
reckart authored Jun 13, 2024
2 parents 45b88ff + 528e13e commit b6ee369
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import static de.tudarmstadt.ukp.inception.kb.ConceptFeatureValueType.INSTANCE;
import static de.tudarmstadt.ukp.inception.support.lambda.LambdaBehavior.visibleWhen;

import java.util.Optional;
import java.util.Set;

import org.apache.wicket.ajax.AjaxRequestTarget;
Expand All @@ -34,13 +33,12 @@
import org.wicketstuff.event.annotation.OnEvent;

import de.tudarmstadt.ukp.clarin.webanno.model.Project;
import de.tudarmstadt.ukp.inception.kb.ConceptFeatureTraits;
import de.tudarmstadt.ukp.inception.kb.ConceptFeatureTraits_ImplBase;
import de.tudarmstadt.ukp.inception.kb.KnowledgeBaseService;
import de.tudarmstadt.ukp.inception.kb.graph.KBConcept;
import de.tudarmstadt.ukp.inception.kb.graph.KBInstance;
import de.tudarmstadt.ukp.inception.kb.graph.KBObject;
import de.tudarmstadt.ukp.inception.kb.model.KnowledgeBase;
import de.tudarmstadt.ukp.inception.rendering.editorstate.FeatureState;
import de.tudarmstadt.ukp.inception.schema.api.feature.FeatureSupportRegistry;
import de.tudarmstadt.ukp.inception.support.lambda.LambdaAjaxLink;
import de.tudarmstadt.ukp.inception.ui.kb.event.AjaxConceptNavigateEvent;
Expand All @@ -60,18 +58,16 @@ public class BrowseKnowledgeBaseDialogContentPanel
private final IModel<KBObject> concept;
private final IModel<KBObject> instance;

public BrowseKnowledgeBaseDialogContentPanel(String aId, IModel<FeatureState> aModel)
public BrowseKnowledgeBaseDialogContentPanel(String aId, IModel<Project> aProject,
IModel<KBObject> aModel, IModel<ConceptFeatureTraits_ImplBase> aTraits)
{
super(aId, aModel);

var project = aModel.getObject().feature.getProject();
var project = aProject.getObject();

ConceptFeatureTraits conceptFeatureTraits = fsRegistry
.readTraits(aModel.getObject().feature, ConceptFeatureTraits::new);
knowledgeBase = Model.of(findKnowledgeBase(project, aTraits.getObject()));

knowledgeBase = Model.of(findKnowledgeBase(project, conceptFeatureTraits));

KBObject kbObject = (KBObject) aModel.getObject().value;
var kbObject = (KBObject) aModel.getObject();
if (knowledgeBase.isPresent().getObject() && kbObject != null
&& !(kbObject instanceof KBInstance || kbObject instanceof KBConcept)) {
kbObject = kbService.readItem(knowledgeBase.getObject(), kbObject.getIdentifier())
Expand All @@ -91,16 +87,16 @@ public BrowseKnowledgeBaseDialogContentPanel(String aId, IModel<FeatureState> aM

instanceListBrowser = new InstanceListBrowser("instances", concept, instance);
instanceListBrowser.add(visibleWhen(() -> Set.of(ANY_OBJECT, INSTANCE)
.contains(conceptFeatureTraits.getAllowedValueType())));
.contains(aTraits.getObject().getAllowedValueType())));
instanceListBrowser.setOutputMarkupPlaceholderTag(true);

conceptTreeBrowser = new ConceptTreeBrowser("concepts", knowledgeBase, concept);
conceptTreeBrowser.add(visibleWhen(() -> Set.of(ANY_OBJECT, CONCEPT, INSTANCE)
.contains(conceptFeatureTraits.getAllowedValueType())));
.contains(aTraits.getObject().getAllowedValueType())));
conceptTreeBrowser.setConceptNavigationEnabled(
Set.of(ANY_OBJECT, INSTANCE).contains(conceptFeatureTraits.getAllowedValueType()));
Set.of(ANY_OBJECT, INSTANCE).contains(aTraits.getObject().getAllowedValueType()));
conceptTreeBrowser.setConceptSelectionEnabled(
Set.of(ANY_OBJECT, CONCEPT).contains(conceptFeatureTraits.getAllowedValueType()));
Set.of(ANY_OBJECT, CONCEPT).contains(aTraits.getObject().getAllowedValueType()));
conceptTreeBrowser.setOutputMarkupPlaceholderTag(true);

queue(instanceListBrowser, conceptTreeBrowser);
Expand All @@ -116,10 +112,10 @@ public void onConceptNavigationEvent(AjaxConceptNavigateEvent aEvent)
}

private KnowledgeBase findKnowledgeBase(Project project,
ConceptFeatureTraits conceptFeatureTraits)
ConceptFeatureTraits_ImplBase conceptFeatureTraits)
{
if (conceptFeatureTraits.getRepositoryId() != null) {
Optional<KnowledgeBase> kb = kbService.getKnowledgeBaseById(project,
var kb = kbService.getKnowledgeBaseById(project,
conceptFeatureTraits.getRepositoryId());
if (kb.isPresent() && kb.get().isEnabled() && kb.get().isSupportConceptLinking()) {
return kb.get();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
<i class="fas fa-external-link-alt"/>
</a>
<span class="float-end">
<a wicket:id="openBrowseDialog" class="float-end">
<i class="fas fa-sitemap"/>
</a>
<span wicket:id="deprecationMarker" class="badge rounded-pill text-secondary border border-secondary">deprecated</span>
<span wicket:id="disabledKBWarning"/>
</span>
Expand All @@ -37,10 +40,7 @@
<div class="input-group-text border-0">
<span wicket:id="iriInfoBadge"/>
</div>
<button wicket:id="openBrowseDialog" class="btn btn-outline-secondary border-secondary-subtle border-top-0 border-bottom-0" type="button">
<i class="fas fa-sitemap"/>
</button>
<input class="flex-content border-0" wicket:id="value" type="text"/>
<input class="flex-content border-bottom-0 border-end-0 border-top-0 " wicket:id="value" type="text"/>
</div>
</ul>
<ul wicket:id="descriptionContainer" class="list-group-item p-0 m-0 overflow-hidden" readonly>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import org.apache.wicket.markup.html.link.ExternalLink;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.request.IRequestParameters;
import org.apache.wicket.request.http.WebRequest;
import org.apache.wicket.spring.injection.annot.SpringBean;
Expand Down Expand Up @@ -96,10 +97,10 @@ public ConceptFeatureEditor(String aId, MarkupContainer aItem, IModel<FeatureSta
{
super(aId, aItem, aModel);

AnnotationFeature feat = getModelObject().feature;
ConceptFeatureTraits traits = readFeatureTraits(feat);
var feat = getModelObject().feature;
var traits = readFeatureTraits(feat);

IModel<String> iriModel = LoadableDetachableModel.of(this::iriTooltipValue);
var iriModel = LoadableDetachableModel.of(this::iriTooltipValue);

iriBadge = new IriInfoBadge("iriInfoBadge", iriModel);
iriBadge.setOutputMarkupPlaceholderTag(true);
Expand Down Expand Up @@ -163,7 +164,12 @@ private boolean isBrowsingAllowed()

private void actionOpenBrowseDialog(AjaxRequestTarget aTarget)
{
var content = new BrowseKnowledgeBaseDialogContentPanel(CONTENT_ID, getModel());
var traits = featureSupportRegistry.readTraits(getModelObject().feature,
ConceptFeatureTraits::new);

var content = new BrowseKnowledgeBaseDialogContentPanel(CONTENT_ID,
getModel().map(fs -> fs.getFeature().getProject()),
getModel().map(fs -> (KBObject) fs.value), Model.of(traits));
dialog.open(content, aTarget);
}

Expand Down Expand Up @@ -218,8 +224,7 @@ private void selectItem(AjaxRequestTarget aTarget, KBObject aKBObject)
{
getModelObject().value = aKBObject;
dialog.close(aTarget);
send(focusComponent, BUBBLE,
new FeatureEditorValueChangedEvent(ConceptFeatureEditor.this, aTarget));
send(focusComponent, BUBBLE, new FeatureEditorValueChangedEvent(this, aTarget));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,18 @@
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
<wicket:panel>
<div wicket:id="dialog"/>
<div class="row form-row" wicket:enclosure="value">
<label wicket:for="value" wicket:enclosure="feature" class="feature-editor-label col-form-label">
<span wicket:id="feature"/>
<span class="float-end">
<a wicket:id="openBrowseDialog" class="float-end">
<i class="fas fa-sitemap"/>
</a>
<span wicket:id="disabledKBWarning"/>
</span>
</label>
<div class="feature-editor-value">
<div class="feature-editor-value d-flex flex-row">
<select wicket:id="value" type="text"/>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,29 +17,44 @@
*/
package de.tudarmstadt.ukp.inception.ui.kb.feature;

import static org.apache.wicket.event.Broadcast.BUBBLE;
import static org.apache.wicket.extensions.ajax.markup.html.modal.ModalDialog.CONTENT_ID;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.apache.wicket.MarkupContainer;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.markup.html.form.FormComponent;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.wicketstuff.event.annotation.OnEvent;

import com.googlecode.wicket.jquery.core.JQueryBehavior;
import com.googlecode.wicket.jquery.core.template.IJQueryTemplate;
import com.googlecode.wicket.kendo.ui.form.multiselect.lazy.MultiSelect;
import com.googlecode.wicket.kendo.ui.renderer.ChoiceRenderer;

import de.tudarmstadt.ukp.clarin.webanno.model.AnnotationFeature;
import de.tudarmstadt.ukp.inception.bootstrap.BootstrapModalDialog;
import de.tudarmstadt.ukp.inception.editor.action.AnnotationActionHandler;
import de.tudarmstadt.ukp.inception.kb.ConceptFeatureValueType;
import de.tudarmstadt.ukp.inception.kb.KnowledgeBaseService;
import de.tudarmstadt.ukp.inception.kb.MultiValueConceptFeatureTraits;
import de.tudarmstadt.ukp.inception.kb.graph.KBHandle;
import de.tudarmstadt.ukp.inception.kb.graph.KBObject;
import de.tudarmstadt.ukp.inception.rendering.editorstate.AnnotatorState;
import de.tudarmstadt.ukp.inception.rendering.editorstate.FeatureState;
import de.tudarmstadt.ukp.inception.schema.api.feature.FeatureEditorValueChangedEvent;
import de.tudarmstadt.ukp.inception.schema.api.feature.FeatureSupport;
import de.tudarmstadt.ukp.inception.schema.api.feature.FeatureSupportRegistry;
import de.tudarmstadt.ukp.inception.support.kendo.KendoStyleUtils;
import de.tudarmstadt.ukp.inception.support.lambda.LambdaAjaxLink;
import de.tudarmstadt.ukp.inception.support.lambda.LambdaBehavior;
import de.tudarmstadt.ukp.inception.ui.kb.event.AjaxConceptSelectionEvent;
import de.tudarmstadt.ukp.inception.ui.kb.event.AjaxInstanceSelectionEvent;

public class MultiValueConceptFeatureEditor
extends ConceptFeatureEditor_ImplBase
Expand All @@ -49,11 +64,13 @@ public class MultiValueConceptFeatureEditor
private static final String CID_VALUE = "value";

private @SpringBean FeatureSupportRegistry featureSupportRegistry;
private @SpringBean KnowledgeBaseService knowledgeBaseService;

private FormComponent<Collection<KBHandle>> focusComponent;
private BootstrapModalDialog dialog;

private final AnnotationActionHandler handler;
private final IModel<AnnotatorState> stateModel;

private FormComponent<Collection<KBHandle>> focusComponent;
private boolean featureUpdateBehaviorRequested = false;
private boolean featureUpdateBehaviorAdded = false;

Expand All @@ -68,6 +85,13 @@ public MultiValueConceptFeatureEditor(String aId, MarkupContainer aItem,

focusComponent = createInput();
add(focusComponent);

dialog = new BootstrapModalDialog("dialog");
dialog.trapFocus();
queue(dialog);

queue(new LambdaAjaxLink("openBrowseDialog", this::actionOpenBrowseDialog)
.add(LambdaBehavior.visibleWhen(this::isBrowsingAllowed)));
}

@SuppressWarnings("unchecked")
Expand Down Expand Up @@ -156,6 +180,56 @@ protected MultiValueConceptFeatureTraits readFeatureTraits(AnnotationFeature aAn
return (MultiValueConceptFeatureTraits) fs.readTraits(aAnnotationFeature);
}

private boolean isBrowsingAllowed()
{
var traits = featureSupportRegistry.readTraits(getModelObject().feature,
MultiValueConceptFeatureTraits::new);

// There is now KB selector in the browser yet, so we do not show it unless either the
// feature is bound to a specific KB or there is only a single KB in the project.
if (traits.getRepositoryId() == null && knowledgeBaseService
.getEnabledKnowledgeBases(getModelObject().feature.getProject()).size() > 1) {
return false;
}

// Properties are not supported in the browser
if (traits.getAllowedValueType() == ConceptFeatureValueType.PROPERTY) {
return false;
}

return true;
}

private void actionOpenBrowseDialog(AjaxRequestTarget aTarget)
{
var traits = featureSupportRegistry.readTraits(getModelObject().feature,
MultiValueConceptFeatureTraits::new);

var content = new BrowseKnowledgeBaseDialogContentPanel(CONTENT_ID,
getModel().map(fs -> fs.getFeature().getProject()), Model.of(), Model.of(traits));
dialog.open(content, aTarget);
}

@OnEvent
public void onConceptSelectionEvent(AjaxConceptSelectionEvent aEvent)
{
selectItem(aEvent.getTarget(), aEvent.getSelection());
}

@OnEvent
public void onInstanceSelectionEvent(AjaxInstanceSelectionEvent aEvent)
{
selectItem(aEvent.getTarget(), aEvent.getSelection());
}

private void selectItem(AjaxRequestTarget aTarget, KBObject aKBObject)
{
((Collection<KBObject>) getModelObject().value).add(aKBObject);
dialog.close(aTarget);
aTarget.add(this);
send(focusComponent, BUBBLE, new FeatureEditorValueChangedEvent(this, aTarget));
}

private final class KBHandleMultiSelect
extends MultiSelect<KBHandle>
{
Expand Down

0 comments on commit b6ee369

Please sign in to comment.