Skip to content

Commit c92704a

Browse files
committed
added layers grid
1 parent 733d9a4 commit c92704a

File tree

6 files changed

+199
-4
lines changed

6 files changed

+199
-4
lines changed

logicaldoc-gui/src/main/java/com/logicaldoc/gui/frontend/client/ai/model/GUIModel.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package com.logicaldoc.gui.frontend.client.ai.model;
22

33
import java.io.Serializable;
4+
import java.util.ArrayList;
5+
import java.util.List;
46

57
/**
68
* A GUI bean representing an AI model
@@ -32,6 +34,8 @@ public class GUIModel implements Serializable {
3234

3335
private String loss = "NEGATIVELOGLIKELIHOOD";
3436

37+
private List<GUINeuralNetworkLayer> layers = new ArrayList<>();
38+
3539
public GUIModel(long id, String name) {
3640
super();
3741
this.id = id;
@@ -125,4 +129,12 @@ public String getLoss() {
125129
public void setLoss(String loss) {
126130
this.loss = loss;
127131
}
132+
133+
public List<GUINeuralNetworkLayer> getLayers() {
134+
return layers;
135+
}
136+
137+
public void setLayers(List<GUINeuralNetworkLayer> layers) {
138+
this.layers = layers;
139+
}
128140
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package com.logicaldoc.gui.frontend.client.ai.model;
2+
3+
import java.io.Serializable;
4+
5+
/**
6+
* A GUI bean representing a layer of a neural network
7+
*
8+
* @author Marco Meschieri - LogicalDOC
9+
* @since 9.2
10+
*/
11+
public class GUINeuralNetworkLayer implements Serializable {
12+
13+
private static final long serialVersionUID = 1L;
14+
15+
private String name;
16+
17+
/**
18+
* Number of output nodes
19+
*/
20+
private int outputNodes = 3;
21+
22+
private String activation = "RELU";
23+
24+
public GUINeuralNetworkLayer() {
25+
super();
26+
}
27+
28+
public GUINeuralNetworkLayer(String name, int outputNodes, String activation) {
29+
super();
30+
this.name = name;
31+
this.outputNodes = outputNodes;
32+
this.activation = activation;
33+
}
34+
35+
public String getName() {
36+
return name;
37+
}
38+
39+
public void setName(String name) {
40+
this.name = name;
41+
}
42+
43+
public int getOutputNodes() {
44+
return outputNodes;
45+
}
46+
47+
public void setOutputNodes(int outputNodes) {
48+
this.outputNodes = outputNodes;
49+
}
50+
51+
public String getActivation() {
52+
return activation;
53+
}
54+
55+
public void setActivation(String activation) {
56+
this.activation = activation;
57+
}
58+
59+
}

logicaldoc-gui/src/main/java/com/logicaldoc/gui/frontend/client/ai/model/ModelProperties.java

Lines changed: 118 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,30 @@
22

33
import java.util.LinkedHashMap;
44

5+
import com.logicaldoc.gui.common.client.grid.IdListGridField;
6+
import com.logicaldoc.gui.common.client.i18n.I18N;
57
import com.logicaldoc.gui.common.client.util.ItemFactory;
68
import com.logicaldoc.gui.common.client.widgets.DocumentSelector;
7-
import com.logicaldoc.i18n.I18N;
9+
import com.logicaldoc.gui.frontend.client.ai.sampler.GUISampler;
810
import com.smartgwt.client.data.AdvancedCriteria;
11+
import com.smartgwt.client.types.AutoFitWidthApproach;
912
import com.smartgwt.client.types.OperatorId;
13+
import com.smartgwt.client.types.SelectionStyle;
1014
import com.smartgwt.client.types.TitleOrientation;
1115
import com.smartgwt.client.widgets.form.DynamicForm;
1216
import com.smartgwt.client.widgets.form.fields.SelectItem;
1317
import com.smartgwt.client.widgets.form.fields.StaticTextItem;
1418
import com.smartgwt.client.widgets.form.fields.TextAreaItem;
1519
import com.smartgwt.client.widgets.form.fields.TextItem;
1620
import com.smartgwt.client.widgets.form.fields.events.ChangedHandler;
21+
import com.smartgwt.client.widgets.grid.ListGrid;
22+
import com.smartgwt.client.widgets.grid.ListGridField;
23+
import com.smartgwt.client.widgets.grid.ListGridRecord;
1724
import com.smartgwt.client.widgets.layout.HLayout;
25+
import com.smartgwt.client.widgets.layout.SectionStack;
26+
import com.smartgwt.client.widgets.layout.SectionStackSection;
27+
import com.smartgwt.client.widgets.menu.Menu;
28+
import com.smartgwt.client.widgets.menu.MenuItem;
1829

