implemented maintenance tasks
This commit is contained in:
2
pom.xml
2
pom.xml
@@ -4,7 +4,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>de.srsoftware</groupId>
|
||||
<artifactId>web4rail</artifactId>
|
||||
<version>1.4.14</version>
|
||||
<version>1.4.15</version>
|
||||
<name>Web4Rail</name>
|
||||
<packaging>jar</packaging>
|
||||
<description>Java Model Railway Control</description>
|
||||
|
||||
@@ -342,6 +342,10 @@ table tr.disabled:hover td {
|
||||
background: yellow;
|
||||
}
|
||||
|
||||
tr.due td{
|
||||
background: orange;
|
||||
}
|
||||
|
||||
table.brake-times tr > *{
|
||||
border-style: solid;
|
||||
border-color: black;
|
||||
|
||||
@@ -130,9 +130,11 @@ disable {} : {} deaktivieren
|
||||
disabled routes : deaktivierte Fahrstraßen
|
||||
DisableEnableBlock : Block (de)aktivieren
|
||||
Display "{}" on {}. : „{}“ auf {} anzeigen.
|
||||
driven distance : zurückgelegte Strecke
|
||||
Drop : Verwerfen
|
||||
Drop brake times : Bremszeiten löschen
|
||||
Dropped destination of {}. : Ziel von {} verworfen.
|
||||
due after : fällig ab
|
||||
1) Duration between 5 {} steps during brake process. : 1) Zeit zwischen 5 {}-Schritten beim Bremsvorgang.
|
||||
EAST : Osten
|
||||
edit : bearbeiten
|
||||
@@ -147,6 +149,7 @@ enable {} : {} aktivieren
|
||||
Engage {} : {} aktivieren
|
||||
EngageDecoupler : Entkuppler aktivieren
|
||||
Enter new name for plan : Neuen Namen für den Plan eingeben
|
||||
executed : ausgeführt
|
||||
extended address : erweiterte Adresse
|
||||
export : exportieren
|
||||
Faster (10 {}) : 10 {} schneller
|
||||
@@ -156,6 +159,7 @@ Firing {} : starte {}
|
||||
For each {} do : Mit jedem {}
|
||||
forward : vorwärts
|
||||
Found {} routes. : {} Routen gefunden.
|
||||
free : frei machen
|
||||
FreeStartBlock : Start-Block freigeben
|
||||
Free tiles behind train : Kacheln hinter dem Zug freigeben
|
||||
Fullscreen : Vollbild
|
||||
@@ -170,6 +174,7 @@ If car of train\: inspect car number : Falls Fahrzeug aus Zug: Untersuche Fahrze
|
||||
If checked, tiles behind the train are freed according to the length of the train and the tiles. If it is unchecked, tiles will not get free before route is finished.
|
||||
Falls aktiviert, wird die Strecke anhand von Zug- und Kachel-Länge hinter dem Zug freigegeben, Falls deaktiviert wird die Strecke hinter dem Zug erst bei Abschluss der Route freigegeben.
|
||||
internal contacts : interne Kontakte
|
||||
Interval : Intervall
|
||||
inverted : invertiert
|
||||
Inverts the direction {} is heading to. : Kehrt die Richtung, in welche {} fährt, um.
|
||||
{} is not a block! : {} ist kein Block!
|
||||
@@ -181,6 +186,7 @@ known locomotives : bekannte Lokomotiven
|
||||
known trains : bekannte Züge
|
||||
Label for state {} : Beschriftung für Status {}
|
||||
Last blocks : Letzte Blöcke
|
||||
Last execution : letzte Ausführung
|
||||
last parked train : letzten geparkten Zug
|
||||
learn : lernen
|
||||
LEFT : links
|
||||
@@ -195,6 +201,7 @@ Locomotives : Lokomotiven
|
||||
Locomotives and cars : Lokomotiven und Waggons
|
||||
Loop : Wiederholung
|
||||
Lower speed limit : Minimale Geschwindigkeit
|
||||
Maintenance : Wartung
|
||||
Manage cars : Waggons verwalten
|
||||
Manage locos : Lokomotiven verwalten
|
||||
Manage trains : Züge verwalten
|
||||
@@ -203,6 +210,7 @@ Maximum Speed : Höchstgeschwindigkeit
|
||||
maximum speed v<sub>max</sub> : Höchstgeschwindigkeit v<sub>max</sub>
|
||||
Maximum train length : maximale Zug-Länge
|
||||
mid speed v<sub>mid</sub> : mittlere Geschwindigeit v<sub>mid</sub>
|
||||
mileage : Laufleistung
|
||||
Minimum delay : minimale Verzögerung
|
||||
Minimum and maximum times (in Miliseconds) trains with the respective tag have to wait in this block. : Minamle und maximale Block-Haltezeit (in Millisekunden) für Züge mit der entsprchender Markierung.
|
||||
minimum starting voltage v<sub>min</sub> : Mindestanfahrspannung v<sub>min</sub>
|
||||
@@ -351,6 +359,8 @@ Switch power on : Strom anschalten
|
||||
SYSTEM : Betriebssystem
|
||||
Tag : Markierung
|
||||
Tags : Markierungen
|
||||
Task : Aufgabe
|
||||
Task type : Aufgabe
|
||||
Text to display on clients : Text, welcher auf den Clients angezeigt werden soll
|
||||
Text to show on display : Text, welcher in der Anzeige dargestellt werden soll
|
||||
Tile(s) : Kachel(n)
|
||||
|
||||
@@ -127,6 +127,8 @@ public class Application extends BaseClass{
|
||||
return plan.controlUnit().process(params);
|
||||
case REALM_LOCO:
|
||||
return Locomotive.action(params,plan);
|
||||
case REALM_MAINTENANCE:
|
||||
return MaintnanceTask.action(params);
|
||||
case REALM_PLAN:
|
||||
return plan.action(params);
|
||||
case REALM_ROUTE:
|
||||
|
||||
@@ -2,6 +2,7 @@ package de.srsoftware.web4rail;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.AbstractMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@@ -567,6 +568,11 @@ public abstract class BaseClass implements Constants{
|
||||
return Translation.get(Application.class, txt, fills);
|
||||
}
|
||||
|
||||
public static String time(Date date) {
|
||||
return isSet(date) ? new SimpleDateFormat("YYYY-dd-MM HH:mm").format(date) : null;
|
||||
}
|
||||
|
||||
|
||||
public static long timestamp() {
|
||||
return new Date().getTime();
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ public interface Constants {
|
||||
public static final String REALM_CONTACT = "contact";
|
||||
public static final String REALM_CU = "cu";
|
||||
public static final String REALM_LOCO = "loco";
|
||||
public static final String REALM_MAINTENANCE = "maintenance";
|
||||
public static final String REALM_ROUTE = "route";
|
||||
public static final String REALM_PLAN = "plan";
|
||||
public static final String REALM_TRAIN = "train";
|
||||
|
||||
150
src/main/java/de/srsoftware/web4rail/MaintnanceTask.java
Normal file
150
src/main/java/de/srsoftware/web4rail/MaintnanceTask.java
Normal file
@@ -0,0 +1,150 @@
|
||||
package de.srsoftware.web4rail;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import de.srsoftware.web4rail.moving.Car;
|
||||
import de.srsoftware.web4rail.moving.Train;
|
||||
import de.srsoftware.web4rail.tags.AddSelect;
|
||||
import de.srsoftware.web4rail.tags.Button;
|
||||
import de.srsoftware.web4rail.tiles.Block;
|
||||
|
||||
public class MaintnanceTask extends BaseClass{
|
||||
private static final HashSet<String> tasks = new HashSet<>();
|
||||
|
||||
private static final String NAME = "name";
|
||||
|
||||
public static final String INTERVAL = "interval";
|
||||
|
||||
private static final String LAST_DATE = "last_date";
|
||||
|
||||
private static final String LAST_DIST = "last_dist";
|
||||
|
||||
private long interval;
|
||||
private long lastExecutionDist;
|
||||
private Date lastExecutionDate;
|
||||
private String name;
|
||||
|
||||
public MaintnanceTask(Car car, String name, long interval) {
|
||||
this.name = name;
|
||||
this.interval = interval;
|
||||
parent(car);
|
||||
register();
|
||||
if (isSet(name)) tasks.add(name);
|
||||
}
|
||||
|
||||
public static Object action(HashMap<String, String> params) {
|
||||
String action = params.get(ACTION);
|
||||
if (isNull(action)) return t("No action set!");
|
||||
|
||||
MaintnanceTask task = BaseClass.get(Id.from(params));
|
||||
|
||||
switch (action) {
|
||||
case ACTION_ADD:
|
||||
Car car = BaseClass.get(Id.from(params, REALM_CAR));
|
||||
return car.addTask(createTask(params));
|
||||
case ACTION_DROP:
|
||||
if (isSet(task)) {
|
||||
BaseClass parent = task.parent();
|
||||
task.remove();
|
||||
return parent.properties();
|
||||
}
|
||||
return t("No task!");
|
||||
case ACTION_START:
|
||||
return isSet(task) ? task.executed() : t("No task!");
|
||||
}
|
||||
String err = t("unknown action: {}",action);
|
||||
return (isSet(task)) ? task.parent().properties(err) : err;
|
||||
}
|
||||
|
||||
private static MaintnanceTask createTask(HashMap<String, String> params) {
|
||||
String name = params.get(NAME);
|
||||
long interval = Long.parseLong(params.get(INTERVAL));
|
||||
Car car = BaseClass.get(Id.from(params, REALM_CAR));
|
||||
return new MaintnanceTask(car, name,interval);
|
||||
}
|
||||
|
||||
public Button execBtn() {
|
||||
return button(t("executed"), Map.of(REALM,REALM_MAINTENANCE,ACTION,ACTION_START));
|
||||
}
|
||||
|
||||
private Object executed() {
|
||||
BaseClass parent = parent();
|
||||
if (parent instanceof Car) {
|
||||
Car car = (Car) parent;
|
||||
lastExecutionDate = new Date();
|
||||
lastExecutionDist = car.drivenDistance();
|
||||
Train train = car.train();
|
||||
if (isSet(train)) {
|
||||
Block block = train.currentBlock();
|
||||
if (isSet(block)) plan.place(block);
|
||||
}
|
||||
return car.properties();
|
||||
}
|
||||
return t("parent is not a car!");
|
||||
}
|
||||
|
||||
public long interval() {
|
||||
return interval;
|
||||
}
|
||||
|
||||
public boolean isDue() {
|
||||
return ((Car)parent()).drivenDistance() > lastExecutionDist+interval;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSONObject json() {
|
||||
JSONObject json = super.json();
|
||||
json.put(NAME, name);
|
||||
json.put(INTERVAL, interval);
|
||||
if (isSet(lastExecutionDate)) {
|
||||
json.put(LAST_DATE, lastExecutionDate.getTime());
|
||||
json.put(LAST_DIST, lastExecutionDist);
|
||||
}
|
||||
return json;
|
||||
}
|
||||
|
||||
public Date lastDate() {
|
||||
return lastExecutionDate;
|
||||
}
|
||||
|
||||
public long lastMileage() {
|
||||
return lastExecutionDist;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MaintnanceTask load(JSONObject json) {
|
||||
json.remove(ID); // we're using the id created by the constructor!
|
||||
super.load(json);
|
||||
name = json.getString(NAME);
|
||||
interval = json.getLong(INTERVAL);
|
||||
if (json.has(LAST_DATE)) lastExecutionDate = new Date(json.getLong(LAST_DATE));
|
||||
if (json.has(LAST_DIST)) lastExecutionDist = json.getLong(LAST_DIST);
|
||||
if (isSet(name)) tasks.add(name);
|
||||
return this;
|
||||
}
|
||||
|
||||
public long nextMileage() {
|
||||
return lastExecutionDist+interval;
|
||||
}
|
||||
|
||||
public Button removeBtn() {
|
||||
return button(t("delete"), Map.of(REALM,REALM_MAINTENANCE,ACTION,ACTION_DROP));
|
||||
}
|
||||
|
||||
public static AddSelect selector() {
|
||||
AddSelect select = new AddSelect(NAME);
|
||||
select.addOption(t("create new task type"));
|
||||
tasks.forEach(task -> select.addOption(task));
|
||||
return select;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
@@ -492,6 +492,10 @@ public class Route extends BaseClass {
|
||||
return json;
|
||||
}
|
||||
|
||||
public long length() {
|
||||
return path.stream().mapToLong(Tile::length).sum();
|
||||
}
|
||||
|
||||
private Route load(JSONObject json,Plan plan) {
|
||||
if (json.has(ID)) id = Id.from(json);
|
||||
if (json.has(NAME)) name(json.getString(NAME));
|
||||
|
||||
@@ -14,12 +14,14 @@ import java.util.TreeSet;
|
||||
import java.util.Vector;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import de.srsoftware.tools.Tag;
|
||||
import de.srsoftware.web4rail.BaseClass;
|
||||
import de.srsoftware.web4rail.MaintnanceTask;
|
||||
import de.srsoftware.web4rail.Plan;
|
||||
import de.srsoftware.web4rail.tags.Button;
|
||||
import de.srsoftware.web4rail.tags.Fieldset;
|
||||
@@ -45,7 +47,12 @@ public class Car extends BaseClass implements Comparable<Car>{
|
||||
private static final String MAX_SPEED_REVERSE = "max_speed_reverse";
|
||||
private static final String ORDER = "order";
|
||||
private static final String ORIENTATION = "orientation";
|
||||
protected HashSet<String> tags = new HashSet<String>();
|
||||
|
||||
private static final String DRIVEN_DISTANCE = "driven_distance";
|
||||
|
||||
private static final String MAINTENANCE = "maintenance";
|
||||
protected HashSet<String> tags = new HashSet<>();
|
||||
private HashSet<MaintnanceTask> tasks = new HashSet<>();
|
||||
|
||||
private String name;
|
||||
public int length;
|
||||
@@ -54,6 +61,7 @@ public class Car extends BaseClass implements Comparable<Car>{
|
||||
protected int maxSpeedForward = 0;
|
||||
protected int maxSpeedReverse = 0;
|
||||
protected boolean orientation = FORWARD;
|
||||
protected long distanceCounter = 0;
|
||||
|
||||
public Car(String name) {
|
||||
this(name,null);
|
||||
@@ -93,6 +101,11 @@ public class Car extends BaseClass implements Comparable<Car>{
|
||||
return t("Unknown action: {}",params.get(ACTION));
|
||||
}
|
||||
|
||||
public Object addTask(MaintnanceTask newTask) {
|
||||
tasks.add(newTask);
|
||||
return properties();
|
||||
}
|
||||
|
||||
public Car clone() {
|
||||
Car clone = new Car(name);
|
||||
clone.maxSpeedForward = maxSpeedForward;
|
||||
@@ -114,6 +127,14 @@ public class Car extends BaseClass implements Comparable<Car>{
|
||||
public int compareTo(Car o) {
|
||||
return (stockId+":"+name).compareTo(o.stockId+":"+o.name);
|
||||
}
|
||||
|
||||
public Object addDistance(long len) {
|
||||
return distanceCounter+= len;
|
||||
}
|
||||
|
||||
public long drivenDistance() {
|
||||
return distanceCounter;
|
||||
}
|
||||
|
||||
public JSONObject json() {
|
||||
JSONObject json = super.json();
|
||||
@@ -123,7 +144,12 @@ public class Car extends BaseClass implements Comparable<Car>{
|
||||
if (maxSpeedReverse != 0) json.put(MAX_SPEED_REVERSE, maxSpeedReverse);
|
||||
json.put(ORIENTATION, orientation);
|
||||
json.put(STOCK_ID, stockId);
|
||||
if (distanceCounter>0) json.put(DRIVEN_DISTANCE, distanceCounter);
|
||||
if (!tags.isEmpty()) json.put(TAGS, tags);
|
||||
if (!tasks.isEmpty()) {
|
||||
json.put(MAINTENANCE, tasks.stream().map(MaintnanceTask::json).collect(Collectors.toList()));
|
||||
LOG.debug("json: {}",json);
|
||||
}
|
||||
return json;
|
||||
}
|
||||
|
||||
@@ -166,9 +192,38 @@ public class Car extends BaseClass implements Comparable<Car>{
|
||||
if (json.has(STOCK_ID)) stockId = json.getString(STOCK_ID);
|
||||
if (json.has(TAGS)) json.getJSONArray(TAGS).forEach(elem -> { tags.add(elem.toString()); });
|
||||
if (json.has(ORIENTATION)) orientation=json.getBoolean(ORIENTATION);
|
||||
if (json.has(DRIVEN_DISTANCE)) distanceCounter = json.getLong(DRIVEN_DISTANCE);
|
||||
if (json.has(MAINTENANCE)) loadMaintenance(json.getJSONArray(MAINTENANCE));
|
||||
return this;
|
||||
}
|
||||
|
||||
private void loadMaintenance(JSONArray arr) {
|
||||
arr.forEach(o -> {
|
||||
if (o instanceof JSONObject) {
|
||||
tasks.add(new MaintnanceTask(this,null,0).load((JSONObject) o));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private Fieldset maintenance() {
|
||||
Fieldset fieldset = new Fieldset(t("Maintenance")+(needsMaintenance()?NBSP+"⚠":""));
|
||||
Table table = new Table();
|
||||
table.addHead(t("Task"),t("Last execution"),t("due after"),t("Interval"),t("Actions"));
|
||||
for (MaintnanceTask task : tasks) {
|
||||
Tag row = table.addRow(task,time(task.lastDate())+" / "+task.lastMileage()+NBSP+Plan.lengthUnit,task.nextMileage()+NBSP+Plan.lengthUnit,task.interval()+NBSP+Plan.lengthUnit,task.execBtn()+NBSP+task.removeBtn());
|
||||
if (task.isDue()) row.clazz("due");
|
||||
}
|
||||
table.addTo(fieldset);
|
||||
Form form = new Form("create-task");
|
||||
new Input(REALM,REALM_MAINTENANCE).hideIn(form);
|
||||
new Input(ACTION,ACTION_ADD).hideIn(form);
|
||||
new Input(REALM_CAR,id()).hideIn(form);
|
||||
MaintnanceTask.selector().addTo(new Label(t("Task type")+NBSP)).addTo(form);
|
||||
new Input(MaintnanceTask.INTERVAL,1_000_000).numeric().addTo(new Label(t("Interval")+NBSP)).content(NBSP+Plan.lengthUnit).addTo(form);
|
||||
new Button(t("add"), form).addTo(form);
|
||||
return form.addTo(fieldset);
|
||||
}
|
||||
|
||||
public static Object manager(Map<String, String> params) {
|
||||
Window win = new Window("car-manager", t("Car manager"));
|
||||
new Tag("h4").content(t("known cars")).addTo(win);
|
||||
@@ -177,7 +232,7 @@ public class Car extends BaseClass implements Comparable<Car>{
|
||||
String order = params.get(ORDER);
|
||||
|
||||
Tag nameLink = link("span", t("Name"), Map.of(REALM,REALM_CAR,ACTION,ACTION_PROPS,ORDER,NAME));
|
||||
Table table = new Table().addHead(t("Stock ID"),nameLink,t("Max. Speed",speedUnit),t("Length"),t("Train"),t("Tags"),t("Actions"));
|
||||
Table table = new Table().addHead(t("Stock ID"),nameLink,t("Max. Speed",speedUnit),t("Length"),t("Train"),t("Tags"),t("driven distance"),t("Actions"));
|
||||
List<Car> cars = BaseClass.listElements(Car.class)
|
||||
.stream()
|
||||
.filter(car -> !(car instanceof Locomotive))
|
||||
@@ -210,6 +265,7 @@ public class Car extends BaseClass implements Comparable<Car>{
|
||||
car.length+NBSP+lengthUnit,
|
||||
isSet(car.train) ? car.train.link("span", car.train) : "",
|
||||
String.join(", ", car.tags()),
|
||||
car.distanceCounter,
|
||||
actions
|
||||
);
|
||||
}
|
||||
@@ -238,6 +294,12 @@ public class Car extends BaseClass implements Comparable<Car>{
|
||||
return name;
|
||||
}
|
||||
|
||||
boolean needsMaintenance() {
|
||||
for (MaintnanceTask task : tasks) {
|
||||
if (task.isDue()) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public boolean orientation() {
|
||||
return orientation;
|
||||
}
|
||||
@@ -252,15 +314,17 @@ public class Car extends BaseClass implements Comparable<Car>{
|
||||
new Input(MAX_SPEED, maxSpeedForward).numeric().addTo(new Tag("p")).content(NBSP+speedUnit+NBSP+t("forward")).addTo(div);
|
||||
new Input(MAX_SPEED_REVERSE, maxSpeedReverse).numeric().addTo(new Tag("p")).content(NBSP+speedUnit+NBSP+t("backward")).addTo(div);
|
||||
formInputs.add(t("Maximum Speed"),div);
|
||||
if (train != null) formInputs.add(t("Train"), train.link());
|
||||
if (isSet(train)) formInputs.add(t("Train"), train.link());
|
||||
formInputs.add(t("Current orientation"),new Tag("span").content(orientation ? t("forward") : t("reverse")));
|
||||
|
||||
formInputs.add(t("driven distance"),new Tag("span").content(distanceCounter+" "+Plan.lengthUnit));
|
||||
postForm.add(maintenance());
|
||||
return super.properties(preForm,formInputs,postForm,errors);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void removeChild(BaseClass child) {
|
||||
if (child == train) train = null;
|
||||
tasks.remove(child);
|
||||
super.removeChild(child);
|
||||
}
|
||||
|
||||
|
||||
@@ -270,14 +270,21 @@ public class Locomotive extends Car implements Constants,Device{
|
||||
|
||||
new Tag("p").content(t("Click on a name to edit the entry.")).addTo(win);
|
||||
|
||||
Table table = new Table().addHead(t("Stock ID"),t("Name"),t("Max. Speed",speedUnit),t("Protocol"),t("Address"),t("Length"),t("Tags"));
|
||||
Table table = new Table().addHead(t("Stock ID"),t("Name"),t("Max. Speed",speedUnit),t("Protocol"),t("Address"),t("Length"),t("driven distance"),t("Tags"));
|
||||
List<Locomotive> locos = BaseClass.listElements(Locomotive.class);
|
||||
locos.sort(Comparator.comparing(loco -> loco.address));
|
||||
locos.sort(Comparator.comparing(loco -> loco.stockId));
|
||||
for (Locomotive loco : locos) {
|
||||
String maxSpeed = (loco.maxSpeedForward == 0 ? "–":""+loco.maxSpeedForward)+NBSP;
|
||||
if (loco.maxSpeedReverse != loco.maxSpeedForward) maxSpeed += "("+loco.maxSpeedReverse+")"+NBSP;
|
||||
table.addRow(loco.stockId,loco.link(),maxSpeed+speedUnit,loco.proto,loco.address,loco.length+NBSP+lengthUnit,String.join(", ", loco.tags()));
|
||||
table.addRow(loco.stockId,
|
||||
loco.link(),
|
||||
maxSpeed+NBSP+speedUnit,
|
||||
loco.proto,
|
||||
loco.address,
|
||||
loco.length+NBSP+lengthUnit,
|
||||
loco.distanceCounter,
|
||||
String.join(", ", loco.tags()));
|
||||
}
|
||||
table.addTo(win);
|
||||
|
||||
|
||||
@@ -229,7 +229,7 @@ public class Train extends BaseClass implements Comparable<Train> {
|
||||
|
||||
boolean first = true;
|
||||
for (Car car : cars) {
|
||||
Tag link = car.link(car.name()+(car.stockId.isEmpty() ? "" : " ("+car.stockId+")"));
|
||||
Tag link = car.link(car.name()+(car.needsMaintenance()?"⚠":"")+(car.stockId.isEmpty() ? "" : " ("+car.stockId+")"));
|
||||
Tag buttons = new Tag("span");
|
||||
|
||||
car.button(t("turn within train"),Map.of(ACTION,ACTION_TURN)).addTo(buttons);
|
||||
@@ -390,6 +390,7 @@ public class Train extends BaseClass implements Comparable<Train> {
|
||||
|
||||
public String directedName() {
|
||||
String result = name();
|
||||
if (needsMainenance()) result+="⚠";
|
||||
String mark = autopilot ? "ⓐ" : "";
|
||||
if (isNull(direction)) return result;
|
||||
switch (direction) {
|
||||
@@ -516,6 +517,9 @@ public class Train extends BaseClass implements Comparable<Train> {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
long len = endedRoute.length();
|
||||
if (len>0) cars.forEach(car -> car.addDistance(len));
|
||||
}
|
||||
|
||||
private Tag faster(int steps) {
|
||||
@@ -733,6 +737,13 @@ public class Train extends BaseClass implements Comparable<Train> {
|
||||
return this;
|
||||
}
|
||||
|
||||
private boolean needsMainenance() {
|
||||
for (Car car: cars) {
|
||||
if (car.needsMaintenance()) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean onTrace(Tile t) {
|
||||
return trace.contains(t);
|
||||
}
|
||||
@@ -783,7 +794,7 @@ public class Train extends BaseClass implements Comparable<Train> {
|
||||
formInputs.add(t("Tags"), new Input(TAGS,String.join(", ", tags)));
|
||||
|
||||
if (this.hasLoco()) preForm.add(Locomotive.cockpit(this));
|
||||
postForm.add(propList.addTo(new Fieldset(t("other train properties")).id("props-other")));
|
||||
postForm.add(propList.addTo(new Fieldset(t("other train properties")+(needsMainenance()?NBSP+"⚠":"")).id("props-other")));
|
||||
postForm.add(brakeTimes());
|
||||
postForm.add(blockHistory());
|
||||
|
||||
|
||||
26
src/main/java/de/srsoftware/web4rail/tags/AddSelect.java
Normal file
26
src/main/java/de/srsoftware/web4rail/tags/AddSelect.java
Normal file
@@ -0,0 +1,26 @@
|
||||
package de.srsoftware.web4rail.tags;
|
||||
|
||||
import de.srsoftware.tools.Tag;
|
||||
|
||||
public class AddSelect extends Input {
|
||||
private static final long serialVersionUID = -2168654457876014503L;
|
||||
private Tag dataList;
|
||||
|
||||
public AddSelect(String name) {
|
||||
super("select");
|
||||
attr("name",name);
|
||||
attr("list","list-options");
|
||||
dataList = new Tag("datalist").id("list-options");
|
||||
dataList.addTo(this);
|
||||
}
|
||||
|
||||
public Tag addOption(Object value) {
|
||||
return addOption(value, value);
|
||||
}
|
||||
|
||||
public Tag addOption(Object value, Object text) {
|
||||
Tag option = new Tag("option").attr("value", value.toString()).content(text.toString());
|
||||
option.addTo(dataList);
|
||||
return option;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user