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

View File

@@ -78,7 +78,6 @@ public class MainView extends VerticalLayout implements BeforeEnterObserver {
private final NodeEditor nodeEditor;
private final Map<Integer, BlockInstance> instances = new HashMap<>();
private Div palettePanel;
private Component paletteDivider;
private String currentListName;
public MainView(BlockTypeRegistry registry,
@@ -145,9 +144,7 @@ public class MainView extends VerticalLayout implements BeforeEnterObserver {
H2 title = new H2("Workflow Editor");
title.addClassName("tasklist-title");
Span subtitle = new Span("Funktionsblöcke per Drag & Drop in eine Reihenfolge bringen");
subtitle.addClassName("tasklist-subtitle");
title.getStyle().set("white-space", "nowrap");
Button clear = new Button("Workflow löschen", new Icon(VaadinIcon.TRASH));
clear.addThemeVariants(ButtonVariant.LUMO_TERTIARY);
@@ -176,7 +173,7 @@ public class MainView extends VerticalLayout implements BeforeEnterObserver {
Span spacer = new Span();
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;
}
@@ -193,18 +190,28 @@ public class MainView extends VerticalLayout implements BeforeEnterObserver {
hint.addClassName("panel-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));
customType.addThemeVariants(ButtonVariant.LUMO_SMALL, ButtonVariant.LUMO_TERTIARY);
customType.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
customType.addClassName("palette-add-type");
customType.setWidthFull();
customType.addClickListener(e -> openCustomTypeDialog());
panel.add(customType);
// Selbst definierte Elemente
for (BlockType type : registry.all()) {
if (isCustomType(type)) {
addCustomPaletteItem(type);
} else {
panel.add(buildPaletteItem(type));
}
}
return panel;
@@ -214,12 +221,8 @@ public class MainView extends VerticalLayout implements BeforeEnterObserver {
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) {
if (paletteDivider == null) {
paletteDivider = buildPaletteDivider();
palettePanel.add(paletteDivider);
}
palettePanel.add(buildPaletteItem(type));
}
@@ -412,11 +415,6 @@ public class MainView extends VerticalLayout implements BeforeEnterObserver {
+ ex.getMessage());
}
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());
Notification.show("Typ " + type.taskType() + "" + type.label() + "“ gelöscht.");
}