Skip to content

Commit

Permalink
Feature/finished/iia 1365 implement data refresh on submit for compon…
Browse files Browse the repository at this point in the history
…ent and component set (#248)

* Update version to start feature: IIA-1367-New-Implement-Capability-to-Submit-Data-in-database-for-Component-sets

* Update version to finish feature: IIA-1367-New-Implement-Capability-to-Submit-Data-in-database-for-Component-sets

* Fixed code broken by the git process.

* Some more fixes
  • Loading branch information
swaroopsalvi authored Feb 6, 2025
1 parent e18bf66 commit 37535e9
Show file tree
Hide file tree
Showing 14 changed files with 241 additions and 112 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
package dev.ikm.komet.layout.component.version.field;

import dev.ikm.tinkar.common.bind.annotations.names.RegularName;
import dev.ikm.tinkar.entity.Entity;
import dev.ikm.tinkar.entity.EntityVersion;

import java.util.Set;
import dev.ikm.tinkar.common.id.IntIdSet;

/**
* Represents a field that holds a set of component entities.
Expand All @@ -14,11 +11,9 @@
* manage and interact with a collection of versioned component entities
* in the context of knowledge layout.
*
* @param <E> The type of the entity in the set.
* @param <V> The type of the entity version.
* @TODO should we have separate list and set types, or should they be combined into one component that can be constrained to prohibit addition of duplicates?
*
*/
@RegularName("Component Set Field")
public interface KlComponentSetField<E extends Entity<V>, V extends EntityVersion> extends KlSetField<Set<E>> {
public interface KlComponentSetField extends KlField<IntIdSet> {
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
package dev.ikm.komet.kview.controls;

import dev.ikm.komet.kview.controls.skin.KLComponentSetControlSkin;
import dev.ikm.tinkar.common.id.IntIdSet;
import dev.ikm.tinkar.common.id.impl.IntIdSetArray;
import dev.ikm.tinkar.entity.Entity;
import dev.ikm.tinkar.terms.EntityProxy;
import javafx.beans.property.ListProperty;
import javafx.beans.property.SimpleListProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.scene.control.Control;
import javafx.scene.control.Skin;

import java.util.LinkedList;
import java.util.List;
import java.util.stream.IntStream;

/**
* <p>KLComponentSetControl is a custom control that acts as a template capable of populating multiple,
Expand Down Expand Up @@ -60,14 +59,30 @@ public final void setTitle(String value) {
/**
* This property holds the list of {@link Entity Entities} that have been added to the control
*/
private final ListProperty<EntityProxy> entitiesProperty = new SimpleListProperty<>(FXCollections.observableList(new LinkedList<>()));
public final ListProperty<EntityProxy> entitiesProperty() {
return entitiesProperty;
private final ObjectProperty<IntIdSet> valueProperty = new SimpleObjectProperty<>(this, null);
public final ObjectProperty<IntIdSet> valueProperty() {
return valueProperty;
}
public final List<EntityProxy> getEntitiesList() {
return entitiesProperty.get();
public final IntIdSet getValue() {
return valueProperty.get();
}

public final void setValue(IntIdSet intIdSet) {
valueProperty.set(intIdSet);
}

public void addValue(int nid) {
IntIdSet intIdSet = getValue().with(nid);
setValue(intIdSet);
}

public final void removeValue(int nid) {
IntStream intStream = valueProperty.get().with(nid).intStream().filter((p) -> p != nid);
IntIdSet newIntIdSet = IntIdSetArray.newIntIdSet(intStream.toArray());
valueProperty.set(newIntIdSet);
}


/** {@inheritDoc} */
@Override
protected Skin<?> createDefaultSkin() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ private void setupDragNDrop() {
int nid = EntityService.get().nidForPublicId(dropInfo.publicId());
EntityProxy entity = EntityProxy.make(nid);
if (!(control.getParent() instanceof KLComponentSetControl componentSetControl) ||
!componentSetControl.getEntitiesList().contains(entity)) {
!componentSetControl.getValue().contains(nid)) {
control.setEntity(entity);
addConceptNode(entity);
success = true;
Expand All @@ -230,7 +230,7 @@ private void setupDragNDrop() {

private boolean hasAllowedDND(KLComponentControl control) {
return control != null && control.getEntity() != null &&
((control.getParent() instanceof KLComponentSetControl cs && cs.getEntitiesList().size() > 1) ||
((control.getParent() instanceof KLComponentSetControl cs && cs.getValue().size() > 1) ||
(control.getParent() instanceof KLComponentListControl cl && cl.getEntitiesList().size() > 1));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package dev.ikm.komet.kview.controls.skin;

import dev.ikm.komet.kview.controls.KLComponentSetControl;
import dev.ikm.komet.kview.controls.KLComponentControl;
import dev.ikm.komet.kview.controls.KLComponentSetControl;
import dev.ikm.tinkar.terms.EntityProxy;
import javafx.beans.binding.Bindings;
import javafx.collections.ListChangeListener;
Expand All @@ -26,28 +26,19 @@ public class KLComponentSetControlSkin extends SkinBase<KLComponentSetControl> {

private final Label titleLabel;
private final Button addEntryButton;
private final int FIRST_CC_INDEX = 1;

private final ListChangeListener<Node> nodeListChangeListener = change -> {
while (change.next()) {
while(change.next()) {
if (change.wasAdded() && change.getAddedSize() == 1) {
EntityProxy entity = ((KLComponentControl) change.getAddedSubList().getFirst()).getEntity();
if (entity != null) {
int index = change.getFrom() - FIRST_CC_INDEX;
if (index >= getSkinnable().getEntitiesList().size()) {
getSkinnable().getEntitiesList().add(entity);
} else {
getSkinnable().getEntitiesList().add(index, entity);
EntityProxy entity = ((KLComponentControl) change.getAddedSubList().getFirst()).getEntity();
if (entity != null) {
getSkinnable().addValue(entity.nid());
}
}
} else if (change.wasRemoved() && change.getRemovedSize() == 1) {
int index = change.getFrom() - FIRST_CC_INDEX;
if (index >= 0) {
getSkinnable().getEntitiesList().remove(index);
}
EntityProxy entity = ((KLComponentControl) change.getRemoved().getFirst()).getEntity();
getSkinnable().removeValue(entity.nid());
}
}

};

/**
Expand All @@ -66,37 +57,39 @@ public KLComponentSetControlSkin(KLComponentSetControl control) {

addEntryButton = new Button(getString("add.entry.button.text"));
addEntryButton.getStyleClass().add("add-entry-button");
addEntryButton.setOnAction(e -> {
addEntryButton.setOnAction(e -> createComponentUI(0));
getChildren().addAll(titleLabel, addEntryButton);
getChildren().addListener(nodeListChangeListener);
// Only allow one empty KLComponentControl
addEntryButton.disableProperty().bind(Bindings.createBooleanBinding(() ->
getChildren().stream().anyMatch(n -> n instanceof KLComponentControl cc && cc.getEntity() == null)
,getChildren(), control.valueProperty()));
getSkinnable().setOnMouseDragReleased(Event::consume);
control.getValue().forEach(this::createComponentUI);
}

private void createComponentUI(int nid) {
KLComponentSetControl klComponentSetControl = getSkinnable();
KLComponentControl componentControl = new KLComponentControl();
Subscription subscription = componentControl.entityProperty().subscribe(entity -> {
if (entity != null) {
int index = getChildren().indexOf(componentControl) - FIRST_CC_INDEX;
if (index < control.getEntitiesList().size()) {
control.getEntitiesList().set(index, entity);
} else {
control.getEntitiesList().add(entity);
}
if (nid != 0){
EntityProxy entityProxy = EntityProxy.make(nid);
componentControl.setEntity(entityProxy);
}
Subscription subscription = componentControl.entityProperty().subscribe((ep) -> {
if (ep !=null && !klComponentSetControl.getValue().contains(ep.nid())) {
klComponentSetControl.addValue(ep.nid());
}
});
componentControl.setOnRemoveAction(ev -> {
subscription.unsubscribe();
getChildren().remove(componentControl);
if (control.getEntitiesList().isEmpty()) {
klComponentSetControl.removeValue(nid);
if (klComponentSetControl.getValue().isEmpty()) {
addEntryButton.fire();
}
});
getChildren().add(getChildren().size() - 1, componentControl);
getChildren().add(componentControl);
getSkinnable().requestLayout();
});
getChildren().addAll(titleLabel, addEntryButton);
getChildren().addListener(nodeListChangeListener);
addEntryButton.fire();
// Only allow one empty KLComponentControl
addEntryButton.disableProperty().bind(Bindings.createBooleanBinding(() ->
getChildren().stream().anyMatch(n -> n instanceof KLComponentControl cc && cc.getEntity() == null),
getChildren(), control.entitiesProperty()));

getSkinnable().setOnMouseDragReleased(Event::consume);
}

/** {@inheritDoc} */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,21 @@ public class GenEditingEvent extends Evt {

public static final EvtType<GenEditingEvent> PUBLISH = new EvtType<>(Evt.ANY, "GEN_EDIT_PUBLISH_SEMANTIC");

private List<ObservableField> list;
private List<ObservableField<?>> list;

public GenEditingEvent(Object source,EvtType eventType, List<ObservableField> list){
private int nid;

public GenEditingEvent(Object source,EvtType eventType, List<ObservableField<?>> list, int nid){
super(source,eventType);
this.list = list;
this.nid = nid;
}

public List<ObservableField> getList(){
public List<ObservableField<?>> getList(){
return list;
}

public int getNid() {
return nid;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,10 @@ public static void putArrowOnRight(TitledPane pane, double buttonSpacing, String
}

/**
* TODO: Commented out putArrowOnRight causing exception for translateXProperty
* default params wrapper method for putArrowOnRight
* @param pane
*/
public static void putArrowOnRight(TitledPane pane) {
//putArrowOnRight(pane, DEFAULT_BUTTON_SPACING, ".title", ".arrow-button");
putArrowOnRight(pane, DEFAULT_BUTTON_SPACING, ".title", ".arrow-button");
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package dev.ikm.komet.kview.klfields;

import static dev.ikm.komet.kview.mvvm.model.DataModelHelper.obtainObservableField;
import dev.ikm.komet.framework.observable.ObservableField;
import dev.ikm.komet.framework.view.ViewProperties;
import dev.ikm.komet.kview.klfields.booleanfield.KlBooleanFieldFactory;
import dev.ikm.komet.kview.klfields.componentfield.KlComponentFieldFactory;
import dev.ikm.komet.kview.klfields.componentfield.KlComponentSetFieldFactory;
import dev.ikm.komet.kview.klfields.floatfield.KlFloatFieldFactory;
import dev.ikm.komet.kview.klfields.integerfield.KlIntegerFieldFactory;
import dev.ikm.komet.kview.klfields.readonly.ReadOnlyKLFieldFactory;
Expand All @@ -18,10 +20,10 @@
import javafx.scene.Node;
import javafx.scene.control.Separator;
import javafx.scene.layout.Pane;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import static dev.ikm.komet.kview.mvvm.model.DataModelHelper.obtainObservableField;

public class KlFieldHelper {

Expand Down Expand Up @@ -57,7 +59,8 @@ public static List<ObservableField<?>> displayEditableSemanticFields(ViewPropert

Node node = null;
int dataTypeNid = fieldRecord.dataType().nid();
ObservableField observableField = obtainObservableField(viewProperties, semanticEntityVersionLatest, fieldRecord);
ObservableField writeObservableField = obtainObservableField(viewProperties, semanticEntityVersionLatest, fieldRecord);
ObservableField observableField = new ObservableField(writeObservableField.field(), true);
observableFields.add(observableField);
if (dataTypeNid == TinkarTerm.COMPONENT_FIELD.nid()) {
// load a read-only component
Expand All @@ -67,7 +70,8 @@ public static List<ObservableField<?>> displayEditableSemanticFields(ViewPropert
KlStringFieldFactory stringFieldTextFactory = new KlStringFieldFactory();
node = stringFieldTextFactory.create(observableField, viewProperties.nodeView(), true).klWidget();
} else if (dataTypeNid == TinkarTerm.COMPONENT_ID_SET_FIELD.nid()) {
node = rowf.createReadOnlyComponentSet(viewProperties, fieldRecord);
KlComponentSetFieldFactory klComponentSetFieldFactory = new KlComponentSetFieldFactory();
node = klComponentSetFieldFactory.create(observableField, viewProperties.nodeView(), true).klWidget();
} else if (dataTypeNid == TinkarTerm.COMPONENT_ID_LIST_FIELD.nid()) {
node = rowf.createReadOnlyComponentList(viewProperties, fieldRecord);
} else if (dataTypeNid == TinkarTerm.DITREE_FIELD.nid()) {
Expand Down Expand Up @@ -107,7 +111,8 @@ public static List<ObservableField<?>> displayReadOnlySemanticFields(ViewPropert

Node readOnlyNode = null;
int dataTypeNid = fieldRecord.dataType().nid();
ObservableField observableField = obtainObservableField(viewProperties, semanticEntityVersionLatest, fieldRecord);
ObservableField<?> writeObservableField = obtainObservableField(viewProperties, semanticEntityVersionLatest, fieldRecord);
ObservableField observableField = new ObservableField(writeObservableField.field(), false);
observableFields.add(observableField);
// substitute each data type.
if (dataTypeNid == TinkarTerm.COMPONENT_FIELD.nid()) {
Expand All @@ -118,7 +123,8 @@ public static List<ObservableField<?>> displayReadOnlySemanticFields(ViewPropert
KlStringFieldFactory klStringFieldFactory = new KlStringFieldFactory();
readOnlyNode = klStringFieldFactory.create(observableField, viewProperties.nodeView(), false).klWidget();
} else if (dataTypeNid == TinkarTerm.COMPONENT_ID_SET_FIELD.nid()) {
readOnlyNode = rowf.createReadOnlyComponentSet(viewProperties, fieldRecord);
KlComponentSetFieldFactory klComponentSetFieldFactory = new KlComponentSetFieldFactory();
readOnlyNode = klComponentSetFieldFactory.create(observableField, viewProperties.nodeView(), false).klWidget();
} else if (dataTypeNid == TinkarTerm.COMPONENT_ID_LIST_FIELD.nid()) {
readOnlyNode = rowf.createReadOnlyComponentList(viewProperties, fieldRecord);
} else if (dataTypeNid == TinkarTerm.DITREE_FIELD.nid()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package dev.ikm.komet.kview.klfields.componentfield;

import dev.ikm.komet.framework.Identicon;
import dev.ikm.komet.framework.observable.ObservableField;
import dev.ikm.komet.framework.view.ObservableView;
import dev.ikm.komet.kview.controls.KLComponentSetControl;
import dev.ikm.komet.kview.controls.KLReadOnlyComponentControl;
import dev.ikm.komet.kview.klfields.BaseDefaultKlField;
import dev.ikm.komet.layout.component.version.field.KlComponentSetField;
import dev.ikm.tinkar.common.id.IntIdSet;
import dev.ikm.tinkar.terms.EntityProxy;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;

public class DefaultKlComponentSetField extends BaseDefaultKlField<IntIdSet> implements KlComponentSetField {

public DefaultKlComponentSetField(ObservableField<IntIdSet> observableComponentSetField, ObservableView observableView, boolean isEditable) {
super(observableComponentSetField, observableView, isEditable);
Node node;
if (isEditable) {
KLComponentSetControl klComponentSetControl = new KLComponentSetControl();
klComponentSetControl.setTitle(getTitle());
klComponentSetControl.valueProperty().bindBidirectional(observableComponentSetField.valueProperty());
node = klComponentSetControl;
} else {
VBox vBox = new VBox();
observableComponentSetField.valueProperty().subscribe(intIdSet -> {
vBox.getChildren().clear();
vBox.getChildren().add(new Label(getTitle()));
intIdSet.forEach(nid -> {
KLReadOnlyComponentControl readOnlyComponentControl = new KLReadOnlyComponentControl();
EntityProxy entityProxy = EntityProxy.make(nid);
readOnlyComponentControl.setText(entityProxy.description());
readOnlyComponentControl.setIcon(Identicon.generateIdenticonImage(entityProxy.publicId()));
vBox.getChildren().add(readOnlyComponentControl);
});
});
node = vBox;

}
setKlWidget(node);
}
}
Loading

0 comments on commit 37535e9

Please sign in to comment.