- added else branch to conditional actions

- implemented history for any object extending BaseClass (i.e. almost any)
- added distance() calculation method to base class
- Button "edit JSON" in Action Lists now hidden by default, can be enabled in plan properties

- fixed bugs:
    - updating json of DisplayText was not working properly
    - log output in Tile.isFreeFor was broken
This commit is contained in:
Stephan Richter
2021-04-09 18:55:20 +02:00
parent 559e095e33
commit 77166acf91
18 changed files with 252 additions and 38 deletions

View File

@@ -12,6 +12,7 @@ import org.slf4j.LoggerFactory;
import de.srsoftware.tools.Tag;
import de.srsoftware.web4rail.BaseClass;
import de.srsoftware.web4rail.LoadCallback;
import de.srsoftware.web4rail.tags.Button;
import de.srsoftware.web4rail.tags.Fieldset;
import de.srsoftware.web4rail.tags.Form;
@@ -110,6 +111,7 @@ public abstract class Action extends BaseClass {
((ActionList)this).clear();
}
load(json);
LoadCallback.fire();
return context().properties();
}
Window win = new Window("json-import-export-"+id(), t("JSON code of {}",this));

View File

@@ -123,23 +123,22 @@ public class ActionList extends Action implements Iterable<Action>{
return json;
}
public Tag list() {
Tag span = new Tag("span");
button(t("add action"), Map.of(ACTION, ACTION_ADD)).addTo(span);
button(t("export"), Map.of(ACTION, ACTION_SAVE)).addTo(span);
public <T extends Tag> T listAt(T parent) {
button(parent.is("fieldset") ? t("add action") : "+", Map.of(ACTION, ACTION_ADD)).title(t("add action")).addTo(parent);
if (plan.allowJsonEdit) button(t("edit JSON"), Map.of(ACTION, ACTION_SAVE)).addTo(parent);
if (!isEmpty()) {
Tag list = new Tag("ol");
for (Action action : actions) {
Tag item = action.link("span",action).addTo(new Tag("li")).content(NBSP);
action.button("-", Map.of(ACTION,ACTION_DROP)).addTo(item);
action.button("", Map.of(ACTION,ACTION_MOVE)).addTo(item);
if (action instanceof ActionList) ((ActionList) action).list().addTo(item);
action.button("", Map.of(ACTION,ACTION_MOVE)).title(t("move up")).addTo(item);
action.button("-", Map.of(ACTION,ACTION_DROP)).title(t("delete")).addTo(item);
if (action instanceof ActionList) ((ActionList) action).listAt(item);
item.addTo(list);
}
list.addTo(span);
list.addTo(parent);
}
return span;
return (T)parent;
}
public Action load(JSONObject json) {
@@ -248,9 +247,7 @@ public class ActionList extends Action implements Iterable<Action>{
@Override
protected Window properties(List<Fieldset> preForm, FormInput formInputs, List<Fieldset> postForm,String...errors) {
Fieldset fieldset = new Fieldset(t("Actions"));
list().addTo(fieldset);
postForm.add(fieldset);
preForm.add(listAt(new Fieldset(t("Actions")).clazz("actions")));
return super.properties(preForm, formInputs, postForm,errors);
}

View File

@@ -2,10 +2,13 @@ package de.srsoftware.web4rail.actions;
import java.util.HashMap;
import java.util.List;
import java.util.Optional;
import java.util.Vector;
import org.json.JSONArray;
import org.json.JSONObject;
import de.srsoftware.tools.Tag;
import de.srsoftware.web4rail.BaseClass;
import de.srsoftware.web4rail.conditions.Condition;
import de.srsoftware.web4rail.conditions.ConditionList;
@@ -15,11 +18,14 @@ import de.srsoftware.web4rail.tags.Window;
public class ConditionalAction extends ActionList {
private static final String CONDITIONS = "conditions";
private static final String ELSE_ACTONS = "else_actions";
private ConditionList conditions = new ConditionList();
private ActionList elseActions;
public ConditionalAction(BaseClass parent) {
super(parent);
conditions.parent(this);
elseActions = new ActionList(parent);
}
public boolean equals(ConditionalAction other) {
@@ -29,7 +35,7 @@ public class ConditionalAction extends ActionList {
@Override
public boolean fire(Context context,Object cause) {
for (Condition condition : conditions) {
if (!condition.fulfilledBy(context)) return true; // wenn die Bedingung nicht erfüllt ist, ist das kein Fehler!
if (!condition.fulfilledBy(context)) return elseActions.fire(context, cause);
}
return super.fire(context.clone(),cause); // actions, that happen within the conditional action list must not modify the global context.
}
@@ -48,13 +54,27 @@ public class ConditionalAction extends ActionList {
JSONArray conditions = new JSONArray();
for (Condition condition : this.conditions) conditions.put(condition.json());
json.put(CONDITIONS, conditions);
if (!elseActions.isEmpty()) json.put(ELSE_ACTONS, elseActions.json());
return json;
}
@Override
public <T extends Tag> T listAt(T parent) {
T tag = super.listAt(parent);
if (!elseActions.isEmpty()) {
Tag div = new Tag("div").clazz("else");
new Tag("span").content(t("else:")+NBSP).addTo(div);
elseActions.listAt(div);
div.addTo(tag);
}
return tag;
}
@Override
public Action load(JSONObject json) {
super.load(json);
super.load(json);
if (json.has(CONDITIONS)) {
conditions.clear();
for (Object o : json.getJSONArray(CONDITIONS)) {
if (o instanceof JSONObject) {
JSONObject j = (JSONObject) o;
@@ -66,13 +86,37 @@ public class ConditionalAction extends ActionList {
}
}
}
if (json.has(ELSE_ACTONS)) elseActions.load(json.getJSONObject(ELSE_ACTONS));
return this;
}
@Override
protected Window properties(List<Fieldset> preForm, FormInput formInputs, List<Fieldset> postForm,String...errors) {
preForm.add(conditions.list());
return super.properties(preForm, formInputs, postForm,errors);
Window win = super.properties(preForm, formInputs, postForm,errors);
Optional<Fieldset> actionFieldSet = win.children()
.stream()
.filter(tag -> tag instanceof Fieldset)
.map(tag -> (Fieldset)tag)
.filter(fs -> "actions".equals(fs.get("class")))
.findFirst();
if (actionFieldSet.isPresent()) {
Vector<Tag> children = actionFieldSet.get().children();
children.insertElementAt(new Tag("h3").content(t("Actions in case conditions are fulfilled")),1);
LOG.debug("children: "+children);
Optional<Tag> elseTag = children.stream().filter(tag -> "else".equals(tag.get("class"))).findFirst();
if (elseTag.isPresent()) {
children = elseTag.get().children();
children.remove(0);
children.insertElementAt(new Tag("h3").content(t("Actions in case conditions are <em>not</em> fulfilled")),0);
} else {
children.add(new Tag("h3").content(t("Actions in case conditions are <em>not</em> fulfilled")));
elseActions.listAt(actionFieldSet.get());
}
}
return win;
}

View File

@@ -69,14 +69,14 @@ public class WaitForContact extends ActionList {
}
@Override
public Tag list() {
Tag list = super.list();
public <T extends Tag> T listAt(T parent) {
T list = super.listAt(parent);
for (Tag child : list.children()) {
if (child.is("ol")) {
break;
}
}
timeoutActions.list().addTo(new Tag("span").content(t("On timeout (after {} ms)",timeout)+":")).addTo(list);
timeoutActions.listAt(new Tag("span").content(t("On timeout (after {} ms)",timeout)+":")).addTo(list);
return list;
}
@@ -103,7 +103,7 @@ public class WaitForContact extends ActionList {
Fieldset fieldset = new Fieldset(t("Actions on timeout"));
fieldset.id("actions");
timeoutActions.list().addTo(fieldset);
timeoutActions.listAt(fieldset);
postForm.add(fieldset);
return super.properties(preForm, formInputs, postForm,errors);