feat: Palette-Layout überarbeitet und Start/Abschluss als reguläre Elemente

- "Eigenen Typ anlegen" als blauer Primary-Button (wie Export-Button)
- Button und Trenner fest zwischen Standard- und Custom-Typen platziert
- Header vereinfacht: Untertitel entfernt, Titel umbruchfrei
- Start/Abschluss-Beschreibungen ohne "virtuell/nicht exportiert"

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-29 17:01:46 +02:00
parent 23b403711d
commit cdfc779bc8
2 changed files with 18 additions and 20 deletions

View File

@@ -36,7 +36,7 @@ public class BlockTypeRegistry {
register(new BlockType( register(new BlockType(
"start", "start",
"Start", "Start",
"Virtuelle Markierung für den Beginn des Workflows (wird nicht exportiert).", "Element für den Beginn des Workflows.",
"vaadin:play", "vaadin:play",
"#16a34a", "#16a34a",
START_TASK_TYPE, START_TASK_TYPE,
@@ -47,7 +47,7 @@ public class BlockTypeRegistry {
register(new BlockType( register(new BlockType(
"abschluss", "abschluss",
"Abschluss", "Abschluss",
"Virtuelle Markierung für das Ende des Workflows (wird nicht exportiert).", "Element für das Ende des Workflows.",
"vaadin:flag-checkered", "vaadin:flag-checkered",
"#b91c1c", "#b91c1c",
END_TASK_TYPE, END_TASK_TYPE,

View File

@@ -78,7 +78,6 @@ public class MainView extends VerticalLayout implements BeforeEnterObserver {
private final NodeEditor nodeEditor; private final NodeEditor nodeEditor;
private final Map<Integer, BlockInstance> instances = new HashMap<>(); private final Map<Integer, BlockInstance> instances = new HashMap<>();
private Div palettePanel; private Div palettePanel;
private Component paletteDivider;
private String currentListName; private String currentListName;
public MainView(BlockTypeRegistry registry, public MainView(BlockTypeRegistry registry,
@@ -145,9 +144,7 @@ public class MainView extends VerticalLayout implements BeforeEnterObserver {
H2 title = new H2("Workflow Editor"); H2 title = new H2("Workflow Editor");
title.addClassName("tasklist-title"); title.addClassName("tasklist-title");
title.getStyle().set("white-space", "nowrap");
Span subtitle = new Span("Funktionsblöcke per Drag & Drop in eine Reihenfolge bringen");
subtitle.addClassName("tasklist-subtitle");
Button clear = new Button("Workflow löschen", new Icon(VaadinIcon.TRASH)); Button clear = new Button("Workflow löschen", new Icon(VaadinIcon.TRASH));
clear.addThemeVariants(ButtonVariant.LUMO_TERTIARY); clear.addThemeVariants(ButtonVariant.LUMO_TERTIARY);
@@ -176,7 +173,7 @@ public class MainView extends VerticalLayout implements BeforeEnterObserver {
Span spacer = new Span(); Span spacer = new Span();
spacer.getStyle().set("flex", "1"); spacer.getStyle().set("flex", "1");
header.add(title, subtitle, spacer, clear, saveCanvas, loadCanvas, appJson, export); header.add(title, spacer, clear, saveCanvas, loadCanvas, appJson, export);
return header; return header;
} }
@@ -193,18 +190,28 @@ public class MainView extends VerticalLayout implements BeforeEnterObserver {
hint.addClassName("panel-hint"); hint.addClassName("panel-hint");
panel.add(hint); panel.add(hint);
// Standardelemente
for (BlockType type : registry.all()) {
if (!isCustomType(type)) {
panel.add(buildPaletteItem(type));
}
}
// Trenner und "Eigenen Typ anlegen"-Button: immer unter den
// Standardelementen und vor den selbst definierten Typen.
panel.add(buildPaletteDivider());
Button customType = new Button("Eigenen Typ anlegen", new Icon(VaadinIcon.PLUS)); Button customType = new Button("Eigenen Typ anlegen", new Icon(VaadinIcon.PLUS));
customType.addThemeVariants(ButtonVariant.LUMO_SMALL, ButtonVariant.LUMO_TERTIARY); customType.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
customType.addClassName("palette-add-type"); customType.addClassName("palette-add-type");
customType.setWidthFull(); customType.setWidthFull();
customType.addClickListener(e -> openCustomTypeDialog()); customType.addClickListener(e -> openCustomTypeDialog());
panel.add(customType); panel.add(customType);
// Selbst definierte Elemente
for (BlockType type : registry.all()) { for (BlockType type : registry.all()) {
if (isCustomType(type)) { if (isCustomType(type)) {
addCustomPaletteItem(type); addCustomPaletteItem(type);
} else {
panel.add(buildPaletteItem(type));
} }
} }
return panel; return panel;
@@ -214,12 +221,8 @@ public class MainView extends VerticalLayout implements BeforeEnterObserver {
return type.taskType() >= BlockTypeRegistry.CUSTOM_TYPE_START; return type.taskType() >= BlockTypeRegistry.CUSTOM_TYPE_START;
} }
/** Fügt ein benutzerdefiniertes Element hinzu und blendet davor einmalig einen Trenner ein. */ /** Fügt ein benutzerdefiniertes Element ans Ende der Palette an (nach dem Button). */
private void addCustomPaletteItem(BlockType type) { private void addCustomPaletteItem(BlockType type) {
if (paletteDivider == null) {
paletteDivider = buildPaletteDivider();
palettePanel.add(paletteDivider);
}
palettePanel.add(buildPaletteItem(type)); palettePanel.add(buildPaletteItem(type));
} }
@@ -412,11 +415,6 @@ public class MainView extends VerticalLayout implements BeforeEnterObserver {
+ ex.getMessage()); + ex.getMessage());
} }
palettePanel.remove(tile); palettePanel.remove(tile);
// Trenner entfernen, wenn kein benutzerdefinierter Typ mehr vorhanden ist.
if (paletteDivider != null && registry.all().stream().noneMatch(this::isCustomType)) {
palettePanel.remove(paletteDivider);
paletteDivider = null;
}
nodeEditor.registerBlockTypes(registry.all()); nodeEditor.registerBlockTypes(registry.all());
Notification.show("Typ " + type.taskType() + "" + type.label() + "“ gelöscht."); Notification.show("Typ " + type.taskType() + "" + type.label() + "“ gelöscht.");
} }