Skip to content

Commit 1f0ab4d

Browse files
vollbrecht-workVollbrecht
authored andcommitted
Refactor Add and Edit Description Forms into unified Controller
The newly added DescriptionBaseController now holds all duplicated code that was present in the AddFullyQualifiedNameController, AddOtherNameController, EditFullyQualifiedNameController and EditDescriptionFormController. Four new controllers were edded that still holds the some controller specific's from the old above Controllers. They now are called Description{Edit/Add}{Other/Fqn}Controller. A unified FXML was introduced called description-form.fxml, to reduce copy pasted view's, helping reduce the UI bug surface.
1 parent c5531d2 commit 1f0ab4d

File tree

9 files changed

+1402
-24
lines changed

9 files changed

+1402
-24
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package dev.ikm.komet.kview.mvvm.model;
2+
3+
public enum DescriptionFormType {
4+
ADD_FQN("Add Description: Fully Qualified Name", "Fully Qualified Name", true),
5+
ADD_OTHER_NAME("Add New Description: Other Name", "Other Name", true),
6+
EDIT_FQN("Edit Description: Fully Qualified Name", "Fully Qualified Name", false),
7+
EDIT_OTHER_NAME("Edit Description: Other Name", "Other Name", false);
8+
9+
private final String title;
10+
private final String typePrompt;
11+
private final boolean isAddMode;
12+
13+
DescriptionFormType(String title, String typePrompt, boolean isAddMode) {
14+
this.title = title;
15+
this.typePrompt = typePrompt;
16+
this.isAddMode = isAddMode;
17+
}
18+
19+
public String getTitle() { return title; }
20+
public String getTypePrompt() { return typePrompt; }
21+
public boolean isAddMode() { return isAddMode; }
22+
public boolean isEditMode() { return !isAddMode; }
23+
public boolean isFqnType() { return this == ADD_FQN || this == EDIT_FQN; }
24+
}
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
package dev.ikm.komet.kview.mvvm.view.properties;
2+
3+
import dev.ikm.komet.kview.events.ClosePropertiesPanelEvent;
4+
import dev.ikm.komet.kview.events.CreateConceptEvent;
5+
import dev.ikm.komet.kview.mvvm.model.DescrName;
6+
import dev.ikm.komet.kview.mvvm.model.DescriptionFormType;
7+
import dev.ikm.komet.kview.mvvm.viewmodel.DescrNameViewModel;
8+
import dev.ikm.tinkar.entity.ConceptEntity;
9+
import dev.ikm.tinkar.entity.Entity;
10+
import dev.ikm.tinkar.terms.EntityFacade;
11+
import dev.ikm.tinkar.terms.State;
12+
import dev.ikm.tinkar.terms.TinkarTerm;
13+
import javafx.beans.InvalidationListener;
14+
import javafx.scene.control.ComboBox;
15+
import javafx.scene.control.ListCell;
16+
import javafx.util.Callback;
17+
import javafx.util.StringConverter;
18+
import org.carlfx.cognitive.loader.InjectViewModel;
19+
import org.slf4j.Logger;
20+
import org.slf4j.LoggerFactory;
21+
22+
import java.util.Collection;
23+
import java.util.Optional;
24+
import java.util.UUID;
25+
26+
import static dev.ikm.komet.kview.mvvm.viewmodel.DescrNameViewModel.*;
27+
import static dev.ikm.komet.kview.mvvm.viewmodel.DescrNameViewModel.CASE_SIGNIFICANCE;
28+
import static dev.ikm.komet.kview.mvvm.viewmodel.DescrNameViewModel.LANGUAGE;
29+
import static dev.ikm.komet.kview.mvvm.viewmodel.DescrNameViewModel.MODULE;
30+
31+
public class DescriptionAddFqnController extends DescriptionBaseController<EntityFacade>{
32+
private static final Logger LOG = LoggerFactory.getLogger(DescriptionAddFqnController.class);
33+
@InjectViewModel
34+
private DescrNameViewModel fqnViewModel;
35+
36+
public DescriptionAddFqnController(UUID conceptTopic) {
37+
super(DescriptionFormType.ADD_FQN, conceptTopic);
38+
}
39+
40+
@Override
41+
protected void initializeData() {
42+
configureDialectVisibility(false);
43+
44+
submitButton.setDisable(true);
45+
46+
// Initialize the fqnViewModel
47+
fqnViewModel
48+
.setPropertyValue(NAME_TYPE, TinkarTerm.FULLY_QUALIFIED_NAME_DESCRIPTION_TYPE)
49+
.setPropertyValue(STATUS, TinkarTerm.ACTIVE_STATE);
50+
51+
// register listeners
52+
InvalidationListener formValid = (obs) -> {
53+
boolean isFormValid = isFormPopulated();
54+
if (isFormValid) {
55+
copyUIToViewModelProperties();
56+
}
57+
submitButton.setDisable(!isFormValid);
58+
};
59+
60+
// Initialize combo boxes with appropriate data for FQN add mode
61+
nameTextField.textProperty().addListener(formValid);
62+
setupComboBoxAdd(moduleComboBox, formValid);
63+
setupComboBoxAdd(statusComboBox, formValid);
64+
setupComboBoxAdd(caseSignificanceComboBox, formValid);
65+
setupComboBoxAdd(languageComboBox, formValid);
66+
67+
68+
}
69+
70+
@Override
71+
protected void onCancel() {
72+
close(cancelButton);
73+
}
74+
75+
@Override
76+
protected void onSubmit() {
77+
// TODO assuming it's valid save() check for errors and publish event
78+
79+
fqnViewModel.save();
80+
if (fqnViewModel.getValidationMessages().isEmpty()) {
81+
// publish event with the fqnViewModel.
82+
// ... This property may not be needed.
83+
fqnViewModel.setPropertyValue(IS_SUBMITTED, true);
84+
}
85+
86+
LOG.info("Ready to add to the concept view model: " + fqnViewModel);
87+
88+
//////////////////////////////////////////////////////////////////////////////////////////
89+
// event received in Details Controller that will call conceptViewModel.createConcept()
90+
//////////////////////////////////////////////////////////////////////////////////////////
91+
DescrName fqnDescrName = fqnViewModel.create();
92+
eventBus.publish(conceptTopic, new CreateConceptEvent(this, CreateConceptEvent.ADD_FQN, fqnDescrName));
93+
94+
// clear the form after saving. otherwise when you navigate back to Add Other Name
95+
// you would have the previous form values still there
96+
clearView();
97+
close(submitButton);
98+
}
99+
100+
101+
private void populate(ComboBox comboBox, Collection<ConceptEntity> entities) {
102+
comboBox.getItems().setAll(entities);
103+
}
104+
105+
@Override
106+
public void updateView() {
107+
108+
// populate form combo fields module, status, case significance, lang.
109+
populate(moduleComboBox, fqnViewModel.findAllModules(getViewProperties()));
110+
populate(statusComboBox, fqnViewModel.findAllStatuses(getViewProperties()));
111+
populate(caseSignificanceComboBox, fqnViewModel.findAllCaseSignificants(getViewProperties()));
112+
populate(languageComboBox, fqnViewModel.findAllLanguages(getViewProperties()));
113+
114+
// Set UI to default values
115+
caseSignificanceComboBox.setValue(TinkarTerm.DESCRIPTION_NOT_CASE_SENSITIVE);
116+
statusComboBox.setValue(Entity.getFast(State.ACTIVE.nid()));
117+
moduleComboBox.setValue(TinkarTerm.DEVELOPMENT_MODULE);
118+
languageComboBox.setValue(TinkarTerm.ENGLISH_LANGUAGE);
119+
}
120+
121+
@Override
122+
public void clearView() {
123+
nameTextField.setText("");
124+
moduleComboBox.setValue(null);
125+
statusComboBox.setValue(null);
126+
caseSignificanceComboBox.setValue(null);
127+
languageComboBox.setValue(null);
128+
// if (fqnViewModel != null) {
129+
// copyUIToViewModelProperties();
130+
// fqnViewModel.save(true); // make UI properties as model values
131+
// }
132+
moduleComboBox.getItems().clear();
133+
statusComboBox.getItems().clear();
134+
caseSignificanceComboBox.getItems().clear();
135+
languageComboBox.getItems().clear();
136+
}
137+
138+
/**
139+
* TODO: This is appropriate. A better solution is binding properties on the view model. If so, we'd need to unbind.
140+
* This copies form values into the ViewModel's property values. It does not save or validate.
141+
*/
142+
private void copyUIToViewModelProperties() {
143+
if (fqnViewModel != null) {
144+
fqnViewModel.setPropertyValue(NAME_TEXT, nameTextField.getText())
145+
.setPropertyValue(NAME_TYPE, TinkarTerm.FULLY_QUALIFIED_NAME_DESCRIPTION_TYPE)
146+
.setPropertyValue(CASE_SIGNIFICANCE, caseSignificanceComboBox.getSelectionModel().getSelectedItem())
147+
.setPropertyValue(STATUS, statusComboBox.getSelectionModel().getSelectedItem())
148+
.setPropertyValue(MODULE, moduleComboBox.getSelectionModel().getSelectedItem())
149+
.setPropertyValue(LANGUAGE, languageComboBox.getSelectionModel().getSelectedItem());
150+
}
151+
}
152+
153+
154+
@Override
155+
public DescrNameViewModel getViewModel() {
156+
return fqnViewModel;
157+
}
158+
159+
160+
}
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
package dev.ikm.komet.kview.mvvm.view.properties;
2+
3+
import dev.ikm.komet.framework.view.ViewProperties;
4+
import dev.ikm.komet.kview.events.CreateConceptEvent;
5+
import dev.ikm.komet.kview.mvvm.model.DescriptionFormType;
6+
import dev.ikm.komet.kview.mvvm.viewmodel.OtherNameViewModel;
7+
import dev.ikm.tinkar.entity.ConceptEntity;
8+
import dev.ikm.tinkar.entity.Entity;
9+
import dev.ikm.tinkar.terms.EntityFacade;
10+
import dev.ikm.tinkar.terms.State;
11+
import dev.ikm.tinkar.terms.TinkarTerm;
12+
import javafx.beans.InvalidationListener;
13+
import javafx.scene.control.ComboBox;
14+
import org.carlfx.cognitive.loader.InjectViewModel;
15+
import org.carlfx.cognitive.viewmodel.ViewModel;
16+
import org.slf4j.Logger;
17+
import org.slf4j.LoggerFactory;
18+
19+
import java.util.Collection;
20+
import java.util.UUID;
21+
22+
import static dev.ikm.komet.kview.mvvm.viewmodel.DescrNameViewModel.*;
23+
import static dev.ikm.komet.kview.mvvm.viewmodel.DescrNameViewModel.CASE_SIGNIFICANCE;
24+
import static dev.ikm.komet.kview.mvvm.viewmodel.DescrNameViewModel.LANGUAGE;
25+
import static dev.ikm.komet.kview.mvvm.viewmodel.DescrNameViewModel.MODULE;
26+
import static dev.ikm.komet.kview.mvvm.viewmodel.OtherNameViewModel.OtherNameProperties.*;
27+
28+
public class DescriptionAddOtherController extends DescriptionBaseController<EntityFacade>{
29+
private static final Logger LOG = LoggerFactory.getLogger(DescriptionAddOtherController.class);
30+
@InjectViewModel
31+
private OtherNameViewModel otherNameViewModel; // TODO why we need that wrapper only for this class but can get away in all 3 others
32+
33+
34+
// TODO: how does it work with no UUID
35+
//public DescriptionAddOtherController() {
36+
// super(DescriptionFormType.ADD_OTHER_NAME, conceptTopic);
37+
//}
38+
39+
public DescriptionAddOtherController(UUID conceptTopic) {
40+
super(DescriptionFormType.ADD_OTHER_NAME, conceptTopic);
41+
}
42+
43+
44+
@Override
45+
protected void initializeData() {
46+
configureDialectVisibility(false);
47+
48+
submitButton.setDisable(true);
49+
50+
titleLabel.setText("Add New Description: Other Name"); // TODO: check if needed ?
51+
otherNameViewModel
52+
.setPropertyValue(NAME_TYPE, TinkarTerm.REGULAR_NAME_DESCRIPTION_TYPE)
53+
.setPropertyValue(STATUS, TinkarTerm.ACTIVE_STATE);
54+
// register listeners
55+
InvalidationListener formValid = (obs) -> {
56+
boolean isFormValid = isFormPopulated();
57+
if (isFormValid) {
58+
copyUIToViewModelProperties();
59+
}
60+
submitButton.setDisable(!isFormValid);
61+
};
62+
63+
nameTextField.textProperty().addListener(formValid);
64+
setupComboBoxAdd(moduleComboBox, formValid);
65+
setupComboBoxAdd(statusComboBox, formValid);
66+
setupComboBoxAdd(caseSignificanceComboBox, formValid);
67+
setupComboBoxAdd(languageComboBox, formValid);
68+
}
69+
70+
@Override
71+
public void updateView() {
72+
// populate form combo fields module, status, case significance, lang.
73+
populate(moduleComboBox, otherNameViewModel.findAllModules(getViewProperties()));
74+
populate(statusComboBox, otherNameViewModel.findAllStatuses(getViewProperties()));
75+
populate(caseSignificanceComboBox, otherNameViewModel.findAllCaseSignificants(getViewProperties()));
76+
populate(languageComboBox, otherNameViewModel.findAllLanguages(getViewProperties()));
77+
78+
boolean hasOtherName = getViewModel().getValue(HAS_OTHER_NAME);
79+
80+
if (hasOtherName) {
81+
caseSignificanceComboBox.setValue(getViewModel().getValue(FQN_CASE_SIGNIFICANCE));
82+
} else {
83+
caseSignificanceComboBox.setValue(TinkarTerm.DESCRIPTION_NOT_CASE_SENSITIVE);
84+
}
85+
statusComboBox.setValue(Entity.getFast(State.ACTIVE.nid()));
86+
moduleComboBox.setValue(TinkarTerm.DEVELOPMENT_MODULE);
87+
if (hasOtherName) {
88+
languageComboBox.setValue(getViewModel().getValue(FQN_LANGUAGE));
89+
} else {
90+
languageComboBox.setValue(TinkarTerm.ENGLISH_LANGUAGE);
91+
}
92+
}
93+
94+
public void updateModel(final ViewProperties viewProperties) {
95+
this.viewProperties = viewProperties;
96+
}
97+
98+
@Override
99+
public void clearView() {
100+
nameTextField.setText("");
101+
moduleComboBox.setValue(null);
102+
statusComboBox.setValue(null);
103+
caseSignificanceComboBox.setValue(null);
104+
languageComboBox.setValue(null);
105+
moduleComboBox.getItems().clear();
106+
statusComboBox.getItems().clear();
107+
caseSignificanceComboBox.getItems().clear();
108+
languageComboBox.getItems().clear();
109+
}
110+
111+
@Override
112+
protected void onCancel() {
113+
close(cancelButton);
114+
}
115+
116+
@Override
117+
protected void onSubmit() {
118+
// TODO assuming it's valid save() check for errors and publish event
119+
otherNameViewModel.setPropertyValue(IS_SUBMITTED, true);
120+
otherNameViewModel.save();
121+
if (otherNameViewModel.hasNoErrorMsgs()) {
122+
// publish event with the otherNameViewModel.
123+
// ...
124+
LOG.info("Ready to add to the concept view model: " + otherNameViewModel);
125+
eventBus.publish(conceptTopic, new CreateConceptEvent(this, CreateConceptEvent.ADD_OTHER_NAME,
126+
otherNameViewModel.create()));
127+
clearView();
128+
close(submitButton);
129+
}
130+
}
131+
132+
@Override
133+
public OtherNameViewModel getViewModel() {
134+
return otherNameViewModel;
135+
}
136+
137+
/**
138+
* TODO: This is appropriate. A better solution is binding properties on the view model. If so, we'd need to unbind.
139+
* This copies form values into the ViewModel's property values. It does not save or validate.
140+
*/
141+
private void copyUIToViewModelProperties() {
142+
if (otherNameViewModel != null) {
143+
otherNameViewModel.setPropertyValue(NAME_TEXT, nameTextField.getText())
144+
.setPropertyValue(NAME_TYPE, TinkarTerm.REGULAR_NAME_DESCRIPTION_TYPE)
145+
.setPropertyValue(CASE_SIGNIFICANCE, caseSignificanceComboBox.getSelectionModel().getSelectedItem())
146+
.setPropertyValue(STATUS, statusComboBox.getSelectionModel().getSelectedItem())
147+
.setPropertyValue(MODULE, moduleComboBox.getSelectionModel().getSelectedItem())
148+
.setPropertyValue(LANGUAGE, languageComboBox.getSelectionModel().getSelectedItem());
149+
}
150+
}
151+
152+
public void setAddOtherNameTitleLabel(String addDescriptionTitleLabelText) {
153+
this.titleLabel.setText(addDescriptionTitleLabelText);
154+
}
155+
156+
public void populate(ComboBox comboBox, Collection<ConceptEntity> entities) {
157+
comboBox.getItems().addAll(entities);
158+
}
159+
160+
public void hideNonUsed() {
161+
dialect1.setVisible(false);
162+
dialectComboBox1.setVisible(false);
163+
164+
}
165+
}

0 commit comments

Comments
 (0)