1930
/**
2031
* Shows model's standard properties and read-only data
@@ -38,6 +49,10 @@ public class ModelProperties extends ModelDetailsTab {
3849

3950
private DocumentSelector documentSelector;
4051

52+
private ListGrid layers;
53+
54+
private SectionStack layersStack = new SectionStack();
55+
4156
public ModelProperties(GUIModel model, final ChangedHandler changedHandler) {
4257
super(model, changedHandler);
4358
setWidth100();
@@ -94,13 +109,21 @@ private void refresh() {
94109

95110
TextItem features = ItemFactory.newTextItem("features", model.getFeatures());
96111
features.addChangedHandler(changedHandler);
112+
features.setColSpan(4);
113+
features.setWidth(400);
97114
features.setHint(I18N.message("valuescommaseparated"));
115+
features.setShowHintInField(true);
116+
features.setValue(model.getFeatures());
98117
features.setVisibleWhen(new AdvancedCriteria(TYPE, OperatorId.EQUALS, "neural"));
99118
features.setRequiredWhen(new AdvancedCriteria(TYPE, OperatorId.EQUALS, "neural"));
100119

101120
TextItem categories = ItemFactory.newTextItem("categories", model.getCategories());
102121
categories.addChangedHandler(changedHandler);
122+
categories.setColSpan(4);
123+
categories.setValue(model.getCategories());
124+
categories.setWidth(400);
103125
categories.setHint(I18N.message("valuescommaseparated"));
126+
categories.setShowHintInField(true);
104127
categories.setVisibleWhen(new AdvancedCriteria(TYPE, OperatorId.EQUALS, "neural"));
105128
categories.setRequiredWhen(new AdvancedCriteria(TYPE, OperatorId.EQUALS, "neural"));
106129

@@ -115,6 +138,8 @@ private void refresh() {
115138

116139
container.setMembersMargin(3);
117140
container.addMember(form);
141+
142+
prepareLayers();
118143
}
119144

120145
private SelectItem lossSeletor() {
@@ -127,6 +152,8 @@ private SelectItem lossSeletor() {
127152
map.put("NEGATIVELOGLIKELIHOOD", "NEGATIVELOGLIKELIHOOD");
128153
item.setValueMap(map);
129154

155+
item.setValue(model.getLoss());
156+
130157
item.setVisibleWhen(new AdvancedCriteria(TYPE, OperatorId.EQUALS, "neural"));
131158
item.setRequiredWhen(new AdvancedCriteria(TYPE, OperatorId.EQUALS, "neural"));
132159

@@ -146,6 +173,8 @@ private SelectItem weightInitSeletor() {
146173
map.put("XAVIER", "XAVIER");
147174
item.setValueMap(map);
148175

176+
item.setValue(model.getWeightInit());
177+
149178
item.setVisibleWhen(new AdvancedCriteria(TYPE, OperatorId.EQUALS, "neural"));
150179
item.setRequiredWhen(new AdvancedCriteria(TYPE, OperatorId.EQUALS, "neural"));
151180
return item;
@@ -177,6 +206,8 @@ private SelectItem activationSeletor() {
177206
map.put("MISH", "MISH");
178207
item.setValueMap(map);
179208

209+
item.setValue(model.getActivation());
210+
180211
item.setVisibleWhen(new AdvancedCriteria(TYPE, OperatorId.EQUALS, "neural"));
181212
item.setRequiredWhen(new AdvancedCriteria(TYPE, OperatorId.EQUALS, "neural"));
182213
return item;
@@ -192,9 +223,95 @@ boolean validate() {
192223
model.setCategories(form.getValueAsString("categories"));
193224
model.setActivation(form.getValueAsString("activation"));
194225
model.setWeightInit(form.getValueAsString("weightInit"));
226+
model.setLoss(form.getValueAsString("loss"));
195227
}
196228
return !form.hasErrors();
197229
}
230+
231+
private void prepareLayers() {
232+
layers = new ListGrid();
233+
layers.setEmptyMessage(I18N.message("notitemstoshow"));
234+
layers.setWidth100();
235+
layers.setHeight100();
236+
layers.setEmptyMessage(I18N.message("norecords"));
237+
layers.setCanSort(false);
238+
layers.setCanFreezeFields(false);
239+
layers.setCanGroupBy(false);
240+
layers.setLeaveScrollbarGap(false);
241+
layers.setShowHeader(true);
242+
layers.setSelectionType(SelectionStyle.MULTIPLE);
243+
layers.setCanEdit(false);
244+
layers.setShowRowNumbers(true);
245+
layers.setCanReorderRecords(true);
246+
layers.setAutoFetchData(true);
247+
layers.setShowRecordComponents(true);
248+
layers.setShowRecordComponentsByCell(true);
249+
layers.addDropCompleteHandler(dropCompleted -> changedHandler.onChanged(null));
250+
layers.addCellContextClickHandler(event -> {
251+
showContextMenu();
252+
event.cancel();
253+
});
254+
255+
256+
ListGridField name = new ListGridField(NAME, I18N.message(NAME));
257+
name.setCanEdit(true);
258+
name.setCanSort(false);
259+
name.setAutoFitWidth(true);
260+
name.setAutoFitWidthApproach(AutoFitWidthApproach.BOTH);
261+
262+
ListGridField outputNodes = new ListGridField("outputnodes", I18N.message("outputnodes"));
263+
outputNodes.setCanEdit(true);
264+
outputNodes.setCanSort(false);
265+
outputNodes.setAutoFitWidth(true);
266+
outputNodes.setAutoFitWidthApproach(AutoFitWidthApproach.BOTH);
267+
268+
ListGridField activation = new ListGridField("activation", I18N.message("activationfunction"));
269+
activation.setCanEdit(true);
270+
activation.setCanSort(false);
271+
activation.setAutoFitWidth(true);
272+
activation.setAutoFitWidthApproach(AutoFitWidthApproach.BOTH);
273+
274+
layers.setFields(name, outputNodes, activation);
275+
276+
// Initialize the layers grid
277+
for (GUINeuralNetworkLayer layer : model.getLayers()) {
278+
ListGridRecord rec = new ListGridRecord();
279+
rec.setAttribute(NAME, layer.getName());
280+
rec.setAttribute("outputnodes", layer.getOutputNodes());
281+
rec.setAttribute("activation", layer.getActivation());
282+
layers.addData(rec);
283+
}
284+
285+
DynamicForm buttonsForm = new DynamicForm();
286+
// buttonsForm.setItems(addSampler);
287+
288+
layersStack.setHeight100();
289+
layersStack.setVisible("neural".equals(model.getType()));
290+
291+
SectionStackSection section = new SectionStackSection("<b>" + I18N.message("layers") + "</b>");
292+
section.setCanCollapse(false);
293+
section.setExpanded(true);
294+
section.setItems(layers, buttonsForm);
295+
296+
layersStack.setSections(section);
297+
layersStack.draw();
298+
299+
container.addMember(layersStack);
300+
}
301+
302+
private void showContextMenu() {
303+
Menu contextMenu = new Menu();
304+
MenuItem delete = new MenuItem();
305+
delete.setTitle(I18N.message("ddelete"));
306+
delete.addClickHandler(click -> {
307+
layers.removeSelectedData();
308+
changedHandler.onChanged(null);
309+
});
310+
311+
contextMenu.setItems(delete);
312+
contextMenu.showContextMenu();
313+
}
314+
198315

199316
@Override
200317
public boolean equals(Object other) {

logicaldoc-gui/src/main/java/com/logicaldoc/gui/frontend/client/ai/sampler/SamplerProperties.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.logicaldoc.gui.common.client.grid.IdListGridField;
44
import com.logicaldoc.gui.common.client.i18n.I18N;
5+
import com.logicaldoc.gui.common.client.log.GuiLog;
56
import com.logicaldoc.gui.common.client.util.ItemFactory;
67
import com.logicaldoc.gui.common.client.widgets.DocumentSelector;
78
import com.logicaldoc.gui.common.client.widgets.FolderSelector;
@@ -155,7 +156,6 @@ private void refresh() {
155156
container.addMember(form);
156157

157158
prepareChain();
158-
159159
}
160160

161161
private void prepareChain() {
@@ -290,8 +290,13 @@ boolean validate() {
290290
sampler.setFolder(folderSelector.getFolder());
291291
sampler.setDocument(documentSelector.getDocument());
292292

293+
if ("chain".equals(sampler.getType()) && chain.getRecordList().isEmpty()) {
294+
GuiLog.error("samplerchainempty");
295+
return false;
296+
}
297+
293298
sampler.getChain().clear();
294-
if ("chain".equals(sampler.getType()) && !chain.getRecordList().isEmpty()) {
299+
if ("chain".equals(sampler.getType())) {
295300
com.smartgwt.client.data.Record[] chainRecords = chain.getRecordList().toArray();
296301
for (com.smartgwt.client.data.Record chainRecord : chainRecords)
297302
sampler.getChain()

logicaldoc-gui/src/main/java/com/logicaldoc/gui/frontend/client/security/ldap/LDAPServerDetailsPanel.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ public LDAPServerDetailsPanel(LDAPServersPanel listing, GUILDAPServer server) {
201201
ToggleItem keepMembership = ItemFactory.newToggleItem(KEEPMEMBERSHIP, "keepmembershiplocalgroups",
202202
this.server.isKeepLocalMemberships());
203203
keepMembership.setRequired(true);
204+
keepMembership.setEndRow(true);
204205

205206
TextAreaItem validation = ItemFactory.newTextAreaItemForAutomation(VALIDATION, this.server.getValidation(),
206207
null, false);

logicaldoc-i18n/src/main/resources/i18n/messages.properties

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2663,4 +2663,5 @@ selectamodel = Select a model
26632663
valuescommaseparated = values separated by comma
26642664
weightinitscheme = Weight Init Scheme
26652665
activationfunction = Activation Function
2666-
lossfunction = Loss Function
2666+
lossfunction = Loss Function
2667+
samplerchainempty = Cannot save an empty sampler chain

0 commit comments

Comments
 (0)